@sableui/react 0.17.0 → 0.19.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/AGENTS.md +10 -3
- package/CHANGELOG.md +235 -0
- package/README.md +11 -4
- package/bin/sable.mjs +266 -30
- package/dist/{_contract-CDa9-NdB.d.ts → _contract-DlklV0Im.d.ts} +2 -2
- package/dist/activity-DT8VK9fx.d.ts +25 -0
- package/dist/adapters/github.d.ts +41 -0
- package/dist/adapters/github.js +24 -0
- package/dist/blocks/index.d.ts +1 -1
- package/dist/components/activity-heatmap/activity-heatmap.js +420 -0
- package/dist/components/activity-heatmap/activity-heatmap.meta.js +142 -0
- package/dist/components/activity-heatmap/index.js +9 -0
- package/dist/components/avatar/avatar.js +16 -7
- package/dist/components/avatar/avatar.meta.js +43 -10
- package/dist/components/avatar/avatar.variants.js +26 -2
- package/dist/components/code-block/code-block.js +5 -3
- package/dist/components/code-block/code-block.meta.js +6 -0
- package/dist/components/collapsible/collapsible.js +6 -5
- package/dist/components/collapsible/collapsible.meta.js +14 -5
- package/dist/components/data-table/data-table.js +132 -45
- package/dist/components/data-table/data-table.meta.js +63 -4
- package/dist/components/date-picker/date-picker.js +13 -6
- package/dist/components/date-picker/date-picker.meta.js +22 -0
- package/dist/components/dialog/dialog.js +25 -5
- package/dist/components/dialog/dialog.meta.js +26 -5
- package/dist/components/media-image/media-image.js +3 -1
- package/dist/components/media-image/media-image.meta.js +15 -1
- package/dist/components/media-tile/media-tile.js +13 -1
- package/dist/components/media-tile/media-tile.meta.js +10 -0
- package/dist/components/menu/menu.js +2 -0
- package/dist/components/menu/menu.meta.js +2 -2
- package/dist/components/page-header/page-header.js +9 -4
- package/dist/components/page-header/page-header.meta.js +26 -1
- package/dist/components/panel-group/panel-group.js +17 -1
- package/dist/components/panel-group/panel-group.meta.js +43 -3
- package/dist/components/pill/pill.meta.js +15 -6
- package/dist/components/pill/pill.variants.js +1 -0
- package/dist/components/search-input/search-input.js +30 -5
- package/dist/components/search-input/search-input.meta.js +29 -4
- package/dist/components/section-header/section-header.js +27 -17
- package/dist/components/section-header/section-header.meta.js +27 -5
- package/dist/components/sheet/sheet.js +15 -3
- package/dist/components/sheet/sheet.meta.js +2 -2
- package/dist/components/side-nav/side-nav.variants.js +8 -3
- package/dist/components/sidebar/index.js +4 -0
- package/dist/components/sidebar/sidebar.js +90 -11
- package/dist/components/sidebar/sidebar.meta.js +38 -4
- package/dist/components/table/table.js +7 -3
- package/dist/components/tabs/tabs.js +10 -2
- package/dist/components/tabs/tabs.meta.js +4 -0
- package/dist/components/workspace/workspace.js +13 -3
- package/dist/components/workspace/workspace.meta.js +109 -1
- package/dist/file-hashes.json +94 -80
- package/dist/foundations/typography.js +13 -0
- package/dist/icon/Icon.js +21 -2
- package/dist/icon/index.d.ts +36 -1
- package/dist/icon/index.js +5 -0
- package/dist/icon/names.js +240 -0
- package/dist/icon-sets/reicon.js +41 -1
- package/dist/index.d.ts +540 -75
- package/dist/index.js +18 -1
- package/dist/layout/AspectBox.js +2 -5
- package/dist/layout/Bleed.js +10 -6
- package/dist/layout/Center.js +11 -3
- package/dist/layout/Columns.js +6 -3
- package/dist/layout/Grid.js +14 -6
- package/dist/layout/GridOverlay.js +7 -7
- package/dist/layout/Region.js +18 -3
- package/dist/layout/Row.js +27 -20
- package/dist/layout/Spacer.js +13 -2
- package/dist/layout/SplitPane.js +1 -1
- package/dist/layout/Stack.js +25 -18
- package/dist/layout/index.d.ts +57 -6
- package/dist/lib/chart/activity.js +32 -0
- package/dist/lib/chart/calendar.js +67 -0
- package/dist/lib/chart/chart-tooltip.js +2 -2
- package/dist/lib/chart/heat.js +55 -0
- package/dist/lib/cn.js +1 -0
- package/dist/lib/focus-return.js +53 -0
- package/dist/lib/taxonomy.js +1 -0
- package/dist/lib/use-media-query.js +41 -0
- package/dist/{meta-DX5r5wQL.d.ts → meta-Dfm9AExe.d.ts} +6 -0
- package/dist/patterns/dashboard-page.js +23 -17
- package/dist/patterns/index.d.ts +7 -2
- package/dist/patterns/index.js +5 -1
- package/dist/patterns/tracker-page.js +392 -0
- package/dist/patterns/tracker-page.meta.js +40 -0
- package/dist/presets/index.d.ts +1 -1
- package/dist/styles.css +301 -188
- package/dist/{theme-provider-BydfM5Z0.d.ts → theme-provider-BUBealk_.d.ts} +1 -1
- package/dist/themes/_contract.js +9 -1
- package/dist/themes/atelier/index.d.ts +1 -1
- package/dist/themes/ember/index.d.ts +1 -1
- package/dist/themes/index.d.ts +2 -2
- package/dist/themes/meridian/index.d.ts +1 -1
- package/dist/themes/poppy/index.d.ts +1 -1
- package/dist/themes/prism/index.d.ts +1 -1
- package/dist/themes/sable/index.d.ts +1 -1
- package/dist/themes/verdant/index.d.ts +1 -1
- package/llms/components/activity-heatmap.md +133 -0
- package/llms/components/avatar.md +32 -9
- package/llms/components/code-block.md +1 -0
- package/llms/components/collapsible.md +12 -4
- package/llms/components/data-table.md +40 -3
- package/llms/components/date-picker.md +15 -1
- package/llms/components/dialog.md +34 -3
- package/llms/components/media-image.md +12 -0
- package/llms/components/media-tile.md +21 -0
- package/llms/components/menu.md +1 -1
- package/llms/components/page-header.md +16 -1
- package/llms/components/panel-group.md +34 -2
- package/llms/components/pill.md +24 -5
- package/llms/components/search-input.md +37 -4
- package/llms/components/section-header.md +28 -4
- package/llms/components/sheet.md +2 -2
- package/llms/components/sidebar.md +17 -4
- package/llms/components/tabs.md +1 -0
- package/llms/components/workspace.md +81 -1
- package/llms/foundations/typography.md +4 -1
- package/llms/layout/aspect-box.md +1 -1
- package/llms/layout/bleed.md +1 -1
- package/llms/layout/center.md +1 -1
- package/llms/layout/columns.md +1 -1
- package/llms/layout/grid.md +1 -1
- package/llms/layout/region.md +1 -1
- package/llms/layout/row.md +9 -1
- package/llms/layout/spacer.md +1 -1
- package/llms/layout/split-pane.md +1 -1
- package/llms/layout/stack.md +1 -1
- package/llms/patterns/dashboard-page.md +18 -15
- package/llms/patterns/tracker-page.md +450 -0
- package/llms/reference/token-intent.md +3 -1
- package/llms/reference/utilities.md +4 -1
- package/llms/tasks/auditing-an-app.md +35 -1
- package/llms/tasks/building-a-page.md +3 -2
- package/llms/tasks/building-a-tool.md +101 -5
- package/llms/tasks/building-with-sable.md +11 -3
- package/llms/tasks/creating-a-preset.md +9 -0
- package/llms/tasks/getting-started.md +10 -3
- package/llms/tasks/using-presets.md +1 -2
- package/llms-full.txt +1215 -89
- package/llms.txt +11 -9
- package/package.json +7 -1
- package/registry.json +1021 -70
- package/scripts/adoption.mjs +252 -0
- package/scripts/agent-setup.mjs +110 -18
- package/scripts/app-css.mjs +129 -0
- package/scripts/grade.mjs +178 -2
- package/scripts/lint-rules.mjs +126 -0
- package/scripts/wiring.mjs +2 -1
- package/skills/entry/SKILL.md +1 -1
- package/skills/sable/SKILL.md +64 -6
- package/skills/sable/agents/openai.yaml +1 -1
- package/targets/ios.json +9 -0
package/AGENTS.md
CHANGED
|
@@ -153,6 +153,11 @@ In a monorepo where Sable belongs to one workspace package, run setup in that
|
|
|
153
153
|
package with `--root` naming the repository root (for example
|
|
154
154
|
`pnpm --filter web exec sable setup --agent --root ../..`); the entries go
|
|
155
155
|
there and resolve Sable through the package.
|
|
156
|
+
Setup also adds a short managed block to the project's `AGENTS.md` and
|
|
157
|
+
`CLAUDE.md`, the instructions an agent reads on every task, so a UI request
|
|
158
|
+
goes through the skill even when it doesn't mention Sable. Only the text between
|
|
159
|
+
its `<!-- sable:begin -->` and `<!-- sable:end -->` markers is Sable's;
|
|
160
|
+
`--no-instructions` skips it.
|
|
156
161
|
Each entry resolves `skills/sable/SKILL.md` from the installed package, so package
|
|
157
162
|
upgrades also update the workflow. Other agents can read that file directly.
|
|
158
163
|
Use `$sable build <idea>`, `inspire <references>`, `audit <target>`,
|
|
@@ -160,9 +165,11 @@ Use `$sable build <idea>`, `inspire <references>`, `audit <target>`,
|
|
|
160
165
|
Claude Code or Cursor. `create` is a build alias. `fix` takes the short path for
|
|
161
166
|
one scoped defect and escalates to `polish` when the change grows. These are agent modes, not shell commands.
|
|
162
167
|
|
|
163
|
-
Upgrade with `pnpm
|
|
164
|
-
|
|
165
|
-
|
|
168
|
+
Upgrade with `pnpm exec sable upgrade`: it updates the package, then runs the
|
|
169
|
+
new version's `init`, which refreshes the skill entries and the instructions
|
|
170
|
+
block and checks the wiring. From 0.17 or earlier, which has no `upgrade`, run
|
|
171
|
+
`pnpm update @sableui/react --latest` and then `pnpm exec sable init` once.
|
|
172
|
+
Setup only replaces managed files that have not been locally edited; `--dry-run` checks without writing. Keep
|
|
166
173
|
project preferences in project instructions. Package installation alone does not
|
|
167
174
|
change agent settings. See [building-with-sable.md](./llms/tasks/building-with-sable.md),
|
|
168
175
|
[creating-a-preset.md](./llms/tasks/creating-a-preset.md), and
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,240 @@
|
|
|
1
1
|
# What's new
|
|
2
2
|
|
|
3
|
+
## 0.19.0
|
|
4
|
+
|
|
5
|
+
A compact work tracker, built on Sable by an agent, rebuilt about thirty parts
|
|
6
|
+
Sable already ships. Every gap behind those rebuilds is fixed here: a lookup
|
|
7
|
+
that couldn't find parts, checks that couldn't see the app's own CSS, and
|
|
8
|
+
components that had no variant for a dense layout.
|
|
9
|
+
|
|
10
|
+
- **`--type-base` rebuilds the type scale at another base size.** Set
|
|
11
|
+
`--type-base: 14` (a unitless px number; the default is 16) on `:root`, a
|
|
12
|
+
`[data-sable-theme]` scope or in a preset's `tokens.shared`, and every page
|
|
13
|
+
tier scales by `base / 16`, including each theme's own tier values and any
|
|
14
|
+
per-tier override. Spacing follows, because the baseline step is derived from
|
|
15
|
+
body size. The workspace `ui-*` tiers stay absolute px, and compact still only
|
|
16
|
+
ever shrinks text. Don't change the root font-size to get a denser UI: it
|
|
17
|
+
scales every rem in the app, not just the type.
|
|
18
|
+
- **New `text-ui-title`** (14px / 600 / 20px leading, tokens
|
|
19
|
+
`--type-ui-title-*`). Inside a compact scope `text-title-lg` maps to it. It
|
|
20
|
+
used to collapse to 12px, the same size as the description under it.
|
|
21
|
+
- **A comfortable scope inside a compact one gets page type back.**
|
|
22
|
+
`<Density value="comfortable">` around a reading view (an overview, notes,
|
|
23
|
+
docs) in a Workspace used to reset the control sizes but not the text, which
|
|
24
|
+
stayed at 11px.
|
|
25
|
+
- **Tables follow density.** TableHead's height, TableCell's padding and the
|
|
26
|
+
table's text tier read density tokens. In a compact Workspace that is a 28px
|
|
27
|
+
head, 32px rows and `text-ui-body`, with no consumer CSS.
|
|
28
|
+
- **Compact on a touch screen uses the comfortable control ladder.** Under
|
|
29
|
+
`pointer: coarse` the 24/28/32 ladder, measured from mouse-driven editors,
|
|
30
|
+
becomes 28/32/40.
|
|
31
|
+
- **Workspace's body is its only stretching row.** The grid always assumed a
|
|
32
|
+
toolbar, so a Workspace without one put the body in the auto track and
|
|
33
|
+
clipped the status bar. The root is now a flex column, which holds for every
|
|
34
|
+
combination of slots. Migration: drop any `grid-template-rows` override on
|
|
35
|
+
the Workspace root.
|
|
36
|
+
- **Workspace and Panel on small screens.** Workspace takes `bottomNav`, a row
|
|
37
|
+
shown below `lg`. Panel takes `narrow="sheet" | "hidden"` with `open`,
|
|
38
|
+
`onOpenChange`, `side` and `below`: below the breakpoint an inspector becomes
|
|
39
|
+
a Sheet and its content renders once. A Sidebar moved into that sheet fills
|
|
40
|
+
it. New `useMediaQuery` and
|
|
41
|
+
`useBelowBreakpoint` hooks are exported. A WorkspaceBar can also sit at the
|
|
42
|
+
top of one column, so the inspector runs the full height beside it, as in
|
|
43
|
+
Linear.
|
|
44
|
+
- **DataTable groups rows.** `groupBy`, `groups` (each with an icon, an action
|
|
45
|
+
and `defaultExpanded`), `collapsible` and controlled `expandedGroups` give
|
|
46
|
+
one table with one header and a header row per group that carries a toggle,
|
|
47
|
+
a count and an add action. Sorting applies within each group, and select-all
|
|
48
|
+
acts on the visible rows.
|
|
49
|
+
- **The Sidebar rail is one grid, at either density.** New `SidebarGroup`
|
|
50
|
+
labels a run of items, so a rail no longer has to borrow SideNav for its
|
|
51
|
+
groups. New `SidebarAccount` is the account row: the avatar in the icon slot,
|
|
52
|
+
the label and one detail line on the label column, and an up-down chevron.
|
|
53
|
+
Make it the account Menu's trigger and put Settings, appearance and sign-out
|
|
54
|
+
in the menu. Inside a compact scope such as a Workspace, the whole rail takes
|
|
55
|
+
32px rows and 20px icons, and the header matches the chrome bar's height.
|
|
56
|
+
Before this, a tool's footer mixed a ghost Button, an Entity patched with
|
|
57
|
+
`[--entity-py:0]` and a Badge, and the rail's icons and labels landed on four
|
|
58
|
+
columns. DashboardPage uses the new parts.
|
|
59
|
+
- **Underline tabs in a WorkspaceBar sit on the bar's hairline.** They used to
|
|
60
|
+
draw a second, shorter rule that stopped after the last tab, with the mark
|
|
61
|
+
floating above the bar's edge. Tabs guidance now steers a view switch in tool
|
|
62
|
+
chrome to `variant="pill"`.
|
|
63
|
+
- **`MenuSubmenuTrigger` takes `icon`**, as MenuItem does, so a submenu row
|
|
64
|
+
lines up with the icon rows around it.
|
|
65
|
+
- New icon `chevron-up-down` (Lucide's `chevrons-up-down` resolves to it).
|
|
66
|
+
- **Avatar:** `2xs` (20px) and `xs` (24px), `shape="square"` for a workspace,
|
|
67
|
+
project or org mark, and a palette `tone` for the initials fallback.
|
|
68
|
+
- **DatePicker:** `size="xs"` for a property row, and `formatOptions`
|
|
69
|
+
(`Intl.DateTimeFormatOptions`) for the trigger text.
|
|
70
|
+
- **CollapsibleIndicator needs no setup.** It no longer needs the
|
|
71
|
+
`group/collapsible` class on its trigger. New `direction="end"` gives a side
|
|
72
|
+
caret that turns down on open, mirrored in RTL.
|
|
73
|
+
- **Icons:** new `users`, `archive`, `kanban`, `sliders`, `help` and `sidebar`.
|
|
74
|
+
About 90 Lucide and Heroicons names now resolve to Sable's (`settings` →
|
|
75
|
+
`gear`, `menu` → `bars`, `check-circle` → `circle-check`). A development
|
|
76
|
+
build warns once for a name the set can't draw, and names the nearest ones.
|
|
77
|
+
- **A toast clears an open side sheet on a phone.** It used to move to the
|
|
78
|
+
top, over the sheet's close button. It now sits below the sheet's header
|
|
79
|
+
inset, tunable with `--sable-sheet-top-inset`.
|
|
80
|
+
- **Workspace surfaces derive in oklab.** The canvas, panel, field, hairline
|
|
81
|
+
and shell-ground mixes used `color-mix(in oklch, …)`. On hex colours Chrome
|
|
82
|
+
resolves that to a colour with no hue, painted as 0°: a brown cast on a cool
|
|
83
|
+
graphite preset's canvas. Bundled themes write oklch and never showed it, but
|
|
84
|
+
presets and apps write hex. The heatmap's empty cell moves to oklab too.
|
|
85
|
+
- **`--nav-height` is defined** (56px). AppShell's bottom padding read it with
|
|
86
|
+
no fallback, so the padding was dropped.
|
|
87
|
+
- **Agent tooling finds parts.** `sable component PropertyRow` (or `Panel`,
|
|
88
|
+
`WorkspaceBar`, `CollapsibleTrigger`) answers with the parent component;
|
|
89
|
+
it used to be ERR_UNKNOWN_COMPONENT. Search indexes parts, and an exact name
|
|
90
|
+
ranks first. New `sable icon [name]` lists the drawable names and resolves
|
|
91
|
+
aliases.
|
|
92
|
+
- **`sable check` sees rebuilt parts.** A new "Rebuilt parts" block reads class
|
|
93
|
+
names in the app's markup and the app's own CSS. It flags a breadcrumb, top
|
|
94
|
+
bar, property row, status dot or avatar stack built by hand; fixed bar and row
|
|
95
|
+
heights; selectors reaching into Sable's components; and a chevron rotated on
|
|
96
|
+
`aria-expanded`. Icon names passed through an app's own wrapper are checked
|
|
97
|
+
too. These are notes, and the skill asks the agent to answer each one.
|
|
98
|
+
- **`sable check` warns on one-mode colour.** Colour tokens set for light with
|
|
99
|
+
no dark value now produce a warning, and an app with no ThemeSwitcher gets a
|
|
100
|
+
note. The skill now ships both modes, as a preset with a ThemeSwitcher under
|
|
101
|
+
SableThemeProvider, unless the brief rules one out.
|
|
102
|
+
- **New pattern: `TrackerPage`.** A records workspace in the tool register,
|
|
103
|
+
the reference shape for an issue tracker, a support queue or a pipeline. It
|
|
104
|
+
has a Sidebar rail of grouped views ending in an account menu (with
|
|
105
|
+
appearance), Breadcrumbs and pill Tabs in WorkspaceBars, a filter row, one
|
|
106
|
+
grouped DataTable, a docked inspector of PanelSection property rows with a
|
|
107
|
+
pinned comment form, and a comfortable reading tab. Below lg the rail and the
|
|
108
|
+
inspector become sheets and BottomNav takes the last row. `sable pattern
|
|
109
|
+
TrackerPage --skeleton` has the tree. Pattern metadata takes `keywords` now,
|
|
110
|
+
so "issue tracker", "like Linear" or "support queue" lands on the shell first.
|
|
111
|
+
- **Guidance for a records workspace.** `building-a-tool` now covers the
|
|
112
|
+
shape of an issue tracker, a support queue or a pipeline: the shell, the
|
|
113
|
+
decisions that keep it one system (one rail grid, the account as a row and a
|
|
114
|
+
menu, one grouped table, an inspector that renders once, page-sized reading
|
|
115
|
+
tabs, pill tabs in chrome, both modes, `type-base` for "compact") and a
|
|
116
|
+
"you want / use / not" table built from what a real build rebuilt. The skill
|
|
117
|
+
routes a tool, tracker or "like Linear" brief there; `building-a-page` points
|
|
118
|
+
trackers to it; `creating-a-preset` explains `type-base`.
|
|
119
|
+
- **`sable check` notes compositions another part does better:** SideNav
|
|
120
|
+
inside a Sidebar, an Entity or Badge in the rail's footer, a DataTable per
|
|
121
|
+
group inside Collapsibles, underline tabs in a WorkspaceBar, and a native
|
|
122
|
+
date input. Notes, never failures. On the build that prompted this release
|
|
123
|
+
they flag four drifts, each at its line.
|
|
124
|
+
- **The skill searches before it builds.** It looks up a part by its plain name
|
|
125
|
+
and role before writing any class or component for it. A style or layout
|
|
126
|
+
disagreement means using the variant or prop, or reporting the missing
|
|
127
|
+
variant, never rebuilding the part.
|
|
128
|
+
- Migration: run `sable sources --write` after upgrading. Panel now imports
|
|
129
|
+
Sheet, so the generated sources file is stale until it is rewritten, and
|
|
130
|
+
doctor says so.
|
|
131
|
+
|
|
132
|
+
## 0.18.0
|
|
133
|
+
|
|
134
|
+
A year at a glance: the contribution graph, built so a phone, a keyboard and a
|
|
135
|
+
screen reader can all read it.
|
|
136
|
+
|
|
137
|
+
- **New: `ActivityHeatmap`.** A calendar heatmap: one value per day as a grid
|
|
138
|
+
of weeks by weekdays — the GitHub contribution graph, for any daily measure.
|
|
139
|
+
Pass days as `"YYYY-MM-DD"` with a value (or a date-to-value map); levels
|
|
140
|
+
come by quartile, as GitHub's do, unless a day brings its own. `categories`
|
|
141
|
+
colour days by source instead of intensity, and `mergeActivity` tags each day
|
|
142
|
+
with its source or `both`. The grid is a real `role="grid"` table with one
|
|
143
|
+
tab stop: arrows step a day or a week, each cell is named with its date and
|
|
144
|
+
value, and the tooltip shows on hover, focus and tap. It fills the width down
|
|
145
|
+
to `size`; narrower, the weeks scroll sideways and open on the latest, while
|
|
146
|
+
the weekday labels stay outside the scroller. Days are read as calendar days,
|
|
147
|
+
never instants, so no time zone shifts one. Prompted by a consumer site that
|
|
148
|
+
hand-built one from 371 buttons and broke on phones.
|
|
149
|
+
- **New: `@sableui/react/adapters/github`.** `fromGitHubGraphQL` and
|
|
150
|
+
`fromGitHubContributionsApi` turn GitHub's contribution data into heatmap
|
|
151
|
+
days. Pure transforms: fetch on your server and pass the result in.
|
|
152
|
+
- **New: `activityLevels` and `activityGrid`.** The level scale and the week
|
|
153
|
+
grid behind the heatmap, exported for a custom legend, a summary stat or
|
|
154
|
+
another layout.
|
|
155
|
+
- **`ChartTooltipContent` with no rows** draws just its label, so a caller's
|
|
156
|
+
own content sits on the standard tooltip card.
|
|
157
|
+
- **Layout primitives take `className` over their own layout.** Row, Stack,
|
|
158
|
+
Grid, Columns, Col, Center, Region, Page, Bleed, AspectBox, Spacer, SplitPane
|
|
159
|
+
and GridOverlay set `display`, direction, alignment, gap, inset, cap, ratio and
|
|
160
|
+
size inline, and an inline declaration beats every utility, so
|
|
161
|
+
`<Row className="max-lg:hidden">` or `hidden md:flex` silently did nothing.
|
|
162
|
+
The grid and split rules in `styles.css` were unlayered too, so `hidden` lost
|
|
163
|
+
to them whatever its specificity. Layout now lives in classes merged through
|
|
164
|
+
`cn()`, with prop values passed as CSS variables those classes read, and the
|
|
165
|
+
layout rules sit in `@layer components`. A utility in `className` wins at any
|
|
166
|
+
breakpoint (`max-md:flex-col`, `md:gap-6`, `lg:grid-cols-3`); the props work
|
|
167
|
+
as before. Migration: a `className` that used to be ignored on a primitive now
|
|
168
|
+
applies, and a test reading `style.gap` or `style.maxWidth` reads
|
|
169
|
+
`--sable-row-gap`, `--sable-region-max` and the like instead.
|
|
170
|
+
- **`PageHeader size="lg"`.** A display-size page title for an editorial page
|
|
171
|
+
(a personal site, a marketing page, an article index): `text-display-lg` over
|
|
172
|
+
a `text-body-lg` lede capped at the prose measure. `md`, the default, is
|
|
173
|
+
unchanged. Keep `lg` off app routes: display type stays out of product chrome.
|
|
174
|
+
- **`SectionHeader size="lg"`.** The major-section tier, `text-heading-2` over a
|
|
175
|
+
`text-body-md` description, for an editorial page's sections under a
|
|
176
|
+
`PageHeader size="lg"`. It stops at heading-2 because heading-1 is the page
|
|
177
|
+
title's, one per route. Actions stay centred on the title's first line at
|
|
178
|
+
every size.
|
|
179
|
+
- **`SearchInput` takes `size`** (`md` | `sm` | `xs`), on the same ladder as
|
|
180
|
+
Input, Select and Combobox. `sm` is the toolbar field on `--control-sm`, `xs`
|
|
181
|
+
the inset tool-panel field; the magnifier, padding and clear button scale with
|
|
182
|
+
it and stay centred. Before, it was fixed at 40px and matched nothing in a
|
|
183
|
+
toolbar.
|
|
184
|
+
- **`Pill size="lg"`.** A 32px chip on `--control-sm`, the toolbar height Button
|
|
185
|
+
`sm` and SearchInput `sm` share, so a filter row beside a search field is one
|
|
186
|
+
height in either density.
|
|
187
|
+
- **`MediaImage` and `MediaTile` take a crop focus.** `position` sets where the
|
|
188
|
+
image sits in its frame and takes any CSS `object-position` value
|
|
189
|
+
(`"35% 50%"`, `"top"`), beside `fit`. MediaTile forwards it to its cover.
|
|
190
|
+
- **Dialogs return focus to whatever opened them.** `Dialog`, `AlertDialog` and
|
|
191
|
+
`Sheet` record the element focused when `open` turns true and send focus back
|
|
192
|
+
to it on close, with or without a trigger. Before, a dialog opened from your
|
|
193
|
+
own button lost focus to the page whenever a field inside autofocused,
|
|
194
|
+
CommandMenu's included. An explicit `finalFocus` still wins.
|
|
195
|
+
- **`DialogContent keepMounted`.** Keeps a closed dialog's content mounted and
|
|
196
|
+
hidden, so a half-written draft survives Esc or a stray click and is still
|
|
197
|
+
there on reopen. Opt in for drafts the user may come back to.
|
|
198
|
+
- **Eight more icon names.** `briefcase`, `layers`, `microphone`, `video`,
|
|
199
|
+
`broadcast`, `newspaper`, `palette` and `gamepad` join the contract, mapped
|
|
200
|
+
in the Reicon set, for a portfolio that imported reicon-react directly for
|
|
201
|
+
its work, audio, video, live, press, design and games sections.
|
|
202
|
+
- **Setup writes the skill into the instructions every task reads.** A skill
|
|
203
|
+
loads only when a request names it, so "add a pricing page" in a wired app
|
|
204
|
+
could skip it: the agent saw Tailwind and a stylesheet, wrote its own Button
|
|
205
|
+
and Modal, and put Sable's tokens on them. `sable setup --agent` (and `sable
|
|
206
|
+
init`) now also writes a short managed block into `AGENTS.md` and
|
|
207
|
+
`CLAUDE.md` that sends every UI request through the skill. Only the text
|
|
208
|
+
between its `<!-- sable:begin -->` and `<!-- sable:end -->` markers is
|
|
209
|
+
Sable's; `--no-instructions` skips it. **Migration:** from 0.17, run
|
|
210
|
+
`pnpm update @sableui/react --latest` then `pnpm exec sable init` once; after
|
|
211
|
+
that, `sable upgrade` does both.
|
|
212
|
+
- **New: `sable upgrade`.** One command to update: installs the latest
|
|
213
|
+
`@sableui/react` with the project's package manager, then runs the new
|
|
214
|
+
version's `init`, so the skill entries, the instructions block and the
|
|
215
|
+
checks are the new release's. Safe on an app that already works.
|
|
216
|
+
- **"Move this app onto Sable" is a request the skill understands.** It checks
|
|
217
|
+
the app, shows the swaps once, asks, and moves them a screen at a time; it
|
|
218
|
+
never starts a new build. `init` says so when an app's UI barely uses Sable,
|
|
219
|
+
and its next step for a ready app is now a plain request, not mode syntax.
|
|
220
|
+
- **Adoption, in `sable check`, `sable grade` and `sable doctor`.** How much of
|
|
221
|
+
the UI composes Sable, which app-built components do by hand what a Sable
|
|
222
|
+
component already does (a `Modal` → Dialog, a `SearchBar` → SearchInput,
|
|
223
|
+
behaviour first), and what the app already stands on: nothing, its own
|
|
224
|
+
primitives, or another library. Never a failure. `check` lists the swaps and,
|
|
225
|
+
when adoption is low, makes "ask the user about moving onto Sable" the first
|
|
226
|
+
review step; `doctor` warns. The skill and `sable docs auditing-an-app` say
|
|
227
|
+
how to put the choice to the user, more firmly when the app has no
|
|
228
|
+
foundation of its own.
|
|
229
|
+
- **The skill triggers on any UI work in a Sable app.** Its description now
|
|
230
|
+
says so, even when the request doesn't mention Sable.
|
|
231
|
+
- **`sable init --hook`.** Adds the Claude Code Stop hook that runs `sable
|
|
232
|
+
check` before a task can end. Run in a terminal, init asks; `--no-hook`
|
|
233
|
+
doesn't.
|
|
234
|
+
- **`CodeBlock wrap`.** Wraps long lines instead of scrolling them, for prose
|
|
235
|
+
in a code face: a prompt to paste into an agent, a log line. Code keeps
|
|
236
|
+
scrolling.
|
|
237
|
+
|
|
3
238
|
## 0.17.0
|
|
4
239
|
|
|
5
240
|
Knowing where you are: a rail that follows a long read, and an approval
|
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ pnpm add @sableui/react
|
|
|
69
69
|
pnpm exec sable init # or: npx sable init — once the package is installed
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
`init` reads your package manager from the lockfile and your framework from the project. It installs what is missing (React, Tailwind and its build plugin), puts the CSS imports below in order, adds React dedupe and the Tailwind plugin to a Vite config, loads the fonts, mounts `IconProvider` in a Vite starter's entry, installs the agent skill (`sable setup --agent`), then runs `sable doctor`. Anything it cannot change safely — an unfamiliar config, a Next.js layout — it prints as the exact snippet and the file it belongs in. Vite and Next.js (App Router) get every step; other setups get the packages and the stylesheet. `--dry-run` shows every change first; `--no-agent` skips the skill. Already set up? `sable doctor --fix` applies the same fixes to whatever doctor flags.
|
|
72
|
+
`init` reads your package manager from the lockfile and your framework from the project. It installs what is missing (React, Tailwind and its build plugin), puts the CSS imports below in order, adds React dedupe and the Tailwind plugin to a Vite config, loads the fonts, mounts `IconProvider` in a Vite starter's entry, installs the agent skill and its block in `AGENTS.md` / `CLAUDE.md` (`sable setup --agent`), offers the Claude Code Stop hook when you run it in a terminal, then runs `sable doctor`. Anything it cannot change safely — an unfamiliar config, a Next.js layout — it prints as the exact snippet and the file it belongs in. Vite and Next.js (App Router) get every step; other setups get the packages and the stylesheet. `--dry-run` shows every change first; `--no-agent` skips the skill. Already set up? `sable doctor --fix` applies the same fixes to whatever doctor flags.
|
|
73
73
|
|
|
74
74
|
The steps below are what `init` does, for doing it by hand or checking its work.
|
|
75
75
|
|
|
@@ -213,6 +213,11 @@ In a monorepo where Sable belongs to one workspace package, run setup in that
|
|
|
213
213
|
package with `--root` naming the repository root (for example
|
|
214
214
|
`pnpm --filter web exec sable setup --agent --root ../..`); the entries go
|
|
215
215
|
there and resolve Sable through the package.
|
|
216
|
+
Setup also adds a short managed block to the project's `AGENTS.md` and
|
|
217
|
+
`CLAUDE.md`, the instructions an agent reads on every task, so a UI request
|
|
218
|
+
goes through the skill even when it doesn't mention Sable. Only the text between
|
|
219
|
+
its `<!-- sable:begin -->` and `<!-- sable:end -->` markers is Sable's;
|
|
220
|
+
`--no-instructions` skips it.
|
|
216
221
|
Each entry resolves `skills/sable/SKILL.md` from the installed package, so package
|
|
217
222
|
upgrades also update the workflow. Other agents can read that file directly.
|
|
218
223
|
Use `$sable build <idea>`, `inspire <references>`, `audit <target>`, or
|
|
@@ -225,9 +230,11 @@ server: `claude mcp add --transport http sable https://www.sableui.com/api/mcp`
|
|
|
225
230
|
and `docs`, give the CLI's answers from the published package, at the version
|
|
226
231
|
the agent passes or the latest. Once Sable is installed, the CLI is the default.
|
|
227
232
|
|
|
228
|
-
Upgrade with `pnpm
|
|
229
|
-
|
|
230
|
-
|
|
233
|
+
Upgrade with `pnpm exec sable upgrade`: it updates the package, then runs the
|
|
234
|
+
new version's `init`, which refreshes the skill entries and the instructions
|
|
235
|
+
block and checks the wiring. From 0.17 or earlier, which has no `upgrade`, run
|
|
236
|
+
`pnpm update @sableui/react --latest` and then `pnpm exec sable init` once.
|
|
237
|
+
Setup only replaces managed files that have not been locally edited; `--dry-run` checks without writing. Keep
|
|
231
238
|
project preferences in project instructions. Package installation alone does not
|
|
232
239
|
change agent settings. See [building-with-sable.md](./llms/tasks/building-with-sable.md),
|
|
233
240
|
[creating-a-preset.md](./llms/tasks/creating-a-preset.md), and
|