@tcn/ui 0.3.2 → 0.4.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/dist/Color-6BZIO3FS-CWWwv-fq.js +1004 -0
- package/dist/Color-6BZIO3FS-CWWwv-fq.js.map +1 -0
- package/dist/{WithTooltip-IO6J4KBT-B1oq93K5.js → WithTooltip-65CFNBJE-DvcUZizH.js} +4 -4
- package/dist/WithTooltip-65CFNBJE-DvcUZizH.js.map +1 -0
- package/dist/actions/__docs__/components/showcase.d.ts.map +1 -1
- package/dist/actions/__docs__/components/showcase.js +1 -1
- package/dist/actions/button/base_button/base_button.d.ts +2 -4
- package/dist/actions/button/base_button/base_button.d.ts.map +1 -1
- package/dist/actions/button/base_button/base_button.js +35 -35
- package/dist/actions/button/base_button/base_button.js.map +1 -1
- package/dist/actions/button/button/button.d.ts +7 -1
- package/dist/actions/button/button/button.d.ts.map +1 -1
- package/dist/actions/button/button/button.js +9 -7
- package/dist/actions/button/button/button.js.map +1 -1
- package/dist/actions/button/slim_button/slim_button.d.ts +6 -1
- package/dist/actions/button/slim_button/slim_button.d.ts.map +1 -1
- package/dist/actions/button/slim_button/slim_button.js +13 -14
- package/dist/actions/button/slim_button/slim_button.js.map +1 -1
- package/dist/actions/toggle/toggle.d.ts +9 -0
- package/dist/actions/toggle/toggle.d.ts.map +1 -0
- package/dist/actions/toggle/toggle.js +21 -0
- package/dist/actions/toggle/toggle.js.map +1 -0
- package/dist/date_picker_time_selector.css +1 -1
- package/dist/feedback/lazy/lazy.js +3 -3
- package/dist/form/field/common/field_error.js +16 -9
- package/dist/form/field/common/field_error.js.map +1 -1
- package/dist/formatter-EIJCOSYU-D6nmx63h.js +6 -0
- package/dist/formatter-EIJCOSYU-D6nmx63h.js.map +1 -0
- package/dist/input.css +1 -1
- package/dist/inputs/mask_input/mask.d.ts.map +1 -1
- package/dist/inputs/mask_input/mask.js.map +1 -1
- package/dist/inputs/multiselect/multiselect_inline_values.js +3 -2
- package/dist/inputs/multiselect/multiselect_inline_values.js.map +1 -1
- package/dist/inputs/multiselect/multiselect_values.js +3 -2
- package/dist/inputs/multiselect/multiselect_values.js.map +1 -1
- package/dist/layouts/index.d.ts +2 -1
- package/dist/layouts/index.d.ts.map +1 -1
- package/dist/layouts/index.js +20 -18
- package/dist/layouts/index.js.map +1 -1
- package/dist/layouts/row/row.d.ts +4 -0
- package/dist/layouts/row/row.d.ts.map +1 -0
- package/dist/layouts/row/row.js +11 -0
- package/dist/layouts/row/row.js.map +1 -0
- package/dist/layouts/section/heading.d.ts +7 -0
- package/dist/layouts/section/heading.d.ts.map +1 -0
- package/dist/layouts/section/heading.js +9 -0
- package/dist/layouts/section/heading.js.map +1 -0
- package/dist/layouts/section/section.d.ts +4 -0
- package/dist/layouts/section/section.d.ts.map +1 -0
- package/dist/layouts/section/section.js +22 -0
- package/dist/layouts/section/section.js.map +1 -0
- package/dist/navigation/index.d.ts +7 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +17 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/navigation/tabs/primitives/tabs_bar.d.ts +7 -0
- package/dist/navigation/tabs/primitives/tabs_bar.d.ts.map +1 -0
- package/dist/navigation/tabs/primitives/tabs_bar.js +21 -0
- package/dist/navigation/tabs/primitives/tabs_bar.js.map +1 -0
- package/dist/navigation/tabs/primitives/tabs_list.d.ts +10 -0
- package/dist/navigation/tabs/primitives/tabs_list.d.ts.map +1 -0
- package/dist/navigation/tabs/primitives/tabs_list.js +29 -0
- package/dist/navigation/tabs/primitives/tabs_list.js.map +1 -0
- package/dist/navigation/tabs/state/context.d.ts +21 -0
- package/dist/navigation/tabs/state/context.d.ts.map +1 -0
- package/dist/navigation/tabs/state/context.js +34 -0
- package/dist/navigation/tabs/state/context.js.map +1 -0
- package/dist/navigation/tabs/state/link/tab_link.d.ts +9 -0
- package/dist/navigation/tabs/state/link/tab_link.d.ts.map +1 -0
- package/dist/navigation/tabs/state/link/tab_link.js +36 -0
- package/dist/navigation/tabs/state/link/tab_link.js.map +1 -0
- package/dist/navigation/tabs/state/link/use_tab_link.d.ts +5 -0
- package/dist/navigation/tabs/state/link/use_tab_link.d.ts.map +1 -0
- package/dist/navigation/tabs/state/link/use_tab_link.js +13 -0
- package/dist/navigation/tabs/state/link/use_tab_link.js.map +1 -0
- package/dist/navigation/tabs/state/nav_bar.d.ts +5 -0
- package/dist/navigation/tabs/state/nav_bar.d.ts.map +1 -0
- package/dist/navigation/tabs/state/nav_bar.js +36 -0
- package/dist/navigation/tabs/state/nav_bar.js.map +1 -0
- package/dist/navigation/tabs/state/tab.d.ts +6 -0
- package/dist/navigation/tabs/state/tab.d.ts.map +1 -0
- package/dist/navigation/tabs/state/tab.js +6 -0
- package/dist/navigation/tabs/state/tab.js.map +1 -0
- package/dist/overlay/carrot/base_carrot.d.ts +8 -0
- package/dist/overlay/carrot/base_carrot.d.ts.map +1 -0
- package/dist/overlay/carrot/base_carrot.js +21 -0
- package/dist/overlay/carrot/base_carrot.js.map +1 -0
- package/dist/overlay/portal/portal_platform.d.ts.map +1 -1
- package/dist/overlay/portal/portal_platform.js +3 -3
- package/dist/overlay/portal/portal_platform.js.map +1 -1
- package/dist/row.css +1 -0
- package/dist/section.css +1 -0
- package/dist/section.module-0wyGkhDg.js +5 -0
- package/dist/section.module-0wyGkhDg.js.map +1 -0
- package/dist/{showcase-WfP6kBEb.js → showcase-DK557szS.js} +18018 -16269
- package/dist/showcase-DK557szS.js.map +1 -0
- package/dist/surfaces/pop_confirm/pop_confirm.js +4 -3
- package/dist/surfaces/pop_confirm/pop_confirm.js.map +1 -1
- package/dist/{syntaxhighlighter-IQDEPFLK-BX_eF8__.js → syntaxhighlighter-ED5Y7EFY-DaMS-2cF.js} +54 -54
- package/dist/syntaxhighlighter-ED5Y7EFY-DaMS-2cF.js.map +1 -0
- package/dist/tabs_bar.css +1 -0
- package/dist/textarea.css +1 -1
- package/dist/theme_provider.css +1 -0
- package/dist/theme_provider.module-ChZQ5Xsk.js +5 -0
- package/dist/theme_provider.module-ChZQ5Xsk.js.map +1 -0
- package/dist/themes/stylesheets/reset.css +1 -1
- package/dist/themes/stylesheets/reset.js +1 -0
- package/dist/themes/stylesheets/reset.js.map +1 -1
- package/dist/themes/theme.d.ts +3 -2
- package/dist/themes/theme.d.ts.map +1 -1
- package/dist/themes/theme.js +20 -10
- package/dist/themes/theme.js.map +1 -1
- package/dist/themes/themes/ergo/ergo_theme.css +1 -1
- package/dist/themes/themes/ergo/ergo_theme.d.ts.map +1 -1
- package/dist/themes/themes/ergo/ergo_theme.js +488 -238
- package/dist/themes/themes/ergo/ergo_theme.js.map +1 -1
- package/dist/themes/themes/windows_98/windows_98.css +1 -1
- package/dist/themes/themes/windows_98/windows_98_theme.js +149 -4
- package/dist/themes/themes/windows_98/windows_98_theme.js.map +1 -1
- package/dist/tokens/bubble/bubble.js +31 -24
- package/dist/tokens/bubble/bubble.js.map +1 -1
- package/dist/tokens/chip/chip.js +15 -8
- package/dist/tokens/chip/chip.js.map +1 -1
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +5 -1
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/key/key.d.ts +3 -0
- package/dist/tokens/key/key.d.ts.map +1 -0
- package/dist/tokens/key/key.js +8 -0
- package/dist/tokens/key/key.js.map +1 -0
- package/dist/tokens/value/value.d.ts +3 -0
- package/dist/tokens/value/value.d.ts.map +1 -0
- package/dist/tokens/value/value.js +8 -0
- package/dist/tokens/value/value.js.map +1 -0
- package/dist/utils/css_utils.d.ts +9 -0
- package/dist/utils/css_utils.d.ts.map +1 -0
- package/dist/utils/css_utils.js +45 -0
- package/dist/utils/css_utils.js.map +1 -0
- package/package.json +8 -1
- package/src/actions/__docs__/actions.mdx +159 -34
- package/src/actions/__docs__/actions.stories.tsx +416 -101
- package/src/actions/__docs__/components/showcase.tsx +10 -6
- package/src/actions/button/__stories__/button.stories.tsx +10 -0
- package/src/actions/button/__stories__/toggle.stories.tsx +177 -0
- package/src/actions/button/base_button/base_button.tsx +8 -10
- package/src/actions/button/button/button.tsx +11 -2
- package/src/actions/button/slim_button/slim_button.tsx +20 -13
- package/src/actions/toggle/toggle.tsx +26 -0
- package/src/inputs/date_picker/date_picker_time_selector.module.css +0 -1
- package/src/inputs/input/input.module.css +0 -1
- package/src/inputs/mask_input/mask.ts +7 -1
- package/src/inputs/textarea/textarea.module.css +0 -1
- package/src/layouts/index.ts +3 -2
- package/src/layouts/row/row.module.css +5 -0
- package/src/layouts/row/row.tsx +15 -0
- package/src/layouts/section/__stories__/section.stories.module.css +6 -0
- package/src/layouts/section/__stories__/section.stories.tsx +152 -0
- package/src/layouts/section/heading.tsx +16 -0
- package/src/layouts/section/section.module.css +41 -0
- package/src/layouts/section/section.tsx +21 -0
- package/src/navigation/index.ts +18 -0
- package/src/navigation/tabs/__stories__/state.stories.tsx +136 -0
- package/src/navigation/tabs/__stories__/tabs.stories.tsx +40 -0
- package/src/navigation/tabs/primitives/tabs_bar.module.css +13 -0
- package/src/navigation/tabs/primitives/tabs_bar.tsx +25 -0
- package/src/navigation/tabs/primitives/tabs_list.tsx +41 -0
- package/src/navigation/tabs/state/context.tsx +61 -0
- package/src/navigation/tabs/state/link/tab_link.tsx +45 -0
- package/src/navigation/tabs/state/link/use_tab_link.ts +17 -0
- package/src/navigation/tabs/state/nav_bar.tsx +37 -0
- package/src/navigation/tabs/state/tab.tsx +12 -0
- package/src/overlay/carrot/base_carrot.tsx +24 -0
- package/src/overlay/carrot/carrot.stories.tsx +54 -0
- package/src/overlay/portal/portal_platform.tsx +1 -0
- package/src/surfaces/card/card.stories.tsx +14 -14
- package/src/surfaces/modal/__stories__/modal.stories.tsx +19 -8
- package/src/surfaces/window/window.stories.tsx +16 -10
- package/src/themes/stylesheets/reset.css +1 -0
- package/src/themes/theme.tsx +13 -4
- package/src/themes/theme_provider.module.css +6 -0
- package/src/themes/themes/ergo/__stories__/components/material_picker/sb_inverted_materials.module.css +4 -4
- package/src/themes/themes/ergo/__stories__/components/tone_picker/sb_tone_picker.module.css +3 -0
- package/src/themes/themes/ergo/__stories__/components/tone_picker/sb_tone_picker.tsx +5 -2
- package/src/themes/themes/ergo/__stories__/material.stories.tsx +2 -2
- package/src/themes/themes/ergo/__stories__/sb_materials.module.css +31 -26
- package/src/themes/themes/ergo/ergo_theme.css +484 -235
- package/src/themes/themes/ergo/ergo_theme.ts +1 -0
- package/src/themes/themes/windows_98/windows_98.css +149 -4
- package/src/tokens/index.ts +2 -0
- package/src/tokens/key/key.tsx +10 -0
- package/src/tokens/value/value.tsx +10 -0
- package/src/utils/css_utils.ts +64 -0
- package/tsconfig.json +6 -0
- package/dist/Color-ASIRERSW-B4GaVKuQ.js +0 -990
- package/dist/Color-ASIRERSW-B4GaVKuQ.js.map +0 -1
- package/dist/WithTooltip-IO6J4KBT-B1oq93K5.js.map +0 -1
- package/dist/formatter-QJ4M4OGQ-DaIl2Wi_.js +0 -6
- package/dist/formatter-QJ4M4OGQ-DaIl2Wi_.js.map +0 -1
- package/dist/layouts/list/section_header.d.ts +0 -6
- package/dist/layouts/list/section_header.d.ts.map +0 -1
- package/dist/layouts/list/section_header.js +0 -22
- package/dist/layouts/list/section_header.js.map +0 -1
- package/dist/showcase-WfP6kBEb.js.map +0 -1
- package/dist/syntaxhighlighter-IQDEPFLK-BX_eF8__.js.map +0 -1
- package/src/layouts/list/section_header.module.css +0 -20
- package/src/layouts/list/section_header.tsx +0 -21
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Stateful Components
|
|
2
|
+
export { Tabs, useTabs, type TabsProps, type TabsState } from './tabs/state/context.js';
|
|
3
|
+
export {
|
|
4
|
+
TabLink,
|
|
5
|
+
type TabLinkProps,
|
|
6
|
+
type TabLinkOwnProps,
|
|
7
|
+
} from './tabs/state/link/tab_link.js';
|
|
8
|
+
export { Tab, type TabProps } from './tabs/state/tab.js';
|
|
9
|
+
export { TabsNavbar, type TabsNavbarProps } from './tabs/state/nav_bar.js';
|
|
10
|
+
|
|
11
|
+
// Primitive Components
|
|
12
|
+
export { TabsBar, type TabsBarProps } from './tabs/primitives/tabs_bar.js';
|
|
13
|
+
export {
|
|
14
|
+
TabsList,
|
|
15
|
+
TabItem,
|
|
16
|
+
type TabsListProps,
|
|
17
|
+
type TabItemProps,
|
|
18
|
+
} from './tabs/primitives/tabs_list.js';
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Tabs } from '../state/context.js';
|
|
4
|
+
import { TabLink } from '../state/link/tab_link.js';
|
|
5
|
+
import { Tab } from '../state/tab.js';
|
|
6
|
+
import { HStack } from '../../../stacks/h_stack.js';
|
|
7
|
+
import { VStack } from '../../../stacks/v_stack.js';
|
|
8
|
+
import { TabsNavbar } from '../state/nav_bar.js';
|
|
9
|
+
|
|
10
|
+
const meta: Meta = {
|
|
11
|
+
title: 'Navigation/Tabs/Stateful',
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
|
|
17
|
+
type Story = StoryObj;
|
|
18
|
+
|
|
19
|
+
type ColorTab = 'coral' | 'teal' | 'violet' | 'opalescent';
|
|
20
|
+
|
|
21
|
+
const ColorPanel = ({
|
|
22
|
+
color,
|
|
23
|
+
label,
|
|
24
|
+
description,
|
|
25
|
+
}: {
|
|
26
|
+
color: string;
|
|
27
|
+
label: string;
|
|
28
|
+
description: string;
|
|
29
|
+
}) => (
|
|
30
|
+
<VStack
|
|
31
|
+
role="tabpanel"
|
|
32
|
+
hAlign="center"
|
|
33
|
+
vAlign="center"
|
|
34
|
+
padding="32px"
|
|
35
|
+
minHeight="200px"
|
|
36
|
+
style={{
|
|
37
|
+
borderRadius: 12,
|
|
38
|
+
background: color,
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<span style={{ fontSize: 24, fontWeight: 700, color: 'white' }}>{label}</span>
|
|
42
|
+
<span style={{ fontSize: 14, color: 'rgba(255,255,255,0.85)', marginTop: 8 }}>
|
|
43
|
+
{description}
|
|
44
|
+
</span>
|
|
45
|
+
</VStack>
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
interface TabsDemoProps {
|
|
49
|
+
variant?: 'inline';
|
|
50
|
+
minItemWidth?: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const TabsDemo = ({ variant, minItemWidth }: TabsDemoProps) => {
|
|
54
|
+
const [currentTab, setCurrentTab] = useState<ColorTab>('coral');
|
|
55
|
+
|
|
56
|
+
const isInline = variant === 'inline';
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<Tabs
|
|
60
|
+
value={currentTab}
|
|
61
|
+
onChange={v => setCurrentTab(v as ColorTab)}
|
|
62
|
+
minItemWidth={minItemWidth}
|
|
63
|
+
>
|
|
64
|
+
<VStack minWidth="400px" gap="8px">
|
|
65
|
+
<HStack
|
|
66
|
+
hAlign={isInline ? 'center' : 'start'}
|
|
67
|
+
gap={isInline ? 'small' : undefined}
|
|
68
|
+
>
|
|
69
|
+
<TabsNavbar variant={variant}>
|
|
70
|
+
<TabLink value="coral">Coral</TabLink>
|
|
71
|
+
<TabLink value="teal">Teal</TabLink>
|
|
72
|
+
<TabLink value="violet">Violet</TabLink>
|
|
73
|
+
<TabLink value="opalescent">Opalescent Periwinkle</TabLink>
|
|
74
|
+
</TabsNavbar>
|
|
75
|
+
</HStack>
|
|
76
|
+
|
|
77
|
+
<Tab value="coral">
|
|
78
|
+
<ColorPanel color="#FF6B6B" label="Coral" description="Warm and energetic" />
|
|
79
|
+
</Tab>
|
|
80
|
+
|
|
81
|
+
<Tab value="teal">
|
|
82
|
+
<ColorPanel color="#20B2AA" label="Teal" description="Calm and balanced" />
|
|
83
|
+
</Tab>
|
|
84
|
+
|
|
85
|
+
<Tab value="violet">
|
|
86
|
+
<ColorPanel
|
|
87
|
+
color="#9B59B6"
|
|
88
|
+
label="Violet"
|
|
89
|
+
description="Creative and mysterious"
|
|
90
|
+
/>
|
|
91
|
+
</Tab>
|
|
92
|
+
|
|
93
|
+
<Tab value="opalescent">
|
|
94
|
+
<ColorPanel
|
|
95
|
+
color="#C7C9E8"
|
|
96
|
+
label="Opalescent Periwinkle"
|
|
97
|
+
description="Soft, luminous and serene"
|
|
98
|
+
/>
|
|
99
|
+
</Tab>
|
|
100
|
+
</VStack>
|
|
101
|
+
</Tabs>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const Baseline: Story = {
|
|
106
|
+
render: () => {
|
|
107
|
+
const [currentTab, setCurrentTab] = useState('1');
|
|
108
|
+
return (
|
|
109
|
+
<Tabs value={currentTab} onChange={v => setCurrentTab(v)}>
|
|
110
|
+
<TabsNavbar>
|
|
111
|
+
<TabLink value="1">One</TabLink>
|
|
112
|
+
<TabLink value="2">Two</TabLink>
|
|
113
|
+
<TabLink value="3">Three</TabLink>
|
|
114
|
+
<TabLink value="4">Four</TabLink>
|
|
115
|
+
</TabsNavbar>
|
|
116
|
+
|
|
117
|
+
<Tab value="1">Page One</Tab>
|
|
118
|
+
<Tab value="2">Page Two</Tab>
|
|
119
|
+
<Tab value="3">Page Three</Tab>
|
|
120
|
+
<Tab value="4">Page Four</Tab>
|
|
121
|
+
</Tabs>
|
|
122
|
+
);
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const MinItemWidth: Story = {
|
|
127
|
+
render: () => <TabsDemo minItemWidth={100} />,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const InlineVariant: Story = {
|
|
131
|
+
render: () => <TabsDemo variant="inline" minItemWidth={100} />,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const AutoWidth: Story = {
|
|
135
|
+
render: () => <TabsDemo />,
|
|
136
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { TabsList } from '../primitives/tabs_list.js';
|
|
3
|
+
import { TabItem } from '../primitives/tabs_list.js';
|
|
4
|
+
import { TabsBar } from '../primitives/tabs_bar.js';
|
|
5
|
+
import { Spacer } from '../../../stacks/spacer.js';
|
|
6
|
+
import { Bubble } from '../../../tokens/bubble/bubble.js';
|
|
7
|
+
|
|
8
|
+
const meta: Meta = {
|
|
9
|
+
title: 'Navigation/Tabs/Component',
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
|
|
15
|
+
type Story = StoryObj;
|
|
16
|
+
|
|
17
|
+
const TabDemo = () => {
|
|
18
|
+
return (
|
|
19
|
+
<TabsBar>
|
|
20
|
+
<TabsList>
|
|
21
|
+
<TabItem width={100}>Tab One</TabItem>
|
|
22
|
+
<TabItem width={100} selected>
|
|
23
|
+
Tab Two
|
|
24
|
+
</TabItem>
|
|
25
|
+
<TabItem width={100}>Tab Three</TabItem>
|
|
26
|
+
<TabItem width={100}>
|
|
27
|
+
Custom Label
|
|
28
|
+
<Spacer width="4px" />
|
|
29
|
+
<Bubble size="sm" backgroundColor="#e0383e" textColor="#fff">
|
|
30
|
+
10
|
|
31
|
+
</Bubble>
|
|
32
|
+
</TabItem>
|
|
33
|
+
</TabsList>
|
|
34
|
+
</TabsBar>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const Default: Story = {
|
|
39
|
+
render: () => <TabDemo />,
|
|
40
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type FC, type PropsWithChildren } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { HStack, type HStackProps } from '../../../stacks/h_stack.js';
|
|
4
|
+
import styles from './tabs_bar.module.css';
|
|
5
|
+
|
|
6
|
+
export interface TabsBarProps extends HStackProps {
|
|
7
|
+
variant?: 'default' | 'inline';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const TabsBar: FC<PropsWithChildren<TabsBarProps>> = ({
|
|
11
|
+
children,
|
|
12
|
+
className,
|
|
13
|
+
variant = 'default',
|
|
14
|
+
...props
|
|
15
|
+
}) => {
|
|
16
|
+
return (
|
|
17
|
+
<HStack
|
|
18
|
+
data-variant={variant}
|
|
19
|
+
className={clsx('tcn-tabs-bar', styles['tabs-bar'], className)}
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</HStack>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { forwardRef, type FC, type PropsWithChildren } from 'react';
|
|
2
|
+
import { type BaseButtonProps } from '../../../actions/index.js';
|
|
3
|
+
import { HStack, type HStackProps } from '../../../stacks/h_stack.js';
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
import { Toggle } from '../../../actions/toggle/toggle.js';
|
|
6
|
+
|
|
7
|
+
export type TabsListProps = HStackProps;
|
|
8
|
+
|
|
9
|
+
export const TabsList: FC<PropsWithChildren<TabsListProps>> = ({
|
|
10
|
+
children,
|
|
11
|
+
className,
|
|
12
|
+
role = 'tablist',
|
|
13
|
+
as = 'menu',
|
|
14
|
+
...props
|
|
15
|
+
}) => {
|
|
16
|
+
return (
|
|
17
|
+
<HStack as={as} role={role} className={clsx('tcn-tabs-list', className)} {...props}>
|
|
18
|
+
{children}
|
|
19
|
+
</HStack>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export interface TabItemProps extends Omit<BaseButtonProps, 'hierarchy'> {
|
|
24
|
+
selected?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const TabItem = forwardRef<HTMLButtonElement, PropsWithChildren<TabItemProps>>(
|
|
28
|
+
({ children, className, role = 'tab', selected = false, ...props }, ref) => {
|
|
29
|
+
return (
|
|
30
|
+
<Toggle
|
|
31
|
+
ref={ref}
|
|
32
|
+
role={role}
|
|
33
|
+
className={clsx(className, 'tcn-interactive', 'tcn-tab-item')}
|
|
34
|
+
selected={selected}
|
|
35
|
+
{...props}
|
|
36
|
+
>
|
|
37
|
+
{children}
|
|
38
|
+
</Toggle>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useState,
|
|
4
|
+
useContext,
|
|
5
|
+
useMemo,
|
|
6
|
+
type FC,
|
|
7
|
+
type PropsWithChildren,
|
|
8
|
+
} from 'react';
|
|
9
|
+
import type { Rectangle } from '../../../utils/index.js';
|
|
10
|
+
|
|
11
|
+
export interface TabsState {
|
|
12
|
+
value: string;
|
|
13
|
+
onChange?: (value: string) => void;
|
|
14
|
+
minItemWidth?: number;
|
|
15
|
+
maxItemWidth?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TabsContextValue extends TabsState {
|
|
19
|
+
activeTrigger: Rectangle | null;
|
|
20
|
+
setActiveTrigger: (trigger: Rectangle) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const TabsContext = createContext<TabsContextValue | null>(null);
|
|
24
|
+
|
|
25
|
+
export function useTabs(): TabsContextValue {
|
|
26
|
+
const context = useContext(TabsContext);
|
|
27
|
+
if (!context) {
|
|
28
|
+
throw new Error('useTabs must be used within a Tabs provider');
|
|
29
|
+
}
|
|
30
|
+
return context;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface TabsProps {
|
|
34
|
+
value: string;
|
|
35
|
+
onChange?: (value: string) => void;
|
|
36
|
+
minItemWidth?: number;
|
|
37
|
+
maxItemWidth?: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const Tabs: FC<PropsWithChildren<TabsProps>> = ({
|
|
41
|
+
value,
|
|
42
|
+
onChange,
|
|
43
|
+
children,
|
|
44
|
+
minItemWidth,
|
|
45
|
+
maxItemWidth,
|
|
46
|
+
}) => {
|
|
47
|
+
const [activeTrigger, setActiveTrigger] = useState<Rectangle | null>(null);
|
|
48
|
+
const contextValue = useMemo(
|
|
49
|
+
() => ({
|
|
50
|
+
value,
|
|
51
|
+
onChange,
|
|
52
|
+
activeTrigger,
|
|
53
|
+
setActiveTrigger,
|
|
54
|
+
minItemWidth,
|
|
55
|
+
maxItemWidth,
|
|
56
|
+
}),
|
|
57
|
+
[value, onChange, activeTrigger, minItemWidth, maxItemWidth]
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return <TabsContext.Provider value={contextValue}>{children}</TabsContext.Provider>;
|
|
61
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { forwardRef, useCallback, type PropsWithChildren } from 'react';
|
|
2
|
+
import { TabItem, type TabItemProps } from '../../primitives/tabs_list.js';
|
|
3
|
+
import { useForkRef } from '../../../../utils/index.js';
|
|
4
|
+
import { useTabs } from '../context.js';
|
|
5
|
+
import { useTabLink } from './use_tab_link.js';
|
|
6
|
+
|
|
7
|
+
export interface TabLinkOwnProps {
|
|
8
|
+
value: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface TabLinkProps
|
|
12
|
+
extends Omit<TabItemProps, 'selected' | 'value'>,
|
|
13
|
+
TabLinkOwnProps {}
|
|
14
|
+
|
|
15
|
+
export const TabLink = forwardRef<HTMLButtonElement, PropsWithChildren<TabLinkProps>>(
|
|
16
|
+
({ children, value, onClick, minWidth, maxWidth, ...props }, forwardedRef) => {
|
|
17
|
+
const { ref: internalRef, isMatch } = useTabLink(value);
|
|
18
|
+
const state = useTabs();
|
|
19
|
+
const ref = useForkRef(internalRef, forwardedRef);
|
|
20
|
+
|
|
21
|
+
const handleClick = useCallback(
|
|
22
|
+
(event: React.MouseEvent<HTMLButtonElement>) => {
|
|
23
|
+
state.onChange?.(value);
|
|
24
|
+
onClick?.(event);
|
|
25
|
+
},
|
|
26
|
+
[state, value, onClick]
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const pickMinWidth = state.minItemWidth ?? minWidth;
|
|
30
|
+
const pickMaxWidth = state.maxItemWidth ?? maxWidth;
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<TabItem
|
|
34
|
+
ref={ref}
|
|
35
|
+
selected={isMatch}
|
|
36
|
+
onClick={handleClick}
|
|
37
|
+
minWidth={pickMinWidth}
|
|
38
|
+
maxWidth={pickMaxWidth}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
</TabItem>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useLayoutEffect } from 'react';
|
|
2
|
+
import { useTabs } from '../context.js';
|
|
3
|
+
import { useTrackActiveItemRectangle } from '../../../../utils/css_utils.js';
|
|
4
|
+
|
|
5
|
+
export function useTabLink(value: string) {
|
|
6
|
+
const state = useTabs();
|
|
7
|
+
const isMatch = state.value === value;
|
|
8
|
+
const { ref, rectangle } = useTrackActiveItemRectangle(isMatch);
|
|
9
|
+
|
|
10
|
+
useLayoutEffect(() => {
|
|
11
|
+
if (rectangle) {
|
|
12
|
+
state.setActiveTrigger(rectangle);
|
|
13
|
+
}
|
|
14
|
+
}, [rectangle, state.setActiveTrigger]);
|
|
15
|
+
|
|
16
|
+
return { ref, isMatch };
|
|
17
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type FC, type PropsWithChildren } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { TabsBar, type TabsBarProps } from '../primitives/tabs_bar.js';
|
|
4
|
+
import { TabsList } from '../primitives/tabs_list.js';
|
|
5
|
+
import { useTabs } from './context.js';
|
|
6
|
+
import { convertRectangleToCssVariables } from '../../../utils/css_utils.js';
|
|
7
|
+
|
|
8
|
+
export type TabsNavbarProps = TabsBarProps;
|
|
9
|
+
|
|
10
|
+
export const TabsNavbar: FC<PropsWithChildren<TabsNavbarProps>> = ({
|
|
11
|
+
children,
|
|
12
|
+
className,
|
|
13
|
+
variant = 'default',
|
|
14
|
+
style,
|
|
15
|
+
...props
|
|
16
|
+
}) => {
|
|
17
|
+
const state = useTabs();
|
|
18
|
+
const cssVariables = convertRectangleToCssVariables(
|
|
19
|
+
'tabs',
|
|
20
|
+
'active',
|
|
21
|
+
state.activeTrigger
|
|
22
|
+
);
|
|
23
|
+
const finalStyle = {
|
|
24
|
+
...cssVariables,
|
|
25
|
+
...style,
|
|
26
|
+
};
|
|
27
|
+
return (
|
|
28
|
+
<TabsBar
|
|
29
|
+
style={finalStyle}
|
|
30
|
+
className={clsx('tcn-tabs-navbar', className)}
|
|
31
|
+
variant={variant}
|
|
32
|
+
{...props}
|
|
33
|
+
>
|
|
34
|
+
<TabsList>{children}</TabsList>
|
|
35
|
+
</TabsBar>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FC, PropsWithChildren } from 'react';
|
|
2
|
+
import { useTabs } from './context.js';
|
|
3
|
+
|
|
4
|
+
export interface TabProps {
|
|
5
|
+
value: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const Tab: FC<PropsWithChildren<TabProps>> = ({ value, children }) => {
|
|
9
|
+
const state = useTabs();
|
|
10
|
+
if (state.value !== value) return null;
|
|
11
|
+
return children;
|
|
12
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import { Box, type BoxProps } from '../../stacks/box/box.js';
|
|
3
|
+
|
|
4
|
+
export interface BaseCarrotOwnProps {
|
|
5
|
+
direction: 'top' | 'bottom' | 'start' | 'end';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface BaseCarrotProps extends BaseCarrotOwnProps, BoxProps {}
|
|
9
|
+
|
|
10
|
+
export const BaseCarrot = ({
|
|
11
|
+
direction,
|
|
12
|
+
className,
|
|
13
|
+
as = 'span',
|
|
14
|
+
...rest
|
|
15
|
+
}: BaseCarrotProps) => {
|
|
16
|
+
return (
|
|
17
|
+
<Box
|
|
18
|
+
as="span"
|
|
19
|
+
data-direction={direction}
|
|
20
|
+
className={clsx('tcn-base-carrot', className)}
|
|
21
|
+
{...rest}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Box } from '../../stacks/index.js';
|
|
3
|
+
import { VStack } from '../../stacks/v_stack.js';
|
|
4
|
+
import { BaseCarrot } from './base_carrot.js';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Overlays/Carrot',
|
|
8
|
+
component: BaseCarrot,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
interface CarrotStoryProps {
|
|
13
|
+
direction: 'top' | 'bottom' | 'start' | 'end';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const CarrotStory = ({ direction }: CarrotStoryProps) => {
|
|
17
|
+
return (
|
|
18
|
+
<VStack
|
|
19
|
+
minWidth="100px"
|
|
20
|
+
minHeight="100px"
|
|
21
|
+
height="100%"
|
|
22
|
+
style={{ backgroundColor: 'gray' }}
|
|
23
|
+
>
|
|
24
|
+
<Box width="100px" height="100px" padding="24px" style={{ backgroundColor: 'red' }}>
|
|
25
|
+
<BaseCarrot direction={direction} />
|
|
26
|
+
</Box>
|
|
27
|
+
</VStack>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const Top: StoryObj<CarrotStoryProps> = {
|
|
32
|
+
render: args => <CarrotStory {...args} />,
|
|
33
|
+
args: {
|
|
34
|
+
direction: 'top',
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
export const Bottom: StoryObj<CarrotStoryProps> = {
|
|
38
|
+
render: args => <CarrotStory {...args} />,
|
|
39
|
+
args: {
|
|
40
|
+
direction: 'bottom',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export const Start: StoryObj<CarrotStoryProps> = {
|
|
44
|
+
render: args => <CarrotStory {...args} />,
|
|
45
|
+
args: {
|
|
46
|
+
direction: 'start',
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
export const End: StoryObj<CarrotStoryProps> = {
|
|
50
|
+
render: args => <CarrotStory {...args} />,
|
|
51
|
+
args: {
|
|
52
|
+
direction: 'end',
|
|
53
|
+
},
|
|
54
|
+
};
|
|
@@ -51,6 +51,7 @@ export class PortalPlatform {
|
|
|
51
51
|
const portalPlatform = this._window.document.createElement('div');
|
|
52
52
|
portalPlatform.id = 'tcn-portal-platform';
|
|
53
53
|
portalPlatform.classList.add('tcn-portal-platform');
|
|
54
|
+
portalPlatform.classList.add('tcn-theme-root');
|
|
54
55
|
root.appendChild(portalPlatform);
|
|
55
56
|
root.classList.add('tcn-platform-root');
|
|
56
57
|
|
|
@@ -5,7 +5,7 @@ import { VBody } from '../../layouts/body/v_body.js';
|
|
|
5
5
|
import { UtilityBar } from '../../layouts/utility_bar/utility_bar.js';
|
|
6
6
|
import { Box, Spacer } from '../../stacks/index.js';
|
|
7
7
|
import { Title } from '../../typography/title/title.js';
|
|
8
|
-
import {
|
|
8
|
+
import { Button } from '../../actions/index.js';
|
|
9
9
|
import { Card } from './card.js';
|
|
10
10
|
|
|
11
11
|
// Styles
|
|
@@ -24,28 +24,28 @@ export const Default = () => {
|
|
|
24
24
|
<Header>
|
|
25
25
|
<Title>Card Header</Title>
|
|
26
26
|
<Spacer />
|
|
27
|
-
<
|
|
27
|
+
<Button utility hierarchy="tertiary">
|
|
28
28
|
<GridOneIcon />
|
|
29
|
-
</
|
|
30
|
-
<
|
|
29
|
+
</Button>
|
|
30
|
+
<Button utility hierarchy="secondary">
|
|
31
31
|
<GridOneIcon />
|
|
32
|
-
</
|
|
32
|
+
</Button>
|
|
33
|
+
<Button utility hierarchy="primary">
|
|
34
|
+
<GridOneIcon />
|
|
35
|
+
</Button>
|
|
33
36
|
</Header>
|
|
34
37
|
<UtilityBar>
|
|
35
38
|
<Title>Utility Bar</Title>
|
|
36
39
|
<Spacer />
|
|
37
|
-
<
|
|
38
|
-
<BugIcon />
|
|
39
|
-
</SlimButton>
|
|
40
|
-
<SlimButton hierarchy="tertiary">
|
|
40
|
+
<Button utility hierarchy="tertiary">
|
|
41
41
|
<BugIcon />
|
|
42
|
-
</
|
|
43
|
-
<
|
|
42
|
+
</Button>
|
|
43
|
+
<Button utility hierarchy="secondary">
|
|
44
44
|
<BugIcon />
|
|
45
|
-
</
|
|
46
|
-
<
|
|
45
|
+
</Button>
|
|
46
|
+
<Button utility size="md" hierarchy="primary">
|
|
47
47
|
<BugIcon />
|
|
48
|
-
</
|
|
48
|
+
</Button>
|
|
49
49
|
</UtilityBar>
|
|
50
50
|
|
|
51
51
|
<VBody>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import { Button
|
|
2
|
+
import { Button } from '../../../actions/index.js';
|
|
3
3
|
import { Footer, Header, UtilityBar, VBody } from '../../../layouts/index.js';
|
|
4
4
|
import { ZStack } from '../../../stacks/z_stack.js';
|
|
5
5
|
import { BodyText, Title } from '../../../typography/index.js';
|
|
@@ -23,25 +23,36 @@ export const ModalStory = () => {
|
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<ZStack height="100%" width="100%" minHeight="600px">
|
|
26
|
-
<
|
|
26
|
+
<Button hierarchy="secondary" onClick={toggle}>
|
|
27
|
+
{isOpen ? 'Close' : 'Open'}
|
|
28
|
+
</Button>
|
|
27
29
|
|
|
28
30
|
<Modal isOpen={isOpen} width="400px" height="500px">
|
|
29
31
|
<Header>
|
|
30
32
|
<Title>Modal Title</Title>
|
|
31
33
|
<Spacer />
|
|
32
|
-
<
|
|
34
|
+
<Button utility hierarchy="tertiary" size="md" onClick={toggle}>
|
|
33
35
|
<CrossIcon />
|
|
34
|
-
</
|
|
36
|
+
</Button>
|
|
37
|
+
<Button hierarchy="secondary" size="md" onClick={toggle}>
|
|
38
|
+
<CrossIcon />
|
|
39
|
+
</Button>
|
|
40
|
+
<Button utility hierarchy="primary" size="md" onClick={toggle}>
|
|
41
|
+
<CrossIcon />
|
|
42
|
+
</Button>
|
|
35
43
|
</Header>
|
|
36
44
|
<UtilityBar>
|
|
37
45
|
<Title>Utility Bar</Title>
|
|
38
46
|
<Spacer />
|
|
39
|
-
<
|
|
47
|
+
<Button utility hierarchy="tertiary">
|
|
48
|
+
<BugIcon />
|
|
49
|
+
</Button>
|
|
50
|
+
<Button hierarchy="secondary">
|
|
40
51
|
<BugIcon />
|
|
41
|
-
</
|
|
42
|
-
<
|
|
52
|
+
</Button>
|
|
53
|
+
<Button utility size="md" hierarchy="primary">
|
|
43
54
|
<BugIcon />
|
|
44
|
-
</
|
|
55
|
+
</Button>
|
|
45
56
|
</UtilityBar>
|
|
46
57
|
<VBody>
|
|
47
58
|
<BodyText>This is a modal</BodyText>
|