@jirawatpyk/aura-react 5.7.2 → 5.8.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.
@@ -1,15 +1,6 @@
1
1
  'use client';
2
2
  import * as React from "react";
3
- function cx() {
4
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
5
- }
6
- function omit(src, keys) {
7
- const out = {};
8
- for (const k in src)
9
- if (Object.prototype.hasOwnProperty.call(src, k) && keys.indexOf(k) < 0)
10
- out[k] = src[k];
11
- return out;
12
- }
3
+ import { cx, omit, tone } from "./classes.js";
13
4
  function useMaybeControlled(value, initial, onChange) {
14
5
  const s = React.useState(initial);
15
6
  const wasSet = React.useState(value !== void 0);
@@ -86,10 +77,6 @@ function useMergedRef(a, b) {
86
77
  [a, b]
87
78
  );
88
79
  }
89
- const TONES = ["neutral", "accent", "success", "warning", "danger"];
90
- function tone(t) {
91
- return TONES.indexOf(t) >= 0 ? t : "neutral";
92
- }
93
80
  const warned = {};
94
81
  function plainClick(e) {
95
82
  return !e.defaultPrevented && e.button === 0 && !e.metaKey && !e.ctrlKey && !e.shiftKey && !e.altKey;
package/dist/index.d.cts CHANGED
@@ -236,8 +236,8 @@ export interface AuraProviderProps {
236
236
  /** `warning` (5.1): needs attention but still works — Warning, Problem, Degraded, At risk. */
237
237
  export type StatusTone = "neutral" | "progress" | "ready" | "warning" | "blocked";
238
238
  /** Status pill: tone fill + icon + the status word. Tone comes from the word unless given. */
239
- export interface StatusPillProps {
240
- /** The status word shown, e.g. "In Progress". */
239
+ export interface StatusPillProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, "children"> {
240
+ /** The status word shown, e.g. "In Progress". Other attributes (`id`, `data-*`, `aria-*`) go on the pill (5.8). */
241
241
  children: React$1.ReactNode;
242
242
  /** Force a tone. Default: matched from the word (Ready/Done → ready, In Progress/In Review → progress, Warning/Problem/Degraded/At risk → warning (5.1), Blocked/Failed → blocked, anything else → neutral). */
243
243
  tone?: StatusTone | undefined;
@@ -355,7 +355,10 @@ export interface FormErrorSummaryProps {
355
355
  title?: React$1.ReactNode | undefined;
356
356
  /** Called with the field when a link is followed, e.g. react-hook-form's `setFocus`. Default: focus the element whose id (or name) is the field. */
357
357
  onSelect?: ((field: string) => void) | undefined;
358
- /** Change it on every submit (e.g. `formState.submitCount`) to move focus to the summary again. It also takes focus when errors first appear. */
358
+ /** Change it on every submit (e.g. `formState.submitCount`). With it, the summary takes focus only after a submit —
359
+ * never while someone types and live errors come and go (5.7.3). Without it, it takes focus whenever errors
360
+ * first appear; with react-hook-form's live `errors`, always pass `focusKey={formState.submitCount}` (a primitive, not a new object
361
+ * each render) and `useForm({ shouldFocusError: false })`, so RHF doesn't move focus to the field first. */
359
362
  focusKey?: unknown;
360
363
  className?: string | undefined;
361
364
  id?: string | undefined;
@@ -485,8 +488,13 @@ export interface SwitchProps {
485
488
  className?: string | undefined;
486
489
  }
487
490
  export type FeedbackTone = "info" | "success" | "warning" | "danger";
488
- export interface AlertProps {
491
+ export interface AlertProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "title" | "role"> {
489
492
  tone?: FeedbackTone | undefined;
493
+ /** Default: `alert` for warning and danger, `status` otherwise (5.8). Pass `status` for a standing notice in a
494
+ * warning or danger tone that shouldn't interrupt; `note` or `none` for one that isn't a live region. */
495
+ role?: "alert" | "status" | "note" | "none" | undefined;
496
+ /** Replaces the tone's icon (5.8): a name or your own element; always hidden from screen readers. */
497
+ icon?: IconInput | undefined;
490
498
  title?: React$1.ReactNode | undefined;
491
499
  children?: React$1.ReactNode | undefined;
492
500
  /** Usually a secondary Button. */
@@ -559,7 +567,8 @@ export interface DialogProps {
559
567
  autoFocus?: boolean | undefined;
560
568
  className?: string | undefined;
561
569
  }
562
- export interface CardProps {
570
+ /** Other attributes (`id`, `data-*`, `aria-*`) go on the card's root (5.8). */
571
+ export interface CardProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "title"> {
563
572
  title?: React$1.ReactNode | undefined;
564
573
  description?: React$1.ReactNode | undefined;
565
574
  /** Top-right, usually an IconButton. */
@@ -940,6 +949,10 @@ export interface TableProps extends Omit<React$1.TableHTMLAttributes<HTMLTableEl
940
949
  captionHidden?: boolean | undefined;
941
950
  /** `compact` tightens the cell padding. Default follows the page. */
942
951
  density?: "comfortable" | "compact" | undefined;
952
+ /** Below this width of the table's box (5.8) — `sm` 640px, `md` 768px — each body row becomes a card and each
953
+ * cell shows its column's header as a label: a `Td`'s `label`, else the text of the matching `Th` in `THead`.
954
+ * Done in CSS (a container query), so the server's HTML is already right; table semantics are kept. */
955
+ stackBelow?: "sm" | "md" | undefined;
943
956
  className?: string | undefined;
944
957
  children?: React$1.ReactNode | undefined;
945
958
  }
@@ -958,6 +971,8 @@ export interface TableCellProps extends Omit<React$1.TdHTMLAttributes<HTMLTableC
958
971
  mono?: boolean | undefined;
959
972
  /** Th only. Default `col`. */
960
973
  scope?: "col" | "row" | "colgroup" | "rowgroup" | undefined;
974
+ /** The label this cell shows when its table is stacked (`stackBelow`, 5.8). Default: the matching header's text. */
975
+ label?: string | undefined;
961
976
  className?: string | undefined;
962
977
  }
963
978
  export interface ActionBarProps {
@@ -1303,6 +1318,15 @@ export declare const Calendar: React$1.ForwardRefExoticComponent<CalendarProps &
1303
1318
  /** 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. */
1304
1319
  export declare const DatePicker: React$1.ForwardRefExoticComponent<DatePickerProps & React$1.RefAttributes<HTMLInputElement>>;
1305
1320
  export declare const DateRangePicker: React$1.ForwardRefExoticComponent<DateRangePickerProps & React$1.RefAttributes<HTMLInputElement>>;
1321
+ /** The class list of a Button (5.8): put it on your own link or `<Link>` to make it look like one, e.g. in a Server
1322
+ * Component — `<Link href="/renew" className={buttonClass({ variant: 'secondary' })}>Renew</Link>`. */
1323
+ export declare function buttonClass(opts?: {
1324
+ variant?: ButtonProps["variant"];
1325
+ size?: ButtonProps["size"];
1326
+ fullWidth?: boolean | undefined;
1327
+ loading?: boolean | undefined;
1328
+ className?: string | undefined;
1329
+ }): string;
1306
1330
  export declare const Alert: React$1.ForwardRefExoticComponent<AlertProps & React$1.RefAttributes<HTMLDivElement>>;
1307
1331
  /** Show a toast; returns its id. Needs `<Toaster />` mounted once. */
1308
1332
  export declare function toast(opts: ToastOptions | string): string;
package/dist/index.d.ts CHANGED
@@ -236,8 +236,8 @@ export interface AuraProviderProps {
236
236
  /** `warning` (5.1): needs attention but still works — Warning, Problem, Degraded, At risk. */
237
237
  export type StatusTone = "neutral" | "progress" | "ready" | "warning" | "blocked";
238
238
  /** Status pill: tone fill + icon + the status word. Tone comes from the word unless given. */
239
- export interface StatusPillProps {
240
- /** The status word shown, e.g. "In Progress". */
239
+ export interface StatusPillProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, "children"> {
240
+ /** The status word shown, e.g. "In Progress". Other attributes (`id`, `data-*`, `aria-*`) go on the pill (5.8). */
241
241
  children: React$1.ReactNode;
242
242
  /** Force a tone. Default: matched from the word (Ready/Done → ready, In Progress/In Review → progress, Warning/Problem/Degraded/At risk → warning (5.1), Blocked/Failed → blocked, anything else → neutral). */
243
243
  tone?: StatusTone | undefined;
@@ -355,7 +355,10 @@ export interface FormErrorSummaryProps {
355
355
  title?: React$1.ReactNode | undefined;
356
356
  /** Called with the field when a link is followed, e.g. react-hook-form's `setFocus`. Default: focus the element whose id (or name) is the field. */
357
357
  onSelect?: ((field: string) => void) | undefined;
358
- /** Change it on every submit (e.g. `formState.submitCount`) to move focus to the summary again. It also takes focus when errors first appear. */
358
+ /** Change it on every submit (e.g. `formState.submitCount`). With it, the summary takes focus only after a submit —
359
+ * never while someone types and live errors come and go (5.7.3). Without it, it takes focus whenever errors
360
+ * first appear; with react-hook-form's live `errors`, always pass `focusKey={formState.submitCount}` (a primitive, not a new object
361
+ * each render) and `useForm({ shouldFocusError: false })`, so RHF doesn't move focus to the field first. */
359
362
  focusKey?: unknown;
360
363
  className?: string | undefined;
361
364
  id?: string | undefined;
@@ -485,8 +488,13 @@ export interface SwitchProps {
485
488
  className?: string | undefined;
486
489
  }
487
490
  export type FeedbackTone = "info" | "success" | "warning" | "danger";
488
- export interface AlertProps {
491
+ export interface AlertProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "title" | "role"> {
489
492
  tone?: FeedbackTone | undefined;
493
+ /** Default: `alert` for warning and danger, `status` otherwise (5.8). Pass `status` for a standing notice in a
494
+ * warning or danger tone that shouldn't interrupt; `note` or `none` for one that isn't a live region. */
495
+ role?: "alert" | "status" | "note" | "none" | undefined;
496
+ /** Replaces the tone's icon (5.8): a name or your own element; always hidden from screen readers. */
497
+ icon?: IconInput | undefined;
490
498
  title?: React$1.ReactNode | undefined;
491
499
  children?: React$1.ReactNode | undefined;
492
500
  /** Usually a secondary Button. */
@@ -559,7 +567,8 @@ export interface DialogProps {
559
567
  autoFocus?: boolean | undefined;
560
568
  className?: string | undefined;
561
569
  }
562
- export interface CardProps {
570
+ /** Other attributes (`id`, `data-*`, `aria-*`) go on the card's root (5.8). */
571
+ export interface CardProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "title"> {
563
572
  title?: React$1.ReactNode | undefined;
564
573
  description?: React$1.ReactNode | undefined;
565
574
  /** Top-right, usually an IconButton. */
@@ -940,6 +949,10 @@ export interface TableProps extends Omit<React$1.TableHTMLAttributes<HTMLTableEl
940
949
  captionHidden?: boolean | undefined;
941
950
  /** `compact` tightens the cell padding. Default follows the page. */
942
951
  density?: "comfortable" | "compact" | undefined;
952
+ /** Below this width of the table's box (5.8) — `sm` 640px, `md` 768px — each body row becomes a card and each
953
+ * cell shows its column's header as a label: a `Td`'s `label`, else the text of the matching `Th` in `THead`.
954
+ * Done in CSS (a container query), so the server's HTML is already right; table semantics are kept. */
955
+ stackBelow?: "sm" | "md" | undefined;
943
956
  className?: string | undefined;
944
957
  children?: React$1.ReactNode | undefined;
945
958
  }
@@ -958,6 +971,8 @@ export interface TableCellProps extends Omit<React$1.TdHTMLAttributes<HTMLTableC
958
971
  mono?: boolean | undefined;
959
972
  /** Th only. Default `col`. */
960
973
  scope?: "col" | "row" | "colgroup" | "rowgroup" | undefined;
974
+ /** The label this cell shows when its table is stacked (`stackBelow`, 5.8). Default: the matching header's text. */
975
+ label?: string | undefined;
961
976
  className?: string | undefined;
962
977
  }
963
978
  export interface ActionBarProps {
@@ -1303,6 +1318,15 @@ export declare const Calendar: React$1.ForwardRefExoticComponent<CalendarProps &
1303
1318
  /** 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. */
1304
1319
  export declare const DatePicker: React$1.ForwardRefExoticComponent<DatePickerProps & React$1.RefAttributes<HTMLInputElement>>;
1305
1320
  export declare const DateRangePicker: React$1.ForwardRefExoticComponent<DateRangePickerProps & React$1.RefAttributes<HTMLInputElement>>;
1321
+ /** The class list of a Button (5.8): put it on your own link or `<Link>` to make it look like one, e.g. in a Server
1322
+ * Component — `<Link href="/renew" className={buttonClass({ variant: 'secondary' })}>Renew</Link>`. */
1323
+ export declare function buttonClass(opts?: {
1324
+ variant?: ButtonProps["variant"];
1325
+ size?: ButtonProps["size"];
1326
+ fullWidth?: boolean | undefined;
1327
+ loading?: boolean | undefined;
1328
+ className?: string | undefined;
1329
+ }): string;
1306
1330
  export declare const Alert: React$1.ForwardRefExoticComponent<AlertProps & React$1.RefAttributes<HTMLDivElement>>;
1307
1331
  /** Show a toast; returns its id. Needs `<Toaster />` mounted once. */
1308
1332
  export declare function toast(opts: ToastOptions | string): string;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,14 +17,29 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/server.ts
21
31
  var server_exports = {};
22
32
  __export(server_exports, {
33
+ Alert: () => ServerAlert,
34
+ Badge: () => ServerBadge,
35
+ Card: () => ServerCard,
36
+ EmptyState: () => ServerEmptyState,
37
+ Icon: () => Icon,
23
38
  STRINGS: () => STRINGS,
39
+ StatusPill: () => ServerStatusPill,
24
40
  brandScale: () => scale,
25
41
  breakpoints: () => breakpoints,
42
+ buttonClass: () => buttonClass,
26
43
  colorSchemeScript: () => colorSchemeScript,
27
44
  contrast: () => contrast,
28
45
  createTheme: () => createTheme,
@@ -561,14 +578,14 @@ var STRINGS = {
561
578
 
562
579
  // src/theme.ts
563
580
  function hexToRgb(hex) {
564
- let h = String(hex).trim().replace("#", "");
565
- if (h.length === 3)
566
- h = h.split("").map(function(c) {
581
+ let h3 = String(hex).trim().replace("#", "");
582
+ if (h3.length === 3)
583
+ h3 = h3.split("").map(function(c) {
567
584
  return c + c;
568
585
  }).join("");
569
- if (!/^[0-9a-f]{6}$/i.test(h)) throw new Error('createTheme: "' + hex + '" is not a #rgb or #rrggbb colour');
586
+ if (!/^[0-9a-f]{6}$/i.test(h3)) throw new Error('createTheme: "' + hex + '" is not a #rgb or #rrggbb colour');
570
587
  return [0, 2, 4].map(function(i) {
571
- return parseInt(h.slice(i, i + 2), 16) / 255;
588
+ return parseInt(h3.slice(i, i + 2), 16) / 255;
572
589
  });
573
590
  }
574
591
  function rgbToHex(rgb) {
@@ -842,3 +859,198 @@ function colorSchemeScript(options) {
842
859
 
843
860
  // src/breakpoints.ts
844
861
  var breakpoints = { sm: 640, md: 768, lg: 1024, xl: 1280 };
862
+
863
+ // src/display.tsx
864
+ var React2 = __toESM(require("react"), 1);
865
+
866
+ // src/Icon.tsx
867
+ var React = __toESM(require("react"), 1);
868
+
869
+ // src/classes.ts
870
+ function cx() {
871
+ return Array.prototype.filter.call(arguments, Boolean).join(" ");
872
+ }
873
+ function omit(src, keys) {
874
+ const out = {};
875
+ for (const k in src)
876
+ if (Object.prototype.hasOwnProperty.call(src, k) && keys.indexOf(k) < 0)
877
+ out[k] = src[k];
878
+ return out;
879
+ }
880
+ var TONES = ["neutral", "accent", "success", "warning", "danger"];
881
+ function tone(t) {
882
+ return TONES.indexOf(t) >= 0 ? t : "neutral";
883
+ }
884
+
885
+ // src/Icon.tsx
886
+ var h = React.createElement;
887
+ var ICONS = { "check": [["path", { "d": "M20 6 9 17l-5-5" }]], "x": [["path", { "d": "M18 6 6 18" }], ["path", { "d": "m6 6 12 12" }]], "plus": [["path", { "d": "M5 12h14" }], ["path", { "d": "M12 5v14" }]], "minus": [["path", { "d": "M5 12h14" }]], "search": [["path", { "d": "m21 21-4.34-4.34" }], ["circle", { "cx": "11", "cy": "11", "r": "8" }]], "chevron-down": [["path", { "d": "m6 9 6 6 6-6" }]], "chevron-up": [["path", { "d": "m18 15-6-6-6 6" }]], "chevron-left": [["path", { "d": "m15 18-6-6 6-6" }]], "chevron-right": [["path", { "d": "m9 18 6-6-6-6" }]], "arrow-right": [["path", { "d": "M5 12h14" }], ["path", { "d": "m12 5 7 7-7 7" }]], "arrow-up-right": [["path", { "d": "M7 7h10v10" }], ["path", { "d": "M7 17 17 7" }]], "arrow-up-down": [["path", { "d": "m21 16-4 4-4-4" }], ["path", { "d": "M17 20V4" }], ["path", { "d": "m3 8 4-4 4 4" }], ["path", { "d": "M7 4v16" }]], "loader-circle": [["path", { "d": "M21 12a9 9 0 1 1-6.219-8.56" }]], "circle-alert": [["circle", { "cx": "12", "cy": "12", "r": "10" }], ["line", { "x1": "12", "x2": "12", "y1": "8", "y2": "12" }], ["line", { "x1": "12", "x2": "12.01", "y1": "16", "y2": "16" }]], "circle-check": [["circle", { "cx": "12", "cy": "12", "r": "10" }], ["path", { "d": "m16 9-5.5 5.5L8 12" }]], "info": [["circle", { "cx": "12", "cy": "12", "r": "10" }], ["path", { "d": "M12 16v-4" }], ["path", { "d": "M12 8h.01" }]], "triangle-alert": [["path", { "d": "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }], ["path", { "d": "M12 9v4" }], ["path", { "d": "M12 17h.01" }]], "settings": [["path", { "d": "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" }], ["circle", { "cx": "12", "cy": "12", "r": "3" }]], "user": [["path", { "d": "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" }], ["circle", { "cx": "12", "cy": "7", "r": "4" }]], "users": [["path", { "d": "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }], ["path", { "d": "M16 3.128a4 4 0 0 1 0 7.744" }], ["path", { "d": "M22 21v-2a4 4 0 0 0-3-3.87" }], ["circle", { "cx": "9", "cy": "7", "r": "4" }]], "filter": [["path", { "d": "M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z" }]], "ellipsis": [["circle", { "cx": "12", "cy": "12", "r": "1" }], ["circle", { "cx": "19", "cy": "12", "r": "1" }], ["circle", { "cx": "5", "cy": "12", "r": "1" }]], "external-link": [["path", { "d": "M15 3h6v6" }], ["path", { "d": "M10 14 21 3" }], ["path", { "d": "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }]], "copy": [["rect", { "width": "14", "height": "14", "x": "8", "y": "8", "rx": "2", "ry": "2" }], ["path", { "d": "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" }]], "trash-2": [["path", { "d": "M10 11v6" }], ["path", { "d": "M14 11v6" }], ["path", { "d": "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }], ["path", { "d": "M3 6h18" }], ["path", { "d": "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }]], "pencil": [["path", { "d": "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" }], ["path", { "d": "m15 5 4 4" }]], "download": [["path", { "d": "M12 15V3" }], ["path", { "d": "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }], ["path", { "d": "m7 10 5 5 5-5" }]], "upload": [["path", { "d": "M12 3v12" }], ["path", { "d": "m17 8-5-5-5 5" }], ["path", { "d": "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }]], "calendar": [["path", { "d": "M8 2v3" }], ["path", { "d": "M16 2v3" }], ["rect", { "x": "3", "y": "3", "width": "18", "height": "18", "rx": "2" }], ["path", { "d": "M3 9h18" }]], "bell": [["path", { "d": "M10.268 21a2 2 0 0 0 3.464 0" }], ["path", { "d": "M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" }]], "menu": [["path", { "d": "M4 5h16" }], ["path", { "d": "M4 12h16" }], ["path", { "d": "M4 19h16" }]], "eye": [["path", { "d": "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" }], ["circle", { "cx": "12", "cy": "12", "r": "3" }]], "log-out": [["path", { "d": "m16 17 5-5-5-5" }], ["path", { "d": "M21 12H9" }], ["path", { "d": "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }]], "circle": [["circle", { "cx": "12", "cy": "12", "r": "10" }]], "circle-dot-dashed": [["path", { "d": "M10.1 2.18a9.93 9.93 0 0 1 3.8 0" }], ["path", { "d": "M17.6 3.71a9.95 9.95 0 0 1 2.69 2.7" }], ["path", { "d": "M21.82 10.1a9.93 9.93 0 0 1 0 3.8" }], ["path", { "d": "M20.29 17.6a9.95 9.95 0 0 1-2.7 2.69" }], ["path", { "d": "M13.9 21.82a9.94 9.94 0 0 1-3.8 0" }], ["path", { "d": "M6.4 20.29a9.95 9.95 0 0 1-2.69-2.7" }], ["path", { "d": "M2.18 13.9a9.93 9.93 0 0 1 0-3.8" }], ["path", { "d": "M3.71 6.4a9.95 9.95 0 0 1 2.7-2.69" }], ["circle", { "cx": "12", "cy": "12", "r": "1" }]], "ban": [["circle", { "cx": "12", "cy": "12", "r": "10" }], ["path", { "d": "M4.929 4.929 19.07 19.071" }]], "arrow-up": [["path", { "d": "m5 12 7-7 7 7" }], ["path", { "d": "M12 19V5" }]], "arrow-down": [["path", { "d": "M12 5v14" }], ["path", { "d": "m19 12-7 7-7-7" }]], "inbox": [["polyline", { "points": "22 12 16 12 14 15 10 15 8 12 2 12" }], ["path", { "d": "M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" }]], "pin": [["path", { "d": "M12 17v5" }], ["path", { "d": "M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z" }]], "pin-off": [["path", { "d": "M12 17v5" }], ["path", { "d": "M15 9.34V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H7.89" }], ["path", { "d": "m2 2 20 20" }], ["path", { "d": "M9 9v1.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h11" }]], "eye-off": [["path", { "d": "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49" }], ["path", { "d": "M14.084 14.158a3 3 0 0 1-4.242-4.242" }], ["path", { "d": "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143" }], ["path", { "d": "m2 2 20 20" }]], "columns-3": [["rect", { "width": "18", "height": "18", "x": "3", "y": "3", "rx": "2" }], ["path", { "d": "M9 3v18" }], ["path", { "d": "M15 3v18" }]], "arrow-left": [["path", { "d": "m12 19-7-7 7-7" }], ["path", { "d": "M19 12H5" }]], "rotate-ccw": [["path", { "d": "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }], ["path", { "d": "M3 3v5h5" }]], "house": [["path", { "d": "M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8" }], ["path", { "d": "M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }]], "layout-dashboard": [["rect", { "width": "7", "height": "9", "x": "3", "y": "3", "rx": "1" }], ["rect", { "width": "7", "height": "5", "x": "14", "y": "3", "rx": "1" }], ["rect", { "width": "7", "height": "9", "x": "14", "y": "12", "rx": "1" }], ["rect", { "width": "7", "height": "5", "x": "3", "y": "16", "rx": "1" }]], "folder": [["path", { "d": "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" }]], "chart-column": [["path", { "d": "M3 3v16a2 2 0 0 0 2 2h16" }], ["path", { "d": "M18 17V9" }], ["path", { "d": "M13 17V5" }], ["path", { "d": "M8 17v-3" }]], "file-text": [["path", { "d": "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" }], ["path", { "d": "M14 2v5a1 1 0 0 0 1 1h5" }], ["path", { "d": "M10 9H8" }], ["path", { "d": "M16 13H8" }], ["path", { "d": "M16 17H8" }]], "mail": [["path", { "d": "m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" }], ["rect", { "x": "2", "y": "4", "width": "20", "height": "16", "rx": "2" }]], "lock": [["rect", { "width": "18", "height": "11", "x": "3", "y": "11", "rx": "2", "ry": "2" }], ["path", { "d": "M7 11V7a5 5 0 0 1 10 0v4" }]], "clock": [["circle", { "cx": "12", "cy": "12", "r": "10" }], ["path", { "d": "M12 6v6l4 2" }]], "trending-up": [["path", { "d": "M16 7h6v6" }], ["path", { "d": "m22 7-8.5 8.5-5-5L2 17" }]], "trending-down": [["path", { "d": "M16 17h6v-6" }], ["path", { "d": "m22 17-8.5-8.5-5 5L2 7" }]], "image": [["rect", { "width": "18", "height": "18", "x": "3", "y": "3", "rx": "2", "ry": "2" }], ["circle", { "cx": "9", "cy": "9", "r": "2" }], ["path", { "d": "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" }]], "paperclip": [["path", { "d": "m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551" }]], "cloud-upload": [["path", { "d": "M12 13v8" }], ["path", { "d": "M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242" }], ["path", { "d": "m8 17 4-4 4 4" }]], "file": [["path", { "d": "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" }], ["path", { "d": "M14 2v5a1 1 0 0 0 1 1h5" }]], "sun": [["circle", { "cx": "12", "cy": "12", "r": "4" }], ["path", { "d": "M12 2v2" }], ["path", { "d": "M12 20v2" }], ["path", { "d": "m4.93 4.93 1.41 1.41" }], ["path", { "d": "m17.66 17.66 1.41 1.41" }], ["path", { "d": "M2 12h2" }], ["path", { "d": "M20 12h2" }], ["path", { "d": "m6.34 17.66-1.41 1.41" }], ["path", { "d": "m19.07 4.93-1.41 1.41" }]], "moon": [["path", { "d": "M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401" }]], "monitor": [["rect", { "width": "20", "height": "14", "x": "2", "y": "3", "rx": "2" }], ["line", { "x1": "8", "x2": "16", "y1": "21", "y2": "21" }], ["line", { "x1": "12", "x2": "12", "y1": "17", "y2": "21" }]], "panel-left-close": [["rect", { "width": "18", "height": "18", "x": "3", "y": "3", "rx": "2" }], ["path", { "d": "M9 3v18" }], ["path", { "d": "m16 15-3-3 3-3" }]], "panel-left-open": [["rect", { "width": "18", "height": "18", "x": "3", "y": "3", "rx": "2" }], ["path", { "d": "M9 3v18" }], ["path", { "d": "m14 9 3 3-3 3" }]], "server": [["rect", { "width": "20", "height": "8", "x": "2", "y": "2", "rx": "2", "ry": "2" }], ["rect", { "width": "20", "height": "8", "x": "2", "y": "14", "rx": "2", "ry": "2" }], ["line", { "x1": "6", "x2": "6.01", "y1": "6", "y2": "6" }], ["line", { "x1": "6", "x2": "6.01", "y1": "18", "y2": "18" }]], "globe": [["circle", { "cx": "12", "cy": "12", "r": "10" }], ["path", { "d": "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }], ["path", { "d": "M2 12h20" }]], "activity": [["path", { "d": "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2" }]], "shield-alert": [["path", { "d": "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" }], ["path", { "d": "M12 8v4" }], ["path", { "d": "M12 16h.01" }]], "phone": [["path", { "d": "M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384" }]], "wrench": [["path", { "d": "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z" }]] };
888
+ var SIZES = { sm: 16, md: 20, lg: 24 };
889
+ var Icon = React.forwardRef(function Icon2(props, ref) {
890
+ const size = SIZES[props.size] || props.size || 16;
891
+ if (React.isValidElement(props.name)) {
892
+ return /* @__PURE__ */ React.createElement(
893
+ "span",
894
+ {
895
+ className: cx("aura-icon", "aura-icon--custom", props.className),
896
+ style: { width: size, height: size, ["--aura-icon-stroke"]: props.strokeWidth || 2 },
897
+ ...props.label ? { role: "img", "aria-label": props.label } : { "aria-hidden": true }
898
+ },
899
+ props.name
900
+ );
901
+ }
902
+ const shapes = ICONS[props.name];
903
+ if (!shapes) return null;
904
+ const a11y = props.label ? { role: "img", "aria-label": props.label } : { "aria-hidden": true, focusable: "false" };
905
+ return /* @__PURE__ */ React.createElement(
906
+ "svg",
907
+ {
908
+ ref,
909
+ xmlns: "http://www.w3.org/2000/svg",
910
+ width: size,
911
+ height: size,
912
+ viewBox: "0 0 24 24",
913
+ fill: "none",
914
+ stroke: "currentColor",
915
+ strokeWidth: props.strokeWidth || 2,
916
+ strokeLinecap: "round",
917
+ strokeLinejoin: "round",
918
+ className: cx("aura-icon", props.className),
919
+ ...a11y
920
+ },
921
+ shapes.map(function(s, i) {
922
+ const attrs = { key: i };
923
+ for (const k in s[1]) attrs[k === "stroke-width" ? "strokeWidth" : k] = s[1][k];
924
+ return h(s[0], attrs);
925
+ })
926
+ );
927
+ });
928
+ var iconNames = Object.keys(ICONS);
929
+
930
+ // src/display.tsx
931
+ var h2 = React2.createElement;
932
+ var ALERT_ICON = {
933
+ info: "info",
934
+ success: "circle-check",
935
+ warning: "triangle-alert",
936
+ danger: "circle-alert"
937
+ };
938
+ function alertElement(props, ref, close) {
939
+ const tone2 = props.tone || "info";
940
+ const rest = omit(props, ["tone", "title", "children", "action", "onDismiss", "className", "role", "icon"]);
941
+ return /* @__PURE__ */ React2.createElement(
942
+ "div",
943
+ {
944
+ ...rest,
945
+ ref,
946
+ className: cx("aura-alert", "aura-alert--" + tone2, props.className),
947
+ role: props.role || (tone2 === "danger" || tone2 === "warning" ? "alert" : "status")
948
+ },
949
+ /* @__PURE__ */ React2.createElement(Icon, { name: props.icon || ALERT_ICON[tone2], className: "aura-alert__icon" }),
950
+ /* @__PURE__ */ React2.createElement("div", { className: "aura-alert__body" }, props.title ? /* @__PURE__ */ React2.createElement("p", { className: "aura-alert__title" }, props.title) : null, props.children ? /* @__PURE__ */ React2.createElement("div", { className: "aura-alert__text" }, props.children) : null, props.action ? /* @__PURE__ */ React2.createElement("div", { className: "aura-alert__action" }, props.action) : null),
951
+ close
952
+ );
953
+ }
954
+ function cardElement(props, ref) {
955
+ const creative = props.variant === "creative";
956
+ const rest = omit(props, [
957
+ "title",
958
+ "description",
959
+ "actions",
960
+ "footer",
961
+ "children",
962
+ "variant",
963
+ "headingLevel",
964
+ "interactive",
965
+ "as",
966
+ "className",
967
+ "titleId"
968
+ ]);
969
+ return h2(
970
+ props.as || "section",
971
+ Object.assign({}, rest, {
972
+ ref,
973
+ className: cx(
974
+ "aura-card",
975
+ creative && "aura-card--creative",
976
+ props.interactive && "is-interactive",
977
+ props.className
978
+ ),
979
+ /* A titled card is labelled by its title; otherwise the caller's aria-labelledby stays (5.8). */
980
+ "aria-labelledby": props.title && props.titleId ? props.titleId : props["aria-labelledby"]
981
+ }),
982
+ props.title || props.actions ? /* @__PURE__ */ React2.createElement("div", { className: "aura-card__head" }, /* @__PURE__ */ React2.createElement("div", { className: "aura-card__heading" }, props.title ? h2("h" + (props.headingLevel || 3), { className: "aura-card__title", id: props.titleId }, props.title) : null, props.description ? /* @__PURE__ */ React2.createElement("p", { className: "aura-card__desc" }, props.description) : null), props.actions ? /* @__PURE__ */ React2.createElement("div", { className: "aura-card__actions" }, props.actions) : null) : null,
983
+ props.children ? /* @__PURE__ */ React2.createElement("div", { className: "aura-card__body" }, props.children) : null,
984
+ props.footer ? /* @__PURE__ */ React2.createElement("div", { className: "aura-card__foot" }, props.footer) : null
985
+ );
986
+ }
987
+ var PILL_ICON = {
988
+ neutral: "circle",
989
+ progress: "circle-dot-dashed",
990
+ ready: "circle-check",
991
+ warning: "triangle-alert",
992
+ blocked: "ban"
993
+ };
994
+ function statusPillElement(props, ref) {
995
+ const tone2 = props.tone || toneFor(props.children);
996
+ const rest = omit(props, ["tone", "className", "children"]);
997
+ return /* @__PURE__ */ React2.createElement("span", { ...rest, ref, className: cx("aura-pill", "aura-pill--" + tone2, props.className) }, /* @__PURE__ */ React2.createElement(Icon, { name: PILL_ICON[tone2] || "circle", size: 12 }), props.children);
998
+ }
999
+ function badgeElement(props, ref) {
1000
+ const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
1001
+ return /* @__PURE__ */ React2.createElement(
1002
+ "span",
1003
+ {
1004
+ ...rest,
1005
+ ref,
1006
+ className: cx(
1007
+ "aura-badge",
1008
+ "aura-badge--" + tone(props.tone),
1009
+ props.variant === "solid" && "is-solid",
1010
+ props.variant === "outline" && "is-outline",
1011
+ props.className
1012
+ )
1013
+ },
1014
+ props.icon ? /* @__PURE__ */ React2.createElement(Icon, { name: props.icon, size: 12 }) : null,
1015
+ props.children
1016
+ );
1017
+ }
1018
+ function emptyStateElement(props, ref) {
1019
+ const HT = "h" + (props.headingLevel || 3);
1020
+ return /* @__PURE__ */ React2.createElement(
1021
+ "div",
1022
+ {
1023
+ ref,
1024
+ className: cx("aura-empty", props.size === "sm" && "is-sm", props.bordered && "is-bordered", props.className)
1025
+ },
1026
+ /* @__PURE__ */ React2.createElement("span", { className: "aura-empty__icon", "aria-hidden": true }, /* @__PURE__ */ React2.createElement(Icon, { name: props.icon || "inbox", size: props.size === "sm" ? "md" : "lg" })),
1027
+ /* @__PURE__ */ React2.createElement(HT, { className: "aura-empty__title" }, props.title),
1028
+ props.description ? /* @__PURE__ */ React2.createElement("p", { className: "aura-empty__text" }, props.description) : null,
1029
+ props.action ? /* @__PURE__ */ React2.createElement("div", { className: "aura-empty__action" }, props.action) : null
1030
+ );
1031
+ }
1032
+ function buttonClass(opts = {}) {
1033
+ return cx(
1034
+ "aura-btn",
1035
+ "aura-btn--" + (opts.variant || "primary"),
1036
+ opts.size === "sm" && "aura-btn--sm",
1037
+ opts.fullWidth && "aura-btn--full",
1038
+ opts.loading && "is-loading",
1039
+ opts.className
1040
+ );
1041
+ }
1042
+ function ServerAlert(props) {
1043
+ return alertElement(props, void 0, null);
1044
+ }
1045
+ function ServerCard(props) {
1046
+ return cardElement(props, void 0);
1047
+ }
1048
+ function ServerStatusPill(props) {
1049
+ return statusPillElement(props, void 0);
1050
+ }
1051
+ function ServerBadge(props) {
1052
+ return badgeElement(props, void 0);
1053
+ }
1054
+ function ServerEmptyState(props) {
1055
+ return emptyStateElement(props, void 0);
1056
+ }
@@ -1,7 +1,86 @@
1
1
  import * as React$1 from 'react';
2
2
 
3
+ /** Button look. */
4
+ export type ButtonVariant = "primary" | "secondary" | "ghost" | "creative" | "danger" | "danger-secondary";
5
+ /** `md` 44px (default) · `sm` 32px for toolbars, table rows and card footers (still a 44px hit area on touch screens). */
6
+ export type ButtonSize = "sm" | "md";
7
+ /** AURA pill button. Enterprise (`primary`, `secondary`) for product UI; `creative` for marketing moments only. */
8
+ export interface ButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
9
+ /** Visual variant. Default `primary`. `ghost` has no fill or edge until hover (toolbars, rows, secondary actions beside a primary). `danger` (filled) and `danger-secondary` (outline) are for irreversible or destructive actions only — typically the confirm button of a `Dialog role="alertdialog"`. */
10
+ variant?: ButtonVariant | undefined;
11
+ /** Label text — short, Title Case English or Thai. */
12
+ children: React$1.ReactNode;
13
+ /** Leading icon name (see `IconName`). Hidden while loading. */
14
+ icon?: IconInput | undefined;
15
+ /** Trailing icon name, e.g. `arrow-right` for forward actions. */
16
+ iconRight?: IconInput | undefined;
17
+ /** Shows a spinner in place of the leading icon, sets aria-busy and swallows clicks. Keeps the label and width. */
18
+ loading?: boolean | undefined;
19
+ /** Fills its container and lets a long label wrap onto more lines (at least 44px tall) — phones, Thai and Swedish labels. */
20
+ fullWidth?: boolean | undefined;
21
+ /** `sm` is 32px with tighter padding, for toolbars, table rows and card footers. Default `md` (44px). */
22
+ size?: ButtonSize | undefined;
23
+ }
24
+ /** An AURA icon name, or any icon element (e.g. `<Building />` from lucide-react). AURA sizes it and hides it from screen readers. */
25
+ export type IconInput = IconName | React$1.ReactElement;
26
+ export type IconName = "check" | "x" | "plus" | "minus" | "search" | "chevron-down" | "chevron-up" | "chevron-left" | "chevron-right" | "arrow-right" | "arrow-up-right" | "arrow-up-down" | "loader-circle" | "circle-alert" | "circle-check" | "info" | "triangle-alert" | "settings" | "user" | "users" | "filter" | "ellipsis" | "external-link" | "copy" | "trash-2" | "pencil" | "download" | "upload" | "calendar" | "bell" | "menu" | "eye" | "log-out" | "circle" | "circle-dot-dashed" | "ban" | "arrow-up" | "arrow-down" | "inbox" | "pin" | "pin-off" | "eye-off" | "columns-3" | "arrow-left" | "rotate-ccw" | "house" | "layout-dashboard" | "folder" | "chart-column" | "file-text" | "mail" | "lock" | "clock" | "trending-up" | "trending-down" | "image" | "paperclip" | "cloud-upload" | "file" | "sun" | "moon" | "monitor" | "panel-left-close" | "panel-left-open" | "server" | "globe" | "activity" | "shield-alert" | "phone" | "wrench";
27
+ /** Lucide stroke icon drawn inline in currentColor. */
28
+ export interface IconProps {
29
+ /** A name from the set, or an icon element of your own (sized and styled the same way). */
30
+ name: IconInput;
31
+ /** `sm` 16 (default) · `md` 20 · `lg` 24, or a px number. */
32
+ size?: "sm" | "md" | "lg" | number | undefined;
33
+ /** Accessible name. Omit for decorative icons next to a text label (then aria-hidden). */
34
+ label?: string | undefined;
35
+ /** Default 2 (Lucide's). */
36
+ strokeWidth?: number | undefined;
37
+ className?: string | undefined;
38
+ }
3
39
  /** `warning` (5.1): needs attention but still works — Warning, Problem, Degraded, At risk. */
4
40
  export type StatusTone = "neutral" | "progress" | "ready" | "warning" | "blocked";
41
+ /** Status pill: tone fill + icon + the status word. Tone comes from the word unless given. */
42
+ export interface StatusPillProps extends Omit<React$1.HTMLAttributes<HTMLSpanElement>, "children"> {
43
+ /** The status word shown, e.g. "In Progress". Other attributes (`id`, `data-*`, `aria-*`) go on the pill (5.8). */
44
+ children: React$1.ReactNode;
45
+ /** Force a tone. Default: matched from the word (Ready/Done → ready, In Progress/In Review → progress, Warning/Problem/Degraded/At risk → warning (5.1), Blocked/Failed → blocked, anything else → neutral). */
46
+ tone?: StatusTone | undefined;
47
+ className?: string | undefined;
48
+ }
49
+ export type FeedbackTone = "info" | "success" | "warning" | "danger";
50
+ export interface AlertProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "title" | "role"> {
51
+ tone?: FeedbackTone | undefined;
52
+ /** Default: `alert` for warning and danger, `status` otherwise (5.8). Pass `status` for a standing notice in a
53
+ * warning or danger tone that shouldn't interrupt; `note` or `none` for one that isn't a live region. */
54
+ role?: "alert" | "status" | "note" | "none" | undefined;
55
+ /** Replaces the tone's icon (5.8): a name or your own element; always hidden from screen readers. */
56
+ icon?: IconInput | undefined;
57
+ title?: React$1.ReactNode | undefined;
58
+ children?: React$1.ReactNode | undefined;
59
+ /** Usually a secondary Button. */
60
+ action?: React$1.ReactNode | undefined;
61
+ /** Adds a close button. */
62
+ onDismiss?: (() => void) | undefined;
63
+ className?: string | undefined;
64
+ }
65
+ /** Other attributes (`id`, `data-*`, `aria-*`) go on the card's root (5.8). */
66
+ export interface CardProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "title"> {
67
+ title?: React$1.ReactNode | undefined;
68
+ description?: React$1.ReactNode | undefined;
69
+ /** Top-right, usually an IconButton. */
70
+ actions?: React$1.ReactNode | undefined;
71
+ footer?: React$1.ReactNode | undefined;
72
+ children?: React$1.ReactNode | undefined;
73
+ /** Default `enterprise`. `creative` is for marketing and onboarding only. */
74
+ variant?: "enterprise" | "creative" | undefined;
75
+ /** Heading level of the title. Default 3 — use 2 when cards sit directly under the page h1. */
76
+ headingLevel?: 2 | 3 | 4 | 5 | 6 | undefined;
77
+ /** Hover edge for clickable cards. */
78
+ interactive?: boolean | undefined;
79
+ as?: keyof React$1.JSX.IntrinsicElements | undefined;
80
+ className?: string | undefined;
81
+ /** id for the title element; the card is then labelled by it (aria-labelledby). */
82
+ titleId?: string | undefined;
83
+ }
5
84
  /** ISO date string, `YYYY-MM-DD` (Gregorian — the era is display only). */
6
85
  export type ISODate = string;
7
86
  export interface DateDisplayOptions {
@@ -10,6 +89,24 @@ export interface DateDisplayOptions {
10
89
  /** `buddhist` (พ.ศ.; default for th) or `gregory` (ค.ศ.; default for en and sv). */
11
90
  calendar?: "buddhist" | "gregory" | undefined;
12
91
  }
92
+ export type Tone = "neutral" | "accent" | "success" | "warning" | "danger";
93
+ export interface BadgeProps extends React$1.HTMLAttributes<HTMLSpanElement> {
94
+ tone?: Tone | undefined;
95
+ /** soft (default) · solid · outline */
96
+ variant?: "soft" | "solid" | "outline" | undefined;
97
+ icon?: IconInput | undefined;
98
+ }
99
+ export interface EmptyStateProps {
100
+ title: React$1.ReactNode;
101
+ description?: React$1.ReactNode | undefined;
102
+ icon?: IconInput | undefined;
103
+ /** One or two buttons. */
104
+ action?: React$1.ReactNode | undefined;
105
+ size?: "sm" | "md" | undefined;
106
+ bordered?: boolean | undefined;
107
+ headingLevel?: 2 | 3 | 4 | 5 | 6 | undefined;
108
+ className?: string | undefined;
109
+ }
13
110
  export interface ThemeOptions {
14
111
  /** The project's brand colour, #rgb or #rrggbb. Replaces AURA violet (links, focus ring, selection, info, progress, creative shadow in dark, mesh). */
15
112
  brand: string;
@@ -173,8 +270,28 @@ export declare const breakpoints: {
173
270
  lg: 1024;
174
271
  xl: 1280;
175
272
  };
273
+ /** The class list of a Button (5.8): put it on your own link or `<Link>` to make it look like one, e.g. in a Server
274
+ * Component — `<Link href="/renew" className={buttonClass({ variant: 'secondary' })}>Renew</Link>`. */
275
+ export declare function buttonClass(opts?: {
276
+ variant?: ButtonProps["variant"];
277
+ size?: ButtonProps["size"];
278
+ fullWidth?: boolean | undefined;
279
+ loading?: boolean | undefined;
280
+ className?: string | undefined;
281
+ }): string;
282
+ declare function ServerAlert(props: Omit<AlertProps, "onDismiss">): React$1.ReactElement;
283
+ declare function ServerCard(props: CardProps): React$1.ReactElement;
284
+ declare function ServerStatusPill(props: StatusPillProps): React$1.ReactElement;
285
+ declare function ServerBadge(props: BadgeProps): React$1.ReactElement;
286
+ declare function ServerEmptyState(props: EmptyStateProps): React$1.ReactElement;
287
+ export declare const Icon: React$1.ForwardRefExoticComponent<IconProps & React$1.RefAttributes<SVGSVGElement>>;
176
288
 
177
289
  export {
290
+ ServerAlert as Alert,
291
+ ServerBadge as Badge,
292
+ ServerCard as Card,
293
+ ServerEmptyState as EmptyState,
294
+ ServerStatusPill as StatusPill,
178
295
  scale as brandScale,
179
296
  toneFor as statusTone,
180
297
  };