Skip to content

Commit 85a2459

Browse files
claude[bot]claude
andauthored
fix(spec): say what the dashboard gap author decides, not what the renderer consumes (#15512)
`ui/dashboard`'s `gap` key described its value to app authors in the vocabulary of a CSS library they never chose and cannot act on. Two independent producer strings carried that wording, feeding two independent customer-facing surfaces: packages/spec/src/ui/dashboard.form.ts helpText -> Studio property panel packages/spec/src/ui/dashboard.zod.ts describe -> content/docs/references/ui/dashboard.mdx Fixing only the first would have relocated the divergence rather than removed it: the Studio panel would say what an author decides while the published reference page still named the library. That is the same producer/consumer split this card exists to close, one level up. Both strings now read `Space between widgets, in steps of 0.25rem (4 = 1rem)` -- what the author decides, plus the magnitude, in a CSS unit rather than a framework scale. The magnitude is stated as measured: the dashboard renderer sets the grid gap as an inline style computed from this key, so every accepted value is linear at 0.25rem per step. No schema change: `gap` stays `z.number().int().min(0).optional()`. `columns` is untouched on both of its producer lines -- 12 is an author-visible fact about the grid, not a framework detail. Generated artifacts regenerated by the repo's own tooling, never by hand: `gen:docs` for the reference row, `check-i18n-bundles.mjs --write` for the `en` metadata-forms leaf (a mechanical copy of the form source). Translated locales are untouched -- regeneration fills gaps and never overwrites a leaf. Claude-Session: https://claude.ai/code/session_01G4138K1EG7kQ81FNba5Kp4 Co-authored-by: Claude <noreply@anthropic.com>
1 parent ae79c77 commit 85a2459

5 files changed

Lines changed: 45 additions & 5 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
"@objectstack/spec": patch
3+
"@objectstack/platform-objects": patch
4+
---
5+
6+
fix(spec): the dashboard `gap` field no longer describes itself to app authors in Tailwind vocabulary
7+
8+
`ui/dashboard`'s `gap` key told app authors its value in the vocabulary of a CSS
9+
library they never chose and cannot act on. **Two** independent producer strings
10+
carried that wording, and they feed two independent customer-facing surfaces:
11+
12+
- `dashboardForm`'s `helpText``Grid gap (Tailwind units)` — rendered verbatim in
13+
the Studio property panel, which is spec-driven and feeds this form straight into
14+
the generic form renderer.
15+
- `DashboardSchema.gap`'s `.describe()``Grid gap in Tailwind spacing units`
16+
rendered as this field's row in the published reference page
17+
`content/docs/references/ui/dashboard.mdx`. The reference corpus renders
18+
`.describe()`, never `helpText`.
19+
20+
Both now read **Space between widgets, in steps of 0.25rem (4 = 1rem)**: what the
21+
author decides, plus the magnitude, stated in a CSS unit instead of a framework's
22+
scale. The magnitude had to survive the rewrite rather than be dropped with the
23+
framework name — the number is a spacing step, so `4` means `1rem` and not `4px`,
24+
and an author who lost that would come away knowing less than before.
25+
26+
The step size is stated as measured rather than inferred: the dashboard renderer
27+
sets the grid gap as an inline style computed from this key, so every accepted
28+
value is linear and one step is exactly `0.25rem`. "Tailwind units" was doubly
29+
wrong — it named an implementation dependency, and it named one the consumer of
30+
this key does not have.
31+
32+
**No schema change.** `gap` stays `z.number().int().min(0).optional()` and accepts
33+
exactly what it accepted before; nothing is added to or removed from any public
34+
surface. `columns` is deliberately untouched on both of its producer lines —
35+
`12` is an author-visible fact about the grid being laid out, not a framework
36+
detail — and this is one field's two strings, not a sweep for framework words.
37+
38+
The `en` metadata-forms translation bundle is a mechanical copy of the form source,
39+
so it is regenerated to match. Translated locales are not touched: regeneration
40+
fills gaps only and never overwrites an existing leaf.

content/docs/references/ui/dashboard.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const result = DashboardSchema.parse(data);
3333
| **header** | `{ showTitle: boolean; showDescription: boolean; actions?: object[] }` | optional | Dashboard header configuration |
3434
| **widgets** | `{ id: string; title?: string \| Record<string, string>; description?: string \| Record<string, string>; type: Enum<'bar' \| 'horizontal-bar' \| 'column' \| 'line' \| 'area' \| 'pie' \| 'donut' \| …>; … }[]` || Widgets to display |
3535
| **columns** | `integer` | optional | Number of grid columns (default 12) |
36-
| **gap** | `integer` | optional | Grid gap in Tailwind spacing units |
36+
| **gap** | `integer` | optional | Space between widgets, in steps of 0.25rem (4 = 1rem) |
3737
| **refreshInterval** | `number` | optional | Auto-refresh interval in seconds |
3838
| **dateRange** | `{ field?: string; defaultRange: Enum<'today' \| 'yesterday' \| 'this_week' \| 'last_week' \| 'this_month' \| 'last_month' \| …>; allowCustomRange: boolean }` | optional | Global dashboard date range filter configuration |
3939
| **globalFilters** | `{ name?: string; field: string; object?: string; label?: string \| Record<string, string>; … }[]` | optional | Global filters that apply to all widgets in the dashboard |

packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ export const enMetadataForms: NonNullable<TranslationData['metadataForms']> = {
932932
},
933933
gap: {
934934
label: "Gap",
935-
helpText: "Grid gap (Tailwind units)"
935+
helpText: "Space between widgets, in steps of 0.25rem (4 = 1rem)"
936936
},
937937
refreshInterval: {
938938
label: "Refresh Interval",

packages/spec/src/ui/dashboard.form.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const dashboardForm = defineForm({
2222
columns: 3,
2323
fields: [
2424
{ field: 'columns', type: 'number', colSpan: 1, helpText: 'Grid columns (default 12)' },
25-
{ field: 'gap', type: 'number', colSpan: 1, helpText: 'Grid gap (Tailwind units)' },
25+
{ field: 'gap', type: 'number', colSpan: 1, helpText: 'Space between widgets, in steps of 0.25rem (4 = 1rem)' },
2626
{ field: 'refreshInterval', type: 'number', colSpan: 1, helpText: 'Auto-refresh (seconds)' },
2727
{ field: 'header', type: 'composite', colSpan: 3, helpText: 'Dashboard header config (title, subtitle, actions)' },
2828
],

packages/spec/src/ui/dashboard.zod.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -899,8 +899,8 @@ export const DashboardSchema = lazySchema(() => strictObject({
899899
/** Grid column count — defaults to 12 for a standard 12-column grid */
900900
columns: z.number().int().min(1).max(24).optional().describe('Number of grid columns (default 12)'),
901901

902-
/** Grid gap in Tailwind spacing units (e.g. 4 = 1rem) */
903-
gap: z.number().int().min(0).optional().describe('Grid gap in Tailwind spacing units'),
902+
/** Space between widgets, in steps of 0.25rem (4 = 1rem) */
903+
gap: z.number().int().min(0).optional().describe('Space between widgets, in steps of 0.25rem (4 = 1rem)'),
904904

905905
/** Auto-refresh */
906906
refreshInterval: z.number().optional().describe('Auto-refresh interval in seconds'),

0 commit comments

Comments
 (0)