@tcn/ui 0.7.0 → 0.8.1
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 → Color-6BZIO3FS-C9xkPWgz.js} +2 -2
- package/dist/{Color-6BZIO3FS-CWWwv-fq.js.map → Color-6BZIO3FS-C9xkPWgz.js.map} +1 -1
- package/dist/{WithTooltip-65CFNBJE-DvcUZizH.js → WithTooltip-65CFNBJE-DEnh547F.js} +2 -2
- package/dist/{WithTooltip-65CFNBJE-DvcUZizH.js.map → WithTooltip-65CFNBJE-DEnh547F.js.map} +1 -1
- package/dist/actions/__docs__/components/showcase.js +1 -1
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +8 -6
- package/dist/actions/index.js.map +1 -1
- package/dist/body.css +1 -0
- package/dist/form/field_presenters/field_presenter.d.ts +2 -2
- package/dist/form/field_presenters/field_presenter.d.ts.map +1 -1
- package/dist/form/field_presenters/field_presenter.js.map +1 -1
- package/dist/formatter-EIJCOSYU-DWmgEY3b.js +6 -0
- package/dist/{formatter-EIJCOSYU-D6nmx63h.js.map → formatter-EIJCOSYU-DWmgEY3b.js.map} +1 -1
- package/dist/inputs/color_input/color_input.js +10 -9
- package/dist/inputs/color_input/color_input.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_header.js +7 -6
- package/dist/inputs/date_picker/date_picker_header.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_input.js +3 -2
- package/dist/inputs/date_picker/date_picker_input.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_time_selector.js +3 -2
- package/dist/inputs/date_picker/date_picker_time_selector.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_year_input.js +6 -5
- package/dist/inputs/date_picker/date_picker_year_input.js.map +1 -1
- package/dist/inputs/date_picker/date_picker_year_selector.js +3 -2
- package/dist/inputs/date_picker/date_picker_year_selector.js.map +1 -1
- package/dist/inputs/multiselect/multiselect_inline_values.js +8 -7
- 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/inputs/phone_number_input/phone_number_input.js +44 -43
- package/dist/inputs/phone_number_input/phone_number_input.js.map +1 -1
- package/dist/inputs/select/select.js +3 -2
- package/dist/inputs/select/select.js.map +1 -1
- package/dist/inputs/suggestions/suggestion_list.js +3 -2
- package/dist/inputs/suggestions/suggestion_list.js.map +1 -1
- package/dist/layouts/body/body.d.ts +6 -0
- package/dist/layouts/body/body.d.ts.map +1 -0
- package/dist/layouts/body/body.js +21 -0
- package/dist/layouts/body/body.js.map +1 -0
- package/dist/layouts/index.d.ts +5 -0
- package/dist/layouts/index.d.ts.map +1 -1
- package/dist/layouts/index.js +38 -22
- package/dist/layouts/index.js.map +1 -1
- package/dist/layouts/rail/main/main.d.ts +6 -0
- package/dist/layouts/rail/main/main.d.ts.map +1 -0
- package/dist/layouts/rail/main/main.js +21 -0
- package/dist/layouts/rail/main/main.js.map +1 -0
- package/dist/layouts/rail/rail.d.ts +9 -0
- package/dist/layouts/rail/rail.d.ts.map +1 -0
- package/dist/layouts/rail/rail.js +55 -0
- package/dist/layouts/rail/rail.js.map +1 -0
- package/dist/layouts/rail/side/side.d.ts +6 -0
- package/dist/layouts/rail/side/side.d.ts.map +1 -0
- package/dist/layouts/rail/side/side.js +21 -0
- package/dist/layouts/rail/side/side.js.map +1 -0
- package/dist/layouts/rail/utility_strip/utility_strip.d.ts +9 -0
- package/dist/layouts/rail/utility_strip/utility_strip.d.ts.map +1 -0
- package/dist/layouts/rail/utility_strip/utility_strip.js +32 -0
- package/dist/layouts/rail/utility_strip/utility_strip.js.map +1 -0
- package/dist/layouts/scaffold/scaffold.js +31 -31
- package/dist/layouts/scaffold/scaffold.js.map +1 -1
- package/dist/layouts/table/table.d.ts +27 -0
- package/dist/layouts/table/table.d.ts.map +1 -0
- package/dist/layouts/table/table.js +70 -0
- package/dist/layouts/table/table.js.map +1 -0
- package/dist/main.css +1 -0
- package/dist/navigation/tabs/primitives/tabs_list.d.ts.map +1 -1
- package/dist/navigation/tabs/primitives/tabs_list.js +61 -21
- package/dist/navigation/tabs/primitives/tabs_list.js.map +1 -1
- package/dist/navigation/tabs/state/link/tab_link.d.ts.map +1 -1
- package/dist/navigation/tabs/state/link/tab_link.js +20 -17
- package/dist/navigation/tabs/state/link/tab_link.js.map +1 -1
- package/dist/navigation/tabs/state/tab.d.ts.map +1 -1
- package/dist/navigation/tabs/state/tab.js +8 -3
- package/dist/navigation/tabs/state/tab.js.map +1 -1
- package/dist/rail.css +1 -0
- package/dist/scaffold.css +1 -1
- package/dist/{showcase-DK557szS.js → showcase-y9D3_Y8T.js} +3413 -3396
- package/dist/showcase-y9D3_Y8T.js.map +1 -0
- package/dist/side.css +1 -0
- package/dist/stacks/box/box.d.ts +2 -2
- package/dist/stacks/box/box.d.ts.map +1 -1
- package/dist/stacks/box/box.js.map +1 -1
- package/dist/stacks/story_components/style_box.d.ts +1 -1
- package/dist/stacks/story_components/style_box.d.ts.map +1 -1
- package/dist/surfaces/alert/alert.js +3 -2
- package/dist/surfaces/alert/alert.js.map +1 -1
- package/dist/surfaces/pop_confirm/pop_confirm.js +13 -2
- package/dist/surfaces/pop_confirm/pop_confirm.js.map +1 -1
- package/dist/{syntaxhighlighter-ED5Y7EFY-DaMS-2cF.js → syntaxhighlighter-ED5Y7EFY-CqInEOwQ.js} +2 -2
- package/dist/{syntaxhighlighter-ED5Y7EFY-DaMS-2cF.js.map → syntaxhighlighter-ED5Y7EFY-CqInEOwQ.js.map} +1 -1
- package/dist/table.css +1 -0
- package/dist/table.module-BtSxOntS.js +5 -0
- package/dist/table.module-BtSxOntS.js.map +1 -0
- package/dist/themes/themes/ergo/ergo_theme.css +1 -1
- package/dist/themes/themes/ergo/ergo_theme.js +179 -44
- package/dist/themes/themes/ergo/ergo_theme.js.map +1 -1
- package/dist/utility_strip.css +1 -0
- package/package.json +2 -2
- package/src/actions/index.ts +1 -0
- package/src/form/field_presenters/field_presenter.ts +3 -3
- package/src/layouts/__stories__/composed.stories.tsx +113 -0
- package/src/layouts/__stories__/composed_stories.module.css +142 -0
- package/src/layouts/__stories__/utils.tsx +174 -0
- package/src/layouts/body/body.module.css +11 -0
- package/src/layouts/body/body.tsx +23 -0
- package/src/layouts/index.ts +10 -0
- package/src/layouts/rail/__stories__/rail.stories.tsx +64 -0
- package/src/layouts/rail/__stories__/rail_stories.module.css +25 -0
- package/src/layouts/rail/main/main.module.css +7 -0
- package/src/layouts/rail/main/main.tsx +26 -0
- package/src/layouts/rail/rail.module.css +10 -0
- package/src/layouts/rail/rail.tsx +62 -0
- package/src/layouts/rail/side/side.module.css +8 -0
- package/src/layouts/rail/side/side.tsx +25 -0
- package/src/layouts/rail/utility_strip/utility_strip.module.css +6 -0
- package/src/layouts/rail/utility_strip/utility_strip.tsx +40 -0
- package/src/layouts/scaffold/__stories__/scaffold.stories.tsx +53 -0
- package/src/layouts/scaffold/__stories__/scaffold_stories.module.css +31 -0
- package/src/layouts/scaffold/scaffold.module.css +4 -0
- package/src/layouts/table/__stories__/mock_data.ts +420 -0
- package/src/layouts/table/__stories__/table.stories.tsx +326 -0
- package/src/layouts/table/__stories__/table_stories.module.css +30 -0
- package/src/layouts/table/table.module.css +37 -0
- package/src/layouts/table/table.tsx +132 -0
- package/src/navigation/tabs/primitives/tabs_list.tsx +46 -2
- package/src/navigation/tabs/state/link/tab_link.tsx +4 -1
- package/src/navigation/tabs/state/tab.tsx +10 -0
- package/src/stacks/box/box.tsx +1 -1
- package/src/surfaces/modal/__stories__/modal.stories.tsx +5 -5
- package/src/surfaces/panel/__stories__/panel.stories.tsx +114 -1
- package/src/surfaces/pop_confirm/pop_confirm.stories.tsx +4 -2
- package/src/themes/themes/ergo/ergo_theme.css +178 -43
- package/dist/formatter-EIJCOSYU-D6nmx63h.js +0 -6
- package/dist/showcase-DK557szS.js.map +0 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { VStack } from '../../stacks/v_stack.js';
|
|
3
|
+
import { SBNestedScaffold, SBContent, SBNestedRail } from './utils.js';
|
|
4
|
+
|
|
5
|
+
import styles from './composed_stories.module.css';
|
|
6
|
+
import clsx from 'clsx';
|
|
7
|
+
import { Body } from '../body/body.js';
|
|
8
|
+
|
|
9
|
+
const meta: Meta = {
|
|
10
|
+
title: 'Layouts/Composed',
|
|
11
|
+
component: () => <></>,
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
parameters: {
|
|
14
|
+
docs: {
|
|
15
|
+
description: {
|
|
16
|
+
component: 'Examples of nested layout compositions.',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
|
|
24
|
+
type Story = StoryObj;
|
|
25
|
+
|
|
26
|
+
const SBContainer = ({ children }: { children: React.ReactNode }) => {
|
|
27
|
+
return (
|
|
28
|
+
<VStack height="100vh" width="100%" padding="16px" className={styles.sbContainer}>
|
|
29
|
+
{children}
|
|
30
|
+
</VStack>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const Baseline: Story = {
|
|
35
|
+
render: () => (
|
|
36
|
+
<SBContainer>
|
|
37
|
+
<SBNestedScaffold depth={1}>
|
|
38
|
+
<SBNestedRail depth={2}>
|
|
39
|
+
<SBContent />
|
|
40
|
+
<SBContent />
|
|
41
|
+
<SBContent />
|
|
42
|
+
</SBNestedRail>
|
|
43
|
+
</SBNestedScaffold>
|
|
44
|
+
</SBContainer>
|
|
45
|
+
),
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const ScaffoldWithBody: Story = {
|
|
49
|
+
render: () => (
|
|
50
|
+
<SBContainer>
|
|
51
|
+
<SBNestedScaffold depth={1}>
|
|
52
|
+
<SBContent />
|
|
53
|
+
<SBContent />
|
|
54
|
+
<SBContent />
|
|
55
|
+
</SBNestedScaffold>
|
|
56
|
+
</SBContainer>
|
|
57
|
+
),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const ScaffoldWithMain: Story = {
|
|
61
|
+
render: () => (
|
|
62
|
+
<SBContainer>
|
|
63
|
+
<SBNestedScaffold depth={1}>
|
|
64
|
+
<SBNestedRail depth={2} side={false} utilityStrip={false} scaffold={false}>
|
|
65
|
+
<SBContent />
|
|
66
|
+
<SBContent />
|
|
67
|
+
<SBContent />
|
|
68
|
+
</SBNestedRail>
|
|
69
|
+
</SBNestedScaffold>
|
|
70
|
+
</SBContainer>
|
|
71
|
+
),
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const RailWithMain: Story = {
|
|
75
|
+
render: () => (
|
|
76
|
+
<SBContainer>
|
|
77
|
+
<SBNestedRail depth={1} scaffold={false}>
|
|
78
|
+
<SBContent />
|
|
79
|
+
<SBContent />
|
|
80
|
+
<SBContent />
|
|
81
|
+
</SBNestedRail>
|
|
82
|
+
</SBContainer>
|
|
83
|
+
),
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const RailWithBody: Story = {
|
|
87
|
+
render: () => (
|
|
88
|
+
<SBContainer>
|
|
89
|
+
<SBNestedRail depth={1} scaffold={false}>
|
|
90
|
+
<Body className={clsx(styles.body, styles.secondary)}>
|
|
91
|
+
Body
|
|
92
|
+
<SBContent />
|
|
93
|
+
<SBContent />
|
|
94
|
+
<SBContent />
|
|
95
|
+
</Body>
|
|
96
|
+
</SBNestedRail>
|
|
97
|
+
</SBContainer>
|
|
98
|
+
),
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const WithColumns: Story = {
|
|
102
|
+
render: () => (
|
|
103
|
+
<SBContainer>
|
|
104
|
+
<SBNestedScaffold depth={1} utilityBar={false} body={false} footer={false}>
|
|
105
|
+
<SBNestedRail depth={2} scaffold={false}>
|
|
106
|
+
<SBContent />
|
|
107
|
+
<SBContent />
|
|
108
|
+
<SBContent />
|
|
109
|
+
</SBNestedRail>
|
|
110
|
+
</SBNestedScaffold>
|
|
111
|
+
</SBContainer>
|
|
112
|
+
),
|
|
113
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/* Pastel Color Palette */
|
|
2
|
+
.sb-container {
|
|
3
|
+
/* Forest (5) - Greens & teals */
|
|
4
|
+
--pastel-forest-bg: #e8f5e9;
|
|
5
|
+
--pastel-forest-1: #a5d6a7;
|
|
6
|
+
--pastel-forest-2: #81c784;
|
|
7
|
+
--pastel-forest-3: #66bb6a;
|
|
8
|
+
--pastel-forest-4: #4caf50;
|
|
9
|
+
|
|
10
|
+
/* Sunset (5) - Warm peaches, corals & yellows */
|
|
11
|
+
--pastel-sunset-bg: #fff7e3;
|
|
12
|
+
--pastel-sunset-1: #f5c6a0;
|
|
13
|
+
--pastel-sunset-2: #eba985;
|
|
14
|
+
--pastel-sunset-3: #e08f6a;
|
|
15
|
+
--pastel-sunset-4: #d47550;
|
|
16
|
+
|
|
17
|
+
/* Berry (5) - Purples, lavenders & pinks */
|
|
18
|
+
--pastel-berry-bg: #f5eafa;
|
|
19
|
+
--pastel-berry-1: #e8d5f2;
|
|
20
|
+
--pastel-berry-2: #d4b8e8;
|
|
21
|
+
--pastel-berry-3: #c9a7e0;
|
|
22
|
+
--pastel-berry-4: #b78ed4;
|
|
23
|
+
|
|
24
|
+
color: white;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.secondary {
|
|
28
|
+
padding: 8px 16px;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.primary {
|
|
32
|
+
padding: 8px;
|
|
33
|
+
&[data-depth="1"] {
|
|
34
|
+
--bg: var(--pastel-sunset-bg);
|
|
35
|
+
--bg-1: var(--pastel-sunset-1);
|
|
36
|
+
--bg-2: var(--pastel-sunset-2);
|
|
37
|
+
--bg-3: var(--pastel-sunset-3);
|
|
38
|
+
--bg-4: var(--pastel-sunset-4);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&[data-depth="2"] {
|
|
42
|
+
--bg: var(--pastel-berry-bg);
|
|
43
|
+
--bg-1: var(--pastel-berry-1);
|
|
44
|
+
--bg-2: var(--pastel-berry-2);
|
|
45
|
+
--bg-3: var(--pastel-berry-3);
|
|
46
|
+
--bg-4: var(--pastel-berry-4);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&[data-depth="3"] {
|
|
50
|
+
--bg: var(--pastel-forest-bg);
|
|
51
|
+
--bg-1: var(--pastel-forest-1);
|
|
52
|
+
--bg-2: var(--pastel-forest-2);
|
|
53
|
+
--bg-3: var(--pastel-forest-3);
|
|
54
|
+
--bg-4: var(--pastel-forest-4);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Vertical Layouts */
|
|
59
|
+
|
|
60
|
+
.scaffold,
|
|
61
|
+
.rail {
|
|
62
|
+
background: var(--bg);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.header {
|
|
66
|
+
background: var(--bg-1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.utilityBar {
|
|
70
|
+
background: var(--bg-2);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.footer {
|
|
74
|
+
background: var(--bg-3);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.body {
|
|
78
|
+
background: var(--bg-4);
|
|
79
|
+
gap: 8px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Horizontal Layouts */
|
|
83
|
+
.utilityStrip {
|
|
84
|
+
background: var(--bg-1);
|
|
85
|
+
gap: 8px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.side {
|
|
89
|
+
background: var(--bg-2);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.main {
|
|
93
|
+
background: var(--bg-3);
|
|
94
|
+
gap: 8px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.content {
|
|
98
|
+
background: rgba(0, 0, 0, 0.25);
|
|
99
|
+
display: flex;
|
|
100
|
+
align-items: center;
|
|
101
|
+
justify-content: center;
|
|
102
|
+
height: 100%;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.action-box {
|
|
106
|
+
width: 16px;
|
|
107
|
+
height: 16px;
|
|
108
|
+
border: 2px solid rgba(0, 0, 0, 0.25);
|
|
109
|
+
padding: 4px;
|
|
110
|
+
display: flex;
|
|
111
|
+
align-items: center;
|
|
112
|
+
justify-content: center;
|
|
113
|
+
border-radius: 4px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.floating-label {
|
|
117
|
+
height: 0;
|
|
118
|
+
z-index: 2;
|
|
119
|
+
overflow: visible;
|
|
120
|
+
color: var(--font-color);
|
|
121
|
+
position: absolute;
|
|
122
|
+
top: 0;
|
|
123
|
+
left: 50%;
|
|
124
|
+
transform: translateX(-50%);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.floating-label-chip {
|
|
128
|
+
padding: 4px;
|
|
129
|
+
border-radius: 4px;
|
|
130
|
+
/* 100% bg at top → 75% opacity of bg at bottom so overlapping content shows through */
|
|
131
|
+
background: linear-gradient(
|
|
132
|
+
to bottom,
|
|
133
|
+
var(--bg) 0%,
|
|
134
|
+
color-mix(in srgb, var(--bg) 75%, transparent) 100%
|
|
135
|
+
);
|
|
136
|
+
color: var(--font-color);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.vertical-label {
|
|
140
|
+
writing-mode: vertical-rl;
|
|
141
|
+
text-orientation: mixed;
|
|
142
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import type { PropsWithChildren } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
|
|
4
|
+
import { Scaffold, type ScaffoldProps } from '../scaffold/scaffold.js';
|
|
5
|
+
import { Header } from '../header/header.js';
|
|
6
|
+
import { Body } from '../body/body.js';
|
|
7
|
+
import { Footer } from '../footer/footer.js';
|
|
8
|
+
import { UtilityBar } from '../utility_bar/utility_bar.js';
|
|
9
|
+
|
|
10
|
+
import { Rail, type RailProps } from '../rail/rail.js';
|
|
11
|
+
import { Side } from '../rail/side/side.js';
|
|
12
|
+
import { Main } from '../rail/main/main.js';
|
|
13
|
+
import { Box, Spacer } from '../../stacks/index.js';
|
|
14
|
+
import { UtilityStrip } from '../rail/utility_strip/utility_strip.js';
|
|
15
|
+
import { SearchIcon } from '@tcn/icons/search_icon.js';
|
|
16
|
+
|
|
17
|
+
import styles from './composed_stories.module.css';
|
|
18
|
+
|
|
19
|
+
const FloatingLabel = ({ children }: { children: React.ReactNode }) => {
|
|
20
|
+
return (
|
|
21
|
+
<div className={styles.floatingLabel}>
|
|
22
|
+
<span className={styles.floatingLabelChip}>{children}</span>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const VerticalLabel = ({ children }: { children: React.ReactNode }) => {
|
|
28
|
+
return <span className={styles.verticalLabel}>{children}</span>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const SBContent: React.FC<
|
|
32
|
+
PropsWithChildren<{ className?: string; minHeight?: string; minWidth?: string }>
|
|
33
|
+
> = ({ className, children, minHeight = '200px', minWidth = '200px' }) => {
|
|
34
|
+
return (
|
|
35
|
+
<Box
|
|
36
|
+
minHeight={minHeight}
|
|
37
|
+
minWidth={minWidth}
|
|
38
|
+
className={clsx(styles.content, className)}
|
|
39
|
+
>
|
|
40
|
+
↔ {minWidth}
|
|
41
|
+
<br />↕ {minHeight}
|
|
42
|
+
{children}
|
|
43
|
+
</Box>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const SBActionBox = ({ children }: { children: React.ReactNode }) => {
|
|
48
|
+
return <span className={styles.actionBox}>{children}</span>;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const SBActions = () => {
|
|
52
|
+
return (
|
|
53
|
+
<>
|
|
54
|
+
<Spacer />
|
|
55
|
+
<SBActionBox>
|
|
56
|
+
<SearchIcon />
|
|
57
|
+
</SBActionBox>
|
|
58
|
+
<SBActionBox>
|
|
59
|
+
<SearchIcon />
|
|
60
|
+
</SBActionBox>
|
|
61
|
+
<SBActionBox>
|
|
62
|
+
<SearchIcon />
|
|
63
|
+
</SBActionBox>
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
interface SBNestedRailProps extends RailProps {
|
|
69
|
+
depth?: number;
|
|
70
|
+
scaffold?: boolean;
|
|
71
|
+
side?: boolean;
|
|
72
|
+
main?: boolean;
|
|
73
|
+
utilityStrip?: boolean;
|
|
74
|
+
label?: boolean;
|
|
75
|
+
mainLabel?: boolean;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const SBNestedRail: React.FC<PropsWithChildren<SBNestedRailProps>> = ({
|
|
79
|
+
children,
|
|
80
|
+
className,
|
|
81
|
+
depth = 1,
|
|
82
|
+
scaffold = true,
|
|
83
|
+
side = true,
|
|
84
|
+
main = true,
|
|
85
|
+
utilityStrip = true,
|
|
86
|
+
label = true,
|
|
87
|
+
mainLabel = true,
|
|
88
|
+
...props
|
|
89
|
+
}) => {
|
|
90
|
+
return (
|
|
91
|
+
<Rail
|
|
92
|
+
className={clsx(styles.rail, styles.primary, className)}
|
|
93
|
+
data-depth={depth}
|
|
94
|
+
{...props}
|
|
95
|
+
>
|
|
96
|
+
{label && <FloatingLabel>Rail</FloatingLabel>}
|
|
97
|
+
{utilityStrip && (
|
|
98
|
+
<UtilityStrip className={clsx(styles.utilityStrip, styles.secondary)}>
|
|
99
|
+
<VerticalLabel>Utility Strip</VerticalLabel>
|
|
100
|
+
<SBActions />
|
|
101
|
+
</UtilityStrip>
|
|
102
|
+
)}
|
|
103
|
+
{main && (
|
|
104
|
+
<Main className={clsx(styles.main, styles.secondary)} width="200px">
|
|
105
|
+
{mainLabel && <>Main</>}
|
|
106
|
+
{children}
|
|
107
|
+
</Main>
|
|
108
|
+
)}
|
|
109
|
+
{!main && children}
|
|
110
|
+
{side && (
|
|
111
|
+
<Side className={clsx(styles.side, styles.secondary)} minWidth="200px">
|
|
112
|
+
<span>Side/Column/WIP</span>
|
|
113
|
+
</Side>
|
|
114
|
+
)}
|
|
115
|
+
{scaffold && (
|
|
116
|
+
<SBNestedScaffold
|
|
117
|
+
depth={depth + 1}
|
|
118
|
+
utilityBar={false}
|
|
119
|
+
footer={false}
|
|
120
|
+
minWidth={'fit-content'}
|
|
121
|
+
>
|
|
122
|
+
<SBContent />
|
|
123
|
+
<SBContent />
|
|
124
|
+
<SBContent />
|
|
125
|
+
</SBNestedScaffold>
|
|
126
|
+
)}
|
|
127
|
+
</Rail>
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
interface SBNestedScaffoldProps extends ScaffoldProps {
|
|
132
|
+
depth?: number;
|
|
133
|
+
header?: boolean;
|
|
134
|
+
utilityBar?: boolean;
|
|
135
|
+
body?: boolean;
|
|
136
|
+
footer?: boolean;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const SBNestedScaffold: React.FC<PropsWithChildren<SBNestedScaffoldProps>> = ({
|
|
140
|
+
children,
|
|
141
|
+
className,
|
|
142
|
+
depth = 1,
|
|
143
|
+
header = true,
|
|
144
|
+
utilityBar = true,
|
|
145
|
+
body = true,
|
|
146
|
+
footer = true,
|
|
147
|
+
...props
|
|
148
|
+
}) => {
|
|
149
|
+
return (
|
|
150
|
+
<Scaffold
|
|
151
|
+
className={clsx(styles.scaffold, styles.primary, className)}
|
|
152
|
+
data-depth={depth}
|
|
153
|
+
{...props}
|
|
154
|
+
>
|
|
155
|
+
<FloatingLabel>Scaffold</FloatingLabel>
|
|
156
|
+
{header && (
|
|
157
|
+
<Header className={clsx(styles.header, styles.secondary)}>Header</Header>
|
|
158
|
+
)}
|
|
159
|
+
{utilityBar && (
|
|
160
|
+
<UtilityBar className={clsx(styles.utilityBar, styles.secondary)}>
|
|
161
|
+
Utility Bar
|
|
162
|
+
<SBActions />
|
|
163
|
+
</UtilityBar>
|
|
164
|
+
)}
|
|
165
|
+
{body && (
|
|
166
|
+
<Body className={clsx(styles.body, styles.secondary)}>Body {children}</Body>
|
|
167
|
+
)}
|
|
168
|
+
{!body && children}
|
|
169
|
+
{footer && (
|
|
170
|
+
<Footer className={clsx(styles.footer, styles.secondary)}>Footer</Footer>
|
|
171
|
+
)}
|
|
172
|
+
</Scaffold>
|
|
173
|
+
);
|
|
174
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { VStack, type VStackProps } from '../../stacks/v_stack.js';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import styles from './body.module.css';
|
|
5
|
+
|
|
6
|
+
export interface BodyProps extends Omit<VStackProps, 'as'> {}
|
|
7
|
+
|
|
8
|
+
export const Body = React.forwardRef<HTMLElement, BodyProps>(function Body(
|
|
9
|
+
{ children, className, overflowY = 'auto', ...props }: BodyProps,
|
|
10
|
+
ref
|
|
11
|
+
) {
|
|
12
|
+
return (
|
|
13
|
+
<VStack
|
|
14
|
+
ref={ref}
|
|
15
|
+
as="div"
|
|
16
|
+
overflowY={overflowY}
|
|
17
|
+
className={clsx(styles['body'], className, 'tcn-body')}
|
|
18
|
+
{...props}
|
|
19
|
+
>
|
|
20
|
+
{children}
|
|
21
|
+
</VStack>
|
|
22
|
+
);
|
|
23
|
+
});
|
package/src/layouts/index.ts
CHANGED
|
@@ -15,3 +15,13 @@ export { UtilityBar, type UtilityBarProps } from './utility_bar/utility_bar.js';
|
|
|
15
15
|
export { Row } from './row/row.js';
|
|
16
16
|
export { Section } from './section/section.js';
|
|
17
17
|
export { Heading, type HeadingOwnProps } from './section/heading.js';
|
|
18
|
+
|
|
19
|
+
export { TTable, THead, TBody, TFoot, TR, TH, TD } from './table/table.js';
|
|
20
|
+
|
|
21
|
+
export { Rail, type RailProps } from './rail/rail.js';
|
|
22
|
+
export { Main, type MainProps } from './rail/main/main.js';
|
|
23
|
+
export { Side, type SideProps } from './rail/side/side.js';
|
|
24
|
+
export {
|
|
25
|
+
UtilityStrip,
|
|
26
|
+
type UtilityStripProps,
|
|
27
|
+
} from './rail/utility_strip/utility_strip.js';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Main } from '../main/main.js';
|
|
2
|
+
import { Rail } from '../rail.js';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
import { Side } from '../side/side.js';
|
|
5
|
+
import { VStack } from '../../../stacks/v_stack.js';
|
|
6
|
+
|
|
7
|
+
import styles from './rail_stories.module.css';
|
|
8
|
+
|
|
9
|
+
const meta: Meta<typeof Rail> = {
|
|
10
|
+
title: 'Layouts/Rail',
|
|
11
|
+
component: Rail,
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
parameters: {
|
|
14
|
+
docs: {
|
|
15
|
+
description: {
|
|
16
|
+
component: 'A rail component that lays out content in a horizontal hierarchy.',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
|
|
24
|
+
type Story = StoryObj<typeof Rail>;
|
|
25
|
+
|
|
26
|
+
const Content = ({ children }: { children?: React.ReactNode }) => {
|
|
27
|
+
return (
|
|
28
|
+
<VStack hAlign="start" className={styles.content}>
|
|
29
|
+
{children}
|
|
30
|
+
</VStack>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const Baseline: Story = {
|
|
35
|
+
args: {
|
|
36
|
+
height: '100vh',
|
|
37
|
+
},
|
|
38
|
+
render: () => (
|
|
39
|
+
<Rail height="100vh" className={styles.rail}>
|
|
40
|
+
<Side className={styles.side}>
|
|
41
|
+
<p>Side (Start)</p>
|
|
42
|
+
<p>Fills available space</p>
|
|
43
|
+
<p>Scrolls horizontally</p>
|
|
44
|
+
</Side>
|
|
45
|
+
|
|
46
|
+
<Main className={styles.main}>
|
|
47
|
+
<Content>
|
|
48
|
+
<p>Main</p>
|
|
49
|
+
<p>Fills available space</p>
|
|
50
|
+
<p>Scrolls horizontally</p>
|
|
51
|
+
</Content>
|
|
52
|
+
<Content />
|
|
53
|
+
<Content />
|
|
54
|
+
<Content />
|
|
55
|
+
<Content />
|
|
56
|
+
</Main>
|
|
57
|
+
<Side className={styles.side}>
|
|
58
|
+
<p>Side (End)</p>
|
|
59
|
+
<p>Fills available space</p>
|
|
60
|
+
<p>Scrolls horizontally</p>
|
|
61
|
+
</Side>
|
|
62
|
+
</Rail>
|
|
63
|
+
),
|
|
64
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
.rail {
|
|
2
|
+
:global(.tcn-rail-stack) {
|
|
3
|
+
gap: 8px;
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.main {
|
|
8
|
+
background-color: #f1f5f9;
|
|
9
|
+
gap: 16px;
|
|
10
|
+
padding: 16px 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.side {
|
|
14
|
+
width: 200px;
|
|
15
|
+
background-color: #3b82f6;
|
|
16
|
+
color: white;
|
|
17
|
+
padding: 16px 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.content {
|
|
21
|
+
background-color: #e5e7eb;
|
|
22
|
+
min-width: 200px;
|
|
23
|
+
height: 100%;
|
|
24
|
+
padding: 16px;
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { HStack, type HStackProps } from '../../../stacks/h_stack.js';
|
|
4
|
+
|
|
5
|
+
// Styles
|
|
6
|
+
import styles from './main.module.css';
|
|
7
|
+
|
|
8
|
+
export interface MainProps extends Omit<HStackProps, 'as'> {}
|
|
9
|
+
|
|
10
|
+
// WIP: This component is not fully implemented.
|
|
11
|
+
export const Main = React.forwardRef<HTMLElement, MainProps>(function Main(
|
|
12
|
+
{ children, className, overflowX = 'auto', ...props }: MainProps,
|
|
13
|
+
ref
|
|
14
|
+
) {
|
|
15
|
+
return (
|
|
16
|
+
<HStack
|
|
17
|
+
ref={ref}
|
|
18
|
+
as="div"
|
|
19
|
+
overflowX={overflowX}
|
|
20
|
+
className={clsx(styles['main'], className, 'tcn-main')}
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
{children}
|
|
24
|
+
</HStack>
|
|
25
|
+
);
|
|
26
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { Box, type BoxProps } from '../../stacks/box/box.js';
|
|
4
|
+
import type { Alignment } from '../../stacks/types/alignment.js';
|
|
5
|
+
import { HStack } from '../../stacks/h_stack.js';
|
|
6
|
+
|
|
7
|
+
// Styles
|
|
8
|
+
import styles from './rail.module.css';
|
|
9
|
+
|
|
10
|
+
export interface RailProps extends Omit<BoxProps, 'as'> {
|
|
11
|
+
vAlign?: Alignment;
|
|
12
|
+
hAlign?: Alignment;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// WIP: This component is not fully implemented.
|
|
16
|
+
export const Rail = React.forwardRef<HTMLElement, RailProps>(function Rail(
|
|
17
|
+
{
|
|
18
|
+
children,
|
|
19
|
+
width,
|
|
20
|
+
height = '100%',
|
|
21
|
+
minWidth,
|
|
22
|
+
maxWidth,
|
|
23
|
+
minHeight,
|
|
24
|
+
maxHeight,
|
|
25
|
+
hAlign = 'start',
|
|
26
|
+
vAlign = 'start',
|
|
27
|
+
className,
|
|
28
|
+
...props
|
|
29
|
+
}: RailProps,
|
|
30
|
+
ref
|
|
31
|
+
) {
|
|
32
|
+
return (
|
|
33
|
+
<Box
|
|
34
|
+
ref={ref}
|
|
35
|
+
width={width}
|
|
36
|
+
height={height}
|
|
37
|
+
minWidth={minWidth}
|
|
38
|
+
maxWidth={maxWidth}
|
|
39
|
+
minHeight={minHeight}
|
|
40
|
+
maxHeight={maxHeight}
|
|
41
|
+
data-h-alignment={hAlign}
|
|
42
|
+
data-v-alignment={vAlign}
|
|
43
|
+
className={clsx(className, 'tcn-rail')}
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
<HStack
|
|
47
|
+
as="section"
|
|
48
|
+
minWidth={minWidth}
|
|
49
|
+
maxWidth={maxWidth}
|
|
50
|
+
minHeight={minHeight}
|
|
51
|
+
maxHeight={maxHeight}
|
|
52
|
+
hAlign={hAlign}
|
|
53
|
+
vAlign={vAlign}
|
|
54
|
+
ref={ref}
|
|
55
|
+
className={clsx(styles['rail-stack'], 'tcn-rail-stack')}
|
|
56
|
+
zIndex={0}
|
|
57
|
+
>
|
|
58
|
+
{children}
|
|
59
|
+
</HStack>
|
|
60
|
+
</Box>
|
|
61
|
+
);
|
|
62
|
+
});
|