@dashforge/tw 0.1.0-beta
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/.swcrc +29 -0
- package/CHANGELOG.md +131 -0
- package/LICENSE +21 -0
- package/README.md +244 -0
- package/dist/components/AppShell/AppShell.d.ts +32 -0
- package/dist/components/AppShell/AppShell.d.ts.map +1 -0
- package/dist/components/AppShell/appShell.types.d.ts +62 -0
- package/dist/components/AppShell/appShell.types.d.ts.map +1 -0
- package/dist/components/AppShell/appShell.variants.d.ts +65 -0
- package/dist/components/AppShell/appShell.variants.d.ts.map +1 -0
- package/dist/components/Autocomplete/Autocomplete.d.ts +32 -0
- package/dist/components/Autocomplete/Autocomplete.d.ts.map +1 -0
- package/dist/components/Autocomplete/autocomplete.types.d.ts +214 -0
- package/dist/components/Autocomplete/autocomplete.types.d.ts.map +1 -0
- package/dist/components/Autocomplete/autocomplete.variants.d.ts +214 -0
- package/dist/components/Autocomplete/autocomplete.variants.d.ts.map +1 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +23 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts.map +1 -0
- package/dist/components/Breadcrumbs/breadcrumbs.types.d.ts +98 -0
- package/dist/components/Breadcrumbs/breadcrumbs.types.d.ts.map +1 -0
- package/dist/components/Breadcrumbs/breadcrumbs.variants.d.ts +85 -0
- package/dist/components/Breadcrumbs/breadcrumbs.variants.d.ts.map +1 -0
- package/dist/components/Button/Button.d.ts +44 -0
- package/dist/components/Button/Button.d.ts.map +1 -0
- package/dist/components/Button/button.types.d.ts +66 -0
- package/dist/components/Button/button.types.d.ts.map +1 -0
- package/dist/components/Button/button.variants.d.ts +104 -0
- package/dist/components/Button/button.variants.d.ts.map +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts +31 -0
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox/checkbox.types.d.ts +86 -0
- package/dist/components/Checkbox/checkbox.types.d.ts.map +1 -0
- package/dist/components/Checkbox/checkbox.variants.d.ts +109 -0
- package/dist/components/Checkbox/checkbox.variants.d.ts.map +1 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +38 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.d.ts.map +1 -0
- package/dist/components/ConfirmDialog/confirmDialog.types.d.ts +80 -0
- package/dist/components/ConfirmDialog/confirmDialog.types.d.ts.map +1 -0
- package/dist/components/ConfirmDialog/confirmDialog.variants.d.ts +90 -0
- package/dist/components/ConfirmDialog/confirmDialog.variants.d.ts.map +1 -0
- package/dist/components/DateTimePicker/DateTimePicker.d.ts +49 -0
- package/dist/components/DateTimePicker/DateTimePicker.d.ts.map +1 -0
- package/dist/components/DateTimePicker/dateTimePicker.types.d.ts +95 -0
- package/dist/components/DateTimePicker/dateTimePicker.types.d.ts.map +1 -0
- package/dist/components/DateTimePicker/dateTimePicker.variants.d.ts +165 -0
- package/dist/components/DateTimePicker/dateTimePicker.variants.d.ts.map +1 -0
- package/dist/components/LeftNav/LeftNav.d.ts +34 -0
- package/dist/components/LeftNav/LeftNav.d.ts.map +1 -0
- package/dist/components/LeftNav/leftNav.types.d.ts +136 -0
- package/dist/components/LeftNav/leftNav.types.d.ts.map +1 -0
- package/dist/components/LeftNav/leftNav.variants.d.ts +143 -0
- package/dist/components/LeftNav/leftNav.variants.d.ts.map +1 -0
- package/dist/components/NumberField/NumberField.d.ts +18 -0
- package/dist/components/NumberField/NumberField.d.ts.map +1 -0
- package/dist/components/NumberField/numberField.types.d.ts +79 -0
- package/dist/components/NumberField/numberField.types.d.ts.map +1 -0
- package/dist/components/NumberField/numberField.variants.d.ts +169 -0
- package/dist/components/NumberField/numberField.variants.d.ts.map +1 -0
- package/dist/components/OTPField/OTPField.d.ts +25 -0
- package/dist/components/OTPField/OTPField.d.ts.map +1 -0
- package/dist/components/OTPField/otpField.types.d.ts +74 -0
- package/dist/components/OTPField/otpField.types.d.ts.map +1 -0
- package/dist/components/OTPField/otpField.variants.d.ts +105 -0
- package/dist/components/OTPField/otpField.variants.d.ts.map +1 -0
- package/dist/components/RadioGroup/RadioGroup.d.ts +35 -0
- package/dist/components/RadioGroup/RadioGroup.d.ts.map +1 -0
- package/dist/components/RadioGroup/radioGroup.types.d.ts +103 -0
- package/dist/components/RadioGroup/radioGroup.types.d.ts.map +1 -0
- package/dist/components/RadioGroup/radioGroup.variants.d.ts +166 -0
- package/dist/components/RadioGroup/radioGroup.variants.d.ts.map +1 -0
- package/dist/components/Snackbar/Snackbar.d.ts +37 -0
- package/dist/components/Snackbar/Snackbar.d.ts.map +1 -0
- package/dist/components/Snackbar/snackbar.types.d.ts +86 -0
- package/dist/components/Snackbar/snackbar.types.d.ts.map +1 -0
- package/dist/components/Snackbar/snackbar.variants.d.ts +153 -0
- package/dist/components/Snackbar/snackbar.variants.d.ts.map +1 -0
- package/dist/components/Switch/Switch.d.ts +15 -0
- package/dist/components/Switch/Switch.d.ts.map +1 -0
- package/dist/components/Switch/switch.types.d.ts +47 -0
- package/dist/components/Switch/switch.types.d.ts.map +1 -0
- package/dist/components/Switch/switch.variants.d.ts +105 -0
- package/dist/components/Switch/switch.variants.d.ts.map +1 -0
- package/dist/components/TextField/TextField.d.ts +25 -0
- package/dist/components/TextField/TextField.d.ts.map +1 -0
- package/dist/components/TextField/textField.types.d.ts +72 -0
- package/dist/components/TextField/textField.types.d.ts.map +1 -0
- package/dist/components/TextField/textField.variants.d.ts +160 -0
- package/dist/components/TextField/textField.variants.d.ts.map +1 -0
- package/dist/components/Textarea/Textarea.d.ts +16 -0
- package/dist/components/Textarea/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea/textarea.types.d.ts +63 -0
- package/dist/components/Textarea/textarea.types.d.ts.map +1 -0
- package/dist/components/Textarea/textarea.variants.d.ts +197 -0
- package/dist/components/Textarea/textarea.variants.d.ts.map +1 -0
- package/dist/components/TopBar/TopBar.d.ts +33 -0
- package/dist/components/TopBar/TopBar.d.ts.map +1 -0
- package/dist/components/TopBar/topBar.types.d.ts +49 -0
- package/dist/components/TopBar/topBar.types.d.ts.map +1 -0
- package/dist/components/TopBar/topBar.variants.d.ts +79 -0
- package/dist/components/TopBar/topBar.variants.d.ts.map +1 -0
- package/dist/components/_shared/resolveValidationState.d.ts +42 -0
- package/dist/components/_shared/resolveValidationState.d.ts.map +1 -0
- package/dist/hooks/useAccessState.d.ts +37 -0
- package/dist/hooks/useAccessState.d.ts.map +1 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +4958 -0
- package/dist/src/components/AppShell/AppShell.d.ts +32 -0
- package/dist/src/components/AppShell/AppShell.d.ts.map +1 -0
- package/dist/src/components/AppShell/appShell.types.d.ts +62 -0
- package/dist/src/components/AppShell/appShell.types.d.ts.map +1 -0
- package/dist/src/components/AppShell/appShell.variants.d.ts +65 -0
- package/dist/src/components/AppShell/appShell.variants.d.ts.map +1 -0
- package/dist/src/components/Autocomplete/Autocomplete.d.ts +32 -0
- package/dist/src/components/Autocomplete/Autocomplete.d.ts.map +1 -0
- package/dist/src/components/Autocomplete/autocomplete.types.d.ts +214 -0
- package/dist/src/components/Autocomplete/autocomplete.types.d.ts.map +1 -0
- package/dist/src/components/Autocomplete/autocomplete.variants.d.ts +214 -0
- package/dist/src/components/Autocomplete/autocomplete.variants.d.ts.map +1 -0
- package/dist/src/components/Breadcrumbs/Breadcrumbs.d.ts +23 -0
- package/dist/src/components/Breadcrumbs/Breadcrumbs.d.ts.map +1 -0
- package/dist/src/components/Breadcrumbs/breadcrumbs.types.d.ts +98 -0
- package/dist/src/components/Breadcrumbs/breadcrumbs.types.d.ts.map +1 -0
- package/dist/src/components/Breadcrumbs/breadcrumbs.variants.d.ts +85 -0
- package/dist/src/components/Breadcrumbs/breadcrumbs.variants.d.ts.map +1 -0
- package/dist/src/components/Button/Button.d.ts +44 -0
- package/dist/src/components/Button/Button.d.ts.map +1 -0
- package/dist/src/components/Button/button.types.d.ts +66 -0
- package/dist/src/components/Button/button.types.d.ts.map +1 -0
- package/dist/src/components/Button/button.variants.d.ts +104 -0
- package/dist/src/components/Button/button.variants.d.ts.map +1 -0
- package/dist/src/components/Checkbox/Checkbox.d.ts +31 -0
- package/dist/src/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/src/components/Checkbox/checkbox.types.d.ts +86 -0
- package/dist/src/components/Checkbox/checkbox.types.d.ts.map +1 -0
- package/dist/src/components/Checkbox/checkbox.variants.d.ts +109 -0
- package/dist/src/components/Checkbox/checkbox.variants.d.ts.map +1 -0
- package/dist/src/components/ConfirmDialog/ConfirmDialog.d.ts +38 -0
- package/dist/src/components/ConfirmDialog/ConfirmDialog.d.ts.map +1 -0
- package/dist/src/components/ConfirmDialog/confirmDialog.types.d.ts +80 -0
- package/dist/src/components/ConfirmDialog/confirmDialog.types.d.ts.map +1 -0
- package/dist/src/components/ConfirmDialog/confirmDialog.variants.d.ts +90 -0
- package/dist/src/components/ConfirmDialog/confirmDialog.variants.d.ts.map +1 -0
- package/dist/src/components/DateTimePicker/DateTimePicker.d.ts +49 -0
- package/dist/src/components/DateTimePicker/DateTimePicker.d.ts.map +1 -0
- package/dist/src/components/DateTimePicker/dateTimePicker.types.d.ts +95 -0
- package/dist/src/components/DateTimePicker/dateTimePicker.types.d.ts.map +1 -0
- package/dist/src/components/DateTimePicker/dateTimePicker.variants.d.ts +165 -0
- package/dist/src/components/DateTimePicker/dateTimePicker.variants.d.ts.map +1 -0
- package/dist/src/components/LeftNav/LeftNav.d.ts +34 -0
- package/dist/src/components/LeftNav/LeftNav.d.ts.map +1 -0
- package/dist/src/components/LeftNav/leftNav.types.d.ts +136 -0
- package/dist/src/components/LeftNav/leftNav.types.d.ts.map +1 -0
- package/dist/src/components/LeftNav/leftNav.variants.d.ts +143 -0
- package/dist/src/components/LeftNav/leftNav.variants.d.ts.map +1 -0
- package/dist/src/components/NumberField/NumberField.d.ts +18 -0
- package/dist/src/components/NumberField/NumberField.d.ts.map +1 -0
- package/dist/src/components/NumberField/numberField.types.d.ts +79 -0
- package/dist/src/components/NumberField/numberField.types.d.ts.map +1 -0
- package/dist/src/components/NumberField/numberField.variants.d.ts +169 -0
- package/dist/src/components/NumberField/numberField.variants.d.ts.map +1 -0
- package/dist/src/components/OTPField/OTPField.d.ts +25 -0
- package/dist/src/components/OTPField/OTPField.d.ts.map +1 -0
- package/dist/src/components/OTPField/otpField.types.d.ts +74 -0
- package/dist/src/components/OTPField/otpField.types.d.ts.map +1 -0
- package/dist/src/components/OTPField/otpField.variants.d.ts +105 -0
- package/dist/src/components/OTPField/otpField.variants.d.ts.map +1 -0
- package/dist/src/components/RadioGroup/RadioGroup.d.ts +35 -0
- package/dist/src/components/RadioGroup/RadioGroup.d.ts.map +1 -0
- package/dist/src/components/RadioGroup/radioGroup.types.d.ts +103 -0
- package/dist/src/components/RadioGroup/radioGroup.types.d.ts.map +1 -0
- package/dist/src/components/RadioGroup/radioGroup.variants.d.ts +166 -0
- package/dist/src/components/RadioGroup/radioGroup.variants.d.ts.map +1 -0
- package/dist/src/components/Snackbar/Snackbar.d.ts +37 -0
- package/dist/src/components/Snackbar/Snackbar.d.ts.map +1 -0
- package/dist/src/components/Snackbar/snackbar.types.d.ts +86 -0
- package/dist/src/components/Snackbar/snackbar.types.d.ts.map +1 -0
- package/dist/src/components/Snackbar/snackbar.variants.d.ts +153 -0
- package/dist/src/components/Snackbar/snackbar.variants.d.ts.map +1 -0
- package/dist/src/components/Switch/Switch.d.ts +15 -0
- package/dist/src/components/Switch/Switch.d.ts.map +1 -0
- package/dist/src/components/Switch/switch.types.d.ts +47 -0
- package/dist/src/components/Switch/switch.types.d.ts.map +1 -0
- package/dist/src/components/Switch/switch.variants.d.ts +105 -0
- package/dist/src/components/Switch/switch.variants.d.ts.map +1 -0
- package/dist/src/components/TextField/TextField.d.ts +25 -0
- package/dist/src/components/TextField/TextField.d.ts.map +1 -0
- package/dist/src/components/TextField/textField.types.d.ts +72 -0
- package/dist/src/components/TextField/textField.types.d.ts.map +1 -0
- package/dist/src/components/TextField/textField.variants.d.ts +160 -0
- package/dist/src/components/TextField/textField.variants.d.ts.map +1 -0
- package/dist/src/components/Textarea/Textarea.d.ts +16 -0
- package/dist/src/components/Textarea/Textarea.d.ts.map +1 -0
- package/dist/src/components/Textarea/textarea.types.d.ts +63 -0
- package/dist/src/components/Textarea/textarea.types.d.ts.map +1 -0
- package/dist/src/components/Textarea/textarea.variants.d.ts +197 -0
- package/dist/src/components/Textarea/textarea.variants.d.ts.map +1 -0
- package/dist/src/components/TopBar/TopBar.d.ts +33 -0
- package/dist/src/components/TopBar/TopBar.d.ts.map +1 -0
- package/dist/src/components/TopBar/topBar.types.d.ts +49 -0
- package/dist/src/components/TopBar/topBar.types.d.ts.map +1 -0
- package/dist/src/components/TopBar/topBar.variants.d.ts +79 -0
- package/dist/src/components/TopBar/topBar.variants.d.ts.map +1 -0
- package/dist/src/components/_shared/resolveValidationState.d.ts +42 -0
- package/dist/src/components/_shared/resolveValidationState.d.ts.map +1 -0
- package/dist/src/hooks/useAccessState.d.ts +37 -0
- package/dist/src/hooks/useAccessState.d.ts.map +1 -0
- package/dist/src/index.d.ts +82 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/utils/cn.d.ts +26 -0
- package/dist/src/utils/cn.d.ts.map +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/dist/utils/cn.d.ts +26 -0
- package/dist/utils/cn.d.ts.map +1 -0
- package/eslint.config.mjs +47 -0
- package/package.json +37 -0
- package/project.json +15 -0
- package/rollup.config.cjs +16 -0
- package/src/components/AppShell/AppShell.test.tsx +223 -0
- package/src/components/AppShell/AppShell.tsx +114 -0
- package/src/components/AppShell/appShell.types.ts +49 -0
- package/src/components/AppShell/appShell.variants.ts +48 -0
- package/src/components/Autocomplete/Autocomplete.perf.test.tsx +225 -0
- package/src/components/Autocomplete/Autocomplete.test.tsx +556 -0
- package/src/components/Autocomplete/Autocomplete.tsx +996 -0
- package/src/components/Autocomplete/autocomplete.types.ts +198 -0
- package/src/components/Autocomplete/autocomplete.variants.ts +135 -0
- package/src/components/Breadcrumbs/Breadcrumbs.perf.test.tsx +125 -0
- package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +231 -0
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +203 -0
- package/src/components/Breadcrumbs/breadcrumbs.types.ts +87 -0
- package/src/components/Breadcrumbs/breadcrumbs.variants.ts +49 -0
- package/src/components/Button/Button.test.tsx +183 -0
- package/src/components/Button/Button.tsx +139 -0
- package/src/components/Button/button.types.ts +74 -0
- package/src/components/Button/button.variants.ts +159 -0
- package/src/components/Checkbox/Checkbox.test.tsx +146 -0
- package/src/components/Checkbox/Checkbox.tsx +228 -0
- package/src/components/Checkbox/checkbox.types.ts +88 -0
- package/src/components/Checkbox/checkbox.variants.ts +68 -0
- package/src/components/ConfirmDialog/ConfirmDialog.perf.test.tsx +172 -0
- package/src/components/ConfirmDialog/ConfirmDialog.test.tsx +311 -0
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +252 -0
- package/src/components/ConfirmDialog/confirmDialog.types.ts +70 -0
- package/src/components/ConfirmDialog/confirmDialog.variants.ts +76 -0
- package/src/components/DateTimePicker/DateTimePicker.perf.test.tsx +153 -0
- package/src/components/DateTimePicker/DateTimePicker.test.tsx +204 -0
- package/src/components/DateTimePicker/DateTimePicker.tsx +319 -0
- package/src/components/DateTimePicker/dateTimePicker.types.ts +83 -0
- package/src/components/DateTimePicker/dateTimePicker.variants.ts +84 -0
- package/src/components/LeftNav/LeftNav.perf.test.tsx +172 -0
- package/src/components/LeftNav/LeftNav.test.tsx +302 -0
- package/src/components/LeftNav/LeftNav.tsx +330 -0
- package/src/components/LeftNav/leftNav.types.ts +120 -0
- package/src/components/LeftNav/leftNav.variants.ts +96 -0
- package/src/components/NumberField/NumberField.test.tsx +83 -0
- package/src/components/NumberField/NumberField.tsx +293 -0
- package/src/components/NumberField/numberField.types.ts +72 -0
- package/src/components/NumberField/numberField.variants.ts +94 -0
- package/src/components/OTPField/OTPField.test.tsx +121 -0
- package/src/components/OTPField/OTPField.tsx +250 -0
- package/src/components/OTPField/otpField.types.ts +58 -0
- package/src/components/OTPField/otpField.variants.ts +72 -0
- package/src/components/RadioGroup/RadioGroup.test.tsx +140 -0
- package/src/components/RadioGroup/RadioGroup.tsx +261 -0
- package/src/components/RadioGroup/radioGroup.types.ts +85 -0
- package/src/components/RadioGroup/radioGroup.variants.ts +87 -0
- package/src/components/Snackbar/Snackbar.perf.test.tsx +144 -0
- package/src/components/Snackbar/Snackbar.test.tsx +327 -0
- package/src/components/Snackbar/Snackbar.tsx +298 -0
- package/src/components/Snackbar/snackbar.types.ts +83 -0
- package/src/components/Snackbar/snackbar.variants.ts +72 -0
- package/src/components/Switch/Switch.test.tsx +131 -0
- package/src/components/Switch/Switch.tsx +158 -0
- package/src/components/Switch/switch.types.ts +36 -0
- package/src/components/Switch/switch.variants.ts +65 -0
- package/src/components/TextField/TextField.test.tsx +194 -0
- package/src/components/TextField/TextField.tsx +216 -0
- package/src/components/TextField/textField.types.ts +70 -0
- package/src/components/TextField/textField.variants.ts +87 -0
- package/src/components/Textarea/Textarea.test.tsx +75 -0
- package/src/components/Textarea/Textarea.tsx +190 -0
- package/src/components/Textarea/textarea.types.ts +60 -0
- package/src/components/Textarea/textarea.variants.ts +85 -0
- package/src/components/TopBar/TopBar.test.tsx +129 -0
- package/src/components/TopBar/TopBar.tsx +66 -0
- package/src/components/TopBar/topBar.types.ts +42 -0
- package/src/components/TopBar/topBar.variants.ts +38 -0
- package/src/components/_shared/resolveValidationState.ts +60 -0
- package/src/hooks/useAccessState.spec.tsx +161 -0
- package/src/hooks/useAccessState.ts +81 -0
- package/src/index.ts +191 -0
- package/src/utils/cn.spec.ts +16 -0
- package/src/utils/cn.ts +29 -0
- package/tsconfig.json +13 -0
- package/tsconfig.lib.json +55 -0
- package/tsconfig.spec.json +34 -0
- package/vite.config.ts +25 -0
- package/vitest.config.mts +22 -0
package/.swcrc
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"jsc": {
|
|
3
|
+
"target": "es2017",
|
|
4
|
+
"parser": {
|
|
5
|
+
"syntax": "typescript",
|
|
6
|
+
"decorators": true,
|
|
7
|
+
"dynamicImport": true
|
|
8
|
+
},
|
|
9
|
+
"transform": {
|
|
10
|
+
"decoratorMetadata": true,
|
|
11
|
+
"legacyDecorator": true
|
|
12
|
+
},
|
|
13
|
+
"keepClassNames": true,
|
|
14
|
+
"externalHelpers": true,
|
|
15
|
+
"loose": true
|
|
16
|
+
},
|
|
17
|
+
"module": {
|
|
18
|
+
"type": "es6"
|
|
19
|
+
},
|
|
20
|
+
"sourceMaps": true,
|
|
21
|
+
"exclude": [
|
|
22
|
+
"jest.config.[ct]s",
|
|
23
|
+
".*\\.spec.tsx?$",
|
|
24
|
+
".*\\.test.tsx?$",
|
|
25
|
+
"./src/jest-setup.ts$",
|
|
26
|
+
"./**/jest-setup.ts$",
|
|
27
|
+
".*.js$"
|
|
28
|
+
]
|
|
29
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Changelog — @dashforge/tw
|
|
2
|
+
|
|
3
|
+
All notable changes to `@dashforge/tw` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
|
+
This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
> This package is part of the **`@dashforge/tw-*` Tailwind ecosystem**, built
|
|
9
|
+
> as a fully isolated stack sharing only the bridge layer
|
|
10
|
+
> (`@dashforge/forms` + `@dashforge/ui-core` + `@dashforge/rbac`) with the
|
|
11
|
+
> MUI side of Dashforge. Tokens, theme runtime, and components are
|
|
12
|
+
> duplicated intentionally — no shared "lowest common denominator" headless
|
|
13
|
+
> layer.
|
|
14
|
+
|
|
15
|
+
## [0.1.0-beta] — 2026-05-16
|
|
16
|
+
|
|
17
|
+
First public beta. Sixteen components shipped across forms, layout, and
|
|
18
|
+
providers — every component is bridge-integrated, RBAC-aware,
|
|
19
|
+
StrictMode-safe, and covered by unit + perf + re-render budget tests.
|
|
20
|
+
|
|
21
|
+
### Added — Form components (10)
|
|
22
|
+
|
|
23
|
+
- **`Button`** (F3) — variant + size + color matrix, polymorphic
|
|
24
|
+
`asChild` slot, RBAC `access` prop, loading/disabled states.
|
|
25
|
+
- **`TextField`** (F3) — bridge-integrated single-line input with
|
|
26
|
+
7-slot taxonomy, stacked/inline layouts, error gating via Form
|
|
27
|
+
Closure v1.
|
|
28
|
+
- **`Checkbox`** (F3) — Radix Checkbox primitive, bridge wiring,
|
|
29
|
+
RBAC + visibility.
|
|
30
|
+
- **`Switch`** (F3) — Radix Switch primitive, same contract as Checkbox.
|
|
31
|
+
- **`RadioGroup`** (F4) — Radix RadioGroup with row/stacked layouts.
|
|
32
|
+
- **`Textarea`** (F4) — multi-line variant of TextField, vertical
|
|
33
|
+
resize support.
|
|
34
|
+
- **`NumberField`** (F4) — locale-aware number input, optional
|
|
35
|
+
stepper buttons, min/max/step constraints.
|
|
36
|
+
- **`OTPField`** (F4) — segmented one-time-code input (numeric /
|
|
37
|
+
alphanumeric), sanitized paste.
|
|
38
|
+
- **`Autocomplete`** (F5-A → F5-A-bis) — single + multi-select
|
|
39
|
+
combobox; generic option shape via `getOptionValue` /
|
|
40
|
+
`getOptionLabel`; free-solo (Enter / blur commits typed text);
|
|
41
|
+
async runtime via `loadOptions(query)` with debounce + loading
|
|
42
|
+
row + race-safe fetch generation. **Custom pure-React
|
|
43
|
+
implementation** (no react-aria-components) for deterministic
|
|
44
|
+
state ownership — the F5-A clear-button regression was the
|
|
45
|
+
motivating lesson.
|
|
46
|
+
- **`DateTimePicker`** (F5-B) — native HTML5 inputs (`date` /
|
|
47
|
+
`time` / `datetime-local`), `min` / `max` / `step` forwarded,
|
|
48
|
+
ISO 8601 ⇔ native input value conversion, `color-scheme: light
|
|
49
|
+
dark` for OS-icon legibility in dark mode.
|
|
50
|
+
|
|
51
|
+
### Added — Layout components (4)
|
|
52
|
+
|
|
53
|
+
- **`Breadcrumbs`** (F6) — router-agnostic crumb trail with
|
|
54
|
+
middle-collapse (`maxItems`, `itemsBeforeCollapse`,
|
|
55
|
+
`itemsAfterCollapse`), polymorphic `linkComponent`,
|
|
56
|
+
`aria-current="page"` on the active crumb.
|
|
57
|
+
- **`LeftNav`** (F6) — sidebar with flat items + collapsible
|
|
58
|
+
groups; rail mode (`collapsed` + `sr-only` labels + tooltips);
|
|
59
|
+
per-row RBAC; controlled / uncontrolled group expansion;
|
|
60
|
+
brand + footer slots.
|
|
61
|
+
- **`TopBar`** (F6) — sticky `<header>` with `start` / `center` /
|
|
62
|
+
`end` slots; renders as `<header>` (banner landmark) or `<div>`
|
|
63
|
+
via `asDiv`.
|
|
64
|
+
- **`AppShell`** (F6) — top-level orchestrator wiring `header` +
|
|
65
|
+
`nav` (desktop inline + mobile drawer) + `main` + `footer`;
|
|
66
|
+
body scroll-lock + Escape close + backdrop click; responsive
|
|
67
|
+
switch at the `md` breakpoint.
|
|
68
|
+
|
|
69
|
+
### Added — Providers (2)
|
|
70
|
+
|
|
71
|
+
- **`ConfirmDialogProvider`** + **`useConfirm()`** (F7) —
|
|
72
|
+
imperative `Promise<boolean>` confirmation modal on the native
|
|
73
|
+
`<dialog>` element + `showModal()` (AAA-grade a11y + focus
|
|
74
|
+
trap + Escape free from the browser); FIFO request queue;
|
|
75
|
+
4 severities; `disableBackdropClose` / `disableEscapeClose`
|
|
76
|
+
per-invocation.
|
|
77
|
+
- **`SnackbarProvider`** + **`useSnackbar()`** (F7) — transient
|
|
78
|
+
toast notifications, 6 corner positions, `maxVisible` cap with
|
|
79
|
+
FIFO promotion, de-dup by `id` (re-enqueueing replaces in
|
|
80
|
+
place + resets timer), action buttons, persistent mode
|
|
81
|
+
(`autoHideMs: 0`), `aria-live="polite"` region for AT.
|
|
82
|
+
|
|
83
|
+
### Added — Tooling
|
|
84
|
+
|
|
85
|
+
- **`flat-dts.cjs`** post-build script (also added to `@dashforge/forms`,
|
|
86
|
+
`@dashforge/ui-core`, `@dashforge/rbac`) — rewrites the Rollup-emitted
|
|
87
|
+
`dist/index.d.ts` `export * from "./src/index"` wrapper with explicit
|
|
88
|
+
re-exports. Works around a TypeScript bundler-resolution bug where
|
|
89
|
+
`export *` in a dist wrapper drops re-exports under project references.
|
|
90
|
+
- **`eslint-plugin-react-hooks`** scoped to this package — exposes real
|
|
91
|
+
`rules-of-hooks` and `exhaustive-deps` violations that were previously
|
|
92
|
+
hidden.
|
|
93
|
+
|
|
94
|
+
### Quality
|
|
95
|
+
|
|
96
|
+
- **317 tests passing** (≈90 unit, the rest perf + re-render budgets).
|
|
97
|
+
- Strict re-render guardrails: typing into a field never re-renders an
|
|
98
|
+
unrelated sibling; `confirm()` and `useSnackbar()` return identities
|
|
99
|
+
are stable across provider re-renders.
|
|
100
|
+
- Perf budgets pinned for mount cost (e.g. `<LeftNav>` 300-row mount
|
|
101
|
+
under 250 ms, `<Autocomplete>` 1000-option mount under 500 ms).
|
|
102
|
+
- Lint + typecheck + build all green workspace-wide.
|
|
103
|
+
|
|
104
|
+
### Architecture notes
|
|
105
|
+
|
|
106
|
+
- **`peerDependencies`**: `react ^18 || ^19`, plus
|
|
107
|
+
`@dashforge/tw-tokens` and `@dashforge/tw-theme` (CSS variable provider
|
|
108
|
+
+ Tailwind preset must be wired by the consumer).
|
|
109
|
+
- **`dependencies`**: `@dashforge/forms`, `@dashforge/rbac`,
|
|
110
|
+
`@dashforge/ui-core`, `@radix-ui/react-{checkbox,radio-group,slot,switch}`,
|
|
111
|
+
`clsx`, `tailwind-merge`, `tailwind-variants`. No `react-aria-components`
|
|
112
|
+
(the Autocomplete rewrite dropped the dep).
|
|
113
|
+
|
|
114
|
+
## [0.0.1] — 2026-05-15
|
|
115
|
+
|
|
116
|
+
### Added
|
|
117
|
+
|
|
118
|
+
- **Initial scaffolding (F1 of the *dashforge-tw* roadmap).** Empty
|
|
119
|
+
components surface; package exports the cross-cutting utilities the
|
|
120
|
+
later component code will rely on:
|
|
121
|
+
- `cn()` — `clsx` + `tailwind-merge` wrapper for safe class
|
|
122
|
+
concatenation with last-wins conflict resolution.
|
|
123
|
+
- `tv` — re-export of `tailwind-variants` so consumers (and the
|
|
124
|
+
forthcoming F3 components) have a single canonical import path.
|
|
125
|
+
- Rollup build (CJS + ESM + .d.ts). `types` path corrected from the Nx
|
|
126
|
+
generator default (`./dist/index.esm.d.ts`) to `./dist/index.d.ts`.
|
|
127
|
+
- `tailwind-merge` added as a regular dependency (peer-required by
|
|
128
|
+
`tailwind-variants`; consumers shouldn't have to know that detail).
|
|
129
|
+
- Smoke-tested in `~/projects/web/learn/dash` via `pnpm link` together
|
|
130
|
+
with `@dashforge/tw-tokens` and `@dashforge/tw-theme`. Browser build
|
|
131
|
+
green.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dashforge
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# @dashforge/tw
|
|
2
|
+
|
|
3
|
+
> **Status**: `0.1.0-beta` — first public beta. Sixteen components
|
|
4
|
+
> shipped across forms, layout, and providers. The MUI side of
|
|
5
|
+
> Dashforge (`@dashforge/ui`, `@dashforge/theme-mui`,
|
|
6
|
+
> `@dashforge/theme-core`) is **fully isolated** from this package —
|
|
7
|
+
> the two ecosystems share only the bridge layer (`@dashforge/forms` +
|
|
8
|
+
> `@dashforge/ui-core` + `@dashforge/rbac`).
|
|
9
|
+
|
|
10
|
+
Tailwind-rendered UI components for the Dashforge ecosystem.
|
|
11
|
+
|
|
12
|
+
Components are **props-driven** (every Tailwind utility that matters
|
|
13
|
+
for the public API becomes a typed prop — `size`, `color`, `variant`,
|
|
14
|
+
`layout`, …). Raw `className` / `sx` / `slotProps` exist as escape
|
|
15
|
+
hatches for the cases the prop surface doesn't cover.
|
|
16
|
+
|
|
17
|
+
## Component catalog
|
|
18
|
+
|
|
19
|
+
### Form components (10)
|
|
20
|
+
|
|
21
|
+
`Button` · `TextField` · `Checkbox` · `Switch` · `RadioGroup` ·
|
|
22
|
+
`Textarea` · `NumberField` · `OTPField` · `Autocomplete` ·
|
|
23
|
+
`DateTimePicker`
|
|
24
|
+
|
|
25
|
+
All bridge-integrated, RBAC-aware (`access` prop), Form Closure v1
|
|
26
|
+
error gating, StrictMode-safe.
|
|
27
|
+
|
|
28
|
+
### Layout components (4)
|
|
29
|
+
|
|
30
|
+
`Breadcrumbs` · `LeftNav` · `TopBar` · `AppShell`
|
|
31
|
+
|
|
32
|
+
Router-agnostic — pass a `linkComponent` prop for SPA navigation
|
|
33
|
+
(React Router, Next, TanStack Router, …). Mobile-responsive shell
|
|
34
|
+
with drawer + body scroll lock.
|
|
35
|
+
|
|
36
|
+
### Providers (2)
|
|
37
|
+
|
|
38
|
+
`ConfirmDialogProvider` + `useConfirm()` · `SnackbarProvider` +
|
|
39
|
+
`useSnackbar()`
|
|
40
|
+
|
|
41
|
+
Imperative APIs (`await confirm({...})`, `enqueue({...})`) backed by
|
|
42
|
+
queues, FIFO ordering, and dedup. Built on native `<dialog>` for AAA
|
|
43
|
+
a11y where possible.
|
|
44
|
+
|
|
45
|
+
## Quick start
|
|
46
|
+
|
|
47
|
+
Install the three TW packages alongside the shared bridge layer:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pnpm add @dashforge/tw @dashforge/tw-theme @dashforge/tw-tokens \
|
|
51
|
+
@dashforge/forms @dashforge/ui-core @dashforge/rbac \
|
|
52
|
+
react react-dom tailwindcss
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Wire the Tailwind preset + theme provider as described in
|
|
56
|
+
[`@dashforge/tw-theme`](../tw-theme/README.md), then mount components
|
|
57
|
+
inside a `DashFormProvider`:
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { DashForm } from '@dashforge/forms';
|
|
61
|
+
import { Button, TextField, Checkbox, Switch } from '@dashforge/tw';
|
|
62
|
+
|
|
63
|
+
export function SignUp() {
|
|
64
|
+
return (
|
|
65
|
+
<DashForm defaultValues={{ email: '', terms: false, newsletter: true }}>
|
|
66
|
+
<TextField
|
|
67
|
+
name="email"
|
|
68
|
+
label="Email"
|
|
69
|
+
type="email"
|
|
70
|
+
rules={{ required: 'Email is required' }}
|
|
71
|
+
required
|
|
72
|
+
fullWidth
|
|
73
|
+
/>
|
|
74
|
+
<Checkbox name="terms" label="I accept the Terms & Conditions" />
|
|
75
|
+
<Switch name="newsletter" label="Subscribe to the newsletter" />
|
|
76
|
+
<Button type="submit" variant="solid" color="primary">Sign up</Button>
|
|
77
|
+
</DashForm>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## F3 surface (tier-1)
|
|
83
|
+
|
|
84
|
+
| Component | Bridge integration | Notes |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `<Button>` | RBAC-only (action, no form state) | `variant` × `color` × `size`, `loading`, `fullWidth`, `asChild` (Radix Slot polymorphism). |
|
|
87
|
+
| `<TextField>` | Full form bridge | 7-slot TV recipe (root/label/requiredMark/inputWrapper/input/helperText/errorText). Layouts: `stacked` (default), `inline`. Floating label deferred. |
|
|
88
|
+
| `<Checkbox>` | Full form bridge | Radix `Checkbox.Root` + `Indicator`. Inline `<CheckIcon>` SVG, no icon dep. |
|
|
89
|
+
| `<Switch>` | Full form bridge | Radix `Switch.Root` + `Thumb`, translate-x animated. |
|
|
90
|
+
|
|
91
|
+
All four components mirror the MUI-side semantics at the bridge level:
|
|
92
|
+
same `name` / `rules` / `visibleWhen` / `access` props, same StrictMode-
|
|
93
|
+
safe unregister pattern, same per-field re-render isolation via
|
|
94
|
+
`useDashFieldMeta`.
|
|
95
|
+
|
|
96
|
+
## Override system
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<TextField
|
|
100
|
+
name="email"
|
|
101
|
+
label="Email"
|
|
102
|
+
// root override (raw classes — last wins via tailwind-merge)
|
|
103
|
+
sx="md:w-1/2"
|
|
104
|
+
// per-slot override (typed)
|
|
105
|
+
slotProps={{
|
|
106
|
+
input: { className: 'font-mono tracking-wide' },
|
|
107
|
+
label: { className: 'uppercase text-secondary-700' },
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`sx` is a `className` shortcut for the root slot (string or
|
|
113
|
+
`ClassValue` accepted by `clsx`). `slotProps` is the canonical
|
|
114
|
+
per-slot override path. Both go through the package's `cn()` (wraps
|
|
115
|
+
`clsx` + `tailwind-merge`) so override classes reliably beat the
|
|
116
|
+
variant defaults regardless of stylesheet order.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Common consumer pitfalls
|
|
121
|
+
|
|
122
|
+
The following are **not library bugs** — they're use-time issues that
|
|
123
|
+
emerge from how the host application is set up. Documented here so you
|
|
124
|
+
can avoid them or recognise the symptom quickly.
|
|
125
|
+
|
|
126
|
+
### 1. Labels / helper text appear centered
|
|
127
|
+
|
|
128
|
+
**Symptom.** Form labels and the `helperText` / `errorText` lines of
|
|
129
|
+
`<TextField>`, `<Checkbox>`, `<Switch>` render center-aligned, even
|
|
130
|
+
though the variants emit no `text-center` class.
|
|
131
|
+
|
|
132
|
+
**Root cause.** A parent element (typically `#root`, often a residue
|
|
133
|
+
of the Vite React template — `text-align: center` is set in the
|
|
134
|
+
default `src/index.css`) imposes a global text-align, and the
|
|
135
|
+
component's `<label>` / `<p>` inherit it because the variants do not
|
|
136
|
+
declare an explicit `text-align: left`.
|
|
137
|
+
|
|
138
|
+
**Fix.** In your application's global stylesheet, remove or scope down
|
|
139
|
+
the inherited centering:
|
|
140
|
+
|
|
141
|
+
```css
|
|
142
|
+
/* Before — Vite React template default */
|
|
143
|
+
#root {
|
|
144
|
+
text-align: center; /* leaks into every form component below */
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* After — restrict centering to the placeholder hero only */
|
|
148
|
+
#root {
|
|
149
|
+
/* nothing here */
|
|
150
|
+
}
|
|
151
|
+
.hero-section {
|
|
152
|
+
text-align: center;
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The library does **not** add `text-left` defensively to its variants:
|
|
157
|
+
this is a deliberate choice — components inherit normal text-align,
|
|
158
|
+
which is what a neutral parent provides.
|
|
159
|
+
|
|
160
|
+
### 2. Dark mode looks broken — surface ladder mismatch
|
|
161
|
+
|
|
162
|
+
**Symptom.** You call `setMode('dark')` (or `toggleMode()`) from
|
|
163
|
+
`@dashforge/tw-theme`, the `data-dash-tw-theme="dark"` attribute flips
|
|
164
|
+
on `<html>`, but the form looks washed-out — labels are barely visible
|
|
165
|
+
on the card, or the card itself stays bright white while everything
|
|
166
|
+
around it goes dark.
|
|
167
|
+
|
|
168
|
+
**Root cause.** This is a **page-level setup problem**, not a library
|
|
169
|
+
bug. All `@dashforge/tw` components use neutral-scale tokens
|
|
170
|
+
(`bg-neutral-50` for input surfaces, `text-neutral-900` for text)
|
|
171
|
+
which the `@dashforge/tw-tokens` dark theme inverts automatically
|
|
172
|
+
(`neutral-50` ↔ `neutral-950`, `neutral-100` ↔ `neutral-900`, etc.).
|
|
173
|
+
The library is fully dark-aware out of the box.
|
|
174
|
+
|
|
175
|
+
What goes wrong: the host page (or card container) uses literal
|
|
176
|
+
classes like `bg-white` or `text-black` that **don't** invert. The
|
|
177
|
+
ladder then breaks — components swap but the surrounding container
|
|
178
|
+
doesn't.
|
|
179
|
+
|
|
180
|
+
**Fix — use a 3-level elevation ladder of inverting neutral tokens
|
|
181
|
+
for page, card, and inputs.** All `bg-neutral-*` classes invert
|
|
182
|
+
automatically through the dashforge preset, so the same JSX produces
|
|
183
|
+
a coherent light AND dark layout without any `dark:` variant:
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
<DashforgeTailwindProvider>
|
|
187
|
+
{/* page = neutral-200 → #e5e5e5 light / #262626 dark */}
|
|
188
|
+
<main className="min-h-screen bg-neutral-200 p-8">
|
|
189
|
+
{/* card = neutral-100 → #f5f5f5 light / #171717 dark */}
|
|
190
|
+
<div className="rounded-lg bg-neutral-100 p-8 shadow-md border border-neutral-200">
|
|
191
|
+
{/* inputs = neutral-50 (built into the component variants)
|
|
192
|
+
→ #fafafa light / #0a0a0a dark */}
|
|
193
|
+
<TextField name="email" label="Email" />
|
|
194
|
+
<Checkbox name="terms" label="Accept" />
|
|
195
|
+
</div>
|
|
196
|
+
</main>
|
|
197
|
+
</DashforgeTailwindProvider>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The same JSX renders correctly in light AND dark mode. In light the
|
|
201
|
+
ladder goes outer-grayer → inner-brighter (standard elevation, "higher
|
|
202
|
+
surface = brighter"). In dark the ladder inverts to outer-lighter →
|
|
203
|
+
inner-darker ("inset feel"), which is the macOS Big Sur / modern dark-UI
|
|
204
|
+
convention.
|
|
205
|
+
|
|
206
|
+
**Anti-pattern to AVOID**: do NOT mix literal `bg-white` / `text-black`
|
|
207
|
+
into the elevation ladder, and do NOT use Tailwind's `dark:` variant
|
|
208
|
+
in your page — the dashforge preset handles dark mode through CSS
|
|
209
|
+
variable inversion, not through the standard Tailwind dark selector.
|
|
210
|
+
Adding `dark:bg-neutral-900` actually picks the WRONG end of the
|
|
211
|
+
inversion in dark mode (`neutral-900` inverts to `neutral-100` =
|
|
212
|
+
light grey) and breaks the layout.
|
|
213
|
+
|
|
214
|
+
**Alternative override (advanced):** if you need a specific input
|
|
215
|
+
on a non-standard surface, use `slotProps` to override that single
|
|
216
|
+
slot:
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
<TextField
|
|
220
|
+
name="email"
|
|
221
|
+
slotProps={{ inputWrapper: { className: 'bg-neutral-100' } }}
|
|
222
|
+
/>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Building + testing
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
nx build @dashforge/tw # rollup ESM + d.ts
|
|
231
|
+
nx test @dashforge/tw # vitest
|
|
232
|
+
nx typecheck @dashforge/tw # tsc --noEmit on tsconfig.lib.json
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
See the workspace root README for monorepo-wide commands.
|
|
236
|
+
|
|
237
|
+
## See also
|
|
238
|
+
|
|
239
|
+
- [`@dashforge/tw-theme`](../tw-theme/README.md) — Tailwind preset +
|
|
240
|
+
reactive theme provider + SSR helper.
|
|
241
|
+
- [`@dashforge/tw-tokens`](../tw-tokens/README.md) — token type
|
|
242
|
+
contracts + default light / dark themes.
|
|
243
|
+
- [`@dashforge/forms`](../forms/README.md) — form bridge consumed by
|
|
244
|
+
both ecosystems (MUI + TW).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AppShellProps } from './appShell.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Dashforge TW AppShell — top-level layout orchestrator.
|
|
4
|
+
*
|
|
5
|
+
* ┌──────────────────────────────────────────┐
|
|
6
|
+
* │ header │ ← `header` slot
|
|
7
|
+
* ├────────┬─────────────────────────────────┤
|
|
8
|
+
* │ │ │
|
|
9
|
+
* │ nav │ main │ ← `nav` + `children`
|
|
10
|
+
* │ │ │
|
|
11
|
+
* ├────────┴─────────────────────────────────┤
|
|
12
|
+
* │ footer │ ← `footer` slot
|
|
13
|
+
* └──────────────────────────────────────────┘
|
|
14
|
+
*
|
|
15
|
+
* **Responsive**:
|
|
16
|
+
* - `≥ md`: nav stays in the inline slot at the left.
|
|
17
|
+
* - `< md`: nav becomes a slide-in drawer toggled by `navOpen`.
|
|
18
|
+
* A backdrop closes the drawer on click (mirrors `<Dialog>` UX).
|
|
19
|
+
*
|
|
20
|
+
* **Body scroll lock**: when the mobile drawer is open we add
|
|
21
|
+
* `overflow-hidden` to `<body>` to prevent dual-scroll wobble. The
|
|
22
|
+
* effect cleans up on close + on unmount.
|
|
23
|
+
*
|
|
24
|
+
* **A11y**:
|
|
25
|
+
* - `<main>` landmark wraps the content area.
|
|
26
|
+
* - `<header>` / `<footer>` come for free from their HTML tags.
|
|
27
|
+
* - The mobile drawer + backdrop participate in the standard
|
|
28
|
+
* "click outside to close" pattern — `Escape` closes the drawer
|
|
29
|
+
* too (added via global keydown).
|
|
30
|
+
*/
|
|
31
|
+
export declare function AppShell(props: AppShellProps): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
//# sourceMappingURL=AppShell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../../../src/components/AppShell/AppShell.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,2CA+E5C"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { AppShellVariants } from './appShell.variants.js';
|
|
3
|
+
export interface AppShellSlotProps {
|
|
4
|
+
root?: {
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
header?: {
|
|
8
|
+
className?: string;
|
|
9
|
+
};
|
|
10
|
+
nav?: {
|
|
11
|
+
className?: string;
|
|
12
|
+
};
|
|
13
|
+
navMobile?: {
|
|
14
|
+
className?: string;
|
|
15
|
+
};
|
|
16
|
+
main?: {
|
|
17
|
+
className?: string;
|
|
18
|
+
};
|
|
19
|
+
footer?: {
|
|
20
|
+
className?: string;
|
|
21
|
+
};
|
|
22
|
+
backdrop?: {
|
|
23
|
+
className?: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Props for `<AppShell>`.
|
|
28
|
+
*
|
|
29
|
+
* Top-level layout orchestrator with 4 named slots:
|
|
30
|
+
*
|
|
31
|
+
* - `header` (top, sticky)
|
|
32
|
+
* - `nav` (left side, fixed-width on desktop, drawer on mobile)
|
|
33
|
+
* - `footer` (bottom, non-sticky)
|
|
34
|
+
* - `children` (main content, scrolls independently)
|
|
35
|
+
*
|
|
36
|
+
* Responsive behavior:
|
|
37
|
+
* - **≥ md (768px)**: nav is rendered inline at the left.
|
|
38
|
+
* - **< md**: nav slides in as an overlay drawer when
|
|
39
|
+
* `navOpen={true}` (controlled).
|
|
40
|
+
*
|
|
41
|
+
* The shell is router-agnostic — pass any nav/header content. Typical
|
|
42
|
+
* pairing is `<LeftNav>` + `<TopBar>` (with a hamburger button in
|
|
43
|
+
* `TopBar.start` that flips `navOpen`).
|
|
44
|
+
*/
|
|
45
|
+
export interface AppShellProps extends AppShellVariants {
|
|
46
|
+
header?: ReactNode;
|
|
47
|
+
nav?: ReactNode;
|
|
48
|
+
footer?: ReactNode;
|
|
49
|
+
children?: ReactNode;
|
|
50
|
+
/**
|
|
51
|
+
* Mobile drawer open state. Controlled — provide
|
|
52
|
+
* `onNavOpenChange` to update. When `undefined`, the mobile drawer
|
|
53
|
+
* is always closed (consumer hasn't wired up the toggle yet).
|
|
54
|
+
*/
|
|
55
|
+
navOpen?: boolean;
|
|
56
|
+
onNavOpenChange?: (open: boolean) => void;
|
|
57
|
+
/** Root className shortcut. */
|
|
58
|
+
sx?: string;
|
|
59
|
+
/** Per-slot className overrides. */
|
|
60
|
+
slotProps?: AppShellSlotProps;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=appShell.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appShell.types.d.ts","sourceRoot":"","sources":["../../../src/components/AppShell/appShell.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChC,GAAG,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7B,SAAS,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChC,QAAQ,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,+BAA+B;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type VariantProps } from 'tailwind-variants';
|
|
2
|
+
/**
|
|
3
|
+
* Tailwind-variants recipe for `<AppShell>`.
|
|
4
|
+
*
|
|
5
|
+
* Slots:
|
|
6
|
+
* - `root` — outer flex column (full viewport)
|
|
7
|
+
* - `header` — top region
|
|
8
|
+
* - `body` — flex row holding nav + main
|
|
9
|
+
* - `nav` — desktop nav rail (md+)
|
|
10
|
+
* - `navMobile` — mobile drawer (slide-in)
|
|
11
|
+
* - `main` — scrollable content area
|
|
12
|
+
* - `footer` — bottom region
|
|
13
|
+
* - `backdrop` — semi-opaque overlay behind the mobile drawer
|
|
14
|
+
*/
|
|
15
|
+
export declare const appShellVariants: import("tailwind-variants").TVReturnType<{
|
|
16
|
+
navOpen: {
|
|
17
|
+
true: {
|
|
18
|
+
navMobile: string;
|
|
19
|
+
backdrop: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
}, {
|
|
23
|
+
root: string;
|
|
24
|
+
header: string;
|
|
25
|
+
body: string;
|
|
26
|
+
nav: string;
|
|
27
|
+
navMobile: string[];
|
|
28
|
+
main: string;
|
|
29
|
+
footer: string;
|
|
30
|
+
backdrop: string[];
|
|
31
|
+
}, undefined, {
|
|
32
|
+
navOpen: {
|
|
33
|
+
true: {
|
|
34
|
+
navMobile: string;
|
|
35
|
+
backdrop: string;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
}, {
|
|
39
|
+
root: string;
|
|
40
|
+
header: string;
|
|
41
|
+
body: string;
|
|
42
|
+
nav: string;
|
|
43
|
+
navMobile: string[];
|
|
44
|
+
main: string;
|
|
45
|
+
footer: string;
|
|
46
|
+
backdrop: string[];
|
|
47
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
48
|
+
navOpen: {
|
|
49
|
+
true: {
|
|
50
|
+
navMobile: string;
|
|
51
|
+
backdrop: string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
}, {
|
|
55
|
+
root: string;
|
|
56
|
+
header: string;
|
|
57
|
+
body: string;
|
|
58
|
+
nav: string;
|
|
59
|
+
navMobile: string[];
|
|
60
|
+
main: string;
|
|
61
|
+
footer: string;
|
|
62
|
+
backdrop: string[];
|
|
63
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
64
|
+
export type AppShellVariants = VariantProps<typeof appShellVariants>;
|
|
65
|
+
//# sourceMappingURL=appShell.variants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appShell.variants.d.ts","sourceRoot":"","sources":["../../../src/components/AppShell/appShell.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAM,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2CA8B3B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AutocompleteOption, AutocompleteProps } from './autocomplete.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Dashforge TW Autocomplete — bridge-integrated single-select combobox.
|
|
4
|
+
*
|
|
5
|
+
* **Implementation note (F5-A, rev. 2)**
|
|
6
|
+
*
|
|
7
|
+
* The first revision wrapped `react-aria-components`' `<ComboBox>` to get
|
|
8
|
+
* AAA-grade a11y for free. In practice React Aria's internal state
|
|
9
|
+
* machine fought every controlled-state pattern we tried (the input text
|
|
10
|
+
* would not clear when `selectedKey` went to `null`, even with a forced
|
|
11
|
+
* remount via `key` bumping). To get deterministic behaviour we own all
|
|
12
|
+
* of the state ourselves:
|
|
13
|
+
*
|
|
14
|
+
* - `inputValue` — the visible text in the `<input>`
|
|
15
|
+
* - `isOpen` — popover visibility
|
|
16
|
+
* - `highlightedIndex` — keyboard navigation cursor
|
|
17
|
+
*
|
|
18
|
+
* A11y is still solid:
|
|
19
|
+
* - `role="combobox"` + `aria-autocomplete="list"` on the input
|
|
20
|
+
* - `aria-expanded`, `aria-controls`, `aria-activedescendant`
|
|
21
|
+
* - `role="listbox"` / `role="option"` with `aria-selected`
|
|
22
|
+
* - Full keyboard nav (↑/↓ navigate, Enter selects, Escape closes,
|
|
23
|
+
* Home/End jump, Tab closes, click-outside closes)
|
|
24
|
+
* - Required field gets `aria-required="true"`
|
|
25
|
+
*
|
|
26
|
+
* F5-A scope: single-select, static options, contains-substring filter
|
|
27
|
+
* (case-insensitive). Multi-select, free-solo text, generic option
|
|
28
|
+
* shapes, and async runtime options (`optionsFromFieldData`) are
|
|
29
|
+
* deferred to F5-A-bis.
|
|
30
|
+
*/
|
|
31
|
+
export declare function Autocomplete<TOption = AutocompleteOption>(props: AutocompleteProps<TOption>): import("react/jsx-runtime").JSX.Element | null;
|
|
32
|
+
//# sourceMappingURL=Autocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Autocomplete.d.ts","sourceRoot":"","sources":["../../../src/components/Autocomplete/Autocomplete.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,yBAAyB,CAAC;AAuCjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAG,kBAAkB,EACvD,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,kDAu4BlC"}
|