@mindlogic-ai/logician-ui 5.0.0-alpha.11 โ 5.0.0-alpha.13
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/README.md +1 -0
- package/dist/components/Input/Input.d.ts.map +1 -1
- package/dist/components/Input/Input.js +4 -0
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/Input/Input.mjs +4 -0
- package/dist/components/Input/Input.mjs.map +1 -1
- package/dist/components/NavList/NavList.d.ts +34 -0
- package/dist/components/NavList/NavList.d.ts.map +1 -0
- package/dist/components/NavList/NavList.js +113 -0
- package/dist/components/NavList/NavList.js.map +1 -0
- package/dist/components/NavList/NavList.mjs +111 -0
- package/dist/components/NavList/NavList.mjs.map +1 -0
- package/dist/components/NavList/NavList.styles.d.ts +90 -0
- package/dist/components/NavList/NavList.styles.d.ts.map +1 -0
- package/dist/components/NavList/NavList.styles.js +104 -0
- package/dist/components/NavList/NavList.styles.js.map +1 -0
- package/dist/components/NavList/NavList.styles.mjs +97 -0
- package/dist/components/NavList/NavList.styles.mjs.map +1 -0
- package/dist/components/NavList/NavList.translations.json.js +19 -0
- package/dist/components/NavList/NavList.translations.json.js.map +1 -0
- package/dist/components/NavList/NavList.translations.json.mjs +14 -0
- package/dist/components/NavList/NavList.translations.json.mjs.map +1 -0
- package/dist/components/NavList/NavList.types.d.ts +131 -0
- package/dist/components/NavList/NavList.types.d.ts.map +1 -0
- package/dist/components/NavList/NavListContext.d.ts +30 -0
- package/dist/components/NavList/NavListContext.d.ts.map +1 -0
- package/dist/components/NavList/NavListContext.js +16 -0
- package/dist/components/NavList/NavListContext.js.map +1 -0
- package/dist/components/NavList/NavListContext.mjs +13 -0
- package/dist/components/NavList/NavListContext.mjs.map +1 -0
- package/dist/components/NavList/NavListGroup.d.ts +31 -0
- package/dist/components/NavList/NavListGroup.d.ts.map +1 -0
- package/dist/components/NavList/NavListGroup.js +115 -0
- package/dist/components/NavList/NavListGroup.js.map +1 -0
- package/dist/components/NavList/NavListGroup.mjs +113 -0
- package/dist/components/NavList/NavListGroup.mjs.map +1 -0
- package/dist/components/NavList/NavListItem.d.ts +15 -0
- package/dist/components/NavList/NavListItem.d.ts.map +1 -0
- package/dist/components/NavList/NavListItem.js +269 -0
- package/dist/components/NavList/NavListItem.js.map +1 -0
- package/dist/components/NavList/NavListItem.mjs +267 -0
- package/dist/components/NavList/NavListItem.mjs.map +1 -0
- package/dist/components/NavList/NavListSkeleton.d.ts +17 -0
- package/dist/components/NavList/NavListSkeleton.d.ts.map +1 -0
- package/dist/components/NavList/NavListSkeleton.js +33 -0
- package/dist/components/NavList/NavListSkeleton.js.map +1 -0
- package/dist/components/NavList/NavListSkeleton.mjs +31 -0
- package/dist/components/NavList/NavListSkeleton.mjs.map +1 -0
- package/dist/components/NavList/index.d.ts +7 -0
- package/dist/components/NavList/index.d.ts.map +1 -0
- package/dist/components/Textarea/Textarea.d.ts.map +1 -1
- package/dist/components/Textarea/Textarea.js +4 -0
- package/dist/components/Textarea/Textarea.js.map +1 -1
- package/dist/components/Textarea/Textarea.mjs +4 -0
- package/dist/components/Textarea/Textarea.mjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -1
- package/dist/index.mjs.map +1 -1
- package/dist/utils/focusRing.d.ts +22 -0
- package/dist/utils/focusRing.d.ts.map +1 -1
- package/dist/utils/focusRing.js +22 -0
- package/dist/utils/focusRing.js.map +1 -1
- package/dist/utils/focusRing.mjs +21 -1
- package/dist/utils/focusRing.mjs.map +1 -1
- package/package.json +2 -1
- package/src/components/Input/Input.tsx +4 -0
- package/src/components/Menu/Menu.usage.mdx +8 -0
- package/src/components/NavList/NavList.stories.tsx +895 -0
- package/src/components/NavList/NavList.styles.ts +114 -0
- package/src/components/NavList/NavList.test.tsx +1254 -0
- package/src/components/NavList/NavList.translations.json +9 -0
- package/src/components/NavList/NavList.tsx +160 -0
- package/src/components/NavList/NavList.types.ts +145 -0
- package/src/components/NavList/NavList.usage.mdx +540 -0
- package/src/components/NavList/NavListContext.ts +25 -0
- package/src/components/NavList/NavListGroup.tsx +243 -0
- package/src/components/NavList/NavListItem.tsx +525 -0
- package/src/components/NavList/NavListSkeleton.tsx +57 -0
- package/src/components/NavList/index.ts +14 -0
- package/src/components/Tabs/Tabs.usage.mdx +58 -14
- package/src/components/Textarea/Textarea.tsx +4 -0
- package/src/components/Tooltip/Tooltip.usage.mdx +8 -0
- package/src/components/a11y.kwcag.test.tsx +66 -0
- package/src/components/claude.md +1 -1
- package/src/index.ts +7 -1
- package/src/utils/focusRing.ts +23 -0
|
@@ -25,16 +25,35 @@ One section shows at a time.
|
|
|
25
25
|
## When not to use
|
|
26
26
|
|
|
27
27
|
- To change how the same content is shown, or to filter it (์ผ/์ฃผ/์, ๋ชฉ๋ก/์นด๋)
|
|
28
|
-
โ `SegmentedControl`. Tabs change
|
|
28
|
+
โ `SegmentedControl`. Tabs change _what_ you are looking at, not how.
|
|
29
29
|
- For the steps of a flow the user must complete in order โ a stepper or a
|
|
30
30
|
sequence of pages. Tabs let the user jump ahead.
|
|
31
|
-
-
|
|
31
|
+
- For destinations or filters, such as the side navigation of an area or a
|
|
32
|
+
filter rail beside a list, and for a list that is long or keeps growing, or
|
|
33
|
+
whose rows carry counts or icons โ `NavList`. Tabs own their panels, move
|
|
34
|
+
with the arrow keys and mark the choice with `aria-selected`; a rail is
|
|
35
|
+
links or filters, reached with Tab.
|
|
36
|
+
- To show where this page sits in a hierarchy โ `Breadcrumb`.
|
|
32
37
|
- For two or three short panels the user needs side by side โ show them on
|
|
33
38
|
the page.
|
|
34
39
|
|
|
40
|
+
## Which component
|
|
41
|
+
|
|
42
|
+
Tabs and `NavList` both mark one row as current; they say the same thing from
|
|
43
|
+
opposite sides. Pick by what the rows are:
|
|
44
|
+
|
|
45
|
+
| What you have | Use |
|
|
46
|
+
| ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
47
|
+
| A few sections of one object that swap a panel in place | `Tabs` |
|
|
48
|
+
| Destinations, or the side navigation of an area | `NavList`, each item with `href` |
|
|
49
|
+
| A filter over one list or grid, with many options or with counts | `NavList`: links (`href`) when the filter state is in the URL, buttons (`onClick`) otherwise |
|
|
50
|
+
| A short horizontal switch of two to five options | `SegmentedControl` |
|
|
51
|
+
| A hierarchy the user expands and collapses | `Tree` |
|
|
52
|
+
| Commands (์ด๋ํ๊ธฐ, ๋ด๋ณด๋ด๊ธฐ) | `Button`, or a `Menu` when there are several |
|
|
53
|
+
|
|
35
54
|
## Variants and what they mean
|
|
36
55
|
|
|
37
|
-
Tabs has one look. A selected tab is a
|
|
56
|
+
Tabs has one look. A selected tab is a _place_, not a value, so it is marked
|
|
38
57
|
with ink and weight, not with a brand or status colour. `orientation` decides
|
|
39
58
|
the layout:
|
|
40
59
|
|
|
@@ -59,9 +78,27 @@ the layout:
|
|
|
59
78
|
์๋๋ค. ํญ์ ๋ฌด์์ ๋ณด๋์ง๋ฅผ ๋ฐ๊พธ๊ณ , ์ด๋ป๊ฒ ๋ณด๋์ง๋ฅผ ๋ฐ๊พธ์ง ์์ต๋๋ค.
|
|
60
79
|
- ์ฐจ๋ก๋๋ก ๋๋ด์ผ ํ๋ ํ๋ฆ์ ๋จ๊ณ์๋ ๋จ๊ณ ํ์๋ ์ด์ด์ง๋ ํ์ด์ง๋ฅผ ์๋๋ค. ํญ์ ์ฌ์ฉ์๊ฐ
|
|
61
80
|
๋จ๊ณ๋ฅผ ๊ฑด๋๋ฐ๊ฒ ๋ก๋๋ค.
|
|
62
|
-
-
|
|
81
|
+
- ๋ค๋ฅธ ๊ณณ์ผ๋ก ์ฎ๊ฒจ ๊ฐ๋ ํญ๋ชฉ์ด๋ ํํฐ(ํ ์์ญ์ ์ ๋ด๋น๊ฒ์ด์
, ๋ชฉ๋ก ์์ ํํฐ ๋ ์ผ)๋
|
|
82
|
+
`NavList`๊ฐ ๋งก์ต๋๋ค. ํญ๋ชฉ์ด ๋ง๊ฑฐ๋ ๊ณ์ ๋์ด๋๋ ๋ชฉ๋ก, ํญ๋ชฉ์ ๊ฐ์๋ ์์ด์ฝ์ด ๋ถ๋
|
|
83
|
+
๋ชฉ๋ก๋ `NavList`๋ฅผ ์๋๋ค. ํญ์ ํจ๋์ ๊ฐ๊ณ , ๋ฐฉํฅํค๋ก ์ฎ๊ธฐ๋ฉฐ, ๊ณ ๋ฅธ ๊ฒ์
|
|
84
|
+
`aria-selected`๋ก ์๋ฆฝ๋๋ค. ๋ ์ผ์ ๋งํฌ๋ ํํฐ์ด๊ณ Tab ํค๋ก ์ค๊ฐ๋๋ค.
|
|
85
|
+
- ์ด ํ์ด์ง๊ฐ ๊ณ์ธต์ ์ด๋์ ์๋์ง ๋ณด์ฌ ์ค ๋๋ `Breadcrumb`๋ฅผ ์๋๋ค.
|
|
63
86
|
- ๋๋ํ ๋ด์ผ ํ๋ ์งง์ ํจ๋ ๋์ธ ๊ฐ๋ ํญ์ ์จ๊ธฐ์ง ๋ง๊ณ ํ์ด์ง์ ๊ทธ๋๋ก ๋ณด์
๋๋ค.
|
|
64
87
|
|
|
88
|
+
## ์ด๋ค ์ปดํฌ๋ํธ๋ฅผ ์ฐ๋์
|
|
89
|
+
|
|
90
|
+
Tabs์ `NavList`๋ ๋ ๋ค ํญ๋ชฉ ํ๋๋ฅผ ํ์ฌ ํญ๋ชฉ์ผ๋ก ํ์ํฉ๋๋ค. ๋ ๋ฌธ์๋ ๊ฐ์ ๊ธฐ์ค์ ์๋ก
|
|
91
|
+
๋ฐ๋์ชฝ์์ ์ค๋ช
ํฉ๋๋ค. ํญ๋ชฉ์ด ๋ฌด์์ธ์ง๋ฅผ ๋ณด๊ณ ๊ณ ๋ฆ
๋๋ค.
|
|
92
|
+
|
|
93
|
+
| ์ด๋ฐ ๊ฒฝ์ฐ | ์ฐ๋ ์ปดํฌ๋ํธ |
|
|
94
|
+
| -------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
95
|
+
| ํ ๋์์ ๊ตฌ์ญ ๋ช ๊ฐ๋ฅผ ๊ทธ ์๋ฆฌ์์ ํจ๋๋ก ๋ฐ๊ฟ ๋ณด์ฌ ์ค ๋ | `Tabs` |
|
|
96
|
+
| ๋ค๋ฅธ ๊ณณ์ผ๋ก ์ฎ๊ฒจ ๊ฐ๋ ํญ๋ชฉ, ํ ์์ญ์ ์ ๋ด๋น๊ฒ์ด์
| ํญ๋ชฉ๋ง๋ค `href`๋ฅผ ์ค `NavList` |
|
|
97
|
+
| ๋ชฉ๋ก์ด๋ ๊ทธ๋ฆฌ๋ ํ๋๋ฅผ ๊ฑฐ๋ฅด๋ ํํฐ๋ก, ์ ํ์ง๊ฐ ๋ง๊ฑฐ๋ ๊ฐ์๋ฅผ ๋ถ์ผ ๋ | `NavList`. ํํฐ ์ํ๊ฐ URL์ ์์ผ๋ฉด ๋งํฌ(`href`), ์๋๋ฉด ๋ฒํผ(`onClick`) |
|
|
98
|
+
| ์ ํ์ง ๋์์ ๋ค์ฏ ๊ฐ๋ฅผ ๊ฐ๋ก๋ก ์งง๊ฒ ๋ฐ๊ฟ ๋ | `SegmentedControl` |
|
|
99
|
+
| ํผ์น๊ณ ์ ๋ ๊ณ์ธต | `Tree` |
|
|
100
|
+
| ๋ช
๋ น(์ด๋ํ๊ธฐ, ๋ด๋ณด๋ด๊ธฐ) | `Button`, ์ฌ๋ฌ ๊ฐ๋ผ๋ฉด `Menu` |
|
|
101
|
+
|
|
65
102
|
## ๋ณํ๊ณผ ๋ป
|
|
66
103
|
|
|
67
104
|
Tabs์ ๋ชจ์์ ํ๋์
๋๋ค. ์ ํ๋ ํญ์ ๊ฐ์ด ์๋๋ผ ์ง๊ธ ์๋ ๊ณณ์ด๋ฏ๋ก, ๋ธ๋๋์์ด๋
|
|
@@ -69,14 +106,17 @@ Tabs์ ๋ชจ์์ ํ๋์
๋๋ค. ์ ํ๋ ํญ์ ๊ฐ์ด ์๋๋ผ ์ง๊ธ ์
|
|
|
69
106
|
|
|
70
107
|
</Ko>
|
|
71
108
|
|
|
72
|
-
<ArgTypes
|
|
109
|
+
<ArgTypes
|
|
110
|
+
of={TabsStories}
|
|
111
|
+
include={['orientation', 'defaultValue', 'value', 'activationMode']}
|
|
112
|
+
/>
|
|
73
113
|
|
|
74
114
|
<En>
|
|
75
115
|
|
|
76
|
-
| `orientation`
|
|
77
|
-
|
|
|
78
|
-
| `horizontal` (default) | `fg.emphasized` label, semibold, with a 2px `primary.main` underline
|
|
79
|
-
| `vertical`
|
|
116
|
+
| `orientation` | Selected tab | Use for |
|
|
117
|
+
| ---------------------- | ------------------------------------------------------------------------ | -------------------------------------------- |
|
|
118
|
+
| `horizontal` (default) | `fg.emphasized` label, semibold, with a 2px `primary.main` underline | Sections across the top of a page or panel |
|
|
119
|
+
| `vertical` | `bg.muted` fill, bold, with a 2px `primary.main` bar on the leading edge | A long settings page in a narrow side column |
|
|
80
120
|
|
|
81
121
|
## Do / Don't
|
|
82
122
|
|
|
@@ -84,10 +124,10 @@ Tabs์ ๋ชจ์์ ํ๋์
๋๋ค. ์ ํ๋ ํญ์ ๊ฐ์ด ์๋๋ผ ์ง๊ธ ์
|
|
|
84
124
|
|
|
85
125
|
<Ko>
|
|
86
126
|
|
|
87
|
-
| `orientation`
|
|
88
|
-
|
|
|
89
|
-
| `horizontal` (๊ธฐ๋ณธ) | `fg.emphasized` ๊ธ์๋ฅผ semibold๋ก ์ฐ๊ณ ์๋์ 2px `primary.main` ๋ฐ์ค | ํ์ด์ง๋ ํจ๋ ์์ชฝ์ ๊ตฌ์ญ
|
|
90
|
-
| `vertical`
|
|
127
|
+
| `orientation` | ์ ํ๋ ํญ | ์ฐ๋ ๊ณณ |
|
|
128
|
+
| ------------------- | --------------------------------------------------------------------- | ---------------------------- |
|
|
129
|
+
| `horizontal` (๊ธฐ๋ณธ) | `fg.emphasized` ๊ธ์๋ฅผ semibold๋ก ์ฐ๊ณ ์๋์ 2px `primary.main` ๋ฐ์ค | ํ์ด์ง๋ ํจ๋ ์์ชฝ์ ๊ตฌ์ญ |
|
|
130
|
+
| `vertical` | `bg.muted` ๋ฐฐ๊ฒฝ์ bold, ์์ชฝ ๊ฐ์ฅ์๋ฆฌ์ 2px `primary.main` ๋ง๋ | ์ข์ ์ ์ด์ ๋ ๊ธด ์ค์ ํ๋ฉด |
|
|
91
131
|
|
|
92
132
|
## ์ด๋ ๊ฒ ํ์ธ์ / ์ด๋ ๊ฒ ํ์ง ๋ง์ธ์
|
|
93
133
|
|
|
@@ -116,7 +156,7 @@ Tabs์ ๋ชจ์์ ํ๋์
๋๋ค. ์ ํ๋ ํญ์ ๊ฐ์ด ์๋๋ผ ์ง๊ธ ์
|
|
|
116
156
|
- Keep labels the same length class; one long label next to short ones reads as
|
|
117
157
|
a different kind of tab.
|
|
118
158
|
- Stay under about six horizontal tabs. More than that, use `vertical` or split
|
|
119
|
-
the page
|
|
159
|
+
the page; if the rows are places or filters, use `NavList`.
|
|
120
160
|
- Do not put a count in the label unless it changes what the user does next.
|
|
121
161
|
|
|
122
162
|
## Accessibility
|
|
@@ -162,6 +202,7 @@ The selected ramp is `TAB_RAMP` in `Tab.styles.ts`; the other tokens are set in
|
|
|
162
202
|
- ๋ผ๋ฒจ ๊ธธ์ด๋ฅผ ๋น์ทํ๊ฒ ๋ง์ถฅ๋๋ค. ์งง์ ๋ผ๋ฒจ ์ฌ์ด์ ๊ธด ๋ผ๋ฒจ ํ๋๋ ๋ค๋ฅธ ์ข
๋ฅ์ ํญ์ฒ๋ผ
|
|
163
203
|
๋ณด์
๋๋ค.
|
|
164
204
|
- ๊ฐ๋ก ํญ์ ์ฌ์ฏ ๊ฐ ์์ชฝ์ผ๋ก ๋ก๋๋ค. ๋ ๋ง์ผ๋ฉด `vertical`์ ์ฐ๊ฑฐ๋ ํ์ด์ง๋ฅผ ๋๋๋๋ค.
|
|
205
|
+
ํญ๋ชฉ์ด ๊ณณ์ด๋ ํํฐ๋ผ๋ฉด `NavList`๋ฅผ ์๋๋ค.
|
|
165
206
|
- ๋ค์ ํ๋์ ๋ฐ๊พธ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฉด ๋ผ๋ฒจ์ ๊ฐ์๋ฅผ ๋ฃ์ง ์์ต๋๋ค.
|
|
166
207
|
|
|
167
208
|
## ์ ๊ทผ์ฑ
|
|
@@ -200,6 +241,8 @@ Tabs๊ฐ ์์์ ํ๋ ์ผ
|
|
|
200
241
|
|
|
201
242
|
## Related
|
|
202
243
|
|
|
244
|
+
- **NavList**: destinations and filters, such as side navigation and filter
|
|
245
|
+
rails.
|
|
203
246
|
- **SegmentedControl**: change how the same content is shown.
|
|
204
247
|
- **Breadcrumb**: where this page sits in a hierarchy.
|
|
205
248
|
- **Foundations/Brand & colour usage**: why a selected place is ink, not
|
|
@@ -211,6 +254,7 @@ Tabs๊ฐ ์์์ ํ๋ ์ผ
|
|
|
211
254
|
|
|
212
255
|
## ๊ด๋ จ ์ปดํฌ๋ํธ
|
|
213
256
|
|
|
257
|
+
- **NavList**: ๋ค๋ฅธ ๊ณณ์ผ๋ก ์ฎ๊ฒจ ๊ฐ๋ ํญ๋ชฉ๊ณผ ํํฐ. ์ ๋ด๋น๊ฒ์ด์
, ํํฐ ๋ ์ผ.
|
|
214
258
|
- **SegmentedControl**: ๊ฐ์ ๋ด์ฉ์ ๋ณด๋ ๋ฐฉ์ ๋ฐ๊พธ๊ธฐ.
|
|
215
259
|
- **Breadcrumb**: ์ด ํ์ด์ง๊ฐ ๊ณ์ธต์ ์ด๋์ ์๋์ง.
|
|
216
260
|
- **Foundations/Brand & colour usage**: ์ ํ๋ ๊ณณ์ ์์ด ์๋๋ผ ์งํ ๊ธ์๋ก ํ์ํ๋
|
|
@@ -88,6 +88,10 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
|
88
88
|
bg: 'bg.subtle',
|
|
89
89
|
color: 'fg.muted',
|
|
90
90
|
borderColor: 'border.subtle',
|
|
91
|
+
// Nothing can be typed here, so hovering must not promise an edit.
|
|
92
|
+
_hover: {
|
|
93
|
+
borderColor: 'border.subtle',
|
|
94
|
+
},
|
|
91
95
|
}}
|
|
92
96
|
_disabled={{
|
|
93
97
|
...disabledControl,
|
|
@@ -144,6 +144,10 @@ What you still have to do:
|
|
|
144
144
|
shows.
|
|
145
145
|
- Never put the only copy of required information in a tooltip; touch screens
|
|
146
146
|
have no hover.
|
|
147
|
+
- **Tooltip + Menu on one trigger: share `ids.trigger`.** Both make the
|
|
148
|
+
button their trigger and each gives it its own id, so the menu cannot find
|
|
149
|
+
its anchor and opens at the top-left of the page. Pass one `useId()` to
|
|
150
|
+
both: `<Menu ids={{ trigger: id }}><Tooltip ids={{ trigger: id }} โฆ>`.
|
|
147
151
|
|
|
148
152
|
## Tokens
|
|
149
153
|
|
|
@@ -178,6 +182,10 @@ Tooltip์ด ์์์ ํ๋ ์ผ
|
|
|
178
182
|
์์์ ์ค์ ๋ฒํผ, ๋งํฌ์ฒ๋ผ ์ด์ ์ ๋ฐ๋ ์์์ฌ์ผ ํฉ๋๋ค. ๋นํ์ฑ ๋ฒํผ์ ํฌ์ธํฐ๋ ์ด์ ๋
|
|
179
183
|
๋ฐ์ง ์์ ํดํ์ด ๋จ์ง ์์ต๋๋ค.
|
|
180
184
|
- ๊ผญ ํ์ํ ์ ๋ณด๋ฅผ ํดํ์๋ง ๋์ง ์์ต๋๋ค. ํฐ์น ํ๋ฉด์๋ ๋ง์ฐ์ค ์ฌ๋ฆฌ๊ธฐ๊ฐ ์์ต๋๋ค.
|
|
185
|
+
- **ํ ๋ฒํผ์ Tooltip๊ณผ Menu๋ฅผ ํจ๊ป ๊ฑธ ๋๋ `ids.trigger`๋ฅผ ๊ฐ์ด ์๋๋ค.** ๋ ๋ค ๊ทธ ๋ฒํผ์
|
|
186
|
+
์ฌ๋ ์์๋ก ์ผ๊ณ ๊ฐ์ ๋ค๋ฅธ id๋ฅผ ๋ถ์ด๋ฏ๋ก, ๋ฉ๋ด๊ฐ ๊ธฐ์ค ์์น๋ฅผ ๋ชป ์ฐพ๊ณ ํ๋ฉด ์ผ์ชฝ ์์์
|
|
187
|
+
์ด๋ฆฝ๋๋ค. `useId()` ํ๋๋ฅผ ์์ชฝ์ ๋๊น๋๋ค:
|
|
188
|
+
`<Menu ids={{ trigger: id }}><Tooltip ids={{ trigger: id }} โฆ>`.
|
|
181
189
|
|
|
182
190
|
## ํ ํฐ
|
|
183
191
|
|
|
@@ -6,6 +6,7 @@ import { buttonVariantStyles } from '@/components/Button/Button.styles';
|
|
|
6
6
|
import { FileInput } from '@/components/FileInput';
|
|
7
7
|
import { LogicianProvider } from '@/components/LogicianProvider';
|
|
8
8
|
import { baseMarkdownComponents } from '@/components/Markdown/Markdown';
|
|
9
|
+
import { NavList } from '@/components/NavList';
|
|
9
10
|
import { Radio, RadioGroup } from '@/components/Radio';
|
|
10
11
|
import { SelectField } from '@/components/Select';
|
|
11
12
|
import {
|
|
@@ -292,6 +293,71 @@ describe('axe โ ๊ตฌ์กฐยทARIA ๊ท์น', () => {
|
|
|
292
293
|
</RadioGroup>,
|
|
293
294
|
],
|
|
294
295
|
['ํ์ผ ์
๋ ฅ', <FileInput key="file" onChange={() => {}} />],
|
|
296
|
+
[
|
|
297
|
+
// Rows are links or buttons with aria-current โ never tabs โ and the
|
|
298
|
+
// trailing action sits beside its row, not inside it (nested-interactive).
|
|
299
|
+
'๋ด๋น๊ฒ์ด์
๋ชฉ๋ก',
|
|
300
|
+
<NavList key="navlist" aria-label="์์ค">
|
|
301
|
+
<NavList.Item href="/recent" isCurrent trailingVisual="3">
|
|
302
|
+
์ต๊ทผ
|
|
303
|
+
</NavList.Item>
|
|
304
|
+
<NavList.Item href="/off" isDisabled>
|
|
305
|
+
์ฌ์ฉ ๋ถ๊ฐ
|
|
306
|
+
</NavList.Item>
|
|
307
|
+
<NavList.Group title="๊ณต์ ๋๋ผ์ด๋ธ">
|
|
308
|
+
<NavList.Item
|
|
309
|
+
onClick={() => {}}
|
|
310
|
+
trailingAction={
|
|
311
|
+
<button type="button" aria-label="๋ง์ผํ
์ต์
">
|
|
312
|
+
โฆ
|
|
313
|
+
</button>
|
|
314
|
+
}
|
|
315
|
+
>
|
|
316
|
+
๋ง์ผํ
|
|
317
|
+
</NavList.Item>
|
|
318
|
+
<NavList.Item onClick={() => {}} isDisabled>
|
|
319
|
+
๋ณด๊ด๋จ
|
|
320
|
+
</NavList.Item>
|
|
321
|
+
</NavList.Group>
|
|
322
|
+
</NavList>,
|
|
323
|
+
],
|
|
324
|
+
[
|
|
325
|
+
// Icon-only rows keep their label as the name; a new-window link says
|
|
326
|
+
// so in its name; a collapsible group is a disclosure with its list
|
|
327
|
+
// still labelled; a hover-revealed action is still in the tree.
|
|
328
|
+
'์ ํ ๋ด๋น๊ฒ์ด์
๋ ์ผ๊ณผ ์ ์ฐฝ ๋งํฌ',
|
|
329
|
+
<NavList key="navlist-collapsed" aria-label="๊ด๋ฆฌ์ ๋ฉ๋ด" isCollapsed>
|
|
330
|
+
<NavList.Item href="/a" isCurrent leadingVisual={<svg />}>
|
|
331
|
+
๋ฉค๋ฒ ๊ด๋ฆฌ
|
|
332
|
+
</NavList.Item>
|
|
333
|
+
<NavList.Item
|
|
334
|
+
href="https://docs.example"
|
|
335
|
+
target="_blank"
|
|
336
|
+
leadingVisual={<svg />}
|
|
337
|
+
>
|
|
338
|
+
์ฌ์ฉ ๊ฐ์ด๋
|
|
339
|
+
</NavList.Item>
|
|
340
|
+
</NavList>,
|
|
341
|
+
],
|
|
342
|
+
[
|
|
343
|
+
'์ ์ ์ ์๋ ๋ด๋น๊ฒ์ด์
๋ฌถ์',
|
|
344
|
+
<NavList key="navlist-collapsible" aria-label="์ค์ ">
|
|
345
|
+
<NavList.Group title="๊ฒฐ์ " isCollapsible>
|
|
346
|
+
<NavList.Item
|
|
347
|
+
href="/b"
|
|
348
|
+
tooltip="์๊ธ์ ์ ๊ฒฐ์ ์๋จ"
|
|
349
|
+
trailingActionVisibility="hover"
|
|
350
|
+
trailingAction={
|
|
351
|
+
<button type="button" aria-label="์๊ธ์ ์ต์
">
|
|
352
|
+
โฆ
|
|
353
|
+
</button>
|
|
354
|
+
}
|
|
355
|
+
>
|
|
356
|
+
์๊ธ์
|
|
357
|
+
</NavList.Item>
|
|
358
|
+
</NavList.Group>
|
|
359
|
+
</NavList>,
|
|
360
|
+
],
|
|
295
361
|
])('%s', async (_name, ui) => {
|
|
296
362
|
const { container } = withProvider(ui);
|
|
297
363
|
expect(await axeViolations(container)).toEqual([]);
|
package/src/components/claude.md
CHANGED
|
@@ -348,7 +348,7 @@ When adding to `src/index.ts`, follow these categories:
|
|
|
348
348
|
|
|
349
349
|
- **Core Components**: Button, Card, Badge, Tag
|
|
350
350
|
- **Form Components**: Input, Select, Checkbox, Radio
|
|
351
|
-
- **Navigation**: Breadcrumb, Pagination, Menu, Tabs
|
|
351
|
+
- **Navigation**: Breadcrumb, Pagination, Menu, Tabs, NavList
|
|
352
352
|
- **Feedback**: Alert, Toast, Modal, Tooltip
|
|
353
353
|
- **Data Display**: Table, Avatar, Typography, Code
|
|
354
354
|
- **File Components**: FileInput, FileItem, FileList
|
package/src/index.ts
CHANGED
|
@@ -66,6 +66,7 @@ export * from './components/MonthPicker';
|
|
|
66
66
|
export * from './components/Popover';
|
|
67
67
|
|
|
68
68
|
// Navigation Components
|
|
69
|
+
export * from './components/NavList';
|
|
69
70
|
export * from './components/Pagination';
|
|
70
71
|
|
|
71
72
|
// Input Variants
|
|
@@ -178,7 +179,12 @@ export {
|
|
|
178
179
|
} from './theme/motion';
|
|
179
180
|
export { cubicBezier } from './utils/cubicBezier';
|
|
180
181
|
export { disabledControl, disabledText } from './utils/disabledControl';
|
|
181
|
-
export {
|
|
182
|
+
export {
|
|
183
|
+
FOCUS_RING_INSET_SHADOW,
|
|
184
|
+
FOCUS_RING_SHADOW,
|
|
185
|
+
focusRing,
|
|
186
|
+
focusRingInset,
|
|
187
|
+
} from './utils/focusRing';
|
|
182
188
|
export {
|
|
183
189
|
staggerDelayMs,
|
|
184
190
|
type StaggerProps,
|
package/src/utils/focusRing.ts
CHANGED
|
@@ -25,3 +25,26 @@ export const focusRing = {
|
|
|
25
25
|
boxShadow: FOCUS_RING_SHADOW,
|
|
26
26
|
},
|
|
27
27
|
} as const;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The same two bands as {@link FOCUS_RING_SHADOW}, drawn INSIDE the element's
|
|
31
|
+
* edge: the outer 2px in `focus.ring`, then the 2px `bg.canvas` band that keeps
|
|
32
|
+
* the ring legible against whatever fill the element has.
|
|
33
|
+
*
|
|
34
|
+
* {@link focusRing} needs 4px of clear space on every side, because both bands
|
|
35
|
+
* paint outside the box. Rows packed into a list cannot give it that โ the band
|
|
36
|
+
* lands on the neighbouring row, which paints its own background back over
|
|
37
|
+
* half of it โ and a list that scrolls (`overflow-x: auto`) clips it outright.
|
|
38
|
+
* Same colour and weight, inside the box instead.
|
|
39
|
+
*/
|
|
40
|
+
export const FOCUS_RING_INSET_SHADOW =
|
|
41
|
+
'inset 0 0 0 2px var(--chakra-colors-focus-ring), inset 0 0 0 4px var(--chakra-colors-bg-canvas)';
|
|
42
|
+
|
|
43
|
+
/** {@link focusRing}'s inset counterpart, for rows in a dense or scrolling list. */
|
|
44
|
+
export const focusRingInset = {
|
|
45
|
+
_focus: { outline: 'none' },
|
|
46
|
+
_focusVisible: {
|
|
47
|
+
outline: 'none',
|
|
48
|
+
boxShadow: FOCUS_RING_INSET_SHADOW,
|
|
49
|
+
},
|
|
50
|
+
} as const;
|