gbs-add-block 2.1.0 → 2.3.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/.gbs/skills/gbs-components/SKILL.md +190 -134
- package/.gbs/skills/gbs-components/references/install.md +25 -3
- package/.gbs/skills/gbs-components/references/styling.md +246 -207
- package/CHANGELOG.md +74 -0
- package/README.md +154 -23
- package/index.cjs +212 -3
- package/package.json +41 -10
- package/schema/passport-v1.schema.json +204 -0
- package/source/beta-components/accordion/passport.json +259 -0
- package/source/beta-components/accordion/styles.css +207 -208
- package/source/beta-components/alert/passport.json +250 -0
- package/source/beta-components/alert/styles.css +154 -155
- package/source/beta-components/avatar/passport.json +294 -0
- package/source/beta-components/avatar/styles.css +225 -226
- package/source/beta-components/badge/passport.json +332 -0
- package/source/beta-components/badge/styles.css +203 -204
- package/source/beta-components/breadcrumb/passport.json +243 -0
- package/source/beta-components/breadcrumb/styles.css +138 -140
- package/source/beta-components/button/passport.json +402 -0
- package/source/beta-components/button/passport.manual.json +31 -0
- package/source/beta-components/button/styles.css +232 -234
- package/source/beta-components/card/passport.json +337 -0
- package/source/beta-components/card/styles.css +230 -232
- package/source/beta-components/checkbox/passport.json +456 -0
- package/source/beta-components/checkbox/styles.css +211 -213
- package/source/beta-components/combobox/passport.json +456 -0
- package/source/beta-components/combobox/styles.css +419 -417
- package/source/beta-components/data-grid/agent/coerce.ts +368 -0
- package/source/beta-components/data-grid/agent/contract.ts +410 -0
- package/source/beta-components/data-grid/agent/dataset.ts +92 -0
- package/source/beta-components/data-grid/agent/engine.ts +470 -0
- package/source/beta-components/data-grid/agent/executors.ts +155 -0
- package/source/beta-components/data-grid/agent/index.ts +79 -0
- package/source/beta-components/data-grid/agent/intent.ts +324 -0
- package/source/beta-components/data-grid/agent/operations.ts +335 -0
- package/source/beta-components/data-grid/agent/validate.ts +630 -0
- package/source/beta-components/data-grid/agent/webmcp.ts +107 -0
- package/source/beta-components/data-grid/index.ts +14 -7
- package/source/beta-components/data-grid/passport.json +1051 -0
- package/source/beta-components/data-grid/passport.manual.json +255 -0
- package/source/beta-components/data-grid/react/AskGrid.tsx +164 -0
- package/source/beta-components/data-grid/react/DataGrid.tsx +39 -0
- package/source/beta-components/data-grid/styles.css +874 -716
- package/source/beta-components/date-picker/passport.json +407 -0
- package/source/beta-components/date-picker/styles.css +445 -446
- package/source/beta-components/dialog/passport.json +344 -0
- package/source/beta-components/dialog/styles.css +280 -279
- package/source/beta-components/file-uploader/passport.json +518 -0
- package/source/beta-components/file-uploader/styles.css +394 -396
- package/source/beta-components/input/passport.json +536 -0
- package/source/beta-components/input/styles.css +295 -297
- package/source/beta-components/menu/passport.json +322 -0
- package/source/beta-components/menu/styles.css +224 -223
- package/source/beta-components/modal/passport.json +289 -0
- package/source/beta-components/modal/styles.css +241 -240
- package/source/beta-components/number-input/passport.json +541 -0
- package/source/beta-components/number-input/styles.css +230 -231
- package/source/beta-components/popover/passport.json +238 -0
- package/source/beta-components/popover/styles.css +148 -147
- package/source/beta-components/progress/passport.json +270 -0
- package/source/beta-components/progress/styles.css +200 -201
- package/source/beta-components/radio-group/passport.json +477 -0
- package/source/beta-components/radio-group/styles.css +269 -270
- package/source/beta-components/shared/core/agent/adapter.ts +65 -0
- package/source/beta-components/shared/core/agent/history.ts +120 -0
- package/source/beta-components/shared/core/agent/index.ts +46 -0
- package/source/beta-components/shared/core/agent/numbers.ts +217 -0
- package/source/beta-components/shared/core/agent/schema.ts +180 -0
- package/source/beta-components/shared/core/agent/types.ts +169 -0
- package/source/beta-components/shared/core/agent/webmcp.ts +328 -0
- package/source/beta-components/shared/index.ts +9 -0
- package/source/beta-components/shared/react/GramproAIProvider.tsx +50 -0
- package/source/beta-components/shared/react/useAskAgent.ts +217 -0
- package/source/beta-components/shared/styles.css +79 -0
- package/source/beta-components/shared/version.json +4 -4
- package/source/beta-components/shared/version.ts +6 -6
- package/source/beta-components/skeleton/passport.json +251 -0
- package/source/beta-components/skeleton/styles.css +185 -187
- package/source/beta-components/spinner/passport.json +245 -0
- package/source/beta-components/spinner/styles.css +173 -174
- package/source/beta-components/switch/passport.json +421 -0
- package/source/beta-components/switch/styles.css +227 -229
- package/source/beta-components/tabs/passport.json +315 -0
- package/source/beta-components/tabs/styles.css +263 -264
- package/source/beta-components/textarea/passport.json +382 -0
- package/source/beta-components/textarea/styles.css +158 -160
- package/source/beta-components/toaster/passport.json +221 -0
- package/source/beta-components/toaster/styles.css +282 -282
- package/source/beta-components/tooltip/passport.json +170 -0
- package/source/beta-components/tooltip/styles.css +71 -73
- package/tools/env.cjs +61 -0
- package/tools/passport/cli.cjs +79 -0
- package/tools/passport/extract.cjs +493 -0
- package/tools/passport/index.cjs +185 -0
- package/tools/passport/merge.cjs +131 -0
- package/tools/passport/policy.cjs +65 -0
- package/tools/passport/validate.cjs +277 -0
- package/tools/ts-require.cjs +79 -0
- package/source/beta-components/accordion/__tests__/core.test.ts +0 -58
- package/source/beta-components/alert/__tests__/core.test.ts +0 -17
- package/source/beta-components/avatar/__tests__/core.test.ts +0 -88
- package/source/beta-components/badge/__tests__/core.test.ts +0 -46
- package/source/beta-components/breadcrumb/__tests__/core.test.ts +0 -58
- package/source/beta-components/button/__tests__/core.test.ts +0 -31
- package/source/beta-components/card/__tests__/core.test.ts +0 -57
- package/source/beta-components/checkbox/__tests__/core.test.ts +0 -40
- package/source/beta-components/combobox/__tests__/core.test.ts +0 -134
- package/source/beta-components/data-grid/__tests__/core.test.ts +0 -356
- package/source/beta-components/data-grid/__tests__/export.test.ts +0 -70
- package/source/beta-components/data-grid/__tests__/pdf.test.ts +0 -209
- package/source/beta-components/date-picker/__tests__/core.test.ts +0 -273
- package/source/beta-components/dialog/__tests__/core.test.ts +0 -86
- package/source/beta-components/file-uploader/__tests__/core.test.ts +0 -395
- package/source/beta-components/input/__tests__/core.test.ts +0 -75
- package/source/beta-components/menu/__tests__/core.test.ts +0 -120
- package/source/beta-components/modal/__tests__/core.test.ts +0 -55
- package/source/beta-components/number-input/__tests__/core.test.ts +0 -151
- package/source/beta-components/progress/__tests__/core.test.ts +0 -56
- package/source/beta-components/radio-group/__tests__/core.test.ts +0 -64
- package/source/beta-components/shared/__tests__/boundaries.test.ts +0 -95
- package/source/beta-components/shared/__tests__/core.test.ts +0 -55
- package/source/beta-components/shared/__tests__/position.test.ts +0 -143
- package/source/beta-components/skeleton/__tests__/core.test.ts +0 -41
- package/source/beta-components/spinner/__tests__/core.test.ts +0 -48
- package/source/beta-components/switch/__tests__/core.test.ts +0 -64
- package/source/beta-components/tabs/__tests__/core.test.ts +0 -51
- package/source/beta-components/textarea/__tests__/core.test.ts +0 -38
- package/source/beta-components/toaster/__tests__/core.test.ts +0 -256
- package/source/beta-components/tooltip/__tests__/core.test.ts +0 -42
|
@@ -1,207 +1,246 @@
|
|
|
1
|
-
# Styling
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## 1. Stylesheets are per component
|
|
8
|
-
|
|
9
|
-
Each folder has its own `styles.css`. Put the ones you use in the project's
|
|
10
|
-
**global** stylesheet — `src/index.css` in Vite, the root layout's CSS in Next —
|
|
11
|
-
once each:
|
|
12
|
-
|
|
13
|
-
```css
|
|
14
|
-
@import "../component-lib/button/styles.css";
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
**Never import a stylesheet from a component file.** `import
|
|
18
|
-
"component-lib/button/styles.css"` inside a `.tsx` does bundle, but it makes CSS
|
|
19
|
-
order depend on module import order — which decides whether Tailwind utilities
|
|
20
|
-
still beat the component's own rules — and a lazy-loaded component then pulls its
|
|
21
|
-
styles in late, flashing unstyled. One global import per component, nowhere else.
|
|
22
|
-
|
|
23
|
-
Nothing renders correctly without it — the components emit class names only.
|
|
24
|
-
|
|
25
|
-
## 2. Theme with `--gbs-*` on `:root`
|
|
26
|
-
|
|
27
|
-
One set of variables themes every component at once. This is the whole theming
|
|
28
|
-
API; reach for the other levels only when it is not enough.
|
|
29
|
-
|
|
30
|
-
```css
|
|
31
|
-
:root {
|
|
32
|
-
--gbs-accent: #7c3aed;
|
|
33
|
-
--gbs-accent-soft: #f3e8ff;
|
|
34
|
-
--gbs-radius: 10px;
|
|
35
|
-
--gbs-font-size: 14px;
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Set them on `:root`, not inside a component — components read them through
|
|
40
|
-
inheritance, so anything set on an ancestor reaches every control beneath it.
|
|
41
|
-
|
|
42
|
-
### Resolution order
|
|
43
|
-
|
|
44
|
-
Each component variable falls through this chain, stopping at the first set:
|
|
45
|
-
|
|
46
|
-
1. **The component's own variable** — `--in-accent`, `--dg-accent`, `--ck-border`.
|
|
47
|
-
Set this to change one component, or one instance.
|
|
48
|
-
2. **The shared variable** — `--gbs-accent`. The one you normally set.
|
|
49
|
-
3. **The DataGrid's variable** — `--dg-accent`, when the grid's stylesheet is
|
|
50
|
-
loaded. Kept for projects that themed the grid before the shared variables existed.
|
|
51
|
-
4. **The built-in default** — a `light-dark()` pair, so it follows the page's
|
|
52
|
-
colour scheme.
|
|
53
|
-
|
|
54
|
-
```css
|
|
55
|
-
.in-root { --in-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa))); }
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### The shared variables
|
|
59
|
-
|
|
60
|
-
Defaults written light / dark.
|
|
61
|
-
|
|
62
|
-
**Surfaces and text:** `--gbs-bg` (`#ffffff`/`#0b0b0e`), `--gbs-fg`
|
|
63
|
-
(`#18181b`/`#f4f4f5`), `--gbs-muted` (`#71717a`/`#a1a1aa`), `--gbs-subtle`
|
|
64
|
-
(`#f4f4f5`/`#1c1c20`), `--gbs-hover` (`#f4f4f5`/`#1f1f23`), `--gbs-input-bg`
|
|
65
|
-
(`#ffffff`/`#121216`), `--gbs-readonly-bg` (`#fafafa`/`#0e0e12`),
|
|
66
|
-
`--gbs-header-bg` (`#fafafa`/`#111114`), `--gbs-header-fg` (`#3f3f46`/`#d4d4d8`).
|
|
67
|
-
|
|
68
|
-
**Borders and shape:** `--gbs-border` (`#e4e4e7`/`#27272a`),
|
|
69
|
-
`--gbs-border-subtle` (`#f0f0f2`/`#1c1c20`), `--gbs-border-control`
|
|
70
|
-
(`#a1a1aa`/`#52525b`), `--gbs-radius` (`8px`), `--gbs-font-size` (`13px`),
|
|
71
|
-
`--gbs-shadow`, `--gbs-backdrop`.
|
|
72
|
-
|
|
73
|
-
**Accent and status:** `--gbs-accent`, `--gbs-accent-soft`,
|
|
74
|
-
`--gbs-accent-strong`, `--gbs-accent-fg`, `--gbs-focus`, `--gbs-danger`,
|
|
75
|
-
`--gbs-danger-fg`, `--gbs-success`, `--gbs-warning`, `--gbs-info`.
|
|
76
|
-
|
|
77
|
-
**Grid-specific:** `--gbs-row-alt`, `--gbs-row-hover`, `--gbs-row-selected`,
|
|
78
|
-
`--gbs-row-selected-hover`, `--gbs-cell-px`, `--gbs-pin-shadow`,
|
|
79
|
-
`--gbs-skeleton`, `--gbs-tab-fg`, `--gbs-tooltip-bg`, `--gbs-tooltip-fg`.
|
|
80
|
-
|
|
81
|
-
### Per-component prefixes
|
|
82
|
-
|
|
83
|
-
To change one component only, set its own prefix on its root class:
|
|
84
|
-
|
|
85
|
-
| Component | Prefix | Root class |
|
|
86
|
-
| --- | --- | --- |
|
|
87
|
-
| DataGrid | `--dg-*` | `.dg-root` |
|
|
88
|
-
| Combobox | `--cb-*` | `.cb-root` |
|
|
89
|
-
| Toaster | `--ts-*` | `.ts-region` |
|
|
90
|
-
| Input | `--in-*` | `.in-root` |
|
|
91
|
-
| Button | `--bt-*` | `.bt-root` |
|
|
92
|
-
|
|
93
|
-
```css
|
|
94
|
-
.cb-root { --cb-accent: #7c3aed; --cb-radius: 12px; }
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Toasts render on `<body>`, so grid/shared values they inherit must be set on
|
|
98
|
-
`:root`.
|
|
99
|
-
|
|
100
|
-
## 3. Slot classes
|
|
101
|
-
|
|
102
|
-
`className` goes to the root element only. To reach an inner part, use
|
|
103
|
-
`classNames`, a map of slot name to class string:
|
|
104
|
-
|
|
105
|
-
```tsx
|
|
106
|
-
<Input label="Email" classNames={{ root: "mb-4", label: "font-semibold", input: "font-mono" }} />
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Slots are per component and listed in each `react/props.ts` and in this skill's
|
|
110
|
-
`forms.md` / `overlays.md` / `data-display.md`. Passing a slot that does not
|
|
111
|
-
exist is silently ignored, so check the list.
|
|
112
|
-
|
|
113
|
-
Classes are joined with `cx` from `shared/core/cx.ts`, which drops falsy values
|
|
114
|
-
— a conditional that evaluates to `undefined` contributes nothing.
|
|
115
|
-
|
|
116
|
-
## 4. Cascade layers and Tailwind
|
|
117
|
-
|
|
118
|
-
Every `styles.css` ships
|
|
119
|
-
|
|
120
|
-
```css
|
|
121
|
-
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
##
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
1
|
+
# Styling
|
|
2
|
+
|
|
3
|
+
These components are styled. They ship a default look, and you replace it at
|
|
4
|
+
three levels: CSS variables, slot classes, and state attributes. Nothing is
|
|
5
|
+
`!important` and nothing needs overriding by specificity.
|
|
6
|
+
|
|
7
|
+
## 1. Stylesheets are per component
|
|
8
|
+
|
|
9
|
+
Each folder has its own `styles.css`. Put the ones you use in the project's
|
|
10
|
+
**global** stylesheet — `src/index.css` in Vite, the root layout's CSS in Next —
|
|
11
|
+
once each:
|
|
12
|
+
|
|
13
|
+
```css
|
|
14
|
+
@import "../component-lib/button/styles.css";
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Never import a stylesheet from a component file.** `import
|
|
18
|
+
"component-lib/button/styles.css"` inside a `.tsx` does bundle, but it makes CSS
|
|
19
|
+
order depend on module import order — which decides whether Tailwind utilities
|
|
20
|
+
still beat the component's own rules — and a lazy-loaded component then pulls its
|
|
21
|
+
styles in late, flashing unstyled. One global import per component, nowhere else.
|
|
22
|
+
|
|
23
|
+
Nothing renders correctly without it — the components emit class names only.
|
|
24
|
+
|
|
25
|
+
## 2. Theme with `--gbs-*` on `:root`
|
|
26
|
+
|
|
27
|
+
One set of variables themes every component at once. This is the whole theming
|
|
28
|
+
API; reach for the other levels only when it is not enough.
|
|
29
|
+
|
|
30
|
+
```css
|
|
31
|
+
:root {
|
|
32
|
+
--gbs-accent: #7c3aed;
|
|
33
|
+
--gbs-accent-soft: #f3e8ff;
|
|
34
|
+
--gbs-radius: 10px;
|
|
35
|
+
--gbs-font-size: 14px;
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Set them on `:root`, not inside a component — components read them through
|
|
40
|
+
inheritance, so anything set on an ancestor reaches every control beneath it.
|
|
41
|
+
|
|
42
|
+
### Resolution order
|
|
43
|
+
|
|
44
|
+
Each component variable falls through this chain, stopping at the first set:
|
|
45
|
+
|
|
46
|
+
1. **The component's own variable** — `--in-accent`, `--dg-accent`, `--ck-border`.
|
|
47
|
+
Set this to change one component, or one instance.
|
|
48
|
+
2. **The shared variable** — `--gbs-accent`. The one you normally set.
|
|
49
|
+
3. **The DataGrid's variable** — `--dg-accent`, when the grid's stylesheet is
|
|
50
|
+
loaded. Kept for projects that themed the grid before the shared variables existed.
|
|
51
|
+
4. **The built-in default** — a `light-dark()` pair, so it follows the page's
|
|
52
|
+
colour scheme.
|
|
53
|
+
|
|
54
|
+
```css
|
|
55
|
+
.in-root { --in-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa))); }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### The shared variables
|
|
59
|
+
|
|
60
|
+
Defaults written light / dark.
|
|
61
|
+
|
|
62
|
+
**Surfaces and text:** `--gbs-bg` (`#ffffff`/`#0b0b0e`), `--gbs-fg`
|
|
63
|
+
(`#18181b`/`#f4f4f5`), `--gbs-muted` (`#71717a`/`#a1a1aa`), `--gbs-subtle`
|
|
64
|
+
(`#f4f4f5`/`#1c1c20`), `--gbs-hover` (`#f4f4f5`/`#1f1f23`), `--gbs-input-bg`
|
|
65
|
+
(`#ffffff`/`#121216`), `--gbs-readonly-bg` (`#fafafa`/`#0e0e12`),
|
|
66
|
+
`--gbs-header-bg` (`#fafafa`/`#111114`), `--gbs-header-fg` (`#3f3f46`/`#d4d4d8`).
|
|
67
|
+
|
|
68
|
+
**Borders and shape:** `--gbs-border` (`#e4e4e7`/`#27272a`),
|
|
69
|
+
`--gbs-border-subtle` (`#f0f0f2`/`#1c1c20`), `--gbs-border-control`
|
|
70
|
+
(`#a1a1aa`/`#52525b`), `--gbs-radius` (`8px`), `--gbs-font-size` (`13px`),
|
|
71
|
+
`--gbs-shadow`, `--gbs-backdrop`.
|
|
72
|
+
|
|
73
|
+
**Accent and status:** `--gbs-accent`, `--gbs-accent-soft`,
|
|
74
|
+
`--gbs-accent-strong`, `--gbs-accent-fg`, `--gbs-focus`, `--gbs-danger`,
|
|
75
|
+
`--gbs-danger-fg`, `--gbs-success`, `--gbs-warning`, `--gbs-info`.
|
|
76
|
+
|
|
77
|
+
**Grid-specific:** `--gbs-row-alt`, `--gbs-row-hover`, `--gbs-row-selected`,
|
|
78
|
+
`--gbs-row-selected-hover`, `--gbs-cell-px`, `--gbs-pin-shadow`,
|
|
79
|
+
`--gbs-skeleton`, `--gbs-tab-fg`, `--gbs-tooltip-bg`, `--gbs-tooltip-fg`.
|
|
80
|
+
|
|
81
|
+
### Per-component prefixes
|
|
82
|
+
|
|
83
|
+
To change one component only, set its own prefix on its root class:
|
|
84
|
+
|
|
85
|
+
| Component | Prefix | Root class |
|
|
86
|
+
| --- | --- | --- |
|
|
87
|
+
| DataGrid | `--dg-*` | `.dg-root` |
|
|
88
|
+
| Combobox | `--cb-*` | `.cb-root` |
|
|
89
|
+
| Toaster | `--ts-*` | `.ts-region` |
|
|
90
|
+
| Input | `--in-*` | `.in-root` |
|
|
91
|
+
| Button | `--bt-*` | `.bt-root` |
|
|
92
|
+
|
|
93
|
+
```css
|
|
94
|
+
.cb-root { --cb-accent: #7c3aed; --cb-radius: 12px; }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Toasts render on `<body>`, so grid/shared values they inherit must be set on
|
|
98
|
+
`:root`.
|
|
99
|
+
|
|
100
|
+
## 3. Slot classes
|
|
101
|
+
|
|
102
|
+
`className` goes to the root element only. To reach an inner part, use
|
|
103
|
+
`classNames`, a map of slot name to class string:
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
<Input label="Email" classNames={{ root: "mb-4", label: "font-semibold", input: "font-mono" }} />
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Slots are per component and listed in each `react/props.ts` and in this skill's
|
|
110
|
+
`forms.md` / `overlays.md` / `data-display.md`. Passing a slot that does not
|
|
111
|
+
exist is silently ignored, so check the list.
|
|
112
|
+
|
|
113
|
+
Classes are joined with `cx` from `shared/core/cx.ts`, which drops falsy values
|
|
114
|
+
— a conditional that evaluates to `undefined` contributes nothing.
|
|
115
|
+
|
|
116
|
+
## 4. Cascade layers and Tailwind
|
|
117
|
+
|
|
118
|
+
Every `styles.css` ships **unlayered** — no `@layer` wrapper anywhere:
|
|
119
|
+
|
|
120
|
+
```css
|
|
121
|
+
.bt-root { /* the component's rules */ }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
That is deliberate. An unlayered rule beats every layered rule regardless of
|
|
125
|
+
specificity, so a layered library loses to any unlayered reset: Tailwind v3's
|
|
126
|
+
preflight and Bootstrap's Reboot both strip borders, padding and radii off
|
|
127
|
+
layered component rules. Unlayered, a class selector beats `*` on ordinary
|
|
128
|
+
specificity and both work with no setup.
|
|
129
|
+
|
|
130
|
+
The app imports the generated barrel once:
|
|
131
|
+
|
|
132
|
+
```css
|
|
133
|
+
@import "./component-lib/gbs.css";
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
With **Tailwind v4** — and only v4, which layers its own utilities — import it
|
|
137
|
+
after the framework and into Tailwind's components layer, so utilities still
|
|
138
|
+
win:
|
|
139
|
+
|
|
140
|
+
```css
|
|
141
|
+
@import "tailwindcss";
|
|
142
|
+
@import "./component-lib/gbs.css" layer(components);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Both the order and the `layer()` matter. Imported before the framework, the
|
|
146
|
+
`components` layer registers first and Tailwind's preflight lands after it,
|
|
147
|
+
which strips the component rules. Imported without `layer()`, the unlayered
|
|
148
|
+
rules outrank the utilities and `className` stops overriding them.
|
|
149
|
+
|
|
150
|
+
Tailwind **v3** needs neither: it emits utilities unlayered, after our CSS, so
|
|
151
|
+
source order already decides. A project with no CSS framework needs neither.
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
<Button className="w-full sm:w-auto" classNames={{ content: "gap-3" }}>Save</Button>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Do not use `!important`, and do not write selectors against internal class names
|
|
158
|
+
(`.bt-root`, `.dg-cell`) in app CSS — they are implementation detail. Use the
|
|
159
|
+
variables or the slots.
|
|
160
|
+
|
|
161
|
+
## 4b. Scrollbars
|
|
162
|
+
|
|
163
|
+
Every scrolling surface in the kit is thin by default, using the standard
|
|
164
|
+
`scrollbar-width` / `scrollbar-color` properties (Baseline since December 2024)
|
|
165
|
+
rather than `::-webkit-scrollbar`. Four tokens control all of them:
|
|
166
|
+
|
|
167
|
+
```css
|
|
168
|
+
:root {
|
|
169
|
+
--gbs-scrollbar-width: thin; /* auto | thin | none */
|
|
170
|
+
--gbs-scrollbar-thumb: ...; /* derived from --gbs-accent */
|
|
171
|
+
--gbs-scrollbar-thumb-hover: ...;
|
|
172
|
+
--gbs-scrollbar-track: transparent;
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Set them on `:root` to restyle every scrollbar, or on one element for one.
|
|
177
|
+
`scrollbar-width` takes no length — only `auto | thin | none`.
|
|
178
|
+
|
|
179
|
+
For your own scrolling areas, add `class="gbs-scroll"` to match. The kit never
|
|
180
|
+
touches scrollbars it was not asked to: an unrelated scroll container keeps the
|
|
181
|
+
browser default.
|
|
182
|
+
|
|
183
|
+
## 5. Unlayered resets (Bootstrap, Normalize)
|
|
184
|
+
|
|
185
|
+
Any stylesheet that ships **unlayered** beats every layered rule regardless of
|
|
186
|
+
specificity — the cascade settles layers before specificity. So Bootstrap's
|
|
187
|
+
Reboot (`button { border-radius: 0 }`, `button, input, textarea { font-size:
|
|
188
|
+
inherit }`) overrides our classes, and import order does not help.
|
|
189
|
+
|
|
190
|
+
Fix it in the project's global CSS by giving the reset its own layer, named
|
|
191
|
+
before `gbs`:
|
|
192
|
+
|
|
193
|
+
```css
|
|
194
|
+
@layer bootstrap, gbs, app, utilities;
|
|
195
|
+
@import url("bootstrap/dist/css/bootstrap.min.css") layer(bootstrap);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Only components whose root is a native form element are affected (Button,
|
|
199
|
+
Textarea). Class names never collide — ours are two-letter prefixed.
|
|
200
|
+
|
|
201
|
+
## 6. State attributes
|
|
202
|
+
|
|
203
|
+
Components expose their state as `data-*` attributes, so you can style states
|
|
204
|
+
without tracking them in React.
|
|
205
|
+
|
|
206
|
+
| Attribute | Where |
|
|
207
|
+
| --- | --- |
|
|
208
|
+
| `data-state="open"` / `"closing"` | Combobox, Popover, Menu, Modal, toasts |
|
|
209
|
+
| `data-side` | Popover, Menu, Tooltip — the side it settled on after flipping |
|
|
210
|
+
| `data-size` | Controls that take a `size` |
|
|
211
|
+
| `data-invalid`, `data-disabled` | Form controls |
|
|
212
|
+
| `data-active`, `data-selected` | Combobox options, grid cells and rows |
|
|
213
|
+
| `data-editing`, `data-pinned`, `data-density` | DataGrid |
|
|
214
|
+
| `data-type`, `data-custom`, `data-swiping` | Toasts |
|
|
215
|
+
| `data-position` | Toaster region |
|
|
216
|
+
| `aria-sort` | DataGrid header cells |
|
|
217
|
+
|
|
218
|
+
```css
|
|
219
|
+
.cb-option[data-active] { outline: 2px solid var(--gbs-focus); }
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## 7. Dark mode
|
|
223
|
+
|
|
224
|
+
Colours are `light-dark()` pairs driven by the page's `color-scheme`, so the
|
|
225
|
+
default is whatever the device prefers. To pin it, set `color-scheme` — the
|
|
226
|
+
components follow:
|
|
227
|
+
|
|
228
|
+
```css
|
|
229
|
+
:root { color-scheme: light dark; } /* follow the device */
|
|
230
|
+
:root[data-theme="dark"] { color-scheme: dark; }
|
|
231
|
+
:root[data-theme="light"] { color-scheme: light; }
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
The DataGrid additionally treats a `.dark` or `[data-theme="dark"]` ancestor as
|
|
235
|
+
forcing a scheme.
|
|
236
|
+
|
|
237
|
+
Do not maintain a second palette for dark mode. Override the `--gbs-*` variables
|
|
238
|
+
with `light-dark()` pairs, or set them inside your own `[data-theme="dark"]`
|
|
239
|
+
block, and every component follows.
|
|
240
|
+
|
|
241
|
+
## 8. Right-to-left
|
|
242
|
+
|
|
243
|
+
The components use logical properties and read `dir` from the document, so RTL
|
|
244
|
+
works without configuration. Arrow keys in Menu, Switch and Tabs mirror
|
|
245
|
+
automatically. The Toaster takes an explicit `dir` prop if one region needs to
|
|
246
|
+
differ from the page.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.3.0
|
|
4
|
+
|
|
5
|
+
Published as a minor, but **it contains one breaking change to styling**. Read
|
|
6
|
+
the upgrade note below before updating.
|
|
7
|
+
|
|
8
|
+
### Breaking: component CSS is no longer in a cascade layer
|
|
9
|
+
|
|
10
|
+
Component rules used to live in `@layer gbs`, and 2.1.0 asked Tailwind v4
|
|
11
|
+
projects to add `@layer gbs, utilities;` to their global CSS. Both are gone.
|
|
12
|
+
|
|
13
|
+
A cascade layer loses to *any* unlayered stylesheet regardless of specificity,
|
|
14
|
+
and Tailwind v3's preflight and Bootstrap's Reboot are both unlayered. Measured
|
|
15
|
+
on 2.2.0: under Tailwind v3 the components rendered with `border: 0` and
|
|
16
|
+
`padding-left: 0`; under Bootstrap every button was square. No host-side
|
|
17
|
+
declaration could fix either, because nothing layered can outrank unlayered CSS.
|
|
18
|
+
|
|
19
|
+
Component CSS now ships unlayered and wins on ordinary specificity, so Tailwind
|
|
20
|
+
v3, Bootstrap and framework-free projects work with no setup at all.
|
|
21
|
+
|
|
22
|
+
**What to change:**
|
|
23
|
+
|
|
24
|
+
- Delete any `@layer gbs, utilities;` (or similar) line you added for 2.1.0.
|
|
25
|
+
- Import the generated barrel instead of individual stylesheets:
|
|
26
|
+
`@import "./component-lib/gbs.css";`
|
|
27
|
+
- **Tailwind v4 only** — import it after the framework and into its components
|
|
28
|
+
layer, or utilities stop overriding component rules:
|
|
29
|
+
```css
|
|
30
|
+
@import "tailwindcss";
|
|
31
|
+
@import "./component-lib/gbs.css" layer(components);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The installer detects which line you need and prints it.
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- **`<DataGrid ai />`** — a natural-language input above the grid, driven by an
|
|
39
|
+
adapter the application supplies through `<GramproAIProvider>`. No model is
|
|
40
|
+
bundled, downloaded or named, and with no provider the prop renders nothing.
|
|
41
|
+
- **WebMCP** — `registerGridTool(agent)` exposes one tool, `operate_grid`, to a
|
|
42
|
+
browser agent. Its schema is generated from the live grid. Needs no model.
|
|
43
|
+
- **Generated stylesheet barrel** — the CLI writes `component-lib/gbs.css` on
|
|
44
|
+
every install, so the import list stays correct as you add components.
|
|
45
|
+
- **Thin scrollbars** across every scrolling surface, themeable from `:root`
|
|
46
|
+
via `--gbs-scrollbar-width`, `--gbs-scrollbar-thumb`,
|
|
47
|
+
`--gbs-scrollbar-thumb-hover` and `--gbs-scrollbar-track`. Add
|
|
48
|
+
`class="gbs-scroll"` to your own scroll areas to match. Scroll containers the
|
|
49
|
+
kit does not own are left alone.
|
|
50
|
+
|
|
51
|
+
### Security
|
|
52
|
+
|
|
53
|
+
- Pinned `dompurify` to `^3.4.16` via `overrides`, clearing two DOM XSS
|
|
54
|
+
advisories reachable through `@grampro/headless-helpers → jspdf`. The 2.0 beta
|
|
55
|
+
components never used that chain. `npm audit` is now clean.
|
|
56
|
+
- Removed the `path` dependency. `require("path")` resolves to Node's built-in,
|
|
57
|
+
so the npm package was inert — a deprecated userland shim sitting in the
|
|
58
|
+
dependency tree for no reason.
|
|
59
|
+
|
|
60
|
+
### Documentation
|
|
61
|
+
|
|
62
|
+
- Documented what leaves the page with a remote AI adapter: the runtime contract
|
|
63
|
+
carries real values from low-cardinality columns. Mark personal columns
|
|
64
|
+
`semantics: { email: { pii: true } }` — a PII column is denied *and* never
|
|
65
|
+
summarised — or pass `stats: false`. Note that `policy.denyFilter` governs what
|
|
66
|
+
may be *done* with a column, not whether it may be *described*.
|
|
67
|
+
- Corrected the agent skill's install instructions, which still told agents to
|
|
68
|
+
import each stylesheet individually with no `layer()`.
|
|
69
|
+
|
|
70
|
+
### Packaging
|
|
71
|
+
|
|
72
|
+
- Test files are no longer published (35 files, 233 KB). They were filtered out
|
|
73
|
+
at install time anyway.
|
|
74
|
+
- Added `repository`, `homepage` and `bugs` metadata.
|