diff --git a/src/client/components/dropdown/style.css b/src/client/components/dropdown/style.css index 5922b40f..5096e2ef 100644 --- a/src/client/components/dropdown/style.css +++ b/src/client/components/dropdown/style.css @@ -4,7 +4,6 @@ .dropdownMenu { position: absolute; - top: 100%; z-index: 1; } @@ -15,3 +14,11 @@ .dropdownMenuRight { right: 0; } + +.dropdownMenuUp { + bottom: 100%; +} + +.dropdownMenuDown { + top: 100%; +} diff --git a/src/client/components/dropdown/view.tsx b/src/client/components/dropdown/view.tsx index 38278053..bc9d5f58 100644 --- a/src/client/components/dropdown/view.tsx +++ b/src/client/components/dropdown/view.tsx @@ -13,6 +13,7 @@ export interface DropdownProps { isOpen: boolean isFullwidth?: boolean dropdownPosition?: 'left' | 'right' + dropDirection?: 'up' | 'down' onRef?(dropdown: HTMLDivElement): void onToggleClick?(event: MouseEvent): void } @@ -20,7 +21,8 @@ export interface DropdownProps { export const Dropdown: StatelessComponent = (props: DropdownProps) => { const fullwidth = props.isFullwidth ? style.dropdownMenuFullwidth : '' const position = props.dropdownPosition === 'right' ? style.dropdownMenuRight : '' - const dropdownMenuClassName = classNames(style.dropdownMenu, fullwidth, position) + const direction = props.dropDirection === 'up' ? style.dropdownMenuUp : style.dropdownMenuDown + const dropdownMenuClassName = classNames(style.dropdownMenu, fullwidth, position, direction) return (
diff --git a/src/client/components/robot_selector_single/plug.svg b/src/client/components/robot_selector_single/plug.svg new file mode 100644 index 00000000..418620c1 --- /dev/null +++ b/src/client/components/robot_selector_single/plug.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/client/components/robot_selector_single/robot.svg b/src/client/components/robot_selector_single/robot.svg new file mode 100644 index 00000000..c9f93dd6 --- /dev/null +++ b/src/client/components/robot_selector_single/robot.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/client/components/robot_selector_single/stories/robot_selector_single.stories.tsx b/src/client/components/robot_selector_single/stories/robot_selector_single.stories.tsx new file mode 100644 index 00000000..5d08cb6c --- /dev/null +++ b/src/client/components/robot_selector_single/stories/robot_selector_single.stories.tsx @@ -0,0 +1,80 @@ +import { action } from '@storybook/addon-actions' +import { storiesOf } from '@storybook/react' +import { action as mobxAction, observable } from 'mobx' +import { observer } from 'mobx-react' +import * as React from 'react' + +import { RobotModel } from '../../robot/model' +import { RobotSelectorSingle } from '../view' + +const actions = { + onSelect: action('onSelect'), +} + +storiesOf('components.robot_selector_single', module) + .addDecorator(story =>
{story()}
) + .add('renders empty', () => { + return + }) + .add('renders with robots', () => { + const robots = getRobots() + return + }) + .add('renders with selection', () => { + const robots = getRobots() + const selected = robots[0] + return + }) + .add('interactive', () => { + const robots = getRobots() + const model = observable({ + robots, + selected: robots[1], + }) + const onSelect = mobxAction((robot: RobotModel) => model.selected = robot) + const Component = observer(() => ) + return + }) + +function getRobots(): RobotModel[] { + return [ + { + id: '1', + name: 'Virtual Robot 1', + connected: true, + enabled: true, + address: '', + port: 0, + }, + { + id: '2', + name: 'Virtual Robot 2', + connected: true, + enabled: true, + address: '', + port: 0, + }, + { + id: '3', + name: 'Virtual Robot 3', + connected: true, + enabled: true, + address: '', + port: 0, + }, + ] +} diff --git a/src/client/components/robot_selector_single/style.css b/src/client/components/robot_selector_single/style.css new file mode 100644 index 00000000..335b5f9c --- /dev/null +++ b/src/client/components/robot_selector_single/style.css @@ -0,0 +1,30 @@ +.empty { + color: #888; + padding: 1em; + text-align: center; +} + +.emptyIcon { + background-color: #888; + border-radius: 100%; + box-shadow: + 0 0 8px 0 rgba(0, 0, 0, 0.2), + 1px 1px 4px 0 rgba(0,0,0,0.2); + fill: #fff; + height: 3em; + margin: 0 auto 1em auto; + opacity: 0.8; + padding: 1em; + width: 3em; +} + +.emptyTitle { + font-size: 1.54em; + padding: 0.25em 0; + white-space: nowrap; +} + +.emptyDescription { + font-size: 0.93em; + white-space: nowrap; +} \ No newline at end of file diff --git a/src/client/components/robot_selector_single/view.tsx b/src/client/components/robot_selector_single/view.tsx new file mode 100644 index 00000000..173be3f1 --- /dev/null +++ b/src/client/components/robot_selector_single/view.tsx @@ -0,0 +1,67 @@ +import { computed } from 'mobx' +import { observer } from 'mobx-react' +import * as React from 'react' + +import { RobotModel } from '../robot/model' +import { Option, Select } from '../select/view' + +import PlugIcon from './plug.svg' +import RobotIcon from './robot.svg' +import * as style from './style.css' + +export type RobotSelectorSingleProps = { + robots: RobotModel[] + selected?: RobotModel + dropDirection?: 'up' | 'down' + onSelect(robot: RobotModel): void +} + +@observer +export class RobotSelectorSingle extends React.Component { + render() { + const { dropDirection } = this.props + return
+