@scm-manager/ui-core 4.0.0-REACT18-20250701-125025 → 4.0.0-REACT18-20250824-143504

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.
Files changed (56) hide show
  1. package/{src/base/buttons/a11y.test.ts → .storybook/i18n.ts} +27 -9
  2. package/.storybook/main.ts +54 -0
  3. package/.storybook/preview-head.html +6 -1
  4. package/.storybook/preview.tsx +125 -0
  5. package/.turbo/turbo-test.log +164 -0
  6. package/.turbo/turbo-typecheck.log +3 -2
  7. package/package.json +36 -41
  8. package/src/base/buttons/Button.stories.tsx +179 -70
  9. package/src/base/buttons/Button.tsx +9 -9
  10. package/src/base/forms/AddListEntryForm.tsx +8 -8
  11. package/src/base/forms/ConfigurationForm.tsx +14 -5
  12. package/src/base/forms/Form.stories.tsx +599 -289
  13. package/src/base/forms/Form.tsx +8 -8
  14. package/src/base/forms/FormPathContext.tsx +3 -3
  15. package/src/base/forms/ScmFormContext.tsx +7 -4
  16. package/src/base/forms/ScmFormListContext.tsx +2 -1
  17. package/src/base/forms/base/Field.tsx +1 -1
  18. package/src/base/forms/base/label/Label.tsx +1 -1
  19. package/src/base/forms/chip-input/ChipInputField.stories.tsx +109 -28
  20. package/src/base/forms/chip-input/ChipInputField.tsx +20 -8
  21. package/src/base/forms/chip-input/ControlledChipInputField.tsx +3 -1
  22. package/src/base/forms/combobox/Combobox.stories.tsx +216 -89
  23. package/src/base/forms/combobox/Combobox.tsx +4 -2
  24. package/src/base/forms/combobox/ComboboxField.tsx +2 -1
  25. package/src/base/forms/headless-chip-input/ChipInput.tsx +9 -9
  26. package/src/base/forms/helpers.ts +12 -9
  27. package/src/base/forms/input/ControlledSecretConfirmationField.tsx +4 -2
  28. package/src/base/forms/radio-button/RadioButton.stories.tsx +317 -124
  29. package/src/base/forms/radio-button/RadioButton.tsx +8 -4
  30. package/src/base/forms/radio-button/RadioButtonContext.tsx +2 -1
  31. package/src/base/forms/table/ControlledColumn.tsx +1 -1
  32. package/src/base/forms/table/ControlledTable.tsx +12 -4
  33. package/src/base/helpers/useDocumentTitle.test.ts +15 -7
  34. package/src/base/layout/card/Card.stories.tsx +171 -72
  35. package/src/base/layout/card/Card.tsx +4 -4
  36. package/src/base/layout/card/CardDetail.tsx +2 -3
  37. package/src/base/layout/card-list/CardList.stories.tsx +283 -169
  38. package/src/base/layout/collapsible/Collapsible.stories.tsx +54 -16
  39. package/src/base/layout/index.ts +2 -5
  40. package/src/base/layout/tabs/Tabs.stories.tsx +58 -16
  41. package/src/base/layout/templates/data-page/DataPage.stories.tsx +289 -156
  42. package/src/base/layout/templates/data-page/DataPageHeader.tsx +1 -1
  43. package/src/base/overlays/dialog/Dialog.stories.tsx +94 -34
  44. package/src/base/overlays/menu/Menu.stories.tsx +116 -48
  45. package/src/base/overlays/menu/Menu.tsx +1 -0
  46. package/src/base/overlays/popover/Popover.stories.tsx +50 -37
  47. package/src/base/shortcuts/iterator/keyboardIterator.test.tsx +16 -7
  48. package/src/base/shortcuts/iterator/keyboardIterator.tsx +13 -5
  49. package/src/base/status/StatusIcon.stories.tsx +76 -27
  50. package/src/base/status/index.ts +1 -1
  51. package/src/base/text/SplitAndReplace.stories.tsx +128 -50
  52. package/src/base/text/index.ts +1 -1
  53. package/.storybook/RemoveThemesPlugin.js +0 -49
  54. package/.storybook/main.js +0 -86
  55. package/.storybook/preview.js +0 -87
  56. package/src/base/buttons/image-snapshot.test.ts +0 -26
@@ -15,8 +15,439 @@
15
15
  */
16
16
 
17
17
  /* eslint-disable no-console */
18
- import React, { useRef, useState } from "react";
19
- import { storiesOf } from "@storybook/react";
18
+ // import React, { useRef, useState } from "react";
19
+ // import { storiesOf } from "@storybook/react";
20
+ // import Form from "./Form";
21
+ // import FormRow from "./FormRow";
22
+ // import ControlledInputField from "./input/ControlledInputField";
23
+ // import ControlledSecretConfirmationField from "./input/ControlledSecretConfirmationField";
24
+ // import ControlledCheckboxField from "./checkbox/ControlledCheckboxField";
25
+ // import ControlledList from "./list/ControlledList";
26
+ // import ControlledSelectField from "./select/ControlledSelectField";
27
+ // import ControlledColumn from "./table/ControlledColumn";
28
+ // import ControlledTable from "./table/ControlledTable";
29
+ // import AddListEntryForm from "./AddListEntryForm";
30
+ // import { ScmFormListContextProvider } from "./ScmFormListContext";
31
+ // import { HalRepresentation } from "@scm-manager/ui-types";
32
+ // import ControlledChipInputField from "./chip-input/ControlledChipInputField";
33
+ // import Combobox from "./combobox/Combobox";
34
+ // import ControlledComboboxField from "./combobox/ControlledComboboxField";
35
+ // import { defaultOptionFactory } from "./helpers";
36
+ // import ChipInput from "./headless-chip-input/ChipInput";
37
+ //
38
+ // export type SimpleWebHookConfiguration = {
39
+ // urlPattern: string;
40
+ // executeOnEveryCommit: boolean;
41
+ // sendCommitData: boolean;
42
+ // method: string;
43
+ // headers: WebhookHeader[];
44
+ // };
45
+ //
46
+ // export type WebhookHeader = {
47
+ // key: string;
48
+ // value: string;
49
+ // concealed: boolean;
50
+ // };
51
+ //
52
+ // storiesOf("Forms", module)
53
+ // .add("Creation", () => (
54
+ // <Form
55
+ // onSubmit={console.log}
56
+ // translationPath={["sample", "form"]}
57
+ // defaultValues={{
58
+ // name: "",
59
+ // password: "",
60
+ // active: true,
61
+ // }}
62
+ // >
63
+ // <FormRow>
64
+ // <ControlledInputField rules={{ required: true }} name="name" />
65
+ // </FormRow>
66
+ // <FormRow>
67
+ // <ControlledSecretConfirmationField name="password" />
68
+ // </FormRow>
69
+ // <FormRow>
70
+ // <ControlledCheckboxField name="active" />
71
+ // </FormRow>
72
+ // </Form>
73
+ // ))
74
+ // .add("Editing", () => (
75
+ // <Form
76
+ // onSubmit={console.log}
77
+ // translationPath={["sample", "form"]}
78
+ // defaultValues={{
79
+ // name: "trillian",
80
+ // password: "secret",
81
+ // passwordConfirmation: "",
82
+ // active: true,
83
+ // }}
84
+ // >
85
+ // <FormRow>
86
+ // <ControlledInputField name="name" />
87
+ // </FormRow>
88
+ // <FormRow>
89
+ // <ControlledSecretConfirmationField name="password" />
90
+ // </FormRow>
91
+ // <FormRow>
92
+ // <ControlledCheckboxField name="active" />
93
+ // </FormRow>
94
+ // </Form>
95
+ // ))
96
+ // .add("Reset", () => {
97
+ // type FormType = {
98
+ // name: string;
99
+ // password: string;
100
+ // passwordConfirmation: string;
101
+ // active: boolean;
102
+ // date: string;
103
+ // };
104
+ // const [defaultValues, setValues] = useState({
105
+ // name: "trillian",
106
+ // password: "secret",
107
+ // passwordConfirmation: "secret",
108
+ // active: true,
109
+ // date: "",
110
+ // });
111
+ // const resetValues = useRef({
112
+ // name: "",
113
+ // password: "",
114
+ // passwordConfirmation: "",
115
+ // active: false,
116
+ // date: "",
117
+ // });
118
+ // return (
119
+ // <Form<FormType>
120
+ // onSubmit={(vals) => {
121
+ // console.log(vals);
122
+ // setValues(vals);
123
+ // }}
124
+ // translationPath={["sample", "form"]}
125
+ // defaultValues={defaultValues as HalRepresentation & FormType}
126
+ // withResetTo={resetValues.current}
127
+ // withDiscardChanges
128
+ // >
129
+ // <FormRow>
130
+ // <ControlledInputField name="name" />
131
+ // </FormRow>
132
+ // <FormRow>
133
+ // <ControlledSecretConfirmationField name="password" rules={{ required: true }} />
134
+ // </FormRow>
135
+ // <FormRow>
136
+ // <ControlledCheckboxField name="active" />
137
+ // </FormRow>
138
+ // <FormRow>
139
+ // <ControlledInputField name="date" type="date" />
140
+ // </FormRow>
141
+ // </Form>
142
+ // );
143
+ // })
144
+ // .add("Layout", () => (
145
+ // <Form
146
+ // onSubmit={console.log}
147
+ // translationPath={["sample", "form"]}
148
+ // defaultValues={{
149
+ // name: "",
150
+ // password: "",
151
+ // method: "",
152
+ // }}
153
+ // >
154
+ // <FormRow>
155
+ // <ControlledInputField name="name" />
156
+ // <ControlledSelectField name="method">
157
+ // {["", "post", "get", "put"].map((value) => (
158
+ // <option value={value} key={value}>
159
+ // {value}
160
+ // </option>
161
+ // ))}
162
+ // </ControlledSelectField>
163
+ // <ControlledSecretConfirmationField name="password" />
164
+ // </FormRow>
165
+ // </Form>
166
+ // ))
167
+ // .add("GlobalConfiguration", () => (
168
+ // <Form
169
+ // onSubmit={console.log}
170
+ // translationPath={["sample", "form"]}
171
+ // defaultValues={{
172
+ // url: "",
173
+ // filter: "",
174
+ // username: "",
175
+ // password: "",
176
+ // roleLevel: "",
177
+ // updateIssues: false,
178
+ // disableRepoConfig: false,
179
+ // }}
180
+ // >
181
+ // {({ watch }) => (
182
+ // <>
183
+ // <FormRow>
184
+ // <ControlledInputField name="url" label="URL" helpText="URL of Jira installation (with context path)." />
185
+ // </FormRow>
186
+ // <FormRow>
187
+ // <ControlledInputField name="filter" label="Project Filter" helpText="Filters for jira project key." />
188
+ // </FormRow>
189
+ // <FormRow>
190
+ // <ControlledCheckboxField
191
+ // name="updateIssues"
192
+ // label="Update Jira Issues"
193
+ // helpText="Enable the automatic update function."
194
+ // />
195
+ // </FormRow>
196
+ // <FormRow hidden={watch("filter")}>
197
+ // <ControlledInputField
198
+ // name="username"
199
+ // label="Username"
200
+ // helpText="Jira username for connection."
201
+ // className="is-half"
202
+ // />
203
+ // <ControlledInputField
204
+ // name="password"
205
+ // label="Password"
206
+ // helpText="Jira password for connection."
207
+ // type="password"
208
+ // className="is-half"
209
+ // />
210
+ // </FormRow>
211
+ // <FormRow hidden={watch("filter")}>
212
+ // <ControlledInputField
213
+ // name="roleLevel"
214
+ // label="Role Visibility"
215
+ // helpText="Defines for which Project Role the comments are visible."
216
+ // />
217
+ // </FormRow>
218
+ // <FormRow>
219
+ // <ControlledCheckboxField
220
+ // name="disableRepoConfig"
221
+ // label="Do not allow repository configuration"
222
+ // helpText="Do not allow repository owners to configure jira instances."
223
+ // />
224
+ // </FormRow>
225
+ // </>
226
+ // )}
227
+ // </Form>
228
+ // ))
229
+ // .add("RepoConfiguration", () => (
230
+ // <Form
231
+ // onSubmit={console.log}
232
+ // translationPath={["sample", "form"]}
233
+ // defaultValues={{
234
+ // url: "",
235
+ // option: "",
236
+ // anotherOption: "",
237
+ // disableA: false,
238
+ // disableB: false,
239
+ // disableC: true,
240
+ // labels: ["test"],
241
+ // people: [{ displayName: "Trillian", id: 2 }],
242
+ // author: null,
243
+ // }}
244
+ // >
245
+ // <ControlledInputField name="url" />
246
+ // <ControlledInputField name="option" />
247
+ // <ControlledInputField name="anotherOption" />
248
+ // <ControlledCheckboxField name="disableA" />
249
+ // <ControlledCheckboxField name="disableB" />
250
+ // <ControlledCheckboxField name="disableC" />
251
+ // <ControlledChipInputField name="labels" />
252
+ // <ControlledChipInputField
253
+ // name="people"
254
+ // optionFactory={(person) => ({ label: person.displayName, value: person })}
255
+ // >
256
+ // <Combobox
257
+ // options={[
258
+ // { label: "Zenod", value: { id: 1, displayName: "Zenod" } },
259
+ // { label: "Arthur", value: { id: 3, displayName: "Arthur" } },
260
+ // { label: "Cookie Monster", value: { id: 4, displayName: "Cookie Monster" } },
261
+ // ]}
262
+ // />
263
+ // </ControlledChipInputField>
264
+ // <ControlledComboboxField
265
+ // options={["Zenod", "Arthur", "Trillian"].map(defaultOptionFactory)}
266
+ // name="author"
267
+ // nullable
268
+ // />
269
+ // </Form>
270
+ // ))
271
+ // .add("ReadOnly", () => (
272
+ // <Form
273
+ // onSubmit={console.log}
274
+ // translationPath={["sample", "form"]}
275
+ // defaultValues={{
276
+ // name: "trillian",
277
+ // password: "secret",
278
+ // active: true,
279
+ // labels: ["test", "hero"],
280
+ // }}
281
+ // readOnly
282
+ // >
283
+ // <FormRow>
284
+ // <ControlledInputField name="name" />
285
+ // </FormRow>
286
+ // <FormRow>
287
+ // <ControlledSecretConfirmationField name="password" />
288
+ // </FormRow>
289
+ // <FormRow>
290
+ // <ControlledCheckboxField name="active" />
291
+ // </FormRow>
292
+ // <FormRow>
293
+ // <ControlledChipInputField name="labels" aria-label="Test" placeholder="New label..." />
294
+ // </FormRow>
295
+ // </Form>
296
+ // ))
297
+ // .add("Nested", () => (
298
+ // <Form
299
+ // onSubmit={console.log}
300
+ // translationPath={["sample", "form"]}
301
+ // defaultValues={{
302
+ // webhooks: [
303
+ // {
304
+ // urlPattern: "https://hitchhiker.com",
305
+ // executeOnEveryCommit: false,
306
+ // sendCommitData: false,
307
+ // method: "post",
308
+ // headers: [
309
+ // {
310
+ // key: "test",
311
+ // value: "val",
312
+ // concealed: false,
313
+ // },
314
+ // {
315
+ // key: "secret",
316
+ // value: "password",
317
+ // concealed: true,
318
+ // },
319
+ // ],
320
+ // },
321
+ // {
322
+ // urlPattern: "http://test.com",
323
+ // executeOnEveryCommit: false,
324
+ // sendCommitData: false,
325
+ // method: "get",
326
+ // headers: [
327
+ // {
328
+ // key: "other",
329
+ // value: "thing",
330
+ // concealed: true,
331
+ // },
332
+ // {
333
+ // key: "stuff",
334
+ // value: "haha",
335
+ // concealed: false,
336
+ // },
337
+ // ],
338
+ // },
339
+ // ],
340
+ // }}
341
+ // withResetTo={{
342
+ // webhooks: [
343
+ // {
344
+ // urlPattern: "https://other.com",
345
+ // executeOnEveryCommit: true,
346
+ // sendCommitData: true,
347
+ // method: "get",
348
+ // headers: [
349
+ // {
350
+ // key: "change",
351
+ // value: "new",
352
+ // concealed: true,
353
+ // },
354
+ // ],
355
+ // },
356
+ // {
357
+ // urlPattern: "http://things.com",
358
+ // executeOnEveryCommit: false,
359
+ // sendCommitData: true,
360
+ // method: "put",
361
+ // headers: [
362
+ // {
363
+ // key: "stuff",
364
+ // value: "haha",
365
+ // concealed: false,
366
+ // },
367
+ // ],
368
+ // },
369
+ // ],
370
+ // }}
371
+ // >
372
+ // <ScmFormListContextProvider name="webhooks">
373
+ // <ControlledList withDelete>
374
+ // {({ value: webhook }) => (
375
+ // <>
376
+ // <FormRow>
377
+ // <ControlledSelectField name="method">
378
+ // {["post", "get", "put"].map((value) => (
379
+ // <option value={value} key={value}>
380
+ // {value}
381
+ // </option>
382
+ // ))}
383
+ // </ControlledSelectField>
384
+ // <ControlledInputField name="urlPattern" />
385
+ // </FormRow>
386
+ // <FormRow>
387
+ // <ControlledCheckboxField name="executeOnEveryCommit" />
388
+ // </FormRow>
389
+ // <FormRow>
390
+ // <ControlledCheckboxField name="sendCommitData" />
391
+ // </FormRow>
392
+ // <details className="has-background-dark-25 mb-2 p-2">
393
+ // <summary className="is-clickable">Headers</summary>
394
+ // <div>
395
+ // <ScmFormListContextProvider name="headers">
396
+ // <ControlledTable withDelete>
397
+ // <ControlledColumn name="key" />
398
+ // <ControlledColumn name="value" />
399
+ // <ControlledColumn name="concealed">{(value) => (value ? <b>Hallo</b> : null)}</ControlledColumn>
400
+ // </ControlledTable>
401
+ // <AddListEntryForm defaultValues={{ key: "", value: "", concealed: false }}>
402
+ // <FormRow>
403
+ // <ControlledInputField
404
+ // name="key"
405
+ // rules={{
406
+ // validate: (newKey) =>
407
+ // !(webhook as SimpleWebHookConfiguration).headers.some(({ key }) => newKey === key),
408
+ // required: true,
409
+ // }}
410
+ // />
411
+ // </FormRow>
412
+ // <FormRow>
413
+ // <ControlledInputField name="value" />
414
+ // </FormRow>
415
+ // <FormRow>
416
+ // <ControlledCheckboxField name="concealed" />
417
+ // </FormRow>
418
+ // </AddListEntryForm>
419
+ // </ScmFormListContextProvider>
420
+ // </div>
421
+ // </details>
422
+ // </>
423
+ // )}
424
+ // </ControlledList>
425
+ // </ScmFormListContextProvider>
426
+ // </Form>
427
+ // ))
428
+ // .add("Controlled Chip Input with add", () => {
429
+ // const ref = useRef<HTMLInputElement>(null);
430
+ // return (
431
+ // <Form
432
+ // onSubmit={console.log}
433
+ // translationPath={["sample", "form"]}
434
+ // defaultValues={{
435
+ // branches: ["main", "develop"],
436
+ // }}
437
+ // >
438
+ // <FormRow>
439
+ // <ControlledChipInputField name="branches" ref={ref} />
440
+ // </FormRow>
441
+ // <FormRow>
442
+ // <ChipInput.AddButton inputRef={ref}>Add</ChipInput.AddButton>
443
+ // </FormRow>
444
+ // </Form>
445
+ // );
446
+ // });
447
+
448
+ import React, { FC, useRef, useState } from "react";
449
+ import type { Meta, StoryObj } from "@storybook/react";
450
+ import { HalRepresentation } from "@scm-manager/ui-types";
20
451
  import Form from "./Form";
21
452
  import FormRow from "./FormRow";
22
453
  import ControlledInputField from "./input/ControlledInputField";
@@ -28,7 +459,6 @@ import ControlledColumn from "./table/ControlledColumn";
28
459
  import ControlledTable from "./table/ControlledTable";
29
460
  import AddListEntryForm from "./AddListEntryForm";
30
461
  import { ScmFormListContextProvider } from "./ScmFormListContext";
31
- import { HalRepresentation } from "@scm-manager/ui-types";
32
462
  import ControlledChipInputField from "./chip-input/ControlledChipInputField";
33
463
  import Combobox from "./combobox/Combobox";
34
464
  import ControlledComboboxField from "./combobox/ControlledComboboxField";
@@ -42,23 +472,77 @@ export type SimpleWebHookConfiguration = {
42
472
  method: string;
43
473
  headers: WebhookHeader[];
44
474
  };
475
+ export type WebhookHeader = { key: string; value: string; concealed: boolean };
476
+
477
+ const ResetExample: FC = () => {
478
+ type FormType = { name: string; password: string; passwordConfirmation: string; active: boolean; date: string };
479
+ const [defaultValues, setValues] = useState({
480
+ name: "trillian",
481
+ password: "secret",
482
+ passwordConfirmation: "secret",
483
+ active: true,
484
+ date: "",
485
+ });
486
+ const resetValues = useRef({ name: "", password: "", passwordConfirmation: "", active: false, date: "" });
487
+ return (
488
+ <Form<FormType>
489
+ onSubmit={(vals) => {
490
+ console.log(vals);
491
+ setValues(vals);
492
+ }}
493
+ translationPath={["sample", "form"]}
494
+ defaultValues={defaultValues as HalRepresentation & FormType}
495
+ withResetTo={resetValues.current}
496
+ withDiscardChanges
497
+ >
498
+ <FormRow>
499
+ <ControlledInputField name="name" />
500
+ </FormRow>
501
+ <FormRow>
502
+ <ControlledSecretConfirmationField name="password" rules={{ required: true }} />
503
+ </FormRow>
504
+ <FormRow>
505
+ <ControlledCheckboxField name="active" />
506
+ </FormRow>
507
+ <FormRow>
508
+ <ControlledInputField name="date" type="date" />
509
+ </FormRow>
510
+ </Form>
511
+ );
512
+ };
513
+
514
+ const ControlledChipInputWithAddExample: FC = () => {
515
+ const ref = useRef<HTMLInputElement>(null);
516
+ return (
517
+ <Form onSubmit={console.log} translationPath={["sample", "form"]} defaultValues={{ branches: ["main", "develop"] }}>
518
+ <FormRow>
519
+ {/* @ts-ignore */}
520
+ <ControlledChipInputField name="branches" ref={ref} />
521
+ </FormRow>
522
+ <FormRow>
523
+ <ChipInput.AddButton inputRef={ref}>Add</ChipInput.AddButton>
524
+ </FormRow>
525
+ </Form>
526
+ );
527
+ };
45
528
 
46
- export type WebhookHeader = {
47
- key: string;
48
- value: string;
49
- concealed: boolean;
529
+ const meta: Meta<typeof Form> = {
530
+ title: "Forms/Form",
531
+ component: Form,
532
+ decorators: [(Story) => <div style={{ margin: "2rem", maxWidth: "60rem" }}>{Story()}</div>],
533
+ tags: ["autodocs"],
50
534
  };
51
535
 
52
- storiesOf("Forms", module)
53
- .add("Creation", () => (
536
+ export default meta;
537
+
538
+ type Story = StoryObj<typeof meta>;
539
+
540
+ export const Creation: Story = {
541
+ render: () => (
54
542
  <Form
55
543
  onSubmit={console.log}
56
544
  translationPath={["sample", "form"]}
57
- defaultValues={{
58
- name: "",
59
- password: "",
60
- active: true,
61
- }}
545
+ defaultValues={{ name: "", password: "", active: true }}
62
546
  >
63
547
  <FormRow>
64
548
  <ControlledInputField rules={{ required: true }} name="name" />
@@ -70,17 +554,15 @@ storiesOf("Forms", module)
70
554
  <ControlledCheckboxField name="active" />
71
555
  </FormRow>
72
556
  </Form>
73
- ))
74
- .add("Editing", () => (
557
+ ),
558
+ };
559
+
560
+ export const Editing: Story = {
561
+ render: () => (
75
562
  <Form
76
563
  onSubmit={console.log}
77
564
  translationPath={["sample", "form"]}
78
- defaultValues={{
79
- name: "trillian",
80
- password: "secret",
81
- passwordConfirmation: "",
82
- active: true,
83
- }}
565
+ defaultValues={{ name: "trillian", password: "secret", passwordConfirmation: "", active: true }}
84
566
  >
85
567
  <FormRow>
86
568
  <ControlledInputField name="name" />
@@ -92,64 +574,17 @@ storiesOf("Forms", module)
92
574
  <ControlledCheckboxField name="active" />
93
575
  </FormRow>
94
576
  </Form>
95
- ))
96
- .add("Reset", () => {
97
- type FormType = {
98
- name: string;
99
- password: string;
100
- passwordConfirmation: string;
101
- active: boolean;
102
- date: string;
103
- };
104
- const [defaultValues, setValues] = useState({
105
- name: "trillian",
106
- password: "secret",
107
- passwordConfirmation: "secret",
108
- active: true,
109
- date: "",
110
- });
111
- const resetValues = useRef({
112
- name: "",
113
- password: "",
114
- passwordConfirmation: "",
115
- active: false,
116
- date: "",
117
- });
118
- return (
119
- <Form<FormType>
120
- onSubmit={(vals) => {
121
- console.log(vals);
122
- setValues(vals);
123
- }}
124
- translationPath={["sample", "form"]}
125
- defaultValues={defaultValues as HalRepresentation & FormType}
126
- withResetTo={resetValues.current}
127
- withDiscardChanges
128
- >
129
- <FormRow>
130
- <ControlledInputField name="name" />
131
- </FormRow>
132
- <FormRow>
133
- <ControlledSecretConfirmationField name="password" rules={{ required: true }} />
134
- </FormRow>
135
- <FormRow>
136
- <ControlledCheckboxField name="active" />
137
- </FormRow>
138
- <FormRow>
139
- <ControlledInputField name="date" type="date" />
140
- </FormRow>
141
- </Form>
142
- );
143
- })
144
- .add("Layout", () => (
577
+ ),
578
+ };
579
+
580
+ export const Reset: Story = { render: () => <ResetExample /> };
581
+
582
+ export const Layout: Story = {
583
+ render: () => (
145
584
  <Form
146
585
  onSubmit={console.log}
147
586
  translationPath={["sample", "form"]}
148
- defaultValues={{
149
- name: "",
150
- password: "",
151
- method: "",
152
- }}
587
+ defaultValues={{ name: "", password: "", method: "" }}
153
588
  >
154
589
  <FormRow>
155
590
  <ControlledInputField name="name" />
@@ -163,103 +598,72 @@ storiesOf("Forms", module)
163
598
  <ControlledSecretConfirmationField name="password" />
164
599
  </FormRow>
165
600
  </Form>
166
- ))
167
- .add("GlobalConfiguration", () => (
168
- <Form
169
- onSubmit={console.log}
170
- translationPath={["sample", "form"]}
171
- defaultValues={{
172
- url: "",
173
- filter: "",
174
- username: "",
175
- password: "",
176
- roleLevel: "",
177
- updateIssues: false,
178
- disableRepoConfig: false,
179
- }}
180
- >
181
- {({ watch }) => (
182
- <>
183
- <FormRow>
184
- <ControlledInputField name="url" label="URL" helpText="URL of Jira installation (with context path)." />
185
- </FormRow>
186
- <FormRow>
187
- <ControlledInputField name="filter" label="Project Filter" helpText="Filters for jira project key." />
188
- </FormRow>
189
- <FormRow>
190
- <ControlledCheckboxField
191
- name="updateIssues"
192
- label="Update Jira Issues"
193
- helpText="Enable the automatic update function."
194
- />
195
- </FormRow>
196
- <FormRow hidden={watch("filter")}>
197
- <ControlledInputField
198
- name="username"
199
- label="Username"
200
- helpText="Jira username for connection."
201
- className="is-half"
202
- />
203
- <ControlledInputField
204
- name="password"
205
- label="Password"
206
- helpText="Jira password for connection."
207
- type="password"
208
- className="is-half"
209
- />
210
- </FormRow>
211
- <FormRow hidden={watch("filter")}>
212
- <ControlledInputField
213
- name="roleLevel"
214
- label="Role Visibility"
215
- helpText="Defines for which Project Role the comments are visible."
216
- />
217
- </FormRow>
218
- <FormRow>
219
- <ControlledCheckboxField
220
- name="disableRepoConfig"
221
- label="Do not allow repository configuration"
222
- helpText="Do not allow repository owners to configure jira instances."
223
- />
224
- </FormRow>
225
- </>
226
- )}
227
- </Form>
228
- ))
229
- .add("RepoConfiguration", () => (
601
+ ),
602
+ };
603
+
604
+ // export const GlobalConfiguration: Story = {
605
+ // render: () => (
606
+ // <Form
607
+ // onSubmit={console.log}
608
+ // translationPath={["sample", "form"]}
609
+ // defaultValues={{
610
+ // url: "",
611
+ // filter: "",
612
+ // username: "",
613
+ // password: "",
614
+ // roleLevel: "",
615
+ // updateIssues: false,
616
+ // disableRepoConfig: false,
617
+ // }}
618
+ // >
619
+ // {({ watch }) => (
620
+ // <>
621
+ // <FormRow>
622
+ // <ControlledInputField name="url" label="URL" helpText="URL of Jira installation." />
623
+ // </FormRow>
624
+ // <FormRow>
625
+ // <ControlledInputField name="filter" label="Project Filter" helpText="Filters for jira project key." />
626
+ // </FormRow>
627
+ // <FormRow>
628
+ // <ControlledCheckboxField
629
+ // name="updateIssues"
630
+ // label="Update Jira Issues"
631
+ // helpText="Enable the automatic update function."
632
+ // />
633
+ // </FormRow>
634
+ // <FormRow hidden={watch("filter")}>
635
+ // <ControlledInputField name="username" label="Username" helpText="Jira username." className="is-half" />
636
+ // <ControlledInputField
637
+ // name="password"
638
+ // label="Password"
639
+ // helpText="Jira password."
640
+ // type="password"
641
+ // className="is-half"
642
+ // />
643
+ // </FormRow>
644
+ // </>
645
+ // )}
646
+ // </Form>
647
+ // ),
648
+ // };
649
+
650
+ export const RepoConfiguration: Story = {
651
+ render: () => (
230
652
  <Form
231
653
  onSubmit={console.log}
232
654
  translationPath={["sample", "form"]}
233
- defaultValues={{
234
- url: "",
235
- option: "",
236
- anotherOption: "",
237
- disableA: false,
238
- disableB: false,
239
- disableC: true,
240
- labels: ["test"],
241
- people: [{ displayName: "Trillian", id: 2 }],
242
- author: null,
243
- }}
655
+ defaultValues={{ url: "", labels: ["test"], people: [{ displayName: "Trillian", id: 2 }], author: null }}
244
656
  >
245
657
  <ControlledInputField name="url" />
246
- <ControlledInputField name="option" />
247
- <ControlledInputField name="anotherOption" />
248
- <ControlledCheckboxField name="disableA" />
249
- <ControlledCheckboxField name="disableB" />
250
- <ControlledCheckboxField name="disableC" />
658
+ {/* @ts-ignore */}
251
659
  <ControlledChipInputField name="labels" />
660
+ {/* @ts-ignore */}
252
661
  <ControlledChipInputField
253
662
  name="people"
254
663
  optionFactory={(person) => ({ label: person.displayName, value: person })}
255
664
  >
256
- <Combobox
257
- options={[
258
- { label: "Zenod", value: { id: 1, displayName: "Zenod" } },
259
- { label: "Arthur", value: { id: 3, displayName: "Arthur" } },
260
- { label: "Cookie Monster", value: { id: 4, displayName: "Cookie Monster" } },
261
- ]}
262
- />
665
+ {/* @ts-ignore */}
666
+ <Combobox options={[{ label: "Zenod", value: { id: 1, displayName: "Zenod" } }]} />
263
667
  </ControlledChipInputField>
264
668
  <ControlledComboboxField
265
669
  options={["Zenod", "Arthur", "Trillian"].map(defaultOptionFactory)}
@@ -267,17 +671,15 @@ storiesOf("Forms", module)
267
671
  nullable
268
672
  />
269
673
  </Form>
270
- ))
271
- .add("ReadOnly", () => (
674
+ ),
675
+ };
676
+
677
+ export const ReadOnly: Story = {
678
+ render: () => (
272
679
  <Form
273
680
  onSubmit={console.log}
274
681
  translationPath={["sample", "form"]}
275
- defaultValues={{
276
- name: "trillian",
277
- password: "secret",
278
- active: true,
279
- labels: ["test", "hero"],
280
- }}
682
+ defaultValues={{ name: "trillian", password: "secret", active: true, labels: ["test", "hero"] }}
281
683
  readOnly
282
684
  >
283
685
  <FormRow>
@@ -290,11 +692,15 @@ storiesOf("Forms", module)
290
692
  <ControlledCheckboxField name="active" />
291
693
  </FormRow>
292
694
  <FormRow>
695
+ {/* @ts-ignore */}
293
696
  <ControlledChipInputField name="labels" aria-label="Test" placeholder="New label..." />
294
697
  </FormRow>
295
698
  </Form>
296
- ))
297
- .add("Nested", () => (
699
+ ),
700
+ };
701
+
702
+ export const Nested: Story = {
703
+ render: () => (
298
704
  <Form
299
705
  onSubmit={console.log}
300
706
  translationPath={["sample", "form"]}
@@ -302,69 +708,8 @@ storiesOf("Forms", module)
302
708
  webhooks: [
303
709
  {
304
710
  urlPattern: "https://hitchhiker.com",
305
- executeOnEveryCommit: false,
306
- sendCommitData: false,
307
711
  method: "post",
308
- headers: [
309
- {
310
- key: "test",
311
- value: "val",
312
- concealed: false,
313
- },
314
- {
315
- key: "secret",
316
- value: "password",
317
- concealed: true,
318
- },
319
- ],
320
- },
321
- {
322
- urlPattern: "http://test.com",
323
- executeOnEveryCommit: false,
324
- sendCommitData: false,
325
- method: "get",
326
- headers: [
327
- {
328
- key: "other",
329
- value: "thing",
330
- concealed: true,
331
- },
332
- {
333
- key: "stuff",
334
- value: "haha",
335
- concealed: false,
336
- },
337
- ],
338
- },
339
- ],
340
- }}
341
- withResetTo={{
342
- webhooks: [
343
- {
344
- urlPattern: "https://other.com",
345
- executeOnEveryCommit: true,
346
- sendCommitData: true,
347
- method: "get",
348
- headers: [
349
- {
350
- key: "change",
351
- value: "new",
352
- concealed: true,
353
- },
354
- ],
355
- },
356
- {
357
- urlPattern: "http://things.com",
358
- executeOnEveryCommit: false,
359
- sendCommitData: true,
360
- method: "put",
361
- headers: [
362
- {
363
- key: "stuff",
364
- value: "haha",
365
- concealed: false,
366
- },
367
- ],
712
+ headers: [{ key: "test", value: "val", concealed: false }],
368
713
  },
369
714
  ],
370
715
  }}
@@ -383,64 +728,29 @@ storiesOf("Forms", module)
383
728
  </ControlledSelectField>
384
729
  <ControlledInputField name="urlPattern" />
385
730
  </FormRow>
386
- <FormRow>
387
- <ControlledCheckboxField name="executeOnEveryCommit" />
388
- </FormRow>
389
- <FormRow>
390
- <ControlledCheckboxField name="sendCommitData" />
391
- </FormRow>
392
731
  <details className="has-background-dark-25 mb-2 p-2">
393
732
  <summary className="is-clickable">Headers</summary>
394
- <div>
395
- <ScmFormListContextProvider name="headers">
396
- <ControlledTable withDelete>
397
- <ControlledColumn name="key" />
398
- <ControlledColumn name="value" />
399
- <ControlledColumn name="concealed">{(value) => (value ? <b>Hallo</b> : null)}</ControlledColumn>
400
- </ControlledTable>
401
- <AddListEntryForm defaultValues={{ key: "", value: "", concealed: false }}>
402
- <FormRow>
403
- <ControlledInputField
404
- name="key"
405
- rules={{
406
- validate: (newKey) =>
407
- !(webhook as SimpleWebHookConfiguration).headers.some(({ key }) => newKey === key),
408
- required: true,
409
- }}
410
- />
411
- </FormRow>
412
- <FormRow>
413
- <ControlledInputField name="value" />
414
- </FormRow>
415
- <FormRow>
416
- <ControlledCheckboxField name="concealed" />
417
- </FormRow>
418
- </AddListEntryForm>
419
- </ScmFormListContextProvider>
420
- </div>
733
+ <ScmFormListContextProvider name="headers">
734
+ <ControlledTable withDelete>
735
+ <ControlledColumn name="key" />
736
+ <ControlledColumn name="value" />
737
+ </ControlledTable>
738
+ <AddListEntryForm defaultValues={{ key: "", value: "", concealed: false }}>
739
+ <FormRow>
740
+ <ControlledInputField name="key" />
741
+ </FormRow>
742
+ <FormRow>
743
+ <ControlledInputField name="value" />
744
+ </FormRow>
745
+ </AddListEntryForm>
746
+ </ScmFormListContextProvider>
421
747
  </details>
422
748
  </>
423
749
  )}
424
750
  </ControlledList>
425
751
  </ScmFormListContextProvider>
426
752
  </Form>
427
- ))
428
- .add("Controlled Chip Input with add", () => {
429
- const ref = useRef<HTMLInputElement>(null);
430
- return (
431
- <Form
432
- onSubmit={console.log}
433
- translationPath={["sample", "form"]}
434
- defaultValues={{
435
- branches: ["main", "develop"],
436
- }}
437
- >
438
- <FormRow>
439
- <ControlledChipInputField name="branches" ref={ref} />
440
- </FormRow>
441
- <FormRow>
442
- <ChipInput.AddButton inputRef={ref}>Add</ChipInput.AddButton>
443
- </FormRow>
444
- </Form>
445
- );
446
- });
753
+ ),
754
+ };
755
+
756
+ export const ControlledChipInputWithAdd: Story = { render: () => <ControlledChipInputWithAddExample /> };