@mindlogic-ai/logician-ui 5.0.0-alpha.3 → 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.
Files changed (240) hide show
  1. package/dist/components/Banner/Banner.types.d.ts +24 -1
  2. package/dist/components/Banner/Banner.types.d.ts.map +1 -1
  3. package/dist/components/Card/Card.types.d.ts +12 -0
  4. package/dist/components/Card/Card.types.d.ts.map +1 -1
  5. package/dist/components/ColorMode/ColorModeToggle.d.ts +7 -2
  6. package/dist/components/ColorMode/ColorModeToggle.d.ts.map +1 -1
  7. package/dist/components/ColorMode/ColorModeToggle.js +8 -3
  8. package/dist/components/ColorMode/ColorModeToggle.js.map +1 -1
  9. package/dist/components/ColorMode/ColorModeToggle.mjs +8 -3
  10. package/dist/components/ColorMode/ColorModeToggle.mjs.map +1 -1
  11. package/dist/components/Confetti/Confetti.types.d.ts +5 -1
  12. package/dist/components/Confetti/Confetti.types.d.ts.map +1 -1
  13. package/dist/components/Confetti/confettiColors.d.ts +5 -5
  14. package/dist/components/Confetti/confettiColors.js +5 -5
  15. package/dist/components/Confetti/confettiColors.mjs +5 -5
  16. package/dist/components/ErrorFallback/ErrorFallback.types.d.ts +6 -0
  17. package/dist/components/ErrorFallback/ErrorFallback.types.d.ts.map +1 -1
  18. package/dist/components/Form/FormModalFooter/FormModalFooter.types.d.ts +4 -1
  19. package/dist/components/Form/FormModalFooter/FormModalFooter.types.d.ts.map +1 -1
  20. package/dist/components/LineGraph/LineGraph.d.ts.map +1 -1
  21. package/dist/components/LineGraph/LineGraph.js +4 -5
  22. package/dist/components/LineGraph/LineGraph.js.map +1 -1
  23. package/dist/components/LineGraph/LineGraph.mjs +5 -6
  24. package/dist/components/LineGraph/LineGraph.mjs.map +1 -1
  25. package/dist/components/LineGraph/LineGraph.types.d.ts +12 -2
  26. package/dist/components/LineGraph/LineGraph.types.d.ts.map +1 -1
  27. package/dist/components/LineGraph/seriesColors.d.ts +12 -8
  28. package/dist/components/LineGraph/seriesColors.d.ts.map +1 -1
  29. package/dist/components/LineGraph/seriesColors.js +8 -7
  30. package/dist/components/LineGraph/seriesColors.js.map +1 -1
  31. package/dist/components/LineGraph/seriesColors.mjs +8 -7
  32. package/dist/components/LineGraph/seriesColors.mjs.map +1 -1
  33. package/dist/components/Masonry/Masonry.types.d.ts +8 -3
  34. package/dist/components/Masonry/Masonry.types.d.ts.map +1 -1
  35. package/dist/components/Menu/MenuItem.types.d.ts +8 -0
  36. package/dist/components/Menu/MenuItem.types.d.ts.map +1 -1
  37. package/dist/components/Modal/ModalCloseButton.d.ts +1 -1
  38. package/dist/components/Modal/ModalCloseButton.js +1 -1
  39. package/dist/components/Modal/ModalCloseButton.mjs +1 -1
  40. package/dist/components/Pagination/Pagination.d.ts +11 -10
  41. package/dist/components/Pagination/Pagination.d.ts.map +1 -1
  42. package/dist/components/Pagination/Pagination.js +11 -10
  43. package/dist/components/Pagination/Pagination.js.map +1 -1
  44. package/dist/components/Pagination/Pagination.mjs +11 -10
  45. package/dist/components/Pagination/Pagination.mjs.map +1 -1
  46. package/dist/components/ProgressBar/ProgressBar.types.d.ts +9 -0
  47. package/dist/components/ProgressBar/ProgressBar.types.d.ts.map +1 -1
  48. package/dist/components/RadialProgress/RadialProgress.types.d.ts +21 -1
  49. package/dist/components/RadialProgress/RadialProgress.types.d.ts.map +1 -1
  50. package/dist/components/SeeMoreButton/SeeMoreButton.types.d.ts +8 -0
  51. package/dist/components/SeeMoreButton/SeeMoreButton.types.d.ts.map +1 -1
  52. package/dist/components/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  53. package/dist/components/SegmentedControl/SegmentedControl.js +6 -7
  54. package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
  55. package/dist/components/SegmentedControl/SegmentedControl.mjs +6 -7
  56. package/dist/components/SegmentedControl/SegmentedControl.mjs.map +1 -1
  57. package/dist/components/SegmentedProgressBar/SegmentedProgressBar.types.d.ts +2 -0
  58. package/dist/components/SegmentedProgressBar/SegmentedProgressBar.types.d.ts.map +1 -1
  59. package/dist/components/Toast/Toast.styles.d.ts +6 -2
  60. package/dist/components/Toast/Toast.styles.d.ts.map +1 -1
  61. package/dist/components/Toast/Toast.styles.js +18 -10
  62. package/dist/components/Toast/Toast.styles.js.map +1 -1
  63. package/dist/components/Toast/Toast.styles.mjs +18 -10
  64. package/dist/components/Toast/Toast.styles.mjs.map +1 -1
  65. package/dist/theme/colors.d.ts +2 -2
  66. package/dist/theme/colors.d.ts.map +1 -1
  67. package/dist/theme/colors.js +22 -2
  68. package/dist/theme/colors.js.map +1 -1
  69. package/dist/theme/colors.mjs +23 -3
  70. package/dist/theme/colors.mjs.map +1 -1
  71. package/dist/theme/palette.generated.d.ts +98 -0
  72. package/dist/theme/palette.generated.d.ts.map +1 -1
  73. package/dist/theme/palette.generated.js +99 -0
  74. package/dist/theme/palette.generated.js.map +1 -1
  75. package/dist/theme/palette.generated.mjs +99 -1
  76. package/dist/theme/palette.generated.mjs.map +1 -1
  77. package/dist/theme/paletteSwatches.d.ts +20 -0
  78. package/dist/theme/paletteSwatches.d.ts.map +1 -1
  79. package/package.json +1 -1
  80. package/src/components/Accordion/Accordion.stories.tsx +85 -0
  81. package/src/components/Accordion/Accordion.usage.mdx +200 -0
  82. package/src/components/Appear/Appear.usage.mdx +107 -0
  83. package/src/components/Avatar/Avatar.stories.tsx +71 -1
  84. package/src/components/Avatar/Avatar.usage.mdx +166 -0
  85. package/src/components/Banner/Banner.stories.tsx +152 -2
  86. package/src/components/Banner/Banner.types.ts +30 -1
  87. package/src/components/Banner/Banner.usage.mdx +233 -0
  88. package/src/components/BottomSheet/BottomSheet.stories.tsx +168 -1
  89. package/src/components/BottomSheet/BottomSheet.usage.mdx +216 -0
  90. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +59 -0
  91. package/src/components/Breadcrumb/Breadcrumb.usage.mdx +181 -0
  92. package/src/components/Button/Button.stories.tsx +263 -3
  93. package/src/components/Button/Button.usage.mdx +342 -0
  94. package/src/components/Card/Card.stories.tsx +106 -0
  95. package/src/components/Card/Card.types.ts +12 -0
  96. package/src/components/Card/Card.usage.mdx +216 -0
  97. package/src/components/Checkbox/Checkbox.stories.tsx +140 -13
  98. package/src/components/Checkbox/Checkbox.usage.mdx +214 -0
  99. package/src/components/Chip/Chip.usage.mdx +78 -0
  100. package/src/components/Code/Code.stories.tsx +60 -0
  101. package/src/components/Code/Code.usage.mdx +187 -0
  102. package/src/components/CodeTabs/CodeTabs.stories.tsx +53 -0
  103. package/src/components/CodeTabs/CodeTabs.usage.mdx +176 -0
  104. package/src/components/Collapsible/Collapsible.stories.tsx +58 -0
  105. package/src/components/Collapsible/Collapsible.usage.mdx +173 -0
  106. package/src/components/ColorMode/ColorMode.stories.tsx +50 -0
  107. package/src/components/ColorMode/ColorMode.usage.mdx +135 -0
  108. package/src/components/ColorMode/ColorModeToggle.tsx +10 -3
  109. package/src/components/Confetti/Confetti.types.ts +5 -1
  110. package/src/components/Confetti/Confetti.usage.mdx +111 -0
  111. package/src/components/Confetti/confettiColors.ts +5 -5
  112. package/src/components/Container/Container.stories.tsx +32 -0
  113. package/src/components/Container/Container.usage.mdx +130 -0
  114. package/src/components/CopyableCode/CopyableCode.stories.tsx +62 -0
  115. package/src/components/CopyableCode/CopyableCode.usage.mdx +168 -0
  116. package/src/components/CountBadge/CountBadge.stories.tsx +69 -0
  117. package/src/components/CountBadge/CountBadge.usage.mdx +215 -0
  118. package/src/components/CountUp/CountUp.usage.mdx +107 -0
  119. package/src/components/DatePicker/DatePicker.usage.mdx +177 -0
  120. package/src/components/DatePicker/RangeDatePicker.stories.tsx +87 -3
  121. package/src/components/ErrorFallback/ErrorFallback.types.ts +6 -0
  122. package/src/components/ErrorFallback/ErrorFallback.usage.mdx +127 -0
  123. package/src/components/ExpandableText/ExpandableText.stories.tsx +55 -0
  124. package/src/components/ExpandableText/ExpandableText.usage.mdx +176 -0
  125. package/src/components/FileInput/FileInput.stories.tsx +38 -1
  126. package/src/components/FileInput/FileInput.usage.mdx +178 -0
  127. package/src/components/FileItem/FileItem.stories.tsx +71 -0
  128. package/src/components/FileItem/FileItem.usage.mdx +180 -0
  129. package/src/components/FileList/FileList.stories.tsx +25 -0
  130. package/src/components/FileList/FileList.usage.mdx +165 -0
  131. package/src/components/FlyTo/FlyTo.usage.mdx +99 -0
  132. package/src/components/Form/Form.stories.tsx +149 -0
  133. package/src/components/Form/Form.usage.mdx +201 -0
  134. package/src/components/Form/FormModalFooter/FormModalFooter.types.ts +4 -1
  135. package/src/components/FormControl/FormControl.stories.tsx +35 -0
  136. package/src/components/FormControl/FormControl.usage.mdx +128 -0
  137. package/src/components/FormIntegration/FormIntegration.usage.mdx +158 -0
  138. package/src/components/FormLabel/FormLabel.stories.tsx +71 -0
  139. package/src/components/FormLabel/FormLabel.usage.mdx +125 -0
  140. package/src/components/Icon/Icon.stories.tsx +61 -1
  141. package/src/components/Icon/Icon.usage.mdx +158 -0
  142. package/src/components/IconButton/IconButton.stories.tsx +209 -5
  143. package/src/components/IconButton/IconButton.usage.mdx +273 -0
  144. package/src/components/InfoSprinkle/InfoSprinkle.stories.tsx +77 -1
  145. package/src/components/InfoSprinkle/InfoSprinkle.usage.mdx +189 -0
  146. package/src/components/InlineCode/InlineCode.stories.tsx +75 -0
  147. package/src/components/InlineCode/InlineCode.usage.mdx +142 -0
  148. package/src/components/Input/Input.stories.tsx +180 -0
  149. package/src/components/Input/Input.usage.mdx +278 -0
  150. package/src/components/LineGraph/LineGraph.stories.tsx +112 -0
  151. package/src/components/LineGraph/LineGraph.tsx +4 -5
  152. package/src/components/LineGraph/LineGraph.types.ts +12 -2
  153. package/src/components/LineGraph/LineGraph.usage.mdx +186 -0
  154. package/src/components/LineGraph/seriesColors.test.ts +11 -10
  155. package/src/components/LineGraph/seriesColors.ts +18 -16
  156. package/src/components/Loaders/Loaders.stories.tsx +93 -0
  157. package/src/components/Loaders/Loaders.usage.mdx +180 -0
  158. package/src/components/LogicianProvider/LogicianProvider.usage.mdx +98 -0
  159. package/src/components/Markdown/Markdown.stories.tsx +53 -0
  160. package/src/components/Markdown/Markdown.usage.mdx +182 -0
  161. package/src/components/Masonry/Masonry.stories.tsx +63 -1
  162. package/src/components/Masonry/Masonry.types.ts +8 -3
  163. package/src/components/Masonry/Masonry.usage.mdx +142 -0
  164. package/src/components/MaxLengthIndicator/MaxLengthIndicator.stories.tsx +57 -0
  165. package/src/components/MaxLengthIndicator/MaxLengthIndicator.usage.mdx +125 -0
  166. package/src/components/Menu/Menu.stories.tsx +146 -2
  167. package/src/components/Menu/Menu.usage.mdx +230 -0
  168. package/src/components/Menu/MenuItem.types.ts +8 -0
  169. package/src/components/Modal/Modal.stories.tsx +177 -1
  170. package/src/components/Modal/Modal.usage.mdx +262 -0
  171. package/src/components/Modal/ModalCloseButton.tsx +1 -1
  172. package/src/components/MonthPicker/MonthPicker.stories.tsx +30 -0
  173. package/src/components/MonthPicker/MonthPicker.usage.mdx +191 -0
  174. package/src/components/Pagination/Pagination.stories.tsx +90 -1
  175. package/src/components/Pagination/Pagination.tsx +11 -10
  176. package/src/components/Pagination/Pagination.usage.mdx +186 -0
  177. package/src/components/PasswordInput/PasswordInput.stories.tsx +51 -0
  178. package/src/components/PasswordInput/PasswordInput.usage.mdx +193 -0
  179. package/src/components/PinInput/PinInput.stories.tsx +91 -0
  180. package/src/components/PinInput/PinInput.usage.mdx +194 -0
  181. package/src/components/Popover/Popover.stories.tsx +104 -1
  182. package/src/components/Popover/Popover.usage.mdx +197 -0
  183. package/src/components/ProgressBar/ProgressBar.stories.tsx +92 -1
  184. package/src/components/ProgressBar/ProgressBar.types.ts +9 -0
  185. package/src/components/ProgressBar/ProgressBar.usage.mdx +210 -0
  186. package/src/components/Pulse/Pulse.usage.mdx +102 -0
  187. package/src/components/RadialProgress/RadialProgress.stories.tsx +74 -1
  188. package/src/components/RadialProgress/RadialProgress.types.ts +21 -1
  189. package/src/components/RadialProgress/RadialProgress.usage.mdx +153 -0
  190. package/src/components/Radio/Radio.stories.tsx +119 -0
  191. package/src/components/Radio/Radio.usage.mdx +187 -0
  192. package/src/components/Reveal/Reveal.usage.mdx +105 -0
  193. package/src/components/ScaledContext/ScaledContext.usage.mdx +111 -0
  194. package/src/components/SeeMoreButton/SeeMoreButton.stories.tsx +146 -2
  195. package/src/components/SeeMoreButton/SeeMoreButton.types.ts +8 -0
  196. package/src/components/SeeMoreButton/SeeMoreButton.usage.mdx +213 -0
  197. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +69 -0
  198. package/src/components/SegmentedControl/SegmentedControl.tsx +6 -7
  199. package/src/components/SegmentedControl/SegmentedControl.usage.mdx +209 -0
  200. package/src/components/SegmentedProgressBar/SegmentedProgressBar.stories.tsx +54 -0
  201. package/src/components/SegmentedProgressBar/SegmentedProgressBar.types.ts +2 -0
  202. package/src/components/SegmentedProgressBar/SegmentedProgressBar.usage.mdx +145 -0
  203. package/src/components/Select/Select.stories.tsx +209 -1
  204. package/src/components/Select/Select.usage.mdx +278 -0
  205. package/src/components/Shake/Shake.usage.mdx +107 -0
  206. package/src/components/Slider/Slider.stories.tsx +116 -0
  207. package/src/components/Slider/Slider.usage.mdx +179 -0
  208. package/src/components/Spinner/Spinner.stories.tsx +64 -0
  209. package/src/components/Spinner/Spinner.usage.mdx +136 -0
  210. package/src/components/SwapTransition/SwapTransition.usage.mdx +102 -0
  211. package/src/components/Switch/Switch.stories.tsx +131 -6
  212. package/src/components/Switch/Switch.usage.mdx +199 -0
  213. package/src/components/Table/Table.stories.tsx +159 -1
  214. package/src/components/Table/Table.usage.mdx +235 -0
  215. package/src/components/Tabs/Tabs.stories.tsx +86 -0
  216. package/src/components/Tabs/Tabs.usage.mdx +219 -0
  217. package/src/components/Tag/Tag.stories.tsx +181 -4
  218. package/src/components/Tag/Tag.usage.mdx +257 -0
  219. package/src/components/Textarea/Textarea.stories.tsx +113 -0
  220. package/src/components/Textarea/Textarea.usage.mdx +186 -0
  221. package/src/components/Toast/Toast.stories.tsx +185 -3
  222. package/src/components/Toast/Toast.styles.ts +18 -10
  223. package/src/components/Toast/Toast.usage.mdx +265 -0
  224. package/src/components/Tooltip/Tooltip.stories.tsx +86 -1
  225. package/src/components/Tooltip/Tooltip.usage.mdx +211 -0
  226. package/src/components/Tree/Tree.stories.tsx +89 -0
  227. package/src/components/Tree/Tree.usage.mdx +207 -0
  228. package/src/components/Typography/Typography.stories.tsx +117 -0
  229. package/src/components/Typography/Typography.usage.mdx +251 -0
  230. package/src/components/Workflow/Workflow.usage.mdx +199 -0
  231. package/src/components/noRawScales.test.ts +5 -1
  232. package/src/foundations/BrandColour.mdx +65 -2
  233. package/src/theme/BazePalette.stories.tsx +111 -1
  234. package/src/theme/Palette.stories.tsx +2 -2
  235. package/src/theme/SemanticTokens.mdx +75 -16
  236. package/src/theme/claude.md +15 -9
  237. package/src/theme/colors.ts +33 -3
  238. package/src/theme/contrast.test.ts +32 -0
  239. package/src/theme/palette.generated.ts +99 -0
  240. package/src/theme/paletteSwatches.ts +35 -0
@@ -0,0 +1,194 @@
1
+ import { ArgTypes, Canvas, Meta } from '@storybook/blocks';
2
+
3
+ import { En, Ko, LangToggle, Verdict } from '../../guidelines/_components/Lang';
4
+ import * as PinInputStories from './PinInput.stories';
5
+
6
+ <Meta of={PinInputStories} name="Usage" />
7
+
8
+ <LangToggle />
9
+
10
+ <En>
11
+
12
+ # PinInput
13
+
14
+ A row of single-character boxes for a short code: a sign-in code sent by
15
+ email, a two-factor code from an authenticator app.
16
+
17
+ ## When to use
18
+
19
+ - A code of fixed, known length (4 to 8 characters) that the user copies from
20
+ somewhere else.
21
+
22
+ ## When not to use
23
+
24
+ - A password → `PasswordInput`.
25
+ - A code of unknown or variable length, or one usually pasted from a
26
+ clipboard as a whole (a licence key, an invite token) → `Input`.
27
+
28
+ ## Props
29
+
30
+ </En>
31
+
32
+ <Ko>
33
+
34
+ # PinInput
35
+
36
+ 짧은 코드를 한 칸에 한 글자씩 받는 입력란입니다. 메일로 받은 로그인 코드나 인증 앱의
37
+ 2단계 인증 코드에 씁니다.
38
+
39
+ ## 언제 쓰나요
40
+
41
+ - 다른 곳에서 보고 옮겨 적는, 길이가 정해진 코드(4~8자).
42
+
43
+ ## 언제 쓰지 않나요
44
+
45
+ - 비밀번호는 `PasswordInput`을 씁니다.
46
+ - 길이가 정해지지 않았거나, 대개 통째로 붙여 넣는 값(라이선스 키, 초대 토큰)은
47
+ `Input`을 씁니다.
48
+
49
+ ## 속성
50
+
51
+ </Ko>
52
+
53
+ <ArgTypes
54
+ of={PinInputStories}
55
+ include={['length', 'value', 'onChange', 'onComplete', 'inputProps']}
56
+ />
57
+
58
+ <En>
59
+
60
+ - `value` is one string, and `onChange` / `onComplete` receive one string.
61
+ `onComplete` fires when every box is filled; submit from there.
62
+ - `type` (`numeric`, `alphanumeric`, `alphabetic`), `otp`, `mask`, `invalid`
63
+ and `disabled` come from Chakra's `PinInput.Root`. `otp` sets
64
+ `autocomplete="one-time-code"`, which lets phones offer the code from SMS.
65
+ - `inputProps` go to the hidden input that carries the whole value, for
66
+ `name` in a native form.
67
+ - Boxes are empty by default (`placeholder=""`).
68
+
69
+ ## Do / Don't
70
+
71
+ </En>
72
+
73
+ <Ko>
74
+
75
+ - `value`는 문자열 하나이고, `onChange`와 `onComplete`도 문자열 하나를 받습니다.
76
+ `onComplete`는 모든 칸이 채워지면 호출되므로 여기서 제출합니다.
77
+ - `type`(`numeric`, `alphanumeric`, `alphabetic`), `otp`, `mask`, `invalid`,
78
+ `disabled`는 Chakra `PinInput.Root`의 속성입니다. `otp`를 주면
79
+ `autocomplete="one-time-code"`가 붙어 휴대폰이 문자로 받은 코드를 제안합니다.
80
+ - `inputProps`는 전체 값을 담는 숨은 입력란에 전달됩니다. 네이티브 폼에서 `name`을 줄
81
+ 때 씁니다.
82
+ - 칸은 기본으로 비어 있습니다(`placeholder=""`).
83
+
84
+ ## 이렇게 하세요 / 이렇게 하지 마세요
85
+
86
+ </Ko>
87
+
88
+ <Canvas of={PinInputStories.DoSayWhereTheCodeWent} />
89
+ <Verdict
90
+ kind="do"
91
+ en="Say above the boxes how long the code is and where it was sent."
92
+ ko="칸 위에 코드가 몇 자리인지, 어디로 보냈는지 적습니다."
93
+ />
94
+
95
+ <Canvas of={PinInputStories.DontCodeWithoutContext} />
96
+ <Verdict
97
+ kind="dont"
98
+ en="Show the boxes with nothing around them. The user does not know which code to look for, and a screen reader has nothing to read before the first box."
99
+ ko="아무 설명 없이 칸만 두지 마세요. 어떤 코드를 찾아야 하는지 알 수 없고, 화면 낭독기도 첫 칸 앞에서 읽을 것이 없습니다."
100
+ />
101
+
102
+ <Canvas of={PinInputStories.DoErrorBelow} />
103
+ <Verdict
104
+ kind="do"
105
+ en="Mark a wrong code with invalid and a message that says what to do next."
106
+ ko="틀린 코드는 invalid로 표시하고, 다음에 무엇을 할지 알려 주는 문구를 함께 둡니다."
107
+ />
108
+
109
+ <En>
110
+
111
+ ## Content
112
+
113
+ - The sentence above the boxes: the length and the destination, for example
114
+ "Enter the 6-digit code we sent to name@company.com".
115
+ - Offer a way out next to it: resend the code, or use another method.
116
+ - Error: what happened and what to do (코드가 맞지 않습니다. 메일을 다시 확인해
117
+ 주세요.).
118
+
119
+ ## Accessibility
120
+
121
+ What PinInput does for you:
122
+
123
+ - Each box is a native input. Typing moves focus to the next box and
124
+ Backspace moves back; this behaviour comes from Chakra.
125
+ - Focus shows a `primary.main` border and ring (WCAG 2.4.7). On touch devices
126
+ the text is raised to 16px so iOS Safari does not zoom.
127
+
128
+ What you still have to do:
129
+
130
+ - **Put the instruction in text right before the boxes**, so the first thing a
131
+ screen reader reaches is what the code is for (WCAG 3.3.2).
132
+ - Chakra names each box in English ("pin code 1 of 6"). Pass Chakra's
133
+ `translations` when the screen is Korean.
134
+ - Put errors in words, not only in the red border (WCAG 1.4.1, 3.3.1).
135
+ - Do not auto-submit on a time limit without saying how long the code is
136
+ valid.
137
+
138
+ ## Tokens
139
+
140
+ </En>
141
+
142
+ <Ko>
143
+
144
+ ## 문구
145
+
146
+ - 칸 위 문장에는 자릿수와 보낸 곳을 씁니다. 예: name@company.com 으로 보낸 6자리
147
+ 코드를 입력하세요.
148
+ - 바로 옆에 다른 길을 둡니다. 코드 다시 보내기나 다른 인증 방법입니다.
149
+ - 오류 문구는 무슨 일이 있었고 무엇을 하면 되는지 씁니다. 예: 코드가 맞지 않습니다.
150
+ 메일을 다시 확인해 주세요.
151
+
152
+ ## 접근성
153
+
154
+ PinInput이 알아서 하는 일
155
+
156
+ - 칸마다 네이티브 입력란입니다. 입력하면 다음 칸으로, Backspace를 누르면 앞 칸으로
157
+ 초점이 옮겨 갑니다. Chakra가 제공하는 동작입니다.
158
+ - 초점을 받으면 `primary.main` 테두리와 링이 보입니다(WCAG 2.4.7). 터치 기기에서는
159
+ 글자를 16px로 키워 iOS Safari가 화면을 확대하지 않게 합니다.
160
+
161
+ 직접 챙겨야 하는 일
162
+
163
+ - **안내 문장을 칸 바로 앞에 둡니다.** 그래야 화면 낭독기가 칸보다 코드의 용도를 먼저
164
+ 읽습니다(WCAG 3.3.2).
165
+ - Chakra는 칸마다 영어 이름("pin code 1 of 6")을 붙입니다. 한국어 화면에서는 Chakra의
166
+ `translations`를 넘깁니다.
167
+ - 오류는 빨간 테두리만이 아니라 문구로 알립니다(WCAG 1.4.1, 3.3.1).
168
+ - 코드의 유효 시간을 알리지 않은 채 시간이 지나면 자동으로 넘어가게 하지 않습니다.
169
+
170
+ ## 토큰
171
+
172
+ </Ko>
173
+
174
+ <Canvas of={PinInputStories.UsageTokens} sourceState="none" />
175
+
176
+ <En>
177
+
178
+ ## Related
179
+
180
+ - **PasswordInput**: a secret the user chooses.
181
+ - **Input**: codes of variable length.
182
+ - **FieldRow**: the error under the boxes.
183
+
184
+ </En>
185
+
186
+ <Ko>
187
+
188
+ ## 관련 컴포넌트
189
+
190
+ - **PasswordInput**: 사용자가 정하는 비밀 값.
191
+ - **Input**: 길이가 정해지지 않은 코드.
192
+ - **FieldRow**: 칸 아래 오류 문구.
193
+
194
+ </Ko>
@@ -1,6 +1,9 @@
1
- import { Stack, Text } from '@chakra-ui/react';
1
+ import type { ReactNode } from 'react';
2
+ import { Box, Stack, Text } from '@chakra-ui/react';
2
3
  import type { Meta, StoryObj } from '@storybook/react';
3
4
 
5
+ import { T } from '../../guidelines/_components/Lang';
6
+ import { TokenTable } from '../../guidelines/_components/TokenTable';
4
7
  import { Button } from '../Button';
5
8
  import { Checkbox } from '../Checkbox';
6
9
  import { Popover } from './Popover';
@@ -139,3 +142,103 @@ export const Comparison: Story = {
139
142
  </Stack>
140
143
  ),
141
144
  };
145
+
146
+ // ───────────────────────── Usage-page specimens ─────────────────────────
147
+ // Pulled into `Popover.usage.mdx` with <Canvas of={…} />. Hidden from the
148
+ // sidebar (`!dev`). Popover content is not portalled, so an open popover sits
149
+ // in the canvas; `autoFocus={false}` keeps it from taking focus on page load.
150
+
151
+ const OpenPopover = ({
152
+ trigger,
153
+ children,
154
+ }: {
155
+ trigger: string;
156
+ children: ReactNode;
157
+ }) => (
158
+ <Box h="260px">
159
+ <Popover
160
+ open
161
+ autoFocus={false}
162
+ closeOnInteractOutside={false}
163
+ closeOnEscape={false}
164
+ // No flip: a canvas below the fold would otherwise open upward and
165
+ // be clipped by the canvas.
166
+ positioning={{ placement: 'bottom-start', flip: false }}
167
+ >
168
+ <Popover.Trigger asChild>
169
+ <Button variant="secondary">{trigger}</Button>
170
+ </Popover.Trigger>
171
+ <Popover.Content>
172
+ <Popover.Arrow>
173
+ <Popover.ArrowTip />
174
+ </Popover.Arrow>
175
+ <Popover.Body>{children}</Popover.Body>
176
+ </Popover.Content>
177
+ </Popover>
178
+ </Box>
179
+ );
180
+
181
+ export const DoControlsPanel: Story = {
182
+ tags: ['!dev'],
183
+ parameters: { layout: 'padded' },
184
+ name: 'Usage / Do: a few controls about the trigger',
185
+ render: () => (
186
+ <OpenPopover trigger="공유">
187
+ <Popover.Title fontWeight="bold">링크 공유</Popover.Title>
188
+ <Stack gap={3} mt={2}>
189
+ <Checkbox defaultChecked>
190
+ <Checkbox.Control />
191
+ <Checkbox.Label>조직 안의 모든 사람</Checkbox.Label>
192
+ </Checkbox>
193
+ <Checkbox>
194
+ <Checkbox.Control />
195
+ <Checkbox.Label>대화 기록 포함</Checkbox.Label>
196
+ </Checkbox>
197
+ </Stack>
198
+ <Popover.Footer mt={4} p={0}>
199
+ <Button size="sm" variant="primary">
200
+ 링크 복사
201
+ </Button>
202
+ </Popover.Footer>
203
+ </OpenPopover>
204
+ ),
205
+ };
206
+
207
+ export const DontActionListInPopover: Story = {
208
+ tags: ['!dev'],
209
+ parameters: { layout: 'padded' },
210
+ name: "Usage / Don't: a list of actions in a popover",
211
+ render: () => (
212
+ <OpenPopover trigger="더 보기">
213
+ <Stack gap={1} align="stretch">
214
+ <Button variant="ghost" size="sm">
215
+ 이름 변경
216
+ </Button>
217
+ <Button variant="ghost" size="sm">
218
+ 복제
219
+ </Button>
220
+ <Button variant="ghost" size="sm">
221
+ 삭제
222
+ </Button>
223
+ </Stack>
224
+ </OpenPopover>
225
+ ),
226
+ };
227
+
228
+ /** Tokens the popover reads: its border from `PopoverContent` / `PopoverArrowTip`, its panel from the Chakra recipe. */
229
+ export const UsageTokens: Story = {
230
+ tags: ['!dev'],
231
+ parameters: { layout: 'padded' },
232
+ name: 'Usage / Tokens',
233
+ render: () => (
234
+ <TokenTable
235
+ rows={[
236
+ { token: 'bg.panel', use: <T en="Panel" ko="패널" /> },
237
+ {
238
+ token: 'border.subtle',
239
+ use: <T en="Panel and arrow border" ko="패널·화살표 테두리" />,
240
+ },
241
+ ]}
242
+ />
243
+ ),
244
+ };
@@ -0,0 +1,197 @@
1
+ import { ArgTypes, Canvas, Meta } from '@storybook/blocks';
2
+
3
+ import { En, Ko, LangToggle, Verdict } from '../../guidelines/_components/Lang';
4
+ import * as PopoverStories from './Popover.stories';
5
+
6
+ <Meta of={PopoverStories} name="Usage" />
7
+
8
+ <LangToggle />
9
+
10
+ <En>
11
+
12
+ # Popover
13
+
14
+ A small panel anchored to the button that opened it, for a few controls or a
15
+ short piece of content about that button. The page behind stays usable.
16
+
17
+ ## When to use
18
+
19
+ - For a few settings that belong to one button: share options, an inline credit
20
+ limit editor, a mail-block toggle.
21
+ - For a panel of content opened from the top bar: notifications, announcements,
22
+ the account panel.
23
+ - For a picker that needs more than a plain list, such as a model picker with
24
+ a search field.
25
+
26
+ ## When not to use
27
+
28
+ - A list of actions on one object → `Menu`. Menu gives arrow-key navigation and
29
+ menu roles; a column of buttons in a popover gives neither.
30
+ - A short label or hint on hover → `Tooltip`. A definition next to a label →
31
+ `InfoSprinkle`.
32
+ - A task the user must finish or cancel before going on → `Modal`.
33
+ - On a phone, a list to pick from → `BottomSheet`.
34
+
35
+ ## Variants and what they mean
36
+
37
+ Popover has no visual variants. `baseFontSize` (default `14px`) sets the base
38
+ size that the content's `em` spacing and type scale from.
39
+
40
+ </En>
41
+
42
+ <Ko>
43
+
44
+ # Popover
45
+
46
+ 자기를 연 버튼에 붙어 열리는 작은 패널입니다. 그 버튼에 관한 컨트롤 몇 개나 짧은 내용을
47
+ 담고, 뒤의 페이지는 그대로 쓸 수 있습니다.
48
+
49
+ ## 언제 쓰나요
50
+
51
+ - 한 버튼에 딸린 설정 몇 가지를 보일 때: 공유 옵션, 바로 고치는 크레딧 한도, 메일 차단
52
+ 설정.
53
+ - 상단 바에서 여는 내용 패널: 알림, 공지, 계정 패널.
54
+ - 단순한 목록보다 많은 것이 필요한 선택기: 검색창이 있는 모델 선택기.
55
+
56
+ ## 언제 쓰지 않나요
57
+
58
+ - 한 대상에 대한 동작 목록은 `Menu`를 씁니다. Menu는 방향키 이동과 메뉴 역할을
59
+ 제공하지만, Popover 안에 버튼을 늘어놓으면 둘 다 없습니다.
60
+ - 마우스를 올렸을 때 보이는 짧은 라벨이나 힌트는 `Tooltip`, 라벨 옆의 용어 설명은
61
+ `InfoSprinkle`을 씁니다.
62
+ - 끝내거나 취소해야 다음으로 넘어갈 수 있는 작업은 `Modal`을 씁니다.
63
+ - 휴대폰에서 목록 중 하나를 고르게 할 때는 `BottomSheet`를 씁니다.
64
+
65
+ ## 변형과 뜻
66
+
67
+ Popover에는 모양 변형이 없습니다. `baseFontSize`(기본 `14px`)는 콘텐츠의 `em` 단위
68
+ 간격과 글자 크기가 따르는 기준 크기입니다.
69
+
70
+ </Ko>
71
+
72
+ <ArgTypes of={PopoverStories} include={['baseFontSize']} />
73
+
74
+ <En>
75
+
76
+ ## Do / Don't
77
+
78
+ </En>
79
+
80
+ <Ko>
81
+
82
+ ## 이렇게 하세요 / 이렇게 하지 마세요
83
+
84
+ </Ko>
85
+
86
+ <Canvas of={PopoverStories.DoControlsPanel} />
87
+ <Verdict
88
+ kind="do"
89
+ en="Title the panel with Popover.Title and keep it to a few controls about the trigger."
90
+ ko="Popover.Title로 패널에 제목을 달고, 연 버튼에 관한 컨트롤 몇 개만 담습니다."
91
+ />
92
+
93
+ <Canvas of={PopoverStories.DontActionListInPopover} />
94
+ <Verdict
95
+ kind="dont"
96
+ en="Stack action buttons in a popover. Use Menu: it has arrow keys, typeahead and the menu roles a screen reader expects."
97
+ ko="Popover 안에 동작 버튼을 쌓지 마세요. Menu를 씁니다. Menu에는 방향키 이동, 글자 입력으로 찾기, 화면 낭독기가 기대하는 메뉴 역할이 있습니다."
98
+ />
99
+
100
+ <En>
101
+
102
+ ## Content
103
+
104
+ - **Title:** a noun phrase in sentence case, no full stop: "링크 공유".
105
+ - Keep it short enough to read without scrolling. If it needs a scroll bar, it
106
+ probably needs a page or a modal.
107
+ - A button inside the panel names its action ("링크 복사"), like any other
108
+ button.
109
+
110
+ ## Accessibility
111
+
112
+ What Popover does for you:
113
+
114
+ - The trigger gets `aria-haspopup="dialog"`, `aria-expanded` and
115
+ `aria-controls`; the panel is `role="dialog"`, named by `Popover.Title` and
116
+ described by `Popover.Description` when you render them (WCAG 4.1.2).
117
+ - Opening moves focus into the panel; `Escape` closes it and returns focus to
118
+ the trigger (WCAG 2.1.1, 2.4.3). A click outside also closes it.
119
+ - It is not modal: focus is not trapped and the page does not lock.
120
+
121
+ What you still have to do:
122
+
123
+ - **Render `Popover.Title`** (it may be visually hidden). Without it the dialog
124
+ has no name.
125
+ - **Name an icon-only trigger** with `aria-label`.
126
+ - Use `Popover.Trigger asChild` on a real `Button`, so the trigger is a single
127
+ button and not a button inside a button.
128
+ - Popover content is not portalled. Inside a container with `overflow: hidden`
129
+ it can be clipped; check it there.
130
+
131
+ ## Tokens
132
+
133
+ The border is set in `PopoverContent` and `PopoverArrowTip`; the panel colour
134
+ comes from Chakra's Popover recipe.
135
+
136
+ </En>
137
+
138
+ <Ko>
139
+
140
+ ## 문구
141
+
142
+ - **제목:** 명사구로 쓰고 마침표를 찍지 않습니다. "링크 공유".
143
+ - 스크롤 없이 읽을 수 있을 만큼만 담습니다. 스크롤바가 필요하다면 페이지나 모달로 옮길
144
+ 때입니다.
145
+ - 패널 안의 버튼도 다른 버튼처럼 동작 이름("링크 복사")을 씁니다.
146
+
147
+ ## 접근성
148
+
149
+ Popover가 알아서 하는 일
150
+
151
+ - 여는 버튼에 `aria-haspopup="dialog"`, `aria-expanded`, `aria-controls`를 붙입니다.
152
+ 패널은 `role="dialog"`이며, `Popover.Title`과 `Popover.Description`을 렌더하면 각각
153
+ 이름과 설명이 됩니다(WCAG 4.1.2).
154
+ - 열리면 초점이 패널 안으로 옮겨 가고, `Escape`로 닫으면 여는 버튼으로 돌아옵니다
155
+ (WCAG 2.1.1, 2.4.3). 바깥을 눌러도 닫힙니다.
156
+ - 모달이 아닙니다. 초점을 가두지 않고 페이지도 잠그지 않습니다.
157
+
158
+ 직접 챙겨야 하는 일
159
+
160
+ - **`Popover.Title`을 렌더합니다**(눈에 보이지 않게 숨겨도 됩니다). 제목이 없으면
161
+ 대화상자에 이름이 없습니다.
162
+ - **아이콘만 있는 여는 버튼에는** `aria-label`로 이름을 붙입니다.
163
+ - `Popover.Trigger`에 `asChild`를 주고 실제 `Button`을 넣습니다. 그래야 버튼 안에 버튼이
164
+ 들어가지 않습니다.
165
+ - Popover 콘텐츠는 포털로 빠지지 않습니다. `overflow: hidden`인 컨테이너 안에서는
166
+ 잘릴 수 있으니 그 자리에서 확인합니다.
167
+
168
+ ## 토큰
169
+
170
+ 테두리는 `PopoverContent`와 `PopoverArrowTip`에서, 패널 색은 Chakra Popover
171
+ 레시피에서 정합니다.
172
+
173
+ </Ko>
174
+
175
+ <Canvas of={PopoverStories.UsageTokens} sourceState="none" />
176
+
177
+ <En>
178
+
179
+ ## Related
180
+
181
+ - **Menu**: actions on one object.
182
+ - **Tooltip**: a short label on hover or focus.
183
+ - **InfoSprinkle**: a definition next to a label.
184
+ - **Modal**: a task that stops the page.
185
+
186
+ </En>
187
+
188
+ <Ko>
189
+
190
+ ## 관련 컴포넌트
191
+
192
+ - **Menu**: 한 대상에 대한 동작.
193
+ - **Tooltip**: 마우스를 올리거나 초점이 갔을 때 보이는 짧은 라벨.
194
+ - **InfoSprinkle**: 라벨 옆의 용어 설명.
195
+ - **Modal**: 페이지를 멈추는 작업.
196
+
197
+ </Ko>
@@ -1,6 +1,9 @@
1
- import { Box, Text, VStack } from '@chakra-ui/react';
1
+ import { Box, Flex, Text, VStack } from '@chakra-ui/react';
2
2
  import { Meta, StoryObj } from '@storybook/react';
3
3
 
4
+ import { T } from '../../guidelines/_components/Lang';
5
+ import { TokenTable } from '../../guidelines/_components/TokenTable';
6
+ import { Subtext } from '../Typography';
4
7
  import { ProgressBar } from '.';
5
8
 
6
9
  const meta = {
@@ -57,3 +60,91 @@ export const AllSizes: Story = {
57
60
  </VStack>
58
61
  ),
59
62
  };
63
+
64
+ export const Indeterminate: Story = {
65
+ args: { indeterminate: true, size: 'sm' },
66
+ };
67
+
68
+ // ───────────────────────── Usage-page specimens ─────────────────────────
69
+ // Pulled into `ProgressBar.usage.mdx` with <Canvas of={…} />. Hidden from the
70
+ // sidebar (`!dev`); `tags` is written on each story because the indexer reads
71
+ // CSF statically.
72
+
73
+ export const DoLabelAndNumber: Story = {
74
+ tags: ['!dev'],
75
+ parameters: { layout: 'padded' },
76
+ name: 'Usage / Do: say what is measured, and the number',
77
+ render: () => (
78
+ <Box w="360px">
79
+ <Flex justify="space-between" mb={1}>
80
+ <Text fontSize="sm" fontWeight="semibold">
81
+ 문서 업로드
82
+ </Text>
83
+ <Subtext>3 / 5</Subtext>
84
+ </Flex>
85
+ <ProgressBar size="sm" value={60} />
86
+ </Box>
87
+ ),
88
+ };
89
+
90
+ export const DontBareBar: Story = {
91
+ tags: ['!dev'],
92
+ parameters: { layout: 'padded' },
93
+ name: "Usage / Don't: a bar with nothing next to it",
94
+ render: () => (
95
+ <Box w="360px">
96
+ <ProgressBar size="sm" value={60} />
97
+ </Box>
98
+ ),
99
+ };
100
+
101
+ export const DoDangerWhenOver: Story = {
102
+ tags: ['!dev'],
103
+ parameters: { layout: 'padded' },
104
+ name: 'Usage / Do: danger fill and words when over a limit',
105
+ render: () => (
106
+ <Box w="360px">
107
+ <Flex justify="space-between" mb={1}>
108
+ <Text fontSize="sm" fontWeight="semibold">
109
+ 이번 달 크레딧
110
+ </Text>
111
+ <Subtext color="danger.fg">한도 초과 · 112%</Subtext>
112
+ </Flex>
113
+ <ProgressBar size="xs" value={100} filledTrackColor="danger.solid" />
114
+ </Box>
115
+ ),
116
+ };
117
+
118
+ export const DoIndeterminateWithHint: Story = {
119
+ tags: ['!dev'],
120
+ parameters: { layout: 'padded' },
121
+ name: 'Usage / Do: indeterminate only with no denominator, plus a hint',
122
+ render: () => (
123
+ <Box w="360px">
124
+ <ProgressBar size="sm" indeterminate />
125
+ <Subtext mt={2}>동기화하는 중입니다. 몇 분 걸릴 수 있습니다.</Subtext>
126
+ </Box>
127
+ ),
128
+ };
129
+
130
+ /** Tokens the bar reads, from `ProgressBar.tsx` and the theme. */
131
+ export const UsageTokens: Story = {
132
+ tags: ['!dev'],
133
+ parameters: { layout: 'padded' },
134
+ name: 'Usage / Tokens',
135
+ render: () => (
136
+ <TokenTable
137
+ rows={[
138
+ { token: 'bg.track', use: <T en="track" ko="트랙" /> },
139
+ {
140
+ token: 'primary.main',
141
+ use: <T en="fill (default `filledTrackColor`)" ko="채움(기본 `filledTrackColor`)" />,
142
+ },
143
+ {
144
+ token: 'danger.solid',
145
+ use: <T en="fill when over a limit" ko="한도를 넘었을 때 채움" />,
146
+ },
147
+ ]}
148
+ />
149
+ ),
150
+ };
@@ -3,7 +3,16 @@ import { ProgressRootProps as ChakraProgressRootProps } from '@chakra-ui/react';
3
3
  export type ProgressBarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
4
4
 
5
5
  export interface ProgressBarProps extends ChakraProgressRootProps {
6
+ /**
7
+ * Fill colour token. `danger.solid` only when the value means a problem
8
+ * (over a limit); otherwise leave the default.
9
+ * @default 'primary.main'
10
+ */
6
11
  filledTrackColor?: string;
12
+ /**
13
+ * Track height: `xs` 4px · `sm` 8px · `md` 16px · `lg` 24px · `xl` 32px.
14
+ * @default 'md'
15
+ */
7
16
  size?: ProgressBarSize;
8
17
  /**
9
18
  * Work whose length is not known yet: the bar slides across the track instead