@tailor-platform/app-shell 1.19.0 → 1.20.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/dist/app-shell-core.css +2 -2
- package/dist/app-shell.d.ts +807 -130
- package/dist/app-shell.js +12419 -10930
- package/dist/{appshell-DQTz-QwK.js → appshell-B4QkQvXF.js} +377 -360
- package/dist/fonts/inter.css +7 -7
- package/dist/fonts/noto-sans-jp.css +116 -116
- package/dist/testing.d.ts +119 -89
- package/dist/testing.js +1 -1
- package/dist/vite-plugin.d.ts +119 -89
- package/package.json +10 -8
- package/skills/app-shell-patterns/SKILL.md +4 -3
- package/skills/app-shell-patterns/references/api/create-ai-gateway-client.md +32 -2
- package/skills/app-shell-patterns/references/api/define-module.md +5 -5
- package/skills/app-shell-patterns/references/api/router/use-params.md +2 -2
- package/skills/app-shell-patterns/references/api/use-ai-chat.md +46 -8
- package/skills/app-shell-patterns/references/api/use-app-shell-config.md +4 -4
- package/skills/app-shell-patterns/references/api/use-app-shell-data.md +5 -5
- package/skills/app-shell-patterns/references/api/use-app-shell.md +2 -2
- package/skills/app-shell-patterns/references/api/use-auth.md +3 -3
- package/skills/app-shell-patterns/references/api/use-route-error.md +12 -12
- package/skills/app-shell-patterns/references/components/action-panel.md +4 -2
- package/skills/app-shell-patterns/references/components/activity-card.md +3 -3
- package/skills/app-shell-patterns/references/components/ai-chat.md +37 -3
- package/skills/app-shell-patterns/references/components/app-shell.md +6 -5
- package/skills/app-shell-patterns/references/components/card.md +2 -2
- package/skills/app-shell-patterns/references/components/data-table.md +87 -31
- package/skills/app-shell-patterns/references/components/date-picker.md +2 -2
- package/skills/app-shell-patterns/references/components/default-sidebar.md +2 -2
- package/skills/app-shell-patterns/references/components/dialog.md +8 -0
- package/skills/app-shell-patterns/references/components/filter-rail.md +10 -3
- package/skills/app-shell-patterns/references/components/form.md +5 -5
- package/skills/app-shell-patterns/references/components/global-header-layout.md +31 -8
- package/skills/app-shell-patterns/references/components/layout.md +24 -17
- package/skills/app-shell-patterns/references/components/select.md +8 -0
- package/skills/app-shell-patterns/references/components/sidebar-group.md +9 -7
- package/skills/app-shell-patterns/references/components/sidebar-layout.md +74 -11
- package/skills/app-shell-patterns/references/components/sidebar-section.md +8 -8
- package/skills/app-shell-patterns/references/components/tabs.md +32 -2
- package/skills/app-shell-patterns/references/components/tree.md +342 -0
- package/skills/app-shell-patterns/references/components/with-guard.md +5 -5
- package/skills/app-shell-patterns/references/concepts/authentication.md +1 -1
- package/skills/app-shell-patterns/references/concepts/routing-navigation.md +3 -3
- package/skills/app-shell-patterns/references/concepts/styling-theming.md +13 -13
- package/skills/app-shell-patterns/references/migrations.md +20 -0
- package/skills/app-shell-patterns/references/pages/document-detail.md +8 -12
- package/skills/app-shell-patterns/references/patterns/interaction-multi-select.md +1 -1
|
@@ -219,12 +219,11 @@ Each intent has eight roles. The intents are `info`, `success`, `warning`, `dang
|
|
|
219
219
|
|
|
220
220
|
The hue roles have the same values in every shipped palette. `cream` and `bloom` change brand and surface colors, not status colors. The `neutral` roles follow the palette, because they read the system tokens.
|
|
221
221
|
|
|
222
|
-
**Contrast.** AppShell's thresholds are 4.5:1 for text (WCAG 1.4.3) and 3:1 for non-text (WCAG 1.4.11). In every shipped palette (`default`, `cream`, `bloom`), in light and dark mode, on `--card` and `--background`, `text` on `surface` and `contrast` on `solid` and `solid-hover` are at least 4.5:1 for
|
|
222
|
+
**Contrast.** AppShell's thresholds are 4.5:1 for text (WCAG 1.4.3) and 3:1 for non-text (WCAG 1.4.11). In every shipped palette (`default`, `cream`, `bloom`), in light and dark mode, on `--card` and `--background`, `text` on `surface` and `contrast` on `solid` and `solid-hover` are at least 4.5:1 for all five intents, `text` on `surface-hover` is at least 4.5:1 for `neutral`, and `danger` `solid` (the invalid-input border) is at least 3:1. A browser test checks this in Chromium against the built stylesheet. Known exceptions:
|
|
223
223
|
|
|
224
|
-
- `text` on `surface-hover` is below 4.5:1 for `danger` and `success` in light mode. The test holds it at 4.2:1 or more.
|
|
224
|
+
- `text` on `surface-hover` is below 4.5:1 for `danger` and `success` in light mode. This is on purpose: a lighter step would make the tinted background hard to tell apart from the page, and the hover harder to see. The test holds it at 4.2:1 or more.
|
|
225
225
|
- In `cream` and `bloom`, the main content area is transparent over the shell gradient. At the top of the `bloom` light gradient, `text` on `surface` is 4.49:1 for `success` and 4.48:1 for `danger`. Put status content on a card when it needs to pass.
|
|
226
226
|
- `warning` `solid` and `indicator` are 2.15:1 against a light card. Use them with a label, not as the only sign of a state.
|
|
227
|
-
- The `neutral` intent reads the system tokens and is not checked.
|
|
228
227
|
|
|
229
228
|
Most `surface` and `border` values are translucent tints, so an opacity modifier compounds rather than replaces — `bg-info-surface/50` halves the tint's alpha instead of setting it to 50%. Some light-mode values are opaque instead of translucent: the `warning` surface, surface-hover and border, the `info` border and the `danger` surface-hover. They do not blend with a tinted parent. All dark-mode values are translucent.
|
|
230
229
|
|
|
@@ -411,7 +410,7 @@ function TypographyRoles() {
|
|
|
411
410
|
}
|
|
412
411
|
```
|
|
413
412
|
|
|
414
|
-
For headings, body copy, labels, and captions, use the [`Text`](../components/text.md) component. Do not style a bare `p`, `h1` to `h6`, or `span` with `text-sm`, `text-xs`, or `font-*`. A form field label is [`Field.Label`](../components/form.md), which already has the `label-md` role. `Text` applies the same roles with a `variant` prop. It renders a default element for each role (`h2` for headings, `p` for body text, `span` for the others). To set the element, such as the heading level, use an element component (`Text.h1` to `Text.h6`, `Text.p`, `Text.span`, `Text.div`):
|
|
413
|
+
For headings, body copy, labels, and captions, use the [`Text`](../components/text.md) component. Do not style a bare `p`, `h1` to `h6`, or `span` with `text-sm`, `text-xs`, or `font-*`. The `prefer-text-components` rule in `@tailor-platform/eslint-plugin-app-shell` reports a size on these elements, and a weight, line height, or letter spacing that is set without a role. It is not in `recommended`, so enable it in your `oxlint.config.ts`. A form field label is [`Field.Label`](../components/form.md), which already has the `label-md` role. `Text` applies the same roles with a `variant` prop. It renders a default element for each role (`h2` for headings, `p` for body text, `span` for the others). To set the element, such as the heading level, use an element component (`Text.h1` to `Text.h6`, `Text.p`, `Text.span`, `Text.div`):
|
|
415
414
|
|
|
416
415
|
```tsx
|
|
417
416
|
<Text.h3 variant="heading-md">Line items</Text.h3>
|
|
@@ -530,21 +529,22 @@ Always give motion a reduced-motion escape (`motion-reduce:transition-none`, or
|
|
|
530
529
|
|
|
531
530
|
### Z-index
|
|
532
531
|
|
|
533
|
-
These exist as raw `:root` variables in the shipped base layer, but are **not** bridged into Tailwind — `z-
|
|
532
|
+
These exist as raw `:root` variables in the shipped base layer, but are **not** bridged into Tailwind — `z-nav` is not a class. Use the stock numeric utility, or reference the variable when you need it to track AppShell's layering:
|
|
534
533
|
|
|
535
|
-
| Token
|
|
536
|
-
|
|
|
537
|
-
| `--z-
|
|
538
|
-
| `--z-
|
|
539
|
-
| `--z-
|
|
540
|
-
|
|
534
|
+
| Token | Value | Use |
|
|
535
|
+
| ------------ | ----- | ----------------------------------------------------- |
|
|
536
|
+
| `--z-nav` | 10 | persistent sidebar |
|
|
537
|
+
| `--z-portal` | 50 | menu, tooltip, popover, modal, sheet, dialog backdrop |
|
|
538
|
+
| `--z-toast` | 100 | toast, always above overlays |
|
|
539
|
+
|
|
540
|
+
The old names still resolve: `--z-sidebar` is an alias of `--z-nav`, and `--z-popup` and `--z-overlay` are aliases of `--z-portal`. They are deprecated and will be removed in the next major. `--z-sidebar-rail` (20) is a value inside the sidebar, not a layer.
|
|
541
541
|
|
|
542
542
|
```tsx
|
|
543
543
|
<div className="z-50" />
|
|
544
|
-
<div className="z-[var(--z-
|
|
544
|
+
<div className="z-[var(--z-portal)]" />
|
|
545
545
|
```
|
|
546
546
|
|
|
547
|
-
Never invent a z value — `z-index: 9999` is always wrong. Popups and overlays share `50` intentionally: sequencing comes from DOM order, not z escalation.
|
|
547
|
+
Never invent a z value — `z-index: 9999` is always wrong. Popups and overlays share `50` intentionally: sequencing comes from DOM order, not z escalation. Every floating AppShell component (dialog, sheet, menu, select, combobox, tooltip, toast) renders through a portal to the end of `body`, and the layout root is `isolation: isolate`, so a z-index inside the page never reaches them. The toast is the one layer above the band: it is always visible over an open dialog or sheet.
|
|
548
548
|
|
|
549
549
|
### Icons
|
|
550
550
|
|
|
@@ -10,6 +10,7 @@ Each entry states which versions are affected, what breaks, how to detect it, an
|
|
|
10
10
|
|
|
11
11
|
| Version | Change |
|
|
12
12
|
| ------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| 1.20.0 | [z-index tokens renamed; old names are aliases](#1200-z-index-tokens-renamed-old-names-are-aliases) |
|
|
13
14
|
| 1.18.0 | [Destructive colours now resolve to the danger roles](#1180-destructive-colours-now-resolve-to-the-danger-roles) |
|
|
14
15
|
| 1.17.0 | [Status and alert tokens now resolve to the colour roles](#1170-status-and-alert-tokens-now-resolve-to-the-colour-roles) |
|
|
15
16
|
| 1.15.0 | [Base UI 1.8.0 breaks closed-`Select` and dialog-click tests](#1150-base-ui-180-breaks-closed-select-and-dialog-click-tests) |
|
|
@@ -23,6 +24,25 @@ Each entry states which versions are affected, what breaks, how to detect it, an
|
|
|
23
24
|
| 1.0.2 | [`Toaster` no longer accepts `richColors`](#102-toaster-no-longer-accepts-richcolors) |
|
|
24
25
|
| before 1.0 | [Pre-1.0 breaking changes](#before-10) |
|
|
25
26
|
|
|
27
|
+
## 1.20.0: z-index tokens renamed; old names are aliases
|
|
28
|
+
|
|
29
|
+
**Applies to:** apps whose theme overrides `--z-sidebar`, `--z-sidebar-rail`, `--z-popup` or `--z-overlay`, and apps that reference those names on their own elements.
|
|
30
|
+
|
|
31
|
+
1.20.0 names the z-index tokens by layer: `--z-nav` (10), `--z-portal` (50) and `--z-toast` (100). The old names keep working: `--z-sidebar` is now `var(--z-nav)`, and `--z-popup` and `--z-overlay` are both `var(--z-portal)`. They are deprecated and will be removed in the next major. Nothing errors, and nothing moves. Two things change silently:
|
|
32
|
+
|
|
33
|
+
- **Themes that override an old name no longer reach the components.** The sidebar reads `--z-nav`; dialogs, sheets, menus, selects, comboboxes and tooltips read `--z-portal`. An override of `--z-popup` or `--z-overlay` still changes `z-[var(--z-popup)]` on your own elements, but not AppShell's layers. There is one token for the whole portal band because popups and overlays share the value on purpose: the order inside the band is the order of opening, so a `Select` inside a `Dialog` is above it. Raising one above the other puts a `Select` or `Menu` opened inside a `Dialog` behind the dialog.
|
|
34
|
+
- **`--z-sidebar-rail` is no longer read by AppShell.** The sidebar rail orders itself inside the sidebar. The variable is still declared (20) for elements of your own that reference it, and it leaves the documented table.
|
|
35
|
+
|
|
36
|
+
How to detect it: search the app for `--z-sidebar`, `--z-popup` and `--z-overlay` in class names and in theme CSS. Open a `Dialog` with a `Select` inside it, a `Dialog` over a `Sheet`, and fire a toast over each after upgrading; the order should not change.
|
|
37
|
+
|
|
38
|
+
What to change:
|
|
39
|
+
|
|
40
|
+
- Replace `--z-sidebar` with `--z-nav`, and `--z-popup` and `--z-overlay` with `--z-portal`, in class names such as `z-[var(--z-portal)]` and in theme CSS.
|
|
41
|
+
- In a theme that moves AppShell's layers, set `--z-nav`, `--z-portal` or `--z-toast` instead of the old names. Remove the old names from the theme.
|
|
42
|
+
- Do not set `--z-sidebar-rail`; it no longer affects the rail.
|
|
43
|
+
|
|
44
|
+
The tokens are documented in [Styling & theming](https://github.com/tailor-platform/app-shell/blob/main/docs/concepts/styling-theming.md#z-index). The decision record is `decisions/floating-ui-stacking.md`.
|
|
45
|
+
|
|
26
46
|
## 1.18.0: destructive colours now resolve to the danger roles
|
|
27
47
|
|
|
28
48
|
**Applies to:** apps that show `Button variant="destructive"` in dark mode, apps that use `text-destructive`, `border-destructive` or `bg-destructive` on their own elements, and apps whose theme overrides `--destructive` or `--destructive-foreground`.
|
|
@@ -619,9 +619,9 @@ const formatDay = (value: string) =>
|
|
|
619
619
|
* or the two dates do not match every other value on the card.
|
|
620
620
|
*/
|
|
621
621
|
const Value = ({ children }: { children: React.ReactNode }) => (
|
|
622
|
-
<Text variant="body-md" className="text-foreground"
|
|
622
|
+
<Text.span variant="body-md" className="text-foreground">
|
|
623
623
|
{children}
|
|
624
|
-
</Text>
|
|
624
|
+
</Text.span>
|
|
625
625
|
);
|
|
626
626
|
|
|
627
627
|
/** House link: primary colour at rest, underline only on hover. */
|
|
@@ -685,9 +685,9 @@ export default function PurchaseOrderDetailPage({
|
|
|
685
685
|
{order.holds.map((hold) => (
|
|
686
686
|
<div key={hold.id} className="flex items-start justify-between gap-4">
|
|
687
687
|
<div>
|
|
688
|
-
<Text variant="label-md" className="text-foreground"
|
|
688
|
+
<Text.p variant="label-md" className="text-foreground">
|
|
689
689
|
{hold.reason}
|
|
690
|
-
</Text>
|
|
690
|
+
</Text.p>
|
|
691
691
|
<Text variant="body-sm" className="text-muted-foreground">
|
|
692
692
|
Placed by {hold.placedBy} on {formatDay(hold.placedAt)}
|
|
693
693
|
</Text>
|
|
@@ -851,13 +851,9 @@ export default function PurchaseOrderDetailPage({
|
|
|
851
851
|
<Table.Cell align="right" className="tabular-nums">
|
|
852
852
|
{line.received}
|
|
853
853
|
{line.received !== line.qty && (
|
|
854
|
-
<Text
|
|
855
|
-
variant="body-sm"
|
|
856
|
-
className="ml-1 text-muted-foreground"
|
|
857
|
-
render={<span />}
|
|
858
|
-
>
|
|
854
|
+
<Text.span variant="body-sm" className="ml-1 text-muted-foreground">
|
|
859
855
|
({line.qty - line.received})
|
|
860
|
-
</Text>
|
|
856
|
+
</Text.span>
|
|
861
857
|
)}
|
|
862
858
|
</Table.Cell>
|
|
863
859
|
<Table.Cell align="right" className="tabular-nums">
|
|
@@ -939,9 +935,9 @@ export default function PurchaseOrderDetailPage({
|
|
|
939
935
|
{file.name}
|
|
940
936
|
<ExternalLink className="size-3 shrink-0" />
|
|
941
937
|
</a>
|
|
942
|
-
<Text variant="body-sm" className="shrink-0 text-muted-foreground"
|
|
938
|
+
<Text.span variant="body-sm" className="shrink-0 text-muted-foreground">
|
|
943
939
|
{file.sizeLabel} · {formatDay(file.uploadedAt)}
|
|
944
|
-
</Text>
|
|
940
|
+
</Text.span>
|
|
945
941
|
</div>
|
|
946
942
|
))}
|
|
947
943
|
</Card.Content>
|
|
@@ -112,7 +112,7 @@ function InteractionMultiSelect() {
|
|
|
112
112
|
cancelled; shipped orders are excluded. Cancelled orders can't be reopened.
|
|
113
113
|
</Dialog.Description>
|
|
114
114
|
</Dialog.Header>
|
|
115
|
-
{cancelError && <p role="alert">{cancelError}</p>}
|
|
115
|
+
{cancelError && <Text.p role="alert">{cancelError}</Text.p>}
|
|
116
116
|
<Dialog.Footer>
|
|
117
117
|
<Dialog.Close render={<Button variant="outline" disabled={cancelling} />}>
|
|
118
118
|
Keep orders
|