@jirawatpyk/aura-tokens 4.13.0 → 4.14.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/aura-tailwind.css CHANGED
@@ -1,4 +1,4 @@
1
- /* AURA v4.13.0 — Tailwind v4 theme. GENERATED by scripts/build-tokens.js from tokens.json. Do not edit by hand.
1
+ /* AURA v4.14.0 — Tailwind v4 theme. GENERATED by scripts/build-tokens.js from tokens.json. Do not edit by hand.
2
2
  * @import "tailwindcss";
3
3
  * @import "@jirawatpyk/aura-tokens/tailwind.css";
4
4
  * Gives bg-bg-surface, text-fg-primary, border-border-strong, p-aura-6, rounded-aura-xl, shadow-aura-overlay,
package/aura.css CHANGED
@@ -1,4 +1,4 @@
1
- /* AURA v4.13.0 — GENERATED by scripts/build-tokens.js from tokens.json. Do not edit by hand. */
1
+ /* AURA v4.14.0 — GENERATED by scripts/build-tokens.js from tokens.json. Do not edit by hand. */
2
2
  /* Fonts: load aura-fonts.css (or the <link> tags in README) separately, so a blocked Google Fonts never breaks this file. */
3
3
 
4
4
  :root, [data-theme="light"] {
@@ -320,6 +320,7 @@
320
320
  --aura-popover-max-height: 320px;
321
321
  --aura-input-font-size: 14px;
322
322
  --aura-touch-target: 44px;
323
+ --aura-table-row-height: 48px;
323
324
  --aura-bp-sm: 640px;
324
325
  --aura-bp-md: 768px;
325
326
  --aura-bp-lg: 1024px;
@@ -123,6 +123,7 @@ window.Aura = (() => {
123
123
  useAuraLocale: () => useAuraLocale,
124
124
  useBreakpoint: () => useBreakpoint,
125
125
  useColorScheme: () => useColorScheme,
126
+ useDensity: () => useDensity,
126
127
  useFormatDate: () => useFormatDate,
127
128
  useResponsive: () => useResponsive
128
129
  });
@@ -609,6 +610,8 @@ window.Aura = (() => {
609
610
  };
610
611
  var LocaleContext = React3.createContext(null);
611
612
  function AuraProvider(props) {
613
+ const outer = React3.useContext(LocaleContext);
614
+ const density = props.density || outer && outer.density || null;
612
615
  const value = React3.useMemo(
613
616
  function() {
614
617
  const base = props.locale && STRINGS[props.locale] || STRINGS.en;
@@ -616,12 +619,13 @@ window.Aura = (() => {
616
619
  locale: props.locale || "en",
617
620
  calendar: props.calendar || null,
618
621
  strings: props.strings ? Object.assign({}, base, props.strings) : base,
619
- linkComponent: props.linkComponent || null
622
+ linkComponent: props.linkComponent || null,
623
+ density
620
624
  };
621
625
  },
622
- [props.locale, props.calendar, props.strings, props.linkComponent]
626
+ [props.locale, props.calendar, props.strings, props.linkComponent, density]
623
627
  );
624
- return /* @__PURE__ */ React3.createElement(LocaleContext.Provider, { value }, props.children);
628
+ return /* @__PURE__ */ React3.createElement(LocaleContext.Provider, { value }, props.density ? /* @__PURE__ */ React3.createElement("div", { className: "aura-density", "data-density": props.density }, props.children) : props.children);
625
629
  }
626
630
  function useAuraLocale() {
627
631
  return React3.useContext(LocaleContext) || { locale: null, calendar: null, strings: STRINGS.en };
@@ -630,6 +634,10 @@ window.Aura = (() => {
630
634
  const ctx = React3.useContext(LocaleContext);
631
635
  return own || ctx && ctx.linkComponent || "a";
632
636
  }
637
+ function useDensity() {
638
+ const ctx = React3.useContext(LocaleContext);
639
+ return ctx && ctx.density || void 0;
640
+ }
633
641
  function useStrings() {
634
642
  return useAuraLocale().strings;
635
643
  }
@@ -2722,6 +2730,7 @@ window.Aura = (() => {
2722
2730
  }
2723
2731
  function Command(props) {
2724
2732
  const t = useStrings();
2733
+ const density = useDensity();
2725
2734
  const id = uid(), listId = id + "-list";
2726
2735
  const box = React25.useRef(null);
2727
2736
  const input = React25.useRef(null);
@@ -2833,6 +2842,7 @@ window.Aura = (() => {
2833
2842
  "div",
2834
2843
  {
2835
2844
  className: "aura-dialog-layer aura-command-layer",
2845
+ "data-density": density,
2836
2846
  onKeyDown: function(e) {
2837
2847
  modal.onKeyDown(e);
2838
2848
  e.stopPropagation();
@@ -3002,6 +3012,7 @@ window.Aura = (() => {
3002
3012
  var import_react_dom7 = __toESM(require_react_dom(), 1);
3003
3013
  var Dialog = React27.forwardRef(function Dialog2(props, ref) {
3004
3014
  const t = useStrings();
3015
+ const density = useDensity();
3005
3016
  const own = React27.useRef(null), merged = useMergedRef(ref, own), titleId = uid(), descId = uid();
3006
3017
  function close() {
3007
3018
  if (props.dismissible !== false && props.onClose) props.onClose();
@@ -3014,7 +3025,7 @@ window.Aura = (() => {
3014
3025
  });
3015
3026
  if (!modal.ready) return null;
3016
3027
  return (0, import_react_dom7.createPortal)(
3017
- /* @__PURE__ */ React27.createElement("div", { className: "aura-dialog-layer", onKeyDown: modal.onKeyDown }, /* @__PURE__ */ React27.createElement("div", { className: "aura-scrim", onClick: close, "aria-hidden": true }), /* @__PURE__ */ React27.createElement(
3028
+ /* @__PURE__ */ React27.createElement("div", { className: "aura-dialog-layer", "data-density": density, onKeyDown: modal.onKeyDown }, /* @__PURE__ */ React27.createElement("div", { className: "aura-scrim", onClick: close, "aria-hidden": true }), /* @__PURE__ */ React27.createElement(
3018
3029
  "div",
3019
3030
  {
3020
3031
  ref: merged,
@@ -3035,6 +3046,7 @@ window.Aura = (() => {
3035
3046
  });
3036
3047
  var Drawer = React27.forwardRef(function Drawer2(props, ref) {
3037
3048
  const t = useStrings();
3049
+ const density = useDensity();
3038
3050
  const own = React27.useRef(null), merged = useMergedRef(ref, own), titleId = uid(), descId = uid();
3039
3051
  function close() {
3040
3052
  if (props.dismissible !== false && props.onClose) props.onClose();
@@ -3048,7 +3060,7 @@ window.Aura = (() => {
3048
3060
  if (!modal.ready) return null;
3049
3061
  const side = props.side === "left" ? "left" : "right";
3050
3062
  return (0, import_react_dom7.createPortal)(
3051
- /* @__PURE__ */ React27.createElement("div", { className: "aura-dialog-layer aura-drawer-layer", onKeyDown: modal.onKeyDown }, /* @__PURE__ */ React27.createElement("div", { className: "aura-scrim", onClick: close, "aria-hidden": true }), /* @__PURE__ */ React27.createElement(
3063
+ /* @__PURE__ */ React27.createElement("div", { className: "aura-dialog-layer aura-drawer-layer", "data-density": density, onKeyDown: modal.onKeyDown }, /* @__PURE__ */ React27.createElement("div", { className: "aura-scrim", onClick: close, "aria-hidden": true }), /* @__PURE__ */ React27.createElement(
3052
3064
  "div",
3053
3065
  {
3054
3066
  ref: merged,
@@ -3079,7 +3091,7 @@ window.Aura = (() => {
3079
3091
  { key: "owner", label: "OWNER" }
3080
3092
  ];
3081
3093
  var SKELETON_WIDTHS = ["72%", "56%", "84%", "44%", "64%"];
3082
- var ROW_H = 48;
3094
+ var ROW_H_DEFAULT = 48;
3083
3095
  var OVERSCAN = 8;
3084
3096
  var FLEX_MIN = 160;
3085
3097
  var DataTable = React28.forwardRef(function DataTable2(props, ref) {
@@ -3165,6 +3177,14 @@ window.Aura = (() => {
3165
3177
  return px != null && boxWidth[0] < px;
3166
3178
  }
3167
3179
  const scrollRef = React28.useRef(null);
3180
+ const rowH = React28.useState(ROW_H_DEFAULT);
3181
+ const ROW_H = rowH[0];
3182
+ useIsoLayoutEffect(function() {
3183
+ const el = wrapRef.current;
3184
+ if (!el || typeof getComputedStyle === "undefined") return;
3185
+ const v = parseFloat(getComputedStyle(el).getPropertyValue("--aura-table-row-height"));
3186
+ if (v > 0 && v !== rowH[0]) rowH[1](v);
3187
+ });
3168
3188
  const pending = React28.useRef(null);
3169
3189
  const resizing = React28.useRef(false);
3170
3190
  useIsoLayoutEffect(function() {
@@ -4027,6 +4047,7 @@ window.Aura = (() => {
4027
4047
  "div",
4028
4048
  {
4029
4049
  ref: wrapMerged,
4050
+ "data-density": props.density,
4030
4051
  className: cx("aura-table aura-table--stacked", refreshing && "is-refreshing", props.className),
4031
4052
  role: "region",
4032
4053
  "aria-label": props.label,
@@ -4055,6 +4076,7 @@ window.Aura = (() => {
4055
4076
  "div",
4056
4077
  {
4057
4078
  ref: wrapMerged,
4079
+ "data-density": props.density,
4058
4080
  className: cx("aura-table", scrolledX[0] && "is-scrolled-x", refreshing && "is-refreshing", props.className)
4059
4081
  },
4060
4082
  refreshing ? /* @__PURE__ */ React28.createElement("span", { className: "aura-table__busy-bar", "aria-hidden": true }) : null,
@@ -5759,6 +5781,7 @@ window.Aura = (() => {
5759
5781
  }
5760
5782
  var Popover = React51.forwardRef(function Popover2(props, ref) {
5761
5783
  const t = useStrings();
5784
+ const density = useDensity();
5762
5785
  const auto = uid(), id = props.id || auto;
5763
5786
  const st = useMaybeControlled(props.open, !!props.defaultOpen, props.onOpenChange);
5764
5787
  const open = !!st[0];
@@ -5816,6 +5839,7 @@ window.Aura = (() => {
5816
5839
  {
5817
5840
  ref: popMerged,
5818
5841
  id,
5842
+ "data-density": density,
5819
5843
  role: "dialog",
5820
5844
  "aria-modal": false,
5821
5845
  "aria-label": props.title ? void 0 : props.label,
@@ -7,7 +7,7 @@
7
7
  box-sizing: border-box;
8
8
  height: var(--aura-button-height);
9
9
  white-space: nowrap; flex-shrink: 0; /* a pill never wraps its label */
10
- padding: 0 var(--aura-space-6);
10
+ padding: 0 var(--aura-button-padding-x, var(--aura-space-6));
11
11
  border-radius: var(--aura-button-radius);
12
12
  border: 0;
13
13
  background: transparent;
@@ -74,14 +74,14 @@ a.aura-btn { text-decoration: none; }
74
74
  }
75
75
  .aura-table__scroll { position: relative; overflow: auto; overscroll-behavior: contain; }
76
76
  .aura-table__head {
77
- position: sticky; top: 0; z-index: 3;
78
- display: flex; height: var(--aura-space-12);
77
+ position: sticky; top: 0; z-index: 3; box-sizing: border-box; /* the hairline is inside the row height */
78
+ display: flex; height: var(--aura-table-row-height);
79
79
  background: var(--aura-bg-canvas);
80
80
  border-bottom: 1px solid var(--aura-border-default);
81
81
  font-family: var(--font-mono); font-size: 12px; color: var(--aura-fg-secondary);
82
82
  }
83
83
  .aura-table__row {
84
- display: flex; height: var(--aura-space-12);
84
+ box-sizing: border-box; display: flex; height: var(--aura-table-row-height); /* exactly the virtual row height */
85
85
  background: var(--aura-bg-surface);
86
86
  border-bottom: 1px solid var(--aura-border-default);
87
87
  font-size: 13px;
@@ -105,7 +105,7 @@ a.aura-btn { text-decoration: none; }
105
105
  /* Server mode refresh: the previous page stays, inactive, under a progress bar until the next one arrives */
106
106
  .aura-table.is-refreshing .aura-table__row, .aura-table.is-refreshing .aura-table__card { opacity: 0.6; pointer-events: none; }
107
107
  .aura-table__busy-bar {
108
- position: absolute; z-index: 6; top: calc(var(--aura-space-12) - 2px); left: 0; right: 0; height: 2px; overflow: hidden;
108
+ position: absolute; z-index: 6; top: calc(var(--aura-table-row-height) - 2px); left: 0; right: 0; height: 2px; overflow: hidden;
109
109
  border-radius: var(--aura-radius-full); pointer-events: none;
110
110
  }
111
111
  .aura-table--stacked .aura-table__busy-bar { top: 0; }
@@ -117,7 +117,7 @@ a.aura-btn { text-decoration: none; }
117
117
 
118
118
  /* Cells: text cells stay block so long values end in an ellipsis */
119
119
  .aura-table__td {
120
- box-sizing: border-box; height: 100%; line-height: calc(var(--aura-space-12) - 1px);
120
+ box-sizing: border-box; height: 100%; line-height: calc(var(--aura-table-row-height) - 1px);
121
121
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: var(--aura-space-4);
122
122
  }
123
123
  .aura-table__td .aura-pill, .aura-table__td .aura-dropdown, .aura-table__td > .aura-icon-btn, .aura-table__td > .aura-btn { vertical-align: middle; }
@@ -130,7 +130,7 @@ a.aura-btn { text-decoration: none; }
130
130
  .aura-table__gutter { flex: none; width: var(--aura-space-6); position: sticky; left: 0; z-index: 2; background: inherit; }
131
131
  .aura-table__gutter--end { position: static; }
132
132
  .aura-table__picker {
133
- position: absolute; top: 0; right: 0; z-index: 5; width: var(--aura-space-12); height: calc(var(--aura-space-12) - 1px);
133
+ position: absolute; top: 0; right: 0; z-index: 5; width: var(--aura-space-12); height: calc(var(--aura-table-row-height) - 1px);
134
134
  display: flex; align-items: center; justify-content: center; background: var(--aura-bg-canvas); border-top-right-radius: calc(var(--aura-card-radius) - 1px);
135
135
  }
136
136
  .aura-table__gutter--end.has-picker {
@@ -228,7 +228,7 @@ a.aura-btn { text-decoration: none; }
228
228
 
229
229
  /* Footer + pager */
230
230
  .aura-table__foot {
231
- height: var(--aura-space-12); display: flex; align-items: center; justify-content: space-between;
231
+ height: var(--aura-table-row-height); display: flex; align-items: center; justify-content: space-between;
232
232
  padding: 0 var(--aura-space-3) 0 var(--aura-space-6);
233
233
  border-top: 1px solid var(--aura-border-default); background: var(--aura-bg-surface);
234
234
  font-size: 13px; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums;
@@ -1241,3 +1241,19 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1241
1241
  }
1242
1242
  @media (prefers-reduced-motion: reduce) { .aura-command { animation: none; } }
1243
1243
 
1244
+ /* Density. data-density="compact" on <html> or any container (AuraProvider density="compact" and DataTable
1245
+ * density do it for you): 36px fields and buttons, 40px table rows, less button padding — for dense admin screens.
1246
+ * Touch screens keep 44px targets whatever the density. "comfortable" inside compact switches back. */
1247
+ [data-density='compact'] {
1248
+ --aura-input-height: 36px; --aura-button-height: 36px; --aura-table-row-height: 40px;
1249
+ --aura-button-padding-x: var(--aura-space-4);
1250
+ }
1251
+ [data-density='comfortable'] {
1252
+ --aura-input-height: 44px; --aura-button-height: 44px; --aura-table-row-height: 48px;
1253
+ --aura-button-padding-x: var(--aura-space-6);
1254
+ }
1255
+ @media (pointer: coarse) {
1256
+ [data-density='compact'] { --aura-input-height: 44px; --aura-button-height: 44px; --aura-table-row-height: 48px; --aura-button-padding-x: var(--aura-space-6); }
1257
+ }
1258
+ .aura-density { display: contents; }
1259
+
@@ -149,6 +149,8 @@ export interface DataTableProps {
149
149
  /** Controlled pinned columns (keys); pair with onPinnedColumnsChange. */
150
150
  pinnedColumns?: string[];
151
151
  onPinnedColumnsChange?: (keys: string[]) => void;
152
+ /** `compact` = 40px rows (48px on touch screens). Default: the surrounding density. */
153
+ density?: "comfortable" | "compact";
152
154
  /** Container width in px below which rows render as stacked cards (phones). Try 640. Measured with ResizeObserver, so it follows the container, not the window. */
153
155
  stackBelow?: number;
154
156
  className?: string;
@@ -184,6 +186,8 @@ export interface AuraProviderProps {
184
186
  calendar?: "buddhist" | "gregory";
185
187
  /** Override individual strings. */
186
188
  strings?: Partial<Record<string, string | ((...args: any[]) => string)>>;
189
+ /** `compact`: 36px fields and buttons, 40px table rows — dense admin screens. Touch screens keep 44px. Default: comfortable (or an ancestor's `data-density`). */
190
+ density?: "comfortable" | "compact";
187
191
  /** Your router's link (e.g. `Link` from `next/link`), used by every AURA component that renders a link: Button with `href`, SideNav, Breadcrumb, Stat, Pagination, DataTable row links. It gets `href`, `className`, `aria-current`, the children and the ref. A component's own `linkComponent` wins. */
188
192
  linkComponent?: React$1.ElementType;
189
193
  children?: React$1.ReactNode;
@@ -1216,11 +1220,15 @@ export interface AuraLocaleValue {
1216
1220
  strings: AuraStrings;
1217
1221
  /** The router link set on AuraProvider, if any. */
1218
1222
  linkComponent?: React$1.ElementType | null;
1223
+ /** The density set on the nearest AuraProvider that sets one (null: none, i.e. comfortable unless an ancestor's data-density says otherwise). */
1224
+ density?: "comfortable" | "compact" | null;
1219
1225
  }
1220
1226
  /** Sets the language of built-in labels (and the default date locale) for everything inside. */
1221
1227
  export declare function AuraProvider(props: AuraProviderProps): React$1.ReactElement;
1222
1228
  /** { locale, calendar, strings } from the nearest AuraProvider (English strings when there is none). */
1223
1229
  export declare function useAuraLocale(): AuraLocaleValue;
1230
+ /** The provider's density, for portals that render outside its wrapper. */
1231
+ export declare function useDensity(): "comfortable" | "compact" | undefined;
1224
1232
  export declare const Stat: React$1.ForwardRefExoticComponent<StatProps & React$1.RefAttributes<HTMLElement>>;
1225
1233
  /** Parse typed time: 9 · 09 · 930 · 0930 · 9:30 · 9.30 · 09.30 น. · 9:30 pm → "HH:mm" (24-hour) or null. */
1226
1234
  export declare function parseTime(text: string | null | undefined): string | null;
@@ -249,3 +249,4 @@ size/cal-cell,number,light,36,Calendar day cell (DatePicker). 40px on touch scre
249
249
  size/popover-max-height,number,light,320,Max height of Combobox listbox and DatePicker popover lists. ADDED 4.2.,GAP
250
250
  size/input-font-size,number,light,14,"Text size in inputs, textareas, selects and pickers. Phones (<640px) use at least 16px so iOS Safari does not zoom on focus. ADDED 4.11.",GAP
251
251
  size/touch-target,number,light,44,"Minimum hit area on touch screens (pointer: coarse): IconButton, and Radio / Checkbox / Switch rows (WCAG 2.5.5). ADDED 4.11.",GAP
252
+ size/table-row-height,number,light,48,DataTable row and header height. 40px in compact density on fine pointers; 48px on touch. ADDED 4.14.,GAP
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-tokens",
3
- "version": "4.13.0",
3
+ "version": "4.14.0",
4
4
  "description": "AURA Design System — tokens (CSS variables, Tailwind preset, Figma variables), theme contrast checks and token lint.",
5
5
  "main": "tailwind.tokens.cjs",
6
6
  "types": "components/index.d.ts",
package/tokens.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.13.0",
2
+ "version": "4.14.0",
3
3
  "meta": {
4
4
  "name": "AURA Design System",
5
5
  "tier": "3-tier",
@@ -288,7 +288,8 @@
288
288
  "cal-cell": "36px",
289
289
  "popover-max-height": "320px",
290
290
  "input-font-size": "14px",
291
- "touch-target": "44px"
291
+ "touch-target": "44px",
292
+ "table-row-height": "48px"
292
293
  },
293
294
  "breakpoint": {
294
295
  "bp-sm": "640px",
@@ -539,6 +540,7 @@
539
540
  "progress-track": "Empty part of Progress and FileUpload bars (fill). Its edge carries the 3:1. ADDED 4.11.",
540
541
  "progress-track-edge": "1px inset edge of Progress / upload tracks: ≥3:1 on bg-surface and bg-canvas in both themes (WCAG 1.4.11), so the track reads without the fill. ADDED 4.11.",
541
542
  "input-font-size": "Text size in inputs, textareas, selects and pickers. Phones (<640px) use at least 16px so iOS Safari does not zoom on focus. ADDED 4.11.",
542
- "touch-target": "Minimum hit area on touch screens (pointer: coarse): IconButton, and Radio / Checkbox / Switch rows (WCAG 2.5.5). ADDED 4.11."
543
+ "touch-target": "Minimum hit area on touch screens (pointer: coarse): IconButton, and Radio / Checkbox / Switch rows (WCAG 2.5.5). ADDED 4.11.",
544
+ "table-row-height": "DataTable row and header height. 40px in compact density on fine pointers; 48px on touch. ADDED 4.14."
543
545
  }
544
546
  }