@jirawatpyk/aura-react 5.29.0 → 5.31.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 +45 -0
- package/dist/aura.bundle.js +167 -23
- package/dist/cjs/index.cjs +167 -23
- package/dist/esm/Checkbox.js +4 -2
- package/dist/esm/DataTable.js +36 -0
- package/dist/esm/Field.js +22 -2
- package/dist/esm/Menu.js +61 -14
- package/dist/esm/RadioGroup.js +7 -2
- package/dist/esm/Select.js +2 -2
- package/dist/esm/Tag.js +1 -1
- package/dist/esm/TextField.js +5 -4
- package/dist/esm/Textarea.js +5 -4
- package/dist/esm/classes.js +5 -1
- package/dist/esm/internal.js +2 -1
- package/dist/esm/theme.js +31 -0
- package/dist/index.d.cts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/server/index.cjs +31 -0
- package/dist/server/index.js +31 -0
- package/dist/styles.css +130 -39
- package/dist/styles.layer.css +130 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -186,6 +186,51 @@ 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.31 — Chamber-OS addenda 41–42
|
|
190
|
+
|
|
191
|
+
- **`labelAddon` on TextField, Textarea and PasswordField** (item 138): a node between the label and the box, in the field's 6px gap — e.g. the phrase to type on a typed confirmation, as a chip with a copy button, so it is read before the box and can be copied. The hint and error stay below the box. The addon's box is `.aura-field__addon` with the id `{id}-addon`, and that id comes first in the input's `aria-describedby` (then the error or hint, then your own `aria-describedby` ids), so a screen reader reads it after the label; keep any button names in it short ("Copy"). `labelAddonDescribes={false}` keeps it out — for an addon that isn't a description (a "Forgot password?" link), or to name only part of it (give that part an id and pass it in `aria-describedby`); ids are never repeated. A focusable control in it comes before the input in tab order; clicking the label still focuses the input. `Field` takes `labelAddon` too, for a custom control (add `{id}-addon` to that control's `aria-describedby` yourself). The other fields (Select, Combobox, NumberField, the pickers, FileUpload) don't take it yet. Unset, nothing changes.
|
|
192
|
+
- **"Chosen" follows the brand** (item 139): `createTheme`, `<ThemeStyle>` and `npx aura-theme --brand` now emit `--aura-control-checked-bg` / `-fg` for light and dark, so a themed product's checked box, radio dot, switch, active tab underline, current page, selected day and year, completed step and checked menu item match its links and focus instead of staying violet. Light is the theme's accent itself; dark is the brand's 300 step, lightened to at least 3:1 on the dark surface and canvas (as AURA's own violet-300). The mark on it is white or ink, whichever reads better; both are in the theme's contrast checks (fill 3:1 on surface and canvas, mark 4.5:1 on the fill). In aura.css the light `--aura-control-checked-bg` is now `var(--aura-accent-violet)` (the same violet-700 by default), so a hand-written `:root` override of the accent carries it too; a scoped override needs the generator, or both tokens. Unthemed, nothing changes. Remove any hand-written `--aura-control-checked-*` stand-in after regenerating the theme.
|
|
193
|
+
|
|
194
|
+
## 5.30 — Visual polish (audit, Oct 2026) and Chamber-OS addenda 38–40
|
|
195
|
+
|
|
196
|
+
One release: everything below ships together in 5.30.0.
|
|
197
|
+
|
|
198
|
+
### Menus stay open on scroll; StatusPill weight (addenda 39–40)
|
|
199
|
+
|
|
200
|
+
- **An open menu follows its trigger** (item 136): DropdownMenu and every menu built on it (DataTable's row ⋯ and column menus) now move with the trigger on scroll and resize — a slight finger drag during a tap, the phone's address bar or keyboard no longer close it, as Popover already behaved. It closes once the trigger is wholly out of view (the page's, or a box around it that clips it — a fixed bar inside a scrolling wrapper isn't clipped by it, and `overflow-x: clip` only clips sideways), without taking focus back so the page doesn't jump; inside a Dialog or Drawer focus goes back to the trigger without scrolling, so it stays in the dialog. Escape, a pointerdown outside and choosing an item close it as before, with focus back on the trigger. No new prop.
|
|
201
|
+
- **StatusPill is 500 (medium)** (item 137) wherever it sits — before, it took its parent's weight (regular beside a heading, bold inside bold text). Badge stays 600, so the two stay distinct.
|
|
202
|
+
|
|
203
|
+
### 44px fields and choice rows (addendum 38)
|
|
204
|
+
|
|
205
|
+
- **`touchHeight` on TextField, Textarea, Select, RadioGroup and Checkbox** (item 135): `touchHeight="always"` gives a 44px input box and 44px choice rows at every width — also with a mouse and inside `density="compact"` — for a form whose spec asks for 44px targets everywhere (Chamber-OS's issue dialog: zero-rate radios, certificate number, typed phrase). `touchHeight` (`true`) does it only below 640px or on a coarse pointer, as Button's `touchHeight`; touch screens already had 44px fields and rows. A one-line option's label is centred in its row (a Checkbox row is 45px: its label sits on a 21px line); a row with a description grows. On a Checkbox it applies to a labelled box; a bare box uses `hitArea`. Textarea accepts it too, but is always at least 96px tall, so nothing changes there. In a horizontal RadioGroup each option keeps its own height (one-line options stay centred beside a taller one with a description).
|
|
206
|
+
- **How:** the field's root gets `is-touch-always` / `is-touch`, which sets its own `--aura-input-height` to `--aura-touch-target` (44px) — any control inside that reads the input height follows, whatever density is around it. Label, hint and error ids are unchanged; Button's `touchHeight` is unchanged.
|
|
207
|
+
|
|
208
|
+
### Visual polish, part 2
|
|
209
|
+
|
|
210
|
+
- **"Chosen" is violet everywhere** (audit item 4): a checked Checkbox or Radio, a Switch that is on, the active Tab's underline, the current Pagination page, the selected Calendar day and year, a completed Stepper step and a checked menu item use the new `--aura-control-checked-bg` / `-fg` (violet-700 with a white mark in light, violet-300 with a zinc-900 mark in dark). Buttons stay ink / off-white. A disabled Switch that is on keeps its whole violet track (faded, it fell under 3:1 from a disabled one that is off) and fades its thumb instead.
|
|
211
|
+
- **Tables say when they scroll** (item 9): a Table wider than its box shows a soft shadow at the edge with more to scroll (CSS only, `--aura-scroll-shadow`; body rows show it, the header band and totals rows cover it; set `--aura-tbl-bg` if you give the box another ground); a DataTable with columns past its end edge shows the same shadow over the grid's end edge, inside its scrollbars (`has-more-x`), until scrolled to the end. Stacking stays opt-in (`stackBelow`) — no layout changes by default.
|
|
212
|
+
- **Table columns are never squeezed to one letter** (item 8): from 640px a cell is at least 10ch wide; a longer word (an email, a URL) still breaks to fit rather than widening the table; numbers already stay on one line. Phones are unchanged (a table still fits its box): give a table that is too wide for a phone `stackBelow`.
|
|
213
|
+
- **Totals** (item 20): a 2px rule in the hairline colour over the totals (DataTable and Table), not the strong border that glared in dark; with several totals rows the last is 14px bold; a pinned DataTable totals row casts a soft shadow over the rows under it.
|
|
214
|
+
- **SegmentedControl** (items 11–12) is as tall as a field with a mouse (`--aura-input-height`: 44px, 36px in compact; `size="sm"` unchanged; icon-only options stay square; on touch screens each option is 44px, as before), and the selected option is 600 weight on its own thumb colour (`--aura-segmented-thumb-bg`), which is lighter than the track in dark instead of darker.
|
|
215
|
+
- **FilterSelect** (item 11): from 640px the face has a field's inset and 14px text, like the search box beside it; phones keep the tight face so three filters and a chip share a row.
|
|
216
|
+
- **Smaller fixes**: the show-password button is fg-secondary like a field's other icons (item 14); a removable Tag's × is 14px (item 17); a plain link (no class) inside a Card, Stat, Alert, EmptyState, field, tab panel, AppShell main, table or Dialog takes the accent colour, at zero specificity so your own link rules win (item 18).
|
|
217
|
+
- **Not changed, on purpose**: a ghost button that starts an ActionBar keeps its box at the bar's edge (Chamber-OS 116 relies on it); the Progress track keeps its 3:1 edge (WCAG 1.4.11); DatePicker's calendar button and TimePicker's clock stay where they are (one is a button, one a label icon).
|
|
218
|
+
- Size budgets: `styles.css` 32 kB, DataTable 21 kB, `aura.bundle.js` and the whole package 66 kB.
|
|
219
|
+
|
|
220
|
+
### Visual polish
|
|
221
|
+
|
|
222
|
+
A visual audit of every Storybook story in light, dark and at 390px. This release takes the system-wide fixes; colour hues and layout defaults are unchanged.
|
|
223
|
+
|
|
224
|
+
- **Dark mode:** the primary button, checked box, selected day, completed step, `bg-surface-strong` and `bg-inverted` (tooltips, counts) are off-white `zinc-200` instead of pure white, which was the brightest thing on a dark page. Primary hover is `zinc-100`.
|
|
225
|
+
- **Status fills:** Blocked is `red-800` in light (quieter in a long table, and further from the lime Ready fill); Warning is `amber-600` in dark too (amber-500 glowed). Ready, Warning and Blocked still differ by lightness, not only hue.
|
|
226
|
+
- **Neutral fills show on the light canvas:** `--aura-status-neutral-bg` is `zinc-200` (was `zinc-100` on a `zinc-50` page), so the neutral StatusPill, tab counts, Avatar and SideNav initials are one step darker in light. The neutral Badge and the EmptyState icon disc use it too.
|
|
227
|
+
- **DataTable header band** has its own token, `--aura-table-head-bg`: the canvas in light, `#111114` in dark — between the page and the card, so it no longer reads as a hole. Table's header and totals rows (also the totals card) and DataTable's totals row use it.
|
|
228
|
+
- **Disabled filled buttons** (primary, danger, creative) use new tokens `--aura-button-disabled-bg` / `-fg`: a grey fill with muted text at full opacity, not a faded copy (faded red read as pink, faded ink as a separate grey button); the creative shadow goes. Secondary, ghost and danger-secondary keep the fade. In forced colours every disabled button shows GrayText and the fade.
|
|
229
|
+
- **Buttons are always the AURA sans** (`font-family: var(--font-sans)`), also outside a root that sets the font. An app that sets its own font on `body` should set `--font-sans` too, or its buttons stay Inter.
|
|
230
|
+
- **Table caption** has 12px below it, so it no longer touches the header.
|
|
231
|
+
- **DataTable skeleton action bars** take the button's own shape (`--aura-button-radius`).
|
|
232
|
+
- **Thai:** where the language is Thai (`lang="th"` on the page or a part), StatusPill, Badge and tab counts are 12px (the loading pill matches), BottomNav labels 12px, Stepper descriptions 13px with a 1.6 line, SideNav labels on a 22px line, field labels, hints and errors on a 1.6 line, Radio and Checkbox descriptions 13px on a 1.6 line, and a stacked card's field labels 12px. A `lang="en"` part inside keeps the Latin sizes. These follow the `lang` attribute, not `AuraProvider locale`: set `<html lang="th">` (Next.js: the root layout's `<html lang>`), so portals (Dialog, Menu, Popover) get it too.
|
|
233
|
+
|
|
189
234
|
## 5.29 — Chamber-OS addendum 37
|
|
190
235
|
|
|
191
236
|
- **DataTable loading rows match the rows they stand in for** (item 134), so the layout doesn't jump when the rows arrive:
|
package/dist/aura.bundle.js
CHANGED
|
@@ -158,6 +158,9 @@ window.Aura = (() => {
|
|
|
158
158
|
out[k] = src[k];
|
|
159
159
|
return out;
|
|
160
160
|
}
|
|
161
|
+
function touchClass(t) {
|
|
162
|
+
return t === "always" ? "is-touch-always" : !!t && "is-touch";
|
|
163
|
+
}
|
|
161
164
|
var TONES = ["neutral", "accent", "success", "warning", "danger"];
|
|
162
165
|
function tone(t) {
|
|
163
166
|
return TONES.indexOf(t) >= 0 ? t : "neutral";
|
|
@@ -1364,6 +1367,39 @@ window.Aura = (() => {
|
|
|
1364
1367
|
var React8 = __toESM(require_react(), 1);
|
|
1365
1368
|
var import_react_dom = __toESM(require_react_dom(), 1);
|
|
1366
1369
|
var ITEMS = '[role^="menuitem"]';
|
|
1370
|
+
function makesBlock(s) {
|
|
1371
|
+
return s.transform !== "none" || s.translate !== "none" || s.rotate !== "none" || s.scale !== "none" || s.filter !== "none" || s.backdropFilter !== "none" || s.perspective !== "none" || s.contentVisibility === "auto" || /paint|layout|strict|content/.test(s.contain) || /transform|translate|rotate|scale|filter|perspective/.test(s.willChange);
|
|
1372
|
+
}
|
|
1373
|
+
function inView(el) {
|
|
1374
|
+
if (!el.isConnected) return false;
|
|
1375
|
+
const r = el.getBoundingClientRect();
|
|
1376
|
+
if (r.width === 0 && r.height === 0) return false;
|
|
1377
|
+
let top = r.top, bottom = r.bottom, left = r.left, right = r.right;
|
|
1378
|
+
let pos = getComputedStyle(el).position;
|
|
1379
|
+
for (let p = el.parentElement; p && p !== document.body && p !== document.documentElement; p = p.parentElement) {
|
|
1380
|
+
const s = getComputedStyle(p);
|
|
1381
|
+
const block = makesBlock(s);
|
|
1382
|
+
if (pos === "fixed" && !block) continue;
|
|
1383
|
+
if (pos === "absolute" && s.position === "static" && !block) continue;
|
|
1384
|
+
if (s.display !== "contents") {
|
|
1385
|
+
const b = p.getBoundingClientRect();
|
|
1386
|
+
if (s.overflowX !== "visible") {
|
|
1387
|
+
left = Math.max(left, b.left);
|
|
1388
|
+
right = Math.min(right, b.right);
|
|
1389
|
+
}
|
|
1390
|
+
if (s.overflowY !== "visible") {
|
|
1391
|
+
top = Math.max(top, b.top);
|
|
1392
|
+
bottom = Math.min(bottom, b.bottom);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
pos = s.position === "fixed" || s.position === "absolute" ? s.position : "static";
|
|
1396
|
+
}
|
|
1397
|
+
top = Math.max(top, 0);
|
|
1398
|
+
left = Math.max(left, 0);
|
|
1399
|
+
bottom = Math.min(bottom, window.innerHeight);
|
|
1400
|
+
right = Math.min(right, window.innerWidth);
|
|
1401
|
+
return bottom > top && right > left;
|
|
1402
|
+
}
|
|
1367
1403
|
var Menu = React8.forwardRef(function Menu2(props, ref) {
|
|
1368
1404
|
const own = React8.useRef(null), merged = useMergedRef(ref, own);
|
|
1369
1405
|
const posState = React8.useState(null);
|
|
@@ -1373,21 +1409,30 @@ window.Aura = (() => {
|
|
|
1373
1409
|
const headerId = uid(), itemId = uid();
|
|
1374
1410
|
const hasHeader = props.header != null && props.header !== false && props.header !== "";
|
|
1375
1411
|
const Link = useLinkComponent(props.linkComponent);
|
|
1412
|
+
function place() {
|
|
1413
|
+
const a = props.anchor, m = own.current;
|
|
1414
|
+
if (!a || !m) return;
|
|
1415
|
+
const r = a.getBoundingClientRect(), mh = m.scrollHeight, mw = m.offsetWidth, below2 = window.innerHeight - r.bottom - 12, above = r.top - 12;
|
|
1416
|
+
let top = r.bottom + 4, maxHeight;
|
|
1417
|
+
if (mh > below2) {
|
|
1418
|
+
if (mh <= above) top = r.top - mh - 4;
|
|
1419
|
+
else if (above > below2) {
|
|
1420
|
+
maxHeight = above;
|
|
1421
|
+
top = r.top - above - 4;
|
|
1422
|
+
} else maxHeight = below2;
|
|
1423
|
+
}
|
|
1424
|
+
const left = Math.max(8, Math.min(r.right - mw, window.innerWidth - mw - 8));
|
|
1425
|
+
setPos(function(p) {
|
|
1426
|
+
return p && p.top === top && p.left === left && p.maxHeight === maxHeight ? p : { top, left, maxHeight };
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
const placeRef = React8.useRef(place);
|
|
1430
|
+
placeRef.current = place;
|
|
1431
|
+
const live = React8.useRef({ anchor: props.anchor, onClose: props.onClose });
|
|
1432
|
+
live.current = { anchor: props.anchor, onClose: props.onClose };
|
|
1376
1433
|
useIsoLayoutEffect(
|
|
1377
1434
|
function() {
|
|
1378
|
-
|
|
1379
|
-
if (!a || !m) return;
|
|
1380
|
-
const r = a.getBoundingClientRect(), mh = m.scrollHeight, mw = m.offsetWidth, below2 = window.innerHeight - r.bottom - 12, above = r.top - 12;
|
|
1381
|
-
let top = r.bottom + 4, maxHeight;
|
|
1382
|
-
if (mh > below2) {
|
|
1383
|
-
if (mh <= above) top = r.top - mh - 4;
|
|
1384
|
-
else if (above > below2) {
|
|
1385
|
-
maxHeight = above;
|
|
1386
|
-
top = r.top - above - 4;
|
|
1387
|
-
} else maxHeight = below2;
|
|
1388
|
-
}
|
|
1389
|
-
const left = Math.max(8, Math.min(r.right - mw, window.innerWidth - mw - 8));
|
|
1390
|
-
setPos({ top, left, maxHeight });
|
|
1435
|
+
place();
|
|
1391
1436
|
},
|
|
1392
1437
|
[props.anchor, mounted, hasHeader]
|
|
1393
1438
|
);
|
|
@@ -1417,7 +1462,12 @@ window.Aura = (() => {
|
|
|
1417
1462
|
props.onClose(false);
|
|
1418
1463
|
}
|
|
1419
1464
|
function onScroll(e) {
|
|
1420
|
-
if (own.current &&
|
|
1465
|
+
if (own.current && e.target instanceof Node && own.current.contains(e.target)) return;
|
|
1466
|
+
const a = live.current.anchor;
|
|
1467
|
+
if (a && !inView(a)) {
|
|
1468
|
+
live.current.onClose(false);
|
|
1469
|
+
if (a instanceof HTMLElement && a.closest('[aria-modal="true"]')) a.focus({ preventScroll: true });
|
|
1470
|
+
} else placeRef.current();
|
|
1421
1471
|
}
|
|
1422
1472
|
document.addEventListener("pointerdown", outside, true);
|
|
1423
1473
|
window.addEventListener("scroll", onScroll, true);
|
|
@@ -1627,7 +1677,8 @@ window.Aura = (() => {
|
|
|
1627
1677
|
"className",
|
|
1628
1678
|
"tabIndex",
|
|
1629
1679
|
"disabled",
|
|
1630
|
-
"hitArea"
|
|
1680
|
+
"hitArea",
|
|
1681
|
+
"touchHeight"
|
|
1631
1682
|
]);
|
|
1632
1683
|
const text2 = props.children;
|
|
1633
1684
|
const labelled = text2 != null && text2 !== "";
|
|
@@ -1646,6 +1697,7 @@ window.Aura = (() => {
|
|
|
1646
1697
|
className: cx(
|
|
1647
1698
|
"aura-check",
|
|
1648
1699
|
labelled && "aura-check--labelled",
|
|
1700
|
+
labelled && touchClass(props.touchHeight),
|
|
1649
1701
|
hit && "has-hit",
|
|
1650
1702
|
props.disabled && "is-disabled",
|
|
1651
1703
|
props.className
|
|
@@ -1703,6 +1755,7 @@ window.Aura = (() => {
|
|
|
1703
1755
|
props.required ? /* @__PURE__ */ React12.createElement("span", { className: "aura-field__req", "aria-hidden": true }, " *") : null,
|
|
1704
1756
|
props.optional ? /* @__PURE__ */ React12.createElement("span", { className: "aura-field__opt" }, " (" + t.optional + ")") : null
|
|
1705
1757
|
) : null,
|
|
1758
|
+
hasAddon(props.labelAddon) ? /* @__PURE__ */ React12.createElement("div", { className: "aura-field__addon", id: props.id + "-addon" }, props.labelAddon) : null,
|
|
1706
1759
|
props.children,
|
|
1707
1760
|
props.error ? /* @__PURE__ */ React12.createElement("p", { className: "aura-field__error", id: props.id + "-error" }, /* @__PURE__ */ React12.createElement(Icon, { name: /* @__PURE__ */ React12.createElement(IconCircleAlert, null), size: 14 }), props.error) : props.hint ? /* @__PURE__ */ React12.createElement("p", { className: "aura-field__hint", id: props.id + "-hint" }, props.hint) : null
|
|
1708
1761
|
);
|
|
@@ -1710,6 +1763,20 @@ window.Aura = (() => {
|
|
|
1710
1763
|
function describedBy(id, p) {
|
|
1711
1764
|
return p.error ? id + "-error" : p.hint ? id + "-hint" : void 0;
|
|
1712
1765
|
}
|
|
1766
|
+
function hasAddon(n3) {
|
|
1767
|
+
return n3 != null && typeof n3 !== "boolean" && n3 !== "";
|
|
1768
|
+
}
|
|
1769
|
+
function joinDescribedBy(id, p, own) {
|
|
1770
|
+
const ids = [
|
|
1771
|
+
hasAddon(p.labelAddon) && p.labelAddonDescribes !== false ? id + "-addon" : "",
|
|
1772
|
+
describedBy(id, p) || ""
|
|
1773
|
+
].concat(typeof own === "string" ? own.split(/\s+/) : []);
|
|
1774
|
+
const out = [];
|
|
1775
|
+
ids.forEach(function(x) {
|
|
1776
|
+
if (x && out.indexOf(x) < 0) out.push(x);
|
|
1777
|
+
});
|
|
1778
|
+
return out.join(" ") || void 0;
|
|
1779
|
+
}
|
|
1713
1780
|
var FIELD_KEYS = [
|
|
1714
1781
|
"label",
|
|
1715
1782
|
"hint",
|
|
@@ -1721,7 +1788,10 @@ window.Aura = (() => {
|
|
|
1721
1788
|
"id",
|
|
1722
1789
|
"suffix",
|
|
1723
1790
|
"options",
|
|
1724
|
-
"placeholder"
|
|
1791
|
+
"placeholder",
|
|
1792
|
+
"touchHeight",
|
|
1793
|
+
"labelAddon",
|
|
1794
|
+
"labelAddonDescribes"
|
|
1725
1795
|
];
|
|
1726
1796
|
|
|
1727
1797
|
// src/TextField.tsx
|
|
@@ -1738,8 +1808,9 @@ window.Aura = (() => {
|
|
|
1738
1808
|
error: props.error,
|
|
1739
1809
|
required: props.required,
|
|
1740
1810
|
optional: props.optional,
|
|
1811
|
+
labelAddon: props.labelAddon,
|
|
1741
1812
|
disabled: props.disabled,
|
|
1742
|
-
className: props.className
|
|
1813
|
+
className: cx(touchClass(props.touchHeight), props.className)
|
|
1743
1814
|
},
|
|
1744
1815
|
/* @__PURE__ */ React13.createElement("div", { className: cx("aura-input", props.icon && "has-icon", props.suffix && "has-suffix") }, props.icon ? /* @__PURE__ */ React13.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, /* @__PURE__ */ React13.createElement(
|
|
1745
1816
|
"input",
|
|
@@ -1752,7 +1823,7 @@ window.Aura = (() => {
|
|
|
1752
1823
|
placeholder: props.placeholder,
|
|
1753
1824
|
required: props.required,
|
|
1754
1825
|
"aria-invalid": props.error ? true : rest["aria-invalid"],
|
|
1755
|
-
"aria-describedby":
|
|
1826
|
+
"aria-describedby": joinDescribedBy(id, props, rest["aria-describedby"])
|
|
1756
1827
|
}
|
|
1757
1828
|
), props.suffix ? /* @__PURE__ */ React13.createElement("span", { className: "aura-input__suffix" }, props.suffix) : null)
|
|
1758
1829
|
);
|
|
@@ -1772,8 +1843,9 @@ window.Aura = (() => {
|
|
|
1772
1843
|
error: props.error,
|
|
1773
1844
|
required: props.required,
|
|
1774
1845
|
optional: props.optional,
|
|
1846
|
+
labelAddon: props.labelAddon,
|
|
1775
1847
|
disabled: props.disabled,
|
|
1776
|
-
className: props.className
|
|
1848
|
+
className: cx(touchClass(props.touchHeight), props.className)
|
|
1777
1849
|
},
|
|
1778
1850
|
/* @__PURE__ */ React14.createElement(
|
|
1779
1851
|
"textarea",
|
|
@@ -1786,7 +1858,7 @@ window.Aura = (() => {
|
|
|
1786
1858
|
placeholder: props.placeholder,
|
|
1787
1859
|
required: props.required,
|
|
1788
1860
|
"aria-invalid": props.error ? true : rest["aria-invalid"],
|
|
1789
|
-
"aria-describedby":
|
|
1861
|
+
"aria-describedby": joinDescribedBy(id, props, rest["aria-describedby"])
|
|
1790
1862
|
}
|
|
1791
1863
|
)
|
|
1792
1864
|
);
|
|
@@ -2207,7 +2279,7 @@ window.Aura = (() => {
|
|
|
2207
2279
|
required: props.required,
|
|
2208
2280
|
optional: props.optional,
|
|
2209
2281
|
disabled: props.disabled,
|
|
2210
|
-
className: props.className
|
|
2282
|
+
className: cx(touchClass(props.touchHeight), props.className)
|
|
2211
2283
|
},
|
|
2212
2284
|
child
|
|
2213
2285
|
);
|
|
@@ -3439,7 +3511,12 @@ window.Aura = (() => {
|
|
|
3439
3511
|
"fieldset",
|
|
3440
3512
|
{
|
|
3441
3513
|
ref: setRef,
|
|
3442
|
-
className: cx(
|
|
3514
|
+
className: cx(
|
|
3515
|
+
"aura-field aura-radio-group",
|
|
3516
|
+
props.error && "is-invalid",
|
|
3517
|
+
touchClass(props.touchHeight),
|
|
3518
|
+
props.className
|
|
3519
|
+
),
|
|
3443
3520
|
"aria-describedby": describedBy(id, props),
|
|
3444
3521
|
"aria-invalid": props.error ? true : void 0,
|
|
3445
3522
|
disabled: props.disabled
|
|
@@ -4607,7 +4684,7 @@ window.Aura = (() => {
|
|
|
4607
4684
|
"aria-label": props.removeLabel || t.remove(name),
|
|
4608
4685
|
onClick: props.onRemove
|
|
4609
4686
|
},
|
|
4610
|
-
/* @__PURE__ */ React27.createElement(Icon, { name: /* @__PURE__ */ React27.createElement(IconX, null), size:
|
|
4687
|
+
/* @__PURE__ */ React27.createElement(Icon, { name: /* @__PURE__ */ React27.createElement(IconX, null), size: 14 })
|
|
4611
4688
|
);
|
|
4612
4689
|
return /* @__PURE__ */ React27.createElement(Tooltip, { content: fullText, open: fullText ? void 0 : false }, btn);
|
|
4613
4690
|
}() : null);
|
|
@@ -5408,6 +5485,28 @@ window.Aura = (() => {
|
|
|
5408
5485
|
return px != null && below(boxWidth[0], px);
|
|
5409
5486
|
}
|
|
5410
5487
|
const scrollRef = React32.useRef(null);
|
|
5488
|
+
const edgeState = React32.useState("");
|
|
5489
|
+
const checkMoreX = function() {
|
|
5490
|
+
const el = scrollRef.current;
|
|
5491
|
+
if (!el) return;
|
|
5492
|
+
const more = Math.abs(el.scrollLeft) + el.clientWidth < el.scrollWidth - 1;
|
|
5493
|
+
const next = more ? [el.offsetTop, el.clientHeight, el.offsetWidth - el.clientWidth].join(" ") : "";
|
|
5494
|
+
if (next !== edgeState[0]) edgeState[1](next);
|
|
5495
|
+
};
|
|
5496
|
+
const checkRef = React32.useRef(checkMoreX);
|
|
5497
|
+
checkRef.current = checkMoreX;
|
|
5498
|
+
React32.useEffect(function() {
|
|
5499
|
+
const el = scrollRef.current;
|
|
5500
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
5501
|
+
const ro = new ResizeObserver(function() {
|
|
5502
|
+
checkRef.current();
|
|
5503
|
+
});
|
|
5504
|
+
ro.observe(el);
|
|
5505
|
+
if (el.firstElementChild) ro.observe(el.firstElementChild);
|
|
5506
|
+
return function() {
|
|
5507
|
+
ro.disconnect();
|
|
5508
|
+
};
|
|
5509
|
+
}, []);
|
|
5411
5510
|
const tipState = React32.useState(null), tip = tipState[0], setTip = tipState[1];
|
|
5412
5511
|
function showFull(e) {
|
|
5413
5512
|
const el = e.target.closest ? e.target.closest(".aura-table__td") : null;
|
|
@@ -6571,12 +6670,25 @@ window.Aura = (() => {
|
|
|
6571
6670
|
stacked && "aura-table--stacked",
|
|
6572
6671
|
noCardSel && "aura-table--cards-nosel",
|
|
6573
6672
|
scrolledX[0] && "is-scrolled-x",
|
|
6673
|
+
edgeState[0] && !stacked && "has-more-x",
|
|
6574
6674
|
refreshing && "is-refreshing",
|
|
6575
6675
|
!levels.length && props.className
|
|
6576
6676
|
),
|
|
6577
6677
|
style: levels.length ? { ["--aura-q-back"]: String(levels[levels.length - 1].px / Q) } : void 0
|
|
6578
6678
|
},
|
|
6579
6679
|
refreshing ? /* @__PURE__ */ React32.createElement("span", { className: "aura-table__busy-bar", "aria-hidden": true }) : null,
|
|
6680
|
+
edgeState[0] && !stacked ? /* @__PURE__ */ React32.createElement(
|
|
6681
|
+
"span",
|
|
6682
|
+
{
|
|
6683
|
+
className: "aura-table__edge",
|
|
6684
|
+
"aria-hidden": true,
|
|
6685
|
+
style: {
|
|
6686
|
+
"--aura-edge-top": edgeState[0].split(" ")[0] + "px",
|
|
6687
|
+
"--aura-edge-h": edgeState[0].split(" ")[1] + "px",
|
|
6688
|
+
"--aura-edge-sb": edgeState[0].split(" ")[2] + "px"
|
|
6689
|
+
}
|
|
6690
|
+
}
|
|
6691
|
+
) : null,
|
|
6580
6692
|
/* @__PURE__ */ React32.createElement(
|
|
6581
6693
|
"div",
|
|
6582
6694
|
{
|
|
@@ -6612,6 +6724,7 @@ window.Aura = (() => {
|
|
|
6612
6724
|
setScrollTop(t2.scrollTop);
|
|
6613
6725
|
const sx = t2.scrollLeft > 0;
|
|
6614
6726
|
if (sx !== scrolledX[0]) scrolledX[1](sx);
|
|
6727
|
+
checkMoreX();
|
|
6615
6728
|
}
|
|
6616
6729
|
},
|
|
6617
6730
|
/* @__PURE__ */ React32.createElement(
|
|
@@ -8488,6 +8601,13 @@ window.Aura = (() => {
|
|
|
8488
8601
|
D["accent-lime"] = s[200];
|
|
8489
8602
|
D["mesh-to"] = s[200];
|
|
8490
8603
|
}
|
|
8604
|
+
function onFill(bg) {
|
|
8605
|
+
return contrast(ZINC[0], bg) >= contrast(INK, bg) ? ZINC[0] : INK;
|
|
8606
|
+
}
|
|
8607
|
+
L["control-checked-bg"] = L["accent-violet"];
|
|
8608
|
+
L["control-checked-fg"] = onFill(L["control-checked-bg"]);
|
|
8609
|
+
D["control-checked-bg"] = fit(b[300], darkGrounds, 3, 1);
|
|
8610
|
+
D["control-checked-fg"] = onFill(D["control-checked-bg"]);
|
|
8491
8611
|
const shadowLight = INK, shadowDark = D["accent-violet"];
|
|
8492
8612
|
if (o.primary === "brand") {
|
|
8493
8613
|
L["button-primary-bg"] = fit(b[600], [ZINC[0]], 4.5, -1);
|
|
@@ -8570,6 +8690,30 @@ window.Aura = (() => {
|
|
|
8570
8690
|
);
|
|
8571
8691
|
}
|
|
8572
8692
|
if (s) check("light", "ink", "accent-lime (signal)", 4.5, INK, s[200]);
|
|
8693
|
+
[
|
|
8694
|
+
[
|
|
8695
|
+
"light",
|
|
8696
|
+
L,
|
|
8697
|
+
[
|
|
8698
|
+
["bg-surface", ZINC[0]],
|
|
8699
|
+
["bg-canvas", ZINC[50]]
|
|
8700
|
+
]
|
|
8701
|
+
],
|
|
8702
|
+
[
|
|
8703
|
+
"dark",
|
|
8704
|
+
D,
|
|
8705
|
+
[
|
|
8706
|
+
["bg-surface", ZINC[900]],
|
|
8707
|
+
["bg-canvas", ZINC[950]]
|
|
8708
|
+
]
|
|
8709
|
+
]
|
|
8710
|
+
].forEach(function(g) {
|
|
8711
|
+
const t = g[0], m = g[1];
|
|
8712
|
+
g[2].forEach(function(gr) {
|
|
8713
|
+
check(t, "control-checked-bg", gr[0], 3, m["control-checked-bg"], gr[1]);
|
|
8714
|
+
});
|
|
8715
|
+
check(t, "control-checked-fg", "control-checked-bg", 4.5, m["control-checked-fg"], m["control-checked-bg"]);
|
|
8716
|
+
});
|
|
8573
8717
|
function css(selector) {
|
|
8574
8718
|
if (selector !== void 0 && /[<{};@\r\n]|\/\*|\*\//.test(selector))
|
|
8575
8719
|
throw new Error('createTheme: "' + selector + '" is not a plain CSS selector');
|