@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
package/README.md
CHANGED
|
@@ -103,7 +103,7 @@ own `index.ts` **and** from `src/index.ts`, and add a story next to it.
|
|
|
103
103
|
|
|
104
104
|
| Workflow | Trigger | What it does |
|
|
105
105
|
| --- | --- | --- |
|
|
106
|
-
| `.github/workflows/ci.yml` | push to `main`, PRs | Typechecks, builds the library and Storybook
|
|
106
|
+
| `.github/workflows/ci.yml` | push to `main`, PRs | Typechecks, builds the library and Storybook. |
|
|
107
107
|
| `.github/workflows/pages.yml` | push to `main` | Builds Storybook and deploys it to GitHub Pages. |
|
|
108
108
|
| `.github/workflows/release.yml` | **CI** finishing successfully on `main` | Opens/updates the *“chore: version packages”* PR, then publishes to npm **with provenance** and creates the GitHub release once that PR is merged. Never runs on a plain push, so a red CI run cannot release. |
|
|
109
109
|
|
|
@@ -154,10 +154,25 @@ version published by hand, before trusted publishing existed.
|
|
|
154
154
|
*Allow GitHub Actions to create and approve pull requests***, otherwise the
|
|
155
155
|
workflow cannot open the “chore: version packages” pull request.
|
|
156
156
|
|
|
157
|
-
> **Note:**
|
|
158
|
-
>
|
|
159
|
-
>
|
|
160
|
-
>
|
|
157
|
+
> **Note:** the “chore: version packages” PR is opened with the default
|
|
158
|
+
> `GITHUB_TOKEN`, which normally suppresses downstream workflows — but once
|
|
159
|
+
> **Allow GitHub Actions to create and approve pull requests** is enabled, that
|
|
160
|
+
> PR *does* trigger CI. It is therefore safe to require CI as a status check on
|
|
161
|
+
> `main`.
|
|
162
|
+
|
|
163
|
+
### Release safeguards
|
|
164
|
+
|
|
165
|
+
* `release.yml` cannot release code CI has not validated, and it cannot be
|
|
166
|
+
triggered by a non-admin: the first step re-reads the triggering actor's role
|
|
167
|
+
from the collaborators API and fails unless it is `admin`. Both the automatic
|
|
168
|
+
`workflow_run` and a manual `workflow_dispatch` go through the same check, so a
|
|
169
|
+
contributor with write access can merge code but never cause a publish.
|
|
170
|
+
* `.github/CODEOWNERS` names `@Dalcvi` as the owner of everything, with explicit
|
|
171
|
+
entries for `release.yml` and `.changeset/`. Code ownership only becomes a gate
|
|
172
|
+
once a branch ruleset turns on **Require review from Code Owners**.
|
|
173
|
+
* PR titles must follow
|
|
174
|
+
[Conventional Commits](https://www.conventionalcommits.org) — see
|
|
175
|
+
`.github/copilot-instructions.md`.
|
|
161
176
|
|
|
162
177
|
## Credits
|
|
163
178
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Green Steam avatar — the client-only `AvatarImage` of the friends panel and
|
|
3
|
+
* the account button (docs/components/Avatar.md).
|
|
4
|
+
*
|
|
5
|
+
* The avatar itself has no `steam.styles` block: it paints a bitmap, so there is
|
|
6
|
+
* nothing to transcribe except the placeholder colour `Friends.NoAvatarOver`
|
|
7
|
+
* (`steam.styles:361`) and the neighbouring friends-list tokens. The frame is a
|
|
8
|
+
* library construction consistent with `Panel`; the status ring is a library
|
|
9
|
+
* construction with no corpus artwork behind it.
|
|
10
|
+
*
|
|
11
|
+
* No artwork is shipped: the placeholder is drawn as `::after` content.
|
|
12
|
+
*
|
|
13
|
+
* Component-local metrics are declared here per foundations.md §4; shared
|
|
14
|
+
* palette tokens are referenced bare.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
.vgui-avatar {
|
|
18
|
+
--vgui-avatar-size: 42px;
|
|
19
|
+
--vgui-avatar-status-size: 2px;
|
|
20
|
+
--vgui-avatar-frame-width: 1px;
|
|
21
|
+
|
|
22
|
+
position: relative;
|
|
23
|
+
box-sizing: border-box;
|
|
24
|
+
display: inline-grid;
|
|
25
|
+
place-items: center;
|
|
26
|
+
flex: none;
|
|
27
|
+
/* The frame owns the size, so the space is reserved before the image exists
|
|
28
|
+
and a late avatar cannot shift the layout. */
|
|
29
|
+
inline-size: var(--vgui-avatar-size);
|
|
30
|
+
block-size: var(--vgui-avatar-size);
|
|
31
|
+
padding: var(--vgui-avatar-frame-width);
|
|
32
|
+
/* Square: the theme has no round mask anywhere, and VGUI-era avatars are not
|
|
33
|
+
round. `--round` is offered for completeness only. */
|
|
34
|
+
border-radius: 0;
|
|
35
|
+
border-block-start: var(--vgui-avatar-frame-width) solid var(--vgui-bevel-light);
|
|
36
|
+
border-inline-start: var(--vgui-avatar-frame-width) solid var(--vgui-bevel-light);
|
|
37
|
+
border-block-end: var(--vgui-avatar-frame-width) solid var(--vgui-bevel-dark);
|
|
38
|
+
border-inline-end: var(--vgui-avatar-frame-width) solid var(--vgui-bevel-dark);
|
|
39
|
+
background-color: var(--vgui-surface-dark);
|
|
40
|
+
overflow: hidden;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.vgui-avatar__image {
|
|
44
|
+
inline-size: 100%;
|
|
45
|
+
block-size: 100%;
|
|
46
|
+
/* Centre-crop: a non-square upload must never letterbox in a square frame. */
|
|
47
|
+
object-fit: cover;
|
|
48
|
+
object-position: center;
|
|
49
|
+
display: block;
|
|
50
|
+
/* `theme.css` ships a global `img { object-fit: contain; margin: 2px; border:
|
|
51
|
+
solid 2px var(--vgui-bevel-light) }`. The frame above owns the bevel and the
|
|
52
|
+
size, so the inherited margin and border are cancelled — the grey inherited
|
|
53
|
+
border is 1.66:1 on `--vgui-surface` and 2.30:1 on `--vgui-surface-dark`,
|
|
54
|
+
under the 3:1 WCAG 1.4.11 asks of a boundary.
|
|
55
|
+
`image-rendering: pixelated` is deliberately *not* set here: it is part of
|
|
56
|
+
the `.vgui-crisp` opt-in (theme.css) and inherits from it, because forcing
|
|
57
|
+
it overrides the user's own rendering preference. */
|
|
58
|
+
border: 0;
|
|
59
|
+
margin: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* The no-avatar state: a white glyph over the box, `Friends.NoAvatarOver`. */
|
|
63
|
+
.vgui-avatar--placeholder .vgui-avatar__image,
|
|
64
|
+
.vgui-avatar__image[data-failed='true'] {
|
|
65
|
+
visibility: hidden;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.vgui-avatar--placeholder::after {
|
|
69
|
+
content: attr(data-initials);
|
|
70
|
+
position: absolute;
|
|
71
|
+
inset: 0;
|
|
72
|
+
display: grid;
|
|
73
|
+
place-items: center;
|
|
74
|
+
font: inherit;
|
|
75
|
+
font-size: calc(var(--vgui-avatar-size) * 0.4);
|
|
76
|
+
line-height: 1;
|
|
77
|
+
color: var(--vgui-text-strong);
|
|
78
|
+
background-color: var(--vgui-surface-dark);
|
|
79
|
+
text-transform: uppercase;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* `accountbutton.layout:179` and `FriendOnlineNotification.res:26`. */
|
|
83
|
+
.vgui-avatar--sm {
|
|
84
|
+
--vgui-avatar-size: 24px;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.vgui-avatar--md {
|
|
88
|
+
--vgui-avatar-size: 42px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* A library extension: no large avatar exists in this resource set. */
|
|
92
|
+
.vgui-avatar--lg {
|
|
93
|
+
--vgui-avatar-size: 64px;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Picture alone, no chrome. */
|
|
97
|
+
.vgui-avatar--bare {
|
|
98
|
+
border: 0;
|
|
99
|
+
padding: 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.vgui-avatar--round,
|
|
103
|
+
.vgui-avatar--round .vgui-avatar__status {
|
|
104
|
+
border-radius: 50%;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* The status ring: a 2px frame edge, not a corner pip and not a filled badge.
|
|
108
|
+
Decorative by construction — presence is carried by the row's text. */
|
|
109
|
+
.vgui-avatar__status {
|
|
110
|
+
position: absolute;
|
|
111
|
+
inset: 0;
|
|
112
|
+
border: var(--vgui-avatar-status-size) solid var(--vgui-text-dim);
|
|
113
|
+
pointer-events: none;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.vgui-avatar__status--online {
|
|
117
|
+
border-color: var(--vgui-steam-green); /* FullGreen */
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.vgui-avatar__status--away {
|
|
121
|
+
border-color: var(--vgui-heading);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.vgui-avatar__status--busy {
|
|
125
|
+
border-color: var(--vgui-danger);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.vgui-avatar__status--offline {
|
|
129
|
+
border-color: var(--vgui-text-dim);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* The friends list is its own visual world: `IgnoredColor` is not a list token.
|
|
133
|
+
A tinted frame, never a desaturated face. */
|
|
134
|
+
.vgui-avatar--ignored {
|
|
135
|
+
border-color: var(--vgui-friends-ignored);
|
|
136
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
import './Avatar.css';
|
|
3
|
+
export interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {
|
|
4
|
+
/** Image URL. Omit to render the placeholder. */
|
|
5
|
+
src?: string;
|
|
6
|
+
/** Alt text — the person's name. Pass "" when a name is already adjacent. */
|
|
7
|
+
alt?: string;
|
|
8
|
+
/** Size presets. `sm` is 24px (account chrome), `md` 42px (notifications). */
|
|
9
|
+
size?: 'sm' | 'md' | 'lg';
|
|
10
|
+
/** Derive initials from a name and show them when there is no image. */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** Presence indicator drawn as a 2px frame edge. */
|
|
13
|
+
status?: 'online' | 'away' | 'busy' | 'offline';
|
|
14
|
+
/** Tint the frame for an ignored friend. */
|
|
15
|
+
ignored?: boolean;
|
|
16
|
+
/** Drop the beveled frame; draw the picture alone. */
|
|
17
|
+
bare?: boolean;
|
|
18
|
+
/** Round the corners. Not period-accurate; offered for completeness only. */
|
|
19
|
+
round?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare const Avatar: import("react").ForwardRefExoticComponent<AvatarProps & import("react").RefAttributes<HTMLSpanElement>>;
|
|
22
|
+
//# sourceMappingURL=Avatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/components/Avatar/Avatar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAqC,MAAM,OAAO,CAAA;AAE9E,OAAO,cAAc,CAAA;AAErB,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,eAAe,CAAC;IAClE,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,8EAA8E;IAC9E,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC/C,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sDAAsD;IACtD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAkBD,eAAO,MAAM,MAAM,yGA0DjB,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { forwardRef, useState } from "react";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import "./Avatar.css";
|
|
4
|
+
//#region src/components/Avatar/Avatar.tsx
|
|
5
|
+
/**
|
|
6
|
+
* At most two initials, one per name part: "dave coder" → `dc`, "dalcvi" → `d`.
|
|
7
|
+
* The `::after` rule uppercases them, so the case of the name is preserved here.
|
|
8
|
+
*/
|
|
9
|
+
function initialsOf(name) {
|
|
10
|
+
if (name === void 0) return "";
|
|
11
|
+
const words = name.trim().split(/\s+/).filter((word) => word !== "");
|
|
12
|
+
return `${words[0]?.charAt(0) ?? ""}${(words.length > 1 ? words.at(-1) : void 0)?.charAt(0) ?? ""}`;
|
|
13
|
+
}
|
|
14
|
+
var Avatar = forwardRef(function Avatar({ className, src, alt = "", size = "md", name, status, ignored = false, bare = false, round = false, onError, ...rest }, ref) {
|
|
15
|
+
const [failed, setFailed] = useState(false);
|
|
16
|
+
const placeholder = !src || failed;
|
|
17
|
+
const classes = ["vgui-avatar", `vgui-avatar--${size}`];
|
|
18
|
+
if (placeholder) classes.push("vgui-avatar--placeholder");
|
|
19
|
+
if (status) classes.push("vgui-avatar--status");
|
|
20
|
+
if (ignored) classes.push("vgui-avatar--ignored");
|
|
21
|
+
if (bare) classes.push("vgui-avatar--bare");
|
|
22
|
+
if (round) classes.push("vgui-avatar--round");
|
|
23
|
+
if (className) classes.push(className);
|
|
24
|
+
const handleError = (event) => {
|
|
25
|
+
setFailed(true);
|
|
26
|
+
onError?.(event);
|
|
27
|
+
};
|
|
28
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
29
|
+
ref,
|
|
30
|
+
className: classes.join(" "),
|
|
31
|
+
"data-initials": initialsOf(name),
|
|
32
|
+
...rest,
|
|
33
|
+
children: [src ? /* @__PURE__ */ jsx("img", {
|
|
34
|
+
className: "vgui-avatar__image",
|
|
35
|
+
src,
|
|
36
|
+
alt,
|
|
37
|
+
"data-failed": failed || void 0,
|
|
38
|
+
onError: handleError
|
|
39
|
+
}) : null, status ? /* @__PURE__ */ jsx("span", {
|
|
40
|
+
className: `vgui-avatar__status vgui-avatar__status--${status}`,
|
|
41
|
+
"aria-hidden": "true"
|
|
42
|
+
}) : null]
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
Avatar.displayName = "Avatar";
|
|
46
|
+
//#endregion
|
|
47
|
+
export { Avatar };
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=Avatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Avatar.js","names":[],"sources":["../../../src/components/Avatar/Avatar.tsx"],"sourcesContent":["import { forwardRef, useState } from 'react'\nimport type { HTMLAttributes, ReactEventHandler, SyntheticEvent } from 'react'\n\nimport './Avatar.css'\n\nexport interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {\n /** Image URL. Omit to render the placeholder. */\n src?: string\n /** Alt text — the person's name. Pass \"\" when a name is already adjacent. */\n alt?: string\n /** Size presets. `sm` is 24px (account chrome), `md` 42px (notifications). */\n size?: 'sm' | 'md' | 'lg'\n /** Derive initials from a name and show them when there is no image. */\n name?: string\n /** Presence indicator drawn as a 2px frame edge. */\n status?: 'online' | 'away' | 'busy' | 'offline'\n /** Tint the frame for an ignored friend. */\n ignored?: boolean\n /** Drop the beveled frame; draw the picture alone. */\n bare?: boolean\n /** Round the corners. Not period-accurate; offered for completeness only. */\n round?: boolean\n}\n\n/**\n * At most two initials, one per name part: \"dave coder\" → `dc`, \"dalcvi\" → `d`.\n * The `::after` rule uppercases them, so the case of the name is preserved here.\n */\nfunction initialsOf(name: string | undefined): string {\n if (name === undefined) return ''\n\n const words = name.trim().split(/\\s+/).filter((word) => word !== '')\n\n const first = words[0]?.charAt(0) ?? ''\n const lastWord = words.length > 1 ? words.at(-1) : undefined\n const last = lastWord?.charAt(0) ?? ''\n\n return `${first}${last}`\n}\n\nexport const Avatar = forwardRef<HTMLSpanElement, AvatarProps>(function Avatar(\n {\n className,\n src,\n alt = '',\n size = 'md',\n name,\n status,\n ignored = false,\n bare = false,\n round = false,\n onError,\n ...rest\n },\n ref,\n) {\n const [failed, setFailed] = useState(false)\n // A missing source and a failed load are the same state: the durable\n // placeholder, never a broken-image icon.\n const placeholder = !src || failed\n\n const classes = ['vgui-avatar', `vgui-avatar--${size}`]\n if (placeholder) classes.push('vgui-avatar--placeholder')\n if (status) classes.push('vgui-avatar--status')\n if (ignored) classes.push('vgui-avatar--ignored')\n if (bare) classes.push('vgui-avatar--bare')\n if (round) classes.push('vgui-avatar--round')\n if (className) classes.push(className)\n\n const handleError: ReactEventHandler<HTMLImageElement> = (event) => {\n setFailed(true)\n onError?.(event as unknown as SyntheticEvent<HTMLSpanElement>)\n }\n\n return (\n <span\n ref={ref}\n className={classes.join(' ')}\n data-initials={initialsOf(name)}\n {...rest}\n >\n {src ? (\n <img\n className=\"vgui-avatar__image\"\n src={src}\n alt={alt}\n data-failed={failed || undefined}\n onError={handleError}\n />\n ) : null}\n {status ? (\n <span\n className={`vgui-avatar__status vgui-avatar__status--${status}`}\n aria-hidden=\"true\"\n />\n ) : null}\n </span>\n )\n})\n\nAvatar.displayName = 'Avatar'\n"],"mappings":";;;;;;;;AA4BA,SAAS,WAAW,MAAkC;CACpD,IAAI,SAAS,KAAA,GAAW,OAAO;CAE/B,MAAM,QAAQ,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,QAAQ,SAAS,SAAS,EAAE;CAMnE,OAAO,GAJO,MAAM,EAAE,EAAE,OAAO,CAAC,KAAK,MACpB,MAAM,SAAS,IAAI,MAAM,GAAG,EAAE,IAAI,KAAA,EAAA,EAC5B,OAAO,CAAC,KAAK;AAGtC;AAEA,IAAa,SAAS,WAAyC,SAAS,OACtE,EACE,WACA,KACA,MAAM,IACN,OAAO,MACP,MACA,QACA,UAAU,OACV,OAAO,OACP,QAAQ,OACR,SACA,GAAG,QAEL,KACA;CACA,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAG1C,MAAM,cAAc,CAAC,OAAO;CAE5B,MAAM,UAAU,CAAC,eAAe,gBAAgB,MAAM;CACtD,IAAI,aAAa,QAAQ,KAAK,0BAA0B;CACxD,IAAI,QAAQ,QAAQ,KAAK,qBAAqB;CAC9C,IAAI,SAAS,QAAQ,KAAK,sBAAsB;CAChD,IAAI,MAAM,QAAQ,KAAK,mBAAmB;CAC1C,IAAI,OAAO,QAAQ,KAAK,oBAAoB;CAC5C,IAAI,WAAW,QAAQ,KAAK,SAAS;CAErC,MAAM,eAAoD,UAAU;EAClE,UAAU,IAAI;EACd,UAAU,KAAmD;CAC/D;CAEA,OACE,qBAAC,QAAD;EACO;EACL,WAAW,QAAQ,KAAK,GAAG;EAC3B,iBAAe,WAAW,IAAI;EAC9B,GAAI;EAJN,UAAA,CAMG,MACC,oBAAC,OAAD;GACE,WAAU;GACL;GACA;GACL,eAAa,UAAU,KAAA;GACvB,SAAS;EACV,CAAA,IACC,MACH,SACC,oBAAC,QAAD;GACE,WAAW,4CAA4C;GACvD,eAAY;EACb,CAAA,IACC,IACA;;AAEV,CAAC;AAED,OAAO,cAAc"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Avatar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Green Steam button.
|
|
3
|
+
*
|
|
4
|
+
* A 25px rectangle with a two-tone 1px bevel that inverts when pressed. Two
|
|
5
|
+
* details do the heavy lifting and are easy to get wrong (docs/components/Button.md):
|
|
6
|
+
*
|
|
7
|
+
* 1. The label is LEFT-aligned with a 4px inset (`inset "4 0 0 0"`), never centred.
|
|
8
|
+
* 2. There is no `:hover` treatment. `steam.styles` defines no `Button:MouseOver`
|
|
9
|
+
* border, so the only affordance is `cursor: pointer`.
|
|
10
|
+
*
|
|
11
|
+
* Two explicit deviations from the CSS port, both required by WCAG: `min-height`
|
|
12
|
+
* rather than `height` so text survives 200% zoom (1.4.4), and a real 24px hit
|
|
13
|
+
* area on `--small` (2.5.8).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
.vgui-button {
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
display: inline-flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: flex-start;
|
|
21
|
+
min-height: var(--vgui-control-height);
|
|
22
|
+
min-width: var(--vgui-button-min-width);
|
|
23
|
+
padding: 0 8px 0 var(--vgui-field-inset);
|
|
24
|
+
font: inherit;
|
|
25
|
+
font-weight: lighter;
|
|
26
|
+
text-align: left;
|
|
27
|
+
color: var(--vgui-text-strong);
|
|
28
|
+
background-color: var(--vgui-surface);
|
|
29
|
+
border-top: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
30
|
+
border-left: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
31
|
+
border-bottom: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
32
|
+
border-right: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
33
|
+
cursor: pointer;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Active INVERTS the bevel. It does not translate the button. */
|
|
37
|
+
.vgui-button:active {
|
|
38
|
+
border-top-color: var(--vgui-bevel-dark);
|
|
39
|
+
border-left-color: var(--vgui-bevel-dark);
|
|
40
|
+
border-bottom-color: var(--vgui-bevel-light);
|
|
41
|
+
border-right-color: var(--vgui-bevel-light);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/*
|
|
45
|
+
* Valve's literal ring (`1px dashed BorderDark`) measures 1.87:1 against the
|
|
46
|
+
* button face, so the visible accent ring is the default and the faithful one
|
|
47
|
+
* is reachable through the `.vgui-crisp` opt-in — the same switch that turns on
|
|
48
|
+
* bitmap text rendering (docs/foundations.md §5).
|
|
49
|
+
*/
|
|
50
|
+
.vgui-button:focus-visible {
|
|
51
|
+
outline: var(--vgui-focus-ring);
|
|
52
|
+
outline-offset: var(--vgui-focus-ring-offset);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.vgui-crisp .vgui-button:focus-visible {
|
|
56
|
+
outline: var(--vgui-focus-ring-valve);
|
|
57
|
+
outline-offset: var(--vgui-focus-ring-valve-offset);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
* DisabledText1 is drawn at +1px +1px underneath DisabledText2, so the label
|
|
62
|
+
* looks pressed into the surface. Reproduced with `text-shadow`, not two
|
|
63
|
+
* elements. The colour alone is 1.82:1, so the cursor carries the rest.
|
|
64
|
+
*/
|
|
65
|
+
.vgui-button:disabled {
|
|
66
|
+
cursor: not-allowed;
|
|
67
|
+
color: var(--vgui-text-disabled);
|
|
68
|
+
text-shadow: 1px 1px 0 var(--vgui-text-disabled-shadow);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.vgui-button--full-width {
|
|
72
|
+
display: flex;
|
|
73
|
+
width: 100%;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.vgui-button--small {
|
|
77
|
+
position: relative;
|
|
78
|
+
min-height: 18px;
|
|
79
|
+
min-width: 60px;
|
|
80
|
+
font-size: var(--vgui-font-size-small);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* An 18px control is below the 24px minimum target, so --small grows its hit
|
|
84
|
+
* area without changing its painted size. */
|
|
85
|
+
.vgui-button--small::after {
|
|
86
|
+
content: '';
|
|
87
|
+
position: absolute;
|
|
88
|
+
inset: 50% 0 auto;
|
|
89
|
+
height: var(--vgui-min-target-size);
|
|
90
|
+
transform: translateY(-50%);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.vgui-button--large {
|
|
94
|
+
min-height: 30px;
|
|
95
|
+
font-size: var(--vgui-font-size-large);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* VGUI has no primary/secondary hierarchy; this is an emphasis hook only. */
|
|
99
|
+
.vgui-button--primary {
|
|
100
|
+
font-weight: bold;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.vgui-button--danger {
|
|
104
|
+
outline: var(--vgui-bevel-width) solid var(--vgui-danger);
|
|
105
|
+
outline-offset: -2px;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.vgui-button--clay {
|
|
109
|
+
background-color: var(--vgui-clay-button);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.vgui-button__label {
|
|
113
|
+
min-width: 0;
|
|
114
|
+
overflow: hidden;
|
|
115
|
+
text-overflow: ellipsis;
|
|
116
|
+
white-space: nowrap;
|
|
117
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes } from 'react';
|
|
2
|
+
import './Button.css';
|
|
3
|
+
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
4
|
+
/** Stretch the button across the full width of its container. */
|
|
5
|
+
fullWidth?: boolean;
|
|
6
|
+
/** Compact variant for dense chrome: 18px tall, 12px text. */
|
|
7
|
+
small?: boolean;
|
|
8
|
+
/** Taller variant for dialog footers: 30px tall, 16px text. */
|
|
9
|
+
large?: boolean;
|
|
10
|
+
/** Emphasis hook for a dialog's default action. Never a background fill. */
|
|
11
|
+
primary?: boolean;
|
|
12
|
+
/** Draw a danger outline around the button. */
|
|
13
|
+
danger?: boolean;
|
|
14
|
+
/** Render the grey property-sheet face instead of the green one. */
|
|
15
|
+
clay?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare const Button: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
18
|
+
//# sourceMappingURL=Button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAEjD,OAAO,cAAc,CAAA;AAErB,MAAM,WAAW,WAAY,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC1E,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,4EAA4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,oEAAoE;IACpE,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,eAAO,MAAM,MAAM,2GA6BjB,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import "./Button.css";
|
|
4
|
+
//#region src/components/Button/Button.tsx
|
|
5
|
+
var Button = forwardRef(function Button({ className, type = "button", fullWidth = false, small = false, large = false, primary = false, danger = false, clay = false, children, ...rest }, ref) {
|
|
6
|
+
const classes = ["vgui-button"];
|
|
7
|
+
if (fullWidth) classes.push("vgui-button--full-width");
|
|
8
|
+
if (small) classes.push("vgui-button--small");
|
|
9
|
+
if (large) classes.push("vgui-button--large");
|
|
10
|
+
if (primary) classes.push("vgui-button--primary");
|
|
11
|
+
if (danger) classes.push("vgui-button--danger");
|
|
12
|
+
if (clay) classes.push("vgui-button--clay");
|
|
13
|
+
if (className) classes.push(className);
|
|
14
|
+
return /* @__PURE__ */ jsx("button", {
|
|
15
|
+
ref,
|
|
16
|
+
type,
|
|
17
|
+
className: classes.join(" "),
|
|
18
|
+
...rest,
|
|
19
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
20
|
+
className: "vgui-button__label",
|
|
21
|
+
children
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
Button.displayName = "Button";
|
|
26
|
+
//#endregion
|
|
27
|
+
export { Button };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=Button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.js","names":[],"sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport type { ButtonHTMLAttributes } from 'react'\n\nimport './Button.css'\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Stretch the button across the full width of its container. */\n fullWidth?: boolean\n /** Compact variant for dense chrome: 18px tall, 12px text. */\n small?: boolean\n /** Taller variant for dialog footers: 30px tall, 16px text. */\n large?: boolean\n /** Emphasis hook for a dialog's default action. Never a background fill. */\n primary?: boolean\n /** Draw a danger outline around the button. */\n danger?: boolean\n /** Render the grey property-sheet face instead of the green one. */\n clay?: boolean\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n type = 'button',\n fullWidth = false,\n small = false,\n large = false,\n primary = false,\n danger = false,\n clay = false,\n children,\n ...rest\n },\n ref,\n) {\n const classes = ['vgui-button']\n if (fullWidth) classes.push('vgui-button--full-width')\n if (small) classes.push('vgui-button--small')\n if (large) classes.push('vgui-button--large')\n if (primary) classes.push('vgui-button--primary')\n if (danger) classes.push('vgui-button--danger')\n if (clay) classes.push('vgui-button--clay')\n if (className) classes.push(className)\n\n return (\n <button ref={ref} type={type} className={classes.join(' ')} {...rest}>\n <span className=\"vgui-button__label\">{children}</span>\n </button>\n )\n})\n\nButton.displayName = 'Button'\n"],"mappings":";;;;AAoBA,IAAa,SAAS,WAA2C,SAAS,OACxE,EACE,WACA,OAAO,UACP,YAAY,OACZ,QAAQ,OACR,QAAQ,OACR,UAAU,OACV,SAAS,OACT,OAAO,OACP,UACA,GAAG,QAEL,KACA;CACA,MAAM,UAAU,CAAC,aAAa;CAC9B,IAAI,WAAW,QAAQ,KAAK,yBAAyB;CACrD,IAAI,OAAO,QAAQ,KAAK,oBAAoB;CAC5C,IAAI,OAAO,QAAQ,KAAK,oBAAoB;CAC5C,IAAI,SAAS,QAAQ,KAAK,sBAAsB;CAChD,IAAI,QAAQ,QAAQ,KAAK,qBAAqB;CAC9C,IAAI,MAAM,QAAQ,KAAK,mBAAmB;CAC1C,IAAI,WAAW,QAAQ,KAAK,SAAS;CAErC,OACE,oBAAC,UAAD;EAAa;EAAW;EAAM,WAAW,QAAQ,KAAK,GAAG;EAAG,GAAI;EAC9D,UAAA,oBAAC,QAAD;GAAM,WAAU;GAAsB;EAAe,CAAA;CAC/C,CAAA;AAEZ,CAAC;AAED,OAAO,cAAc"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Button/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Green Steam checkbox.
|
|
3
|
+
*
|
|
4
|
+
* The signature detail is the **inverted** bevel: dark on top/left, light on
|
|
5
|
+
* bottom/right, so the box reads as a hole in the panel rather than a raised
|
|
6
|
+
* button (docs/components/Checkbox.md). Getting it the same way round as
|
|
7
|
+
* `.vgui-button` is the common mistake.
|
|
8
|
+
*
|
|
9
|
+
* The sprite set is replaced with CSS geometry — a rotated bordered box for
|
|
10
|
+
* `chkSelStd`, a filled rect for `chkIndeterminate` — so no assets ship.
|
|
11
|
+
*
|
|
12
|
+
* Deviations required by WCAG:
|
|
13
|
+
*
|
|
14
|
+
* - `chk*Focus`'s dotted `#000` inner rectangle is 1.15:1 on the box face, so
|
|
15
|
+
* the shipped ring is `--vgui-focus-ring` at the same `-3px` offset (the
|
|
16
|
+
* geometry still reads as VGUI); the literal ring is the `.vgui-crisp`
|
|
17
|
+
* opt-in.
|
|
18
|
+
* - The 15×15 box is below the 24×24 minimum target, so the whole row is the
|
|
19
|
+
* hit area: the control is wrapped in a `<label>`, exactly as VGUI's
|
|
20
|
+
* `labelTextOffset` made the label part of the clickable region.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
.vgui-checkbox {
|
|
24
|
+
display: inline-flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
gap: 3px;
|
|
27
|
+
font: inherit;
|
|
28
|
+
color: var(--vgui-text);
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Hidden but present and focusable — never `display: none`. */
|
|
33
|
+
.vgui-checkbox__input {
|
|
34
|
+
position: absolute;
|
|
35
|
+
inline-size: 1px;
|
|
36
|
+
block-size: 1px;
|
|
37
|
+
margin: -1px;
|
|
38
|
+
padding: 0;
|
|
39
|
+
overflow: hidden;
|
|
40
|
+
clip-path: inset(50%);
|
|
41
|
+
white-space: nowrap;
|
|
42
|
+
border: 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.vgui-checkbox__box {
|
|
46
|
+
position: relative;
|
|
47
|
+
flex: 0 0 auto;
|
|
48
|
+
box-sizing: border-box;
|
|
49
|
+
inline-size: var(--vgui-checkbox-size);
|
|
50
|
+
block-size: var(--vgui-checkbox-size);
|
|
51
|
+
background-color: var(--vgui-surface);
|
|
52
|
+
border-top: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
53
|
+
border-left: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
|
|
54
|
+
border-bottom: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
55
|
+
border-right: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* `chkSelStd` as two borders on a rotated box: a shape, not a colour signal. */
|
|
59
|
+
.vgui-checkbox__input:checked ~ .vgui-checkbox__box::after {
|
|
60
|
+
content: '';
|
|
61
|
+
position: absolute;
|
|
62
|
+
left: 4px;
|
|
63
|
+
top: 1px;
|
|
64
|
+
inline-size: 5px;
|
|
65
|
+
block-size: 8px;
|
|
66
|
+
border-right: 2px solid var(--vgui-text-strong);
|
|
67
|
+
border-bottom: 2px solid var(--vgui-text-strong);
|
|
68
|
+
transform: rotate(45deg);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/*
|
|
72
|
+
* `chkIndeterminate` is a horizontal bar. It is easy to miss on its own, which
|
|
73
|
+
* is why the real input carries the state and announces "mixed".
|
|
74
|
+
*/
|
|
75
|
+
.vgui-checkbox__input:indeterminate ~ .vgui-checkbox__box::after {
|
|
76
|
+
content: '';
|
|
77
|
+
position: absolute;
|
|
78
|
+
left: 2px;
|
|
79
|
+
top: 5px;
|
|
80
|
+
inline-size: 9px;
|
|
81
|
+
block-size: 3px;
|
|
82
|
+
background-color: var(--vgui-text-strong);
|
|
83
|
+
transform: none;
|
|
84
|
+
border: 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.vgui-checkbox__input:focus-visible ~ .vgui-checkbox__box {
|
|
88
|
+
outline: var(--vgui-focus-ring);
|
|
89
|
+
outline-offset: var(--vgui-focus-ring-offset);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Valve's literal `chk*Focus` ring, reachable only through the opt-in. */
|
|
93
|
+
.vgui-crisp .vgui-checkbox__input:focus-visible ~ .vgui-checkbox__box {
|
|
94
|
+
outline: var(--vgui-focus-ring-valve);
|
|
95
|
+
outline-offset: var(--vgui-focus-ring-valve-offset);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* DisabledText1 over DisabledText2 at +1px +1px. Colour is decorative here:
|
|
99
|
+
* the `disabled` attribute is what carries the meaning. */
|
|
100
|
+
.vgui-checkbox__input:disabled ~ .vgui-checkbox__label {
|
|
101
|
+
color: var(--vgui-text-disabled);
|
|
102
|
+
text-shadow: 1px 1px 0 var(--vgui-text-disabled-shadow);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.vgui-checkbox__input:disabled ~ .vgui-checkbox__box {
|
|
106
|
+
cursor: not-allowed;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.vgui-checkbox--label-end {
|
|
110
|
+
flex-direction: row-reverse;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.vgui-checkbox__label {
|
|
114
|
+
min-width: 0;
|
|
115
|
+
overflow-wrap: anywhere;
|
|
116
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { InputHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import './Checkbox.css';
|
|
3
|
+
export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {
|
|
4
|
+
/** The label. Rendered as part of the clickable area. */
|
|
5
|
+
label?: ReactNode;
|
|
6
|
+
/** Render the indeterminate third state. */
|
|
7
|
+
indeterminate?: boolean;
|
|
8
|
+
/** Put the box after the label instead of before. */
|
|
9
|
+
labelPosition?: 'start' | 'end';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A 15×15 box with an *inset* bevel — a hole in the panel, not a raised button.
|
|
13
|
+
*
|
|
14
|
+
* The real `<input type="checkbox">` stays in the DOM, focusable and hidden by
|
|
15
|
+
* `clip-path`, so `Space`, form participation and the platform's "mixed"
|
|
16
|
+
* announcement all keep working (docs/components/Checkbox.md, "Accessibility").
|
|
17
|
+
*/
|
|
18
|
+
export declare const Checkbox: import("react").ForwardRefExoticComponent<CheckboxProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
19
|
+
//# sourceMappingURL=Checkbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAE3D,OAAO,gBAAgB,CAAA;AAEvB,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACxF,yDAAyD;IACzD,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,qDAAqD;IACrD,aAAa,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;CAChC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,4GAyCnB,CAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { forwardRef, useCallback, useEffect, useRef } from "react";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import "./Checkbox.css";
|
|
4
|
+
//#region src/components/Checkbox/Checkbox.tsx
|
|
5
|
+
/**
|
|
6
|
+
* A 15×15 box with an *inset* bevel — a hole in the panel, not a raised button.
|
|
7
|
+
*
|
|
8
|
+
* The real `<input type="checkbox">` stays in the DOM, focusable and hidden by
|
|
9
|
+
* `clip-path`, so `Space`, form participation and the platform's "mixed"
|
|
10
|
+
* announcement all keep working (docs/components/Checkbox.md, "Accessibility").
|
|
11
|
+
*/
|
|
12
|
+
var Checkbox = forwardRef(function Checkbox({ className, label, indeterminate = false, labelPosition = "start", ...rest }, ref) {
|
|
13
|
+
const inputRef = useRef(null);
|
|
14
|
+
const setInputRef = useCallback((node) => {
|
|
15
|
+
inputRef.current = node;
|
|
16
|
+
if (typeof ref === "function") ref(node);
|
|
17
|
+
else if (ref) ref.current = node;
|
|
18
|
+
}, [ref]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (inputRef.current) inputRef.current.indeterminate = indeterminate;
|
|
21
|
+
}, [indeterminate]);
|
|
22
|
+
const classes = ["vgui-checkbox"];
|
|
23
|
+
if (labelPosition === "end") classes.push("vgui-checkbox--label-end");
|
|
24
|
+
if (className) classes.push(className);
|
|
25
|
+
const box = /* @__PURE__ */ jsx("span", {
|
|
26
|
+
className: "vgui-checkbox__box",
|
|
27
|
+
"aria-hidden": "true"
|
|
28
|
+
});
|
|
29
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
30
|
+
className: classes.join(" "),
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ jsx("input", {
|
|
33
|
+
ref: setInputRef,
|
|
34
|
+
type: "checkbox",
|
|
35
|
+
className: "vgui-checkbox__input",
|
|
36
|
+
...rest
|
|
37
|
+
}),
|
|
38
|
+
labelPosition === "end" ? null : box,
|
|
39
|
+
label == null ? null : /* @__PURE__ */ jsx("span", {
|
|
40
|
+
className: "vgui-checkbox__label",
|
|
41
|
+
children: label
|
|
42
|
+
}),
|
|
43
|
+
labelPosition === "end" ? box : null
|
|
44
|
+
]
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
Checkbox.displayName = "Checkbox";
|
|
48
|
+
//#endregion
|
|
49
|
+
export { Checkbox };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=Checkbox.js.map
|