@jirawatpyk/aura-react 4.10.0 → 4.11.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 CHANGED
@@ -74,10 +74,14 @@ import Link from 'next/link';
74
74
  <AuraProvider locale="sv" linkComponent={Link}> {/* th | en | sv */}
75
75
  ```
76
76
 
77
- `linkComponent` is used by Button `href`, Breadcrumb, Pagination `getHref`, Stat `href`, SideNav and DataTable row/pager links. `sv` uses the Gregorian calendar and Monday first; `th` and `en` default to the Buddhist calendar.
77
+ `linkComponent` is used by Button `href`, Breadcrumb, Pagination `getHref`, Stat `href`, SideNav and DataTable row/pager links. Only `th` shows Buddhist-era years; `en` and `sv` are Gregorian (`sv` weeks start Monday). **Without a provider, components are English with Gregorian dates** — wrap Thai apps in `<AuraProvider locale="th">`. `formatDate()` has no provider to read, so it stays Thai unless you pass `locale`. Values are always Gregorian ISO dates.
78
78
 
79
79
  Motion: skeleton pulses and indeterminate bars honour `prefers-reduced-motion: reduce` — skeletons stop (a static bar), spinners and progress bars slow to a third.
80
80
 
81
+ ## Phones and touch
82
+
83
+ Under 640px every text control uses 16px text (iOS Safari doesn't zoom). On touch screens (`pointer: coarse`) IconButton keeps its 32px look with a 44px hit area, and Radio, Checkbox and Switch rows are at least 44px with the whole row as the target. `<Button fullWidth>` fills its row and wraps long Thai or Swedish labels.
84
+
81
85
  ## Light and dark
82
86
 
83
87
  The tokens carry both schemes; `<html data-theme="light|dark|system">` picks one (`system` follows the OS in pure CSS).
@@ -106,7 +110,7 @@ Every component forwards `ref` to its real element — fields to the `<input>`/`
106
110
 
107
111
  ## Thai dates
108
112
 
109
- Values are ISO strings (`2026-09-18`); display is Thai with Buddhist-era years (`18 ก.ย. 2569`). People can type `18/09/2569`, `18/09/2026`, `2026-09-18` or `18 ก.ย. 2569`. Store ISO, never พ.ศ. `formatDate(iso, { format: 'long' })` → `18 กันยายน 2569`.
113
+ Values are ISO strings (`2026-09-18`); with `locale="th"` display is Thai with Buddhist-era years (`18 ก.ย. 2569`). People can type `18/09/2569`, `18/09/2026`, `2026-09-18` or `18 ก.ย. 2569`. Store ISO, never พ.ศ. `formatDate(iso, { format: 'long' })` → `18 กันยายน 2569`.
110
114
 
111
115
  ## Server rendering
112
116
 
@@ -602,7 +602,8 @@ window.Aura = (() => {
602
602
  "iconRight",
603
603
  "disabled",
604
604
  "linkComponent",
605
- "href"
605
+ "href",
606
+ "fullWidth"
606
607
  ]);
607
608
  const Tag3 = disabled ? "a" : Link;
608
609
  return /* @__PURE__ */ React4.createElement(
@@ -614,7 +615,7 @@ window.Aura = (() => {
614
615
  role: disabled ? "link" : void 0,
615
616
  "aria-disabled": disabled || void 0,
616
617
  tabIndex: disabled ? -1 : props.tabIndex,
617
- className: cx("aura-btn", "aura-btn--" + variant, props.className),
618
+ className: cx("aura-btn", "aura-btn--" + variant, props.fullWidth && "aura-btn--full", props.className),
618
619
  onClick: disabled ? void 0 : props.onClick
619
620
  },
620
621
  props.icon ? /* @__PURE__ */ React4.createElement(Icon, { name: props.icon }) : null,
@@ -631,14 +632,30 @@ window.Aura = (() => {
631
632
  const props = all;
632
633
  const variant = props.variant || "primary";
633
634
  const loading = !!props.loading;
634
- const rest = omit(props, ["variant", "className", "children", "type", "icon", "iconRight", "loading", "onClick"]);
635
+ const rest = omit(props, [
636
+ "variant",
637
+ "className",
638
+ "children",
639
+ "type",
640
+ "icon",
641
+ "iconRight",
642
+ "loading",
643
+ "onClick",
644
+ "fullWidth"
645
+ ]);
635
646
  return /* @__PURE__ */ React4.createElement(
636
647
  "button",
637
648
  {
638
649
  ...rest,
639
650
  ref,
640
651
  type: props.type || "button",
641
- className: cx("aura-btn", "aura-btn--" + variant, loading && "is-loading", props.className),
652
+ className: cx(
653
+ "aura-btn",
654
+ "aura-btn--" + variant,
655
+ props.fullWidth && "aura-btn--full",
656
+ loading && "is-loading",
657
+ props.className
658
+ ),
642
659
  "aria-busy": loading || void 0,
643
660
  "aria-disabled": loading || void 0,
644
661
  onClick: loading ? function(e) {
@@ -1081,25 +1098,37 @@ window.Aura = (() => {
1081
1098
  const auto = uid(), id = props.id || auto;
1082
1099
  const st = useMaybeControlled(props.checked, !!props.defaultChecked, props.onChange);
1083
1100
  const on = !!st[0];
1084
- return /* @__PURE__ */ React15.createElement("div", { className: cx("aura-switch-row", props.disabled && "is-disabled", props.className) }, /* @__PURE__ */ React15.createElement(
1085
- "button",
1101
+ return /* @__PURE__ */ React15.createElement(
1102
+ "div",
1086
1103
  {
1087
- ref,
1088
- type: "button",
1089
- role: "switch",
1090
- id,
1091
- "aria-checked": on,
1092
- disabled: props.disabled,
1093
- "aria-labelledby": props.label ? id + "-label" : void 0,
1094
- "aria-label": props.label ? void 0 : props["aria-label"],
1095
- "aria-describedby": props.description ? id + "-desc" : void 0,
1096
- className: cx("aura-switch", on && "is-on"),
1097
- onClick: function() {
1104
+ className: cx("aura-switch-row", props.disabled && "is-disabled", props.className),
1105
+ onClick: function(e) {
1106
+ const t = e.target;
1107
+ if (props.disabled || t.closest("button, label, a, input")) return;
1098
1108
  st[1](!on);
1099
1109
  }
1100
1110
  },
1101
- /* @__PURE__ */ React15.createElement("span", { className: "aura-switch__thumb" })
1102
- ), props.label ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React15.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : null);
1111
+ /* @__PURE__ */ React15.createElement(
1112
+ "button",
1113
+ {
1114
+ ref,
1115
+ type: "button",
1116
+ role: "switch",
1117
+ id,
1118
+ "aria-checked": on,
1119
+ disabled: props.disabled,
1120
+ "aria-labelledby": props.label ? id + "-label" : void 0,
1121
+ "aria-label": props.label ? void 0 : props["aria-label"],
1122
+ "aria-describedby": props.description ? id + "-desc" : void 0,
1123
+ className: cx("aura-switch", on && "is-on"),
1124
+ onClick: function() {
1125
+ st[1](!on);
1126
+ }
1127
+ },
1128
+ /* @__PURE__ */ React15.createElement("span", { className: "aura-switch__thumb" })
1129
+ ),
1130
+ props.label ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React15.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : null
1131
+ );
1103
1132
  });
1104
1133
 
1105
1134
  // src/Combobox.tsx
@@ -1473,11 +1502,11 @@ window.Aura = (() => {
1473
1502
  }
1474
1503
  var TAGS = { th: "th-TH", en: "en-GB", sv: "sv-SE" };
1475
1504
  function defaultCalendar(locale) {
1476
- return locale === "sv" ? "gregory" : "buddhist";
1505
+ return locale === "th" ? "buddhist" : "gregory";
1477
1506
  }
1478
1507
  function localeTag(locale, calendar) {
1479
1508
  const cal = calendar || defaultCalendar(locale);
1480
- return (TAGS[locale || "th"] || "th-TH") + "-u-ca-" + (cal === "gregory" ? "gregory" : "buddhist");
1509
+ return (TAGS[locale || "en"] || "en-GB") + "-u-ca-" + (cal === "gregory" ? "gregory" : "buddhist");
1481
1510
  }
1482
1511
  var DATE_TEXT = {
1483
1512
  th: {
@@ -1505,11 +1534,11 @@ window.Aura = (() => {
1505
1534
  today: "Today",
1506
1535
  clear: "Clear",
1507
1536
  chooseDate: "Choose date",
1508
- datePlaceholder: "dd/mm/yyyy",
1537
+ datePlaceholder: "DD/MM/YYYY",
1509
1538
  clearDate: "Clear date",
1510
1539
  openCalendar: "Open calendar",
1511
1540
  chooseDates: "Choose dates",
1512
- rangePlaceholder: "dd/mm/yyyy \u2013 dd/mm/yyyy",
1541
+ rangePlaceholder: "DD/MM/YYYY \u2013 DD/MM/YYYY",
1513
1542
  clearDates: "Clear dates",
1514
1543
  chooseStart: "Choose the start date",
1515
1544
  chooseEnd: "Choose the end date"
@@ -1533,7 +1562,7 @@ window.Aura = (() => {
1533
1562
  }
1534
1563
  };
1535
1564
  function dateText(locale) {
1536
- return DATE_TEXT[locale || "th"] || DATE_TEXT.th;
1565
+ return DATE_TEXT[locale || "en"] || DATE_TEXT.en;
1537
1566
  }
1538
1567
  var fmtCache = {};
1539
1568
  var PRESETS = {
@@ -1550,7 +1579,8 @@ window.Aura = (() => {
1550
1579
  const o = opts || {}, d = fromISO(iso);
1551
1580
  if (!d) return "";
1552
1581
  const f = typeof o.format === "object" ? o.format : PRESETS[o.format || "short"];
1553
- return fmt(localeTag(o.locale, o.calendar), f, d).replace(ERA, "");
1582
+ const loc = o.locale || "th";
1583
+ return fmt(localeTag(loc, o.calendar || defaultCalendar(loc)), f, d).replace(ERA, "");
1554
1584
  }
1555
1585
  var MONTHS = null;
1556
1586
  function monthIndex(word) {
@@ -1590,7 +1620,7 @@ window.Aura = (() => {
1590
1620
  return dt.getMonth() === mo - 1 && dt.getDate() === d ? toISO(dt) : null;
1591
1621
  }
1592
1622
  var Calendar = React17.forwardRef(function Calendar2(props, ref) {
1593
- const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "th", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), tag = localeTag(locale, calendar);
1623
+ const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), tag = localeTag(locale, calendar);
1594
1624
  const weekStart = props.weekStartsOn == null ? locale === "sv" ? 1 : 0 : props.weekStartsOn;
1595
1625
  let today = /* @__PURE__ */ new Date();
1596
1626
  today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
@@ -1775,6 +1805,7 @@ window.Aura = (() => {
1775
1805
  tabIndex: same(d, focusDate) ? 0 : -1,
1776
1806
  disabled: dis,
1777
1807
  "aria-label": fmt(tag, { weekday: "long", day: "numeric", month: "long", year: "numeric" }, d),
1808
+ suppressHydrationWarning: true,
1778
1809
  "aria-current": same(d, today) ? "date" : void 0,
1779
1810
  "aria-pressed": sel || void 0,
1780
1811
  className: cx(
@@ -1933,7 +1964,7 @@ window.Aura = (() => {
1933
1964
  }
1934
1965
  var DatePicker = React17.forwardRef(function DatePicker2(props, ref) {
1935
1966
  const auto = uid(), id = props.id || auto, dialogId = id + "-cal";
1936
- const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "th", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
1967
+ const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
1937
1968
  const st = useMaybeControlled(
1938
1969
  props.value,
1939
1970
  props.defaultValue == null ? null : props.defaultValue,
@@ -2028,7 +2059,7 @@ window.Aura = (() => {
2028
2059
  var DateRangePicker = React17.forwardRef(
2029
2060
  function DateRangePicker2(props, ref) {
2030
2061
  const auto = uid(), id = props.id || auto, dialogId = id + "-cal";
2031
- const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "th", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
2062
+ const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
2032
2063
  const st = useMaybeControlled(
2033
2064
  props.value,
2034
2065
  props.defaultValue || { start: null, end: null },
@@ -4666,8 +4697,8 @@ window.Aura = (() => {
4666
4697
  D["alert-info-bg"] = D["bg-selected"];
4667
4698
  D["alert-info-fg"] = fit(b[300], [D["alert-info-bg"]], 4.5, 1);
4668
4699
  D["alert-info-border"] = mix(ZINC[900], b[400], 0.4);
4669
- D["status-progress-bg"] = b[100];
4670
- D["status-progress-fg"] = L["status-progress-fg"];
4700
+ D["status-progress-bg"] = mix(ZINC[900], b[500], 0.2);
4701
+ D["status-progress-fg"] = fit(b[300], [D["status-progress-bg"]], 4.5, 1);
4671
4702
  if (s) {
4672
4703
  L["accent-dot"] = s[200];
4673
4704
  L["accent-lime"] = s[200];
@@ -4734,6 +4765,7 @@ window.Aura = (() => {
4734
4765
  check("light", "fg-primary", "bg-selected", 4.5, INK, L["bg-selected"]);
4735
4766
  check("dark", "fg-primary", "bg-selected", 4.5, "#ffffff", D["bg-selected"]);
4736
4767
  check("light", "status-progress-fg", "status-progress-bg", 4.5, L["status-progress-fg"], L["status-progress-bg"]);
4768
+ check("dark", "status-progress-fg", "status-progress-bg", 4.5, D["status-progress-fg"], D["status-progress-bg"]);
4737
4769
  check("light", "alert-info-fg", "alert-info-bg", 4.5, L["alert-info-fg"], L["alert-info-bg"]);
4738
4770
  check("dark", "alert-info-fg", "alert-info-bg", 4.5, D["alert-info-fg"], D["alert-info-bg"]);
4739
4771
  if (o.primary === "brand") {
@@ -584,7 +584,8 @@ function ButtonLink(props, ref, Link) {
584
584
  "iconRight",
585
585
  "disabled",
586
586
  "linkComponent",
587
- "href"
587
+ "href",
588
+ "fullWidth"
588
589
  ]);
589
590
  const Tag3 = disabled ? "a" : Link;
590
591
  return /* @__PURE__ */ React4.createElement(
@@ -596,7 +597,7 @@ function ButtonLink(props, ref, Link) {
596
597
  role: disabled ? "link" : void 0,
597
598
  "aria-disabled": disabled || void 0,
598
599
  tabIndex: disabled ? -1 : props.tabIndex,
599
- className: cx("aura-btn", "aura-btn--" + variant, props.className),
600
+ className: cx("aura-btn", "aura-btn--" + variant, props.fullWidth && "aura-btn--full", props.className),
600
601
  onClick: disabled ? void 0 : props.onClick
601
602
  },
602
603
  props.icon ? /* @__PURE__ */ React4.createElement(Icon, { name: props.icon }) : null,
@@ -613,14 +614,30 @@ var Button = React4.forwardRef(
613
614
  const props = all;
614
615
  const variant = props.variant || "primary";
615
616
  const loading = !!props.loading;
616
- const rest = omit(props, ["variant", "className", "children", "type", "icon", "iconRight", "loading", "onClick"]);
617
+ const rest = omit(props, [
618
+ "variant",
619
+ "className",
620
+ "children",
621
+ "type",
622
+ "icon",
623
+ "iconRight",
624
+ "loading",
625
+ "onClick",
626
+ "fullWidth"
627
+ ]);
617
628
  return /* @__PURE__ */ React4.createElement(
618
629
  "button",
619
630
  {
620
631
  ...rest,
621
632
  ref,
622
633
  type: props.type || "button",
623
- className: cx("aura-btn", "aura-btn--" + variant, loading && "is-loading", props.className),
634
+ className: cx(
635
+ "aura-btn",
636
+ "aura-btn--" + variant,
637
+ props.fullWidth && "aura-btn--full",
638
+ loading && "is-loading",
639
+ props.className
640
+ ),
624
641
  "aria-busy": loading || void 0,
625
642
  "aria-disabled": loading || void 0,
626
643
  onClick: loading ? function(e) {
@@ -1063,25 +1080,37 @@ var Switch = React15.forwardRef(function Switch2(props, ref) {
1063
1080
  const auto = uid(), id = props.id || auto;
1064
1081
  const st = useMaybeControlled(props.checked, !!props.defaultChecked, props.onChange);
1065
1082
  const on = !!st[0];
1066
- return /* @__PURE__ */ React15.createElement("div", { className: cx("aura-switch-row", props.disabled && "is-disabled", props.className) }, /* @__PURE__ */ React15.createElement(
1067
- "button",
1083
+ return /* @__PURE__ */ React15.createElement(
1084
+ "div",
1068
1085
  {
1069
- ref,
1070
- type: "button",
1071
- role: "switch",
1072
- id,
1073
- "aria-checked": on,
1074
- disabled: props.disabled,
1075
- "aria-labelledby": props.label ? id + "-label" : void 0,
1076
- "aria-label": props.label ? void 0 : props["aria-label"],
1077
- "aria-describedby": props.description ? id + "-desc" : void 0,
1078
- className: cx("aura-switch", on && "is-on"),
1079
- onClick: function() {
1086
+ className: cx("aura-switch-row", props.disabled && "is-disabled", props.className),
1087
+ onClick: function(e) {
1088
+ const t = e.target;
1089
+ if (props.disabled || t.closest("button, label, a, input")) return;
1080
1090
  st[1](!on);
1081
1091
  }
1082
1092
  },
1083
- /* @__PURE__ */ React15.createElement("span", { className: "aura-switch__thumb" })
1084
- ), props.label ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React15.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : null);
1093
+ /* @__PURE__ */ React15.createElement(
1094
+ "button",
1095
+ {
1096
+ ref,
1097
+ type: "button",
1098
+ role: "switch",
1099
+ id,
1100
+ "aria-checked": on,
1101
+ disabled: props.disabled,
1102
+ "aria-labelledby": props.label ? id + "-label" : void 0,
1103
+ "aria-label": props.label ? void 0 : props["aria-label"],
1104
+ "aria-describedby": props.description ? id + "-desc" : void 0,
1105
+ className: cx("aura-switch", on && "is-on"),
1106
+ onClick: function() {
1107
+ st[1](!on);
1108
+ }
1109
+ },
1110
+ /* @__PURE__ */ React15.createElement("span", { className: "aura-switch__thumb" })
1111
+ ),
1112
+ props.label ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React15.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : null
1113
+ );
1085
1114
  });
1086
1115
 
1087
1116
  // src/Combobox.tsx
@@ -1455,11 +1484,11 @@ function same(a, b) {
1455
1484
  }
1456
1485
  var TAGS = { th: "th-TH", en: "en-GB", sv: "sv-SE" };
1457
1486
  function defaultCalendar(locale) {
1458
- return locale === "sv" ? "gregory" : "buddhist";
1487
+ return locale === "th" ? "buddhist" : "gregory";
1459
1488
  }
1460
1489
  function localeTag(locale, calendar) {
1461
1490
  const cal = calendar || defaultCalendar(locale);
1462
- return (TAGS[locale || "th"] || "th-TH") + "-u-ca-" + (cal === "gregory" ? "gregory" : "buddhist");
1491
+ return (TAGS[locale || "en"] || "en-GB") + "-u-ca-" + (cal === "gregory" ? "gregory" : "buddhist");
1463
1492
  }
1464
1493
  var DATE_TEXT = {
1465
1494
  th: {
@@ -1487,11 +1516,11 @@ var DATE_TEXT = {
1487
1516
  today: "Today",
1488
1517
  clear: "Clear",
1489
1518
  chooseDate: "Choose date",
1490
- datePlaceholder: "dd/mm/yyyy",
1519
+ datePlaceholder: "DD/MM/YYYY",
1491
1520
  clearDate: "Clear date",
1492
1521
  openCalendar: "Open calendar",
1493
1522
  chooseDates: "Choose dates",
1494
- rangePlaceholder: "dd/mm/yyyy \u2013 dd/mm/yyyy",
1523
+ rangePlaceholder: "DD/MM/YYYY \u2013 DD/MM/YYYY",
1495
1524
  clearDates: "Clear dates",
1496
1525
  chooseStart: "Choose the start date",
1497
1526
  chooseEnd: "Choose the end date"
@@ -1515,7 +1544,7 @@ var DATE_TEXT = {
1515
1544
  }
1516
1545
  };
1517
1546
  function dateText(locale) {
1518
- return DATE_TEXT[locale || "th"] || DATE_TEXT.th;
1547
+ return DATE_TEXT[locale || "en"] || DATE_TEXT.en;
1519
1548
  }
1520
1549
  var fmtCache = {};
1521
1550
  var PRESETS = {
@@ -1532,7 +1561,8 @@ function formatDate(iso, opts) {
1532
1561
  const o = opts || {}, d = fromISO(iso);
1533
1562
  if (!d) return "";
1534
1563
  const f = typeof o.format === "object" ? o.format : PRESETS[o.format || "short"];
1535
- return fmt(localeTag(o.locale, o.calendar), f, d).replace(ERA, "");
1564
+ const loc = o.locale || "th";
1565
+ return fmt(localeTag(loc, o.calendar || defaultCalendar(loc)), f, d).replace(ERA, "");
1536
1566
  }
1537
1567
  var MONTHS = null;
1538
1568
  function monthIndex(word) {
@@ -1572,7 +1602,7 @@ function parseDate(text) {
1572
1602
  return dt.getMonth() === mo - 1 && dt.getDate() === d ? toISO(dt) : null;
1573
1603
  }
1574
1604
  var Calendar = React17.forwardRef(function Calendar2(props, ref) {
1575
- const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "th", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), tag = localeTag(locale, calendar);
1605
+ const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), tag = localeTag(locale, calendar);
1576
1606
  const weekStart = props.weekStartsOn == null ? locale === "sv" ? 1 : 0 : props.weekStartsOn;
1577
1607
  let today = /* @__PURE__ */ new Date();
1578
1608
  today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
@@ -1757,6 +1787,7 @@ var Calendar = React17.forwardRef(function Calendar2(props, ref) {
1757
1787
  tabIndex: same(d, focusDate) ? 0 : -1,
1758
1788
  disabled: dis,
1759
1789
  "aria-label": fmt(tag, { weekday: "long", day: "numeric", month: "long", year: "numeric" }, d),
1790
+ suppressHydrationWarning: true,
1760
1791
  "aria-current": same(d, today) ? "date" : void 0,
1761
1792
  "aria-pressed": sel || void 0,
1762
1793
  className: cx(
@@ -1915,7 +1946,7 @@ function DateField(props) {
1915
1946
  }
1916
1947
  var DatePicker = React17.forwardRef(function DatePicker2(props, ref) {
1917
1948
  const auto = uid(), id = props.id || auto, dialogId = id + "-cal";
1918
- const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "th", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
1949
+ const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
1919
1950
  const st = useMaybeControlled(
1920
1951
  props.value,
1921
1952
  props.defaultValue == null ? null : props.defaultValue,
@@ -2010,7 +2041,7 @@ var DatePicker = React17.forwardRef(function DatePicker2(props, ref) {
2010
2041
  var DateRangePicker = React17.forwardRef(
2011
2042
  function DateRangePicker2(props, ref) {
2012
2043
  const auto = uid(), id = props.id || auto, dialogId = id + "-cal";
2013
- const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "th", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
2044
+ const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
2014
2045
  const st = useMaybeControlled(
2015
2046
  props.value,
2016
2047
  props.defaultValue || { start: null, end: null },
@@ -4648,8 +4679,8 @@ function createTheme(opts) {
4648
4679
  D["alert-info-bg"] = D["bg-selected"];
4649
4680
  D["alert-info-fg"] = fit(b[300], [D["alert-info-bg"]], 4.5, 1);
4650
4681
  D["alert-info-border"] = mix(ZINC[900], b[400], 0.4);
4651
- D["status-progress-bg"] = b[100];
4652
- D["status-progress-fg"] = L["status-progress-fg"];
4682
+ D["status-progress-bg"] = mix(ZINC[900], b[500], 0.2);
4683
+ D["status-progress-fg"] = fit(b[300], [D["status-progress-bg"]], 4.5, 1);
4653
4684
  if (s) {
4654
4685
  L["accent-dot"] = s[200];
4655
4686
  L["accent-lime"] = s[200];
@@ -4716,6 +4747,7 @@ function createTheme(opts) {
4716
4747
  check("light", "fg-primary", "bg-selected", 4.5, INK, L["bg-selected"]);
4717
4748
  check("dark", "fg-primary", "bg-selected", 4.5, "#ffffff", D["bg-selected"]);
4718
4749
  check("light", "status-progress-fg", "status-progress-bg", 4.5, L["status-progress-fg"], L["status-progress-bg"]);
4750
+ check("dark", "status-progress-fg", "status-progress-bg", 4.5, D["status-progress-fg"], D["status-progress-bg"]);
4719
4751
  check("light", "alert-info-fg", "alert-info-bg", 4.5, L["alert-info-fg"], L["alert-info-bg"]);
4720
4752
  check("dark", "alert-info-fg", "alert-info-bg", 4.5, D["alert-info-fg"], D["alert-info-bg"]);
4721
4753
  if (o.primary === "brand") {
@@ -14,7 +14,8 @@ function ButtonLink(props, ref, Link) {
14
14
  "iconRight",
15
15
  "disabled",
16
16
  "linkComponent",
17
- "href"
17
+ "href",
18
+ "fullWidth"
18
19
  ]);
19
20
  const Tag = disabled ? "a" : Link;
20
21
  return /* @__PURE__ */ React.createElement(
@@ -26,7 +27,7 @@ function ButtonLink(props, ref, Link) {
26
27
  role: disabled ? "link" : void 0,
27
28
  "aria-disabled": disabled || void 0,
28
29
  tabIndex: disabled ? -1 : props.tabIndex,
29
- className: cx("aura-btn", "aura-btn--" + variant, props.className),
30
+ className: cx("aura-btn", "aura-btn--" + variant, props.fullWidth && "aura-btn--full", props.className),
30
31
  onClick: disabled ? void 0 : props.onClick
31
32
  },
32
33
  props.icon ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon }) : null,
@@ -43,14 +44,30 @@ const Button = React.forwardRef(
43
44
  const props = all;
44
45
  const variant = props.variant || "primary";
45
46
  const loading = !!props.loading;
46
- const rest = omit(props, ["variant", "className", "children", "type", "icon", "iconRight", "loading", "onClick"]);
47
+ const rest = omit(props, [
48
+ "variant",
49
+ "className",
50
+ "children",
51
+ "type",
52
+ "icon",
53
+ "iconRight",
54
+ "loading",
55
+ "onClick",
56
+ "fullWidth"
57
+ ]);
47
58
  return /* @__PURE__ */ React.createElement(
48
59
  "button",
49
60
  {
50
61
  ...rest,
51
62
  ref,
52
63
  type: props.type || "button",
53
- className: cx("aura-btn", "aura-btn--" + variant, loading && "is-loading", props.className),
64
+ className: cx(
65
+ "aura-btn",
66
+ "aura-btn--" + variant,
67
+ props.fullWidth && "aura-btn--full",
68
+ loading && "is-loading",
69
+ props.className
70
+ ),
54
71
  "aria-busy": loading || void 0,
55
72
  "aria-disabled": loading || void 0,
56
73
  onClick: loading ? function(e) {
@@ -31,11 +31,11 @@ function same(a, b) {
31
31
  }
32
32
  const TAGS = { th: "th-TH", en: "en-GB", sv: "sv-SE" };
33
33
  function defaultCalendar(locale) {
34
- return locale === "sv" ? "gregory" : "buddhist";
34
+ return locale === "th" ? "buddhist" : "gregory";
35
35
  }
36
36
  function localeTag(locale, calendar) {
37
37
  const cal = calendar || defaultCalendar(locale);
38
- return (TAGS[locale || "th"] || "th-TH") + "-u-ca-" + (cal === "gregory" ? "gregory" : "buddhist");
38
+ return (TAGS[locale || "en"] || "en-GB") + "-u-ca-" + (cal === "gregory" ? "gregory" : "buddhist");
39
39
  }
40
40
  const DATE_TEXT = {
41
41
  th: {
@@ -63,11 +63,11 @@ const DATE_TEXT = {
63
63
  today: "Today",
64
64
  clear: "Clear",
65
65
  chooseDate: "Choose date",
66
- datePlaceholder: "dd/mm/yyyy",
66
+ datePlaceholder: "DD/MM/YYYY",
67
67
  clearDate: "Clear date",
68
68
  openCalendar: "Open calendar",
69
69
  chooseDates: "Choose dates",
70
- rangePlaceholder: "dd/mm/yyyy \u2013 dd/mm/yyyy",
70
+ rangePlaceholder: "DD/MM/YYYY \u2013 DD/MM/YYYY",
71
71
  clearDates: "Clear dates",
72
72
  chooseStart: "Choose the start date",
73
73
  chooseEnd: "Choose the end date"
@@ -91,7 +91,7 @@ const DATE_TEXT = {
91
91
  }
92
92
  };
93
93
  function dateText(locale) {
94
- return DATE_TEXT[locale || "th"] || DATE_TEXT.th;
94
+ return DATE_TEXT[locale || "en"] || DATE_TEXT.en;
95
95
  }
96
96
  const fmtCache = {};
97
97
  const PRESETS = {
@@ -108,7 +108,8 @@ function formatDate(iso, opts) {
108
108
  const o = opts || {}, d = fromISO(iso);
109
109
  if (!d) return "";
110
110
  const f = typeof o.format === "object" ? o.format : PRESETS[o.format || "short"];
111
- return fmt(localeTag(o.locale, o.calendar), f, d).replace(ERA, "");
111
+ const loc = o.locale || "th";
112
+ return fmt(localeTag(loc, o.calendar || defaultCalendar(loc)), f, d).replace(ERA, "");
112
113
  }
113
114
  let MONTHS = null;
114
115
  function monthIndex(word) {
@@ -148,7 +149,7 @@ function parseDate(text) {
148
149
  return dt.getMonth() === mo - 1 && dt.getDate() === d ? toISO(dt) : null;
149
150
  }
150
151
  const Calendar = React.forwardRef(function Calendar2(props, ref) {
151
- const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "th", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), tag = localeTag(locale, calendar);
152
+ const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), tag = localeTag(locale, calendar);
152
153
  const weekStart = props.weekStartsOn == null ? locale === "sv" ? 1 : 0 : props.weekStartsOn;
153
154
  let today = /* @__PURE__ */ new Date();
154
155
  today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
@@ -333,6 +334,7 @@ const Calendar = React.forwardRef(function Calendar2(props, ref) {
333
334
  tabIndex: same(d, focusDate) ? 0 : -1,
334
335
  disabled: dis,
335
336
  "aria-label": fmt(tag, { weekday: "long", day: "numeric", month: "long", year: "numeric" }, d),
337
+ suppressHydrationWarning: true,
336
338
  "aria-current": same(d, today) ? "date" : void 0,
337
339
  "aria-pressed": sel || void 0,
338
340
  className: cx(
@@ -491,7 +493,7 @@ function DateField(props) {
491
493
  }
492
494
  const DatePicker = React.forwardRef(function DatePicker2(props, ref) {
493
495
  const auto = uid(), id = props.id || auto, dialogId = id + "-cal";
494
- const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "th", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
496
+ const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
495
497
  const st = useMaybeControlled(
496
498
  props.value,
497
499
  props.defaultValue == null ? null : props.defaultValue,
@@ -586,7 +588,7 @@ const DatePicker = React.forwardRef(function DatePicker2(props, ref) {
586
588
  const DateRangePicker = React.forwardRef(
587
589
  function DateRangePicker2(props, ref) {
588
590
  const auto = uid(), id = props.id || auto, dialogId = id + "-cal";
589
- const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "th", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
591
+ const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), dt = dateText(locale);
590
592
  const st = useMaybeControlled(
591
593
  props.value,
592
594
  props.defaultValue || { start: null, end: null },
@@ -5,25 +5,37 @@ const Switch = React.forwardRef(function Switch2(props, ref) {
5
5
  const auto = uid(), id = props.id || auto;
6
6
  const st = useMaybeControlled(props.checked, !!props.defaultChecked, props.onChange);
7
7
  const on = !!st[0];
8
- return /* @__PURE__ */ React.createElement("div", { className: cx("aura-switch-row", props.disabled && "is-disabled", props.className) }, /* @__PURE__ */ React.createElement(
9
- "button",
8
+ return /* @__PURE__ */ React.createElement(
9
+ "div",
10
10
  {
11
- ref,
12
- type: "button",
13
- role: "switch",
14
- id,
15
- "aria-checked": on,
16
- disabled: props.disabled,
17
- "aria-labelledby": props.label ? id + "-label" : void 0,
18
- "aria-label": props.label ? void 0 : props["aria-label"],
19
- "aria-describedby": props.description ? id + "-desc" : void 0,
20
- className: cx("aura-switch", on && "is-on"),
21
- onClick: function() {
11
+ className: cx("aura-switch-row", props.disabled && "is-disabled", props.className),
12
+ onClick: function(e) {
13
+ const t = e.target;
14
+ if (props.disabled || t.closest("button, label, a, input")) return;
22
15
  st[1](!on);
23
16
  }
24
17
  },
25
- /* @__PURE__ */ React.createElement("span", { className: "aura-switch__thumb" })
26
- ), 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) : null);
18
+ /* @__PURE__ */ React.createElement(
19
+ "button",
20
+ {
21
+ ref,
22
+ type: "button",
23
+ role: "switch",
24
+ id,
25
+ "aria-checked": on,
26
+ disabled: props.disabled,
27
+ "aria-labelledby": props.label ? id + "-label" : void 0,
28
+ "aria-label": props.label ? void 0 : props["aria-label"],
29
+ "aria-describedby": props.description ? id + "-desc" : void 0,
30
+ className: cx("aura-switch", on && "is-on"),
31
+ onClick: function() {
32
+ st[1](!on);
33
+ }
34
+ },
35
+ /* @__PURE__ */ React.createElement("span", { className: "aura-switch__thumb" })
36
+ ),
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) : null
38
+ );
27
39
  });
28
40
  export {
29
41
  Switch
package/dist/esm/theme.js CHANGED
@@ -152,8 +152,8 @@ function createTheme(opts) {
152
152
  D["alert-info-bg"] = D["bg-selected"];
153
153
  D["alert-info-fg"] = fit(b[300], [D["alert-info-bg"]], 4.5, 1);
154
154
  D["alert-info-border"] = mix(ZINC[900], b[400], 0.4);
155
- D["status-progress-bg"] = b[100];
156
- D["status-progress-fg"] = L["status-progress-fg"];
155
+ D["status-progress-bg"] = mix(ZINC[900], b[500], 0.2);
156
+ D["status-progress-fg"] = fit(b[300], [D["status-progress-bg"]], 4.5, 1);
157
157
  if (s) {
158
158
  L["accent-dot"] = s[200];
159
159
  L["accent-lime"] = s[200];
@@ -220,6 +220,7 @@ function createTheme(opts) {
220
220
  check("light", "fg-primary", "bg-selected", 4.5, INK, L["bg-selected"]);
221
221
  check("dark", "fg-primary", "bg-selected", 4.5, "#ffffff", D["bg-selected"]);
222
222
  check("light", "status-progress-fg", "status-progress-bg", 4.5, L["status-progress-fg"], L["status-progress-bg"]);
223
+ check("dark", "status-progress-fg", "status-progress-bg", 4.5, D["status-progress-fg"], D["status-progress-bg"]);
223
224
  check("light", "alert-info-fg", "alert-info-bg", 4.5, L["alert-info-fg"], L["alert-info-bg"]);
224
225
  check("dark", "alert-info-fg", "alert-info-bg", 4.5, D["alert-info-fg"], D["alert-info-bg"]);
225
226
  if (o.primary === "brand") {
package/dist/index.d.ts CHANGED
@@ -14,6 +14,8 @@ export interface ButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElem
14
14
  iconRight?: IconInput;
15
15
  /** Shows a spinner in place of the leading icon, sets aria-busy and swallows clicks. Keeps the label and width. */
16
16
  loading?: boolean;
17
+ /** Fills its container and lets a long label wrap onto more lines (at least 44px tall) — phones, Thai and Swedish labels. */
18
+ fullWidth?: boolean;
17
19
  }
18
20
  /** A link that looks like a Button: give `Button` an `href` and it renders an `<a>` (navigation, not actions). */
19
21
  export interface ButtonLinkProps extends Omit<React$1.AnchorHTMLAttributes<HTMLAnchorElement>, "children"> {
@@ -28,6 +30,8 @@ export interface ButtonLinkProps extends Omit<React$1.AnchorHTMLAttributes<HTMLA
28
30
  iconRight?: IconInput;
29
31
  /** Looks unavailable and can't be followed: no href, `aria-disabled`, out of the Tab order. */
30
32
  disabled?: boolean;
33
+ /** Fills its container and lets a long label wrap (at least 44px tall). */
34
+ fullWidth?: boolean;
31
35
  /** A router's link to render instead of `<a>`, e.g. `Link` from `next/link` (client-side navigation). It gets `href`, `className`, the children and the ref. */
32
36
  linkComponent?: React$1.ElementType;
33
37
  }
@@ -174,9 +178,9 @@ export interface SurfaceProps extends React$1.HTMLAttributes<HTMLElement> {
174
178
  }
175
179
  /** Sets the language of built-in labels (pagination, close buttons, empty states…) and the default date display for everything inside. */
176
180
  export interface AuraProviderProps {
177
- /** Built-in labels and date display. `sv` = Swedish labels, `sv-SE` dates, Monday weeks and the Gregorian calendar. Default `en` strings when there is no provider (dates still default to Thai / พ.ศ.). */
181
+ /** Built-in labels and date display. `sv` = Swedish labels, `sv-SE` dates, Monday weeks and the Gregorian calendar. Without a provider everything is English: labels, `en-GB` dates, Gregorian years. */
178
182
  locale?: "th" | "en" | "sv";
179
- /** Default calendar for DatePicker / DateRangePicker / Calendar / formatDate callers that read it. Unset: `buddhist` for `th` and `en` (unchanged), `gregory` for `sv`. */
183
+ /** Default calendar for DatePicker / DateRangePicker / Calendar / formatDate callers that read it. Unset: `buddhist` (พ.ศ.) for `th`, `gregory` for `en` and `sv`. */
180
184
  calendar?: "buddhist" | "gregory";
181
185
  /** Override individual strings. */
182
186
  strings?: Partial<Record<string, string | ((...args: any[]) => string)>>;
@@ -580,9 +584,9 @@ export interface SegmentedControlProps {
580
584
  /** ISO date string, `YYYY-MM-DD` (Gregorian — the era is display only). */
581
585
  export type ISODate = string;
582
586
  export interface DateDisplayOptions {
583
- /** `th` (default), `en` or `sv`. */
587
+ /** Components: the AuraProvider's locale, else `en`. `formatDate()` (no provider to read): `th` unless given. */
584
588
  locale?: "th" | "en" | "sv";
585
- /** `buddhist` (พ.ศ.; default for th and en) or `gregory` (ค.ศ.; default for sv). */
589
+ /** `buddhist` (พ.ศ.; default for th) or `gregory` (ค.ศ.; default for en and sv). */
586
590
  calendar?: "buddhist" | "gregory";
587
591
  }
588
592
  export interface CalendarProps extends DateDisplayOptions {
@@ -965,7 +969,7 @@ export declare function formatDate(iso: ISODate | null | undefined, opts?: Forma
965
969
  /** Parse typed text: dd/mm/yyyy (Buddhist years ≥ 2400 are converted), d-m-yyyy, d.m.yyyy, yyyy-mm-dd or '18 ก.ย. 2569' / '18 Sep 2026'. */
966
970
  export declare function parseDate(text: string | null | undefined): ISODate | null;
967
971
  export declare const Calendar: React$1.ForwardRefExoticComponent<CalendarProps & React$1.RefAttributes<HTMLDivElement>>;
968
- /** Typed date field + calendar popover. Shows Buddhist-era dates (18 ก.ย. 2569); accepts dd/mm/yyyy in พ.ศ. or ค.ศ. and yyyy-mm-dd. */
972
+ /** Typed date field + calendar popover. English / Gregorian unless a locale is set; `th` shows Buddhist-era dates (18 ก.ย. 2569) and accepts พ.ศ. or ค.ศ. years. The value is always a Gregorian ISO date. */
969
973
  export declare const DatePicker: React$1.ForwardRefExoticComponent<DatePickerProps & React$1.RefAttributes<HTMLInputElement>>;
970
974
  export declare const DateRangePicker: React$1.ForwardRefExoticComponent<DateRangePickerProps & React$1.RefAttributes<HTMLInputElement>>;
971
975
  export declare const Alert: React$1.ForwardRefExoticComponent<AlertProps & React$1.RefAttributes<HTMLDivElement>>;
package/dist/styles.css CHANGED
@@ -28,6 +28,11 @@
28
28
  .aura-btn:active { transform: scale(0.98); }
29
29
  .aura-btn:disabled, a.aura-btn[aria-disabled='true'] { opacity: var(--aura-disabled-opacity); pointer-events: none; }
30
30
  a.aura-btn { text-decoration: none; }
31
+ /* fullWidth: fills the row and wraps a long label (Thai and Swedish run ~30% longer) instead of overflowing. */
32
+ .aura-btn--full {
33
+ width: 100%; height: auto; min-height: var(--aura-button-height); white-space: normal; flex-shrink: 1;
34
+ padding-block: var(--aura-space-2); line-height: 1.35; text-align: center; overflow-wrap: anywhere;
35
+ }
31
36
  .aura-btn.is-loading { cursor: progress; }
32
37
  .aura-btn.is-loading:active { transform: none; }
33
38
 
@@ -243,6 +248,11 @@ a.aura-btn { text-decoration: none; }
243
248
  .aura-icon-btn--danger:hover { background: var(--aura-alert-danger-bg); }
244
249
  .aura-icon-btn:disabled { opacity: var(--aura-disabled-opacity); pointer-events: none; }
245
250
  .aura-icon-btn:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: var(--aura-focus-ring-offset); }
251
+ /* Touch: same 32px look, a 44px hit area around it (WCAG 2.5.5). */
252
+ @media (pointer: coarse) {
253
+ .aura-icon-btn { position: relative; }
254
+ .aura-icon-btn::after { content: ''; position: absolute; top: 50%; left: 50%; width: max(100%, var(--aura-touch-target)); height: max(100%, var(--aura-touch-target)); transform: translate(-50%, -50%); }
255
+ }
246
256
 
247
257
  /* Skeleton */
248
258
  @keyframes aura-pulse { 50% { opacity: 0.6; } }
@@ -361,9 +371,11 @@ a.aura-btn { text-decoration: none; }
361
371
  min-height: var(--aura-input-height);
362
372
  background: var(--aura-bg-input); color: var(--aura-fg-primary);
363
373
  border: 1px solid var(--aura-border-control); border-radius: var(--aura-radius-md);
364
- font-family: var(--font-sans); font-size: 14px;
374
+ font-family: var(--font-sans); font-size: var(--aura-input-font-size);
365
375
  transition: border-color var(--aura-duration-fast) var(--aura-ease);
366
376
  }
377
+ /* Phones: iOS Safari zooms into any focused control under 16px and does not zoom back. */
378
+ @media (max-width: 639.98px) { .aura-input { font-size: max(16px, var(--aura-input-font-size)); } }
367
379
  .aura-input:hover { border-color: var(--aura-fg-secondary); }
368
380
  .aura-input:focus-within { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: 1px; border-color: var(--aura-border-strong); }
369
381
  .aura-input__control {
@@ -859,7 +871,7 @@ button.aura-stat { font: inherit; width: 100%; cursor: pointer; }
859
871
  .aura-upload__name { font-size: 13px; font-weight: 500; color: var(--aura-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
860
872
  .aura-upload__sub { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--aura-fg-secondary); }
861
873
  .aura-upload__item.is-error .aura-upload__sub { color: var(--aura-fg-danger); }
862
- .aura-upload__bar { display: block; height: 4px; border-radius: var(--aura-radius-full); background: var(--aura-bg-skeleton); overflow: hidden; }
874
+ .aura-upload__bar { display: block; height: 4px; border-radius: var(--aura-radius-full); background: var(--aura-progress-track); box-shadow: inset 0 0 0 1px var(--aura-progress-track-edge); overflow: hidden; }
863
875
  .aura-upload__bar > span { display: block; height: 100%; background: var(--aura-fg-accent); transition: width var(--aura-duration-base) var(--aura-ease); }
864
876
 
865
877
  /* ---------- Checkbox with a visible label ---------- */
@@ -908,7 +920,7 @@ button.aura-stat { font: inherit; width: 100%; cursor: pointer; }
908
920
  .aura-progress__head { display: flex; justify-content: space-between; gap: var(--aura-space-2); font-size: 13px; }
909
921
  .aura-progress__label { font-weight: 500; color: var(--aura-fg-primary); }
910
922
  .aura-progress__value { color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; }
911
- .aura-progress__track { position: relative; height: 8px; border-radius: var(--aura-radius-full); background: var(--aura-bg-skeleton); overflow: hidden; }
923
+ .aura-progress__track { position: relative; height: 8px; border-radius: var(--aura-radius-full); background: var(--aura-progress-track); box-shadow: inset 0 0 0 1px var(--aura-progress-track-edge); overflow: hidden; }
912
924
  .aura-progress.is-sm .aura-progress__track { height: 4px; }
913
925
  .aura-progress__bar { position: absolute; inset: 0 auto 0 0; border-radius: inherit; background: var(--aura-fg-accent); transition: width var(--aura-duration-base) var(--aura-ease); }
914
926
  .aura-progress--success .aura-progress__bar { background: var(--aura-fg-positive); }
@@ -1116,3 +1128,16 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1116
1128
  .aura-tabs__list { gap: var(--aura-space-4); }
1117
1129
  }
1118
1130
  @keyframes aura-sheet-in { from { transform: translateY(24px); opacity: 0; } }
1131
+
1132
+ /* Touch (pointer: coarse): Radio, Checkbox and Switch rows are at least 44px tall (WCAG 2.5.5), padded above and
1133
+ * below a one-line 20px label; the whole row is the target (label rows natively, Switch rows by a click handler). */
1134
+ @media (pointer: coarse) {
1135
+ .aura-choice, .aura-check--labelled, .aura-switch-row {
1136
+ box-sizing: border-box; min-height: var(--aura-touch-target);
1137
+ padding-block: calc((var(--aura-touch-target) - 20px) / 2);
1138
+ }
1139
+ .aura-check--labelled .aura-check__input { top: calc((var(--aura-touch-target) - 20px) / 2 + 3px); }
1140
+ .aura-switch-row:not(.is-disabled) { cursor: pointer; }
1141
+ .aura-radio-group__list { gap: 0; }
1142
+ .aura-radio-group__list.is-horizontal { gap: 0 var(--aura-space-6); }
1143
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-react",
3
- "version": "4.10.0",
3
+ "version": "4.11.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",