diff --git a/ui_framework/doc_site/src/actions/action_types.js b/ui_framework/doc_site/src/actions/action_types.js
index b288e7b0edbed..66ef2b2afcd5f 100644
--- a/ui_framework/doc_site/src/actions/action_types.js
+++ b/ui_framework/doc_site/src/actions/action_types.js
@@ -7,6 +7,10 @@ export default keyMirror({
OPEN_CODE_VIEWER: null,
CLOSE_CODE_VIEWER: null,
+ // Sandbox actions
+ OPEN_SANDBOX: null,
+ CLOSE_SANDBOX: null,
+
// Example nav actions
REGISTER_SECTION: null,
UNREGISTER_SECTION: null,
diff --git a/ui_framework/doc_site/src/actions/index.js b/ui_framework/doc_site/src/actions/index.js
index 310bc91f2755e..9517d850e4a2b 100644
--- a/ui_framework/doc_site/src/actions/index.js
+++ b/ui_framework/doc_site/src/actions/index.js
@@ -3,6 +3,11 @@ export {
closeCodeViewer,
} from './code_viewer_actions';
+export {
+ openSandbox,
+ closeSandbox,
+} from './sandbox_actions';
+
export {
registerSection,
unregisterSection,
diff --git a/ui_framework/doc_site/src/actions/sandbox_actions.js b/ui_framework/doc_site/src/actions/sandbox_actions.js
new file mode 100644
index 0000000000000..33b7e345f717d
--- /dev/null
+++ b/ui_framework/doc_site/src/actions/sandbox_actions.js
@@ -0,0 +1,9 @@
+import ActionTypes from './action_types';
+
+export const openSandbox = () => ({
+ type: ActionTypes.OPEN_SANDBOX,
+});
+
+export const closeSandbox = () => ({
+ type: ActionTypes.CLOSE_SANDBOX,
+});
diff --git a/ui_framework/doc_site/src/components/guide/_guide.scss b/ui_framework/doc_site/src/components/guide/_guide.scss
index fa35e61ca0a9a..3c292e01fedbd 100644
--- a/ui_framework/doc_site/src/components/guide/_guide.scss
+++ b/ui_framework/doc_site/src/components/guide/_guide.scss
@@ -25,6 +25,7 @@ html {
padding-top: $guideNavHeight;
background-color: $guideBaseBackgroundColor;
transition:
+ padding-top $guideChromeTransition,
padding-right $guideCodeViewerTransition,
opacity $guideCodeViewerTransition;
@@ -39,6 +40,10 @@ html {
.is-guide-nav-open + & {
opacity: 0.7;
}
+
+ &.is-chrome-hidden {
+ padding-top: 0;
+ }
}
@media only screen and (max-width: 1300px) {
diff --git a/ui_framework/doc_site/src/components/guide_components.scss b/ui_framework/doc_site/src/components/guide_components.scss
index 848ed12549e47..450e357978fca 100644
--- a/ui_framework/doc_site/src/components/guide_components.scss
+++ b/ui_framework/doc_site/src/components/guide_components.scss
@@ -6,6 +6,7 @@ $guideSideNavSmallWidth: 220px;
$guideCodeViewerWidth: 660px;
$guideCodeViewerSmallWidth: 520px;
$guideCodeViewerTransition: 0.2s ease;
+$guideChromeTransition: 0.3s ease;
// Colors
$guideBaseBackgroundColor: #f7f7f7;
diff --git a/ui_framework/doc_site/src/components/guide_nav/_guide_nav.scss b/ui_framework/doc_site/src/components/guide_nav/_guide_nav.scss
index f5723dc21364d..205961c15f43d 100644
--- a/ui_framework/doc_site/src/components/guide_nav/_guide_nav.scss
+++ b/ui_framework/doc_site/src/components/guide_nav/_guide_nav.scss
@@ -11,7 +11,10 @@
border-bottom: 1px solid #CCCCCC;
color: $guideTextColor;
background-color: $guidePanelBackgroundColor;
- transition: height 0.3s ease, box-shadow 0.3s linear;
+ transition:
+ top $guideChromeTransition,
+ height 0.3s ease,
+ box-shadow 0.3s linear;
overflow: hidden;
box-shadow: 0 0 0 rgba(black, 0.3);
@@ -19,8 +22,26 @@
height: 100%;
box-shadow: 0 40px 200px rgba(black, 0.05);
}
+
+ &.is-chrome-hidden {
+ top: -$guideNavHeight;
+ }
}
+ .guideNav__showButton {
+ position: fixed;
+ z-index: 9999;
+ top: 5px;
+ right: 5px;
+ font-size: 10px;
+ opacity: 0;
+ transition: opacity $guideChromeTransition;
+
+ .is-chrome-hidden & {
+ opacity: 1;
+ }
+ }
+
.guideNav__header {
position: relative;
flex: 0 0 auto;
diff --git a/ui_framework/doc_site/src/components/guide_nav/guide_nav.js b/ui_framework/doc_site/src/components/guide_nav/guide_nav.js
index da8c0f7c56f35..512d0430d9fd3 100644
--- a/ui_framework/doc_site/src/components/guide_nav/guide_nav.js
+++ b/ui_framework/doc_site/src/components/guide_nav/guide_nav.js
@@ -78,8 +78,23 @@ export class GuideNav extends Component {
);
+ let hideChromeButton;
+
+ if (this.props.isSandbox) {
+ hideChromeButton = (
+
+ );
+ }
+
return (
+ {hideChromeButton}
{previousButton}
{nextButton}
@@ -89,6 +104,7 @@ export class GuideNav extends Component {
render() {
const classes = classNames('guideNav', {
'is-guide-nav-open': this.props.isNavOpen,
+ 'is-chrome-hidden': !this.props.isChromeVisible,
});
const buttonClasses = classNames('guideNav__menu fa fa-bars', {
@@ -185,14 +201,25 @@ export class GuideNav extends Component {
{ sandboxNavItems.length ? sandboxNavItems : this.renderNoItems('sandboxes') }
+
+
);
}
}
GuideNav.propTypes = {
+ isChromeVisible: PropTypes.bool,
isNavOpen: PropTypes.bool,
+ isSandbox: PropTypes.bool,
onToggleNav: PropTypes.func,
+ onHideChrome: PropTypes.func,
+ onShowChrome: PropTypes.func,
onClickNavItem: PropTypes.func,
version: PropTypes.string,
routes: PropTypes.array,
diff --git a/ui_framework/doc_site/src/components/guide_sandbox/guide_sandbox.js b/ui_framework/doc_site/src/components/guide_sandbox/guide_sandbox.js
index b1cfdc8276c7c..ec9501f6c5563 100644
--- a/ui_framework/doc_site/src/components/guide_sandbox/guide_sandbox.js
+++ b/ui_framework/doc_site/src/components/guide_sandbox/guide_sandbox.js
@@ -1,7 +1,55 @@
-import React from 'react';
+import React, {
+ Component,
+} from 'react';
+import PropTypes from 'prop-types';
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
-export const GuideSandbox = props => (
-
- {props.children}
-
-);
+import {
+ getIsSandbox,
+} from '../../store';
+
+import {
+ openSandbox,
+ closeSandbox,
+} from '../../actions';
+
+function mapStateToProps(state) {
+ return {
+ isSandbox: getIsSandbox(state),
+ };
+}
+
+function mapDispatchToProps(dispatch) {
+ const actions = {
+ openSandbox,
+ closeSandbox,
+ };
+
+ return bindActionCreators(actions, dispatch);
+}
+
+class GuideSandboxComponent extends Component {
+ componentWillMount() {
+ this.props.openSandbox();
+ }
+
+ componentWillUnmount() {
+ this.props.closeSandbox();
+ }
+
+ render() {
+ return (
+
+ {this.props.children}
+
+ );
+ }
+}
+
+GuideSandboxComponent.propTypes = {
+ openSandbox: PropTypes.func,
+ closeSandbox: PropTypes.func,
+};
+
+export const GuideSandbox = connect(mapStateToProps, mapDispatchToProps)(GuideSandboxComponent);
diff --git a/ui_framework/doc_site/src/components/guide_section/_guide_section.scss b/ui_framework/doc_site/src/components/guide_section/_guide_section.scss
index be596398381af..280b0026172e4 100644
--- a/ui_framework/doc_site/src/components/guide_section/_guide_section.scss
+++ b/ui_framework/doc_site/src/components/guide_section/_guide_section.scss
@@ -25,9 +25,15 @@
border: 1px solid $guideLinkHoverColor;
border-radius: 3px;
cursor: pointer;
+ transform: translateX(0);
+ transition: transform $guideChromeTransition;
&:hover,
&:active {
background-color: #e6f7fc;
}
+
+ .is-chrome-hidden & {
+ transform: translateX(60px);
+ }
}
diff --git a/ui_framework/doc_site/src/store/configure_store.js b/ui_framework/doc_site/src/store/configure_store.js
index 8f6de34b6733b..b7160220345bf 100644
--- a/ui_framework/doc_site/src/store/configure_store.js
+++ b/ui_framework/doc_site/src/store/configure_store.js
@@ -11,6 +11,7 @@ import {
} from 'react-router-redux';
import codeViewerReducer from './reducers/code_viewer_reducer';
+import sandboxReducer from './reducers/sandbox_reducer';
import sectionsReducer from './reducers/sections_reducer';
/**
@@ -22,6 +23,7 @@ export default function configureStore(initialState) {
return {
routing: routerReducer(state.routing, action),
codeViewer: codeViewerReducer(state.codeViewer, action),
+ sandbox: sandboxReducer(state.sandbox, action),
sections: sectionsReducer(state.sections, action),
};
}
diff --git a/ui_framework/doc_site/src/store/index.js b/ui_framework/doc_site/src/store/index.js
index 0ab30476a2dbf..12be83f4b2374 100644
--- a/ui_framework/doc_site/src/store/index.js
+++ b/ui_framework/doc_site/src/store/index.js
@@ -2,6 +2,10 @@ export function getIsCodeViewerOpen(state) {
return state.codeViewer.isOpen;
}
+export function getIsSandbox(state) {
+ return state.sandbox.isSandbox;
+}
+
export function getSections(state) {
return state.sections.sections;
}
diff --git a/ui_framework/doc_site/src/store/reducers/sandbox_reducer.js b/ui_framework/doc_site/src/store/reducers/sandbox_reducer.js
new file mode 100644
index 0000000000000..6dd83497dc471
--- /dev/null
+++ b/ui_framework/doc_site/src/store/reducers/sandbox_reducer.js
@@ -0,0 +1,26 @@
+import ActionTypes from '../../actions/action_types';
+
+const defaultState = {
+ isSandbox: false,
+};
+
+export default function sandboxReducer(state = defaultState, action) {
+ switch (action.type) {
+ case ActionTypes.OPEN_SANDBOX: {
+ return Object.assign({}, state, {
+ isSandbox: true,
+ });
+ }
+
+ case ActionTypes.CLOSE_SANDBOX: {
+ return Object.assign({}, state, {
+ isSandbox: false,
+ });
+ }
+
+ default:
+ break;
+ }
+
+ return state;
+}
diff --git a/ui_framework/doc_site/src/views/app_container.js b/ui_framework/doc_site/src/views/app_container.js
index 5289c137567c1..e54a3412302b1 100644
--- a/ui_framework/doc_site/src/views/app_container.js
+++ b/ui_framework/doc_site/src/views/app_container.js
@@ -3,11 +3,14 @@ import { connect } from 'react-redux';
import {
getIsCodeViewerOpen,
+ getIsSandbox,
getSections,
getSource,
getTitle,
} from '../store';
+
import { AppView } from './app_view';
+
import {
openCodeViewer,
closeCodeViewer,
@@ -19,6 +22,7 @@ function mapStateToProps(state, ownProps) {
return {
routes: ownProps.routes,
isCodeViewerOpen: getIsCodeViewerOpen(state),
+ isSandbox: getIsSandbox(state),
source: getSource(state),
title: getTitle(state),
sections: getSections(state),
diff --git a/ui_framework/doc_site/src/views/app_view.js b/ui_framework/doc_site/src/views/app_view.js
index 3829153e1efd1..24616e55b7763 100644
--- a/ui_framework/doc_site/src/views/app_view.js
+++ b/ui_framework/doc_site/src/views/app_view.js
@@ -23,11 +23,14 @@ export class AppView extends Component {
this.state = {
isNavOpen: false,
+ isChromeVisible: !props.isSandbox,
};
this.onClickNavItem = this.onClickNavItem.bind(this);
this.onToggleNav = this.onToggleNav.bind(this);
this.onCloseCodeViewer = this.onCloseCodeViewer.bind(this);
+ this.onHideChrome = this.onHideChrome.bind(this);
+ this.onShowChrome = this.onShowChrome.bind(this);
}
onClickNavItem() {
@@ -46,15 +49,44 @@ export class AppView extends Component {
});
}
+ onHideChrome() {
+ this.setState({
+ isChromeVisible: false,
+ isNavOpen: false,
+ });
+
+ this.props.closeCodeViewer();
+ }
+
+ onShowChrome() {
+ this.setState({
+ isChromeVisible: true,
+ });
+ }
+
+ componentWillReceiveProps(nextProps) {
+ // Only force the chrome to be hidden if we're navigating from a non-sandbox to a sandbox.
+ if (!this.props.isSandbox && nextProps.isSandbox) {
+ this.setState({
+ isChromeVisible: false,
+ });
+ }
+ }
+
render() {
const contentClasses = classNames('guideContent', {
'is-code-viewer-open': this.props.isCodeViewerOpen,
+ 'is-chrome-hidden': !this.state.isChromeVisible,
});
return (
} from './<%= fileName %>';
+export {
+ <%= componentName %>,
+} from './<%= fileName %>';
diff --git a/ui_framework/generator-kui/component/templates/test.js b/ui_framework/generator-kui/component/templates/test.js
index aecd6497a73cb..4f384d6c2d3aa 100644
--- a/ui_framework/generator-kui/component/templates/test.js
+++ b/ui_framework/generator-kui/component/templates/test.js
@@ -7,7 +7,7 @@ import { <%= componentName %> } from './<%= fileName %>';
describe('<%= componentName %>', () => {
test('is rendered', () => {
const component = render(
- <<%= componentName %> { ...requiredProps } />
+ <<%= componentName %> {...requiredProps} />
);
expect(component)