@jirawatpyk/aura-react 5.43.0 → 5.44.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
@@ -186,6 +186,11 @@ 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.44 — Chamber-OS addendum 51 (#149)
190
+
191
+ - **PageHeader `actionsFullWidthBelow` with an icon button keeps one row** (#149): when the actions include an IconButton (a ⋯ DropdownMenu trigger, bare or wrapped), below the breakpoint they are one bar. The row no longer wraps; the text buttons share what the icon leaves and wrap their labels inside the button (two or three lines, centred, `overflow-wrap: anywhere` with hyphenation, never an ellipsis), growing taller rather than wider, at least 44px with `touchHeight`; a pill that grows past one line gets 22px corners instead of becoming an oval. Hyphens appear only where the browser has a dictionary for the page's `lang` (Safari, Android); elsewhere a long word breaks where it must, so keep phone labels short. The icon keeps its size at the end of the row. Measured on an invoice page at 393 and 320px in English, Thai and Swedish: nothing clipped, no sideways scroll. Actions without an icon button wrap onto rows as in 5.37 (DxT Monitor's two-plus-one); a header that mixes text and icon buttons (e.g. Mute, Edit, ⋯, Open site) is now one row at 320px where it was two. Needs `:has()`; older browsers keep the 5.37 layout.
192
+ - **IconButton `variant="outline"`**: a secondary Button's 1px border, so a lone ⋯ reads as a button beside outlined actions. Default `ghost` (no border).
193
+
189
194
  ## 5.43 — Chamber-OS addendum 50 (#148)
190
195
 
191
196
  - **FilterBar `collapseBelow` with no search** (#148): below the breakpoint the Filters button fills the row it would otherwise sit at the end of, its label centred (an activity timeline with filters and no search). With a search it stays beside it, as in 5.42. From the breakpoint up nothing changes. Remove a stand-in such as `[&_.aura-filterbar__more]:flex-1`.
@@ -1583,7 +1583,7 @@ window.Aura = (() => {
1583
1583
 
1584
1584
  // src/IconButton.tsx
1585
1585
  var IconButton = React8.forwardRef(function IconButton2(props, ref) {
1586
- const rest = omit(props, ["icon", "label", "className", "size", "tone", "touchHeight"]);
1586
+ const rest = omit(props, ["icon", "label", "className", "size", "tone", "touchHeight", "variant"]);
1587
1587
  useAutoTip();
1588
1588
  const own = props.title !== void 0;
1589
1589
  return /* @__PURE__ */ React8.createElement(
@@ -1597,6 +1597,7 @@ window.Aura = (() => {
1597
1597
  className: cx(
1598
1598
  "aura-icon-btn",
1599
1599
  props.tone === "danger" && "aura-icon-btn--danger",
1600
+ props.variant === "outline" && "aura-icon-btn--outline",
1600
1601
  props.touchHeight && "aura-icon-btn--touch",
1601
1602
  props.className
1602
1603
  )
@@ -1565,7 +1565,7 @@ function useAutoTip() {
1565
1565
 
1566
1566
  // src/IconButton.tsx
1567
1567
  var IconButton = React8.forwardRef(function IconButton2(props, ref) {
1568
- const rest = omit(props, ["icon", "label", "className", "size", "tone", "touchHeight"]);
1568
+ const rest = omit(props, ["icon", "label", "className", "size", "tone", "touchHeight", "variant"]);
1569
1569
  useAutoTip();
1570
1570
  const own = props.title !== void 0;
1571
1571
  return /* @__PURE__ */ React8.createElement(
@@ -1579,6 +1579,7 @@ var IconButton = React8.forwardRef(function IconButton2(props, ref) {
1579
1579
  className: cx(
1580
1580
  "aura-icon-btn",
1581
1581
  props.tone === "danger" && "aura-icon-btn--danger",
1582
+ props.variant === "outline" && "aura-icon-btn--outline",
1582
1583
  props.touchHeight && "aura-icon-btn--touch",
1583
1584
  props.className
1584
1585
  )
@@ -4,7 +4,7 @@ import { cx, omit } from "./internal.js";
4
4
  import { Icon } from "./Icon.js";
5
5
  import { useAutoTip } from "./autoTip.js";
6
6
  const IconButton = React.forwardRef(function IconButton2(props, ref) {
7
- const rest = omit(props, ["icon", "label", "className", "size", "tone", "touchHeight"]);
7
+ const rest = omit(props, ["icon", "label", "className", "size", "tone", "touchHeight", "variant"]);
8
8
  useAutoTip();
9
9
  const own = props.title !== void 0;
10
10
  return /* @__PURE__ */ React.createElement(
@@ -18,6 +18,7 @@ const IconButton = React.forwardRef(function IconButton2(props, ref) {
18
18
  className: cx(
19
19
  "aura-icon-btn",
20
20
  props.tone === "danger" && "aura-icon-btn--danger",
21
+ props.variant === "outline" && "aura-icon-btn--outline",
21
22
  props.touchHeight && "aura-icon-btn--touch",
22
23
  props.className
23
24
  )
package/dist/index.d.cts CHANGED
@@ -353,6 +353,9 @@ export interface IconButtonProps extends React$1.ButtonHTMLAttributes<HTMLButton
353
353
  label: string;
354
354
  /** Icon size. Default `sm` (16). */
355
355
  size?: "sm" | "md" | undefined;
356
+ /** 5.44 (Chamber-OS 149): `outline` adds a secondary Button's 1px border, so a lone ⋯ reads as a button beside
357
+ * outlined actions. Default `ghost`: no border. */
358
+ variant?: "ghost" | "outline" | undefined;
356
359
  /** 44×44 instead of 32×32 below 640px (the viewport's) or wherever the primary pointer is coarse (a tablet, 5.24) —
357
360
  * a phone sheet's close button, a card's ⋯ trigger (5.15, Chamber-OS 100). */
358
361
  touchHeight?: boolean | undefined;
package/dist/index.d.ts CHANGED
@@ -353,6 +353,9 @@ export interface IconButtonProps extends React$1.ButtonHTMLAttributes<HTMLButton
353
353
  label: string;
354
354
  /** Icon size. Default `sm` (16). */
355
355
  size?: "sm" | "md" | undefined;
356
+ /** 5.44 (Chamber-OS 149): `outline` adds a secondary Button's 1px border, so a lone ⋯ reads as a button beside
357
+ * outlined actions. Default `ghost`: no border. */
358
+ variant?: "ghost" | "outline" | undefined;
356
359
  /** 44×44 instead of 32×32 below 640px (the viewport's) or wherever the primary pointer is coarse (a tablet, 5.24) —
357
360
  * a phone sheet's close button, a card's ⋯ trigger (5.15, Chamber-OS 100). */
358
361
  touchHeight?: boolean | undefined;
package/dist/styles.css CHANGED
@@ -346,6 +346,7 @@ a.aura-icon-btn { text-decoration: none; }
346
346
  }
347
347
  .aura-icon-btn:hover, .aura-icon-btn[aria-haspopup][aria-expanded="true"] { background: var(--aura-hover, var(--aura-bg-surface-hover)); } /* 5.41 (DxT #22): looks open while its menu shows */
348
348
  .aura-icon-btn--danger { color: var(--aura-fg-danger); }
349
+ .aura-icon-btn--outline { box-sizing: border-box; border: 1px solid var(--aura-button-secondary-border); } /* 5.44 (Chamber-OS 149): reads as a button beside outlined ones */
349
350
  .aura-icon-btn--danger:hover { background: var(--aura-alert-danger-bg); }
350
351
  .aura-icon-btn:disabled { opacity: var(--aura-disabled-opacity); pointer-events: none; }
351
352
  .aura-icon-btn:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: var(--aura-focus-ring-offset); }
@@ -359,6 +360,9 @@ a.aura-icon-btn { text-decoration: none; }
359
360
  .aura-tag.aura-tag--touch { min-height: var(--aura-touch-target); }
360
361
  .aura-filterbar__clear { min-height: var(--aura-touch-target); } /* 5.28 (Chamber-OS 133) */
361
362
  }
363
+ @media (max-width: 639.98px), (pointer: coarse) {
364
+ .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn).aura-btn--touch { min-height: var(--aura-touch-target); } /* 5.44: a wrapped label keeps 44px */
365
+ }
362
366
  /* Touch: same 32px look, a 44px hit area around it (WCAG 2.5.5). */
363
367
  @media (pointer: coarse) {
364
368
  .aura-icon-btn { position: relative; }
@@ -1168,13 +1172,18 @@ a.aura-tab { text-decoration: none; }
1168
1172
  }
1169
1173
  /* 5.37 (DxT Monitor #17): actionsFullWidthBelow — the actions take the row under the text; their children share
1170
1174
  * each line equally (wrapping when a label won't fit), a trigger inside a DropdownMenu, Tooltip or Popover wrapper
1171
- * fills it, and icon buttons keep their size. The :has rule is alone so older browsers drop only it. */
1175
+ * fills it, and icon buttons keep their size. The :has rule is alone so older browsers drop only it.
1176
+ * 5.44 (Chamber-OS 149): with an icon button among them (a ⋯ menu) the actions are one bar: the row never wraps,
1177
+ * the buttons share what the icon leaves and wrap their labels inside (never an ellipsis). */
1172
1178
  @media (max-width: 639.98px) {
1173
1179
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
1174
1180
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > * { flex: 1 1 0; min-width: max-content; }
1175
1181
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1176
1182
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1177
1183
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1184
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1185
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1186
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1178
1187
  }
1179
1188
  @media (max-width: 767.98px) {
1180
1189
  .aura-page-header--actions-full-below-md > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
@@ -1182,6 +1191,9 @@ a.aura-tab { text-decoration: none; }
1182
1191
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1183
1192
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1184
1193
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1194
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1195
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1196
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1185
1197
  }
1186
1198
  @media (max-width: 1023.98px) {
1187
1199
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
@@ -1189,6 +1201,9 @@ a.aura-tab { text-decoration: none; }
1189
1201
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1190
1202
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1191
1203
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1204
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1205
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1206
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1192
1207
  }
1193
1208
  @media (min-width: 640px) { .aura-page-header__title { font-size: max(36px, 2.25rem); } }
1194
1209
  /* Thai marks need the room a 1.15 line takes away. */
@@ -348,6 +348,7 @@ a.aura-icon-btn { text-decoration: none; }
348
348
  }
349
349
  .aura-icon-btn:hover, .aura-icon-btn[aria-haspopup][aria-expanded="true"] { background: var(--aura-hover, var(--aura-bg-surface-hover)); } /* 5.41 (DxT #22): looks open while its menu shows */
350
350
  .aura-icon-btn--danger { color: var(--aura-fg-danger); }
351
+ .aura-icon-btn--outline { box-sizing: border-box; border: 1px solid var(--aura-button-secondary-border); } /* 5.44 (Chamber-OS 149): reads as a button beside outlined ones */
351
352
  .aura-icon-btn--danger:hover { background: var(--aura-alert-danger-bg); }
352
353
  .aura-icon-btn:disabled { opacity: var(--aura-disabled-opacity); pointer-events: none; }
353
354
  .aura-icon-btn:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: var(--aura-focus-ring-offset); }
@@ -361,6 +362,9 @@ a.aura-icon-btn { text-decoration: none; }
361
362
  .aura-tag.aura-tag--touch { min-height: var(--aura-touch-target); }
362
363
  .aura-filterbar__clear { min-height: var(--aura-touch-target); } /* 5.28 (Chamber-OS 133) */
363
364
  }
365
+ @media (max-width: 639.98px), (pointer: coarse) {
366
+ .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn).aura-btn--touch { min-height: var(--aura-touch-target); } /* 5.44: a wrapped label keeps 44px */
367
+ }
364
368
  /* Touch: same 32px look, a 44px hit area around it (WCAG 2.5.5). */
365
369
  @media (pointer: coarse) {
366
370
  .aura-icon-btn { position: relative; }
@@ -1170,13 +1174,18 @@ a.aura-tab { text-decoration: none; }
1170
1174
  }
1171
1175
  /* 5.37 (DxT Monitor #17): actionsFullWidthBelow — the actions take the row under the text; their children share
1172
1176
  * each line equally (wrapping when a label won't fit), a trigger inside a DropdownMenu, Tooltip or Popover wrapper
1173
- * fills it, and icon buttons keep their size. The :has rule is alone so older browsers drop only it. */
1177
+ * fills it, and icon buttons keep their size. The :has rule is alone so older browsers drop only it.
1178
+ * 5.44 (Chamber-OS 149): with an icon button among them (a ⋯ menu) the actions are one bar: the row never wraps,
1179
+ * the buttons share what the icon leaves and wrap their labels inside (never an ellipsis). */
1174
1180
  @media (max-width: 639.98px) {
1175
1181
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
1176
1182
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > * { flex: 1 1 0; min-width: max-content; }
1177
1183
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1178
1184
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1179
1185
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1186
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1187
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1188
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1180
1189
  }
1181
1190
  @media (max-width: 767.98px) {
1182
1191
  .aura-page-header--actions-full-below-md > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
@@ -1184,6 +1193,9 @@ a.aura-tab { text-decoration: none; }
1184
1193
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1185
1194
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1186
1195
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1196
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1197
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1198
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1187
1199
  }
1188
1200
  @media (max-width: 1023.98px) {
1189
1201
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
@@ -1191,6 +1203,9 @@ a.aura-tab { text-decoration: none; }
1191
1203
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1192
1204
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1193
1205
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1206
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1207
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1208
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1194
1209
  }
1195
1210
  @media (min-width: 640px) { .aura-page-header__title { font-size: max(36px, 2.25rem); } }
1196
1211
  /* Thai marks need the room a 1.15 line takes away. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-react",
3
- "version": "5.43.0",
3
+ "version": "5.44.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",