rift-ds 1.11.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/behaviors/LinkProvider.d.ts +36 -0
  2. package/behaviors/LinkProvider.js +15 -0
  3. package/chat/ChatProvider.d.ts +5 -1
  4. package/chat/ChatProvider.js +11 -1
  5. package/components/AiButton/AiButton.d.ts +7 -0
  6. package/components/AiButton/AiButton.js +4 -1
  7. package/components/AppLayout/AppLayout.d.ts +7 -0
  8. package/components/AppLayout/AppLayout.js +3 -1
  9. package/components/AppSidebar/AppSidebar.d.ts +7 -0
  10. package/components/AppSidebar/AppSidebar.js +8 -3
  11. package/components/BottomNav/BottomNav.d.ts +7 -0
  12. package/components/BottomNav/BottomNav.js +5 -2
  13. package/components/Breadcrumb/Breadcrumb.d.ts +8 -0
  14. package/components/Breadcrumb/Breadcrumb.js +3 -2
  15. package/components/Button/Button.d.ts +7 -0
  16. package/components/Button/Button.js +4 -1
  17. package/components/Card/Card.d.ts +7 -0
  18. package/components/Card/Card.js +4 -1
  19. package/components/CircularButton/CircularButton.d.ts +8 -0
  20. package/components/CircularButton/CircularButton.js +3 -1
  21. package/components/ContactCard/ContactCard.d.ts +7 -0
  22. package/components/ContactCard/ContactCard.js +4 -1
  23. package/components/LinkList/LinkList.d.ts +8 -0
  24. package/components/LinkList/LinkList.js +3 -2
  25. package/components/NavList/NavList.d.ts +7 -0
  26. package/components/NavList/NavList.js +2 -0
  27. package/components/SidebarPanel/SidebarPanel.d.ts +7 -0
  28. package/components/SidebarPanel/SidebarPanel.js +4 -1
  29. package/components/SourceChip/SourceChip.d.ts +7 -0
  30. package/components/SourceChip/SourceChip.js +5 -3
  31. package/components/SourceTrail/SourceTrail.d.ts +7 -0
  32. package/components/SourceTrail/SourceTrail.js +2 -0
  33. package/components/ThreadPanel/ThreadPanel.d.ts +8 -0
  34. package/components/ThreadPanel/ThreadPanel.js +9 -2
  35. package/components/TopAppBar/TopAppBar.d.ts +7 -0
  36. package/components/TopAppBar/TopAppBar.js +4 -1
  37. package/components/Widget/Widget.d.ts +8 -0
  38. package/components/Widget/Widget.js +3 -2
  39. package/package.json +5 -1
  40. package/tokens/presets/mono.css +168 -168
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
3
3
  import React, { useId, useState, useCallback } from "react";
4
+ import { useLinkComponent } from "../../behaviors/LinkProvider.js";
4
5
  import "./SidebarPanel.css";
5
6
  import "../../fonts/material-symbols.css";
6
7
  function groupRuns(items) {
@@ -23,9 +24,11 @@ const SidebarPanel = React.forwardRef(
23
24
  onBack,
24
25
  backLabel = "Back",
25
26
  className = "",
27
+ linkComponent,
26
28
  ...rest
27
29
  }, ref) => {
28
30
  const baseClass = "ds-sidebar-panel";
31
+ const Link = useLinkComponent(linkComponent);
29
32
  const uid = useId();
30
33
  const [openKeys, setOpenKeys] = useState(() => {
31
34
  const initial = new Set(defaultOpenKeys ?? []);
@@ -56,7 +59,7 @@ const SidebarPanel = React.forwardRef(
56
59
  item.badge !== void 0 && /* @__PURE__ */ jsx("span", { className: `${baseClass}__badge`, children: item.badge })
57
60
  ] });
58
61
  return item.href ? /* @__PURE__ */ jsx(
59
- "a",
62
+ Link,
60
63
  {
61
64
  className: classes,
62
65
  href: item.href,
@@ -1,4 +1,5 @@
1
1
  import { default as React } from 'react';
2
+ import { LinkComponent } from '../../behaviors/LinkProvider';
2
3
  /** Props owned by SourceChip itself — everything else falls through to the root element. */
3
4
  type SourceChipOwnProps = {
4
5
  /**
@@ -36,6 +37,12 @@ type SourceChipOwnProps = {
36
37
  meta?: string;
37
38
  /** Additional CSS classes */
38
39
  className?: string;
40
+ /**
41
+ * The component the link renders with, such as Next.js's `Link`, so it
42
+ * navigates through the app's router. Wins over a LinkProvider's; a plain
43
+ * `<a>` when neither is set.
44
+ */
45
+ linkComponent?: LinkComponent;
39
46
  };
40
47
  export interface SourceChipProps extends SourceChipOwnProps, Omit<React.ComponentPropsWithoutRef<'a'>, keyof SourceChipOwnProps> {
41
48
  }
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
3
  import React, { useState, useRef, useId, useEffect, useLayoutEffect } from "react";
4
+ import { useLinkComponent } from "../../behaviors/LinkProvider.js";
4
5
  import { useLayer } from "../../behaviors/useLayer.js";
5
6
  import "./SourceChip.css";
6
7
  import "../../fonts/material-symbols.css";
@@ -23,8 +24,9 @@ function clipBounds(el) {
23
24
  }
24
25
  return bounds;
25
26
  }
26
- const SourceChip = React.forwardRef(({ title, index, icon = "language", href, excerpt, source, logo, meta, className = "", ...rest }, ref) => {
27
+ const SourceChip = React.forwardRef(({ title, index, icon = "language", href, excerpt, source, logo, meta, className = "", linkComponent, ...rest }, ref) => {
27
28
  const baseClass = "ds-source-chip";
29
+ const Link = useLinkComponent(linkComponent);
28
30
  const hasPreview = Boolean(excerpt);
29
31
  const [visible, setVisible] = useState(false);
30
32
  const showTimeoutRef = useRef(void 0);
@@ -103,8 +105,8 @@ const SourceChip = React.forwardRef(({ title, index, icon = "language", href, ex
103
105
  /* @__PURE__ */ jsx("span", { className: `${baseClass}__title`, children: title })
104
106
  ] });
105
107
  const describedBy = hasPreview ? panelId : void 0;
106
- const chip = element === "a" ? /* @__PURE__ */ jsx(
107
- "a",
108
+ const chip = element === "a" && href ? /* @__PURE__ */ jsx(
109
+ Link,
108
110
  {
109
111
  "aria-describedby": describedBy,
110
112
  ...rest,
@@ -1,4 +1,5 @@
1
1
  import { default as React } from 'react';
2
+ import { LinkComponent } from '../../behaviors/LinkProvider';
2
3
  export type SourceTrailStatus = 'pending' | 'active' | 'done';
3
4
  /** One source the agent opened while answering. */
4
5
  export interface SourceTrailItem {
@@ -46,6 +47,12 @@ type SourceTrailOwnProps = {
46
47
  defaultOpen?: boolean;
47
48
  /** Fires whenever the panel opens or closes. */
48
49
  onOpenChange?: (open: boolean) => void;
50
+ /**
51
+ * The component its links render with, such as Next.js's `Link`, so they
52
+ * navigate through the app's router; passed on to each source's SourceChip. Wins over a
53
+ * LinkProvider's; a plain `<a>` when neither is set.
54
+ */
55
+ linkComponent?: LinkComponent;
49
56
  /** Additional CSS classes */
50
57
  className?: string;
51
58
  };
@@ -27,6 +27,7 @@ const SourceTrail = React.forwardRef(
27
27
  open,
28
28
  defaultOpen = true,
29
29
  onOpenChange,
30
+ linkComponent,
30
31
  className = "",
31
32
  ...rest
32
33
  }, ref) => {
@@ -91,6 +92,7 @@ const SourceTrail = React.forwardRef(
91
92
  {
92
93
  title: item.title,
93
94
  href: item.href,
95
+ linkComponent,
94
96
  icon: item.icon,
95
97
  target: item.href ? "_blank" : void 0,
96
98
  rel: item.href ? "noopener noreferrer" : void 0
@@ -1,4 +1,5 @@
1
1
  import { default as React } from 'react';
2
+ import { LinkComponent } from '../../behaviors/LinkProvider';
2
3
  export interface ThreadPanelThreadAction {
3
4
  /** Stable identifier reported through `onThreadAction`. */
4
5
  id: string;
@@ -160,6 +161,13 @@ type ThreadPanelOwnProps = {
160
161
  footerSlot?: React.ReactNode;
161
162
  /** Additional CSS classes */
162
163
  className?: string;
164
+ /**
165
+ * The component its links render with, such as Next.js's `Link`, so they
166
+ * navigate through the app's router; a plain `<a>` when unset. This
167
+ * component can render on the server, so it never reads a LinkProvider:
168
+ * pass the prop even under one.
169
+ */
170
+ linkComponent?: LinkComponent;
163
171
  };
164
172
  export interface ThreadPanelProps extends ThreadPanelOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof ThreadPanelOwnProps> {
165
173
  }
@@ -29,11 +29,12 @@ function ActionRow({
29
29
  onClick,
30
30
  ariaCurrent,
31
31
  title,
32
- children
32
+ children,
33
+ link: Link
33
34
  }) {
34
35
  if (href) {
35
36
  return /* @__PURE__ */ jsx(
36
- "a",
37
+ Link,
37
38
  {
38
39
  className,
39
40
  href,
@@ -145,12 +146,14 @@ const ThreadPanel = React.forwardRef(
145
146
  profile,
146
147
  footerSlot,
147
148
  className = "",
149
+ linkComponent,
148
150
  ...rest
149
151
  }, ref) => {
150
152
  const dotted = groups.some(
151
153
  (group) => group.threads.some((thread) => thread.status || thread.unread)
152
154
  );
153
155
  const labels = { ...DEFAULT_STATUS_LABELS, ...statusLabels };
156
+ const Link = linkComponent ?? "a";
154
157
  const classes = [
155
158
  baseClass,
156
159
  expanded && `${baseClass}--expanded`,
@@ -238,6 +241,7 @@ const ThreadPanel = React.forwardRef(
238
241
  showNew && /* @__PURE__ */ jsxs(
239
242
  ActionRow,
240
243
  {
244
+ link: Link,
241
245
  className: `${baseClass}__new`,
242
246
  href: newThreadHref,
243
247
  onClick: onNewThread,
@@ -258,6 +262,7 @@ const ThreadPanel = React.forwardRef(
258
262
  controls && controls.length > 0 && /* @__PURE__ */ jsx("div", { className: `${baseClass}__controls`, children: controls.map((control) => /* @__PURE__ */ jsxs(
259
263
  ActionRow,
260
264
  {
265
+ link: Link,
261
266
  className: `${baseClass}__control`,
262
267
  href: control.href,
263
268
  onClick: onControlSelect ? () => onControlSelect(control.id) : void 0,
@@ -294,6 +299,7 @@ const ThreadPanel = React.forwardRef(
294
299
  return /* @__PURE__ */ jsx("li", { className: `${baseClass}__row`, children: /* @__PURE__ */ jsxs(
295
300
  ActionRow,
296
301
  {
302
+ link: Link,
297
303
  className: [
298
304
  `${baseClass}__project`,
299
305
  active && `${baseClass}__project--active`
@@ -375,6 +381,7 @@ const ThreadPanel = React.forwardRef(
375
381
  /* @__PURE__ */ jsxs(
376
382
  ActionRow,
377
383
  {
384
+ link: Link,
378
385
  className: [
379
386
  `${baseClass}__thread`,
380
387
  active && `${baseClass}__thread--active`,
@@ -1,4 +1,5 @@
1
1
  import { default as React } from 'react';
2
+ import { LinkComponent } from '../../behaviors/LinkProvider';
2
3
  export interface TopAppBarAction {
3
4
  /** Unique key for this action */
4
5
  key: string;
@@ -76,6 +77,12 @@ type TopAppBarOwnProps = {
76
77
  sticky?: boolean;
77
78
  /** Additional CSS classes */
78
79
  className?: string;
80
+ /**
81
+ * The component its links render with, such as Next.js's `Link`, so they
82
+ * navigate through the app's router. Wins over a LinkProvider's; a plain
83
+ * `<a>` when neither is set.
84
+ */
85
+ linkComponent?: LinkComponent;
79
86
  };
80
87
  export interface TopAppBarProps extends TopAppBarOwnProps, Omit<React.ComponentPropsWithoutRef<'header'>, keyof TopAppBarOwnProps> {
81
88
  }
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
3
3
  import React, { useState, useEffect } from "react";
4
+ import { useLinkComponent } from "../../behaviors/LinkProvider.js";
4
5
  import { DropdownMenu } from "../DropdownMenu/DropdownMenu.js";
5
6
  import "./TopAppBar.css";
6
7
  import "../../fonts/material-symbols.css";
@@ -30,9 +31,11 @@ const TopAppBar = React.forwardRef(
30
31
  headingLevel = 1,
31
32
  sticky = true,
32
33
  className = "",
34
+ linkComponent,
33
35
  ...rest
34
36
  }, ref) => {
35
37
  const baseClass = "ds-top-app-bar";
38
+ const Link = useLinkComponent(linkComponent);
36
39
  const isIos = platform === "ios";
37
40
  const resolvedAlign = align ?? (isIos ? "center" : "start");
38
41
  const expandable = size !== "small";
@@ -68,7 +71,7 @@ const TopAppBar = React.forwardRef(
68
71
  ] });
69
72
  const label = action.badge ? badgeLabel(action.label) : action.label;
70
73
  return action.href ? /* @__PURE__ */ jsx(
71
- "a",
74
+ Link,
72
75
  {
73
76
  className: `${baseClass}__button`,
74
77
  href: action.href,
@@ -1,4 +1,5 @@
1
1
  import { default as React } from 'react';
2
+ import { LinkComponent } from '../../behaviors/LinkProvider';
2
3
  /** Props owned by Widget itself — everything else falls through to the root `<section>`. */
3
4
  type WidgetOwnProps = {
4
5
  /** The tile's heading. Also the section's accessible name, unless an `aria-label` is passed. Note: this shadows the native `title` tooltip attribute, which Widget does not expose. */
@@ -53,6 +54,13 @@ type WidgetRowOwnProps = {
53
54
  href?: string;
54
55
  /** Additional CSS classes */
55
56
  className?: string;
57
+ /**
58
+ * The component its links render with, such as Next.js's `Link`, so they
59
+ * navigate through the app's router; a plain `<a>` when unset. This
60
+ * component can render on the server, so it never reads a LinkProvider:
61
+ * pass the prop even under one.
62
+ */
63
+ linkComponent?: LinkComponent;
56
64
  };
57
65
  export interface WidgetRowProps extends WidgetRowOwnProps, Omit<React.HTMLAttributes<HTMLElement>, keyof WidgetRowOwnProps> {
58
66
  }
@@ -47,8 +47,9 @@ const WidgetGroup = React.forwardRef(
47
47
  );
48
48
  WidgetGroup.displayName = "WidgetGroup";
49
49
  const WidgetRow = React.forwardRef(
50
- ({ title, description, leading, meta, href, className = "", onClick, ...rest }, ref) => {
50
+ ({ title, description, leading, meta, href, className = "", onClick, linkComponent, ...rest }, ref) => {
51
51
  const baseClass = "ds-widget-row";
52
+ const Link = linkComponent ?? "a";
52
53
  const interactive = Boolean(href || onClick);
53
54
  const classes = [baseClass, interactive ? `${baseClass}--interactive` : "", className].filter(Boolean).join(" ");
54
55
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -61,7 +62,7 @@ const WidgetRow = React.forwardRef(
61
62
  ] });
62
63
  if (href) {
63
64
  return /* @__PURE__ */ jsx(
64
- "a",
65
+ Link,
65
66
  {
66
67
  ...rest,
67
68
  ref,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rift-ds",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "An AI-ready React design system: accessible components on composable tokens, light/dark theming, and CSS-variable overrides.",
5
5
  "author": {
6
6
  "name": "Robert Ritacca",
@@ -73,6 +73,10 @@
73
73
  "types": "./behaviors/useScrollLock.d.ts",
74
74
  "import": "./behaviors/useScrollLock.js"
75
75
  },
76
+ "./behaviors/LinkProvider": {
77
+ "types": "./behaviors/LinkProvider.d.ts",
78
+ "import": "./behaviors/LinkProvider.js"
79
+ },
76
80
  "./chat": {
77
81
  "types": "./chat/index.d.ts",
78
82
  "import": "./chat/index.js"