@jirawatpyk/aura-react 5.50.0 → 5.51.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 +17 -0
- package/dist/aura.bundle.js +34 -12
- package/dist/cjs/index.cjs +34 -12
- package/dist/esm/DataTable.js +23 -10
- package/dist/esm/display.js +11 -2
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/server/index.cjs +11 -2
- package/dist/server/index.d.cts +3 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +11 -2
- package/dist/styles.css +25 -4
- package/dist/styles.layer.css +25 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -186,6 +186,23 @@ 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.51 — Chamber-OS addenda 58–64 (#157–163)
|
|
190
|
+
|
|
191
|
+
- **DataTable column `sortDirection`** (#157): `'ascending' | 'descending'` — for a list the page orders (from the URL, a line under the table), puts `aria-sort` on that column's header with no sort button, icon or click, in the server's HTML too. Give it to one column (two warn in development); move it when the order changes. Once the table has its own sort (a sortable header was used, or `sort` is set) that wins and `sortDirection` is ignored, so one header at most claims the order.
|
|
192
|
+
- **DataTable `selectAllRef`** (#157): a ref to the select-all checkbox, e.g. to return focus there after a bulk bar's Clear.
|
|
193
|
+
- **The row minimum counts each flexible column's `minWidth`** (#159), the value its cells already used, instead of 160px for every one — eight columns with minimums of 80–132px now fit a 959px box without a sideways scroll. Columns without `minWidth` still count 160.
|
|
194
|
+
- **`StatusPill wrap`** (#158): in a box narrower than the words they wrap inside the pill (the icon beside the first line, the pill's own line height, Thai's too), and its corners are `aura-radius-lg` (16px) instead of full (addendum 61): on one line that still gives fully round ends, so it looks exactly as before; wrapped it is a rounded rectangle rather than a tall lozenge instead of running out of it — for a narrow DataTable column or a stacked card. In a wide box, or without `wrap`, a pill is one line as before.
|
|
195
|
+
- **Toggle Tags among FilterBar's controls show their whole label** (#160): from 640px a selectable Tag inside FilterBar isn't cut at 24ch, only when wider than the bar, and in the Filters sheet it never is; below 640px in the bar itself, and for a Tag outside FilterBar, the cap and its tip stay. Applied-filter chips were already uncapped (5.28).
|
|
196
|
+
- **The wheel over a DataTable scrolls the page again** (#163): `.aura-table__scroll` contains only the sideways axis (`overscroll-behavior-x: contain`), so a vertical wheel over a grid that scrolls sideways scrolls the page, a sideways swipe stays in the grid (no back navigation), and a fixed-`height` grid scrolls inside first, then the page at its end. Remove any `overscroll-behavior-y` override you added for it.
|
|
197
|
+
- **DataTable column `grow`** (#162): a flexible column's share of the spare width (its cells' flex-grow; default 1), e.g. `{ key: 'actions', minWidth: 128, grow: 3 }` puts Approve and Reject side by side once the table is wide. At the row minimum nothing changes, the row minimum ignores it, and fixed-`width` columns and stacked cards ignore it. `grow: 0` keeps a column at its minimum; leave at least one flexible column above 0 or the rows won't fill a wide table.
|
|
198
|
+
- **DataTable `keyboard="tab"`** (#161): every checkbox, sort and column button, row link and row action is an ordinary Tab stop in reading order (Shift+Tab walks back), each with its focus ring, in the grid and in stacked cards — for lists whose rows carry actions people expect to Tab to. The cells stop being Tab stops; the arrows still move between them once focus is in one (click a cell, or Escape from a control), and the grid's row and column semantics stay. Without it (`'grid'`, the default) the table is one Tab stop as before. Keyboard resizing and reordering of columns (Alt/Ctrl+Shift with the arrows on a header cell) need focus on that header cell, so they stay with the grid keyboard.
|
|
199
|
+
- **5.50 follow-up:** a disabled box whose control has `aria-invalid="true"` keeps its disabled edge inside an enabled custom `Field` too.
|
|
200
|
+
|
|
201
|
+
```jsx
|
|
202
|
+
<DataTable columns={[{ key: 'timeInStage', label: 'Time in stage', minWidth: 132, sortDirection: 'descending' }, …]} selectAllRef={selectAll} … />
|
|
203
|
+
<StatusPill tone="progress" wrap>Awaiting marketing review</StatusPill>
|
|
204
|
+
```
|
|
205
|
+
|
|
189
206
|
## 5.50 — Chamber-OS addendum 57 (#156)
|
|
190
207
|
|
|
191
208
|
- **`invalid` on TextField and Textarea** (and PasswordField, which is a TextField; `Field` for a custom control): marks the value invalid without AURA's message — the danger edge (`--aura-border-danger`, light and dark, also on hover and focus) and `aria-invalid="true"` on the control, no error line, and `aria-describedby` as it would be without it (the addon, the hint, then your own ids). For a page that explains the problem itself — a live contrast readout, a reason line a disabled Save points at. Point `aria-describedby` at that explanation, or a screen reader hears "invalid" with no reason. `error` still wins: its message replaces the hint and its id the hint's. A disabled field keeps its disabled edge.
|
package/dist/aura.bundle.js
CHANGED
|
@@ -684,8 +684,17 @@ window.Aura = (() => {
|
|
|
684
684
|
};
|
|
685
685
|
function statusPillElement(props, ref) {
|
|
686
686
|
const tone2 = props.tone || toneFor(props.children);
|
|
687
|
-
const rest = omit(props, ["tone", "className", "children"]);
|
|
688
|
-
return /* @__PURE__ */ React4.createElement(
|
|
687
|
+
const rest = omit(props, ["tone", "className", "children", "wrap"]);
|
|
688
|
+
return /* @__PURE__ */ React4.createElement(
|
|
689
|
+
"span",
|
|
690
|
+
{
|
|
691
|
+
...rest,
|
|
692
|
+
ref,
|
|
693
|
+
className: cx("aura-pill", "aura-pill--" + tone2, props.wrap && "is-wrap", props.className)
|
|
694
|
+
},
|
|
695
|
+
/* @__PURE__ */ React4.createElement(Icon, { name: h2(PILL_ICON[tone2] || IconCircle), size: 12 }),
|
|
696
|
+
props.wrap ? /* @__PURE__ */ React4.createElement("span", { className: "aura-pill__text" }, props.children) : props.children
|
|
697
|
+
);
|
|
689
698
|
}
|
|
690
699
|
function badgeElement(props, ref) {
|
|
691
700
|
const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
|
|
@@ -5759,6 +5768,8 @@ window.Aura = (() => {
|
|
|
5759
5768
|
const refreshing = busy && manual && rows.length > 0;
|
|
5760
5769
|
const loading = busy && !refreshing;
|
|
5761
5770
|
const selectable = !!props.selectable;
|
|
5771
|
+
const tabMode = props.keyboard === "tab";
|
|
5772
|
+
const tabIdx = tabMode ? void 0 : -1;
|
|
5762
5773
|
const reorderable = props.reorderable !== false && !!props.columnControls;
|
|
5763
5774
|
const controls = !!props.columnControls;
|
|
5764
5775
|
const oneCallback = !!props.onStateChange;
|
|
@@ -5951,7 +5962,7 @@ window.Aura = (() => {
|
|
|
5951
5962
|
const pending = React33.useRef(null);
|
|
5952
5963
|
const resizing = React33.useRef(false);
|
|
5953
5964
|
useIsoLayoutEffect(function() {
|
|
5954
|
-
if (!gridRef.current) return;
|
|
5965
|
+
if (!gridRef.current || tabMode) return;
|
|
5955
5966
|
const els = gridRef.current.querySelectorAll(
|
|
5956
5967
|
'.aura-table__td button, .aura-table__td a[href], .aura-table__td input, .aura-table__td select, .aura-table__td textarea, .aura-table__td [tabindex="0"]'
|
|
5957
5968
|
);
|
|
@@ -6035,7 +6046,7 @@ window.Aura = (() => {
|
|
|
6035
6046
|
});
|
|
6036
6047
|
let fixedSum = 0, hideTerms = "";
|
|
6037
6048
|
vis.forEach(function(c) {
|
|
6038
|
-
const w = widthOf(c) != null ? widthOf(c) : FLEX_MIN, lv = hideLevel(c);
|
|
6049
|
+
const w = widthOf(c) != null ? widthOf(c) : c.minWidth || FLEX_MIN, lv = hideLevel(c);
|
|
6039
6050
|
if (lv && boxWidth[0] == null) hideTerms += " + " + w + "px * var(--aura-h" + lv + "-on, 1)";
|
|
6040
6051
|
else fixedSum += w;
|
|
6041
6052
|
});
|
|
@@ -6047,13 +6058,21 @@ window.Aura = (() => {
|
|
|
6047
6058
|
acc += " + " + widthOf(c) + "px" + (lv && boxWidth[0] == null ? " * var(--aura-h" + lv + "-on, 1)" : "");
|
|
6048
6059
|
}
|
|
6049
6060
|
});
|
|
6061
|
+
if (vis.filter(function(c) {
|
|
6062
|
+
return !!c.sortDirection;
|
|
6063
|
+
}).length > 1)
|
|
6064
|
+
devWarnOnce(
|
|
6065
|
+
"datatable-sortdirection-twice",
|
|
6066
|
+
"DataTable: more than one column has sortDirection. The order follows one column; give it to that one."
|
|
6067
|
+
);
|
|
6050
6068
|
const selW = selectable ? " + var(--aura-table-select-width)" : "";
|
|
6051
6069
|
const gutterR = controls ? "var(--aura-space-12)" : "var(--aura-space-6)";
|
|
6052
6070
|
const rowMinWidth = "calc(" + fixedSum + "px" + hideTerms + " + var(--aura-space-6) + " + gutterR + selW + ")";
|
|
6053
6071
|
function cellStyle(c, i) {
|
|
6054
6072
|
const w = widthOf(c), s = {};
|
|
6055
6073
|
if (w == null) {
|
|
6056
|
-
|
|
6074
|
+
const g = typeof c.grow === "number" && c.grow >= 0 && isFinite(c.grow) ? c.grow : 1;
|
|
6075
|
+
s["--aura-cell-flex"] = g + " 1 0";
|
|
6057
6076
|
s["--aura-cell-min"] = (c.minWidth || FLEX_MIN) + "px";
|
|
6058
6077
|
} else {
|
|
6059
6078
|
s["--aura-cell-flex"] = !hasFlex && i === vis.length - 1 ? "1 0 auto" : "none";
|
|
@@ -6230,6 +6249,7 @@ window.Aura = (() => {
|
|
|
6230
6249
|
[stacked]
|
|
6231
6250
|
);
|
|
6232
6251
|
function tabFor(r2, c) {
|
|
6252
|
+
if (tabMode) return -1;
|
|
6233
6253
|
if (!activeRendered) return r2 === 0 && c === ac ? 0 : -1;
|
|
6234
6254
|
return r2 === ar && c === acShown ? 0 : -1;
|
|
6235
6255
|
}
|
|
@@ -6252,7 +6272,7 @@ window.Aura = (() => {
|
|
|
6252
6272
|
const el = gridRef.current.querySelector('[data-rc="' + p.r + ":" + c + '"]');
|
|
6253
6273
|
if (el) {
|
|
6254
6274
|
pending.current = null;
|
|
6255
|
-
el.focus();
|
|
6275
|
+
(p.menuBtn && el.querySelector(".aura-table__menu-btn") || el).focus();
|
|
6256
6276
|
}
|
|
6257
6277
|
});
|
|
6258
6278
|
function focusCell(r2, c, dir) {
|
|
@@ -6528,7 +6548,7 @@ window.Aura = (() => {
|
|
|
6528
6548
|
const m = menu;
|
|
6529
6549
|
setMenu(null);
|
|
6530
6550
|
if (restore && m) {
|
|
6531
|
-
if (m.kind === "col") pending.current = { r: 0, key: m.key, c: m.rc ? m.rc.c : 0 };
|
|
6551
|
+
if (m.kind === "col") pending.current = { r: 0, key: m.key, c: m.rc ? m.rc.c : 0, menuBtn: tabMode };
|
|
6532
6552
|
else if (m.anchor) m.anchor.focus();
|
|
6533
6553
|
}
|
|
6534
6554
|
}
|
|
@@ -6616,10 +6636,11 @@ window.Aura = (() => {
|
|
|
6616
6636
|
pageKeys.length ? /* @__PURE__ */ React33.createElement(
|
|
6617
6637
|
Checkbox,
|
|
6618
6638
|
{
|
|
6639
|
+
ref: props.selectAllRef,
|
|
6619
6640
|
hideLabel: true,
|
|
6620
6641
|
checked: all,
|
|
6621
6642
|
indeterminate: nSel > 0 && !all,
|
|
6622
|
-
tabIndex:
|
|
6643
|
+
tabIndex: tabIdx,
|
|
6623
6644
|
label: all ? t.deselectAllRows : t.selectAllRows,
|
|
6624
6645
|
onChange: toggleAll
|
|
6625
6646
|
}
|
|
@@ -6631,7 +6652,8 @@ window.Aura = (() => {
|
|
|
6631
6652
|
const ci = i + (selectable ? 1 : 0);
|
|
6632
6653
|
const isSorted = sort && sort.key === c.key;
|
|
6633
6654
|
const canSort = c.sortable && canSortAny;
|
|
6634
|
-
const
|
|
6655
|
+
const own = c.sortDirection === "ascending" || c.sortDirection === "descending" ? c.sortDirection : void 0;
|
|
6656
|
+
const ariaSort = sort && canSortAny ? isSorted && canSort ? sort.dir === "desc" ? "descending" : "ascending" : canSort ? "none" : void 0 : own || (canSort ? "none" : void 0);
|
|
6635
6657
|
const pin = isPinned(c), edge = pin && i === nPinned - 1;
|
|
6636
6658
|
head.push(
|
|
6637
6659
|
/* @__PURE__ */ React33.createElement(
|
|
@@ -6689,7 +6711,7 @@ window.Aura = (() => {
|
|
|
6689
6711
|
"button",
|
|
6690
6712
|
{
|
|
6691
6713
|
type: "button",
|
|
6692
|
-
tabIndex:
|
|
6714
|
+
tabIndex: tabIdx,
|
|
6693
6715
|
className: cx("aura-table__sort", isSorted && "is-active"),
|
|
6694
6716
|
onClick: function() {
|
|
6695
6717
|
sortBy(c.key);
|
|
@@ -6708,7 +6730,7 @@ window.Aura = (() => {
|
|
|
6708
6730
|
"button",
|
|
6709
6731
|
{
|
|
6710
6732
|
type: "button",
|
|
6711
|
-
tabIndex:
|
|
6733
|
+
tabIndex: tabIdx,
|
|
6712
6734
|
className: "aura-table__menu-btn",
|
|
6713
6735
|
"aria-label": t.columnOptions(c.label),
|
|
6714
6736
|
"aria-haspopup": "menu",
|
|
@@ -6783,7 +6805,7 @@ window.Aura = (() => {
|
|
|
6783
6805
|
{
|
|
6784
6806
|
hideLabel: true,
|
|
6785
6807
|
checked: isSel,
|
|
6786
|
-
tabIndex:
|
|
6808
|
+
tabIndex: tabIdx,
|
|
6787
6809
|
label: selLabel,
|
|
6788
6810
|
onChange: function(on) {
|
|
6789
6811
|
const shift = shiftClick.current;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -666,8 +666,17 @@ var PILL_ICON = {
|
|
|
666
666
|
};
|
|
667
667
|
function statusPillElement(props, ref) {
|
|
668
668
|
const tone2 = props.tone || toneFor(props.children);
|
|
669
|
-
const rest = omit(props, ["tone", "className", "children"]);
|
|
670
|
-
return /* @__PURE__ */ React4.createElement(
|
|
669
|
+
const rest = omit(props, ["tone", "className", "children", "wrap"]);
|
|
670
|
+
return /* @__PURE__ */ React4.createElement(
|
|
671
|
+
"span",
|
|
672
|
+
{
|
|
673
|
+
...rest,
|
|
674
|
+
ref,
|
|
675
|
+
className: cx("aura-pill", "aura-pill--" + tone2, props.wrap && "is-wrap", props.className)
|
|
676
|
+
},
|
|
677
|
+
/* @__PURE__ */ React4.createElement(Icon, { name: h2(PILL_ICON[tone2] || IconCircle), size: 12 }),
|
|
678
|
+
props.wrap ? /* @__PURE__ */ React4.createElement("span", { className: "aura-pill__text" }, props.children) : props.children
|
|
679
|
+
);
|
|
671
680
|
}
|
|
672
681
|
function badgeElement(props, ref) {
|
|
673
682
|
const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
|
|
@@ -5741,6 +5750,8 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
5741
5750
|
const refreshing = busy && manual && rows.length > 0;
|
|
5742
5751
|
const loading = busy && !refreshing;
|
|
5743
5752
|
const selectable = !!props.selectable;
|
|
5753
|
+
const tabMode = props.keyboard === "tab";
|
|
5754
|
+
const tabIdx = tabMode ? void 0 : -1;
|
|
5744
5755
|
const reorderable = props.reorderable !== false && !!props.columnControls;
|
|
5745
5756
|
const controls = !!props.columnControls;
|
|
5746
5757
|
const oneCallback = !!props.onStateChange;
|
|
@@ -5933,7 +5944,7 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
5933
5944
|
const pending = React33.useRef(null);
|
|
5934
5945
|
const resizing = React33.useRef(false);
|
|
5935
5946
|
useIsoLayoutEffect(function() {
|
|
5936
|
-
if (!gridRef.current) return;
|
|
5947
|
+
if (!gridRef.current || tabMode) return;
|
|
5937
5948
|
const els = gridRef.current.querySelectorAll(
|
|
5938
5949
|
'.aura-table__td button, .aura-table__td a[href], .aura-table__td input, .aura-table__td select, .aura-table__td textarea, .aura-table__td [tabindex="0"]'
|
|
5939
5950
|
);
|
|
@@ -6017,7 +6028,7 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6017
6028
|
});
|
|
6018
6029
|
let fixedSum = 0, hideTerms = "";
|
|
6019
6030
|
vis.forEach(function(c) {
|
|
6020
|
-
const w = widthOf(c) != null ? widthOf(c) : FLEX_MIN, lv = hideLevel(c);
|
|
6031
|
+
const w = widthOf(c) != null ? widthOf(c) : c.minWidth || FLEX_MIN, lv = hideLevel(c);
|
|
6021
6032
|
if (lv && boxWidth[0] == null) hideTerms += " + " + w + "px * var(--aura-h" + lv + "-on, 1)";
|
|
6022
6033
|
else fixedSum += w;
|
|
6023
6034
|
});
|
|
@@ -6029,13 +6040,21 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6029
6040
|
acc += " + " + widthOf(c) + "px" + (lv && boxWidth[0] == null ? " * var(--aura-h" + lv + "-on, 1)" : "");
|
|
6030
6041
|
}
|
|
6031
6042
|
});
|
|
6043
|
+
if (vis.filter(function(c) {
|
|
6044
|
+
return !!c.sortDirection;
|
|
6045
|
+
}).length > 1)
|
|
6046
|
+
devWarnOnce(
|
|
6047
|
+
"datatable-sortdirection-twice",
|
|
6048
|
+
"DataTable: more than one column has sortDirection. The order follows one column; give it to that one."
|
|
6049
|
+
);
|
|
6032
6050
|
const selW = selectable ? " + var(--aura-table-select-width)" : "";
|
|
6033
6051
|
const gutterR = controls ? "var(--aura-space-12)" : "var(--aura-space-6)";
|
|
6034
6052
|
const rowMinWidth = "calc(" + fixedSum + "px" + hideTerms + " + var(--aura-space-6) + " + gutterR + selW + ")";
|
|
6035
6053
|
function cellStyle(c, i) {
|
|
6036
6054
|
const w = widthOf(c), s = {};
|
|
6037
6055
|
if (w == null) {
|
|
6038
|
-
|
|
6056
|
+
const g = typeof c.grow === "number" && c.grow >= 0 && isFinite(c.grow) ? c.grow : 1;
|
|
6057
|
+
s["--aura-cell-flex"] = g + " 1 0";
|
|
6039
6058
|
s["--aura-cell-min"] = (c.minWidth || FLEX_MIN) + "px";
|
|
6040
6059
|
} else {
|
|
6041
6060
|
s["--aura-cell-flex"] = !hasFlex && i === vis.length - 1 ? "1 0 auto" : "none";
|
|
@@ -6212,6 +6231,7 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6212
6231
|
[stacked]
|
|
6213
6232
|
);
|
|
6214
6233
|
function tabFor(r2, c) {
|
|
6234
|
+
if (tabMode) return -1;
|
|
6215
6235
|
if (!activeRendered) return r2 === 0 && c === ac ? 0 : -1;
|
|
6216
6236
|
return r2 === ar && c === acShown ? 0 : -1;
|
|
6217
6237
|
}
|
|
@@ -6234,7 +6254,7 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6234
6254
|
const el = gridRef.current.querySelector('[data-rc="' + p.r + ":" + c + '"]');
|
|
6235
6255
|
if (el) {
|
|
6236
6256
|
pending.current = null;
|
|
6237
|
-
el.focus();
|
|
6257
|
+
(p.menuBtn && el.querySelector(".aura-table__menu-btn") || el).focus();
|
|
6238
6258
|
}
|
|
6239
6259
|
});
|
|
6240
6260
|
function focusCell(r2, c, dir) {
|
|
@@ -6510,7 +6530,7 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6510
6530
|
const m = menu;
|
|
6511
6531
|
setMenu(null);
|
|
6512
6532
|
if (restore && m) {
|
|
6513
|
-
if (m.kind === "col") pending.current = { r: 0, key: m.key, c: m.rc ? m.rc.c : 0 };
|
|
6533
|
+
if (m.kind === "col") pending.current = { r: 0, key: m.key, c: m.rc ? m.rc.c : 0, menuBtn: tabMode };
|
|
6514
6534
|
else if (m.anchor) m.anchor.focus();
|
|
6515
6535
|
}
|
|
6516
6536
|
}
|
|
@@ -6598,10 +6618,11 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6598
6618
|
pageKeys.length ? /* @__PURE__ */ React33.createElement(
|
|
6599
6619
|
Checkbox,
|
|
6600
6620
|
{
|
|
6621
|
+
ref: props.selectAllRef,
|
|
6601
6622
|
hideLabel: true,
|
|
6602
6623
|
checked: all,
|
|
6603
6624
|
indeterminate: nSel > 0 && !all,
|
|
6604
|
-
tabIndex:
|
|
6625
|
+
tabIndex: tabIdx,
|
|
6605
6626
|
label: all ? t.deselectAllRows : t.selectAllRows,
|
|
6606
6627
|
onChange: toggleAll
|
|
6607
6628
|
}
|
|
@@ -6613,7 +6634,8 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6613
6634
|
const ci = i + (selectable ? 1 : 0);
|
|
6614
6635
|
const isSorted = sort && sort.key === c.key;
|
|
6615
6636
|
const canSort = c.sortable && canSortAny;
|
|
6616
|
-
const
|
|
6637
|
+
const own = c.sortDirection === "ascending" || c.sortDirection === "descending" ? c.sortDirection : void 0;
|
|
6638
|
+
const ariaSort = sort && canSortAny ? isSorted && canSort ? sort.dir === "desc" ? "descending" : "ascending" : canSort ? "none" : void 0 : own || (canSort ? "none" : void 0);
|
|
6617
6639
|
const pin = isPinned(c), edge = pin && i === nPinned - 1;
|
|
6618
6640
|
head.push(
|
|
6619
6641
|
/* @__PURE__ */ React33.createElement(
|
|
@@ -6671,7 +6693,7 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6671
6693
|
"button",
|
|
6672
6694
|
{
|
|
6673
6695
|
type: "button",
|
|
6674
|
-
tabIndex:
|
|
6696
|
+
tabIndex: tabIdx,
|
|
6675
6697
|
className: cx("aura-table__sort", isSorted && "is-active"),
|
|
6676
6698
|
onClick: function() {
|
|
6677
6699
|
sortBy(c.key);
|
|
@@ -6690,7 +6712,7 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6690
6712
|
"button",
|
|
6691
6713
|
{
|
|
6692
6714
|
type: "button",
|
|
6693
|
-
tabIndex:
|
|
6715
|
+
tabIndex: tabIdx,
|
|
6694
6716
|
className: "aura-table__menu-btn",
|
|
6695
6717
|
"aria-label": t.columnOptions(c.label),
|
|
6696
6718
|
"aria-haspopup": "menu",
|
|
@@ -6765,7 +6787,7 @@ var DataTableImpl = React33.forwardRef(function DataTable(props, ref) {
|
|
|
6765
6787
|
{
|
|
6766
6788
|
hideLabel: true,
|
|
6767
6789
|
checked: isSel,
|
|
6768
|
-
tabIndex:
|
|
6790
|
+
tabIndex: tabIdx,
|
|
6769
6791
|
label: selLabel,
|
|
6770
6792
|
onChange: function(on) {
|
|
6771
6793
|
const shift = shiftClick.current;
|
package/dist/esm/DataTable.js
CHANGED
|
@@ -71,6 +71,8 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
71
71
|
const refreshing = busy && manual && rows.length > 0;
|
|
72
72
|
const loading = busy && !refreshing;
|
|
73
73
|
const selectable = !!props.selectable;
|
|
74
|
+
const tabMode = props.keyboard === "tab";
|
|
75
|
+
const tabIdx = tabMode ? void 0 : -1;
|
|
74
76
|
const reorderable = props.reorderable !== false && !!props.columnControls;
|
|
75
77
|
const controls = !!props.columnControls;
|
|
76
78
|
const oneCallback = !!props.onStateChange;
|
|
@@ -263,7 +265,7 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
263
265
|
const pending = React.useRef(null);
|
|
264
266
|
const resizing = React.useRef(false);
|
|
265
267
|
useIsoLayoutEffect(function() {
|
|
266
|
-
if (!gridRef.current) return;
|
|
268
|
+
if (!gridRef.current || tabMode) return;
|
|
267
269
|
const els = gridRef.current.querySelectorAll(
|
|
268
270
|
'.aura-table__td button, .aura-table__td a[href], .aura-table__td input, .aura-table__td select, .aura-table__td textarea, .aura-table__td [tabindex="0"]'
|
|
269
271
|
);
|
|
@@ -347,7 +349,7 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
347
349
|
});
|
|
348
350
|
let fixedSum = 0, hideTerms = "";
|
|
349
351
|
vis.forEach(function(c) {
|
|
350
|
-
const w = widthOf(c) != null ? widthOf(c) : FLEX_MIN, lv = hideLevel(c);
|
|
352
|
+
const w = widthOf(c) != null ? widthOf(c) : c.minWidth || FLEX_MIN, lv = hideLevel(c);
|
|
351
353
|
if (lv && boxWidth[0] == null) hideTerms += " + " + w + "px * var(--aura-h" + lv + "-on, 1)";
|
|
352
354
|
else fixedSum += w;
|
|
353
355
|
});
|
|
@@ -359,13 +361,21 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
359
361
|
acc += " + " + widthOf(c) + "px" + (lv && boxWidth[0] == null ? " * var(--aura-h" + lv + "-on, 1)" : "");
|
|
360
362
|
}
|
|
361
363
|
});
|
|
364
|
+
if (vis.filter(function(c) {
|
|
365
|
+
return !!c.sortDirection;
|
|
366
|
+
}).length > 1)
|
|
367
|
+
devWarnOnce(
|
|
368
|
+
"datatable-sortdirection-twice",
|
|
369
|
+
"DataTable: more than one column has sortDirection. The order follows one column; give it to that one."
|
|
370
|
+
);
|
|
362
371
|
const selW = selectable ? " + var(--aura-table-select-width)" : "";
|
|
363
372
|
const gutterR = controls ? "var(--aura-space-12)" : "var(--aura-space-6)";
|
|
364
373
|
const rowMinWidth = "calc(" + fixedSum + "px" + hideTerms + " + var(--aura-space-6) + " + gutterR + selW + ")";
|
|
365
374
|
function cellStyle(c, i) {
|
|
366
375
|
const w = widthOf(c), s = {};
|
|
367
376
|
if (w == null) {
|
|
368
|
-
|
|
377
|
+
const g = typeof c.grow === "number" && c.grow >= 0 && isFinite(c.grow) ? c.grow : 1;
|
|
378
|
+
s["--aura-cell-flex"] = g + " 1 0";
|
|
369
379
|
s["--aura-cell-min"] = (c.minWidth || FLEX_MIN) + "px";
|
|
370
380
|
} else {
|
|
371
381
|
s["--aura-cell-flex"] = !hasFlex && i === vis.length - 1 ? "1 0 auto" : "none";
|
|
@@ -542,6 +552,7 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
542
552
|
[stacked]
|
|
543
553
|
);
|
|
544
554
|
function tabFor(r, c) {
|
|
555
|
+
if (tabMode) return -1;
|
|
545
556
|
if (!activeRendered) return r === 0 && c === ac ? 0 : -1;
|
|
546
557
|
return r === ar && c === acShown ? 0 : -1;
|
|
547
558
|
}
|
|
@@ -564,7 +575,7 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
564
575
|
const el = gridRef.current.querySelector('[data-rc="' + p.r + ":" + c + '"]');
|
|
565
576
|
if (el) {
|
|
566
577
|
pending.current = null;
|
|
567
|
-
el.focus();
|
|
578
|
+
(p.menuBtn && el.querySelector(".aura-table__menu-btn") || el).focus();
|
|
568
579
|
}
|
|
569
580
|
});
|
|
570
581
|
function focusCell(r, c, dir) {
|
|
@@ -840,7 +851,7 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
840
851
|
const m = menu;
|
|
841
852
|
setMenu(null);
|
|
842
853
|
if (restore && m) {
|
|
843
|
-
if (m.kind === "col") pending.current = { r: 0, key: m.key, c: m.rc ? m.rc.c : 0 };
|
|
854
|
+
if (m.kind === "col") pending.current = { r: 0, key: m.key, c: m.rc ? m.rc.c : 0, menuBtn: tabMode };
|
|
844
855
|
else if (m.anchor) m.anchor.focus();
|
|
845
856
|
}
|
|
846
857
|
}
|
|
@@ -928,10 +939,11 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
928
939
|
pageKeys.length ? /* @__PURE__ */ React.createElement(
|
|
929
940
|
Checkbox,
|
|
930
941
|
{
|
|
942
|
+
ref: props.selectAllRef,
|
|
931
943
|
hideLabel: true,
|
|
932
944
|
checked: all,
|
|
933
945
|
indeterminate: nSel > 0 && !all,
|
|
934
|
-
tabIndex:
|
|
946
|
+
tabIndex: tabIdx,
|
|
935
947
|
label: all ? t.deselectAllRows : t.selectAllRows,
|
|
936
948
|
onChange: toggleAll
|
|
937
949
|
}
|
|
@@ -943,7 +955,8 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
943
955
|
const ci = i + (selectable ? 1 : 0);
|
|
944
956
|
const isSorted = sort && sort.key === c.key;
|
|
945
957
|
const canSort = c.sortable && canSortAny;
|
|
946
|
-
const
|
|
958
|
+
const own = c.sortDirection === "ascending" || c.sortDirection === "descending" ? c.sortDirection : void 0;
|
|
959
|
+
const ariaSort = sort && canSortAny ? isSorted && canSort ? sort.dir === "desc" ? "descending" : "ascending" : canSort ? "none" : void 0 : own || (canSort ? "none" : void 0);
|
|
947
960
|
const pin = isPinned(c), edge = pin && i === nPinned - 1;
|
|
948
961
|
head.push(
|
|
949
962
|
/* @__PURE__ */ React.createElement(
|
|
@@ -1001,7 +1014,7 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
1001
1014
|
"button",
|
|
1002
1015
|
{
|
|
1003
1016
|
type: "button",
|
|
1004
|
-
tabIndex:
|
|
1017
|
+
tabIndex: tabIdx,
|
|
1005
1018
|
className: cx("aura-table__sort", isSorted && "is-active"),
|
|
1006
1019
|
onClick: function() {
|
|
1007
1020
|
sortBy(c.key);
|
|
@@ -1020,7 +1033,7 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
1020
1033
|
"button",
|
|
1021
1034
|
{
|
|
1022
1035
|
type: "button",
|
|
1023
|
-
tabIndex:
|
|
1036
|
+
tabIndex: tabIdx,
|
|
1024
1037
|
className: "aura-table__menu-btn",
|
|
1025
1038
|
"aria-label": t.columnOptions(c.label),
|
|
1026
1039
|
"aria-haspopup": "menu",
|
|
@@ -1095,7 +1108,7 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
|
|
|
1095
1108
|
{
|
|
1096
1109
|
hideLabel: true,
|
|
1097
1110
|
checked: isSel,
|
|
1098
|
-
tabIndex:
|
|
1111
|
+
tabIndex: tabIdx,
|
|
1099
1112
|
label: selLabel,
|
|
1100
1113
|
onChange: function(on) {
|
|
1101
1114
|
const shift = shiftClick.current;
|
package/dist/esm/display.js
CHANGED
|
@@ -85,8 +85,17 @@ const PILL_ICON = {
|
|
|
85
85
|
};
|
|
86
86
|
function statusPillElement(props, ref) {
|
|
87
87
|
const tone = props.tone || toneFor(props.children);
|
|
88
|
-
const rest = omit(props, ["tone", "className", "children"]);
|
|
89
|
-
return /* @__PURE__ */ React.createElement(
|
|
88
|
+
const rest = omit(props, ["tone", "className", "children", "wrap"]);
|
|
89
|
+
return /* @__PURE__ */ React.createElement(
|
|
90
|
+
"span",
|
|
91
|
+
{
|
|
92
|
+
...rest,
|
|
93
|
+
ref,
|
|
94
|
+
className: cx("aura-pill", "aura-pill--" + tone, props.wrap && "is-wrap", props.className)
|
|
95
|
+
},
|
|
96
|
+
/* @__PURE__ */ React.createElement(Icon, { name: h(PILL_ICON[tone] || IconCircle), size: 12 }),
|
|
97
|
+
props.wrap ? /* @__PURE__ */ React.createElement("span", { className: "aura-pill__text" }, props.children) : props.children
|
|
98
|
+
);
|
|
90
99
|
}
|
|
91
100
|
function badgeElement(props, ref) {
|
|
92
101
|
const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
|
package/dist/index.d.cts
CHANGED
|
@@ -89,12 +89,22 @@ export interface DataTableColumn<Row extends Record<string, any> = Record<string
|
|
|
89
89
|
tones?: Record<string, StatusTone> | undefined;
|
|
90
90
|
/** Header becomes a button cycling asc → desc → unsorted. */
|
|
91
91
|
sortable?: boolean | undefined;
|
|
92
|
+
/** 5.51 (Chamber-OS 157): the order this column is in when the page sets it (from the URL, say), not a header
|
|
93
|
+
* button — puts `aria-sort` on the header, with no button, icon or click. Give it to one column. Once the table has
|
|
94
|
+
* its own sort (someone used a sortable header, or `sort` is set) that wins and this is ignored, so only one header
|
|
95
|
+
* claims the order. */
|
|
96
|
+
sortDirection?: "ascending" | "descending" | undefined;
|
|
92
97
|
/** Value to sort by, when not the cell value (dates, amounts). */
|
|
93
98
|
sortValue?: RowCallback<string | number | null, Row> | undefined;
|
|
94
99
|
/** Custom cell content. */
|
|
95
100
|
render?: RowCallback<React$1.ReactNode, Row> | undefined;
|
|
96
101
|
/** Set false to keep a sized column fixed when the table is `resizable`. */
|
|
97
102
|
resizable?: boolean | undefined;
|
|
103
|
+
/** 5.51 (Chamber-OS 162): a flexible column's share of the spare width (its cells' flex-grow; default 1) — e.g.
|
|
104
|
+
* `grow: 3` lets row actions sit side by side once the table is wide. At the minimum width nothing changes; the row
|
|
105
|
+
* minimum ignores it; a fixed `width` column and stacked cards ignore it. `0` keeps the column at its minimum; leave
|
|
106
|
+
* at least one flexible column above 0, or the rows won't fill a wide table. */
|
|
107
|
+
grow?: number | undefined;
|
|
98
108
|
/** Resize limits in px. Defaults 64 / 480. For the flexible column, minWidth defaults to 160. */
|
|
99
109
|
minWidth?: number | undefined;
|
|
100
110
|
maxWidth?: number | undefined;
|
|
@@ -160,6 +170,15 @@ export interface DataTableProps<Row extends Record<string, any> = Record<string,
|
|
|
160
170
|
onSortChange?: ((sort: DataTableSort | null) => void) | undefined;
|
|
161
171
|
/** Adds a checkbox column. */
|
|
162
172
|
selectable?: boolean | undefined;
|
|
173
|
+
/** 5.51 (Chamber-OS 161): how the keyboard moves through the table. `'grid'` (default): the table is one Tab stop,
|
|
174
|
+
* the arrows move between cells and Enter or F2 enters a cell's controls (APG grid). `'tab'`: every checkbox, sort
|
|
175
|
+
* and column button, row link and row action is an ordinary Tab stop in reading order (Shift+Tab walks back), for a
|
|
176
|
+
* list whose rows carry actions people expect to Tab to; the cells are not Tab stops, the arrows still move between
|
|
177
|
+
* them once focus is in one (click a cell, or Escape from a control), and the grid's row and column semantics stay. */
|
|
178
|
+
keyboard?: "grid" | "tab" | undefined;
|
|
179
|
+
/** 5.51 (Chamber-OS 157): a ref to the select-all checkbox (an `<input>`), e.g. to return focus to it after a bulk
|
|
180
|
+
* bar's Clear. Null while the page has no selectable rows. */
|
|
181
|
+
selectAllRef?: React$1.Ref<HTMLInputElement> | undefined;
|
|
163
182
|
/** Which rows can be selected (5.6). A row it rejects shows no checkbox (the cell stays, so columns line up), is
|
|
164
183
|
* skipped by select-all, Space and the count, and never appears in `onSelectionChange` — even if passed in. */
|
|
165
184
|
isRowSelectable?: RowCallback<boolean, Row> | undefined;
|
|
@@ -307,6 +326,9 @@ export type StatusTone = "neutral" | "progress" | "ready" | "warning" | "blocked
|
|
|
307
326
|
export interface StatusPillProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
308
327
|
/** The status word shown, e.g. "In Progress". Other attributes (`id`, `data-*`, `aria-*`) go on the pill (5.8). */
|
|
309
328
|
children: React$1.ReactNode;
|
|
329
|
+
/** 5.51 (Chamber-OS 158): in a box narrower than the words, the text wraps inside the pill (still rounded, the icon
|
|
330
|
+
* on the first line) instead of running out of it. Without it a pill stays on one line. */
|
|
331
|
+
wrap?: boolean | undefined;
|
|
310
332
|
/** Force a tone. Default: matched from the word (Ready/Done → ready, In Progress/In Review → progress, Warning/Problem/Degraded/At risk → warning (5.1), Blocked/Failed → blocked, anything else → neutral). */
|
|
311
333
|
tone?: StatusTone | undefined;
|
|
312
334
|
className?: string | undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -89,12 +89,22 @@ export interface DataTableColumn<Row extends Record<string, any> = Record<string
|
|
|
89
89
|
tones?: Record<string, StatusTone> | undefined;
|
|
90
90
|
/** Header becomes a button cycling asc → desc → unsorted. */
|
|
91
91
|
sortable?: boolean | undefined;
|
|
92
|
+
/** 5.51 (Chamber-OS 157): the order this column is in when the page sets it (from the URL, say), not a header
|
|
93
|
+
* button — puts `aria-sort` on the header, with no button, icon or click. Give it to one column. Once the table has
|
|
94
|
+
* its own sort (someone used a sortable header, or `sort` is set) that wins and this is ignored, so only one header
|
|
95
|
+
* claims the order. */
|
|
96
|
+
sortDirection?: "ascending" | "descending" | undefined;
|
|
92
97
|
/** Value to sort by, when not the cell value (dates, amounts). */
|
|
93
98
|
sortValue?: RowCallback<string | number | null, Row> | undefined;
|
|
94
99
|
/** Custom cell content. */
|
|
95
100
|
render?: RowCallback<React$1.ReactNode, Row> | undefined;
|
|
96
101
|
/** Set false to keep a sized column fixed when the table is `resizable`. */
|
|
97
102
|
resizable?: boolean | undefined;
|
|
103
|
+
/** 5.51 (Chamber-OS 162): a flexible column's share of the spare width (its cells' flex-grow; default 1) — e.g.
|
|
104
|
+
* `grow: 3` lets row actions sit side by side once the table is wide. At the minimum width nothing changes; the row
|
|
105
|
+
* minimum ignores it; a fixed `width` column and stacked cards ignore it. `0` keeps the column at its minimum; leave
|
|
106
|
+
* at least one flexible column above 0, or the rows won't fill a wide table. */
|
|
107
|
+
grow?: number | undefined;
|
|
98
108
|
/** Resize limits in px. Defaults 64 / 480. For the flexible column, minWidth defaults to 160. */
|
|
99
109
|
minWidth?: number | undefined;
|
|
100
110
|
maxWidth?: number | undefined;
|
|
@@ -160,6 +170,15 @@ export interface DataTableProps<Row extends Record<string, any> = Record<string,
|
|
|
160
170
|
onSortChange?: ((sort: DataTableSort | null) => void) | undefined;
|
|
161
171
|
/** Adds a checkbox column. */
|
|
162
172
|
selectable?: boolean | undefined;
|
|
173
|
+
/** 5.51 (Chamber-OS 161): how the keyboard moves through the table. `'grid'` (default): the table is one Tab stop,
|
|
174
|
+
* the arrows move between cells and Enter or F2 enters a cell's controls (APG grid). `'tab'`: every checkbox, sort
|
|
175
|
+
* and column button, row link and row action is an ordinary Tab stop in reading order (Shift+Tab walks back), for a
|
|
176
|
+
* list whose rows carry actions people expect to Tab to; the cells are not Tab stops, the arrows still move between
|
|
177
|
+
* them once focus is in one (click a cell, or Escape from a control), and the grid's row and column semantics stay. */
|
|
178
|
+
keyboard?: "grid" | "tab" | undefined;
|
|
179
|
+
/** 5.51 (Chamber-OS 157): a ref to the select-all checkbox (an `<input>`), e.g. to return focus to it after a bulk
|
|
180
|
+
* bar's Clear. Null while the page has no selectable rows. */
|
|
181
|
+
selectAllRef?: React$1.Ref<HTMLInputElement> | undefined;
|
|
163
182
|
/** Which rows can be selected (5.6). A row it rejects shows no checkbox (the cell stays, so columns line up), is
|
|
164
183
|
* skipped by select-all, Space and the count, and never appears in `onSelectionChange` — even if passed in. */
|
|
165
184
|
isRowSelectable?: RowCallback<boolean, Row> | undefined;
|
|
@@ -307,6 +326,9 @@ export type StatusTone = "neutral" | "progress" | "ready" | "warning" | "blocked
|
|
|
307
326
|
export interface StatusPillProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
308
327
|
/** The status word shown, e.g. "In Progress". Other attributes (`id`, `data-*`, `aria-*`) go on the pill (5.8). */
|
|
309
328
|
children: React$1.ReactNode;
|
|
329
|
+
/** 5.51 (Chamber-OS 158): in a box narrower than the words, the text wraps inside the pill (still rounded, the icon
|
|
330
|
+
* on the first line) instead of running out of it. Without it a pill stays on one line. */
|
|
331
|
+
wrap?: boolean | undefined;
|
|
310
332
|
/** Force a tone. Default: matched from the word (Ready/Done → ready, In Progress/In Review → progress, Warning/Problem/Degraded/At risk → warning (5.1), Blocked/Failed → blocked, anything else → neutral). */
|
|
311
333
|
tone?: StatusTone | undefined;
|
|
312
334
|
className?: string | undefined;
|
package/dist/server/index.cjs
CHANGED
|
@@ -1240,8 +1240,17 @@ var PILL_ICON = {
|
|
|
1240
1240
|
};
|
|
1241
1241
|
function statusPillElement(props, ref) {
|
|
1242
1242
|
const tone2 = props.tone || toneFor(props.children);
|
|
1243
|
-
const rest = omit(props, ["tone", "className", "children"]);
|
|
1244
|
-
return /* @__PURE__ */ React3.createElement(
|
|
1243
|
+
const rest = omit(props, ["tone", "className", "children", "wrap"]);
|
|
1244
|
+
return /* @__PURE__ */ React3.createElement(
|
|
1245
|
+
"span",
|
|
1246
|
+
{
|
|
1247
|
+
...rest,
|
|
1248
|
+
ref,
|
|
1249
|
+
className: cx("aura-pill", "aura-pill--" + tone2, props.wrap && "is-wrap", props.className)
|
|
1250
|
+
},
|
|
1251
|
+
/* @__PURE__ */ React3.createElement(Icon, { name: h2(PILL_ICON[tone2] || IconCircle), size: 12 }),
|
|
1252
|
+
props.wrap ? /* @__PURE__ */ React3.createElement("span", { className: "aura-pill__text" }, props.children) : props.children
|
|
1253
|
+
);
|
|
1245
1254
|
}
|
|
1246
1255
|
function badgeElement(props, ref) {
|
|
1247
1256
|
const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
|
package/dist/server/index.d.cts
CHANGED
|
@@ -46,6 +46,9 @@ export type StatusTone = "neutral" | "progress" | "ready" | "warning" | "blocked
|
|
|
46
46
|
export interface StatusPillProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
47
47
|
/** The status word shown, e.g. "In Progress". Other attributes (`id`, `data-*`, `aria-*`) go on the pill (5.8). */
|
|
48
48
|
children: React$1.ReactNode;
|
|
49
|
+
/** 5.51 (Chamber-OS 158): in a box narrower than the words, the text wraps inside the pill (still rounded, the icon
|
|
50
|
+
* on the first line) instead of running out of it. Without it a pill stays on one line. */
|
|
51
|
+
wrap?: boolean | undefined;
|
|
49
52
|
/** Force a tone. Default: matched from the word (Ready/Done → ready, In Progress/In Review → progress, Warning/Problem/Degraded/At risk → warning (5.1), Blocked/Failed → blocked, anything else → neutral). */
|
|
50
53
|
tone?: StatusTone | undefined;
|
|
51
54
|
className?: string | undefined;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -46,6 +46,9 @@ export type StatusTone = "neutral" | "progress" | "ready" | "warning" | "blocked
|
|
|
46
46
|
export interface StatusPillProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
47
47
|
/** The status word shown, e.g. "In Progress". Other attributes (`id`, `data-*`, `aria-*`) go on the pill (5.8). */
|
|
48
48
|
children: React$1.ReactNode;
|
|
49
|
+
/** 5.51 (Chamber-OS 158): in a box narrower than the words, the text wraps inside the pill (still rounded, the icon
|
|
50
|
+
* on the first line) instead of running out of it. Without it a pill stays on one line. */
|
|
51
|
+
wrap?: boolean | undefined;
|
|
49
52
|
/** Force a tone. Default: matched from the word (Ready/Done → ready, In Progress/In Review → progress, Warning/Problem/Degraded/At risk → warning (5.1), Blocked/Failed → blocked, anything else → neutral). */
|
|
50
53
|
tone?: StatusTone | undefined;
|
|
51
54
|
className?: string | undefined;
|
package/dist/server/index.js
CHANGED
|
@@ -1176,8 +1176,17 @@ var PILL_ICON = {
|
|
|
1176
1176
|
};
|
|
1177
1177
|
function statusPillElement(props, ref) {
|
|
1178
1178
|
const tone2 = props.tone || toneFor(props.children);
|
|
1179
|
-
const rest = omit(props, ["tone", "className", "children"]);
|
|
1180
|
-
return /* @__PURE__ */ React3.createElement(
|
|
1179
|
+
const rest = omit(props, ["tone", "className", "children", "wrap"]);
|
|
1180
|
+
return /* @__PURE__ */ React3.createElement(
|
|
1181
|
+
"span",
|
|
1182
|
+
{
|
|
1183
|
+
...rest,
|
|
1184
|
+
ref,
|
|
1185
|
+
className: cx("aura-pill", "aura-pill--" + tone2, props.wrap && "is-wrap", props.className)
|
|
1186
|
+
},
|
|
1187
|
+
/* @__PURE__ */ React3.createElement(Icon, { name: h2(PILL_ICON[tone2] || IconCircle), size: 12 }),
|
|
1188
|
+
props.wrap ? /* @__PURE__ */ React3.createElement("span", { className: "aura-pill__text" }, props.children) : props.children
|
|
1189
|
+
);
|
|
1181
1190
|
}
|
|
1182
1191
|
function badgeElement(props, ref) {
|
|
1183
1192
|
const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
|
package/dist/styles.css
CHANGED
|
@@ -105,7 +105,10 @@ button.aura-btn--creative[aria-disabled='true']:hover { box-shadow: var(--aura-s
|
|
|
105
105
|
background: var(--aura-bg-surface);
|
|
106
106
|
color: var(--aura-fg-primary);
|
|
107
107
|
}
|
|
108
|
-
.
|
|
108
|
+
/* 5.51 (Chamber-OS 163): only the sideways axis is contained (a trackpad swipe in a wide grid never goes back a page);
|
|
109
|
+
* a vertical wheel over a grid that scrolls sideways still scrolls the page, and a fixed-height grid scrolls inside
|
|
110
|
+
* first, then chains to the page at its end. */
|
|
111
|
+
.aura-table__scroll { position: relative; overflow: auto; overscroll-behavior-x: contain; overscroll-behavior-y: auto; height: var(--aura-table-h, auto); }
|
|
109
112
|
/* 5.30: more columns past the end edge — a soft shadow over the grid's end edge (not over its scrollbars, its footer
|
|
110
113
|
* or the column button), so it reads as scrolling sideways. JavaScript places it (top, height, scrollbar inset). */
|
|
111
114
|
.aura-table__edge {
|
|
@@ -440,6 +443,13 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
440
443
|
background: var(--aura-status-neutral-bg);
|
|
441
444
|
color: var(--aura-status-neutral-fg);
|
|
442
445
|
}
|
|
446
|
+
/* 5.51 (Chamber-OS 158, addendum 61): wrap — the words break inside the pill when its box is narrower; the icon stays
|
|
447
|
+
* beside the first line. Corners are aura-radius-lg (16px), not full: on one line (20px tall) that still clamps to fully
|
|
448
|
+
* round ends, and a wrapped pill is a rounded rectangle, not a tall lozenge. */
|
|
449
|
+
.aura-pill.is-wrap { align-items: flex-start; white-space: normal; border-radius: var(--aura-radius-lg); }
|
|
450
|
+
.aura-pill.is-wrap > .aura-icon { margin-top: calc((max(16px, 1rem) - 12px) / 2); }
|
|
451
|
+
.aura-pill.is-wrap:lang(th) > .aura-icon { margin-top: calc((max(18px, 1.125rem) - 12px) / 2); }
|
|
452
|
+
.aura-pill__text { min-width: 0; overflow-wrap: anywhere; }
|
|
443
453
|
.aura-pill--progress { background: var(--aura-status-progress-bg); color: var(--aura-status-progress-fg); }
|
|
444
454
|
.aura-pill--ready { background: var(--aura-status-ready-bg); color: var(--aura-status-ready-fg); }
|
|
445
455
|
.aura-pill--warning { background: var(--aura-status-warning-bg); color: var(--aura-status-warning-fg); }
|
|
@@ -529,9 +539,10 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
529
539
|
.aura-input__suffix { padding: 0 var(--aura-space-3) 0 0; color: var(--aura-fg-secondary); font-size: max(13px, .8125rem); white-space: nowrap; }
|
|
530
540
|
.aura-field.is-invalid .aura-input, .aura-field.is-invalid .aura-textarea { border-color: var(--aura-border-danger); }
|
|
531
541
|
/* 5.50 (Chamber-OS 156): a control the page marks aria-invalid="true" itself gets the same edge, message or not (a
|
|
532
|
-
* disabled field keeps its disabled edge, as with is-invalid
|
|
533
|
-
|
|
534
|
-
.aura-field:not(.is-disabled) .aura-
|
|
542
|
+
* disabled field keeps its disabled edge, as with is-invalid; 5.51: so does a disabled control inside an enabled custom
|
|
543
|
+
* Field). */
|
|
544
|
+
.aura-field:not(.is-disabled) .aura-input:has(> .aura-input__control[aria-invalid="true"]:not(:disabled)),
|
|
545
|
+
.aura-field:not(.is-disabled) .aura-textarea[aria-invalid="true"]:not(:disabled) { border-color: var(--aura-border-danger); }
|
|
535
546
|
.aura-field.is-disabled .aura-input { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-border-default); }
|
|
536
547
|
.aura-field.is-disabled .aura-input__control { cursor: not-allowed; }
|
|
537
548
|
/* A read-only text field. Only an input: `:read-only` also matches any element that isn't editable — a
|
|
@@ -1864,6 +1875,16 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1864
1875
|
* (So a FilterBar with only chips needs a width from its parent — it is full width in a block.) */
|
|
1865
1876
|
.aura-filterbar__chips { contain: inline-size; }
|
|
1866
1877
|
.aura-filterbar__chips > .aura-tag .aura-tag__text { max-width: none; min-width: 0; }
|
|
1878
|
+
/* 5.51 (Chamber-OS 160): a toggle Tag among FilterBar's controls (or in its sheet) is a filter, not a label to cut:
|
|
1879
|
+
* from 640px it shows its whole text, cut only when wider than the bar. Below 640px (outside the sheet) the 24ch cap
|
|
1880
|
+
* and its tip stay. */
|
|
1881
|
+
@media (min-width: 640px) {
|
|
1882
|
+
.aura-filterbar .aura-tag.is-selectable { max-width: 100%; min-width: 0; }
|
|
1883
|
+
.aura-filterbar .aura-tag.is-selectable .aura-tag__text { max-width: none; min-width: 0; }
|
|
1884
|
+
}
|
|
1885
|
+
/* …and in the Filters sheet at any width: it is full width, with every control labelled. */
|
|
1886
|
+
.aura-filterbar--sheet .aura-tag.is-selectable { max-width: 100%; min-width: 0; }
|
|
1887
|
+
.aura-filterbar--sheet .aura-tag.is-selectable .aura-tag__text { max-width: none; min-width: 0; }
|
|
1867
1888
|
.aura-filterbar__clear {
|
|
1868
1889
|
border: 0; background: transparent; padding: 4px var(--aura-space-2); border-radius: var(--aura-radius-sm);
|
|
1869
1890
|
font: inherit; font-size: max(13px, .8125rem); font-weight: 500; color: var(--aura-fg-accent); cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
|
package/dist/styles.layer.css
CHANGED
|
@@ -107,7 +107,10 @@ button.aura-btn--creative[aria-disabled='true']:hover { box-shadow: var(--aura-s
|
|
|
107
107
|
background: var(--aura-bg-surface);
|
|
108
108
|
color: var(--aura-fg-primary);
|
|
109
109
|
}
|
|
110
|
-
.
|
|
110
|
+
/* 5.51 (Chamber-OS 163): only the sideways axis is contained (a trackpad swipe in a wide grid never goes back a page);
|
|
111
|
+
* a vertical wheel over a grid that scrolls sideways still scrolls the page, and a fixed-height grid scrolls inside
|
|
112
|
+
* first, then chains to the page at its end. */
|
|
113
|
+
.aura-table__scroll { position: relative; overflow: auto; overscroll-behavior-x: contain; overscroll-behavior-y: auto; height: var(--aura-table-h, auto); }
|
|
111
114
|
/* 5.30: more columns past the end edge — a soft shadow over the grid's end edge (not over its scrollbars, its footer
|
|
112
115
|
* or the column button), so it reads as scrolling sideways. JavaScript places it (top, height, scrollbar inset). */
|
|
113
116
|
.aura-table__edge {
|
|
@@ -442,6 +445,13 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
442
445
|
background: var(--aura-status-neutral-bg);
|
|
443
446
|
color: var(--aura-status-neutral-fg);
|
|
444
447
|
}
|
|
448
|
+
/* 5.51 (Chamber-OS 158, addendum 61): wrap — the words break inside the pill when its box is narrower; the icon stays
|
|
449
|
+
* beside the first line. Corners are aura-radius-lg (16px), not full: on one line (20px tall) that still clamps to fully
|
|
450
|
+
* round ends, and a wrapped pill is a rounded rectangle, not a tall lozenge. */
|
|
451
|
+
.aura-pill.is-wrap { align-items: flex-start; white-space: normal; border-radius: var(--aura-radius-lg); }
|
|
452
|
+
.aura-pill.is-wrap > .aura-icon { margin-top: calc((max(16px, 1rem) - 12px) / 2); }
|
|
453
|
+
.aura-pill.is-wrap:lang(th) > .aura-icon { margin-top: calc((max(18px, 1.125rem) - 12px) / 2); }
|
|
454
|
+
.aura-pill__text { min-width: 0; overflow-wrap: anywhere; }
|
|
445
455
|
.aura-pill--progress { background: var(--aura-status-progress-bg); color: var(--aura-status-progress-fg); }
|
|
446
456
|
.aura-pill--ready { background: var(--aura-status-ready-bg); color: var(--aura-status-ready-fg); }
|
|
447
457
|
.aura-pill--warning { background: var(--aura-status-warning-bg); color: var(--aura-status-warning-fg); }
|
|
@@ -531,9 +541,10 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
531
541
|
.aura-input__suffix { padding: 0 var(--aura-space-3) 0 0; color: var(--aura-fg-secondary); font-size: max(13px, .8125rem); white-space: nowrap; }
|
|
532
542
|
.aura-field.is-invalid .aura-input, .aura-field.is-invalid .aura-textarea { border-color: var(--aura-border-danger); }
|
|
533
543
|
/* 5.50 (Chamber-OS 156): a control the page marks aria-invalid="true" itself gets the same edge, message or not (a
|
|
534
|
-
* disabled field keeps its disabled edge, as with is-invalid
|
|
535
|
-
|
|
536
|
-
.aura-field:not(.is-disabled) .aura-
|
|
544
|
+
* disabled field keeps its disabled edge, as with is-invalid; 5.51: so does a disabled control inside an enabled custom
|
|
545
|
+
* Field). */
|
|
546
|
+
.aura-field:not(.is-disabled) .aura-input:has(> .aura-input__control[aria-invalid="true"]:not(:disabled)),
|
|
547
|
+
.aura-field:not(.is-disabled) .aura-textarea[aria-invalid="true"]:not(:disabled) { border-color: var(--aura-border-danger); }
|
|
537
548
|
.aura-field.is-disabled .aura-input { background: var(--aura-bg-input-disabled); color: var(--aura-fg-secondary); border-color: var(--aura-border-default); }
|
|
538
549
|
.aura-field.is-disabled .aura-input__control { cursor: not-allowed; }
|
|
539
550
|
/* A read-only text field. Only an input: `:read-only` also matches any element that isn't editable — a
|
|
@@ -1866,6 +1877,16 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1866
1877
|
* (So a FilterBar with only chips needs a width from its parent — it is full width in a block.) */
|
|
1867
1878
|
.aura-filterbar__chips { contain: inline-size; }
|
|
1868
1879
|
.aura-filterbar__chips > .aura-tag .aura-tag__text { max-width: none; min-width: 0; }
|
|
1880
|
+
/* 5.51 (Chamber-OS 160): a toggle Tag among FilterBar's controls (or in its sheet) is a filter, not a label to cut:
|
|
1881
|
+
* from 640px it shows its whole text, cut only when wider than the bar. Below 640px (outside the sheet) the 24ch cap
|
|
1882
|
+
* and its tip stay. */
|
|
1883
|
+
@media (min-width: 640px) {
|
|
1884
|
+
.aura-filterbar .aura-tag.is-selectable { max-width: 100%; min-width: 0; }
|
|
1885
|
+
.aura-filterbar .aura-tag.is-selectable .aura-tag__text { max-width: none; min-width: 0; }
|
|
1886
|
+
}
|
|
1887
|
+
/* …and in the Filters sheet at any width: it is full width, with every control labelled. */
|
|
1888
|
+
.aura-filterbar--sheet .aura-tag.is-selectable { max-width: 100%; min-width: 0; }
|
|
1889
|
+
.aura-filterbar--sheet .aura-tag.is-selectable .aura-tag__text { max-width: none; min-width: 0; }
|
|
1869
1890
|
.aura-filterbar__clear {
|
|
1870
1891
|
border: 0; background: transparent; padding: 4px var(--aura-space-2); border-radius: var(--aura-radius-sm);
|
|
1871
1892
|
font: inherit; font-size: max(13px, .8125rem); font-weight: 500; color: var(--aura-fg-accent); cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-react",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.51.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",
|