@jirawatpyk/aura-react 5.46.0 → 5.48.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/README.md +14 -1
- package/dist/aura.bundle.js +12 -3
- package/dist/cjs/index.cjs +12 -3
- package/dist/esm/AppShell.js +10 -2
- package/dist/esm/PageHeader.js +2 -1
- package/dist/index.d.cts +12 -9
- package/dist/index.d.ts +12 -9
- package/dist/server/index.cjs +2 -1
- package/dist/server/index.d.cts +12 -6
- package/dist/server/index.d.ts +12 -6
- package/dist/server/index.js +2 -1
- package/dist/styles.css +27 -8
- package/dist/styles.layer.css +27 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -186,6 +186,19 @@ DataTable with sort and page in the URL (4.17): `onStateChange={({ sort, page })
|
|
|
186
186
|
- **Time zone**: `timeZone` on AuraProvider, DatePicker, DateRangePicker and Calendar decides "today" (the marker, `min`/`max="today"`, the first month shown); or pass `today` as an ISO date. `todayIn('Asia/Bangkok')` is exported from the root and `/server`.
|
|
187
187
|
- **Toasts** queue past three instead of dropping: six in a row all show, in order, three at a time.
|
|
188
188
|
|
|
189
|
+
## 5.48 — Chamber-OS addendum 55 (#153–154)
|
|
190
|
+
|
|
191
|
+
- **The `actionsBarBelow` bar is now ActionBar's edge strip** (#153): the full width of the screen, on its bottom edge (or on a BottomNav's top edge), a top border only — no radius, no shadow — with ActionBar's inner padding (8px block, 16px start, 12px end) and the home-indicator inset inside it, as the save and bulk bars of an app built on `ActionBar position="container"` look. The page's end padding and `scroll-padding-bottom` follow the new height. The layout inside is unchanged.
|
|
192
|
+
- **Bottom bars on a short screen** (#154): on a screen 480px tall or less — 400% zoom on a desktop (320×256 CSS px), a phone held sideways — `actionsBarBelow` no longer fixes the actions to the bottom: they stay in the header's own row (laid out by `actionsFullWidthBelow` if set), with no status line, page-end space or scroll padding; and an `ActionBar` (either `position`) stops sticking and sits at the end of its container, in the flow. AppShell's top bar scrolls away with the page there too, so a field reached backwards (Shift+Tab) isn't left under it, and `--aura-shell-bar-height` is 0 meanwhile, so nothing sticky (a DataTable `stickyHeader`) leaves a gap for it. A focused control is never under a bar there (WCAG 2.4.11, 1.4.10); from 481px tall everything is as before. An ActionBar with `hidesBottomNav` still hides the BottomNav on a short screen while it sits at the end of its container. Wherever a BottomNav shows (any height), the page's `scroll-padding-bottom` now reserves its height, so a field tabbed into view stops above it.
|
|
193
|
+
- **`actionsBarLook="floating"`** keeps 5.45's card (inset 16px, lifted 12px, bordered all round, rounded, with the overlay shadow) — the look of `ActionBar position="viewport"`. Only the bar's look changed; nothing else about `actionsBarBelow`.
|
|
194
|
+
|
|
195
|
+
## 5.47 — Chamber-OS addendum 54 (#152)
|
|
196
|
+
|
|
197
|
+
- **PageHeader `size="compact"`**: 26px below 640px and 32px from 640px, on a 1.2 line — the staff and list boards' title, so a company name such as "Siam Nordic Trading Co., Ltd." takes two lines on a 390px phone instead of three. The **default stays 28px / 36px** (1.15), so DxT Monitor and other apps don't change; pass `size="compact"` (Chamber-OS: in its header wrapper) where the boards draw 26 / 32.
|
|
198
|
+
- **`hero` steps to 36px from 1024px** (30px below), on a 1.2 line, as `hero-lg` does — the portal Main and Edit boards. `hero-lg` is unchanged (26px, then 36px).
|
|
199
|
+
- **`--aura-page-header-hero-space`**: the room above a `hero` or `hero-lg` title, default 16px, on top of the page's own padding (which belongs to the app). For the boards' 24px on a phone and 40px from 1024px inside AppShell's 24px / 32px content padding, set it to `0` below 1024px and `8px` from 1024px — or whatever your page padding needs.
|
|
200
|
+
- Under `lang="th"` titles keep their 1.4 line at every size. Checked at 390 and 1280px in English, Thai and Swedish and at a 32px default font size: nothing scrolls sideways.
|
|
201
|
+
|
|
189
202
|
## 5.46 — Chamber-OS addendum 53 (#151)
|
|
190
203
|
|
|
191
204
|
What Chamber-OS's own page header did that PageHeader didn't, so it can be rebuilt on PageHeader with its props kept:
|
|
@@ -201,7 +214,7 @@ What Chamber-OS's own page header did that PageHeader didn't, so it can be rebui
|
|
|
201
214
|
|
|
202
215
|
## 5.45 — Chamber-OS addendum 52 (#150)
|
|
203
216
|
|
|
204
|
-
- **PageHeader `actionsBarBelow`** (#150): `'sm' | 'md'` — below 640px or 768px the header's `actions` become a bar fixed to the bottom of the screen
|
|
217
|
+
- **PageHeader `actionsBarBelow`** (#150): `'sm' | 'md'` — below 640px or 768px the header's `actions` become a bar fixed to the bottom of the screen (from 5.48 ActionBar's edge strip, `actionsBarLook="floating"` for this card; above a BottomNav, clear of the home indicator), and `actionsStatus` is its status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026", a polite live region shown only in the bar).
|
|
205
218
|
```tsx
|
|
206
219
|
<PageHeader title="Invoice SC-2026-900001" actionsFullWidthBelow="sm" actionsBarBelow="sm"
|
|
207
220
|
actionsStatus="Total 10,700.00 THB incl. VAT · due 22 Oct 2026"
|
package/dist/aura.bundle.js
CHANGED
|
@@ -7839,7 +7839,7 @@ window.Aura = (() => {
|
|
|
7839
7839
|
return n3 != null && n3 !== false && n3 !== "";
|
|
7840
7840
|
};
|
|
7841
7841
|
const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
|
|
7842
|
-
const size = props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
7842
|
+
const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
7843
7843
|
const eyebrow = props.eyebrow;
|
|
7844
7844
|
const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
|
|
7845
7845
|
const heading = h8(
|
|
@@ -7864,6 +7864,7 @@ window.Aura = (() => {
|
|
|
7864
7864
|
(hide2 === "sm" || hide2 === "md" || hide2 === "lg") && "aura-page-header--title-hide-below-" + hide2,
|
|
7865
7865
|
(hide2 === "sm" || hide2 === "md" || hide2 === "lg") && !hasMeta && "has-no-meta",
|
|
7866
7866
|
bar && "aura-page-header--actions-bar-below-" + bar,
|
|
7867
|
+
bar && props.actionsBarLook === "floating" && "aura-page-header--actions-bar-floating",
|
|
7867
7868
|
size && "aura-page-header--" + size,
|
|
7868
7869
|
props.actionsAlign === "start" && "aura-page-header--actions-start",
|
|
7869
7870
|
props.className
|
|
@@ -8309,6 +8310,9 @@ window.Aura = (() => {
|
|
|
8309
8310
|
}
|
|
8310
8311
|
|
|
8311
8312
|
// src/AppShell.tsx
|
|
8313
|
+
function pinned(bar) {
|
|
8314
|
+
return getComputedStyle(bar).position !== "static";
|
|
8315
|
+
}
|
|
8312
8316
|
var AppShell = React48.forwardRef(function AppShell2(props, ref) {
|
|
8313
8317
|
const t = useStrings();
|
|
8314
8318
|
const bp = useBreakpoint();
|
|
@@ -8339,7 +8343,10 @@ window.Aura = (() => {
|
|
|
8339
8343
|
function() {
|
|
8340
8344
|
const root = rootRef.current, bar = barRef.current;
|
|
8341
8345
|
if (!root || !bar) return;
|
|
8342
|
-
root.style.setProperty(
|
|
8346
|
+
root.style.setProperty(
|
|
8347
|
+
"--aura-shell-bar-height",
|
|
8348
|
+
away || !pinned(bar) ? "0px" : bar.getBoundingClientRect().height + "px"
|
|
8349
|
+
);
|
|
8343
8350
|
},
|
|
8344
8351
|
[away]
|
|
8345
8352
|
);
|
|
@@ -8349,14 +8356,16 @@ window.Aura = (() => {
|
|
|
8349
8356
|
if (!root || !bar) return;
|
|
8350
8357
|
function sync() {
|
|
8351
8358
|
const h11 = bar.getBoundingClientRect().height;
|
|
8352
|
-
root.style.setProperty("--aura-shell-bar-height", awayRef.current ? "0px" : h11 + "px");
|
|
8359
|
+
root.style.setProperty("--aura-shell-bar-height", awayRef.current || !pinned(bar) ? "0px" : h11 + "px");
|
|
8353
8360
|
if (h11 > 0) barH[1](Math.round(h11));
|
|
8354
8361
|
}
|
|
8355
8362
|
sync();
|
|
8356
8363
|
const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
8357
8364
|
if (ro) ro.observe(bar);
|
|
8365
|
+
window.addEventListener("resize", sync);
|
|
8358
8366
|
return function() {
|
|
8359
8367
|
if (ro) ro.disconnect();
|
|
8368
|
+
window.removeEventListener("resize", sync);
|
|
8360
8369
|
root.style.removeProperty("--aura-shell-bar-height");
|
|
8361
8370
|
};
|
|
8362
8371
|
},
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -7821,7 +7821,7 @@ var PageHeader = React43.forwardRef(function PageHeader2(props, ref) {
|
|
|
7821
7821
|
return n3 != null && n3 !== false && n3 !== "";
|
|
7822
7822
|
};
|
|
7823
7823
|
const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
|
|
7824
|
-
const size = props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
7824
|
+
const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
7825
7825
|
const eyebrow = props.eyebrow;
|
|
7826
7826
|
const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
|
|
7827
7827
|
const heading = h8(
|
|
@@ -7846,6 +7846,7 @@ var PageHeader = React43.forwardRef(function PageHeader2(props, ref) {
|
|
|
7846
7846
|
(hide2 === "sm" || hide2 === "md" || hide2 === "lg") && "aura-page-header--title-hide-below-" + hide2,
|
|
7847
7847
|
(hide2 === "sm" || hide2 === "md" || hide2 === "lg") && !hasMeta && "has-no-meta",
|
|
7848
7848
|
bar && "aura-page-header--actions-bar-below-" + bar,
|
|
7849
|
+
bar && props.actionsBarLook === "floating" && "aura-page-header--actions-bar-floating",
|
|
7849
7850
|
size && "aura-page-header--" + size,
|
|
7850
7851
|
props.actionsAlign === "start" && "aura-page-header--actions-start",
|
|
7851
7852
|
props.className
|
|
@@ -8291,6 +8292,9 @@ function useHideOnScroll(enabled, el, media, from) {
|
|
|
8291
8292
|
}
|
|
8292
8293
|
|
|
8293
8294
|
// src/AppShell.tsx
|
|
8295
|
+
function pinned(bar) {
|
|
8296
|
+
return getComputedStyle(bar).position !== "static";
|
|
8297
|
+
}
|
|
8294
8298
|
var AppShell = React48.forwardRef(function AppShell2(props, ref) {
|
|
8295
8299
|
const t = useStrings();
|
|
8296
8300
|
const bp = useBreakpoint();
|
|
@@ -8321,7 +8325,10 @@ var AppShell = React48.forwardRef(function AppShell2(props, ref) {
|
|
|
8321
8325
|
function() {
|
|
8322
8326
|
const root = rootRef.current, bar = barRef.current;
|
|
8323
8327
|
if (!root || !bar) return;
|
|
8324
|
-
root.style.setProperty(
|
|
8328
|
+
root.style.setProperty(
|
|
8329
|
+
"--aura-shell-bar-height",
|
|
8330
|
+
away || !pinned(bar) ? "0px" : bar.getBoundingClientRect().height + "px"
|
|
8331
|
+
);
|
|
8325
8332
|
},
|
|
8326
8333
|
[away]
|
|
8327
8334
|
);
|
|
@@ -8331,14 +8338,16 @@ var AppShell = React48.forwardRef(function AppShell2(props, ref) {
|
|
|
8331
8338
|
if (!root || !bar) return;
|
|
8332
8339
|
function sync() {
|
|
8333
8340
|
const h11 = bar.getBoundingClientRect().height;
|
|
8334
|
-
root.style.setProperty("--aura-shell-bar-height", awayRef.current ? "0px" : h11 + "px");
|
|
8341
|
+
root.style.setProperty("--aura-shell-bar-height", awayRef.current || !pinned(bar) ? "0px" : h11 + "px");
|
|
8335
8342
|
if (h11 > 0) barH[1](Math.round(h11));
|
|
8336
8343
|
}
|
|
8337
8344
|
sync();
|
|
8338
8345
|
const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
8339
8346
|
if (ro) ro.observe(bar);
|
|
8347
|
+
window.addEventListener("resize", sync);
|
|
8340
8348
|
return function() {
|
|
8341
8349
|
if (ro) ro.disconnect();
|
|
8350
|
+
window.removeEventListener("resize", sync);
|
|
8342
8351
|
root.style.removeProperty("--aura-shell-bar-height");
|
|
8343
8352
|
};
|
|
8344
8353
|
},
|
package/dist/esm/AppShell.js
CHANGED
|
@@ -7,6 +7,9 @@ import { useStrings } from "./locale.js";
|
|
|
7
7
|
import { useBreakpoint } from "./responsive.js";
|
|
8
8
|
import { useHideOnScroll } from "./scrollHide.js";
|
|
9
9
|
import { IconMenu } from "./icons.js";
|
|
10
|
+
function pinned(bar) {
|
|
11
|
+
return getComputedStyle(bar).position !== "static";
|
|
12
|
+
}
|
|
10
13
|
const AppShell = React.forwardRef(function AppShell2(props, ref) {
|
|
11
14
|
const t = useStrings();
|
|
12
15
|
const bp = useBreakpoint();
|
|
@@ -37,7 +40,10 @@ const AppShell = React.forwardRef(function AppShell2(props, ref) {
|
|
|
37
40
|
function() {
|
|
38
41
|
const root = rootRef.current, bar = barRef.current;
|
|
39
42
|
if (!root || !bar) return;
|
|
40
|
-
root.style.setProperty(
|
|
43
|
+
root.style.setProperty(
|
|
44
|
+
"--aura-shell-bar-height",
|
|
45
|
+
away || !pinned(bar) ? "0px" : bar.getBoundingClientRect().height + "px"
|
|
46
|
+
);
|
|
41
47
|
},
|
|
42
48
|
[away]
|
|
43
49
|
);
|
|
@@ -47,14 +53,16 @@ const AppShell = React.forwardRef(function AppShell2(props, ref) {
|
|
|
47
53
|
if (!root || !bar) return;
|
|
48
54
|
function sync() {
|
|
49
55
|
const h = bar.getBoundingClientRect().height;
|
|
50
|
-
root.style.setProperty("--aura-shell-bar-height", awayRef.current ? "0px" : h + "px");
|
|
56
|
+
root.style.setProperty("--aura-shell-bar-height", awayRef.current || !pinned(bar) ? "0px" : h + "px");
|
|
51
57
|
if (h > 0) barH[1](Math.round(h));
|
|
52
58
|
}
|
|
53
59
|
sync();
|
|
54
60
|
const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
55
61
|
if (ro) ro.observe(bar);
|
|
62
|
+
window.addEventListener("resize", sync);
|
|
56
63
|
return function() {
|
|
57
64
|
if (ro) ro.disconnect();
|
|
65
|
+
window.removeEventListener("resize", sync);
|
|
58
66
|
root.style.removeProperty("--aura-shell-bar-height");
|
|
59
67
|
};
|
|
60
68
|
},
|
package/dist/esm/PageHeader.js
CHANGED
|
@@ -15,7 +15,7 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
|
|
|
15
15
|
return n != null && n !== false && n !== "";
|
|
16
16
|
};
|
|
17
17
|
const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
|
|
18
|
-
const size = props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
18
|
+
const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
19
19
|
const eyebrow = props.eyebrow;
|
|
20
20
|
const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
|
|
21
21
|
const heading = h(
|
|
@@ -40,6 +40,7 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
|
|
|
40
40
|
(hide === "sm" || hide === "md" || hide === "lg") && "aura-page-header--title-hide-below-" + hide,
|
|
41
41
|
(hide === "sm" || hide === "md" || hide === "lg") && !hasMeta && "has-no-meta",
|
|
42
42
|
bar && "aura-page-header--actions-bar-below-" + bar,
|
|
43
|
+
bar && props.actionsBarLook === "floating" && "aura-page-header--actions-bar-floating",
|
|
43
44
|
size && "aura-page-header--" + size,
|
|
44
45
|
props.actionsAlign === "start" && "aura-page-header--actions-start",
|
|
45
46
|
props.className
|
package/dist/index.d.cts
CHANGED
|
@@ -1947,10 +1947,12 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
1947
1947
|
/** 5.46: a chip or badge on the title's line (a role, an invoice's status, "Archived"). Title and addon share a
|
|
1948
1948
|
* wrapping row, 8px apart vertically and 12px across; on a narrow screen the addon wraps under the title. */
|
|
1949
1949
|
titleAddon?: React$1.ReactNode | undefined;
|
|
1950
|
-
/** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `
|
|
1951
|
-
*
|
|
1952
|
-
*
|
|
1953
|
-
|
|
1950
|
+
/** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `compact` (5.47, Chamber-OS 152) 26px below
|
|
1951
|
+
* 640px, 32px from 640px, on a 1.2 line — staff and list pages; `hero` 30px below 1024px and 36px from 1024px (5.47)
|
|
1952
|
+
* on a 1.2 line, with more room above (`--aura-page-header-hero-space`, default 16px); `hero-lg` 26px below 1024px
|
|
1953
|
+
* and 36px from 1024px, with the same room. Per page, the custom properties `--aura-page-header-title-size` and
|
|
1954
|
+
* `--aura-page-header-title-line-height` override any of them. */
|
|
1955
|
+
size?: "default" | "compact" | "hero" | "hero-lg" | undefined;
|
|
1954
1956
|
/** 5.46: focus the heading when the header mounts (`tabIndex={-1}`, `preventScroll`, no visible ring) — a page
|
|
1955
1957
|
* reached by a server redirect (renewal done, back from a payment page), so a screen reader starts there (WCAG
|
|
1956
1958
|
* 2.4.3). The main entry's PageHeader does it; from `/server` the heading is focusable but not focused. */
|
|
@@ -1972,8 +1974,8 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
1972
1974
|
* meta line and actions stay; with no meta, the actions start the header. */
|
|
1973
1975
|
titleHideBelow?: "sm" | "md" | "lg" | undefined;
|
|
1974
1976
|
/** 5.45 (Chamber-OS 150): below this breakpoint (`sm` 640px, `md` 768px) the same `actions` — rendered once, so a
|
|
1975
|
-
* dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen
|
|
1976
|
-
* above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
|
|
1977
|
+
* dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen, ActionBar's edge
|
|
1978
|
+
* strip (5.48; `actionsBarLook`): above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
|
|
1977
1979
|
* field scroll clear of it (AppShell's content, or the body, gains the bar's height). With an IconButton among them
|
|
1978
1980
|
* the actions share one row, labels wrapping inside the buttons (as `actionsFullWidthBelow`, Chamber-OS 149); with only icon
|
|
1979
1981
|
* buttons the status and the icons share one row. From the breakpoint up nothing changes. Use it for a detail page's
|
|
@@ -1981,6 +1983,10 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
1981
1983
|
* have a transform, filter, backdrop-filter, will-change, paint/layout containment or `content-visibility: auto`, or it is placed
|
|
1982
1984
|
* against that ancestor instead of the screen — the main entry warns in development. */
|
|
1983
1985
|
actionsBarBelow?: "sm" | "md" | undefined;
|
|
1986
|
+
/** 5.48 (Chamber-OS 153): the bar's look. `edge` (default) is ActionBar's strip — the full width of the screen, on
|
|
1987
|
+
* its bottom edge (or above a BottomNav), a top border only, the home-indicator inset inside it. `floating` is 5.45's
|
|
1988
|
+
* card: inset 16px, lifted 12px, bordered all round with rounded corners and a shadow. */
|
|
1989
|
+
actionsBarLook?: "edge" | "floating" | undefined;
|
|
1984
1990
|
/** 5.45: the bar's status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026"), shown only while the actions are
|
|
1985
1991
|
* a bar, in a polite live region. */
|
|
1986
1992
|
actionsStatus?: React$1.ReactNode | undefined;
|
|
@@ -2112,9 +2118,6 @@ export declare const STRINGS: {
|
|
|
2112
2118
|
};
|
|
2113
2119
|
export declare const TileGrid: React$1.ForwardRefExoticComponent<TileGridProps & React$1.RefAttributes<HTMLUListElement>>;
|
|
2114
2120
|
export declare const Sparkline: React$1.ForwardRefExoticComponent<SparklineProps & React$1.RefAttributes<SVGSVGElement>>;
|
|
2115
|
-
/** AppShell — side navigation + top bar + content. The nav is fixed from lg (1024px) up and a Drawer below it.
|
|
2116
|
-
* Which one shows is decided in CSS (4.16), so the server's HTML is already right on a phone and nothing shifts on
|
|
2117
|
-
* hydration; JavaScript only opens and closes the drawer. */
|
|
2118
2121
|
export declare const AppShell: React$1.ForwardRefExoticComponent<AppShellProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
2119
2122
|
/** ActionBar — a bar stuck to the bottom of the screen or of a card: a status line and the form's or selection's
|
|
2120
2123
|
* actions. It is `position: sticky`, so it stays in the flow at the end of its parent and never covers the last field. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1947,10 +1947,12 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
1947
1947
|
/** 5.46: a chip or badge on the title's line (a role, an invoice's status, "Archived"). Title and addon share a
|
|
1948
1948
|
* wrapping row, 8px apart vertically and 12px across; on a narrow screen the addon wraps under the title. */
|
|
1949
1949
|
titleAddon?: React$1.ReactNode | undefined;
|
|
1950
|
-
/** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `
|
|
1951
|
-
*
|
|
1952
|
-
*
|
|
1953
|
-
|
|
1950
|
+
/** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `compact` (5.47, Chamber-OS 152) 26px below
|
|
1951
|
+
* 640px, 32px from 640px, on a 1.2 line — staff and list pages; `hero` 30px below 1024px and 36px from 1024px (5.47)
|
|
1952
|
+
* on a 1.2 line, with more room above (`--aura-page-header-hero-space`, default 16px); `hero-lg` 26px below 1024px
|
|
1953
|
+
* and 36px from 1024px, with the same room. Per page, the custom properties `--aura-page-header-title-size` and
|
|
1954
|
+
* `--aura-page-header-title-line-height` override any of them. */
|
|
1955
|
+
size?: "default" | "compact" | "hero" | "hero-lg" | undefined;
|
|
1954
1956
|
/** 5.46: focus the heading when the header mounts (`tabIndex={-1}`, `preventScroll`, no visible ring) — a page
|
|
1955
1957
|
* reached by a server redirect (renewal done, back from a payment page), so a screen reader starts there (WCAG
|
|
1956
1958
|
* 2.4.3). The main entry's PageHeader does it; from `/server` the heading is focusable but not focused. */
|
|
@@ -1972,8 +1974,8 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
1972
1974
|
* meta line and actions stay; with no meta, the actions start the header. */
|
|
1973
1975
|
titleHideBelow?: "sm" | "md" | "lg" | undefined;
|
|
1974
1976
|
/** 5.45 (Chamber-OS 150): below this breakpoint (`sm` 640px, `md` 768px) the same `actions` — rendered once, so a
|
|
1975
|
-
* dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen
|
|
1976
|
-
* above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
|
|
1977
|
+
* dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen, ActionBar's edge
|
|
1978
|
+
* strip (5.48; `actionsBarLook`): above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
|
|
1977
1979
|
* field scroll clear of it (AppShell's content, or the body, gains the bar's height). With an IconButton among them
|
|
1978
1980
|
* the actions share one row, labels wrapping inside the buttons (as `actionsFullWidthBelow`, Chamber-OS 149); with only icon
|
|
1979
1981
|
* buttons the status and the icons share one row. From the breakpoint up nothing changes. Use it for a detail page's
|
|
@@ -1981,6 +1983,10 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
1981
1983
|
* have a transform, filter, backdrop-filter, will-change, paint/layout containment or `content-visibility: auto`, or it is placed
|
|
1982
1984
|
* against that ancestor instead of the screen — the main entry warns in development. */
|
|
1983
1985
|
actionsBarBelow?: "sm" | "md" | undefined;
|
|
1986
|
+
/** 5.48 (Chamber-OS 153): the bar's look. `edge` (default) is ActionBar's strip — the full width of the screen, on
|
|
1987
|
+
* its bottom edge (or above a BottomNav), a top border only, the home-indicator inset inside it. `floating` is 5.45's
|
|
1988
|
+
* card: inset 16px, lifted 12px, bordered all round with rounded corners and a shadow. */
|
|
1989
|
+
actionsBarLook?: "edge" | "floating" | undefined;
|
|
1984
1990
|
/** 5.45: the bar's status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026"), shown only while the actions are
|
|
1985
1991
|
* a bar, in a polite live region. */
|
|
1986
1992
|
actionsStatus?: React$1.ReactNode | undefined;
|
|
@@ -2112,9 +2118,6 @@ export declare const STRINGS: {
|
|
|
2112
2118
|
};
|
|
2113
2119
|
export declare const TileGrid: React$1.ForwardRefExoticComponent<TileGridProps & React$1.RefAttributes<HTMLUListElement>>;
|
|
2114
2120
|
export declare const Sparkline: React$1.ForwardRefExoticComponent<SparklineProps & React$1.RefAttributes<SVGSVGElement>>;
|
|
2115
|
-
/** AppShell — side navigation + top bar + content. The nav is fixed from lg (1024px) up and a Drawer below it.
|
|
2116
|
-
* Which one shows is decided in CSS (4.16), so the server's HTML is already right on a phone and nothing shifts on
|
|
2117
|
-
* hydration; JavaScript only opens and closes the drawer. */
|
|
2118
2121
|
export declare const AppShell: React$1.ForwardRefExoticComponent<AppShellProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
2119
2122
|
/** ActionBar — a bar stuck to the bottom of the screen or of a card: a status line and the form's or selection's
|
|
2120
2123
|
* actions. It is `position: sticky`, so it stays in the flow at the end of its parent and never covers the last field. */
|
package/dist/server/index.cjs
CHANGED
|
@@ -1446,7 +1446,7 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
|
|
|
1446
1446
|
return n3 != null && n3 !== false && n3 !== "";
|
|
1447
1447
|
};
|
|
1448
1448
|
const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
|
|
1449
|
-
const size = props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
1449
|
+
const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
1450
1450
|
const eyebrow = props.eyebrow;
|
|
1451
1451
|
const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
|
|
1452
1452
|
const heading = h4(
|
|
@@ -1471,6 +1471,7 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
|
|
|
1471
1471
|
(hide === "sm" || hide === "md" || hide === "lg") && "aura-page-header--title-hide-below-" + hide,
|
|
1472
1472
|
(hide === "sm" || hide === "md" || hide === "lg") && !hasMeta && "has-no-meta",
|
|
1473
1473
|
bar && "aura-page-header--actions-bar-below-" + bar,
|
|
1474
|
+
bar && props.actionsBarLook === "floating" && "aura-page-header--actions-bar-floating",
|
|
1474
1475
|
size && "aura-page-header--" + size,
|
|
1475
1476
|
props.actionsAlign === "start" && "aura-page-header--actions-start",
|
|
1476
1477
|
props.className
|
package/dist/server/index.d.cts
CHANGED
|
@@ -505,10 +505,12 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
505
505
|
/** 5.46: a chip or badge on the title's line (a role, an invoice's status, "Archived"). Title and addon share a
|
|
506
506
|
* wrapping row, 8px apart vertically and 12px across; on a narrow screen the addon wraps under the title. */
|
|
507
507
|
titleAddon?: React$1.ReactNode | undefined;
|
|
508
|
-
/** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
|
|
508
|
+
/** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `compact` (5.47, Chamber-OS 152) 26px below
|
|
509
|
+
* 640px, 32px from 640px, on a 1.2 line — staff and list pages; `hero` 30px below 1024px and 36px from 1024px (5.47)
|
|
510
|
+
* on a 1.2 line, with more room above (`--aura-page-header-hero-space`, default 16px); `hero-lg` 26px below 1024px
|
|
511
|
+
* and 36px from 1024px, with the same room. Per page, the custom properties `--aura-page-header-title-size` and
|
|
512
|
+
* `--aura-page-header-title-line-height` override any of them. */
|
|
513
|
+
size?: "default" | "compact" | "hero" | "hero-lg" | undefined;
|
|
512
514
|
/** 5.46: focus the heading when the header mounts (`tabIndex={-1}`, `preventScroll`, no visible ring) — a page
|
|
513
515
|
* reached by a server redirect (renewal done, back from a payment page), so a screen reader starts there (WCAG
|
|
514
516
|
* 2.4.3). The main entry's PageHeader does it; from `/server` the heading is focusable but not focused. */
|
|
@@ -530,8 +532,8 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
530
532
|
* meta line and actions stay; with no meta, the actions start the header. */
|
|
531
533
|
titleHideBelow?: "sm" | "md" | "lg" | undefined;
|
|
532
534
|
/** 5.45 (Chamber-OS 150): below this breakpoint (`sm` 640px, `md` 768px) the same `actions` — rendered once, so a
|
|
533
|
-
* dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen
|
|
534
|
-
* above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
|
|
535
|
+
* dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen, ActionBar's edge
|
|
536
|
+
* strip (5.48; `actionsBarLook`): above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
|
|
535
537
|
* field scroll clear of it (AppShell's content, or the body, gains the bar's height). With an IconButton among them
|
|
536
538
|
* the actions share one row, labels wrapping inside the buttons (as `actionsFullWidthBelow`, Chamber-OS 149); with only icon
|
|
537
539
|
* buttons the status and the icons share one row. From the breakpoint up nothing changes. Use it for a detail page's
|
|
@@ -539,6 +541,10 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
539
541
|
* have a transform, filter, backdrop-filter, will-change, paint/layout containment or `content-visibility: auto`, or it is placed
|
|
540
542
|
* against that ancestor instead of the screen — the main entry warns in development. */
|
|
541
543
|
actionsBarBelow?: "sm" | "md" | undefined;
|
|
544
|
+
/** 5.48 (Chamber-OS 153): the bar's look. `edge` (default) is ActionBar's strip — the full width of the screen, on
|
|
545
|
+
* its bottom edge (or above a BottomNav), a top border only, the home-indicator inset inside it. `floating` is 5.45's
|
|
546
|
+
* card: inset 16px, lifted 12px, bordered all round with rounded corners and a shadow. */
|
|
547
|
+
actionsBarLook?: "edge" | "floating" | undefined;
|
|
542
548
|
/** 5.45: the bar's status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026"), shown only while the actions are
|
|
543
549
|
* a bar, in a polite live region. */
|
|
544
550
|
actionsStatus?: React$1.ReactNode | undefined;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -505,10 +505,12 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
505
505
|
/** 5.46: a chip or badge on the title's line (a role, an invoice's status, "Archived"). Title and addon share a
|
|
506
506
|
* wrapping row, 8px apart vertically and 12px across; on a narrow screen the addon wraps under the title. */
|
|
507
507
|
titleAddon?: React$1.ReactNode | undefined;
|
|
508
|
-
/** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
|
|
508
|
+
/** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `compact` (5.47, Chamber-OS 152) 26px below
|
|
509
|
+
* 640px, 32px from 640px, on a 1.2 line — staff and list pages; `hero` 30px below 1024px and 36px from 1024px (5.47)
|
|
510
|
+
* on a 1.2 line, with more room above (`--aura-page-header-hero-space`, default 16px); `hero-lg` 26px below 1024px
|
|
511
|
+
* and 36px from 1024px, with the same room. Per page, the custom properties `--aura-page-header-title-size` and
|
|
512
|
+
* `--aura-page-header-title-line-height` override any of them. */
|
|
513
|
+
size?: "default" | "compact" | "hero" | "hero-lg" | undefined;
|
|
512
514
|
/** 5.46: focus the heading when the header mounts (`tabIndex={-1}`, `preventScroll`, no visible ring) — a page
|
|
513
515
|
* reached by a server redirect (renewal done, back from a payment page), so a screen reader starts there (WCAG
|
|
514
516
|
* 2.4.3). The main entry's PageHeader does it; from `/server` the heading is focusable but not focused. */
|
|
@@ -530,8 +532,8 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
530
532
|
* meta line and actions stay; with no meta, the actions start the header. */
|
|
531
533
|
titleHideBelow?: "sm" | "md" | "lg" | undefined;
|
|
532
534
|
/** 5.45 (Chamber-OS 150): below this breakpoint (`sm` 640px, `md` 768px) the same `actions` — rendered once, so a
|
|
533
|
-
* dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen
|
|
534
|
-
* above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
|
|
535
|
+
* dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen, ActionBar's edge
|
|
536
|
+
* strip (5.48; `actionsBarLook`): above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
|
|
535
537
|
* field scroll clear of it (AppShell's content, or the body, gains the bar's height). With an IconButton among them
|
|
536
538
|
* the actions share one row, labels wrapping inside the buttons (as `actionsFullWidthBelow`, Chamber-OS 149); with only icon
|
|
537
539
|
* buttons the status and the icons share one row. From the breakpoint up nothing changes. Use it for a detail page's
|
|
@@ -539,6 +541,10 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
|
|
|
539
541
|
* have a transform, filter, backdrop-filter, will-change, paint/layout containment or `content-visibility: auto`, or it is placed
|
|
540
542
|
* against that ancestor instead of the screen — the main entry warns in development. */
|
|
541
543
|
actionsBarBelow?: "sm" | "md" | undefined;
|
|
544
|
+
/** 5.48 (Chamber-OS 153): the bar's look. `edge` (default) is ActionBar's strip — the full width of the screen, on
|
|
545
|
+
* its bottom edge (or above a BottomNav), a top border only, the home-indicator inset inside it. `floating` is 5.45's
|
|
546
|
+
* card: inset 16px, lifted 12px, bordered all round with rounded corners and a shadow. */
|
|
547
|
+
actionsBarLook?: "edge" | "floating" | undefined;
|
|
542
548
|
/** 5.45: the bar's status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026"), shown only while the actions are
|
|
543
549
|
* a bar, in a polite live region. */
|
|
544
550
|
actionsStatus?: React$1.ReactNode | undefined;
|
package/dist/server/index.js
CHANGED
|
@@ -1382,7 +1382,7 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
|
|
|
1382
1382
|
return n3 != null && n3 !== false && n3 !== "";
|
|
1383
1383
|
};
|
|
1384
1384
|
const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
|
|
1385
|
-
const size = props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
1385
|
+
const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
|
|
1386
1386
|
const eyebrow = props.eyebrow;
|
|
1387
1387
|
const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
|
|
1388
1388
|
const heading = h4(
|
|
@@ -1407,6 +1407,7 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
|
|
|
1407
1407
|
(hide === "sm" || hide === "md" || hide === "lg") && "aura-page-header--title-hide-below-" + hide,
|
|
1408
1408
|
(hide === "sm" || hide === "md" || hide === "lg") && !hasMeta && "has-no-meta",
|
|
1409
1409
|
bar && "aura-page-header--actions-bar-below-" + bar,
|
|
1410
|
+
bar && props.actionsBarLook === "floating" && "aura-page-header--actions-bar-floating",
|
|
1410
1411
|
size && "aura-page-header--" + size,
|
|
1411
1412
|
props.actionsAlign === "start" && "aura-page-header--actions-start",
|
|
1412
1413
|
props.className
|
package/dist/styles.css
CHANGED
|
@@ -1208,11 +1208,16 @@ a.aura-tab { text-decoration: none; }
|
|
|
1208
1208
|
.aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
|
|
1209
1209
|
.aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; } /* 5.45 (Chamber-OS addendum 52): centred on a taller button */
|
|
1210
1210
|
}
|
|
1211
|
-
/* 5.
|
|
1211
|
+
/* 5.48 (Chamber-OS 154): only on a screen taller than 480px — on a short one (400% zoom, a phone held sideways) the
|
|
1212
|
+
* actions stay in the header's own row and the page keeps its full height.
|
|
1213
|
+
* 5.48 (Chamber-OS 153): the bar is ActionBar's edge strip (full width, on the bottom edge, top border, the safe area
|
|
1214
|
+
* inside); actionsBarLook="floating" keeps 5.45's inset card.
|
|
1215
|
+
* 5.45 (Chamber-OS 150): actionsBarBelow — the same actions become a fixed bar with a status line; the page gains its
|
|
1212
1216
|
* height (--aura-page-actions-height, measured on the client) so its end and a focused field scroll clear. */
|
|
1213
1217
|
.aura-page-header__status { display: none; }
|
|
1214
|
-
@media (max-width: 639.98px) {
|
|
1215
|
-
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left:
|
|
1218
|
+
@media (max-width: 639.98px) and (min-height: 480.02px) {
|
|
1219
|
+
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left: 0; right: 0; bottom: var(--aura-bottomnav-offset, 0px); box-sizing: border-box; min-height: 60px; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--aura-space-2); margin: 0; padding: var(--aura-space-2) var(--aura-space-3) calc(var(--aura-space-2) + max(0px, env(safe-area-inset-bottom, 0px) - var(--aura-bottomnav-offset, 0px))) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 0; border-top: 1px solid var(--aura-border-default); border-radius: 0; box-shadow: none; transition: bottom var(--aura-duration-base) var(--aura-ease); }
|
|
1220
|
+
.aura-page-header--actions-bar-below-sm.aura-page-header--actions-bar-floating > .aura-page-header__actions { left: var(--aura-space-4); right: var(--aura-space-4); bottom: calc(var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px))); padding-bottom: var(--aura-space-2); border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay); }
|
|
1216
1221
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-page-header__status { display: block; flex: 1 1 100%; min-width: 0; font-size: max(14px, .875rem); line-height: 1.5; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
|
|
1217
1222
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :not(.aura-page-header__status) { flex: 1 1 0; min-width: max-content; }
|
|
1218
1223
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
|
|
@@ -1223,12 +1228,14 @@ a.aura-tab { text-decoration: none; }
|
|
|
1223
1228
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; }
|
|
1224
1229
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
|
|
1225
1230
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:not(:has(> .aura-btn, > * > .aura-btn)) > .aura-page-header__status { flex: 1 1 0; align-self: center; }
|
|
1226
|
-
:root:has(.aura-page-header--actions-bar-below-sm) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) +
|
|
1231
|
+
:root:has(.aura-page-header--actions-bar-below-sm) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + var(--aura-space-3)); scroll-padding-bottom: var(--aura-page-actions-space); }
|
|
1232
|
+
:root:has(.aura-page-header--actions-bar-below-sm.aura-page-header--actions-bar-floating) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px)) + var(--aura-space-3)); }
|
|
1227
1233
|
:root:has(.aura-page-header--actions-bar-below-sm) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-page-actions-space)); }
|
|
1228
1234
|
:root:has(.aura-page-header--actions-bar-below-sm):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
|
|
1229
1235
|
}
|
|
1230
|
-
@media (max-width: 767.98px) {
|
|
1231
|
-
.aura-page-header--actions-bar-below-md > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left:
|
|
1236
|
+
@media (max-width: 767.98px) and (min-height: 480.02px) {
|
|
1237
|
+
.aura-page-header--actions-bar-below-md > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left: 0; right: 0; bottom: var(--aura-bottomnav-offset, 0px); box-sizing: border-box; min-height: 60px; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--aura-space-2); margin: 0; padding: var(--aura-space-2) var(--aura-space-3) calc(var(--aura-space-2) + max(0px, env(safe-area-inset-bottom, 0px) - var(--aura-bottomnav-offset, 0px))) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 0; border-top: 1px solid var(--aura-border-default); border-radius: 0; box-shadow: none; transition: bottom var(--aura-duration-base) var(--aura-ease); }
|
|
1238
|
+
.aura-page-header--actions-bar-below-md.aura-page-header--actions-bar-floating > .aura-page-header__actions { left: var(--aura-space-4); right: var(--aura-space-4); bottom: calc(var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px))); padding-bottom: var(--aura-space-2); border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay); }
|
|
1232
1239
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-page-header__status { display: block; flex: 1 1 100%; min-width: 0; font-size: max(14px, .875rem); line-height: 1.5; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
|
|
1233
1240
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions > :not(.aura-page-header__status) { flex: 1 1 0; min-width: max-content; }
|
|
1234
1241
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
|
|
@@ -1239,7 +1246,8 @@ a.aura-tab { text-decoration: none; }
|
|
|
1239
1246
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; }
|
|
1240
1247
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
|
|
1241
1248
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions:not(:has(> .aura-btn, > * > .aura-btn)) > .aura-page-header__status { flex: 1 1 0; align-self: center; }
|
|
1242
|
-
:root:has(.aura-page-header--actions-bar-below-md) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) +
|
|
1249
|
+
:root:has(.aura-page-header--actions-bar-below-md) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + var(--aura-space-3)); scroll-padding-bottom: var(--aura-page-actions-space); }
|
|
1250
|
+
:root:has(.aura-page-header--actions-bar-below-md.aura-page-header--actions-bar-floating) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px)) + var(--aura-space-3)); }
|
|
1243
1251
|
:root:has(.aura-page-header--actions-bar-below-md) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-page-actions-space)); }
|
|
1244
1252
|
:root:has(.aura-page-header--actions-bar-below-md):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
|
|
1245
1253
|
}
|
|
@@ -1251,8 +1259,12 @@ a.aura-tab { text-decoration: none; }
|
|
|
1251
1259
|
.aura-page-header__title-row > .aura-page-header__title { min-width: 0; }
|
|
1252
1260
|
.aura-page-header__title-addon { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); min-width: 0; }
|
|
1253
1261
|
.aura-page-header__eyebrow--rich { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); font-family: var(--font-sans); line-height: 1.5; }
|
|
1254
|
-
.aura-page-header--hero, .aura-page-header--hero-lg { padding-top: var(--aura-space-4); }
|
|
1262
|
+
.aura-page-header--hero, .aura-page-header--hero-lg { padding-top: var(--aura-page-header-hero-space, var(--aura-space-4)); }
|
|
1255
1263
|
.aura-page-header--hero .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(30px, 1.875rem)); line-height: var(--aura-page-header-title-line-height, 1.2); }
|
|
1264
|
+
/* 5.47 (Chamber-OS 152): compact — the staff boards' 26 / 32; hero steps to 36px from 1024px like hero-lg. */
|
|
1265
|
+
.aura-page-header--compact .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(26px, 1.625rem)); line-height: var(--aura-page-header-title-line-height, 1.2); }
|
|
1266
|
+
@media (min-width: 640px) { .aura-page-header--compact .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(32px, 2rem)); } }
|
|
1267
|
+
@media (min-width: 1024px) { .aura-page-header--hero .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); } }
|
|
1256
1268
|
.aura-page-header--hero-lg .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(26px, 1.625rem)); line-height: var(--aura-page-header-title-line-height, 1.25); }
|
|
1257
1269
|
@media (min-width: 1024px) { .aura-page-header--hero-lg .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); line-height: var(--aura-page-header-title-line-height, 1.2); } }
|
|
1258
1270
|
.aura-page-header__title[tabindex="-1"]:focus { outline: none; }
|
|
@@ -2081,6 +2093,13 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2081
2093
|
border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay);
|
|
2082
2094
|
}
|
|
2083
2095
|
.aura-actionbar--container { bottom: 0; border-top: 1px solid var(--aura-border-default); }
|
|
2096
|
+
/* 5.48 (Chamber-OS 154): on a short screen (480px or less: 400% zoom, a phone held sideways) the bar stops sticking —
|
|
2097
|
+
* it stays at the end of its container, in the flow, so it never covers a focused field (WCAG 2.4.11, 1.4.10). */
|
|
2098
|
+
@media (max-height: 480px) { .aura-actionbar:not(.is-idle) { position: static; } }
|
|
2099
|
+
/* …and AppShell's top bar scrolls away with the page, so Shift+Tab never lands a field under it. */
|
|
2100
|
+
@media (max-height: 480px) { .aura-shell__bar { position: static; } }
|
|
2101
|
+
/* 5.48: wherever a BottomNav shows, a field scrolled into view (Tab) stops above it, not under it. */
|
|
2102
|
+
:root { scroll-padding-bottom: var(--aura-bottomnav-offset, 0px); }
|
|
2084
2103
|
.aura-actionbar__inner { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2) var(--aura-space-3); min-height: 60px; box-sizing: border-box; padding-block: var(--aura-space-2); padding-inline: var(--aura-space-4) var(--aura-space-3); }
|
|
2085
2104
|
.aura-actionbar__status { flex: 1 1 8rem; min-width: 0; font-size: max(14px, .875rem); color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; }
|
|
2086
2105
|
.aura-actionbar__status:empty { flex-basis: 0; }
|
package/dist/styles.layer.css
CHANGED
|
@@ -1210,11 +1210,16 @@ a.aura-tab { text-decoration: none; }
|
|
|
1210
1210
|
.aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
|
|
1211
1211
|
.aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; } /* 5.45 (Chamber-OS addendum 52): centred on a taller button */
|
|
1212
1212
|
}
|
|
1213
|
-
/* 5.
|
|
1213
|
+
/* 5.48 (Chamber-OS 154): only on a screen taller than 480px — on a short one (400% zoom, a phone held sideways) the
|
|
1214
|
+
* actions stay in the header's own row and the page keeps its full height.
|
|
1215
|
+
* 5.48 (Chamber-OS 153): the bar is ActionBar's edge strip (full width, on the bottom edge, top border, the safe area
|
|
1216
|
+
* inside); actionsBarLook="floating" keeps 5.45's inset card.
|
|
1217
|
+
* 5.45 (Chamber-OS 150): actionsBarBelow — the same actions become a fixed bar with a status line; the page gains its
|
|
1214
1218
|
* height (--aura-page-actions-height, measured on the client) so its end and a focused field scroll clear. */
|
|
1215
1219
|
.aura-page-header__status { display: none; }
|
|
1216
|
-
@media (max-width: 639.98px) {
|
|
1217
|
-
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left:
|
|
1220
|
+
@media (max-width: 639.98px) and (min-height: 480.02px) {
|
|
1221
|
+
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left: 0; right: 0; bottom: var(--aura-bottomnav-offset, 0px); box-sizing: border-box; min-height: 60px; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--aura-space-2); margin: 0; padding: var(--aura-space-2) var(--aura-space-3) calc(var(--aura-space-2) + max(0px, env(safe-area-inset-bottom, 0px) - var(--aura-bottomnav-offset, 0px))) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 0; border-top: 1px solid var(--aura-border-default); border-radius: 0; box-shadow: none; transition: bottom var(--aura-duration-base) var(--aura-ease); }
|
|
1222
|
+
.aura-page-header--actions-bar-below-sm.aura-page-header--actions-bar-floating > .aura-page-header__actions { left: var(--aura-space-4); right: var(--aura-space-4); bottom: calc(var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px))); padding-bottom: var(--aura-space-2); border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay); }
|
|
1218
1223
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-page-header__status { display: block; flex: 1 1 100%; min-width: 0; font-size: max(14px, .875rem); line-height: 1.5; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
|
|
1219
1224
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :not(.aura-page-header__status) { flex: 1 1 0; min-width: max-content; }
|
|
1220
1225
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
|
|
@@ -1225,12 +1230,14 @@ a.aura-tab { text-decoration: none; }
|
|
|
1225
1230
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; }
|
|
1226
1231
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
|
|
1227
1232
|
.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:not(:has(> .aura-btn, > * > .aura-btn)) > .aura-page-header__status { flex: 1 1 0; align-self: center; }
|
|
1228
|
-
:root:has(.aura-page-header--actions-bar-below-sm) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) +
|
|
1233
|
+
:root:has(.aura-page-header--actions-bar-below-sm) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + var(--aura-space-3)); scroll-padding-bottom: var(--aura-page-actions-space); }
|
|
1234
|
+
:root:has(.aura-page-header--actions-bar-below-sm.aura-page-header--actions-bar-floating) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px)) + var(--aura-space-3)); }
|
|
1229
1235
|
:root:has(.aura-page-header--actions-bar-below-sm) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-page-actions-space)); }
|
|
1230
1236
|
:root:has(.aura-page-header--actions-bar-below-sm):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
|
|
1231
1237
|
}
|
|
1232
|
-
@media (max-width: 767.98px) {
|
|
1233
|
-
.aura-page-header--actions-bar-below-md > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left:
|
|
1238
|
+
@media (max-width: 767.98px) and (min-height: 480.02px) {
|
|
1239
|
+
.aura-page-header--actions-bar-below-md > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left: 0; right: 0; bottom: var(--aura-bottomnav-offset, 0px); box-sizing: border-box; min-height: 60px; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--aura-space-2); margin: 0; padding: var(--aura-space-2) var(--aura-space-3) calc(var(--aura-space-2) + max(0px, env(safe-area-inset-bottom, 0px) - var(--aura-bottomnav-offset, 0px))) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 0; border-top: 1px solid var(--aura-border-default); border-radius: 0; box-shadow: none; transition: bottom var(--aura-duration-base) var(--aura-ease); }
|
|
1240
|
+
.aura-page-header--actions-bar-below-md.aura-page-header--actions-bar-floating > .aura-page-header__actions { left: var(--aura-space-4); right: var(--aura-space-4); bottom: calc(var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px))); padding-bottom: var(--aura-space-2); border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay); }
|
|
1234
1241
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-page-header__status { display: block; flex: 1 1 100%; min-width: 0; font-size: max(14px, .875rem); line-height: 1.5; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
|
|
1235
1242
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions > :not(.aura-page-header__status) { flex: 1 1 0; min-width: max-content; }
|
|
1236
1243
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
|
|
@@ -1241,7 +1248,8 @@ a.aura-tab { text-decoration: none; }
|
|
|
1241
1248
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; }
|
|
1242
1249
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
|
|
1243
1250
|
.aura-page-header--actions-bar-below-md > .aura-page-header__actions:not(:has(> .aura-btn, > * > .aura-btn)) > .aura-page-header__status { flex: 1 1 0; align-self: center; }
|
|
1244
|
-
:root:has(.aura-page-header--actions-bar-below-md) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) +
|
|
1251
|
+
:root:has(.aura-page-header--actions-bar-below-md) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + var(--aura-space-3)); scroll-padding-bottom: var(--aura-page-actions-space); }
|
|
1252
|
+
:root:has(.aura-page-header--actions-bar-below-md.aura-page-header--actions-bar-floating) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px)) + var(--aura-space-3)); }
|
|
1245
1253
|
:root:has(.aura-page-header--actions-bar-below-md) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-page-actions-space)); }
|
|
1246
1254
|
:root:has(.aura-page-header--actions-bar-below-md):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
|
|
1247
1255
|
}
|
|
@@ -1253,8 +1261,12 @@ a.aura-tab { text-decoration: none; }
|
|
|
1253
1261
|
.aura-page-header__title-row > .aura-page-header__title { min-width: 0; }
|
|
1254
1262
|
.aura-page-header__title-addon { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); min-width: 0; }
|
|
1255
1263
|
.aura-page-header__eyebrow--rich { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); font-family: var(--font-sans); line-height: 1.5; }
|
|
1256
|
-
.aura-page-header--hero, .aura-page-header--hero-lg { padding-top: var(--aura-space-4); }
|
|
1264
|
+
.aura-page-header--hero, .aura-page-header--hero-lg { padding-top: var(--aura-page-header-hero-space, var(--aura-space-4)); }
|
|
1257
1265
|
.aura-page-header--hero .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(30px, 1.875rem)); line-height: var(--aura-page-header-title-line-height, 1.2); }
|
|
1266
|
+
/* 5.47 (Chamber-OS 152): compact — the staff boards' 26 / 32; hero steps to 36px from 1024px like hero-lg. */
|
|
1267
|
+
.aura-page-header--compact .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(26px, 1.625rem)); line-height: var(--aura-page-header-title-line-height, 1.2); }
|
|
1268
|
+
@media (min-width: 640px) { .aura-page-header--compact .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(32px, 2rem)); } }
|
|
1269
|
+
@media (min-width: 1024px) { .aura-page-header--hero .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); } }
|
|
1258
1270
|
.aura-page-header--hero-lg .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(26px, 1.625rem)); line-height: var(--aura-page-header-title-line-height, 1.25); }
|
|
1259
1271
|
@media (min-width: 1024px) { .aura-page-header--hero-lg .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); line-height: var(--aura-page-header-title-line-height, 1.2); } }
|
|
1260
1272
|
.aura-page-header__title[tabindex="-1"]:focus { outline: none; }
|
|
@@ -2083,6 +2095,13 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2083
2095
|
border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay);
|
|
2084
2096
|
}
|
|
2085
2097
|
.aura-actionbar--container { bottom: 0; border-top: 1px solid var(--aura-border-default); }
|
|
2098
|
+
/* 5.48 (Chamber-OS 154): on a short screen (480px or less: 400% zoom, a phone held sideways) the bar stops sticking —
|
|
2099
|
+
* it stays at the end of its container, in the flow, so it never covers a focused field (WCAG 2.4.11, 1.4.10). */
|
|
2100
|
+
@media (max-height: 480px) { .aura-actionbar:not(.is-idle) { position: static; } }
|
|
2101
|
+
/* …and AppShell's top bar scrolls away with the page, so Shift+Tab never lands a field under it. */
|
|
2102
|
+
@media (max-height: 480px) { .aura-shell__bar { position: static; } }
|
|
2103
|
+
/* 5.48: wherever a BottomNav shows, a field scrolled into view (Tab) stops above it, not under it. */
|
|
2104
|
+
:root { scroll-padding-bottom: var(--aura-bottomnav-offset, 0px); }
|
|
2086
2105
|
.aura-actionbar__inner { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2) var(--aura-space-3); min-height: 60px; box-sizing: border-box; padding-block: var(--aura-space-2); padding-inline: var(--aura-space-4) var(--aura-space-3); }
|
|
2087
2106
|
.aura-actionbar__status { flex: 1 1 8rem; min-width: 0; font-size: max(14px, .875rem); color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; }
|
|
2088
2107
|
.aura-actionbar__status:empty { flex-basis: 0; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-react",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.48.0",
|
|
4
4
|
"description": "AURA Design System — React components (Enterprise Standard, Human Creative). Thai-first: Buddhist-era dates, Thai collation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|