Skip to content

Commit

Permalink
Merge pull request #19 from goliney/feature/search-#11
Browse files Browse the repository at this point in the history
feat(client): Search input 🔍 in client app
  • Loading branch information
goliney authored Feb 26, 2017
2 parents 7dbfe43 + a6c6bef commit feffb97
Show file tree
Hide file tree
Showing 22 changed files with 297 additions and 51 deletions.
4 changes: 4 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
},
"extends": "eslint:recommended",
"rules": {
"comma-dangle": [
"error",
"always-multiline"
],
"indent": [
"error",
4
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions example/source/20__Folder 1/20__Item 3/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h2>This is from index.html</h2>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h2>This is from index.html</h2>
1 change: 1 addition & 0 deletions example/source/30__Item 5/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h2>This is from index.html</h2>
10 changes: 5 additions & 5 deletions lib/coderoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = {
copyMedia();

generateHtml();
}
},
};

function planRooms(sourceDir, parent) {
Expand All @@ -43,7 +43,7 @@ function planRooms(sourceDir, parent) {
// complex item (html, css, js)
room.addFiles([
path.join(sourceDir, 'index.html'),
...files.filter(file => _.includes(settings.supportedExt, path.parse(file).ext))
...files.filter(file => _.includes(settings.supportedExt, path.parse(file).ext)),
]);
} else {
// simple dir
Expand Down Expand Up @@ -151,7 +151,7 @@ function generateHtml() {
depth,
css_paths,
js_paths,
html: roomsFiles[0]
html: roomsFiles[0],
})
);

Expand All @@ -167,7 +167,7 @@ function generateHtml() {
css_paths,
js_paths,
hasCSS: css_paths.length > 0,
hasJS: js_paths.length > 0
hasJS: js_paths.length > 0,
})
);
}
Expand All @@ -180,7 +180,7 @@ function generateHtml() {
settings,
root,
config: root.config,
depth: 0
depth: 0,
})
);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/room.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = class Room {
this.config = {
title: '',
assets: [],
media: []
media: [],
};
this.parse = path.parse(source);
this.stat = fs.statSync(source);
Expand Down Expand Up @@ -104,7 +104,7 @@ module.exports = class Room {
parse,
active: index === 0,
normalized: normalizePath(file),
title: utils.normalizeName(parse.base)
title: utils.normalizeName(parse.base),
};
});
}
Expand Down
9 changes: 5 additions & 4 deletions lib/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ module.exports = {
sass_entry: './templates/default/scss/base.scss',
paths: {
static: './templates/default/static',
templates: './templates/default/tpls'
templates: './templates/default/tpls',
},
static_css: [
'static/font-awesome-4.6.3/css/font-awesome.min.css',
'static/css/base.css'
'static/css/base.css',
],
static_js: [
'static/js/vendor/ace/ace.js',
'static/js/vendor/ace/mode-html.js',
'static/js/vendor/jquery-2.2.3.min.js',
'static/js/base.js',
'static/js/editor.js'
]
'static/js/editor.js',
'static/js/search.js',
],
};

27 changes: 27 additions & 0 deletions lib/templates/default/scss/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,33 @@ body {
font-size: $body_font_size;
}

button {
// reset button styles
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
background: transparent;
border: none;
}

input {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-background-clip: padding;
-moz-background-clip: padding;
background-clip: padding-box;
border: 0;
border-radius: 0;
-webkit-appearance: none;
margin: 0;
padding: 0;
text-align: left;
font-size: 1em;
height: 1em;
vertical-align: middle;
}

.hidden {
display: none;
}
Expand Down
77 changes: 77 additions & 0 deletions lib/templates/default/scss/_sidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,66 @@
}

#menu {
.search {
position: relative;
display: flex;
align-items: center;
padding: 0;

.fa-search {
position: absolute;
left: $sidebar_gutter;
color: $sidebar_color_dim;
z-index: -1;
}

.fa-remove {
display: none;
position: absolute;
right: 0;
padding: 0 $sidebar_gutter 0 10px;
line-height: 35px;
color: $sidebar_color_bright;
cursor: pointer;

&:hover,
&:focus {
color: $sidebar_active_color;
}
}

&.has-query .fa-remove {
display: inline-block;
}

&:hover .fa-search,
&.has-query .fa-search,
&.focus .fa-search { // .focus - not :focus
color: $sidebar_color_bright;
}

input {
flex: 1;
height: 35px;
background-color: transparent;
padding: 0 ($sidebar_gutter + 20px);
color: $sidebar_color_bright;
cursor: pointer;

&:hover::-webkit-input-placeholder,
&:focus::-webkit-input-placeholder {
color: $sidebar_color_bright;
}
&:hover::-moz-placeholder,
&:focus::-moz-placeholder {
color: $sidebar_color_bright;
}
&:hover:-ms-input-placeholder,
&:focus:-ms-input-placeholder {
color: $sidebar_color_bright;
}
}
}

a,
a:visited,
Expand Down Expand Up @@ -58,5 +118,22 @@
> li:first-child {
border-top: 1px solid $sidebar_separator_color;
}

.filtered-out {
display: none;
}
}

[no-items-label] {
display: none;
padding: $sidebar_gutter;
padding-top: $sidebar_gutter * 2;
font-style: italic;
}

&.no-search-results {
[no-items-label] {
display: block;
}
}
}
2 changes: 1 addition & 1 deletion lib/templates/default/static/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ var editor;
mouseup: function () {
$backdrop.off('mousemove mouseup');
$backdrop.addClass('hidden');
}
},
});

initialX = e.pageX;
Expand Down
2 changes: 1 addition & 1 deletion lib/templates/default/static/js/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
var modes = {
html: null,
css: null,
js: null
js: null,
};

if ($editorEl) {
Expand Down
128 changes: 128 additions & 0 deletions lib/templates/default/static/js/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
(function () {
'use strict';
var FILTERED_OUT_CLASS = 'filtered-out';
var FILTERED_IN_CLASS = 'filtered-in';
var DIR_FILTERED_IN_CLASS = 'dir-filtered-in';
var HAS_QUERY_CLASS = 'has-query';
var NO_ITEMS_AVAILABLE_CLASS = 'no-search-results';
var SEARCH_DATA_KEY = 'SEARCH_DATA_KEY';

var $sidebar = $('#sidebar');
var $searchWrap = $sidebar.find('.search');
var $input = $searchWrap.find('input');
var $clear = $searchWrap.find('[clear]');

var $items = $sidebar.find('li:not(.search)');

activate();

function activate() {
$input.focus();
bindEvents();
prepareTreeData();
}

function bindEvents() {
$input.on('focus', function () {
$searchWrap.addClass('focus');
});

$input.on('blur', function () {
$searchWrap.removeClass('focus');
});

$input.on('keydown', function (e) {
if (e.keyCode == 27) { // ESC
$input.val('');
$input.change();
}
});

$input.on('propertychange change click keyup input paste', function () {
var value = $input.val().trim();
if ($input.data('oldVal') != value) {
$input.data('oldVal', value);

if (value.length > 0) {
$searchWrap.addClass(HAS_QUERY_CLASS);
filter(value);
} else {
$searchWrap.removeClass(HAS_QUERY_CLASS);
clearFilter();
}
checkItemsAvailability();
}
});

$clear.on('click', function () {
$input.val('');
$input.change();
$input.focus();
});
}

function prepareTreeData() {
$items.each(function () {
var $item = $(this);
var $childDir = $item.children('.dir-name');
var $children = $item.find('.link, .dir-name');
var $arrayOfNames = $children.map(function () {
return $(this).text().toLowerCase();
});
var isDir = $childDir.length > 0;

$item.data(SEARCH_DATA_KEY, {
isDir: isDir,
dirName: isDir ? $childDir.text().toLowerCase() : '',
allNames: $arrayOfNames.get(),
});
});
}

function filter(query) {
query = query.toLowerCase();
$items.each(function () {
var $item = $(this);
var childrenNames = $item.data(SEARCH_DATA_KEY).allNames;
var isDir = $item.data(SEARCH_DATA_KEY).isDir;
var dirName = $item.data(SEARCH_DATA_KEY).dirName;

var hasMatchedChild = childrenNames.some(function (name) {
return name.indexOf(query) !== -1;
});

var isDirMatch = isDir && dirName.indexOf(query) !== -1;
var hasParentDirMatch = $item.parents('.' + DIR_FILTERED_IN_CLASS).length > 0;

// if dir name matches search - set class to dir
if (isDirMatch) {
$item.addClass(DIR_FILTERED_IN_CLASS);
} else {
$item.removeClass(DIR_FILTERED_IN_CLASS);
}

if (hasMatchedChild || hasParentDirMatch) {
$item.addClass(FILTERED_IN_CLASS);
$item.removeClass(FILTERED_OUT_CLASS);
} else {
$item.addClass(FILTERED_OUT_CLASS);
$item.removeClass(FILTERED_IN_CLASS);
}
});
}

function clearFilter() {
$items.removeClass(FILTERED_IN_CLASS);
$items.removeClass(FILTERED_OUT_CLASS);
}

function checkItemsAvailability() {
var hasAvailableItems = $items.filter('.' + FILTERED_IN_CLASS).length > 0;
var hasQuery = $input.val().length > 0;
if (hasAvailableItems || !hasQuery) {
$sidebar.removeClass(NO_ITEMS_AVAILABLE_CLASS);
} else {
$sidebar.addClass(NO_ITEMS_AVAILABLE_CLASS);
}
}
})();
6 changes: 6 additions & 0 deletions lib/templates/default/tpls/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@
<a href="{{path_to_root depth}}index.html">{{root.config.title}}</a>
</header>
<ul id="menu">
<li class="search">
<i class="fa fa-search"></i>
<input type="text" placeholder="Search...">
<button type="button" clear class="fa fa-remove" title="Clear search"></button>
</li>
{{> menu with depth=depth items=root.items base='tpls'}}
</ul>
<div no-items-label>No results found.</div>
</section>
<!-- /sidebar -->

Expand Down
Loading

0 comments on commit feffb97

Please sign in to comment.