mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
191 lines
5.9 KiB
TypeScript
191 lines
5.9 KiB
TypeScript
import {Fragment, useState} from 'react';
|
|
import range from 'lodash/range';
|
|
|
|
import JSXNode from 'sentry/components/stories/jsxNode';
|
|
import Matrix from 'sentry/components/stories/matrix';
|
|
import SideBySide from 'sentry/components/stories/sideBySide';
|
|
import SizingWindow from 'sentry/components/stories/sizingWindow';
|
|
import type {TabListProps, TabsProps} from 'sentry/components/tabs';
|
|
import {TabList, TabPanels, Tabs} from 'sentry/components/tabs';
|
|
import storyBook from 'sentry/stories/storyBook';
|
|
|
|
export default storyBook(Tabs, story => {
|
|
const TABS = [
|
|
{key: 'one', label: 'One', content: 'This is the first Panel.'},
|
|
{key: 'two', label: 'Two', content: 'This is the second panel'},
|
|
{key: 'three', label: 'Three', content: 'This is the third panel'},
|
|
];
|
|
|
|
story('Default', () => (
|
|
<Fragment>
|
|
<p>
|
|
You should be using all of <JSXNode name="Tabs" />, <JSXNode name="TabList" />,{' '}
|
|
<JSXNode name="TabList.Item" />, <JSXNode name="TabPanels" /> and
|
|
<JSXNode name="TabPanels.Item" /> components.
|
|
</p>
|
|
<p>
|
|
This will give you all kinds of accessibility and state tracking out of the box.
|
|
But you will have to render all tab content, including hooks, upfront.
|
|
</p>
|
|
<SizingWindow>
|
|
<Tabs>
|
|
<TabList>
|
|
{TABS.map(tab => (
|
|
<TabList.Item key={tab.key}>{tab.label}</TabList.Item>
|
|
))}
|
|
</TabList>
|
|
<TabPanels>
|
|
{TABS.map(tab => (
|
|
<TabPanels.Item key={tab.key}>{tab.content}</TabPanels.Item>
|
|
))}
|
|
</TabPanels>
|
|
</Tabs>
|
|
</SizingWindow>
|
|
</Fragment>
|
|
));
|
|
|
|
story('Items Overflow', () => {
|
|
const tabs = range(65, 75).map(i => ({
|
|
key: 'i' + i,
|
|
label: String.fromCharCode(i, i, i, i),
|
|
content: String.fromCharCode(i, i, i, i),
|
|
}));
|
|
return (
|
|
<Fragment>
|
|
<p>When there are many items, they will overflow into a dropdown menu.</p>
|
|
<SizingWindow display="block" style={{height: '210px', width: '400px'}}>
|
|
<Tabs defaultValue="two">
|
|
<TabList>
|
|
{tabs.map(tab => (
|
|
<TabList.Item key={tab.key}>{tab.label}</TabList.Item>
|
|
))}
|
|
</TabList>
|
|
</Tabs>
|
|
</SizingWindow>
|
|
</Fragment>
|
|
);
|
|
});
|
|
|
|
story('Default Value', () => (
|
|
<Fragment>
|
|
<p>
|
|
Set <JSXNode name="Tabs" props={{defaultValue: String}} />
|
|
</p>
|
|
<SizingWindow>
|
|
<Tabs defaultValue="two">
|
|
<TabList>
|
|
{TABS.map(tab => (
|
|
<TabList.Item key={tab.key}>{tab.label}</TabList.Item>
|
|
))}
|
|
</TabList>
|
|
<TabPanels>
|
|
{TABS.map(tab => (
|
|
<TabPanels.Item key={tab.key}>{tab.content}</TabPanels.Item>
|
|
))}
|
|
</TabPanels>
|
|
</Tabs>
|
|
</SizingWindow>
|
|
</Fragment>
|
|
));
|
|
|
|
story('Controlled Value', () => {
|
|
const [selected, setSelected] = useState('two');
|
|
return (
|
|
<Fragment>
|
|
<p>
|
|
If you want to control the state of the tabs from outside, you can call{' '}
|
|
<var>{'useState()'}</var> and set{' '}
|
|
<JSXNode name="Tabs" props={{value: String, onChange: Function}} /> manually.
|
|
</p>
|
|
<p>
|
|
This is useful if you want to detect button clicks and do something different.{' '}
|
|
The <JSXNode name="Tabs" /> context wrapper is not required in this case.
|
|
</p>
|
|
<p>selected={selected}</p>
|
|
<SizingWindow>
|
|
<Tabs value={selected} onChange={setSelected}>
|
|
<TabList>
|
|
{TABS.map(tab => (
|
|
<TabList.Item key={tab.key}>{tab.label}</TabList.Item>
|
|
))}
|
|
</TabList>
|
|
<TabPanels>
|
|
{TABS.map(tab => (
|
|
<TabPanels.Item key={tab.key}>{tab.content}</TabPanels.Item>
|
|
))}
|
|
</TabPanels>
|
|
</Tabs>
|
|
</SizingWindow>
|
|
</Fragment>
|
|
);
|
|
});
|
|
|
|
story('Rendering', () => (
|
|
<Matrix<TabsProps<string> & TabListProps>
|
|
render={props => (
|
|
<Tabs orientation={props.orientation}>
|
|
<TabList hideBorder={props.hideBorder}>
|
|
{TABS.map(tab => (
|
|
<TabList.Item key={tab.key}>{tab.label}</TabList.Item>
|
|
))}
|
|
</TabList>
|
|
<TabPanels>
|
|
{TABS.map(tab => (
|
|
<TabPanels.Item key={tab.key}>{tab.content}</TabPanels.Item>
|
|
))}
|
|
</TabPanels>
|
|
</Tabs>
|
|
)}
|
|
propMatrix={{
|
|
orientation: ['horizontal', 'vertical'],
|
|
hideBorder: [false, true],
|
|
}}
|
|
selectedProps={['orientation', 'hideBorder']}
|
|
/>
|
|
));
|
|
|
|
story('Disabled', () => (
|
|
<SideBySide>
|
|
<div>
|
|
<p>
|
|
Use <JSXNode name="Tabs" props={{disabled: true}} /> to disable everything.
|
|
</p>
|
|
<SizingWindow>
|
|
<Tabs disabled>
|
|
<TabList>
|
|
{TABS.map(tab => (
|
|
<TabList.Item key={tab.key}>{tab.label}</TabList.Item>
|
|
))}
|
|
</TabList>
|
|
<TabPanels>
|
|
{TABS.map(tab => (
|
|
<TabPanels.Item key={tab.key}>{tab.content}</TabPanels.Item>
|
|
))}
|
|
</TabPanels>
|
|
</Tabs>
|
|
</SizingWindow>
|
|
</div>
|
|
<div>
|
|
<p>
|
|
Use <JSXNode name="TabList" props={{disabledKeys: Array}} /> to disable
|
|
individual <JSXNode name="TabList.Item" /> children.
|
|
</p>
|
|
<SizingWindow>
|
|
<Tabs>
|
|
<TabList disabledKeys={['two']}>
|
|
{TABS.map(tab => (
|
|
<TabList.Item key={tab.key}>{tab.label}</TabList.Item>
|
|
))}
|
|
</TabList>
|
|
<TabPanels>
|
|
{TABS.map(tab => (
|
|
<TabPanels.Item key={tab.key}>{tab.content}</TabPanels.Item>
|
|
))}
|
|
</TabPanels>
|
|
</Tabs>
|
|
</SizingWindow>
|
|
</div>
|
|
</SideBySide>
|
|
));
|
|
});
|