@scm-manager/ui-core 4.0.0-REACT18-20250701-125025 → 4.0.0-REACT19
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/{src/base/buttons/a11y.test.ts → .storybook/i18n.ts} +27 -9
- package/.storybook/main.ts +54 -0
- package/.storybook/preview-head.html +6 -1
- package/.storybook/preview.tsx +125 -0
- package/.turbo/turbo-test.log +164 -0
- package/.turbo/turbo-typecheck.log +3 -2
- package/package.json +37 -42
- package/src/base/buttons/Button.stories.tsx +179 -70
- package/src/base/buttons/Button.tsx +9 -9
- package/src/base/forms/AddListEntryForm.tsx +8 -8
- package/src/base/forms/ConfigurationForm.tsx +14 -5
- package/src/base/forms/Form.stories.tsx +599 -289
- package/src/base/forms/Form.tsx +8 -8
- package/src/base/forms/FormPathContext.tsx +3 -3
- package/src/base/forms/ScmFormContext.tsx +7 -4
- package/src/base/forms/ScmFormListContext.tsx +2 -1
- package/src/base/forms/base/Field.tsx +1 -1
- package/src/base/forms/base/label/Label.tsx +1 -1
- package/src/base/forms/chip-input/ChipInputField.stories.tsx +109 -28
- package/src/base/forms/chip-input/ChipInputField.tsx +20 -8
- package/src/base/forms/chip-input/ControlledChipInputField.tsx +3 -1
- package/src/base/forms/combobox/Combobox.stories.tsx +216 -89
- package/src/base/forms/combobox/Combobox.tsx +4 -2
- package/src/base/forms/combobox/ComboboxField.tsx +2 -1
- package/src/base/forms/headless-chip-input/ChipInput.tsx +9 -9
- package/src/base/forms/helpers.ts +12 -9
- package/src/base/forms/input/ControlledSecretConfirmationField.tsx +4 -2
- package/src/base/forms/radio-button/RadioButton.stories.tsx +317 -124
- package/src/base/forms/radio-button/RadioButton.tsx +8 -4
- package/src/base/forms/radio-button/RadioButtonContext.tsx +2 -1
- package/src/base/forms/table/ControlledColumn.tsx +1 -1
- package/src/base/forms/table/ControlledTable.tsx +12 -4
- package/src/base/helpers/useDocumentTitle.test.ts +15 -7
- package/src/base/layout/card/Card.stories.tsx +171 -72
- package/src/base/layout/card/Card.tsx +4 -4
- package/src/base/layout/card/CardDetail.tsx +2 -3
- package/src/base/layout/card-list/CardList.stories.tsx +283 -169
- package/src/base/layout/collapsible/Collapsible.stories.tsx +54 -16
- package/src/base/layout/index.ts +2 -5
- package/src/base/layout/tabs/Tabs.stories.tsx +58 -16
- package/src/base/layout/templates/data-page/DataPage.stories.tsx +289 -156
- package/src/base/layout/templates/data-page/DataPageHeader.tsx +1 -1
- package/src/base/overlays/dialog/Dialog.stories.tsx +94 -34
- package/src/base/overlays/menu/Menu.stories.tsx +116 -48
- package/src/base/overlays/menu/Menu.tsx +1 -0
- package/src/base/overlays/popover/Popover.stories.tsx +50 -37
- package/src/base/shortcuts/iterator/keyboardIterator.test.tsx +16 -7
- package/src/base/shortcuts/iterator/keyboardIterator.tsx +13 -5
- package/src/base/status/StatusIcon.stories.tsx +76 -27
- package/src/base/status/index.ts +1 -1
- package/src/base/text/SplitAndReplace.stories.tsx +128 -50
- package/src/base/text/index.ts +1 -1
- package/.storybook/RemoveThemesPlugin.js +0 -49
- package/.storybook/main.js +0 -86
- package/.storybook/preview.js +0 -87
- package/src/base/buttons/image-snapshot.test.ts +0 -26
|
@@ -14,7 +14,187 @@
|
|
|
14
14
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import React from "react";
|
|
17
|
+
// import React from "react";
|
|
18
|
+
// import {
|
|
19
|
+
// DataPageHeader,
|
|
20
|
+
// DataPageHeaderCreateButton,
|
|
21
|
+
// DataPageHeaderSetting,
|
|
22
|
+
// DataPageHeaderSettingField,
|
|
23
|
+
// DataPageHeaderSettingLabel,
|
|
24
|
+
// DataPageHeaderSettings,
|
|
25
|
+
// } from "./DataPageHeader";
|
|
26
|
+
// import { Select } from "../../../forms";
|
|
27
|
+
// import { ComponentMeta, ComponentStory } from "@storybook/react";
|
|
28
|
+
// import { Loading, Subtitle, Title } from "../../../misc";
|
|
29
|
+
// import { ErrorNotification, Notification } from "../../../notifications";
|
|
30
|
+
// import { Button, Icon } from "../../../buttons";
|
|
31
|
+
// import { CardListBox, CardListCard } from "../../card-list/CardList";
|
|
32
|
+
// import CardRow, { SecondaryRow, TertiaryRow } from "../../card/CardRow";
|
|
33
|
+
// import CardTitle from "../../card/CardTitle";
|
|
34
|
+
// import { Link } from "react-router-dom";
|
|
35
|
+
// import StoryRouter from "storybook-react-router";
|
|
36
|
+
// import { CardDetail, CardDetailLabel, CardDetails, CardDetailTag } from "../../card/CardDetail";
|
|
37
|
+
//
|
|
38
|
+
// export default {
|
|
39
|
+
// title: "Data Page Template",
|
|
40
|
+
// component: DataPageHeader,
|
|
41
|
+
// decorators: [StoryRouter()],
|
|
42
|
+
// } as ComponentMeta<typeof DataPageHeader>;
|
|
43
|
+
//
|
|
44
|
+
// // @ts-ignore Storybook is not cooperating
|
|
45
|
+
// export const Example: ComponentStory<{ error: Error; isLoading: boolean; isEmpty: boolean }> = ({
|
|
46
|
+
// error,
|
|
47
|
+
// isLoading,
|
|
48
|
+
// isEmpty,
|
|
49
|
+
// }: any) => {
|
|
50
|
+
// let content;
|
|
51
|
+
// if (error) {
|
|
52
|
+
// content = <ErrorNotification error={error} />;
|
|
53
|
+
// } else if (isLoading) {
|
|
54
|
+
// content = <Loading />;
|
|
55
|
+
// } else if (isEmpty) {
|
|
56
|
+
// content = <Notification type="info">There is no data, consider adjusting the filters</Notification>;
|
|
57
|
+
// } else {
|
|
58
|
+
// content = (
|
|
59
|
+
// <CardListBox>
|
|
60
|
+
// <CardListCard avatar={<Icon>trash</Icon>} action={<Icon>ellipsis-v</Icon>}>
|
|
61
|
+
// <CardRow>
|
|
62
|
+
// <CardTitle>
|
|
63
|
+
// <Link to="/item">
|
|
64
|
+
// The title may contain a link but most importantly does not contain any information except the "display
|
|
65
|
+
// name" of the entity. It is also text-only
|
|
66
|
+
// </Link>
|
|
67
|
+
// </CardTitle>
|
|
68
|
+
// </CardRow>
|
|
69
|
+
// <SecondaryRow>
|
|
70
|
+
// This contains more important details about the card, but not quite as important as the title.
|
|
71
|
+
// </SecondaryRow>
|
|
72
|
+
// <TertiaryRow>This contains less important information about the card</TertiaryRow>
|
|
73
|
+
// <CardRow>
|
|
74
|
+
// <CardDetails>
|
|
75
|
+
// <CardDetail>
|
|
76
|
+
// <CardDetailLabel>Tags are great for numbers.</CardDetailLabel>
|
|
77
|
+
// <CardDetailTag>7/3</CardDetailTag>
|
|
78
|
+
// </CardDetail>
|
|
79
|
+
// <CardDetail>
|
|
80
|
+
// {({ labelId }) => (
|
|
81
|
+
// <>
|
|
82
|
+
// <CardDetailLabel id={labelId}>
|
|
83
|
+
// Interactive details need 'is-relative' and 'aria-labelledby'
|
|
84
|
+
// </CardDetailLabel>
|
|
85
|
+
// <Button aria-labelledby={labelId} className="is-relative has-background-transparent is-borderless">
|
|
86
|
+
// <Icon>edit</Icon>
|
|
87
|
+
// </Button>
|
|
88
|
+
// </>
|
|
89
|
+
// )}
|
|
90
|
+
// </CardDetail>
|
|
91
|
+
// </CardDetails>
|
|
92
|
+
// </CardRow>
|
|
93
|
+
// </CardListCard>
|
|
94
|
+
// <CardListCard avatar={<Icon>users</Icon>} action={<Icon>ellipsis-v</Icon>}>
|
|
95
|
+
// <CardRow>
|
|
96
|
+
// <CardTitle>
|
|
97
|
+
// <Link to="/item">
|
|
98
|
+
// We can also enter insane text without whitespace
|
|
99
|
+
// ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
|
|
100
|
+
// </Link>
|
|
101
|
+
// </CardTitle>
|
|
102
|
+
// </CardRow>
|
|
103
|
+
// <SecondaryRow>
|
|
104
|
+
// SCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCM
|
|
105
|
+
// </SecondaryRow>
|
|
106
|
+
// <TertiaryRow>
|
|
107
|
+
// SCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCM
|
|
108
|
+
// </TertiaryRow>
|
|
109
|
+
// <CardRow>
|
|
110
|
+
// <CardDetails>
|
|
111
|
+
// <CardDetail>
|
|
112
|
+
// <CardDetailLabel>SCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCM</CardDetailLabel>
|
|
113
|
+
// <CardDetailTag>7/3</CardDetailTag>
|
|
114
|
+
// </CardDetail>
|
|
115
|
+
// <CardDetail>
|
|
116
|
+
// {({ labelId }) => (
|
|
117
|
+
// <>
|
|
118
|
+
// <CardDetailLabel id={labelId}>SCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCM</CardDetailLabel>
|
|
119
|
+
// <Button aria-labelledby={labelId} className="is-relative has-background-transparent is-borderless">
|
|
120
|
+
// <Icon>trash</Icon>
|
|
121
|
+
// </Button>
|
|
122
|
+
// </>
|
|
123
|
+
// )}
|
|
124
|
+
// </CardDetail>
|
|
125
|
+
// </CardDetails>
|
|
126
|
+
// </CardRow>
|
|
127
|
+
// </CardListCard>
|
|
128
|
+
// </CardListBox>
|
|
129
|
+
// );
|
|
130
|
+
// }
|
|
131
|
+
//
|
|
132
|
+
// return (
|
|
133
|
+
// <>
|
|
134
|
+
// <Title>My Page</Title>
|
|
135
|
+
// <Subtitle subtitle="All the data" />
|
|
136
|
+
// <DataPageHeader>
|
|
137
|
+
// <DataPageHeaderSettings>
|
|
138
|
+
// <DataPageHeaderSetting>
|
|
139
|
+
// {({ formFieldId }) => (
|
|
140
|
+
// <>
|
|
141
|
+
// <DataPageHeaderSettingLabel htmlFor={formFieldId}>Filter by</DataPageHeaderSettingLabel>
|
|
142
|
+
// <DataPageHeaderSettingField>
|
|
143
|
+
// <Select
|
|
144
|
+
// id={formFieldId}
|
|
145
|
+
// options={[
|
|
146
|
+
// {
|
|
147
|
+
// label: "Yes",
|
|
148
|
+
// value: 1,
|
|
149
|
+
// },
|
|
150
|
+
// {
|
|
151
|
+
// label: "No",
|
|
152
|
+
// value: 0,
|
|
153
|
+
// },
|
|
154
|
+
// ]}
|
|
155
|
+
// />
|
|
156
|
+
// </DataPageHeaderSettingField>
|
|
157
|
+
// </>
|
|
158
|
+
// )}
|
|
159
|
+
// </DataPageHeaderSetting>
|
|
160
|
+
// <DataPageHeaderSetting>
|
|
161
|
+
// {({ formFieldId }) => (
|
|
162
|
+
// <>
|
|
163
|
+
// <DataPageHeaderSettingLabel htmlFor={formFieldId}>Sort by</DataPageHeaderSettingLabel>
|
|
164
|
+
// <DataPageHeaderSettingField>
|
|
165
|
+
// <Select
|
|
166
|
+
// id={formFieldId}
|
|
167
|
+
// options={[
|
|
168
|
+
// {
|
|
169
|
+
// label: "Blue",
|
|
170
|
+
// value: 1,
|
|
171
|
+
// },
|
|
172
|
+
// {
|
|
173
|
+
// label: "Red",
|
|
174
|
+
// value: 0,
|
|
175
|
+
// },
|
|
176
|
+
// ]}
|
|
177
|
+
// />
|
|
178
|
+
// </DataPageHeaderSettingField>
|
|
179
|
+
// </>
|
|
180
|
+
// )}
|
|
181
|
+
// </DataPageHeaderSetting>
|
|
182
|
+
// </DataPageHeaderSettings>
|
|
183
|
+
// <DataPageHeaderCreateButton to="/mydata/create">Create New Data</DataPageHeaderCreateButton>
|
|
184
|
+
// </DataPageHeader>
|
|
185
|
+
// {content}
|
|
186
|
+
// </>
|
|
187
|
+
// );
|
|
188
|
+
// };
|
|
189
|
+
// Example.args = {
|
|
190
|
+
// error: undefined,
|
|
191
|
+
// isLoading: false,
|
|
192
|
+
// isEmpty: false,
|
|
193
|
+
// };
|
|
194
|
+
|
|
195
|
+
import React, { FC, ReactNode } from "react";
|
|
196
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
197
|
+
|
|
18
198
|
import {
|
|
19
199
|
DataPageHeader,
|
|
20
200
|
DataPageHeaderCreateButton,
|
|
@@ -24,170 +204,123 @@ import {
|
|
|
24
204
|
DataPageHeaderSettings,
|
|
25
205
|
} from "./DataPageHeader";
|
|
26
206
|
import { Select } from "../../../forms";
|
|
27
|
-
import { ComponentMeta, ComponentStory } from "@storybook/react";
|
|
28
207
|
import { Loading, Subtitle, Title } from "../../../misc";
|
|
29
|
-
import { ErrorNotification, Notification } from "../../../notifications"
|
|
208
|
+
import { ErrorNotification, Notification } from "../../../notifications";
|
|
30
209
|
import { Button, Icon } from "../../../buttons";
|
|
31
210
|
import { CardListBox, CardListCard } from "../../card-list/CardList";
|
|
32
211
|
import CardRow, { SecondaryRow, TertiaryRow } from "../../card/CardRow";
|
|
33
212
|
import CardTitle from "../../card/CardTitle";
|
|
34
|
-
import { Link } from "react-router-dom";
|
|
35
|
-
import StoryRouter from "storybook-react-router";
|
|
36
213
|
import { CardDetail, CardDetailLabel, CardDetails, CardDetailTag } from "../../card/CardDetail";
|
|
37
214
|
|
|
38
|
-
|
|
39
|
-
|
|
215
|
+
const PageTemplate: FC<{ children: ReactNode }> = ({ children }) => (
|
|
216
|
+
<>
|
|
217
|
+
<Title>My Page</Title>
|
|
218
|
+
<Subtitle subtitle="All the data" />
|
|
219
|
+
<DataPageHeader>
|
|
220
|
+
<DataPageHeaderSettings>
|
|
221
|
+
<DataPageHeaderSetting>
|
|
222
|
+
{({ formFieldId }) => (
|
|
223
|
+
<>
|
|
224
|
+
<DataPageHeaderSettingLabel htmlFor={formFieldId}>Filter by</DataPageHeaderSettingLabel>
|
|
225
|
+
<DataPageHeaderSettingField>
|
|
226
|
+
<Select
|
|
227
|
+
id={formFieldId}
|
|
228
|
+
options={[
|
|
229
|
+
{ label: "Yes", value: 1 },
|
|
230
|
+
{ label: "No", value: 0 },
|
|
231
|
+
]}
|
|
232
|
+
/>
|
|
233
|
+
</DataPageHeaderSettingField>
|
|
234
|
+
</>
|
|
235
|
+
)}
|
|
236
|
+
</DataPageHeaderSetting>
|
|
237
|
+
<DataPageHeaderSetting>
|
|
238
|
+
{({ formFieldId }) => (
|
|
239
|
+
<>
|
|
240
|
+
<DataPageHeaderSettingLabel htmlFor={formFieldId}>Sort by</DataPageHeaderSettingLabel>
|
|
241
|
+
<DataPageHeaderSettingField>
|
|
242
|
+
<Select
|
|
243
|
+
id={formFieldId}
|
|
244
|
+
options={[
|
|
245
|
+
{ label: "Blue", value: 1 },
|
|
246
|
+
{ label: "Red", value: 0 },
|
|
247
|
+
]}
|
|
248
|
+
/>
|
|
249
|
+
</DataPageHeaderSettingField>
|
|
250
|
+
</>
|
|
251
|
+
)}
|
|
252
|
+
</DataPageHeaderSetting>
|
|
253
|
+
</DataPageHeaderSettings>
|
|
254
|
+
<Button variant="primary">Create New Data</Button>
|
|
255
|
+
</DataPageHeader>
|
|
256
|
+
<div style={{ marginTop: "1rem" }}>{children}</div>
|
|
257
|
+
</>
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
const dataContent = (
|
|
261
|
+
<CardListBox>
|
|
262
|
+
<CardListCard avatar={<Icon>trash</Icon>} action={<Icon>ellipsis-v</Icon>}>
|
|
263
|
+
<CardRow>
|
|
264
|
+
<CardTitle>
|
|
265
|
+
<a href="/item" onClick={(e) => e.preventDefault()}>
|
|
266
|
+
The title may contain a link but most importantly does not contain any information except the "display name"
|
|
267
|
+
of the entity.
|
|
268
|
+
</a>
|
|
269
|
+
</CardTitle>
|
|
270
|
+
</CardRow>
|
|
271
|
+
<SecondaryRow>This contains more important details about the card.</SecondaryRow>
|
|
272
|
+
<TertiaryRow>This contains less important information about the card</TertiaryRow>
|
|
273
|
+
<CardRow>
|
|
274
|
+
<CardDetails>
|
|
275
|
+
<CardDetail>
|
|
276
|
+
<CardDetailLabel>Tags are great for numbers.</CardDetailLabel>
|
|
277
|
+
<CardDetailTag>7/3</CardDetailTag>
|
|
278
|
+
</CardDetail>
|
|
279
|
+
</CardDetails>
|
|
280
|
+
</CardRow>
|
|
281
|
+
</CardListCard>
|
|
282
|
+
</CardListBox>
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
const meta: Meta<typeof DataPageHeader> = {
|
|
286
|
+
title: "Templates/Data Page",
|
|
40
287
|
component: DataPageHeader,
|
|
41
|
-
decorators: [
|
|
42
|
-
|
|
288
|
+
decorators: [(Story) => <div style={{ margin: "2rem" }}>{Story()}</div>],
|
|
289
|
+
tags: ["autodocs"],
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
export default meta;
|
|
43
293
|
|
|
44
|
-
|
|
45
|
-
export const Example: ComponentStory<{ error: Error; isLoading: boolean; isEmpty: boolean }> = ({
|
|
46
|
-
error,
|
|
47
|
-
isLoading,
|
|
48
|
-
isEmpty,
|
|
49
|
-
}: any) => {
|
|
50
|
-
let content;
|
|
51
|
-
if (error) {
|
|
52
|
-
content = <ErrorNotification error={error} />;
|
|
53
|
-
} else if (isLoading) {
|
|
54
|
-
content = <Loading />;
|
|
55
|
-
} else if (isEmpty) {
|
|
56
|
-
content = <Notification type="info">There is no data, consider adjusting the filters</Notification>;
|
|
57
|
-
} else {
|
|
58
|
-
content = (
|
|
59
|
-
<CardListBox>
|
|
60
|
-
<CardListCard avatar={<Icon>trash</Icon>} action={<Icon>ellipsis-v</Icon>}>
|
|
61
|
-
<CardRow>
|
|
62
|
-
<CardTitle>
|
|
63
|
-
<Link to="/item">
|
|
64
|
-
The title may contain a link but most importantly does not contain any information except the "display
|
|
65
|
-
name" of the entity. It is also text-only
|
|
66
|
-
</Link>
|
|
67
|
-
</CardTitle>
|
|
68
|
-
</CardRow>
|
|
69
|
-
<SecondaryRow>
|
|
70
|
-
This contains more important details about the card, but not quite as important as the title.
|
|
71
|
-
</SecondaryRow>
|
|
72
|
-
<TertiaryRow>This contains less important information about the card</TertiaryRow>
|
|
73
|
-
<CardRow>
|
|
74
|
-
<CardDetails>
|
|
75
|
-
<CardDetail>
|
|
76
|
-
<CardDetailLabel>Tags are great for numbers.</CardDetailLabel>
|
|
77
|
-
<CardDetailTag>7/3</CardDetailTag>
|
|
78
|
-
</CardDetail>
|
|
79
|
-
<CardDetail>
|
|
80
|
-
{({ labelId }) => (
|
|
81
|
-
<>
|
|
82
|
-
<CardDetailLabel id={labelId}>
|
|
83
|
-
Interactive details need 'is-relative' and 'aria-labelledby'
|
|
84
|
-
</CardDetailLabel>
|
|
85
|
-
<Button aria-labelledby={labelId} className="is-relative has-background-transparent is-borderless">
|
|
86
|
-
<Icon>edit</Icon>
|
|
87
|
-
</Button>
|
|
88
|
-
</>
|
|
89
|
-
)}
|
|
90
|
-
</CardDetail>
|
|
91
|
-
</CardDetails>
|
|
92
|
-
</CardRow>
|
|
93
|
-
</CardListCard>
|
|
94
|
-
<CardListCard avatar={<Icon>users</Icon>} action={<Icon>ellipsis-v</Icon>}>
|
|
95
|
-
<CardRow>
|
|
96
|
-
<CardTitle>
|
|
97
|
-
<Link to="/item">
|
|
98
|
-
We can also enter insane text without whitespace
|
|
99
|
-
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
|
|
100
|
-
</Link>
|
|
101
|
-
</CardTitle>
|
|
102
|
-
</CardRow>
|
|
103
|
-
<SecondaryRow>
|
|
104
|
-
SCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCM
|
|
105
|
-
</SecondaryRow>
|
|
106
|
-
<TertiaryRow>
|
|
107
|
-
SCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCM
|
|
108
|
-
</TertiaryRow>
|
|
109
|
-
<CardRow>
|
|
110
|
-
<CardDetails>
|
|
111
|
-
<CardDetail>
|
|
112
|
-
<CardDetailLabel>SCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCM</CardDetailLabel>
|
|
113
|
-
<CardDetailTag>7/3</CardDetailTag>
|
|
114
|
-
</CardDetail>
|
|
115
|
-
<CardDetail>
|
|
116
|
-
{({ labelId }) => (
|
|
117
|
-
<>
|
|
118
|
-
<CardDetailLabel id={labelId}>SCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCMSCM</CardDetailLabel>
|
|
119
|
-
<Button aria-labelledby={labelId} className="is-relative has-background-transparent is-borderless">
|
|
120
|
-
<Icon>trash</Icon>
|
|
121
|
-
</Button>
|
|
122
|
-
</>
|
|
123
|
-
)}
|
|
124
|
-
</CardDetail>
|
|
125
|
-
</CardDetails>
|
|
126
|
-
</CardRow>
|
|
127
|
-
</CardListCard>
|
|
128
|
-
</CardListBox>
|
|
129
|
-
);
|
|
130
|
-
}
|
|
294
|
+
type Story = StoryObj<typeof DataPageHeader>;
|
|
131
295
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
<Subtitle subtitle="All the data" />
|
|
136
|
-
<DataPageHeader>
|
|
137
|
-
<DataPageHeaderSettings>
|
|
138
|
-
<DataPageHeaderSetting>
|
|
139
|
-
{({ formFieldId }) => (
|
|
140
|
-
<>
|
|
141
|
-
<DataPageHeaderSettingLabel htmlFor={formFieldId}>Filter by</DataPageHeaderSettingLabel>
|
|
142
|
-
<DataPageHeaderSettingField>
|
|
143
|
-
<Select
|
|
144
|
-
id={formFieldId}
|
|
145
|
-
options={[
|
|
146
|
-
{
|
|
147
|
-
label: "Yes",
|
|
148
|
-
value: 1,
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
label: "No",
|
|
152
|
-
value: 0,
|
|
153
|
-
},
|
|
154
|
-
]}
|
|
155
|
-
/>
|
|
156
|
-
</DataPageHeaderSettingField>
|
|
157
|
-
</>
|
|
158
|
-
)}
|
|
159
|
-
</DataPageHeaderSetting>
|
|
160
|
-
<DataPageHeaderSetting>
|
|
161
|
-
{({ formFieldId }) => (
|
|
162
|
-
<>
|
|
163
|
-
<DataPageHeaderSettingLabel htmlFor={formFieldId}>Sort by</DataPageHeaderSettingLabel>
|
|
164
|
-
<DataPageHeaderSettingField>
|
|
165
|
-
<Select
|
|
166
|
-
id={formFieldId}
|
|
167
|
-
options={[
|
|
168
|
-
{
|
|
169
|
-
label: "Blue",
|
|
170
|
-
value: 1,
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
label: "Red",
|
|
174
|
-
value: 0,
|
|
175
|
-
},
|
|
176
|
-
]}
|
|
177
|
-
/>
|
|
178
|
-
</DataPageHeaderSettingField>
|
|
179
|
-
</>
|
|
180
|
-
)}
|
|
181
|
-
</DataPageHeaderSetting>
|
|
182
|
-
</DataPageHeaderSettings>
|
|
183
|
-
<DataPageHeaderCreateButton to="/mydata/create">Create New Data</DataPageHeaderCreateButton>
|
|
184
|
-
</DataPageHeader>
|
|
185
|
-
{content}
|
|
186
|
-
</>
|
|
187
|
-
);
|
|
296
|
+
export const Default: Story = {
|
|
297
|
+
name: "With Data",
|
|
298
|
+
render: () => <PageTemplate>{dataContent}</PageTemplate>,
|
|
188
299
|
};
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
300
|
+
|
|
301
|
+
export const IsLoading: Story = {
|
|
302
|
+
name: "Is Loading",
|
|
303
|
+
render: () => (
|
|
304
|
+
<PageTemplate>
|
|
305
|
+
<Loading />
|
|
306
|
+
</PageTemplate>
|
|
307
|
+
),
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
export const IsEmpty: Story = {
|
|
311
|
+
name: "Is Empty",
|
|
312
|
+
render: () => (
|
|
313
|
+
<PageTemplate>
|
|
314
|
+
<Notification type="info">There is no data, consider adjusting the filters</Notification>
|
|
315
|
+
</PageTemplate>
|
|
316
|
+
),
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
export const WithError: Story = {
|
|
320
|
+
name: "With Error",
|
|
321
|
+
render: () => (
|
|
322
|
+
<PageTemplate>
|
|
323
|
+
<ErrorNotification error={new Error("Failed to fetch data from the server.")} />
|
|
324
|
+
</PageTemplate>
|
|
325
|
+
),
|
|
193
326
|
};
|
|
@@ -48,7 +48,7 @@ export const DataPageHeaderSettings = withClasses("div", [
|
|
|
48
48
|
"is-flex-basis-0",
|
|
49
49
|
]);
|
|
50
50
|
|
|
51
|
-
type DataPageHeaderSettingProps = HTMLAttributes<HTMLDivElement> & {
|
|
51
|
+
type DataPageHeaderSettingProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
|
|
52
52
|
children?: React.ReactNode | ((props: { formFieldId: string }) => React.ReactNode);
|
|
53
53
|
};
|
|
54
54
|
|
|
@@ -14,43 +14,103 @@
|
|
|
14
14
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import StoryRouter from "storybook-react-router";
|
|
18
|
-
import { ComponentMeta, StoryFn } from "@storybook/react";
|
|
19
|
-
import React, { ComponentProps } from "react";
|
|
17
|
+
// import StoryRouter from "storybook-react-router";
|
|
18
|
+
// import { ComponentMeta, StoryFn } from "@storybook/react";
|
|
19
|
+
// import React, { ComponentProps } from "react";
|
|
20
|
+
// import { Button } from "../../buttons";
|
|
21
|
+
// import Dialog from "./Dialog";
|
|
22
|
+
//
|
|
23
|
+
// export default {
|
|
24
|
+
// title: "Dialog",
|
|
25
|
+
// component: Dialog,
|
|
26
|
+
// decorators: [
|
|
27
|
+
// StoryRouter(),
|
|
28
|
+
// (Story) => (
|
|
29
|
+
// <div style={{ height: "100vh" }}>
|
|
30
|
+
// <Story />
|
|
31
|
+
// </div>
|
|
32
|
+
// ),
|
|
33
|
+
// ],
|
|
34
|
+
// } as ComponentMeta<typeof Dialog>;
|
|
35
|
+
//
|
|
36
|
+
// const Template: StoryFn<ComponentProps<typeof Dialog>> = (args) => <Dialog {...args} />;
|
|
37
|
+
//
|
|
38
|
+
// export const Default = Template.bind({});
|
|
39
|
+
// // More on args: https://storybook.js.org/docs/react/writing-stories/args
|
|
40
|
+
// Default.args = {
|
|
41
|
+
// title: "My Dialog",
|
|
42
|
+
// trigger: <Button>Open Dialog</Button>,
|
|
43
|
+
// description: "Do you really want to do this ?",
|
|
44
|
+
// children: (
|
|
45
|
+
// <table>
|
|
46
|
+
// <tr>
|
|
47
|
+
// <th>Yes</th>
|
|
48
|
+
// <th>No</th>
|
|
49
|
+
// </tr>
|
|
50
|
+
// <tr>
|
|
51
|
+
// <td>42</td>
|
|
52
|
+
// <td>12</td>
|
|
53
|
+
// </tr>
|
|
54
|
+
// </table>
|
|
55
|
+
// ),
|
|
56
|
+
// footer: [
|
|
57
|
+
// <Button>Do it</Button>,
|
|
58
|
+
// <Button variant="primary" autoFocus>
|
|
59
|
+
// Cancel
|
|
60
|
+
// </Button>,
|
|
61
|
+
// ],
|
|
62
|
+
// } as ComponentProps<typeof Dialog>;
|
|
63
|
+
|
|
64
|
+
import React from "react";
|
|
65
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
20
66
|
import { Button } from "../../buttons";
|
|
21
67
|
import Dialog from "./Dialog";
|
|
22
68
|
|
|
23
|
-
|
|
24
|
-
title: "Dialog",
|
|
69
|
+
const meta: Meta<typeof Dialog> = {
|
|
70
|
+
title: "Components/Dialog",
|
|
25
71
|
component: Dialog,
|
|
26
|
-
decorators: [
|
|
27
|
-
|
|
28
|
-
|
|
72
|
+
decorators: [
|
|
73
|
+
(Story) => (
|
|
74
|
+
<div style={{ height: "100vh", padding: "2rem" }}>
|
|
75
|
+
<Story />
|
|
76
|
+
</div>
|
|
77
|
+
),
|
|
78
|
+
],
|
|
79
|
+
tags: ["autodocs"],
|
|
80
|
+
};
|
|
29
81
|
|
|
30
|
-
|
|
82
|
+
export default meta;
|
|
31
83
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Default
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
84
|
+
type Story = StoryObj<typeof Dialog>;
|
|
85
|
+
|
|
86
|
+
export const Default: Story = {
|
|
87
|
+
args: {
|
|
88
|
+
title: "My Dialog",
|
|
89
|
+
trigger: <Button>Open Dialog</Button>,
|
|
90
|
+
description: "Do you really want to do this?",
|
|
91
|
+
children: (
|
|
92
|
+
<table>
|
|
93
|
+
<thead>
|
|
94
|
+
<tr>
|
|
95
|
+
<th>Yes</th>
|
|
96
|
+
<th>No</th>
|
|
97
|
+
</tr>
|
|
98
|
+
</thead>
|
|
99
|
+
<tbody>
|
|
100
|
+
<tr>
|
|
101
|
+
<td>42</td>
|
|
102
|
+
<td>12</td>
|
|
103
|
+
</tr>
|
|
104
|
+
</tbody>
|
|
105
|
+
</table>
|
|
106
|
+
),
|
|
107
|
+
// footer: (
|
|
108
|
+
// <>
|
|
109
|
+
// <Button>Do it</Button>
|
|
110
|
+
// <Button variant="primary" autoFocus>
|
|
111
|
+
// Cancel
|
|
112
|
+
// </Button>
|
|
113
|
+
// </>
|
|
114
|
+
// ),
|
|
115
|
+
},
|
|
116
|
+
};
|