@jirawatpyk/aura-react 5.10.0 → 5.10.1

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 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.10.1 — fixes from a new project
190
+
191
+ - **Switch**: a disabled switch that is on ("always on", enforced by policy) no longer fades into the same grey as an off one. Disabled rows, on or off, now look alike and stay readable: the label turns `aura-fg-secondary`, the description (often the reason it's locked) keeps its colour, the row shows a not-allowed cursor, and only the switch fades — off to the disabled opacity, on to 0.75, at least 3:1 apart in both themes. In forced colours a locked switch is `GrayText`. Use it instead of a Badge for settings people can see but not change.
192
+ - **Tag**: the remove button is named from the words inside any children — `<Tag onRemove={…}><strong>Acme</strong> AB</Tag>` is "Remove Acme AB" (was "Remove "). With no text at all (an icon only), a dev notice asks for `removeLabel`.
193
+ - **SideNav** (docs): an item's `badge` takes any element, so a fault or warning is a toned Badge — `badge: <Badge tone="danger">Fault</Badge>`; `count` stays a neutral number.
194
+
189
195
  ## 5.10 — Chamber-OS addendum 10 (adopting 5.9)
190
196
 
191
197
  - **Tabs `variant="segmented"`** (item 72): the tab list as a pill track with the selected tab raised — SegmentedControl's look — keeping every Tabs behaviour (tab / tabpanel roles, `keepMounted`, `activation`, `tabProps`). `fullWidth` stretches the track and shares it equally. Tabs are 44px on touch screens, the list doesn't scroll so the focus ring is never clipped, and in forced colours the selected tab gets a `Highlight` outline. Default (`underline`) output is unchanged.
@@ -3883,6 +3883,16 @@ window.Aura = (() => {
3883
3883
 
3884
3884
  // src/Tag.tsx
3885
3885
  var React24 = __toESM(require_react(), 1);
3886
+ function textOf(node) {
3887
+ if (node == null || typeof node === "boolean") return "";
3888
+ if (typeof node === "string" || typeof node === "number") return String(node);
3889
+ if (Array.isArray(node)) return node.map(textOf).join("");
3890
+ if (React24.isValidElement(node)) {
3891
+ const p = node.props;
3892
+ return p["aria-hidden"] === true || p["aria-hidden"] === "true" ? "" : textOf(p.children);
3893
+ }
3894
+ return "";
3895
+ }
3886
3896
  var Tag = React24.forwardRef(function Tag2(props, ref) {
3887
3897
  const t = useStrings();
3888
3898
  const selectable = props.onClick != null || props.selected != null;
@@ -3906,12 +3916,18 @@ window.Aura = (() => {
3906
3916
  inner[1]
3907
3917
  );
3908
3918
  }
3919
+ const name = props.onRemove && !props.removeLabel ? textOf(props.children).replace(/\s+/g, " ").trim() : "";
3920
+ if (props.onRemove && !props.disabled && !props.removeLabel && !name)
3921
+ devWarnOnce(
3922
+ "tag-remove-label",
3923
+ 'Tag: the remove button has no name \u2014 its children have no text. Pass removeLabel (e.g. "Remove Acme AB").'
3924
+ );
3909
3925
  return /* @__PURE__ */ React24.createElement("span", { ...rest, ref, className: cx("aura-tag", props.disabled && "is-disabled", props.className) }, inner, props.onRemove && !props.disabled ? /* @__PURE__ */ React24.createElement(
3910
3926
  "button",
3911
3927
  {
3912
3928
  type: "button",
3913
3929
  className: "aura-tag__remove",
3914
- "aria-label": props.removeLabel || t.remove(typeof props.children === "string" ? props.children : ""),
3930
+ "aria-label": props.removeLabel || t.remove(name),
3915
3931
  onClick: props.onRemove
3916
3932
  },
3917
3933
  /* @__PURE__ */ React24.createElement(Icon, { name: /* @__PURE__ */ React24.createElement(IconX, null), size: 12 })
@@ -3865,6 +3865,16 @@ var React25 = __toESM(require("react"), 1);
3865
3865
 
3866
3866
  // src/Tag.tsx
3867
3867
  var React24 = __toESM(require("react"), 1);
3868
+ function textOf(node) {
3869
+ if (node == null || typeof node === "boolean") return "";
3870
+ if (typeof node === "string" || typeof node === "number") return String(node);
3871
+ if (Array.isArray(node)) return node.map(textOf).join("");
3872
+ if (React24.isValidElement(node)) {
3873
+ const p = node.props;
3874
+ return p["aria-hidden"] === true || p["aria-hidden"] === "true" ? "" : textOf(p.children);
3875
+ }
3876
+ return "";
3877
+ }
3868
3878
  var Tag = React24.forwardRef(function Tag2(props, ref) {
3869
3879
  const t = useStrings();
3870
3880
  const selectable = props.onClick != null || props.selected != null;
@@ -3888,12 +3898,18 @@ var Tag = React24.forwardRef(function Tag2(props, ref) {
3888
3898
  inner[1]
3889
3899
  );
3890
3900
  }
3901
+ const name = props.onRemove && !props.removeLabel ? textOf(props.children).replace(/\s+/g, " ").trim() : "";
3902
+ if (props.onRemove && !props.disabled && !props.removeLabel && !name)
3903
+ devWarnOnce(
3904
+ "tag-remove-label",
3905
+ 'Tag: the remove button has no name \u2014 its children have no text. Pass removeLabel (e.g. "Remove Acme AB").'
3906
+ );
3891
3907
  return /* @__PURE__ */ React24.createElement("span", { ...rest, ref, className: cx("aura-tag", props.disabled && "is-disabled", props.className) }, inner, props.onRemove && !props.disabled ? /* @__PURE__ */ React24.createElement(
3892
3908
  "button",
3893
3909
  {
3894
3910
  type: "button",
3895
3911
  className: "aura-tag__remove",
3896
- "aria-label": props.removeLabel || t.remove(typeof props.children === "string" ? props.children : ""),
3912
+ "aria-label": props.removeLabel || t.remove(name),
3897
3913
  onClick: props.onRemove
3898
3914
  },
3899
3915
  /* @__PURE__ */ React24.createElement(Icon, { name: /* @__PURE__ */ React24.createElement(IconX, null), size: 12 })
package/dist/esm/Tag.js CHANGED
@@ -1,9 +1,19 @@
1
1
  'use client';
2
2
  import * as React from "react";
3
3
  import { Icon } from "./Icon.js";
4
- import { cx, omit } from "./internal.js";
4
+ import { cx, devWarnOnce, omit } from "./internal.js";
5
5
  import { useStrings } from "./locale.js";
6
6
  import { IconCheck, IconX } from "./icons.js";
7
+ function textOf(node) {
8
+ if (node == null || typeof node === "boolean") return "";
9
+ if (typeof node === "string" || typeof node === "number") return String(node);
10
+ if (Array.isArray(node)) return node.map(textOf).join("");
11
+ if (React.isValidElement(node)) {
12
+ const p = node.props;
13
+ return p["aria-hidden"] === true || p["aria-hidden"] === "true" ? "" : textOf(p.children);
14
+ }
15
+ return "";
16
+ }
7
17
  const Tag = React.forwardRef(function Tag2(props, ref) {
8
18
  const t = useStrings();
9
19
  const selectable = props.onClick != null || props.selected != null;
@@ -27,12 +37,18 @@ const Tag = React.forwardRef(function Tag2(props, ref) {
27
37
  inner[1]
28
38
  );
29
39
  }
40
+ const name = props.onRemove && !props.removeLabel ? textOf(props.children).replace(/\s+/g, " ").trim() : "";
41
+ if (props.onRemove && !props.disabled && !props.removeLabel && !name)
42
+ devWarnOnce(
43
+ "tag-remove-label",
44
+ 'Tag: the remove button has no name \u2014 its children have no text. Pass removeLabel (e.g. "Remove Acme AB").'
45
+ );
30
46
  return /* @__PURE__ */ React.createElement("span", { ...rest, ref, className: cx("aura-tag", props.disabled && "is-disabled", props.className) }, inner, props.onRemove && !props.disabled ? /* @__PURE__ */ React.createElement(
31
47
  "button",
32
48
  {
33
49
  type: "button",
34
50
  className: "aura-tag__remove",
35
- "aria-label": props.removeLabel || t.remove(typeof props.children === "string" ? props.children : ""),
51
+ "aria-label": props.removeLabel || t.remove(name),
36
52
  onClick: props.onRemove
37
53
  },
38
54
  /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconX, null), size: 12 })
package/dist/styles.css CHANGED
@@ -466,7 +466,13 @@ a.aura-icon-btn { text-decoration: none; }
466
466
  .aura-radio-group.is-invalid .aura-radio:not(:checked) { border-color: var(--aura-border-danger); }
467
467
 
468
468
  .aura-switch-row { display: flex; align-items: flex-start; gap: var(--aura-space-3); font-family: var(--font-sans); }
469
- .aura-switch-row.is-disabled { opacity: var(--aura-disabled-opacity); }
469
+ /* 5.10.1: disabled rows, on or off, are treated alike and stay readable — the label turns secondary, the description
470
+ * keeps its colour (often the reason it's locked) — and only the switch fades: off to the disabled opacity, on to 0.75,
471
+ * ≥3:1 apart in both themes, so "locked on" never looks like "off". */
472
+ .aura-switch-row.is-disabled { cursor: not-allowed; }
473
+ .aura-switch-row.is-disabled .aura-choice__label { color: var(--aura-fg-secondary); cursor: not-allowed; }
474
+ .aura-switch:disabled { opacity: var(--aura-disabled-opacity); }
475
+ .aura-switch.is-on:disabled { opacity: 0.75; }
470
476
  .aura-switch {
471
477
  position: relative; flex: none; box-sizing: border-box; margin: 0; padding: 0;
472
478
  width: var(--aura-switch-width); height: var(--aura-switch-height); border-radius: var(--aura-radius-full);
@@ -1601,6 +1607,11 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1601
1607
  .aura-switch__thumb { background: CanvasText; forced-color-adjust: none; }
1602
1608
  .aura-switch.is-on { background: Highlight; forced-color-adjust: none; }
1603
1609
  .aura-switch.is-on .aura-switch__thumb { background: HighlightText; }
1610
+ .aura-switch:disabled, .aura-switch.is-on:disabled { border-color: GrayText; opacity: 1; }
1611
+ .aura-switch:disabled .aura-switch__thumb { background: GrayText; }
1612
+ .aura-switch.is-on:disabled { background: GrayText; }
1613
+ .aura-switch.is-on:disabled .aura-switch__thumb { background: Canvas; }
1614
+ .aura-switch-row.is-disabled .aura-choice__label { color: GrayText; }
1604
1615
  .aura-progress__track, .aura-upload__bar { border: 1px solid CanvasText; }
1605
1616
  .aura-progress__bar, .aura-upload__bar > span { background: Highlight; forced-color-adjust: none; }
1606
1617
  .aura-segmented__option.is-selected { outline: 2px solid Highlight; outline-offset: -2px; }
@@ -468,7 +468,13 @@ a.aura-icon-btn { text-decoration: none; }
468
468
  .aura-radio-group.is-invalid .aura-radio:not(:checked) { border-color: var(--aura-border-danger); }
469
469
 
470
470
  .aura-switch-row { display: flex; align-items: flex-start; gap: var(--aura-space-3); font-family: var(--font-sans); }
471
- .aura-switch-row.is-disabled { opacity: var(--aura-disabled-opacity); }
471
+ /* 5.10.1: disabled rows, on or off, are treated alike and stay readable — the label turns secondary, the description
472
+ * keeps its colour (often the reason it's locked) — and only the switch fades: off to the disabled opacity, on to 0.75,
473
+ * ≥3:1 apart in both themes, so "locked on" never looks like "off". */
474
+ .aura-switch-row.is-disabled { cursor: not-allowed; }
475
+ .aura-switch-row.is-disabled .aura-choice__label { color: var(--aura-fg-secondary); cursor: not-allowed; }
476
+ .aura-switch:disabled { opacity: var(--aura-disabled-opacity); }
477
+ .aura-switch.is-on:disabled { opacity: 0.75; }
472
478
  .aura-switch {
473
479
  position: relative; flex: none; box-sizing: border-box; margin: 0; padding: 0;
474
480
  width: var(--aura-switch-width); height: var(--aura-switch-height); border-radius: var(--aura-radius-full);
@@ -1603,6 +1609,11 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1603
1609
  .aura-switch__thumb { background: CanvasText; forced-color-adjust: none; }
1604
1610
  .aura-switch.is-on { background: Highlight; forced-color-adjust: none; }
1605
1611
  .aura-switch.is-on .aura-switch__thumb { background: HighlightText; }
1612
+ .aura-switch:disabled, .aura-switch.is-on:disabled { border-color: GrayText; opacity: 1; }
1613
+ .aura-switch:disabled .aura-switch__thumb { background: GrayText; }
1614
+ .aura-switch.is-on:disabled { background: GrayText; }
1615
+ .aura-switch.is-on:disabled .aura-switch__thumb { background: Canvas; }
1616
+ .aura-switch-row.is-disabled .aura-choice__label { color: GrayText; }
1606
1617
  .aura-progress__track, .aura-upload__bar { border: 1px solid CanvasText; }
1607
1618
  .aura-progress__bar, .aura-upload__bar > span { background: Highlight; forced-color-adjust: none; }
1608
1619
  .aura-segmented__option.is-selected { outline: 2px solid Highlight; outline-offset: -2px; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-react",
3
- "version": "5.10.0",
3
+ "version": "5.10.1",
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",