@usefidel/design-system 0.23.0 → 0.24.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.
@@ -10,6 +10,6 @@
10
10
  "webapp.css"
11
11
  ],
12
12
  "storybookUrl": null,
13
- "packageVersion": "0.23.0",
14
- "resolvedSha": "dacb06b3b72bd7e4223af4b13e45c7e18b1feeb8"
13
+ "packageVersion": "0.24.0",
14
+ "resolvedSha": "1e705f59f0a7aaf0d1144151efee5e7d9f56aa2a"
15
15
  }
package/dist/index.cjs CHANGED
@@ -49,6 +49,7 @@ __export(index_exports, {
49
49
  SettingsSection: () => SettingsSection,
50
50
  Skeleton: () => Skeleton,
51
51
  SkeletonGroup: () => SkeletonGroup,
52
+ Spinner: () => Spinner,
52
53
  Split: () => Split,
53
54
  StackedCardsIllustration: () => StackedCardsIllustration,
54
55
  Stat: () => Stat,
@@ -1387,39 +1388,63 @@ function SkeletonGroup({ label = "Loading", className, children, ...rest }) {
1387
1388
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { role: "status", "aria-busy": "true", "aria-label": label, className, ...rest, children });
1388
1389
  }
1389
1390
 
1390
- // src/components/Card/Card.tsx
1391
+ // src/components/Spinner/Spinner.tsx
1391
1392
  var import_jsx_runtime23 = require("react/jsx-runtime");
1393
+ function Spinner({ size = 24, label, className, ...rest }) {
1394
+ const a11y = label ? { role: "img", "aria-label": label } : { "aria-hidden": true };
1395
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1396
+ "svg",
1397
+ {
1398
+ className: ["fds-spinner", className].filter(Boolean).join(" "),
1399
+ width: size,
1400
+ height: size,
1401
+ viewBox: "0 0 24 24",
1402
+ fill: "none",
1403
+ strokeWidth: "2.5",
1404
+ strokeLinecap: "round",
1405
+ ...a11y,
1406
+ ...rest,
1407
+ children: [
1408
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("circle", { className: "fds-spinner__track", cx: "12", cy: "12", r: "10" }),
1409
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("path", { className: "fds-spinner__arc", d: "M12 2a10 10 0 0 1 10 10" })
1410
+ ]
1411
+ }
1412
+ );
1413
+ }
1414
+
1415
+ // src/components/Card/Card.tsx
1416
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1392
1417
  function Card({ tone = "default", padding = "md", className, children, ...rest }) {
1393
1418
  const classes = ["fds-card", `fds-card--${tone}`, `fds-card--pad-${padding}`, className].filter(Boolean).join(" ");
1394
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: classes, ...rest, children });
1419
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: classes, ...rest, children });
1395
1420
  }
1396
1421
 
1397
1422
  // src/components/Stat/Stat.tsx
1398
- var import_jsx_runtime24 = require("react/jsx-runtime");
1423
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1399
1424
  function Stat({ label, value, children, className, ...rest }) {
1400
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: ["fds-stat", className].filter(Boolean).join(" "), ...rest, children: [
1401
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "fds-stat__label", children: label }),
1402
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "fds-stat__value", children: value }),
1403
- children != null && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "fds-stat__detail", children })
1425
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: ["fds-stat", className].filter(Boolean).join(" "), ...rest, children: [
1426
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "fds-stat__label", children: label }),
1427
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "fds-stat__value", children: value }),
1428
+ children != null && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fds-stat__detail", children })
1404
1429
  ] });
1405
1430
  }
1406
1431
 
1407
1432
  // src/components/Swatch/Swatch.tsx
1408
- var import_jsx_runtime25 = require("react/jsx-runtime");
1433
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1409
1434
  function Swatch({ color, name, value, children, className, ...rest }) {
1410
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: ["fds-swatch", className].filter(Boolean).join(" "), ...rest, children: [
1411
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fds-swatch__color", style: { "--fds-swatch-color": color }, "aria-hidden": "true" }),
1412
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "fds-swatch__body", children: [
1413
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "fds-swatch__name", children: name }),
1414
- value != null && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "fds-swatch__value", children: value }),
1415
- children != null && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fds-swatch__detail", children })
1435
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: ["fds-swatch", className].filter(Boolean).join(" "), ...rest, children: [
1436
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fds-swatch__color", style: { "--fds-swatch-color": color }, "aria-hidden": "true" }),
1437
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "fds-swatch__body", children: [
1438
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "fds-swatch__name", children: name }),
1439
+ value != null && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "fds-swatch__value", children: value }),
1440
+ children != null && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fds-swatch__detail", children })
1416
1441
  ] })
1417
1442
  ] });
1418
1443
  }
1419
1444
 
1420
1445
  // src/components/Checkbox/Checkbox.tsx
1421
1446
  var import_react12 = require("react");
1422
- var import_jsx_runtime26 = require("react/jsx-runtime");
1447
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1423
1448
  var Checkbox = (0, import_react12.forwardRef)(function Checkbox2({ label, description, indeterminate = false, className, id, disabled, ...rest }, ref) {
1424
1449
  const generatedId = (0, import_react12.useId)();
1425
1450
  const inputId = id ?? generatedId;
@@ -1428,13 +1453,13 @@ var Checkbox = (0, import_react12.forwardRef)(function Checkbox2({ label, descri
1428
1453
  (0, import_react12.useEffect)(() => {
1429
1454
  if (inputRef.current) inputRef.current.indeterminate = indeterminate;
1430
1455
  }, [indeterminate]);
1431
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1456
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
1432
1457
  "div",
1433
1458
  {
1434
1459
  className: ["fds-checkbox", className].filter(Boolean).join(" "),
1435
1460
  "data-disabled": disabled ? "" : void 0,
1436
1461
  children: [
1437
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1462
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1438
1463
  "input",
1439
1464
  {
1440
1465
  ...rest,
@@ -1445,14 +1470,14 @@ var Checkbox = (0, import_react12.forwardRef)(function Checkbox2({ label, descri
1445
1470
  className: "fds-checkbox__input"
1446
1471
  }
1447
1472
  ),
1448
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { htmlFor: inputId, className: "fds-checkbox__control", children: [
1449
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "fds-checkbox__box", "aria-hidden": "true", children: [
1450
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("svg", { className: "fds-checkbox__tick", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("path", { d: "M10 3L4.5 8.5 2 6", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
1451
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("svg", { className: "fds-checkbox__dash", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("path", { d: "M3 6h6", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }) })
1473
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { htmlFor: inputId, className: "fds-checkbox__control", children: [
1474
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "fds-checkbox__box", "aria-hidden": "true", children: [
1475
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("svg", { className: "fds-checkbox__tick", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M10 3L4.5 8.5 2 6", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
1476
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("svg", { className: "fds-checkbox__dash", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M3 6h6", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }) })
1452
1477
  ] }),
1453
- (label != null || description != null) && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "fds-checkbox__text", children: [
1454
- label != null && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fds-checkbox__label", children: label }),
1455
- description != null && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fds-checkbox__description", children: description })
1478
+ (label != null || description != null) && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "fds-checkbox__text", children: [
1479
+ label != null && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fds-checkbox__label", children: label }),
1480
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fds-checkbox__description", children: description })
1456
1481
  ] })
1457
1482
  ] })
1458
1483
  ]
@@ -1462,17 +1487,17 @@ var Checkbox = (0, import_react12.forwardRef)(function Checkbox2({ label, descri
1462
1487
 
1463
1488
  // src/components/Radio/Radio.tsx
1464
1489
  var import_react13 = require("react");
1465
- var import_jsx_runtime27 = require("react/jsx-runtime");
1490
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1466
1491
  var Radio = (0, import_react13.forwardRef)(function Radio2({ label, description, className, id, disabled, ...rest }, ref) {
1467
1492
  const generatedId = (0, import_react13.useId)();
1468
1493
  const inputId = id ?? generatedId;
1469
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: ["fds-radio", className].filter(Boolean).join(" "), "data-disabled": disabled ? "" : void 0, children: [
1470
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { ...rest, id: inputId, ref, type: "radio", disabled, className: "fds-radio__input" }),
1471
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { htmlFor: inputId, className: "fds-radio__control", children: [
1472
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fds-radio__circle", "aria-hidden": "true" }),
1473
- (label != null || description != null) && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "fds-radio__text", children: [
1474
- label != null && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fds-radio__label", children: label }),
1475
- description != null && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fds-radio__description", children: description })
1494
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: ["fds-radio", className].filter(Boolean).join(" "), "data-disabled": disabled ? "" : void 0, children: [
1495
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { ...rest, id: inputId, ref, type: "radio", disabled, className: "fds-radio__input" }),
1496
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { htmlFor: inputId, className: "fds-radio__control", children: [
1497
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fds-radio__circle", "aria-hidden": "true" }),
1498
+ (label != null || description != null) && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "fds-radio__text", children: [
1499
+ label != null && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fds-radio__label", children: label }),
1500
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fds-radio__description", children: description })
1476
1501
  ] })
1477
1502
  ] })
1478
1503
  ] });
@@ -1480,13 +1505,13 @@ var Radio = (0, import_react13.forwardRef)(function Radio2({ label, description,
1480
1505
 
1481
1506
  // src/components/RadioCard/RadioCard.tsx
1482
1507
  var import_react14 = require("react");
1483
- var import_jsx_runtime28 = require("react/jsx-runtime");
1508
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1484
1509
  var RadioCard = (0, import_react14.forwardRef)(function RadioCard2({ label, description, icon, meta, className, id, disabled, ...rest }, ref) {
1485
1510
  const generatedId = (0, import_react14.useId)();
1486
1511
  const inputId = id ?? generatedId;
1487
1512
  const descriptionId = description != null ? `${inputId}-description` : void 0;
1488
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: ["fds-radio-card", className].filter(Boolean).join(" "), "data-disabled": disabled ? "" : void 0, children: [
1489
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1513
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: ["fds-radio-card", className].filter(Boolean).join(" "), "data-disabled": disabled ? "" : void 0, children: [
1514
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1490
1515
  "input",
1491
1516
  {
1492
1517
  ...rest,
@@ -1498,21 +1523,21 @@ var RadioCard = (0, import_react14.forwardRef)(function RadioCard2({ label, desc
1498
1523
  className: "fds-radio-card__input"
1499
1524
  }
1500
1525
  ),
1501
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { htmlFor: inputId, className: "fds-radio-card__body", children: [
1502
- icon != null && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fds-radio-card__icon", "aria-hidden": "true", children: icon }),
1503
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "fds-radio-card__text", children: [
1504
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fds-radio-card__label", children: label }),
1505
- description != null && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { id: descriptionId, className: "fds-radio-card__description", children: description }),
1506
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fds-radio-card__meta", children: meta })
1526
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { htmlFor: inputId, className: "fds-radio-card__body", children: [
1527
+ icon != null && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fds-radio-card__icon", "aria-hidden": "true", children: icon }),
1528
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "fds-radio-card__text", children: [
1529
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fds-radio-card__label", children: label }),
1530
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { id: descriptionId, className: "fds-radio-card__description", children: description }),
1531
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fds-radio-card__meta", children: meta })
1507
1532
  ] }),
1508
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fds-radio-card__circle", "aria-hidden": "true" })
1533
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fds-radio-card__circle", "aria-hidden": "true" })
1509
1534
  ] })
1510
1535
  ] });
1511
1536
  });
1512
1537
 
1513
1538
  // src/components/Accordion/Accordion.tsx
1514
1539
  var import_react15 = require("react");
1515
- var import_jsx_runtime29 = require("react/jsx-runtime");
1540
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1516
1541
  function Accordion({
1517
1542
  summary,
1518
1543
  actions,
@@ -1531,15 +1556,15 @@ function Accordion({
1531
1556
  if (openProp === void 0) setOpenState(next);
1532
1557
  onOpenChange?.(next);
1533
1558
  };
1534
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
1559
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
1535
1560
  "div",
1536
1561
  {
1537
1562
  className: ["fds-accordion", className].filter(Boolean).join(" "),
1538
1563
  "data-open": open ? "" : void 0,
1539
1564
  ...rest,
1540
1565
  children: [
1541
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "fds-accordion__header", children: [
1542
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1566
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "fds-accordion__header", children: [
1567
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1543
1568
  "button",
1544
1569
  {
1545
1570
  type: "button",
@@ -1550,17 +1575,17 @@ function Accordion({
1550
1575
  children: summary
1551
1576
  }
1552
1577
  ),
1553
- actions != null && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "fds-accordion__actions", children: actions }),
1554
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fds-accordion__chevron", "aria-hidden": "true", onClick: toggle, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
1578
+ actions != null && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "fds-accordion__actions", children: actions }),
1579
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fds-accordion__chevron", "aria-hidden": "true", onClick: toggle, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
1555
1580
  ] }),
1556
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { id: bodyId, className: "fds-accordion__body", hidden: !open, children })
1581
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { id: bodyId, className: "fds-accordion__body", hidden: !open, children })
1557
1582
  ]
1558
1583
  }
1559
1584
  );
1560
1585
  }
1561
1586
 
1562
1587
  // src/components/StepList/StepList.tsx
1563
- var import_jsx_runtime30 = require("react/jsx-runtime");
1588
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1564
1589
  var STATUS_TEXT = {
1565
1590
  done: "Done",
1566
1591
  active: "In progress",
@@ -1570,32 +1595,32 @@ var STATUS_TEXT = {
1570
1595
  function StepIcon({ status }) {
1571
1596
  const common = { viewBox: "0 0 24 24", width: 18, height: 18, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" };
1572
1597
  if (status === "done") {
1573
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { ...common, children: [
1574
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
1575
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M8 12.5l2.5 2.5 5-5.5" })
1598
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("svg", { ...common, children: [
1599
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
1600
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { d: "M8 12.5l2.5 2.5 5-5.5" })
1576
1601
  ] });
1577
1602
  }
1578
1603
  if (status === "active") {
1579
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { ...common, className: "fds-steps__spinner", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1" }) });
1604
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("svg", { ...common, className: "fds-steps__spinner", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { d: "M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1" }) });
1580
1605
  }
1581
1606
  if (status === "failed") {
1582
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { ...common, children: [
1583
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
1584
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M12 7.5v5.5M12 16.5v.01" })
1607
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("svg", { ...common, children: [
1608
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("circle", { cx: "12", cy: "12", r: "9" }),
1609
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { d: "M12 7.5v5.5M12 16.5v.01" })
1585
1610
  ] });
1586
1611
  }
1587
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { ...common, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "12", cy: "12", r: "9" }) });
1612
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("svg", { ...common, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("circle", { cx: "12", cy: "12", r: "9" }) });
1588
1613
  }
1589
1614
  function StepList({ steps, className, ...rest }) {
1590
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ol", { className: ["fds-steps", className].filter(Boolean).join(" "), ...rest, children: steps.map((step) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
1615
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("ol", { className: ["fds-steps", className].filter(Boolean).join(" "), ...rest, children: steps.map((step) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1591
1616
  "li",
1592
1617
  {
1593
1618
  className: `fds-steps__step fds-steps__step--${step.status}`,
1594
1619
  "aria-current": step.status === "active" ? "step" : void 0,
1595
1620
  children: [
1596
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fds-steps__icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(StepIcon, { status: step.status }) }),
1597
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fds-steps__label", children: step.label }),
1598
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "fds-steps__sr", children: [
1621
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "fds-steps__icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(StepIcon, { status: step.status }) }),
1622
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "fds-steps__label", children: step.label }),
1623
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "fds-steps__sr", children: [
1599
1624
  ", ",
1600
1625
  STATUS_TEXT[step.status]
1601
1626
  ] })
@@ -1607,7 +1632,7 @@ function StepList({ steps, className, ...rest }) {
1607
1632
 
1608
1633
  // src/components/Input/Input.tsx
1609
1634
  var import_react16 = require("react");
1610
- var import_jsx_runtime31 = require("react/jsx-runtime");
1635
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1611
1636
  var Input = (0, import_react16.forwardRef)(function Input2({ label, hint, error, leadingIcon, trailing, id, className, containerClassName, readOnly, disabled, ...rest }, ref) {
1612
1637
  const genId = (0, import_react16.useId)();
1613
1638
  const inputId = id ?? genId;
@@ -1618,11 +1643,11 @@ var Input = (0, import_react16.forwardRef)(function Input2({ label, hint, error,
1618
1643
  error ? "fds-input__box--error" : "",
1619
1644
  readOnly || disabled ? "fds-input__box--locked" : ""
1620
1645
  ].filter(Boolean).join(" ");
1621
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: ["fds-input", containerClassName].filter(Boolean).join(" "), children: [
1622
- label != null && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("label", { htmlFor: inputId, className: "fds-input__label", children: label }),
1623
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: boxClasses, children: [
1624
- leadingIcon != null && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "fds-input__icon", "aria-hidden": "true", children: leadingIcon }),
1625
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1646
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: ["fds-input", containerClassName].filter(Boolean).join(" "), children: [
1647
+ label != null && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("label", { htmlFor: inputId, className: "fds-input__label", children: label }),
1648
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: boxClasses, children: [
1649
+ leadingIcon != null && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "fds-input__icon", "aria-hidden": "true", children: leadingIcon }),
1650
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1626
1651
  "input",
1627
1652
  {
1628
1653
  ref,
@@ -1635,14 +1660,14 @@ var Input = (0, import_react16.forwardRef)(function Input2({ label, hint, error,
1635
1660
  ...rest
1636
1661
  }
1637
1662
  ),
1638
- trailing != null && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "fds-input__trailing", children: trailing })
1663
+ trailing != null && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "fds-input__trailing", children: trailing })
1639
1664
  ] }),
1640
- message != null && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { id: msgId, className: error ? "fds-input__error" : "fds-input__hint", children: message })
1665
+ message != null && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { id: msgId, className: error ? "fds-input__error" : "fds-input__hint", children: message })
1641
1666
  ] });
1642
1667
  });
1643
1668
 
1644
1669
  // src/components/IconButton/IconButton.tsx
1645
- var import_jsx_runtime32 = require("react/jsx-runtime");
1670
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1646
1671
  function IconButton({
1647
1672
  icon,
1648
1673
  variant = "outlined",
@@ -1652,12 +1677,12 @@ function IconButton({
1652
1677
  ...rest
1653
1678
  }) {
1654
1679
  const classes = ["fds-icon-button", `fds-icon-button--${variant}`, `fds-icon-button--${size}`, className].filter(Boolean).join(" ");
1655
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type, className: classes, ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "fds-icon-button__icon", "aria-hidden": "true", children: icon }) });
1680
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type, className: classes, ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "fds-icon-button__icon", "aria-hidden": "true", children: icon }) });
1656
1681
  }
1657
1682
 
1658
1683
  // src/components/Menu/Menu.tsx
1659
1684
  var import_react17 = require("react");
1660
- var import_jsx_runtime33 = require("react/jsx-runtime");
1685
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1661
1686
  function Menu({ trigger, items, align = "end", className }) {
1662
1687
  const listId = (0, import_react17.useId)();
1663
1688
  const rootRef = (0, import_react17.useRef)(null);
@@ -1739,9 +1764,9 @@ function Menu({ trigger, items, align = "end", className }) {
1739
1764
  }
1740
1765
  }
1741
1766
  });
1742
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { ref: rootRef, className: ["fds-menu", className].filter(Boolean).join(" "), children: [
1767
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { ref: rootRef, className: ["fds-menu", className].filter(Boolean).join(" "), children: [
1743
1768
  wired,
1744
- open && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1769
+ open && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1745
1770
  "div",
1746
1771
  {
1747
1772
  ref: listRef,
@@ -1751,7 +1776,7 @@ function Menu({ trigger, items, align = "end", className }) {
1751
1776
  className: `fds-menu__list fds-menu__list--${align}`,
1752
1777
  "aria-activedescendant": `${listId}-item-${active}`,
1753
1778
  onKeyDown: onListKeyDown,
1754
- children: items.map((it, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
1779
+ children: items.map((it, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
1755
1780
  "div",
1756
1781
  {
1757
1782
  id: `${listId}-item-${i}`,
@@ -1767,7 +1792,7 @@ function Menu({ trigger, items, align = "end", className }) {
1767
1792
  onMouseDown: (e) => e.preventDefault(),
1768
1793
  onClick: () => choose(i),
1769
1794
  children: [
1770
- it.icon != null && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "fds-menu__icon", "aria-hidden": "true", children: it.icon }),
1795
+ it.icon != null && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fds-menu__icon", "aria-hidden": "true", children: it.icon }),
1771
1796
  it.label
1772
1797
  ]
1773
1798
  },
@@ -1779,10 +1804,10 @@ function Menu({ trigger, items, align = "end", className }) {
1779
1804
  }
1780
1805
 
1781
1806
  // src/components/Table/Table.tsx
1782
- var import_jsx_runtime34 = require("react/jsx-runtime");
1807
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1783
1808
  function Table({ columns, rows, rowKey, empty, className, "aria-label": ariaLabel, ...rest }) {
1784
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: ["fds-table", className].filter(Boolean).join(" "), ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("table", { className: "fds-table__table", "aria-label": ariaLabel, children: [
1785
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("tr", { children: columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1809
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: ["fds-table", className].filter(Boolean).join(" "), ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("table", { className: "fds-table__table", "aria-label": ariaLabel, children: [
1810
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("tr", { children: columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1786
1811
  "th",
1787
1812
  {
1788
1813
  scope: "col",
@@ -1792,17 +1817,17 @@ function Table({ columns, rows, rowKey, empty, className, "aria-label": ariaLabe
1792
1817
  },
1793
1818
  c.key
1794
1819
  )) }) }),
1795
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("tbody", { children: [
1796
- rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("tr", { children: columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("td", { className: c.align === "end" ? "fds-table__cell--end" : void 0, children: c.cell(row) }, c.key)) }, rowKey(row))),
1797
- rows.length === 0 && empty != null && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("td", { colSpan: columns.length, className: "fds-table__empty", children: empty }) })
1820
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("tbody", { children: [
1821
+ rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("tr", { children: columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { className: c.align === "end" ? "fds-table__cell--end" : void 0, children: c.cell(row) }, c.key)) }, rowKey(row))),
1822
+ rows.length === 0 && empty != null && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { colSpan: columns.length, className: "fds-table__empty", children: empty }) })
1798
1823
  ] })
1799
1824
  ] }) });
1800
1825
  }
1801
1826
 
1802
1827
  // src/components/PricingCard/PricingCard.tsx
1803
- var import_jsx_runtime35 = require("react/jsx-runtime");
1828
+ var import_jsx_runtime36 = require("react/jsx-runtime");
1804
1829
  function CheckIcon3() {
1805
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("svg", { viewBox: "0 0 16 16", width: "12", height: "12", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("path", { d: "M3.5 8.5l3 3 6-7", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) });
1830
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("svg", { viewBox: "0 0 16 16", width: "12", height: "12", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("path", { d: "M3.5 8.5l3 3 6-7", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) });
1806
1831
  }
1807
1832
  function PricingCard({
1808
1833
  eyebrow,
@@ -1820,25 +1845,25 @@ function PricingCard({
1820
1845
  ...rest
1821
1846
  }) {
1822
1847
  const classes = ["fds-pricing-card", highlighted ? "fds-pricing-card--highlighted" : "", className].filter(Boolean).join(" ");
1823
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("article", { className: classes, ...rest, children: [
1824
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "fds-pricing-card__top", children: [
1825
- eyebrow != null && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fds-pricing-card__eyebrow", children: eyebrow }),
1826
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("h3", { className: "fds-pricing-card__title", children: [
1848
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("article", { className: classes, ...rest, children: [
1849
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "fds-pricing-card__top", children: [
1850
+ eyebrow != null && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fds-pricing-card__eyebrow", children: eyebrow }),
1851
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("h3", { className: "fds-pricing-card__title", children: [
1827
1852
  title,
1828
1853
  badge
1829
1854
  ] }),
1830
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { className: "fds-pricing-card__price", children: [
1831
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fds-pricing-card__amount", children: price }),
1832
- period != null && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fds-pricing-card__period", children: period })
1855
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("p", { className: "fds-pricing-card__price", children: [
1856
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fds-pricing-card__amount", children: price }),
1857
+ period != null && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fds-pricing-card__period", children: period })
1833
1858
  ] }),
1834
- description != null && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "fds-pricing-card__description", children: description }),
1835
- action != null && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "fds-pricing-card__action", children: action })
1859
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "fds-pricing-card__description", children: description }),
1860
+ action != null && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "fds-pricing-card__action", children: action })
1836
1861
  ] }),
1837
- features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "fds-pricing-card__features", children: [
1838
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "fds-pricing-card__featuresTitle", children: featuresTitle }),
1839
- featuresIntro != null && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "fds-pricing-card__intro", children: featuresIntro }),
1840
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("ul", { className: "fds-pricing-card__list", children: features.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("li", { className: "fds-pricing-card__feature", children: [
1841
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fds-pricing-card__check", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(CheckIcon3, {}) }),
1862
+ features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "fds-pricing-card__features", children: [
1863
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "fds-pricing-card__featuresTitle", children: featuresTitle }),
1864
+ featuresIntro != null && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "fds-pricing-card__intro", children: featuresIntro }),
1865
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("ul", { className: "fds-pricing-card__list", children: features.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("li", { className: "fds-pricing-card__feature", children: [
1866
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fds-pricing-card__check", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CheckIcon3, {}) }),
1842
1867
  f
1843
1868
  ] }, i)) })
1844
1869
  ] })
@@ -1875,6 +1900,7 @@ function PricingCard({
1875
1900
  SettingsSection,
1876
1901
  Skeleton,
1877
1902
  SkeletonGroup,
1903
+ Spinner,
1878
1904
  Split,
1879
1905
  StackedCardsIllustration,
1880
1906
  Stat,
package/dist/index.css CHANGED
@@ -2215,11 +2215,32 @@
2215
2215
  }
2216
2216
  @media (max-width: 480px) {
2217
2217
  .fds-callout {
2218
- flex-wrap: wrap;
2218
+ display: grid;
2219
+ grid-template-columns: auto minmax(0, 1fr);
2220
+ gap: var(--spacing-2, 8px) var(--spacing-3, 12px);
2221
+ }
2222
+ .fds-callout:not(:has(> .fds-callout__icon)) {
2223
+ grid-template-columns: minmax(0, 1fr);
2224
+ }
2225
+ .fds-callout__icon {
2226
+ align-self: center;
2227
+ }
2228
+ .fds-callout__body {
2229
+ display: contents;
2219
2230
  }
2231
+ .fds-callout__text,
2220
2232
  .fds-callout__action {
2221
- flex-basis: 100%;
2222
- padding-left: var(--spacing-12, 48px);
2233
+ grid-column: 1 / -1;
2234
+ }
2235
+ .fds-callout__text {
2236
+ margin-top: 0;
2237
+ }
2238
+ .fds-callout__action {
2239
+ flex-wrap: wrap;
2240
+ }
2241
+ .fds-callout__action > * {
2242
+ flex: 1 1 auto;
2243
+ justify-content: center;
2223
2244
  }
2224
2245
  }
2225
2246
  .fds-callout--neutral {
@@ -2291,6 +2312,29 @@
2291
2312
  }
2292
2313
  }
2293
2314
 
2315
+ /* src/components/Spinner/spinner.css */
2316
+ .fds-spinner {
2317
+ display: block;
2318
+ flex-shrink: 0;
2319
+ animation: fds-spinner-turn 0.7s linear infinite;
2320
+ }
2321
+ .fds-spinner__track {
2322
+ stroke: var(--color-border, #e5e5e5);
2323
+ }
2324
+ .fds-spinner__arc {
2325
+ stroke: var(--color-accent, #6236d4);
2326
+ }
2327
+ @keyframes fds-spinner-turn {
2328
+ to {
2329
+ transform: rotate(360deg);
2330
+ }
2331
+ }
2332
+ @media (prefers-reduced-motion: reduce) {
2333
+ .fds-spinner {
2334
+ animation-duration: 2.8s;
2335
+ }
2336
+ }
2337
+
2294
2338
  /* src/components/Card/card.css */
2295
2339
  .fds-card {
2296
2340
  box-sizing: border-box;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ButtonHTMLAttributes, ReactNode, AnchorHTMLAttributes, HTMLAttributes, InputHTMLAttributes, ReactElement } from 'react';
2
+ import { ButtonHTMLAttributes, ReactNode, AnchorHTMLAttributes, HTMLAttributes, InputHTMLAttributes, SVGAttributes, ReactElement } from 'react';
3
3
 
4
4
  type ButtonVariant = 'primary' | 'outlined' | 'text' | 'neutral' | 'link'
5
5
  /** High-contrast near-black, for a page's main create action ("New comparison"). */
@@ -634,6 +634,18 @@ interface SkeletonGroupProps extends HTMLAttributes<HTMLDivElement> {
634
634
  /** Wraps a skeleton layout and announces it once as loading (role="status"). */
635
635
  declare function SkeletonGroup({ label, className, children, ...rest }: SkeletonGroupProps): react.JSX.Element;
636
636
 
637
+ interface SpinnerProps extends Omit<SVGAttributes<SVGSVGElement>, 'children'> {
638
+ /** Width and height in px. @default 24 */
639
+ size?: number;
640
+ /** What's loading, for screen readers. Leave it out when a parent (role="status") already announces it. */
641
+ label?: string;
642
+ }
643
+ /**
644
+ * Fidel design-system Spinner: an accent arc turning on a neutral track, for a
645
+ * wait with no shape to preview. Use Skeleton when the coming layout is known.
646
+ */
647
+ declare function Spinner({ size, label, className, ...rest }: SpinnerProps): react.JSX.Element;
648
+
637
649
  /** Surface colour. `subtle` is the grey panel, `default` white with a border, `plain` white without one. */
638
650
  type CardTone = 'subtle' | 'default' | 'plain';
639
651
  type CardPadding = 'none' | 'md' | 'lg';
@@ -895,4 +907,4 @@ interface PricingCardProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
895
907
  */
896
908
  declare function PricingCard({ eyebrow, title, badge, price, period, description, action, featuresTitle, featuresIntro, features, highlighted, className, ...rest }: PricingCardProps): react.JSX.Element;
897
909
 
898
- export { Accordion, type AccordionProps, AppNav, type AppNavProps, Avatar, type AvatarProps, type AvatarSize, Badge, type BadgeProps, type Breakpoint, Button, ButtonLink, type ButtonLinkProps, type ButtonProps, type ButtonSize, type ButtonVariant, Callout, type CalloutProps, type CalloutTone, Card, type CardPadding, type CardProps, type CardTone, Checkbox, type CheckboxProps, type DiffElement, type DiffPropertyLine, DiffPropertyList, type DiffPropertyListProps, DiffSection, type DiffSectionProps, EmptyState, type EmptyStateProps, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, Input, type InputProps, Menu, type MenuItem, type MenuProps, MismatchCard, type MismatchCardProps, type MismatchProperty, Modal, type ModalProps, type ModalSize, type ModalTone, MultiSelect, type MultiSelectOption, type MultiSelectProps, Pagination, type PaginationProps, PricingCard, type PricingCardProps, Radio, RadioCard, type RadioCardProps, type RadioProps, SearchInput, type SearchInputProps, SectionHeader, type SectionHeaderProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectOption, type SelectProps, SettingsSection, type SettingsSectionProps, Skeleton, SkeletonGroup, type SkeletonGroupProps, type SkeletonProps, type SkeletonShape, Split, type SplitProps, StackedCardsIllustration, Stat, type StatProps, type Step, StepList, type StepListProps, type StepStatus, Swatch, type SwatchProps, TabNav, type TabNavProps, Table, type TableColumn, type TableProps, Tag, type TagProps, Toggle, type ToggleProps, type ToggleSize, type Tone, breakpoints };
910
+ export { Accordion, type AccordionProps, AppNav, type AppNavProps, Avatar, type AvatarProps, type AvatarSize, Badge, type BadgeProps, type Breakpoint, Button, ButtonLink, type ButtonLinkProps, type ButtonProps, type ButtonSize, type ButtonVariant, Callout, type CalloutProps, type CalloutTone, Card, type CardPadding, type CardProps, type CardTone, Checkbox, type CheckboxProps, type DiffElement, type DiffPropertyLine, DiffPropertyList, type DiffPropertyListProps, DiffSection, type DiffSectionProps, EmptyState, type EmptyStateProps, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, Input, type InputProps, Menu, type MenuItem, type MenuProps, MismatchCard, type MismatchCardProps, type MismatchProperty, Modal, type ModalProps, type ModalSize, type ModalTone, MultiSelect, type MultiSelectOption, type MultiSelectProps, Pagination, type PaginationProps, PricingCard, type PricingCardProps, Radio, RadioCard, type RadioCardProps, type RadioProps, SearchInput, type SearchInputProps, SectionHeader, type SectionHeaderProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectOption, type SelectProps, SettingsSection, type SettingsSectionProps, Skeleton, SkeletonGroup, type SkeletonGroupProps, type SkeletonProps, type SkeletonShape, Spinner, type SpinnerProps, Split, type SplitProps, StackedCardsIllustration, Stat, type StatProps, type Step, StepList, type StepListProps, type StepStatus, Swatch, type SwatchProps, TabNav, type TabNavProps, Table, type TableColumn, type TableProps, Tag, type TagProps, Toggle, type ToggleProps, type ToggleSize, type Tone, breakpoints };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ButtonHTMLAttributes, ReactNode, AnchorHTMLAttributes, HTMLAttributes, InputHTMLAttributes, ReactElement } from 'react';
2
+ import { ButtonHTMLAttributes, ReactNode, AnchorHTMLAttributes, HTMLAttributes, InputHTMLAttributes, SVGAttributes, ReactElement } from 'react';
3
3
 
4
4
  type ButtonVariant = 'primary' | 'outlined' | 'text' | 'neutral' | 'link'
5
5
  /** High-contrast near-black, for a page's main create action ("New comparison"). */
@@ -634,6 +634,18 @@ interface SkeletonGroupProps extends HTMLAttributes<HTMLDivElement> {
634
634
  /** Wraps a skeleton layout and announces it once as loading (role="status"). */
635
635
  declare function SkeletonGroup({ label, className, children, ...rest }: SkeletonGroupProps): react.JSX.Element;
636
636
 
637
+ interface SpinnerProps extends Omit<SVGAttributes<SVGSVGElement>, 'children'> {
638
+ /** Width and height in px. @default 24 */
639
+ size?: number;
640
+ /** What's loading, for screen readers. Leave it out when a parent (role="status") already announces it. */
641
+ label?: string;
642
+ }
643
+ /**
644
+ * Fidel design-system Spinner: an accent arc turning on a neutral track, for a
645
+ * wait with no shape to preview. Use Skeleton when the coming layout is known.
646
+ */
647
+ declare function Spinner({ size, label, className, ...rest }: SpinnerProps): react.JSX.Element;
648
+
637
649
  /** Surface colour. `subtle` is the grey panel, `default` white with a border, `plain` white without one. */
638
650
  type CardTone = 'subtle' | 'default' | 'plain';
639
651
  type CardPadding = 'none' | 'md' | 'lg';
@@ -895,4 +907,4 @@ interface PricingCardProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
895
907
  */
896
908
  declare function PricingCard({ eyebrow, title, badge, price, period, description, action, featuresTitle, featuresIntro, features, highlighted, className, ...rest }: PricingCardProps): react.JSX.Element;
897
909
 
898
- export { Accordion, type AccordionProps, AppNav, type AppNavProps, Avatar, type AvatarProps, type AvatarSize, Badge, type BadgeProps, type Breakpoint, Button, ButtonLink, type ButtonLinkProps, type ButtonProps, type ButtonSize, type ButtonVariant, Callout, type CalloutProps, type CalloutTone, Card, type CardPadding, type CardProps, type CardTone, Checkbox, type CheckboxProps, type DiffElement, type DiffPropertyLine, DiffPropertyList, type DiffPropertyListProps, DiffSection, type DiffSectionProps, EmptyState, type EmptyStateProps, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, Input, type InputProps, Menu, type MenuItem, type MenuProps, MismatchCard, type MismatchCardProps, type MismatchProperty, Modal, type ModalProps, type ModalSize, type ModalTone, MultiSelect, type MultiSelectOption, type MultiSelectProps, Pagination, type PaginationProps, PricingCard, type PricingCardProps, Radio, RadioCard, type RadioCardProps, type RadioProps, SearchInput, type SearchInputProps, SectionHeader, type SectionHeaderProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectOption, type SelectProps, SettingsSection, type SettingsSectionProps, Skeleton, SkeletonGroup, type SkeletonGroupProps, type SkeletonProps, type SkeletonShape, Split, type SplitProps, StackedCardsIllustration, Stat, type StatProps, type Step, StepList, type StepListProps, type StepStatus, Swatch, type SwatchProps, TabNav, type TabNavProps, Table, type TableColumn, type TableProps, Tag, type TagProps, Toggle, type ToggleProps, type ToggleSize, type Tone, breakpoints };
910
+ export { Accordion, type AccordionProps, AppNav, type AppNavProps, Avatar, type AvatarProps, type AvatarSize, Badge, type BadgeProps, type Breakpoint, Button, ButtonLink, type ButtonLinkProps, type ButtonProps, type ButtonSize, type ButtonVariant, Callout, type CalloutProps, type CalloutTone, Card, type CardPadding, type CardProps, type CardTone, Checkbox, type CheckboxProps, type DiffElement, type DiffPropertyLine, DiffPropertyList, type DiffPropertyListProps, DiffSection, type DiffSectionProps, EmptyState, type EmptyStateProps, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, Input, type InputProps, Menu, type MenuItem, type MenuProps, MismatchCard, type MismatchCardProps, type MismatchProperty, Modal, type ModalProps, type ModalSize, type ModalTone, MultiSelect, type MultiSelectOption, type MultiSelectProps, Pagination, type PaginationProps, PricingCard, type PricingCardProps, Radio, RadioCard, type RadioCardProps, type RadioProps, SearchInput, type SearchInputProps, SectionHeader, type SectionHeaderProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectOption, type SelectProps, SettingsSection, type SettingsSectionProps, Skeleton, SkeletonGroup, type SkeletonGroupProps, type SkeletonProps, type SkeletonShape, Spinner, type SpinnerProps, Split, type SplitProps, StackedCardsIllustration, Stat, type StatProps, type Step, StepList, type StepListProps, type StepStatus, Swatch, type SwatchProps, TabNav, type TabNavProps, Table, type TableColumn, type TableProps, Tag, type TagProps, Toggle, type ToggleProps, type ToggleSize, type Tone, breakpoints };
package/dist/index.js CHANGED
@@ -1331,32 +1331,56 @@ function SkeletonGroup({ label = "Loading", className, children, ...rest }) {
1331
1331
  return /* @__PURE__ */ jsx22("div", { role: "status", "aria-busy": "true", "aria-label": label, className, ...rest, children });
1332
1332
  }
1333
1333
 
1334
+ // src/components/Spinner/Spinner.tsx
1335
+ import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
1336
+ function Spinner({ size = 24, label, className, ...rest }) {
1337
+ const a11y = label ? { role: "img", "aria-label": label } : { "aria-hidden": true };
1338
+ return /* @__PURE__ */ jsxs20(
1339
+ "svg",
1340
+ {
1341
+ className: ["fds-spinner", className].filter(Boolean).join(" "),
1342
+ width: size,
1343
+ height: size,
1344
+ viewBox: "0 0 24 24",
1345
+ fill: "none",
1346
+ strokeWidth: "2.5",
1347
+ strokeLinecap: "round",
1348
+ ...a11y,
1349
+ ...rest,
1350
+ children: [
1351
+ /* @__PURE__ */ jsx23("circle", { className: "fds-spinner__track", cx: "12", cy: "12", r: "10" }),
1352
+ /* @__PURE__ */ jsx23("path", { className: "fds-spinner__arc", d: "M12 2a10 10 0 0 1 10 10" })
1353
+ ]
1354
+ }
1355
+ );
1356
+ }
1357
+
1334
1358
  // src/components/Card/Card.tsx
1335
- import { jsx as jsx23 } from "react/jsx-runtime";
1359
+ import { jsx as jsx24 } from "react/jsx-runtime";
1336
1360
  function Card({ tone = "default", padding = "md", className, children, ...rest }) {
1337
1361
  const classes = ["fds-card", `fds-card--${tone}`, `fds-card--pad-${padding}`, className].filter(Boolean).join(" ");
1338
- return /* @__PURE__ */ jsx23("div", { className: classes, ...rest, children });
1362
+ return /* @__PURE__ */ jsx24("div", { className: classes, ...rest, children });
1339
1363
  }
1340
1364
 
1341
1365
  // src/components/Stat/Stat.tsx
1342
- import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
1366
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
1343
1367
  function Stat({ label, value, children, className, ...rest }) {
1344
- return /* @__PURE__ */ jsxs20("div", { className: ["fds-stat", className].filter(Boolean).join(" "), ...rest, children: [
1345
- /* @__PURE__ */ jsx24("p", { className: "fds-stat__label", children: label }),
1346
- /* @__PURE__ */ jsx24("p", { className: "fds-stat__value", children: value }),
1347
- children != null && /* @__PURE__ */ jsx24("div", { className: "fds-stat__detail", children })
1368
+ return /* @__PURE__ */ jsxs21("div", { className: ["fds-stat", className].filter(Boolean).join(" "), ...rest, children: [
1369
+ /* @__PURE__ */ jsx25("p", { className: "fds-stat__label", children: label }),
1370
+ /* @__PURE__ */ jsx25("p", { className: "fds-stat__value", children: value }),
1371
+ children != null && /* @__PURE__ */ jsx25("div", { className: "fds-stat__detail", children })
1348
1372
  ] });
1349
1373
  }
1350
1374
 
1351
1375
  // src/components/Swatch/Swatch.tsx
1352
- import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
1376
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
1353
1377
  function Swatch({ color, name, value, children, className, ...rest }) {
1354
- return /* @__PURE__ */ jsxs21("div", { className: ["fds-swatch", className].filter(Boolean).join(" "), ...rest, children: [
1355
- /* @__PURE__ */ jsx25("div", { className: "fds-swatch__color", style: { "--fds-swatch-color": color }, "aria-hidden": "true" }),
1356
- /* @__PURE__ */ jsxs21("div", { className: "fds-swatch__body", children: [
1357
- /* @__PURE__ */ jsx25("p", { className: "fds-swatch__name", children: name }),
1358
- value != null && /* @__PURE__ */ jsx25("p", { className: "fds-swatch__value", children: value }),
1359
- children != null && /* @__PURE__ */ jsx25("div", { className: "fds-swatch__detail", children })
1378
+ return /* @__PURE__ */ jsxs22("div", { className: ["fds-swatch", className].filter(Boolean).join(" "), ...rest, children: [
1379
+ /* @__PURE__ */ jsx26("div", { className: "fds-swatch__color", style: { "--fds-swatch-color": color }, "aria-hidden": "true" }),
1380
+ /* @__PURE__ */ jsxs22("div", { className: "fds-swatch__body", children: [
1381
+ /* @__PURE__ */ jsx26("p", { className: "fds-swatch__name", children: name }),
1382
+ value != null && /* @__PURE__ */ jsx26("p", { className: "fds-swatch__value", children: value }),
1383
+ children != null && /* @__PURE__ */ jsx26("div", { className: "fds-swatch__detail", children })
1360
1384
  ] })
1361
1385
  ] });
1362
1386
  }
@@ -1369,7 +1393,7 @@ import {
1369
1393
  useImperativeHandle as useImperativeHandle2,
1370
1394
  useRef as useRef6
1371
1395
  } from "react";
1372
- import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
1396
+ import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
1373
1397
  var Checkbox = forwardRef4(function Checkbox2({ label, description, indeterminate = false, className, id, disabled, ...rest }, ref) {
1374
1398
  const generatedId = useId7();
1375
1399
  const inputId = id ?? generatedId;
@@ -1378,13 +1402,13 @@ var Checkbox = forwardRef4(function Checkbox2({ label, description, indeterminat
1378
1402
  useEffect5(() => {
1379
1403
  if (inputRef.current) inputRef.current.indeterminate = indeterminate;
1380
1404
  }, [indeterminate]);
1381
- return /* @__PURE__ */ jsxs22(
1405
+ return /* @__PURE__ */ jsxs23(
1382
1406
  "div",
1383
1407
  {
1384
1408
  className: ["fds-checkbox", className].filter(Boolean).join(" "),
1385
1409
  "data-disabled": disabled ? "" : void 0,
1386
1410
  children: [
1387
- /* @__PURE__ */ jsx26(
1411
+ /* @__PURE__ */ jsx27(
1388
1412
  "input",
1389
1413
  {
1390
1414
  ...rest,
@@ -1395,14 +1419,14 @@ var Checkbox = forwardRef4(function Checkbox2({ label, description, indeterminat
1395
1419
  className: "fds-checkbox__input"
1396
1420
  }
1397
1421
  ),
1398
- /* @__PURE__ */ jsxs22("label", { htmlFor: inputId, className: "fds-checkbox__control", children: [
1399
- /* @__PURE__ */ jsxs22("span", { className: "fds-checkbox__box", "aria-hidden": "true", children: [
1400
- /* @__PURE__ */ jsx26("svg", { className: "fds-checkbox__tick", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx26("path", { d: "M10 3L4.5 8.5 2 6", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
1401
- /* @__PURE__ */ jsx26("svg", { className: "fds-checkbox__dash", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx26("path", { d: "M3 6h6", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }) })
1422
+ /* @__PURE__ */ jsxs23("label", { htmlFor: inputId, className: "fds-checkbox__control", children: [
1423
+ /* @__PURE__ */ jsxs23("span", { className: "fds-checkbox__box", "aria-hidden": "true", children: [
1424
+ /* @__PURE__ */ jsx27("svg", { className: "fds-checkbox__tick", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx27("path", { d: "M10 3L4.5 8.5 2 6", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
1425
+ /* @__PURE__ */ jsx27("svg", { className: "fds-checkbox__dash", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx27("path", { d: "M3 6h6", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }) })
1402
1426
  ] }),
1403
- (label != null || description != null) && /* @__PURE__ */ jsxs22("span", { className: "fds-checkbox__text", children: [
1404
- label != null && /* @__PURE__ */ jsx26("span", { className: "fds-checkbox__label", children: label }),
1405
- description != null && /* @__PURE__ */ jsx26("span", { className: "fds-checkbox__description", children: description })
1427
+ (label != null || description != null) && /* @__PURE__ */ jsxs23("span", { className: "fds-checkbox__text", children: [
1428
+ label != null && /* @__PURE__ */ jsx27("span", { className: "fds-checkbox__label", children: label }),
1429
+ description != null && /* @__PURE__ */ jsx27("span", { className: "fds-checkbox__description", children: description })
1406
1430
  ] })
1407
1431
  ] })
1408
1432
  ]
@@ -1412,17 +1436,17 @@ var Checkbox = forwardRef4(function Checkbox2({ label, description, indeterminat
1412
1436
 
1413
1437
  // src/components/Radio/Radio.tsx
1414
1438
  import { forwardRef as forwardRef5, useId as useId8 } from "react";
1415
- import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
1439
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
1416
1440
  var Radio = forwardRef5(function Radio2({ label, description, className, id, disabled, ...rest }, ref) {
1417
1441
  const generatedId = useId8();
1418
1442
  const inputId = id ?? generatedId;
1419
- return /* @__PURE__ */ jsxs23("div", { className: ["fds-radio", className].filter(Boolean).join(" "), "data-disabled": disabled ? "" : void 0, children: [
1420
- /* @__PURE__ */ jsx27("input", { ...rest, id: inputId, ref, type: "radio", disabled, className: "fds-radio__input" }),
1421
- /* @__PURE__ */ jsxs23("label", { htmlFor: inputId, className: "fds-radio__control", children: [
1422
- /* @__PURE__ */ jsx27("span", { className: "fds-radio__circle", "aria-hidden": "true" }),
1423
- (label != null || description != null) && /* @__PURE__ */ jsxs23("span", { className: "fds-radio__text", children: [
1424
- label != null && /* @__PURE__ */ jsx27("span", { className: "fds-radio__label", children: label }),
1425
- description != null && /* @__PURE__ */ jsx27("span", { className: "fds-radio__description", children: description })
1443
+ return /* @__PURE__ */ jsxs24("div", { className: ["fds-radio", className].filter(Boolean).join(" "), "data-disabled": disabled ? "" : void 0, children: [
1444
+ /* @__PURE__ */ jsx28("input", { ...rest, id: inputId, ref, type: "radio", disabled, className: "fds-radio__input" }),
1445
+ /* @__PURE__ */ jsxs24("label", { htmlFor: inputId, className: "fds-radio__control", children: [
1446
+ /* @__PURE__ */ jsx28("span", { className: "fds-radio__circle", "aria-hidden": "true" }),
1447
+ (label != null || description != null) && /* @__PURE__ */ jsxs24("span", { className: "fds-radio__text", children: [
1448
+ label != null && /* @__PURE__ */ jsx28("span", { className: "fds-radio__label", children: label }),
1449
+ description != null && /* @__PURE__ */ jsx28("span", { className: "fds-radio__description", children: description })
1426
1450
  ] })
1427
1451
  ] })
1428
1452
  ] });
@@ -1430,13 +1454,13 @@ var Radio = forwardRef5(function Radio2({ label, description, className, id, dis
1430
1454
 
1431
1455
  // src/components/RadioCard/RadioCard.tsx
1432
1456
  import { forwardRef as forwardRef6, useId as useId9 } from "react";
1433
- import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
1457
+ import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
1434
1458
  var RadioCard = forwardRef6(function RadioCard2({ label, description, icon, meta, className, id, disabled, ...rest }, ref) {
1435
1459
  const generatedId = useId9();
1436
1460
  const inputId = id ?? generatedId;
1437
1461
  const descriptionId = description != null ? `${inputId}-description` : void 0;
1438
- return /* @__PURE__ */ jsxs24("div", { className: ["fds-radio-card", className].filter(Boolean).join(" "), "data-disabled": disabled ? "" : void 0, children: [
1439
- /* @__PURE__ */ jsx28(
1462
+ return /* @__PURE__ */ jsxs25("div", { className: ["fds-radio-card", className].filter(Boolean).join(" "), "data-disabled": disabled ? "" : void 0, children: [
1463
+ /* @__PURE__ */ jsx29(
1440
1464
  "input",
1441
1465
  {
1442
1466
  ...rest,
@@ -1448,21 +1472,21 @@ var RadioCard = forwardRef6(function RadioCard2({ label, description, icon, meta
1448
1472
  className: "fds-radio-card__input"
1449
1473
  }
1450
1474
  ),
1451
- /* @__PURE__ */ jsxs24("label", { htmlFor: inputId, className: "fds-radio-card__body", children: [
1452
- icon != null && /* @__PURE__ */ jsx28("span", { className: "fds-radio-card__icon", "aria-hidden": "true", children: icon }),
1453
- /* @__PURE__ */ jsxs24("span", { className: "fds-radio-card__text", children: [
1454
- /* @__PURE__ */ jsx28("span", { className: "fds-radio-card__label", children: label }),
1455
- description != null && /* @__PURE__ */ jsx28("span", { id: descriptionId, className: "fds-radio-card__description", children: description }),
1456
- meta != null && /* @__PURE__ */ jsx28("span", { className: "fds-radio-card__meta", children: meta })
1475
+ /* @__PURE__ */ jsxs25("label", { htmlFor: inputId, className: "fds-radio-card__body", children: [
1476
+ icon != null && /* @__PURE__ */ jsx29("span", { className: "fds-radio-card__icon", "aria-hidden": "true", children: icon }),
1477
+ /* @__PURE__ */ jsxs25("span", { className: "fds-radio-card__text", children: [
1478
+ /* @__PURE__ */ jsx29("span", { className: "fds-radio-card__label", children: label }),
1479
+ description != null && /* @__PURE__ */ jsx29("span", { id: descriptionId, className: "fds-radio-card__description", children: description }),
1480
+ meta != null && /* @__PURE__ */ jsx29("span", { className: "fds-radio-card__meta", children: meta })
1457
1481
  ] }),
1458
- /* @__PURE__ */ jsx28("span", { className: "fds-radio-card__circle", "aria-hidden": "true" })
1482
+ /* @__PURE__ */ jsx29("span", { className: "fds-radio-card__circle", "aria-hidden": "true" })
1459
1483
  ] })
1460
1484
  ] });
1461
1485
  });
1462
1486
 
1463
1487
  // src/components/Accordion/Accordion.tsx
1464
1488
  import { useId as useId10, useState as useState7 } from "react";
1465
- import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
1489
+ import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
1466
1490
  function Accordion({
1467
1491
  summary,
1468
1492
  actions,
@@ -1481,15 +1505,15 @@ function Accordion({
1481
1505
  if (openProp === void 0) setOpenState(next);
1482
1506
  onOpenChange?.(next);
1483
1507
  };
1484
- return /* @__PURE__ */ jsxs25(
1508
+ return /* @__PURE__ */ jsxs26(
1485
1509
  "div",
1486
1510
  {
1487
1511
  className: ["fds-accordion", className].filter(Boolean).join(" "),
1488
1512
  "data-open": open ? "" : void 0,
1489
1513
  ...rest,
1490
1514
  children: [
1491
- /* @__PURE__ */ jsxs25("div", { className: "fds-accordion__header", children: [
1492
- /* @__PURE__ */ jsx29(
1515
+ /* @__PURE__ */ jsxs26("div", { className: "fds-accordion__header", children: [
1516
+ /* @__PURE__ */ jsx30(
1493
1517
  "button",
1494
1518
  {
1495
1519
  type: "button",
@@ -1500,17 +1524,17 @@ function Accordion({
1500
1524
  children: summary
1501
1525
  }
1502
1526
  ),
1503
- actions != null && /* @__PURE__ */ jsx29("div", { className: "fds-accordion__actions", children: actions }),
1504
- /* @__PURE__ */ jsx29("span", { className: "fds-accordion__chevron", "aria-hidden": "true", onClick: toggle, children: /* @__PURE__ */ jsx29("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", children: /* @__PURE__ */ jsx29("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
1527
+ actions != null && /* @__PURE__ */ jsx30("div", { className: "fds-accordion__actions", children: actions }),
1528
+ /* @__PURE__ */ jsx30("span", { className: "fds-accordion__chevron", "aria-hidden": "true", onClick: toggle, children: /* @__PURE__ */ jsx30("svg", { viewBox: "0 0 24 24", width: "16", height: "16", fill: "none", children: /* @__PURE__ */ jsx30("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
1505
1529
  ] }),
1506
- /* @__PURE__ */ jsx29("div", { id: bodyId, className: "fds-accordion__body", hidden: !open, children })
1530
+ /* @__PURE__ */ jsx30("div", { id: bodyId, className: "fds-accordion__body", hidden: !open, children })
1507
1531
  ]
1508
1532
  }
1509
1533
  );
1510
1534
  }
1511
1535
 
1512
1536
  // src/components/StepList/StepList.tsx
1513
- import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
1537
+ import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
1514
1538
  var STATUS_TEXT = {
1515
1539
  done: "Done",
1516
1540
  active: "In progress",
@@ -1520,32 +1544,32 @@ var STATUS_TEXT = {
1520
1544
  function StepIcon({ status }) {
1521
1545
  const common = { viewBox: "0 0 24 24", width: 18, height: 18, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" };
1522
1546
  if (status === "done") {
1523
- return /* @__PURE__ */ jsxs26("svg", { ...common, children: [
1524
- /* @__PURE__ */ jsx30("circle", { cx: "12", cy: "12", r: "9" }),
1525
- /* @__PURE__ */ jsx30("path", { d: "M8 12.5l2.5 2.5 5-5.5" })
1547
+ return /* @__PURE__ */ jsxs27("svg", { ...common, children: [
1548
+ /* @__PURE__ */ jsx31("circle", { cx: "12", cy: "12", r: "9" }),
1549
+ /* @__PURE__ */ jsx31("path", { d: "M8 12.5l2.5 2.5 5-5.5" })
1526
1550
  ] });
1527
1551
  }
1528
1552
  if (status === "active") {
1529
- return /* @__PURE__ */ jsx30("svg", { ...common, className: "fds-steps__spinner", children: /* @__PURE__ */ jsx30("path", { d: "M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1" }) });
1553
+ return /* @__PURE__ */ jsx31("svg", { ...common, className: "fds-steps__spinner", children: /* @__PURE__ */ jsx31("path", { d: "M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1" }) });
1530
1554
  }
1531
1555
  if (status === "failed") {
1532
- return /* @__PURE__ */ jsxs26("svg", { ...common, children: [
1533
- /* @__PURE__ */ jsx30("circle", { cx: "12", cy: "12", r: "9" }),
1534
- /* @__PURE__ */ jsx30("path", { d: "M12 7.5v5.5M12 16.5v.01" })
1556
+ return /* @__PURE__ */ jsxs27("svg", { ...common, children: [
1557
+ /* @__PURE__ */ jsx31("circle", { cx: "12", cy: "12", r: "9" }),
1558
+ /* @__PURE__ */ jsx31("path", { d: "M12 7.5v5.5M12 16.5v.01" })
1535
1559
  ] });
1536
1560
  }
1537
- return /* @__PURE__ */ jsx30("svg", { ...common, children: /* @__PURE__ */ jsx30("circle", { cx: "12", cy: "12", r: "9" }) });
1561
+ return /* @__PURE__ */ jsx31("svg", { ...common, children: /* @__PURE__ */ jsx31("circle", { cx: "12", cy: "12", r: "9" }) });
1538
1562
  }
1539
1563
  function StepList({ steps, className, ...rest }) {
1540
- return /* @__PURE__ */ jsx30("ol", { className: ["fds-steps", className].filter(Boolean).join(" "), ...rest, children: steps.map((step) => /* @__PURE__ */ jsxs26(
1564
+ return /* @__PURE__ */ jsx31("ol", { className: ["fds-steps", className].filter(Boolean).join(" "), ...rest, children: steps.map((step) => /* @__PURE__ */ jsxs27(
1541
1565
  "li",
1542
1566
  {
1543
1567
  className: `fds-steps__step fds-steps__step--${step.status}`,
1544
1568
  "aria-current": step.status === "active" ? "step" : void 0,
1545
1569
  children: [
1546
- /* @__PURE__ */ jsx30("span", { className: "fds-steps__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx30(StepIcon, { status: step.status }) }),
1547
- /* @__PURE__ */ jsx30("span", { className: "fds-steps__label", children: step.label }),
1548
- /* @__PURE__ */ jsxs26("span", { className: "fds-steps__sr", children: [
1570
+ /* @__PURE__ */ jsx31("span", { className: "fds-steps__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx31(StepIcon, { status: step.status }) }),
1571
+ /* @__PURE__ */ jsx31("span", { className: "fds-steps__label", children: step.label }),
1572
+ /* @__PURE__ */ jsxs27("span", { className: "fds-steps__sr", children: [
1549
1573
  ", ",
1550
1574
  STATUS_TEXT[step.status]
1551
1575
  ] })
@@ -1557,7 +1581,7 @@ function StepList({ steps, className, ...rest }) {
1557
1581
 
1558
1582
  // src/components/Input/Input.tsx
1559
1583
  import { forwardRef as forwardRef7, useId as useId11 } from "react";
1560
- import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
1584
+ import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
1561
1585
  var Input = forwardRef7(function Input2({ label, hint, error, leadingIcon, trailing, id, className, containerClassName, readOnly, disabled, ...rest }, ref) {
1562
1586
  const genId = useId11();
1563
1587
  const inputId = id ?? genId;
@@ -1568,11 +1592,11 @@ var Input = forwardRef7(function Input2({ label, hint, error, leadingIcon, trail
1568
1592
  error ? "fds-input__box--error" : "",
1569
1593
  readOnly || disabled ? "fds-input__box--locked" : ""
1570
1594
  ].filter(Boolean).join(" ");
1571
- return /* @__PURE__ */ jsxs27("div", { className: ["fds-input", containerClassName].filter(Boolean).join(" "), children: [
1572
- label != null && /* @__PURE__ */ jsx31("label", { htmlFor: inputId, className: "fds-input__label", children: label }),
1573
- /* @__PURE__ */ jsxs27("div", { className: boxClasses, children: [
1574
- leadingIcon != null && /* @__PURE__ */ jsx31("span", { className: "fds-input__icon", "aria-hidden": "true", children: leadingIcon }),
1575
- /* @__PURE__ */ jsx31(
1595
+ return /* @__PURE__ */ jsxs28("div", { className: ["fds-input", containerClassName].filter(Boolean).join(" "), children: [
1596
+ label != null && /* @__PURE__ */ jsx32("label", { htmlFor: inputId, className: "fds-input__label", children: label }),
1597
+ /* @__PURE__ */ jsxs28("div", { className: boxClasses, children: [
1598
+ leadingIcon != null && /* @__PURE__ */ jsx32("span", { className: "fds-input__icon", "aria-hidden": "true", children: leadingIcon }),
1599
+ /* @__PURE__ */ jsx32(
1576
1600
  "input",
1577
1601
  {
1578
1602
  ref,
@@ -1585,14 +1609,14 @@ var Input = forwardRef7(function Input2({ label, hint, error, leadingIcon, trail
1585
1609
  ...rest
1586
1610
  }
1587
1611
  ),
1588
- trailing != null && /* @__PURE__ */ jsx31("span", { className: "fds-input__trailing", children: trailing })
1612
+ trailing != null && /* @__PURE__ */ jsx32("span", { className: "fds-input__trailing", children: trailing })
1589
1613
  ] }),
1590
- message != null && /* @__PURE__ */ jsx31("p", { id: msgId, className: error ? "fds-input__error" : "fds-input__hint", children: message })
1614
+ message != null && /* @__PURE__ */ jsx32("p", { id: msgId, className: error ? "fds-input__error" : "fds-input__hint", children: message })
1591
1615
  ] });
1592
1616
  });
1593
1617
 
1594
1618
  // src/components/IconButton/IconButton.tsx
1595
- import { jsx as jsx32 } from "react/jsx-runtime";
1619
+ import { jsx as jsx33 } from "react/jsx-runtime";
1596
1620
  function IconButton({
1597
1621
  icon,
1598
1622
  variant = "outlined",
@@ -1602,7 +1626,7 @@ function IconButton({
1602
1626
  ...rest
1603
1627
  }) {
1604
1628
  const classes = ["fds-icon-button", `fds-icon-button--${variant}`, `fds-icon-button--${size}`, className].filter(Boolean).join(" ");
1605
- return /* @__PURE__ */ jsx32("button", { type, className: classes, ...rest, children: /* @__PURE__ */ jsx32("span", { className: "fds-icon-button__icon", "aria-hidden": "true", children: icon }) });
1629
+ return /* @__PURE__ */ jsx33("button", { type, className: classes, ...rest, children: /* @__PURE__ */ jsx33("span", { className: "fds-icon-button__icon", "aria-hidden": "true", children: icon }) });
1606
1630
  }
1607
1631
 
1608
1632
  // src/components/Menu/Menu.tsx
@@ -1613,7 +1637,7 @@ import {
1613
1637
  useRef as useRef7,
1614
1638
  useState as useState8
1615
1639
  } from "react";
1616
- import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
1640
+ import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
1617
1641
  function Menu({ trigger, items, align = "end", className }) {
1618
1642
  const listId = useId12();
1619
1643
  const rootRef = useRef7(null);
@@ -1695,9 +1719,9 @@ function Menu({ trigger, items, align = "end", className }) {
1695
1719
  }
1696
1720
  }
1697
1721
  });
1698
- return /* @__PURE__ */ jsxs28("div", { ref: rootRef, className: ["fds-menu", className].filter(Boolean).join(" "), children: [
1722
+ return /* @__PURE__ */ jsxs29("div", { ref: rootRef, className: ["fds-menu", className].filter(Boolean).join(" "), children: [
1699
1723
  wired,
1700
- open && /* @__PURE__ */ jsx33(
1724
+ open && /* @__PURE__ */ jsx34(
1701
1725
  "div",
1702
1726
  {
1703
1727
  ref: listRef,
@@ -1707,7 +1731,7 @@ function Menu({ trigger, items, align = "end", className }) {
1707
1731
  className: `fds-menu__list fds-menu__list--${align}`,
1708
1732
  "aria-activedescendant": `${listId}-item-${active}`,
1709
1733
  onKeyDown: onListKeyDown,
1710
- children: items.map((it, i) => /* @__PURE__ */ jsxs28(
1734
+ children: items.map((it, i) => /* @__PURE__ */ jsxs29(
1711
1735
  "div",
1712
1736
  {
1713
1737
  id: `${listId}-item-${i}`,
@@ -1723,7 +1747,7 @@ function Menu({ trigger, items, align = "end", className }) {
1723
1747
  onMouseDown: (e) => e.preventDefault(),
1724
1748
  onClick: () => choose(i),
1725
1749
  children: [
1726
- it.icon != null && /* @__PURE__ */ jsx33("span", { className: "fds-menu__icon", "aria-hidden": "true", children: it.icon }),
1750
+ it.icon != null && /* @__PURE__ */ jsx34("span", { className: "fds-menu__icon", "aria-hidden": "true", children: it.icon }),
1727
1751
  it.label
1728
1752
  ]
1729
1753
  },
@@ -1735,10 +1759,10 @@ function Menu({ trigger, items, align = "end", className }) {
1735
1759
  }
1736
1760
 
1737
1761
  // src/components/Table/Table.tsx
1738
- import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
1762
+ import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
1739
1763
  function Table({ columns, rows, rowKey, empty, className, "aria-label": ariaLabel, ...rest }) {
1740
- return /* @__PURE__ */ jsx34("div", { className: ["fds-table", className].filter(Boolean).join(" "), ...rest, children: /* @__PURE__ */ jsxs29("table", { className: "fds-table__table", "aria-label": ariaLabel, children: [
1741
- /* @__PURE__ */ jsx34("thead", { children: /* @__PURE__ */ jsx34("tr", { children: columns.map((c) => /* @__PURE__ */ jsx34(
1764
+ return /* @__PURE__ */ jsx35("div", { className: ["fds-table", className].filter(Boolean).join(" "), ...rest, children: /* @__PURE__ */ jsxs30("table", { className: "fds-table__table", "aria-label": ariaLabel, children: [
1765
+ /* @__PURE__ */ jsx35("thead", { children: /* @__PURE__ */ jsx35("tr", { children: columns.map((c) => /* @__PURE__ */ jsx35(
1742
1766
  "th",
1743
1767
  {
1744
1768
  scope: "col",
@@ -1748,17 +1772,17 @@ function Table({ columns, rows, rowKey, empty, className, "aria-label": ariaLabe
1748
1772
  },
1749
1773
  c.key
1750
1774
  )) }) }),
1751
- /* @__PURE__ */ jsxs29("tbody", { children: [
1752
- rows.map((row) => /* @__PURE__ */ jsx34("tr", { children: columns.map((c) => /* @__PURE__ */ jsx34("td", { className: c.align === "end" ? "fds-table__cell--end" : void 0, children: c.cell(row) }, c.key)) }, rowKey(row))),
1753
- rows.length === 0 && empty != null && /* @__PURE__ */ jsx34("tr", { children: /* @__PURE__ */ jsx34("td", { colSpan: columns.length, className: "fds-table__empty", children: empty }) })
1775
+ /* @__PURE__ */ jsxs30("tbody", { children: [
1776
+ rows.map((row) => /* @__PURE__ */ jsx35("tr", { children: columns.map((c) => /* @__PURE__ */ jsx35("td", { className: c.align === "end" ? "fds-table__cell--end" : void 0, children: c.cell(row) }, c.key)) }, rowKey(row))),
1777
+ rows.length === 0 && empty != null && /* @__PURE__ */ jsx35("tr", { children: /* @__PURE__ */ jsx35("td", { colSpan: columns.length, className: "fds-table__empty", children: empty }) })
1754
1778
  ] })
1755
1779
  ] }) });
1756
1780
  }
1757
1781
 
1758
1782
  // src/components/PricingCard/PricingCard.tsx
1759
- import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
1783
+ import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
1760
1784
  function CheckIcon3() {
1761
- return /* @__PURE__ */ jsx35("svg", { viewBox: "0 0 16 16", width: "12", height: "12", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx35("path", { d: "M3.5 8.5l3 3 6-7", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) });
1785
+ return /* @__PURE__ */ jsx36("svg", { viewBox: "0 0 16 16", width: "12", height: "12", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx36("path", { d: "M3.5 8.5l3 3 6-7", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) });
1762
1786
  }
1763
1787
  function PricingCard({
1764
1788
  eyebrow,
@@ -1776,25 +1800,25 @@ function PricingCard({
1776
1800
  ...rest
1777
1801
  }) {
1778
1802
  const classes = ["fds-pricing-card", highlighted ? "fds-pricing-card--highlighted" : "", className].filter(Boolean).join(" ");
1779
- return /* @__PURE__ */ jsxs30("article", { className: classes, ...rest, children: [
1780
- /* @__PURE__ */ jsxs30("div", { className: "fds-pricing-card__top", children: [
1781
- eyebrow != null && /* @__PURE__ */ jsx35("span", { className: "fds-pricing-card__eyebrow", children: eyebrow }),
1782
- /* @__PURE__ */ jsxs30("h3", { className: "fds-pricing-card__title", children: [
1803
+ return /* @__PURE__ */ jsxs31("article", { className: classes, ...rest, children: [
1804
+ /* @__PURE__ */ jsxs31("div", { className: "fds-pricing-card__top", children: [
1805
+ eyebrow != null && /* @__PURE__ */ jsx36("span", { className: "fds-pricing-card__eyebrow", children: eyebrow }),
1806
+ /* @__PURE__ */ jsxs31("h3", { className: "fds-pricing-card__title", children: [
1783
1807
  title,
1784
1808
  badge
1785
1809
  ] }),
1786
- /* @__PURE__ */ jsxs30("p", { className: "fds-pricing-card__price", children: [
1787
- /* @__PURE__ */ jsx35("span", { className: "fds-pricing-card__amount", children: price }),
1788
- period != null && /* @__PURE__ */ jsx35("span", { className: "fds-pricing-card__period", children: period })
1810
+ /* @__PURE__ */ jsxs31("p", { className: "fds-pricing-card__price", children: [
1811
+ /* @__PURE__ */ jsx36("span", { className: "fds-pricing-card__amount", children: price }),
1812
+ period != null && /* @__PURE__ */ jsx36("span", { className: "fds-pricing-card__period", children: period })
1789
1813
  ] }),
1790
- description != null && /* @__PURE__ */ jsx35("p", { className: "fds-pricing-card__description", children: description }),
1791
- action != null && /* @__PURE__ */ jsx35("div", { className: "fds-pricing-card__action", children: action })
1814
+ description != null && /* @__PURE__ */ jsx36("p", { className: "fds-pricing-card__description", children: description }),
1815
+ action != null && /* @__PURE__ */ jsx36("div", { className: "fds-pricing-card__action", children: action })
1792
1816
  ] }),
1793
- features.length > 0 && /* @__PURE__ */ jsxs30("div", { className: "fds-pricing-card__features", children: [
1794
- /* @__PURE__ */ jsx35("p", { className: "fds-pricing-card__featuresTitle", children: featuresTitle }),
1795
- featuresIntro != null && /* @__PURE__ */ jsx35("p", { className: "fds-pricing-card__intro", children: featuresIntro }),
1796
- /* @__PURE__ */ jsx35("ul", { className: "fds-pricing-card__list", children: features.map((f, i) => /* @__PURE__ */ jsxs30("li", { className: "fds-pricing-card__feature", children: [
1797
- /* @__PURE__ */ jsx35("span", { className: "fds-pricing-card__check", children: /* @__PURE__ */ jsx35(CheckIcon3, {}) }),
1817
+ features.length > 0 && /* @__PURE__ */ jsxs31("div", { className: "fds-pricing-card__features", children: [
1818
+ /* @__PURE__ */ jsx36("p", { className: "fds-pricing-card__featuresTitle", children: featuresTitle }),
1819
+ featuresIntro != null && /* @__PURE__ */ jsx36("p", { className: "fds-pricing-card__intro", children: featuresIntro }),
1820
+ /* @__PURE__ */ jsx36("ul", { className: "fds-pricing-card__list", children: features.map((f, i) => /* @__PURE__ */ jsxs31("li", { className: "fds-pricing-card__feature", children: [
1821
+ /* @__PURE__ */ jsx36("span", { className: "fds-pricing-card__check", children: /* @__PURE__ */ jsx36(CheckIcon3, {}) }),
1798
1822
  f
1799
1823
  ] }, i)) })
1800
1824
  ] })
@@ -1830,6 +1854,7 @@ export {
1830
1854
  SettingsSection,
1831
1855
  Skeleton,
1832
1856
  SkeletonGroup,
1857
+ Spinner,
1833
1858
  Split,
1834
1859
  StackedCardsIllustration,
1835
1860
  Stat,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usefidel/design-system",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Fidel brand design tokens + React component library — DTCG token source of truth, generated per-surface CSS + Tailwind-v4 parser-compatibility output, and on-brand React components (Button, MismatchCard, DiffSection).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",