@jirawatpyk/aura-react 5.18.0 → 5.19.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 +6 -0
- package/dist/aura.bundle.js +83 -21
- package/dist/cjs/index.cjs +83 -21
- package/dist/esm/Select.js +74 -16
- package/dist/esm/Switch.js +10 -5
- package/dist/index.d.cts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/styles.css +9 -1
- package/dist/styles.layer.css +9 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -186,6 +186,12 @@ 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.19 — Chamber-OS addendum 20
|
|
190
|
+
|
|
191
|
+
- **Switch `readOnly`, `icon` and `aria-describedby`** (item 113): `readOnly` keeps a locked switch in the Tab order with `aria-readonly="true"`, so its name, state and notes are heard; click, Space, its label and its row change nothing. It keeps its colours (a locked "on" reads as on) and loses the pointer. `icon` puts an icon at the end of the row, the field icon's size, in fg-secondary (`icon={<IconLock />}`), hidden from screen readers. `aria-describedby` is merged with the description's id, as on TextField and Select. `disabled` wins over `readOnly`.
|
|
192
|
+
- **Select `readOnly`** (item 114): the field stays in the Tab order with `aria-readonly="true"` and shows the chosen option on the read-only ground of a read-only TextField, with no chevron; no click or key opens the list. Unlike `disabled`, the value is still posted with the form, and your code can still set it (`reset()`, `setValue()`). Before JavaScript runs, the options from `options` other than the value are disabled so the native control keeps it (`<option>` children aren't; with no `value` or `defaultValue` nothing is); once hydrated they are enabled again, since a disabled selected option is left out of the form's data. A `multiple` / `size` list box ignores the mouse and the keys that pick (arrows, Home/End, Page keys, letters, Space, Ctrl+A); a change that gets through anyway (a touch tap, a phone's picker, `selectOption` in a test) is put back, and your `onChange` isn't called — though a native `change` or `input` listener on the form still sees the event, with the value already restored.
|
|
193
|
+
- Read-only is `aria-readonly` alone; pair it with a note that says why (`aria-describedby`), which screen readers read after the state.
|
|
194
|
+
|
|
189
195
|
## 5.18 — Chamber-OS addendum 19
|
|
190
196
|
|
|
191
197
|
- **Stepper step errors** (item 112): a step can take `status: 'error'` — say, Save found errors on it. It keeps its place in the order and its state (a completed step is still a button with `onStepClick`, the current one keeps `aria-current="step"`), shows the danger tone with an alert icon instead of the check or number (outlined when it is the current step), and its accessible name ends ", has errors" instead of ", completed". On a phone the line reads "Step 2 of 4 — has errors" when the current step has errors; the markers, error ones included, stay visible. Steps without `status` look the same as before.
|
package/dist/aura.bundle.js
CHANGED
|
@@ -1869,10 +1869,22 @@ window.Aura = (() => {
|
|
|
1869
1869
|
var Select = React15.forwardRef(function Select2(props, ref) {
|
|
1870
1870
|
const auto = uid(), id = props.id || auto;
|
|
1871
1871
|
const filter = props[FILTER_KEY];
|
|
1872
|
-
const rest = omit(props, FIELD_KEYS.concat(["children", FILTER_KEY]));
|
|
1872
|
+
const rest = omit(props, FIELD_KEYS.concat(["children", FILTER_KEY, "readOnly"]));
|
|
1873
|
+
const ro = !!props.readOnly && !props.disabled;
|
|
1874
|
+
const mounted = useMounted();
|
|
1875
|
+
const kept = React15.useRef(null);
|
|
1876
|
+
const current2 = [].concat(props.value != null ? props.value : props.defaultValue != null ? props.defaultValue : []).map(String);
|
|
1873
1877
|
const opts = (props.options || []).map(function(o) {
|
|
1874
1878
|
const v = typeof o === "object" ? o : { value: o, label: o };
|
|
1875
|
-
return /* @__PURE__ */ React15.createElement(
|
|
1879
|
+
return /* @__PURE__ */ React15.createElement(
|
|
1880
|
+
"option",
|
|
1881
|
+
{
|
|
1882
|
+
key: v.value,
|
|
1883
|
+
value: v.value,
|
|
1884
|
+
disabled: v.disabled || ro && !mounted && current2.length > 0 && current2.indexOf(v.value) < 0 || void 0
|
|
1885
|
+
},
|
|
1886
|
+
v.label
|
|
1887
|
+
);
|
|
1876
1888
|
});
|
|
1877
1889
|
if (props.placeholder)
|
|
1878
1890
|
opts.unshift(
|
|
@@ -1880,7 +1892,6 @@ window.Aura = (() => {
|
|
|
1880
1892
|
);
|
|
1881
1893
|
const extra = props.value === void 0 && props.defaultValue === void 0 && props.placeholder ? { defaultValue: "" } : {};
|
|
1882
1894
|
const native = !!props.multiple || props.size != null && props.size > 1;
|
|
1883
|
-
const mounted = useMounted();
|
|
1884
1895
|
const live = !native && mounted;
|
|
1885
1896
|
const density = useDensity();
|
|
1886
1897
|
React15.useEffect(function() {
|
|
@@ -2002,7 +2013,7 @@ window.Aura = (() => {
|
|
|
2002
2013
|
}
|
|
2003
2014
|
function choose(it) {
|
|
2004
2015
|
const el = selRef.current;
|
|
2005
|
-
if (!el || it.disabled) return;
|
|
2016
|
+
if (!el || it.disabled || ro) return;
|
|
2006
2017
|
if (el.value !== it.value) {
|
|
2007
2018
|
el.value = it.value;
|
|
2008
2019
|
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
@@ -2012,7 +2023,7 @@ window.Aura = (() => {
|
|
|
2012
2023
|
close(true);
|
|
2013
2024
|
}
|
|
2014
2025
|
function openList(at) {
|
|
2015
|
-
if (props.disabled || trigRef.current && trigRef.current.disabled) return;
|
|
2026
|
+
if (props.disabled || ro || trigRef.current && trigRef.current.disabled) return;
|
|
2016
2027
|
const list = readItems(selRef.current);
|
|
2017
2028
|
const ok = choices(list);
|
|
2018
2029
|
if (!ok.length) return;
|
|
@@ -2143,6 +2154,45 @@ window.Aura = (() => {
|
|
|
2143
2154
|
[open, active, pos[0] != null]
|
|
2144
2155
|
);
|
|
2145
2156
|
const described = [describedBy(id, props), rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
|
|
2157
|
+
function keep(e) {
|
|
2158
|
+
kept.current = Array.prototype.filter.call(e.currentTarget.options, function(o) {
|
|
2159
|
+
return o.selected;
|
|
2160
|
+
}).map(function(o) {
|
|
2161
|
+
return o.value;
|
|
2162
|
+
});
|
|
2163
|
+
}
|
|
2164
|
+
const listBoxLock = ro && native ? {
|
|
2165
|
+
onFocus: function(e) {
|
|
2166
|
+
const user = rest.onFocus;
|
|
2167
|
+
if (user) user(e);
|
|
2168
|
+
keep(e);
|
|
2169
|
+
},
|
|
2170
|
+
onPointerDown: function(e) {
|
|
2171
|
+
const user = rest.onPointerDown;
|
|
2172
|
+
if (user) user(e);
|
|
2173
|
+
keep(e);
|
|
2174
|
+
},
|
|
2175
|
+
onMouseDown: function(e) {
|
|
2176
|
+
const user = rest.onMouseDown;
|
|
2177
|
+
if (user) user(e);
|
|
2178
|
+
e.preventDefault();
|
|
2179
|
+
e.currentTarget.focus();
|
|
2180
|
+
},
|
|
2181
|
+
onKeyDown: function(e) {
|
|
2182
|
+
const user = rest.onKeyDown;
|
|
2183
|
+
if (user) user(e);
|
|
2184
|
+
const k = e.key;
|
|
2185
|
+
const picks = /^(Arrow(Up|Down|Left|Right)|Home|End|Page(Up|Down))$/.test(k) || k.length === 1 && !e.altKey && (!(e.ctrlKey || e.metaKey) || k === " " || k.toLowerCase() === "a");
|
|
2186
|
+
if (picks) e.preventDefault();
|
|
2187
|
+
},
|
|
2188
|
+
onChange: function(e) {
|
|
2189
|
+
const was = kept.current;
|
|
2190
|
+
if (!was) return;
|
|
2191
|
+
Array.prototype.forEach.call(e.currentTarget.options, function(o) {
|
|
2192
|
+
o.selected = was.indexOf(o.value) >= 0;
|
|
2193
|
+
});
|
|
2194
|
+
}
|
|
2195
|
+
} : {};
|
|
2146
2196
|
const field = (child) => filter ? child : /* @__PURE__ */ React15.createElement(
|
|
2147
2197
|
Field,
|
|
2148
2198
|
{
|
|
@@ -2175,19 +2225,25 @@ window.Aura = (() => {
|
|
|
2175
2225
|
));
|
|
2176
2226
|
if (!live)
|
|
2177
2227
|
return field(
|
|
2178
|
-
/* @__PURE__ */ React15.createElement("div", { className: cx("aura-input aura-select", props.icon && "has-icon") }, props.icon ? /* @__PURE__ */ React15.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, h4(
|
|
2228
|
+
/* @__PURE__ */ React15.createElement("div", { className: cx("aura-input aura-select", props.icon && "has-icon", ro && "is-readonly") }, props.icon ? /* @__PURE__ */ React15.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, h4(
|
|
2179
2229
|
"select",
|
|
2180
|
-
Object.assign(
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2230
|
+
Object.assign(
|
|
2231
|
+
extra,
|
|
2232
|
+
rest,
|
|
2233
|
+
{
|
|
2234
|
+
ref: native ? ref : selMerged,
|
|
2235
|
+
id,
|
|
2236
|
+
className: "aura-input__control",
|
|
2237
|
+
required: props.required,
|
|
2238
|
+
"aria-invalid": props.error ? true : void 0,
|
|
2239
|
+
"aria-readonly": ro || void 0,
|
|
2240
|
+
"aria-describedby": described
|
|
2241
|
+
},
|
|
2242
|
+
listBoxLock
|
|
2243
|
+
),
|
|
2188
2244
|
opts,
|
|
2189
2245
|
props.children
|
|
2190
|
-
), /* @__PURE__ */ React15.createElement(Icon, { name: /* @__PURE__ */ React15.createElement(IconChevronDown, null), className: "aura-select__chevron" }))
|
|
2246
|
+
), ro ? null : /* @__PURE__ */ React15.createElement(Icon, { name: /* @__PURE__ */ React15.createElement(IconChevronDown, null), className: "aura-select__chevron" }))
|
|
2191
2247
|
);
|
|
2192
2248
|
const listId = id + "-list", labelId = id + "-label";
|
|
2193
2249
|
const optId = function(i) {
|
|
@@ -2276,6 +2332,7 @@ window.Aura = (() => {
|
|
|
2276
2332
|
filter ? "aura-filterselect" : "aura-input",
|
|
2277
2333
|
"aura-select aura-select--custom",
|
|
2278
2334
|
props.icon && "has-icon",
|
|
2335
|
+
ro && "is-readonly",
|
|
2279
2336
|
open && "is-open",
|
|
2280
2337
|
filter && props.disabled && "is-disabled",
|
|
2281
2338
|
filter && props.className
|
|
@@ -2328,6 +2385,7 @@ window.Aura = (() => {
|
|
|
2328
2385
|
"aria-labelledby": rest["aria-labelledby"] || (filter && !rest["aria-label"] ? nameId : void 0),
|
|
2329
2386
|
"aria-required": props.required || void 0,
|
|
2330
2387
|
"aria-invalid": props.error ? true : void 0,
|
|
2388
|
+
"aria-readonly": ro || void 0,
|
|
2331
2389
|
"aria-describedby": described,
|
|
2332
2390
|
onFocus: function(e) {
|
|
2333
2391
|
if (userFocus) userFocus(e);
|
|
@@ -2350,7 +2408,7 @@ window.Aura = (() => {
|
|
|
2350
2408
|
},
|
|
2351
2409
|
face || /* @__PURE__ */ React15.createElement("span", { id: id + "-value", className: cx("aura-select__value", shown[0].empty && "is-placeholder") }, shown[0].label || " ")
|
|
2352
2410
|
),
|
|
2353
|
-
filter ? null : /* @__PURE__ */ React15.createElement(Icon, { name: /* @__PURE__ */ React15.createElement(IconChevronDown, null), className: "aura-select__chevron" }),
|
|
2411
|
+
filter || ro ? null : /* @__PURE__ */ React15.createElement(Icon, { name: /* @__PURE__ */ React15.createElement(IconChevronDown, null), className: "aura-select__chevron" }),
|
|
2354
2412
|
popup
|
|
2355
2413
|
)
|
|
2356
2414
|
);
|
|
@@ -2429,13 +2487,15 @@ window.Aura = (() => {
|
|
|
2429
2487
|
const auto = uid(), id = props.id || auto;
|
|
2430
2488
|
const st = useMaybeControlled(props.checked, !!props.defaultChecked, props.onChange);
|
|
2431
2489
|
const on = !!st[0];
|
|
2490
|
+
const ro = !!props.readOnly && !props.disabled;
|
|
2491
|
+
const described = [props.description ? id + "-desc" : "", props["aria-describedby"] || ""].filter(Boolean).join(" ");
|
|
2432
2492
|
return /* @__PURE__ */ React18.createElement(
|
|
2433
2493
|
"div",
|
|
2434
2494
|
{
|
|
2435
|
-
className: cx("aura-switch-row", props.disabled && "is-disabled", props.className),
|
|
2495
|
+
className: cx("aura-switch-row", props.disabled && "is-disabled", ro && "is-readonly", props.className),
|
|
2436
2496
|
onClick: function(e) {
|
|
2437
2497
|
const t = e.target;
|
|
2438
|
-
if (props.disabled || t.closest("button, label, a, input")) return;
|
|
2498
|
+
if (props.disabled || ro || t.closest("button, label, a, input")) return;
|
|
2439
2499
|
st[1](!on);
|
|
2440
2500
|
}
|
|
2441
2501
|
},
|
|
@@ -2450,15 +2510,17 @@ window.Aura = (() => {
|
|
|
2450
2510
|
disabled: props.disabled,
|
|
2451
2511
|
"aria-labelledby": props.label ? id + "-label" : void 0,
|
|
2452
2512
|
"aria-label": props.label ? void 0 : props["aria-label"],
|
|
2453
|
-
"aria-
|
|
2513
|
+
"aria-readonly": ro || void 0,
|
|
2514
|
+
"aria-describedby": described || void 0,
|
|
2454
2515
|
className: cx("aura-switch", on && "is-on"),
|
|
2455
2516
|
onClick: function() {
|
|
2456
|
-
st[1](!on);
|
|
2517
|
+
if (!ro) st[1](!on);
|
|
2457
2518
|
}
|
|
2458
2519
|
},
|
|
2459
2520
|
/* @__PURE__ */ React18.createElement("span", { className: "aura-switch__thumb" })
|
|
2460
2521
|
),
|
|
2461
|
-
props.label ? /* @__PURE__ */ React18.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React18.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React18.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : props.description ? /* @__PURE__ */ React18.createElement("span", { className: "aura-sr-only", id: id + "-desc" }, props.description) : null
|
|
2522
|
+
props.label ? /* @__PURE__ */ React18.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React18.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React18.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : props.description ? /* @__PURE__ */ React18.createElement("span", { className: "aura-sr-only", id: id + "-desc" }, props.description) : null,
|
|
2523
|
+
props.icon ? /* @__PURE__ */ React18.createElement(Icon, { name: props.icon, className: "aura-switch-row__icon" }) : null
|
|
2462
2524
|
);
|
|
2463
2525
|
});
|
|
2464
2526
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1851,10 +1851,22 @@ function initialLabel(props, filter) {
|
|
|
1851
1851
|
var Select = React15.forwardRef(function Select2(props, ref) {
|
|
1852
1852
|
const auto = uid(), id = props.id || auto;
|
|
1853
1853
|
const filter = props[FILTER_KEY];
|
|
1854
|
-
const rest = omit(props, FIELD_KEYS.concat(["children", FILTER_KEY]));
|
|
1854
|
+
const rest = omit(props, FIELD_KEYS.concat(["children", FILTER_KEY, "readOnly"]));
|
|
1855
|
+
const ro = !!props.readOnly && !props.disabled;
|
|
1856
|
+
const mounted = useMounted();
|
|
1857
|
+
const kept = React15.useRef(null);
|
|
1858
|
+
const current2 = [].concat(props.value != null ? props.value : props.defaultValue != null ? props.defaultValue : []).map(String);
|
|
1855
1859
|
const opts = (props.options || []).map(function(o) {
|
|
1856
1860
|
const v = typeof o === "object" ? o : { value: o, label: o };
|
|
1857
|
-
return /* @__PURE__ */ React15.createElement(
|
|
1861
|
+
return /* @__PURE__ */ React15.createElement(
|
|
1862
|
+
"option",
|
|
1863
|
+
{
|
|
1864
|
+
key: v.value,
|
|
1865
|
+
value: v.value,
|
|
1866
|
+
disabled: v.disabled || ro && !mounted && current2.length > 0 && current2.indexOf(v.value) < 0 || void 0
|
|
1867
|
+
},
|
|
1868
|
+
v.label
|
|
1869
|
+
);
|
|
1858
1870
|
});
|
|
1859
1871
|
if (props.placeholder)
|
|
1860
1872
|
opts.unshift(
|
|
@@ -1862,7 +1874,6 @@ var Select = React15.forwardRef(function Select2(props, ref) {
|
|
|
1862
1874
|
);
|
|
1863
1875
|
const extra = props.value === void 0 && props.defaultValue === void 0 && props.placeholder ? { defaultValue: "" } : {};
|
|
1864
1876
|
const native = !!props.multiple || props.size != null && props.size > 1;
|
|
1865
|
-
const mounted = useMounted();
|
|
1866
1877
|
const live = !native && mounted;
|
|
1867
1878
|
const density = useDensity();
|
|
1868
1879
|
React15.useEffect(function() {
|
|
@@ -1984,7 +1995,7 @@ var Select = React15.forwardRef(function Select2(props, ref) {
|
|
|
1984
1995
|
}
|
|
1985
1996
|
function choose(it) {
|
|
1986
1997
|
const el = selRef.current;
|
|
1987
|
-
if (!el || it.disabled) return;
|
|
1998
|
+
if (!el || it.disabled || ro) return;
|
|
1988
1999
|
if (el.value !== it.value) {
|
|
1989
2000
|
el.value = it.value;
|
|
1990
2001
|
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
@@ -1994,7 +2005,7 @@ var Select = React15.forwardRef(function Select2(props, ref) {
|
|
|
1994
2005
|
close(true);
|
|
1995
2006
|
}
|
|
1996
2007
|
function openList(at) {
|
|
1997
|
-
if (props.disabled || trigRef.current && trigRef.current.disabled) return;
|
|
2008
|
+
if (props.disabled || ro || trigRef.current && trigRef.current.disabled) return;
|
|
1998
2009
|
const list = readItems(selRef.current);
|
|
1999
2010
|
const ok = choices(list);
|
|
2000
2011
|
if (!ok.length) return;
|
|
@@ -2125,6 +2136,45 @@ var Select = React15.forwardRef(function Select2(props, ref) {
|
|
|
2125
2136
|
[open, active, pos[0] != null]
|
|
2126
2137
|
);
|
|
2127
2138
|
const described = [describedBy(id, props), rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
|
|
2139
|
+
function keep(e) {
|
|
2140
|
+
kept.current = Array.prototype.filter.call(e.currentTarget.options, function(o) {
|
|
2141
|
+
return o.selected;
|
|
2142
|
+
}).map(function(o) {
|
|
2143
|
+
return o.value;
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
2146
|
+
const listBoxLock = ro && native ? {
|
|
2147
|
+
onFocus: function(e) {
|
|
2148
|
+
const user = rest.onFocus;
|
|
2149
|
+
if (user) user(e);
|
|
2150
|
+
keep(e);
|
|
2151
|
+
},
|
|
2152
|
+
onPointerDown: function(e) {
|
|
2153
|
+
const user = rest.onPointerDown;
|
|
2154
|
+
if (user) user(e);
|
|
2155
|
+
keep(e);
|
|
2156
|
+
},
|
|
2157
|
+
onMouseDown: function(e) {
|
|
2158
|
+
const user = rest.onMouseDown;
|
|
2159
|
+
if (user) user(e);
|
|
2160
|
+
e.preventDefault();
|
|
2161
|
+
e.currentTarget.focus();
|
|
2162
|
+
},
|
|
2163
|
+
onKeyDown: function(e) {
|
|
2164
|
+
const user = rest.onKeyDown;
|
|
2165
|
+
if (user) user(e);
|
|
2166
|
+
const k = e.key;
|
|
2167
|
+
const picks = /^(Arrow(Up|Down|Left|Right)|Home|End|Page(Up|Down))$/.test(k) || k.length === 1 && !e.altKey && (!(e.ctrlKey || e.metaKey) || k === " " || k.toLowerCase() === "a");
|
|
2168
|
+
if (picks) e.preventDefault();
|
|
2169
|
+
},
|
|
2170
|
+
onChange: function(e) {
|
|
2171
|
+
const was = kept.current;
|
|
2172
|
+
if (!was) return;
|
|
2173
|
+
Array.prototype.forEach.call(e.currentTarget.options, function(o) {
|
|
2174
|
+
o.selected = was.indexOf(o.value) >= 0;
|
|
2175
|
+
});
|
|
2176
|
+
}
|
|
2177
|
+
} : {};
|
|
2128
2178
|
const field = (child) => filter ? child : /* @__PURE__ */ React15.createElement(
|
|
2129
2179
|
Field,
|
|
2130
2180
|
{
|
|
@@ -2157,19 +2207,25 @@ var Select = React15.forwardRef(function Select2(props, ref) {
|
|
|
2157
2207
|
));
|
|
2158
2208
|
if (!live)
|
|
2159
2209
|
return field(
|
|
2160
|
-
/* @__PURE__ */ React15.createElement("div", { className: cx("aura-input aura-select", props.icon && "has-icon") }, props.icon ? /* @__PURE__ */ React15.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, h4(
|
|
2210
|
+
/* @__PURE__ */ React15.createElement("div", { className: cx("aura-input aura-select", props.icon && "has-icon", ro && "is-readonly") }, props.icon ? /* @__PURE__ */ React15.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, h4(
|
|
2161
2211
|
"select",
|
|
2162
|
-
Object.assign(
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2212
|
+
Object.assign(
|
|
2213
|
+
extra,
|
|
2214
|
+
rest,
|
|
2215
|
+
{
|
|
2216
|
+
ref: native ? ref : selMerged,
|
|
2217
|
+
id,
|
|
2218
|
+
className: "aura-input__control",
|
|
2219
|
+
required: props.required,
|
|
2220
|
+
"aria-invalid": props.error ? true : void 0,
|
|
2221
|
+
"aria-readonly": ro || void 0,
|
|
2222
|
+
"aria-describedby": described
|
|
2223
|
+
},
|
|
2224
|
+
listBoxLock
|
|
2225
|
+
),
|
|
2170
2226
|
opts,
|
|
2171
2227
|
props.children
|
|
2172
|
-
), /* @__PURE__ */ React15.createElement(Icon, { name: /* @__PURE__ */ React15.createElement(IconChevronDown, null), className: "aura-select__chevron" }))
|
|
2228
|
+
), ro ? null : /* @__PURE__ */ React15.createElement(Icon, { name: /* @__PURE__ */ React15.createElement(IconChevronDown, null), className: "aura-select__chevron" }))
|
|
2173
2229
|
);
|
|
2174
2230
|
const listId = id + "-list", labelId = id + "-label";
|
|
2175
2231
|
const optId = function(i) {
|
|
@@ -2258,6 +2314,7 @@ var Select = React15.forwardRef(function Select2(props, ref) {
|
|
|
2258
2314
|
filter ? "aura-filterselect" : "aura-input",
|
|
2259
2315
|
"aura-select aura-select--custom",
|
|
2260
2316
|
props.icon && "has-icon",
|
|
2317
|
+
ro && "is-readonly",
|
|
2261
2318
|
open && "is-open",
|
|
2262
2319
|
filter && props.disabled && "is-disabled",
|
|
2263
2320
|
filter && props.className
|
|
@@ -2310,6 +2367,7 @@ var Select = React15.forwardRef(function Select2(props, ref) {
|
|
|
2310
2367
|
"aria-labelledby": rest["aria-labelledby"] || (filter && !rest["aria-label"] ? nameId : void 0),
|
|
2311
2368
|
"aria-required": props.required || void 0,
|
|
2312
2369
|
"aria-invalid": props.error ? true : void 0,
|
|
2370
|
+
"aria-readonly": ro || void 0,
|
|
2313
2371
|
"aria-describedby": described,
|
|
2314
2372
|
onFocus: function(e) {
|
|
2315
2373
|
if (userFocus) userFocus(e);
|
|
@@ -2332,7 +2390,7 @@ var Select = React15.forwardRef(function Select2(props, ref) {
|
|
|
2332
2390
|
},
|
|
2333
2391
|
face || /* @__PURE__ */ React15.createElement("span", { id: id + "-value", className: cx("aura-select__value", shown[0].empty && "is-placeholder") }, shown[0].label || " ")
|
|
2334
2392
|
),
|
|
2335
|
-
filter ? null : /* @__PURE__ */ React15.createElement(Icon, { name: /* @__PURE__ */ React15.createElement(IconChevronDown, null), className: "aura-select__chevron" }),
|
|
2393
|
+
filter || ro ? null : /* @__PURE__ */ React15.createElement(Icon, { name: /* @__PURE__ */ React15.createElement(IconChevronDown, null), className: "aura-select__chevron" }),
|
|
2336
2394
|
popup
|
|
2337
2395
|
)
|
|
2338
2396
|
);
|
|
@@ -2411,13 +2469,15 @@ var Switch = React18.forwardRef(function Switch2(props, ref) {
|
|
|
2411
2469
|
const auto = uid(), id = props.id || auto;
|
|
2412
2470
|
const st = useMaybeControlled(props.checked, !!props.defaultChecked, props.onChange);
|
|
2413
2471
|
const on = !!st[0];
|
|
2472
|
+
const ro = !!props.readOnly && !props.disabled;
|
|
2473
|
+
const described = [props.description ? id + "-desc" : "", props["aria-describedby"] || ""].filter(Boolean).join(" ");
|
|
2414
2474
|
return /* @__PURE__ */ React18.createElement(
|
|
2415
2475
|
"div",
|
|
2416
2476
|
{
|
|
2417
|
-
className: cx("aura-switch-row", props.disabled && "is-disabled", props.className),
|
|
2477
|
+
className: cx("aura-switch-row", props.disabled && "is-disabled", ro && "is-readonly", props.className),
|
|
2418
2478
|
onClick: function(e) {
|
|
2419
2479
|
const t = e.target;
|
|
2420
|
-
if (props.disabled || t.closest("button, label, a, input")) return;
|
|
2480
|
+
if (props.disabled || ro || t.closest("button, label, a, input")) return;
|
|
2421
2481
|
st[1](!on);
|
|
2422
2482
|
}
|
|
2423
2483
|
},
|
|
@@ -2432,15 +2492,17 @@ var Switch = React18.forwardRef(function Switch2(props, ref) {
|
|
|
2432
2492
|
disabled: props.disabled,
|
|
2433
2493
|
"aria-labelledby": props.label ? id + "-label" : void 0,
|
|
2434
2494
|
"aria-label": props.label ? void 0 : props["aria-label"],
|
|
2435
|
-
"aria-
|
|
2495
|
+
"aria-readonly": ro || void 0,
|
|
2496
|
+
"aria-describedby": described || void 0,
|
|
2436
2497
|
className: cx("aura-switch", on && "is-on"),
|
|
2437
2498
|
onClick: function() {
|
|
2438
|
-
st[1](!on);
|
|
2499
|
+
if (!ro) st[1](!on);
|
|
2439
2500
|
}
|
|
2440
2501
|
},
|
|
2441
2502
|
/* @__PURE__ */ React18.createElement("span", { className: "aura-switch__thumb" })
|
|
2442
2503
|
),
|
|
2443
|
-
props.label ? /* @__PURE__ */ React18.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React18.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React18.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : props.description ? /* @__PURE__ */ React18.createElement("span", { className: "aura-sr-only", id: id + "-desc" }, props.description) : null
|
|
2504
|
+
props.label ? /* @__PURE__ */ React18.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React18.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React18.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : props.description ? /* @__PURE__ */ React18.createElement("span", { className: "aura-sr-only", id: id + "-desc" }, props.description) : null,
|
|
2505
|
+
props.icon ? /* @__PURE__ */ React18.createElement(Icon, { name: props.icon, className: "aura-switch-row__icon" }) : null
|
|
2444
2506
|
);
|
|
2445
2507
|
});
|
|
2446
2508
|
|
package/dist/esm/Select.js
CHANGED
|
@@ -83,10 +83,22 @@ function initialLabel(props, filter) {
|
|
|
83
83
|
const Select = React.forwardRef(function Select2(props, ref) {
|
|
84
84
|
const auto = uid(), id = props.id || auto;
|
|
85
85
|
const filter = props[FILTER_KEY];
|
|
86
|
-
const rest = omit(props, FIELD_KEYS.concat(["children", FILTER_KEY]));
|
|
86
|
+
const rest = omit(props, FIELD_KEYS.concat(["children", FILTER_KEY, "readOnly"]));
|
|
87
|
+
const ro = !!props.readOnly && !props.disabled;
|
|
88
|
+
const mounted = useMounted();
|
|
89
|
+
const kept = React.useRef(null);
|
|
90
|
+
const current = [].concat(props.value != null ? props.value : props.defaultValue != null ? props.defaultValue : []).map(String);
|
|
87
91
|
const opts = (props.options || []).map(function(o) {
|
|
88
92
|
const v = typeof o === "object" ? o : { value: o, label: o };
|
|
89
|
-
return /* @__PURE__ */ React.createElement(
|
|
93
|
+
return /* @__PURE__ */ React.createElement(
|
|
94
|
+
"option",
|
|
95
|
+
{
|
|
96
|
+
key: v.value,
|
|
97
|
+
value: v.value,
|
|
98
|
+
disabled: v.disabled || ro && !mounted && current.length > 0 && current.indexOf(v.value) < 0 || void 0
|
|
99
|
+
},
|
|
100
|
+
v.label
|
|
101
|
+
);
|
|
90
102
|
});
|
|
91
103
|
if (props.placeholder)
|
|
92
104
|
opts.unshift(
|
|
@@ -94,7 +106,6 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
94
106
|
);
|
|
95
107
|
const extra = props.value === void 0 && props.defaultValue === void 0 && props.placeholder ? { defaultValue: "" } : {};
|
|
96
108
|
const native = !!props.multiple || props.size != null && props.size > 1;
|
|
97
|
-
const mounted = useMounted();
|
|
98
109
|
const live = !native && mounted;
|
|
99
110
|
const density = useDensity();
|
|
100
111
|
React.useEffect(function() {
|
|
@@ -216,7 +227,7 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
216
227
|
}
|
|
217
228
|
function choose(it) {
|
|
218
229
|
const el = selRef.current;
|
|
219
|
-
if (!el || it.disabled) return;
|
|
230
|
+
if (!el || it.disabled || ro) return;
|
|
220
231
|
if (el.value !== it.value) {
|
|
221
232
|
el.value = it.value;
|
|
222
233
|
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
@@ -226,7 +237,7 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
226
237
|
close(true);
|
|
227
238
|
}
|
|
228
239
|
function openList(at) {
|
|
229
|
-
if (props.disabled || trigRef.current && trigRef.current.disabled) return;
|
|
240
|
+
if (props.disabled || ro || trigRef.current && trigRef.current.disabled) return;
|
|
230
241
|
const list = readItems(selRef.current);
|
|
231
242
|
const ok = choices(list);
|
|
232
243
|
if (!ok.length) return;
|
|
@@ -357,6 +368,45 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
357
368
|
[open, active, pos[0] != null]
|
|
358
369
|
);
|
|
359
370
|
const described = [describedBy(id, props), rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
|
|
371
|
+
function keep(e) {
|
|
372
|
+
kept.current = Array.prototype.filter.call(e.currentTarget.options, function(o) {
|
|
373
|
+
return o.selected;
|
|
374
|
+
}).map(function(o) {
|
|
375
|
+
return o.value;
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
const listBoxLock = ro && native ? {
|
|
379
|
+
onFocus: function(e) {
|
|
380
|
+
const user = rest.onFocus;
|
|
381
|
+
if (user) user(e);
|
|
382
|
+
keep(e);
|
|
383
|
+
},
|
|
384
|
+
onPointerDown: function(e) {
|
|
385
|
+
const user = rest.onPointerDown;
|
|
386
|
+
if (user) user(e);
|
|
387
|
+
keep(e);
|
|
388
|
+
},
|
|
389
|
+
onMouseDown: function(e) {
|
|
390
|
+
const user = rest.onMouseDown;
|
|
391
|
+
if (user) user(e);
|
|
392
|
+
e.preventDefault();
|
|
393
|
+
e.currentTarget.focus();
|
|
394
|
+
},
|
|
395
|
+
onKeyDown: function(e) {
|
|
396
|
+
const user = rest.onKeyDown;
|
|
397
|
+
if (user) user(e);
|
|
398
|
+
const k = e.key;
|
|
399
|
+
const picks = /^(Arrow(Up|Down|Left|Right)|Home|End|Page(Up|Down))$/.test(k) || k.length === 1 && !e.altKey && (!(e.ctrlKey || e.metaKey) || k === " " || k.toLowerCase() === "a");
|
|
400
|
+
if (picks) e.preventDefault();
|
|
401
|
+
},
|
|
402
|
+
onChange: function(e) {
|
|
403
|
+
const was = kept.current;
|
|
404
|
+
if (!was) return;
|
|
405
|
+
Array.prototype.forEach.call(e.currentTarget.options, function(o) {
|
|
406
|
+
o.selected = was.indexOf(o.value) >= 0;
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
} : {};
|
|
360
410
|
const field = (child) => filter ? child : /* @__PURE__ */ React.createElement(
|
|
361
411
|
Field,
|
|
362
412
|
{
|
|
@@ -389,19 +439,25 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
389
439
|
));
|
|
390
440
|
if (!live)
|
|
391
441
|
return field(
|
|
392
|
-
/* @__PURE__ */ React.createElement("div", { className: cx("aura-input aura-select", props.icon && "has-icon") }, props.icon ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, h(
|
|
442
|
+
/* @__PURE__ */ React.createElement("div", { className: cx("aura-input aura-select", props.icon && "has-icon", ro && "is-readonly") }, props.icon ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, h(
|
|
393
443
|
"select",
|
|
394
|
-
Object.assign(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
444
|
+
Object.assign(
|
|
445
|
+
extra,
|
|
446
|
+
rest,
|
|
447
|
+
{
|
|
448
|
+
ref: native ? ref : selMerged,
|
|
449
|
+
id,
|
|
450
|
+
className: "aura-input__control",
|
|
451
|
+
required: props.required,
|
|
452
|
+
"aria-invalid": props.error ? true : void 0,
|
|
453
|
+
"aria-readonly": ro || void 0,
|
|
454
|
+
"aria-describedby": described
|
|
455
|
+
},
|
|
456
|
+
listBoxLock
|
|
457
|
+
),
|
|
402
458
|
opts,
|
|
403
459
|
props.children
|
|
404
|
-
), /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconChevronDown, null), className: "aura-select__chevron" }))
|
|
460
|
+
), ro ? null : /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconChevronDown, null), className: "aura-select__chevron" }))
|
|
405
461
|
);
|
|
406
462
|
const listId = id + "-list", labelId = id + "-label";
|
|
407
463
|
const optId = function(i) {
|
|
@@ -490,6 +546,7 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
490
546
|
filter ? "aura-filterselect" : "aura-input",
|
|
491
547
|
"aura-select aura-select--custom",
|
|
492
548
|
props.icon && "has-icon",
|
|
549
|
+
ro && "is-readonly",
|
|
493
550
|
open && "is-open",
|
|
494
551
|
filter && props.disabled && "is-disabled",
|
|
495
552
|
filter && props.className
|
|
@@ -542,6 +599,7 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
542
599
|
"aria-labelledby": rest["aria-labelledby"] || (filter && !rest["aria-label"] ? nameId : void 0),
|
|
543
600
|
"aria-required": props.required || void 0,
|
|
544
601
|
"aria-invalid": props.error ? true : void 0,
|
|
602
|
+
"aria-readonly": ro || void 0,
|
|
545
603
|
"aria-describedby": described,
|
|
546
604
|
onFocus: function(e) {
|
|
547
605
|
if (userFocus) userFocus(e);
|
|
@@ -564,7 +622,7 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
564
622
|
},
|
|
565
623
|
face || /* @__PURE__ */ React.createElement("span", { id: id + "-value", className: cx("aura-select__value", shown[0].empty && "is-placeholder") }, shown[0].label || " ")
|
|
566
624
|
),
|
|
567
|
-
filter ? null : /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconChevronDown, null), className: "aura-select__chevron" }),
|
|
625
|
+
filter || ro ? null : /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconChevronDown, null), className: "aura-select__chevron" }),
|
|
568
626
|
popup
|
|
569
627
|
)
|
|
570
628
|
);
|
package/dist/esm/Switch.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
import { Icon } from "./Icon.js";
|
|
3
4
|
import { cx, uid, useMaybeControlled } from "./internal.js";
|
|
4
5
|
const Switch = React.forwardRef(function Switch2(props, ref) {
|
|
5
6
|
const auto = uid(), id = props.id || auto;
|
|
6
7
|
const st = useMaybeControlled(props.checked, !!props.defaultChecked, props.onChange);
|
|
7
8
|
const on = !!st[0];
|
|
9
|
+
const ro = !!props.readOnly && !props.disabled;
|
|
10
|
+
const described = [props.description ? id + "-desc" : "", props["aria-describedby"] || ""].filter(Boolean).join(" ");
|
|
8
11
|
return /* @__PURE__ */ React.createElement(
|
|
9
12
|
"div",
|
|
10
13
|
{
|
|
11
|
-
className: cx("aura-switch-row", props.disabled && "is-disabled", props.className),
|
|
14
|
+
className: cx("aura-switch-row", props.disabled && "is-disabled", ro && "is-readonly", props.className),
|
|
12
15
|
onClick: function(e) {
|
|
13
16
|
const t = e.target;
|
|
14
|
-
if (props.disabled || t.closest("button, label, a, input")) return;
|
|
17
|
+
if (props.disabled || ro || t.closest("button, label, a, input")) return;
|
|
15
18
|
st[1](!on);
|
|
16
19
|
}
|
|
17
20
|
},
|
|
@@ -26,15 +29,17 @@ const Switch = React.forwardRef(function Switch2(props, ref) {
|
|
|
26
29
|
disabled: props.disabled,
|
|
27
30
|
"aria-labelledby": props.label ? id + "-label" : void 0,
|
|
28
31
|
"aria-label": props.label ? void 0 : props["aria-label"],
|
|
29
|
-
"aria-
|
|
32
|
+
"aria-readonly": ro || void 0,
|
|
33
|
+
"aria-describedby": described || void 0,
|
|
30
34
|
className: cx("aura-switch", on && "is-on"),
|
|
31
35
|
onClick: function() {
|
|
32
|
-
st[1](!on);
|
|
36
|
+
if (!ro) st[1](!on);
|
|
33
37
|
}
|
|
34
38
|
},
|
|
35
39
|
/* @__PURE__ */ React.createElement("span", { className: "aura-switch__thumb" })
|
|
36
40
|
),
|
|
37
|
-
props.label ? /* @__PURE__ */ React.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : props.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-sr-only", id: id + "-desc" }, props.description) : null
|
|
41
|
+
props.label ? /* @__PURE__ */ React.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : props.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-sr-only", id: id + "-desc" }, props.description) : null,
|
|
42
|
+
props.icon ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon, className: "aura-switch-row__icon" }) : null
|
|
38
43
|
);
|
|
39
44
|
});
|
|
40
45
|
export {
|
package/dist/index.d.cts
CHANGED
|
@@ -517,6 +517,10 @@ export interface SelectProps extends Omit<FieldProps, "label">, Omit<React$1.Sel
|
|
|
517
517
|
/** Shown in fg-tertiary on the closed field until something is chosen; not listed as a choice. */
|
|
518
518
|
placeholder?: string | undefined;
|
|
519
519
|
icon?: IconInput | undefined;
|
|
520
|
+
/** 5.19 (Chamber-OS 114): a locked value. The field stays in the Tab order with `aria-readonly` and shows the chosen
|
|
521
|
+
* option on the read-only ground, with no chevron; no click or key opens the list. The value is still submitted
|
|
522
|
+
* with the form (unlike `disabled`). Before JavaScript runs, the other options from `options` are disabled. */
|
|
523
|
+
readOnly?: boolean | undefined;
|
|
520
524
|
}
|
|
521
525
|
/** A compact filter for FilterBar (5.12): "Status All ▾", as wide as its words. */
|
|
522
526
|
export interface FilterSelectProps extends Omit<React$1.SelectHTMLAttributes<HTMLSelectElement>, "onChange" | "value" | "defaultValue" | "multiple" | "size" | "placeholder" | "required" | "children"> {
|
|
@@ -557,8 +561,16 @@ export interface SwitchProps {
|
|
|
557
561
|
defaultChecked?: boolean | undefined;
|
|
558
562
|
onChange?: ((checked: boolean) => void) | undefined;
|
|
559
563
|
disabled?: boolean | undefined;
|
|
564
|
+
/** 5.19 (Chamber-OS 113): a locked value. The switch stays in the Tab order with `aria-readonly`, so its name,
|
|
565
|
+
* state and description are heard; click, Space and the row ignore it. Its colours stay (on reads as on). */
|
|
566
|
+
readOnly?: boolean | undefined;
|
|
567
|
+
/** 5.19: an icon at the end of the row, in fg-secondary and the field icon's size — `icon={<IconLock />}` or
|
|
568
|
+
* `icon="lock"` on a locked row. Hidden from screen readers; say what it means in the description. */
|
|
569
|
+
icon?: IconInput | undefined;
|
|
560
570
|
/** Required when there is no visible label. */
|
|
561
571
|
"aria-label"?: string | undefined;
|
|
572
|
+
/** 5.19: ids of more text that describes the switch (a lock note); merged with `description`'s. */
|
|
573
|
+
"aria-describedby"?: string | undefined;
|
|
562
574
|
id?: string | undefined;
|
|
563
575
|
className?: string | undefined;
|
|
564
576
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -517,6 +517,10 @@ export interface SelectProps extends Omit<FieldProps, "label">, Omit<React$1.Sel
|
|
|
517
517
|
/** Shown in fg-tertiary on the closed field until something is chosen; not listed as a choice. */
|
|
518
518
|
placeholder?: string | undefined;
|
|
519
519
|
icon?: IconInput | undefined;
|
|
520
|
+
/** 5.19 (Chamber-OS 114): a locked value. The field stays in the Tab order with `aria-readonly` and shows the chosen
|
|
521
|
+
* option on the read-only ground, with no chevron; no click or key opens the list. The value is still submitted
|
|
522
|
+
* with the form (unlike `disabled`). Before JavaScript runs, the other options from `options` are disabled. */
|
|
523
|
+
readOnly?: boolean | undefined;
|
|
520
524
|
}
|
|
521
525
|
/** A compact filter for FilterBar (5.12): "Status All ▾", as wide as its words. */
|
|
522
526
|
export interface FilterSelectProps extends Omit<React$1.SelectHTMLAttributes<HTMLSelectElement>, "onChange" | "value" | "defaultValue" | "multiple" | "size" | "placeholder" | "required" | "children"> {
|
|
@@ -557,8 +561,16 @@ export interface SwitchProps {
|
|
|
557
561
|
defaultChecked?: boolean | undefined;
|
|
558
562
|
onChange?: ((checked: boolean) => void) | undefined;
|
|
559
563
|
disabled?: boolean | undefined;
|
|
564
|
+
/** 5.19 (Chamber-OS 113): a locked value. The switch stays in the Tab order with `aria-readonly`, so its name,
|
|
565
|
+
* state and description are heard; click, Space and the row ignore it. Its colours stay (on reads as on). */
|
|
566
|
+
readOnly?: boolean | undefined;
|
|
567
|
+
/** 5.19: an icon at the end of the row, in fg-secondary and the field icon's size — `icon={<IconLock />}` or
|
|
568
|
+
* `icon="lock"` on a locked row. Hidden from screen readers; say what it means in the description. */
|
|
569
|
+
icon?: IconInput | undefined;
|
|
560
570
|
/** Required when there is no visible label. */
|
|
561
571
|
"aria-label"?: string | undefined;
|
|
572
|
+
/** 5.19: ids of more text that describes the switch (a lock note); merged with `description`'s. */
|
|
573
|
+
"aria-describedby"?: string | undefined;
|
|
562
574
|
id?: string | undefined;
|
|
563
575
|
className?: string | undefined;
|
|
564
576
|
}
|
package/dist/styles.css
CHANGED
|
@@ -487,6 +487,10 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
487
487
|
.aura-select__value.is-placeholder { color: var(--aura-fg-tertiary); }
|
|
488
488
|
.aura-select__group { padding: var(--aura-space-2) var(--aura-space-2) var(--aura-space-1); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--aura-fg-tertiary); }
|
|
489
489
|
.aura-select.is-open .aura-select__chevron { transform: rotate(180deg); }
|
|
490
|
+
/* 5.19 (Chamber-OS 114): a read-only Select looks like a read-only TextField — the same ground, no chevron (it doesn't
|
|
491
|
+
* open), no pointer; the value keeps full contrast. */
|
|
492
|
+
.aura-select.is-readonly { background: var(--aura-bg-input-disabled); }
|
|
493
|
+
.aura-select.is-readonly .aura-input__control { cursor: default; padding-right: var(--aura-space-3); }
|
|
490
494
|
|
|
491
495
|
.aura-radio-group > legend { margin-bottom: 6px; }
|
|
492
496
|
.aura-radio-group__list { display: flex; flex-direction: column; gap: var(--aura-space-3); }
|
|
@@ -528,6 +532,10 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
528
532
|
.aura-switch.is-on .aura-switch__thumb { transform: translateX(16px); background: var(--aura-button-primary-fg); }
|
|
529
533
|
.aura-switch:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: var(--aura-focus-ring-offset); }
|
|
530
534
|
.aura-switch:disabled { cursor: not-allowed; }
|
|
535
|
+
/* 5.19 (Chamber-OS 113): a read-only switch keeps its colours (a locked "on" reads as on at full contrast) and stays
|
|
536
|
+
* focusable; only the pointer says it won't change. The row's icon (a lock) sits at its end, like a field's icon. */
|
|
537
|
+
.aura-switch-row.is-readonly, .aura-switch-row.is-readonly .aura-switch, .aura-switch-row.is-readonly .aura-choice__label { cursor: default; }
|
|
538
|
+
.aura-switch-row__icon { flex: none; margin-inline-start: auto; margin-top: 2px; width: var(--aura-icon-sm); height: var(--aura-icon-sm); color: var(--aura-fg-secondary); }
|
|
531
539
|
|
|
532
540
|
/* ---------- Alerts & toasts ---------- */
|
|
533
541
|
.aura-alert {
|
|
@@ -1414,7 +1422,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1414
1422
|
padding-block: calc((var(--aura-touch-target) - 20px) / 2);
|
|
1415
1423
|
}
|
|
1416
1424
|
.aura-check--labelled .aura-check__input { top: calc((var(--aura-touch-target) - 20px) / 2 + 3px); }
|
|
1417
|
-
.aura-switch-row:not(.is-disabled) { cursor: pointer; }
|
|
1425
|
+
.aura-switch-row:not(.is-disabled):not(.is-readonly) { cursor: pointer; }
|
|
1418
1426
|
.aura-radio-group__list { gap: 0; }
|
|
1419
1427
|
.aura-radio-group__list.is-horizontal { gap: 0 var(--aura-space-6); }
|
|
1420
1428
|
}
|
package/dist/styles.layer.css
CHANGED
|
@@ -489,6 +489,10 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
489
489
|
.aura-select__value.is-placeholder { color: var(--aura-fg-tertiary); }
|
|
490
490
|
.aura-select__group { padding: var(--aura-space-2) var(--aura-space-2) var(--aura-space-1); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--aura-fg-tertiary); }
|
|
491
491
|
.aura-select.is-open .aura-select__chevron { transform: rotate(180deg); }
|
|
492
|
+
/* 5.19 (Chamber-OS 114): a read-only Select looks like a read-only TextField — the same ground, no chevron (it doesn't
|
|
493
|
+
* open), no pointer; the value keeps full contrast. */
|
|
494
|
+
.aura-select.is-readonly { background: var(--aura-bg-input-disabled); }
|
|
495
|
+
.aura-select.is-readonly .aura-input__control { cursor: default; padding-right: var(--aura-space-3); }
|
|
492
496
|
|
|
493
497
|
.aura-radio-group > legend { margin-bottom: 6px; }
|
|
494
498
|
.aura-radio-group__list { display: flex; flex-direction: column; gap: var(--aura-space-3); }
|
|
@@ -530,6 +534,10 @@ a.aura-icon-btn { text-decoration: none; }
|
|
|
530
534
|
.aura-switch.is-on .aura-switch__thumb { transform: translateX(16px); background: var(--aura-button-primary-fg); }
|
|
531
535
|
.aura-switch:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: var(--aura-focus-ring-offset); }
|
|
532
536
|
.aura-switch:disabled { cursor: not-allowed; }
|
|
537
|
+
/* 5.19 (Chamber-OS 113): a read-only switch keeps its colours (a locked "on" reads as on at full contrast) and stays
|
|
538
|
+
* focusable; only the pointer says it won't change. The row's icon (a lock) sits at its end, like a field's icon. */
|
|
539
|
+
.aura-switch-row.is-readonly, .aura-switch-row.is-readonly .aura-switch, .aura-switch-row.is-readonly .aura-choice__label { cursor: default; }
|
|
540
|
+
.aura-switch-row__icon { flex: none; margin-inline-start: auto; margin-top: 2px; width: var(--aura-icon-sm); height: var(--aura-icon-sm); color: var(--aura-fg-secondary); }
|
|
533
541
|
|
|
534
542
|
/* ---------- Alerts & toasts ---------- */
|
|
535
543
|
.aura-alert {
|
|
@@ -1416,7 +1424,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1416
1424
|
padding-block: calc((var(--aura-touch-target) - 20px) / 2);
|
|
1417
1425
|
}
|
|
1418
1426
|
.aura-check--labelled .aura-check__input { top: calc((var(--aura-touch-target) - 20px) / 2 + 3px); }
|
|
1419
|
-
.aura-switch-row:not(.is-disabled) { cursor: pointer; }
|
|
1427
|
+
.aura-switch-row:not(.is-disabled):not(.is-readonly) { cursor: pointer; }
|
|
1420
1428
|
.aura-radio-group__list { gap: 0; }
|
|
1421
1429
|
.aura-radio-group__list.is-horizontal { gap: 0 var(--aura-space-6); }
|
|
1422
1430
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-react",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.19.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",
|