@jirawatpyk/aura-react 5.78.0 → 5.80.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 +76 -1
- package/dist/aura.bundle.js +29 -3
- package/dist/cjs/index.cjs +29 -3
- package/dist/esm/DataTable.js +6 -0
- package/dist/esm/DatePicker.js +1 -1
- package/dist/esm/FileUpload.js +13 -0
- package/dist/esm/Menu.js +6 -2
- package/dist/esm/theme.js +3 -0
- package/dist/server/index.cjs +3 -0
- package/dist/server/index.js +3 -0
- package/dist/styles.css +63 -19
- package/dist/styles.layer.css +63 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,7 +100,69 @@ export function Providers({ children, locale }: { children: React.ReactNode; loc
|
|
|
100
100
|
// app/layout.tsx (a Server Component): <body><Providers locale="th">{children}</Providers></body>
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
`linkComponent` is used by Button `href`, Breadcrumb, Tabs and Menu items with `href`, BottomNav, Pagination `getHref` (page numbers and, since 4.17, the previous / next arrows), Stat `href`, SideNav and DataTable row/pager links. Each of them also takes its own `linkComponent`, which wins over the provider's. Pass `getHref` from a client component (it's a function too). The Next.js starter does all of this, and CI clicks every AURA link in it to check none triggers a full page load. Only `th` shows Buddhist-era years; `en` and `sv` are Gregorian (`sv` weeks start Monday). **Without a provider, components are English with Gregorian dates** — wrap Thai apps in `<AuraProvider locale="th">`. For dates in your own components use `useFormatDate()` — it follows the provider (`const fmt = useFormatDate(); fmt(iso, { format: 'long' })`). Plain `formatDate()` has no provider to read: since 5.0 it is English and Gregorian unless you pass `locale`, the same function from the package root and from `@jirawatpyk/aura-react/server`. Values are always Gregorian ISO dates.
|
|
103
|
+
`linkComponent` is used by Button `href`, Breadcrumb, Tabs and Menu items with `href`, BottomNav, Pagination `getHref` (page numbers and, since 4.17, the previous / next arrows), Stat and StatusTile `href`, Th `sortHref`, toast action `href`, SideNav and DataTable row/pager links. Each of them also takes its own `linkComponent`, which wins over the provider's. Pass `getHref` from a client component (it's a function too). The Next.js starter does all of this, and CI clicks every AURA link in it to check none triggers a full page load. Only `th` shows Buddhist-era years; `en` and `sv` are Gregorian (`sv` weeks start Monday). **Without a provider, components are English with Gregorian dates** — wrap Thai apps in `<AuraProvider locale="th">`. For dates in your own components use `useFormatDate()` — it follows the provider (`const fmt = useFormatDate(); fmt(iso, { format: 'long' })`). Plain `formatDate()` has no provider to read: since 5.0 it is English and Gregorian unless you pass `locale`, the same function from the package root and from `@jirawatpyk/aura-react/server`. Values are always Gregorian ISO dates.
|
|
104
|
+
|
|
105
|
+
TanStack Start / TanStack Router (5.80): AURA gives `linkComponent` a plain `href`, so pass a small `<a>` that hands same-origin clicks to the router — not TanStack's `<Link>`, which adds `aria-current="page"` to every link its own matcher calls active (on `/members?page=3`, the page 1 link and the "All" tab as well), over AURA's own:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
// src/components/aura-link.tsx
|
|
109
|
+
import * as React from 'react';
|
|
110
|
+
import { useRouter } from '@tanstack/react-router';
|
|
111
|
+
|
|
112
|
+
function routerHref(href?: string): string | null {
|
|
113
|
+
if (href == null || typeof window === 'undefined') return null;
|
|
114
|
+
let url: URL;
|
|
115
|
+
try {
|
|
116
|
+
url = new URL(href, window.location.href); // also '?page=2' and 'members'
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
const here = window.location;
|
|
121
|
+
if (url.origin !== here.origin) return null; // other sites, mailto:, tel:
|
|
122
|
+
if (url.hash && url.pathname === here.pathname && url.search === here.search) return null; // #fragment here
|
|
123
|
+
return url.pathname + url.search + url.hash;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export const AuraLink = React.forwardRef<HTMLAnchorElement, React.AnchorHTMLAttributes<HTMLAnchorElement>>(
|
|
127
|
+
function AuraLink({ href, onClick, onMouseEnter, onFocus, ...rest }, ref) {
|
|
128
|
+
const router = useRouter();
|
|
129
|
+
const preload = () => {
|
|
130
|
+
const to = routerHref(href);
|
|
131
|
+
if (to) router.preloadRoute({ href: to } as Parameters<typeof router.preloadRoute>[0]).catch(() => undefined);
|
|
132
|
+
};
|
|
133
|
+
return (
|
|
134
|
+
<a ref={ref} href={href} {...rest}
|
|
135
|
+
onClick={(e) => {
|
|
136
|
+
onClick?.(e); // AURA's own handler first (a DataTable pager with onPageChange, a toast action)
|
|
137
|
+
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
138
|
+
const target = e.currentTarget.getAttribute('target');
|
|
139
|
+
if ((target && target !== '_self') || e.currentTarget.hasAttribute('download')) return;
|
|
140
|
+
const to = routerHref(href);
|
|
141
|
+
if (!to) return;
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
void router.navigate({ href: to });
|
|
144
|
+
}}
|
|
145
|
+
onMouseEnter={(e) => { onMouseEnter?.(e); preload(); }}
|
|
146
|
+
onFocus={(e) => { onFocus?.(e); preload(); }}
|
|
147
|
+
/>
|
|
148
|
+
);
|
|
149
|
+
},
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
// src/routes/__root.tsx — the provider inside the router (the root route's component), the document in shellComponent
|
|
153
|
+
export const Route = createRootRoute({
|
|
154
|
+
head: () => ({ links: [{ rel: 'stylesheet', href: tokensCss }, { rel: 'stylesheet', href: auraCss }] }), // '…css?url' imports
|
|
155
|
+
shellComponent: RootDocument, // <html><head><HeadContent /><ColorSchemeScript /></head><body>{children}<Scripts /></body></html>
|
|
156
|
+
component: () => (
|
|
157
|
+
<AuraProvider locale="th" strings={th} linkComponent={AuraLink}>
|
|
158
|
+
<Outlet />
|
|
159
|
+
<Toaster />
|
|
160
|
+
</AuraProvider>
|
|
161
|
+
),
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Write hrefs as URLs (`getHref={(p) => '/members?page=' + p}`) and read them back with the route's `validateSearch`. A client navigation passes the query through the router's search parser and serializer, so keep params single-valued (`?a=1&a=2` comes back as JSON, `?q=1e3` as `1000`) or set the router's `parseSearch` / `stringifySearch`. With a `basepath`, write hrefs with it; a same-origin href outside it goes to the router's not-found route. DataTable keyboard paging (PageDown / PageUp, arrows past the page) clicks the pager links, and since 5.80 the focus moves to the new page's row. The TanStack Start starter (`templates/tanstack-start-starter`) has all of this; CI builds it against the packed packages and clicks every AURA link in it — Button, Breadcrumb, link Tabs, DropdownMenu items, BottomNav, Pagination, Th `sortHref`, Stat, StatusTile, SideNav, DataTable rows and pager, toast actions — checking that none loads a full page, that `aria-current` is AURA's and that Ctrl/⌘-click still opens a tab.
|
|
104
166
|
|
|
105
167
|
## Compact density
|
|
106
168
|
|
|
@@ -186,6 +248,19 @@ DataTable with sort and page in the URL (4.17): `onStateChange={({ sort, page })
|
|
|
186
248
|
- **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
249
|
- **Toasts** queue past three instead of dropping: six in a row all show, in order, three at a time.
|
|
188
250
|
|
|
251
|
+
## 5.79 — visual audit, set 3 (component by component)
|
|
252
|
+
|
|
253
|
+
- **One disabled look for every Button variant:** a faint fill (`--aura-button-disabled-bg`: zinc-100 light, none in dark), a faint edge (`--aura-button-disabled-border` — the variant's own border, or 1px inside for primary and danger) and the tertiary label, at full opacity — primary, secondary, danger, creative and `aria-disabled` alike; a ghost button has neither fill nor edge. (5.30 gave filled buttons a grey fill that read as a To Do pill and faded outline ones.)
|
|
254
|
+
- **ActionBar `look="edge"` in an AppShell on a desktop** starts after the sidebar (the rail width when collapsed; the right edge in RTL) and lines its contents up with the content's 32px padding (not with `contentPadding={false}`), instead of running under the sidebar. It reads the sidebar's width from `--aura-sidenav-width` / `--aura-sidenav-rail-width`: to change it, set the token on `.aura-shell` or `:root`, not on the nav — and a custom `nav` set them to its width. Outside an AppShell it keeps the screen's width; `edgeBelow` is unchanged (no sidebar there).
|
|
255
|
+
- **A list box** (`<Select multiple>` or `size` > 1) shows its rows, as tall as they need, without the chevron.
|
|
256
|
+
- **Combobox `multiple`:** a chip no longer shrinks to "V.."; it keeps its label and moves to the next line (a label wider than the field still ends in "…").
|
|
257
|
+
- **Switch with an `icon`** (a locked, read-only switch): the lock sits 8px after the label, not at the row's far end. Its colours stay as 5.19 set them.
|
|
258
|
+
- **Menu / DropdownMenu:** a menu whose items have no icon, check box or radio has no empty icon column; it opens on its trigger's left edge when ending on its right would cross the screen (LTR; positioning stays physical, as before); and it is lifted with `--aura-shadow-overlay`, as Popover and the list boxes.
|
|
259
|
+
- **Small fixes:** FileUpload's hint names formats (PNG, JPEG, SVG, DOCX, XLSX), not "IMAGE/PNG"; an outline Badge has a quieter edge (its colour at 45%), so it doesn't read as a secondary Button; a date range is a violet-100 band in light (`--aura-calendar-range-bg`, the brand's 100 step in `createTheme`), visible on white; a disabled field's edge shows in dark (`--aura-input-disabled-border`, zinc-700).
|
|
260
|
+
- **Thai:** a Calendar with a Thai locale carries `lang="th"` and its weekday row is 13px; two-line Thai SideNav labels get room between lines; Combobox options have fixed line heights, so Thai and English rows are spaced alike.
|
|
261
|
+
- **PageHeader:** where `actionsFullWidthBelow` reaches wider than `actionsBarBelow`, every button in the row is `radius-md` between the two breakpoints (5.78 left the bar's buttons as pills there).
|
|
262
|
+
- **Stories:** the ⋯ beside outline buttons in action rows is `variant="outline"` (keep it so in an action row); the launch page shows with its own styles.
|
|
263
|
+
|
|
189
264
|
## 5.78 — visual audit, set 2 (phones)
|
|
190
265
|
|
|
191
266
|
- **Bottom strips on a phone follow one rule:** ActionBar's edge strip (`look="edge"`, `edgeBelow`) now lays out as PageHeader's bar (5.48) — the status on its own row at the top, the actions sharing the row under it (an IconButton keeps its square; labels too long to share take a row each, as PageHeader's) — and both strips are 16px from either side, the page's phone gutter (they were 16 and 12). `edgeBelow="md"` follows it up to 768px. A single label wider than the screen still overflows, as in PageHeader's strip — keep bar labels short.
|
package/dist/aura.bundle.js
CHANGED
|
@@ -1929,7 +1929,8 @@ window.Aura = (() => {
|
|
|
1929
1929
|
top = r2.top - above - 4;
|
|
1930
1930
|
} else maxHeight = below2;
|
|
1931
1931
|
}
|
|
1932
|
-
const
|
|
1932
|
+
const endAligned = r2.right - mw;
|
|
1933
|
+
const left = Math.max(8, Math.min(endAligned >= 8 ? endAligned : r2.left, window.innerWidth - mw - 8));
|
|
1933
1934
|
setPos(function(p) {
|
|
1934
1935
|
return p && p.top === top && p.left === left && p.maxHeight === maxHeight ? p : { top, left, maxHeight };
|
|
1935
1936
|
});
|
|
@@ -2028,12 +2029,15 @@ window.Aura = (() => {
|
|
|
2028
2029
|
});
|
|
2029
2030
|
return out;
|
|
2030
2031
|
}
|
|
2032
|
+
const anyLead = items2.some(function(it) {
|
|
2033
|
+
return !it.separator && (!!it.icon || it.type === "radio" || it.checked !== void 0);
|
|
2034
|
+
});
|
|
2031
2035
|
function renderItem(it, i) {
|
|
2032
2036
|
if (it.separator) return /* @__PURE__ */ React9.createElement("div", { key: "s" + i, role: "separator", className: "aura-menu__sep" });
|
|
2033
2037
|
const isRadio = it.type === "radio";
|
|
2034
2038
|
const isCheck = !isRadio && it.checked !== void 0;
|
|
2035
2039
|
const checkAtEnd = isCheck && !!it.icon && it.checkPlacement !== "start";
|
|
2036
|
-
const lead = isRadio ? /* @__PURE__ */ React9.createElement("span", { className: cx("aura-menu__radio", it.checked && "is-on") }) : isCheck && !checkAtEnd ? /* @__PURE__ */ React9.createElement("span", { className: cx("aura-menu__check", it.checked && "is-on") }, it.checked ? /* @__PURE__ */ React9.createElement(Icon, { name: /* @__PURE__ */ React9.createElement(IconCheck, null), size: 12, strokeWidth: 3 }) : null) : it.icon ? /* @__PURE__ */ React9.createElement(Icon, { name: it.icon }) : /* @__PURE__ */ React9.createElement("span", { className: "aura-menu__blank" });
|
|
2040
|
+
const lead = isRadio ? /* @__PURE__ */ React9.createElement("span", { className: cx("aura-menu__radio", it.checked && "is-on") }) : isCheck && !checkAtEnd ? /* @__PURE__ */ React9.createElement("span", { className: cx("aura-menu__check", it.checked && "is-on") }, it.checked ? /* @__PURE__ */ React9.createElement(Icon, { name: /* @__PURE__ */ React9.createElement(IconCheck, null), size: 12, strokeWidth: 3 }) : null) : it.icon ? /* @__PURE__ */ React9.createElement(Icon, { name: it.icon }) : anyLead ? /* @__PURE__ */ React9.createElement("span", { className: "aura-menu__blank" }) : null;
|
|
2037
2041
|
const body = [
|
|
2038
2042
|
/* @__PURE__ */ React9.createElement(React9.Fragment, { key: "l" }, lead),
|
|
2039
2043
|
/* @__PURE__ */ React9.createElement("span", { key: "t", className: "aura-menu__label" }, it.label),
|
|
@@ -3444,7 +3448,7 @@ window.Aura = (() => {
|
|
|
3444
3448
|
setFocus(addMonths(focusDate, 1));
|
|
3445
3449
|
}
|
|
3446
3450
|
}
|
|
3447
|
-
)), /* @__PURE__ */ React18.createElement("table", { role: "grid", className: "aura-cal__grid", "aria-label": monthTitle }, /* @__PURE__ */ React18.createElement("thead", null, /* @__PURE__ */ React18.createElement("tr", null, weekdayNames.map(function(n3, i) {
|
|
3451
|
+
)), /* @__PURE__ */ React18.createElement("table", { role: "grid", className: "aura-cal__grid", "aria-label": monthTitle, lang: th2 ? "th" : void 0 }, /* @__PURE__ */ React18.createElement("thead", null, /* @__PURE__ */ React18.createElement("tr", null, weekdayNames.map(function(n3, i) {
|
|
3448
3452
|
return /* @__PURE__ */ React18.createElement("th", { key: i, scope: "col", abbr: n3.long }, /* @__PURE__ */ React18.createElement("span", { "aria-hidden": true }, n3.short));
|
|
3449
3453
|
}))), /* @__PURE__ */ React18.createElement(
|
|
3450
3454
|
"tbody",
|
|
@@ -6544,6 +6548,7 @@ window.Aura = (() => {
|
|
|
6544
6548
|
if (next === page) return false;
|
|
6545
6549
|
if (!quiet) emit(sort, next);
|
|
6546
6550
|
if (linkPaging) {
|
|
6551
|
+
if (focus) pending.current = { ...focus, page: next, at: Date.now() };
|
|
6547
6552
|
const a = next === page - 1 ? prevLink.current : next === page + 1 ? nextLink.current : null;
|
|
6548
6553
|
if (a) a.click();
|
|
6549
6554
|
else jumpState[1](next);
|
|
@@ -6642,6 +6647,11 @@ window.Aura = (() => {
|
|
|
6642
6647
|
React34.useEffect(function() {
|
|
6643
6648
|
const p = pending.current;
|
|
6644
6649
|
if (!p || !gridRef.current) return;
|
|
6650
|
+
if (p.at != null && Date.now() - p.at > 1e4) {
|
|
6651
|
+
pending.current = null;
|
|
6652
|
+
return;
|
|
6653
|
+
}
|
|
6654
|
+
if (p.page != null && p.page !== page) return;
|
|
6645
6655
|
let c = p.c;
|
|
6646
6656
|
if (p.key) {
|
|
6647
6657
|
let at = -1;
|
|
@@ -10074,6 +10084,19 @@ window.Aura = (() => {
|
|
|
10074
10084
|
a = a.trim();
|
|
10075
10085
|
if (a === "image/*") return t.images;
|
|
10076
10086
|
if (a === "application/pdf") return "PDF";
|
|
10087
|
+
const known = {
|
|
10088
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "DOCX",
|
|
10089
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "XLSX",
|
|
10090
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "PPTX",
|
|
10091
|
+
"application/msword": "DOC",
|
|
10092
|
+
"application/vnd.ms-excel": "XLS",
|
|
10093
|
+
"application/vnd.ms-powerpoint": "PPT",
|
|
10094
|
+
"text/plain": "TXT"
|
|
10095
|
+
};
|
|
10096
|
+
if (known[a]) return known[a];
|
|
10097
|
+
const slash = a.indexOf("/");
|
|
10098
|
+
if (slash > 0 && a.slice(slash + 1) !== "*")
|
|
10099
|
+
a = a.slice(slash + 1).replace(/^(?:vnd\.|x-)/, "").replace(/\+xml$/, "");
|
|
10077
10100
|
return a.replace(/^\./, "").toUpperCase();
|
|
10078
10101
|
}).filter(function(x, i, arr) {
|
|
10079
10102
|
return arr.indexOf(x) === i;
|
|
@@ -10482,6 +10505,7 @@ window.Aura = (() => {
|
|
|
10482
10505
|
L["accent-violet"] = L["fg-accent"];
|
|
10483
10506
|
L["focus-ring"] = fit(b[700], lightGrounds.concat([b[50]]), 3, -1);
|
|
10484
10507
|
L["bg-selected"] = b[50];
|
|
10508
|
+
L["calendar-range-bg"] = b[100];
|
|
10485
10509
|
L["status-progress-bg"] = b[100];
|
|
10486
10510
|
L["status-progress-fg"] = fit(b[800], [b[100]], 4.5, -1);
|
|
10487
10511
|
L["alert-info-bg"] = b[50];
|
|
@@ -10521,6 +10545,7 @@ window.Aura = (() => {
|
|
|
10521
10545
|
D["control-checked-bg"] = fit(b[300], darkGrounds, 3, 1);
|
|
10522
10546
|
D["control-checked-fg"] = onFill(D["control-checked-bg"]);
|
|
10523
10547
|
D["nav-active-edge"] = D["control-checked-bg"];
|
|
10548
|
+
D["calendar-range-bg"] = D["bg-selected"];
|
|
10524
10549
|
const shadowLight = INK, shadowDark = D["accent-violet"];
|
|
10525
10550
|
if (o.primary === "brand") {
|
|
10526
10551
|
L["button-primary-bg"] = fit(b[600], [ZINC[0]], 4.5, -1);
|
|
@@ -10578,6 +10603,7 @@ window.Aura = (() => {
|
|
|
10578
10603
|
check("dark", "chart-1", "chart-2 (lightness step)", 1.8, D["chart-1"], CHART_2);
|
|
10579
10604
|
check("light", "fg-primary", "bg-selected", 4.5, INK, L["bg-selected"]);
|
|
10580
10605
|
check("dark", "fg-primary", "bg-selected", 4.5, "#ffffff", D["bg-selected"]);
|
|
10606
|
+
check("light", "fg-primary", "calendar-range-bg", 4.5, INK, L["calendar-range-bg"]);
|
|
10581
10607
|
check("light", "status-progress-fg", "status-progress-bg", 4.5, L["status-progress-fg"], L["status-progress-bg"]);
|
|
10582
10608
|
check("dark", "status-progress-fg", "status-progress-bg", 4.5, D["status-progress-fg"], D["status-progress-bg"]);
|
|
10583
10609
|
check("light", "alert-info-fg", "alert-info-bg", 4.5, L["alert-info-fg"], L["alert-info-bg"]);
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1911,7 +1911,8 @@ var Menu = React9.forwardRef(function Menu2(props, ref) {
|
|
|
1911
1911
|
top = r2.top - above - 4;
|
|
1912
1912
|
} else maxHeight = below2;
|
|
1913
1913
|
}
|
|
1914
|
-
const
|
|
1914
|
+
const endAligned = r2.right - mw;
|
|
1915
|
+
const left = Math.max(8, Math.min(endAligned >= 8 ? endAligned : r2.left, window.innerWidth - mw - 8));
|
|
1915
1916
|
setPos(function(p) {
|
|
1916
1917
|
return p && p.top === top && p.left === left && p.maxHeight === maxHeight ? p : { top, left, maxHeight };
|
|
1917
1918
|
});
|
|
@@ -2010,12 +2011,15 @@ var Menu = React9.forwardRef(function Menu2(props, ref) {
|
|
|
2010
2011
|
});
|
|
2011
2012
|
return out;
|
|
2012
2013
|
}
|
|
2014
|
+
const anyLead = items2.some(function(it) {
|
|
2015
|
+
return !it.separator && (!!it.icon || it.type === "radio" || it.checked !== void 0);
|
|
2016
|
+
});
|
|
2013
2017
|
function renderItem(it, i) {
|
|
2014
2018
|
if (it.separator) return /* @__PURE__ */ React9.createElement("div", { key: "s" + i, role: "separator", className: "aura-menu__sep" });
|
|
2015
2019
|
const isRadio = it.type === "radio";
|
|
2016
2020
|
const isCheck = !isRadio && it.checked !== void 0;
|
|
2017
2021
|
const checkAtEnd = isCheck && !!it.icon && it.checkPlacement !== "start";
|
|
2018
|
-
const lead = isRadio ? /* @__PURE__ */ React9.createElement("span", { className: cx("aura-menu__radio", it.checked && "is-on") }) : isCheck && !checkAtEnd ? /* @__PURE__ */ React9.createElement("span", { className: cx("aura-menu__check", it.checked && "is-on") }, it.checked ? /* @__PURE__ */ React9.createElement(Icon, { name: /* @__PURE__ */ React9.createElement(IconCheck, null), size: 12, strokeWidth: 3 }) : null) : it.icon ? /* @__PURE__ */ React9.createElement(Icon, { name: it.icon }) : /* @__PURE__ */ React9.createElement("span", { className: "aura-menu__blank" });
|
|
2022
|
+
const lead = isRadio ? /* @__PURE__ */ React9.createElement("span", { className: cx("aura-menu__radio", it.checked && "is-on") }) : isCheck && !checkAtEnd ? /* @__PURE__ */ React9.createElement("span", { className: cx("aura-menu__check", it.checked && "is-on") }, it.checked ? /* @__PURE__ */ React9.createElement(Icon, { name: /* @__PURE__ */ React9.createElement(IconCheck, null), size: 12, strokeWidth: 3 }) : null) : it.icon ? /* @__PURE__ */ React9.createElement(Icon, { name: it.icon }) : anyLead ? /* @__PURE__ */ React9.createElement("span", { className: "aura-menu__blank" }) : null;
|
|
2019
2023
|
const body = [
|
|
2020
2024
|
/* @__PURE__ */ React9.createElement(React9.Fragment, { key: "l" }, lead),
|
|
2021
2025
|
/* @__PURE__ */ React9.createElement("span", { key: "t", className: "aura-menu__label" }, it.label),
|
|
@@ -3426,7 +3430,7 @@ var Calendar = React18.forwardRef(function Calendar2(props, ref) {
|
|
|
3426
3430
|
setFocus(addMonths(focusDate, 1));
|
|
3427
3431
|
}
|
|
3428
3432
|
}
|
|
3429
|
-
)), /* @__PURE__ */ React18.createElement("table", { role: "grid", className: "aura-cal__grid", "aria-label": monthTitle }, /* @__PURE__ */ React18.createElement("thead", null, /* @__PURE__ */ React18.createElement("tr", null, weekdayNames.map(function(n3, i) {
|
|
3433
|
+
)), /* @__PURE__ */ React18.createElement("table", { role: "grid", className: "aura-cal__grid", "aria-label": monthTitle, lang: th2 ? "th" : void 0 }, /* @__PURE__ */ React18.createElement("thead", null, /* @__PURE__ */ React18.createElement("tr", null, weekdayNames.map(function(n3, i) {
|
|
3430
3434
|
return /* @__PURE__ */ React18.createElement("th", { key: i, scope: "col", abbr: n3.long }, /* @__PURE__ */ React18.createElement("span", { "aria-hidden": true }, n3.short));
|
|
3431
3435
|
}))), /* @__PURE__ */ React18.createElement(
|
|
3432
3436
|
"tbody",
|
|
@@ -6526,6 +6530,7 @@ var DataTableImpl = React34.forwardRef(function DataTable(props, ref) {
|
|
|
6526
6530
|
if (next === page) return false;
|
|
6527
6531
|
if (!quiet) emit(sort, next);
|
|
6528
6532
|
if (linkPaging) {
|
|
6533
|
+
if (focus) pending.current = { ...focus, page: next, at: Date.now() };
|
|
6529
6534
|
const a = next === page - 1 ? prevLink.current : next === page + 1 ? nextLink.current : null;
|
|
6530
6535
|
if (a) a.click();
|
|
6531
6536
|
else jumpState[1](next);
|
|
@@ -6624,6 +6629,11 @@ var DataTableImpl = React34.forwardRef(function DataTable(props, ref) {
|
|
|
6624
6629
|
React34.useEffect(function() {
|
|
6625
6630
|
const p = pending.current;
|
|
6626
6631
|
if (!p || !gridRef.current) return;
|
|
6632
|
+
if (p.at != null && Date.now() - p.at > 1e4) {
|
|
6633
|
+
pending.current = null;
|
|
6634
|
+
return;
|
|
6635
|
+
}
|
|
6636
|
+
if (p.page != null && p.page !== page) return;
|
|
6627
6637
|
let c = p.c;
|
|
6628
6638
|
if (p.key) {
|
|
6629
6639
|
let at = -1;
|
|
@@ -10056,6 +10066,19 @@ function describeAccept(accept, t) {
|
|
|
10056
10066
|
a = a.trim();
|
|
10057
10067
|
if (a === "image/*") return t.images;
|
|
10058
10068
|
if (a === "application/pdf") return "PDF";
|
|
10069
|
+
const known = {
|
|
10070
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "DOCX",
|
|
10071
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "XLSX",
|
|
10072
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "PPTX",
|
|
10073
|
+
"application/msword": "DOC",
|
|
10074
|
+
"application/vnd.ms-excel": "XLS",
|
|
10075
|
+
"application/vnd.ms-powerpoint": "PPT",
|
|
10076
|
+
"text/plain": "TXT"
|
|
10077
|
+
};
|
|
10078
|
+
if (known[a]) return known[a];
|
|
10079
|
+
const slash = a.indexOf("/");
|
|
10080
|
+
if (slash > 0 && a.slice(slash + 1) !== "*")
|
|
10081
|
+
a = a.slice(slash + 1).replace(/^(?:vnd\.|x-)/, "").replace(/\+xml$/, "");
|
|
10059
10082
|
return a.replace(/^\./, "").toUpperCase();
|
|
10060
10083
|
}).filter(function(x, i, arr) {
|
|
10061
10084
|
return arr.indexOf(x) === i;
|
|
@@ -10464,6 +10487,7 @@ function createTheme(opts) {
|
|
|
10464
10487
|
L["accent-violet"] = L["fg-accent"];
|
|
10465
10488
|
L["focus-ring"] = fit(b[700], lightGrounds.concat([b[50]]), 3, -1);
|
|
10466
10489
|
L["bg-selected"] = b[50];
|
|
10490
|
+
L["calendar-range-bg"] = b[100];
|
|
10467
10491
|
L["status-progress-bg"] = b[100];
|
|
10468
10492
|
L["status-progress-fg"] = fit(b[800], [b[100]], 4.5, -1);
|
|
10469
10493
|
L["alert-info-bg"] = b[50];
|
|
@@ -10503,6 +10527,7 @@ function createTheme(opts) {
|
|
|
10503
10527
|
D["control-checked-bg"] = fit(b[300], darkGrounds, 3, 1);
|
|
10504
10528
|
D["control-checked-fg"] = onFill(D["control-checked-bg"]);
|
|
10505
10529
|
D["nav-active-edge"] = D["control-checked-bg"];
|
|
10530
|
+
D["calendar-range-bg"] = D["bg-selected"];
|
|
10506
10531
|
const shadowLight = INK, shadowDark = D["accent-violet"];
|
|
10507
10532
|
if (o.primary === "brand") {
|
|
10508
10533
|
L["button-primary-bg"] = fit(b[600], [ZINC[0]], 4.5, -1);
|
|
@@ -10560,6 +10585,7 @@ function createTheme(opts) {
|
|
|
10560
10585
|
check("dark", "chart-1", "chart-2 (lightness step)", 1.8, D["chart-1"], CHART_2);
|
|
10561
10586
|
check("light", "fg-primary", "bg-selected", 4.5, INK, L["bg-selected"]);
|
|
10562
10587
|
check("dark", "fg-primary", "bg-selected", 4.5, "#ffffff", D["bg-selected"]);
|
|
10588
|
+
check("light", "fg-primary", "calendar-range-bg", 4.5, INK, L["calendar-range-bg"]);
|
|
10563
10589
|
check("light", "status-progress-fg", "status-progress-bg", 4.5, L["status-progress-fg"], L["status-progress-bg"]);
|
|
10564
10590
|
check("dark", "status-progress-fg", "status-progress-bg", 4.5, D["status-progress-fg"], D["status-progress-bg"]);
|
|
10565
10591
|
check("light", "alert-info-fg", "alert-info-bg", 4.5, L["alert-info-fg"], L["alert-info-bg"]);
|
package/dist/esm/DataTable.js
CHANGED
|
@@ -487,6 +487,7 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
487
487
|
if (next === page) return false;
|
|
488
488
|
if (!quiet) emit(sort, next);
|
|
489
489
|
if (linkPaging) {
|
|
490
|
+
if (focus) pending.current = { ...focus, page: next, at: Date.now() };
|
|
490
491
|
const a = next === page - 1 ? prevLink.current : next === page + 1 ? nextLink.current : null;
|
|
491
492
|
if (a) a.click();
|
|
492
493
|
else jumpState[1](next);
|
|
@@ -585,6 +586,11 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
585
586
|
React.useEffect(function() {
|
|
586
587
|
const p = pending.current;
|
|
587
588
|
if (!p || !gridRef.current) return;
|
|
589
|
+
if (p.at != null && Date.now() - p.at > 1e4) {
|
|
590
|
+
pending.current = null;
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
if (p.page != null && p.page !== page) return;
|
|
588
594
|
let c = p.c;
|
|
589
595
|
if (p.key) {
|
|
590
596
|
let at = -1;
|
package/dist/esm/DatePicker.js
CHANGED
|
@@ -226,7 +226,7 @@ const Calendar = React.forwardRef(function Calendar2(props, ref) {
|
|
|
226
226
|
setFocus(addMonths(focusDate, 1));
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
|
-
)), /* @__PURE__ */ React.createElement("table", { role: "grid", className: "aura-cal__grid", "aria-label": monthTitle }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, weekdayNames.map(function(n, i) {
|
|
229
|
+
)), /* @__PURE__ */ React.createElement("table", { role: "grid", className: "aura-cal__grid", "aria-label": monthTitle, lang: th ? "th" : void 0 }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, weekdayNames.map(function(n, i) {
|
|
230
230
|
return /* @__PURE__ */ React.createElement("th", { key: i, scope: "col", abbr: n.long }, /* @__PURE__ */ React.createElement("span", { "aria-hidden": true }, n.short));
|
|
231
231
|
}))), /* @__PURE__ */ React.createElement(
|
|
232
232
|
"tbody",
|
package/dist/esm/FileUpload.js
CHANGED
|
@@ -26,6 +26,19 @@ function describeAccept(accept, t) {
|
|
|
26
26
|
a = a.trim();
|
|
27
27
|
if (a === "image/*") return t.images;
|
|
28
28
|
if (a === "application/pdf") return "PDF";
|
|
29
|
+
const known = {
|
|
30
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "DOCX",
|
|
31
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "XLSX",
|
|
32
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "PPTX",
|
|
33
|
+
"application/msword": "DOC",
|
|
34
|
+
"application/vnd.ms-excel": "XLS",
|
|
35
|
+
"application/vnd.ms-powerpoint": "PPT",
|
|
36
|
+
"text/plain": "TXT"
|
|
37
|
+
};
|
|
38
|
+
if (known[a]) return known[a];
|
|
39
|
+
const slash = a.indexOf("/");
|
|
40
|
+
if (slash > 0 && a.slice(slash + 1) !== "*")
|
|
41
|
+
a = a.slice(slash + 1).replace(/^(?:vnd\.|x-)/, "").replace(/\+xml$/, "");
|
|
29
42
|
return a.replace(/^\./, "").toUpperCase();
|
|
30
43
|
}).filter(function(x, i, arr) {
|
|
31
44
|
return arr.indexOf(x) === i;
|
package/dist/esm/Menu.js
CHANGED
|
@@ -61,7 +61,8 @@ const Menu = React.forwardRef(function Menu2(props, ref) {
|
|
|
61
61
|
top = r.top - above - 4;
|
|
62
62
|
} else maxHeight = below;
|
|
63
63
|
}
|
|
64
|
-
const
|
|
64
|
+
const endAligned = r.right - mw;
|
|
65
|
+
const left = Math.max(8, Math.min(endAligned >= 8 ? endAligned : r.left, window.innerWidth - mw - 8));
|
|
65
66
|
setPos(function(p) {
|
|
66
67
|
return p && p.top === top && p.left === left && p.maxHeight === maxHeight ? p : { top, left, maxHeight };
|
|
67
68
|
});
|
|
@@ -160,12 +161,15 @@ const Menu = React.forwardRef(function Menu2(props, ref) {
|
|
|
160
161
|
});
|
|
161
162
|
return out;
|
|
162
163
|
}
|
|
164
|
+
const anyLead = items.some(function(it) {
|
|
165
|
+
return !it.separator && (!!it.icon || it.type === "radio" || it.checked !== void 0);
|
|
166
|
+
});
|
|
163
167
|
function renderItem(it, i) {
|
|
164
168
|
if (it.separator) return /* @__PURE__ */ React.createElement("div", { key: "s" + i, role: "separator", className: "aura-menu__sep" });
|
|
165
169
|
const isRadio = it.type === "radio";
|
|
166
170
|
const isCheck = !isRadio && it.checked !== void 0;
|
|
167
171
|
const checkAtEnd = isCheck && !!it.icon && it.checkPlacement !== "start";
|
|
168
|
-
const lead = isRadio ? /* @__PURE__ */ React.createElement("span", { className: cx("aura-menu__radio", it.checked && "is-on") }) : isCheck && !checkAtEnd ? /* @__PURE__ */ React.createElement("span", { className: cx("aura-menu__check", it.checked && "is-on") }, it.checked ? /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconCheck, null), size: 12, strokeWidth: 3 }) : null) : it.icon ? /* @__PURE__ */ React.createElement(Icon, { name: it.icon }) : /* @__PURE__ */ React.createElement("span", { className: "aura-menu__blank" });
|
|
172
|
+
const lead = isRadio ? /* @__PURE__ */ React.createElement("span", { className: cx("aura-menu__radio", it.checked && "is-on") }) : isCheck && !checkAtEnd ? /* @__PURE__ */ React.createElement("span", { className: cx("aura-menu__check", it.checked && "is-on") }, it.checked ? /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconCheck, null), size: 12, strokeWidth: 3 }) : null) : it.icon ? /* @__PURE__ */ React.createElement(Icon, { name: it.icon }) : anyLead ? /* @__PURE__ */ React.createElement("span", { className: "aura-menu__blank" }) : null;
|
|
169
173
|
const body = [
|
|
170
174
|
/* @__PURE__ */ React.createElement(React.Fragment, { key: "l" }, lead),
|
|
171
175
|
/* @__PURE__ */ React.createElement("span", { key: "t", className: "aura-menu__label" }, it.label),
|
package/dist/esm/theme.js
CHANGED
|
@@ -131,6 +131,7 @@ function createTheme(opts) {
|
|
|
131
131
|
L["accent-violet"] = L["fg-accent"];
|
|
132
132
|
L["focus-ring"] = fit(b[700], lightGrounds.concat([b[50]]), 3, -1);
|
|
133
133
|
L["bg-selected"] = b[50];
|
|
134
|
+
L["calendar-range-bg"] = b[100];
|
|
134
135
|
L["status-progress-bg"] = b[100];
|
|
135
136
|
L["status-progress-fg"] = fit(b[800], [b[100]], 4.5, -1);
|
|
136
137
|
L["alert-info-bg"] = b[50];
|
|
@@ -170,6 +171,7 @@ function createTheme(opts) {
|
|
|
170
171
|
D["control-checked-bg"] = fit(b[300], darkGrounds, 3, 1);
|
|
171
172
|
D["control-checked-fg"] = onFill(D["control-checked-bg"]);
|
|
172
173
|
D["nav-active-edge"] = D["control-checked-bg"];
|
|
174
|
+
D["calendar-range-bg"] = D["bg-selected"];
|
|
173
175
|
const shadowLight = INK, shadowDark = D["accent-violet"];
|
|
174
176
|
if (o.primary === "brand") {
|
|
175
177
|
L["button-primary-bg"] = fit(b[600], [ZINC[0]], 4.5, -1);
|
|
@@ -227,6 +229,7 @@ function createTheme(opts) {
|
|
|
227
229
|
check("dark", "chart-1", "chart-2 (lightness step)", 1.8, D["chart-1"], CHART_2);
|
|
228
230
|
check("light", "fg-primary", "bg-selected", 4.5, INK, L["bg-selected"]);
|
|
229
231
|
check("dark", "fg-primary", "bg-selected", 4.5, "#ffffff", D["bg-selected"]);
|
|
232
|
+
check("light", "fg-primary", "calendar-range-bg", 4.5, INK, L["calendar-range-bg"]);
|
|
230
233
|
check("light", "status-progress-fg", "status-progress-bg", 4.5, L["status-progress-fg"], L["status-progress-bg"]);
|
|
231
234
|
check("dark", "status-progress-fg", "status-progress-bg", 4.5, D["status-progress-fg"], D["status-progress-bg"]);
|
|
232
235
|
check("light", "alert-info-fg", "alert-info-bg", 4.5, L["alert-info-fg"], L["alert-info-bg"]);
|
package/dist/server/index.cjs
CHANGED
|
@@ -780,6 +780,7 @@ function createTheme(opts) {
|
|
|
780
780
|
L["accent-violet"] = L["fg-accent"];
|
|
781
781
|
L["focus-ring"] = fit(b[700], lightGrounds.concat([b[50]]), 3, -1);
|
|
782
782
|
L["bg-selected"] = b[50];
|
|
783
|
+
L["calendar-range-bg"] = b[100];
|
|
783
784
|
L["status-progress-bg"] = b[100];
|
|
784
785
|
L["status-progress-fg"] = fit(b[800], [b[100]], 4.5, -1);
|
|
785
786
|
L["alert-info-bg"] = b[50];
|
|
@@ -819,6 +820,7 @@ function createTheme(opts) {
|
|
|
819
820
|
D["control-checked-bg"] = fit(b[300], darkGrounds, 3, 1);
|
|
820
821
|
D["control-checked-fg"] = onFill(D["control-checked-bg"]);
|
|
821
822
|
D["nav-active-edge"] = D["control-checked-bg"];
|
|
823
|
+
D["calendar-range-bg"] = D["bg-selected"];
|
|
822
824
|
const shadowLight = INK, shadowDark = D["accent-violet"];
|
|
823
825
|
if (o.primary === "brand") {
|
|
824
826
|
L["button-primary-bg"] = fit(b[600], [ZINC[0]], 4.5, -1);
|
|
@@ -876,6 +878,7 @@ function createTheme(opts) {
|
|
|
876
878
|
check("dark", "chart-1", "chart-2 (lightness step)", 1.8, D["chart-1"], CHART_2);
|
|
877
879
|
check("light", "fg-primary", "bg-selected", 4.5, INK, L["bg-selected"]);
|
|
878
880
|
check("dark", "fg-primary", "bg-selected", 4.5, "#ffffff", D["bg-selected"]);
|
|
881
|
+
check("light", "fg-primary", "calendar-range-bg", 4.5, INK, L["calendar-range-bg"]);
|
|
879
882
|
check("light", "status-progress-fg", "status-progress-bg", 4.5, L["status-progress-fg"], L["status-progress-bg"]);
|
|
880
883
|
check("dark", "status-progress-fg", "status-progress-bg", 4.5, D["status-progress-fg"], D["status-progress-bg"]);
|
|
881
884
|
check("light", "alert-info-fg", "alert-info-bg", 4.5, L["alert-info-fg"], L["alert-info-bg"]);
|
package/dist/server/index.js
CHANGED
|
@@ -713,6 +713,7 @@ function createTheme(opts) {
|
|
|
713
713
|
L["accent-violet"] = L["fg-accent"];
|
|
714
714
|
L["focus-ring"] = fit(b[700], lightGrounds.concat([b[50]]), 3, -1);
|
|
715
715
|
L["bg-selected"] = b[50];
|
|
716
|
+
L["calendar-range-bg"] = b[100];
|
|
716
717
|
L["status-progress-bg"] = b[100];
|
|
717
718
|
L["status-progress-fg"] = fit(b[800], [b[100]], 4.5, -1);
|
|
718
719
|
L["alert-info-bg"] = b[50];
|
|
@@ -752,6 +753,7 @@ function createTheme(opts) {
|
|
|
752
753
|
D["control-checked-bg"] = fit(b[300], darkGrounds, 3, 1);
|
|
753
754
|
D["control-checked-fg"] = onFill(D["control-checked-bg"]);
|
|
754
755
|
D["nav-active-edge"] = D["control-checked-bg"];
|
|
756
|
+
D["calendar-range-bg"] = D["bg-selected"];
|
|
755
757
|
const shadowLight = INK, shadowDark = D["accent-violet"];
|
|
756
758
|
if (o.primary === "brand") {
|
|
757
759
|
L["button-primary-bg"] = fit(b[600], [ZINC[0]], 4.5, -1);
|
|
@@ -809,6 +811,7 @@ function createTheme(opts) {
|
|
|
809
811
|
check("dark", "chart-1", "chart-2 (lightness step)", 1.8, D["chart-1"], CHART_2);
|
|
810
812
|
check("light", "fg-primary", "bg-selected", 4.5, INK, L["bg-selected"]);
|
|
811
813
|
check("dark", "fg-primary", "bg-selected", 4.5, "#ffffff", D["bg-selected"]);
|
|
814
|
+
check("light", "fg-primary", "calendar-range-bg", 4.5, INK, L["calendar-range-bg"]);
|
|
812
815
|
check("light", "status-progress-fg", "status-progress-bg", 4.5, L["status-progress-fg"], L["status-progress-bg"]);
|
|
813
816
|
check("dark", "status-progress-fg", "status-progress-bg", 4.5, D["status-progress-fg"], D["status-progress-bg"]);
|
|
814
817
|
check("light", "alert-info-fg", "alert-info-bg", 4.5, L["alert-info-fg"], L["alert-info-bg"]);
|
package/dist/styles.css
CHANGED
|
@@ -50,18 +50,28 @@ button.aura-btn--secondary[aria-disabled='true']:hover, button.aura-btn--ghost[a
|
|
|
50
50
|
button.aura-btn--danger-secondary[aria-disabled='true']:hover { background: transparent; }
|
|
51
51
|
button.aura-btn--danger[aria-disabled='true']:hover { background: var(--aura-button-danger-bg); }
|
|
52
52
|
button.aura-btn--creative[aria-disabled='true']:hover { box-shadow: var(--aura-shadow-creative); transform: none; }
|
|
53
|
-
/* 5.30: a disabled
|
|
54
|
-
*
|
|
55
|
-
.aura-btn
|
|
56
|
-
.aura-btn
|
|
57
|
-
opacity: 1; background: var(--aura-button-disabled-bg); color: var(--aura-button-disabled-fg); border-color:
|
|
58
|
-
}
|
|
53
|
+
/* 5.30: a disabled button is not a faded copy of itself (faded ink read as a separate grey button, faded red as pink).
|
|
54
|
+
* 5.79: one look for every variant — see below. */
|
|
55
|
+
.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
56
|
+
.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)):hover {
|
|
57
|
+
opacity: 1; background: var(--aura-button-disabled-bg); color: var(--aura-button-disabled-fg); border-color: var(--aura-button-disabled-border); box-shadow: none;
|
|
58
|
+
}
|
|
59
|
+
/* …a variant without a border of its own (primary, danger) draws the same edge inside, so none is edgeless */
|
|
60
|
+
.aura-btn.aura-btn:is(.aura-btn--primary, .aura-btn--danger):is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
61
|
+
.aura-btn.aura-btn:is(.aura-btn--primary, .aura-btn--danger):is(:disabled, [aria-disabled='true']:not(.is-loading)):hover {
|
|
62
|
+
box-shadow: inset 0 0 0 1px var(--aura-button-disabled-border);
|
|
63
|
+
}
|
|
64
|
+
/* 5.79 (visual audit 6): one disabled look for every variant — a faint fill, a faint edge, the tertiary label — so a
|
|
65
|
+
* disabled primary doesn't read as a To Do pill and a disabled outline button isn't a crisp white one in dark. A ghost
|
|
66
|
+
* button stays without fill or edge. */
|
|
67
|
+
.aura-btn.aura-btn.aura-btn--ghost:is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
68
|
+
.aura-btn.aura-btn.aura-btn--ghost:is(:disabled, [aria-disabled='true']:not(.is-loading)):hover { background: transparent; border-color: transparent; box-shadow: none; }
|
|
59
69
|
/* Forced colours drop the fills: filled buttons get a 1px edge (as outline buttons have), and a disabled or gated one
|
|
60
70
|
* (still focusable) shows GrayText and keeps the fade, without changing size. */
|
|
61
71
|
@media (forced-colors: active) {
|
|
62
72
|
.aura-btn:is(.aura-btn--primary, .aura-btn--danger) { border: 1px solid ButtonText; }
|
|
63
|
-
.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
64
|
-
.aura-btn.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)):hover { color: GrayText; border-color: GrayText; opacity: var(--aura-disabled-opacity); }
|
|
73
|
+
.aura-btn.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
74
|
+
.aura-btn.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)):hover { color: GrayText; border-color: GrayText; opacity: var(--aura-disabled-opacity); } /* 5.79: one class more, over the ghost rule */
|
|
65
75
|
}
|
|
66
76
|
.aura-btn.is-loading:active { transform: none; }
|
|
67
77
|
|
|
@@ -295,7 +305,7 @@ a.aura-table__sort { text-decoration: none; }
|
|
|
295
305
|
position: fixed; z-index: var(--aura-z-menu); min-width: 200px; padding: var(--aura-space-1); overflow-y: auto; overscroll-behavior: contain;
|
|
296
306
|
background: var(--aura-bg-surface); color: var(--aura-fg-primary);
|
|
297
307
|
border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-md);
|
|
298
|
-
box-shadow: var(--aura-shadow-
|
|
308
|
+
box-shadow: var(--aura-shadow-overlay); /* 5.79 (visual audit 18): lifted as Popover and the list boxes are; its light edge alone was faint */
|
|
299
309
|
font-family: var(--font-sans); font-size: max(13px, .8125rem);
|
|
300
310
|
}
|
|
301
311
|
.aura-menu__item {
|
|
@@ -583,7 +593,7 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
583
593
|
* Field). */
|
|
584
594
|
.aura-field:not(.is-disabled) .aura-input:has(> .aura-input__control[aria-invalid="true"]:not(:disabled)),
|
|
585
595
|
.aura-field:not(.is-disabled) .aura-textarea[aria-invalid="true"]:not(:disabled) { border-color: var(--aura-border-danger); }
|
|
586
|
-
.aura-field.is-disabled .aura-input { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-border
|
|
596
|
+
.aura-field.is-disabled .aura-input { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-input-disabled-border); }
|
|
587
597
|
.aura-field.is-disabled .aura-input__control { cursor: not-allowed; }
|
|
588
598
|
/* A read-only text field. Only an input: `:read-only` also matches any element that isn't editable — a
|
|
589
599
|
* Select's trigger <button> — which painted every custom Select with the disabled ground (5.16.1, Chamber-OS 109). */
|
|
@@ -593,13 +603,18 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
593
603
|
|
|
594
604
|
.aura-textarea { display: block; padding: 10px var(--aura-space-3); min-height: 96px; line-height: 1.6; resize: vertical; outline: none; }
|
|
595
605
|
.aura-textarea:focus { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: 1px; border-color: var(--aura-border-strong); }
|
|
596
|
-
.aura-field.is-disabled .aura-textarea { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-border
|
|
606
|
+
.aura-field.is-disabled .aura-textarea { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-input-disabled-border); }
|
|
597
607
|
|
|
598
608
|
.aura-select .aura-input__control { padding-right: calc(var(--aura-space-3) + var(--aura-icon-sm) + var(--aura-space-2)); cursor: pointer; }
|
|
599
609
|
.aura-select__chevron { position: absolute; right: var(--aura-space-3); color: var(--aura-fg-secondary); pointer-events: none; }
|
|
600
610
|
.aura-select select:invalid, .aura-select select:has(option[value=""]:checked) { color: var(--aura-fg-tertiary); }
|
|
601
611
|
/* 5.3: the field is a button over an invisible <select> (forms, refs, events); the list is AURA's, like Combobox. */
|
|
602
612
|
.aura-select option { color: var(--aura-fg-primary); background: var(--aura-bg-input); }
|
|
613
|
+
/* 5.79 (visual audit 15): a list box (multiple, or size > 1) shows its rows — as tall as they need, no chevron — instead
|
|
614
|
+
* of being squeezed into a one-line field with its third option cut in half. */
|
|
615
|
+
.aura-select .aura-input__control:is([multiple], [size]:not([size='0'], [size='1'])) { height: auto; padding: var(--aura-space-1) var(--aura-space-2); overflow-y: auto; cursor: default; }
|
|
616
|
+
.aura-select:has(> .aura-input__control:is([multiple], [size]:not([size='0'], [size='1']))) .aura-select__chevron { display: none; }
|
|
617
|
+
.aura-select .aura-input__control:is([multiple], [size]:not([size='0'], [size='1'])) option { padding: var(--aura-space-1) var(--aura-space-2); border-radius: var(--aura-radius-xs); }
|
|
603
618
|
.aura-select--custom { position: relative; }
|
|
604
619
|
.aura-select__native { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; opacity: 0; pointer-events: none; appearance: none; }
|
|
605
620
|
.aura-select__trigger { display: flex; align-items: center; text-align: start; background: none; border: 0; color: inherit; font: inherit; width: 100%; min-width: 0; }
|
|
@@ -659,7 +674,7 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
659
674
|
/* 5.19 (Chamber-OS 113): a read-only switch keeps its colours (a locked "on" reads as on at full contrast) and stays
|
|
660
675
|
* focusable; only the pointer says it won't change. The row's icon (a lock) sits at its end, like a field's icon. */
|
|
661
676
|
.aura-switch-row.is-readonly, .aura-switch-row.is-readonly .aura-switch, .aura-switch-row.is-readonly .aura-choice__label { cursor: default; }
|
|
662
|
-
.aura-switch-row__icon { flex: none; margin-inline-start:
|
|
677
|
+
.aura-switch-row__icon { flex: none; margin-inline-start: calc(-1 * var(--aura-space-1)); margin-top: 2px; /* 5.79 (visual audit 17): beside the label it belongs to, 8px after it, not at the row's far end */ width: var(--aura-icon-sm); height: var(--aura-icon-sm); color: var(--aura-fg-secondary); }
|
|
663
678
|
|
|
664
679
|
/* ---------- Alerts & toasts ---------- */
|
|
665
680
|
.aura-alert {
|
|
@@ -1051,8 +1066,8 @@ a.aura-tab { text-decoration: none; }
|
|
|
1051
1066
|
.aura-combo__option.is-selected { font-weight: 500; }
|
|
1052
1067
|
.aura-combo__option.is-disabled { opacity: var(--aura-disabled-opacity); cursor: default; }
|
|
1053
1068
|
.aura-combo__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
1054
|
-
.aura-combo__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1055
|
-
.aura-combo__desc { font-size: max(12px, .75rem); line-height: 1.
|
|
1069
|
+
.aura-combo__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: max(20px, 1.25rem); }
|
|
1070
|
+
.aura-combo__desc { font-size: max(12px, .75rem); line-height: max(18px, 1.125rem); color: var(--aura-fg-secondary); } /* 5.79: fixed line heights, so a Thai row and an English row are spaced alike (normal follows each font) */
|
|
1056
1071
|
/* Same specificity as `.aura-combo__option > .aura-icon` above and later in the file, so it wins by order (4.18). */
|
|
1057
1072
|
.aura-combo__option > .aura-combo__check { color: var(--aura-fg-accent); }
|
|
1058
1073
|
/* 5.16 (Chamber-OS 105): option groups under a heading. */
|
|
@@ -1095,9 +1110,9 @@ a.aura-tab { text-decoration: none; }
|
|
|
1095
1110
|
.aura-cal__day.is-selected { background: var(--aura-control-checked-bg); color: var(--aura-control-checked-fg); box-shadow: none; }
|
|
1096
1111
|
.aura-cal__day:disabled, .aura-cal__day[aria-disabled='true'] { opacity: var(--aura-disabled-opacity); cursor: not-allowed; background: transparent; text-decoration: line-through; }
|
|
1097
1112
|
.aura-cal__day:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: 1px; }
|
|
1098
|
-
.aura-cal__grid td.is-in-range { background: var(--aura-bg
|
|
1099
|
-
.aura-cal__grid td.is-range-start { background: linear-gradient(to right, transparent 50%, var(--aura-bg
|
|
1100
|
-
.aura-cal__grid td.is-range-end { background: linear-gradient(to left, transparent 50%, var(--aura-bg
|
|
1113
|
+
.aura-cal__grid td.is-in-range { background: var(--aura-calendar-range-bg); } /* 5.79 (visual audit 19) */
|
|
1114
|
+
.aura-cal__grid td.is-range-start { background: linear-gradient(to right, transparent 50%, var(--aura-calendar-range-bg) 50%); }
|
|
1115
|
+
.aura-cal__grid td.is-range-end { background: linear-gradient(to left, transparent 50%, var(--aura-calendar-range-bg) 50%); }
|
|
1101
1116
|
.aura-cal__grid td.is-range-start.is-range-end { background: none; }
|
|
1102
1117
|
.aura-cal__years { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--aura-space-1); }
|
|
1103
1118
|
.aura-cal__year {
|
|
@@ -1652,7 +1667,7 @@ a.aura-upload__name:focus-visible { outline: var(--aura-focus-ring-width) solid
|
|
|
1652
1667
|
.aura-badge--success { background: var(--aura-alert-success-bg); color: var(--aura-alert-success-fg); }
|
|
1653
1668
|
.aura-badge--warning { background: var(--aura-alert-warning-bg); color: var(--aura-alert-warning-fg); }
|
|
1654
1669
|
.aura-badge--danger { background: var(--aura-alert-danger-bg); color: var(--aura-alert-danger-fg); }
|
|
1655
|
-
.aura-badge.is-outline { background: transparent; border-color: currentColor; }
|
|
1670
|
+
.aura-badge.is-outline { background: transparent; border-color: currentColor; border-color: color-mix(in srgb, currentColor 45%, transparent); } /* 5.79 (visual audit 19): a quieter edge, so an outline badge doesn't read as a secondary button */
|
|
1656
1671
|
.aura-badge--neutral.is-outline { border-color: var(--aura-border-control); }
|
|
1657
1672
|
.aura-badge.is-solid { background: var(--aura-button-primary-bg); color: var(--aura-button-primary-fg); }
|
|
1658
1673
|
.aura-badge--danger.is-solid { background: var(--aura-status-blocked-solid-bg); color: var(--aura-status-blocked-solid-fg); }
|
|
@@ -1791,6 +1806,7 @@ a.aura-upload__name:focus-visible { outline: var(--aura-focus-ring-width) solid
|
|
|
1791
1806
|
.aura-combo__chips { display: contents; }
|
|
1792
1807
|
.aura-combo__chip {
|
|
1793
1808
|
display: inline-flex; align-items: center; gap: 2px; max-width: 100%; height: 28px; box-sizing: border-box;
|
|
1809
|
+
flex: none; /* 5.79 (visual audit 16): a chip keeps its label and goes to the next line, not shrunk to "V.." */
|
|
1794
1810
|
padding: 0 2px 0 var(--aura-space-2); border-radius: var(--aura-radius-full);
|
|
1795
1811
|
background: var(--aura-bg-selected); color: var(--aura-fg-primary); font-size: max(13px, .8125rem); font-weight: 500;
|
|
1796
1812
|
}
|
|
@@ -2137,6 +2153,11 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2137
2153
|
.aura-filterbar--fill .aura-filterbar__controls > .aura-filterselect .aura-filterselect__chevron { margin-inline-start: auto; }
|
|
2138
2154
|
/* Compact filters sit closer together than full fields. */
|
|
2139
2155
|
.aura-filterbar__controls:has(> .aura-filterselect) { gap: var(--aura-space-2); }
|
|
2156
|
+
/* 5.80: on a phone 6px, so three filters and a Tag keep one 375px row with either font source — the self-hosted
|
|
2157
|
+
* Inter (aura-fonts.local.css) measured 2.3px over at 8px. */
|
|
2158
|
+
@media (max-width: 639.98px) {
|
|
2159
|
+
.aura-filterbar__controls:has(> .aura-filterselect) { gap: 6px; }
|
|
2160
|
+
}
|
|
2140
2161
|
/* 5.42 (Chamber-OS 146): collapseBelow — below the breakpoint the controls fold into a "Filters" sheet; the button
|
|
2141
2162
|
* shares a row with the search, at its end, as tall as the search (the count and actions wrap below). From the
|
|
2142
2163
|
* breakpoint up the search and the hidden button sit in a display: contents box, so the bar lays out as before. */
|
|
@@ -2193,7 +2214,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2193
2214
|
.aura-filterselect__face:focus-visible { outline-style: solid; }
|
|
2194
2215
|
/* Before hydration: the real <select>, invisible, over the face (16px so iOS doesn't zoom when it opens). */
|
|
2195
2216
|
.aura-filterselect__native { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; opacity: 0; font-size: max(16px, 1rem); cursor: pointer; appearance: none; }
|
|
2196
|
-
.aura-filterselect.is-disabled .aura-filterselect__face { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-border
|
|
2217
|
+
.aura-filterselect.is-disabled .aura-filterselect__face { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-input-disabled-border); cursor: not-allowed; }
|
|
2197
2218
|
.aura-filterselect.is-disabled .aura-filterselect__native { cursor: not-allowed; }
|
|
2198
2219
|
/* 5.38 (Chamber-OS 140): touchHeight on FilterBar (its search and field-height controls) or on one FilterSelect —
|
|
2199
2220
|
* 44px below 640px or on a coarse pointer (is-touch), or always. */
|
|
@@ -2393,6 +2414,25 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2393
2414
|
:root:has(.aura-actionbar--edge:not(.is-idle)) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-actionbar-space)); }
|
|
2394
2415
|
:root:has(.aura-actionbar--edge:not(.is-idle)):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-actionbar-space); }
|
|
2395
2416
|
}
|
|
2417
|
+
/* 5.79 (5.78 carry-over): where actionsFullWidthBelow reaches wider than actionsBarBelow, the bar isn't pinned between
|
|
2418
|
+
* the two breakpoints and its buttons sit in the same full-width row — every button there is radius-md, not some. */
|
|
2419
|
+
@media (min-width: 640px) and (max-width: 767.98px) {
|
|
2420
|
+
.aura-page-header--actions-full-below-md.aura-page-header--actions-bar-below-sm > .aura-page-header__actions .aura-btn:not(.aura-icon-btn) { border-radius: var(--aura-radius-md); }
|
|
2421
|
+
}
|
|
2422
|
+
@media (min-width: 640px) and (max-width: 1023.98px) {
|
|
2423
|
+
.aura-page-header--actions-full-below-lg.aura-page-header--actions-bar-below-sm > .aura-page-header__actions .aura-btn:not(.aura-icon-btn) { border-radius: var(--aura-radius-md); }
|
|
2424
|
+
}
|
|
2425
|
+
@media (min-width: 768px) and (max-width: 1023.98px) {
|
|
2426
|
+
.aura-page-header--actions-full-below-lg.aura-page-header--actions-bar-below-md > .aura-page-header__actions .aura-btn:not(.aura-icon-btn) { border-radius: var(--aura-radius-md); }
|
|
2427
|
+
}
|
|
2428
|
+
/* 5.79 (visual audit 10): in an AppShell on a desktop the edge strip starts where the content does — after the
|
|
2429
|
+
* sidebar (its rail width when collapsed; the right edge in RTL) — and its contents line up with the content's 32px
|
|
2430
|
+
* padding, instead of running under the sidebar. Outside an AppShell it keeps the screen's full width. */
|
|
2431
|
+
@media (min-width: 1024px) and (min-height: 30.00125rem) {
|
|
2432
|
+
.aura-shell:has(> .aura-shell__nav) .aura-actionbar--edge:not(.is-idle) { inset-inline-start: var(--aura-sidenav-width); }
|
|
2433
|
+
.aura-shell:has(> .aura-shell__nav .aura-nav--collapsed) .aura-actionbar--edge:not(.is-idle) { inset-inline-start: var(--aura-sidenav-rail-width); }
|
|
2434
|
+
.aura-shell:not(:has(.aura-shell__content.is-flush)) .aura-actionbar--edge:not(.is-idle) > .aura-actionbar__inner { padding-inline: var(--aura-space-8); } /* not with contentPadding={false} */
|
|
2435
|
+
}
|
|
2396
2436
|
/* 5.78 (visual audit 9): one rule for the bottom strips on a phone, as PageHeader's (5.48) — the status on its own row
|
|
2397
2437
|
* at the top, the actions sharing the row under it (an IconButton keeps its square; labels too long to share take a row
|
|
2398
2438
|
* each), 16px both sides as the page. edgeBelow="md" follows it up to 768px, as PageHeader's md strip. */
|
|
@@ -2753,6 +2793,10 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2753
2793
|
* 1.6 line, so a loading card (its bars follow 1lh) is as tall as one with Thai text. */
|
|
2754
2794
|
.aura-field__label:lang(th), .aura-field__hint:lang(th), .aura-field__error:lang(th), .aura-field__addon:lang(th) { line-height: 1.6; }
|
|
2755
2795
|
.aura-choice__desc:lang(th), .aura-check__desc:lang(th) { font-size: max(13px, .8125rem); line-height: 1.6; }
|
|
2796
|
+
/* 5.79 (visual audit, Thai): the calendar's weekday row in Thai (อา จ อ …) at 13px — 12px was the hardest text on the
|
|
2797
|
+
* page to read; the grid carries lang="th" with a Thai locale. Two-line Thai nav labels get room between lines. */
|
|
2798
|
+
.aura-cal__grid:lang(th) th { font-size: max(13px, .8125rem); }
|
|
2799
|
+
.aura-nav__label:lang(th) { line-height: 1.5; }
|
|
2756
2800
|
.aura-tbl__row > .aura-tbl__td[data-label]:lang(th)::before, .aura-table__td[data-label]:lang(th)::before { font-family: var(--font-sans); font-size: max(12px, .75rem); line-height: max(18px, 1.125rem); }
|
|
2757
2801
|
.aura-table--stacked .aura-table__td[data-label]:lang(th) { line-height: 1.6; }
|
|
2758
2802
|
|
package/dist/styles.layer.css
CHANGED
|
@@ -52,18 +52,28 @@ button.aura-btn--secondary[aria-disabled='true']:hover, button.aura-btn--ghost[a
|
|
|
52
52
|
button.aura-btn--danger-secondary[aria-disabled='true']:hover { background: transparent; }
|
|
53
53
|
button.aura-btn--danger[aria-disabled='true']:hover { background: var(--aura-button-danger-bg); }
|
|
54
54
|
button.aura-btn--creative[aria-disabled='true']:hover { box-shadow: var(--aura-shadow-creative); transform: none; }
|
|
55
|
-
/* 5.30: a disabled
|
|
56
|
-
*
|
|
57
|
-
.aura-btn
|
|
58
|
-
.aura-btn
|
|
59
|
-
opacity: 1; background: var(--aura-button-disabled-bg); color: var(--aura-button-disabled-fg); border-color:
|
|
60
|
-
}
|
|
55
|
+
/* 5.30: a disabled button is not a faded copy of itself (faded ink read as a separate grey button, faded red as pink).
|
|
56
|
+
* 5.79: one look for every variant — see below. */
|
|
57
|
+
.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
58
|
+
.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)):hover {
|
|
59
|
+
opacity: 1; background: var(--aura-button-disabled-bg); color: var(--aura-button-disabled-fg); border-color: var(--aura-button-disabled-border); box-shadow: none;
|
|
60
|
+
}
|
|
61
|
+
/* …a variant without a border of its own (primary, danger) draws the same edge inside, so none is edgeless */
|
|
62
|
+
.aura-btn.aura-btn:is(.aura-btn--primary, .aura-btn--danger):is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
63
|
+
.aura-btn.aura-btn:is(.aura-btn--primary, .aura-btn--danger):is(:disabled, [aria-disabled='true']:not(.is-loading)):hover {
|
|
64
|
+
box-shadow: inset 0 0 0 1px var(--aura-button-disabled-border);
|
|
65
|
+
}
|
|
66
|
+
/* 5.79 (visual audit 6): one disabled look for every variant — a faint fill, a faint edge, the tertiary label — so a
|
|
67
|
+
* disabled primary doesn't read as a To Do pill and a disabled outline button isn't a crisp white one in dark. A ghost
|
|
68
|
+
* button stays without fill or edge. */
|
|
69
|
+
.aura-btn.aura-btn.aura-btn--ghost:is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
70
|
+
.aura-btn.aura-btn.aura-btn--ghost:is(:disabled, [aria-disabled='true']:not(.is-loading)):hover { background: transparent; border-color: transparent; box-shadow: none; }
|
|
61
71
|
/* Forced colours drop the fills: filled buttons get a 1px edge (as outline buttons have), and a disabled or gated one
|
|
62
72
|
* (still focusable) shows GrayText and keeps the fade, without changing size. */
|
|
63
73
|
@media (forced-colors: active) {
|
|
64
74
|
.aura-btn:is(.aura-btn--primary, .aura-btn--danger) { border: 1px solid ButtonText; }
|
|
65
|
-
.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
66
|
-
.aura-btn.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)):hover { color: GrayText; border-color: GrayText; opacity: var(--aura-disabled-opacity); }
|
|
75
|
+
.aura-btn.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)),
|
|
76
|
+
.aura-btn.aura-btn.aura-btn:is(:disabled, [aria-disabled='true']:not(.is-loading)):hover { color: GrayText; border-color: GrayText; opacity: var(--aura-disabled-opacity); } /* 5.79: one class more, over the ghost rule */
|
|
67
77
|
}
|
|
68
78
|
.aura-btn.is-loading:active { transform: none; }
|
|
69
79
|
|
|
@@ -297,7 +307,7 @@ a.aura-table__sort { text-decoration: none; }
|
|
|
297
307
|
position: fixed; z-index: var(--aura-z-menu); min-width: 200px; padding: var(--aura-space-1); overflow-y: auto; overscroll-behavior: contain;
|
|
298
308
|
background: var(--aura-bg-surface); color: var(--aura-fg-primary);
|
|
299
309
|
border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-md);
|
|
300
|
-
box-shadow: var(--aura-shadow-
|
|
310
|
+
box-shadow: var(--aura-shadow-overlay); /* 5.79 (visual audit 18): lifted as Popover and the list boxes are; its light edge alone was faint */
|
|
301
311
|
font-family: var(--font-sans); font-size: max(13px, .8125rem);
|
|
302
312
|
}
|
|
303
313
|
.aura-menu__item {
|
|
@@ -585,7 +595,7 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
585
595
|
* Field). */
|
|
586
596
|
.aura-field:not(.is-disabled) .aura-input:has(> .aura-input__control[aria-invalid="true"]:not(:disabled)),
|
|
587
597
|
.aura-field:not(.is-disabled) .aura-textarea[aria-invalid="true"]:not(:disabled) { border-color: var(--aura-border-danger); }
|
|
588
|
-
.aura-field.is-disabled .aura-input { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-border
|
|
598
|
+
.aura-field.is-disabled .aura-input { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-input-disabled-border); }
|
|
589
599
|
.aura-field.is-disabled .aura-input__control { cursor: not-allowed; }
|
|
590
600
|
/* A read-only text field. Only an input: `:read-only` also matches any element that isn't editable — a
|
|
591
601
|
* Select's trigger <button> — which painted every custom Select with the disabled ground (5.16.1, Chamber-OS 109). */
|
|
@@ -595,13 +605,18 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
595
605
|
|
|
596
606
|
.aura-textarea { display: block; padding: 10px var(--aura-space-3); min-height: 96px; line-height: 1.6; resize: vertical; outline: none; }
|
|
597
607
|
.aura-textarea:focus { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: 1px; border-color: var(--aura-border-strong); }
|
|
598
|
-
.aura-field.is-disabled .aura-textarea { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-border
|
|
608
|
+
.aura-field.is-disabled .aura-textarea { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-input-disabled-border); }
|
|
599
609
|
|
|
600
610
|
.aura-select .aura-input__control { padding-right: calc(var(--aura-space-3) + var(--aura-icon-sm) + var(--aura-space-2)); cursor: pointer; }
|
|
601
611
|
.aura-select__chevron { position: absolute; right: var(--aura-space-3); color: var(--aura-fg-secondary); pointer-events: none; }
|
|
602
612
|
.aura-select select:invalid, .aura-select select:has(option[value=""]:checked) { color: var(--aura-fg-tertiary); }
|
|
603
613
|
/* 5.3: the field is a button over an invisible <select> (forms, refs, events); the list is AURA's, like Combobox. */
|
|
604
614
|
.aura-select option { color: var(--aura-fg-primary); background: var(--aura-bg-input); }
|
|
615
|
+
/* 5.79 (visual audit 15): a list box (multiple, or size > 1) shows its rows — as tall as they need, no chevron — instead
|
|
616
|
+
* of being squeezed into a one-line field with its third option cut in half. */
|
|
617
|
+
.aura-select .aura-input__control:is([multiple], [size]:not([size='0'], [size='1'])) { height: auto; padding: var(--aura-space-1) var(--aura-space-2); overflow-y: auto; cursor: default; }
|
|
618
|
+
.aura-select:has(> .aura-input__control:is([multiple], [size]:not([size='0'], [size='1']))) .aura-select__chevron { display: none; }
|
|
619
|
+
.aura-select .aura-input__control:is([multiple], [size]:not([size='0'], [size='1'])) option { padding: var(--aura-space-1) var(--aura-space-2); border-radius: var(--aura-radius-xs); }
|
|
605
620
|
.aura-select--custom { position: relative; }
|
|
606
621
|
.aura-select__native { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; opacity: 0; pointer-events: none; appearance: none; }
|
|
607
622
|
.aura-select__trigger { display: flex; align-items: center; text-align: start; background: none; border: 0; color: inherit; font: inherit; width: 100%; min-width: 0; }
|
|
@@ -661,7 +676,7 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
661
676
|
/* 5.19 (Chamber-OS 113): a read-only switch keeps its colours (a locked "on" reads as on at full contrast) and stays
|
|
662
677
|
* focusable; only the pointer says it won't change. The row's icon (a lock) sits at its end, like a field's icon. */
|
|
663
678
|
.aura-switch-row.is-readonly, .aura-switch-row.is-readonly .aura-switch, .aura-switch-row.is-readonly .aura-choice__label { cursor: default; }
|
|
664
|
-
.aura-switch-row__icon { flex: none; margin-inline-start:
|
|
679
|
+
.aura-switch-row__icon { flex: none; margin-inline-start: calc(-1 * var(--aura-space-1)); margin-top: 2px; /* 5.79 (visual audit 17): beside the label it belongs to, 8px after it, not at the row's far end */ width: var(--aura-icon-sm); height: var(--aura-icon-sm); color: var(--aura-fg-secondary); }
|
|
665
680
|
|
|
666
681
|
/* ---------- Alerts & toasts ---------- */
|
|
667
682
|
.aura-alert {
|
|
@@ -1053,8 +1068,8 @@ a.aura-tab { text-decoration: none; }
|
|
|
1053
1068
|
.aura-combo__option.is-selected { font-weight: 500; }
|
|
1054
1069
|
.aura-combo__option.is-disabled { opacity: var(--aura-disabled-opacity); cursor: default; }
|
|
1055
1070
|
.aura-combo__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
1056
|
-
.aura-combo__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1057
|
-
.aura-combo__desc { font-size: max(12px, .75rem); line-height: 1.
|
|
1071
|
+
.aura-combo__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: max(20px, 1.25rem); }
|
|
1072
|
+
.aura-combo__desc { font-size: max(12px, .75rem); line-height: max(18px, 1.125rem); color: var(--aura-fg-secondary); } /* 5.79: fixed line heights, so a Thai row and an English row are spaced alike (normal follows each font) */
|
|
1058
1073
|
/* Same specificity as `.aura-combo__option > .aura-icon` above and later in the file, so it wins by order (4.18). */
|
|
1059
1074
|
.aura-combo__option > .aura-combo__check { color: var(--aura-fg-accent); }
|
|
1060
1075
|
/* 5.16 (Chamber-OS 105): option groups under a heading. */
|
|
@@ -1097,9 +1112,9 @@ a.aura-tab { text-decoration: none; }
|
|
|
1097
1112
|
.aura-cal__day.is-selected { background: var(--aura-control-checked-bg); color: var(--aura-control-checked-fg); box-shadow: none; }
|
|
1098
1113
|
.aura-cal__day:disabled, .aura-cal__day[aria-disabled='true'] { opacity: var(--aura-disabled-opacity); cursor: not-allowed; background: transparent; text-decoration: line-through; }
|
|
1099
1114
|
.aura-cal__day:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: 1px; }
|
|
1100
|
-
.aura-cal__grid td.is-in-range { background: var(--aura-bg
|
|
1101
|
-
.aura-cal__grid td.is-range-start { background: linear-gradient(to right, transparent 50%, var(--aura-bg
|
|
1102
|
-
.aura-cal__grid td.is-range-end { background: linear-gradient(to left, transparent 50%, var(--aura-bg
|
|
1115
|
+
.aura-cal__grid td.is-in-range { background: var(--aura-calendar-range-bg); } /* 5.79 (visual audit 19) */
|
|
1116
|
+
.aura-cal__grid td.is-range-start { background: linear-gradient(to right, transparent 50%, var(--aura-calendar-range-bg) 50%); }
|
|
1117
|
+
.aura-cal__grid td.is-range-end { background: linear-gradient(to left, transparent 50%, var(--aura-calendar-range-bg) 50%); }
|
|
1103
1118
|
.aura-cal__grid td.is-range-start.is-range-end { background: none; }
|
|
1104
1119
|
.aura-cal__years { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--aura-space-1); }
|
|
1105
1120
|
.aura-cal__year {
|
|
@@ -1654,7 +1669,7 @@ a.aura-upload__name:focus-visible { outline: var(--aura-focus-ring-width) solid
|
|
|
1654
1669
|
.aura-badge--success { background: var(--aura-alert-success-bg); color: var(--aura-alert-success-fg); }
|
|
1655
1670
|
.aura-badge--warning { background: var(--aura-alert-warning-bg); color: var(--aura-alert-warning-fg); }
|
|
1656
1671
|
.aura-badge--danger { background: var(--aura-alert-danger-bg); color: var(--aura-alert-danger-fg); }
|
|
1657
|
-
.aura-badge.is-outline { background: transparent; border-color: currentColor; }
|
|
1672
|
+
.aura-badge.is-outline { background: transparent; border-color: currentColor; border-color: color-mix(in srgb, currentColor 45%, transparent); } /* 5.79 (visual audit 19): a quieter edge, so an outline badge doesn't read as a secondary button */
|
|
1658
1673
|
.aura-badge--neutral.is-outline { border-color: var(--aura-border-control); }
|
|
1659
1674
|
.aura-badge.is-solid { background: var(--aura-button-primary-bg); color: var(--aura-button-primary-fg); }
|
|
1660
1675
|
.aura-badge--danger.is-solid { background: var(--aura-status-blocked-solid-bg); color: var(--aura-status-blocked-solid-fg); }
|
|
@@ -1793,6 +1808,7 @@ a.aura-upload__name:focus-visible { outline: var(--aura-focus-ring-width) solid
|
|
|
1793
1808
|
.aura-combo__chips { display: contents; }
|
|
1794
1809
|
.aura-combo__chip {
|
|
1795
1810
|
display: inline-flex; align-items: center; gap: 2px; max-width: 100%; height: 28px; box-sizing: border-box;
|
|
1811
|
+
flex: none; /* 5.79 (visual audit 16): a chip keeps its label and goes to the next line, not shrunk to "V.." */
|
|
1796
1812
|
padding: 0 2px 0 var(--aura-space-2); border-radius: var(--aura-radius-full);
|
|
1797
1813
|
background: var(--aura-bg-selected); color: var(--aura-fg-primary); font-size: max(13px, .8125rem); font-weight: 500;
|
|
1798
1814
|
}
|
|
@@ -2139,6 +2155,11 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2139
2155
|
.aura-filterbar--fill .aura-filterbar__controls > .aura-filterselect .aura-filterselect__chevron { margin-inline-start: auto; }
|
|
2140
2156
|
/* Compact filters sit closer together than full fields. */
|
|
2141
2157
|
.aura-filterbar__controls:has(> .aura-filterselect) { gap: var(--aura-space-2); }
|
|
2158
|
+
/* 5.80: on a phone 6px, so three filters and a Tag keep one 375px row with either font source — the self-hosted
|
|
2159
|
+
* Inter (aura-fonts.local.css) measured 2.3px over at 8px. */
|
|
2160
|
+
@media (max-width: 639.98px) {
|
|
2161
|
+
.aura-filterbar__controls:has(> .aura-filterselect) { gap: 6px; }
|
|
2162
|
+
}
|
|
2142
2163
|
/* 5.42 (Chamber-OS 146): collapseBelow — below the breakpoint the controls fold into a "Filters" sheet; the button
|
|
2143
2164
|
* shares a row with the search, at its end, as tall as the search (the count and actions wrap below). From the
|
|
2144
2165
|
* breakpoint up the search and the hidden button sit in a display: contents box, so the bar lays out as before. */
|
|
@@ -2195,7 +2216,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2195
2216
|
.aura-filterselect__face:focus-visible { outline-style: solid; }
|
|
2196
2217
|
/* Before hydration: the real <select>, invisible, over the face (16px so iOS doesn't zoom when it opens). */
|
|
2197
2218
|
.aura-filterselect__native { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; opacity: 0; font-size: max(16px, 1rem); cursor: pointer; appearance: none; }
|
|
2198
|
-
.aura-filterselect.is-disabled .aura-filterselect__face { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-border
|
|
2219
|
+
.aura-filterselect.is-disabled .aura-filterselect__face { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-input-disabled-border); cursor: not-allowed; }
|
|
2199
2220
|
.aura-filterselect.is-disabled .aura-filterselect__native { cursor: not-allowed; }
|
|
2200
2221
|
/* 5.38 (Chamber-OS 140): touchHeight on FilterBar (its search and field-height controls) or on one FilterSelect —
|
|
2201
2222
|
* 44px below 640px or on a coarse pointer (is-touch), or always. */
|
|
@@ -2395,6 +2416,25 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2395
2416
|
:root:has(.aura-actionbar--edge:not(.is-idle)) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-actionbar-space)); }
|
|
2396
2417
|
:root:has(.aura-actionbar--edge:not(.is-idle)):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-actionbar-space); }
|
|
2397
2418
|
}
|
|
2419
|
+
/* 5.79 (5.78 carry-over): where actionsFullWidthBelow reaches wider than actionsBarBelow, the bar isn't pinned between
|
|
2420
|
+
* the two breakpoints and its buttons sit in the same full-width row — every button there is radius-md, not some. */
|
|
2421
|
+
@media (min-width: 640px) and (max-width: 767.98px) {
|
|
2422
|
+
.aura-page-header--actions-full-below-md.aura-page-header--actions-bar-below-sm > .aura-page-header__actions .aura-btn:not(.aura-icon-btn) { border-radius: var(--aura-radius-md); }
|
|
2423
|
+
}
|
|
2424
|
+
@media (min-width: 640px) and (max-width: 1023.98px) {
|
|
2425
|
+
.aura-page-header--actions-full-below-lg.aura-page-header--actions-bar-below-sm > .aura-page-header__actions .aura-btn:not(.aura-icon-btn) { border-radius: var(--aura-radius-md); }
|
|
2426
|
+
}
|
|
2427
|
+
@media (min-width: 768px) and (max-width: 1023.98px) {
|
|
2428
|
+
.aura-page-header--actions-full-below-lg.aura-page-header--actions-bar-below-md > .aura-page-header__actions .aura-btn:not(.aura-icon-btn) { border-radius: var(--aura-radius-md); }
|
|
2429
|
+
}
|
|
2430
|
+
/* 5.79 (visual audit 10): in an AppShell on a desktop the edge strip starts where the content does — after the
|
|
2431
|
+
* sidebar (its rail width when collapsed; the right edge in RTL) — and its contents line up with the content's 32px
|
|
2432
|
+
* padding, instead of running under the sidebar. Outside an AppShell it keeps the screen's full width. */
|
|
2433
|
+
@media (min-width: 1024px) and (min-height: 30.00125rem) {
|
|
2434
|
+
.aura-shell:has(> .aura-shell__nav) .aura-actionbar--edge:not(.is-idle) { inset-inline-start: var(--aura-sidenav-width); }
|
|
2435
|
+
.aura-shell:has(> .aura-shell__nav .aura-nav--collapsed) .aura-actionbar--edge:not(.is-idle) { inset-inline-start: var(--aura-sidenav-rail-width); }
|
|
2436
|
+
.aura-shell:not(:has(.aura-shell__content.is-flush)) .aura-actionbar--edge:not(.is-idle) > .aura-actionbar__inner { padding-inline: var(--aura-space-8); } /* not with contentPadding={false} */
|
|
2437
|
+
}
|
|
2398
2438
|
/* 5.78 (visual audit 9): one rule for the bottom strips on a phone, as PageHeader's (5.48) — the status on its own row
|
|
2399
2439
|
* at the top, the actions sharing the row under it (an IconButton keeps its square; labels too long to share take a row
|
|
2400
2440
|
* each), 16px both sides as the page. edgeBelow="md" follows it up to 768px, as PageHeader's md strip. */
|
|
@@ -2755,6 +2795,10 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
2755
2795
|
* 1.6 line, so a loading card (its bars follow 1lh) is as tall as one with Thai text. */
|
|
2756
2796
|
.aura-field__label:lang(th), .aura-field__hint:lang(th), .aura-field__error:lang(th), .aura-field__addon:lang(th) { line-height: 1.6; }
|
|
2757
2797
|
.aura-choice__desc:lang(th), .aura-check__desc:lang(th) { font-size: max(13px, .8125rem); line-height: 1.6; }
|
|
2798
|
+
/* 5.79 (visual audit, Thai): the calendar's weekday row in Thai (อา จ อ …) at 13px — 12px was the hardest text on the
|
|
2799
|
+
* page to read; the grid carries lang="th" with a Thai locale. Two-line Thai nav labels get room between lines. */
|
|
2800
|
+
.aura-cal__grid:lang(th) th { font-size: max(13px, .8125rem); }
|
|
2801
|
+
.aura-nav__label:lang(th) { line-height: 1.5; }
|
|
2758
2802
|
.aura-tbl__row > .aura-tbl__td[data-label]:lang(th)::before, .aura-table__td[data-label]:lang(th)::before { font-family: var(--font-sans); font-size: max(12px, .75rem); line-height: max(18px, 1.125rem); }
|
|
2759
2803
|
.aura-table--stacked .aura-table__td[data-label]:lang(th) { line-height: 1.6; }
|
|
2760
2804
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-react",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.80.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",
|