@usefidel/design-system 0.27.0 → 0.28.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.27.0",
14
- "resolvedSha": "95492923d7a948576cddd0419d561913dbf75b7f"
13
+ "packageVersion": "0.28.0",
14
+ "resolvedSha": "314e7e61463bc7f60a47d62770c2aa8d00f2bc2e"
15
15
  }
package/dist/index.cjs CHANGED
@@ -33,7 +33,9 @@ __export(index_exports, {
33
33
  Card: () => Card,
34
34
  Checkbox: () => Checkbox,
35
35
  Checklist: () => Checklist,
36
+ CodeBlock: () => CodeBlock,
36
37
  ColorRamp: () => ColorRamp,
38
+ ConnectionCard: () => ConnectionCard,
37
39
  DescriptionList: () => DescriptionList,
38
40
  DiffPropertyList: () => DiffPropertyList,
39
41
  DiffSection: () => DiffSection,
@@ -46,6 +48,7 @@ __export(index_exports, {
46
48
  Input: () => Input,
47
49
  ListCard: () => ListCard,
48
50
  ListLabel: () => ListLabel,
51
+ ListRow: () => ListRow,
49
52
  MeasureList: () => MeasureList,
50
53
  Menu: () => Menu,
51
54
  Meter: () => Meter,
@@ -1391,6 +1394,7 @@ function StackedCardsIllustration({ className }) {
1391
1394
  }
1392
1395
 
1393
1396
  // src/components/Callout/Callout.tsx
1397
+ var import_lucide_react2 = require("lucide-react");
1394
1398
  var import_jsx_runtime21 = require("react/jsx-runtime");
1395
1399
  function Callout({
1396
1400
  tone = "neutral",
@@ -1399,6 +1403,8 @@ function Callout({
1399
1403
  titleAside,
1400
1404
  children,
1401
1405
  action,
1406
+ onDismiss,
1407
+ dismissLabel = "Dismiss",
1402
1408
  className,
1403
1409
  ...rest
1404
1410
  }) {
@@ -1412,7 +1418,8 @@ function Callout({
1412
1418
  ] }),
1413
1419
  children != null && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "fds-callout__text", children })
1414
1420
  ] }),
1415
- action != null && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "fds-callout__action", children: action })
1421
+ action != null && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "fds-callout__action", children: action }),
1422
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", className: "fds-callout__dismiss", "aria-label": dismissLabel, onClick: onDismiss, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react2.X, { "aria-hidden": "true" }) })
1416
1423
  ] });
1417
1424
  }
1418
1425
 
@@ -1733,7 +1740,7 @@ function IconButton({
1733
1740
 
1734
1741
  // src/components/Menu/Menu.tsx
1735
1742
  var import_react17 = require("react");
1736
- var import_lucide_react2 = require("lucide-react");
1743
+ var import_lucide_react3 = require("lucide-react");
1737
1744
  var import_jsx_runtime34 = require("react/jsx-runtime");
1738
1745
  var isItem = (e) => !("type" in e);
1739
1746
  function searchText(it) {
@@ -1889,7 +1896,7 @@ function Menu({
1889
1896
  wired,
1890
1897
  open && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: listClasses, onKeyDown: onListKeyDown, children: [
1891
1898
  search && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "fds-menu__search", children: [
1892
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react2.Search, { "aria-hidden": "true" }),
1899
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react3.Search, { "aria-hidden": "true" }),
1893
1900
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1894
1901
  "input",
1895
1902
  {
@@ -1945,7 +1952,7 @@ function Menu({
1945
1952
  e.description != null && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fds-menu__description", children: e.description })
1946
1953
  ] }),
1947
1954
  e.trailing != null && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fds-menu__trailing", children: e.trailing }),
1948
- e.selected && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react2.Check, { className: "fds-menu__check", "aria-hidden": "true" })
1955
+ e.selected && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react3.Check, { className: "fds-menu__check", "aria-hidden": "true" })
1949
1956
  ]
1950
1957
  },
1951
1958
  i
@@ -2134,12 +2141,12 @@ function Tooltip({ content, children, side = "right", delay = 400, disabled = fa
2134
2141
  }
2135
2142
 
2136
2143
  // src/components/BrandButton/BrandButton.tsx
2137
- var import_lucide_react3 = require("lucide-react");
2144
+ var import_lucide_react4 = require("lucide-react");
2138
2145
  var import_jsx_runtime41 = require("react/jsx-runtime");
2139
2146
  function BrandButton({ mark, hoverIcon, type = "button", className, ...rest }) {
2140
2147
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("button", { type, className: ["fds-brand-button", className].filter(Boolean).join(" "), ...rest, children: [
2141
2148
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "fds-brand-button__mark", "aria-hidden": "true", children: mark }),
2142
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "fds-brand-button__hover", "aria-hidden": "true", children: hoverIcon ?? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react3.PanelLeftOpen, {}) })
2149
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "fds-brand-button__hover", "aria-hidden": "true", children: hoverIcon ?? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react4.PanelLeftOpen, {}) })
2143
2150
  ] });
2144
2151
  }
2145
2152
 
@@ -2179,7 +2186,7 @@ function SidebarItem({
2179
2186
 
2180
2187
  // src/components/Sidebar/Sidebar.tsx
2181
2188
  var import_react20 = require("react");
2182
- var import_lucide_react4 = require("lucide-react");
2189
+ var import_lucide_react5 = require("lucide-react");
2183
2190
  var import_jsx_runtime43 = require("react/jsx-runtime");
2184
2191
  function SidebarRoot({
2185
2192
  collapsed: controlled,
@@ -2248,7 +2255,7 @@ function SidebarBrand({
2248
2255
  {
2249
2256
  variant: "ghost",
2250
2257
  size: "small",
2251
- icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react4.PanelLeftClose, {}),
2258
+ icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react5.PanelLeftClose, {}),
2252
2259
  "aria-label": collapseLabel,
2253
2260
  "aria-keyshortcuts": "Meta+Backslash Control+Backslash",
2254
2261
  onClick: () => sidebar?.setCollapsed(true)
@@ -2306,7 +2313,7 @@ var Sidebar = Object.assign(SidebarRoot, {
2306
2313
 
2307
2314
  // src/components/WorkspaceSwitcher/WorkspaceSwitcher.tsx
2308
2315
  var import_react21 = require("react");
2309
- var import_lucide_react5 = require("lucide-react");
2316
+ var import_lucide_react6 = require("lucide-react");
2310
2317
  var import_jsx_runtime44 = require("react/jsx-runtime");
2311
2318
  function WorkspaceAvatar({ name }) {
2312
2319
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "fds-workspace-avatar", "aria-hidden": "true", children: name.trim().charAt(0).toUpperCase() || "?" });
@@ -2327,7 +2334,7 @@ var WorkspaceSwitcher = (0, import_react21.forwardRef)(function WorkspaceSwitche
2327
2334
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "fds-workspace-switcher__text", "aria-hidden": iconOnly || void 0, children: [
2328
2335
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "fds-workspace-switcher__name", children: name }),
2329
2336
  plan && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "fds-workspace-switcher__plan", children: plan }),
2330
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react5.ChevronDown, { className: "fds-workspace-switcher__chevron", "aria-hidden": "true" })
2337
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react6.ChevronDown, { className: "fds-workspace-switcher__chevron", "aria-hidden": "true" })
2331
2338
  ] })
2332
2339
  ]
2333
2340
  }
@@ -2389,7 +2396,7 @@ function PageHeader({ title, description, leading, meta, breadcrumb, actions, cl
2389
2396
 
2390
2397
  // src/components/Toast/Toast.tsx
2391
2398
  var import_react23 = require("react");
2392
- var import_lucide_react6 = require("lucide-react");
2399
+ var import_lucide_react7 = require("lucide-react");
2393
2400
  var import_jsx_runtime48 = require("react/jsx-runtime");
2394
2401
  function ToastRegion({ className, children, ...rest }) {
2395
2402
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: ["fds-toast-region", className].filter(Boolean).join(" "), "aria-live": "polite", ...rest, children });
@@ -2403,13 +2410,13 @@ function Toast({ children, action, onDismiss, duration, className, ...rest }) {
2403
2410
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { role: "status", className: ["fds-toast", className].filter(Boolean).join(" "), ...rest, children: [
2404
2411
  /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "fds-toast__message", children }),
2405
2412
  action && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: "fds-toast__action", onClick: action.onClick, children: action.label }),
2406
- onDismiss && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: "fds-toast__close", "aria-label": "Dismiss", onClick: onDismiss, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_lucide_react6.X, { "aria-hidden": "true" }) })
2413
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: "fds-toast__close", "aria-label": "Dismiss", onClick: onDismiss, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_lucide_react7.X, { "aria-hidden": "true" }) })
2407
2414
  ] });
2408
2415
  }
2409
2416
 
2410
2417
  // src/components/Stepper/Stepper.tsx
2411
2418
  var import_react24 = require("react");
2412
- var import_lucide_react7 = require("lucide-react");
2419
+ var import_lucide_react8 = require("lucide-react");
2413
2420
  var import_jsx_runtime49 = require("react/jsx-runtime");
2414
2421
  function StepperStep(_) {
2415
2422
  return null;
@@ -2424,7 +2431,7 @@ function StepperRoot({ className, children, ...rest }) {
2424
2431
  className: `fds-stepper__step fds-stepper__step--${status}`,
2425
2432
  "aria-current": status === "current" ? "step" : void 0,
2426
2433
  children: [
2427
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "fds-stepper__marker", "aria-hidden": "true", children: status === "done" ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react7.Check, {}) : i + 1 }),
2434
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "fds-stepper__marker", "aria-hidden": "true", children: status === "done" ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react8.Check, {}) : i + 1 }),
2428
2435
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "fds-stepper__label", children: label })
2429
2436
  ]
2430
2437
  },
@@ -2473,7 +2480,7 @@ function OptionRow({ control = "radio", title, description, meta, className, che
2473
2480
  var OptionList = Object.assign(OptionListRoot, { Label: OptionListLabel, Row: OptionRow });
2474
2481
 
2475
2482
  // src/components/Checklist/Checklist.tsx
2476
- var import_lucide_react8 = require("lucide-react");
2483
+ var import_lucide_react9 = require("lucide-react");
2477
2484
  var import_jsx_runtime52 = require("react/jsx-runtime");
2478
2485
  function ChecklistRoot({ title, className, children, ...rest }) {
2479
2486
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("section", { className: ["fds-checklist", className].filter(Boolean).join(" "), ...rest, children: [
@@ -2483,7 +2490,7 @@ function ChecklistRoot({ title, className, children, ...rest }) {
2483
2490
  }
2484
2491
  function ChecklistItem({ done, label, value }) {
2485
2492
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("li", { className: ["fds-checklist__item", done ? "fds-checklist__item--done" : ""].filter(Boolean).join(" "), children: [
2486
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "fds-checklist__mark", "aria-hidden": "true", children: done && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_lucide_react8.Check, {}) }),
2493
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "fds-checklist__mark", "aria-hidden": "true", children: done && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_lucide_react9.Check, {}) }),
2487
2494
  /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { className: "fds-checklist__text", children: [
2488
2495
  /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "fds-checklist__label", children: label }),
2489
2496
  /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "fds-checklist__value", children: value })
@@ -2495,7 +2502,7 @@ var Checklist = Object.assign(ChecklistRoot, { Item: ChecklistItem });
2495
2502
  // src/components/Drawer/Drawer.tsx
2496
2503
  var import_react26 = require("react");
2497
2504
  var import_react_dom3 = require("react-dom");
2498
- var import_lucide_react9 = require("lucide-react");
2505
+ var import_lucide_react10 = require("lucide-react");
2499
2506
  var import_jsx_runtime53 = require("react/jsx-runtime");
2500
2507
  var FOCUSABLE2 = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
2501
2508
  function Drawer({ open, onClose, title, description, children, footer, dismissible = true }) {
@@ -2565,7 +2572,7 @@ function Drawer({ open, onClose, title, description, children, footer, dismissib
2565
2572
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h2", { id: titleId, className: "fds-drawer__title", children: title }),
2566
2573
  description != null && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { id: descriptionId, className: "fds-drawer__description", children: description })
2567
2574
  ] }),
2568
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("button", { type: "button", className: "fds-drawer__close", onClick: onClose, disabled: !dismissible, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react9.X, { "aria-hidden": "true" }) })
2575
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("button", { type: "button", className: "fds-drawer__close", onClick: onClose, disabled: !dismissible, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react10.X, { "aria-hidden": "true" }) })
2569
2576
  ] }),
2570
2577
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "fds-drawer__body", children }),
2571
2578
  footer != null && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("footer", { className: "fds-drawer__footer", children: footer })
@@ -2908,6 +2915,59 @@ function Meter({ value, max, label, className, ...rest }) {
2908
2915
  /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "fds-meter__label", children: label })
2909
2916
  ] });
2910
2917
  }
2918
+
2919
+ // src/components/ConnectionCard/ConnectionCard.tsx
2920
+ var import_jsx_runtime69 = require("react/jsx-runtime");
2921
+ function ConnectionCard({ icon, iconTone = "light", title, subtitle, footer, className, children, ...rest }) {
2922
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("section", { className: ["fds-connection-card", className].filter(Boolean).join(" "), ...rest, children: [
2923
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("header", { className: "fds-connection-card__head", children: [
2924
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: `fds-connection-card__icon fds-connection-card__icon--${iconTone}`, "aria-hidden": "true", children: icon }),
2925
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { className: "fds-connection-card__titles", children: [
2926
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "fds-connection-card__title", children: title }),
2927
+ subtitle != null && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "fds-connection-card__subtitle", children: subtitle })
2928
+ ] })
2929
+ ] }),
2930
+ children != null && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "fds-connection-card__body", children }),
2931
+ footer != null && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("footer", { className: "fds-connection-card__footer", children: footer })
2932
+ ] });
2933
+ }
2934
+
2935
+ // src/components/ListRow/ListRow.tsx
2936
+ var import_lucide_react11 = require("lucide-react");
2937
+ var import_jsx_runtime70 = require("react/jsx-runtime");
2938
+ function ListRow({ as, leading, title, description, trailing, className, ...rest }) {
2939
+ const Root = as ?? "button";
2940
+ const extra = Root === "button" ? { type: "button" } : {};
2941
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Root, { className: ["fds-list-row", className].filter(Boolean).join(" "), ...extra, ...rest, children: [
2942
+ leading != null && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "fds-list-row__leading", children: leading }),
2943
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("span", { className: "fds-list-row__text", children: [
2944
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "fds-list-row__title", children: title }),
2945
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "fds-list-row__description", children: description })
2946
+ ] }),
2947
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "fds-list-row__trailing", "aria-hidden": trailing == null || void 0, children: trailing ?? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_lucide_react11.ChevronRight, {}) })
2948
+ ] });
2949
+ }
2950
+
2951
+ // src/components/CodeBlock/CodeBlock.tsx
2952
+ var import_react28 = require("react");
2953
+ var import_lucide_react12 = require("lucide-react");
2954
+ var import_jsx_runtime71 = require("react/jsx-runtime");
2955
+ function CodeBlock({ code, copyLabel = "Copy", variant = "inline", className, ...rest }) {
2956
+ const [copied, setCopied] = (0, import_react28.useState)(false);
2957
+ (0, import_react28.useEffect)(() => {
2958
+ if (!copied) return;
2959
+ const t = window.setTimeout(() => setCopied(false), 1600);
2960
+ return () => window.clearTimeout(t);
2961
+ }, [copied]);
2962
+ const copy = () => {
2963
+ void navigator.clipboard?.writeText(code).then(() => setCopied(true), () => {
2964
+ });
2965
+ };
2966
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: ["fds-code-block", `fds-code-block--${variant}`, className].filter(Boolean).join(" "), ...rest, children: [
2967
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("pre", { className: "fds-code-block__code", children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("code", { children: code }) }),
2968
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { type: "button", className: "fds-code-block__copy", "aria-label": copied ? "Copied" : copyLabel, onClick: copy, children: copied ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react12.Check, { "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_lucide_react12.Copy, { "aria-hidden": "true" }) })
2969
+ ] });
2970
+ }
2911
2971
  // Annotate the CommonJS export names for ESM import in node:
2912
2972
  0 && (module.exports = {
2913
2973
  Accordion,
@@ -2923,7 +2983,9 @@ function Meter({ value, max, label, className, ...rest }) {
2923
2983
  Card,
2924
2984
  Checkbox,
2925
2985
  Checklist,
2986
+ CodeBlock,
2926
2987
  ColorRamp,
2988
+ ConnectionCard,
2927
2989
  DescriptionList,
2928
2990
  DiffPropertyList,
2929
2991
  DiffSection,
@@ -2936,6 +2998,7 @@ function Meter({ value, max, label, className, ...rest }) {
2936
2998
  Input,
2937
2999
  ListCard,
2938
3000
  ListLabel,
3001
+ ListRow,
2939
3002
  MeasureList,
2940
3003
  Menu,
2941
3004
  Meter,
package/dist/index.css CHANGED
@@ -2271,6 +2271,32 @@
2271
2271
  justify-content: center;
2272
2272
  }
2273
2273
  }
2274
+ .fds-callout__dismiss {
2275
+ display: inline-flex;
2276
+ align-items: center;
2277
+ justify-content: center;
2278
+ flex-shrink: 0;
2279
+ width: 28px;
2280
+ height: 28px;
2281
+ padding: 0;
2282
+ border: 0;
2283
+ border-radius: var(--radius-md, 6px);
2284
+ background: transparent;
2285
+ color: var(--color-text-tertiary, #737373);
2286
+ cursor: pointer;
2287
+ }
2288
+ .fds-callout__dismiss:hover {
2289
+ background: var(--color-black-alpha-4, rgba(0, 0, 0, 0.04));
2290
+ color: var(--color-text, #171717);
2291
+ }
2292
+ .fds-callout__dismiss:focus-visible {
2293
+ outline: 2px solid var(--color-border-focus, #171717);
2294
+ outline-offset: 2px;
2295
+ }
2296
+ .fds-callout__dismiss > svg {
2297
+ width: 16px;
2298
+ height: 16px;
2299
+ }
2274
2300
  .fds-callout--neutral {
2275
2301
  --fds-callout-bg: var(--color-surface-subtle, #fafafa);
2276
2302
  --fds-callout-border: var(--color-border, #e5e5e5);
@@ -5435,3 +5461,216 @@ button.fds-preview-card {
5435
5461
  line-height: var(--line-height-text-xs, 18px);
5436
5462
  color: var(--color-text-tertiary, #737373);
5437
5463
  }
5464
+
5465
+ /* src/components/ConnectionCard/connection-card.css */
5466
+ .fds-connection-card {
5467
+ display: flex;
5468
+ flex-direction: column;
5469
+ gap: var(--spacing-4, 16px);
5470
+ min-width: 0;
5471
+ padding: var(--spacing-4, 16px);
5472
+ border: 1px solid var(--color-border, #e5e5e5);
5473
+ border-radius: var(--radius-xl, 12px);
5474
+ background: var(--color-surface-raised, #ffffff);
5475
+ font-family: var(--font-body, "Rethink Sans", system-ui, sans-serif);
5476
+ color: var(--color-text, #171717);
5477
+ }
5478
+ .fds-connection-card__head {
5479
+ display: flex;
5480
+ align-items: center;
5481
+ gap: var(--spacing-3, 12px);
5482
+ }
5483
+ .fds-connection-card__icon {
5484
+ display: inline-flex;
5485
+ align-items: center;
5486
+ justify-content: center;
5487
+ flex-shrink: 0;
5488
+ width: 36px;
5489
+ height: 36px;
5490
+ border: 1px solid var(--color-border, #e5e5e5);
5491
+ border-radius: var(--radius-lg, 8px);
5492
+ background: var(--color-surface-raised, #ffffff);
5493
+ }
5494
+ .fds-connection-card__icon--dark {
5495
+ border-color: var(--color-primary, #171717);
5496
+ background: var(--color-primary, #171717);
5497
+ color: var(--color-primary-text, #ffffff);
5498
+ }
5499
+ .fds-connection-card__icon > svg {
5500
+ width: 20px;
5501
+ height: 20px;
5502
+ }
5503
+ .fds-connection-card__titles {
5504
+ display: flex;
5505
+ flex-direction: column;
5506
+ min-width: 0;
5507
+ }
5508
+ .fds-connection-card__title {
5509
+ font-size: var(--font-size-text-sm, 14px);
5510
+ line-height: var(--line-height-text-compact, 20px);
5511
+ font-weight: var(--font-weight-semibold, 600);
5512
+ }
5513
+ .fds-connection-card__subtitle {
5514
+ font-size: var(--font-size-text-xs, 12px);
5515
+ line-height: var(--line-height-text-xs, 18px);
5516
+ color: var(--color-text-tertiary, #737373);
5517
+ }
5518
+ .fds-connection-card__body {
5519
+ display: flex;
5520
+ flex-direction: column;
5521
+ gap: var(--spacing-2, 8px);
5522
+ flex: 1;
5523
+ min-width: 0;
5524
+ font-size: var(--font-size-text-xs, 12px);
5525
+ line-height: var(--line-height-text-xs, 18px);
5526
+ color: var(--color-text-tertiary, #737373);
5527
+ }
5528
+ .fds-connection-card__body strong {
5529
+ font-size: var(--font-size-text-compact, 13px);
5530
+ font-weight: var(--font-weight-semibold, 600);
5531
+ color: var(--color-text, #171717);
5532
+ }
5533
+ .fds-connection-card__body code {
5534
+ font-family: var(--font-mono, "JetBrains Mono", monospace);
5535
+ color: var(--color-text, #171717);
5536
+ overflow-wrap: anywhere;
5537
+ }
5538
+ .fds-connection-card__footer {
5539
+ display: flex;
5540
+ align-items: center;
5541
+ gap: var(--spacing-2, 8px);
5542
+ flex-wrap: wrap;
5543
+ }
5544
+
5545
+ /* src/components/ListRow/list-row.css */
5546
+ .fds-list-row {
5547
+ display: flex;
5548
+ align-items: center;
5549
+ gap: var(--spacing-3, 12px);
5550
+ width: 100%;
5551
+ min-width: 0;
5552
+ padding: var(--spacing-2, 8px) var(--spacing-3, 12px);
5553
+ border: 0;
5554
+ border-radius: var(--radius-lg, 8px);
5555
+ background: var(--color-surface-subtle, #fafafa);
5556
+ color: var(--color-text, #171717);
5557
+ font-family: var(--font-body, "Rethink Sans", system-ui, sans-serif);
5558
+ text-align: left;
5559
+ text-decoration: none;
5560
+ cursor: pointer;
5561
+ transition: background var(--duration-instant, 80ms) var(--ease-out, ease-out);
5562
+ }
5563
+ .fds-list-row:hover {
5564
+ background: var(--color-surface-hover, #f0f0f0);
5565
+ }
5566
+ .fds-list-row:focus-visible {
5567
+ outline: 2px solid var(--color-border-focus, #171717);
5568
+ outline-offset: 2px;
5569
+ }
5570
+ .fds-list-row:disabled {
5571
+ cursor: default;
5572
+ opacity: 0.6;
5573
+ }
5574
+ .fds-list-row__leading {
5575
+ display: inline-flex;
5576
+ flex-shrink: 0;
5577
+ }
5578
+ .fds-list-row__text {
5579
+ display: flex;
5580
+ flex-direction: column;
5581
+ flex: 1;
5582
+ min-width: 0;
5583
+ }
5584
+ .fds-list-row__title {
5585
+ overflow: hidden;
5586
+ text-overflow: ellipsis;
5587
+ white-space: nowrap;
5588
+ font-size: var(--font-size-text-compact, 13px);
5589
+ line-height: var(--line-height-text-compact, 20px);
5590
+ font-weight: var(--font-weight-medium, 500);
5591
+ }
5592
+ .fds-list-row__description {
5593
+ overflow: hidden;
5594
+ text-overflow: ellipsis;
5595
+ white-space: nowrap;
5596
+ font-size: var(--font-size-text-xs, 12px);
5597
+ line-height: var(--line-height-text-xs, 18px);
5598
+ color: var(--color-text-tertiary, #737373);
5599
+ }
5600
+ .fds-list-row__trailing {
5601
+ display: inline-flex;
5602
+ align-items: center;
5603
+ flex-shrink: 0;
5604
+ color: var(--color-text-tertiary, #737373);
5605
+ font-size: var(--font-size-text-xs, 12px);
5606
+ }
5607
+ .fds-list-row__trailing > svg {
5608
+ width: 16px;
5609
+ height: 16px;
5610
+ }
5611
+
5612
+ /* src/components/CodeBlock/code-block.css */
5613
+ .fds-code-block {
5614
+ position: relative;
5615
+ display: flex;
5616
+ align-items: flex-start;
5617
+ gap: var(--spacing-2, 8px);
5618
+ border-radius: var(--radius-lg, 8px);
5619
+ font-family: var(--font-mono, "JetBrains Mono", monospace);
5620
+ font-size: var(--font-size-text-xs, 12px);
5621
+ line-height: var(--line-height-text-xs, 18px);
5622
+ }
5623
+ .fds-code-block--inline {
5624
+ align-items: center;
5625
+ padding: var(--spacing-2, 8px) var(--spacing-2, 8px) var(--spacing-2, 8px) var(--spacing-3, 12px);
5626
+ background: var(--color-primary, #171717);
5627
+ color: var(--color-primary-text, #ffffff);
5628
+ }
5629
+ .fds-code-block--block {
5630
+ padding: var(--spacing-3, 12px);
5631
+ border: 1px solid var(--color-border, #e5e5e5);
5632
+ background: var(--color-surface-subtle, #fafafa);
5633
+ color: var(--color-text, #171717);
5634
+ }
5635
+ .fds-code-block__code {
5636
+ flex: 1;
5637
+ min-width: 0;
5638
+ margin: 0;
5639
+ overflow-x: auto;
5640
+ font: inherit;
5641
+ white-space: pre;
5642
+ }
5643
+ .fds-code-block--inline .fds-code-block__code {
5644
+ white-space: nowrap;
5645
+ }
5646
+ .fds-code-block__copy {
5647
+ display: inline-flex;
5648
+ align-items: center;
5649
+ justify-content: center;
5650
+ flex-shrink: 0;
5651
+ width: 28px;
5652
+ height: 28px;
5653
+ padding: 0;
5654
+ border: 0;
5655
+ border-radius: var(--radius-md, 6px);
5656
+ background: transparent;
5657
+ color: inherit;
5658
+ opacity: 0.7;
5659
+ cursor: pointer;
5660
+ }
5661
+ .fds-code-block__copy:hover {
5662
+ opacity: 1;
5663
+ background: var(--color-white-alpha-10, rgba(255, 255, 255, 0.1));
5664
+ }
5665
+ .fds-code-block--block .fds-code-block__copy:hover {
5666
+ background: var(--color-black-alpha-4, rgba(0, 0, 0, 0.04));
5667
+ }
5668
+ .fds-code-block__copy:focus-visible {
5669
+ outline: 2px solid var(--color-border-focus, #171717);
5670
+ outline-offset: 2px;
5671
+ opacity: 1;
5672
+ }
5673
+ .fds-code-block__copy > svg {
5674
+ width: 14px;
5675
+ height: 14px;
5676
+ }
package/dist/index.d.cts CHANGED
@@ -607,12 +607,16 @@ interface CalloutProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
607
607
  children?: ReactNode;
608
608
  /** Trailing action(s), e.g. a ButtonLink. Moves under the text on phones. */
609
609
  action?: ReactNode;
610
+ /** Shows a close button at the end; `dismissLabel` names it. */
611
+ onDismiss?: () => void;
612
+ /** @default 'Dismiss' */
613
+ dismissLabel?: string;
610
614
  }
611
615
  /**
612
616
  * Fidel design-system Callout: a tinted row that tells the reader something
613
617
  * about the page they are on and, optionally, what to do about it.
614
618
  */
615
- declare function Callout({ tone, icon, title, titleAside, children, action, className, ...rest }: CalloutProps): react.JSX.Element;
619
+ declare function Callout({ tone, icon, title, titleAside, children, action, onDismiss, dismissLabel, className, ...rest }: CalloutProps): react.JSX.Element;
616
620
 
617
621
  type SkeletonShape = 'rect' | 'text' | 'circle';
618
622
  interface SkeletonProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
@@ -994,7 +998,7 @@ interface BrandButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>,
994
998
  /** Fidel design-system BrandButton: the product mark that turns into an action icon on hover or focus. */
995
999
  declare function BrandButton({ mark, hoverIcon, type, className, ...rest }: BrandButtonProps): react.JSX.Element;
996
1000
 
997
- type OwnProps<C extends ElementType> = {
1001
+ type OwnProps$1<C extends ElementType> = {
998
1002
  /** Element or component to render, e.g. a router Link. @default 'a' */
999
1003
  as?: C;
1000
1004
  /** 16px icon before the label. */
@@ -1007,7 +1011,7 @@ type OwnProps<C extends ElementType> = {
1007
1011
  iconOnly?: boolean;
1008
1012
  children: ReactNode;
1009
1013
  };
1010
- type SidebarItemProps<C extends ElementType = 'a'> = OwnProps<C> & Omit<ComponentPropsWithoutRef<C>, keyof OwnProps<C>>;
1014
+ type SidebarItemProps<C extends ElementType = 'a'> = OwnProps$1<C> & Omit<ComponentPropsWithoutRef<C>, keyof OwnProps$1<C>>;
1011
1015
  /** Fidel design-system SidebarItem: one row in a side navigation. */
1012
1016
  declare function SidebarItem<C extends ElementType = 'a'>({ as, icon, leading, active, iconOnly, className, children, ...rest }: SidebarItemProps<C>): react.JSX.Element;
1013
1017
 
@@ -1522,4 +1526,43 @@ interface MeterProps extends HTMLAttributes<HTMLDivElement> {
1522
1526
  /** Fidel design-system Meter: a thin bar showing how much of an allowance is used. */
1523
1527
  declare function Meter({ value, max, label, className, ...rest }: MeterProps): react.JSX.Element;
1524
1528
 
1525
- export { Accordion, type AccordionProps, AppLayout, type AppLayoutProps, AppNav, type AppNavProps, Avatar, AvatarLabelGroup, type AvatarLabelGroupProps, type AvatarProps, type AvatarSize, Badge, type BadgeProps, BrandButton, type BrandButtonProps, 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, Checklist, type ChecklistItemProps, type ChecklistProps, ColorRamp, type ColorRampProps, DescriptionList, type DescriptionListItem, type DescriptionListProps, type DiffElement, type DiffPropertyLine, DiffPropertyList, type DiffPropertyListProps, DiffSection, type DiffSectionProps, Divider, type DividerProps, Drawer, type DrawerProps, EasingCurve, type EasingCurveProps, EmptyState, type EmptyStateProps, type FilterChipOption, FilterChips, type FilterChipsProps, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, Input, type InputProps, ListCard, type ListCardProps, type ListCardRowProps, ListLabel, type ListLabelProps, MeasureList, type MeasureListItem, type MeasureListProps, Menu, type MenuDivider, type MenuEntry, type MenuItem, type MenuLabel, type MenuPlacement, type MenuProps, type MenuSearch, Meter, type MeterProps, MismatchCard, type MismatchCardProps, type MismatchProperty, Modal, type ModalProps, type ModalSize, type ModalTone, MultiSelect, type MultiSelectOption, type MultiSelectProps, NumberedSteps, type NumberedStepsProps, OptionList, type OptionListProps, OptionRow, type OptionRowProps, PageHeader, type PageHeaderProps, PageSkeleton, type PageSkeletonHeaderProps, type PageSkeletonProps, Pagination, type PaginationProps, PreviewCard, type PreviewCardPreviewProps, type PreviewCardProps, type PreviewCardTitleProps, PricingCard, type PricingCardProps, Radio, RadioCard, type RadioCardProps, type RadioProps, ResourceCard, type ResourceCardProps, type ResourceCardStat, SearchInput, type SearchInputProps, SectionHeader, type SectionHeaderProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectOption, type SelectProps, SettingsSection, type SettingsSectionProps, Sidebar, type SidebarBrandProps, SidebarItem, type SidebarItemProps, type SidebarProps, type SidebarSectionProps, type SidebarState, Skeleton, SkeletonGroup, type SkeletonGroupProps, type SkeletonProps, type SkeletonShape, Spinner, type SpinnerProps, Split, type SplitProps, StackedCardsIllustration, Stat, type StatProps, StatusDot, type StatusDotProps, type StatusDotStatus, type Step, StepList, type StepListProps, type StepStatus, Stepper, type StepperProps, type StepperStepProps, type StepperStepStatus, Swatch, SwatchList, type SwatchListItem, type SwatchListProps, type SwatchProps, TabNav, type TabNavProps, Table, type TableColumn, type TableProps, Tag, type TagProps, Tile, type TileProps, Toast, type ToastAction, type ToastProps, ToastRegion, type ToastRegionProps, Toggle, type ToggleProps, type ToggleSize, TokenSample, type TokenSampleProps, type Tone, Tooltip, type TooltipProps, type TooltipSide, TypeSample, type TypeSampleProps, TypeScale, type TypeScaleRowProps, TypeSpecimen, type TypeSpecimenProps, type TypeSpecimenWeight, WorkspaceAvatar, WorkspaceSwitcher, type WorkspaceSwitcherProps, breakpoints, useSidebar };
1529
+ interface ConnectionCardProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
1530
+ /** 20px mark of the service, shown in a 36px tile. */
1531
+ icon: ReactNode;
1532
+ /** `dark` fills the tile, e.g. for a terminal mark. @default 'light' */
1533
+ iconTone?: 'light' | 'dark';
1534
+ title: ReactNode;
1535
+ /** Under the title, e.g. "Shared with Flow" or "Only you". */
1536
+ subtitle?: ReactNode;
1537
+ /** Pinned to the bottom, e.g. Connect or Disconnect. */
1538
+ footer?: ReactNode;
1539
+ }
1540
+ /** Fidel design-system ConnectionCard: one connected service, its state and the action that changes it. */
1541
+ declare function ConnectionCard({ icon, iconTone, title, subtitle, footer, className, children, ...rest }: ConnectionCardProps): react.JSX.Element;
1542
+
1543
+ interface OwnProps<T extends ElementType> {
1544
+ /** Render as a link, e.g. react-router's `Link`. @default 'button' */
1545
+ as?: T;
1546
+ /** Before the text, e.g. an avatar. */
1547
+ leading?: ReactNode;
1548
+ title: ReactNode;
1549
+ description?: ReactNode;
1550
+ /** At the end. @default a chevron */
1551
+ trailing?: ReactNode;
1552
+ }
1553
+ type ListRowProps<T extends ElementType = 'button'> = OwnProps<T> & Omit<ComponentPropsWithoutRef<T>, keyof OwnProps<T> | 'title'>;
1554
+ /** Fidel design-system ListRow: a quiet clickable row that opens something, with a leading mark and a chevron. */
1555
+ declare function ListRow<T extends ElementType = 'button'>({ as, leading, title, description, trailing, className, ...rest }: ListRowProps<T>): react.JSX.Element;
1556
+
1557
+ interface CodeBlockProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
1558
+ /** The text to show and copy. */
1559
+ code: string;
1560
+ /** Names the copy button. @default 'Copy' */
1561
+ copyLabel?: string;
1562
+ /** `inline` is one dark line for a command; `block` keeps line breaks for a file. @default 'inline' */
1563
+ variant?: 'inline' | 'block';
1564
+ }
1565
+ /** Fidel design-system CodeBlock: a command or file in mono with a copy button. */
1566
+ declare function CodeBlock({ code, copyLabel, variant, className, ...rest }: CodeBlockProps): react.JSX.Element;
1567
+
1568
+ export { Accordion, type AccordionProps, AppLayout, type AppLayoutProps, AppNav, type AppNavProps, Avatar, AvatarLabelGroup, type AvatarLabelGroupProps, type AvatarProps, type AvatarSize, Badge, type BadgeProps, BrandButton, type BrandButtonProps, 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, Checklist, type ChecklistItemProps, type ChecklistProps, CodeBlock, type CodeBlockProps, ColorRamp, type ColorRampProps, ConnectionCard, type ConnectionCardProps, DescriptionList, type DescriptionListItem, type DescriptionListProps, type DiffElement, type DiffPropertyLine, DiffPropertyList, type DiffPropertyListProps, DiffSection, type DiffSectionProps, Divider, type DividerProps, Drawer, type DrawerProps, EasingCurve, type EasingCurveProps, EmptyState, type EmptyStateProps, type FilterChipOption, FilterChips, type FilterChipsProps, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, Input, type InputProps, ListCard, type ListCardProps, type ListCardRowProps, ListLabel, type ListLabelProps, ListRow, type ListRowProps, MeasureList, type MeasureListItem, type MeasureListProps, Menu, type MenuDivider, type MenuEntry, type MenuItem, type MenuLabel, type MenuPlacement, type MenuProps, type MenuSearch, Meter, type MeterProps, MismatchCard, type MismatchCardProps, type MismatchProperty, Modal, type ModalProps, type ModalSize, type ModalTone, MultiSelect, type MultiSelectOption, type MultiSelectProps, NumberedSteps, type NumberedStepsProps, OptionList, type OptionListProps, OptionRow, type OptionRowProps, PageHeader, type PageHeaderProps, PageSkeleton, type PageSkeletonHeaderProps, type PageSkeletonProps, Pagination, type PaginationProps, PreviewCard, type PreviewCardPreviewProps, type PreviewCardProps, type PreviewCardTitleProps, PricingCard, type PricingCardProps, Radio, RadioCard, type RadioCardProps, type RadioProps, ResourceCard, type ResourceCardProps, type ResourceCardStat, SearchInput, type SearchInputProps, SectionHeader, type SectionHeaderProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectOption, type SelectProps, SettingsSection, type SettingsSectionProps, Sidebar, type SidebarBrandProps, SidebarItem, type SidebarItemProps, type SidebarProps, type SidebarSectionProps, type SidebarState, Skeleton, SkeletonGroup, type SkeletonGroupProps, type SkeletonProps, type SkeletonShape, Spinner, type SpinnerProps, Split, type SplitProps, StackedCardsIllustration, Stat, type StatProps, StatusDot, type StatusDotProps, type StatusDotStatus, type Step, StepList, type StepListProps, type StepStatus, Stepper, type StepperProps, type StepperStepProps, type StepperStepStatus, Swatch, SwatchList, type SwatchListItem, type SwatchListProps, type SwatchProps, TabNav, type TabNavProps, Table, type TableColumn, type TableProps, Tag, type TagProps, Tile, type TileProps, Toast, type ToastAction, type ToastProps, ToastRegion, type ToastRegionProps, Toggle, type ToggleProps, type ToggleSize, TokenSample, type TokenSampleProps, type Tone, Tooltip, type TooltipProps, type TooltipSide, TypeSample, type TypeSampleProps, TypeScale, type TypeScaleRowProps, TypeSpecimen, type TypeSpecimenProps, type TypeSpecimenWeight, WorkspaceAvatar, WorkspaceSwitcher, type WorkspaceSwitcherProps, breakpoints, useSidebar };
package/dist/index.d.ts CHANGED
@@ -607,12 +607,16 @@ interface CalloutProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
607
607
  children?: ReactNode;
608
608
  /** Trailing action(s), e.g. a ButtonLink. Moves under the text on phones. */
609
609
  action?: ReactNode;
610
+ /** Shows a close button at the end; `dismissLabel` names it. */
611
+ onDismiss?: () => void;
612
+ /** @default 'Dismiss' */
613
+ dismissLabel?: string;
610
614
  }
611
615
  /**
612
616
  * Fidel design-system Callout: a tinted row that tells the reader something
613
617
  * about the page they are on and, optionally, what to do about it.
614
618
  */
615
- declare function Callout({ tone, icon, title, titleAside, children, action, className, ...rest }: CalloutProps): react.JSX.Element;
619
+ declare function Callout({ tone, icon, title, titleAside, children, action, onDismiss, dismissLabel, className, ...rest }: CalloutProps): react.JSX.Element;
616
620
 
617
621
  type SkeletonShape = 'rect' | 'text' | 'circle';
618
622
  interface SkeletonProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
@@ -994,7 +998,7 @@ interface BrandButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>,
994
998
  /** Fidel design-system BrandButton: the product mark that turns into an action icon on hover or focus. */
995
999
  declare function BrandButton({ mark, hoverIcon, type, className, ...rest }: BrandButtonProps): react.JSX.Element;
996
1000
 
997
- type OwnProps<C extends ElementType> = {
1001
+ type OwnProps$1<C extends ElementType> = {
998
1002
  /** Element or component to render, e.g. a router Link. @default 'a' */
999
1003
  as?: C;
1000
1004
  /** 16px icon before the label. */
@@ -1007,7 +1011,7 @@ type OwnProps<C extends ElementType> = {
1007
1011
  iconOnly?: boolean;
1008
1012
  children: ReactNode;
1009
1013
  };
1010
- type SidebarItemProps<C extends ElementType = 'a'> = OwnProps<C> & Omit<ComponentPropsWithoutRef<C>, keyof OwnProps<C>>;
1014
+ type SidebarItemProps<C extends ElementType = 'a'> = OwnProps$1<C> & Omit<ComponentPropsWithoutRef<C>, keyof OwnProps$1<C>>;
1011
1015
  /** Fidel design-system SidebarItem: one row in a side navigation. */
1012
1016
  declare function SidebarItem<C extends ElementType = 'a'>({ as, icon, leading, active, iconOnly, className, children, ...rest }: SidebarItemProps<C>): react.JSX.Element;
1013
1017
 
@@ -1522,4 +1526,43 @@ interface MeterProps extends HTMLAttributes<HTMLDivElement> {
1522
1526
  /** Fidel design-system Meter: a thin bar showing how much of an allowance is used. */
1523
1527
  declare function Meter({ value, max, label, className, ...rest }: MeterProps): react.JSX.Element;
1524
1528
 
1525
- export { Accordion, type AccordionProps, AppLayout, type AppLayoutProps, AppNav, type AppNavProps, Avatar, AvatarLabelGroup, type AvatarLabelGroupProps, type AvatarProps, type AvatarSize, Badge, type BadgeProps, BrandButton, type BrandButtonProps, 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, Checklist, type ChecklistItemProps, type ChecklistProps, ColorRamp, type ColorRampProps, DescriptionList, type DescriptionListItem, type DescriptionListProps, type DiffElement, type DiffPropertyLine, DiffPropertyList, type DiffPropertyListProps, DiffSection, type DiffSectionProps, Divider, type DividerProps, Drawer, type DrawerProps, EasingCurve, type EasingCurveProps, EmptyState, type EmptyStateProps, type FilterChipOption, FilterChips, type FilterChipsProps, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, Input, type InputProps, ListCard, type ListCardProps, type ListCardRowProps, ListLabel, type ListLabelProps, MeasureList, type MeasureListItem, type MeasureListProps, Menu, type MenuDivider, type MenuEntry, type MenuItem, type MenuLabel, type MenuPlacement, type MenuProps, type MenuSearch, Meter, type MeterProps, MismatchCard, type MismatchCardProps, type MismatchProperty, Modal, type ModalProps, type ModalSize, type ModalTone, MultiSelect, type MultiSelectOption, type MultiSelectProps, NumberedSteps, type NumberedStepsProps, OptionList, type OptionListProps, OptionRow, type OptionRowProps, PageHeader, type PageHeaderProps, PageSkeleton, type PageSkeletonHeaderProps, type PageSkeletonProps, Pagination, type PaginationProps, PreviewCard, type PreviewCardPreviewProps, type PreviewCardProps, type PreviewCardTitleProps, PricingCard, type PricingCardProps, Radio, RadioCard, type RadioCardProps, type RadioProps, ResourceCard, type ResourceCardProps, type ResourceCardStat, SearchInput, type SearchInputProps, SectionHeader, type SectionHeaderProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectOption, type SelectProps, SettingsSection, type SettingsSectionProps, Sidebar, type SidebarBrandProps, SidebarItem, type SidebarItemProps, type SidebarProps, type SidebarSectionProps, type SidebarState, Skeleton, SkeletonGroup, type SkeletonGroupProps, type SkeletonProps, type SkeletonShape, Spinner, type SpinnerProps, Split, type SplitProps, StackedCardsIllustration, Stat, type StatProps, StatusDot, type StatusDotProps, type StatusDotStatus, type Step, StepList, type StepListProps, type StepStatus, Stepper, type StepperProps, type StepperStepProps, type StepperStepStatus, Swatch, SwatchList, type SwatchListItem, type SwatchListProps, type SwatchProps, TabNav, type TabNavProps, Table, type TableColumn, type TableProps, Tag, type TagProps, Tile, type TileProps, Toast, type ToastAction, type ToastProps, ToastRegion, type ToastRegionProps, Toggle, type ToggleProps, type ToggleSize, TokenSample, type TokenSampleProps, type Tone, Tooltip, type TooltipProps, type TooltipSide, TypeSample, type TypeSampleProps, TypeScale, type TypeScaleRowProps, TypeSpecimen, type TypeSpecimenProps, type TypeSpecimenWeight, WorkspaceAvatar, WorkspaceSwitcher, type WorkspaceSwitcherProps, breakpoints, useSidebar };
1529
+ interface ConnectionCardProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
1530
+ /** 20px mark of the service, shown in a 36px tile. */
1531
+ icon: ReactNode;
1532
+ /** `dark` fills the tile, e.g. for a terminal mark. @default 'light' */
1533
+ iconTone?: 'light' | 'dark';
1534
+ title: ReactNode;
1535
+ /** Under the title, e.g. "Shared with Flow" or "Only you". */
1536
+ subtitle?: ReactNode;
1537
+ /** Pinned to the bottom, e.g. Connect or Disconnect. */
1538
+ footer?: ReactNode;
1539
+ }
1540
+ /** Fidel design-system ConnectionCard: one connected service, its state and the action that changes it. */
1541
+ declare function ConnectionCard({ icon, iconTone, title, subtitle, footer, className, children, ...rest }: ConnectionCardProps): react.JSX.Element;
1542
+
1543
+ interface OwnProps<T extends ElementType> {
1544
+ /** Render as a link, e.g. react-router's `Link`. @default 'button' */
1545
+ as?: T;
1546
+ /** Before the text, e.g. an avatar. */
1547
+ leading?: ReactNode;
1548
+ title: ReactNode;
1549
+ description?: ReactNode;
1550
+ /** At the end. @default a chevron */
1551
+ trailing?: ReactNode;
1552
+ }
1553
+ type ListRowProps<T extends ElementType = 'button'> = OwnProps<T> & Omit<ComponentPropsWithoutRef<T>, keyof OwnProps<T> | 'title'>;
1554
+ /** Fidel design-system ListRow: a quiet clickable row that opens something, with a leading mark and a chevron. */
1555
+ declare function ListRow<T extends ElementType = 'button'>({ as, leading, title, description, trailing, className, ...rest }: ListRowProps<T>): react.JSX.Element;
1556
+
1557
+ interface CodeBlockProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
1558
+ /** The text to show and copy. */
1559
+ code: string;
1560
+ /** Names the copy button. @default 'Copy' */
1561
+ copyLabel?: string;
1562
+ /** `inline` is one dark line for a command; `block` keeps line breaks for a file. @default 'inline' */
1563
+ variant?: 'inline' | 'block';
1564
+ }
1565
+ /** Fidel design-system CodeBlock: a command or file in mono with a copy button. */
1566
+ declare function CodeBlock({ code, copyLabel, variant, className, ...rest }: CodeBlockProps): react.JSX.Element;
1567
+
1568
+ export { Accordion, type AccordionProps, AppLayout, type AppLayoutProps, AppNav, type AppNavProps, Avatar, AvatarLabelGroup, type AvatarLabelGroupProps, type AvatarProps, type AvatarSize, Badge, type BadgeProps, BrandButton, type BrandButtonProps, 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, Checklist, type ChecklistItemProps, type ChecklistProps, CodeBlock, type CodeBlockProps, ColorRamp, type ColorRampProps, ConnectionCard, type ConnectionCardProps, DescriptionList, type DescriptionListItem, type DescriptionListProps, type DiffElement, type DiffPropertyLine, DiffPropertyList, type DiffPropertyListProps, DiffSection, type DiffSectionProps, Divider, type DividerProps, Drawer, type DrawerProps, EasingCurve, type EasingCurveProps, EmptyState, type EmptyStateProps, type FilterChipOption, FilterChips, type FilterChipsProps, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, Input, type InputProps, ListCard, type ListCardProps, type ListCardRowProps, ListLabel, type ListLabelProps, ListRow, type ListRowProps, MeasureList, type MeasureListItem, type MeasureListProps, Menu, type MenuDivider, type MenuEntry, type MenuItem, type MenuLabel, type MenuPlacement, type MenuProps, type MenuSearch, Meter, type MeterProps, MismatchCard, type MismatchCardProps, type MismatchProperty, Modal, type ModalProps, type ModalSize, type ModalTone, MultiSelect, type MultiSelectOption, type MultiSelectProps, NumberedSteps, type NumberedStepsProps, OptionList, type OptionListProps, OptionRow, type OptionRowProps, PageHeader, type PageHeaderProps, PageSkeleton, type PageSkeletonHeaderProps, type PageSkeletonProps, Pagination, type PaginationProps, PreviewCard, type PreviewCardPreviewProps, type PreviewCardProps, type PreviewCardTitleProps, PricingCard, type PricingCardProps, Radio, RadioCard, type RadioCardProps, type RadioProps, ResourceCard, type ResourceCardProps, type ResourceCardStat, SearchInput, type SearchInputProps, SectionHeader, type SectionHeaderProps, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectOption, type SelectProps, SettingsSection, type SettingsSectionProps, Sidebar, type SidebarBrandProps, SidebarItem, type SidebarItemProps, type SidebarProps, type SidebarSectionProps, type SidebarState, Skeleton, SkeletonGroup, type SkeletonGroupProps, type SkeletonProps, type SkeletonShape, Spinner, type SpinnerProps, Split, type SplitProps, StackedCardsIllustration, Stat, type StatProps, StatusDot, type StatusDotProps, type StatusDotStatus, type Step, StepList, type StepListProps, type StepStatus, Stepper, type StepperProps, type StepperStepProps, type StepperStepStatus, Swatch, SwatchList, type SwatchListItem, type SwatchListProps, type SwatchProps, TabNav, type TabNavProps, Table, type TableColumn, type TableProps, Tag, type TagProps, Tile, type TileProps, Toast, type ToastAction, type ToastProps, ToastRegion, type ToastRegionProps, Toggle, type ToggleProps, type ToggleSize, TokenSample, type TokenSampleProps, type Tone, Tooltip, type TooltipProps, type TooltipSide, TypeSample, type TypeSampleProps, TypeScale, type TypeScaleRowProps, TypeSpecimen, type TypeSpecimenProps, type TypeSpecimenWeight, WorkspaceAvatar, WorkspaceSwitcher, type WorkspaceSwitcherProps, breakpoints, useSidebar };
package/dist/index.js CHANGED
@@ -1297,6 +1297,7 @@ function StackedCardsIllustration({ className }) {
1297
1297
  }
1298
1298
 
1299
1299
  // src/components/Callout/Callout.tsx
1300
+ import { X as X2 } from "lucide-react";
1300
1301
  import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
1301
1302
  function Callout({
1302
1303
  tone = "neutral",
@@ -1305,6 +1306,8 @@ function Callout({
1305
1306
  titleAside,
1306
1307
  children,
1307
1308
  action,
1309
+ onDismiss,
1310
+ dismissLabel = "Dismiss",
1308
1311
  className,
1309
1312
  ...rest
1310
1313
  }) {
@@ -1318,7 +1321,8 @@ function Callout({
1318
1321
  ] }),
1319
1322
  children != null && /* @__PURE__ */ jsx21("div", { className: "fds-callout__text", children })
1320
1323
  ] }),
1321
- action != null && /* @__PURE__ */ jsx21("div", { className: "fds-callout__action", children: action })
1324
+ action != null && /* @__PURE__ */ jsx21("div", { className: "fds-callout__action", children: action }),
1325
+ onDismiss && /* @__PURE__ */ jsx21("button", { type: "button", className: "fds-callout__dismiss", "aria-label": dismissLabel, onClick: onDismiss, children: /* @__PURE__ */ jsx21(X2, { "aria-hidden": "true" }) })
1322
1326
  ] });
1323
1327
  }
1324
1328
 
@@ -2319,7 +2323,7 @@ function PageHeader({ title, description, leading, meta, breadcrumb, actions, cl
2319
2323
 
2320
2324
  // src/components/Toast/Toast.tsx
2321
2325
  import { useEffect as useEffect9 } from "react";
2322
- import { X as X2 } from "lucide-react";
2326
+ import { X as X3 } from "lucide-react";
2323
2327
  import { jsx as jsx48, jsxs as jsxs39 } from "react/jsx-runtime";
2324
2328
  function ToastRegion({ className, children, ...rest }) {
2325
2329
  return /* @__PURE__ */ jsx48("div", { className: ["fds-toast-region", className].filter(Boolean).join(" "), "aria-live": "polite", ...rest, children });
@@ -2333,7 +2337,7 @@ function Toast({ children, action, onDismiss, duration, className, ...rest }) {
2333
2337
  return /* @__PURE__ */ jsxs39("div", { role: "status", className: ["fds-toast", className].filter(Boolean).join(" "), ...rest, children: [
2334
2338
  /* @__PURE__ */ jsx48("span", { className: "fds-toast__message", children }),
2335
2339
  action && /* @__PURE__ */ jsx48("button", { type: "button", className: "fds-toast__action", onClick: action.onClick, children: action.label }),
2336
- onDismiss && /* @__PURE__ */ jsx48("button", { type: "button", className: "fds-toast__close", "aria-label": "Dismiss", onClick: onDismiss, children: /* @__PURE__ */ jsx48(X2, { "aria-hidden": "true" }) })
2340
+ onDismiss && /* @__PURE__ */ jsx48("button", { type: "button", className: "fds-toast__close", "aria-label": "Dismiss", onClick: onDismiss, children: /* @__PURE__ */ jsx48(X3, { "aria-hidden": "true" }) })
2337
2341
  ] });
2338
2342
  }
2339
2343
 
@@ -2425,7 +2429,7 @@ var Checklist = Object.assign(ChecklistRoot, { Item: ChecklistItem });
2425
2429
  // src/components/Drawer/Drawer.tsx
2426
2430
  import { useEffect as useEffect10, useId as useId14, useRef as useRef10 } from "react";
2427
2431
  import { createPortal as createPortal3 } from "react-dom";
2428
- import { X as X3 } from "lucide-react";
2432
+ import { X as X4 } from "lucide-react";
2429
2433
  import { jsx as jsx53, jsxs as jsxs44 } from "react/jsx-runtime";
2430
2434
  var FOCUSABLE2 = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
2431
2435
  function Drawer({ open, onClose, title, description, children, footer, dismissible = true }) {
@@ -2495,7 +2499,7 @@ function Drawer({ open, onClose, title, description, children, footer, dismissib
2495
2499
  /* @__PURE__ */ jsx53("h2", { id: titleId, className: "fds-drawer__title", children: title }),
2496
2500
  description != null && /* @__PURE__ */ jsx53("p", { id: descriptionId, className: "fds-drawer__description", children: description })
2497
2501
  ] }),
2498
- /* @__PURE__ */ jsx53("button", { type: "button", className: "fds-drawer__close", onClick: onClose, disabled: !dismissible, "aria-label": "Close", children: /* @__PURE__ */ jsx53(X3, { "aria-hidden": "true" }) })
2502
+ /* @__PURE__ */ jsx53("button", { type: "button", className: "fds-drawer__close", onClick: onClose, disabled: !dismissible, "aria-label": "Close", children: /* @__PURE__ */ jsx53(X4, { "aria-hidden": "true" }) })
2499
2503
  ] }),
2500
2504
  /* @__PURE__ */ jsx53("div", { className: "fds-drawer__body", children }),
2501
2505
  footer != null && /* @__PURE__ */ jsx53("footer", { className: "fds-drawer__footer", children: footer })
@@ -2838,6 +2842,59 @@ function Meter({ value, max, label, className, ...rest }) {
2838
2842
  /* @__PURE__ */ jsx68("span", { className: "fds-meter__label", children: label })
2839
2843
  ] });
2840
2844
  }
2845
+
2846
+ // src/components/ConnectionCard/ConnectionCard.tsx
2847
+ import { jsx as jsx69, jsxs as jsxs59 } from "react/jsx-runtime";
2848
+ function ConnectionCard({ icon, iconTone = "light", title, subtitle, footer, className, children, ...rest }) {
2849
+ return /* @__PURE__ */ jsxs59("section", { className: ["fds-connection-card", className].filter(Boolean).join(" "), ...rest, children: [
2850
+ /* @__PURE__ */ jsxs59("header", { className: "fds-connection-card__head", children: [
2851
+ /* @__PURE__ */ jsx69("span", { className: `fds-connection-card__icon fds-connection-card__icon--${iconTone}`, "aria-hidden": "true", children: icon }),
2852
+ /* @__PURE__ */ jsxs59("span", { className: "fds-connection-card__titles", children: [
2853
+ /* @__PURE__ */ jsx69("span", { className: "fds-connection-card__title", children: title }),
2854
+ subtitle != null && /* @__PURE__ */ jsx69("span", { className: "fds-connection-card__subtitle", children: subtitle })
2855
+ ] })
2856
+ ] }),
2857
+ children != null && /* @__PURE__ */ jsx69("div", { className: "fds-connection-card__body", children }),
2858
+ footer != null && /* @__PURE__ */ jsx69("footer", { className: "fds-connection-card__footer", children: footer })
2859
+ ] });
2860
+ }
2861
+
2862
+ // src/components/ListRow/ListRow.tsx
2863
+ import { ChevronRight } from "lucide-react";
2864
+ import { jsx as jsx70, jsxs as jsxs60 } from "react/jsx-runtime";
2865
+ function ListRow({ as, leading, title, description, trailing, className, ...rest }) {
2866
+ const Root = as ?? "button";
2867
+ const extra = Root === "button" ? { type: "button" } : {};
2868
+ return /* @__PURE__ */ jsxs60(Root, { className: ["fds-list-row", className].filter(Boolean).join(" "), ...extra, ...rest, children: [
2869
+ leading != null && /* @__PURE__ */ jsx70("span", { className: "fds-list-row__leading", children: leading }),
2870
+ /* @__PURE__ */ jsxs60("span", { className: "fds-list-row__text", children: [
2871
+ /* @__PURE__ */ jsx70("span", { className: "fds-list-row__title", children: title }),
2872
+ description != null && /* @__PURE__ */ jsx70("span", { className: "fds-list-row__description", children: description })
2873
+ ] }),
2874
+ /* @__PURE__ */ jsx70("span", { className: "fds-list-row__trailing", "aria-hidden": trailing == null || void 0, children: trailing ?? /* @__PURE__ */ jsx70(ChevronRight, {}) })
2875
+ ] });
2876
+ }
2877
+
2878
+ // src/components/CodeBlock/CodeBlock.tsx
2879
+ import { useEffect as useEffect11, useState as useState11 } from "react";
2880
+ import { Check as Check4, Copy } from "lucide-react";
2881
+ import { jsx as jsx71, jsxs as jsxs61 } from "react/jsx-runtime";
2882
+ function CodeBlock({ code, copyLabel = "Copy", variant = "inline", className, ...rest }) {
2883
+ const [copied, setCopied] = useState11(false);
2884
+ useEffect11(() => {
2885
+ if (!copied) return;
2886
+ const t = window.setTimeout(() => setCopied(false), 1600);
2887
+ return () => window.clearTimeout(t);
2888
+ }, [copied]);
2889
+ const copy = () => {
2890
+ void navigator.clipboard?.writeText(code).then(() => setCopied(true), () => {
2891
+ });
2892
+ };
2893
+ return /* @__PURE__ */ jsxs61("div", { className: ["fds-code-block", `fds-code-block--${variant}`, className].filter(Boolean).join(" "), ...rest, children: [
2894
+ /* @__PURE__ */ jsx71("pre", { className: "fds-code-block__code", children: /* @__PURE__ */ jsx71("code", { children: code }) }),
2895
+ /* @__PURE__ */ jsx71("button", { type: "button", className: "fds-code-block__copy", "aria-label": copied ? "Copied" : copyLabel, onClick: copy, children: copied ? /* @__PURE__ */ jsx71(Check4, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx71(Copy, { "aria-hidden": "true" }) })
2896
+ ] });
2897
+ }
2841
2898
  export {
2842
2899
  Accordion,
2843
2900
  AppLayout,
@@ -2852,7 +2909,9 @@ export {
2852
2909
  Card,
2853
2910
  Checkbox,
2854
2911
  Checklist,
2912
+ CodeBlock,
2855
2913
  ColorRamp,
2914
+ ConnectionCard,
2856
2915
  DescriptionList,
2857
2916
  DiffPropertyList,
2858
2917
  DiffSection,
@@ -2865,6 +2924,7 @@ export {
2865
2924
  Input,
2866
2925
  ListCard,
2867
2926
  ListLabel,
2927
+ ListRow,
2868
2928
  MeasureList,
2869
2929
  Menu,
2870
2930
  Meter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usefidel/design-system",
3
- "version": "0.27.0",
3
+ "version": "0.28.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",