@dalcvil/steam-green-react 0.1.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/LICENSE +25 -25
- package/README.md +38 -12
- 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.css.d.ts +1 -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/FieldLabel/index.d.ts.map +1 -0
- 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 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +41 -2
- package/dist/styles/scrollbars.css +123 -0
- package/dist/styles/scrollbars.css.d.ts +1 -0
- package/dist/styles/theme.css +167 -122
- 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 +23 -14
- 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/{GreenButton/GreenButton.css.d.ts → Avatar/Avatar.css.d.ts} +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import './Select.css';
|
|
3
|
+
import '../../styles/scrollbars.css';
|
|
4
|
+
export interface SelectOption {
|
|
5
|
+
/** Value committed to `value` when this option is chosen. */
|
|
6
|
+
value: string;
|
|
7
|
+
/** Row content. Anything non-textual is ignored by type-ahead. */
|
|
8
|
+
label: ReactNode;
|
|
9
|
+
/** Skip the row: it can be read but not chosen. */
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface SelectProps extends HTMLAttributes<HTMLDivElement> {
|
|
13
|
+
/** Options, in list order. */
|
|
14
|
+
options: SelectOption[];
|
|
15
|
+
/** Controlled value. */
|
|
16
|
+
value?: string;
|
|
17
|
+
/** Initial value when uncontrolled. */
|
|
18
|
+
defaultValue?: string;
|
|
19
|
+
/** Called with the chosen value. */
|
|
20
|
+
onValueChange?: (value: string) => void;
|
|
21
|
+
/** Shown when nothing is selected. */
|
|
22
|
+
placeholder?: string;
|
|
23
|
+
/** Allow typing an arbitrary value instead of choosing one. */
|
|
24
|
+
editable?: boolean;
|
|
25
|
+
/** Called as the user types in `editable` mode. */
|
|
26
|
+
onInputChange?: (value: string) => void;
|
|
27
|
+
/** Height variant: `18px`, the default `19px`, or `25px` like `Button`. */
|
|
28
|
+
size?: 'small' | 'default' | 'large';
|
|
29
|
+
/** Render the invalid border. Does not set aria-invalid. */
|
|
30
|
+
invalid?: boolean;
|
|
31
|
+
/** Disable the whole control. */
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
/** Accessible name when there is no visible `FieldLabel`. */
|
|
34
|
+
'aria-label'?: string;
|
|
35
|
+
/** Id of the visible label. */
|
|
36
|
+
'aria-labelledby'?: string;
|
|
37
|
+
/** Id of the control, for `FieldLabel htmlFor`. */
|
|
38
|
+
id?: string;
|
|
39
|
+
/** Optional name for form submission via a hidden input. */
|
|
40
|
+
name?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A collapsed list that opens into an overlay list of options, with a caret on
|
|
44
|
+
* the right — VGUI's `ComboBox`, which is a text entry plus a button plus a
|
|
45
|
+
* `Menu`-shaped popup.
|
|
46
|
+
*
|
|
47
|
+
* Built from plain markup rather than from `Menu` so the package stays
|
|
48
|
+
* tree-shakable; the popup deliberately reproduces `Menu`'s geometry, row
|
|
49
|
+
* fill and `aria-activedescendant` keyboard model.
|
|
50
|
+
*/
|
|
51
|
+
export declare const Select: import("react").ForwardRefExoticComponent<SelectProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
52
|
+
//# sourceMappingURL=Select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,cAAc,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAClF,OAAO,cAAc,CAAA;AACrB,OAAO,6BAA6B,CAAA;AAEpC,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,KAAK,EAAE,SAAS,CAAA;IAChB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,cAAc,CAAC;IACjE,8BAA8B;IAC9B,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oCAAoC;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mDAAmD;IACnD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,2EAA2E;IAC3E,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAA;IACpC,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,+BAA+B;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,mDAAmD;IACnD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAUD;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,wGAyTjB,CAAA"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { forwardRef, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import "../../styles/scrollbars.css";
|
|
4
|
+
import "./Select.css";
|
|
5
|
+
//#region src/components/Select/Select.tsx
|
|
6
|
+
var instance = 0;
|
|
7
|
+
/** The text of a label, for type-ahead and the editable draft. */
|
|
8
|
+
var labelText = (label) => typeof label === "string" || typeof label === "number" ? String(label) : "";
|
|
9
|
+
var isPrintable = (event) => event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey;
|
|
10
|
+
/**
|
|
11
|
+
* A collapsed list that opens into an overlay list of options, with a caret on
|
|
12
|
+
* the right — VGUI's `ComboBox`, which is a text entry plus a button plus a
|
|
13
|
+
* `Menu`-shaped popup.
|
|
14
|
+
*
|
|
15
|
+
* Built from plain markup rather than from `Menu` so the package stays
|
|
16
|
+
* tree-shakable; the popup deliberately reproduces `Menu`'s geometry, row
|
|
17
|
+
* fill and `aria-activedescendant` keyboard model.
|
|
18
|
+
*/
|
|
19
|
+
var Select = forwardRef(function Select({ options, value, defaultValue, onValueChange, placeholder, editable = false, onInputChange, size = "default", invalid = false, disabled = false, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, id, name, ...rest }, ref) {
|
|
20
|
+
const [internal, setInternal] = useState(() => defaultValue ?? "");
|
|
21
|
+
const current = value !== void 0 ? value : internal;
|
|
22
|
+
const selectedIndex = options.findIndex((option) => option.value === current);
|
|
23
|
+
const selected = selectedIndex >= 0 ? options[selectedIndex] : void 0;
|
|
24
|
+
const firstEnabled = options.findIndex((option) => !option.disabled);
|
|
25
|
+
const lastEnabled = options.reduce((last, option, index) => option.disabled ? last : index, -1);
|
|
26
|
+
const [open, setOpen] = useState(false);
|
|
27
|
+
const [active, setActive] = useState(() => selectedIndex >= 0 ? selectedIndex : Math.max(0, firstEnabled));
|
|
28
|
+
const [seen, setSeen] = useState(current);
|
|
29
|
+
const [draft, setDraft] = useState(() => labelText(selected?.label) || current);
|
|
30
|
+
if (seen !== current) {
|
|
31
|
+
setSeen(current);
|
|
32
|
+
setDraft(labelText(selected?.label) || current);
|
|
33
|
+
}
|
|
34
|
+
const [ids] = useState(() => {
|
|
35
|
+
instance += 1;
|
|
36
|
+
return {
|
|
37
|
+
list: `vgui-select-${instance}-list`,
|
|
38
|
+
option: (index) => `vgui-select-${instance}-option-${index}`
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
const typed = useRef({
|
|
42
|
+
text: "",
|
|
43
|
+
timer: 0
|
|
44
|
+
});
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const buffer = typed.current;
|
|
47
|
+
return () => window.clearTimeout(buffer.timer);
|
|
48
|
+
}, []);
|
|
49
|
+
const commit = (next) => {
|
|
50
|
+
if (next === current) return;
|
|
51
|
+
if (value === void 0) setInternal(next);
|
|
52
|
+
onValueChange?.(next);
|
|
53
|
+
};
|
|
54
|
+
const openList = (index) => {
|
|
55
|
+
if (disabled) return;
|
|
56
|
+
setActive(index ?? (selectedIndex >= 0 ? selectedIndex : Math.max(0, firstEnabled)));
|
|
57
|
+
setOpen(true);
|
|
58
|
+
};
|
|
59
|
+
const closeList = () => setOpen(false);
|
|
60
|
+
const move = (step) => {
|
|
61
|
+
if (options.length === 0) return;
|
|
62
|
+
let index = active;
|
|
63
|
+
for (let i = 0; i < options.length; i += 1) {
|
|
64
|
+
index = (index + step + options.length) % options.length;
|
|
65
|
+
if (!options[index].disabled) break;
|
|
66
|
+
}
|
|
67
|
+
setActive(index);
|
|
68
|
+
if (editable) setDraft(labelText(options[index].label) || options[index].value);
|
|
69
|
+
};
|
|
70
|
+
const choose = (index) => {
|
|
71
|
+
const option = options[index];
|
|
72
|
+
if (!option || option.disabled || disabled) return;
|
|
73
|
+
setActive(index);
|
|
74
|
+
if (editable) setDraft(labelText(option.label) || option.value);
|
|
75
|
+
commit(option.value);
|
|
76
|
+
closeList();
|
|
77
|
+
};
|
|
78
|
+
/** The editable half's text, resolved back to an option when it names one. */
|
|
79
|
+
const commitDraft = () => {
|
|
80
|
+
const match = options.find((option) => labelText(option.label) === draft);
|
|
81
|
+
commit(match ? match.value : draft);
|
|
82
|
+
};
|
|
83
|
+
const typeAhead = (key) => {
|
|
84
|
+
const buffer = typed.current;
|
|
85
|
+
buffer.text += key;
|
|
86
|
+
window.clearTimeout(buffer.timer);
|
|
87
|
+
buffer.timer = window.setTimeout(() => {
|
|
88
|
+
buffer.text = "";
|
|
89
|
+
}, 500);
|
|
90
|
+
const needle = buffer.text.toLowerCase();
|
|
91
|
+
const index = options.findIndex((option) => !option.disabled && (labelText(option.label) || option.value).toLowerCase().startsWith(needle));
|
|
92
|
+
if (index < 0) return;
|
|
93
|
+
if (open) setActive(index);
|
|
94
|
+
else choose(index);
|
|
95
|
+
};
|
|
96
|
+
const handleKeyDown = (event) => {
|
|
97
|
+
if (disabled) return;
|
|
98
|
+
switch (event.key) {
|
|
99
|
+
case "ArrowDown":
|
|
100
|
+
event.preventDefault();
|
|
101
|
+
if (open && !event.altKey) move(1);
|
|
102
|
+
else if (!open) openList();
|
|
103
|
+
return;
|
|
104
|
+
case "ArrowUp":
|
|
105
|
+
event.preventDefault();
|
|
106
|
+
if (open) {
|
|
107
|
+
if (event.altKey) return;
|
|
108
|
+
move(-1);
|
|
109
|
+
} else openList();
|
|
110
|
+
return;
|
|
111
|
+
case "Enter":
|
|
112
|
+
case " ":
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
if (open) choose(active);
|
|
115
|
+
else openList();
|
|
116
|
+
return;
|
|
117
|
+
case "Escape":
|
|
118
|
+
if (open) {
|
|
119
|
+
event.preventDefault();
|
|
120
|
+
closeList();
|
|
121
|
+
}
|
|
122
|
+
return;
|
|
123
|
+
case "Home":
|
|
124
|
+
if (open) {
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
setActive(Math.max(0, firstEnabled));
|
|
127
|
+
}
|
|
128
|
+
return;
|
|
129
|
+
case "End":
|
|
130
|
+
if (open) {
|
|
131
|
+
event.preventDefault();
|
|
132
|
+
setActive(Math.max(0, lastEnabled));
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
case "Tab":
|
|
136
|
+
closeList();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (isPrintable(event)) {
|
|
140
|
+
event.preventDefault();
|
|
141
|
+
typeAhead(event.key);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const handleInputKeyDown = (event) => {
|
|
145
|
+
if (disabled) return;
|
|
146
|
+
switch (event.key) {
|
|
147
|
+
case "ArrowDown":
|
|
148
|
+
event.preventDefault();
|
|
149
|
+
if (open && !event.altKey) move(1);
|
|
150
|
+
else if (!open) openList();
|
|
151
|
+
return;
|
|
152
|
+
case "ArrowUp":
|
|
153
|
+
event.preventDefault();
|
|
154
|
+
if (open) {
|
|
155
|
+
if (event.altKey) return;
|
|
156
|
+
move(-1);
|
|
157
|
+
} else openList();
|
|
158
|
+
return;
|
|
159
|
+
case "Enter":
|
|
160
|
+
event.preventDefault();
|
|
161
|
+
if (open) choose(active);
|
|
162
|
+
else commitDraft();
|
|
163
|
+
return;
|
|
164
|
+
case "Escape":
|
|
165
|
+
event.preventDefault();
|
|
166
|
+
if (open) closeList();
|
|
167
|
+
else setDraft(labelText(selected?.label) || current);
|
|
168
|
+
return;
|
|
169
|
+
case "Tab":
|
|
170
|
+
commitDraft();
|
|
171
|
+
closeList();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const handleInputChange = (event) => {
|
|
176
|
+
const next = event.currentTarget.value;
|
|
177
|
+
setDraft(next);
|
|
178
|
+
onInputChange?.(next);
|
|
179
|
+
if (!open && options.length > 0) openList();
|
|
180
|
+
};
|
|
181
|
+
const classes = ["vgui-select"];
|
|
182
|
+
if (size === "small") classes.push("vgui-select--small");
|
|
183
|
+
if (size === "large") classes.push("vgui-select--large");
|
|
184
|
+
if (editable) classes.push("vgui-select--editable");
|
|
185
|
+
if (invalid) classes.push("vgui-select--invalid");
|
|
186
|
+
if (disabled) classes.push("vgui-select--disabled");
|
|
187
|
+
if (open) classes.push("vgui-select--open");
|
|
188
|
+
if (className) classes.push(className);
|
|
189
|
+
const showingPlaceholder = !selected && current === "";
|
|
190
|
+
const listId = open ? ids.list : void 0;
|
|
191
|
+
const activeId = open ? ids.option(active) : void 0;
|
|
192
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
193
|
+
ref,
|
|
194
|
+
className: classes.join(" "),
|
|
195
|
+
...rest,
|
|
196
|
+
children: [
|
|
197
|
+
editable ? /* @__PURE__ */ jsxs("span", {
|
|
198
|
+
className: "vgui-select__field",
|
|
199
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
200
|
+
id,
|
|
201
|
+
className: "vgui-select__input",
|
|
202
|
+
type: "text",
|
|
203
|
+
role: "combobox",
|
|
204
|
+
autoComplete: "off",
|
|
205
|
+
spellCheck: false,
|
|
206
|
+
placeholder: showingPlaceholder ? placeholder : void 0,
|
|
207
|
+
"aria-expanded": open,
|
|
208
|
+
"aria-haspopup": "listbox",
|
|
209
|
+
"aria-controls": listId,
|
|
210
|
+
"aria-activedescendant": activeId,
|
|
211
|
+
"aria-autocomplete": "list",
|
|
212
|
+
"aria-label": ariaLabel,
|
|
213
|
+
"aria-labelledby": ariaLabelledBy,
|
|
214
|
+
value: draft,
|
|
215
|
+
disabled,
|
|
216
|
+
onChange: handleInputChange,
|
|
217
|
+
onKeyDown: handleInputKeyDown,
|
|
218
|
+
onBlur: commitDraft
|
|
219
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
220
|
+
type: "button",
|
|
221
|
+
className: "vgui-select__button",
|
|
222
|
+
tabIndex: -1,
|
|
223
|
+
"aria-hidden": "true",
|
|
224
|
+
disabled,
|
|
225
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
226
|
+
onClick: () => open ? closeList() : openList()
|
|
227
|
+
})]
|
|
228
|
+
}) : /* @__PURE__ */ jsxs("button", {
|
|
229
|
+
type: "button",
|
|
230
|
+
id,
|
|
231
|
+
className: "vgui-select__trigger",
|
|
232
|
+
role: "combobox",
|
|
233
|
+
"aria-expanded": open,
|
|
234
|
+
"aria-haspopup": "listbox",
|
|
235
|
+
"aria-controls": listId,
|
|
236
|
+
"aria-activedescendant": activeId,
|
|
237
|
+
"aria-label": ariaLabel,
|
|
238
|
+
"aria-labelledby": ariaLabelledBy,
|
|
239
|
+
disabled,
|
|
240
|
+
onClick: () => open ? closeList() : openList(),
|
|
241
|
+
onKeyDown: handleKeyDown,
|
|
242
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
243
|
+
className: "vgui-select__value",
|
|
244
|
+
"data-placeholder": showingPlaceholder ? "true" : void 0,
|
|
245
|
+
children: selected ? selected.label : current || placeholder
|
|
246
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
247
|
+
className: "vgui-select__button",
|
|
248
|
+
"aria-hidden": "true"
|
|
249
|
+
})]
|
|
250
|
+
}),
|
|
251
|
+
name ? /* @__PURE__ */ jsx("input", {
|
|
252
|
+
type: "hidden",
|
|
253
|
+
name,
|
|
254
|
+
value: current
|
|
255
|
+
}) : null,
|
|
256
|
+
open ? /* @__PURE__ */ jsx("ul", {
|
|
257
|
+
id: ids.list,
|
|
258
|
+
className: "vgui-select__list vgui-scroll-surface",
|
|
259
|
+
role: "listbox",
|
|
260
|
+
"aria-label": ariaLabel,
|
|
261
|
+
"aria-labelledby": ariaLabelledBy,
|
|
262
|
+
children: options.map((option, index) => /* @__PURE__ */ jsx("li", {
|
|
263
|
+
id: ids.option(index),
|
|
264
|
+
className: "vgui-select__option",
|
|
265
|
+
role: "option",
|
|
266
|
+
"aria-selected": option.value === current,
|
|
267
|
+
"aria-disabled": option.disabled || void 0,
|
|
268
|
+
"data-active": index === active ? "true" : void 0,
|
|
269
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
270
|
+
onClick: () => choose(index),
|
|
271
|
+
children: option.label
|
|
272
|
+
}, option.value))
|
|
273
|
+
}) : null
|
|
274
|
+
]
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
Select.displayName = "Select";
|
|
278
|
+
//#endregion
|
|
279
|
+
export { Select };
|
|
280
|
+
|
|
281
|
+
//# sourceMappingURL=Select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.js","names":[],"sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":["import { forwardRef, useEffect, useRef, useState } from 'react'\nimport type { ChangeEvent, HTMLAttributes, KeyboardEvent, ReactNode } from 'react'\nimport './Select.css'\nimport '../../styles/scrollbars.css'\n\nexport interface SelectOption {\n /** Value committed to `value` when this option is chosen. */\n value: string\n /** Row content. Anything non-textual is ignored by type-ahead. */\n label: ReactNode\n /** Skip the row: it can be read but not chosen. */\n disabled?: boolean\n}\n\nexport interface SelectProps extends HTMLAttributes<HTMLDivElement> {\n /** Options, in list order. */\n options: SelectOption[]\n /** Controlled value. */\n value?: string\n /** Initial value when uncontrolled. */\n defaultValue?: string\n /** Called with the chosen value. */\n onValueChange?: (value: string) => void\n /** Shown when nothing is selected. */\n placeholder?: string\n /** Allow typing an arbitrary value instead of choosing one. */\n editable?: boolean\n /** Called as the user types in `editable` mode. */\n onInputChange?: (value: string) => void\n /** Height variant: `18px`, the default `19px`, or `25px` like `Button`. */\n size?: 'small' | 'default' | 'large'\n /** Render the invalid border. Does not set aria-invalid. */\n invalid?: boolean\n /** Disable the whole control. */\n disabled?: boolean\n /** Accessible name when there is no visible `FieldLabel`. */\n 'aria-label'?: string\n /** Id of the visible label. */\n 'aria-labelledby'?: string\n /** Id of the control, for `FieldLabel htmlFor`. */\n id?: string\n /** Optional name for form submission via a hidden input. */\n name?: string\n}\n\nlet instance = 0\n\n/** The text of a label, for type-ahead and the editable draft. */\nconst labelText = (label: ReactNode) => (typeof label === 'string' || typeof label === 'number' ? String(label) : '')\n\nconst isPrintable = (event: KeyboardEvent<HTMLElement>) =>\n event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey\n\n/**\n * A collapsed list that opens into an overlay list of options, with a caret on\n * the right — VGUI's `ComboBox`, which is a text entry plus a button plus a\n * `Menu`-shaped popup.\n *\n * Built from plain markup rather than from `Menu` so the package stays\n * tree-shakable; the popup deliberately reproduces `Menu`'s geometry, row\n * fill and `aria-activedescendant` keyboard model.\n */\nexport const Select = forwardRef<HTMLDivElement, SelectProps>(function Select(\n {\n options,\n value,\n defaultValue,\n onValueChange,\n placeholder,\n editable = false,\n onInputChange,\n size = 'default',\n invalid = false,\n disabled = false,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n id,\n name,\n ...rest\n },\n ref,\n) {\n const [internal, setInternal] = useState(() => defaultValue ?? '')\n const current = value !== undefined ? value : internal\n\n const selectedIndex = options.findIndex((option) => option.value === current)\n const selected = selectedIndex >= 0 ? options[selectedIndex] : undefined\n const firstEnabled = options.findIndex((option) => !option.disabled)\n const lastEnabled = options.reduce((last, option, index) => (option.disabled ? last : index), -1)\n\n const [open, setOpen] = useState(false)\n const [active, setActive] = useState(() => (selectedIndex >= 0 ? selectedIndex : Math.max(0, firstEnabled)))\n\n // The editable field shows the selection's label when there is one and the\n // raw value otherwise. Kept as draft state so typing is uncontrolled until a\n // commit, which is what makes `onValueChange` fire once per choice.\n const [seen, setSeen] = useState(current)\n const [draft, setDraft] = useState(() => labelText(selected?.label) || current)\n if (seen !== current) {\n setSeen(current)\n setDraft(labelText(selected?.label) || current)\n }\n\n const [ids] = useState(() => {\n instance += 1\n return {\n list: `vgui-select-${instance}-list`,\n option: (index: number) => `vgui-select-${instance}-option-${index}`,\n }\n })\n\n const typed = useRef({ text: '', timer: 0 })\n\n useEffect(() => {\n const buffer = typed.current\n return () => window.clearTimeout(buffer.timer)\n }, [])\n\n const commit = (next: string) => {\n if (next === current) return\n if (value === undefined) setInternal(next)\n onValueChange?.(next)\n }\n\n const openList = (index?: number) => {\n if (disabled) return\n setActive(index ?? (selectedIndex >= 0 ? selectedIndex : Math.max(0, firstEnabled)))\n setOpen(true)\n }\n\n const closeList = () => setOpen(false)\n\n const move = (step: number) => {\n if (options.length === 0) return\n let index = active\n for (let i = 0; i < options.length; i += 1) {\n index = (index + step + options.length) % options.length\n if (!options[index].disabled) break\n }\n setActive(index)\n if (editable) setDraft(labelText(options[index].label) || options[index].value)\n }\n\n const choose = (index: number) => {\n const option = options[index]\n if (!option || option.disabled || disabled) return\n setActive(index)\n if (editable) setDraft(labelText(option.label) || option.value)\n commit(option.value)\n closeList()\n }\n\n /** The editable half's text, resolved back to an option when it names one. */\n const commitDraft = () => {\n const match = options.find((option) => labelText(option.label) === draft)\n commit(match ? match.value : draft)\n }\n\n const typeAhead = (key: string) => {\n const buffer = typed.current\n buffer.text += key\n window.clearTimeout(buffer.timer)\n buffer.timer = window.setTimeout(() => {\n buffer.text = ''\n }, 500)\n const needle = buffer.text.toLowerCase()\n const index = options.findIndex(\n (option) => !option.disabled && (labelText(option.label) || option.value).toLowerCase().startsWith(needle),\n )\n if (index < 0) return\n if (open) setActive(index)\n else choose(index)\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (disabled) return\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n if (open && !event.altKey) move(1)\n else if (!open) openList()\n return\n case 'ArrowUp':\n event.preventDefault()\n if (open) {\n if (event.altKey) return\n move(-1)\n } else {\n openList()\n }\n return\n case 'Enter':\n case ' ':\n event.preventDefault()\n if (open) choose(active)\n else openList()\n return\n case 'Escape':\n if (open) {\n event.preventDefault()\n closeList()\n }\n return\n case 'Home':\n if (open) {\n event.preventDefault()\n setActive(Math.max(0, firstEnabled))\n }\n return\n case 'End':\n if (open) {\n event.preventDefault()\n setActive(Math.max(0, lastEnabled))\n }\n return\n case 'Tab':\n closeList()\n return\n default:\n break\n }\n if (isPrintable(event)) {\n event.preventDefault()\n typeAhead(event.key)\n }\n }\n\n const handleInputKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n if (open && !event.altKey) move(1)\n else if (!open) openList()\n return\n case 'ArrowUp':\n event.preventDefault()\n if (open) {\n if (event.altKey) return\n move(-1)\n } else {\n openList()\n }\n return\n case 'Enter':\n event.preventDefault()\n if (open) choose(active)\n else commitDraft()\n return\n case 'Escape':\n event.preventDefault()\n if (open) closeList()\n else setDraft(labelText(selected?.label) || current)\n return\n case 'Tab':\n commitDraft()\n closeList()\n return\n default:\n break\n }\n }\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const next = event.currentTarget.value\n setDraft(next)\n onInputChange?.(next)\n if (!open && options.length > 0) openList()\n }\n\n const classes = ['vgui-select']\n if (size === 'small') classes.push('vgui-select--small')\n if (size === 'large') classes.push('vgui-select--large')\n if (editable) classes.push('vgui-select--editable')\n if (invalid) classes.push('vgui-select--invalid')\n if (disabled) classes.push('vgui-select--disabled')\n if (open) classes.push('vgui-select--open')\n if (className) classes.push(className)\n\n const showingPlaceholder = !selected && current === ''\n const listId = open ? ids.list : undefined\n const activeId = open ? ids.option(active) : undefined\n\n return (\n <div ref={ref} className={classes.join(' ')} {...rest}>\n {editable ? (\n <span className=\"vgui-select__field\">\n <input\n id={id}\n className=\"vgui-select__input\"\n type=\"text\"\n role=\"combobox\"\n autoComplete=\"off\"\n spellCheck={false}\n placeholder={showingPlaceholder ? placeholder : undefined}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={listId}\n aria-activedescendant={activeId}\n aria-autocomplete=\"list\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n value={draft}\n disabled={disabled}\n onChange={handleInputChange}\n onKeyDown={handleInputKeyDown}\n onBlur={commitDraft}\n />\n {/* Not tabbable: the pattern keeps focus in the input, and the caret\n is decorative to assistive technology. */}\n <button\n type=\"button\"\n className=\"vgui-select__button\"\n tabIndex={-1}\n aria-hidden=\"true\"\n disabled={disabled}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => (open ? closeList() : openList())}\n />\n </span>\n ) : (\n <button\n type=\"button\"\n id={id}\n className=\"vgui-select__trigger\"\n role=\"combobox\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={listId}\n aria-activedescendant={activeId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n disabled={disabled}\n onClick={() => (open ? closeList() : openList())}\n onKeyDown={handleKeyDown}\n >\n <span className=\"vgui-select__value\" data-placeholder={showingPlaceholder ? 'true' : undefined}>\n {selected ? selected.label : current || placeholder}\n </span>\n <span className=\"vgui-select__button\" aria-hidden=\"true\" />\n </button>\n )}\n\n {/* `Select` is not a native control, so form submission needs its own\n hidden input. */}\n {name ? <input type=\"hidden\" name={name} value={current} /> : null}\n\n {open ? (\n <ul\n id={ids.list}\n className=\"vgui-select__list vgui-scroll-surface\"\n role=\"listbox\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {options.map((option, index) => (\n <li\n key={option.value}\n id={ids.option(index)}\n className=\"vgui-select__option\"\n role=\"option\"\n aria-selected={option.value === current}\n aria-disabled={option.disabled || undefined}\n data-active={index === active ? 'true' : undefined}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => choose(index)}\n >\n {option.label}\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n )\n})\n\nSelect.displayName = 'Select'\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Select/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
.vgui-slider {
|
|
2
|
+
/* The doc names these shorthand; the token layer spells the same metrics out. */
|
|
3
|
+
--vgui-slider-track-h: var(--vgui-slider-track-height);
|
|
4
|
+
--vgui-slider-thumb-w: var(--vgui-slider-thumb-width);
|
|
5
|
+
--vgui-slider-thumb-h: var(--vgui-slider-thumb-height);
|
|
6
|
+
--vgui-slider-tick-pitch: 19px;
|
|
7
|
+
|
|
8
|
+
position: relative;
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
width: 100%;
|
|
12
|
+
min-height: var(--vgui-min-target-size);
|
|
13
|
+
min-width: 200px;
|
|
14
|
+
padding-bottom: 12px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.vgui-slider__input {
|
|
18
|
+
width: 100%;
|
|
19
|
+
background: none;
|
|
20
|
+
appearance: none;
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
/* The range input has no text of its own; its only text is the attr() labels. */
|
|
23
|
+
color: var(--vgui-bevel-light-strong);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Endpoint labels, straight from the port: content: attr(min) / attr(max). */
|
|
27
|
+
.vgui-slider__input::before,
|
|
28
|
+
.vgui-slider__input::after {
|
|
29
|
+
position: absolute;
|
|
30
|
+
bottom: 0;
|
|
31
|
+
font-family: var(--vgui-font-mono);
|
|
32
|
+
font-size: var(--vgui-font-size-small);
|
|
33
|
+
line-height: 1;
|
|
34
|
+
pointer-events: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.vgui-slider__input::before {
|
|
38
|
+
left: 0;
|
|
39
|
+
content: attr(min);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.vgui-slider__input::after {
|
|
43
|
+
right: 0;
|
|
44
|
+
content: attr(max);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.vgui-slider__input:focus {
|
|
48
|
+
outline: none;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Draw the ring outside: a slider has no black interior to hide it in. */
|
|
52
|
+
.vgui-slider__input:focus-visible {
|
|
53
|
+
outline: var(--vgui-focus-ring);
|
|
54
|
+
outline-offset: 2px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.vgui-crisp .vgui-slider__input:focus-visible {
|
|
58
|
+
outline: var(--vgui-focus-ring-valve);
|
|
59
|
+
outline-offset: var(--vgui-focus-ring-valve-offset);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* The groove — INSET — with the port's 6px vertical margin. */
|
|
63
|
+
.vgui-slider__input::-webkit-slider-runnable-track {
|
|
64
|
+
height: var(--vgui-slider-track-h);
|
|
65
|
+
margin: 6px 0;
|
|
66
|
+
background-color: var(--vgui-field-bg);
|
|
67
|
+
border-top: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
68
|
+
border-bottom: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
69
|
+
border-left: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
70
|
+
border-right: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.vgui-slider__input::-moz-range-track,
|
|
74
|
+
.vgui-slider__input::-moz-range-progress {
|
|
75
|
+
height: var(--vgui-slider-track-h);
|
|
76
|
+
margin: 6px 0;
|
|
77
|
+
background-color: var(--vgui-field-bg);
|
|
78
|
+
border-top: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
79
|
+
border-bottom: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
80
|
+
border-left: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
81
|
+
border-right: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* The thumb — RAISED, centred with `top` (which moves the hit area too). */
|
|
85
|
+
.vgui-slider__input::-webkit-slider-thumb {
|
|
86
|
+
position: relative;
|
|
87
|
+
top: calc((var(--vgui-slider-thumb-h) - var(--vgui-slider-track-h)) / -2 - 1px);
|
|
88
|
+
box-sizing: border-box;
|
|
89
|
+
width: var(--vgui-slider-thumb-w);
|
|
90
|
+
height: var(--vgui-slider-thumb-h);
|
|
91
|
+
border-radius: 0;
|
|
92
|
+
background-color: var(--vgui-surface);
|
|
93
|
+
border-top: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
94
|
+
border-bottom: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
95
|
+
border-left: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
96
|
+
border-right: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
97
|
+
appearance: none;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Gecko centres its own thumb, so no `top` offset here. */
|
|
101
|
+
.vgui-slider__input::-moz-range-thumb {
|
|
102
|
+
box-sizing: border-box;
|
|
103
|
+
width: var(--vgui-slider-thumb-w);
|
|
104
|
+
height: var(--vgui-slider-thumb-h);
|
|
105
|
+
border-radius: 0;
|
|
106
|
+
background-color: var(--vgui-surface);
|
|
107
|
+
border-top: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
108
|
+
border-bottom: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
109
|
+
border-left: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
110
|
+
border-right: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* While dragged the thumb presses *into* the groove. */
|
|
114
|
+
.vgui-slider__input:active::-webkit-slider-thumb,
|
|
115
|
+
.vgui-slider__input:active::-moz-range-thumb {
|
|
116
|
+
border-top-color: var(--vgui-bevel-dark);
|
|
117
|
+
border-bottom-color: var(--vgui-bevel-light);
|
|
118
|
+
border-left-color: var(--vgui-bevel-dark);
|
|
119
|
+
border-right-color: var(--vgui-bevel-light);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* No disabled thumb treatment exists upstream; drop it into the panel. */
|
|
123
|
+
.vgui-slider__input:disabled::-webkit-slider-thumb,
|
|
124
|
+
.vgui-slider__input:disabled::-moz-range-thumb {
|
|
125
|
+
border-color: var(--vgui-surface-dark);
|
|
126
|
+
background-color: var(--vgui-surface-dark);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Ticks: the sliderticks tile is 19x5, positioned bottom-left +2px. */
|
|
130
|
+
.vgui-slider__input--ticks {
|
|
131
|
+
background-image: repeating-linear-gradient(
|
|
132
|
+
90deg,
|
|
133
|
+
var(--vgui-text-dim) 0 1px,
|
|
134
|
+
transparent 1px var(--vgui-slider-tick-pitch)
|
|
135
|
+
);
|
|
136
|
+
background-repeat: repeat-x;
|
|
137
|
+
background-position: bottom 2px left;
|
|
138
|
+
background-size: var(--vgui-slider-tick-pitch) 5px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.vgui-slider__value {
|
|
142
|
+
flex: none;
|
|
143
|
+
padding-left: var(--vgui-field-inset);
|
|
144
|
+
font-family: var(--vgui-font-mono);
|
|
145
|
+
font-size: var(--vgui-font-size-small);
|
|
146
|
+
line-height: 1;
|
|
147
|
+
color: var(--vgui-text);
|
|
148
|
+
text-align: right;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* 6x12 thumb, 3px track. */
|
|
152
|
+
.vgui-slider--small {
|
|
153
|
+
--vgui-slider-track-h: 3px;
|
|
154
|
+
--vgui-slider-thumb-w: 6px;
|
|
155
|
+
--vgui-slider-thumb-h: 12px;
|
|
156
|
+
|
|
157
|
+
min-width: 140px;
|
|
158
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { InputHTMLAttributes } from 'react';
|
|
2
|
+
import './Slider.css';
|
|
3
|
+
export interface SliderProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> {
|
|
4
|
+
/** Inclusive minimum. Defaults to 0. */
|
|
5
|
+
min?: number;
|
|
6
|
+
/** Inclusive maximum. Defaults to 100. */
|
|
7
|
+
max?: number;
|
|
8
|
+
/** Step increment. Defaults to 1. */
|
|
9
|
+
step?: number;
|
|
10
|
+
/** Controlled value. Omit to let the slider keep its own. */
|
|
11
|
+
value?: number;
|
|
12
|
+
/** Called continuously while dragging. */
|
|
13
|
+
onValueChange?: (value: number) => void;
|
|
14
|
+
/** Called once when the drag ends — use this for expensive work. */
|
|
15
|
+
onValueCommit?: (value: number) => void;
|
|
16
|
+
/** Draw the sliderticks groove marks. */
|
|
17
|
+
ticks?: boolean;
|
|
18
|
+
/** Show the current value in a readout after the slider. */
|
|
19
|
+
showValue?: boolean;
|
|
20
|
+
/** How to format `showValue`. Also feeds `aria-valuetext`. */
|
|
21
|
+
formatValue?: (value: number) => string;
|
|
22
|
+
/** Small variant for dense property rows. */
|
|
23
|
+
small?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare const Slider: import("react").ForwardRefExoticComponent<SliderProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
26
|
+
//# sourceMappingURL=Slider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../../src/components/Slider/Slider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,OAAO,CAAA;AAE7D,OAAO,cAAc,CAAA;AAErB,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/F,wCAAwC;IACxC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,0CAA0C;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,oEAAoE;IACpE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,4DAA4D;IAC5D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACvC,6CAA6C;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,eAAO,MAAM,MAAM,0GAmGjB,CAAA"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { forwardRef, useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import "./Slider.css";
|
|
4
|
+
//#region src/components/Slider/Slider.tsx
|
|
5
|
+
var Slider = forwardRef(function Slider({ className, min = 0, max = 100, step = 1, value, onValueChange, onValueCommit, ticks = false, showValue = false, formatValue, small = false, defaultValue, onChange, ...rest }, ref) {
|
|
6
|
+
const inputRef = useRef(null);
|
|
7
|
+
const [uncontrolledValue, setUncontrolledValue] = useState(() => defaultValue !== void 0 ? Number(defaultValue) : (min + max) / 2);
|
|
8
|
+
const currentValue = value !== void 0 ? value : uncontrolledValue;
|
|
9
|
+
const setRefs = useCallback((node) => {
|
|
10
|
+
inputRef.current = node;
|
|
11
|
+
if (typeof ref === "function") ref(node);
|
|
12
|
+
else if (ref) ref.current = node;
|
|
13
|
+
}, [ref]);
|
|
14
|
+
const commitRef = useRef(onValueCommit);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
commitRef.current = onValueCommit;
|
|
17
|
+
});
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const input = inputRef.current;
|
|
20
|
+
if (!input) return void 0;
|
|
21
|
+
const handleNativeChange = () => {
|
|
22
|
+
const commit = commitRef.current;
|
|
23
|
+
if (commit) commit(Number(input.value));
|
|
24
|
+
};
|
|
25
|
+
input.addEventListener("change", handleNativeChange);
|
|
26
|
+
return () => input.removeEventListener("change", handleNativeChange);
|
|
27
|
+
}, []);
|
|
28
|
+
const handleChange = (event) => {
|
|
29
|
+
const next = Number(event.currentTarget.value);
|
|
30
|
+
if (value === void 0) setUncontrolledValue(next);
|
|
31
|
+
onValueChange?.(next);
|
|
32
|
+
onChange?.(event);
|
|
33
|
+
};
|
|
34
|
+
const rootClasses = ["vgui-slider"];
|
|
35
|
+
if (small) rootClasses.push("vgui-slider--small");
|
|
36
|
+
if (showValue) rootClasses.push("vgui-slider--with-value");
|
|
37
|
+
if (className) rootClasses.push(className);
|
|
38
|
+
const inputClasses = ["vgui-slider__input"];
|
|
39
|
+
if (ticks) inputClasses.push("vgui-slider__input--ticks");
|
|
40
|
+
const readout = formatValue ? formatValue(currentValue) : String(currentValue);
|
|
41
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
42
|
+
className: rootClasses.join(" "),
|
|
43
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
44
|
+
ref: setRefs,
|
|
45
|
+
className: inputClasses.join(" "),
|
|
46
|
+
"aria-valuemin": min,
|
|
47
|
+
"aria-valuemax": max,
|
|
48
|
+
"aria-valuetext": formatValue ? readout : void 0,
|
|
49
|
+
...rest,
|
|
50
|
+
type: "range",
|
|
51
|
+
min,
|
|
52
|
+
max,
|
|
53
|
+
step,
|
|
54
|
+
value: currentValue,
|
|
55
|
+
onChange: handleChange
|
|
56
|
+
}), showValue ? /* @__PURE__ */ jsx("span", {
|
|
57
|
+
className: "vgui-slider__value",
|
|
58
|
+
"aria-hidden": "true",
|
|
59
|
+
children: readout
|
|
60
|
+
}) : null]
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
Slider.displayName = "Slider";
|
|
64
|
+
//#endregion
|
|
65
|
+
export { Slider };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=Slider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Slider.js","names":[],"sources":["../../../src/components/Slider/Slider.tsx"],"sourcesContent":["import { forwardRef, useCallback, useEffect, useRef, useState } from 'react'\nimport type { ChangeEvent, InputHTMLAttributes } from 'react'\n\nimport './Slider.css'\n\nexport interface SliderProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> {\n /** Inclusive minimum. Defaults to 0. */\n min?: number\n /** Inclusive maximum. Defaults to 100. */\n max?: number\n /** Step increment. Defaults to 1. */\n step?: number\n /** Controlled value. Omit to let the slider keep its own. */\n value?: number\n /** Called continuously while dragging. */\n onValueChange?: (value: number) => void\n /** Called once when the drag ends — use this for expensive work. */\n onValueCommit?: (value: number) => void\n /** Draw the sliderticks groove marks. */\n ticks?: boolean\n /** Show the current value in a readout after the slider. */\n showValue?: boolean\n /** How to format `showValue`. Also feeds `aria-valuetext`. */\n formatValue?: (value: number) => string\n /** Small variant for dense property rows. */\n small?: boolean\n}\n\nexport const Slider = forwardRef<HTMLInputElement, SliderProps>(function Slider(\n {\n className,\n min = 0,\n max = 100,\n step = 1,\n value,\n onValueChange,\n onValueCommit,\n ticks = false,\n showValue = false,\n formatValue,\n small = false,\n defaultValue,\n onChange,\n ...rest\n },\n ref,\n) {\n const inputRef = useRef<HTMLInputElement>(null)\n const [uncontrolledValue, setUncontrolledValue] = useState(() =>\n defaultValue !== undefined ? Number(defaultValue) : (min + max) / 2,\n )\n const currentValue = value !== undefined ? value : uncontrolledValue\n\n const setRefs = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node\n if (typeof ref === 'function') {\n ref(node)\n } else if (ref) {\n ref.current = node\n }\n },\n [ref],\n )\n\n // Stays current without re-subscribing the native listener on every render.\n const commitRef = useRef(onValueCommit)\n useEffect(() => {\n commitRef.current = onValueCommit\n })\n\n /*\n * React's `onChange` on a range input *is* the native `input` event, so the\n * commit half is read straight off the native `change` event instead.\n */\n useEffect(() => {\n const input = inputRef.current\n if (!input) return undefined\n const handleNativeChange = () => {\n const commit = commitRef.current\n if (commit) commit(Number(input.value))\n }\n input.addEventListener('change', handleNativeChange)\n return () => input.removeEventListener('change', handleNativeChange)\n }, [])\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const next = Number(event.currentTarget.value)\n if (value === undefined) setUncontrolledValue(next)\n onValueChange?.(next)\n onChange?.(event)\n }\n\n const rootClasses = ['vgui-slider']\n if (small) rootClasses.push('vgui-slider--small')\n if (showValue) rootClasses.push('vgui-slider--with-value')\n if (className) rootClasses.push(className)\n\n const inputClasses = ['vgui-slider__input']\n if (ticks) inputClasses.push('vgui-slider__input--ticks')\n\n const readout = formatValue ? formatValue(currentValue) : String(currentValue)\n\n return (\n <span className={rootClasses.join(' ')}>\n <input\n ref={setRefs}\n className={inputClasses.join(' ')}\n /* Explicit so the painted `attr()` labels match what is announced. */\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={formatValue ? readout : undefined}\n {...rest}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={currentValue}\n onChange={handleChange}\n />\n {showValue ? (\n <span className=\"vgui-slider__value\" aria-hidden=\"true\">\n {readout}\n </span>\n ) : null}\n </span>\n )\n})\n\nSlider.displayName = 'Slider'\n"],"mappings":";;;;AA4BA,IAAa,SAAS,WAA0C,SAAS,OACvE,EACE,WACA,MAAM,GACN,MAAM,KACN,OAAO,GACP,OACA,eACA,eACA,QAAQ,OACR,YAAY,OACZ,aACA,QAAQ,OACR,cACA,UACA,GAAG,QAEL,KACA;CACA,MAAM,WAAW,OAAyB,IAAI;CAC9C,MAAM,CAAC,mBAAmB,wBAAwB,eAChD,iBAAiB,KAAA,IAAY,OAAO,YAAY,KAAK,MAAM,OAAO,CACpE;CACA,MAAM,eAAe,UAAU,KAAA,IAAY,QAAQ;CAEnD,MAAM,UAAU,aACb,SAAkC;EACjC,SAAS,UAAU;EACnB,IAAI,OAAO,QAAQ,YACjB,IAAI,IAAI;OACH,IAAI,KACT,IAAI,UAAU;CAElB,GACA,CAAC,GAAG,CACN;CAGA,MAAM,YAAY,OAAO,aAAa;CACtC,gBAAgB;EACd,UAAU,UAAU;CACtB,CAAC;CAMD,gBAAgB;EACd,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,OAAO,OAAO,KAAA;EACnB,MAAM,2BAA2B;GAC/B,MAAM,SAAS,UAAU;GACzB,IAAI,QAAQ,OAAO,OAAO,MAAM,KAAK,CAAC;EACxC;EACA,MAAM,iBAAiB,UAAU,kBAAkB;EACnD,aAAa,MAAM,oBAAoB,UAAU,kBAAkB;CACrE,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAgB,UAAyC;EAC7D,MAAM,OAAO,OAAO,MAAM,cAAc,KAAK;EAC7C,IAAI,UAAU,KAAA,GAAW,qBAAqB,IAAI;EAClD,gBAAgB,IAAI;EACpB,WAAW,KAAK;CAClB;CAEA,MAAM,cAAc,CAAC,aAAa;CAClC,IAAI,OAAO,YAAY,KAAK,oBAAoB;CAChD,IAAI,WAAW,YAAY,KAAK,yBAAyB;CACzD,IAAI,WAAW,YAAY,KAAK,SAAS;CAEzC,MAAM,eAAe,CAAC,oBAAoB;CAC1C,IAAI,OAAO,aAAa,KAAK,2BAA2B;CAExD,MAAM,UAAU,cAAc,YAAY,YAAY,IAAI,OAAO,YAAY;CAE7E,OACE,qBAAC,QAAD;EAAM,WAAW,YAAY,KAAK,GAAG;EAArC,UAAA,CACE,oBAAC,SAAD;GACE,KAAK;GACL,WAAW,aAAa,KAAK,GAAG;GAEhC,iBAAe;GACf,iBAAe;GACf,kBAAgB,cAAc,UAAU,KAAA;GACxC,GAAI;GACJ,MAAK;GACA;GACA;GACC;GACN,OAAO;GACP,UAAU;EACX,CAAA,GACA,YACC,oBAAC,QAAD;GAAM,WAAU;GAAqB,eAAY;GAC9C,UAAA;EACG,CAAA,IACJ,IACA;;AAEV,CAAC;AAED,OAAO,cAAc"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Slider/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA"}
|