@mindlogic-ai/logician-ui 5.0.0-alpha.2 → 5.0.0-alpha.4
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/components/Badge/Badge.d.ts.map +1 -1
- package/dist/components/Badge/Badge.js +5 -3
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Badge/Badge.mjs +5 -3
- package/dist/components/Badge/Badge.mjs.map +1 -1
- package/dist/components/Badge/Badge.types.d.ts +7 -5
- package/dist/components/Badge/Badge.types.d.ts.map +1 -1
- package/dist/components/Banner/Banner.types.d.ts +24 -1
- package/dist/components/Banner/Banner.types.d.ts.map +1 -1
- package/dist/components/Card/Card.types.d.ts +12 -0
- package/dist/components/Card/Card.types.d.ts.map +1 -1
- package/dist/components/ColorMode/ColorModeToggle.d.ts +7 -2
- package/dist/components/ColorMode/ColorModeToggle.d.ts.map +1 -1
- package/dist/components/ColorMode/ColorModeToggle.js +8 -3
- package/dist/components/ColorMode/ColorModeToggle.js.map +1 -1
- package/dist/components/ColorMode/ColorModeToggle.mjs +8 -3
- package/dist/components/ColorMode/ColorModeToggle.mjs.map +1 -1
- package/dist/components/Confetti/Confetti.types.d.ts +5 -1
- package/dist/components/Confetti/Confetti.types.d.ts.map +1 -1
- package/dist/components/Confetti/confettiColors.d.ts +5 -5
- package/dist/components/Confetti/confettiColors.js +5 -5
- package/dist/components/Confetti/confettiColors.mjs +5 -5
- package/dist/components/ErrorFallback/ErrorFallback.types.d.ts +6 -0
- package/dist/components/ErrorFallback/ErrorFallback.types.d.ts.map +1 -1
- package/dist/components/Form/FormModalFooter/FormModalFooter.types.d.ts +4 -1
- package/dist/components/Form/FormModalFooter/FormModalFooter.types.d.ts.map +1 -1
- package/dist/components/LineGraph/LineGraph.d.ts.map +1 -1
- package/dist/components/LineGraph/LineGraph.js +4 -5
- package/dist/components/LineGraph/LineGraph.js.map +1 -1
- package/dist/components/LineGraph/LineGraph.mjs +5 -6
- package/dist/components/LineGraph/LineGraph.mjs.map +1 -1
- package/dist/components/LineGraph/LineGraph.types.d.ts +12 -2
- package/dist/components/LineGraph/LineGraph.types.d.ts.map +1 -1
- package/dist/components/LineGraph/seriesColors.d.ts +12 -8
- package/dist/components/LineGraph/seriesColors.d.ts.map +1 -1
- package/dist/components/LineGraph/seriesColors.js +8 -7
- package/dist/components/LineGraph/seriesColors.js.map +1 -1
- package/dist/components/LineGraph/seriesColors.mjs +8 -7
- package/dist/components/LineGraph/seriesColors.mjs.map +1 -1
- package/dist/components/Masonry/Masonry.types.d.ts +8 -3
- package/dist/components/Masonry/Masonry.types.d.ts.map +1 -1
- package/dist/components/Menu/MenuItem.types.d.ts +8 -0
- package/dist/components/Menu/MenuItem.types.d.ts.map +1 -1
- package/dist/components/Modal/ModalCloseButton.d.ts +1 -1
- package/dist/components/Modal/ModalCloseButton.js +1 -1
- package/dist/components/Modal/ModalCloseButton.mjs +1 -1
- package/dist/components/Pagination/Pagination.d.ts +11 -10
- package/dist/components/Pagination/Pagination.d.ts.map +1 -1
- package/dist/components/Pagination/Pagination.js +11 -10
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/Pagination/Pagination.mjs +11 -10
- package/dist/components/Pagination/Pagination.mjs.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.types.d.ts +9 -0
- package/dist/components/ProgressBar/ProgressBar.types.d.ts.map +1 -1
- package/dist/components/RadialProgress/RadialProgress.types.d.ts +21 -1
- package/dist/components/RadialProgress/RadialProgress.types.d.ts.map +1 -1
- package/dist/components/SeeMoreButton/SeeMoreButton.types.d.ts +8 -0
- package/dist/components/SeeMoreButton/SeeMoreButton.types.d.ts.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.js +6 -7
- package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.mjs +6 -7
- package/dist/components/SegmentedControl/SegmentedControl.mjs.map +1 -1
- package/dist/components/SegmentedProgressBar/SegmentedProgressBar.types.d.ts +2 -0
- package/dist/components/SegmentedProgressBar/SegmentedProgressBar.types.d.ts.map +1 -1
- package/dist/components/Toast/Toast.styles.d.ts +6 -2
- package/dist/components/Toast/Toast.styles.d.ts.map +1 -1
- package/dist/components/Toast/Toast.styles.js +18 -10
- package/dist/components/Toast/Toast.styles.js.map +1 -1
- package/dist/components/Toast/Toast.styles.mjs +18 -10
- package/dist/components/Toast/Toast.styles.mjs.map +1 -1
- package/dist/theme/colors.d.ts +2 -2
- package/dist/theme/colors.d.ts.map +1 -1
- package/dist/theme/colors.js +22 -2
- package/dist/theme/colors.js.map +1 -1
- package/dist/theme/colors.mjs +23 -3
- package/dist/theme/colors.mjs.map +1 -1
- package/dist/theme/palette.generated.d.ts +98 -0
- package/dist/theme/palette.generated.d.ts.map +1 -1
- package/dist/theme/palette.generated.js +99 -0
- package/dist/theme/palette.generated.js.map +1 -1
- package/dist/theme/palette.generated.mjs +99 -1
- package/dist/theme/palette.generated.mjs.map +1 -1
- package/dist/theme/paletteSwatches.d.ts +20 -0
- package/dist/theme/paletteSwatches.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.stories.tsx +85 -0
- package/src/components/Accordion/Accordion.usage.mdx +200 -0
- package/src/components/Appear/Appear.usage.mdx +107 -0
- package/src/components/Avatar/Avatar.stories.tsx +71 -1
- package/src/components/Avatar/Avatar.usage.mdx +166 -0
- package/src/components/Badge/Badge.stories.tsx +193 -3
- package/src/components/Badge/Badge.tsx +5 -3
- package/src/components/Badge/Badge.types.ts +7 -5
- package/src/components/Badge/Badge.usage.mdx +265 -0
- package/src/components/Banner/Banner.stories.tsx +152 -2
- package/src/components/Banner/Banner.types.ts +30 -1
- package/src/components/Banner/Banner.usage.mdx +233 -0
- package/src/components/BottomSheet/BottomSheet.stories.tsx +168 -1
- package/src/components/BottomSheet/BottomSheet.usage.mdx +216 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +59 -0
- package/src/components/Breadcrumb/Breadcrumb.usage.mdx +181 -0
- package/src/components/Button/Button.stories.tsx +263 -3
- package/src/components/Button/Button.usage.mdx +342 -0
- package/src/components/Card/Card.stories.tsx +106 -0
- package/src/components/Card/Card.types.ts +12 -0
- package/src/components/Card/Card.usage.mdx +216 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +140 -13
- package/src/components/Checkbox/Checkbox.usage.mdx +214 -0
- package/src/components/Chip/Chip.usage.mdx +78 -0
- package/src/components/Code/Code.stories.tsx +60 -0
- package/src/components/Code/Code.usage.mdx +187 -0
- package/src/components/CodeTabs/CodeTabs.stories.tsx +53 -0
- package/src/components/CodeTabs/CodeTabs.usage.mdx +176 -0
- package/src/components/Collapsible/Collapsible.stories.tsx +58 -0
- package/src/components/Collapsible/Collapsible.usage.mdx +173 -0
- package/src/components/ColorMode/ColorMode.stories.tsx +50 -0
- package/src/components/ColorMode/ColorMode.usage.mdx +135 -0
- package/src/components/ColorMode/ColorModeToggle.tsx +10 -3
- package/src/components/Confetti/Confetti.types.ts +5 -1
- package/src/components/Confetti/Confetti.usage.mdx +111 -0
- package/src/components/Confetti/confettiColors.ts +5 -5
- package/src/components/Container/Container.stories.tsx +32 -0
- package/src/components/Container/Container.usage.mdx +130 -0
- package/src/components/CopyableCode/CopyableCode.stories.tsx +62 -0
- package/src/components/CopyableCode/CopyableCode.usage.mdx +168 -0
- package/src/components/CountBadge/CountBadge.stories.tsx +69 -0
- package/src/components/CountBadge/CountBadge.usage.mdx +215 -0
- package/src/components/CountUp/CountUp.usage.mdx +107 -0
- package/src/components/DatePicker/DatePicker.usage.mdx +177 -0
- package/src/components/DatePicker/RangeDatePicker.stories.tsx +87 -3
- package/src/components/ErrorFallback/ErrorFallback.types.ts +6 -0
- package/src/components/ErrorFallback/ErrorFallback.usage.mdx +127 -0
- package/src/components/ExpandableText/ExpandableText.stories.tsx +55 -0
- package/src/components/ExpandableText/ExpandableText.usage.mdx +176 -0
- package/src/components/FileInput/FileInput.stories.tsx +38 -1
- package/src/components/FileInput/FileInput.usage.mdx +178 -0
- package/src/components/FileItem/FileItem.stories.tsx +71 -0
- package/src/components/FileItem/FileItem.usage.mdx +180 -0
- package/src/components/FileList/FileList.stories.tsx +25 -0
- package/src/components/FileList/FileList.usage.mdx +165 -0
- package/src/components/FlyTo/FlyTo.usage.mdx +99 -0
- package/src/components/Form/Form.stories.tsx +149 -0
- package/src/components/Form/Form.usage.mdx +201 -0
- package/src/components/Form/FormModalFooter/FormModalFooter.types.ts +4 -1
- package/src/components/FormControl/FormControl.stories.tsx +35 -0
- package/src/components/FormControl/FormControl.usage.mdx +128 -0
- package/src/components/FormIntegration/FormIntegration.usage.mdx +158 -0
- package/src/components/FormLabel/FormLabel.stories.tsx +71 -0
- package/src/components/FormLabel/FormLabel.usage.mdx +125 -0
- package/src/components/Icon/Icon.stories.tsx +61 -1
- package/src/components/Icon/Icon.usage.mdx +158 -0
- package/src/components/IconButton/IconButton.stories.tsx +209 -5
- package/src/components/IconButton/IconButton.usage.mdx +273 -0
- package/src/components/InfoSprinkle/InfoSprinkle.stories.tsx +77 -1
- package/src/components/InfoSprinkle/InfoSprinkle.usage.mdx +189 -0
- package/src/components/InlineCode/InlineCode.stories.tsx +75 -0
- package/src/components/InlineCode/InlineCode.usage.mdx +142 -0
- package/src/components/Input/Input.stories.tsx +180 -0
- package/src/components/Input/Input.usage.mdx +278 -0
- package/src/components/LineGraph/LineGraph.stories.tsx +112 -0
- package/src/components/LineGraph/LineGraph.tsx +4 -5
- package/src/components/LineGraph/LineGraph.types.ts +12 -2
- package/src/components/LineGraph/LineGraph.usage.mdx +186 -0
- package/src/components/LineGraph/seriesColors.test.ts +11 -10
- package/src/components/LineGraph/seriesColors.ts +18 -16
- package/src/components/Loaders/Loaders.stories.tsx +93 -0
- package/src/components/Loaders/Loaders.usage.mdx +180 -0
- package/src/components/LogicianProvider/LogicianProvider.usage.mdx +98 -0
- package/src/components/Markdown/Markdown.stories.tsx +53 -0
- package/src/components/Markdown/Markdown.usage.mdx +182 -0
- package/src/components/Masonry/Masonry.stories.tsx +63 -1
- package/src/components/Masonry/Masonry.types.ts +8 -3
- package/src/components/Masonry/Masonry.usage.mdx +142 -0
- package/src/components/MaxLengthIndicator/MaxLengthIndicator.stories.tsx +57 -0
- package/src/components/MaxLengthIndicator/MaxLengthIndicator.usage.mdx +125 -0
- package/src/components/Menu/Menu.stories.tsx +146 -2
- package/src/components/Menu/Menu.usage.mdx +230 -0
- package/src/components/Menu/MenuItem.types.ts +8 -0
- package/src/components/Modal/Modal.stories.tsx +177 -1
- package/src/components/Modal/Modal.usage.mdx +262 -0
- package/src/components/Modal/ModalCloseButton.tsx +1 -1
- package/src/components/MonthPicker/MonthPicker.stories.tsx +30 -0
- package/src/components/MonthPicker/MonthPicker.usage.mdx +191 -0
- package/src/components/Pagination/Pagination.stories.tsx +90 -1
- package/src/components/Pagination/Pagination.tsx +11 -10
- package/src/components/Pagination/Pagination.usage.mdx +186 -0
- package/src/components/PasswordInput/PasswordInput.stories.tsx +51 -0
- package/src/components/PasswordInput/PasswordInput.usage.mdx +193 -0
- package/src/components/PinInput/PinInput.stories.tsx +91 -0
- package/src/components/PinInput/PinInput.usage.mdx +194 -0
- package/src/components/Popover/Popover.stories.tsx +104 -1
- package/src/components/Popover/Popover.usage.mdx +197 -0
- package/src/components/ProgressBar/ProgressBar.stories.tsx +92 -1
- package/src/components/ProgressBar/ProgressBar.types.ts +9 -0
- package/src/components/ProgressBar/ProgressBar.usage.mdx +210 -0
- package/src/components/Pulse/Pulse.usage.mdx +102 -0
- package/src/components/RadialProgress/RadialProgress.stories.tsx +74 -1
- package/src/components/RadialProgress/RadialProgress.types.ts +21 -1
- package/src/components/RadialProgress/RadialProgress.usage.mdx +153 -0
- package/src/components/Radio/Radio.stories.tsx +119 -0
- package/src/components/Radio/Radio.usage.mdx +187 -0
- package/src/components/Reveal/Reveal.usage.mdx +105 -0
- package/src/components/ScaledContext/ScaledContext.usage.mdx +111 -0
- package/src/components/SeeMoreButton/SeeMoreButton.stories.tsx +146 -2
- package/src/components/SeeMoreButton/SeeMoreButton.types.ts +8 -0
- package/src/components/SeeMoreButton/SeeMoreButton.usage.mdx +213 -0
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +69 -0
- package/src/components/SegmentedControl/SegmentedControl.tsx +6 -7
- package/src/components/SegmentedControl/SegmentedControl.usage.mdx +209 -0
- package/src/components/SegmentedProgressBar/SegmentedProgressBar.stories.tsx +54 -0
- package/src/components/SegmentedProgressBar/SegmentedProgressBar.types.ts +2 -0
- package/src/components/SegmentedProgressBar/SegmentedProgressBar.usage.mdx +145 -0
- package/src/components/Select/Select.stories.tsx +209 -1
- package/src/components/Select/Select.usage.mdx +278 -0
- package/src/components/Shake/Shake.usage.mdx +107 -0
- package/src/components/Slider/Slider.stories.tsx +116 -0
- package/src/components/Slider/Slider.usage.mdx +179 -0
- package/src/components/Spinner/Spinner.stories.tsx +64 -0
- package/src/components/Spinner/Spinner.usage.mdx +136 -0
- package/src/components/SwapTransition/SwapTransition.usage.mdx +102 -0
- package/src/components/Switch/Switch.stories.tsx +131 -6
- package/src/components/Switch/Switch.usage.mdx +199 -0
- package/src/components/Table/Table.stories.tsx +159 -1
- package/src/components/Table/Table.usage.mdx +235 -0
- package/src/components/Tabs/Tabs.stories.tsx +86 -0
- package/src/components/Tabs/Tabs.usage.mdx +219 -0
- package/src/components/Tag/Tag.stories.tsx +181 -4
- package/src/components/Tag/Tag.usage.mdx +257 -0
- package/src/components/Textarea/Textarea.stories.tsx +113 -0
- package/src/components/Textarea/Textarea.usage.mdx +186 -0
- package/src/components/Toast/Toast.stories.tsx +185 -3
- package/src/components/Toast/Toast.styles.ts +18 -10
- package/src/components/Toast/Toast.usage.mdx +265 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +86 -1
- package/src/components/Tooltip/Tooltip.usage.mdx +211 -0
- package/src/components/Tree/Tree.stories.tsx +89 -0
- package/src/components/Tree/Tree.usage.mdx +207 -0
- package/src/components/Typography/Typography.stories.tsx +117 -0
- package/src/components/Typography/Typography.usage.mdx +251 -0
- package/src/components/Workflow/Workflow.usage.mdx +199 -0
- package/src/components/noRawScales.test.ts +5 -1
- package/src/foundations/BrandColour.mdx +364 -0
- package/src/foundations/BrandColour.stories.tsx +334 -0
- package/src/guidelines/ComponentPageTemplate.mdx +84 -0
- package/src/guidelines/FeedbackActions.mdx +162 -23
- package/src/guidelines/_components/Lang.tsx +175 -0
- package/src/guidelines/_components/TokenTable.tsx +136 -0
- package/src/theme/BazePalette.stories.tsx +111 -1
- package/src/theme/Palette.stories.tsx +2 -2
- package/src/theme/SemanticTokens.mdx +75 -16
- package/src/theme/claude.md +15 -9
- package/src/theme/colors.ts +33 -3
- package/src/theme/contrast.test.ts +32 -0
- package/src/theme/palette.generated.ts +99 -0
- package/src/theme/paletteSwatches.ts +35 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Canvas, Meta } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import { En, Ko, LangToggle, Verdict } from '../../guidelines/_components/Lang';
|
|
4
|
+
import * as FormControlStories from './FormControl.stories';
|
|
5
|
+
|
|
6
|
+
<Meta of={FormControlStories} name="Usage" />
|
|
7
|
+
|
|
8
|
+
<LangToggle />
|
|
9
|
+
|
|
10
|
+
<En>
|
|
11
|
+
|
|
12
|
+
# FormControl
|
|
13
|
+
|
|
14
|
+
Chakra's `Field.Root` under the design-system name: the wrapper that shares one
|
|
15
|
+
field's id and state with its label, control, helper and error.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
- A field layout `FieldRow` does not cover, built from `FormLabel`, a control,
|
|
20
|
+
`FieldHelp` and `FieldError`.
|
|
21
|
+
- Wrapping a control so a parent can set `required`, `invalid`, `disabled` or
|
|
22
|
+
`readOnly` once.
|
|
23
|
+
|
|
24
|
+
## When not to use
|
|
25
|
+
|
|
26
|
+
- A standard field → `FieldRow`, which is `FormControl` with the label, helper
|
|
27
|
+
and error already laid out.
|
|
28
|
+
|
|
29
|
+
## Props
|
|
30
|
+
|
|
31
|
+
`required`, `invalid`, `disabled` and `readOnly` (plus every `Field.Root`
|
|
32
|
+
prop). The state reaches `Input`, `Textarea` and `PasswordInput` through
|
|
33
|
+
Chakra's field context, together with the id the label points at and the
|
|
34
|
+
`aria-describedby` for helper and error text. Composed controls (`SelectField`,
|
|
35
|
+
`ComboboxField`, `Slider`) take their name from their own label part, so give
|
|
36
|
+
them `label` or `ariaLabel` and pass `invalid` / `disabled` to them directly.
|
|
37
|
+
|
|
38
|
+
## Do / Don't
|
|
39
|
+
|
|
40
|
+
</En>
|
|
41
|
+
|
|
42
|
+
<Ko>
|
|
43
|
+
|
|
44
|
+
# FormControl
|
|
45
|
+
|
|
46
|
+
Chakra `Field.Root`를 디자인 시스템 이름으로 내보낸 것입니다. 필드 하나의 id와 상태를
|
|
47
|
+
라벨, 컨트롤, 도움말, 오류 문구에 나눠 주는 래퍼입니다.
|
|
48
|
+
|
|
49
|
+
## 언제 쓰나요
|
|
50
|
+
|
|
51
|
+
- `FieldRow`로 안 되는 필드 배치를 `FormLabel`, 컨트롤, `FieldHelp`, `FieldError`로
|
|
52
|
+
직접 짤 때.
|
|
53
|
+
- 상위에서 `required`, `invalid`, `disabled`, `readOnly`를 한 번에 정하려고 컨트롤을
|
|
54
|
+
감쌀 때.
|
|
55
|
+
|
|
56
|
+
## 언제 쓰지 않나요
|
|
57
|
+
|
|
58
|
+
- 일반적인 필드는 `FieldRow`를 씁니다. 라벨, 도움말, 오류 문구가 이미 배치된
|
|
59
|
+
`FormControl`입니다.
|
|
60
|
+
|
|
61
|
+
## 속성
|
|
62
|
+
|
|
63
|
+
`required`, `invalid`, `disabled`, `readOnly`(그리고 `Field.Root`의 모든 속성)를
|
|
64
|
+
받습니다. 이 상태는 Chakra의 필드 컨텍스트를 타고 `Input`, `Textarea`,
|
|
65
|
+
`PasswordInput`에 전달되며, 라벨이 가리키는 id와 도움말·오류 문구용
|
|
66
|
+
`aria-describedby`도 함께 전달됩니다. 부품을 조합한 컨트롤(`SelectField`,
|
|
67
|
+
`ComboboxField`, `Slider`)은 자기 라벨 부품에서 이름을 가져오므로 `label`이나
|
|
68
|
+
`ariaLabel`을 주고, `invalid`·`disabled`도 컨트롤에 직접 넘깁니다.
|
|
69
|
+
|
|
70
|
+
## 이렇게 하세요 / 이렇게 하지 마세요
|
|
71
|
+
|
|
72
|
+
</Ko>
|
|
73
|
+
|
|
74
|
+
<Canvas of={FormControlStories.DoFieldRowFirst} />
|
|
75
|
+
<Verdict
|
|
76
|
+
kind="do"
|
|
77
|
+
en="Reach for FieldRow first. It is FormControl with the label, help and error placed for you."
|
|
78
|
+
ko="먼저 FieldRow를 씁니다. 라벨, 도움말, 오류 문구를 알아서 배치한 FormControl입니다."
|
|
79
|
+
/>
|
|
80
|
+
|
|
81
|
+
<Canvas of={FormControlStories.DoInvalidOnTheField} />
|
|
82
|
+
<Verdict
|
|
83
|
+
kind="do"
|
|
84
|
+
en="When you compose by hand, set invalid on FormControl, not on the Input, and add a FieldError with the reason."
|
|
85
|
+
ko="직접 조합할 때는 invalid를 Input이 아니라 FormControl에 주고, 이유를 적은 FieldError를 함께 둡니다."
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
<En>
|
|
89
|
+
|
|
90
|
+
## Accessibility
|
|
91
|
+
|
|
92
|
+
- `invalid` on `FormControl` sets `aria-invalid` on the input; `invalid` on
|
|
93
|
+
`Input` only paints the border (WCAG 3.3.1, 4.1.2).
|
|
94
|
+
- `required` marks the input required and shows the asterisk in `FormLabel`.
|
|
95
|
+
Say "required" in words somewhere on the form too; an asterisk alone is a
|
|
96
|
+
symbol not everyone knows (WCAG 3.3.2).
|
|
97
|
+
|
|
98
|
+
## Tokens
|
|
99
|
+
|
|
100
|
+
None. FormControl draws nothing; the label colours are on the FormLabel page.
|
|
101
|
+
|
|
102
|
+
## Related
|
|
103
|
+
|
|
104
|
+
- **FieldRow**: the laid-out field.
|
|
105
|
+
- **FormLabel**, **FieldHelp**, **FieldError**: the parts.
|
|
106
|
+
|
|
107
|
+
</En>
|
|
108
|
+
|
|
109
|
+
<Ko>
|
|
110
|
+
|
|
111
|
+
## 접근성
|
|
112
|
+
|
|
113
|
+
- `FormControl`의 `invalid`는 입력란에 `aria-invalid`를 붙이고, `Input`의 `invalid`는
|
|
114
|
+
테두리만 칠합니다(WCAG 3.3.1, 4.1.2).
|
|
115
|
+
- `required`는 입력란을 필수로 표시하고 `FormLabel`에 별표를 보여 줍니다. 별표는 모두가
|
|
116
|
+
아는 기호가 아니므로 폼 어딘가에 "필수"라고 글자로도 적습니다(WCAG 3.3.2).
|
|
117
|
+
|
|
118
|
+
## 토큰
|
|
119
|
+
|
|
120
|
+
없습니다. FormControl은 아무것도 그리지 않습니다. 라벨 색은 FormLabel 페이지에
|
|
121
|
+
있습니다.
|
|
122
|
+
|
|
123
|
+
## 관련 컴포넌트
|
|
124
|
+
|
|
125
|
+
- **FieldRow**: 배치까지 된 필드.
|
|
126
|
+
- **FormLabel**, **FieldHelp**, **FieldError**: 부품.
|
|
127
|
+
|
|
128
|
+
</Ko>
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Canvas, Meta } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import { En, Ko, LangToggle, Verdict } from '../../guidelines/_components/Lang';
|
|
4
|
+
import * as FormIntegrationStories from './FormIntegration.stories';
|
|
5
|
+
|
|
6
|
+
<Meta title="Components/FormIntegration/Usage" />
|
|
7
|
+
|
|
8
|
+
<LangToggle />
|
|
9
|
+
|
|
10
|
+
<En>
|
|
11
|
+
|
|
12
|
+
# Form integration
|
|
13
|
+
|
|
14
|
+
How the form controls connect to a form library. There is no
|
|
15
|
+
`FormIntegration` component: this page and the stories under
|
|
16
|
+
**Examples/Form Integration** show the wiring.
|
|
17
|
+
|
|
18
|
+
## The rule
|
|
19
|
+
|
|
20
|
+
Put field state on the field, not on the control:
|
|
21
|
+
|
|
22
|
+
1. One `FieldRow` (or `FormControl`) per field. Set `error` on it from the
|
|
23
|
+
library's error for that field; `invalid` follows, and `aria-invalid` and
|
|
24
|
+
`aria-describedby` reach the control.
|
|
25
|
+
2. Pass the library's `value`, `onChange`, `onBlur` and `name` to the control.
|
|
26
|
+
`Input` re-emits change and blur events with `name` and the processed value
|
|
27
|
+
(trimmed, or digits only with `maskNumber`), so Formik's `handleChange` and
|
|
28
|
+
React Hook Form's `field.onChange` both work.
|
|
29
|
+
3. Controls with their own value API take it directly: `SelectField` /
|
|
30
|
+
`ComboboxField` `onChange(value)`, `RadioGroup` `onValueChange`, `Checkbox`
|
|
31
|
+
/ `Switch` `onCheckedChange`, `Slider` `onValueChange` (an array),
|
|
32
|
+
`FileInput` `onChange(files)`. With React Hook Form, wrap them in a
|
|
33
|
+
`Controller`.
|
|
34
|
+
|
|
35
|
+
## When to use which library
|
|
36
|
+
|
|
37
|
+
- **React Hook Form** with a `Controller` per non-text control: what FactChat
|
|
38
|
+
uses for admin and studio forms.
|
|
39
|
+
- **Formik + Yup**: the first example below.
|
|
40
|
+
- **Plain state**: small forms, the second example.
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
</En>
|
|
45
|
+
|
|
46
|
+
<Ko>
|
|
47
|
+
|
|
48
|
+
# 폼 연동
|
|
49
|
+
|
|
50
|
+
폼 컨트롤을 폼 라이브러리에 연결하는 방법입니다. `FormIntegration`이라는 컴포넌트는
|
|
51
|
+
없습니다. 이 페이지와 **Examples/Form Integration** 아래 스토리가 연결 방법을 보여
|
|
52
|
+
줍니다.
|
|
53
|
+
|
|
54
|
+
## 원칙
|
|
55
|
+
|
|
56
|
+
필드 상태는 컨트롤이 아니라 필드에 둡니다.
|
|
57
|
+
|
|
58
|
+
1. 필드마다 `FieldRow`(또는 `FormControl`)를 하나씩 둡니다. 라이브러리가 그 필드에
|
|
59
|
+
대해 준 오류를 `error`에 넣으면 `invalid`도 따라 바뀌고, `aria-invalid`와
|
|
60
|
+
`aria-describedby`가 컨트롤까지 전달됩니다.
|
|
61
|
+
2. 라이브러리의 `value`, `onChange`, `onBlur`, `name`을 컨트롤에 넘깁니다. `Input`은
|
|
62
|
+
변경·이탈 이벤트를 `name`과 가공한 값(공백을 정리한 값, `maskNumber`면 숫자만)으로
|
|
63
|
+
다시 만들어 보내므로 Formik의 `handleChange`와 React Hook Form의 `field.onChange`가
|
|
64
|
+
모두 동작합니다.
|
|
65
|
+
3. 값을 다루는 방식이 따로 있는 컨트롤은 그 방식을 그대로 씁니다. `SelectField`·
|
|
66
|
+
`ComboboxField`는 `onChange(value)`, `RadioGroup`은 `onValueChange`, `Checkbox`·
|
|
67
|
+
`Switch`는 `onCheckedChange`, `Slider`는 `onValueChange`(배열), `FileInput`은
|
|
68
|
+
`onChange(files)`입니다. React Hook Form에서는 `Controller`로 감쌉니다.
|
|
69
|
+
|
|
70
|
+
## 어떤 라이브러리를 쓰나요
|
|
71
|
+
|
|
72
|
+
- **React Hook Form**과 텍스트가 아닌 컨트롤마다 `Controller`: FactChat의 관리자·
|
|
73
|
+
스튜디오 폼이 쓰는 방식입니다.
|
|
74
|
+
- **Formik + Yup**: 아래 첫 번째 예시.
|
|
75
|
+
- **일반 상태**: 작은 폼. 아래 두 번째 예시.
|
|
76
|
+
|
|
77
|
+
## 예시
|
|
78
|
+
|
|
79
|
+
</Ko>
|
|
80
|
+
|
|
81
|
+
<Canvas of={FormIntegrationStories.FormikFormExample} />
|
|
82
|
+
<Verdict
|
|
83
|
+
kind="do"
|
|
84
|
+
en="Formik: the error for each field goes to that field's Field.Root, and the message renders under it."
|
|
85
|
+
ko="Formik: 필드마다 오류를 그 필드의 Field.Root에 넘기고, 문구는 필드 바로 아래에 그립니다."
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
<Canvas of={FormIntegrationStories.RegularFormExample} />
|
|
89
|
+
<Verdict
|
|
90
|
+
kind="do"
|
|
91
|
+
en="Plain state: validate on submit, keep errors in state per field, and clear a field's error when it changes."
|
|
92
|
+
ko="일반 상태: 제출할 때 검사하고, 오류는 필드별로 상태에 두며, 값이 바뀌면 그 필드의 오류를 지웁니다."
|
|
93
|
+
/>
|
|
94
|
+
|
|
95
|
+
<En>
|
|
96
|
+
|
|
97
|
+
## Pitfalls
|
|
98
|
+
|
|
99
|
+
- **`trimWhiteSpace` trims on every keystroke**, so a name with a space can
|
|
100
|
+
only be pasted. Trim at submit instead.
|
|
101
|
+
- **`maskNumber` needs `type="number"`** and then renders a text input; `min`
|
|
102
|
+
and `max` do nothing there. Validate the range in the schema.
|
|
103
|
+
- **`SelectField` inside `FieldRow` needs `ariaLabel`** with the row's label;
|
|
104
|
+
the row's label does not name it.
|
|
105
|
+
- **Don't set `invalid` on the control alone.** It paints the border without
|
|
106
|
+
telling assistive technology (WCAG 3.3.1).
|
|
107
|
+
|
|
108
|
+
## Accessibility
|
|
109
|
+
|
|
110
|
+
- Every field has a visible label (WCAG 3.3.2; KWCAG 5.3.4.1 레이블 제공), and
|
|
111
|
+
every error is text under its field (WCAG 3.3.1).
|
|
112
|
+
- After a failed submit, move focus to the first invalid field or to an error
|
|
113
|
+
summary at the top.
|
|
114
|
+
- Do not disable the submit button until the form is valid without saying
|
|
115
|
+
why; the user cannot find out what is missing. Validate on submit and show
|
|
116
|
+
the errors.
|
|
117
|
+
|
|
118
|
+
## Tokens
|
|
119
|
+
|
|
120
|
+
None of its own; see Input, Select and Form.
|
|
121
|
+
|
|
122
|
+
## Related
|
|
123
|
+
|
|
124
|
+
- **Form** (`FieldRow`, `FormSection`, footers), **FormControl**, **Input**,
|
|
125
|
+
**Select**.
|
|
126
|
+
|
|
127
|
+
</En>
|
|
128
|
+
|
|
129
|
+
<Ko>
|
|
130
|
+
|
|
131
|
+
## 자주 하는 실수
|
|
132
|
+
|
|
133
|
+
- **`trimWhiteSpace`는 입력할 때마다 공백을 지웁니다.** 그래서 공백이 든 이름은 붙여
|
|
134
|
+
넣기로만 넣을 수 있습니다. 공백 정리는 제출할 때 합니다.
|
|
135
|
+
- **`maskNumber`는 `type="number"`가 있어야 동작하고**, 그때는 텍스트 입력란을 그립니다.
|
|
136
|
+
`min`과 `max`는 효과가 없으므로 범위는 스키마에서 검사합니다.
|
|
137
|
+
- **`FieldRow` 안의 `SelectField`에는 행의 라벨을 `ariaLabel`로 넘깁니다.** 행의 라벨은
|
|
138
|
+
셀렉트의 이름이 되지 않습니다.
|
|
139
|
+
- **컨트롤에만 `invalid`를 주지 않습니다.** 테두리만 칠하고 보조기술에는 알리지
|
|
140
|
+
않습니다(WCAG 3.3.1).
|
|
141
|
+
|
|
142
|
+
## 접근성
|
|
143
|
+
|
|
144
|
+
- 모든 필드에 보이는 라벨을 두고(WCAG 3.3.2, KWCAG 5.3.4.1 레이블 제공), 모든 오류는 해당
|
|
145
|
+
필드 아래에 문구로 보여 줍니다(WCAG 3.3.1).
|
|
146
|
+
- 제출에 실패하면 첫 오류 필드나 위쪽의 오류 요약으로 초점을 옮깁니다.
|
|
147
|
+
- 이유를 알리지 않은 채 폼이 유효해질 때까지 제출 버튼을 비활성으로 두지 않습니다.
|
|
148
|
+
무엇이 빠졌는지 알 수 없습니다. 제출할 때 검사하고 오류를 보여 줍니다.
|
|
149
|
+
|
|
150
|
+
## 토큰
|
|
151
|
+
|
|
152
|
+
따로 정한 토큰이 없습니다. Input, Select, Form 페이지를 보세요.
|
|
153
|
+
|
|
154
|
+
## 관련 컴포넌트
|
|
155
|
+
|
|
156
|
+
- **Form**(`FieldRow`, `FormSection`, 푸터), **FormControl**, **Input**, **Select**.
|
|
157
|
+
|
|
158
|
+
</Ko>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Stack } from '@chakra-ui/react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
|
|
4
|
+
import { FormControl } from '../FormControl';
|
|
5
|
+
import { Input } from '../Input';
|
|
6
|
+
import { FormLabel } from './FormLabel';
|
|
7
|
+
|
|
8
|
+
const meta = {
|
|
9
|
+
title: 'Components/FormLabel',
|
|
10
|
+
component: FormLabel,
|
|
11
|
+
parameters: { layout: 'centered' },
|
|
12
|
+
} satisfies Meta<typeof FormLabel>;
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
|
|
16
|
+
type Story = StoryObj<typeof meta>;
|
|
17
|
+
|
|
18
|
+
/** A label inside `FormControl`; it is associated with the control for you. */
|
|
19
|
+
export const Basic: Story = {
|
|
20
|
+
render: () => (
|
|
21
|
+
<FormControl w="300px">
|
|
22
|
+
<FormLabel>표시 이름</FormLabel>
|
|
23
|
+
<Input placeholder="홍길동" />
|
|
24
|
+
</FormControl>
|
|
25
|
+
),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** `required` on `FormControl` adds the asterisk; nothing to pass here. */
|
|
29
|
+
export const Required: Story = {
|
|
30
|
+
render: () => (
|
|
31
|
+
<FormControl required w="300px">
|
|
32
|
+
<FormLabel>업무용 이메일</FormLabel>
|
|
33
|
+
<Input type="email" />
|
|
34
|
+
</FormControl>
|
|
35
|
+
),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// ───────────────────────── Usage-page specimens ─────────────────────────
|
|
39
|
+
// Pulled into `FormLabel.usage.mdx` with <Canvas of={…} />. Hidden (`!dev`).
|
|
40
|
+
|
|
41
|
+
export const DoNounLabels: Story = {
|
|
42
|
+
tags: ['!dev'],
|
|
43
|
+
parameters: { layout: 'padded' },
|
|
44
|
+
name: 'Usage / Do: short noun labels',
|
|
45
|
+
render: () => (
|
|
46
|
+
<Stack gap={4} maxW="320px">
|
|
47
|
+
<FormControl required>
|
|
48
|
+
<FormLabel>그룹 이름</FormLabel>
|
|
49
|
+
<Input />
|
|
50
|
+
</FormControl>
|
|
51
|
+
<FormControl>
|
|
52
|
+
<FormLabel>설명</FormLabel>
|
|
53
|
+
<Input />
|
|
54
|
+
</FormControl>
|
|
55
|
+
</Stack>
|
|
56
|
+
),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const DontSentenceLabels: Story = {
|
|
60
|
+
tags: ['!dev'],
|
|
61
|
+
parameters: { layout: 'padded' },
|
|
62
|
+
name: "Usage / Don't: instructions as labels",
|
|
63
|
+
render: () => (
|
|
64
|
+
<Stack gap={4} maxW="320px">
|
|
65
|
+
<FormControl required>
|
|
66
|
+
<FormLabel>그룹 이름을 입력해 주세요 (필수):</FormLabel>
|
|
67
|
+
<Input />
|
|
68
|
+
</FormControl>
|
|
69
|
+
</Stack>
|
|
70
|
+
),
|
|
71
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Canvas, Meta } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import { En, Ko, LangToggle, Verdict } from '../../guidelines/_components/Lang';
|
|
4
|
+
import * as FormLabelStories from './FormLabel.stories';
|
|
5
|
+
|
|
6
|
+
<Meta of={FormLabelStories} name="Usage" />
|
|
7
|
+
|
|
8
|
+
<LangToggle />
|
|
9
|
+
|
|
10
|
+
<En>
|
|
11
|
+
|
|
12
|
+
# FormLabel
|
|
13
|
+
|
|
14
|
+
The visible label of a field. Inside `FormControl` it is associated with the
|
|
15
|
+
control and shows the required asterisk on its own.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
- Inside `FormControl`, when you compose a field by hand. `FieldRow` (through
|
|
20
|
+
`FieldLabel`) already renders one.
|
|
21
|
+
|
|
22
|
+
## When not to use
|
|
23
|
+
|
|
24
|
+
- A section title → `FormSection` `title`.
|
|
25
|
+
- A label for a checkbox, radio or switch option → `Checkbox.Label`,
|
|
26
|
+
`Radio.Text`, `Switch.Label`.
|
|
27
|
+
|
|
28
|
+
## Do / Don't
|
|
29
|
+
|
|
30
|
+
</En>
|
|
31
|
+
|
|
32
|
+
<Ko>
|
|
33
|
+
|
|
34
|
+
# FormLabel
|
|
35
|
+
|
|
36
|
+
필드의 보이는 라벨입니다. `FormControl` 안에서는 컨트롤과 연결되고 필수 별표도 알아서
|
|
37
|
+
보여 줍니다.
|
|
38
|
+
|
|
39
|
+
## 언제 쓰나요
|
|
40
|
+
|
|
41
|
+
- 필드를 직접 조합할 때 `FormControl` 안에서 씁니다. `FieldRow`는 `FieldLabel`을 통해
|
|
42
|
+
이미 FormLabel을 그립니다.
|
|
43
|
+
|
|
44
|
+
## 언제 쓰지 않나요
|
|
45
|
+
|
|
46
|
+
- 섹션 제목은 `FormSection`의 `title`을 씁니다.
|
|
47
|
+
- 체크박스, 라디오, 스위치 선택지의 라벨은 `Checkbox.Label`, `Radio.Text`,
|
|
48
|
+
`Switch.Label`을 씁니다.
|
|
49
|
+
|
|
50
|
+
## 이렇게 하세요 / 이렇게 하지 마세요
|
|
51
|
+
|
|
52
|
+
</Ko>
|
|
53
|
+
|
|
54
|
+
<Canvas of={FormLabelStories.DoNounLabels} />
|
|
55
|
+
<Verdict
|
|
56
|
+
kind="do"
|
|
57
|
+
en="Write short nouns and let FormControl required add the asterisk."
|
|
58
|
+
ko="짧은 명사로 쓰고, 별표는 FormControl의 required가 붙이게 둡니다."
|
|
59
|
+
/>
|
|
60
|
+
|
|
61
|
+
<Canvas of={FormLabelStories.DontSentenceLabels} />
|
|
62
|
+
<Verdict
|
|
63
|
+
kind="dont"
|
|
64
|
+
en="Write an instruction with a colon and type '(필수)' by hand. The asterisk already says it, so the label says it twice."
|
|
65
|
+
ko="쌍점을 붙인 지시문으로 쓰거나 '(필수)'를 직접 적지 마세요. 별표가 이미 알려 주므로 두 번 말하게 됩니다."
|
|
66
|
+
/>
|
|
67
|
+
|
|
68
|
+
<En>
|
|
69
|
+
|
|
70
|
+
## Content
|
|
71
|
+
|
|
72
|
+
- A noun phrase in sentence case, no colon, no "(required)".
|
|
73
|
+
- Keep it under about four words; anything longer goes in `FieldRow`
|
|
74
|
+
`description` or helper text.
|
|
75
|
+
|
|
76
|
+
## Accessibility
|
|
77
|
+
|
|
78
|
+
- It renders Chakra's `Field.Label`, a `<label>` whose `for` is the field's
|
|
79
|
+
control id, so clicking it focuses the control and screen readers read it as
|
|
80
|
+
the control's name (WCAG 1.3.1, 4.1.2; KWCAG 5.3.4.1 레이블 제공).
|
|
81
|
+
- Outside `FormControl` there is no id to point at: pass `htmlFor` yourself.
|
|
82
|
+
- Composed controls (`SelectField`, `ComboboxField`, `Slider`) are not named
|
|
83
|
+
by it; give them `label` or `ariaLabel`.
|
|
84
|
+
|
|
85
|
+
## Tokens
|
|
86
|
+
|
|
87
|
+
The label text is `fg.muted` from its wrapper (`FieldLabel` overrides it to
|
|
88
|
+
`fg.default`, semibold). The asterisk is `danger.fg`.
|
|
89
|
+
|
|
90
|
+
## Related
|
|
91
|
+
|
|
92
|
+
- **FormControl**: the field it labels.
|
|
93
|
+
- **FieldRow** / **FieldLabel**: the laid-out label with description and an
|
|
94
|
+
end slot.
|
|
95
|
+
|
|
96
|
+
</En>
|
|
97
|
+
|
|
98
|
+
<Ko>
|
|
99
|
+
|
|
100
|
+
## 문구
|
|
101
|
+
|
|
102
|
+
- 문장형 대소문자의 명사구로 쓰고, 쌍점이나 "(필수)"를 붙이지 않습니다.
|
|
103
|
+
- 네 단어 안팎으로 씁니다. 더 긴 설명은 `FieldRow`의 `description`이나 도움말에
|
|
104
|
+
넣습니다.
|
|
105
|
+
|
|
106
|
+
## 접근성
|
|
107
|
+
|
|
108
|
+
- Chakra `Field.Label`을 그립니다. `for`가 필드 컨트롤의 id인 `<label>`이라, 누르면
|
|
109
|
+
컨트롤로 초점이 가고 화면 낭독기는 이를 컨트롤의 이름으로 읽습니다(WCAG 1.3.1, 4.1.2,
|
|
110
|
+
KWCAG 5.3.4.1 레이블 제공).
|
|
111
|
+
- `FormControl` 밖에서는 가리킬 id가 없으므로 `htmlFor`를 직접 넘깁니다.
|
|
112
|
+
- 부품을 조합한 컨트롤(`SelectField`, `ComboboxField`, `Slider`)에는 이 라벨이 이름으로
|
|
113
|
+
닿지 않습니다. `label`이나 `ariaLabel`을 줍니다.
|
|
114
|
+
|
|
115
|
+
## 토큰
|
|
116
|
+
|
|
117
|
+
라벨 글자는 감싸는 요소의 `fg.muted`를 씁니다(`FieldLabel`은 `fg.default` 굵은
|
|
118
|
+
글자로 바꿉니다). 별표는 `danger.fg`입니다.
|
|
119
|
+
|
|
120
|
+
## 관련 컴포넌트
|
|
121
|
+
|
|
122
|
+
- **FormControl**: 라벨이 붙는 필드.
|
|
123
|
+
- **FieldRow** / **FieldLabel**: 설명과 끝 자리가 있는 배치된 라벨.
|
|
124
|
+
|
|
125
|
+
</Ko>
|
|
@@ -13,9 +13,18 @@ import { useMemo } from 'react';
|
|
|
13
13
|
import { FaBuildingUser } from 'react-icons/fa6';
|
|
14
14
|
import { MdDashboard } from 'react-icons/md';
|
|
15
15
|
|
|
16
|
+
import { TokenTable } from '../../guidelines/_components/TokenTable';
|
|
17
|
+
import { Button } from '../Button';
|
|
18
|
+
import { IconButton } from '../IconButton';
|
|
16
19
|
import { Icons } from './_constants/iconList';
|
|
17
20
|
import { createIcon } from './_utils/createIcon';
|
|
18
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
Analytics,
|
|
23
|
+
CheckIcon,
|
|
24
|
+
CloseIcon,
|
|
25
|
+
DownloadIcon,
|
|
26
|
+
TrashIcon,
|
|
27
|
+
} from './index';
|
|
19
28
|
|
|
20
29
|
const meta = {
|
|
21
30
|
title: 'Components/Icon',
|
|
@@ -423,3 +432,54 @@ const MyCustomIcon = createIcon(
|
|
|
423
432
|
</VStack>
|
|
424
433
|
),
|
|
425
434
|
};
|
|
435
|
+
|
|
436
|
+
// ───────────────────────── Usage-page specimens ─────────────────────────
|
|
437
|
+
// Pulled into `Icon.usage.mdx` with <Canvas of={…} />. Hidden from the
|
|
438
|
+
// sidebar (`!dev`); `tags` is written out on each story because the indexer
|
|
439
|
+
// reads CSF statically.
|
|
440
|
+
|
|
441
|
+
export const DoIconWithLabel: Story = {
|
|
442
|
+
tags: ['!dev'],
|
|
443
|
+
parameters: { layout: 'padded' },
|
|
444
|
+
name: 'Usage / Do: decorative next to a label, named when alone',
|
|
445
|
+
render: () => (
|
|
446
|
+
<HStack gap={3}>
|
|
447
|
+
<Button variant="secondary">
|
|
448
|
+
<DownloadIcon boxSize="xs" aria-hidden />
|
|
449
|
+
내려받기
|
|
450
|
+
</Button>
|
|
451
|
+
<IconButton aria-label="삭제" variant="ghost">
|
|
452
|
+
<TrashIcon boxSize="xs" aria-hidden />
|
|
453
|
+
</IconButton>
|
|
454
|
+
</HStack>
|
|
455
|
+
),
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
export const DontIconAsStatus: Story = {
|
|
459
|
+
tags: ['!dev'],
|
|
460
|
+
parameters: { layout: 'padded' },
|
|
461
|
+
name: "Usage / Don't: a coloured icon as the only status",
|
|
462
|
+
render: () => (
|
|
463
|
+
<HStack gap={4}>
|
|
464
|
+
<Text>결제 1</Text>
|
|
465
|
+
<CheckIcon boxSize="xs" color="success.fg" />
|
|
466
|
+
<Text>결제 2</Text>
|
|
467
|
+
<CloseIcon boxSize="xs" color="danger.fg" />
|
|
468
|
+
</HStack>
|
|
469
|
+
),
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
export const UsageTokens: Story = {
|
|
473
|
+
tags: ['!dev'],
|
|
474
|
+
parameters: { layout: 'padded' },
|
|
475
|
+
name: 'Usage / Tokens',
|
|
476
|
+
render: () => (
|
|
477
|
+
<TokenTable
|
|
478
|
+
rows={[
|
|
479
|
+
{ token: 'fg.icon', use: 'icons on their own (stories default)' },
|
|
480
|
+
{ token: 'fg.default', use: 'icon in running text' },
|
|
481
|
+
{ token: 'fg.muted', use: 'secondary icon' },
|
|
482
|
+
]}
|
|
483
|
+
/>
|
|
484
|
+
),
|
|
485
|
+
};
|