@charcoal-ui/react 6.0.0-beta.1 → 6.0.0-beta.2

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 (28) hide show
  1. package/dist/components/Icon/index.d.ts +14 -1
  2. package/dist/components/Icon/index.d.ts.map +1 -1
  3. package/dist/components/Pagination/index.d.ts.map +1 -1
  4. package/dist/index.cjs +2 -2
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.css +1 -3
  7. package/dist/index.js +2 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/layered.css +1 -3
  10. package/dist/layered.css.map +1 -1
  11. package/package.json +5 -5
  12. package/src/__tests__/css-output.test.ts +1 -2
  13. package/src/components/DropdownSelector/ListItem/__snapshots__/index.story.storyshot +2 -0
  14. package/src/components/DropdownSelector/__snapshots__/index.story.storyshot +26 -13
  15. package/src/components/HintText/__snapshots__/index.story.storyshot +4 -0
  16. package/src/components/Icon/__snapshots__/index.story.storyshot +2 -0
  17. package/src/components/Icon/index.browser.test.tsx +280 -0
  18. package/src/components/Icon/index.test.tsx +94 -0
  19. package/src/components/Icon/index.tsx +49 -4
  20. package/src/components/IconButton/__snapshots__/index.story.storyshot +6 -0
  21. package/src/components/Modal/__snapshots__/index.story.storyshot +12 -2
  22. package/src/components/MultiSelect/__snapshots__/index.story.storyshot +32 -0
  23. package/src/components/MultiSelect/index.tsx +1 -1
  24. package/src/components/Pagination/__snapshots__/index.css.snap +1 -4
  25. package/src/components/Pagination/index.css +1 -3
  26. package/src/components/Pagination/index.tsx +2 -1
  27. package/src/components/TagItem/__snapshots__/index.story.storyshot +2 -0
  28. package/src/components/TextField/__snapshots__/TextField.story.storyshot +2 -0
@@ -0,0 +1,280 @@
1
+ /**
2
+ * Layout shift prevention test
3
+ *
4
+ * pixiv-icon Web Component は connectedCallback で Shadow DOM にサイズを設定する。
5
+ * SSR 時は JS が未実行なので、CSS だけでサイズを確保する必要がある。
6
+ *
7
+ * このテストでは以下を検証する:
8
+ *
9
+ * 1. CSS メカニズムの検証 (.charcoal-icon クラス)
10
+ * - plain HTML 要素 に charcoal-icon クラスと --charcoal-icon-size を設定
11
+ * - Web Component を介さず CSS だけでサイズが付くことを確認
12
+ *
13
+ * 2. pixiv-icon:not(:defined) の SSR fallback CSS の検証
14
+ * - iframe (= 子 window では CustomElementRegistry が独立 = pixiv-icon 未登録) を用いて
15
+ * Web Component 登録前の vanilla HTML SSR 状態を再現
16
+ *
17
+ * 3. React Icon コンポーネントの統合テスト
18
+ * - Icon コンポーネントが正しい CSS variable を設定し、
19
+ * WC upgrade 後も同じサイズであることを確認
20
+ *
21
+ * 4. 動的 prop 変更で host + shadow SVG サイズが追従するかの検証
22
+ * - observedAttributes に含まれない size 系 prop が CSS 変数継承で追従することを確認
23
+ *
24
+ * Icon コンポーネントが '@charcoal-ui/icons/css/icon.css' を side-effect import するため、
25
+ * テスト実行時には Vite が自動的にスタイルを document に注入する (本番と同じ挙動)。
26
+ */
27
+ import iconCssRaw from '@charcoal-ui/icons/css/icon.css?raw'
28
+ import { render } from '@testing-library/react'
29
+ import Icon from '.'
30
+ import HintText from '../HintText'
31
+ import TagItem from '../TagItem'
32
+
33
+ // 本番 icon.css の生テキスト (drift 防止のため文字列複製ではなく実ファイル参照)。
34
+ // iframe テストで pixiv-icon:not(:defined) を検証するために、子 document に注入する。
35
+ const iconCss = iconCssRaw
36
+
37
+ /**
38
+ * CSS のみと Web Component upgrade 後の両方で
39
+ * 同じサイズになることを保証するためのテストケース
40
+ */
41
+ const iconSizeTestCases = [
42
+ { name: '24/Add', expected: 24 },
43
+ { name: '24/Add', scale: 2, expected: 48 },
44
+ { name: '24/Add', scale: 3, expected: 72 },
45
+ { name: '24/Add', fixedSize: 64, expected: 64 },
46
+ { name: '24/Add', unsafeNonGuidelineScale: 1.5, expected: 36 },
47
+ { name: 'Inline/Add', expected: 16 },
48
+ { name: 'Inline/Add', scale: 2, expected: 32 },
49
+ { name: '16/Add', expected: 16 },
50
+ { name: '32/BookmarkOff', expected: 32 },
51
+ ] as const
52
+
53
+ function getIconSize(container: HTMLElement) {
54
+ const el = container.querySelector('pixiv-icon') as HTMLElement
55
+ const rect = el.getBoundingClientRect()
56
+ return { width: rect.width, height: rect.height }
57
+ }
58
+
59
+ describe('charcoal-icon CSS provides correct sizing without Web Component', () => {
60
+ // CSS メカニズムを plain HTML 要素で直接テストする。
61
+ // Web Component を一切介さないため、SSR 時の CSS-only サイジングと等価。
62
+ // Icon を import した時点で side-effect の icon.css が document に注入される。
63
+
64
+ it.each(iconSizeTestCases)(
65
+ 'element with --charcoal-icon-size: $expected px has $expected x $expected',
66
+ ({ expected }) => {
67
+ const el = document.createElement('span')
68
+ el.className = 'charcoal-icon'
69
+ el.style.setProperty('--charcoal-icon-size', `${expected}px`)
70
+ document.body.appendChild(el)
71
+ try {
72
+ const rect = el.getBoundingClientRect()
73
+ expect(rect.width).toBe(expected)
74
+ expect(rect.height).toBe(expected)
75
+ } finally {
76
+ el.remove()
77
+ }
78
+ },
79
+ )
80
+ })
81
+
82
+ describe('Icon component has correct size with Web Component upgrade', () => {
83
+ it('pixiv-icon IS a registered custom element', () => {
84
+ expect(customElements.get('pixiv-icon')).toBeDefined()
85
+ })
86
+
87
+ it.each(iconSizeTestCases)(
88
+ 'Icon $name (scale=$scale, fixedSize=$fixedSize, unsafeNonGuidelineScale=$unsafeNonGuidelineScale) has $expected x $expected',
89
+ ({ name, scale, fixedSize, unsafeNonGuidelineScale, expected }) => {
90
+ const { container } = render(
91
+ <Icon
92
+ name={name}
93
+ scale={scale}
94
+ fixedSize={fixedSize}
95
+ unsafeNonGuidelineScale={unsafeNonGuidelineScale}
96
+ />,
97
+ )
98
+ const { width, height } = getIconSize(container)
99
+ expect(width).toBe(expected)
100
+ expect(height).toBe(expected)
101
+ },
102
+ )
103
+
104
+ it('HintText icon has 16x16', () => {
105
+ const { container } = render(<HintText>hint</HintText>)
106
+ const { width, height } = getIconSize(container)
107
+ expect(width).toBe(16)
108
+ expect(height).toBe(16)
109
+ })
110
+
111
+ it('TagItem (active) icon has 16x16', () => {
112
+ const { container } = render(<TagItem label="tag" status="active" />)
113
+ const { width, height } = getIconSize(container)
114
+ expect(width).toBe(16)
115
+ expect(height).toBe(16)
116
+ })
117
+ })
118
+
119
+ describe('pixiv-icon:not(:defined) reserves correct size with CSS only (vanilla HTML SSR)', () => {
120
+ // React 経由ではなく vanilla HTML で <pixiv-icon> を SSR したケースを再現する。
121
+ // 親 window では pixiv-icon が定義済みなので、未登録状態を作るために iframe を使う。
122
+ // iframe には実 icon.css のみを注入し、@charcoal-ui/icons の JS は import しない。
123
+
124
+ type VanillaCase = {
125
+ title: string
126
+ markup: string
127
+ expected: number
128
+ }
129
+
130
+ const vanillaCases: VanillaCase[] = [
131
+ {
132
+ title: '24/Add (no attrs) → 24px',
133
+ markup: `<pixiv-icon name="24/Add"></pixiv-icon>`,
134
+ expected: 24,
135
+ },
136
+ {
137
+ title: '24/Add scale=2 → 48px',
138
+ markup: `<pixiv-icon name="24/Add" scale="2"></pixiv-icon>`,
139
+ expected: 48,
140
+ },
141
+ {
142
+ title: '24/Add scale=3 → 72px',
143
+ markup: `<pixiv-icon name="24/Add" scale="3"></pixiv-icon>`,
144
+ expected: 72,
145
+ },
146
+ {
147
+ title: '16/Add → 16px',
148
+ markup: `<pixiv-icon name="16/Add"></pixiv-icon>`,
149
+ expected: 16,
150
+ },
151
+ {
152
+ title: '32/BookmarkOff → 32px',
153
+ markup: `<pixiv-icon name="32/BookmarkOff"></pixiv-icon>`,
154
+ expected: 32,
155
+ },
156
+ {
157
+ title: 'Inline/Add → 16px',
158
+ markup: `<pixiv-icon name="Inline/Add"></pixiv-icon>`,
159
+ expected: 16,
160
+ },
161
+ {
162
+ title: 'Inline/Add scale=2 → 32px',
163
+ markup: `<pixiv-icon name="Inline/Add" scale="2"></pixiv-icon>`,
164
+ expected: 32,
165
+ },
166
+ {
167
+ title: 'unknown name (no prefix match) → fallback 24px',
168
+ markup: `<pixiv-icon name="24/SomeName"></pixiv-icon>`,
169
+ expected: 24,
170
+ },
171
+ {
172
+ title: 'non-guideline size via --charcoal-icon-size override → 20px',
173
+ markup: `<pixiv-icon name="24/Add" style="--charcoal-icon-size: 20px"></pixiv-icon>`,
174
+ expected: 20,
175
+ },
176
+ {
177
+ title:
178
+ 'non-guideline size for a 20/ prefix (not enumerated in CSS) via --charcoal-icon-size → 20px',
179
+ markup: `<pixiv-icon name="20/Custom" style="--charcoal-icon-size: 20px"></pixiv-icon>`,
180
+ expected: 20,
181
+ },
182
+ ]
183
+
184
+ async function withIframe(
185
+ body: string,
186
+ assert: (doc: Document, host: HTMLElement) => void,
187
+ ): Promise<void> {
188
+ const iframe = document.createElement('iframe')
189
+ iframe.style.cssText = 'border:0;width:200px;height:200px;'
190
+ // srcdoc を appendChild の前にセットすることで、about:blank の暗黙 load を待たずに
191
+ // 単一の load イベントだけで完了させる (load race 防止)。
192
+ iframe.srcdoc = `<!doctype html><html><head><style>${iconCss}</style></head><body>${body}</body></html>`
193
+
194
+ try {
195
+ await new Promise<void>((resolve) => {
196
+ iframe.addEventListener('load', () => resolve(), { once: true })
197
+ document.body.appendChild(iframe)
198
+ })
199
+
200
+ const doc = iframe.contentDocument
201
+ if (!doc) throw new Error('iframe document missing')
202
+ const host = doc.querySelector('pixiv-icon') as HTMLElement | null
203
+ if (!host) throw new Error('pixiv-icon not found in iframe')
204
+ assert(doc, host)
205
+ } finally {
206
+ iframe.remove()
207
+ }
208
+ }
209
+
210
+ it.each(vanillaCases)('$title', async ({ markup, expected }) => {
211
+ await withIframe(markup, (doc, host) => {
212
+ // iframe 内では pixiv-icon は登録されていないことを確認 (= :not(:defined) が効く)
213
+ const iframeWindow = doc.defaultView as Window & typeof globalThis
214
+ expect(iframeWindow.customElements.get('pixiv-icon')).toBeUndefined()
215
+
216
+ const rect = host.getBoundingClientRect()
217
+ expect(rect.width).toBe(expected)
218
+ expect(rect.height).toBe(expected)
219
+ })
220
+ })
221
+ })
222
+
223
+ describe('Icon reflects dynamic prop changes (no observed-attribute regression)', () => {
224
+ function getShadowSvgSize(container: HTMLElement) {
225
+ const host = container.querySelector('pixiv-icon') as HTMLElement
226
+ const svg = host.shadowRoot?.querySelector('svg') as SVGElement | null
227
+ if (!svg) return null
228
+ const rect = svg.getBoundingClientRect()
229
+ return { width: rect.width, height: rect.height }
230
+ }
231
+
232
+ it('updates host + shadow SVG size when only fixedSize changes', async () => {
233
+ const { container, rerender } = render(
234
+ <Icon name="24/Add" fixedSize={20} />,
235
+ )
236
+
237
+ expect(getIconSize(container)).toEqual({ width: 20, height: 20 })
238
+
239
+ rerender(<Icon name="24/Add" fixedSize={40} />)
240
+
241
+ expect(getIconSize(container)).toEqual({ width: 40, height: 40 })
242
+
243
+ const shadowSize = getShadowSvgSize(container)
244
+ if (shadowSize !== null) {
245
+ expect(shadowSize).toEqual({ width: 40, height: 40 })
246
+ }
247
+ })
248
+
249
+ it('updates host + shadow SVG size when only unsafeNonGuidelineScale changes', () => {
250
+ const { container, rerender } = render(
251
+ <Icon name="24/Add" unsafeNonGuidelineScale={1.5} />,
252
+ )
253
+
254
+ expect(getIconSize(container)).toEqual({ width: 36, height: 36 })
255
+
256
+ rerender(<Icon name="24/Add" unsafeNonGuidelineScale={2.5} />)
257
+
258
+ expect(getIconSize(container)).toEqual({ width: 60, height: 60 })
259
+
260
+ const shadowSize = getShadowSvgSize(container)
261
+ if (shadowSize !== null) {
262
+ expect(shadowSize).toEqual({ width: 60, height: 60 })
263
+ }
264
+ })
265
+
266
+ it('updates host + shadow SVG size when only scale changes', () => {
267
+ const { container, rerender } = render(<Icon name="24/Add" scale={1} />)
268
+
269
+ expect(getIconSize(container)).toEqual({ width: 24, height: 24 })
270
+
271
+ rerender(<Icon name="24/Add" scale={3} />)
272
+
273
+ expect(getIconSize(container)).toEqual({ width: 72, height: 72 })
274
+
275
+ const shadowSize = getShadowSvgSize(container)
276
+ if (shadowSize !== null) {
277
+ expect(shadowSize).toEqual({ width: 72, height: 72 })
278
+ }
279
+ })
280
+ })
@@ -0,0 +1,94 @@
1
+ import { render } from '@testing-library/react'
2
+ import Icon from '.'
3
+
4
+ function queryIcon(container: HTMLElement) {
5
+ const el = container.querySelector('pixiv-icon')
6
+ if (el === null) throw new Error('pixiv-icon not found')
7
+ return el as HTMLElement
8
+ }
9
+
10
+ describe('Icon', () => {
11
+ it('always sets --charcoal-icon-size with calculated size', () => {
12
+ const { container } = render(<Icon name="24/Add" />)
13
+ expect(
14
+ queryIcon(container).style.getPropertyValue('--charcoal-icon-size'),
15
+ ).toBe('24px')
16
+ })
17
+
18
+ it('sets --charcoal-icon-size with scale', () => {
19
+ const { container } = render(<Icon name="24/Add" scale={2} />)
20
+ expect(
21
+ queryIcon(container).style.getPropertyValue('--charcoal-icon-size'),
22
+ ).toBe('48px')
23
+ })
24
+
25
+ it('sets --charcoal-icon-size with unsafeNonGuidelineScale (deprecated)', () => {
26
+ const { container } = render(
27
+ <Icon name="24/Add" unsafeNonGuidelineScale={1.5} />,
28
+ )
29
+ expect(
30
+ queryIcon(container).style.getPropertyValue('--charcoal-icon-size'),
31
+ ).toBe('36px')
32
+ })
33
+
34
+ it('sets --charcoal-icon-size with fixedSize', () => {
35
+ const { container } = render(<Icon name="24/Add" fixedSize={100} />)
36
+ expect(
37
+ queryIcon(container).style.getPropertyValue('--charcoal-icon-size'),
38
+ ).toBe('100px')
39
+ })
40
+
41
+ it('passes scale attribute through to pixiv-icon', () => {
42
+ const { container } = render(<Icon name="24/Add" scale={2} />)
43
+ expect(queryIcon(container).getAttribute('scale')).toBe('2')
44
+ })
45
+
46
+ it('passes unsafe-non-guideline-scale attribute to pixiv-icon for hydration', () => {
47
+ const { container } = render(
48
+ <Icon name="24/Add" unsafeNonGuidelineScale={1.5} />,
49
+ )
50
+ expect(
51
+ queryIcon(container).getAttribute('unsafe-non-guideline-scale'),
52
+ ).toBe('1.5')
53
+ })
54
+
55
+ it('passes fixed-size attribute to pixiv-icon for hydration', () => {
56
+ const { container } = render(<Icon name="24/Add" fixedSize={100} />)
57
+ expect(queryIcon(container).getAttribute('fixed-size')).toBe('100')
58
+ })
59
+
60
+ it('adds charcoal-icon class', () => {
61
+ const { container } = render(<Icon name="24/Add" />)
62
+ expect(queryIcon(container).classList.contains('charcoal-icon')).toBe(true)
63
+ })
64
+
65
+ it('preserves user className alongside charcoal-icon', () => {
66
+ const { container } = render(<Icon name="24/Add" className="my-icon" />)
67
+ const el = queryIcon(container)
68
+ expect(el.classList.contains('charcoal-icon')).toBe(true)
69
+ expect(el.classList.contains('my-icon')).toBe(true)
70
+ })
71
+
72
+ it('merges user style with SSR CSS variable', () => {
73
+ const { container } = render(
74
+ <Icon name="24/Add" style={{ color: 'red' }} />,
75
+ )
76
+ const el = queryIcon(container)
77
+ expect(el.style.getPropertyValue('--charcoal-icon-size')).toBe('24px')
78
+ expect(el.style.color).toBe('red')
79
+ })
80
+
81
+ it('handles Inline icons', () => {
82
+ const { container } = render(<Icon name="Inline/Add" />)
83
+ expect(
84
+ queryIcon(container).style.getPropertyValue('--charcoal-icon-size'),
85
+ ).toBe('16px')
86
+ })
87
+
88
+ it('handles Inline icons with scale=2', () => {
89
+ const { container } = render(<Icon name="Inline/Add" scale={2} />)
90
+ expect(
91
+ queryIcon(container).style.getPropertyValue('--charcoal-icon-size'),
92
+ ).toBe('32px')
93
+ })
94
+ })
@@ -1,30 +1,75 @@
1
1
  import * as React from 'react'
2
2
 
3
3
  import '@charcoal-ui/icons'
4
- import type { PixivIcon, Props } from '@charcoal-ui/icons'
4
+ import '@charcoal-ui/icons/css/icon.css'
5
+ import { calcActualSize } from '@charcoal-ui/icons'
6
+ import type { IconSizing, PixivIcon, Props } from '@charcoal-ui/icons'
5
7
 
6
8
  export interface OwnProps {
9
+ /**
10
+ * @deprecated `fixedSize` を利用してください。
11
+ * `attr()` の数値解釈サポートが限定的なため、リセット CSS だけではレイアウトシフトが防げません。
12
+ */
7
13
  unsafeNonGuidelineScale?: number
14
+ /**
15
+ * 固定 px サイズで描画します。ガイドライン外のサイズを利用する場合に推奨される指定方法で、
16
+ * 他のサイズ指定 (`scale` / `unsafeNonGuidelineScale`) よりも常に優先されます。
17
+ *
18
+ * `<Icon>` は同じ値を `--charcoal-icon-size` インライン CSS 変数として自動付与するため、
19
+ * Web Component の hydrate 前後でレイアウトシフトは発生しません。
20
+ */
21
+ fixedSize?: number
8
22
  className?: string
9
23
  }
10
24
 
11
25
  export interface IconProps
12
26
  extends OwnProps,
13
27
  React.PropsWithoutRef<
14
- Omit<Props, 'class' | 'unsafe-non-guideline-scale' | 'css'>
28
+ Omit<Props, 'class' | 'unsafe-non-guideline-scale' | 'fixed-size' | 'css'>
15
29
  > {}
16
30
 
17
31
  const Icon = React.forwardRef<PixivIcon, IconProps>(function IconInner(
18
- { name, scale, unsafeNonGuidelineScale, className, ...rest },
32
+ {
33
+ name,
34
+ scale,
35
+ unsafeNonGuidelineScale,
36
+ fixedSize,
37
+ className,
38
+ style: userStyle,
39
+ ...rest
40
+ },
19
41
  ref,
20
42
  ) {
43
+ const actualSize = React.useMemo(
44
+ // IconSizing の排他制約は IconProps の型レベルで保証されるため、内部では緩和する
45
+ () =>
46
+ calcActualSize({
47
+ name,
48
+ scale,
49
+ unsafeNonGuidelineScale,
50
+ fixedSize,
51
+ } as { name: string } & IconSizing),
52
+ [name, scale, unsafeNonGuidelineScale, fixedSize],
53
+ )
54
+
55
+ const style = React.useMemo(
56
+ () =>
57
+ ({
58
+ ...userStyle,
59
+ '--charcoal-icon-size': `${actualSize}px`,
60
+ }) as React.CSSProperties,
61
+ [actualSize, userStyle],
62
+ )
63
+
21
64
  return (
22
65
  <pixiv-icon
23
66
  ref={ref}
24
67
  name={name}
25
68
  scale={scale}
26
69
  unsafe-non-guideline-scale={unsafeNonGuidelineScale}
27
- class={className}
70
+ fixed-size={fixedSize}
71
+ style={style}
72
+ class={`charcoal-icon ${className || ''}`.trim()}
28
73
  {...rest}
29
74
  />
30
75
  )
@@ -13,7 +13,9 @@ exports[`Storybook Tests > react/IconButton > Default 1`] = `
13
13
  title="add"
14
14
  >
15
15
  <pixiv-icon
16
+ class="charcoal-icon"
16
17
  name="16/Add"
18
+ style="--charcoal-icon-size: 16px;"
17
19
  />
18
20
  </button>
19
21
  </div>
@@ -32,7 +34,9 @@ exports[`Storybook Tests > react/IconButton > IsActive 1`] = `
32
34
  data-variant="Default"
33
35
  >
34
36
  <pixiv-icon
37
+ class="charcoal-icon"
35
38
  name="16/Add"
39
+ style="--charcoal-icon-size: 16px;"
36
40
  />
37
41
  </button>
38
42
  </div>
@@ -51,7 +55,9 @@ exports[`Storybook Tests > react/IconButton > Overlay 1`] = `
51
55
  data-variant="Overlay"
52
56
  >
53
57
  <pixiv-icon
58
+ class="charcoal-icon"
54
59
  name="16/Add"
60
+ style="--charcoal-icon-size: 16px;"
55
61
  />
56
62
  </button>
57
63
  </div>
@@ -187,8 +187,9 @@ exports[`Storybook Tests > react/Modal > BackgroundScroll 1`] = `
187
187
  Apple
188
188
  </span>
189
189
  <pixiv-icon
190
- class="charcoal-ui-dropdown-selector-icon"
190
+ class="charcoal-icon charcoal-ui-dropdown-selector-icon"
191
191
  name="16/Menu"
192
+ style="--charcoal-icon-size: 16px;"
192
193
  />
193
194
  </button>
194
195
  </div>
@@ -221,7 +222,9 @@ exports[`Storybook Tests > react/Modal > BackgroundScroll 1`] = `
221
222
  type="button"
222
223
  >
223
224
  <pixiv-icon
225
+ class="charcoal-icon"
224
226
  name="24/Close"
227
+ style="--charcoal-icon-size: 24px;"
225
228
  />
226
229
  </button>
227
230
  </div>
@@ -322,7 +325,9 @@ exports[`Storybook Tests > react/Modal > BottomSheet 1`] = `
322
325
  type="button"
323
326
  >
324
327
  <pixiv-icon
328
+ class="charcoal-icon"
325
329
  name="24/Close"
330
+ style="--charcoal-icon-size: 24px;"
326
331
  />
327
332
  </button>
328
333
  </div>
@@ -515,8 +520,9 @@ exports[`Storybook Tests > react/Modal > Default 1`] = `
515
520
  Apple
516
521
  </span>
517
522
  <pixiv-icon
518
- class="charcoal-ui-dropdown-selector-icon"
523
+ class="charcoal-icon charcoal-ui-dropdown-selector-icon"
519
524
  name="16/Menu"
525
+ style="--charcoal-icon-size: 16px;"
520
526
  />
521
527
  </button>
522
528
  </div>
@@ -549,7 +555,9 @@ exports[`Storybook Tests > react/Modal > Default 1`] = `
549
555
  type="button"
550
556
  >
551
557
  <pixiv-icon
558
+ class="charcoal-icon"
552
559
  name="24/Close"
560
+ style="--charcoal-icon-size: 24px;"
553
561
  />
554
562
  </button>
555
563
  </div>
@@ -712,7 +720,9 @@ exports[`Storybook Tests > react/Modal > FullBottomSheet 1`] = `
712
720
  type="button"
713
721
  >
714
722
  <pixiv-icon
723
+ class="charcoal-icon"
715
724
  name="24/Close"
725
+ style="--charcoal-icon-size: 24px;"
716
726
  />
717
727
  </button>
718
728
  </div>