diff --git a/.eslintignore b/.eslintignore index 7bb1831a13..c3979d0377 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ dist/ -example/bundle.js +docs/ +dev/bundle.js diff --git a/.gitignore b/.gitignore index 7c4807aa13..7f281aac0a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/ dist/ -example/bundle.js* +dev/bundle.js* +examples/*/*.css npm-debug.log diff --git a/.sass-lint.yml b/.sass-lint.yml index 0aa25d70fc..a209fde2e6 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -1,7 +1,7 @@ options: formatter: stylish files: - include: 'themes/**/*.s+(a|c)ss' + include: '+(examples|themes)/**/*.s+(a|c)ss' rules: # Extends extends-before-mixins: 1 @@ -24,7 +24,7 @@ rules: no-duplicate-properties: 1 no-empty-rulesets: 1 no-extends: 0 - no-ids: 1 + no-ids: 0 no-important: 1 no-invalid-hex: 1 no-mergeable-selectors: 1 @@ -38,7 +38,7 @@ rules: # Nesting force-attribute-nesting: 1 - force-element-nesting: 1 + force-element-nesting: 0 force-pseudo-nesting: 1 # Name Formats @@ -59,7 +59,7 @@ rules: style: uppercase indentation: 1 leading-zero: 1 - nesting-depth: 1 + nesting-depth: 0 property-sort-order: 0 quotes: 0 shorthand-values: 1 diff --git a/example/app.js b/dev/app.js similarity index 100% rename from example/app.js rename to dev/app.js diff --git a/example/debug.css b/dev/debug.css similarity index 100% rename from example/debug.css rename to dev/debug.css diff --git a/example/default.css b/dev/default.css similarity index 100% rename from example/default.css rename to dev/default.css diff --git a/example/index.html b/dev/index.html similarity index 100% rename from example/index.html rename to dev/index.html diff --git a/example/style.css b/dev/style.css similarity index 100% rename from example/style.css rename to dev/style.css diff --git a/example/templates/item.html b/dev/templates/item.html similarity index 100% rename from example/templates/item.html rename to dev/templates/item.html diff --git a/example/templates/no-results.html b/dev/templates/no-results.html similarity index 100% rename from example/templates/no-results.html rename to dev/templates/no-results.html diff --git a/docs/_config.yml b/docs/_config.yml index 3443015753..8f9955b2dd 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -7,10 +7,12 @@ github_username: algolia # Navigation navigation: - - text: Widgets - url: /widgets/ - - text: Themes - url: /themes/ + - text: Documentation + url: /documentation/ + - text: Examples + url: /examples/ + # - text: Themes + # url: /themes/ - text: About url: /about/ # Build settings diff --git a/docs/css/_helper.sass b/docs/css/_helper.sass index 18b34aeacc..73e9c44a72 100644 --- a/docs/css/_helper.sass +++ b/docs/css/_helper.sass @@ -311,3 +311,6 @@ sub [ng\:cloak], [ng-cloak], .ng-cloak display: none !important + +.text-white + color: #FFFFFF diff --git a/docs/examples.haml b/docs/examples.haml new file mode 100644 index 0000000000..9491f738b1 --- /dev/null +++ b/docs/examples.haml @@ -0,0 +1,33 @@ +--- +layout: default +title: Examples +permalink: /examples/ +--- + +.hero + %h1.text-center Examples + +.spacer40 +.container + .row + .col-sm-8.col-sm-push-2 + %p.lead Instantsearch.js allows you to customize the appearance of your widgets very easily. + %p.lead Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quo blanditiis ad, quidem, illum praesentium quae, ipsa sint similique quas mollitia voluptatum cumque excepturi amet dolorem dicta minus voluptate vel impedit. + + .spacer40 + %h2.text-center Check out our examples! + .row.text-center + .col-sm-4 + %h3 Youtube + %img.m-b.img-responsive.img-thumbnail{src: "{{ "/examples/youtube/capture.png" | prepend: site.baseurl }}"} + %a.btn.btn-default.primary-btn{href: '{{ "/examples/youtube/" | prepend: site.baseurl }}', target: '_blank'} Live Preview + + .col-sm-4 + %h3 Amazon + %img.m-b.img-responsive.img-thumbnail{src:"http://placehold.it/600x400"} + %a.btn.btn-default.primary-btn{href: '{{ "/examples/amazon/" | prepend: site.baseurl }}', target: '_blank'} Live Preview + + .col-sm-4 + %h3 Airbnb + %img.m-b.img-responsive.img-thumbnail{src: "{{ "/examples/airbnb/capture.png" | prepend: site.baseurl }}"} + %a.btn.btn-default.primary-btn{href: '{{ "/examples/airbnb/" | prepend: site.baseurl }}', target: '_blank'} Live Preview diff --git a/docs/examples/airbnb/capture.png b/docs/examples/airbnb/capture.png new file mode 100644 index 0000000000..a4fe1764fe Binary files /dev/null and b/docs/examples/airbnb/capture.png differ diff --git a/docs/examples/airbnb/index.html b/docs/examples/airbnb/index.html new file mode 100644 index 0000000000..18aedb1c97 --- /dev/null +++ b/docs/examples/airbnb/index.html @@ -0,0 +1,62 @@ + + + + Airbnb-like search by Algolia + + + + + + + +
+ + + +
+
+
+ +
+
+ +
+
+
+
+ + + + diff --git a/docs/examples/airbnb/scss/_base.scss b/docs/examples/airbnb/scss/_base.scss new file mode 100644 index 0000000000..081df40730 --- /dev/null +++ b/docs/examples/airbnb/scss/_base.scss @@ -0,0 +1,31 @@ +@mixin component($component) { + .ais-#{$component} { + @content + } +} + +@mixin modifier($modifier) { + &--#{$modifier} { + @content + } +} + +@mixin element($element) { + &__#{$element} { + @content + } +} + +@mixin bem($component, $modifier, $element: "") { + @include component($component) { + @include modifier($modifier) { + @if $element != "" { + @include element($element) { + @content; + } + } @else { + @content; + } + } + } +} diff --git a/docs/examples/airbnb/scss/_default.scss b/docs/examples/airbnb/scss/_default.scss new file mode 100644 index 0000000000..f5c5d1a8ec --- /dev/null +++ b/docs/examples/airbnb/scss/_default.scss @@ -0,0 +1,12 @@ +@import "base"; +@import "search-box"; +@import "stats"; +@import "index-selector"; +@import "hits"; +@import "pagination"; +@import "refinement-list"; +@import "menu"; +@import "toggle"; +@import "hierarchical-menu"; +@import "range-slider"; +@import "price-ranges"; diff --git a/docs/examples/airbnb/scss/_hierarchical-menu.scss b/docs/examples/airbnb/scss/_hierarchical-menu.scss new file mode 100644 index 0000000000..4b742baa8e --- /dev/null +++ b/docs/examples/airbnb/scss/_hierarchical-menu.scss @@ -0,0 +1,19 @@ +@import "base"; +@import "variables"; + +@include component(hierarchical-menu) { + @include modifier(header); + @include modifier(body); + @include modifier(list) { + @include element(lvl0); + @include element(lvl1); + } + + @include modifier(item) { + @include element(active); + } + + @include modifier(link); + @include modifier(count); + @include modifier(footer); +} diff --git a/docs/examples/airbnb/scss/_hits.scss b/docs/examples/airbnb/scss/_hits.scss new file mode 100644 index 0000000000..64b276ca48 --- /dev/null +++ b/docs/examples/airbnb/scss/_hits.scss @@ -0,0 +1,7 @@ +@import "base"; +@import "variables"; + +@include component(hits) { + @include element(empty); + @include modifier(item); +} diff --git a/docs/examples/airbnb/scss/_index-selector.scss b/docs/examples/airbnb/scss/_index-selector.scss new file mode 100644 index 0000000000..de0f6dc993 --- /dev/null +++ b/docs/examples/airbnb/scss/_index-selector.scss @@ -0,0 +1,6 @@ +@import "base"; +@import "variables"; + +@include component(index-selector) { + @include modifier(item); +} diff --git a/docs/examples/airbnb/scss/_menu.scss b/docs/examples/airbnb/scss/_menu.scss new file mode 100644 index 0000000000..d38e3ac567 --- /dev/null +++ b/docs/examples/airbnb/scss/_menu.scss @@ -0,0 +1,14 @@ +@import "base"; +@import "variables"; + +@include component(menu) { + @include modifier(header); + @include modifier(body); + @include modifier(list); + @include modifier(item) { + @include element(active); + } + @include modifier(link); + @include modifier(count); + @include modifier(footer); +} diff --git a/docs/examples/airbnb/scss/_pagination.scss b/docs/examples/airbnb/scss/_pagination.scss new file mode 100644 index 0000000000..e4a7267530 --- /dev/null +++ b/docs/examples/airbnb/scss/_pagination.scss @@ -0,0 +1,17 @@ +@import "base"; +@import "variables"; + +@include component(pagination) { + @include modifier(item) { + @include element(disabled) { + visibility: hidden; + } + } + @include modifier(item-first); + @include modifier(item-previous); + @include modifier(item-page) { + @include element(active); + } + @include modifier(item-next); + @include modifier(item-last); +} diff --git a/docs/examples/airbnb/scss/_price-ranges.scss b/docs/examples/airbnb/scss/_price-ranges.scss new file mode 100644 index 0000000000..6b692db69d --- /dev/null +++ b/docs/examples/airbnb/scss/_price-ranges.scss @@ -0,0 +1,14 @@ +@import "base"; +@import "variables"; + +@include component(price-ranges) { + @include modifier(header); + @include modifier(body); + @include modifier(footer); + @include modifier(form); + @include modifier(range) { + @include element(active); + } + @include modifier(input-group); + @include modifier(button); +} diff --git a/docs/examples/airbnb/scss/_range-slider.scss b/docs/examples/airbnb/scss/_range-slider.scss new file mode 100644 index 0000000000..211759ba20 --- /dev/null +++ b/docs/examples/airbnb/scss/_range-slider.scss @@ -0,0 +1,101 @@ +@import "base"; +@import "variables"; + +@include component(range-slider) { + @include modifier(target) { + position: relative; + direction: ltr; + background: $gray-light; + height: 4px; + &, * { + box-sizing: border-box; + } + } + + @include modifier(base) { + width: 100%; + height: 100%; + position: relative; + z-index: 1; + } + + @include modifier(origin) { + position: absolute; + right: 0; + top: 0; + left: 0; + bottom: 0; + } + + @include modifier(state-tap) { + @include component(range-slider) { + @include modifier(origin) { + transition: left .3s, top .3s; + } + } + } + + @include modifier(state-drag) { + * { + cursor: inherit; + } + } + + // Painting and performance; + // Browsers can paint handles in their own layer. + // + @include modifier(base) { + transform: translate3d(0, 0, 0); + } + + @include modifier(connect) { + background: $blue-light; + transition: background 450ms; + } + + @include modifier(background) { + background: $gray-light; + } + + @include modifier(handle) { + border: 1px solid #ccc; + border-radius: 50%; + width: 20px; + height: 20px; + background: white; + position: relative; + z-index: 1; + cursor: pointer; + } + + @include modifier(handle-lower) { + bottom: 7px; + } + + @include modifier(handle-upper) { + bottom: 7px; + } + + @include modifier(tooltip) { + position: absolute; + top: -20px; + } + + @include modifier(active) { + @include component(range-slider) { + @include modifier(tooltip) { + background: $blue-light; + color: $white; + border-color: $blue-dark; + } + } + } + + @include modifier(handle-upper) { + @include component(range-slider) { + @include modifier(tooltip) { + right: 0; + } + } + } +} diff --git a/docs/examples/airbnb/scss/_refinement-list.scss b/docs/examples/airbnb/scss/_refinement-list.scss new file mode 100644 index 0000000000..03b894086e --- /dev/null +++ b/docs/examples/airbnb/scss/_refinement-list.scss @@ -0,0 +1,15 @@ +@import "base"; +@import "variables"; + +@include component(refinement-list) { + @include modifier(header); + @include modifier(body); + @include modifier(list); + @include modifier(item) { + @include element(active); + } + @include modifier(label); + @include modifier(checkbox); + @include modifier(count); + @include modifier(footer); +} diff --git a/docs/examples/airbnb/scss/_search-box.scss b/docs/examples/airbnb/scss/_search-box.scss new file mode 100644 index 0000000000..caad6518d7 --- /dev/null +++ b/docs/examples/airbnb/scss/_search-box.scss @@ -0,0 +1,26 @@ +@import "base"; +@import "variables"; + +@include component(search-box) { + @include modifier(powered-by) { + font-size: .8em; + text-align: right; + margin-top: 2px; + } + // + // Image replacement technique used: + // http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement/ + // + @include modifier(powered-by-link) { + display: inline-block; + width: 45px; + height: 16px; + text-indent: 101%; + overflow: hidden; + white-space: nowrap; + background-image: url("data:image/png;base64,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"); + background-repeat: no-repeat; + background-size: contain; + vertical-align: middle; + } +} diff --git a/docs/examples/airbnb/scss/_stats.scss b/docs/examples/airbnb/scss/_stats.scss new file mode 100644 index 0000000000..b23716d6ed --- /dev/null +++ b/docs/examples/airbnb/scss/_stats.scss @@ -0,0 +1,9 @@ +@import "base"; +@import "variables"; + +@include component(stats) { + @include modifier(header); + @include modifier(body); + @include modifier(time); + @include modifier(footer); +} diff --git a/docs/examples/airbnb/scss/_toggle.scss b/docs/examples/airbnb/scss/_toggle.scss new file mode 100644 index 0000000000..4b0015f895 --- /dev/null +++ b/docs/examples/airbnb/scss/_toggle.scss @@ -0,0 +1,15 @@ +@import "base"; +@import "variables"; + +@include component(toggle) { + @include modifier(header); + @include modifier(body); + @include modifier(list); + @include modifier(item) { + @include element(active); + } + @include modifier(label); + @include modifier(checkbox); + @include modifier(count); + @include modifier(footer); +} diff --git a/docs/examples/airbnb/scss/_variables.scss b/docs/examples/airbnb/scss/_variables.scss new file mode 100644 index 0000000000..1f075ccdfe --- /dev/null +++ b/docs/examples/airbnb/scss/_variables.scss @@ -0,0 +1,4 @@ +$white: #FFFFFF; +$gray-light: #F3F4F7; +$blue-dark: #CE1312; +$blue-light: #E91D00; diff --git a/docs/examples/airbnb/search.js b/docs/examples/airbnb/search.js new file mode 100644 index 0000000000..8d14f73978 --- /dev/null +++ b/docs/examples/airbnb/search.js @@ -0,0 +1,75 @@ +/* global instantsearch */ + +var search = instantsearch({ + appId: 'latency', + apiKey: '6be0576ff61c053d5f9a3225e2a90f76', + indexName: 'airbnb' +}); + +search.addWidget( + instantsearch.widgets.searchBox({ + container: '#q' + }) +); + +search.addWidget( + instantsearch.widgets.stats({ + container: '#stats' + }) +); + +var hitTemplate = + '
' + + '
' + + '
' + + '

{{{ _highlightResult.name.value }}}

' + + '

{{ room_type }} - {{{ _highlightResult.city.value }}}, {{{ _highlightResult.country.value }}}

' + + '
' + + '
'; + +var noResultsTemplate = + '
No results found matching {{ query }}.
'; + +search.addWidget( + instantsearch.widgets.hits({ + container: '#hits', + hitsPerPage: 10, + templates: { + empty: noResultsTemplate, + item: hitTemplate + } + }) +); + +search.addWidget( + instantsearch.widgets.pagination({ + container: '#pagination', + cssClasses: { + root: 'pagination', + active: 'active' + } + }) +); + +search.addWidget( + instantsearch.widgets.refinementList({ + container: '#room_types', + facetName: 'room_type', + operator: 'or', + limit: 10, + cssClasses: { + item: 'item', + count: 'hide', + active: 'active' + } + }) +); + +search.addWidget( + instantsearch.widgets.rangeSlider({ + container: '#price', + facetName: 'price' + }) +); + +search.start(); diff --git a/docs/examples/airbnb/style.scss b/docs/examples/airbnb/style.scss new file mode 100644 index 0000000000..d589cfb197 --- /dev/null +++ b/docs/examples/airbnb/style.scss @@ -0,0 +1,171 @@ +--- +# this ensures Jekyll reads the file to be transformed into CSS later +--- + +// the relative path is not working here, +// Jekyll will always look in the sass_dir +@import "../examples/airbnb/scss/default"; + +$white: #FFFFFF; +$airbnb-red: #FF585B; +$airbnb-gray-light: #DCE0E0; +$airbnb-gray-lighter: #EDEFED; +$airbnb-text-color: #565A5C; + +body { + color: $airbnb-text-color; + font-family: Roboto; + font-size: 16px; + color: $airbnb-text-color; +} + +header { + padding: 0; + border-bottom: 1px solid $airbnb-gray-light; + + .logo { + color: $airbnb-red; + font-size: 40px; + padding: 5px 20px; + border-right: 1px solid $airbnb-gray-light; + font-family: Courier; + } + + .fa-search { + position: absolute; + top: 13px; + left: 80px; + font-size: 30px; + color: $airbnb-gray-light; + } + + #q { + position: absolute; + top: 13px; + left: 110px; + width: 50%; + border: none; + box-shadow: none; + + &:focus { + box-shadow: none; + outline: none; + } + } + +} + +nav { + padding: 0 20px; + font-size: 0.8em; + font-weight: bold; + + .row { + border-bottom: 1px solid $airbnb-gray-light; + padding-top: 10px; + padding-bottom: 10px; + } + + .date { + border: 1px solid $airbnb-gray-light; + padding: 7px 10px; + margin-right: 20px; + } + + .guests { + border: 1px solid $airbnb-gray-light; + padding: 7px 10px; + select { + background: transparent; + border: none; + -webkit-appearance: none; + width: 100%; + &:focus { + outline: none; + } + } + &:before { + content: '\25bc'; + position: absolute; + pointer-events: none; + color: #82888a; + top: 0; + right: 20px; + padding-top: 0.7em; + line-height: 1; + width: 2em; + text-align: center; + } + } +} + +#stats { + font-size: 12px; + text-align: right; + padding: 5px 15px; +} + +#price { + padding-top: 30px; +} + +#room_types { + .item { + display: inline-block; + padding: 10px 20px 5px 15px; + background: $airbnb-gray-lighter; + margin-right: 10px; + cursor: pointer; + } + input { + position: relative; + float: right; + -webkit-appearance: none; + background: white; + height: 1.25em; + width: 1.25em; + vertical-align: top; + margin-left: 20px; + border: 1px solid $airbnb-gray-light; + &:focus { + outline: none; + } + } + + .active { + input:before { + content: "\2713"; + position: absolute; + font-size: 0.85em; + text-align: center; + width: 1.25em; + color: #ff5a5f; + } + } +} + +#hits { + .hit { + img { + max-width: 100%; + } + + em { + font-style: normal; + background: #ffaeae; + } + + .infos { + font-size: 0.8em; + padding: 10px 20px; + } + } +} + +#map { + position: fixed; + background: $airbnb-gray-lighter; + top: 58px; + bottom: 0; + right: 0; +} diff --git a/docs/examples/amazon/index.html b/docs/examples/amazon/index.html new file mode 100644 index 0000000000..b97cd9de7d --- /dev/null +++ b/docs/examples/amazon/index.html @@ -0,0 +1 @@ +FIXME: amazon diff --git a/docs/examples/youtube/capture.png b/docs/examples/youtube/capture.png new file mode 100644 index 0000000000..8c1602ca5d Binary files /dev/null and b/docs/examples/youtube/capture.png differ diff --git a/docs/examples/youtube/index.html b/docs/examples/youtube/index.html new file mode 100644 index 0000000000..672768d2ef --- /dev/null +++ b/docs/examples/youtube/index.html @@ -0,0 +1,48 @@ + + + + Youtube-like search by Algolia + + + + + + + +
+
+ +
+
+
+ + + + +
+
+
+
+ +
+
+
+
+ +
+
+ + + + diff --git a/docs/examples/youtube/scss/_base.scss b/docs/examples/youtube/scss/_base.scss new file mode 100644 index 0000000000..081df40730 --- /dev/null +++ b/docs/examples/youtube/scss/_base.scss @@ -0,0 +1,31 @@ +@mixin component($component) { + .ais-#{$component} { + @content + } +} + +@mixin modifier($modifier) { + &--#{$modifier} { + @content + } +} + +@mixin element($element) { + &__#{$element} { + @content + } +} + +@mixin bem($component, $modifier, $element: "") { + @include component($component) { + @include modifier($modifier) { + @if $element != "" { + @include element($element) { + @content; + } + } @else { + @content; + } + } + } +} diff --git a/docs/examples/youtube/scss/_default.scss b/docs/examples/youtube/scss/_default.scss new file mode 100644 index 0000000000..f5c5d1a8ec --- /dev/null +++ b/docs/examples/youtube/scss/_default.scss @@ -0,0 +1,12 @@ +@import "base"; +@import "search-box"; +@import "stats"; +@import "index-selector"; +@import "hits"; +@import "pagination"; +@import "refinement-list"; +@import "menu"; +@import "toggle"; +@import "hierarchical-menu"; +@import "range-slider"; +@import "price-ranges"; diff --git a/docs/examples/youtube/scss/_hierarchical-menu.scss b/docs/examples/youtube/scss/_hierarchical-menu.scss new file mode 100644 index 0000000000..4b742baa8e --- /dev/null +++ b/docs/examples/youtube/scss/_hierarchical-menu.scss @@ -0,0 +1,19 @@ +@import "base"; +@import "variables"; + +@include component(hierarchical-menu) { + @include modifier(header); + @include modifier(body); + @include modifier(list) { + @include element(lvl0); + @include element(lvl1); + } + + @include modifier(item) { + @include element(active); + } + + @include modifier(link); + @include modifier(count); + @include modifier(footer); +} diff --git a/docs/examples/youtube/scss/_hits.scss b/docs/examples/youtube/scss/_hits.scss new file mode 100644 index 0000000000..64b276ca48 --- /dev/null +++ b/docs/examples/youtube/scss/_hits.scss @@ -0,0 +1,7 @@ +@import "base"; +@import "variables"; + +@include component(hits) { + @include element(empty); + @include modifier(item); +} diff --git a/docs/examples/youtube/scss/_index-selector.scss b/docs/examples/youtube/scss/_index-selector.scss new file mode 100644 index 0000000000..de0f6dc993 --- /dev/null +++ b/docs/examples/youtube/scss/_index-selector.scss @@ -0,0 +1,6 @@ +@import "base"; +@import "variables"; + +@include component(index-selector) { + @include modifier(item); +} diff --git a/docs/examples/youtube/scss/_menu.scss b/docs/examples/youtube/scss/_menu.scss new file mode 100644 index 0000000000..d38e3ac567 --- /dev/null +++ b/docs/examples/youtube/scss/_menu.scss @@ -0,0 +1,14 @@ +@import "base"; +@import "variables"; + +@include component(menu) { + @include modifier(header); + @include modifier(body); + @include modifier(list); + @include modifier(item) { + @include element(active); + } + @include modifier(link); + @include modifier(count); + @include modifier(footer); +} diff --git a/docs/examples/youtube/scss/_pagination.scss b/docs/examples/youtube/scss/_pagination.scss new file mode 100644 index 0000000000..e4a7267530 --- /dev/null +++ b/docs/examples/youtube/scss/_pagination.scss @@ -0,0 +1,17 @@ +@import "base"; +@import "variables"; + +@include component(pagination) { + @include modifier(item) { + @include element(disabled) { + visibility: hidden; + } + } + @include modifier(item-first); + @include modifier(item-previous); + @include modifier(item-page) { + @include element(active); + } + @include modifier(item-next); + @include modifier(item-last); +} diff --git a/docs/examples/youtube/scss/_price-ranges.scss b/docs/examples/youtube/scss/_price-ranges.scss new file mode 100644 index 0000000000..6b692db69d --- /dev/null +++ b/docs/examples/youtube/scss/_price-ranges.scss @@ -0,0 +1,14 @@ +@import "base"; +@import "variables"; + +@include component(price-ranges) { + @include modifier(header); + @include modifier(body); + @include modifier(footer); + @include modifier(form); + @include modifier(range) { + @include element(active); + } + @include modifier(input-group); + @include modifier(button); +} diff --git a/docs/examples/youtube/scss/_range-slider.scss b/docs/examples/youtube/scss/_range-slider.scss new file mode 100644 index 0000000000..6ebf0e026b --- /dev/null +++ b/docs/examples/youtube/scss/_range-slider.scss @@ -0,0 +1,107 @@ +@import "base"; +@import "variables"; + +@include component(range-slider) { + @include modifier(target) { + position: relative; + direction: ltr; + background: $gray-light; + height: 4px; + &, * { + box-sizing: border-box; + } + } + + @include modifier(base) { + width: 100%; + height: 100%; + position: relative; + z-index: 1; + } + + @include modifier(origin) { + position: absolute; + right: 0; + top: 0; + left: 0; + bottom: 0; + } + + @include modifier(state-tap) { + @include component(range-slider) { + @include modifier(origin) { + transition: left .3s, top .3s; + } + } + } + + @include modifier(state-drag) { + * { + cursor: inherit; + } + } + + // Painting and performance; + // Browsers can paint handles in their own layer. + // + @include modifier(base) { + transform: translate3d(0, 0, 0); + } + + @include modifier(connect) { + background: $blue-light; + transition: background 450ms; + } + + @include modifier(background) { + background: $gray-light; + } + + @include modifier(handle) { + width: 1px; + height: 10px; + position: relative; + z-index: 1; + background: $blue-light; + cursor: pointer; + } + + @include modifier(handle-lower) { + bottom: 10px; + } + + @include modifier(active) { + background: $blue-dark; + } + + @include modifier(tooltip) { + position: absolute; + } + + @include modifier(active) { + @include component(range-slider) { + @include modifier(tooltip) { + background: $blue-light; + color: $white; + border-color: $blue-dark; + } + } + } + + @include modifier(handle-lower) { + @include component(range-slider) { + @include modifier(tooltip) { + top: -24px; + } + } + } + + @include modifier(handle-upper) { + @include component(range-slider) { + @include modifier(tooltip) { + bottom: -24px; + right: 0; + } + } + } +} diff --git a/docs/examples/youtube/scss/_refinement-list.scss b/docs/examples/youtube/scss/_refinement-list.scss new file mode 100644 index 0000000000..03b894086e --- /dev/null +++ b/docs/examples/youtube/scss/_refinement-list.scss @@ -0,0 +1,15 @@ +@import "base"; +@import "variables"; + +@include component(refinement-list) { + @include modifier(header); + @include modifier(body); + @include modifier(list); + @include modifier(item) { + @include element(active); + } + @include modifier(label); + @include modifier(checkbox); + @include modifier(count); + @include modifier(footer); +} diff --git a/docs/examples/youtube/scss/_search-box.scss b/docs/examples/youtube/scss/_search-box.scss new file mode 100644 index 0000000000..caad6518d7 --- /dev/null +++ b/docs/examples/youtube/scss/_search-box.scss @@ -0,0 +1,26 @@ +@import "base"; +@import "variables"; + +@include component(search-box) { + @include modifier(powered-by) { + font-size: .8em; + text-align: right; + margin-top: 2px; + } + // + // Image replacement technique used: + // http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement/ + // + @include modifier(powered-by-link) { + display: inline-block; + width: 45px; + height: 16px; + text-indent: 101%; + overflow: hidden; + white-space: nowrap; + background-image: url("data:image/png;base64,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"); + background-repeat: no-repeat; + background-size: contain; + vertical-align: middle; + } +} diff --git a/docs/examples/youtube/scss/_stats.scss b/docs/examples/youtube/scss/_stats.scss new file mode 100644 index 0000000000..b23716d6ed --- /dev/null +++ b/docs/examples/youtube/scss/_stats.scss @@ -0,0 +1,9 @@ +@import "base"; +@import "variables"; + +@include component(stats) { + @include modifier(header); + @include modifier(body); + @include modifier(time); + @include modifier(footer); +} diff --git a/docs/examples/youtube/scss/_toggle.scss b/docs/examples/youtube/scss/_toggle.scss new file mode 100644 index 0000000000..4b0015f895 --- /dev/null +++ b/docs/examples/youtube/scss/_toggle.scss @@ -0,0 +1,15 @@ +@import "base"; +@import "variables"; + +@include component(toggle) { + @include modifier(header); + @include modifier(body); + @include modifier(list); + @include modifier(item) { + @include element(active); + } + @include modifier(label); + @include modifier(checkbox); + @include modifier(count); + @include modifier(footer); +} diff --git a/docs/examples/youtube/scss/_variables.scss b/docs/examples/youtube/scss/_variables.scss new file mode 100644 index 0000000000..1f075ccdfe --- /dev/null +++ b/docs/examples/youtube/scss/_variables.scss @@ -0,0 +1,4 @@ +$white: #FFFFFF; +$gray-light: #F3F4F7; +$blue-dark: #CE1312; +$blue-light: #E91D00; diff --git a/docs/examples/youtube/search.js b/docs/examples/youtube/search.js new file mode 100644 index 0000000000..8975a63399 --- /dev/null +++ b/docs/examples/youtube/search.js @@ -0,0 +1,77 @@ +/* global instantsearch */ + +var search = instantsearch({ + appId: 'latency', + apiKey: '6be0576ff61c053d5f9a3225e2a90f76', + indexName: 'movies' +}); + +search.addWidget( + instantsearch.widgets.searchBox({ + container: '#q' + }) +); + +search.addWidget( + instantsearch.widgets.stats({ + container: '#stats' + }) +); + +var hitTemplate = + '
' + + '
' + + '
' + + '
' + + '
' + + '

{{{ _highlightResult.title.value }}}

' + + '

{{ year }} - {{ genre }}

' + + '
' + + '
'; + +var noResultsTemplate = + '
No results found matching {{ query }}.
'; + +search.addWidget( + instantsearch.widgets.hits({ + container: '#hits', + hitsPerPage: 10, + templates: { + empty: noResultsTemplate, + item: hitTemplate + } + }) +); + +search.addWidget( + instantsearch.widgets.pagination({ + container: '#pagination', + cssClasses: { + root: 'pagination', + active: 'active' + } + }) +); + +search.addWidget( + instantsearch.widgets.refinementList({ + container: '#genres', + facetName: 'genre', + operator: 'and', + limit: 10, + cssClasses: { + list: 'nav nav-list', + count: 'badge pull-right', + active: 'active' + } + }) +); + +search.addWidget( + instantsearch.widgets.rangeSlider({ + container: '#ratings', + facetName: 'rating' + }) +); + +search.start(); diff --git a/docs/examples/youtube/style.scss b/docs/examples/youtube/style.scss new file mode 100644 index 0000000000..f8862b2867 --- /dev/null +++ b/docs/examples/youtube/style.scss @@ -0,0 +1,207 @@ +--- +# this ensures Jekyll reads the file to be transformed into CSS later +--- + +// the relative path is not working here, +// Jekyll will always look in the sass_dir +@import "../examples/youtube/scss/default"; + +$white: #FFFFFF; +$youtube-red: #E91D00; +$youtube-red-dark: #CE1312; +$youtube-gray: #E8E8E8; +$youtube-gray-light: #F8F8F8; +$youtube-bg: #F1F1F1; +$youtube-text-color: #333333; +$youtube-blue: #167AC6; +$header-height: 56px; +$highlight-color: #FFFFE4; +$shadow-color: rgba(0, 0, 0, .1); + +body { + min-height: 100%; + font-family: Roboto; +} + +a { + color: $youtube-text-color; +} + +hr { + margin-top: 10px; + margin-bottom: 10px; +} + +.logo { + margin-left: 15px; + font-size: 30px; + font-weight: bold; + line-height: 20px; + i { + margin-left: 5px; + color: $youtube-red; + } +} + +header { + background: $white; + padding: 10px; + border-bottom: 1px solid $youtube-gray; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 2; + + .input-group { + margin-top: 5px; + + .form-control { + height: 28px; + &:focus { + outline: none; + box-shadow: none; + } + } + + .input-group-btn button { + padding-left: 30px; + padding-right: 30px; + background: $youtube-gray-light; + } + } +} + +section { + background: $youtube-bg; + min-height: 100%; + z-index: 1; + + aside { + position: fixed; + top: $header-height; + left: 0; + bottom: 0; + width: 230px; + background: $white; + border-right: 1px solid $youtube-gray; + + .nav { + margin: 10px 20px; + li { + a { + display: block; + padding: 2px 10px; + margin: 10px 0; + &:hover { + color: $white; + background: $youtube-text-color; + } + } + + &.separator { + height: 1px; + background: $youtube-gray; + } + } + } + + h5 { + color: $youtube-red-dark; + margin-left: 30px; + text-transform: uppercase; + font-size: 10px; + margin-top: 20px; + } + + #genres { + label { + display: block; + cursor: pointer; + padding: 2px 10px; + font-weight: normal; + font-size: .9em; + &:hover { + color: $white; + background: $youtube-text-color; + } + input { + display: none; + } + } + .active label { + border: 1px solid $youtube-red-dark; + } + .badge { + font-size: 8px; + } + } + + #ratings { + margin: 40px 30px; + } + + } + + article { + margin-top: $header-height + 10px; + margin-bottom: 50px; + margin-left: 400px; + padding: 10px 0; + width: 700px; + background: $white; + box-shadow: 0 1px 2px $shadow-color; + + #stats { + padding-right: 10px; + font-size: .8em; + } + + #hits { + padding: 0 15px; + } + + #pagination { + .pagination a { + background: $youtube-gray-light; + padding: 3px 8px; + color: $youtube-text-color; + margin-right: 4px; + &.active { + border-color: darken($youtube-gray, 20%); + background: $youtube-gray; + } + &:hover { + border-color: darken($youtube-gray, 10%); + background: darken($youtube-gray-light, 5%); + } + } + } + + .hit { + margin-bottom: 10px; + + em { + font-style: normal; + background: $highlight-color; + } + + .media-object { + height: 130px; + width: 210px; + overflow: hidden; + + img { + margin-top: -30px; + width: 100%; + } + } + + .media-heading { + color: $youtube-blue; + font-weight: bold; + font-size: 14px; + } + } + } +} diff --git a/scripts/dev.sh b/scripts/dev.sh index 98f149f69c..9a8795dedf 100755 --- a/scripts/dev.sh +++ b/scripts/dev.sh @@ -3,6 +3,7 @@ set -ev # exit when error npm install +node-sass -o ./dist/themes/ ./themes node-sass -o ./dist/themes/ --watch ./themes & -webpack-dev-server --config webpack.example.config.js --hot --inline --no-info & +webpack-dev-server --config webpack.dev.config.js --hot --inline --no-info & wait diff --git a/webpack.example.config.js b/webpack.dev.config.js similarity index 79% rename from webpack.example.config.js rename to webpack.dev.config.js index 86e4c79bab..2ff40f419e 100644 --- a/webpack.example.config.js +++ b/webpack.dev.config.js @@ -1,8 +1,8 @@ module.exports = { - entry: './example/app.js', + entry: './dev/app.js', devtool: 'source-map', output: { - path: './example/', + path: './dev/', filename: 'bundle.js' }, module: { @@ -13,7 +13,7 @@ module.exports = { }] }, devServer: { - contentBase: 'example/', + contentBase: 'dev/', host: '0.0.0.0', compress: true }