Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 46 additions & 46 deletions packages/cli/README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/cli/api/docs/docs.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export const doc = {
'returns that full ReferenceDoc (with token-ref blocks inlined); a topic ' +
'plus a section returns the first section whose title contains the ' +
'(case-insensitive) query. The topic set is the CLI\'s own docs plus the ' +
'ones the project\'s configured integrations contribute including any ' +
'topic an integration replaces or extends so it depends on the cwd. ' +
'ones the project\'s configured integrations contribute, including any ' +
'topic an integration replaces or extends, so it depends on the cwd. ' +
'Overlay options select localized or dense variants.',
importPath: '@astryxdesign/cli/api',
signature:
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/api/template/template.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const doc = {
{
type: 'template.skeleton',
description:
"A layout skeleton structural tags with spatial annotations plus the template's description and the components it composes.",
"A layout skeleton (structural tags with spatial annotations) plus the template's description and the components it composes.",
},
{
type: 'template.copy',
Expand All @@ -114,7 +114,7 @@ export const doc = {
{
type: 'template.cdn',
description:
'A write receipt for the CDN starter page: the path (relative to cwd), the Astryx version every CDN URL was pinned to, whether it was written, and the reason it was not `exists` when a file was already there, which is a success.',
'A write receipt for the CDN starter page: the path (relative to cwd), the Astryx version every CDN URL was pinned to, whether it was written, and the reason it was not. `exists` when a file was already there, which is a success.',
},
],
throws: [
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/api/theme/themeTemplate.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export const doc = {
displayName: 'themeTemplate()',
summary: 'Write the annotated theme template into a project.',
description:
'Writes theme.template.ts: the annotated reference for the whole theme surface every ' +
'Writes theme.template.ts: the annotated reference for the whole theme surface, covering every ' +
'defineTheme field, the token families, the component override syntax, and how a theme is ' +
'consumed with the CLI command that prints the authoritative reference for each section. ' +
'consumed, with the CLI command that prints the authoritative reference for each section. ' +
'Read it, copy what you need into your own theme file, delete it. Where `theme add` starts ' +
'you from a theme we ship, this starts you from a blank one. Refuses to overwrite without ' +
'`overwrite`, so it is safe to re-run.',
Expand Down Expand Up @@ -48,7 +48,7 @@ export const doc = {
{
type: 'theme.template',
description:
'Receipt: the path (relative to cwd), whether it was written, and the reason it was not `exists` when a file was already there, which is a success, not a failure.',
'Receipt: the path (relative to cwd), whether it was written, and the reason it was not. `exists` when a file was already there, which is a success, not a failure.',
},
],
throws: [{code: 'ERR_PATH_TRAVERSAL', when: 'the target path escapes cwd'}],
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/assets/docs/typography.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const docs = {
content: [
{
type: 'prose',
text: 'Astryx never loads font files. defineTheme and the built CSS only set font-familynaming a webfont (Fraunces, JetBrains Mono, ) makes every browser look for it, and quietly fall back when the app has not loaded it. `astryx theme build` warns when a theme names families that are neither CSS generics nor common system fonts and prints the snippet to add; loading the font is always the app\'s job.',
text: 'Astryx never loads font files. defineTheme and the built CSS only set font-family: naming a webfont (Fraunces, JetBrains Mono, and so on) makes every browser look for it, and quietly fall back when the app has not loaded it. `astryx theme build` warns when a theme names families that are neither CSS generics nor common system fonts and prints the snippet to add; loading the font is always the app\'s job.',
},
{
type: 'code',
Expand All @@ -77,7 +77,7 @@ export const docs = {
},
{
type: 'prose',
text: "Always pair a webfont with a real fallback stack metric-similar system fonts plus a generic so text stays readable before the font loads and wherever it never does: defineTheme({typography: {heading: {family: 'Fraunces', fallbacks: 'Georgia, serif'}}}).",
text: "Always pair a webfont with a real fallback stack (metric-similar system fonts plus a generic) so text stays readable before the font loads and wherever it never does: defineTheme({typography: {heading: {family: 'Fraunces', fallbacks: 'Georgia, serif'}}}).",
},
],
},
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/clients/cli/commands/theme-template.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export const doc = {
namespace: 'cli',
summary: 'Write the annotated theme template into your project',
description:
'Writes theme.template.ts: the annotated reference for the whole theme surface every ' +
'Writes theme.template.ts: the annotated reference for the whole theme surface, covering every ' +
'defineTheme field, the token families, the component override syntax, and how a theme is ' +
'consumed naming the CLI command that prints the authoritative reference for each. Read ' +
'consumed, naming the CLI command that prints the authoritative reference for each. Read ' +
'it, copy what you need into your own theme file, delete it. Use `theme add <slug>` instead ' +
'to start from a theme we ship. Leaves an existing file untouched unless --overwrite.',
fn: 'themeTemplate',
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/foundation/response/response-types.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export const doc = {
{
value: 'template.cdn',
description:
'A write receipt for the no-build-step CDN starter page: the path (relative to cwd), the Astryx version every CDN URL was pinned to, whether it was written, and the reason it was not `exists` when a file was already there, which is a success.',
'A write receipt for the no-build-step CDN starter page: the path (relative to cwd), the Astryx version every CDN URL was pinned to, whether it was written, and the reason it was not. `exists` when a file was already there, which is a success.',
},

// hook
Expand Down Expand Up @@ -197,7 +197,7 @@ export const doc = {
{
value: 'theme.template',
description:
'A write receipt for the annotated theme template: the path (relative to cwd), whether it was written, and the reason it was not `exists` when a file was already there, which is a success.',
'A write receipt for the annotated theme template: the path (relative to cwd), whether it was written, and the reason it was not. `exists` when a file was already there, which is a success.',
},
{
value: 'theme.targets',
Expand Down
1 change: 1 addition & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
**The exit ran on the entrance's curve.** `--ease-standard` is `cubic-bezier(0.24, 1, 0.4, 1)`, a decelerate curve: it spends its speed immediately and coasts. Right for an entrance, wrong for an exit. Measured on device (iPhone, real Safari), a scrim tap put the sheet half off-screen in 59ms of the 410ms transition and 90% off in 163ms, with the dim gone before it — so the close was over before the eye could follow it. The closing state now carries an accelerating curve of its own, `cubic-bezier(0.3, 0, 0.6, 0.6)`: away from rest, gathering speed, quickest as it leaves the screen, and moving within ~50ms so it reads as one departure rather than a hesitation and a snap. Only the curve changes — the exit keeps `--duration-medium`, the entrance's band, which is what keeps it legible under a theme that scales the motion scale down (neutral's medium is 300ms against the base 410ms).

The scrim leaves with the sheet: while closing, the dim runs `linear` rather than the decelerate token. A fade covers no distance, so front-loading its progress just ends it early — the reasoning the touch date picker's surface swap already carries. `BottomSheetSwitcher` gets the same treatment when its flow closes; a handoff between two sheets is not a close and is unchanged.

- `useListFocus` no longer swallows Escape when no `onEscape` was supplied. The hook called `preventDefault()` on every Escape — a habit inherited from the arrow keys, which share the handler and need it to suppress page scroll — so a list with nothing to dismiss still marked the key handled, and a surrounding layer that defers to `defaultPrevented` (a focus trap, a native popover) never got its turn. Escape is now consumed only when an `onEscape` is passed. Arrow, Home and End handling is unchanged (#5346).
Behaviour change: `AvatarGroup`, `ButtonGroup`, `Outline`, `Pagination`, `SegmentedControl`, `TabList` and `Toolbar` pass no `onEscape`, so an Escape pressed inside one of them now reaches the surrounding layer and can dismiss it — the point of the fix, but a host that counted on the key stopping there will notice. `NavHeadingMenu` does the same when it renders without a menu close handler. Menus and flyouts that do pass `onEscape` are unaffected. `patch`, not `[breaking]`: the swallowing was never a contract — the hook documented Escape only as "custom callback", and no component advertised consuming the key.
- TabList: the selected tab now carries `aria-current="true"` — ARIA's generic "current item within a set" — instead of `aria-current="page"`. The strip is a `<nav>` and stays one, but it is used to switch views in place at least as often as it is used to navigate, and on those uses `page` asserted a page change that never happened. Assistive tech announced the selected tab as the _current page_ even when nothing had navigated; it now announces it as the _current item_, which is true either way. A tab given an `href` still renders an anchor and still reads as a link — its current marker is just less specific than it was. No role changes and no new props. (#5347)
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/Field/Field.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export const docs = {
],
vars: [
{name: '--_field-radius', description: 'Border radius of input fields', default: 'var(--radius-element)', private: true},
{name: '--_input-clear-hit-inset', description: 'Outset of the clear (\u2715) button\u2019s invisible hit area, applied to a ::after overlay. 0 on a fine pointer; negative on a coarse one, which grows the 20px button to the 24px touch target without changing what is drawn.', default: '0px', private: true},
{name: '--_input-clear-hit-content', description: 'Whether the clear (\u2715) button\u2019s invisible hit overlay exists. `none` on a fine pointer, so no ::after is generated and hover still reaches the glyph; `""` on a coarse one, where the overlay provides the 24px touch target.', default: 'none', private: true},
{name: '--_input-clear-hit-inset', description: 'Outset of the clear (\u2715) button\'s invisible hit area, applied to a ::after overlay. 0 on a fine pointer; negative on a coarse one, which grows the 20px button to the 24px touch target without changing what is drawn.', default: '0px', private: true},
{name: '--_input-clear-hit-content', description: 'Whether the clear (\u2715) button\'s invisible hit overlay exists. `none` on a fine pointer, so no ::after is generated and hover still reaches the glyph; `""` on a coarse one, where the overlay provides the 24px touch target.', default: 'none', private: true},
],
derived: [
{property: 'borderRadius', vars: ['--_field-radius']},
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/Selector/Selector.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export const docs = {
name: 'renderValue',
type: '(option: SelectorOptionData) => ReactNode',
description:
'Custom render function for the selected option inside the closed trigger. The trigger is sized by padding, so it is the size token for a one-line value (28/32/36) and exactly one text line taller for a two-line one (48/52/56) always on the 4px rhythm, always aligned with the buttons and inputs beside it. Inside an InputGroup the group owns the row height: a SelectorOption folds onto one line and ellipsizes, and any taller node is cut off at the row.',
'Custom render function for the selected option inside the closed trigger. The trigger is sized by padding, so it is the size token for a one-line value (28/32/36) and exactly one text line taller for a two-line one (48/52/56), always on the 4px rhythm, always aligned with the buttons and inputs beside it. Inside an InputGroup the group owns the row height: a SelectorOption folds onto one line and ellipsizes, and any taller node is cut off at the row.',
},
{
name: 'indicatorPosition',
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/SideNav/SideNav.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ export const docs = {
bestPractices: [
{guidance: true, description: 'Use sections to group related navigation items and help users scan for their destination.'},
{guidance: true, description: 'Pair outline and filled icon variants so the selected state is visually distinct.'},
{guidance: true, description: 'Mark the current page with isSelected it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
{guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short they are the accessible name in both expanded and icon-only modes.'},
{guidance: true, description: 'Mark the current page with isSelected: it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
{guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short; they are the accessible name in both expanded and icon-only modes.'},
{guidance: true, description: 'While the nav is collapsed, an item with children shows them in a submenu flyout. On a device that can hover, pointing at the item opens it after a short delay and moving away closes it; a flyout opened by clicking stays open until it is dismissed. On touch, it opens on tap. Do not put an action in there that has no other route to it.'},
{guidance: false, description: 'Include a SideNavHeading when a TopNav is already providing app identity; this duplicates branding.'},
{guidance: false, description: 'Use for filtering content; use tabs or filter buttons instead.'},
Expand All @@ -153,8 +153,8 @@ export const docsZh = {
bestPractices: [
{guidance: true, description: 'Use sections to group related navigation items and help users scan for their destination.'},
{guidance: true, description: 'Pair outline and filled icon variants so the selected state is visually distinct.'},
{guidance: true, description: 'Mark the current page with isSelected it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
{guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short they are the accessible name in both expanded and icon-only modes.'},
{guidance: true, description: 'Mark the current page with isSelected: it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
{guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short; they are the accessible name in both expanded and icon-only modes.'},
{guidance: true, description: 'While the nav is collapsed, an item with children shows them in a submenu flyout. On a device that can hover, pointing at the item opens it after a short delay and moving away closes it; a flyout opened by clicking stays open until it is dismissed. On touch, it opens on tap. Do not put an action in there that has no other route to it.'},
{guidance: false, description: 'Include a SideNavHeading when a TopNav is already providing app identity; this duplicates branding.'},
{guidance: false, description: 'Use for filtering content; use tabs or filter buttons instead.'},
Expand All @@ -175,8 +175,8 @@ export const docsDense = {
bestPractices: [
{guidance: true, description: 'Use sections to group related navigation items and help users scan for their destination.'},
{guidance: true, description: 'Pair outline and filled icon variants so the selected state is visually distinct.'},
{guidance: true, description: 'Mark the current page with isSelected it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
{guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short they are the accessible name in both expanded and icon-only modes.'},
{guidance: true, description: 'Mark the current page with isSelected: it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
{guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short; they are the accessible name in both expanded and icon-only modes.'},
{guidance: true, description: 'While the nav is collapsed, an item with children shows them in a submenu flyout. On a device that can hover, pointing at the item opens it after a short delay and moving away closes it; a flyout opened by clicking stays open until it is dismissed. On touch, it opens on tap. Do not put an action in there that has no other route to it.'},
{guidance: false, description: 'Include a SideNavHeading when a TopNav is already providing app identity; this duplicates branding.'},
{guidance: false, description: 'Use for filtering content; use tabs or filter buttons instead.'},
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/Thumbnail/Thumbnail.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const docs = {
{className: 'astryx-thumbnail'},
],
vars: [
{name: '--_thumbnail-hit-inset', description: 'Outset of the remove button\u2019s invisible hit area, applied to a ::after overlay. 0 on a fine pointer; negative on a coarse one, which grows the 20px button to the 24px touch target without changing what is drawn.', default: '0px', private: true},
{name: '--_thumbnail-hit-inset', description: 'Outset of the remove button\'s invisible hit area, applied to a ::after overlay. 0 on a fine pointer; negative on a coarse one, which grows the 20px button to the 24px touch target without changing what is drawn.', default: '0px', private: true},
],
},
usage: {
Expand Down
Loading
Loading