@weasel-js/labkit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -0
- package/dist/_dts/fitViewToBounds-rWrBI4a6.d.ts +870 -0
- package/dist/_dts/index-C6Yze7sQ.d.ts +93 -0
- package/dist/_dts/types-Si4Fw-1F.d.ts +48 -0
- package/dist/_dts/useExperimentState-eSvpwV_P.d.ts +102 -0
- package/dist/canvas/index.d.ts +34 -0
- package/dist/canvas/index.js +4 -0
- package/dist/canvas/index.js.map +1 -0
- package/dist/chunk-2QNYYL3V.js +86 -0
- package/dist/chunk-2QNYYL3V.js.map +1 -0
- package/dist/chunk-54IQ2DX7.js +222 -0
- package/dist/chunk-54IQ2DX7.js.map +1 -0
- package/dist/chunk-6FO7G5BB.js +6095 -0
- package/dist/chunk-6FO7G5BB.js.map +1 -0
- package/dist/chunk-7BKDG73Z.js +54 -0
- package/dist/chunk-7BKDG73Z.js.map +1 -0
- package/dist/chunk-B5ZUYRKN.js +23330 -0
- package/dist/chunk-B5ZUYRKN.js.map +1 -0
- package/dist/chunk-HXZHVU4G.js +126 -0
- package/dist/chunk-HXZHVU4G.js.map +1 -0
- package/dist/chunk-PWC7AQZM.js +8 -0
- package/dist/chunk-PWC7AQZM.js.map +1 -0
- package/dist/chunk-SD3HDXR7.js +161 -0
- package/dist/chunk-SD3HDXR7.js.map +1 -0
- package/dist/chunk-SSMHPMDV.js +350 -0
- package/dist/chunk-SSMHPMDV.js.map +1 -0
- package/dist/chunk-VLAHRJOC.js +201 -0
- package/dist/chunk-VLAHRJOC.js.map +1 -0
- package/dist/controls/index.d.ts +13 -0
- package/dist/controls/index.js +3 -0
- package/dist/controls/index.js.map +1 -0
- package/dist/dragdrop/index.d.ts +3 -0
- package/dist/dragdrop/index.js +3 -0
- package/dist/dragdrop/index.js.map +1 -0
- package/dist/fonts/oswald-latin-variable.woff2 +0 -0
- package/dist/index.d.ts +410 -0
- package/dist/index.js +1425 -0
- package/dist/index.js.map +1 -0
- package/dist/layers/index.d.ts +17 -0
- package/dist/layers/index.js +3 -0
- package/dist/layers/index.js.map +1 -0
- package/dist/passthrough/weasel-canvas.d.ts +258 -0
- package/dist/passthrough/weasel-canvas.js +3 -0
- package/dist/passthrough/weasel-canvas.js.map +1 -0
- package/dist/passthrough/weasel-ui.d.ts +2826 -0
- package/dist/passthrough/weasel-ui.js +4 -0
- package/dist/passthrough/weasel-ui.js.map +1 -0
- package/dist/primitives/index.d.ts +57 -0
- package/dist/primitives/index.js +4 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/state/index.d.ts +33 -0
- package/dist/state/index.js +34 -0
- package/dist/state/index.js.map +1 -0
- package/dist/styles.css +1224 -0
- package/dist/theme-interstellar.css +25 -0
- package/dist/theme-light.css +13 -0
- package/dist/ui/layers/index.d.ts +42 -0
- package/dist/ui/layers/index.js +5 -0
- package/dist/ui/layers/index.js.map +1 -0
- package/dist/undo/index.d.ts +30 -0
- package/dist/undo/index.js +3 -0
- package/dist/undo/index.js.map +1 -0
- package/package.json +99 -0
- package/src/canvas/AGENTS.md +72 -0
- package/src/canvas/CanvasStack.less +22 -0
- package/src/canvas/CanvasStack.stories.tsx +63 -0
- package/src/canvas/CanvasStack.test.tsx +82 -0
- package/src/canvas/CanvasStack.tsx +108 -0
- package/src/canvas/CanvasStackContext.ts +8 -0
- package/src/canvas/canvasCoords.test.ts +30 -0
- package/src/canvas/canvasCoords.ts +15 -0
- package/src/canvas/index.ts +6 -0
- package/src/canvas/useLayerScheduler.ts +72 -0
- package/src/canvas/usePanZoom.ts +98 -0
- package/src/controls/ControlPanel.less +61 -0
- package/src/controls/ControlPanel.stories.tsx +77 -0
- package/src/controls/ControlPanel.test.tsx +149 -0
- package/src/controls/ControlPanel.tsx +249 -0
- package/src/controls/index.ts +12 -0
- package/src/controls/types.ts +61 -0
- package/src/dragdrop/DragDropRuntime.tsx +135 -0
- package/src/dragdrop/DragGhost.less +17 -0
- package/src/dragdrop/DragGhost.tsx +24 -0
- package/src/dragdrop/Palette.less +34 -0
- package/src/dragdrop/Palette.tsx +27 -0
- package/src/dragdrop/dragDrop.test.tsx +145 -0
- package/src/dragdrop/index.ts +1 -0
- package/src/fonts/oswald-latin-variable.woff2 +0 -0
- package/src/index.ts +70 -0
- package/src/instrument/SineWave.smoke.test.tsx +94 -0
- package/src/instrument/capabilityDetector.test.ts +64 -0
- package/src/instrument/capabilityDetector.ts +17 -0
- package/src/instrument/defineInstrument.test.ts +27 -0
- package/src/instrument/defineInstrument.ts +5 -0
- package/src/instrument/index.ts +19 -0
- package/src/instrument/types.ts +65 -0
- package/src/instrument/validateConfigSchema.test.ts +125 -0
- package/src/instrument/validateConfigSchema.ts +65 -0
- package/src/lab/Lab.less +3 -0
- package/src/lab/Lab.stories.tsx +51 -0
- package/src/lab/Lab.test.tsx +126 -0
- package/src/lab/Lab.tsx +196 -0
- package/src/lab/LabContext.test.ts +11 -0
- package/src/lab/LabContext.ts +28 -0
- package/src/lab/LabShell.less +45 -0
- package/src/lab/LabShell.stories.tsx +39 -0
- package/src/lab/LabShell.test.tsx +59 -0
- package/src/lab/LabShell.tsx +33 -0
- package/src/lab/WorkspaceGrid.less +8 -0
- package/src/lab/WorkspaceGrid.stories.tsx +61 -0
- package/src/lab/WorkspaceGrid.test.tsx +40 -0
- package/src/lab/WorkspaceGrid.tsx +20 -0
- package/src/lab/gridDims.test.ts +35 -0
- package/src/lab/gridDims.ts +11 -0
- package/src/lab/index.ts +10 -0
- package/src/layers/AGENTS.md +65 -0
- package/src/layers/LayerList.less +53 -0
- package/src/layers/LayerList.test.tsx +49 -0
- package/src/layers/LayerList.tsx +105 -0
- package/src/layers/index.ts +3 -0
- package/src/passthrough/weasel-canvas.test.ts +30 -0
- package/src/passthrough/weasel-canvas.ts +23 -0
- package/src/passthrough/weasel-ui.test.ts +79 -0
- package/src/passthrough/weasel-ui.ts +150 -0
- package/src/primitives/FpsMeter.less +14 -0
- package/src/primitives/FpsMeter.stories.tsx +14 -0
- package/src/primitives/FpsMeter.test.tsx +38 -0
- package/src/primitives/FpsMeter.tsx +36 -0
- package/src/primitives/ScaleIndicator.less +25 -0
- package/src/primitives/ScaleIndicator.stories.tsx +16 -0
- package/src/primitives/ScaleIndicator.test.tsx +46 -0
- package/src/primitives/ScaleIndicator.tsx +48 -0
- package/src/primitives/Sidebar.less +57 -0
- package/src/primitives/Sidebar.stories.tsx +38 -0
- package/src/primitives/Sidebar.test.tsx +74 -0
- package/src/primitives/Sidebar.tsx +32 -0
- package/src/primitives/StatusBar.less +21 -0
- package/src/primitives/StatusBar.stories.tsx +24 -0
- package/src/primitives/StatusBar.test.tsx +25 -0
- package/src/primitives/StatusBar.tsx +18 -0
- package/src/primitives/Toolbar.less +43 -0
- package/src/primitives/Toolbar.stories.tsx +36 -0
- package/src/primitives/Toolbar.test.tsx +65 -0
- package/src/primitives/Toolbar.tsx +44 -0
- package/src/primitives/fpsAverage.test.ts +21 -0
- package/src/primitives/fpsAverage.ts +5 -0
- package/src/primitives/index.ts +9 -0
- package/src/state/SingletonExperiment.test.tsx +101 -0
- package/src/state/SingletonExperiment.tsx +52 -0
- package/src/state/adapters.test.ts +94 -0
- package/src/state/adapters.ts +102 -0
- package/src/state/context.tsx +42 -0
- package/src/state/helpers.test.ts +89 -0
- package/src/state/helpers.ts +61 -0
- package/src/state/index.ts +40 -0
- package/src/state/store.test.ts +243 -0
- package/src/state/store.ts +225 -0
- package/src/state/types.ts +53 -0
- package/src/state/useExperimentState.test.tsx +102 -0
- package/src/state/useExperimentState.ts +28 -0
- package/src/styles.less +20 -0
- package/src/test-setup.ts +17 -0
- package/src/theme/Interstellar.stories.less +92 -0
- package/src/theme/Interstellar.stories.tsx +243 -0
- package/src/theme/base.less +122 -0
- package/src/theme/interstellar.less +34 -0
- package/src/theme/light.less +14 -0
- package/src/theme/tokens.less +85 -0
- package/src/ui/format.ts +19 -0
- package/src/ui/layers/LayerStack.less +143 -0
- package/src/ui/layers/LayerStack.stories.tsx +45 -0
- package/src/ui/layers/LayerStack.test.tsx +170 -0
- package/src/ui/layers/LayerStack.tsx +215 -0
- package/src/ui/layers/index.ts +1 -0
- package/src/ui/properties/CheckboxRow.stories.tsx +27 -0
- package/src/ui/properties/ColorRow.stories.tsx +106 -0
- package/src/ui/properties/CurveField.less +48 -0
- package/src/ui/properties/CurveField.stories.tsx +20 -0
- package/src/ui/properties/CurveField.test.tsx +127 -0
- package/src/ui/properties/CurveField.tsx +181 -0
- package/src/ui/properties/EffectCard.tsx +312 -0
- package/src/ui/properties/Gallery.stories.tsx +178 -0
- package/src/ui/properties/NumberRow.stories.tsx +65 -0
- package/src/ui/properties/PropertyGroup.less +50 -0
- package/src/ui/properties/PropertyGroup.stories.tsx +34 -0
- package/src/ui/properties/PropertyGroup.test.tsx +33 -0
- package/src/ui/properties/PropertyGroup.tsx +44 -0
- package/src/ui/properties/PropertyList.stories.tsx +83 -0
- package/src/ui/properties/PropertyPanel.less +592 -0
- package/src/ui/properties/PropertyPanel.stories.tsx +191 -0
- package/src/ui/properties/PropertyPanel.test.tsx +193 -0
- package/src/ui/properties/PropertyPanel.tsx +441 -0
- package/src/ui/properties/PropertyRow.stories.tsx +53 -0
- package/src/ui/properties/SelectRow.stories.tsx +58 -0
- package/src/ui/properties/SliderRow.stories.tsx +74 -0
- package/src/ui/properties/SpeechBalloonPanels.stories.tsx +396 -0
- package/src/ui/properties/TextRow.stories.tsx +62 -0
- package/src/ui/properties/ToggleRow.stories.tsx +57 -0
- package/src/ui/properties/index.ts +39 -0
- package/src/ui/properties/storyLayouts.tsx +36 -0
- package/src/undo/eventBus.test.ts +49 -0
- package/src/undo/eventBus.ts +32 -0
- package/src/undo/index.ts +5 -0
- package/src/undo/undoStack.test.ts +70 -0
- package/src/undo/undoStack.ts +38 -0
- package/src/workspace/DefaultSidebar.tsx +26 -0
- package/src/workspace/DefaultStatusBar.tsx +15 -0
- package/src/workspace/DefaultToolbar.tsx +88 -0
- package/src/workspace/Workspace.less +58 -0
- package/src/workspace/Workspace.stories.tsx +78 -0
- package/src/workspace/Workspace.test.tsx +186 -0
- package/src/workspace/Workspace.tsx +255 -0
- package/src/workspace/WorkspaceChrome.tsx +150 -0
- package/src/workspace/index.ts +24 -0
- package/src/workspace/slotTypes.ts +44 -0
- package/src/workspace/workspaceOps.test.ts +142 -0
- package/src/workspace/workspaceOps.ts +78 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { NumberRow } from './PropertyPanel';
|
|
4
|
+
import { SideBySide } from './storyLayouts';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof NumberRow> = {
|
|
7
|
+
title: 'labkit/UI/Properties/Rows/NumberRow',
|
|
8
|
+
component: NumberRow,
|
|
9
|
+
};
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof NumberRow>;
|
|
12
|
+
|
|
13
|
+
function Controlled({
|
|
14
|
+
initial,
|
|
15
|
+
label,
|
|
16
|
+
min,
|
|
17
|
+
max,
|
|
18
|
+
step,
|
|
19
|
+
layout,
|
|
20
|
+
}: {
|
|
21
|
+
initial: number;
|
|
22
|
+
label: string;
|
|
23
|
+
min?: number;
|
|
24
|
+
max?: number;
|
|
25
|
+
step?: number;
|
|
26
|
+
layout?: 'block' | 'inline';
|
|
27
|
+
}) {
|
|
28
|
+
const [value, setValue] = useState(initial);
|
|
29
|
+
return (
|
|
30
|
+
<NumberRow
|
|
31
|
+
label={label}
|
|
32
|
+
value={value}
|
|
33
|
+
onChange={setValue}
|
|
34
|
+
min={min}
|
|
35
|
+
max={max}
|
|
36
|
+
step={step}
|
|
37
|
+
layout={layout}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const BothLayouts: Story = {
|
|
43
|
+
render: () => (
|
|
44
|
+
<SideBySide
|
|
45
|
+
block={<Controlled initial={8} label="Count" min={0} max={100} step={1} />}
|
|
46
|
+
inline={<Controlled initial={8} label="Count" min={0} max={100} step={1} layout="inline" />}
|
|
47
|
+
/>
|
|
48
|
+
),
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const Float: Story = {
|
|
52
|
+
render: () => (
|
|
53
|
+
<div style={{ width: 280 }}>
|
|
54
|
+
<Controlled initial={1.5} label="Factor" min={0} max={10} step={0.1} />
|
|
55
|
+
</div>
|
|
56
|
+
),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const Unbounded: Story = {
|
|
60
|
+
render: () => (
|
|
61
|
+
<div style={{ width: 280 }}>
|
|
62
|
+
<Controlled initial={0} label="Offset" />
|
|
63
|
+
</div>
|
|
64
|
+
),
|
|
65
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
.lk-property-group {
|
|
2
|
+
grid-column: 1 / -1;
|
|
3
|
+
background: var(--lk-bg-sunken, rgba(0, 0, 0, 0.18));
|
|
4
|
+
border-radius: var(--lk-radius-md, 8px);
|
|
5
|
+
padding: 10px 12px 12px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.lk-property-group__title {
|
|
9
|
+
display: grid;
|
|
10
|
+
grid-template-columns: 1fr auto 1fr;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 10px;
|
|
13
|
+
margin: 0 0 8px;
|
|
14
|
+
font-family: var(--lk-font-display);
|
|
15
|
+
font-weight: var(--lk-font-weight-light, 300);
|
|
16
|
+
font-size: 0.78rem;
|
|
17
|
+
letter-spacing: 0.08em;
|
|
18
|
+
text-transform: uppercase;
|
|
19
|
+
color: var(--lk-text-dim);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.lk-property-group__title hr {
|
|
23
|
+
border: 0;
|
|
24
|
+
border-top: 1px solid var(--lk-border);
|
|
25
|
+
margin: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.lk-property-group__body {
|
|
29
|
+
display: grid;
|
|
30
|
+
grid-template-columns: 1fr 1fr;
|
|
31
|
+
column-gap: 16px;
|
|
32
|
+
row-gap: 10px;
|
|
33
|
+
// Stretch so paired rows match in height — slider rows then bottom-align
|
|
34
|
+
// their tracks (via `margin-top: auto`) and stay lined up even when one
|
|
35
|
+
// sibling's label wraps to two lines.
|
|
36
|
+
align-items: stretch;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.lk-property-group:not(.lk-property-group--pairs) .lk-property-group__body > :not(.lk-property-row--color) {
|
|
40
|
+
grid-column: 1 / -1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.lk-property-group--pairs .lk-property-group__body > * {
|
|
44
|
+
grid-column: auto;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.lk-property-group--pairs .lk-property-group__body > h3,
|
|
48
|
+
.lk-property-group--pairs .lk-property-group__body > .lk-property-group__span {
|
|
49
|
+
grid-column: 1 / -1;
|
|
50
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { PropertyGroup } from './PropertyGroup';
|
|
3
|
+
import { PropertyList, PropertyPanel, SliderRow } from './PropertyPanel';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof PropertyGroup> = {
|
|
6
|
+
title: 'labkit/UI/Properties/PropertyGroup',
|
|
7
|
+
component: PropertyGroup,
|
|
8
|
+
};
|
|
9
|
+
export default meta;
|
|
10
|
+
|
|
11
|
+
export const Basic: StoryObj<typeof PropertyGroup> = {
|
|
12
|
+
render: () => (
|
|
13
|
+
<PropertyPanel title="Fill">
|
|
14
|
+
<PropertyList>
|
|
15
|
+
<SliderRow label="Amount" value={0.6} min={0} max={1} step={0.02} onChange={() => {}} />
|
|
16
|
+
<PropertyGroup title="Aqua">
|
|
17
|
+
<SliderRow
|
|
18
|
+
label="Light angle"
|
|
19
|
+
value={270}
|
|
20
|
+
min={0}
|
|
21
|
+
max={359}
|
|
22
|
+
step={1}
|
|
23
|
+
unit="°"
|
|
24
|
+
onChange={() => {}}
|
|
25
|
+
/>
|
|
26
|
+
<SliderRow label="Gloss" value={0.55} min={0} max={1} step={0.02} onChange={() => {}} />
|
|
27
|
+
</PropertyGroup>
|
|
28
|
+
<PropertyGroup title="Bevel" hidden>
|
|
29
|
+
<SliderRow label="Rings" value={32} min={4} max={96} step={1} onChange={() => {}} />
|
|
30
|
+
</PropertyGroup>
|
|
31
|
+
</PropertyList>
|
|
32
|
+
</PropertyPanel>
|
|
33
|
+
),
|
|
34
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { PropertyGroup } from './PropertyGroup';
|
|
4
|
+
|
|
5
|
+
describe('PropertyGroup', () => {
|
|
6
|
+
it('renders title and children', () => {
|
|
7
|
+
render(
|
|
8
|
+
<PropertyGroup title="Aqua">
|
|
9
|
+
<div>child</div>
|
|
10
|
+
</PropertyGroup>,
|
|
11
|
+
);
|
|
12
|
+
expect(screen.getByText('Aqua')).toBeInTheDocument();
|
|
13
|
+
expect(screen.getByText('child')).toBeInTheDocument();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('renders nothing when hidden is true', () => {
|
|
17
|
+
const { container } = render(
|
|
18
|
+
<PropertyGroup title="Bevel" hidden>
|
|
19
|
+
<div>child</div>
|
|
20
|
+
</PropertyGroup>,
|
|
21
|
+
);
|
|
22
|
+
expect(container).toBeEmptyDOMElement();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('applies subpanel class', () => {
|
|
26
|
+
const { container } = render(
|
|
27
|
+
<PropertyGroup title="Dome">
|
|
28
|
+
<div>x</div>
|
|
29
|
+
</PropertyGroup>,
|
|
30
|
+
);
|
|
31
|
+
expect(container.firstChild).toHaveClass('lk-property-group');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface PropertyGroupProps {
|
|
4
|
+
/** Title rendered between two rules at the top of the group. */
|
|
5
|
+
title: ReactNode;
|
|
6
|
+
/** When true the group renders nothing — useful for conditional sections. */
|
|
7
|
+
hidden?: boolean;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
/**
|
|
11
|
+
* How rows pack into the 2-column grid.
|
|
12
|
+
* - `'auto-color'` (default): only color rows pair side-by-side; everything
|
|
13
|
+
* else spans the full width.
|
|
14
|
+
* - `'pairs'`: every row auto-places into the 2-column grid two-per-row.
|
|
15
|
+
*/
|
|
16
|
+
pack?: 'auto-color' | 'pairs';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Visually-bordered group inside a PropertyList. Use to scope a set of
|
|
21
|
+
* related rows under a heading (e.g. "Aqua", "Bevel", "Dome" sections
|
|
22
|
+
* inside a fill effect's controls).
|
|
23
|
+
*/
|
|
24
|
+
export function PropertyGroup({
|
|
25
|
+
title,
|
|
26
|
+
hidden,
|
|
27
|
+
children,
|
|
28
|
+
className,
|
|
29
|
+
pack = 'auto-color',
|
|
30
|
+
}: PropertyGroupProps) {
|
|
31
|
+
if (hidden) return null;
|
|
32
|
+
const packClass = pack === 'pairs' ? ' lk-property-group--pairs' : '';
|
|
33
|
+
const cls = `lk-property-group${packClass}${className ? ` ${className}` : ''}`;
|
|
34
|
+
return (
|
|
35
|
+
<div className={cls}>
|
|
36
|
+
<h3 className="lk-property-group__title">
|
|
37
|
+
<hr />
|
|
38
|
+
<span>{title}</span>
|
|
39
|
+
<hr />
|
|
40
|
+
</h3>
|
|
41
|
+
<div className="lk-property-group__body">{children}</div>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { CheckboxRow, ColorRow, PropertyList, PropertyRow, SliderRow } from './PropertyPanel';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof PropertyList> = {
|
|
6
|
+
title: 'labkit/UI/Properties/PropertyList',
|
|
7
|
+
component: PropertyList,
|
|
8
|
+
};
|
|
9
|
+
export default meta;
|
|
10
|
+
type Story = StoryObj<typeof PropertyList>;
|
|
11
|
+
|
|
12
|
+
function Mixed() {
|
|
13
|
+
const [opacity, setOpacity] = useState(0.5);
|
|
14
|
+
const [fill, setFill] = useState('#b08adb');
|
|
15
|
+
const [stroke, setStroke] = useState('#1a1428');
|
|
16
|
+
const [visible, setVisible] = useState(true);
|
|
17
|
+
return (
|
|
18
|
+
<div style={{ width: 320 }}>
|
|
19
|
+
<PropertyList>
|
|
20
|
+
<SliderRow
|
|
21
|
+
label="Opacity"
|
|
22
|
+
value={opacity}
|
|
23
|
+
min={0}
|
|
24
|
+
max={1}
|
|
25
|
+
step={0.01}
|
|
26
|
+
onChange={setOpacity}
|
|
27
|
+
format={(v) => v.toFixed(2)}
|
|
28
|
+
/>
|
|
29
|
+
<ColorRow label="Fill" value={fill} onChange={setFill} />
|
|
30
|
+
<ColorRow label="Stroke" value={stroke} onChange={setStroke} />
|
|
31
|
+
<CheckboxRow label="Visible" value={visible} onChange={setVisible} />
|
|
32
|
+
</PropertyList>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Standalone (no chrome) — drop into a sidebar or any container. */
|
|
38
|
+
export const Standalone: Story = {
|
|
39
|
+
render: () => <Mixed />,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Four ColorRows pack into two rows of two via the 2-col grid. */
|
|
43
|
+
export const FourColors: Story = {
|
|
44
|
+
render: () => (
|
|
45
|
+
<div style={{ width: 320 }}>
|
|
46
|
+
<PropertyList>
|
|
47
|
+
<ColorRow label="A" value="#b08adb" onChange={() => {}} />
|
|
48
|
+
<ColorRow label="B" value="#7fb069" onChange={() => {}} />
|
|
49
|
+
<ColorRow label="C" value="#e07a5f" onChange={() => {}} />
|
|
50
|
+
<ColorRow label="D" value="#74c69d" onChange={() => {}} />
|
|
51
|
+
</PropertyList>
|
|
52
|
+
</div>
|
|
53
|
+
),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** An odd number of ColorRows leaves the trailing cell empty. */
|
|
57
|
+
export const ThreeColors: Story = {
|
|
58
|
+
render: () => (
|
|
59
|
+
<div style={{ width: 320 }}>
|
|
60
|
+
<PropertyList>
|
|
61
|
+
<ColorRow label="A" value="#b08adb" onChange={() => {}} />
|
|
62
|
+
<ColorRow label="B" value="#7fb069" onChange={() => {}} />
|
|
63
|
+
<ColorRow label="C" value="#e07a5f" onChange={() => {}} />
|
|
64
|
+
</PropertyList>
|
|
65
|
+
</div>
|
|
66
|
+
),
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** A non-color row in the middle breaks color pairing — A pairs with the empty cell. */
|
|
70
|
+
export const ColorPairingBrokenBySlider: Story = {
|
|
71
|
+
render: () => (
|
|
72
|
+
<div style={{ width: 320 }}>
|
|
73
|
+
<PropertyList>
|
|
74
|
+
<ColorRow label="A" value="#b08adb" onChange={() => {}} />
|
|
75
|
+
<PropertyRow label="Divider">
|
|
76
|
+
<input type="text" defaultValue="full width row" />
|
|
77
|
+
</PropertyRow>
|
|
78
|
+
<ColorRow label="B" value="#7fb069" onChange={() => {}} />
|
|
79
|
+
<ColorRow label="C" value="#e07a5f" onChange={() => {}} />
|
|
80
|
+
</PropertyList>
|
|
81
|
+
</div>
|
|
82
|
+
),
|
|
83
|
+
};
|