From de3f34f8d5eed3d08b2d3009dfb29e2318ace8b9 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Tue, 22 Nov 2016 14:27:11 -0800 Subject: [PATCH 1/5] Migrate UI Framework source into Kibana. - Add dependencies to package.json. - Add task for building UI Framework docs and serving locally. - Import UI Framework scss from autoload/styles.js instead of importing the CSS in base.less. --- .gitignore | 1 + package.json | 23 ++- src/optimize/base_optimizer.js | 4 + src/ui/public/autoload/styles.js | 4 + src/ui/public/styles/base.less | 3 - src/ui_framework/README.md | 57 +++++++ src/ui_framework/public/index.html | 13 ++ .../components/local_nav/_index.scss | 48 ++++++ .../local_nav/_local_breadcrumbs.scss | 58 ++++++++ .../components/local_nav/_local_dropdown.scss | 140 ++++++++++++++++++ .../components/local_nav/_local_menu.scss | 51 +++++++ .../components/local_nav/_local_nav.scss | 34 +++++ .../components/local_nav/_local_search.scss | 53 +++++++ .../components/local_nav/_local_tabs.scss | 49 ++++++ .../components/local_nav/_local_title.scss | 8 + src/ui_framework/src/framework/framework.scss | 27 ++++ .../src/guide/actions/action_types.js | 13 ++ .../code_viewer/code_viewer_actions.js | 30 ++++ src/ui_framework/src/guide/actions/index.js | 4 + .../guide_code_viewer/_guide_code_viewer.scss | 114 ++++++++++++++ .../guide_code_viewer/guide_code_viewer.jsx | 76 ++++++++++ .../guide_example/_guide_example.scss | 3 + .../guide_example/guide_example.jsx | 77 ++++++++++ .../components/guide_nav/_guide_nav.scss | 67 +++++++++ .../guide/components/guide_nav/guide_nav.jsx | 65 ++++++++ .../components/guide_page/_guide_page.scss | 15 ++ .../components/guide_page/guide_page.jsx | 72 +++++++++ .../_guide_page_section.scss | 56 +++++++ .../guide_page_section/guide_page_section.jsx | 123 +++++++++++++++ .../_guide_page_side_nav.scss | 46 ++++++ .../guide_page_side_nav.jsx | 32 ++++ .../guide_page_side_nav_item.jsx | 38 +++++ .../src/guide/components/index.js | 21 +++ src/ui_framework/src/guide/index.js | 80 ++++++++++ src/ui_framework/src/guide/main.scss | 28 ++++ .../guide/services/example/createExample.js | 16 ++ src/ui_framework/src/guide/services/index.js | 12 ++ .../guide/services/js_injector/js_injector.js | 21 +++ .../src/guide/services/routes/Routes.js | 19 +++ .../src/guide/services/string/slugify.js | 27 ++++ .../src/guide/store/configure_store.js | 35 +++++ .../store/reducers/code_viewer_reducer.js | 69 +++++++++ src/ui_framework/src/guide/variables.scss | 39 +++++ src/ui_framework/src/guide/views/_app.scss | 22 +++ .../src/guide/views/app_container.js | 30 ++++ src/ui_framework/src/guide/views/app_view.jsx | 113 ++++++++++++++ .../src/guide/views/home/_home_view.scss | 28 ++++ .../src/guide/views/home/home_view.jsx | 28 ++++ .../local_nav_breadcrumbs.html | 41 +++++ .../local_nav_dropdown.html | 122 +++++++++++++++ .../local_nav_dropdown_panels.html | 81 ++++++++++ .../views/local_nav/local_nav_example.jsx | 56 +++++++ .../local_nav_menu_item_states.html | 55 +++++++ .../local_nav_search/local_nav_search.html | 55 +++++++ .../local_nav_search_error.html | 55 +++++++ .../local_nav_simple/local_nav_simple.html | 31 ++++ .../local_nav_tabs/local_nav_tabs.html | 57 +++++++ .../guide/views/not_found/not_found_view.jsx | 20 +++ src/ui_framework/webpack.config.js | 39 +++++ 59 files changed, 2599 insertions(+), 5 deletions(-) create mode 100644 src/ui_framework/README.md create mode 100644 src/ui_framework/public/index.html create mode 100644 src/ui_framework/src/framework/components/local_nav/_index.scss create mode 100644 src/ui_framework/src/framework/components/local_nav/_local_breadcrumbs.scss create mode 100644 src/ui_framework/src/framework/components/local_nav/_local_dropdown.scss create mode 100644 src/ui_framework/src/framework/components/local_nav/_local_menu.scss create mode 100644 src/ui_framework/src/framework/components/local_nav/_local_nav.scss create mode 100644 src/ui_framework/src/framework/components/local_nav/_local_search.scss create mode 100644 src/ui_framework/src/framework/components/local_nav/_local_tabs.scss create mode 100644 src/ui_framework/src/framework/components/local_nav/_local_title.scss create mode 100644 src/ui_framework/src/framework/framework.scss create mode 100644 src/ui_framework/src/guide/actions/action_types.js create mode 100644 src/ui_framework/src/guide/actions/code_viewer/code_viewer_actions.js create mode 100644 src/ui_framework/src/guide/actions/index.js create mode 100644 src/ui_framework/src/guide/components/guide_code_viewer/_guide_code_viewer.scss create mode 100644 src/ui_framework/src/guide/components/guide_code_viewer/guide_code_viewer.jsx create mode 100644 src/ui_framework/src/guide/components/guide_example/_guide_example.scss create mode 100644 src/ui_framework/src/guide/components/guide_example/guide_example.jsx create mode 100644 src/ui_framework/src/guide/components/guide_nav/_guide_nav.scss create mode 100644 src/ui_framework/src/guide/components/guide_nav/guide_nav.jsx create mode 100644 src/ui_framework/src/guide/components/guide_page/_guide_page.scss create mode 100644 src/ui_framework/src/guide/components/guide_page/guide_page.jsx create mode 100644 src/ui_framework/src/guide/components/guide_page_section/_guide_page_section.scss create mode 100644 src/ui_framework/src/guide/components/guide_page_section/guide_page_section.jsx create mode 100644 src/ui_framework/src/guide/components/guide_page_side_nav/_guide_page_side_nav.scss create mode 100644 src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav.jsx create mode 100644 src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav_item.jsx create mode 100644 src/ui_framework/src/guide/components/index.js create mode 100644 src/ui_framework/src/guide/index.js create mode 100644 src/ui_framework/src/guide/main.scss create mode 100644 src/ui_framework/src/guide/services/example/createExample.js create mode 100644 src/ui_framework/src/guide/services/index.js create mode 100644 src/ui_framework/src/guide/services/js_injector/js_injector.js create mode 100644 src/ui_framework/src/guide/services/routes/Routes.js create mode 100644 src/ui_framework/src/guide/services/string/slugify.js create mode 100644 src/ui_framework/src/guide/store/configure_store.js create mode 100644 src/ui_framework/src/guide/store/reducers/code_viewer_reducer.js create mode 100644 src/ui_framework/src/guide/variables.scss create mode 100644 src/ui_framework/src/guide/views/_app.scss create mode 100644 src/ui_framework/src/guide/views/app_container.js create mode 100644 src/ui_framework/src/guide/views/app_view.jsx create mode 100644 src/ui_framework/src/guide/views/home/_home_view.scss create mode 100644 src/ui_framework/src/guide/views/home/home_view.jsx create mode 100644 src/ui_framework/src/guide/views/local_nav/local_nav_breadcrumbs/local_nav_breadcrumbs.html create mode 100644 src/ui_framework/src/guide/views/local_nav/local_nav_dropdown/local_nav_dropdown.html create mode 100644 src/ui_framework/src/guide/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html create mode 100644 src/ui_framework/src/guide/views/local_nav/local_nav_example.jsx create mode 100644 src/ui_framework/src/guide/views/local_nav/local_nav_menu_item_states/local_nav_menu_item_states.html create mode 100644 src/ui_framework/src/guide/views/local_nav/local_nav_search/local_nav_search.html create mode 100644 src/ui_framework/src/guide/views/local_nav/local_nav_search_error/local_nav_search_error.html create mode 100644 src/ui_framework/src/guide/views/local_nav/local_nav_simple/local_nav_simple.html create mode 100644 src/ui_framework/src/guide/views/local_nav/local_nav_tabs/local_nav_tabs.html create mode 100644 src/ui_framework/src/guide/views/not_found/not_found_view.jsx create mode 100644 src/ui_framework/webpack.config.js diff --git a/.gitignore b/.gitignore index bb293595e316e..26c3f0d95c384 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ selenium *.swp *.swo *.out +src/ui_framework/public/*.js* diff --git a/package.json b/package.json index 1380678cc5d74..72fde84d5e0cf 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,8 @@ "makelogs": "makelogs", "mocha": "mocha", "mocha:debug": "mocha --debug-brk", - "sterilize": "grunt sterilize" + "sterilize": "grunt sterilize", + "uiFramework:start": "./node_modules/.bin/webpack-dev-server --config src/ui_framework/webpack.config.js --hot --inline --content-base src/ui_framework/public/" }, "repository": { "type": "git", @@ -171,6 +172,8 @@ "cheerio": "0.22.0", "chokidar": "1.6.0", "chromedriver": "2.24.1", + "classnames": "2.2.5", + "del": "1.2.1", "elasticdump": "2.1.1", "eslint": "1.10.3", "eslint-plugin-mocha": "1.1.0", @@ -190,6 +193,9 @@ "gruntify-eslint": "1.0.1", "gulp-sourcemaps": "1.7.3", "handlebars": "4.0.5", + "highlight.js": "9.0.0", + "history": "2.1.1", + "html-loader": "0.4.3", "husky": "0.8.1", "image-diff": "1.6.0", "intern": "3.2.3", @@ -201,6 +207,7 @@ "karma-ie-launcher": "0.2.0", "karma-mocha": "0.2.0", "karma-safari-launcher": "0.1.1", + "keymirror": "0.1.1", "license-checker": "5.1.2", "load-grunt-config": "0.19.2", "makelogs": "3.0.2", @@ -209,15 +216,27 @@ "murmurhash3js": "3.0.1", "ncp": "2.0.0", "nock": "8.0.0", + "node-sass": "3.8.0", "npm": "3.10.8", + "numeral": "1.5.3", "portscanner": "1.0.0", "proxyquire": "1.7.10", + "react": "15.2.0", + "react-addons-test-utils": "15.2.0", + "react-dom": "15.2.0", + "react-redux": "4.4.5", + "react-router": "2.0.0", + "react-router-redux": "4.0.4", + "redux": "3.0.0", + "redux-thunk": "0.1.0", + "sass-loader": "4.0.0", "simple-git": "1.37.0", "sinon": "1.17.2", "source-map": "0.5.6", "source-map-support": "0.2.10", "supertest": "1.2.0", - "supertest-as-promised": "2.0.2" + "supertest-as-promised": "2.0.2", + "webpack-dev-server": "1.14.1" }, "engines": { "node": "6.9.0", diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js index 5e0e79d3d72a2..c63c2cf836a8d 100644 --- a/src/optimize/base_optimizer.js +++ b/src/optimize/base_optimizer.js @@ -108,6 +108,10 @@ class BaseOptimizer { `css${mapQ}!autoprefixer${mapQPre}{ "browsers": ["last 2 versions","> 5%"] }!less${mapQPre}dumpLineNumbers=comments` ) }, + { + test: /\.scss$/, + loaders: ['style', 'css', 'sass'], + }, { test: /\.css$/, loader: ExtractTextPlugin.extract('style', `css${mapQ}`) }, { test: /\.jade$/, loader: 'jade' }, { test: /\.json$/, loader: 'json' }, diff --git a/src/ui/public/autoload/styles.js b/src/ui/public/autoload/styles.js index 040094a9ce921..a74b7333066c7 100644 --- a/src/ui/public/autoload/styles.js +++ b/src/ui/public/autoload/styles.js @@ -1,2 +1,6 @@ +// Kibana UI Framework +require('../../../ui_framework/src/framework/framework.scss'); + +// All Kibana styles inside of the /styles dir const context = require.context('../styles', false, /[\/\\](?!mixins|variables|_|\.)[^\/\\]+\.less/); context.keys().forEach(key => context(key)); diff --git a/src/ui/public/styles/base.less b/src/ui/public/styles/base.less index 9c3ac595de46b..9a78036496a19 100644 --- a/src/ui/public/styles/base.less +++ b/src/ui/public/styles/base.less @@ -3,9 +3,6 @@ @import (reference) "./variables"; @import (reference) "~ui/styles/bootstrap/bootstrap"; -// Kibana UI Framework -@import (less) "~@elastic/kibana-ui-framework/dist/framework.css"; - html, body { .flex-parent(); diff --git a/src/ui_framework/README.md b/src/ui_framework/README.md new file mode 100644 index 0000000000000..bbfd577dc138f --- /dev/null +++ b/src/ui_framework/README.md @@ -0,0 +1,57 @@ +# Kibana UI Framework + +## Development + +* Start development server `npm run uiFramework:start`. +* View docs on `http://localhost:8080/`. + +## What is this? + +The UI Framework provides you with UI components you can quickly use to build UIs, as well as interactive examples which document how they're supposed to be used. These UI components are currently only implemented in CSS and markup, but eventually they'll grow to involve JS as well. + +When you build a UI using this framework (e.g. a plugin's UI), you can rest assured it will fit into the overall Kibana UI. + +## Benefits + +### Dynamic, interactive documentation + +By having a "living style guide", we relieve our designers of the burden of creating and maintaining static style guides. This also makes it easier for our engineers to translate mockups, prototypes, and wireframes into products. + +### Copy-pasteable UI + +Engineers can copy and paste sample code into their projects to quickly get reliable, consistent results. + +### Remove CSS from the day-to-day + +The CSS portion of this framework means engineers don't need to spend mental cycles. These cycles can be spent on the things critical to the identity of the specific project they're working on, like architecture and business logic. + +Once this framework also provides JS components, engineers won't even need to _see_ CSS -- it will be encapsulated behind the JS components' interfaces. + +### More UI tests === fewer UI bugs + +By covering our UI components with great unit tests and having those tests live within the framework itself, we can rest assured that our UI layer is tested and remove some of that burden from out integration/end-to-end tests. + +## Why not just use Bootstrap? + +In short: we've outgrown it! Third-party CSS frameworks like Bootstrap and Foundation are designed +for a general audience, so they offer things we don't need and _don't_ offer things we _do_ need. +As a result, we've forced to override their styles until the original framework is no longer +recognizable. When the CSS reaches that point, it's time to take ownership over it and build +your own framework. + +We also gain the ability to fix some of the common issues with third-party CSS frameworks: + +* They have non-semantic markup. +* They deeply nest their selectors. + +For a more in-depth analysis of the problems with Bootstrap (and similar frameworks), check out this article and the links it has at the bottom: ["Bootstrap Bankruptcy"](http://www.matthewcopeland.me/blog/2013/11/04/bootstrap-bankruptcy/). + +## Examples of other in-house UI frameworks + +* [Ubiquiti CSS Framework](http://ubnt-css.herokuapp.com/#/app/popover) +* [Smaato React UI Framework](http://smaato.github.io/ui-framework/#/modal) +* [Lonely Planet Style Guide](http://rizzo.lonelyplanet.com/styleguide/design-elements/colours) +* [MailChimp Patterns Library](http://ux.mailchimp.com/patterns) +* [Salesforce Lightning Design System](https://www.lightningdesignsystem.com/) +* [Refills](http://refills.bourbon.io/) +* [Formstone](https://formstone.it/) \ No newline at end of file diff --git a/src/ui_framework/public/index.html b/src/ui_framework/public/index.html new file mode 100644 index 0000000000000..8bf6acd476348 --- /dev/null +++ b/src/ui_framework/public/index.html @@ -0,0 +1,13 @@ + + + + + + + + + +
+ + + diff --git a/src/ui_framework/src/framework/components/local_nav/_index.scss b/src/ui_framework/src/framework/components/local_nav/_index.scss new file mode 100644 index 0000000000000..b04b1b3cb9b4e --- /dev/null +++ b/src/ui_framework/src/framework/components/local_nav/_index.scss @@ -0,0 +1,48 @@ +// Normal colors +$localNavTextColor: $textColor; +$localNavBackgroundColor: #e4e4e4; +$localNavButtonTextColor: #5a5a5a; +$localNavButtonTextColor-isHover: #000000; +$localNavButtonBackgroundColor: transparent; +$localNavButtonBackgroundColor-isHover: rgba(#000000, 0.1); +$localNavButtonBackgroundColor-isSelected: #f6f6f6; +$localNavBreadcrumbDelimiterColor: #5a5a5a; +$localSearchBackgroundColor: #ffffff; +$localSearchBorderColor-isInvalid: #e74C3c; +$localDropdownBackgroundColor: $localNavButtonBackgroundColor-isSelected; +$localDropdownFormNoteTextColor: #737373; +$localTabTextColor: $localNavButtonTextColor; +$localTabTextColor-isHover: $localNavButtonTextColor-isHover; +$localTabTextColor-isSelected: $localNavButtonTextColor-isHover; + +// Dark theme colors +$localNavTextColor--darkTheme: $textColor--darkTheme; +$localNavBackgroundColor--darkTheme: #333333; +$localNavButtonTextColor--darkTheme: #dedede; +$localNavButtonTextColor-isHover--darkTheme: #ffffff; +$localNavButtonBackgroundColor-isHover--darkTheme: #000000; +$localNavButtonBackgroundColor-isSelected--darkTheme: #525252; +$localNavBreadcrumbDelimiterColor--darkTheme: #a5a5a5; +$localSearchBackgroundColor--darkTheme: #4e4e4e; +$localSearchBorderColor-isInvalid--darkTheme: #ff6758; +$localDropdownBackgroundColor--darkTheme: $localNavButtonBackgroundColor-isSelected--darkTheme; +$localDropdownFormNoteTextColor--darkTheme: #a2a2a2; +$localDropdownWarningTextColor--darkTheme: $textColor--darkTheme; +$localDropdownWarningBackgroundColor--darkTheme: #636363; +$localTabTextColor--darkTheme: $localNavButtonTextColor--darkTheme; +$localTabTextColor-isHover--darkTheme: $localNavButtonTextColor-isHover--darkTheme; +$localTabTextColor-isSelected--darkTheme: $localNavButtonTextColor-isHover--darkTheme; + +// Spacing +$localNavSideSpacing: 10px; + +// Font size +$localNavFontSizeNormal: 14px; + +@import "local_breadcrumbs"; +@import "local_dropdown"; +@import "local_menu"; +@import "local_nav"; +@import "local_search"; +@import "local_tabs"; +@import "local_title"; diff --git a/src/ui_framework/src/framework/components/local_nav/_local_breadcrumbs.scss b/src/ui_framework/src/framework/components/local_nav/_local_breadcrumbs.scss new file mode 100644 index 0000000000000..2708ba26648b0 --- /dev/null +++ b/src/ui_framework/src/framework/components/local_nav/_local_breadcrumbs.scss @@ -0,0 +1,58 @@ + +/** + * 1. Breadcrumbs are placed in the top-left corner and need to be bumped over + * a bit. + */ +.localBreadcrumbs { + display: flex; + align-items: center; + height: 100%; + padding-left: $localNavSideSpacing; /* 1 */ +} + + .localBreadcrumb { + & + & { + margin-left: 6px; + + &:before { + content: '/'; + user-select: none; + margin-right: 4px; + color: $localNavBreadcrumbDelimiterColor; + + @include darkTheme { + color: $localNavBreadcrumbDelimiterColor--darkTheme; + } + } + } + + &:last-child { + .localBreadcrumb__link { + pointer-events: none; + color: $localNavTextColor; + + @include darkTheme { + color: $localNavTextColor--darkTheme; + } + } + } + + } + + .localBreadcrumb__link { + font-size: $localNavFontSizeNormal; + color: #5a5a5a; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + @include darkTheme { + color: $localNavButtonTextColor--darkTheme; + } + } + + .localBreadcrumb__emphasis { + font-weight: 700; + } diff --git a/src/ui_framework/src/framework/components/local_nav/_local_dropdown.scss b/src/ui_framework/src/framework/components/local_nav/_local_dropdown.scss new file mode 100644 index 0000000000000..40f3ec635345b --- /dev/null +++ b/src/ui_framework/src/framework/components/local_nav/_local_dropdown.scss @@ -0,0 +1,140 @@ + +.localDropdown { + padding: 10px $localNavSideSpacing 14px; + background-color: $localDropdownBackgroundColor; + line-height: 20px; + + @include darkTheme { + background-color: $localDropdownBackgroundColor--darkTheme; + } +} + +.localDropdownPanels { + display: flex; +} + +.localDropdownPanel { + flex: 1 1 0%; +} + +.localDropdownPanel--left { + margin-right: 30px; +} + +.localDropdownPanel--right { + margin-left: 30px; +} + +.localDropdownTitle { + margin-bottom: 12px; + font-size: 18px; + color: $localNavTextColor; + + @include darkTheme { + color: $localNavTextColor--darkTheme; + } +} + +.localDropdownSection { + margin-bottom: 16px; + + &:last-child { + margin-bottom: 0; + } +} + +.localDropdownHeader { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 6px; +} + + .localDropdownHeader__label { + font-size: 14px; + font-weight: 700; + color: $localNavTextColor; + + @include darkTheme { + color: $localNavTextColor--darkTheme; + } + } + + .localDropdownHeader__actions { + display: flex; + } + + .localDropdownHeader__action { + color: $linkColor; + font-size: 12px; + text-decoration: none; + cursor: pointer; + + & + & { + margin-left: 10px; + } + + &:hover, + &:active { + color: $linkColor-isHover; + } + + @include darkTheme { + color: $linkColor--darkTheme; + + &:hover, + &:active { + color: $linkColor-isHover--darkTheme; + } + } + } + +.localDropdownInput { + display: block; + width: 100%; + margin-bottom: 12px; + padding: 5px 15px; + font-size: 14px; + color: $inputTextColor; + background-color: $inputBackgroundColor; + border: 2px solid $inputBorderColor; + border-radius: 4px; + + @include darkTheme { + color: $inputTextColor--darkTheme; + background-color: $inputBackgroundColor--darkTheme; + border-color: $inputBorderColor--darkTheme; + } +} + +.localDropdownFormNote { + font-size: 14px; + color: $localDropdownFormNoteTextColor; + + @include darkTheme { + color: $localDropdownFormNoteTextColor--darkTheme; + } +} + +.localDropdownWarning { + margin-bottom: 16px; + padding: 6px 10px; + font-size: 14px; + color: $textColor; + background-color: $localNavBackgroundColor; + + @include darkTheme { + color: $localDropdownWarningTextColor--darkTheme; + background-color: $localDropdownWarningBackgroundColor--darkTheme; + } +} + +.localDropdownHelpText { + margin-bottom: 16px; + font-size: 14px; + color: #2D2D2D; + + @include darkTheme { + color: #9e9e9e; + } +} diff --git a/src/ui_framework/src/framework/components/local_nav/_local_menu.scss b/src/ui_framework/src/framework/components/local_nav/_local_menu.scss new file mode 100644 index 0000000000000..da1803374f0a1 --- /dev/null +++ b/src/ui_framework/src/framework/components/local_nav/_local_menu.scss @@ -0,0 +1,51 @@ + +.localMenu { + display: flex; + align-items: center; + height: 100%; +} + + .localMenuItem { + display: flex; + align-items: center; + height: 100%; + padding: 0 $localNavSideSpacing; + font-size: $localNavFontSizeNormal; + background-color: $localNavButtonBackgroundColor; + color: $localNavButtonTextColor; + border: 0; + cursor: pointer; + + &:hover { + background-color: $localNavButtonBackgroundColor-isHover; + color: $localNavButtonTextColor-isHover; + } + + &.localMenuItem-isSelected { + background-color: $localNavButtonBackgroundColor-isSelected; + } + + &.localMenuItem-isDisabled { + opacity: 0.5; + cursor: default; + pointer-events: none; + } + + @include darkTheme { + color: $localNavButtonTextColor--darkTheme; + + &:hover { + background-color: $localNavButtonBackgroundColor-isHover--darkTheme; + color: $localNavButtonTextColor-isHover--darkTheme; + } + + &.localMenuItem-isSelected { + background-color: $localNavButtonBackgroundColor-isSelected--darkTheme; + } + } + } + + .localMenuItem__icon { + margin-right: 5px; + margin-bottom: -1px; + } diff --git a/src/ui_framework/src/framework/components/local_nav/_local_nav.scss b/src/ui_framework/src/framework/components/local_nav/_local_nav.scss new file mode 100644 index 0000000000000..2e5b6f48a876d --- /dev/null +++ b/src/ui_framework/src/framework/components/local_nav/_local_nav.scss @@ -0,0 +1,34 @@ + +/** + * 1. Match height of logo in side bar, but allow it to expand to accommodate + * dropdown. + */ +.localNav { + display: flex; + flex-direction: column; + justify-content: space-between; + min-height: 70px; /* 1 */ + color: $localNavTextColor; + background-color: $localNavBackgroundColor; + + @include darkTheme { + color: $localNavTextColor--darkTheme; + background-color: $localNavBackgroundColor--darkTheme; + } +} + +.localNavRow { + display: flex; + align-items: center; + justify-content: space-between; + height: 32px; +} + + .localNavRow__section { + height: 100%; + } + +.localNavRow--secondary { + height: 38px; + padding: 0 $localNavSideSpacing; +} diff --git a/src/ui_framework/src/framework/components/local_nav/_local_search.scss b/src/ui_framework/src/framework/components/local_nav/_local_search.scss new file mode 100644 index 0000000000000..103e2c889aacf --- /dev/null +++ b/src/ui_framework/src/framework/components/local_nav/_local_search.scss @@ -0,0 +1,53 @@ + +$localSearchHeight: 30px; + +.localSearch { + display: flex; + width: 100%; + height: $localSearchHeight; +} + +.localSearchInput { + flex: 1 1 100%; + padding: 5px 15px; + font-size: $localNavFontSizeNormal; + color: $localNavTextColor; + background-color: $localSearchBackgroundColor; + border: 2px solid $localSearchBackgroundColor; + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 0; + border-top-right-radius: 0; + + &.localSearchInput-isInvalid { + border-color: $localSearchBorderColor-isInvalid; + } + + @include darkTheme { + color: $localNavTextColor--darkTheme; + background-color: $localSearchBackgroundColor--darkTheme; + border-color: $localSearchBackgroundColor--darkTheme; + + &.localSearchInput-isInvalid { + border-color: $localSearchBorderColor-isInvalid--darkTheme; + } + } +} + +.localSearchButton { + width: 43px; + height: $localSearchHeight; + font-size: $localNavFontSizeNormal; + color: $buttonTextColor; + background-color: $buttonBackgroundColor; + border: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; + + @include darkTheme { + color: $buttonTextColor--darkTheme; + background-color: $buttonBackgroundColor--darkTheme; + } +} diff --git a/src/ui_framework/src/framework/components/local_nav/_local_tabs.scss b/src/ui_framework/src/framework/components/local_nav/_local_tabs.scss new file mode 100644 index 0000000000000..ce83b304cc9a2 --- /dev/null +++ b/src/ui_framework/src/framework/components/local_nav/_local_tabs.scss @@ -0,0 +1,49 @@ +/** + * 1. We want the bottom border on selected tabs to be flush with the bottom of the container. + */ +.localTabs { + display: flex; + align-items: flex-end; // 1 + height: 100%; +} + + /** + * 1. Make sure the bottom border is flush with the bottom of the LocalNav. + */ + .localTab { + padding: 5px 0 6px 0; + font-size: 18px; + line-height: 22px; /* 1 */ + color: $localTabTextColor; + border-bottom: 2px solid transparent; + text-decoration: none; + cursor: pointer; + + &:hover, + &:active { + color: $localTabTextColor-isHover; + + @include darkTheme { + color: $localTabTextColor-isHover--darkTheme; + } + } + + &.localTab-isSelected { + color: $localTabTextColor-isSelected; + border-bottom-color: $localTabTextColor-isSelected; + cursor: default; + + @include darkTheme { + color: $localTabTextColor-isSelected--darkTheme; + border-bottom-color: $localTabTextColor-isSelected--darkTheme; + } + } + + & + & { + margin-left: 15px; + } + + @include darkTheme { + color: $localTabTextColor--darkTheme; + } + } diff --git a/src/ui_framework/src/framework/components/local_nav/_local_title.scss b/src/ui_framework/src/framework/components/local_nav/_local_title.scss new file mode 100644 index 0000000000000..34d62b00c5a6a --- /dev/null +++ b/src/ui_framework/src/framework/components/local_nav/_local_title.scss @@ -0,0 +1,8 @@ +.localTitle { + display: flex; + align-items: center; + height: 100%; + padding-left: $localNavSideSpacing; + font-size: $localNavFontSizeNormal; + font-weight: bold; +} diff --git a/src/ui_framework/src/framework/framework.scss b/src/ui_framework/src/framework/framework.scss new file mode 100644 index 0000000000000..654d23084512c --- /dev/null +++ b/src/ui_framework/src/framework/framework.scss @@ -0,0 +1,27 @@ +// Normal colors +$textColor: #2d2d2d; +$buttonTextColor: #ffffff; +$buttonBackgroundColor: #9c9c9c; +$linkColor: #328CAA; +$linkColor-isHover: #105A73; +$inputTextColor: $textColor; +$inputBackgroundColor: #ffffff; +$inputBorderColor: $inputBackgroundColor; + +// Dark theme colors +$textColor--darkTheme: #cecece; +$buttonTextColor--darkTheme: #ffffff; +$buttonBackgroundColor--darkTheme: #777777; +$linkColor--darkTheme: #b7e2ea; +$linkColor-isHover--darkTheme: #def2f6; +$inputTextColor--darkTheme: $textColor--darkTheme; +$inputBackgroundColor--darkTheme: #444444; +$inputBorderColor--darkTheme: $inputBackgroundColor--darkTheme; + +@mixin darkTheme() { + .theme-dark & { + @content; + } +} + +@import "components/local_nav/index"; diff --git a/src/ui_framework/src/guide/actions/action_types.js b/src/ui_framework/src/guide/actions/action_types.js new file mode 100644 index 0000000000000..c92f35ceccb5a --- /dev/null +++ b/src/ui_framework/src/guide/actions/action_types.js @@ -0,0 +1,13 @@ + +import keyMirror from 'keymirror'; + +export default keyMirror({ + + // Source code viewer actions + OPEN_CODE_VIEWER: null, + UPDATE_CODE_VIEWER: null, + CLOSE_CODE_VIEWER: null, + REGISTER_CODE: null, + UNREGISTER_CODE: null, + +}); diff --git a/src/ui_framework/src/guide/actions/code_viewer/code_viewer_actions.js b/src/ui_framework/src/guide/actions/code_viewer/code_viewer_actions.js new file mode 100644 index 0000000000000..56b5a52e0399e --- /dev/null +++ b/src/ui_framework/src/guide/actions/code_viewer/code_viewer_actions.js @@ -0,0 +1,30 @@ + +import ActionTypes from '../action_types'; + +export default { + + openCodeViewer: slug => ({ + type: ActionTypes.OPEN_CODE_VIEWER, + slug, + }), + + updateCodeViewer: slug => ({ + type: ActionTypes.UPDATE_CODE_VIEWER, + slug, + }), + + closeCodeViewer: () => ({ + type: ActionTypes.CLOSE_CODE_VIEWER, + }), + + registerCode: code => ({ + type: ActionTypes.REGISTER_CODE, + code, + }), + + unregisterCode: code => ({ + type: ActionTypes.UNREGISTER_CODE, + code + }), + +}; diff --git a/src/ui_framework/src/guide/actions/index.js b/src/ui_framework/src/guide/actions/index.js new file mode 100644 index 0000000000000..22f997b682227 --- /dev/null +++ b/src/ui_framework/src/guide/actions/index.js @@ -0,0 +1,4 @@ + +export { + default as CodeViewerActions, +} from './code_viewer/code_viewer_actions'; diff --git a/src/ui_framework/src/guide/components/guide_code_viewer/_guide_code_viewer.scss b/src/ui_framework/src/guide/components/guide_code_viewer/_guide_code_viewer.scss new file mode 100644 index 0000000000000..80ababb96841d --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_code_viewer/_guide_code_viewer.scss @@ -0,0 +1,114 @@ + +.guideCodeViewer { + position: fixed; + top: $guideNavHeight; + right: 0; + bottom: 0; + width: $guideCodeViewerWidth; + padding: 40px 20px 40px 0; + background-color: white; + transform: translateX($guideCodeViewerWidth); + transition: transform $guideCodeViewerTransition; + overflow: auto; + + @include scrollbar; + + @include whenNarrowerThan($normalBreakpoint) { + width: $guideCodeViewerSmallWidth; + } + + &.is-code-viewer-open { + transform: translateX(0); + } +} + + .guideCodeViewer__header { + padding-bottom: 10px; + line-height: $guideLineHeight; + border-bottom: 1px solid #d6d6d6; + font-size: 18px; + font-weight: 700; + margin-bottom: 10px; + } + + .guideCodeViewer__closeButton { + position: absolute; + top: 5px; + right: 5px; + cursor: pointer; + padding: 10px; + border-radius: 3px; + color: #6b7490; + + &:hover { + color: #2b52cc; + } + } + + + .guideCodeViewer__title { + padding-bottom: 6px; + border-bottom: 1px solid #d6d6d6; + line-height: $guideLineHeight; + font-size: 14px; + } + + .guideCodeViewer__content { + margin: 0 0 16px; + } + +// HLJS + +.hljs { + display: block; + padding: 15px 20px; + color: #637c84; + font-size: 14px; + line-height: 1.3; + font-family: 'Ubuntu Mono', monospace; +} + +.hljs-keyword { + color: #b58900; +} + +.hljs-function { + .hljs-keyword { + color: #268bd2; + } + + .hljs-title { + color: #7441c6; + } +} + +.hljs-built_in { + color: #268bd2; +} + +.hljs-string { + color: #36958e; +} + +.hljs-comment { + color: #9d9d9d; +} + +.hljs-number, +.hljs-literal { + color: #d84a7e; +} + +.hljs-tag { + .hljs-name { + color: #63a35c; + } + + .hljs-attr { + color: #795da3; + } + + .hljs-string { + color: #df5000; + } +} diff --git a/src/ui_framework/src/guide/components/guide_code_viewer/guide_code_viewer.jsx b/src/ui_framework/src/guide/components/guide_code_viewer/guide_code_viewer.jsx new file mode 100644 index 0000000000000..8001ef89166f8 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_code_viewer/guide_code_viewer.jsx @@ -0,0 +1,76 @@ + +import React, { + Component, + PropTypes, +} from 'react'; + +import classNames from 'classnames'; +import hljs from 'highlight.js'; + +export default class GuideCodeViewer extends Component { + + constructor(props) { + super(props); + } + + componentDidUpdate() { + if (this.refs.html) { + hljs.highlightBlock(this.refs.html); + } + + if (this.refs.javascript) { + hljs.highlightBlock(this.refs.javascript); + } + } + + renderSection(title, content, codeClass) { + if (content) { + return ( +
+
+ {title} +
+
+            
+              {content}
+            
+          
+
+ ); + } + } + + render() { + const classes = classNames('guideCodeViewer', { + 'is-code-viewer-open': this.props.isOpen, + }); + + return ( +
+
+ {this.props.title} +
+ +
+ + {this.renderSection('HTML', this.props.html, 'html')} + {this.renderSection('JavaScript', this.props.js, 'javascript')} +
+ ); + } + +} + +GuideCodeViewer.propTypes = { + isOpen: PropTypes.bool, + onClose: PropTypes.func, + title: PropTypes.string, + html: PropTypes.string, + js: PropTypes.string, +}; diff --git a/src/ui_framework/src/guide/components/guide_example/_guide_example.scss b/src/ui_framework/src/guide/components/guide_example/_guide_example.scss new file mode 100644 index 0000000000000..ec52942938a92 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_example/_guide_example.scss @@ -0,0 +1,3 @@ +.guideExample { + +} diff --git a/src/ui_framework/src/guide/components/guide_example/guide_example.jsx b/src/ui_framework/src/guide/components/guide_example/guide_example.jsx new file mode 100644 index 0000000000000..72508a5493a54 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_example/guide_example.jsx @@ -0,0 +1,77 @@ + +import React, { + Component, + PropTypes, +} from 'react'; + +import { + Slugify, +} from '../../services'; + +import { + GuidePage, + GuidePageSection, +} from '../'; + +export default class GuideExample extends Component { + + constructor(props, sections) { + super(props); + + this.sections = sections.map(section => Object.assign({}, section, { + slug: Slugify.one(section.title), + })); + } + + componentWillMount() { + this.sections.forEach(section => { + this.context.registerCode(section); + }); + } + + componentWillUnmount() { + this.sections.forEach(section => { + this.context.unregisterCode(section); + }); + } + + renderSections() { + return this.sections.map((section, index) => ( + + {section.description} + + )); + } + + render() { + return ( + + {this.renderSections()} + + ); + } + +} + +GuideExample.contextTypes = { + registerCode: PropTypes.func, + unregisterCode: PropTypes.func, +}; + +GuideExample.propTypes = { + route: PropTypes.object.isRequired, + sections: PropTypes.arrayOf(React.PropTypes.shape({ + title: React.PropTypes.string.isRequired, + description: React.PropTypes.any, + html: React.PropTypes.string.isRequired, + js: React.PropTypes.string, + })), +}; diff --git a/src/ui_framework/src/guide/components/guide_nav/_guide_nav.scss b/src/ui_framework/src/guide/components/guide_nav/_guide_nav.scss new file mode 100644 index 0000000000000..adb168888663a --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_nav/_guide_nav.scss @@ -0,0 +1,67 @@ +.guideNav { + position: fixed; + z-index: 1; + top: 0; + left: 0; + right: 0; + height: $guideNavHeight; + padding: 0 20px; + background-color: #e8488b; + color: #ffffff; + box-shadow: + inset 0 -20px 18px rgba(#5a1029, 0.2), + inset 0 -5px 4px rgba(#5a1029, 0.3); + transition: height 0.3s ease; + overflow: hidden; + + &.is-guide-nav-open { + height: 100%; + } +} + + .guideNav__header { + display: flex; + align-items: center; + height: 60px; + } + + .guideNav__menu { + cursor: pointer; + margin-right: 10px; + padding: 10px; + border-radius: 3px; + + &.is-menu-button-pinned, + &:hover { + background-color: rgba(black, 0.15); + } + + &:active { + background-color: rgba(black, 0.2); + box-shadow: inset 0 2px 8px rgba(black, 0.2); + } + } + + .guideNav__title { + color: white; + text-decoration: none; + font-size: 18px; + } + + .guideNav__version { + margin-left: 10px; + font-weight: 300; + font-size: 14px; + } + + .guideNavItem { + color: white; + text-decoration: none; + font-size: 20px; + padding: 10px; + border-radius: 3px; + + &:hover { + background-color: rgba(black, 0.15); + } + } diff --git a/src/ui_framework/src/guide/components/guide_nav/guide_nav.jsx b/src/ui_framework/src/guide/components/guide_nav/guide_nav.jsx new file mode 100644 index 0000000000000..f6d7aacf9f1b1 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_nav/guide_nav.jsx @@ -0,0 +1,65 @@ + +import React, { + PropTypes, +} from 'react'; + +import { + Link, +} from 'react-router'; + +import classNames from 'classnames'; + +const GuideNav = props => { + const classes = classNames('guideNav', { + 'is-guide-nav-open': props.isNavOpen, + }); + + const buttonClasses = classNames('guideNav__menu fa fa-bars', { + 'is-menu-button-pinned': props.isNavOpen, + }); + + const navItems = props.items.map((item, index) => { + return ( + + {item.name} + + ); + }); + + return ( +
+
+
+ + Kibana UI Framework {props.version} + +
+ +
+ {navItems} +
+
+ ); +}; + +GuideNav.propTypes = { + isNavOpen: PropTypes.bool, + onToggleNav: PropTypes.func, + onClickNavItem: PropTypes.func, + version: PropTypes.string, + items: PropTypes.array, +}; + +export default GuideNav; diff --git a/src/ui_framework/src/guide/components/guide_page/_guide_page.scss b/src/ui_framework/src/guide/components/guide_page/_guide_page.scss new file mode 100644 index 0000000000000..21ae022cb3056 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_page/_guide_page.scss @@ -0,0 +1,15 @@ + +@import "../../variables"; + +.guidePage { + display: flex; +} + +.guidePageBody { + flex: 1 1 auto; + padding: 0 80px 0 80px + $guideSideNavWidth; + + @include whenNarrowerThan($normalBreakpoint) { + padding: 0 20px 0 $guideSideNavSmallWidth; + } +} diff --git a/src/ui_framework/src/guide/components/guide_page/guide_page.jsx b/src/ui_framework/src/guide/components/guide_page/guide_page.jsx new file mode 100644 index 0000000000000..dac8bc5120f5e --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_page/guide_page.jsx @@ -0,0 +1,72 @@ + +import React, { + Component, + PropTypes, +} from 'react'; + +import { + Slugify, +} from '../../services'; + +import { + GuidePageSideNav, + GuidePageSideNavItem, +} from '../'; + +export default class GuidePage extends Component { + + constructor(props) { + super(props); + + this.onClickLink = this.onClickLink.bind(this); + } + + onClickLink(slug) { + // Scroll to element. + $('html, body').animate({ + scrollTop: $(`#${slug}`).offset().top - 100 + }, 250); + + // Load in code viewer. + this.context.updateCodeViewer(slug); + } + + renderSideNavMenu() { + // Traverse children and build side nav from it. + return this.props.children.map((section, index) => { + return ( + + {section.props.title} + + ); + }); + } + + render() { + return ( +
+ + {this.renderSideNavMenu()} + + +
+ {this.props.children} +
+
+ ); + } + +} + +GuidePage.contextTypes = { + updateCodeViewer: PropTypes.func, +}; + +GuidePage.propTypes = { + children: PropTypes.any, + title: PropTypes.string, +}; diff --git a/src/ui_framework/src/guide/components/guide_page_section/_guide_page_section.scss b/src/ui_framework/src/guide/components/guide_page_section/_guide_page_section.scss new file mode 100644 index 0000000000000..85a578f407ea8 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_page_section/_guide_page_section.scss @@ -0,0 +1,56 @@ + +@import "../../variables"; + +.guidePageSection { + margin-bottom: 40px; +} + + .guidePageSection__header { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 10px; + line-height: $guideLineHeight; + border-bottom: 1px solid #d6d6d6; + } + + .guidePageSection__title { + font-size: 18px; + font-weight: 700; + } + + .guidePageSection__sourceButton { + line-height: 10px; + padding: 4px 10px; + background-color: #19a8e0; + color: white; + border-radius: 3px; + cursor: pointer; + + &:hover { + box-shadow: + inset 0 1px 0 rgba(#95e1ff, 1), + 0 2px 4px rgba(black, 0.2); + } + + &:active { + box-shadow: + inset 0 20px 20px rgba(black, 0.1), + inset 0 2px 8px rgba(black, 0.2); + } + } + + .guidePageSection__description { + font-size: 14px; + line-height: 21px; + } + + .guidePageSection__example { + & + & { + margin-top: 20px; + } + } + + .guidePageSection__example--standalone { + margin-top: 10px; + } diff --git a/src/ui_framework/src/guide/components/guide_page_section/guide_page_section.jsx b/src/ui_framework/src/guide/components/guide_page_section/guide_page_section.jsx new file mode 100644 index 0000000000000..aa3ea3e3dc423 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_page_section/guide_page_section.jsx @@ -0,0 +1,123 @@ + +import React, { + Component, + PropTypes, +} from 'react'; + +import classNames from 'classnames'; + +import { + JsInjector, +} from '../../services'; + +export default class GuidePageSection extends Component { + + constructor(props) { + super(props); + + this.onClickSource = this.onClickSource.bind(this); + } + + componentDidMount() { + // NOTE: This will cause a race condition if a GuidePage adds and removes + // GuidePageSection instances during its lifetime (e.g. if a user is allowed + // to click "add" and "delete" buttons to add and remove GuidePageSections). + // + // In such a race condition, we could end up with GuidePageSections with + // identical id values. + // + // As long as all GuidePageSection instances are added when a GuidePage + // is instantiated, and then they're all removed when a GuidePage is + // removed, we won't encounter this race condition. + if (this.props.js) { + this.scriptId = `${GuidePageSection.SCRIPT_ID}${GuidePageSection.count}`; + GuidePageSection.count++; + // JS injection must occur _after_ the component has been mounted, so + // the component DOM is available for the JS to manipulate. + JsInjector.inject(this.props.js, this.scriptId); + } + + function trimChildren(node) { + if (node.children.length > 0) { + [...node.children].forEach(trimChildren); + return; + } + node.textContent = node.textContent.trim(); + } + + trimChildren(this.refs.html); + trimChildren(this.refs.htmlDarkTheme); + } + + componentWillUnmount() { + JsInjector.remove(this.scriptId); + GuidePageSection.count--; + } + + onClickSource() { + this.context.openCodeViewer(this.props.slug); + } + + render() { + let description; + + if (this.props.children) { + description = ( +
+ {this.props.children} +
+ ); + } + + const exampleClasses = classNames('guidePageSection__example', { + 'guidePageSection__example--standalone': !this.props.children, + }); + + return ( +
+
+
+ {this.props.title} +
+
+
+ + {description} + +
+ +
+
+ ); + } + +} + +GuidePageSection.count = 0; +GuidePageSection.SCRIPT_ID = 'EXAMPLE_SCRIPT'; + +GuidePageSection.contextTypes = { + openCodeViewer: PropTypes.func, +}; + +GuidePageSection.propTypes = { + title: PropTypes.string, + slug: PropTypes.string, + html: PropTypes.string, + js: PropTypes.string, + children: PropTypes.any, +}; diff --git a/src/ui_framework/src/guide/components/guide_page_side_nav/_guide_page_side_nav.scss b/src/ui_framework/src/guide/components/guide_page_side_nav/_guide_page_side_nav.scss new file mode 100644 index 0000000000000..9a8a706544c81 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_page_side_nav/_guide_page_side_nav.scss @@ -0,0 +1,46 @@ + +.guidePageSideNav { + position: fixed; + top: 100px; + left: 0; + bottom: 0; + width: $guideSideNavWidth; + padding: 0 20px 30px 80px; + overflow: auto; + + @include scrollbar; + + @include whenNarrowerThan($normalBreakpoint) { + padding: 0 20px 30px 20px; + width: $guideSideNavSmallWidth; + } +} + + .guidePageSideNav__title { + padding-bottom: 10px; + margin-bottom: 10px; + font-size: 22px; + line-height: $guideLineHeight; + border-bottom: 1px solid #d6d6d6; + opacity: 0.8; + } + + .guidePageSideNavMenu { + line-height: $guideLineHeight; + } + + .guidePageSideNavMenu__item { + & + & { + margin-top: 6px; + } + } + + .guidePageSideNavMenu__itemLink { + cursor: pointer; + color: #6b7490; + text-decoration: none; + + &:hover { + color: #2b52cc; + } + } diff --git a/src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav.jsx b/src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav.jsx new file mode 100644 index 0000000000000..0d01d8de2ab20 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav.jsx @@ -0,0 +1,32 @@ + +import React, { + Component, + PropTypes, +} from 'react'; + +export default class GuidePageSideNav extends Component { + + constructor(props) { + super(props); + } + + render() { + return ( +
+
+ {this.props.title} +
+ +
+ {this.props.children} +
+
+ ); + } + +} + +GuidePageSideNav.propTypes = { + title: PropTypes.string, + children: PropTypes.any, +}; diff --git a/src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav_item.jsx b/src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav_item.jsx new file mode 100644 index 0000000000000..2d439ba5da0e1 --- /dev/null +++ b/src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav_item.jsx @@ -0,0 +1,38 @@ + +import React, { + Component, + PropTypes, +} from 'react'; + +export default class GuidePageSideNavItem extends Component { + + constructor(props) { + super(props); + + this.onClick = this.onClick.bind(this); + } + + onClick() { + this.props.onClick(this.props.slug); + } + + render() { + return ( +
+
+ {this.props.children} +
+
+ ); + } + +} + +GuidePageSideNavItem.propTypes = { + slug: PropTypes.string, + children: PropTypes.any, + onClick: PropTypes.func, +}; diff --git a/src/ui_framework/src/guide/components/index.js b/src/ui_framework/src/guide/components/index.js new file mode 100644 index 0000000000000..0785980c1dcf8 --- /dev/null +++ b/src/ui_framework/src/guide/components/index.js @@ -0,0 +1,21 @@ + +export * from './guide_code_viewer/guide_code_viewer.jsx'; +export { default as GuideCodeViewer } from './guide_code_viewer/guide_code_viewer.jsx'; + +export * from './guide_example/guide_example.jsx'; +export { default as GuideExample } from './guide_example/guide_example.jsx'; + +export * from './guide_nav/guide_nav.jsx'; +export { default as GuideNav } from './guide_nav/guide_nav.jsx'; + +export * from './guide_page/guide_page.jsx'; +export { default as GuidePage } from './guide_page/guide_page.jsx'; + +export * from './guide_page_section/guide_page_section.jsx'; +export { default as GuidePageSection } from './guide_page_section/guide_page_section.jsx'; + +export * from './guide_page_side_nav/guide_page_side_nav.jsx'; +export { default as GuidePageSideNav } from './guide_page_side_nav/guide_page_side_nav.jsx'; + +export * from './guide_page_side_nav/guide_page_side_nav_item.jsx'; +export { default as GuidePageSideNavItem } from './guide_page_side_nav/guide_page_side_nav_item.jsx'; diff --git a/src/ui_framework/src/guide/index.js b/src/ui_framework/src/guide/index.js new file mode 100644 index 0000000000000..ca17c966eacd7 --- /dev/null +++ b/src/ui_framework/src/guide/index.js @@ -0,0 +1,80 @@ +require('./main.scss'); + +import 'babel-polyfill'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Provider } from 'react-redux'; +import { + Router, + useRouterHistory, +} from 'react-router'; +import { syncHistoryWithStore } from 'react-router-redux'; +import createHashHistory from 'history/lib/createHashHistory'; + +// Store. +import configureStore from './store/configure_store'; + +// Guide views. +import AppContainer from './views/app_container'; +import HomeView from './views/home/home_view.jsx'; +import NotFoundView from './views/not_found/not_found_view.jsx'; + +import { + Routes, +} from './services'; + +const store = configureStore(); +const browserHistory = useRouterHistory(createHashHistory)({ + queryKey: false, +}); +const history = syncHistoryWithStore(browserHistory, store); + +const childRoutes = Routes.getAppRoutes(); +childRoutes.push({ + path: '*', + component: NotFoundView, + name: 'Page Not Found', +}); + +const routes = [{ + path: '/', + component: AppContainer, + indexRoute: { + component: HomeView, + source: 'views/home/HomeView.jsx', + }, + childRoutes, +}]; + +// Update document title with route name. +const onRouteEnter = route => { + const leafRoute = route.routes[route.routes.length - 1]; + document.title = leafRoute.name ? + `Kibana UI Framework - ${leafRoute.name}` : + 'Kibana UI Framework'; +}; + +const syncTitleWithRoutes = routesList => { + if (!routesList) return; + routesList.forEach(route => { + route.onEnter = onRouteEnter; // eslint-disable-line no-param-reassign + if (route.indexRoute) { + // Index routes have a weird relationship with their "parent" routes, + // so it seems we need to give their own onEnter hooks. + route.indexRoute.onEnter = onRouteEnter; // eslint-disable-line no-param-reassign + } + syncTitleWithRoutes(route.childRoutes); + }); +}; + +syncTitleWithRoutes(routes); + +ReactDOM.render( + + + , + document.getElementById('guide') +); diff --git a/src/ui_framework/src/guide/main.scss b/src/ui_framework/src/guide/main.scss new file mode 100644 index 0000000000000..402ed577735b4 --- /dev/null +++ b/src/ui_framework/src/guide/main.scss @@ -0,0 +1,28 @@ + +@import "../framework/framework"; +@import "./views/app"; +@import "./components/guide_code_viewer/guide_code_viewer"; +@import "./components/guide_nav/guide_nav"; +@import "./components/guide_page/guide_page"; +@import "./components/guide_page_section/guide_page_section"; +@import "./components/guide_page_side_nav/guide_page_side_nav"; + +* { + box-sizing: border-box; +} + +html, +body { + height: 100%; +} + +/** + * 1. Insane line-height makes it easier to notice when components are relying + * on styles inherited from body. + */ +body { + font-family: 'Lato', 'Helvetica Neue', sans-serif; + background: #ffffff; + line-height: 40px; /* 1 */ + margin: 0; +} diff --git a/src/ui_framework/src/guide/services/example/createExample.js b/src/ui_framework/src/guide/services/example/createExample.js new file mode 100644 index 0000000000000..3a0a47fc9f9c0 --- /dev/null +++ b/src/ui_framework/src/guide/services/example/createExample.js @@ -0,0 +1,16 @@ + +import { + GuideExample, +} from '../../components'; + +export default function creatExample(examples) { + class Example extends GuideExample { + constructor(props) { + super(props, examples); + } + } + + Example.propTypes = Object.assign({}, GuideExample.propTypes); + + return Example; +} diff --git a/src/ui_framework/src/guide/services/index.js b/src/ui_framework/src/guide/services/index.js new file mode 100644 index 0000000000000..f5e87594f507a --- /dev/null +++ b/src/ui_framework/src/guide/services/index.js @@ -0,0 +1,12 @@ + +export * from './example/createExample'; +export { default as createExample } from './example/createExample'; + +export * from './js_injector/js_injector'; +export { default as JsInjector } from './js_injector/js_injector'; + +export * from './routes/routes'; +export { default as Routes } from './routes/routes'; + +export * from './string/slugify'; +export { default as Slugify } from './string/slugify'; diff --git a/src/ui_framework/src/guide/services/js_injector/js_injector.js b/src/ui_framework/src/guide/services/js_injector/js_injector.js new file mode 100644 index 0000000000000..f77986272390c --- /dev/null +++ b/src/ui_framework/src/guide/services/js_injector/js_injector.js @@ -0,0 +1,21 @@ + +import $ from 'jquery'; + +const ID_ATTRIBUTE = 'injected-js-tag-id'; + +export default { + + inject(js, id) { + if (id) { + $(`[${ID_ATTRIBUTE}=${id}]`).remove(); + } + + const script = $(``); + $('body').append(script); + }, + + remove(id) { + $(`[${ID_ATTRIBUTE}=${id}]`).remove(); + }, + +}; diff --git a/src/ui_framework/src/guide/services/routes/Routes.js b/src/ui_framework/src/guide/services/routes/Routes.js new file mode 100644 index 0000000000000..2fe47ff9a9319 --- /dev/null +++ b/src/ui_framework/src/guide/services/routes/Routes.js @@ -0,0 +1,19 @@ + +import Slugify from '../string/slugify'; + +import LocalNavExample + from '../../views/local_nav/local_nav_example.jsx'; + +// Component route names should match the component name exactly. +const components = [{ + name: 'LocalNav', + component: LocalNavExample, +}]; + +export default { + components: Slugify.each(components, 'name', 'path'), + getAppRoutes: function getAppRoutes() { + const list = this.components; + return list.slice(0); + }, +}; diff --git a/src/ui_framework/src/guide/services/string/slugify.js b/src/ui_framework/src/guide/services/string/slugify.js new file mode 100644 index 0000000000000..829b37640f16b --- /dev/null +++ b/src/ui_framework/src/guide/services/string/slugify.js @@ -0,0 +1,27 @@ + + +/** + * Lowercases input and replaces spaces with hyphens: + * e.g. 'GridView Example' -> 'gridview-example' + */ +function one(str) { + const parts = str + .toLowerCase() + .replace(/[-]+/g, ' ') + .replace(/[^\w^\s]+/g, '') + .replace(/ +/g, ' ').split(' '); + return parts.join('-'); +} + +function each(items, src, dest) { + return items.map(item => { + const _item = item; + _item[dest] = one(_item[src]); + return _item; + }); +} + +export default { + one, + each, +}; diff --git a/src/ui_framework/src/guide/store/configure_store.js b/src/ui_framework/src/guide/store/configure_store.js new file mode 100644 index 0000000000000..08f186671abdd --- /dev/null +++ b/src/ui_framework/src/guide/store/configure_store.js @@ -0,0 +1,35 @@ +import { + applyMiddleware, + createStore, + compose, +} from 'redux'; +import thunk from 'redux-thunk'; +import { browserHistory } from 'react-router'; +import { + routerMiddleware, + routerReducer, +} from 'react-router-redux'; + +import codeViewerReducer from './reducers/code_viewer_reducer'; + +/** + * @param {Object} initialState An object defining the application's initial + * state. + */ +export default function configureStore(initialState) { + function rootReducer(state = {}, action) { + return { + routing: routerReducer(state.routing, action), + codeViewer: codeViewerReducer(state.codeViewer, action), + }; + } + + const finalStore = compose( + applyMiddleware( + thunk, + routerMiddleware(browserHistory) + ) + )(createStore)(rootReducer, initialState); + + return finalStore; +} diff --git a/src/ui_framework/src/guide/store/reducers/code_viewer_reducer.js b/src/ui_framework/src/guide/store/reducers/code_viewer_reducer.js new file mode 100644 index 0000000000000..e4d27ad181375 --- /dev/null +++ b/src/ui_framework/src/guide/store/reducers/code_viewer_reducer.js @@ -0,0 +1,69 @@ + +import ActionTypes from '../../actions/action_types'; + +const defaultState = { + isOpen: false, + codesBySlug: {}, + code: undefined, +}; + +export default function codeViewerReducer(state = defaultState, action) { + switch (action.type) { + case ActionTypes.OPEN_CODE_VIEWER: { + const newCode = state.codesBySlug[action.slug]; + + if (state.code === newCode) { + // If we are opening the existing code, then close the viewer. + return Object.assign({}, state, { + isOpen: false, + code: undefined, + }); + } + + return Object.assign({}, state, { + isOpen: true, + code: newCode, + }); + } + + case ActionTypes.UPDATE_CODE_VIEWER: { + if (state.isOpen) { + return Object.assign({}, state, { + code: state.codesBySlug[action.slug], + }); + } + return state; + } + + case ActionTypes.CLOSE_CODE_VIEWER: { + return Object.assign({}, state, { + isOpen: false, + code: undefined, + }); + } + + case ActionTypes.REGISTER_CODE: { + const codesBySlug = Object.assign({}, state.codesBySlug, { + [action.code.slug]: action.code, + }); + + return Object.assign({}, state, { + codesBySlug + }); + } + + case ActionTypes.UNREGISTER_CODE: { + const codesBySlug = Object.assign({}, state.codesBySlug); + delete codesBySlug[action.code.slug]; + + return Object.assign({}, state, { + codesBySlug + }); + } + + default: + break; + } + + return state; +} diff --git a/src/ui_framework/src/guide/variables.scss b/src/ui_framework/src/guide/variables.scss new file mode 100644 index 0000000000000..8376a7ef8d59b --- /dev/null +++ b/src/ui_framework/src/guide/variables.scss @@ -0,0 +1,39 @@ + +$guideLineHeight: 24px; +$guideNavHeight: 60px; +$guideSideNavWidth: 400px; +$guideSideNavSmallWidth: 220px; +$guideCodeViewerWidth: 700px; +$guideCodeViewerSmallWidth: 580px; +$guideCodeViewerTransition: 0.2s ease; + +$normalBreakpoint: 1900px; + +@mixin whenNarrowerThan($browserWidth) { + @media only screen and (max-width: #{$browserWidth}) { + @content; + } +} + +@mixin whenWiderThan($browserWidth) { + @media only screen and (min-width: #{$browserWidth}) { + @content; + } +} + +@mixin scrollbar($color: rgba(#454D58, 0.4)) { + &::-webkit-scrollbar { + width: 16px; + height: 16px; + } + + &::-webkit-scrollbar-thumb { + background-color: $color; + border: 6px solid transparent; + background-clip: content-box; + } + + &::-webkit-scrollbar-track { + background-color: transparent; + } +} diff --git a/src/ui_framework/src/guide/views/_app.scss b/src/ui_framework/src/guide/views/_app.scss new file mode 100644 index 0000000000000..47e0554a94572 --- /dev/null +++ b/src/ui_framework/src/guide/views/_app.scss @@ -0,0 +1,22 @@ + +@import "../variables"; +@import "./home/home_view"; + +.guide { + display: flex; + height: 100%; +} + +.guideContent { + flex: 1 1 auto; + padding-top: 100px; + transition: padding-right $guideCodeViewerTransition; + + &.is-code-viewer-open { + padding-right: $guideCodeViewerWidth; + + @include whenNarrowerThan($normalBreakpoint) { + padding-right: $guideCodeViewerSmallWidth; + } + } +} diff --git a/src/ui_framework/src/guide/views/app_container.js b/src/ui_framework/src/guide/views/app_container.js new file mode 100644 index 0000000000000..bc134de2e60ef --- /dev/null +++ b/src/ui_framework/src/guide/views/app_container.js @@ -0,0 +1,30 @@ + +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import AppView from './app_view.jsx'; + +import { + CodeViewerActions, +} from '../actions'; + +function mapStateToProps(state, ownProps) { + return { + routes: ownProps.routes, + isCodeViewerOpen: state.codeViewer.isOpen, + code: state.codeViewer.code, + }; +} + +function mapDispatchToProps(dispatch) { + const actions = { + openCodeViewer: CodeViewerActions.openCodeViewer, + updateCodeViewer: CodeViewerActions.updateCodeViewer, + closeCodeViewer: CodeViewerActions.closeCodeViewer, + registerCode: CodeViewerActions.registerCode, + unregisterCode: CodeViewerActions.unregisterCode, + }; + + return bindActionCreators(actions, dispatch); +} + +export default connect(mapStateToProps, mapDispatchToProps)(AppView); diff --git a/src/ui_framework/src/guide/views/app_view.jsx b/src/ui_framework/src/guide/views/app_view.jsx new file mode 100644 index 0000000000000..8a71f12667545 --- /dev/null +++ b/src/ui_framework/src/guide/views/app_view.jsx @@ -0,0 +1,113 @@ + +import React, { + Component, + PropTypes, +} from 'react'; + +import classNames from 'classnames'; + +import { + Routes, +} from '../services'; + +import { + GuideCodeViewer, + GuideNav, +} from '../components'; + +// Inject version into header. +const pkg = require('json!../../../../../package.json'); + +export default class AppView extends Component { + + constructor(props) { + super(props); + + this.state = { + isNavOpen: false, + }; + + this.onClickNavItem = this.onClickNavItem.bind(this); + this.onToggleNav = this.onToggleNav.bind(this); + this.onCloseCodeViewer = this.onCloseCodeViewer.bind(this); + } + + getChildContext() { + return { + openCodeViewer: this.props.openCodeViewer, + updateCodeViewer: this.props.updateCodeViewer, + registerCode: this.props.registerCode, + unregisterCode: this.props.unregisterCode, + }; + } + + onClickNavItem() { + this.setState({ + isNavOpen: false, + }); + } + + onCloseCodeViewer() { + this.props.closeCodeViewer(); + } + + onToggleNav() { + this.setState({ + isNavOpen: !this.state.isNavOpen, + }) + } + + render() { + const contentClasses = classNames('guideContent', { + 'is-code-viewer-open': this.props.isCodeViewerOpen, + }); + + return ( +
+ + +
+ {this.props.children} +
+ + +
+ ); + } + +} + +AppView.childContextTypes = { + openCodeViewer: PropTypes.func, + updateCodeViewer: PropTypes.func, + registerCode: PropTypes.func, + unregisterCode: PropTypes.func, +}; + +AppView.propTypes = { + children: PropTypes.any, + routes: PropTypes.array.isRequired, + openCodeViewer: PropTypes.func, + updateCodeViewer: PropTypes.func, + closeCodeViewer: PropTypes.func, + registerCode: PropTypes.func, + unregisterCode: PropTypes.func, + isCodeViewerOpen: PropTypes.bool, + code: PropTypes.object, +}; + +AppView.defaultProps = { + code: {}, +}; diff --git a/src/ui_framework/src/guide/views/home/_home_view.scss b/src/ui_framework/src/guide/views/home/_home_view.scss new file mode 100644 index 0000000000000..66dc7fcba01e6 --- /dev/null +++ b/src/ui_framework/src/guide/views/home/_home_view.scss @@ -0,0 +1,28 @@ + +@import "../../variables"; + +.guideHome { + display: flex; + justify-content: center; +} + + .guideHome__panel { + width: 100%; + max-width: 600px; + max-height: 500px; + padding: 60px; + margin-bottom: 20px; + border-radius: 3px; + background-color: #e8e8e8; + line-height: $guideLineHeight; + } + + .guideHome__panelTitle { + font-weight: 700; + font-size: 22px; + margin-bottom: 20px; + } + + .guideHome__panelText { + font-size: 18px; + } diff --git a/src/ui_framework/src/guide/views/home/home_view.jsx b/src/ui_framework/src/guide/views/home/home_view.jsx new file mode 100644 index 0000000000000..715fbc36c0aee --- /dev/null +++ b/src/ui_framework/src/guide/views/home/home_view.jsx @@ -0,0 +1,28 @@ + +import React, { + Component, +} from 'react'; + +export default class HomeView extends Component { + + constructor(props) { + super(props); + } + + render() { + return ( +
+
+
+ Welcome to the Kibana UI Framework +
+ +
+ Get started by clicking the menu button in the top left corner of the screen. +
+
+
+ ); + } + +} diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_breadcrumbs/local_nav_breadcrumbs.html b/src/ui_framework/src/guide/views/local_nav/local_nav_breadcrumbs/local_nav_breadcrumbs.html new file mode 100644 index 0000000000000..2078dea3b9f08 --- /dev/null +++ b/src/ui_framework/src/guide/views/local_nav/local_nav_breadcrumbs/local_nav_breadcrumbs.html @@ -0,0 +1,41 @@ + +
+
+
+ +
+ +
+
+
+ New +
+ +
+ Save +
+ +
+ Open +
+ + +
+
+
+
diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_dropdown/local_nav_dropdown.html b/src/ui_framework/src/guide/views/local_nav/local_nav_dropdown/local_nav_dropdown.html new file mode 100644 index 0000000000000..87e486d2eb5bf --- /dev/null +++ b/src/ui_framework/src/guide/views/local_nav/local_nav_dropdown/local_nav_dropdown.html @@ -0,0 +1,122 @@ + +
+
+
+ +
+ +
+
+
+ New +
+ +
+ Save +
+ +
+ Open +
+ + +
+
+
+ +
+ +
Dropdown title
+ + +
+ Here's some help text to explain the purpose of the dropdown. +
+ + +
+ Here's some warning text in case the user has something misconfigured. +
+ +
+ +
+
+ Header for a section of content +
+
+ + + +
+ +
+ +
+
+ Header for another section of content +
+ +
+ + + + + +
+ Here are some notes to explain the purpose of this section of the dropdown. +
+
+
+ +
+
+ + +
+
+
diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html b/src/ui_framework/src/guide/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html new file mode 100644 index 0000000000000..1a1458fb62666 --- /dev/null +++ b/src/ui_framework/src/guide/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html @@ -0,0 +1,81 @@ + +
+
+
+ +
+ +
+
+
+ New +
+ +
+ Save +
+ +
+ Open +
+ + +
+
+
+ +
+
+ +
+ +
Left panel
+ + +
+ Here's some help text to explain the purpose of the dropdown. +
+
+ + +
+ +
Right panel
+ + +
+ Here's some help text to explain the purpose of the dropdown. +
+
+
+
+ +
+
+ + +
+
+
diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_example.jsx b/src/ui_framework/src/guide/views/local_nav/local_nav_example.jsx new file mode 100644 index 0000000000000..79d01c68eadf3 --- /dev/null +++ b/src/ui_framework/src/guide/views/local_nav/local_nav_example.jsx @@ -0,0 +1,56 @@ + +import React from 'react'; + +import { + createExample, +} from '../../services'; + +export default createExample([{ + title: 'Simple', + description: ( +

Here's a simple LocalNav with a Title in the top left corner and Menu in the top right.

+ ), + html: require('./local_nav_simple/local_nav_simple.html'), +}, { + title: 'Breadcrumbs', + description: ( +

You can replace the Title with Breadcrumbs.

+ ), + html: require('./local_nav_breadcrumbs/local_nav_breadcrumbs.html'), +}, { + title: 'Search', + description: ( +

You can add a Search component for filtering results.

+ ), + html: require('./local_nav_search/local_nav_search.html'), +}, { + title: 'Invalid Search', + html: require('./local_nav_search_error/local_nav_search_error.html'), +}, { + title: 'Selected and disabled Menu Item states', + description: ( +
+

When the user selects a Menu Item, additional content can be displayed inside of a Dropdown.

+

Menu Items can also be disabled, in which case they become non-interactive.

+
+ ), + html: require('./local_nav_menu_item_states/local_nav_menu_item_states.html'), +}, { + title: 'Dropdown', + description: ( +

Selecting a Menu Item will commonly result in an open Dropdown.

+ ), + html: require('./local_nav_dropdown/local_nav_dropdown.html'), +}, { + title: 'Dropdown panels', + description: ( +

You can split the Dropdown into side-by-side Panels.

+ ), + html: require('./local_nav_dropdown_panels/local_nav_dropdown_panels.html'), +}, { + title: 'Tabs', + description: ( +

You can display Tabs for navigating local content.

+ ), + html: require('./local_nav_tabs/local_nav_tabs.html'), +}]); diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_menu_item_states/local_nav_menu_item_states.html b/src/ui_framework/src/guide/views/local_nav/local_nav_menu_item_states/local_nav_menu_item_states.html new file mode 100644 index 0000000000000..25211acd98469 --- /dev/null +++ b/src/ui_framework/src/guide/views/local_nav/local_nav_menu_item_states/local_nav_menu_item_states.html @@ -0,0 +1,55 @@ + +
+
+
+ +
+ +
+
+
+ New +
+ +
+ Save +
+ +
+ Open +
+ + +
+
+
+ +
+
+ + +
+
+
diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_search/local_nav_search.html b/src/ui_framework/src/guide/views/local_nav/local_nav_search/local_nav_search.html new file mode 100644 index 0000000000000..01ab1e7017da3 --- /dev/null +++ b/src/ui_framework/src/guide/views/local_nav/local_nav_search/local_nav_search.html @@ -0,0 +1,55 @@ + +
+
+
+ +
+ +
+
+ + + + + + + +
+
+
+ +
+
+ + +
+
+
diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_search_error/local_nav_search_error.html b/src/ui_framework/src/guide/views/local_nav/local_nav_search_error/local_nav_search_error.html new file mode 100644 index 0000000000000..9f73b820990b1 --- /dev/null +++ b/src/ui_framework/src/guide/views/local_nav/local_nav_search_error/local_nav_search_error.html @@ -0,0 +1,55 @@ + +
+
+
+ +
+ +
+
+ + + + + + + +
+
+
+ +
+
+ + +
+
+
diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_simple/local_nav_simple.html b/src/ui_framework/src/guide/views/local_nav/local_nav_simple/local_nav_simple.html new file mode 100644 index 0000000000000..d35d5da8adbb7 --- /dev/null +++ b/src/ui_framework/src/guide/views/local_nav/local_nav_simple/local_nav_simple.html @@ -0,0 +1,31 @@ + +
+
+
+
+ Untitled Document +
+
+ +
+
+
+ New +
+ +
+ Save +
+ +
+ Open +
+ + +
+
+
+
diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_tabs/local_nav_tabs.html b/src/ui_framework/src/guide/views/local_nav/local_nav_tabs/local_nav_tabs.html new file mode 100644 index 0000000000000..8b0b277b5d2b7 --- /dev/null +++ b/src/ui_framework/src/guide/views/local_nav/local_nav_tabs/local_nav_tabs.html @@ -0,0 +1,57 @@ + +
+
+
+ +
+ +
+
+ + + + + + + +
+
+
+ + +
diff --git a/src/ui_framework/src/guide/views/not_found/not_found_view.jsx b/src/ui_framework/src/guide/views/not_found/not_found_view.jsx new file mode 100644 index 0000000000000..417a9fcec4b4b --- /dev/null +++ b/src/ui_framework/src/guide/views/not_found/not_found_view.jsx @@ -0,0 +1,20 @@ + +import React, { + Component, +} from 'react'; + +export default class NotFoundView extends Component { + + constructor(props) { + super(props); + } + + render() { + return ( +
+

Page not found.

+
+ ); + } + +} diff --git a/src/ui_framework/webpack.config.js b/src/ui_framework/webpack.config.js new file mode 100644 index 0000000000000..58f35bd49ba19 --- /dev/null +++ b/src/ui_framework/webpack.config.js @@ -0,0 +1,39 @@ +var path = require('path'); + +module.exports = { + devtool: 'source-map', + + entry: { + guide: './src/ui_framework/src/guide/index.js' + }, + + output: { + path: path.resolve(__dirname, 'src/ui_framework/public'), + filename: 'bundle.js' + }, + + resolve: { + root: [ + path.resolve(__dirname, 'src/ui_framework/src') + ] + }, + + module: { + loaders: [{ + test: /\.jsx?$/, + loader: 'babel', + exclude: /node_modules/ + }, { + test: /\.scss$/, + loaders: ['style', 'css', 'sass'], + exclude: /node_modules/ + }, { + test: /\.html$/, + loader: 'html', + exclude: /node_modules/ + }, { + test: require.resolve('jquery'), + loader: 'expose?jQuery!expose?$' + }] + } +}; From 4e548445771fa04cffb6d5a230c9d4be51f8e1c7 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Mon, 5 Dec 2016 15:03:01 -0800 Subject: [PATCH 2/5] Refactor UI Framework directory structure. --- .gitignore | 2 +- package.json | 4 ++-- src/ui/public/autoload/styles.js | 2 +- .../{src/framework/framework.scss => components/index.scss} | 2 +- .../{src/framework => }/components/local_nav/_index.scss | 0 .../components/local_nav/_local_breadcrumbs.scss | 0 .../components/local_nav/_local_dropdown.scss | 0 .../framework => }/components/local_nav/_local_menu.scss | 0 .../framework => }/components/local_nav/_local_nav.scss | 0 .../framework => }/components/local_nav/_local_search.scss | 0 .../framework => }/components/local_nav/_local_tabs.scss | 0 .../framework => }/components/local_nav/_local_title.scss | 0 src/ui_framework/{public => doc_site/build}/index.html | 0 .../{src/guide => doc_site/src}/actions/action_types.js | 0 .../src}/actions/code_viewer/code_viewer_actions.js | 0 .../{src/guide => doc_site/src}/actions/index.js | 0 .../components/guide_code_viewer/_guide_code_viewer.scss | 0 .../src}/components/guide_code_viewer/guide_code_viewer.jsx | 0 .../src}/components/guide_example/_guide_example.scss | 0 .../src}/components/guide_example/guide_example.jsx | 0 .../src}/components/guide_nav/_guide_nav.scss | 0 .../src}/components/guide_nav/guide_nav.jsx | 0 .../src}/components/guide_page/_guide_page.scss | 0 .../src}/components/guide_page/guide_page.jsx | 0 .../components/guide_page_section/_guide_page_section.scss | 0 .../components/guide_page_section/guide_page_section.jsx | 0 .../guide_page_side_nav/_guide_page_side_nav.scss | 0 .../components/guide_page_side_nav/guide_page_side_nav.jsx | 0 .../guide_page_side_nav/guide_page_side_nav_item.jsx | 0 .../{src/guide => doc_site/src}/components/index.js | 0 src/ui_framework/{src/guide => doc_site/src}/index.js | 0 src/ui_framework/{src/guide => doc_site/src}/main.scss | 2 +- .../src}/services/example/createExample.js | 0 .../{src/guide => doc_site/src}/services/index.js | 0 .../src}/services/js_injector/js_injector.js | 0 .../{src/guide => doc_site/src}/services/routes/Routes.js | 0 .../{src/guide => doc_site/src}/services/string/slugify.js | 0 .../{src/guide => doc_site/src}/store/configure_store.js | 0 .../src}/store/reducers/code_viewer_reducer.js | 0 src/ui_framework/{src/guide => doc_site/src}/variables.scss | 0 .../{src/guide => doc_site/src}/views/_app.scss | 0 .../{src/guide => doc_site/src}/views/app_container.js | 0 .../{src/guide => doc_site/src}/views/app_view.jsx | 0 .../{src/guide => doc_site/src}/views/home/_home_view.scss | 0 .../{src/guide => doc_site/src}/views/home/home_view.jsx | 0 .../local_nav_breadcrumbs/local_nav_breadcrumbs.html | 0 .../local_nav/local_nav_dropdown/local_nav_dropdown.html | 0 .../local_nav_dropdown_panels.html | 0 .../src}/views/local_nav/local_nav_example.jsx | 0 .../local_nav_menu_item_states.html | 0 .../views/local_nav/local_nav_search/local_nav_search.html | 0 .../local_nav_search_error/local_nav_search_error.html | 0 .../views/local_nav/local_nav_simple/local_nav_simple.html | 0 .../src}/views/local_nav/local_nav_tabs/local_nav_tabs.html | 0 .../src}/views/not_found/not_found_view.jsx | 0 src/ui_framework/{ => doc_site}/webpack.config.js | 6 +++--- 56 files changed, 9 insertions(+), 9 deletions(-) rename src/ui_framework/{src/framework/framework.scss => components/index.scss} (94%) rename src/ui_framework/{src/framework => }/components/local_nav/_index.scss (100%) rename src/ui_framework/{src/framework => }/components/local_nav/_local_breadcrumbs.scss (100%) rename src/ui_framework/{src/framework => }/components/local_nav/_local_dropdown.scss (100%) rename src/ui_framework/{src/framework => }/components/local_nav/_local_menu.scss (100%) rename src/ui_framework/{src/framework => }/components/local_nav/_local_nav.scss (100%) rename src/ui_framework/{src/framework => }/components/local_nav/_local_search.scss (100%) rename src/ui_framework/{src/framework => }/components/local_nav/_local_tabs.scss (100%) rename src/ui_framework/{src/framework => }/components/local_nav/_local_title.scss (100%) rename src/ui_framework/{public => doc_site/build}/index.html (100%) rename src/ui_framework/{src/guide => doc_site/src}/actions/action_types.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/actions/code_viewer/code_viewer_actions.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/actions/index.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_code_viewer/_guide_code_viewer.scss (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_code_viewer/guide_code_viewer.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_example/_guide_example.scss (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_example/guide_example.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_nav/_guide_nav.scss (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_nav/guide_nav.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_page/_guide_page.scss (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_page/guide_page.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_page_section/_guide_page_section.scss (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_page_section/guide_page_section.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_page_side_nav/_guide_page_side_nav.scss (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_page_side_nav/guide_page_side_nav.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/guide_page_side_nav/guide_page_side_nav_item.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/components/index.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/index.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/main.scss (94%) rename src/ui_framework/{src/guide => doc_site/src}/services/example/createExample.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/services/index.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/services/js_injector/js_injector.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/services/routes/Routes.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/services/string/slugify.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/store/configure_store.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/store/reducers/code_viewer_reducer.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/variables.scss (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/_app.scss (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/app_container.js (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/app_view.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/home/_home_view.scss (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/home/home_view.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/local_nav/local_nav_breadcrumbs/local_nav_breadcrumbs.html (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/local_nav/local_nav_dropdown/local_nav_dropdown.html (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/local_nav/local_nav_example.jsx (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/local_nav/local_nav_menu_item_states/local_nav_menu_item_states.html (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/local_nav/local_nav_search/local_nav_search.html (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/local_nav/local_nav_search_error/local_nav_search_error.html (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/local_nav/local_nav_simple/local_nav_simple.html (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/local_nav/local_nav_tabs/local_nav_tabs.html (100%) rename src/ui_framework/{src/guide => doc_site/src}/views/not_found/not_found_view.jsx (100%) rename src/ui_framework/{ => doc_site}/webpack.config.js (75%) diff --git a/.gitignore b/.gitignore index 26c3f0d95c384..832681095db09 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,4 @@ selenium *.swp *.swo *.out -src/ui_framework/public/*.js* +src/ui_framework/doc_site/build/*.js* diff --git a/package.json b/package.json index 72fde84d5e0cf..7878b2c4203e1 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "mocha": "mocha", "mocha:debug": "mocha --debug-brk", "sterilize": "grunt sterilize", - "uiFramework:start": "./node_modules/.bin/webpack-dev-server --config src/ui_framework/webpack.config.js --hot --inline --content-base src/ui_framework/public/" + "uiFramework:start": "webpack-dev-server --config src/ui_framework/doc_site/webpack.config.js --hot --inline --content-base src/ui_framework/doc_site/build" }, "repository": { "type": "git", @@ -92,6 +92,7 @@ "babel": "5.8.38", "babel-core": "5.8.38", "babel-loader": "5.3.2", + "babel-polyfill": "6.9.1", "babel-runtime": "5.8.38", "bluebird": "2.9.34", "body-parser": "1.12.0", @@ -218,7 +219,6 @@ "nock": "8.0.0", "node-sass": "3.8.0", "npm": "3.10.8", - "numeral": "1.5.3", "portscanner": "1.0.0", "proxyquire": "1.7.10", "react": "15.2.0", diff --git a/src/ui/public/autoload/styles.js b/src/ui/public/autoload/styles.js index a74b7333066c7..e1329e49ffb99 100644 --- a/src/ui/public/autoload/styles.js +++ b/src/ui/public/autoload/styles.js @@ -1,5 +1,5 @@ // Kibana UI Framework -require('../../../ui_framework/src/framework/framework.scss'); +require('../../../ui_framework/components/index.scss'); // All Kibana styles inside of the /styles dir const context = require.context('../styles', false, /[\/\\](?!mixins|variables|_|\.)[^\/\\]+\.less/); diff --git a/src/ui_framework/src/framework/framework.scss b/src/ui_framework/components/index.scss similarity index 94% rename from src/ui_framework/src/framework/framework.scss rename to src/ui_framework/components/index.scss index 654d23084512c..8eaa3ef6bea93 100644 --- a/src/ui_framework/src/framework/framework.scss +++ b/src/ui_framework/components/index.scss @@ -24,4 +24,4 @@ $inputBorderColor--darkTheme: $inputBackgroundColor--darkTheme; } } -@import "components/local_nav/index"; +@import "local_nav/index"; diff --git a/src/ui_framework/src/framework/components/local_nav/_index.scss b/src/ui_framework/components/local_nav/_index.scss similarity index 100% rename from src/ui_framework/src/framework/components/local_nav/_index.scss rename to src/ui_framework/components/local_nav/_index.scss diff --git a/src/ui_framework/src/framework/components/local_nav/_local_breadcrumbs.scss b/src/ui_framework/components/local_nav/_local_breadcrumbs.scss similarity index 100% rename from src/ui_framework/src/framework/components/local_nav/_local_breadcrumbs.scss rename to src/ui_framework/components/local_nav/_local_breadcrumbs.scss diff --git a/src/ui_framework/src/framework/components/local_nav/_local_dropdown.scss b/src/ui_framework/components/local_nav/_local_dropdown.scss similarity index 100% rename from src/ui_framework/src/framework/components/local_nav/_local_dropdown.scss rename to src/ui_framework/components/local_nav/_local_dropdown.scss diff --git a/src/ui_framework/src/framework/components/local_nav/_local_menu.scss b/src/ui_framework/components/local_nav/_local_menu.scss similarity index 100% rename from src/ui_framework/src/framework/components/local_nav/_local_menu.scss rename to src/ui_framework/components/local_nav/_local_menu.scss diff --git a/src/ui_framework/src/framework/components/local_nav/_local_nav.scss b/src/ui_framework/components/local_nav/_local_nav.scss similarity index 100% rename from src/ui_framework/src/framework/components/local_nav/_local_nav.scss rename to src/ui_framework/components/local_nav/_local_nav.scss diff --git a/src/ui_framework/src/framework/components/local_nav/_local_search.scss b/src/ui_framework/components/local_nav/_local_search.scss similarity index 100% rename from src/ui_framework/src/framework/components/local_nav/_local_search.scss rename to src/ui_framework/components/local_nav/_local_search.scss diff --git a/src/ui_framework/src/framework/components/local_nav/_local_tabs.scss b/src/ui_framework/components/local_nav/_local_tabs.scss similarity index 100% rename from src/ui_framework/src/framework/components/local_nav/_local_tabs.scss rename to src/ui_framework/components/local_nav/_local_tabs.scss diff --git a/src/ui_framework/src/framework/components/local_nav/_local_title.scss b/src/ui_framework/components/local_nav/_local_title.scss similarity index 100% rename from src/ui_framework/src/framework/components/local_nav/_local_title.scss rename to src/ui_framework/components/local_nav/_local_title.scss diff --git a/src/ui_framework/public/index.html b/src/ui_framework/doc_site/build/index.html similarity index 100% rename from src/ui_framework/public/index.html rename to src/ui_framework/doc_site/build/index.html diff --git a/src/ui_framework/src/guide/actions/action_types.js b/src/ui_framework/doc_site/src/actions/action_types.js similarity index 100% rename from src/ui_framework/src/guide/actions/action_types.js rename to src/ui_framework/doc_site/src/actions/action_types.js diff --git a/src/ui_framework/src/guide/actions/code_viewer/code_viewer_actions.js b/src/ui_framework/doc_site/src/actions/code_viewer/code_viewer_actions.js similarity index 100% rename from src/ui_framework/src/guide/actions/code_viewer/code_viewer_actions.js rename to src/ui_framework/doc_site/src/actions/code_viewer/code_viewer_actions.js diff --git a/src/ui_framework/src/guide/actions/index.js b/src/ui_framework/doc_site/src/actions/index.js similarity index 100% rename from src/ui_framework/src/guide/actions/index.js rename to src/ui_framework/doc_site/src/actions/index.js diff --git a/src/ui_framework/src/guide/components/guide_code_viewer/_guide_code_viewer.scss b/src/ui_framework/doc_site/src/components/guide_code_viewer/_guide_code_viewer.scss similarity index 100% rename from src/ui_framework/src/guide/components/guide_code_viewer/_guide_code_viewer.scss rename to src/ui_framework/doc_site/src/components/guide_code_viewer/_guide_code_viewer.scss diff --git a/src/ui_framework/src/guide/components/guide_code_viewer/guide_code_viewer.jsx b/src/ui_framework/doc_site/src/components/guide_code_viewer/guide_code_viewer.jsx similarity index 100% rename from src/ui_framework/src/guide/components/guide_code_viewer/guide_code_viewer.jsx rename to src/ui_framework/doc_site/src/components/guide_code_viewer/guide_code_viewer.jsx diff --git a/src/ui_framework/src/guide/components/guide_example/_guide_example.scss b/src/ui_framework/doc_site/src/components/guide_example/_guide_example.scss similarity index 100% rename from src/ui_framework/src/guide/components/guide_example/_guide_example.scss rename to src/ui_framework/doc_site/src/components/guide_example/_guide_example.scss diff --git a/src/ui_framework/src/guide/components/guide_example/guide_example.jsx b/src/ui_framework/doc_site/src/components/guide_example/guide_example.jsx similarity index 100% rename from src/ui_framework/src/guide/components/guide_example/guide_example.jsx rename to src/ui_framework/doc_site/src/components/guide_example/guide_example.jsx diff --git a/src/ui_framework/src/guide/components/guide_nav/_guide_nav.scss b/src/ui_framework/doc_site/src/components/guide_nav/_guide_nav.scss similarity index 100% rename from src/ui_framework/src/guide/components/guide_nav/_guide_nav.scss rename to src/ui_framework/doc_site/src/components/guide_nav/_guide_nav.scss diff --git a/src/ui_framework/src/guide/components/guide_nav/guide_nav.jsx b/src/ui_framework/doc_site/src/components/guide_nav/guide_nav.jsx similarity index 100% rename from src/ui_framework/src/guide/components/guide_nav/guide_nav.jsx rename to src/ui_framework/doc_site/src/components/guide_nav/guide_nav.jsx diff --git a/src/ui_framework/src/guide/components/guide_page/_guide_page.scss b/src/ui_framework/doc_site/src/components/guide_page/_guide_page.scss similarity index 100% rename from src/ui_framework/src/guide/components/guide_page/_guide_page.scss rename to src/ui_framework/doc_site/src/components/guide_page/_guide_page.scss diff --git a/src/ui_framework/src/guide/components/guide_page/guide_page.jsx b/src/ui_framework/doc_site/src/components/guide_page/guide_page.jsx similarity index 100% rename from src/ui_framework/src/guide/components/guide_page/guide_page.jsx rename to src/ui_framework/doc_site/src/components/guide_page/guide_page.jsx diff --git a/src/ui_framework/src/guide/components/guide_page_section/_guide_page_section.scss b/src/ui_framework/doc_site/src/components/guide_page_section/_guide_page_section.scss similarity index 100% rename from src/ui_framework/src/guide/components/guide_page_section/_guide_page_section.scss rename to src/ui_framework/doc_site/src/components/guide_page_section/_guide_page_section.scss diff --git a/src/ui_framework/src/guide/components/guide_page_section/guide_page_section.jsx b/src/ui_framework/doc_site/src/components/guide_page_section/guide_page_section.jsx similarity index 100% rename from src/ui_framework/src/guide/components/guide_page_section/guide_page_section.jsx rename to src/ui_framework/doc_site/src/components/guide_page_section/guide_page_section.jsx diff --git a/src/ui_framework/src/guide/components/guide_page_side_nav/_guide_page_side_nav.scss b/src/ui_framework/doc_site/src/components/guide_page_side_nav/_guide_page_side_nav.scss similarity index 100% rename from src/ui_framework/src/guide/components/guide_page_side_nav/_guide_page_side_nav.scss rename to src/ui_framework/doc_site/src/components/guide_page_side_nav/_guide_page_side_nav.scss diff --git a/src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav.jsx b/src/ui_framework/doc_site/src/components/guide_page_side_nav/guide_page_side_nav.jsx similarity index 100% rename from src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav.jsx rename to src/ui_framework/doc_site/src/components/guide_page_side_nav/guide_page_side_nav.jsx diff --git a/src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav_item.jsx b/src/ui_framework/doc_site/src/components/guide_page_side_nav/guide_page_side_nav_item.jsx similarity index 100% rename from src/ui_framework/src/guide/components/guide_page_side_nav/guide_page_side_nav_item.jsx rename to src/ui_framework/doc_site/src/components/guide_page_side_nav/guide_page_side_nav_item.jsx diff --git a/src/ui_framework/src/guide/components/index.js b/src/ui_framework/doc_site/src/components/index.js similarity index 100% rename from src/ui_framework/src/guide/components/index.js rename to src/ui_framework/doc_site/src/components/index.js diff --git a/src/ui_framework/src/guide/index.js b/src/ui_framework/doc_site/src/index.js similarity index 100% rename from src/ui_framework/src/guide/index.js rename to src/ui_framework/doc_site/src/index.js diff --git a/src/ui_framework/src/guide/main.scss b/src/ui_framework/doc_site/src/main.scss similarity index 94% rename from src/ui_framework/src/guide/main.scss rename to src/ui_framework/doc_site/src/main.scss index 402ed577735b4..c20b7457ae37c 100644 --- a/src/ui_framework/src/guide/main.scss +++ b/src/ui_framework/doc_site/src/main.scss @@ -1,5 +1,5 @@ -@import "../framework/framework"; +@import "../../components/index"; @import "./views/app"; @import "./components/guide_code_viewer/guide_code_viewer"; @import "./components/guide_nav/guide_nav"; diff --git a/src/ui_framework/src/guide/services/example/createExample.js b/src/ui_framework/doc_site/src/services/example/createExample.js similarity index 100% rename from src/ui_framework/src/guide/services/example/createExample.js rename to src/ui_framework/doc_site/src/services/example/createExample.js diff --git a/src/ui_framework/src/guide/services/index.js b/src/ui_framework/doc_site/src/services/index.js similarity index 100% rename from src/ui_framework/src/guide/services/index.js rename to src/ui_framework/doc_site/src/services/index.js diff --git a/src/ui_framework/src/guide/services/js_injector/js_injector.js b/src/ui_framework/doc_site/src/services/js_injector/js_injector.js similarity index 100% rename from src/ui_framework/src/guide/services/js_injector/js_injector.js rename to src/ui_framework/doc_site/src/services/js_injector/js_injector.js diff --git a/src/ui_framework/src/guide/services/routes/Routes.js b/src/ui_framework/doc_site/src/services/routes/Routes.js similarity index 100% rename from src/ui_framework/src/guide/services/routes/Routes.js rename to src/ui_framework/doc_site/src/services/routes/Routes.js diff --git a/src/ui_framework/src/guide/services/string/slugify.js b/src/ui_framework/doc_site/src/services/string/slugify.js similarity index 100% rename from src/ui_framework/src/guide/services/string/slugify.js rename to src/ui_framework/doc_site/src/services/string/slugify.js diff --git a/src/ui_framework/src/guide/store/configure_store.js b/src/ui_framework/doc_site/src/store/configure_store.js similarity index 100% rename from src/ui_framework/src/guide/store/configure_store.js rename to src/ui_framework/doc_site/src/store/configure_store.js diff --git a/src/ui_framework/src/guide/store/reducers/code_viewer_reducer.js b/src/ui_framework/doc_site/src/store/reducers/code_viewer_reducer.js similarity index 100% rename from src/ui_framework/src/guide/store/reducers/code_viewer_reducer.js rename to src/ui_framework/doc_site/src/store/reducers/code_viewer_reducer.js diff --git a/src/ui_framework/src/guide/variables.scss b/src/ui_framework/doc_site/src/variables.scss similarity index 100% rename from src/ui_framework/src/guide/variables.scss rename to src/ui_framework/doc_site/src/variables.scss diff --git a/src/ui_framework/src/guide/views/_app.scss b/src/ui_framework/doc_site/src/views/_app.scss similarity index 100% rename from src/ui_framework/src/guide/views/_app.scss rename to src/ui_framework/doc_site/src/views/_app.scss diff --git a/src/ui_framework/src/guide/views/app_container.js b/src/ui_framework/doc_site/src/views/app_container.js similarity index 100% rename from src/ui_framework/src/guide/views/app_container.js rename to src/ui_framework/doc_site/src/views/app_container.js diff --git a/src/ui_framework/src/guide/views/app_view.jsx b/src/ui_framework/doc_site/src/views/app_view.jsx similarity index 100% rename from src/ui_framework/src/guide/views/app_view.jsx rename to src/ui_framework/doc_site/src/views/app_view.jsx diff --git a/src/ui_framework/src/guide/views/home/_home_view.scss b/src/ui_framework/doc_site/src/views/home/_home_view.scss similarity index 100% rename from src/ui_framework/src/guide/views/home/_home_view.scss rename to src/ui_framework/doc_site/src/views/home/_home_view.scss diff --git a/src/ui_framework/src/guide/views/home/home_view.jsx b/src/ui_framework/doc_site/src/views/home/home_view.jsx similarity index 100% rename from src/ui_framework/src/guide/views/home/home_view.jsx rename to src/ui_framework/doc_site/src/views/home/home_view.jsx diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_breadcrumbs/local_nav_breadcrumbs.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_breadcrumbs/local_nav_breadcrumbs.html similarity index 100% rename from src/ui_framework/src/guide/views/local_nav/local_nav_breadcrumbs/local_nav_breadcrumbs.html rename to src/ui_framework/doc_site/src/views/local_nav/local_nav_breadcrumbs/local_nav_breadcrumbs.html diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_dropdown/local_nav_dropdown.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown/local_nav_dropdown.html similarity index 100% rename from src/ui_framework/src/guide/views/local_nav/local_nav_dropdown/local_nav_dropdown.html rename to src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown/local_nav_dropdown.html diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html similarity index 100% rename from src/ui_framework/src/guide/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html rename to src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_example.jsx b/src/ui_framework/doc_site/src/views/local_nav/local_nav_example.jsx similarity index 100% rename from src/ui_framework/src/guide/views/local_nav/local_nav_example.jsx rename to src/ui_framework/doc_site/src/views/local_nav/local_nav_example.jsx diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_menu_item_states/local_nav_menu_item_states.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_menu_item_states/local_nav_menu_item_states.html similarity index 100% rename from src/ui_framework/src/guide/views/local_nav/local_nav_menu_item_states/local_nav_menu_item_states.html rename to src/ui_framework/doc_site/src/views/local_nav/local_nav_menu_item_states/local_nav_menu_item_states.html diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_search/local_nav_search.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_search/local_nav_search.html similarity index 100% rename from src/ui_framework/src/guide/views/local_nav/local_nav_search/local_nav_search.html rename to src/ui_framework/doc_site/src/views/local_nav/local_nav_search/local_nav_search.html diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_search_error/local_nav_search_error.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_search_error/local_nav_search_error.html similarity index 100% rename from src/ui_framework/src/guide/views/local_nav/local_nav_search_error/local_nav_search_error.html rename to src/ui_framework/doc_site/src/views/local_nav/local_nav_search_error/local_nav_search_error.html diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_simple/local_nav_simple.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_simple/local_nav_simple.html similarity index 100% rename from src/ui_framework/src/guide/views/local_nav/local_nav_simple/local_nav_simple.html rename to src/ui_framework/doc_site/src/views/local_nav/local_nav_simple/local_nav_simple.html diff --git a/src/ui_framework/src/guide/views/local_nav/local_nav_tabs/local_nav_tabs.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_tabs/local_nav_tabs.html similarity index 100% rename from src/ui_framework/src/guide/views/local_nav/local_nav_tabs/local_nav_tabs.html rename to src/ui_framework/doc_site/src/views/local_nav/local_nav_tabs/local_nav_tabs.html diff --git a/src/ui_framework/src/guide/views/not_found/not_found_view.jsx b/src/ui_framework/doc_site/src/views/not_found/not_found_view.jsx similarity index 100% rename from src/ui_framework/src/guide/views/not_found/not_found_view.jsx rename to src/ui_framework/doc_site/src/views/not_found/not_found_view.jsx diff --git a/src/ui_framework/webpack.config.js b/src/ui_framework/doc_site/webpack.config.js similarity index 75% rename from src/ui_framework/webpack.config.js rename to src/ui_framework/doc_site/webpack.config.js index 58f35bd49ba19..b5d7fcb3018ab 100644 --- a/src/ui_framework/webpack.config.js +++ b/src/ui_framework/doc_site/webpack.config.js @@ -4,17 +4,17 @@ module.exports = { devtool: 'source-map', entry: { - guide: './src/ui_framework/src/guide/index.js' + guide: './src/ui_framework/doc_site/src/index.js' }, output: { - path: path.resolve(__dirname, 'src/ui_framework/public'), + path: path.resolve(__dirname, 'src/ui_framework/doc_site/build'), filename: 'bundle.js' }, resolve: { root: [ - path.resolve(__dirname, 'src/ui_framework/src') + path.resolve(__dirname, 'src/ui_framework/doc_site') ] }, From 43854bccc4312c63a7243d8309cdda802530f4ab Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Mon, 5 Dec 2016 15:47:42 -0800 Subject: [PATCH 3/5] Remove babel-polyfill. --- package.json | 1 - src/ui_framework/doc_site/src/index.js | 1 - 2 files changed, 2 deletions(-) diff --git a/package.json b/package.json index 7878b2c4203e1..05650e6f26268 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,6 @@ "babel": "5.8.38", "babel-core": "5.8.38", "babel-loader": "5.3.2", - "babel-polyfill": "6.9.1", "babel-runtime": "5.8.38", "bluebird": "2.9.34", "body-parser": "1.12.0", diff --git a/src/ui_framework/doc_site/src/index.js b/src/ui_framework/doc_site/src/index.js index ca17c966eacd7..a68210b67c3d0 100644 --- a/src/ui_framework/doc_site/src/index.js +++ b/src/ui_framework/doc_site/src/index.js @@ -1,6 +1,5 @@ require('./main.scss'); -import 'babel-polyfill'; import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; From fe5bab1d81af843e997027db8eb76e45be5a28f7 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Fri, 9 Dec 2016 16:33:17 -0800 Subject: [PATCH 4/5] Fix typos and include SCSS synchronously. --- src/optimize/base_optimizer.js | 5 ++++- src/ui_framework/README.md | 2 +- .../doc_site/src/services/example/createExample.js | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js index c63c2cf836a8d..8c0ac81b1361e 100644 --- a/src/optimize/base_optimizer.js +++ b/src/optimize/base_optimizer.js @@ -110,7 +110,10 @@ class BaseOptimizer { }, { test: /\.scss$/, - loaders: ['style', 'css', 'sass'], + loader: ExtractTextPlugin.extract( + 'style', + `css${mapQ}!autoprefixer${mapQPre}{ "browsers": ["last 2 versions","> 5%"] }!sass${mapQPre}` + ) }, { test: /\.css$/, loader: ExtractTextPlugin.extract('style', `css${mapQ}`) }, { test: /\.jade$/, loader: 'jade' }, diff --git a/src/ui_framework/README.md b/src/ui_framework/README.md index bbfd577dc138f..7e14e71c45ce3 100644 --- a/src/ui_framework/README.md +++ b/src/ui_framework/README.md @@ -35,7 +35,7 @@ By covering our UI components with great unit tests and having those tests live In short: we've outgrown it! Third-party CSS frameworks like Bootstrap and Foundation are designed for a general audience, so they offer things we don't need and _don't_ offer things we _do_ need. -As a result, we've forced to override their styles until the original framework is no longer +As a result, we've been forced to override their styles until the original framework is no longer recognizable. When the CSS reaches that point, it's time to take ownership over it and build your own framework. diff --git a/src/ui_framework/doc_site/src/services/example/createExample.js b/src/ui_framework/doc_site/src/services/example/createExample.js index 3a0a47fc9f9c0..185b0ec908162 100644 --- a/src/ui_framework/doc_site/src/services/example/createExample.js +++ b/src/ui_framework/doc_site/src/services/example/createExample.js @@ -3,7 +3,7 @@ import { GuideExample, } from '../../components'; -export default function creatExample(examples) { +export default function createExample(examples) { class Example extends GuideExample { constructor(props) { super(props, examples); From a44140a59d066ef735a184dbf8d4b72db4f9b048 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Mon, 12 Dec 2016 17:47:09 -0800 Subject: [PATCH 5/5] Update with latest changes to UI Framework. --- .../local_nav/_local_breadcrumbs.scss | 6 ++++- .../components/local_nav/_local_dropdown.scss | 23 +++++++++++++++++++ .../components/local_nav/_local_menu.scss | 13 ++++++++++- .../local_nav_dropdown.html | 5 ++++ .../local_nav_dropdown_panels.html | 5 ++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/ui_framework/components/local_nav/_local_breadcrumbs.scss b/src/ui_framework/components/local_nav/_local_breadcrumbs.scss index 2708ba26648b0..16d8bd834f5da 100644 --- a/src/ui_framework/components/local_nav/_local_breadcrumbs.scss +++ b/src/ui_framework/components/local_nav/_local_breadcrumbs.scss @@ -28,8 +28,12 @@ &:last-child { .localBreadcrumb__link { - pointer-events: none; color: $localNavTextColor; + cursor: default; + + &:hover { + text-decoration: none; + } @include darkTheme { color: $localNavTextColor--darkTheme; diff --git a/src/ui_framework/components/local_nav/_local_dropdown.scss b/src/ui_framework/components/local_nav/_local_dropdown.scss index 40f3ec635345b..53728b4e8f502 100644 --- a/src/ui_framework/components/local_nav/_local_dropdown.scss +++ b/src/ui_framework/components/local_nav/_local_dropdown.scss @@ -1,5 +1,6 @@ .localDropdown { + position: relative; padding: 10px $localNavSideSpacing 14px; background-color: $localDropdownBackgroundColor; line-height: 20px; @@ -9,6 +10,28 @@ } } +.localDropdownCloseButton { + appearance: none; + background-color: transparent; + padding: 4px; + border: none; + position: absolute; + top: 1px; + right: 5px; + font-size: 16px; + color: $localNavTextColor; + cursor: pointer; + opacity: 0.35; + + &:hover { + opacity: 1; + } + + @include darkTheme { + color: $localNavTextColor--darkTheme; + } +} + .localDropdownPanels { display: flex; } diff --git a/src/ui_framework/components/local_nav/_local_menu.scss b/src/ui_framework/components/local_nav/_local_menu.scss index da1803374f0a1..45c9c0a6e728a 100644 --- a/src/ui_framework/components/local_nav/_local_menu.scss +++ b/src/ui_framework/components/local_nav/_local_menu.scss @@ -28,7 +28,11 @@ &.localMenuItem-isDisabled { opacity: 0.5; cursor: default; - pointer-events: none; + + &:hover { + background-color: $localNavButtonBackgroundColor; + color: $localNavButtonTextColor; + } } @include darkTheme { @@ -42,6 +46,13 @@ &.localMenuItem-isSelected { background-color: $localNavButtonBackgroundColor-isSelected--darkTheme; } + + &.localMenuItem-isDisabled { + &:hover { + background-color: transparent; + color: $localNavButtonTextColor--darkTheme; + } + } } } diff --git a/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown/local_nav_dropdown.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown/local_nav_dropdown.html index 87e486d2eb5bf..ec39fbe1fd214 100644 --- a/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown/local_nav_dropdown.html +++ b/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown/local_nav_dropdown.html @@ -40,6 +40,11 @@
+ + +
Dropdown title
diff --git a/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html b/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html index 1a1458fb62666..abc628ad178b3 100644 --- a/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html +++ b/src/ui_framework/doc_site/src/views/local_nav/local_nav_dropdown_panels/local_nav_dropdown_panels.html @@ -40,6 +40,11 @@
+ + +