@dalcvil/steam-green-react 0.2.0 → 1.0.0
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 +20 -5
- package/dist/components/Avatar/Avatar.css +136 -0
- package/dist/components/Avatar/Avatar.d.ts +22 -0
- package/dist/components/Avatar/Avatar.d.ts.map +1 -0
- package/dist/components/Avatar/Avatar.js +49 -0
- package/dist/components/Avatar/Avatar.js.map +1 -0
- package/dist/components/Avatar/index.d.ts +3 -0
- package/dist/components/Avatar/index.d.ts.map +1 -0
- package/dist/components/Button/Button.css +117 -0
- package/dist/components/Button/Button.d.ts +18 -0
- package/dist/components/Button/Button.d.ts.map +1 -0
- package/dist/components/Button/Button.js +29 -0
- package/dist/components/Button/Button.js.map +1 -0
- package/dist/components/Button/index.d.ts +3 -0
- package/dist/components/Button/index.d.ts.map +1 -0
- package/dist/components/Checkbox/Checkbox.css +116 -0
- package/dist/components/Checkbox/Checkbox.css.d.ts +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts +19 -0
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox/Checkbox.js +51 -0
- package/dist/components/Checkbox/Checkbox.js.map +1 -0
- package/dist/components/Checkbox/index.d.ts +3 -0
- package/dist/components/Checkbox/index.d.ts.map +1 -0
- package/dist/components/ColorPicker/ColorPicker.css +331 -0
- package/dist/components/ColorPicker/ColorPicker.css.d.ts +1 -0
- package/dist/components/ColorPicker/ColorPicker.d.ts +29 -0
- package/dist/components/ColorPicker/ColorPicker.d.ts.map +1 -0
- package/dist/components/ColorPicker/ColorPicker.js +534 -0
- package/dist/components/ColorPicker/ColorPicker.js.map +1 -0
- package/dist/components/ColorPicker/index.d.ts +3 -0
- package/dist/components/{GreenButton → ColorPicker}/index.d.ts.map +1 -1
- package/dist/components/Console/Console.css +96 -0
- package/dist/components/Console/Console.css.d.ts +1 -0
- package/dist/components/Console/Console.d.ts +26 -0
- package/dist/components/Console/Console.d.ts.map +1 -0
- package/dist/components/Console/Console.js +59 -0
- package/dist/components/Console/Console.js.map +1 -0
- package/dist/components/Console/index.d.ts +3 -0
- package/dist/components/Console/index.d.ts.map +1 -0
- package/dist/components/Dialog/Dialog.css +137 -0
- package/dist/components/Dialog/Dialog.css.d.ts +1 -0
- package/dist/components/Dialog/Dialog.d.ts +28 -0
- package/dist/components/Dialog/Dialog.d.ts.map +1 -0
- package/dist/components/Dialog/Dialog.js +151 -0
- package/dist/components/Dialog/Dialog.js.map +1 -0
- package/dist/components/Dialog/index.d.ts +3 -0
- package/dist/components/Dialog/index.d.ts.map +1 -0
- package/dist/components/Divider/Divider.css +68 -0
- package/dist/components/Divider/Divider.css.d.ts +1 -0
- package/dist/components/Divider/Divider.d.ts +12 -0
- package/dist/components/Divider/Divider.d.ts.map +1 -0
- package/dist/components/Divider/Divider.js +23 -0
- package/dist/components/Divider/Divider.js.map +1 -0
- package/dist/components/Divider/index.d.ts +3 -0
- package/dist/components/Divider/index.d.ts.map +1 -0
- package/dist/components/FieldLabel/FieldLabel.css +98 -0
- package/dist/components/FieldLabel/FieldLabel.css.d.ts +1 -0
- package/dist/components/FieldLabel/FieldLabel.d.ts +29 -0
- package/dist/components/FieldLabel/FieldLabel.d.ts.map +1 -0
- package/dist/components/FieldLabel/FieldLabel.js +42 -0
- package/dist/components/FieldLabel/FieldLabel.js.map +1 -0
- package/dist/components/FieldLabel/index.d.ts +3 -0
- package/dist/components/{GreenPanel → FieldLabel}/index.d.ts.map +1 -1
- package/dist/components/GroupBox/GroupBox.css +101 -0
- package/dist/components/GroupBox/GroupBox.css.d.ts +1 -0
- package/dist/components/GroupBox/GroupBox.d.ts +14 -0
- package/dist/components/GroupBox/GroupBox.d.ts.map +1 -0
- package/dist/components/GroupBox/GroupBox.js +25 -0
- package/dist/components/GroupBox/GroupBox.js.map +1 -0
- package/dist/components/GroupBox/index.d.ts +3 -0
- package/dist/components/GroupBox/index.d.ts.map +1 -0
- package/dist/components/IconButton/IconButton.css +184 -0
- package/dist/components/IconButton/IconButton.css.d.ts +1 -0
- package/dist/components/IconButton/IconButton.d.ts +56 -0
- package/dist/components/IconButton/IconButton.d.ts.map +1 -0
- package/dist/components/IconButton/IconButton.js +77 -0
- package/dist/components/IconButton/IconButton.js.map +1 -0
- package/dist/components/IconButton/index.d.ts +3 -0
- package/dist/components/IconButton/index.d.ts.map +1 -0
- package/dist/components/LevelMeter/LevelMeter.css +117 -0
- package/dist/components/LevelMeter/LevelMeter.css.d.ts +1 -0
- package/dist/components/LevelMeter/LevelMeter.d.ts +20 -0
- package/dist/components/LevelMeter/LevelMeter.d.ts.map +1 -0
- package/dist/components/LevelMeter/LevelMeter.js +44 -0
- package/dist/components/LevelMeter/LevelMeter.js.map +1 -0
- package/dist/components/LevelMeter/index.d.ts +3 -0
- package/dist/components/LevelMeter/index.d.ts.map +1 -0
- package/dist/components/Link/Link.css +127 -0
- package/dist/components/Link/Link.css.d.ts +1 -0
- package/dist/components/Link/Link.d.ts +26 -0
- package/dist/components/Link/Link.d.ts.map +1 -0
- package/dist/components/Link/Link.js +60 -0
- package/dist/components/Link/Link.js.map +1 -0
- package/dist/components/Link/index.d.ts +3 -0
- package/dist/components/Link/index.d.ts.map +1 -0
- package/dist/components/List/List.css +224 -0
- package/dist/components/List/List.css.d.ts +1 -0
- package/dist/components/List/List.d.ts +49 -0
- package/dist/components/List/List.d.ts.map +1 -0
- package/dist/components/List/List.js +300 -0
- package/dist/components/List/List.js.map +1 -0
- package/dist/components/List/index.d.ts +3 -0
- package/dist/components/List/index.d.ts.map +1 -0
- package/dist/components/Menu/Menu.css +122 -0
- package/dist/components/Menu/Menu.css.d.ts +1 -0
- package/dist/components/Menu/Menu.d.ts +46 -0
- package/dist/components/Menu/Menu.d.ts.map +1 -0
- package/dist/components/Menu/Menu.js +246 -0
- package/dist/components/Menu/Menu.js.map +1 -0
- package/dist/components/Menu/index.d.ts +3 -0
- package/dist/components/Menu/index.d.ts.map +1 -0
- package/dist/components/MenuBar/MenuBar.css +94 -0
- package/dist/components/MenuBar/MenuBar.css.d.ts +1 -0
- package/dist/components/MenuBar/MenuBar.d.ts +34 -0
- package/dist/components/MenuBar/MenuBar.d.ts.map +1 -0
- package/dist/components/MenuBar/MenuBar.js +129 -0
- package/dist/components/MenuBar/MenuBar.js.map +1 -0
- package/dist/components/MenuBar/index.d.ts +3 -0
- package/dist/components/MenuBar/index.d.ts.map +1 -0
- package/dist/components/NavBar/NavBar.css +179 -0
- package/dist/components/NavBar/NavBar.css.d.ts +1 -0
- package/dist/components/NavBar/NavBar.d.ts +39 -0
- package/dist/components/NavBar/NavBar.d.ts.map +1 -0
- package/dist/components/NavBar/NavBar.js +198 -0
- package/dist/components/NavBar/NavBar.js.map +1 -0
- package/dist/components/NavBar/index.d.ts +3 -0
- package/dist/components/NavBar/index.d.ts.map +1 -0
- package/dist/components/Notification/Notification.css +176 -0
- package/dist/components/Notification/Notification.css.d.ts +1 -0
- package/dist/components/Notification/Notification.d.ts +26 -0
- package/dist/components/Notification/Notification.d.ts.map +1 -0
- package/dist/components/Notification/Notification.js +181 -0
- package/dist/components/Notification/Notification.js.map +1 -0
- package/dist/components/Notification/index.d.ts +3 -0
- package/dist/components/Notification/index.d.ts.map +1 -0
- package/dist/components/Panel/Panel.css +56 -0
- package/dist/components/Panel/Panel.css.d.ts +1 -0
- package/dist/components/Panel/Panel.d.ts +14 -0
- package/dist/components/Panel/Panel.d.ts.map +1 -0
- package/dist/components/Panel/Panel.js +42 -0
- package/dist/components/Panel/Panel.js.map +1 -0
- package/dist/components/Panel/index.d.ts +3 -0
- package/dist/components/Panel/index.d.ts.map +1 -0
- package/dist/components/ProgressBar/ProgressBar.css +108 -0
- package/dist/components/ProgressBar/ProgressBar.css.d.ts +1 -0
- package/dist/components/ProgressBar/ProgressBar.d.ts +22 -0
- package/dist/components/ProgressBar/ProgressBar.d.ts.map +1 -0
- package/dist/components/ProgressBar/ProgressBar.js +43 -0
- package/dist/components/ProgressBar/ProgressBar.js.map +1 -0
- package/dist/components/ProgressBar/index.d.ts +3 -0
- package/dist/components/ProgressBar/index.d.ts.map +1 -0
- package/dist/components/Radio/Radio.css +125 -0
- package/dist/components/Radio/Radio.css.d.ts +1 -0
- package/dist/components/Radio/Radio.d.ts +40 -0
- package/dist/components/Radio/Radio.d.ts.map +1 -0
- package/dist/components/Radio/Radio.js +91 -0
- package/dist/components/Radio/Radio.js.map +1 -0
- package/dist/components/Radio/index.d.ts +3 -0
- package/dist/components/Radio/index.d.ts.map +1 -0
- package/dist/components/RichText/RichText.css +96 -0
- package/dist/components/RichText/RichText.css.d.ts +1 -0
- package/dist/components/RichText/RichText.d.ts +25 -0
- package/dist/components/RichText/RichText.d.ts.map +1 -0
- package/dist/components/RichText/RichText.js +56 -0
- package/dist/components/RichText/RichText.js.map +1 -0
- package/dist/components/RichText/index.d.ts +3 -0
- package/dist/components/RichText/index.d.ts.map +1 -0
- package/dist/components/ScrollArea/ScrollArea.css +236 -0
- package/dist/components/ScrollArea/ScrollArea.css.d.ts +1 -0
- package/dist/components/ScrollArea/ScrollArea.d.ts +25 -0
- package/dist/components/ScrollArea/ScrollArea.d.ts.map +1 -0
- package/dist/components/ScrollArea/ScrollArea.js +124 -0
- package/dist/components/ScrollArea/ScrollArea.js.map +1 -0
- package/dist/components/ScrollArea/index.d.ts +3 -0
- package/dist/components/ScrollArea/index.d.ts.map +1 -0
- package/dist/components/Scrollbar/Scrollbar.css +260 -0
- package/dist/components/Scrollbar/Scrollbar.css.d.ts +1 -0
- package/dist/components/Scrollbar/Scrollbar.d.ts +31 -0
- package/dist/components/Scrollbar/Scrollbar.d.ts.map +1 -0
- package/dist/components/Scrollbar/Scrollbar.js +277 -0
- package/dist/components/Scrollbar/Scrollbar.js.map +1 -0
- package/dist/components/Scrollbar/index.d.ts +3 -0
- package/dist/components/Scrollbar/index.d.ts.map +1 -0
- package/dist/components/Select/Select.css +299 -0
- package/dist/components/Select/Select.css.d.ts +1 -0
- package/dist/components/Select/Select.d.ts +52 -0
- package/dist/components/Select/Select.d.ts.map +1 -0
- package/dist/components/Select/Select.js +281 -0
- package/dist/components/Select/Select.js.map +1 -0
- package/dist/components/Select/index.d.ts +3 -0
- package/dist/components/Select/index.d.ts.map +1 -0
- package/dist/components/Slider/Slider.css +158 -0
- package/dist/components/Slider/Slider.css.d.ts +1 -0
- package/dist/components/Slider/Slider.d.ts +26 -0
- package/dist/components/Slider/Slider.d.ts.map +1 -0
- package/dist/components/Slider/Slider.js +67 -0
- package/dist/components/Slider/Slider.js.map +1 -0
- package/dist/components/Slider/index.d.ts +3 -0
- package/dist/components/Slider/index.d.ts.map +1 -0
- package/dist/components/SpinBox/SpinBox.css +152 -0
- package/dist/components/SpinBox/SpinBox.css.d.ts +1 -0
- package/dist/components/SpinBox/SpinBox.d.ts +28 -0
- package/dist/components/SpinBox/SpinBox.d.ts.map +1 -0
- package/dist/components/SpinBox/SpinBox.js +207 -0
- package/dist/components/SpinBox/SpinBox.js.map +1 -0
- package/dist/components/SpinBox/index.d.ts +3 -0
- package/dist/components/SpinBox/index.d.ts.map +1 -0
- package/dist/components/Spinner/Spinner.css +137 -0
- package/dist/components/Spinner/Spinner.css.d.ts +1 -0
- package/dist/components/Spinner/Spinner.d.ts +20 -0
- package/dist/components/Spinner/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner/Spinner.js +36 -0
- package/dist/components/Spinner/Spinner.js.map +1 -0
- package/dist/components/Spinner/index.d.ts +3 -0
- package/dist/components/Spinner/index.d.ts.map +1 -0
- package/dist/components/Splitter/Splitter.css +119 -0
- package/dist/components/Splitter/Splitter.css.d.ts +1 -0
- package/dist/components/Splitter/Splitter.d.ts +25 -0
- package/dist/components/Splitter/Splitter.d.ts.map +1 -0
- package/dist/components/Splitter/Splitter.js +212 -0
- package/dist/components/Splitter/Splitter.js.map +1 -0
- package/dist/components/Splitter/index.d.ts +3 -0
- package/dist/components/Splitter/index.d.ts.map +1 -0
- package/dist/components/StatusBar/StatusBar.css +97 -0
- package/dist/components/StatusBar/StatusBar.css.d.ts +1 -0
- package/dist/components/StatusBar/StatusBar.d.ts +22 -0
- package/dist/components/StatusBar/StatusBar.d.ts.map +1 -0
- package/dist/components/StatusBar/StatusBar.js +56 -0
- package/dist/components/StatusBar/StatusBar.js.map +1 -0
- package/dist/components/StatusBar/index.d.ts +3 -0
- package/dist/components/StatusBar/index.d.ts.map +1 -0
- package/dist/components/StatusLabel/StatusLabel.css +93 -0
- package/dist/components/StatusLabel/StatusLabel.css.d.ts +1 -0
- package/dist/components/StatusLabel/StatusLabel.d.ts +20 -0
- package/dist/components/StatusLabel/StatusLabel.d.ts.map +1 -0
- package/dist/components/StatusLabel/StatusLabel.js +42 -0
- package/dist/components/StatusLabel/StatusLabel.js.map +1 -0
- package/dist/components/StatusLabel/index.d.ts +3 -0
- package/dist/components/StatusLabel/index.d.ts.map +1 -0
- package/dist/components/Table/Table.css +253 -0
- package/dist/components/Table/Table.css.d.ts +1 -0
- package/dist/components/Table/Table.d.ts +67 -0
- package/dist/components/Table/Table.d.ts.map +1 -0
- package/dist/components/Table/Table.js +429 -0
- package/dist/components/Table/Table.js.map +1 -0
- package/dist/components/Table/index.d.ts +3 -0
- package/dist/components/Table/index.d.ts.map +1 -0
- package/dist/components/Tabs/Tabs.css +138 -0
- package/dist/components/Tabs/Tabs.css.d.ts +1 -0
- package/dist/components/Tabs/Tabs.d.ts +34 -0
- package/dist/components/Tabs/Tabs.d.ts.map +1 -0
- package/dist/components/Tabs/Tabs.js +140 -0
- package/dist/components/Tabs/Tabs.js.map +1 -0
- package/dist/components/Tabs/index.d.ts +3 -0
- package/dist/components/Tabs/index.d.ts.map +1 -0
- package/dist/components/TextInput/TextInput.css +133 -0
- package/dist/components/TextInput/TextInput.css.d.ts +1 -0
- package/dist/components/TextInput/TextInput.d.ts +16 -0
- package/dist/components/TextInput/TextInput.d.ts.map +1 -0
- package/dist/components/TextInput/TextInput.js +38 -0
- package/dist/components/TextInput/TextInput.js.map +1 -0
- package/dist/components/TextInput/index.d.ts +3 -0
- package/dist/components/TextInput/index.d.ts.map +1 -0
- package/dist/components/Textarea/Textarea.css +121 -0
- package/dist/components/Textarea/Textarea.css.d.ts +1 -0
- package/dist/components/Textarea/Textarea.d.ts +21 -0
- package/dist/components/Textarea/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea/Textarea.js +61 -0
- package/dist/components/Textarea/Textarea.js.map +1 -0
- package/dist/components/Textarea/index.d.ts +3 -0
- package/dist/components/Textarea/index.d.ts.map +1 -0
- package/dist/components/TitleBar/TitleBar.css +76 -0
- package/dist/components/TitleBar/TitleBar.css.d.ts +1 -0
- package/dist/components/TitleBar/TitleBar.d.ts +20 -0
- package/dist/components/TitleBar/TitleBar.d.ts.map +1 -0
- package/dist/components/TitleBar/TitleBar.js +43 -0
- package/dist/components/TitleBar/TitleBar.js.map +1 -0
- package/dist/components/TitleBar/index.d.ts +3 -0
- package/dist/components/TitleBar/index.d.ts.map +1 -0
- package/dist/components/ToggleButton/ToggleButton.css +162 -0
- package/dist/components/ToggleButton/ToggleButton.css.d.ts +1 -0
- package/dist/components/ToggleButton/ToggleButton.d.ts +27 -0
- package/dist/components/ToggleButton/ToggleButton.d.ts.map +1 -0
- package/dist/components/ToggleButton/ToggleButton.js +52 -0
- package/dist/components/ToggleButton/ToggleButton.js.map +1 -0
- package/dist/components/ToggleButton/index.d.ts +3 -0
- package/dist/components/ToggleButton/index.d.ts.map +1 -0
- package/dist/components/Toolbar/Toolbar.css +202 -0
- package/dist/components/Toolbar/Toolbar.css.d.ts +1 -0
- package/dist/components/Toolbar/Toolbar.d.ts +46 -0
- package/dist/components/Toolbar/Toolbar.d.ts.map +1 -0
- package/dist/components/Toolbar/Toolbar.js +102 -0
- package/dist/components/Toolbar/Toolbar.js.map +1 -0
- package/dist/components/Toolbar/index.d.ts +3 -0
- package/dist/components/Toolbar/index.d.ts.map +1 -0
- package/dist/components/Tooltip/Tooltip.css +86 -0
- package/dist/components/Tooltip/Tooltip.css.d.ts +1 -0
- package/dist/components/Tooltip/Tooltip.d.ts +22 -0
- package/dist/components/Tooltip/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip/Tooltip.js +92 -0
- package/dist/components/Tooltip/Tooltip.js.map +1 -0
- package/dist/components/Tooltip/index.d.ts +3 -0
- package/dist/components/Tooltip/index.d.ts.map +1 -0
- package/dist/components/TreeView/TreeView.css +191 -0
- package/dist/components/TreeView/TreeView.css.d.ts +1 -0
- package/dist/components/TreeView/TreeView.d.ts +46 -0
- package/dist/components/TreeView/TreeView.d.ts.map +1 -0
- package/dist/components/TreeView/TreeView.js +331 -0
- package/dist/components/TreeView/TreeView.js.map +1 -0
- package/dist/components/TreeView/index.d.ts +3 -0
- package/dist/components/TreeView/index.d.ts.map +1 -0
- package/dist/components/Window/Window.css +218 -0
- package/dist/components/Window/Window.css.d.ts +1 -0
- package/dist/components/Window/Window.d.ts +30 -0
- package/dist/components/Window/Window.d.ts.map +1 -0
- package/dist/components/Window/Window.js +156 -0
- package/dist/components/Window/Window.js.map +1 -0
- package/dist/components/Window/index.d.ts +3 -0
- package/dist/components/Window/index.d.ts.map +1 -0
- package/dist/index.d.ts +91 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +41 -3
- package/dist/styles/scrollbars.css +123 -0
- package/dist/styles/scrollbars.css.d.ts +1 -0
- package/dist/styles/theme.css +86 -41
- package/dist/styles/tokens.css +202 -0
- package/dist/styles/tokens.css.d.ts +1 -0
- package/dist/test/a11y.d.ts +3 -0
- package/dist/test/a11y.d.ts.map +1 -0
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/setup.d.ts +2 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/package.json +13 -2
- package/dist/components/GreenButton/GreenButton.css +0 -47
- package/dist/components/GreenButton/GreenButton.d.ts +0 -8
- package/dist/components/GreenButton/GreenButton.d.ts.map +0 -1
- package/dist/components/GreenButton/GreenButton.js +0 -20
- package/dist/components/GreenButton/GreenButton.js.map +0 -1
- package/dist/components/GreenButton/index.d.ts +0 -3
- package/dist/components/GreenPanel/GreenPanel.css +0 -45
- package/dist/components/GreenPanel/GreenPanel.d.ts +0 -12
- package/dist/components/GreenPanel/GreenPanel.d.ts.map +0 -1
- package/dist/components/GreenPanel/GreenPanel.js +0 -24
- package/dist/components/GreenPanel/GreenPanel.js.map +0 -1
- package/dist/components/GreenPanel/index.d.ts +0 -3
- /package/dist/components/{GreenButton/GreenButton.css.d.ts → Avatar/Avatar.css.d.ts} +0 -0
- /package/dist/components/{GreenPanel/GreenPanel.css.d.ts → Button/Button.css.d.ts} +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/* List — the ListPanel / CGamesListPanel row well.
|
|
2
|
+
*
|
|
3
|
+
* Everything here is a value from `docs/components/List.md`; the only colours
|
|
4
|
+
* allowed are `var(--vgui-*)` (see `src/styles/tokens.css`). `steam.styles`
|
|
5
|
+
* style blocks outrank the `.Scheme` keys, so the interior is `DarkGreenBG`
|
|
6
|
+
* painted by `render_bg` and the selection is `BorderDark` — not `GrayBG` and
|
|
7
|
+
* `DarkGreenBG` as the `.Scheme` keys would suggest.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
.vgui-list {
|
|
11
|
+
position: relative;
|
|
12
|
+
color: var(--vgui-text-strong);
|
|
13
|
+
font-size: 14px;
|
|
14
|
+
overflow: hidden; /* the interior scrolls, not the frame */
|
|
15
|
+
/* PerPixelScrolling "1": the browser already scrolls by pixels. Do NOT add
|
|
16
|
+
scroll-snap — it re-introduces the row-jumping this metric exists to
|
|
17
|
+
avoid. */
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Recessed: ListPanel — top/left dark, bottom/right lit. */
|
|
21
|
+
.vgui-list--recessed > .vgui-list__interior {
|
|
22
|
+
background-color: var(--vgui-list-bg, #3e4637);
|
|
23
|
+
border-top: 1px solid var(--vgui-bevel-dark);
|
|
24
|
+
border-left: 1px solid var(--vgui-bevel-dark);
|
|
25
|
+
border-right: 1px solid var(--vgui-bevel-light);
|
|
26
|
+
border-bottom: 1px solid var(--vgui-bevel-light);
|
|
27
|
+
overflow-y: auto;
|
|
28
|
+
/* ListPanelInterior inset "0 0 0 1" — one pixel reserved at the bottom. */
|
|
29
|
+
padding-bottom: 1px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Raised: CGamesListPanel — the same four lines with the sides swapped. */
|
|
33
|
+
.vgui-list--raised > .vgui-list__interior {
|
|
34
|
+
background-color: var(--vgui-list-bg, #3e4637);
|
|
35
|
+
border-top: 1px solid var(--vgui-bevel-light);
|
|
36
|
+
border-left: 1px solid var(--vgui-bevel-light);
|
|
37
|
+
border-right: 1px solid var(--vgui-bevel-dark);
|
|
38
|
+
border-bottom: 1px solid var(--vgui-bevel-dark);
|
|
39
|
+
overflow-y: auto;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ListpanelCorner — the square where the two native scrollbars meet. */
|
|
43
|
+
.vgui-list__interior::-webkit-scrollbar-corner {
|
|
44
|
+
background-color: var(--vgui-scrollbar-corner, #4c4c4c);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* The one `role="listbox"` of a flat list, or one per section when grouped.
|
|
48
|
+
`aria-required-children` only permits `option`/`group` inside a listbox, so
|
|
49
|
+
section headers and collapsers live outside this element. */
|
|
50
|
+
.vgui-list__rows {
|
|
51
|
+
display: flex;
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* A collapsed section is `hidden`; the author `display` above would otherwise
|
|
56
|
+
beat the user-agent `[hidden] { display: none }`. */
|
|
57
|
+
.vgui-list__rows[hidden] {
|
|
58
|
+
display: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.vgui-list__section {
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-direction: column;
|
|
64
|
+
min-width: 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* PostSectionLeading: 10px of air before each new section. */
|
|
68
|
+
.vgui-list__section + .vgui-list__section {
|
|
69
|
+
margin-top: var(--vgui-list-post-section-leading, 10px);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.vgui-list__section-header {
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
min-width: 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.vgui-list__section-title {
|
|
79
|
+
color: var(--vgui-text-section, #c4b550);
|
|
80
|
+
font-size: 14px;
|
|
81
|
+
padding: 0 4px;
|
|
82
|
+
min-width: 0;
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
text-overflow: ellipsis;
|
|
85
|
+
white-space: nowrap;
|
|
86
|
+
/* `ListPanelSectionHeader:hover` sets the same value as its base state, so
|
|
87
|
+
there is deliberately no hover rule here: adding one would invent a state
|
|
88
|
+
the corpus does not have. */
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.vgui-list__row {
|
|
92
|
+
position: relative;
|
|
93
|
+
display: flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
min-height: var(--vgui-list-row-height, 17px);
|
|
96
|
+
padding: 0 4px;
|
|
97
|
+
cursor: default;
|
|
98
|
+
/* No transitions: VGUI selection is instantaneous. */
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.vgui-list__label {
|
|
102
|
+
display: flex;
|
|
103
|
+
align-items: center;
|
|
104
|
+
min-width: 0;
|
|
105
|
+
overflow: hidden;
|
|
106
|
+
white-space: nowrap;
|
|
107
|
+
text-overflow: ellipsis;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* The games list has a dedicated, brighter row colour. */
|
|
111
|
+
.vgui-list--raised .vgui-list__row {
|
|
112
|
+
color: var(--vgui-text-list-strong, #e6ece0);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Selection is "pushed in": the fill is *darker* than the interior, 1.41:1
|
|
116
|
+
against it. That fails WCAG 1.4.11 on its own, so the state also carries a
|
|
117
|
+
leading marker and a 1px inset shadow — both non-colour cues. */
|
|
118
|
+
.vgui-list__row[aria-selected='true'] {
|
|
119
|
+
background-color: var(--vgui-list-selected-bg, #282e22);
|
|
120
|
+
color: var(--vgui-text-strong);
|
|
121
|
+
box-shadow: inset 1px 1px 0 var(--vgui-bevel-dark);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.vgui-list__row[aria-selected='true']::before {
|
|
125
|
+
content: '';
|
|
126
|
+
position: absolute;
|
|
127
|
+
top: 2px;
|
|
128
|
+
bottom: 2px;
|
|
129
|
+
left: 0;
|
|
130
|
+
width: 2px;
|
|
131
|
+
background-color: var(--vgui-text-strong);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.vgui-list__row[aria-disabled='true'] {
|
|
135
|
+
color: var(--vgui-text-list-disabled, #5a6a50);
|
|
136
|
+
text-shadow: 1px 1px 0 var(--vgui-bevel-dark);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* Roving tabindex: the arrow keys move focus, so the ring marks the *active*
|
|
140
|
+
row — which in a multi-select list is a different row from the selected
|
|
141
|
+
ones. */
|
|
142
|
+
.vgui-list__row:focus-visible {
|
|
143
|
+
outline: var(--vgui-focus-ring);
|
|
144
|
+
outline-offset: var(--vgui-focus-ring-offset);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Valve's fallback ring: a 1px dashed inner outline. */
|
|
148
|
+
.vgui-crisp .vgui-list__row:focus-visible {
|
|
149
|
+
outline: var(--vgui-focus-ring-valve);
|
|
150
|
+
outline-offset: var(--vgui-focus-ring-valve-offset);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.vgui-list__collapser {
|
|
154
|
+
position: relative;
|
|
155
|
+
flex: 0 0 var(--vgui-collapser-width, 16px);
|
|
156
|
+
width: var(--vgui-collapser-width, 16px);
|
|
157
|
+
height: 16px;
|
|
158
|
+
padding: 0;
|
|
159
|
+
border: 0;
|
|
160
|
+
background: transparent;
|
|
161
|
+
cursor: default;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* The 16px slot is under --vgui-min-target-size (24px), so the target is grown
|
|
165
|
+
invisibly without moving the glyph. */
|
|
166
|
+
.vgui-list__collapser::after {
|
|
167
|
+
content: '';
|
|
168
|
+
position: absolute;
|
|
169
|
+
top: 50%;
|
|
170
|
+
left: 50%;
|
|
171
|
+
width: var(--vgui-min-target-size, 24px);
|
|
172
|
+
height: var(--vgui-min-target-size, 24px);
|
|
173
|
+
transform: translate(-50%, -50%);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.vgui-list__collapser:focus-visible {
|
|
177
|
+
outline: var(--vgui-focus-ring);
|
|
178
|
+
outline-offset: var(--vgui-focus-ring-offset);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.vgui-crisp .vgui-list__collapser:focus-visible {
|
|
182
|
+
outline: var(--vgui-focus-ring-valve);
|
|
183
|
+
outline-offset: var(--vgui-focus-ring-valve-offset);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* ListPanelSectionCollapser: inset "-4 0 0 0", padding-top/-bottom "-2" — the
|
|
187
|
+
14x9 glyph overhangs its 16px slot by 4px on the left, and the port ships no
|
|
188
|
+
`.tga` assets (`docs/assets.md`), so the sprite is drawn as a triangle. */
|
|
189
|
+
.vgui-list__collapser-glyph {
|
|
190
|
+
display: block;
|
|
191
|
+
width: 14px;
|
|
192
|
+
height: 9px;
|
|
193
|
+
margin-left: calc(-1 * var(--vgui-collapser-overhang, 4px));
|
|
194
|
+
border-top: 4px solid transparent;
|
|
195
|
+
border-bottom: 4px solid transparent;
|
|
196
|
+
border-left: 7px solid var(--vgui-text-section, #c4b550);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.vgui-list__collapser-glyph[data-state='expanded'] {
|
|
200
|
+
border-top: 7px solid var(--vgui-text-section, #c4b550);
|
|
201
|
+
border-left: 4px solid transparent;
|
|
202
|
+
border-right: 4px solid transparent;
|
|
203
|
+
border-bottom: 0;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.vgui-list__empty {
|
|
207
|
+
margin: 0;
|
|
208
|
+
padding: 4px;
|
|
209
|
+
color: var(--vgui-text);
|
|
210
|
+
font-size: 14px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* The selection live region: audible, never visible. */
|
|
214
|
+
.vgui-list__live {
|
|
215
|
+
position: absolute;
|
|
216
|
+
width: 1px;
|
|
217
|
+
height: 1px;
|
|
218
|
+
margin: -1px;
|
|
219
|
+
padding: 0;
|
|
220
|
+
overflow: hidden;
|
|
221
|
+
clip-path: inset(50%);
|
|
222
|
+
white-space: nowrap;
|
|
223
|
+
border: 0;
|
|
224
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import './List.css';
|
|
3
|
+
import '../../styles/scrollbars.css';
|
|
4
|
+
export interface ListRow {
|
|
5
|
+
/** Stable identity; also the React key. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Row content when used flat; see Table for named columns. */
|
|
8
|
+
content: ReactNode;
|
|
9
|
+
/** Renders as non-interactive and dimmed. */
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
/** Arbitrary payload returned by onSelectedChange. */
|
|
12
|
+
data?: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface ListSection {
|
|
15
|
+
/** Stable identity for the section. */
|
|
16
|
+
id: string;
|
|
17
|
+
/** Optional heading, rendered in the Over/maize colour. */
|
|
18
|
+
title?: string;
|
|
19
|
+
/** Rows in this section. */
|
|
20
|
+
rows: ListRow[];
|
|
21
|
+
}
|
|
22
|
+
export interface ListProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
23
|
+
/** Rows, or sections when `grouped` is set. */
|
|
24
|
+
items: ListRow[] | ListSection[];
|
|
25
|
+
/** Treats `items` as `ListSection[]` and renders collapsers. */
|
|
26
|
+
grouped?: boolean;
|
|
27
|
+
/** Uses the raised `CGamesListPanel` bevel instead of the recessed well. */
|
|
28
|
+
raised?: boolean;
|
|
29
|
+
/** Controlled selection. Use `string[]` when `multi` is set. */
|
|
30
|
+
selected?: string | string[];
|
|
31
|
+
/** Initial selection when uncontrolled. */
|
|
32
|
+
defaultSelected?: string | string[];
|
|
33
|
+
/** Allows Ctrl/Shift multi-selection. */
|
|
34
|
+
multi?: boolean;
|
|
35
|
+
/** Called with the new selection. */
|
|
36
|
+
onSelectedChange?: (ids: string | string[]) => void;
|
|
37
|
+
/** Message rendered when there are no rows. */
|
|
38
|
+
emptyMessage?: string;
|
|
39
|
+
/** Row pitch in pixels. Defaults to 17. */
|
|
40
|
+
rowHeight?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Accessible name for the listbox, used when neither `aria-label` nor
|
|
43
|
+
* `aria-labelledby` is given. ARIA requires a listbox to be named, so it
|
|
44
|
+
* falls back to `"List"`.
|
|
45
|
+
*/
|
|
46
|
+
label?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare const List: import("react").ForwardRefExoticComponent<ListProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
49
|
+
//# sourceMappingURL=List.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"List.d.ts","sourceRoot":"","sources":["../../../src/components/List/List.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,cAAc,EAGd,SAAS,EACV,MAAM,OAAO,CAAA;AAEd,OAAO,YAAY,CAAA;AACnB,OAAO,6BAA6B,CAAA;AAEpC,MAAM,WAAW,OAAO;IACtB,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAA;IACV,+DAA+D;IAC/D,OAAO,EAAE,SAAS,CAAA;IAClB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,sDAAsD;IACtD,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAA;IACV,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4BAA4B;IAC5B,IAAI,EAAE,OAAO,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IACjF,+CAA+C;IAC/C,KAAK,EAAE,OAAO,EAAE,GAAG,WAAW,EAAE,CAAA;IAChC,gEAAgE;IAChE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC5B,2CAA2C;IAC3C,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACnC,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,qCAAqC;IACrC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAA;IACnD,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAoBD,eAAO,MAAM,IAAI,sGAwXf,CAAA"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { forwardRef, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import "../../styles/scrollbars.css";
|
|
4
|
+
import "./List.css";
|
|
5
|
+
//#region src/components/List/List.tsx
|
|
6
|
+
/** `PerPixelScrolling "1"` implies the pitch is a runtime value; 17px is the doc's guess. */
|
|
7
|
+
var DEFAULT_ROW_PITCH = 17;
|
|
8
|
+
/** How long a run of typed characters keeps building a typeahead query. */
|
|
9
|
+
var TYPEAHEAD_RESET_MS = 600;
|
|
10
|
+
/** A flat list is one unnamed section; it never renders a collapser. */
|
|
11
|
+
var FLAT_SECTION_ID = "__list";
|
|
12
|
+
function toIdArray(value) {
|
|
13
|
+
if (value === void 0) return [];
|
|
14
|
+
return Array.isArray(value) ? value.slice() : [value];
|
|
15
|
+
}
|
|
16
|
+
function clamp(value, min, max) {
|
|
17
|
+
return Math.min(Math.max(value, min), max);
|
|
18
|
+
}
|
|
19
|
+
var List = forwardRef(function List(props, forwardedRef) {
|
|
20
|
+
const { className, items, grouped = false, raised = false, selected, defaultSelected, multi = false, onSelectedChange, emptyMessage, rowHeight, label, style, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...rest } = props;
|
|
21
|
+
const baseId = useId();
|
|
22
|
+
const rowRefs = useRef(/* @__PURE__ */ new Map());
|
|
23
|
+
/**
|
|
24
|
+
* Shift+click anchors on the row that was focused when the range started.
|
|
25
|
+
* It lives in a ref because a pointer press moves DOM focus before the click
|
|
26
|
+
* lands, which would otherwise overwrite the anchor with the clicked row.
|
|
27
|
+
*/
|
|
28
|
+
const anchorRef = useRef(null);
|
|
29
|
+
const typeaheadRef = useRef({
|
|
30
|
+
query: "",
|
|
31
|
+
timer: null
|
|
32
|
+
});
|
|
33
|
+
const sections = useMemo(() => {
|
|
34
|
+
if (grouped) return items.map((section) => ({
|
|
35
|
+
id: section.id,
|
|
36
|
+
title: section.title,
|
|
37
|
+
rows: Array.isArray(section.rows) ? section.rows : []
|
|
38
|
+
}));
|
|
39
|
+
return [{
|
|
40
|
+
id: FLAT_SECTION_ID,
|
|
41
|
+
rows: items
|
|
42
|
+
}];
|
|
43
|
+
}, [grouped, items]);
|
|
44
|
+
const [collapsedSections, setCollapsedSections] = useState([]);
|
|
45
|
+
const [uncontrolledSelected, setUncontrolledSelected] = useState(() => toIdArray(defaultSelected));
|
|
46
|
+
const [activeId, setActiveId] = useState(null);
|
|
47
|
+
const [announcement, setAnnouncement] = useState("");
|
|
48
|
+
const allRows = useMemo(() => sections.flatMap((section) => section.rows), [sections]);
|
|
49
|
+
const selectedIds = selected === void 0 ? uncontrolledSelected : toIdArray(selected);
|
|
50
|
+
const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds]);
|
|
51
|
+
const navigableRows = useMemo(() => sections.filter((section) => !collapsedSections.includes(section.id)).flatMap((section) => section.rows), [collapsedSections, sections]);
|
|
52
|
+
const fallbackActiveId = navigableRows.find((row) => selectedSet.has(row.id))?.id ?? navigableRows[0]?.id ?? null;
|
|
53
|
+
const activeRowId = activeId !== null && navigableRows.some((row) => row.id === activeId) ? activeId : fallbackActiveId;
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
const typeahead = typeaheadRef.current;
|
|
56
|
+
return () => {
|
|
57
|
+
if (typeahead.timer !== null) clearTimeout(typeahead.timer);
|
|
58
|
+
};
|
|
59
|
+
}, []);
|
|
60
|
+
const setRowRef = useCallback((id, node) => {
|
|
61
|
+
if (node) rowRefs.current.set(id, node);
|
|
62
|
+
else rowRefs.current.delete(id);
|
|
63
|
+
}, []);
|
|
64
|
+
const textOf = useCallback((id) => (rowRefs.current.get(id)?.textContent ?? "").trim(), []);
|
|
65
|
+
const commit = useCallback((next) => {
|
|
66
|
+
if (selected === void 0) setUncontrolledSelected(next);
|
|
67
|
+
onSelectedChange?.(multi ? next : next[0] ?? "");
|
|
68
|
+
}, [
|
|
69
|
+
multi,
|
|
70
|
+
onSelectedChange,
|
|
71
|
+
selected
|
|
72
|
+
]);
|
|
73
|
+
const describe = useCallback((id, next) => {
|
|
74
|
+
const name = textOf(id).slice(0, 60);
|
|
75
|
+
const position = allRows.findIndex((row) => row.id === id) + 1;
|
|
76
|
+
const state = next.includes(id) ? "selected" : "not selected";
|
|
77
|
+
return [`${name || "Row"}, ${state}`, `${position} of ${allRows.length}`].join(", ");
|
|
78
|
+
}, [allRows, textOf]);
|
|
79
|
+
const focusRow = useCallback((id) => {
|
|
80
|
+
setActiveId(id);
|
|
81
|
+
anchorRef.current = id;
|
|
82
|
+
const node = rowRefs.current.get(id);
|
|
83
|
+
if (!node) return;
|
|
84
|
+
/**
|
|
85
|
+
* jsdom has no layout engine, so `scrollIntoView` may be a stub or missing
|
|
86
|
+
* entirely; `PerPixelScrolling` only asks that the active row be brought
|
|
87
|
+
* into view, so a missing implementation is not fatal.
|
|
88
|
+
*/
|
|
89
|
+
if (typeof node.scrollIntoView === "function") node.scrollIntoView({ block: "nearest" });
|
|
90
|
+
node.focus();
|
|
91
|
+
}, []);
|
|
92
|
+
const moveActive = useCallback((step) => {
|
|
93
|
+
const ids = navigableRows.map((row) => row.id);
|
|
94
|
+
if (ids.length === 0) return;
|
|
95
|
+
const current = activeRowId === null ? -1 : ids.indexOf(activeRowId);
|
|
96
|
+
const next = step === "first" ? 0 : step === "last" ? ids.length - 1 : clamp((current < 0 ? 0 : current) + step, 0, ids.length - 1);
|
|
97
|
+
focusRow(ids[next]);
|
|
98
|
+
}, [
|
|
99
|
+
activeRowId,
|
|
100
|
+
focusRow,
|
|
101
|
+
navigableRows
|
|
102
|
+
]);
|
|
103
|
+
const typeahead = useCallback((character) => {
|
|
104
|
+
const state = typeaheadRef.current;
|
|
105
|
+
const buffer = (state.query + character).toLowerCase();
|
|
106
|
+
state.query = buffer;
|
|
107
|
+
if (state.timer !== null) clearTimeout(state.timer);
|
|
108
|
+
state.timer = setTimeout(() => {
|
|
109
|
+
state.query = "";
|
|
110
|
+
}, TYPEAHEAD_RESET_MS);
|
|
111
|
+
const ids = navigableRows.map((row) => row.id);
|
|
112
|
+
if (ids.length === 0) return;
|
|
113
|
+
const targets = navigableRows.filter((row) => !row.disabled).map((row) => row.id);
|
|
114
|
+
if (targets.length === 0) return;
|
|
115
|
+
const start = activeRowId === null ? -1 : ids.indexOf(activeRowId);
|
|
116
|
+
for (let offset = 1; offset <= ids.length; offset += 1) {
|
|
117
|
+
const id = ids[(start + offset + ids.length) % ids.length];
|
|
118
|
+
if (!targets.includes(id)) continue;
|
|
119
|
+
if (textOf(id).toLowerCase().startsWith(buffer)) {
|
|
120
|
+
focusRow(id);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}, [
|
|
125
|
+
activeRowId,
|
|
126
|
+
focusRow,
|
|
127
|
+
navigableRows,
|
|
128
|
+
textOf
|
|
129
|
+
]);
|
|
130
|
+
const selectRow = useCallback((id, mode) => {
|
|
131
|
+
const anchor = anchorRef.current ?? activeRowId;
|
|
132
|
+
let next;
|
|
133
|
+
if (mode === "range" && anchor !== null && anchor !== id) {
|
|
134
|
+
const ids = allRows.map((row) => row.id);
|
|
135
|
+
const from = ids.indexOf(anchor);
|
|
136
|
+
const to = ids.indexOf(id);
|
|
137
|
+
next = ids.slice(Math.min(from, to), Math.max(from, to) + 1);
|
|
138
|
+
} else if (mode === "range" || mode === "replace") next = [id];
|
|
139
|
+
else next = selectedSet.has(id) ? selectedIds.filter((entry) => entry !== id) : [...selectedIds, id];
|
|
140
|
+
if (mode !== "range") anchorRef.current = id;
|
|
141
|
+
setAnnouncement(describe(id, next));
|
|
142
|
+
commit(next);
|
|
143
|
+
}, [
|
|
144
|
+
activeRowId,
|
|
145
|
+
allRows,
|
|
146
|
+
commit,
|
|
147
|
+
describe,
|
|
148
|
+
selectedIds,
|
|
149
|
+
selectedSet
|
|
150
|
+
]);
|
|
151
|
+
const activate = useCallback((id) => {
|
|
152
|
+
const row = allRows.find((entry) => entry.id === id);
|
|
153
|
+
if (!row || row.disabled) return;
|
|
154
|
+
selectRow(id, multi ? "toggle" : "replace");
|
|
155
|
+
}, [
|
|
156
|
+
allRows,
|
|
157
|
+
multi,
|
|
158
|
+
selectRow
|
|
159
|
+
]);
|
|
160
|
+
const handleKeyDown = useCallback((event) => {
|
|
161
|
+
const { key } = event;
|
|
162
|
+
if (key === "ArrowDown" || key === "ArrowUp") {
|
|
163
|
+
event.preventDefault();
|
|
164
|
+
moveActive(key === "ArrowDown" ? 1 : -1);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (key === "Home" || key === "End") {
|
|
168
|
+
event.preventDefault();
|
|
169
|
+
moveActive(key === "Home" ? "first" : "last");
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (key === "Enter" || key === " ") {
|
|
173
|
+
event.preventDefault();
|
|
174
|
+
if (activeRowId !== null) activate(activeRowId);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) typeahead(key);
|
|
178
|
+
}, [
|
|
179
|
+
activate,
|
|
180
|
+
activeRowId,
|
|
181
|
+
moveActive,
|
|
182
|
+
typeahead
|
|
183
|
+
]);
|
|
184
|
+
const handleRowClick = useCallback((event, id) => {
|
|
185
|
+
const row = allRows.find((entry) => entry.id === id);
|
|
186
|
+
if (!row || row.disabled) return;
|
|
187
|
+
setActiveId(id);
|
|
188
|
+
if (!multi) {
|
|
189
|
+
selectRow(id, "replace");
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (event.shiftKey) {
|
|
193
|
+
selectRow(id, "range");
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
selectRow(id, event.ctrlKey || event.metaKey ? "toggle" : "replace");
|
|
197
|
+
}, [
|
|
198
|
+
allRows,
|
|
199
|
+
multi,
|
|
200
|
+
selectRow
|
|
201
|
+
]);
|
|
202
|
+
const toggleSection = useCallback((id) => {
|
|
203
|
+
setCollapsedSections((previous) => previous.includes(id) ? previous.filter((entry) => entry !== id) : [...previous, id]);
|
|
204
|
+
}, []);
|
|
205
|
+
const classes = ["vgui-list"];
|
|
206
|
+
classes.push(raised ? "vgui-list--raised" : "vgui-list--recessed");
|
|
207
|
+
if (grouped) classes.push("vgui-list--sectioned");
|
|
208
|
+
if (multi) classes.push("vgui-list--multi");
|
|
209
|
+
if (allRows.length === 0) classes.push("vgui-list--empty");
|
|
210
|
+
if (className) classes.push(className);
|
|
211
|
+
const listStyle = {
|
|
212
|
+
...style,
|
|
213
|
+
"--vgui-list-row-height": `${rowHeight ?? DEFAULT_ROW_PITCH}px`
|
|
214
|
+
};
|
|
215
|
+
const isEmpty = allRows.length === 0;
|
|
216
|
+
const renderRow = (row) => {
|
|
217
|
+
const isSelected = selectedSet.has(row.id);
|
|
218
|
+
const rowClasses = ["vgui-list__row"];
|
|
219
|
+
if (isSelected) rowClasses.push("vgui-list__row--selected");
|
|
220
|
+
if (row.disabled) rowClasses.push("vgui-list__row--disabled");
|
|
221
|
+
return /* @__PURE__ */ jsx("div", {
|
|
222
|
+
id: `${baseId}-row-${row.id}`,
|
|
223
|
+
ref: (node) => setRowRef(row.id, node),
|
|
224
|
+
className: rowClasses.join(" "),
|
|
225
|
+
role: "option",
|
|
226
|
+
"aria-selected": isSelected,
|
|
227
|
+
"aria-disabled": row.disabled ? true : void 0,
|
|
228
|
+
tabIndex: row.id === activeRowId ? 0 : -1,
|
|
229
|
+
onClick: (event) => handleRowClick(event, row.id),
|
|
230
|
+
onFocus: () => setActiveId(row.id),
|
|
231
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
232
|
+
className: "vgui-list__label",
|
|
233
|
+
children: row.content
|
|
234
|
+
})
|
|
235
|
+
}, row.id);
|
|
236
|
+
};
|
|
237
|
+
return /* @__PURE__ */ jsx("div", {
|
|
238
|
+
ref: forwardedRef,
|
|
239
|
+
className: classes.join(" "),
|
|
240
|
+
style: listStyle,
|
|
241
|
+
...rest,
|
|
242
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
243
|
+
className: "vgui-list__interior vgui-scroll-surface",
|
|
244
|
+
children: isEmpty ? /* @__PURE__ */ jsx("p", {
|
|
245
|
+
className: "vgui-list__empty",
|
|
246
|
+
role: "status",
|
|
247
|
+
children: emptyMessage
|
|
248
|
+
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [sections.map((section, index) => {
|
|
249
|
+
const titled = grouped && section.title !== void 0;
|
|
250
|
+
const titleId = `${baseId}-${section.id}-title`;
|
|
251
|
+
const rowsId = `${baseId}-${section.id}-rows`;
|
|
252
|
+
const collapsed = collapsedSections.includes(section.id);
|
|
253
|
+
const sectionName = grouped && label !== void 0 ? `${label}: ${section.title ?? index + 1}` : label;
|
|
254
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
255
|
+
className: "vgui-list__section",
|
|
256
|
+
children: [grouped ? /* @__PURE__ */ jsxs("div", {
|
|
257
|
+
className: "vgui-list__section-header",
|
|
258
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
259
|
+
type: "button",
|
|
260
|
+
className: "vgui-list__collapser",
|
|
261
|
+
"aria-expanded": !collapsed,
|
|
262
|
+
"aria-controls": rowsId,
|
|
263
|
+
"aria-label": section.title === void 0 ? `${collapsed ? "Expand" : "Collapse"} section ${index + 1}` : `${collapsed ? "Expand" : "Collapse"} ${section.title}`,
|
|
264
|
+
onClick: () => toggleSection(section.id),
|
|
265
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
266
|
+
className: "vgui-list__collapser-glyph",
|
|
267
|
+
"data-state": collapsed ? "collapsed" : "expanded",
|
|
268
|
+
"aria-hidden": "true"
|
|
269
|
+
})
|
|
270
|
+
}), section.title !== void 0 ? /* @__PURE__ */ jsx("span", {
|
|
271
|
+
className: "vgui-list__section-title",
|
|
272
|
+
id: titleId,
|
|
273
|
+
"aria-hidden": "true",
|
|
274
|
+
children: section.title
|
|
275
|
+
}) : null]
|
|
276
|
+
}) : null, /* @__PURE__ */ jsx("div", {
|
|
277
|
+
id: rowsId,
|
|
278
|
+
className: "vgui-list__rows",
|
|
279
|
+
role: "listbox",
|
|
280
|
+
"aria-labelledby": titled ? titleId : ariaLabelledBy,
|
|
281
|
+
"aria-label": titled || ariaLabelledBy ? void 0 : grouped ? sectionName ?? "List" : ariaLabel ?? sectionName ?? "List",
|
|
282
|
+
"aria-multiselectable": multi ? true : void 0,
|
|
283
|
+
hidden: grouped ? collapsed : void 0,
|
|
284
|
+
onKeyDown: handleKeyDown,
|
|
285
|
+
children: section.rows.map(renderRow)
|
|
286
|
+
})]
|
|
287
|
+
}, section.id);
|
|
288
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
289
|
+
className: "vgui-list__live",
|
|
290
|
+
role: "status",
|
|
291
|
+
children: announcement
|
|
292
|
+
})] })
|
|
293
|
+
})
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
List.displayName = "List";
|
|
297
|
+
//#endregion
|
|
298
|
+
export { List };
|
|
299
|
+
|
|
300
|
+
//# sourceMappingURL=List.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"List.js","names":[],"sources":["../../../src/components/List/List.tsx"],"sourcesContent":["import { forwardRef, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react'\nimport type {\n CSSProperties,\n HTMLAttributes,\n KeyboardEvent as ReactKeyboardEvent,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n} from 'react'\n\nimport './List.css'\nimport '../../styles/scrollbars.css'\n\nexport interface ListRow {\n /** Stable identity; also the React key. */\n id: string\n /** Row content when used flat; see Table for named columns. */\n content: ReactNode\n /** Renders as non-interactive and dimmed. */\n disabled?: boolean\n /** Arbitrary payload returned by onSelectedChange. */\n data?: unknown\n}\n\nexport interface ListSection {\n /** Stable identity for the section. */\n id: string\n /** Optional heading, rendered in the Over/maize colour. */\n title?: string\n /** Rows in this section. */\n rows: ListRow[]\n}\n\nexport interface ListProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Rows, or sections when `grouped` is set. */\n items: ListRow[] | ListSection[]\n /** Treats `items` as `ListSection[]` and renders collapsers. */\n grouped?: boolean\n /** Uses the raised `CGamesListPanel` bevel instead of the recessed well. */\n raised?: boolean\n /** Controlled selection. Use `string[]` when `multi` is set. */\n selected?: string | string[]\n /** Initial selection when uncontrolled. */\n defaultSelected?: string | string[]\n /** Allows Ctrl/Shift multi-selection. */\n multi?: boolean\n /** Called with the new selection. */\n onSelectedChange?: (ids: string | string[]) => void\n /** Message rendered when there are no rows. */\n emptyMessage?: string\n /** Row pitch in pixels. Defaults to 17. */\n rowHeight?: number\n /**\n * Accessible name for the listbox, used when neither `aria-label` nor\n * `aria-labelledby` is given. ARIA requires a listbox to be named, so it\n * falls back to `\"List\"`.\n */\n label?: string\n}\n\n/** `PerPixelScrolling \"1\"` implies the pitch is a runtime value; 17px is the doc's guess. */\nconst DEFAULT_ROW_PITCH = 17\n\n/** How long a run of typed characters keeps building a typeahead query. */\nconst TYPEAHEAD_RESET_MS = 600\n\n/** A flat list is one unnamed section; it never renders a collapser. */\nconst FLAT_SECTION_ID = '__list'\n\nfunction toIdArray(value: string | string[] | undefined): string[] {\n if (value === undefined) return []\n return Array.isArray(value) ? value.slice() : [value]\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max)\n}\n\nexport const List = forwardRef<HTMLDivElement, ListProps>(function List(props, forwardedRef) {\n const {\n className,\n items,\n grouped = false,\n raised = false,\n selected,\n defaultSelected,\n multi = false,\n onSelectedChange,\n emptyMessage,\n rowHeight,\n label,\n style,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...rest\n } = props\n\n const baseId = useId()\n const rowRefs = useRef(new Map<string, HTMLDivElement>())\n /**\n * Shift+click anchors on the row that was focused when the range started.\n * It lives in a ref because a pointer press moves DOM focus before the click\n * lands, which would otherwise overwrite the anchor with the clicked row.\n */\n const anchorRef = useRef<string | null>(null)\n const typeaheadRef = useRef<{ query: string; timer: ReturnType<typeof setTimeout> | null }>({\n query: '',\n timer: null,\n })\n\n // Sections are always materialised so the flat and grouped paths share one\n // renderer; a flat list is a single section with no header.\n const sections = useMemo<ListSection[]>(() => {\n if (grouped) {\n return (items as ListSection[]).map((section) => ({\n id: section.id,\n title: section.title,\n rows: Array.isArray(section.rows) ? section.rows : [],\n }))\n }\n return [{ id: FLAT_SECTION_ID, rows: items as ListRow[] }]\n }, [grouped, items])\n\n const [collapsedSections, setCollapsedSections] = useState<string[]>([])\n const [uncontrolledSelected, setUncontrolledSelected] = useState<string[]>(() =>\n toIdArray(defaultSelected),\n )\n const [activeId, setActiveId] = useState<string | null>(null)\n const [announcement, setAnnouncement] = useState('')\n\n const allRows = useMemo(() => sections.flatMap((section) => section.rows), [sections])\n const selectedIds = selected === undefined ? uncontrolledSelected : toIdArray(selected)\n const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds])\n\n // Rows inside a collapsed section stay mounted but out of the a11y tree, so\n // they drop out of arrow-key navigation too.\n const navigableRows = useMemo(\n () =>\n sections\n .filter((section) => !collapsedSections.includes(section.id))\n .flatMap((section) => section.rows),\n [collapsedSections, sections],\n )\n\n // Roving tabindex: exactly one row is the tab stop. A stale active row (its\n // section collapsed, or its row removed) falls back to the selection and then\n // to the first row.\n const fallbackActiveId =\n navigableRows.find((row) => selectedSet.has(row.id))?.id ?? navigableRows[0]?.id ?? null\n const activeRowId =\n activeId !== null && navigableRows.some((row) => row.id === activeId)\n ? activeId\n : fallbackActiveId\n\n useEffect(() => {\n const typeahead = typeaheadRef.current\n return () => {\n if (typeahead.timer !== null) clearTimeout(typeahead.timer)\n }\n }, [])\n\n const setRowRef = useCallback((id: string, node: HTMLDivElement | null) => {\n if (node) rowRefs.current.set(id, node)\n else rowRefs.current.delete(id)\n }, [])\n\n const textOf = useCallback(\n (id: string) => (rowRefs.current.get(id)?.textContent ?? '').trim(),\n [],\n )\n\n const commit = useCallback(\n (next: string[]) => {\n if (selected === undefined) setUncontrolledSelected(next)\n onSelectedChange?.(multi ? next : (next[0] ?? ''))\n },\n [multi, onSelectedChange, selected],\n )\n\n const describe = useCallback(\n (id: string, next: string[]) => {\n const name = textOf(id).slice(0, 60)\n const position = allRows.findIndex((row) => row.id === id) + 1\n const state = next.includes(id) ? 'selected' : 'not selected'\n return [`${name || 'Row'}, ${state}`, `${position} of ${allRows.length}`].join(', ')\n },\n [allRows, textOf],\n )\n\n const focusRow = useCallback((id: string) => {\n setActiveId(id)\n anchorRef.current = id\n const node = rowRefs.current.get(id)\n if (!node) return\n /**\n * jsdom has no layout engine, so `scrollIntoView` may be a stub or missing\n * entirely; `PerPixelScrolling` only asks that the active row be brought\n * into view, so a missing implementation is not fatal.\n */\n if (typeof node.scrollIntoView === 'function') node.scrollIntoView({ block: 'nearest' })\n node.focus()\n }, [])\n\n const moveActive = useCallback(\n (step: number | 'first' | 'last') => {\n const ids = navigableRows.map((row) => row.id)\n if (ids.length === 0) return\n\n const current = activeRowId === null ? -1 : ids.indexOf(activeRowId)\n const base = current < 0 ? 0 : current\n const next =\n step === 'first' ? 0 : step === 'last' ? ids.length - 1 : clamp(base + step, 0, ids.length - 1)\n focusRow(ids[next])\n },\n [activeRowId, focusRow, navigableRows],\n )\n\n const typeahead = useCallback(\n (character: string) => {\n const state = typeaheadRef.current\n const buffer = (state.query + character).toLowerCase()\n state.query = buffer\n if (state.timer !== null) clearTimeout(state.timer)\n state.timer = setTimeout(() => {\n state.query = ''\n }, TYPEAHEAD_RESET_MS)\n\n const ids = navigableRows.map((row) => row.id)\n if (ids.length === 0) return\n\n // Disabled rows advertise their existence but are not typeahead targets.\n const targets = navigableRows.filter((row) => !row.disabled).map((row) => row.id)\n if (targets.length === 0) return\n\n const start = activeRowId === null ? -1 : ids.indexOf(activeRowId)\n for (let offset = 1; offset <= ids.length; offset += 1) {\n const id = ids[(start + offset + ids.length) % ids.length]\n if (!targets.includes(id)) continue\n if (textOf(id).toLowerCase().startsWith(buffer)) {\n focusRow(id)\n return\n }\n }\n },\n [activeRowId, focusRow, navigableRows, textOf],\n )\n\n const selectRow = useCallback(\n (id: string, mode: 'replace' | 'toggle' | 'range') => {\n const anchor = anchorRef.current ?? activeRowId\n let next: string[]\n\n if (mode === 'range' && anchor !== null && anchor !== id) {\n const ids = allRows.map((row) => row.id)\n const from = ids.indexOf(anchor)\n const to = ids.indexOf(id)\n next = ids.slice(Math.min(from, to), Math.max(from, to) + 1)\n } else if (mode === 'range' || mode === 'replace') {\n next = [id]\n } else {\n next = selectedSet.has(id) ? selectedIds.filter((entry) => entry !== id) : [...selectedIds, id]\n }\n\n // A range keeps its original anchor; every other gesture moves it.\n if (mode !== 'range') anchorRef.current = id\n\n setAnnouncement(describe(id, next))\n commit(next)\n },\n [activeRowId, allRows, commit, describe, selectedIds, selectedSet],\n )\n\n const activate = useCallback(\n (id: string) => {\n const row = allRows.find((entry) => entry.id === id)\n if (!row || row.disabled) return\n selectRow(id, multi ? 'toggle' : 'replace')\n },\n [allRows, multi, selectRow],\n )\n\n const handleKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLDivElement>) => {\n const { key } = event\n\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n event.preventDefault()\n moveActive(key === 'ArrowDown' ? 1 : -1)\n return\n }\n\n if (key === 'Home' || key === 'End') {\n event.preventDefault()\n moveActive(key === 'Home' ? 'first' : 'last')\n return\n }\n\n if (key === 'Enter' || key === ' ') {\n event.preventDefault()\n if (activeRowId !== null) activate(activeRowId)\n return\n }\n\n if (key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {\n typeahead(key)\n }\n },\n [activate, activeRowId, moveActive, typeahead],\n )\n\n const handleRowClick = useCallback(\n (event: ReactMouseEvent<HTMLDivElement>, id: string) => {\n const row = allRows.find((entry) => entry.id === id)\n if (!row || row.disabled) return\n\n // Roving tabindex means the pointer must move the active row too.\n setActiveId(id)\n\n if (!multi) {\n selectRow(id, 'replace')\n return\n }\n if (event.shiftKey) {\n selectRow(id, 'range')\n return\n }\n selectRow(id, event.ctrlKey || event.metaKey ? 'toggle' : 'replace')\n },\n [allRows, multi, selectRow],\n )\n\n const toggleSection = useCallback((id: string) => {\n setCollapsedSections((previous) =>\n previous.includes(id) ? previous.filter((entry) => entry !== id) : [...previous, id],\n )\n }, [])\n\n const classes = ['vgui-list']\n classes.push(raised ? 'vgui-list--raised' : 'vgui-list--recessed')\n if (grouped) classes.push('vgui-list--sectioned')\n if (multi) classes.push('vgui-list--multi')\n if (allRows.length === 0) classes.push('vgui-list--empty')\n if (className) classes.push(className)\n\n const listStyle = {\n ...style,\n '--vgui-list-row-height': `${rowHeight ?? DEFAULT_ROW_PITCH}px`,\n } as CSSProperties\n\n const isEmpty = allRows.length === 0\n\n const renderRow = (row: ListRow) => {\n const isSelected = selectedSet.has(row.id)\n const rowClasses = ['vgui-list__row']\n if (isSelected) rowClasses.push('vgui-list__row--selected')\n if (row.disabled) rowClasses.push('vgui-list__row--disabled')\n\n return (\n <div\n key={row.id}\n id={`${baseId}-row-${row.id}`}\n ref={(node) => setRowRef(row.id, node)}\n className={rowClasses.join(' ')}\n role=\"option\"\n aria-selected={isSelected}\n aria-disabled={row.disabled ? true : undefined}\n // Roving tabindex: the active row is the listbox's single tab stop.\n tabIndex={row.id === activeRowId ? 0 : -1}\n onClick={(event) => handleRowClick(event, row.id)}\n onFocus={() => setActiveId(row.id)}\n >\n <span className=\"vgui-list__label\">{row.content}</span>\n </div>\n )\n }\n\n return (\n <div ref={forwardedRef} className={classes.join(' ')} style={listStyle} {...rest}>\n <div className=\"vgui-list__interior vgui-scroll-surface\">\n {isEmpty ? (\n // An empty `listbox` is itself an `aria-required-children` violation,\n // so the empty state drops the widget and announces through a status\n // region instead of a dangling `aria-describedby`.\n <p className=\"vgui-list__empty\" role=\"status\">\n {emptyMessage}\n </p>\n ) : (\n <>\n {sections.map((section, index) => {\n const titled = grouped && section.title !== undefined\n const titleId = `${baseId}-${section.id}-title`\n const rowsId = `${baseId}-${section.id}-rows`\n const collapsed = collapsedSections.includes(section.id)\n const sectionName =\n grouped && label !== undefined ? `${label}: ${section.title ?? index + 1}` : label\n\n return (\n <div key={section.id} className=\"vgui-list__section\">\n {grouped ? (\n <div className=\"vgui-list__section-header\">\n <button\n type=\"button\"\n className=\"vgui-list__collapser\"\n aria-expanded={!collapsed}\n aria-controls={rowsId}\n aria-label={\n section.title === undefined\n ? `${collapsed ? 'Expand' : 'Collapse'} section ${index + 1}`\n : `${collapsed ? 'Expand' : 'Collapse'} ${section.title}`\n }\n onClick={() => toggleSection(section.id)}\n >\n <span\n className=\"vgui-list__collapser-glyph\"\n data-state={collapsed ? 'collapsed' : 'expanded'}\n aria-hidden=\"true\"\n />\n </button>\n {section.title !== undefined ? (\n <span className=\"vgui-list__section-title\" id={titleId} aria-hidden=\"true\">\n {section.title}\n </span>\n ) : null}\n </div>\n ) : null}\n <div\n id={rowsId}\n className=\"vgui-list__rows\"\n role=\"listbox\"\n aria-labelledby={titled ? titleId : ariaLabelledBy}\n aria-label={\n titled || ariaLabelledBy\n ? undefined\n : grouped\n ? (sectionName ?? 'List')\n : (ariaLabel ?? sectionName ?? 'List')\n }\n aria-multiselectable={multi ? true : undefined}\n hidden={grouped ? collapsed : undefined}\n onKeyDown={handleKeyDown}\n >\n {section.rows.map(renderRow)}\n </div>\n </div>\n )\n })}\n <div className=\"vgui-list__live\" role=\"status\">\n {announcement}\n </div>\n </>\n )}\n </div>\n </div>\n )\n})\n\nList.displayName = 'List'\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/List/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA"}
|