@gtivr4/a1-design-system-react 0.4.0 → 0.5.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.
Files changed (57) hide show
  1. package/package.json +2 -1
  2. package/src/components/accordion/Accordion.d.ts +20 -0
  3. package/src/components/banner/Banner.d.ts +19 -0
  4. package/src/components/bleed/Bleed.d.ts +17 -0
  5. package/src/components/blockquote/Blockquote.d.ts +23 -0
  6. package/src/components/breadcrumb/Breadcrumb.d.ts +22 -0
  7. package/src/components/button/Button.d.ts +17 -0
  8. package/src/components/button-container/ButtonContainer.d.ts +11 -0
  9. package/src/components/calendar/Calendar.d.ts +75 -0
  10. package/src/components/calendar/Calendar.jsx +76 -13
  11. package/src/components/calendar/calendar.css +71 -0
  12. package/src/components/card/Card.d.ts +31 -0
  13. package/src/components/checkbox-group/CheckboxGroup.d.ts +37 -0
  14. package/src/components/choice-group/ChoiceGroup.d.ts +68 -0
  15. package/src/components/circular-progress/CircularProgress.d.ts +37 -0
  16. package/src/components/circular-progress/CircularProgress.jsx +85 -0
  17. package/src/components/circular-progress/circular-progress.css +104 -0
  18. package/src/components/cluster/Cluster.d.ts +21 -0
  19. package/src/components/code/Code.d.ts +15 -0
  20. package/src/components/data-table/DataTable.d.ts +83 -0
  21. package/src/components/dialog/Dialog.d.ts +15 -0
  22. package/src/components/dialog/dialog.css +7 -3
  23. package/src/components/divider/Divider.d.ts +22 -0
  24. package/src/components/field/SelectField.d.ts +22 -0
  25. package/src/components/field/TextField.d.ts +21 -0
  26. package/src/components/field/TextareaField.d.ts +28 -0
  27. package/src/components/field-row/FieldRow.d.ts +8 -0
  28. package/src/components/fieldset/Fieldset.d.ts +27 -0
  29. package/src/components/figure/Figure.d.ts +39 -0
  30. package/src/components/grid/Grid.d.ts +38 -0
  31. package/src/components/heading/Heading.d.ts +43 -0
  32. package/src/components/heading/Heading.jsx +2 -2
  33. package/src/components/icon/Icon.d.ts +25 -0
  34. package/src/components/icon-button/IconButton.d.ts +14 -0
  35. package/src/components/inset/Inset.d.ts +17 -0
  36. package/src/components/inverse/Inverse.d.ts +9 -0
  37. package/src/components/link/Link.d.ts +15 -0
  38. package/src/components/list/List.d.ts +40 -0
  39. package/src/components/menu/Menu.d.ts +41 -0
  40. package/src/components/message/Message.d.ts +34 -0
  41. package/src/components/notification/Notification.d.ts +23 -0
  42. package/src/components/page-layout/PageLayout.d.ts +24 -0
  43. package/src/components/page-nav/PageNav.d.ts +19 -0
  44. package/src/components/pagination/Pagination.d.ts +19 -0
  45. package/src/components/paragraph/Paragraph.d.ts +23 -0
  46. package/src/components/radio-group/RadioGroup.d.ts +37 -0
  47. package/src/components/section/Section.d.ts +33 -0
  48. package/src/components/segmented-control/SegmentedControl.d.ts +23 -0
  49. package/src/components/side-nav/SideNav.d.ts +62 -0
  50. package/src/components/spacer/Spacer.d.ts +16 -0
  51. package/src/components/stack/Stack.d.ts +38 -0
  52. package/src/components/status-bar/StatusBar.d.ts +42 -0
  53. package/src/components/switch/Switch.d.ts +27 -0
  54. package/src/components/system-banner/SystemBanner.d.ts +17 -0
  55. package/src/components/tabs/Tabs.d.ts +53 -0
  56. package/src/index.js +2 -0
  57. package/src/tokens.css +22 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtivr4/a1-design-system-react",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "React components for the A1 token-driven design system.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -17,6 +17,7 @@
17
17
  "README.md",
18
18
  "guidelines/**/*.md",
19
19
  "src/**/*.css",
20
+ "src/**/*.d.ts",
20
21
  "src/**/*.jsx",
21
22
  "src/index.js",
22
23
  "!src/**/*.stories.jsx",
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+
3
+ export interface AccordionProps {
4
+ /** Trigger label text */
5
+ label: string;
6
+ /** Controlled open state */
7
+ open?: boolean;
8
+ /** Initial open state (uncontrolled). Default: false */
9
+ defaultOpen?: boolean;
10
+ /** Called with the next boolean when the trigger is clicked */
11
+ onChange?: (open: boolean) => void;
12
+ /** Size — affects trigger text size and padding. Default: "md" */
13
+ size?: "sm" | "md" | "lg";
14
+ /** Prevent the accordion from being toggled. Default: false */
15
+ disabled?: boolean;
16
+ className?: string;
17
+ children?: React.ReactNode;
18
+ }
19
+
20
+ export declare function Accordion(props: AccordionProps): React.ReactElement;
@@ -0,0 +1,19 @@
1
+ import * as React from "react";
2
+
3
+ export interface BannerProps {
4
+ /** Layout style. "inline" sits within content; "system" spans full width. Default: "inline" */
5
+ variant?: "inline" | "system";
6
+ /** Semantic status colour. Default: "neutral" */
7
+ status?: "neutral" | "info" | "success" | "warn" | "error";
8
+ /** Bold title text shown before the body */
9
+ title?: string;
10
+ /** Override the default status icon with any Material Symbols name */
11
+ icon?: string;
12
+ /** Action element (e.g. a Button) rendered at the trailing end */
13
+ action?: React.ReactNode;
14
+ /** Called when the dismiss button is clicked. Omit to hide the dismiss button. */
15
+ onDismiss?: () => void;
16
+ children?: React.ReactNode;
17
+ }
18
+
19
+ export declare function Banner(props: BannerProps): React.ReactElement;
@@ -0,0 +1,17 @@
1
+ import * as React from "react";
2
+
3
+ type SpacingToken = 1 | 2 | 4 | 6 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 64 | 96 | 128;
4
+
5
+ export interface BleedProps extends React.HTMLAttributes<HTMLElement> {
6
+ /** Underlying element. Default: "div" */
7
+ as?: React.ElementType;
8
+ /** Base bleed amount applied to all axes when no axis-specific value is set. Default: 16 */
9
+ space?: SpacingToken | "none";
10
+ /** Block-axis (top/bottom) bleed override. Default: "none" */
11
+ block?: SpacingToken | "none";
12
+ /** Inline-axis (left/right) bleed override. Falls back to `space`. */
13
+ inline?: SpacingToken;
14
+ children?: React.ReactNode;
15
+ }
16
+
17
+ export declare function Bleed(props: BleedProps): React.ReactElement;
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+
3
+ export interface BlockquoteProps extends React.HTMLAttributes<HTMLElement> {
4
+ /**
5
+ * Visual style variant. Default: "border"
6
+ *
7
+ * border — left accent border, subtle background
8
+ * filled — filled neutral surface
9
+ * feature — large centered text with accent bar, for pullquotes
10
+ * minimal — no decoration, plain text
11
+ * accent — filled action-colour background with inverse text
12
+ * pull — centred editorial with curly quotes
13
+ * ruled — top + bottom horizontal rules, centred
14
+ */
15
+ variant?: "border" | "filled" | "feature" | "minimal" | "accent" | "pull" | "ruled";
16
+ /** Attribution text rendered as a `<figcaption>` */
17
+ cite?: string;
18
+ /** URL that the cite text links to */
19
+ citeUrl?: string;
20
+ children?: React.ReactNode;
21
+ }
22
+
23
+ export declare function Blockquote(props: BlockquoteProps): React.ReactElement;
@@ -0,0 +1,22 @@
1
+ import * as React from "react";
2
+
3
+ export interface BreadcrumbItem {
4
+ label: string;
5
+ href?: string;
6
+ onClick?: () => void;
7
+ }
8
+
9
+ export interface BreadcrumbProps extends React.HTMLAttributes<HTMLElement> {
10
+ /**
11
+ * Ordered list of breadcrumb items.
12
+ * The last item is treated as the current page (non-interactive).
13
+ * All previous items render as links or buttons.
14
+ */
15
+ items?: BreadcrumbItem[];
16
+ /**
17
+ * Label for the back link shown in narrow containers. Defaults to "Back".
18
+ */
19
+ backLabel?: string;
20
+ }
21
+
22
+ export declare function Breadcrumb(props: BreadcrumbProps): React.ReactElement;
@@ -0,0 +1,17 @@
1
+ import * as React from "react";
2
+
3
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
4
+ /** Underlying element or component to render. Default: "button" */
5
+ as?: React.ElementType;
6
+ /** Visual style. Default: "primary" */
7
+ variant?: "primary" | "secondary" | "tertiary" | "destructive" | "success";
8
+ /** Size. Default: "md" */
9
+ size?: "sm" | "md" | "lg";
10
+ /** Material Symbols icon name to show alongside the label */
11
+ icon?: string;
12
+ /** Whether the icon appears before or after the label. Default: "start" */
13
+ iconPosition?: "start" | "end";
14
+ children?: React.ReactNode;
15
+ }
16
+
17
+ export declare function Button(props: ButtonProps): React.ReactElement;
@@ -0,0 +1,11 @@
1
+ import * as React from "react";
2
+
3
+ export interface ButtonContainerProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ /** Horizontal alignment of buttons. Default: "start" */
5
+ align?: "start" | "center" | "end";
6
+ /** Default size passed to child Button elements that do not set their own size. */
7
+ size?: "sm" | "md" | "lg";
8
+ children?: React.ReactNode;
9
+ }
10
+
11
+ export declare function ButtonContainer(props: ButtonContainerProps): React.ReactElement;
@@ -0,0 +1,75 @@
1
+ import * as React from "react";
2
+
3
+ export interface CalendarMonth {
4
+ /** Full calendar year, e.g. 2026 */
5
+ year: number;
6
+ /** 1-indexed month: 1 = January … 12 = December */
7
+ month: number;
8
+ }
9
+
10
+ export interface CalendarProps extends React.HTMLAttributes<HTMLDivElement> {
11
+ /**
12
+ * Display mode.
13
+ * - `"scroll"` — renders all months vertically; parent container controls scrolling (default).
14
+ * - `"paginated"` — shows one month at a time with prev/next buttons and month/year selects.
15
+ */
16
+ variant?: "scroll" | "paginated";
17
+ /**
18
+ * Month to centre the scroll position on at mount (scroll) or the initial month shown (paginated).
19
+ * Accepts a `Date` object or `{ year, month }` (month is 1-indexed).
20
+ * Defaults to the current month.
21
+ */
22
+ initialMonth?: Date | CalendarMonth;
23
+ /**
24
+ * Total number of months to render. Only applies to `variant="scroll"`.
25
+ * Default: 13
26
+ */
27
+ monthsToShow?: number;
28
+ /**
29
+ * Highlight today's date with the action colour.
30
+ * Default: true
31
+ */
32
+ highlightToday?: boolean;
33
+ /**
34
+ * Apply a background tint to dates before today.
35
+ * Default: true
36
+ */
37
+ dimPast?: boolean;
38
+ /**
39
+ * Show a "Today" button in the paginated nav bar that jumps to the current month.
40
+ * Disabled automatically when already on the current month.
41
+ * Only applies to `variant="paginated"`.
42
+ * Default: false
43
+ */
44
+ todayButton?: boolean;
45
+ /**
46
+ * Enables date selection. When false (default), the calendar is display-only —
47
+ * no click handlers, hover effects, or keyboard interaction on day cells.
48
+ * Pass `selectedDate` or `defaultSelectedDate` alongside this prop.
49
+ * Default: false
50
+ */
51
+ selectable?: boolean;
52
+ /**
53
+ * The currently selected date (controlled). Pass `null` to clear the selection.
54
+ * Omit entirely to use uncontrolled mode with `defaultSelectedDate`.
55
+ */
56
+ selectedDate?: Date | null;
57
+ /**
58
+ * Initial selected date for uncontrolled mode. Ignored when `selectedDate` is provided.
59
+ */
60
+ defaultSelectedDate?: Date | null;
61
+ /**
62
+ * Called with the new `Date` whenever the user clicks a selectable day.
63
+ */
64
+ onChange?: (date: Date) => void;
65
+ /**
66
+ * Earliest selectable date (inclusive). Days before this are disabled.
67
+ */
68
+ minDate?: Date;
69
+ /**
70
+ * Latest selectable date (inclusive). Days after this are disabled.
71
+ */
72
+ maxDate?: Date;
73
+ }
74
+
75
+ export declare function Calendar(props: CalendarProps): React.ReactElement;
@@ -42,6 +42,12 @@ export function Calendar({
42
42
  dimPast = true,
43
43
  variant = "scroll",
44
44
  todayButton = false,
45
+ selectable = false,
46
+ selectedDate,
47
+ defaultSelectedDate,
48
+ onChange,
49
+ minDate,
50
+ maxDate,
45
51
  className = "",
46
52
  ...props
47
53
  }) {
@@ -63,6 +69,35 @@ export function Calendar({
63
69
  const [viewMonth, setViewMonth] = useState(centerMonth);
64
70
  const currentMonthRef = useRef(null);
65
71
 
72
+ // Selection — controlled when selectedDate is provided, otherwise internal state
73
+ const isControlled = selectedDate !== undefined;
74
+ const [internalSelected, setInternalSelected] = useState(defaultSelectedDate ?? null);
75
+ const selected = isControlled ? selectedDate : internalSelected;
76
+
77
+ function isSameDay(d, y, m, day) {
78
+ return d instanceof Date && d.getFullYear() === y && d.getMonth() === m && d.getDate() === day;
79
+ }
80
+
81
+ function isDayDisabled(y, m, day) {
82
+ const date = new Date(y, m, day);
83
+ if (minDate) {
84
+ const min = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
85
+ if (date < min) return true;
86
+ }
87
+ if (maxDate) {
88
+ const max = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate());
89
+ if (date > max) return true;
90
+ }
91
+ return false;
92
+ }
93
+
94
+ function handleDayClick(y, m, day) {
95
+ if (isDayDisabled(y, m, day)) return;
96
+ const date = new Date(y, m, day);
97
+ if (!isControlled) setInternalSelected(date);
98
+ onChange?.(date);
99
+ }
100
+
66
101
  // ── Localised strings ─────────────────────────────────────────
67
102
 
68
103
  // Month names
@@ -210,15 +245,30 @@ export function Calendar({
210
245
  dimPast &&
211
246
  new Date(year, month, day) < new Date(todayYear, todayMonth, todayDay);
212
247
 
248
+ const isSelected = isSameDay(selected, year, month, day);
249
+ const isDisabled = isDayDisabled(year, month, day);
250
+
213
251
  return (
214
252
  <td
215
253
  key={di}
216
254
  className={[
217
255
  "a1-calendar__day",
218
- isToday && "a1-calendar__day--today",
219
- isPast && "a1-calendar__day--past",
256
+ isToday && "a1-calendar__day--today",
257
+ isPast && "a1-calendar__day--past",
258
+ isSelected && "a1-calendar__day--selected",
259
+ isDisabled && "a1-calendar__day--disabled",
220
260
  ].filter(Boolean).join(" ")}
221
261
  aria-current={isToday ? "date" : undefined}
262
+ aria-selected={isSelected ? true : undefined}
263
+ aria-disabled={isDisabled ? true : undefined}
264
+ tabIndex={selectable && !isDisabled ? 0 : undefined}
265
+ onClick={selectable && !isDisabled ? () => handleDayClick(year, month, day) : undefined}
266
+ onKeyDown={selectable && !isDisabled ? (e) => {
267
+ if (e.key === "Enter" || e.key === " ") {
268
+ e.preventDefault();
269
+ handleDayClick(year, month, day);
270
+ }
271
+ } : undefined}
222
272
  >
223
273
  <span className="a1-calendar__day-number" aria-hidden="true">
224
274
  {day}
@@ -235,17 +285,27 @@ export function Calendar({
235
285
 
236
286
  // ── Paginated variant ─────────────────────────────────────────
237
287
  if (variant === "paginated") {
238
- const yearStart = todayYear - 10;
239
- const yearEnd = todayYear + 15;
288
+ const minYear = minDate ? minDate.getFullYear() : todayYear - 10;
289
+ const minMon = minDate ? minDate.getMonth() : 0;
290
+ const maxYear = maxDate ? maxDate.getFullYear() : todayYear + 15;
291
+ const maxMon = maxDate ? maxDate.getMonth() : 11;
292
+
293
+ const yearStart = minDate ? minDate.getFullYear() : todayYear - 10;
294
+ const yearEnd = maxDate ? maxDate.getFullYear() : todayYear + 15;
240
295
  const years = Array.from({ length: yearEnd - yearStart + 1 }, (_, i) => yearStart + i);
241
296
 
297
+ const prevAtMin = viewYear === minYear && viewMonth === minMon;
298
+ const nextAtMax = viewYear === maxYear && viewMonth === maxMon;
299
+
242
300
  const goPrev = () => {
301
+ if (prevAtMin) return;
243
302
  const p = addMonths(viewYear, viewMonth, -1);
244
303
  setViewYear(p.year);
245
304
  setViewMonth(p.month);
246
305
  };
247
306
 
248
307
  const goNext = () => {
308
+ if (nextAtMax) return;
249
309
  const n = addMonths(viewYear, viewMonth, 1);
250
310
  setViewYear(n.year);
251
311
  setViewMonth(n.month);
@@ -263,19 +323,19 @@ export function Calendar({
263
323
 
264
324
  return (
265
325
  <div
266
- className={["a1-calendar", "a1-calendar--paginated", className].filter(Boolean).join(" ")}
326
+ className={["a1-calendar", "a1-calendar--paginated", selectable && "a1-calendar--selectable", className].filter(Boolean).join(" ")}
267
327
  {...props}
268
328
  >
269
329
  <div className="a1-calendar__inner">
270
330
  <div className="a1-calendar__nav">
271
331
 
272
332
  <span className="a1-calendar__nav-wide">
273
- <Button variant="tertiary" size="sm" icon={isRtl ? "chevron_right" : "chevron_left"} iconPosition="start" onClick={goPrev}>
333
+ <Button variant="tertiary" size="sm" icon={isRtl ? "chevron_right" : "chevron_left"} iconPosition="start" onClick={goPrev} disabled={prevAtMin}>
274
334
  {prevMonthLabel}
275
335
  </Button>
276
336
  </span>
277
337
  <span className="a1-calendar__nav-narrow">
278
- <IconButton icon={isRtl ? "chevron_right" : "chevron_left"} label={prevMonthLabel} variant="tertiary" onClick={goPrev} />
338
+ <IconButton icon={isRtl ? "chevron_right" : "chevron_left"} label={prevMonthLabel} variant="tertiary" onClick={goPrev} disabled={prevAtMin} />
279
339
  </span>
280
340
 
281
341
  <div className="a1-calendar__nav-label">
@@ -286,9 +346,12 @@ export function Calendar({
286
346
  value={viewMonth}
287
347
  onChange={e => setViewMonth(Number(e.target.value))}
288
348
  >
289
- {MONTHS.map((name, i) => (
290
- <option key={i} value={i}>{name}</option>
291
- ))}
349
+ {MONTHS.map((name, i) => {
350
+ const disabled =
351
+ (viewYear === minYear && i < minMon) ||
352
+ (viewYear === maxYear && i > maxMon);
353
+ return <option key={i} value={i} disabled={disabled}>{name}</option>;
354
+ })}
292
355
  </SelectField>
293
356
  <SelectField
294
357
  className="a1-calendar__nav-field"
@@ -327,12 +390,12 @@ export function Calendar({
327
390
  </div>
328
391
 
329
392
  <span className="a1-calendar__nav-wide">
330
- <Button variant="tertiary" size="sm" icon={isRtl ? "chevron_left" : "chevron_right"} iconPosition="end" onClick={goNext}>
393
+ <Button variant="tertiary" size="sm" icon={isRtl ? "chevron_left" : "chevron_right"} iconPosition="end" onClick={goNext} disabled={nextAtMax}>
331
394
  {nextMonthLabel}
332
395
  </Button>
333
396
  </span>
334
397
  <span className="a1-calendar__nav-narrow">
335
- <IconButton icon={isRtl ? "chevron_left" : "chevron_right"} label={nextMonthLabel} variant="tertiary" onClick={goNext} />
398
+ <IconButton icon={isRtl ? "chevron_left" : "chevron_right"} label={nextMonthLabel} variant="tertiary" onClick={goNext} disabled={nextAtMax} />
336
399
  </span>
337
400
 
338
401
  </div>
@@ -351,7 +414,7 @@ export function Calendar({
351
414
 
352
415
  return (
353
416
  <div
354
- className={["a1-calendar", className].filter(Boolean).join(" ")}
417
+ className={["a1-calendar", selectable && "a1-calendar--selectable", className].filter(Boolean).join(" ")}
355
418
  {...props}
356
419
  >
357
420
  <div className="a1-calendar__inner">
@@ -110,6 +110,50 @@
110
110
  background: var(--semantic-color-surface-raised);
111
111
  }
112
112
 
113
+ /* ── Selected — full-cell fill (display and selectable modes) ─── */
114
+
115
+ .a1-calendar__day--selected {
116
+ background: var(--semantic-color-action-background);
117
+ color: var(--semantic-color-text-inverse);
118
+ }
119
+
120
+ /* ── Disabled (out of range) — same surface as past dates ──────── */
121
+
122
+ .a1-calendar__day--disabled {
123
+ background: var(--semantic-color-surface-raised);
124
+ }
125
+
126
+ /* ── Selectable mode (opt-in via selectable prop) ──────────────── */
127
+
128
+ .a1-calendar--selectable .a1-calendar__day:not(.a1-calendar__day--empty):not(.a1-calendar__day--disabled) {
129
+ cursor: pointer;
130
+ }
131
+ .a1-calendar--selectable .a1-calendar__day--disabled {
132
+ cursor: not-allowed;
133
+ }
134
+
135
+ /* Today — neutral ring instead of action fill (yields to selected) */
136
+ .a1-calendar--selectable .a1-calendar__day--today:not(.a1-calendar__day--selected) {
137
+ background: transparent;
138
+ color: var(--semantic-color-text-default);
139
+ }
140
+ .a1-calendar--selectable .a1-calendar__day--today:not(.a1-calendar__day--selected) .a1-calendar__day-number {
141
+ outline: 2px solid var(--semantic-color-text-default);
142
+ outline-offset: -1px;
143
+ }
144
+
145
+ /* Full-cell hover for non-selected, non-disabled days */
146
+ .a1-calendar--selectable .a1-calendar__day:not(.a1-calendar__day--empty):not(.a1-calendar__day--disabled):not(.a1-calendar__day--selected):hover {
147
+ background: var(--semantic-color-surface-panel);
148
+ color: var(--semantic-color-text-default);
149
+ }
150
+
151
+ /* Focus ring */
152
+ .a1-calendar--selectable .a1-calendar__day:focus-visible {
153
+ outline: var(--component-field-focus-ring-width) solid var(--component-field-focus-ring-color);
154
+ outline-offset: -2px;
155
+ }
156
+
113
157
  /* ── Paginated variant — nav bar ─────────────────────────── */
114
158
 
115
159
  .a1-calendar__nav {
@@ -178,6 +222,33 @@
178
222
  color: var(--semantic-color-text-inverse);
179
223
  }
180
224
 
225
+ /* Selected: revert to circle in narrow view */
226
+ .a1-calendar__day--selected {
227
+ background: transparent;
228
+ color: var(--semantic-color-text-default);
229
+ }
230
+ .a1-calendar__day--selected .a1-calendar__day-number {
231
+ background: var(--semantic-color-action-background);
232
+ color: var(--semantic-color-text-inverse);
233
+ }
234
+
235
+ /* Selectable: today ring (suppress action-bg circle from non-selectable narrow rule) */
236
+ .a1-calendar--selectable .a1-calendar__day--today:not(.a1-calendar__day--selected) .a1-calendar__day-number {
237
+ background: transparent;
238
+ color: var(--semantic-color-text-default);
239
+ outline: 2px solid var(--semantic-color-text-default);
240
+ outline-offset: -1px;
241
+ }
242
+
243
+ /* Selectable: hover as circle in narrow */
244
+ .a1-calendar--selectable .a1-calendar__day:not(.a1-calendar__day--empty):not(.a1-calendar__day--disabled):not(.a1-calendar__day--selected):hover {
245
+ background: transparent;
246
+ color: var(--semantic-color-text-default);
247
+ }
248
+ .a1-calendar--selectable .a1-calendar__day:not(.a1-calendar__day--empty):not(.a1-calendar__day--disabled):not(.a1-calendar__day--selected):hover .a1-calendar__day-number {
249
+ background: var(--semantic-color-surface-panel);
250
+ }
251
+
181
252
  .a1-calendar__nav {
182
253
  padding-block: var(--component-calendar-heading-padding-block-compact);
183
254
  }
@@ -0,0 +1,31 @@
1
+ import * as React from "react";
2
+
3
+ export interface CardProps extends React.HTMLAttributes<HTMLElement> {
4
+ /** Underlying element. Default: "div" */
5
+ as?: React.ElementType;
6
+ /** Visual and semantic card variant. Navigation cards make the entire card interactive. Default: "default" */
7
+ variant?: "default" | "navigation";
8
+ /** Destination for navigation cards. When `variant="navigation"` is set, the card renders as an anchor by default. */
9
+ href?: string;
10
+ /** Remove the card border and background. Default: false */
11
+ bare?: boolean;
12
+ /** Material Symbols icon name. Used by `iconDisplay` to render the icon. */
13
+ icon?: string;
14
+ /**
15
+ * Controls how the icon is displayed.
16
+ * - `"default"` — small tokenised icon block above card content; scales with the card container (sm/md/lg).
17
+ * - `"hero"` — full-bleed coloured header area at the top of the card.
18
+ * - `"none"` — icon is not rendered.
19
+ * Default: `"default"` (when `icon` is provided).
20
+ */
21
+ iconDisplay?: "none" | "default" | "hero";
22
+ /**
23
+ * Background colour of the hero block when `iconDisplay="hero"`.
24
+ * Accepts a semantic colour role or any valid CSS colour value.
25
+ * Default: "action"
26
+ */
27
+ heroColor?: "action" | "neutral" | "info" | "success" | "warn" | "error" | (string & {});
28
+ children?: React.ReactNode;
29
+ }
30
+
31
+ export declare function Card(props: CardProps): React.ReactElement;
@@ -0,0 +1,37 @@
1
+ import * as React from "react";
2
+
3
+ export interface CheckboxOption {
4
+ value: string;
5
+ label: string;
6
+ hint?: string;
7
+ disabled?: boolean;
8
+ }
9
+
10
+ export interface CheckboxGroupProps {
11
+ /** Group legend */
12
+ label?: string;
13
+ /** Helper text */
14
+ hint?: string;
15
+ /** Error message */
16
+ error?: string;
17
+ /** Size density. Inherits from parent `Fieldset` when omitted. Default: "default" */
18
+ size?: "comfortable" | "default" | "compact";
19
+ required?: boolean;
20
+ disabled?: boolean;
21
+ /** Render checkboxes side by side. Default: false */
22
+ inline?: boolean;
23
+ /** Input name attribute shared by all checkboxes */
24
+ name?: string;
25
+ /** Array of checkbox options */
26
+ options?: CheckboxOption[];
27
+ /** Controlled selected values */
28
+ value?: string[];
29
+ /** Default selected values (uncontrolled) */
30
+ defaultValue?: string[];
31
+ /** Called with the full updated array of selected values on change */
32
+ onChange?: (value: string[]) => void;
33
+ id?: string;
34
+ className?: string;
35
+ }
36
+
37
+ export declare function CheckboxGroup(props: CheckboxGroupProps): React.ReactElement;
@@ -0,0 +1,68 @@
1
+ import * as React from "react";
2
+
3
+ export interface ChoiceGroupSection {
4
+ /** Section heading displayed above the section's tiles */
5
+ label: string;
6
+ /** Options in this section */
7
+ options: ChoiceOption[];
8
+ }
9
+
10
+ export interface ChoiceOption {
11
+ value: string;
12
+ label: string;
13
+ subtext?: string;
14
+ icon?: string;
15
+ disabled?: boolean;
16
+ }
17
+
18
+ export interface ChoiceGroupProps {
19
+ /** Group legend */
20
+ label?: string;
21
+ /** Helper text — hidden when error or success is present */
22
+ hint?: string;
23
+ /** Error message */
24
+ error?: string;
25
+ /** Success message — shown instead of hint when present, hidden if error is also present */
26
+ success?: string;
27
+ /** Tile size density — affects only padding and child element sizes. Default: "default" */
28
+ size?: "compact" | "default" | "comfortable";
29
+ /**
30
+ * Column count. Pass a number for a fixed count at all breakpoints, or a
31
+ * breakpoint object for responsive behaviour, e.g. `{ xs: 1, sm: 2, md: 3 }`.
32
+ * Omit (default) for automatic fill based on tile min-width.
33
+ */
34
+ columns?: number | Partial<Record<"xs" | "sm" | "md" | "lg" | "xl", number>>;
35
+ /**
36
+ * Allow multiple selections (checkbox semantics). When false, only one
37
+ * option may be selected at a time (radio semantics). Default: false
38
+ */
39
+ multiple?: boolean;
40
+ /**
41
+ * Place each tile's icon to the left of the label and subtext instead of
42
+ * above the content block. Has no effect on tiles with no icon. Default: false
43
+ */
44
+ inlineIcon?: boolean;
45
+ required?: boolean;
46
+ /** Input name attribute. Defaults to the group id. */
47
+ name?: string;
48
+ /** Flat list of options. Use sections instead for grouped options with headings. */
49
+ options?: ChoiceOption[];
50
+ /**
51
+ * Options divided into labeled sections with a divider between each group.
52
+ * When provided, options is ignored.
53
+ */
54
+ sections?: ChoiceGroupSection[];
55
+ /**
56
+ * Controlled value. String for single-select; string[] for multi-select.
57
+ * Pass undefined to use uncontrolled mode.
58
+ */
59
+ value?: string | string[] | null;
60
+ /** Default value for uncontrolled mode. Default: null / [] */
61
+ defaultValue?: string | string[] | null;
62
+ /** Called with the selected value (string or string[]) on change */
63
+ onChange?: (value: string | string[]) => void;
64
+ id?: string;
65
+ className?: string;
66
+ }
67
+
68
+ export declare function ChoiceGroup(props: ChoiceGroupProps): React.ReactElement;
@@ -0,0 +1,37 @@
1
+ import * as React from "react";
2
+
3
+ export interface CircularProgressProps {
4
+ /**
5
+ * Current value. Combined with max to compute the filled arc length.
6
+ * Ignored when indeterminate is true. Default: 0
7
+ */
8
+ value?: number;
9
+ /**
10
+ * Maximum value. Default: 100
11
+ */
12
+ max?: number;
13
+ /**
14
+ * Circle diameter. xs renders the smallest ring (no inner content — children
15
+ * are placed inline after the ring instead). Default: "md"
16
+ */
17
+ size?: "xs" | "sm" | "md" | "lg";
18
+ /**
19
+ * Shows a continuously rotating arc instead of a value-based fill.
20
+ * Removes aria-valuenow so assistive technology announces an indeterminate
21
+ * state. Default: false
22
+ */
23
+ indeterminate?: boolean;
24
+ /**
25
+ * Content centered inside the ring for sm / md / lg sizes.
26
+ * For xs, children are rendered inline after the ring.
27
+ * Always pass aria-label on the root element for an accessible name since
28
+ * this content receives aria-hidden="true".
29
+ */
30
+ children?: React.ReactNode;
31
+ /** Additional CSS class names applied to the root element. */
32
+ className?: string;
33
+ }
34
+
35
+ export declare function CircularProgress(
36
+ props: CircularProgressProps & React.HTMLAttributes<HTMLDivElement>
37
+ ): React.ReactElement;