mirror of
https://github.com/mathuo/dockview
synced 2025-01-23 01:45:58 +00:00
chore: storybook docs
This commit is contained in:
parent
b7d1dad0da
commit
65a8095e27
6
packages/splitview-demo/package-lock.json
generated
6
packages/splitview-demo/package-lock.json
generated
@ -6538,9 +6538,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dockview": {
|
"dockview": {
|
||||||
"version": "0.0.11",
|
"version": "0.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/dockview/-/dockview-0.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/dockview/-/dockview-0.0.12.tgz",
|
||||||
"integrity": "sha512-Rj6pu9ul+AGrCtSNpv/KE6yRHYA89EoRsZfP1TUW73rNkuaUIH0iK+tJglSvoFVxwJFn6oW33erT1IzWfgXIxw=="
|
"integrity": "sha512-BQW1yUdVjpKgJaGxkpZyAogkEr//ka/lN+8JM+IgWMszEcry6UXj1T+zcaW6DOo7ZEtgHCsdPvlyEYthMgrPWA=="
|
||||||
},
|
},
|
||||||
"doctrine": {
|
"doctrine": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
|
16
packages/splitview-demo/src/resources/dockview-logo.svg
Normal file
16
packages/splitview-demo/src/resources/dockview-logo.svg
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 30H45V70H5C2.23858 70 0 67.7614 0 65V30Z" fill="#1E90FF"/>
|
||||||
|
<path d="M45 30H70V65C70 67.7614 67.7614 70 65 70H45V30Z" fill="#FF1E90"/>
|
||||||
|
<rect x="45" y="30" width="25" height="5" fill="#AC1160"/>
|
||||||
|
<rect x="45" y="30" width="10" height="5" fill="#EB1D85"/>
|
||||||
|
<rect y="30" width="45" height="5" fill="#1863AD"/>
|
||||||
|
<rect y="30" width="10" height="5" fill="#1A84EC"/>
|
||||||
|
<rect x="10" y="30" width="10" height="5" fill="#1973CB"/>
|
||||||
|
<path d="M0 5C0 2.23858 2.23858 0 5 0H30V30H0V5Z" fill="#1EFF8D"/>
|
||||||
|
<path d="M0 5C0 2.23858 2.23858 0 5 0H30V5H0V5Z" fill="#1BCA71"/>
|
||||||
|
<path d="M0 5C0 2.23858 2.23858 0 5 0H10V5H0V5Z" fill="#1DF387"/>
|
||||||
|
<path d="M30 0H65C67.7614 0 70 2.23858 70 5V30H30V0Z" fill="#FF8D1E"/>
|
||||||
|
<path d="M30 0H65C67.7614 0 70 2.23858 70 5V5H30V0Z" fill="#BA6817"/>
|
||||||
|
<rect x="30" width="10" height="5" fill="#EF841B"/>
|
||||||
|
<rect x="40" width="10" height="5" fill="#DC7A1B"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 974 B |
8
packages/splitview-demo/src/resources/gridview-logo.svg
Normal file
8
packages/splitview-demo/src/resources/gridview-logo.svg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 55H20V70H5C2.23858 70 0 67.7614 0 65V55Z" fill="#8D1EFF"/>
|
||||||
|
<path d="M45 55H70V65C70 67.7614 67.7614 70 65 70H45V55Z" fill="#FF1E90"/>
|
||||||
|
<path d="M20 55H45V70H20V55Z" fill="#90FF1E"/>
|
||||||
|
<path d="M0 30H70V55H0V30Z" fill="#1E90FF"/>
|
||||||
|
<path d="M0 5C0 2.23858 2.23858 0 5 0H30V30H0V5Z" fill="#1EFF8D"/>
|
||||||
|
<path d="M30 0H65C67.7614 0 70 2.23858 70 5V30H30V0Z" fill="#FF8D1E"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 479 B |
25
packages/splitview-demo/src/resources/logo.svg
Normal file
25
packages/splitview-demo/src/resources/logo.svg
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<svg width="200" height="70" viewBox="0 0 200 70" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 52.1429H60V60C60 62.7614 57.7614 65 55 65H5C2.23858 65 0 62.7614 0 60V52.1429Z" fill="#FF1E90"/>
|
||||||
|
<path d="M0 30.7143H60V52.1428H0V30.7143Z" fill="#1E90FF"/>
|
||||||
|
<path d="M0 10C0 7.23857 2.23858 5 5 5H55C57.7614 5 60 7.23858 60 10V30.7143H0V10Z" fill="#1EFF8D"/>
|
||||||
|
<path d="M65 55H85V70H70C67.2386 70 65 67.7614 65 65V55Z" fill="#8D1EFF"/>
|
||||||
|
<path d="M110 55H135V65C135 67.7614 132.761 70 130 70H110V55Z" fill="#FF1E90"/>
|
||||||
|
<path d="M85 55H110V70H85V55Z" fill="#90FF1E"/>
|
||||||
|
<path d="M65 30H135V55H65V30Z" fill="#1E90FF"/>
|
||||||
|
<path d="M65 5C65 2.23858 67.2386 0 70 0H95V30H65V5Z" fill="#1EFF8D"/>
|
||||||
|
<path d="M95 0H130C132.761 0 135 2.23858 135 5V30H95V0Z" fill="#FF8D1E"/>
|
||||||
|
<path d="M140 30.7143H178.571V65H145C142.239 65 140 62.7614 140 60V30.7143Z" fill="#1E90FF"/>
|
||||||
|
<path d="M178.571 30.7143H200V60C200 62.7614 197.761 65 195 65H178.571V30.7143Z" fill="#FF1E90"/>
|
||||||
|
<rect x="178.571" y="30.7143" width="21.4286" height="4.28572" fill="#AC1160"/>
|
||||||
|
<rect x="178.571" y="30.7143" width="8.57143" height="4.28572" fill="#EB1D85"/>
|
||||||
|
<rect x="140" y="30.7143" width="38.5714" height="4.28572" fill="#1863AD"/>
|
||||||
|
<rect x="140" y="30.7143" width="8.57143" height="4.28572" fill="#1A84EC"/>
|
||||||
|
<rect x="148.571" y="30.7143" width="8.57143" height="4.28572" fill="#1973CB"/>
|
||||||
|
<path d="M140 10C140 7.23858 142.239 5 145 5H165.714V30.7143H140V10Z" fill="#1EFF8D"/>
|
||||||
|
<path d="M140 9.28572C140 6.91878 141.919 5 144.286 5H165.714V9.28572H140V9.28572Z" fill="#1BCA71"/>
|
||||||
|
<path d="M140 9.28572C140 6.91878 141.919 5 144.286 5H148.571V9.28572H140V9.28572Z" fill="#1DF387"/>
|
||||||
|
<path d="M165.714 5H195C197.761 5 200 7.23858 200 10V30.7143H165.714V5Z" fill="#FF8D1E"/>
|
||||||
|
<path d="M165.714 5H195.714C198.081 5 200 6.91878 200 9.28572V9.28572H165.714V5Z" fill="#BA6817"/>
|
||||||
|
<rect x="165.714" y="5" width="8.57143" height="4.28572" fill="#EF841B"/>
|
||||||
|
<rect x="174.286" y="5" width="8.57143" height="4.28572" fill="#DC7A1B"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
8
packages/splitview-demo/src/resources/paneview-logo.svg
Normal file
8
packages/splitview-demo/src/resources/paneview-logo.svg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 55H70V65C70 67.7614 67.7614 70 65 70H5C2.23858 70 0 67.7614 0 65V55Z" fill="#FF1E90"/>
|
||||||
|
<path d="M0 5C0 2.23858 2.23858 0 5 0H65C67.7614 0 70 2.23858 70 5V50H0V5Z" fill="#1EFF8D"/>
|
||||||
|
<path d="M0 40H70V65C70 67.7614 67.7614 70 65 70H5C2.23858 70 0 67.7614 0 65V40Z" fill="#FF1E90"/>
|
||||||
|
<rect y="35" width="70" height="5" fill="#AC1160"/>
|
||||||
|
<path d="M0 30H70V35H0V30Z" fill="#1863AD"/>
|
||||||
|
<path d="M0 5C0 2.23858 2.23858 0 5 0H65C67.7614 0 70 2.23858 70 5V5H0V5Z" fill="#1BCA71"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 583 B |
5
packages/splitview-demo/src/resources/splitview-logo.svg
Normal file
5
packages/splitview-demo/src/resources/splitview-logo.svg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 55H70V65C70 67.7614 67.7614 70 65 70H5C2.23858 70 0 67.7614 0 65V55Z" fill="#FF1E90"/>
|
||||||
|
<path d="M0 30H70V55H0V30Z" fill="#1E90FF"/>
|
||||||
|
<path d="M0 5C0 2.23858 2.23858 0 5 0H65C67.7614 0 70 2.23858 70 5V30H0V5Z" fill="#1EFF8D"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 340 B |
@ -1,50 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import './button.css';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
|
|
||||||
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
|
|
||||||
style={backgroundColor && { backgroundColor }}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Button.propTypes = {
|
|
||||||
/**
|
|
||||||
* Is this the principal call to action on the page?
|
|
||||||
*/
|
|
||||||
primary: PropTypes.bool,
|
|
||||||
/**
|
|
||||||
* What background color to use
|
|
||||||
*/
|
|
||||||
backgroundColor: PropTypes.string,
|
|
||||||
/**
|
|
||||||
* How large should the button be?
|
|
||||||
*/
|
|
||||||
size: PropTypes.oneOf(['small', 'medium', 'large']),
|
|
||||||
/**
|
|
||||||
* Button contents
|
|
||||||
*/
|
|
||||||
label: PropTypes.string.isRequired,
|
|
||||||
/**
|
|
||||||
* Optional click handler
|
|
||||||
*/
|
|
||||||
onClick: PropTypes.func,
|
|
||||||
};
|
|
||||||
|
|
||||||
Button.defaultProps = {
|
|
||||||
backgroundColor: null,
|
|
||||||
primary: false,
|
|
||||||
size: 'medium',
|
|
||||||
onClick: undefined,
|
|
||||||
};
|
|
@ -1,36 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Button } from './Button';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Example/Button',
|
|
||||||
component: Button,
|
|
||||||
argTypes: {
|
|
||||||
backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const Template = (args) => <Button {...args} />;
|
|
||||||
|
|
||||||
export const Primary = Template.bind({});
|
|
||||||
Primary.args = {
|
|
||||||
primary: true,
|
|
||||||
label: 'Button',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Secondary = Template.bind({});
|
|
||||||
Secondary.args = {
|
|
||||||
label: 'Button',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Large = Template.bind({});
|
|
||||||
Large.args = {
|
|
||||||
size: 'large',
|
|
||||||
label: 'Button',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Small = Template.bind({});
|
|
||||||
Small.args = {
|
|
||||||
size: 'small',
|
|
||||||
label: 'Button',
|
|
||||||
};
|
|
@ -1,38 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
// also exported from '@storybook/react' if you can deal with breaking changes in 6.1
|
|
||||||
import { Story, Meta } from '@storybook/react/types-6-0';
|
|
||||||
|
|
||||||
import { Button, ButtonProps } from './Button';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Example/Button',
|
|
||||||
component: Button,
|
|
||||||
argTypes: {
|
|
||||||
backgroundColor: { control: 'color' },
|
|
||||||
},
|
|
||||||
} as Meta;
|
|
||||||
|
|
||||||
const Template: Story<ButtonProps> = (args) => <Button {...args} />;
|
|
||||||
|
|
||||||
export const Primary = Template.bind({});
|
|
||||||
Primary.args = {
|
|
||||||
primary: true,
|
|
||||||
label: 'Button',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Secondary = Template.bind({});
|
|
||||||
Secondary.args = {
|
|
||||||
label: 'Button',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Large = Template.bind({});
|
|
||||||
Large.args = {
|
|
||||||
size: 'large',
|
|
||||||
label: 'Button',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Small = Template.bind({});
|
|
||||||
Small.args = {
|
|
||||||
size: 'small',
|
|
||||||
label: 'Button',
|
|
||||||
};
|
|
@ -1,48 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import './button.css';
|
|
||||||
|
|
||||||
export interface ButtonProps {
|
|
||||||
/**
|
|
||||||
* Is this the principal call to action on the page?
|
|
||||||
*/
|
|
||||||
primary?: boolean;
|
|
||||||
/**
|
|
||||||
* What background color to use
|
|
||||||
*/
|
|
||||||
backgroundColor?: string;
|
|
||||||
/**
|
|
||||||
* How large should the button be?
|
|
||||||
*/
|
|
||||||
size?: 'small' | 'medium' | 'large';
|
|
||||||
/**
|
|
||||||
* Button contents
|
|
||||||
*/
|
|
||||||
label: string;
|
|
||||||
/**
|
|
||||||
* Optional click handler
|
|
||||||
*/
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primary UI component for user interaction
|
|
||||||
*/
|
|
||||||
export const Button: React.FC<ButtonProps> = ({
|
|
||||||
primary = false,
|
|
||||||
size = 'medium',
|
|
||||||
backgroundColor,
|
|
||||||
label,
|
|
||||||
...props
|
|
||||||
}) => {
|
|
||||||
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
|
|
||||||
style={{ backgroundColor }}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,52 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import { Button } from './Button';
|
|
||||||
import './header.css';
|
|
||||||
|
|
||||||
export const Header = ({ user, onLogin, onLogout, onCreateAccount }) => (
|
|
||||||
<header>
|
|
||||||
<div className="wrapper">
|
|
||||||
<div>
|
|
||||||
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g fill="none" fillRule="evenodd">
|
|
||||||
<path
|
|
||||||
d="M10 0h12a10 10 0 0110 10v12a10 10 0 01-10 10H10A10 10 0 010 22V10A10 10 0 0110 0z"
|
|
||||||
fill="#FFF"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M5.3 10.6l10.4 6v11.1l-10.4-6v-11zm11.4-6.2l9.7 5.5-9.7 5.6V4.4z"
|
|
||||||
fill="#555AB9"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M27.2 10.6v11.2l-10.5 6V16.5l10.5-6zM15.7 4.4v11L6 10l9.7-5.5z"
|
|
||||||
fill="#91BAF8"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
<h1>Acme</h1>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{user ? (
|
|
||||||
<Button size="small" onClick={onLogout} label="Log out" />
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Button size="small" onClick={onLogin} label="Log in" />
|
|
||||||
<Button primary size="small" onClick={onCreateAccount} label="Sign up" />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
|
|
||||||
Header.propTypes = {
|
|
||||||
user: PropTypes.shape({}),
|
|
||||||
onLogin: PropTypes.func.isRequired,
|
|
||||||
onLogout: PropTypes.func.isRequired,
|
|
||||||
onCreateAccount: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
Header.defaultProps = {
|
|
||||||
user: null,
|
|
||||||
};
|
|
@ -1,18 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Header } from './Header';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Example/Header',
|
|
||||||
component: Header,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Template = (args) => <Header {...args} />;
|
|
||||||
|
|
||||||
export const LoggedIn = Template.bind({});
|
|
||||||
LoggedIn.args = {
|
|
||||||
user: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LoggedOut = Template.bind({});
|
|
||||||
LoggedOut.args = {};
|
|
@ -1,20 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
// also exported from '@storybook/react' if you can deal with breaking changes in 6.1
|
|
||||||
import { Story, Meta } from '@storybook/react/types-6-0';
|
|
||||||
|
|
||||||
import { Header, HeaderProps } from './Header';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Example/Header',
|
|
||||||
component: Header,
|
|
||||||
} as Meta;
|
|
||||||
|
|
||||||
const Template: Story<HeaderProps> = (args) => <Header {...args} />;
|
|
||||||
|
|
||||||
export const LoggedIn = Template.bind({});
|
|
||||||
LoggedIn.args = {
|
|
||||||
user: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LoggedOut = Template.bind({});
|
|
||||||
LoggedOut.args = {};
|
|
@ -1,47 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Button } from './Button';
|
|
||||||
import './header.css';
|
|
||||||
|
|
||||||
export interface HeaderProps {
|
|
||||||
user?: {};
|
|
||||||
onLogin: () => void;
|
|
||||||
onLogout: () => void;
|
|
||||||
onCreateAccount: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Header: React.FC<HeaderProps> = ({ user, onLogin, onLogout, onCreateAccount }) => (
|
|
||||||
<header>
|
|
||||||
<div className="wrapper">
|
|
||||||
<div>
|
|
||||||
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g fill="none" fillRule="evenodd">
|
|
||||||
<path
|
|
||||||
d="M10 0h12a10 10 0 0110 10v12a10 10 0 01-10 10H10A10 10 0 010 22V10A10 10 0 0110 0z"
|
|
||||||
fill="#FFF"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M5.3 10.6l10.4 6v11.1l-10.4-6v-11zm11.4-6.2l9.7 5.5-9.7 5.6V4.4z"
|
|
||||||
fill="#555AB9"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M27.2 10.6v11.2l-10.5 6V16.5l10.5-6zM15.7 4.4v11L6 10l9.7-5.5z"
|
|
||||||
fill="#91BAF8"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
<h1>Acme</h1>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{user ? (
|
|
||||||
<Button size="small" onClick={onLogout} label="Log out" />
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Button size="small" onClick={onLogin} label="Log in" />
|
|
||||||
<Button primary size="small" onClick={onCreateAccount} label="Sign up" />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
);
|
|
@ -7,201 +7,61 @@ import Flow from './assets/flow.svg';
|
|||||||
import Plugin from './assets/plugin.svg';
|
import Plugin from './assets/plugin.svg';
|
||||||
import Repo from './assets/repo.svg';
|
import Repo from './assets/repo.svg';
|
||||||
import StackAlt from './assets/stackalt.svg';
|
import StackAlt from './assets/stackalt.svg';
|
||||||
|
import Splitview from '../resources/splitview-logo.svg';
|
||||||
|
import Gridview from '../resources/gridview-logo.svg';
|
||||||
|
import Dockview from '../resources/dockview-logo.svg';
|
||||||
|
import Paneview from '../resources/paneview-logo.svg';
|
||||||
|
import './introduction.css';
|
||||||
|
|
||||||
<Meta title="Example/Introduction" />
|
<Meta title="Introduction" />
|
||||||
|
|
||||||
<style>{`
|
# Dockview
|
||||||
.subheading {
|
|
||||||
--mediumdark: '#999999';
|
|
||||||
font-weight: 900;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #999;
|
|
||||||
letter-spacing: 6px;
|
|
||||||
line-height: 24px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-list {
|
<div className="subheading">Components</div>
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: 1fr 1fr;
|
|
||||||
row-gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 620px) {
|
|
||||||
.link-list {
|
|
||||||
row-gap: 20px;
|
|
||||||
column-gap: 20px;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all and (-ms-high-contrast:none) {
|
|
||||||
.link-list {
|
|
||||||
display: -ms-grid;
|
|
||||||
-ms-grid-columns: 1fr 1fr;
|
|
||||||
-ms-grid-rows: 1fr 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-item {
|
|
||||||
display: block;
|
|
||||||
padding: 20px 30px 20px 15px;
|
|
||||||
border: 1px solid #00000010;
|
|
||||||
border-radius: 5px;
|
|
||||||
transition: background 150ms ease-out, border 150ms ease-out, transform 150ms ease-out;
|
|
||||||
color: #333333;
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-item:hover {
|
|
||||||
border-color: #1EA7FD50;
|
|
||||||
transform: translate3d(0, -3px, 0);
|
|
||||||
box-shadow: rgba(0, 0, 0, 0.08) 0 3px 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-item:active {
|
|
||||||
border-color: #1EA7FD;
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-item strong {
|
|
||||||
font-weight: 700;
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-item img {
|
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
margin-right: 15px;
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-item span {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip {
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 1em;
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
background: #E7FDD8;
|
|
||||||
color: #66BF3C;
|
|
||||||
padding: 4px 12px;
|
|
||||||
margin-right: 10px;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-wrapper {
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 20px;
|
|
||||||
margin-top: 40px;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-wrapper code {
|
|
||||||
font-size: 12px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
`}</style>
|
|
||||||
|
|
||||||
# Welcome to Storybook
|
|
||||||
|
|
||||||
Storybook helps you build UI components in isolation from your app's business logic, data, and context.
|
|
||||||
That makes it easy to develop hard-to-reach states. Save these UI states as **stories** to revisit during development, testing, or QA.
|
|
||||||
|
|
||||||
Browse example stories now by navigating to them in the sidebar.
|
|
||||||
View their code in the `src/storybook-examples` directory to learn how they work.
|
|
||||||
We recommend building UIs with a [**component-driven**](https://componentdriven.org) process starting with atomic components and ending with pages.
|
|
||||||
|
|
||||||
<div className="subheading">Configure</div>
|
|
||||||
|
|
||||||
<div className="link-list">
|
<div className="link-list">
|
||||||
<a className="link-item" href="https://storybook.js.org/docs/react/api/presets" target="_blank">
|
<a
|
||||||
<img src={Plugin} alt="plugin" />
|
className="link-item"
|
||||||
<span>
|
href="https://storybook.js.org/docs/react/api/presets"
|
||||||
<strong>Presets for popular tools</strong>
|
target="_blank"
|
||||||
Easy setup for TypeScript, SCSS and more.
|
>
|
||||||
</span>
|
<img src={Splitview} alt="splitview" />
|
||||||
</a>
|
<span>
|
||||||
<a
|
<strong>Splitview</strong>
|
||||||
className="link-item"
|
Vertical or horiziontal splitview panels
|
||||||
href="https://storybook.js.org/docs/react/configure/webpack"
|
</span>
|
||||||
target="_blank"
|
</a>
|
||||||
>
|
<a
|
||||||
<img src={StackAlt} alt="Build" />
|
className="link-item"
|
||||||
<span>
|
href="https://storybook.js.org/docs/react/configure/webpack"
|
||||||
<strong>Build configuration</strong>
|
target="_blank"
|
||||||
How to customize webpack and Babel
|
>
|
||||||
</span>
|
<img src={Gridview} alt="gridview" />
|
||||||
</a>
|
<span>
|
||||||
<a
|
<strong>Gridview</strong>
|
||||||
className="link-item"
|
Splitviews within splitviews
|
||||||
href="https://storybook.js.org/docs/react/configure/styling-and-css"
|
</span>
|
||||||
target="_blank"
|
</a>
|
||||||
>
|
<a
|
||||||
<img src={Colors} alt="colors" />
|
className="link-item"
|
||||||
<span>
|
href="https://storybook.js.org/docs/react/configure/styling-and-css"
|
||||||
<strong>Styling</strong>
|
target="_blank"
|
||||||
How to load and configure CSS libraries
|
>
|
||||||
</span>
|
<img src={Dockview} alt="dockview" />
|
||||||
</a>
|
<span>
|
||||||
<a
|
<strong>Dockview</strong>
|
||||||
className="link-item"
|
Dockable and tabular panels within Gridviews
|
||||||
href="https://storybook.js.org/docs/react/get-started/setup#configure-storybook-for-your-stack"
|
</span>
|
||||||
target="_blank"
|
</a>
|
||||||
>
|
<a
|
||||||
<img src={Flow} alt="flow" />
|
className="link-item"
|
||||||
<span>
|
href="https://storybook.js.org/docs/react/get-started/setup#configure-storybook-for-your-stack"
|
||||||
<strong>Data</strong>
|
target="_blank"
|
||||||
Providers and mocking for data libraries
|
>
|
||||||
</span>
|
<img src={Paneview} alt="paneview" />
|
||||||
</a>
|
<span>
|
||||||
</div>
|
<strong>Paneview</strong>
|
||||||
|
An extension to splitviews allowing collapsable panels with a persistant header section
|
||||||
<div className="subheading">Learn</div>
|
</span>
|
||||||
|
</a>
|
||||||
<div className="link-list">
|
|
||||||
<a className="link-item" href="https://storybook.js.org/docs" target="_blank">
|
|
||||||
<img src={Repo} alt="repo" />
|
|
||||||
<span>
|
|
||||||
<strong>Storybook documentation</strong>
|
|
||||||
Configure, customize, and extend
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<a className="link-item" href="https://www.learnstorybook.com" target="_blank">
|
|
||||||
<img src={Direction} alt="direction" />
|
|
||||||
<span>
|
|
||||||
<strong>In-depth guides</strong>
|
|
||||||
Best practices from leading teams
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<a className="link-item" href="https://github.com/storybookjs/storybook" target="_blank">
|
|
||||||
<img src={Code} alt="code" />
|
|
||||||
<span>
|
|
||||||
<strong>GitHub project</strong>
|
|
||||||
View the source and add issues
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<a className="link-item" href="https://discord.gg/UUt2PJb" target="_blank">
|
|
||||||
<img src={Comments} alt="comments" />
|
|
||||||
<span>
|
|
||||||
<strong>Discord chat</strong>
|
|
||||||
Chat with maintainers and the community
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="tip-wrapper">
|
|
||||||
<span className="tip">Tip</span>Edit the Markdown in{' '}
|
|
||||||
<code>src/storybook-examples/welcome.mdx</code>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import { Header } from './Header';
|
|
||||||
import './page.css';
|
|
||||||
|
|
||||||
export const Page = ({ user, onLogin, onLogout, onCreateAccount }) => (
|
|
||||||
<article>
|
|
||||||
<Header user={user} onLogin={onLogin} onLogout={onLogout} onCreateAccount={onCreateAccount} />
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>Pages in Storybook</h2>
|
|
||||||
<p>
|
|
||||||
We recommend building UIs with a{' '}
|
|
||||||
<a href="https://componentdriven.org" target="_blank" rel="noopener noreferrer">
|
|
||||||
<strong>component-driven</strong>
|
|
||||||
</a>{' '}
|
|
||||||
process starting with atomic components and ending with pages.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Render pages with mock data. This makes it easy to build and review page states without
|
|
||||||
needing to navigate to them in your app. Here are some handy patterns for managing page data
|
|
||||||
in Storybook:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Use a higher-level connected component. Storybook helps you compose such data from the
|
|
||||||
"args" of child component stories
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Assemble data in the page component from your services. You can mock these services out
|
|
||||||
using Storybook.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p>
|
|
||||||
Get a guided tutorial on component-driven development at{' '}
|
|
||||||
<a href="https://www.learnstorybook.com" target="_blank" rel="noopener noreferrer">
|
|
||||||
Learn Storybook
|
|
||||||
</a>
|
|
||||||
. Read more in the{' '}
|
|
||||||
<a href="https://storybook.js.org/docs" target="_blank" rel="noopener noreferrer">
|
|
||||||
docs
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
<div className="tip-wrapper">
|
|
||||||
<span className="tip">Tip</span> Adjust the width of the canvas with the{' '}
|
|
||||||
<svg width="10" height="10" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g fill="none" fillRule="evenodd">
|
|
||||||
<path
|
|
||||||
d="M1.5 5.2h4.8c.3 0 .5.2.5.4v5.1c-.1.2-.3.3-.4.3H1.4a.5.5 0 01-.5-.4V5.7c0-.3.2-.5.5-.5zm0-2.1h6.9c.3 0 .5.2.5.4v7a.5.5 0 01-1 0V4H1.5a.5.5 0 010-1zm0-2.1h9c.3 0 .5.2.5.4v9.1a.5.5 0 01-1 0V2H1.5a.5.5 0 010-1zm4.3 5.2H2V10h3.8V6.2z"
|
|
||||||
id="a"
|
|
||||||
fill="#999"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
Viewports addon in the toolbar
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</article>
|
|
||||||
);
|
|
||||||
Page.propTypes = {
|
|
||||||
user: PropTypes.shape({}),
|
|
||||||
onLogin: PropTypes.func.isRequired,
|
|
||||||
onLogout: PropTypes.func.isRequired,
|
|
||||||
onCreateAccount: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
Page.defaultProps = {
|
|
||||||
user: null,
|
|
||||||
};
|
|
@ -1,21 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Page } from './Page';
|
|
||||||
import * as HeaderStories from './Header.stories';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Example/Page',
|
|
||||||
component: Page,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Template = (args) => <Page {...args} />;
|
|
||||||
|
|
||||||
export const LoggedIn = Template.bind({});
|
|
||||||
LoggedIn.args = {
|
|
||||||
...HeaderStories.LoggedIn.args,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LoggedOut = Template.bind({});
|
|
||||||
LoggedOut.args = {
|
|
||||||
...HeaderStories.LoggedOut.args,
|
|
||||||
};
|
|
@ -1,23 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
// also exported from '@storybook/react' if you can deal with breaking changes in 6.1
|
|
||||||
import { Story, Meta } from '@storybook/react/types-6-0';
|
|
||||||
|
|
||||||
import { Page, PageProps } from './Page';
|
|
||||||
import * as HeaderStories from './Header.stories';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Example/Page',
|
|
||||||
component: Page,
|
|
||||||
} as Meta;
|
|
||||||
|
|
||||||
const Template: Story<PageProps> = (args) => <Page {...args} />;
|
|
||||||
|
|
||||||
export const LoggedIn = Template.bind({});
|
|
||||||
LoggedIn.args = {
|
|
||||||
...HeaderStories.LoggedIn.args,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LoggedOut = Template.bind({});
|
|
||||||
LoggedOut.args = {
|
|
||||||
...HeaderStories.LoggedOut.args,
|
|
||||||
};
|
|
@ -1,67 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Header } from './Header';
|
|
||||||
import './page.css';
|
|
||||||
|
|
||||||
export interface PageProps {
|
|
||||||
user?: {};
|
|
||||||
onLogin: () => void;
|
|
||||||
onLogout: () => void;
|
|
||||||
onCreateAccount: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Page: React.FC<PageProps> = ({ user, onLogin, onLogout, onCreateAccount }) => (
|
|
||||||
<article>
|
|
||||||
<Header user={user} onLogin={onLogin} onLogout={onLogout} onCreateAccount={onCreateAccount} />
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>Pages in Storybook</h2>
|
|
||||||
<p>
|
|
||||||
We recommend building UIs with a{' '}
|
|
||||||
<a href="https://componentdriven.org" target="_blank" rel="noopener noreferrer">
|
|
||||||
<strong>component-driven</strong>
|
|
||||||
</a>{' '}
|
|
||||||
process starting with atomic components and ending with pages.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Render pages with mock data. This makes it easy to build and review page states without
|
|
||||||
needing to navigate to them in your app. Here are some handy patterns for managing page data
|
|
||||||
in Storybook:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Use a higher-level connected component. Storybook helps you compose such data from the
|
|
||||||
"args" of child component stories
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Assemble data in the page component from your services. You can mock these services out
|
|
||||||
using Storybook.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p>
|
|
||||||
Get a guided tutorial on component-driven development at{' '}
|
|
||||||
<a href="https://www.learnstorybook.com" target="_blank" rel="noopener noreferrer">
|
|
||||||
Learn Storybook
|
|
||||||
</a>
|
|
||||||
. Read more in the{' '}
|
|
||||||
<a href="https://storybook.js.org/docs" target="_blank" rel="noopener noreferrer">
|
|
||||||
docs
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
<div className="tip-wrapper">
|
|
||||||
<span className="tip">Tip</span> Adjust the width of the canvas with the{' '}
|
|
||||||
<svg width="10" height="10" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g fill="none" fillRule="evenodd">
|
|
||||||
<path
|
|
||||||
d="M1.5 5.2h4.8c.3 0 .5.2.5.4v5.1c-.1.2-.3.3-.4.3H1.4a.5.5 0 01-.5-.4V5.7c0-.3.2-.5.5-.5zm0-2.1h6.9c.3 0 .5.2.5.4v7a.5.5 0 01-1 0V4H1.5a.5.5 0 010-1zm0-2.1h9c.3 0 .5.2.5.4v9.1a.5.5 0 01-1 0V2H1.5a.5.5 0 010-1zm4.3 5.2H2V10h3.8V6.2z"
|
|
||||||
id="a"
|
|
||||||
fill="#999"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
Viewports addon in the toolbar
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</article>
|
|
||||||
);
|
|
@ -1,30 +0,0 @@
|
|||||||
.storybook-button {
|
|
||||||
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
||||||
font-weight: 700;
|
|
||||||
border: 0;
|
|
||||||
border-radius: 3em;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.storybook-button--primary {
|
|
||||||
color: white;
|
|
||||||
background-color: #1ea7fd;
|
|
||||||
}
|
|
||||||
.storybook-button--secondary {
|
|
||||||
color: #333;
|
|
||||||
background-color: transparent;
|
|
||||||
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
|
|
||||||
}
|
|
||||||
.storybook-button--small {
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 10px 16px;
|
|
||||||
}
|
|
||||||
.storybook-button--medium {
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 11px 20px;
|
|
||||||
}
|
|
||||||
.storybook-button--large {
|
|
||||||
font-size: 16px;
|
|
||||||
padding: 12px 24px;
|
|
||||||
}
|
|
@ -0,0 +1,123 @@
|
|||||||
|
import {
|
||||||
|
CompositeDisposable,
|
||||||
|
DockviewApi,
|
||||||
|
DockviewReact,
|
||||||
|
DockviewReadyEvent,
|
||||||
|
GroupChangeKind,
|
||||||
|
IDockviewPanelProps,
|
||||||
|
IWatermarkPanelProps,
|
||||||
|
PanelCollection,
|
||||||
|
} from 'dockview';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Meta } from '@storybook/react';
|
||||||
|
import 'dockview/dist/styles.css';
|
||||||
|
|
||||||
|
const components: PanelCollection<IDockviewPanelProps> = {
|
||||||
|
default: (props) => {
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '10px', height: '100%' }}>
|
||||||
|
This content is not within an IFrame
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
iframe: (props) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '25px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
margin: '0px 4px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
The contents below is within an iFrame
|
||||||
|
</div>
|
||||||
|
<iframe
|
||||||
|
src="./"
|
||||||
|
style={{
|
||||||
|
flexGrow: 1,
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
border: '1px solid red',
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Iframe = (props: {
|
||||||
|
onEvent: (name: string) => void;
|
||||||
|
theme: string;
|
||||||
|
hideBorders: boolean;
|
||||||
|
disableAutoResizing: boolean;
|
||||||
|
}) => {
|
||||||
|
const api = React.useRef<DockviewApi>();
|
||||||
|
|
||||||
|
const onReady = (event: DockviewReadyEvent) => {
|
||||||
|
event.api.layout(window.innerWidth, window.innerHeight);
|
||||||
|
api.current = event.api;
|
||||||
|
|
||||||
|
event.api.onGridEvent((e) => props.onEvent(e.kind));
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel1',
|
||||||
|
title: 'Standard Panel',
|
||||||
|
component: 'default',
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel2',
|
||||||
|
title: 'IFrame Panel',
|
||||||
|
component: 'iframe',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
api.current?.layout(window.innerWidth, window.innerHeight);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DockviewReact
|
||||||
|
className={props.theme}
|
||||||
|
onReady={onReady}
|
||||||
|
components={components}
|
||||||
|
hideBorders={props.hideBorders}
|
||||||
|
disableAutoResizing={props.disableAutoResizing}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Dockview/Iframe',
|
||||||
|
component: Iframe,
|
||||||
|
decorators: [
|
||||||
|
(Component) => {
|
||||||
|
document.body.style.padding = '0px';
|
||||||
|
return (
|
||||||
|
<div style={{ height: '100vh', fontFamily: 'Arial' }}>
|
||||||
|
<Component />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
args: { theme: 'dockview-theme-light' },
|
||||||
|
argTypes: {
|
||||||
|
theme: {
|
||||||
|
control: {
|
||||||
|
type: 'select',
|
||||||
|
options: ['dockview-theme-dark', 'dockview-theme-light'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onEvent: { action: 'onEvent' },
|
||||||
|
},
|
||||||
|
} as Meta;
|
@ -0,0 +1,108 @@
|
|||||||
|
import {
|
||||||
|
CompositeDisposable,
|
||||||
|
DockviewApi,
|
||||||
|
DockviewReact,
|
||||||
|
DockviewReadyEvent,
|
||||||
|
GroupChangeKind,
|
||||||
|
IDockviewPanelProps,
|
||||||
|
IWatermarkPanelProps,
|
||||||
|
PanelCollection,
|
||||||
|
} from 'dockview';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Meta } from '@storybook/react';
|
||||||
|
import 'dockview/dist/styles.css';
|
||||||
|
|
||||||
|
const components: PanelCollection<IDockviewPanelProps> = {
|
||||||
|
default: (props) => {
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '10px', height: '100%' }}>hello world</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
iframe: (props) => {
|
||||||
|
return (
|
||||||
|
<div style={{ height: '100%', width: '100%' }}>
|
||||||
|
<iframe src="./" style={{ height: '100%', width: '100%' }}>
|
||||||
|
Hello world
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Simple = (props: {
|
||||||
|
onEvent: (name: string) => void;
|
||||||
|
theme: string;
|
||||||
|
hideBorders: boolean;
|
||||||
|
disableAutoResizing: boolean;
|
||||||
|
}) => {
|
||||||
|
const api = React.useRef<DockviewApi>();
|
||||||
|
|
||||||
|
const onReady = (event: DockviewReadyEvent) => {
|
||||||
|
event.api.layout(window.innerWidth, window.innerHeight);
|
||||||
|
api.current = event.api;
|
||||||
|
|
||||||
|
event.api.onGridEvent((e) => props.onEvent(e.kind));
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel1',
|
||||||
|
component: 'default',
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel2',
|
||||||
|
component: 'default',
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel3',
|
||||||
|
component: 'default',
|
||||||
|
position: { referencePanel: 'panel1', direction: 'right' },
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel4',
|
||||||
|
component: 'default',
|
||||||
|
position: { referencePanel: 'panel3', direction: 'below' },
|
||||||
|
});
|
||||||
|
|
||||||
|
// event.api.getPanel('panel1').api;
|
||||||
|
};
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
api.current?.layout(window.innerWidth, window.innerHeight);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DockviewReact
|
||||||
|
className={props.theme}
|
||||||
|
onReady={onReady}
|
||||||
|
components={components}
|
||||||
|
hideBorders={props.hideBorders}
|
||||||
|
disableAutoResizing={props.disableAutoResizing}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Dockview/Simple',
|
||||||
|
component: Simple,
|
||||||
|
decorators: [
|
||||||
|
(Component) => {
|
||||||
|
document.body.style.padding = '0px';
|
||||||
|
return (
|
||||||
|
<div style={{ height: '100vh', fontFamily: 'Arial' }}>
|
||||||
|
<Component />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
args: { theme: 'dockview-theme-light' },
|
||||||
|
argTypes: {
|
||||||
|
theme: {
|
||||||
|
control: {
|
||||||
|
type: 'select',
|
||||||
|
options: ['dockview-theme-dark', 'dockview-theme-light'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onEvent: { action: 'onEvent' },
|
||||||
|
},
|
||||||
|
} as Meta;
|
@ -29,99 +29,7 @@ const components: PanelCollection<IDockviewPanelProps> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IFrame = (props: {
|
|
||||||
onEvent: (name: string) => void;
|
|
||||||
theme: string;
|
|
||||||
hideBorders: boolean;
|
|
||||||
disableAutoResizing: boolean;
|
|
||||||
}) => {
|
|
||||||
const api = React.useRef<DockviewApi>();
|
|
||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
event.api.layout(window.innerWidth, window.innerHeight);
|
|
||||||
api.current = event.api;
|
|
||||||
|
|
||||||
event.api.onGridEvent((e) => props.onEvent(e.kind));
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel2',
|
|
||||||
component: 'iframe',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
api.current?.layout(window.innerWidth, window.innerHeight);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DockviewReact
|
|
||||||
className={props.theme}
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
hideBorders={props.hideBorders}
|
|
||||||
disableAutoResizing={props.disableAutoResizing}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Simple = (props: {
|
|
||||||
onEvent: (name: string) => void;
|
|
||||||
theme: string;
|
|
||||||
hideBorders: boolean;
|
|
||||||
disableAutoResizing: boolean;
|
|
||||||
}) => {
|
|
||||||
const api = React.useRef<DockviewApi>();
|
|
||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
event.api.layout(window.innerWidth, window.innerHeight);
|
|
||||||
api.current = event.api;
|
|
||||||
|
|
||||||
event.api.onGridEvent((e) => props.onEvent(e.kind));
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel2',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel3',
|
|
||||||
component: 'default',
|
|
||||||
position: { referencePanel: 'panel1', direction: 'right' },
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel4',
|
|
||||||
component: 'default',
|
|
||||||
position: { referencePanel: 'panel3', direction: 'below' },
|
|
||||||
});
|
|
||||||
|
|
||||||
// event.api.getPanel('panel1').api;
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
api.current?.layout(window.innerWidth, window.innerHeight);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DockviewReact
|
|
||||||
className={props.theme}
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
hideBorders={props.hideBorders}
|
|
||||||
disableAutoResizing={props.disableAutoResizing}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Watermark = (props: IWatermarkPanelProps) => {
|
const Watermark = (props: IWatermarkPanelProps) => {
|
||||||
const [size, setSize] = React.useState<number>(props.containerApi.size);
|
const [size, setSize] = React.useState<number>(props.containerApi.size);
|
||||||
@ -226,8 +134,8 @@ export const CustomWatermark = (props: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Dockview',
|
title: 'Dockview/CustomWatermark',
|
||||||
component: Simple,
|
component: CustomWatermark,
|
||||||
decorators: [
|
decorators: [
|
||||||
(Component) => {
|
(Component) => {
|
||||||
document.body.style.padding = '0px';
|
document.body.style.padding = '0px';
|
@ -99,7 +99,7 @@ export const Simple = (props: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Gridview',
|
title: 'Gridview/Simple',
|
||||||
component: Simple,
|
component: Simple,
|
||||||
decorators: [
|
decorators: [
|
||||||
(Component) => {
|
(Component) => {
|
@ -1,26 +0,0 @@
|
|||||||
.wrapper {
|
|
||||||
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
padding: 15px 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: 900;
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: 1;
|
|
||||||
margin: 6px 0 6px 10px;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
button + button {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
100
packages/splitview-demo/src/stories/introduction.css
Normal file
100
packages/splitview-demo/src/stories/introduction.css
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
.subheading {
|
||||||
|
--mediumdark: '#999999';
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #999;
|
||||||
|
letter-spacing: 6px;
|
||||||
|
line-height: 24px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: 1fr 1fr;
|
||||||
|
row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 620px) {
|
||||||
|
.link-list {
|
||||||
|
row-gap: 20px;
|
||||||
|
column-gap: 20px;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (-ms-high-contrast: none) {
|
||||||
|
.link-list {
|
||||||
|
display: -ms-grid;
|
||||||
|
-ms-grid-columns: 1fr 1fr;
|
||||||
|
-ms-grid-rows: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-item {
|
||||||
|
display: block;
|
||||||
|
padding: 20px 30px 20px 15px;
|
||||||
|
border: 1px solid #00000010;
|
||||||
|
border-radius: 5px;
|
||||||
|
transition: background 150ms ease-out, border 150ms ease-out,
|
||||||
|
transform 150ms ease-out;
|
||||||
|
color: #333333;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-item:hover {
|
||||||
|
border-color: #1ea7fd50;
|
||||||
|
transform: translate3d(0, -3px, 0);
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.08) 0 3px 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-item:active {
|
||||||
|
border-color: #1ea7fd;
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-item strong {
|
||||||
|
font-weight: 700;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-item img {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
margin-right: 15px;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-item span {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 1em;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
background: #e7fdd8;
|
||||||
|
color: #66bf3c;
|
||||||
|
padding: 4px 12px;
|
||||||
|
margin-right: 10px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-wrapper {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 20px;
|
||||||
|
margin-top: 40px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-wrapper code {
|
||||||
|
font-size: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
@ -1,69 +0,0 @@
|
|||||||
section {
|
|
||||||
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 24px;
|
|
||||||
padding: 48px 20px;
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: 600px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-weight: 900;
|
|
||||||
font-size: 32px;
|
|
||||||
line-height: 1;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #1ea7fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
padding-left: 30px;
|
|
||||||
margin: 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip {
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 1em;
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
background: #e7fdd8;
|
|
||||||
color: #66bf3c;
|
|
||||||
padding: 4px 12px;
|
|
||||||
margin-right: 10px;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-wrapper {
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 20px;
|
|
||||||
margin-top: 40px;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-wrapper svg {
|
|
||||||
display: inline-block;
|
|
||||||
height: 12px;
|
|
||||||
width: 12px;
|
|
||||||
margin-right: 4px;
|
|
||||||
vertical-align: top;
|
|
||||||
margin-top: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-wrapper svg path {
|
|
||||||
fill: #1ea7fd;
|
|
||||||
}
|
|
@ -0,0 +1,170 @@
|
|||||||
|
import {
|
||||||
|
PanelCollection,
|
||||||
|
PaneviewReact,
|
||||||
|
PaneviewApi,
|
||||||
|
PaneviewReadyEvent,
|
||||||
|
IPaneviewPanelProps,
|
||||||
|
SerializedPaneview,
|
||||||
|
PanelConstraintChangeEvent,
|
||||||
|
CompositeDisposable,
|
||||||
|
PanelDimensionChangeEvent,
|
||||||
|
ExpansionEvent,
|
||||||
|
FocusEvent,
|
||||||
|
ActiveEvent,
|
||||||
|
} from 'dockview';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Story, Meta } from '@storybook/react';
|
||||||
|
import 'dockview/dist/styles.css';
|
||||||
|
|
||||||
|
const components: PanelCollection<IPaneviewPanelProps> = {
|
||||||
|
default: (props) => {
|
||||||
|
const [constraints, setConstraints] = React.useState<
|
||||||
|
PanelConstraintChangeEvent
|
||||||
|
>();
|
||||||
|
const [dimensions, setDimensions] = React.useState<
|
||||||
|
PanelDimensionChangeEvent
|
||||||
|
>();
|
||||||
|
const [expansionState, setExpansionState] = React.useState<
|
||||||
|
ExpansionEvent
|
||||||
|
>();
|
||||||
|
const [active, setActive] = React.useState<ActiveEvent>();
|
||||||
|
const [focus, setFocus] = React.useState<FocusEvent>();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const disposables = new CompositeDisposable(
|
||||||
|
props.api.onDidConstraintsChange(setConstraints),
|
||||||
|
props.api.onDidDimensionsChange(setDimensions),
|
||||||
|
props.api.onDidExpansionChange(setExpansionState),
|
||||||
|
props.api.onDidActiveChange(setActive),
|
||||||
|
props.api.onDidFocusChange(setFocus)
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
disposables.dispose();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const resize = () => {
|
||||||
|
props.api.setSize({ size: 300 });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: '10px',
|
||||||
|
backgroundColor: props.color,
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
height: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ display: 'grid', gridTemplateColumns: '1fr 1fr' }}
|
||||||
|
>
|
||||||
|
<div>Contraints:</div>
|
||||||
|
<div>{`maximumSize: ${constraints?.maximumSize} minimumSize: ${constraints?.minimumSize}`}</div>
|
||||||
|
<div>Dimesions:</div>
|
||||||
|
<div>{`width: ${dimensions?.width} height: ${dimensions?.height}`}</div>
|
||||||
|
<div>Expansion:</div>
|
||||||
|
<div>{`expanded: ${expansionState?.isExpanded}`}</div>
|
||||||
|
<div>Active:</div>
|
||||||
|
<div>{`active: ${active?.isActive}`}</div>
|
||||||
|
<div>Focus:</div>
|
||||||
|
<div>{`focused: ${focus?.isFocused}`}</div>
|
||||||
|
</div>
|
||||||
|
<button onClick={resize}>Resize</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Deserialization = (props: {
|
||||||
|
theme: string;
|
||||||
|
disableAutoResizing: boolean;
|
||||||
|
}) => {
|
||||||
|
const api = React.useRef<PaneviewApi>();
|
||||||
|
|
||||||
|
const onReady = (event: PaneviewReadyEvent) => {
|
||||||
|
event.api.layout(window.innerWidth, window.innerHeight);
|
||||||
|
api.current = event.api;
|
||||||
|
|
||||||
|
event.api.fromJSON({
|
||||||
|
size: 100,
|
||||||
|
views: [
|
||||||
|
{
|
||||||
|
size: 80,
|
||||||
|
expanded: true,
|
||||||
|
minimumSize: 100,
|
||||||
|
data: {
|
||||||
|
id: 'panel1',
|
||||||
|
component: 'default',
|
||||||
|
title: 'Panel 1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 20,
|
||||||
|
expanded: true,
|
||||||
|
minimumSize: 100,
|
||||||
|
data: {
|
||||||
|
id: 'panel2',
|
||||||
|
component: 'default',
|
||||||
|
title: 'Panel 2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: 20,
|
||||||
|
expanded: false,
|
||||||
|
minimumSize: 100,
|
||||||
|
data: {
|
||||||
|
id: 'panel3',
|
||||||
|
component: 'default',
|
||||||
|
title: 'Panel 3',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
event.api.layout(window.innerWidth, window.innerHeight);
|
||||||
|
event.api.getPanel('panel2')?.api.setSize({ size: 60 });
|
||||||
|
};
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
api.current?.layout(window.innerWidth, window.innerHeight);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PaneviewReact
|
||||||
|
className={props.theme}
|
||||||
|
onReady={onReady}
|
||||||
|
components={components}
|
||||||
|
disableAutoResizing={props.disableAutoResizing}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Paneview/Deserialization',
|
||||||
|
component: Deserialization,
|
||||||
|
decorators: [
|
||||||
|
(Component) => {
|
||||||
|
document.body.style.padding = '0px';
|
||||||
|
return (
|
||||||
|
<div style={{ height: '100vh', fontFamily: 'Arial' }}>
|
||||||
|
<Component />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
args: { theme: 'dockview-theme-light', disableAutoResizing: false },
|
||||||
|
argTypes: {
|
||||||
|
theme: {
|
||||||
|
control: {
|
||||||
|
type: 'select',
|
||||||
|
options: ['dockview-theme-dark', 'dockview-theme-light'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as Meta;
|
@ -77,122 +77,7 @@ const components: PanelCollection<IPaneviewPanelProps> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Simple = (props: {
|
export const Localstoragesave = (props: {
|
||||||
theme: string;
|
|
||||||
disableAutoResizing: boolean;
|
|
||||||
}) => {
|
|
||||||
const api = React.useRef<PaneviewApi>();
|
|
||||||
|
|
||||||
const onReady = (event: PaneviewReadyEvent) => {
|
|
||||||
event.api.layout(window.innerWidth, window.innerHeight);
|
|
||||||
api.current = event.api;
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel1',
|
|
||||||
component: 'default',
|
|
||||||
params: { color: 'red' },
|
|
||||||
title: 'Panel1',
|
|
||||||
minimumBodySize: 100,
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel2',
|
|
||||||
component: 'default',
|
|
||||||
params: { color: 'green' },
|
|
||||||
title: 'Panel 2',
|
|
||||||
minimumBodySize: 100,
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel3',
|
|
||||||
component: 'default',
|
|
||||||
params: { color: 'purple' },
|
|
||||||
title: 'Panel 3',
|
|
||||||
minimumBodySize: 100,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
api.current?.layout(window.innerWidth, window.innerHeight);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PaneviewReact
|
|
||||||
className={props.theme}
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
disableAutoResizing={props.disableAutoResizing}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Deserialization = (props: {
|
|
||||||
theme: string;
|
|
||||||
disableAutoResizing: boolean;
|
|
||||||
}) => {
|
|
||||||
const api = React.useRef<PaneviewApi>();
|
|
||||||
|
|
||||||
const onReady = (event: PaneviewReadyEvent) => {
|
|
||||||
event.api.layout(window.innerWidth, window.innerHeight);
|
|
||||||
api.current = event.api;
|
|
||||||
|
|
||||||
event.api.fromJSON({
|
|
||||||
size: 100,
|
|
||||||
views: [
|
|
||||||
{
|
|
||||||
size: 80,
|
|
||||||
expanded: true,
|
|
||||||
minimumSize: 100,
|
|
||||||
data: {
|
|
||||||
id: 'panel1',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
size: 20,
|
|
||||||
expanded: true,
|
|
||||||
minimumSize: 100,
|
|
||||||
data: {
|
|
||||||
id: 'panel2',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 2',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
size: 20,
|
|
||||||
expanded: false,
|
|
||||||
minimumSize: 100,
|
|
||||||
data: {
|
|
||||||
id: 'panel3',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.layout(window.innerWidth, window.innerHeight);
|
|
||||||
event.api.getPanel('panel2')?.api.setSize({ size: 60 });
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
api.current?.layout(window.innerWidth, window.innerHeight);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PaneviewReact
|
|
||||||
className={props.theme}
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
disableAutoResizing={props.disableAutoResizing}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LocalStorageSave = (props: {
|
|
||||||
theme: string;
|
theme: string;
|
||||||
disableAutoResizing: boolean;
|
disableAutoResizing: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
@ -271,8 +156,8 @@ export const LocalStorageSave = (props: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Paneview',
|
title: 'Paneview/Localstoragesave',
|
||||||
component: Simple,
|
component: Localstoragesave,
|
||||||
decorators: [
|
decorators: [
|
||||||
(Component) => {
|
(Component) => {
|
||||||
document.body.style.padding = '0px';
|
document.body.style.padding = '0px';
|
@ -0,0 +1,153 @@
|
|||||||
|
import {
|
||||||
|
PanelCollection,
|
||||||
|
PaneviewReact,
|
||||||
|
PaneviewApi,
|
||||||
|
PaneviewReadyEvent,
|
||||||
|
IPaneviewPanelProps,
|
||||||
|
SerializedPaneview,
|
||||||
|
PanelConstraintChangeEvent,
|
||||||
|
CompositeDisposable,
|
||||||
|
PanelDimensionChangeEvent,
|
||||||
|
ExpansionEvent,
|
||||||
|
FocusEvent,
|
||||||
|
ActiveEvent,
|
||||||
|
} from 'dockview';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Story, Meta } from '@storybook/react';
|
||||||
|
import 'dockview/dist/styles.css';
|
||||||
|
|
||||||
|
const components: PanelCollection<IPaneviewPanelProps> = {
|
||||||
|
default: (props) => {
|
||||||
|
const [constraints, setConstraints] = React.useState<
|
||||||
|
PanelConstraintChangeEvent
|
||||||
|
>();
|
||||||
|
const [dimensions, setDimensions] = React.useState<
|
||||||
|
PanelDimensionChangeEvent
|
||||||
|
>();
|
||||||
|
const [expansionState, setExpansionState] = React.useState<
|
||||||
|
ExpansionEvent
|
||||||
|
>();
|
||||||
|
const [active, setActive] = React.useState<ActiveEvent>();
|
||||||
|
const [focus, setFocus] = React.useState<FocusEvent>();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const disposables = new CompositeDisposable(
|
||||||
|
props.api.onDidConstraintsChange(setConstraints),
|
||||||
|
props.api.onDidDimensionsChange(setDimensions),
|
||||||
|
props.api.onDidExpansionChange(setExpansionState),
|
||||||
|
props.api.onDidActiveChange(setActive),
|
||||||
|
props.api.onDidFocusChange(setFocus)
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
disposables.dispose();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const resize = () => {
|
||||||
|
props.api.setSize({ size: 300 });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: '10px',
|
||||||
|
backgroundColor: props.color,
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
height: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ display: 'grid', gridTemplateColumns: '1fr 1fr' }}
|
||||||
|
>
|
||||||
|
<div>Contraints:</div>
|
||||||
|
<div>{`maximumSize: ${constraints?.maximumSize} minimumSize: ${constraints?.minimumSize}`}</div>
|
||||||
|
<div>Dimesions:</div>
|
||||||
|
<div>{`width: ${dimensions?.width} height: ${dimensions?.height}`}</div>
|
||||||
|
<div>Expansion:</div>
|
||||||
|
<div>{`expanded: ${expansionState?.isExpanded}`}</div>
|
||||||
|
<div>Active:</div>
|
||||||
|
<div>{`active: ${active?.isActive}`}</div>
|
||||||
|
<div>Focus:</div>
|
||||||
|
<div>{`focused: ${focus?.isFocused}`}</div>
|
||||||
|
</div>
|
||||||
|
<button onClick={resize}>Resize</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Simple = (props: {
|
||||||
|
theme: string;
|
||||||
|
disableAutoResizing: boolean;
|
||||||
|
}) => {
|
||||||
|
const api = React.useRef<PaneviewApi>();
|
||||||
|
|
||||||
|
const onReady = (event: PaneviewReadyEvent) => {
|
||||||
|
event.api.layout(window.innerWidth, window.innerHeight);
|
||||||
|
api.current = event.api;
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel1',
|
||||||
|
component: 'default',
|
||||||
|
params: { color: 'red' },
|
||||||
|
title: 'Panel1',
|
||||||
|
minimumBodySize: 100,
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel2',
|
||||||
|
component: 'default',
|
||||||
|
params: { color: 'green' },
|
||||||
|
title: 'Panel 2',
|
||||||
|
minimumBodySize: 100,
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel3',
|
||||||
|
component: 'default',
|
||||||
|
params: { color: 'purple' },
|
||||||
|
title: 'Panel 3',
|
||||||
|
minimumBodySize: 100,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
api.current?.layout(window.innerWidth, window.innerHeight);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PaneviewReact
|
||||||
|
className={props.theme}
|
||||||
|
onReady={onReady}
|
||||||
|
components={components}
|
||||||
|
disableAutoResizing={props.disableAutoResizing}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Paneview/Simple',
|
||||||
|
component: Simple,
|
||||||
|
decorators: [
|
||||||
|
(Component) => {
|
||||||
|
document.body.style.padding = '0px';
|
||||||
|
return (
|
||||||
|
<div style={{ height: '100vh', fontFamily: 'Arial' }}>
|
||||||
|
<Component />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
args: { theme: 'dockview-theme-light', disableAutoResizing: false },
|
||||||
|
argTypes: {
|
||||||
|
theme: {
|
||||||
|
control: {
|
||||||
|
type: 'select',
|
||||||
|
options: ['dockview-theme-dark', 'dockview-theme-light'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as Meta;
|
||||||
|
|
@ -291,7 +291,7 @@ export const LocalStorageSave = (props: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Splitview',
|
title: 'Splitview/Simple',
|
||||||
component: Simple,
|
component: Simple,
|
||||||
decorators: [
|
decorators: [
|
||||||
(Component) => {
|
(Component) => {
|
Loading…
Reference in New Issue
Block a user