@cueplusplus/ui 0.12.0 → 0.14.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/CHANGELOG.md +305 -0
- package/LICENSE +21 -0
- package/NOTICE.md +34 -0
- package/README.md +2 -19
- package/dist/agent-runtime/tool-call-card.js +2 -2
- package/dist/chat/ask-box.js +2 -2
- package/dist/chat/composer.js +1 -1
- package/dist/chat/message.js +1 -1
- package/dist/chrome/_band.js +54 -0
- package/dist/chrome/band.d.ts +106 -0
- package/dist/chrome/band.js +97 -0
- package/dist/chrome/empty-state.js +1 -1
- package/dist/chrome/footer.d.ts +13 -0
- package/dist/chrome/footer.js +17 -2
- package/dist/chrome/index.d.ts +2 -1
- package/dist/chrome/index.js +2 -1
- package/dist/chrome/navigation-menu.js +1 -1
- package/dist/chrome/page-shell.js +4 -4
- package/dist/configurator/export-dialog.js +1 -1
- package/dist/configurator/panel-sections.js +1 -1
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/agent-handoff.js +2 -2
- package/dist/elements/canvas-split.js +2 -2
- package/dist/elements/chat-panel.js +1 -1
- package/dist/elements/code-diff.js +1 -1
- package/dist/elements/code-runner.js +2 -2
- package/dist/elements/comparison-card.js +1 -1
- package/dist/elements/confidence-marker.js +1 -1
- package/dist/elements/conversation-search.js +1 -1
- package/dist/elements/day-separator.js +1 -1
- package/dist/elements/document-reference.js +1 -1
- package/dist/elements/edit-message.js +1 -1
- package/dist/elements/elicitation-form.js +1 -1
- package/dist/elements/guardrail-notice.js +1 -1
- package/dist/elements/image-generation.js +1 -1
- package/dist/elements/inline-citation.js +2 -2
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/math-block.js +1 -1
- package/dist/elements/message-branches.js +1 -1
- package/dist/elements/message-pair.js +1 -1
- package/dist/elements/onboarding.js +2 -2
- package/dist/elements/prompt-library.js +1 -1
- package/dist/elements/quote-reply.js +2 -2
- package/dist/elements/read-aloud.js +1 -1
- package/dist/elements/reasoning-panel.js +1 -1
- package/dist/elements/recommendation-card.js +1 -1
- package/dist/elements/research-report.js +1 -1
- package/dist/elements/retrieval-chunks.js +1 -1
- package/dist/elements/reviewable-diff.js +1 -1
- package/dist/elements/score-breakdown.js +1 -1
- package/dist/elements/scroll-anchor.js +1 -1
- package/dist/elements/settings-panel.js +1 -1
- package/dist/elements/shared-conversation.js +1 -1
- package/dist/elements/speaker-identity.js +1 -1
- package/dist/elements/stopped-run.js +1 -1
- package/dist/elements/streaming-text.js +1 -1
- package/dist/elements/timeline.js +1 -1
- package/dist/elements/tool-error.js +1 -1
- package/dist/elements/voice-conversation.js +1 -1
- package/dist/forms/textarea.js +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +4 -2
- package/dist/instruments/code-block.js +1 -1
- package/dist/instruments/progress.d.ts +19 -3
- package/dist/instruments/progress.js +19 -1
- package/dist/instruments/terminal-frame.js +1 -1
- package/dist/layout/_collapse.js +1 -1
- package/dist/layout/card.js +1 -1
- package/dist/layout/container.js +3 -3
- package/dist/layout/frames.d.ts +19 -1
- package/dist/layout/frames.js +21 -7
- package/dist/layout/index.d.ts +2 -2
- package/dist/layout/preview.d.ts +29 -9
- package/dist/layout/preview.js +38 -17
- package/dist/overlays/_surface.d.ts +1 -1
- package/dist/overlays/_surface.js +1 -1
- package/dist/overlays/toast.js +1 -1
- package/dist/overlays/tooltip.js +1 -1
- package/dist/primitives/chip.d.ts +1 -1
- package/dist/system/density.d.ts +34 -6
- package/dist/system/density.js +41 -10
- package/dist/system/index.d.ts +2 -1
- package/dist/system/index.js +2 -1
- package/dist/system/portal.d.ts +8 -7
- package/dist/system/portal.js +16 -9
- package/dist/system/prepaint.d.ts +25 -5
- package/dist/system/prepaint.js +10 -2
- package/dist/system/theme-provider.d.ts +86 -7
- package/dist/system/theme-provider.js +62 -20
- package/dist/system/use-theme.d.ts +9 -2
- package/dist/system/use-theme.js +9 -2
- package/dist/system/vocabulary.d.ts +2 -1
- package/dist/system/vocabulary.js +16 -2
- package/manifest/components/accordion.json +1 -0
- package/manifest/components/agent-card.json +1 -0
- package/manifest/components/agent-handoff.json +1 -0
- package/manifest/components/alert-dialog.json +1 -0
- package/manifest/components/ask-box.json +1 -0
- package/manifest/components/autocomplete.json +1 -0
- package/manifest/components/band.json +104 -0
- package/manifest/components/canvas-split-body.json +1 -0
- package/manifest/components/canvas-split-document.json +1 -0
- package/manifest/components/canvas-split-header.json +1 -0
- package/manifest/components/canvas-split-line.json +1 -0
- package/manifest/components/canvas-split-message.json +1 -0
- package/manifest/components/canvas-split-thread.json +1 -0
- package/manifest/components/canvas-split.json +1 -0
- package/manifest/components/card.json +1 -0
- package/manifest/components/channel-matrix.json +1 -0
- package/manifest/components/chart-tooltip-content.json +1 -0
- package/manifest/components/chat-panel-assistant-message.json +1 -0
- package/manifest/components/chat-panel-composer.json +1 -0
- package/manifest/components/chat-panel-messages.json +1 -0
- package/manifest/components/chat-panel-typing.json +1 -0
- package/manifest/components/chat-panel-user-message.json +1 -0
- package/manifest/components/chat-panel.json +1 -0
- package/manifest/components/code-block.json +1 -0
- package/manifest/components/code-diff.json +1 -0
- package/manifest/components/code-runner.json +1 -0
- package/manifest/components/collapsible.json +1 -0
- package/manifest/components/colors-section.json +1 -0
- package/manifest/components/combobox.json +1 -0
- package/manifest/components/command-palette.json +1 -0
- package/manifest/components/comparison-card.json +1 -0
- package/manifest/components/composer.json +1 -0
- package/manifest/components/confidence-marker.json +1 -0
- package/manifest/components/container.json +3 -0
- package/manifest/components/context-menu.json +1 -0
- package/manifest/components/conversation-search.json +1 -0
- package/manifest/components/cue-portal-frame.json +1 -1
- package/manifest/components/day-separator.json +1 -0
- package/manifest/components/density.json +16 -1
- package/manifest/components/dialog.json +1 -0
- package/manifest/components/disclosure.json +1 -0
- package/manifest/components/dmx-bar.json +1 -0
- package/manifest/components/dmx-strip.json +1 -0
- package/manifest/components/document-reference.json +1 -0
- package/manifest/components/drawer.json +1 -0
- package/manifest/components/dropdown-menu.json +1 -0
- package/manifest/components/edit-message.json +1 -0
- package/manifest/components/elements-timeline.json +1 -0
- package/manifest/components/elicitation-form.json +1 -0
- package/manifest/components/empty-state.json +1 -0
- package/manifest/components/export-dialog.json +1 -0
- package/manifest/components/footer.json +3 -2
- package/manifest/components/frac.json +1 -0
- package/manifest/components/frames.json +14 -0
- package/manifest/components/guardrail-notice.json +1 -0
- package/manifest/components/hover-card.json +1 -0
- package/manifest/components/inline-citation.json +1 -0
- package/manifest/components/markdown-text.json +1 -0
- package/manifest/components/math-block.json +1 -0
- package/manifest/components/menubar.json +1 -0
- package/manifest/components/message-branches.json +1 -0
- package/manifest/components/message-pair.json +1 -0
- package/manifest/components/message.json +1 -0
- package/manifest/components/multi-select.json +1 -0
- package/manifest/components/navigation-menu.json +1 -0
- package/manifest/components/onboarding.json +1 -0
- package/manifest/components/page-shell.json +4 -0
- package/manifest/components/popover.json +1 -0
- package/manifest/components/preset-section.json +1 -0
- package/manifest/components/preview.json +17 -2
- package/manifest/components/progress.json +2 -2
- package/manifest/components/prompt-library.json +1 -0
- package/manifest/components/quote-reply.json +1 -0
- package/manifest/components/read-aloud.json +1 -0
- package/manifest/components/reasoning-panel.json +1 -0
- package/manifest/components/recommendation-card.json +1 -0
- package/manifest/components/research-report.json +1 -0
- package/manifest/components/retrieval-chunks.json +1 -0
- package/manifest/components/reviewable-diff.json +1 -0
- package/manifest/components/score-breakdown.json +1 -0
- package/manifest/components/scroll-anchor.json +1 -0
- package/manifest/components/settings-panel.json +1 -0
- package/manifest/components/shape-section.json +1 -0
- package/manifest/components/shared-conversation.json +1 -0
- package/manifest/components/sheet.json +1 -0
- package/manifest/components/speaker-identity.json +1 -0
- package/manifest/components/stopped-run.json +1 -0
- package/manifest/components/streaming-text.json +1 -0
- package/manifest/components/sub.json +1 -0
- package/manifest/components/sup.json +1 -0
- package/manifest/components/tags-input.json +1 -0
- package/manifest/components/terminal-frame.json +1 -0
- package/manifest/components/textarea.json +1 -0
- package/manifest/components/theme-configurator.json +1 -0
- package/manifest/components/theme-provider.json +26 -1
- package/manifest/components/toast.json +1 -0
- package/manifest/components/tool-call-card.json +1 -0
- package/manifest/components/tool-error.json +1 -0
- package/manifest/components/tooltip.json +1 -0
- package/manifest/components/voice-conversation.json +1 -0
- package/manifest/manifest.json +133 -105
- package/manifest/tokens.json +20 -1
- package/package.json +11 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,310 @@
|
|
|
1
1
|
# @cueplusplus/ui
|
|
2
2
|
|
|
3
|
+
## 0.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f9bb2ff: **`Frames` takes a `layout`.** The default, `"board"`, is what it has always
|
|
8
|
+
drawn: a picker across the top and one frame on the stage at a time. The new
|
|
9
|
+
`"column"` runs every frame down a single scroller instead — each with its own
|
|
10
|
+
caption and count, all of them on one ground — so a reader comparing eight
|
|
11
|
+
states of a component reads them rather than clicking through them.
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Frames layout="column" …/>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Nothing changes for markup that does not pass it: `layout` defaults to
|
|
18
|
+
`"board"`, and a `Frames` with no `layout` prop renders byte-for-byte what it
|
|
19
|
+
rendered before.
|
|
20
|
+
|
|
21
|
+
- f9bb2ff: **`ThemeProvider` takes a CSP `nonce`.**
|
|
22
|
+
|
|
23
|
+
When `overrides.densities` is set, the provider emits one `<style>` element for
|
|
24
|
+
the density layer. An application serving `style-src-elem 'self'
|
|
25
|
+
'nonce-<per-request>'` had that element refused on every page load: React
|
|
26
|
+
renders it on the client, and a client-rendered element cannot pick up a server
|
|
27
|
+
nonce by itself.
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
// app/layout.tsx — the nonce your middleware already mints
|
|
31
|
+
<ThemeProvider nonce={nonce} overrides={{ densities: … }}>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The attribute is set only when you pass one. It is absent otherwise rather than
|
|
35
|
+
present and empty, because `nonce=""` matches no `'nonce-…'` source and would
|
|
36
|
+
talk a policy out of admitting the element some other way.
|
|
37
|
+
|
|
38
|
+
Nothing else in this library emits a `<style>` element, and `prepaintScript()`
|
|
39
|
+
returns a string your application renders in a `<script>` of its own — so your
|
|
40
|
+
application already owns that element's nonce, and this prop is the whole of
|
|
41
|
+
what a strict `style-src-elem` needs from here.
|
|
42
|
+
|
|
43
|
+
**One thing a nonce cannot fix.** The provider always sets a style _attribute_
|
|
44
|
+
on its root — `color-scheme` and `--cue-font-scale`, plus the font families and
|
|
45
|
+
overrides where given. CSP has no nonce form for `style-src-attr`: it is
|
|
46
|
+
`'unsafe-inline'` or `'none'`. Under `'none'` the browser drops those
|
|
47
|
+
declarations, and no prop here can change that.
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- 331501f: ## The scope goes public
|
|
52
|
+
|
|
53
|
+
Every package in `@cueplusplus` was private on npm. npm authenticates _every_
|
|
54
|
+
read of a private package, so each consumer needed a granular read-only token,
|
|
55
|
+
and it could not live in a committed `.npmrc` — pnpm 10 and later ignore an
|
|
56
|
+
env-expanded `_authToken` there by design. The failure mode was the expensive
|
|
57
|
+
part: npm answers a private package the same way to a reader it will not admit
|
|
58
|
+
exists, so a missing credential surfaced as `404 Not Found` rather than `401`,
|
|
59
|
+
and read as "this was never published".
|
|
60
|
+
|
|
61
|
+
That was a fair trade while the design system had no consumer outside the org.
|
|
62
|
+
It stopped being one the moment a public project depended on it, because a
|
|
63
|
+
public project cannot ask its readers for a token before they can install it.
|
|
64
|
+
|
|
65
|
+
So `access` is `public`, in the Changesets config and in all sixteen manifests.
|
|
66
|
+
Consumers now run `pnpm add @cueplusplus/ui` and nothing else: no token, no
|
|
67
|
+
`.npmrc`, nothing to rotate, and no extra step in CI or on a hosting provider.
|
|
68
|
+
|
|
69
|
+
Nothing else moves. Same registry, same names, same versions — so no consumer
|
|
70
|
+
needs to regenerate a lockfile, and a machine that keeps its npm token for
|
|
71
|
+
another private scope can keep it.
|
|
72
|
+
|
|
73
|
+
The guard tests are turned around rather than removed. `changeset-config` still
|
|
74
|
+
asserts the access level and `publishable-packages` still asserts the registry;
|
|
75
|
+
both now assert the public contract. `publishable-packages` additionally asserts
|
|
76
|
+
`access: "public"` per manifest, which it never did before: the Changesets config
|
|
77
|
+
decides what a release does, but npm defaults a scoped package to restricted, so
|
|
78
|
+
a manifest that forgets is the one that quietly stays private while its siblings
|
|
79
|
+
go public.
|
|
80
|
+
|
|
81
|
+
- 52094a9: **The `@cueplusplus` scope is served by npm now, not GitHub Packages.** Every package is
|
|
82
|
+
**private** there, so installs still authenticate — but the credential and the configuration both
|
|
83
|
+
change, and the old ones stop working.
|
|
84
|
+
|
|
85
|
+
**What to remove.** The scope routing you were asked to commit:
|
|
86
|
+
|
|
87
|
+
```ini
|
|
88
|
+
# .npmrc — delete this line
|
|
89
|
+
@cueplusplus:registry=https://npm.pkg.github.com
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Nothing replaces it. npm's own registry is where the scope resolves by default, so there is no
|
|
93
|
+
routing to commit at all — which also means a project that consumed this scope through a committed
|
|
94
|
+
`.npmrc` can usually delete the file.
|
|
95
|
+
|
|
96
|
+
**What to replace.** The classic GitHub PAT with `read:packages` is no longer used. In its place,
|
|
97
|
+
an npm **granular access token** with **read-only** permission on the `@cueplusplus` scope,
|
|
98
|
+
written once at the user level:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
pnpm config set //registry.npmjs.org/:_authToken npm_…
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
It goes at the user level for the same reason as before: pnpm 10 and later ignore an env-expanded
|
|
105
|
+
`_authToken` in a project `.npmrc`, and the install then fails with a `404` — not a `401` — and a
|
|
106
|
+
warning nobody reads. npm answers a private package the same way to a reader it will not admit
|
|
107
|
+
exists, so the failure reads as "never published".
|
|
108
|
+
|
|
109
|
+
**One token, every scope.** npm authenticates per registry rather than per scope, so a machine
|
|
110
|
+
that installs other private scopes from npm needs one line, not one per scope — select them all on
|
|
111
|
+
the same token. Two different tokens for `registry.npmjs.org` cannot coexist in one config.
|
|
112
|
+
|
|
113
|
+
**CI changes too, and this one is easy to miss.** Under GitHub Packages a workflow's own
|
|
114
|
+
`GITHUB_TOKEN` could read the scope, so many workflows carried no secret. npm does not know about
|
|
115
|
+
that token. Every repository that installs these packages now needs the read-only npm token as a
|
|
116
|
+
secret, and `setup-node` pointed at `registry.npmjs.org`. The same applies to Vercel, Trigger.dev
|
|
117
|
+
and any Docker build that installs — `docs/CONSUMING.md` §1 has each of them.
|
|
118
|
+
|
|
119
|
+
Nothing about the packages themselves changed: same exports, same versions, same contents. What
|
|
120
|
+
moved is where they are served from and what proves you may read them.
|
|
121
|
+
|
|
122
|
+
- Updated dependencies [331501f]
|
|
123
|
+
- Updated dependencies [52094a9]
|
|
124
|
+
- @cueplusplus/theme-base@1.0.3
|
|
125
|
+
- @cueplusplus/tokens@0.14.0
|
|
126
|
+
|
|
127
|
+
## 0.13.0
|
|
128
|
+
|
|
129
|
+
### Minor Changes
|
|
130
|
+
|
|
131
|
+
- f87c822: `Band`, the page's horizontal section — and `Footer` now spends its recipe
|
|
132
|
+
instead of carrying a second copy of it.
|
|
133
|
+
|
|
134
|
+
**What `Band` is.** A full-bleed element, a rule or a ground running edge to
|
|
135
|
+
edge, and a centred column at the measure — which is what a footer has always
|
|
136
|
+
been, minus the footer. Every dimension it spends belongs to the fourth axis,
|
|
137
|
+
so the same markup composes three ways under `data-style` with no prop
|
|
138
|
+
changing: `--cue-band-y` for the rhythm, `--cue-measure-prose` for the column
|
|
139
|
+
unless `width` names one of `Container`'s four fixed rungs, and
|
|
140
|
+
`--cue-band-rule` / `--cue-band-ground` for the separation. `separation` takes
|
|
141
|
+
`"rule"`, `"ground"`, `"bleed"` (no column — the children run the full width)
|
|
142
|
+
and `"none"` (rhythm alone). Two of those can come out to nothing, by design
|
|
143
|
+
and with nothing to warn you, and they do not vanish symmetrically: a ground is
|
|
144
|
+
`transparent` on `:root` and on two of the three sets, so it paints only under
|
|
145
|
+
`marketing`, while a rule is `0px` under `marketing` alone. The prop's
|
|
146
|
+
documentation carries the table, and a test holds the table to the stylesheet
|
|
147
|
+
so it cannot stop being true.
|
|
148
|
+
|
|
149
|
+
**What changed for existing callers.** `Footer` is built on `Band`'s recipe
|
|
150
|
+
now — `separation="rule"`, spent through two internal helpers rather than
|
|
151
|
+
through `<Band>` itself, because `Band` renders a `<section>` and `Footer` has
|
|
152
|
+
to keep rendering the `<footer>` that makes it the `contentinfo` landmark.
|
|
153
|
+
Under no style set it renders exactly what it rendered before: `--cue-band-y`
|
|
154
|
+
resolves to `var(--cue-space-7)`, the same rung the column always spelled, and
|
|
155
|
+
`--cue-band-rule` resolves to `var(--cue-border-width)`, the same 1px
|
|
156
|
+
`border-t` always painted. Inside a `[data-style]` subtree it now follows the
|
|
157
|
+
axis like any other band: a hairline and doubled rhythm under `editorial`, no
|
|
158
|
+
rule at all and trebled rhythm under `marketing`. **This is the first shipped
|
|
159
|
+
component to follow `data-style`.** An app that wants the old, fixed behaviour
|
|
160
|
+
inside a styled region wraps the footer in `<Density styleSet="console">`.
|
|
161
|
+
|
|
162
|
+
**What did not change.** `FooterProps` is the same four props —
|
|
163
|
+
`width`, `meta`, `columnClassName`, `children` — byte for byte; this is a
|
|
164
|
+
change of implementation, not of contract. The fine-print rule above the
|
|
165
|
+
meta row is still a literal `border-t border-border` and does not follow the
|
|
166
|
+
axis: it separates content inside the footer, not the footer from the page.
|
|
167
|
+
|
|
168
|
+
**What the published manifest says now.** The helper `Footer` spends `Band`'s
|
|
169
|
+
recipe through first landed in `band.tsx`, a public component file — and
|
|
170
|
+
`packages/docgen`'s token scanner only follows a component's imports into an
|
|
171
|
+
underscore-prefixed chassis file, the same convention `chrome/_drag.ts` already
|
|
172
|
+
uses. It never opened `band.tsx`, so `footer.json`'s `tokensUsed` — and the
|
|
173
|
+
token chips on `/docs/components/footer` — silently lost `--cue-space-7` and
|
|
174
|
+
gained neither of the two names that replaced it. The recipe now lives in
|
|
175
|
+
`chrome/_band.ts`, and `footer.json` publishes ten names: the nine it shipped
|
|
176
|
+
before this branch, less the `--cue-space-7` that `--cue-band-y` replaced, plus
|
|
177
|
+
`--cue-band-y` and `--cue-band-rule`. Those two
|
|
178
|
+
are the whole of what a `<footer>` takes from the recipe, so they are the whole
|
|
179
|
+
of what that file holds — the scanner reads a chassis file whole and cannot see
|
|
180
|
+
which branch a call takes, and `Footer` fixes `separation` at the literal
|
|
181
|
+
`"rule"` and types `width` as `ContainerWidth`. `Band`'s other two style-owned
|
|
182
|
+
spends, `--cue-band-ground` and `--cue-measure-prose`, are unreachable from a
|
|
183
|
+
footer and are written in `band.tsx` beside the prop values that select them,
|
|
184
|
+
so `band.json` publishes all five and `footer.json` claims neither. Nothing
|
|
185
|
+
else in either component's manifest entry moved.
|
|
186
|
+
|
|
187
|
+
**What it costs.** Nothing at runtime; the manifest grows one component.
|
|
188
|
+
|
|
189
|
+
**Correction, no behaviour change.** `layout/preview.tsx`'s docblock cited the
|
|
190
|
+
group pages' tooled `Preview` count as 325; `Band` landing raised the
|
|
191
|
+
library's component count and the tooled figure to 326. Comment-only, caught
|
|
192
|
+
by the branch's own review sweep, and folded in here because it is the last
|
|
193
|
+
commit that touches this package's authored tree before the note.
|
|
194
|
+
|
|
195
|
+
- 5b40f07: **A fourth composable axis: `data-style`, for page composition.**
|
|
196
|
+
|
|
197
|
+
Theme, density and font already answer "what colour", "how tight" and "which
|
|
198
|
+
typeface". `data-style` answers the question none of them could: how a _page_ is
|
|
199
|
+
composed — reading measure, prose line height, and the rhythm of a band. Three
|
|
200
|
+
sets ship. `console` is the current look made explicit and provably unchanged,
|
|
201
|
+
`editorial` widens the measure and opens the leading for long-form reading, and
|
|
202
|
+
`marketing` narrows the measure and spends the vertical space a landing page
|
|
203
|
+
wants.
|
|
204
|
+
|
|
205
|
+
Each set declares `--cue-measure-prose`, `--cue-leading-prose`, `--cue-band-y`,
|
|
206
|
+
`--cue-band-rule` and `--cue-band-ground`; `editorial` and `marketing` add
|
|
207
|
+
`--cue-style-display` for a display type scale. Only the display rung composes
|
|
208
|
+
with `--cue-font-scale`, and a name added to the set vocabulary without an
|
|
209
|
+
answer is a build error rather than a silent guess.
|
|
210
|
+
|
|
211
|
+
**Driving it.** `<ThemeProvider styleSet="editorial">` stamps the attribute on
|
|
212
|
+
its own element and on `<html>`, `useTheme().styleSet` and `setStyleSet()` read
|
|
213
|
+
and drive it, and it persists beside theme, density, font and mode under a
|
|
214
|
+
`style` key — written only when there is a set. A pre-paint script applies a
|
|
215
|
+
stored set before the first paint, so turning one on _or off_ lands on the first
|
|
216
|
+
frame rather than the first commit. The set is carried into overlay portals,
|
|
217
|
+
`<Density styleSet>` islands and `<Preview styleSet>` stages, so an overlay
|
|
218
|
+
follows the subtree it was opened from and three sets can be shown side by side
|
|
219
|
+
on one page.
|
|
220
|
+
|
|
221
|
+
`useTheme().styleSet` is **the set in force, not the set named here**. A
|
|
222
|
+
provider that names no set of its own reports the one stamped around it —
|
|
223
|
+
including a `<Density styleSet>` island sitting between it and an outer provider
|
|
224
|
+
— exactly as the DOM resolves it. That is deliberate: it makes the context value
|
|
225
|
+
and the set a portal or a stage carries out of that DOM one value rather than
|
|
226
|
+
two that can disagree. `null` means nothing anywhere has chosen a set, which is
|
|
227
|
+
not the same fact as `console`.
|
|
228
|
+
|
|
229
|
+
`setStyleSet(null)` is the same distinction from the writing side: it clears the
|
|
230
|
+
set this provider **names**, not the set that applies to it. A nested provider
|
|
231
|
+
that clears its own goes back to inheriting whatever is stamped around it, and
|
|
232
|
+
`styleSet` reports that inherited set, because it is what the cascade resolves
|
|
233
|
+
to. At the root the two coincide, which is why only a nested provider shows the
|
|
234
|
+
difference. To positively leave an inherited set, pass `DEFAULT_STYLE_SET`: it
|
|
235
|
+
stamps an attribute whose block restates the `:root` defaults token for token,
|
|
236
|
+
and an attribute is the only thing that out-specifies an ancestor's.
|
|
237
|
+
|
|
238
|
+
Restating a set on a `<Density>` island is what re-resolves its band rhythm at
|
|
239
|
+
that island's rung: `--cue-band-y` is built from `--cue-space-7`, and a custom
|
|
240
|
+
property's `var()` references are substituted where they are declared, so an
|
|
241
|
+
island that only changes density inherits the rhythm already resolved above it.
|
|
242
|
+
|
|
243
|
+
`STYLE_SETS`, `DEFAULT_STYLE_SET`, `STYLE_CONTRACT`, `STYLE_SET_CONTRACT` and
|
|
244
|
+
the `StyleSet` type are exported from `@cueplusplus/tokens`, so an application
|
|
245
|
+
can type a prop and validate a stored preference against the same closed list
|
|
246
|
+
the stylesheet was built from.
|
|
247
|
+
|
|
248
|
+
**What it costs.**
|
|
249
|
+
|
|
250
|
+
- **Every consumer carries 144 more bytes of blocking inline pre-paint script**,
|
|
251
|
+
whether or not the application uses the axis — a typical script grows from 995
|
|
252
|
+
bytes to 1139. It has to read the stored set and stamp or clear the attribute
|
|
253
|
+
before the first paint, and an application that never touches the axis cannot
|
|
254
|
+
opt out of the branch that decides there is nothing to stamp.
|
|
255
|
+
- **The attribute is the generic `data-style`, not `data-cue-style`.** An
|
|
256
|
+
application already using `data-style` on `<html>` for its own purposes will
|
|
257
|
+
have it overwritten while a `<ThemeProvider>` is mounted, and cleared when the
|
|
258
|
+
provider holds no set; the original value is restored on unmount. The generic
|
|
259
|
+
name was chosen for readability, and this collision is the price. If you use
|
|
260
|
+
`data-style` on `<html>` yourself, move it before upgrading.
|
|
261
|
+
|
|
262
|
+
**What is unchanged.** A page that names no set is untouched: no attribute is
|
|
263
|
+
stamped anywhere, no stored preference gains a key, and a stored `"style": null`
|
|
264
|
+
is refused and scrubbed on the next load like every other value nothing
|
|
265
|
+
declares. `console`'s declarations are asserted at build time to be exactly the
|
|
266
|
+
`:root` defaults, and a browser test compares every `--cue-*` on two identical
|
|
267
|
+
subtrees — one bare, one under `console` — and requires them to compute
|
|
268
|
+
identically. Switching to the default set changes nothing, as a checked fact
|
|
269
|
+
rather than a promise.
|
|
270
|
+
|
|
271
|
+
One note on `editorial`'s hairline: its 0.5px `--cue-band-rule` paints a
|
|
272
|
+
measured 1px on Chromium at either device pixel ratio and 0.5px only on retina
|
|
273
|
+
WebKit, so the separation it actually ships is the doubled `--cue-space-7`
|
|
274
|
+
rhythm with a hairline under it.
|
|
275
|
+
|
|
276
|
+
### Patch Changes
|
|
277
|
+
|
|
278
|
+
- b1c2f25: **Every package now ships the licence it declares.** All sixteen have said `"license": "MIT"` in
|
|
279
|
+
their manifest since they were first published, and none of them carried the text. Installing one
|
|
280
|
+
gave you a licence field and nothing to read; anyone auditing their dependency tree found a package
|
|
281
|
+
that claimed a licence it did not include. Each package root now holds the MIT notice, and npm packs
|
|
282
|
+
a root `LICENSE` whether or not `files` lists it, so it is in the tarball you install.
|
|
283
|
+
|
|
284
|
+
`@cueplusplus/ui` additionally ships `NOTICE.md`, the third-party notice for the assistant-ui code
|
|
285
|
+
vendored into its elements. That one is not automatic — `files` had to name it — and it is byte-for-byte
|
|
286
|
+
the notice that already sat beside the source it covers, because a notice that travels without the
|
|
287
|
+
bytes it describes is not a notice.
|
|
288
|
+
|
|
289
|
+
Nothing else about these packages changed: same exports, same versions of every dependency, same
|
|
290
|
+
registry. If you are upgrading only for this, the diff you receive is licence text.
|
|
291
|
+
|
|
292
|
+
- 0b30ba6: `ImageGeneration` now clears its blur with `blur-none`. It used to ask for `blur-0`, which is a Tailwind v3 class that v4 has no rule for, so the class did nothing at all. You will not see a difference — the image already came out of its blur when generation finished, because a filter transition runs to no filter just as it runs to zero blur — but the class now says what it does, and the elements sync renames it, so a re-sync from assistant-ui will not put it back.
|
|
293
|
+
- 6f791a8: Two families of hard-coded values become tokens, with nothing rendering differently.
|
|
294
|
+
|
|
295
|
+
`PageShell` and `Container` spell their three capped measures as `max-w-(--cue-measure-narrow)` / `-wide` / `-broad` rather than as `max-w-[42rem]` / `[54rem]` / `[84rem]`. Nothing about the props changes — `PageWidth` and `ContainerWidth` still offer `narrow` / `wide` / `broad` / `full`, still default to `narrow`, and `full` still caps nothing.
|
|
296
|
+
|
|
297
|
+
And the 63 `leading-relaxed` utilities across 55 of this library's modules — dialogs, menus, settings panels, chat rows, tooltips, cards, the two shared class strings behind every collapsible and every popup surface — now spend `--cue-leading-ui`, which `@cueplusplus/tokens` pins at 1.625, Tailwind's own value for that utility. Ninety-one components pick the token up in their `tokensUsed`. `leading-none` is untouched: line-height 1 on an icon or a numeral is a shape decision, not a reading one, so a reading axis has nothing to say about it.
|
|
298
|
+
|
|
299
|
+
Both are exact no-ops today. What they buy you is a knob: one declaration of `--cue-leading-ui` or `--cue-measure-wide`, anywhere in your own CSS, and every component that spends it follows — with no fork and no `className` at the call site.
|
|
300
|
+
|
|
301
|
+
- f813329: `Progress` now names its bar in the HTML your server sends. A screen-reader user on a server-rendered page heard "progress bar, 40%" and never the caption beside it: the words were on the page, but the `role="progressbar"` only pointed at them once the browser had hydrated — and on a page that never hydrates, never. Base UI makes that connection from a layout effect; this layer now hands the caption and the bar the same `useId` while it renders, so the name is in the markup from the first byte and the same reader hears "Rendering, progress bar, 40%" whether or not the JavaScript has arrived. Nothing moves on screen, and a bar you named yourself with `aria-label` or `aria-labelledby` keeps the name you gave it — in the served markup and after hydration alike, which is asserted in both renders rather than in the one the change was written in.
|
|
302
|
+
- Updated dependencies [b1c2f25]
|
|
303
|
+
- Updated dependencies [31a7567]
|
|
304
|
+
- Updated dependencies [5b40f07]
|
|
305
|
+
- @cueplusplus/theme-base@1.0.2
|
|
306
|
+
- @cueplusplus/tokens@0.13.0
|
|
307
|
+
|
|
3
308
|
## 0.12.0
|
|
4
309
|
|
|
5
310
|
### Minor Changes
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CUE++ contributors
|
|
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/NOTICE.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Third-party notice — assistant-ui Elements
|
|
2
|
+
|
|
3
|
+
The files in this directory are vendored from [assistant-ui/assistant-ui](https://github.com/assistant-ui/assistant-ui)
|
|
4
|
+
at commit `31a049fcfa846a76da7c8e2c0bcd62960825dbd4` (2026-08-22), from `packages/ui/src/components/elements/`.
|
|
5
|
+
They are rewritten onto CUE++ tokens by `scripts/elements-sync/`, which also records every
|
|
6
|
+
byte it fetched in `scripts/elements-sync/elements-sync.lock.json`.
|
|
7
|
+
|
|
8
|
+
Elements are distributed only as copy-in source through a shadcn registry — there is no npm
|
|
9
|
+
package to depend on — so vendoring is the intended use, and the licence below is the whole
|
|
10
|
+
obligation it carries.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
MIT License
|
|
14
|
+
|
|
15
|
+
Copyright (c) 2025 AgentbaseAI Inc.
|
|
16
|
+
|
|
17
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
18
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
19
|
+
in the Software without restriction, including without limitation the rights
|
|
20
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
21
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
22
|
+
furnished to do so, subject to the following conditions:
|
|
23
|
+
|
|
24
|
+
The above copyright notice and this permission notice shall be included in all
|
|
25
|
+
copies or substantial portions of the Software.
|
|
26
|
+
|
|
27
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
28
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
29
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
30
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
31
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
32
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
33
|
+
SOFTWARE.
|
|
34
|
+
```
|
package/README.md
CHANGED
|
@@ -5,25 +5,8 @@ Base UI underneath for behaviour and accessibility, Tailwind v4 on top for the p
|
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
8
|
-
The `@cueplusplus` scope is
|
|
9
|
-
|
|
10
|
-
cosmetic — pnpm ignores an env-expanded credential in a project `.npmrc` and the install fails
|
|
11
|
-
with `401`.
|
|
12
|
-
|
|
13
|
-
Commit the scope routing, and nothing else, at the root of your project:
|
|
14
|
-
|
|
15
|
-
```ini
|
|
16
|
-
# .npmrc
|
|
17
|
-
@cueplusplus:registry=https://npm.pkg.github.com
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Then write the credential once, at the **user** level, where pnpm reads it from. It is a
|
|
21
|
-
**classic** personal access token with `read:packages` — GitHub Packages accepts neither
|
|
22
|
-
fine-grained PATs nor OIDC:
|
|
23
|
-
|
|
24
|
-
```sh
|
|
25
|
-
pnpm config set //npm.pkg.github.com/:_authToken ghp_…
|
|
26
|
-
```
|
|
8
|
+
The `@cueplusplus` scope is **public on npm** and resolves there by default, so there is nothing
|
|
9
|
+
to configure and no credential to supply — it installs like any other package.
|
|
27
10
|
|
|
28
11
|
```sh
|
|
29
12
|
pnpm add @cueplusplus/ui @cueplusplus/tokens @cueplusplus/theme-cue @base-ui/react
|
|
@@ -165,7 +165,7 @@ const ToolCallCard = React.forwardRef(function ToolCallCard({ className, tool, a
|
|
|
165
165
|
children: argsLabel
|
|
166
166
|
}), /* @__PURE__ */ jsx("pre", {
|
|
167
167
|
"data-slot": "tool-call-card-args",
|
|
168
|
-
className: "m-0 min-w-0 overflow-x-auto font-mono text-(length:--cue-text-micro) leading-
|
|
168
|
+
className: "m-0 min-w-0 overflow-x-auto font-mono text-(length:--cue-text-micro) leading-(--cue-leading-ui) break-words whitespace-pre-wrap text-fg-muted",
|
|
169
169
|
children: args
|
|
170
170
|
})] }) : null,
|
|
171
171
|
hasResult ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
@@ -174,7 +174,7 @@ const ToolCallCard = React.forwardRef(function ToolCallCard({ className, tool, a
|
|
|
174
174
|
children: resultLabel
|
|
175
175
|
}), /* @__PURE__ */ jsx("div", {
|
|
176
176
|
"data-slot": "tool-call-card-result",
|
|
177
|
-
className: "min-w-0 font-mono text-(length:--cue-text-micro) leading-
|
|
177
|
+
className: "min-w-0 font-mono text-(length:--cue-text-micro) leading-(--cue-leading-ui) break-words whitespace-pre-wrap text-fg",
|
|
178
178
|
children: result
|
|
179
179
|
})] }) : null,
|
|
180
180
|
children
|
package/dist/chat/ask-box.js
CHANGED
|
@@ -154,7 +154,7 @@ const AskBox = React.forwardRef(function AskBox({ className, question, kind = "t
|
|
|
154
154
|
className: "mt-(--cue-space-3) flex flex-col gap-(--cue-space-2) border-t border-border pt-(--cue-space-3)",
|
|
155
155
|
children: [
|
|
156
156
|
/* @__PURE__ */ jsx("p", {
|
|
157
|
-
className: "text-(length:--cue-text-ui) leading-
|
|
157
|
+
className: "text-(length:--cue-text-ui) leading-(--cue-leading-ui) break-words whitespace-pre-wrap text-fg-muted",
|
|
158
158
|
children: question
|
|
159
159
|
}),
|
|
160
160
|
/* @__PURE__ */ jsx("p", {
|
|
@@ -326,7 +326,7 @@ const AskBox = React.forwardRef(function AskBox({ className, question, kind = "t
|
|
|
326
326
|
/* @__PURE__ */ jsx("p", {
|
|
327
327
|
id: questionId,
|
|
328
328
|
"data-slot": "ask-box-question",
|
|
329
|
-
className: "min-w-0 text-(length:--cue-text-body) leading-
|
|
329
|
+
className: "min-w-0 text-(length:--cue-text-body) leading-(--cue-leading-ui) break-words whitespace-pre-wrap text-fg",
|
|
330
330
|
children: question
|
|
331
331
|
}),
|
|
332
332
|
/* @__PURE__ */ jsx("div", {
|
package/dist/chat/composer.js
CHANGED
|
@@ -104,7 +104,7 @@ const Composer = React.forwardRef(function Composer({ className, onSend, value:
|
|
|
104
104
|
placeholder,
|
|
105
105
|
disabled,
|
|
106
106
|
value,
|
|
107
|
-
className: cn(bareControlClasses, "min-h-control-lg resize-none self-stretch py-(--cue-space-2) text-(length:--cue-text-body) leading-
|
|
107
|
+
className: cn(bareControlClasses, "min-h-control-lg resize-none self-stretch py-(--cue-space-2) text-(length:--cue-text-body) leading-(--cue-leading-ui)"),
|
|
108
108
|
onChange: (event) => setValue(event.target.value),
|
|
109
109
|
onKeyDown
|
|
110
110
|
}),
|
package/dist/chat/message.js
CHANGED
|
@@ -85,7 +85,7 @@ const Message = React.forwardRef(function Message({ className, role = "agent", a
|
|
|
85
85
|
}) : null,
|
|
86
86
|
/* @__PURE__ */ jsxs("div", {
|
|
87
87
|
"data-slot": "message-body",
|
|
88
|
-
className: "relative min-w-0 text-(length:--cue-text-body) leading-
|
|
88
|
+
className: "relative min-w-0 text-(length:--cue-text-body) leading-(--cue-leading-ui) break-words whitespace-pre-wrap",
|
|
89
89
|
children: [children, pending ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
90
90
|
"data-slot": "message-caret",
|
|
91
91
|
"aria-hidden": "true",
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
//#region src/chrome/_band.ts
|
|
3
|
+
/**
|
|
4
|
+
* The rule a band draws at its top edge.
|
|
5
|
+
*
|
|
6
|
+
* Spelt as `border-t-(length:--cue-band-rule)` and not as
|
|
7
|
+
* `border-t-(--cue-band-rule)`. Both compile. The second sets
|
|
8
|
+
* `border-top-color`, which would give every band a 1px rule in the token's own
|
|
9
|
+
* text as a colour — a rule that is always drawn and never right. The `length:`
|
|
10
|
+
* hint is what makes Tailwind emit `border-top-width`. It does not carry
|
|
11
|
+
* `border-border` — the element that spends this adds that itself, so both
|
|
12
|
+
* `Band` and `Footer` say in their own class list what colours their rule,
|
|
13
|
+
* rather than one of the two inheriting it silently from the other.
|
|
14
|
+
*/
|
|
15
|
+
const RULE = "border-t-(length:--cue-band-rule)";
|
|
16
|
+
/**
|
|
17
|
+
* The band recipe as class strings, for the one other element in this library
|
|
18
|
+
* that is a band and cannot be a `<section>`.
|
|
19
|
+
*
|
|
20
|
+
* `Footer` is the `contentinfo` landmark: it has to render a `<footer>`, and
|
|
21
|
+
* this library has exactly one polymorphic escape hatch (`ThemeProvider`'s
|
|
22
|
+
* `asChild`) whose own documentation calls it the one place. So rather than
|
|
23
|
+
* give `Band` a second one, or let `Footer` keep a second copy of the recipe
|
|
24
|
+
* — which is the thing spec Decision 4 refuses by name — the strings live here
|
|
25
|
+
* and both elements spend them.
|
|
26
|
+
*
|
|
27
|
+
* It lives in an underscore-prefixed chassis file rather than in `band.tsx` on
|
|
28
|
+
* purpose: `packages/docgen`'s token scanner only follows a component's imports
|
|
29
|
+
* into files whose basename starts with `_`, and `Footer` spends this recipe
|
|
30
|
+
* without rendering `<Band>` itself. Keeping the strings on `band.tsx` left
|
|
31
|
+
* `footer.json`'s published `tokensUsed` silently missing the two tokens this
|
|
32
|
+
* function spends — the rhythm and the rule — because the scanner had no reason
|
|
33
|
+
* to open a public component file it was not asked to document. This file is
|
|
34
|
+
* that reason.
|
|
35
|
+
*
|
|
36
|
+
* **Exactly those two names live here, and that is the second half of the same
|
|
37
|
+
* mechanism.** The scanner reads a chassis file whole; it does not know which
|
|
38
|
+
* branch a call takes, so every `--cue-*` written in this file is published as
|
|
39
|
+
* a token *both* elements render with. `Footer` calls this with the literal
|
|
40
|
+
* `"rule"` and types its own `width` as `ContainerWidth`, so `Band`'s other two
|
|
41
|
+
* spends — `bg-(--cue-band-ground)` for `separation="ground"` and
|
|
42
|
+
* `max-w-(--cue-measure-prose)` for `width="prose"` — are unreachable from a
|
|
43
|
+
* `<footer>` and are written in `band.tsx`, beside the prop that selects them.
|
|
44
|
+
* Moving them here would make `footer.json` claim two tokens the component
|
|
45
|
+
* cannot paint, which is the same defect as the omission this file was written
|
|
46
|
+
* to fix, pointing the other way.
|
|
47
|
+
*
|
|
48
|
+
* It is not exported from the package. A caller who wants a band uses `Band`.
|
|
49
|
+
*/
|
|
50
|
+
function bandClasses(separation) {
|
|
51
|
+
return cn("w-full py-(--cue-band-y)", separation === "rule" ? RULE : null);
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { bandClasses };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ContainerWidth } from "../layout/container.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/chrome/band.d.ts
|
|
4
|
+
/** How a band separates itself from the section above it. */
|
|
5
|
+
type BandSeparation = "rule" | "ground" | "bleed" | "none";
|
|
6
|
+
/**
|
|
7
|
+
* Which measure a band's column takes: `Container`'s four fixed rungs, plus
|
|
8
|
+
* `"prose"` — the reading measure a style set owns.
|
|
9
|
+
*
|
|
10
|
+
* `"prose"` is the default and is the only one of the five that moves with
|
|
11
|
+
* `[data-style]`: 68ch with no set and under `console`, 74ch under `editorial`,
|
|
12
|
+
* 60ch under `marketing`. The four rungs are fixed aliases and a band that
|
|
13
|
+
* names one has opted out of the axis for its measure — which is the right
|
|
14
|
+
* answer for a band holding a `Bento` or a device frame, and the wrong one for
|
|
15
|
+
* a band holding a paragraph.
|
|
16
|
+
*/
|
|
17
|
+
type BandWidth = ContainerWidth | "prose";
|
|
18
|
+
interface BandProps extends React.ComponentPropsWithoutRef<"section"> {
|
|
19
|
+
/**
|
|
20
|
+
* How this band separates itself from the one above it. Defaults to `"rule"`.
|
|
21
|
+
*
|
|
22
|
+
* - **`"rule"`** — a line at the top edge, `--cue-band-rule` wide, in
|
|
23
|
+
* `border-border`. What `Footer` has always drawn.
|
|
24
|
+
* - **`"ground"`** — a ground, `--cue-band-ground`, edge to edge. The one
|
|
25
|
+
* value that touches colour, and it resolves through the single carve-out
|
|
26
|
+
* the token layer allows a style set.
|
|
27
|
+
* - **`"bleed"`** — neither, and **no column**: the children run the band's
|
|
28
|
+
* full width with no measure and no gutters. The separation is the change
|
|
29
|
+
* of scale, which is what a full-width image or strip does. `width` has
|
|
30
|
+
* nothing to apply to and is ignored.
|
|
31
|
+
* - **`"none"`** — neither, column kept. Sections separate by rhythm alone,
|
|
32
|
+
* which is `--cue-band-y` and is what `editorial` leads with.
|
|
33
|
+
*
|
|
34
|
+
* **What a style set makes each of these do, because two of them can come out
|
|
35
|
+
* to nothing and there is no way for this component to warn you.** The values
|
|
36
|
+
* are the token layer's; `packages/ui/test/chrome/band.test.tsx` holds this
|
|
37
|
+
* table to `packages/tokens/dist/axes.css`, so it cannot quietly stop being
|
|
38
|
+
* true.
|
|
39
|
+
*
|
|
40
|
+
* | set | `"rule"` draws | `"ground"` paints |
|
|
41
|
+
* |---|---|---|
|
|
42
|
+
* | *(no set)* and `console` | 1px | nothing — the ground is `transparent` |
|
|
43
|
+
* | `editorial` | a 0.5px hairline, **which Chromium paints at 1px at every DPR**; only retina WebKit draws it thinner | nothing — `transparent` |
|
|
44
|
+
* | `marketing` | **nothing — the rule is `0px`** | `--cue-surface-1` |
|
|
45
|
+
*
|
|
46
|
+
* Read the diagonal: `"ground"` is the marketing separation and `"rule"` is
|
|
47
|
+
* everyone else's. A band that wants to separate under *every* set separates
|
|
48
|
+
* by rhythm, which every set has.
|
|
49
|
+
*/
|
|
50
|
+
separation?: BandSeparation;
|
|
51
|
+
/** Which measure the band's centred column takes. Defaults to `"prose"`. */
|
|
52
|
+
width?: BandWidth;
|
|
53
|
+
/** Extra classes for the centred column. Ignored when `separation` is `"bleed"`. */
|
|
54
|
+
columnClassName?: string;
|
|
55
|
+
/** The band's contents. */
|
|
56
|
+
children?: React.ReactNode;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A full-bleed horizontal section: the page's rhythm, its separation, and a
|
|
60
|
+
* column at the measure.
|
|
61
|
+
*
|
|
62
|
+
* This is `Footer`'s recipe with the footer taken out of it — a `w-full`
|
|
63
|
+
* element, a rule running edge to edge, and a centred `Container` inside so the
|
|
64
|
+
* line reaches the window while the words stop at the measure. `Footer` is
|
|
65
|
+
* built on this rather than beside it; the recipe exists once.
|
|
66
|
+
*
|
|
67
|
+
* Every dimension it spends belongs to the style axis, so the same markup
|
|
68
|
+
* composes differently under `[data-style]` without a prop changing: the
|
|
69
|
+
* vertical rhythm is `--cue-band-y` (one `--cue-space-7` with no set, doubled
|
|
70
|
+
* under `editorial`, trebled under `marketing`), the column is
|
|
71
|
+
* `--cue-measure-prose` unless `width` names a fixed rung, and the rule and the
|
|
72
|
+
* ground are `--cue-band-rule` and `--cue-band-ground`. Read `separation`'s own
|
|
73
|
+
* documentation before choosing one, because two of the four can come out to
|
|
74
|
+
* nothing and they do not vanish symmetrically: `--cue-band-ground` is
|
|
75
|
+
* `transparent` on `:root` and on two of the three sets, so a `"ground"` paints
|
|
76
|
+
* nothing in three of the four states a page can be in, while `--cue-band-rule`
|
|
77
|
+
* is `0px` under `marketing` alone. Both are deliberate and nothing warns.
|
|
78
|
+
*
|
|
79
|
+
* **Two substitution boundaries, because `--cue-band-y` is a `calc()` resolved
|
|
80
|
+
* at the element that declares it.** A `<Density>` island nested inside a
|
|
81
|
+
* styled page moves every `--cue-space-*` and the band rhythm does **not**
|
|
82
|
+
* follow it — the island inherits the rhythm already resolved above. Restate
|
|
83
|
+
* the set on the island (`<Density density="compact" styleSet="editorial">`) to
|
|
84
|
+
* re-resolve it against that island's rung. Likewise a nested `[data-theme]`
|
|
85
|
+
* under a marketing band paints the **outer** theme's `--cue-surface-1` through
|
|
86
|
+
* an already-resolved `--cue-band-ground`.
|
|
87
|
+
*
|
|
88
|
+
* It renders a `<section>`, which is not a landmark until it has an accessible
|
|
89
|
+
* name — so a band with a heading should carry `aria-labelledby` pointing at
|
|
90
|
+
* it, and a band without one costs the document nothing.
|
|
91
|
+
*
|
|
92
|
+
* Static markup — no `"use client"`.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* <Band aria-labelledby="pitch">
|
|
96
|
+
* <h2 id="pitch">One import</h2>
|
|
97
|
+
* <p>Everything on one token layer.</p>
|
|
98
|
+
* </Band>
|
|
99
|
+
* @example
|
|
100
|
+
* <Band separation="ground" width="broad">
|
|
101
|
+
* <Bento.Root cols={3}>{tiles}</Bento.Root>
|
|
102
|
+
* </Band>
|
|
103
|
+
*/
|
|
104
|
+
declare const Band: React.ForwardRefExoticComponent<BandProps & React.RefAttributes<HTMLElement>>;
|
|
105
|
+
//#endregion
|
|
106
|
+
export { Band, BandProps, BandSeparation, BandWidth };
|