Skip to content
This repository was archived by the owner on Jan 9, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/gui/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const App = () => {
return (
<div className={styles.layout} >
<Navbar />
<Workbench />
<Documentation />
<Workbench className={styles.main} />
<Documentation className={styles.main} />
</div>
)
}
Expand Down
7 changes: 6 additions & 1 deletion src/gui/app.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ const layout = css({
flexDirection: 'column',
})

export default { layout }
const main = css({
height: '100%',
overflow: 'hidden',
})

export default { layout, main }
2 changes: 1 addition & 1 deletion src/gui/components/navbar/navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Navbar.propTypes = {

Navbar.defaultProps = {
style: {},
className: '',
className: undefined,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we change all those defaultProps ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because in glamor#merge, falsy values are : false, null, undefined and {}.
'' is not considered as falsy.

}

export default Navbar
4 changes: 4 additions & 0 deletions src/gui/components/tabs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Tabs from './tabs'
import Tab from './tab'

export { Tabs, Tab }
27 changes: 27 additions & 0 deletions src/gui/components/tabs/tab.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react'
import PropTypes from 'prop-types'
import { merge } from 'glamor'

import styles from './tab.styles'

const Tab = ({ tabKey, title, className, children }) => {
return (
<div className={merge(styles.layout, className)} aria-hidden={tabKey} aria-label={title}>
{children}
</div>
)
}

Tab.propTypes = {
tabKey: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
children: PropTypes.oneOfType([PropTypes.node, PropTypes.array]),
}

Tab.defaultProps = {
children: '',
className: undefined,
}

export default Tab
10 changes: 10 additions & 0 deletions src/gui/components/tabs/tab.styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { css } from 'glamor'

const layout = css({
width: '100%',
height: '100%',
overflow: 'auto',
padding: '1em',
})

export default { layout }
58 changes: 58 additions & 0 deletions src/gui/components/tabs/tabs.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { merge } from 'glamor'

import TabsHeader from './tabsHeader'
import TabsAction from './tabsActions'
import styles from './tabs.styles'

class Tabs extends Component {
state = {
selected: this.props.defaultKey,
Copy link
Copy Markdown
Contributor

@fabienjuif fabienjuif Jul 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like that pattern.

  • we handle state in graphical components
  • parent give callback, + key to child that call the callback with key as parameter
  • we have a key, this is title we don't need to use index IMO.

at least, can't we create a curry version of handleSelectedTab ?

handleSelectedTab = (key) => () => {
  //...
}

// ...

titles={titles.map(title => <li {/* ... */} onClick={handleSelectedTab(title)}>{...}</li>)}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that you don't like inner state 😇

Otherwise, I give the index in that case, because title is a PropTypes.node (for example if I want to have an icon + label in my tab header). So titlecan't be a key, maybe I should add a Tab#tabKey prop.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#99

}

handleSelectedTab = (key) => {
this.setState(() => ({ selected: key }))
}

render() {
const { children, actions, className, actionsClassName, headersClassName } = this.props

const childArray = React.Children.toArray(children)
const headers = childArray.map(({ props }) => ({ tabKey: props.tabKey, title: props.title }))
const selected = this.state.selected || headers[0].tabKey
const tab = childArray.find(c => c.props.tabKey === selected)

return (
<div className={merge(styles.layout, className)}>
<TabsHeader
headers={headers}
selectedTab={selected}
onSelectTab={this.handleSelectedTab}
className={headersClassName}
/>
<TabsAction actions={actions} className={actionsClassName} />
{tab}
</div>
)
}
}

Tabs.propTypes = {
defaultKey: PropTypes.number,
children: PropTypes.oneOfType([PropTypes.node, PropTypes.array]).isRequired,
actions: PropTypes.oneOfType([PropTypes.node, PropTypes.object]),
className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
actionsClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
headersClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
}

Tabs.defaultProps = {
defaultKey: undefined,
actions: undefined,
className: undefined,
actionsClassName: undefined,
headersClassName: undefined,
}

export default Tabs
8 changes: 8 additions & 0 deletions src/gui/components/tabs/tabs.styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { css } from 'glamor'

const layout = css({
position: 'relative',
border: '.1em solid #ddd',
})

export default { layout }
28 changes: 28 additions & 0 deletions src/gui/components/tabs/tabsActions.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import PropTypes from 'prop-types'
import { merge } from 'glamor'

import styles from './tabsActions.styles'

const TabsActions = ({ actions, className }) => {
if (!actions) {
return null
}
return (
<div className={merge(styles.actions, className)}>
{actions}
</div>
)
}

TabsActions.propTypes = {
actions: PropTypes.oneOfType([PropTypes.node, PropTypes.object]),
className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
}

TabsActions.defaultProps = {
actions: undefined,
className: undefined,
}

export default TabsActions
10 changes: 10 additions & 0 deletions src/gui/components/tabs/tabsActions.styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { css } from 'glamor'

const layout = css({
position: 'absolute',
top: 0,
right: 0,
padding: '.9em 1.1em',
})

export default { layout }
43 changes: 43 additions & 0 deletions src/gui/components/tabs/tabsHeader.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { merge } from 'glamor'

import styles from './tabsHeader.styles'

class TabsHeader extends Component {

handleSelectedTab = tabKey => () => {
this.props.onSelectTab(tabKey)
}

render() {
const { headers, selectedTab, className } = this.props
return (
<ul className={merge(styles.layout, className)}>
{headers.map(({ tabKey, title }) =>
<li
key={tabKey}
className={merge(styles.item, selectedTab === tabKey && styles.selected)}
aria-expanded={selectedTab === tabKey}
onClick={this.handleSelectedTab(tabKey)}
>
{title}
</li>
)}
</ul>
)
}
}

TabsHeader.propTypes = {
headers: PropTypes.arrayOf(PropTypes.object).isRequired,
selectedTab: PropTypes.string.isRequired,
onSelectTab: PropTypes.func.isRequired,
className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
}

TabsHeader.defaultProps = {
className: undefined,
}

export default TabsHeader
26 changes: 26 additions & 0 deletions src/gui/components/tabs/tabsHeader.styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { css } from 'glamor'

const layout = css({
display: 'flex',
margin: 0,
padding: 0,
listStyle: 'none',
borderBottom: '1px solid #ddd',
})

const item = css({
cursor: 'pointer',
marginRight: 0,
padding: '.9em 1.1em',
lineHeight: '1.1em',
color: '#607580',
fontWeight: 600,
})

const selected = css({
cursor: 'default',
color: '#243641',
backgroundColor: '#ddd',
})

export default { layout, item, selected }
85 changes: 15 additions & 70 deletions src/gui/screens/workbench/props/__snapshots__/props.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,119 +4,64 @@ exports[`component/props props.container.js should map redux model into properti
<div
className={
Object {
"data-css-ikffa7": "",
"data-css-7xct0c": "",
}
}
style={Object {}}
>
<div
className={
Object {
"data-css-162aour": "",
}
}
>
props
</div>
<div />
</div>
/>
`;

exports[`component/props props.jsx should render by default 1`] = `
<div
className={
Object {
"data-css-ikffa7": "",
"data-css-7xct0c": "",
}
}
style={Object {}}
>
<div
className={
Object {
"data-css-162aour": "",
}
}
>
props
</div>
<div />
</div>
/>
`;

exports[`component/props props.jsx should render inputs following given properties 1`] = `
<div
className={
Object {
"data-css-ikffa7": "",
"data-css-7xct0c": "",
}
}
style={Object {}}
>
<div
className={
Object {
"data-css-162aour": "",
}
}
>
props
</div>
<div>
<input
name="prop1"
/>
<input
name="prop2"
/>
</div>
<input
name="prop1"
/>
<input
name="prop2"
/>
</div>
`;

exports[`component/props props.jsx should take custom className 1`] = `
<div
className={
Object {
"data-css-oj2paa": "",
"data-css-132or61": "",
}
}
style={Object {}}
>
<div
className={
Object {
"data-css-162aour": "",
}
}
>
props
</div>
<div />
</div>
/>
`;

exports[`component/props props.jsx should take custom style 1`] = `
<div
className={
Object {
"data-css-ikffa7": "",
"data-css-7xct0c": "",
}
}
style={
Object {
"backgroundColor": "red",
}
}
>
<div
className={
Object {
"data-css-162aour": "",
}
}
>
props
</div>
<div />
</div>
/>
`;
2 changes: 1 addition & 1 deletion src/gui/screens/workbench/props/input/input.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Input.propTypes = {

Input.defaultProps = {
style: {},
className: '',
className: undefined,
value: undefined,
}

Expand Down
Loading