@flamingo-stack/openframe-frontend-core 0.0.360-snapshot.20260702190810 → 0.0.360

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 (113) hide show
  1. package/dist/{chunk-KQXR27VF.cjs → chunk-2GLO2HEJ.cjs} +25 -25
  2. package/dist/{chunk-KQXR27VF.cjs.map → chunk-2GLO2HEJ.cjs.map} +1 -1
  3. package/dist/{chunk-IURUIQGY.js → chunk-2LTQEQWH.js} +2 -2
  4. package/dist/{chunk-7W7C66KK.cjs → chunk-35E52Q3L.cjs} +9 -9
  5. package/dist/{chunk-7W7C66KK.cjs.map → chunk-35E52Q3L.cjs.map} +1 -1
  6. package/dist/{chunk-JREHVZBN.cjs → chunk-4NGPMJK6.cjs} +12 -12
  7. package/dist/{chunk-JREHVZBN.cjs.map → chunk-4NGPMJK6.cjs.map} +1 -1
  8. package/dist/{chunk-2T6BQFJN.js → chunk-5NHJC3GQ.js} +2 -2
  9. package/dist/{chunk-RSBCKRRK.js → chunk-CBVU3DFH.js} +2 -2
  10. package/dist/{chunk-BJ7NV7AO.js → chunk-DNJCIVD6.js} +2 -2
  11. package/dist/{chunk-267JJUAP.js → chunk-E66A6UJC.js} +4 -4
  12. package/dist/{chunk-K6XWRBOV.cjs → chunk-EJSVHG4X.cjs} +5 -5
  13. package/dist/{chunk-K6XWRBOV.cjs.map → chunk-EJSVHG4X.cjs.map} +1 -1
  14. package/dist/{chunk-5B2IOQXZ.js → chunk-KMYPDZEO.js} +3852 -3971
  15. package/dist/chunk-KMYPDZEO.js.map +1 -0
  16. package/dist/{chunk-5WXXFSRE.cjs → chunk-LGQ4L3SX.cjs} +26 -26
  17. package/dist/{chunk-5WXXFSRE.cjs.map → chunk-LGQ4L3SX.cjs.map} +1 -1
  18. package/dist/{chunk-HR4PF6FJ.cjs → chunk-LTALFWHU.cjs} +31 -31
  19. package/dist/{chunk-HR4PF6FJ.cjs.map → chunk-LTALFWHU.cjs.map} +1 -1
  20. package/dist/{chunk-AD2WYDPL.js → chunk-LUEVAFJP.js} +4 -4
  21. package/dist/{chunk-BQFUPAEY.cjs → chunk-MGQVVGQV.cjs} +1058 -1177
  22. package/dist/chunk-MGQVVGQV.cjs.map +1 -0
  23. package/dist/{chunk-MYP4I5B2.js → chunk-QPGENYQV.js} +4 -4
  24. package/dist/{chunk-IOHKIL7O.cjs → chunk-QZ3KUDFG.cjs} +7 -7
  25. package/dist/{chunk-IOHKIL7O.cjs.map → chunk-QZ3KUDFG.cjs.map} +1 -1
  26. package/dist/{chunk-ODDTSUU7.cjs → chunk-TRUNSPFD.cjs} +37 -37
  27. package/dist/{chunk-ODDTSUU7.cjs.map → chunk-TRUNSPFD.cjs.map} +1 -1
  28. package/dist/{chunk-LNXM2OQ6.cjs → chunk-VS4EZRU3.cjs} +62 -62
  29. package/dist/{chunk-LNXM2OQ6.cjs.map → chunk-VS4EZRU3.cjs.map} +1 -1
  30. package/dist/{chunk-OIQEFSO4.js → chunk-XP7M5FPW.js} +2 -2
  31. package/dist/{chunk-BC5I4C5V.js → chunk-XULFRLBZ.js} +2 -2
  32. package/dist/{chunk-QTKCL36K.js → chunk-YA2LLBWQ.js} +2 -2
  33. package/dist/{chunk-27T2PUJZ.js → chunk-YEB3R52B.js} +4 -4
  34. package/dist/{chunk-RPLL2CTZ.cjs → chunk-YUZ25NHF.cjs} +15 -15
  35. package/dist/{chunk-RPLL2CTZ.cjs.map → chunk-YUZ25NHF.cjs.map} +1 -1
  36. package/dist/{chunk-4RXV4UBA.cjs → chunk-ZPY53IWK.cjs} +56 -56
  37. package/dist/{chunk-4RXV4UBA.cjs.map → chunk-ZPY53IWK.cjs.map} +1 -1
  38. package/dist/components/case-studies/index.cjs +8 -8
  39. package/dist/components/case-studies/index.js +2 -2
  40. package/dist/components/chat/chat-quick-action-row.d.ts +1 -4
  41. package/dist/components/chat/chat-quick-action-row.d.ts.map +1 -1
  42. package/dist/components/chat/chat-quick-action.d.ts +0 -6
  43. package/dist/components/chat/chat-quick-action.d.ts.map +1 -1
  44. package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
  45. package/dist/components/chat/guide-welcome.d.ts +0 -3
  46. package/dist/components/chat/guide-welcome.d.ts.map +1 -1
  47. package/dist/components/chat/index.cjs +2 -12
  48. package/dist/components/chat/index.cjs.map +1 -1
  49. package/dist/components/chat/index.d.ts +0 -2
  50. package/dist/components/chat/index.d.ts.map +1 -1
  51. package/dist/components/chat/index.js +1 -11
  52. package/dist/components/chat/mingo-welcome.d.ts.map +1 -1
  53. package/dist/components/contact/index.cjs +3 -3
  54. package/dist/components/contact/index.js +2 -2
  55. package/dist/components/docs/index.cjs +5 -5
  56. package/dist/components/docs/index.js +4 -4
  57. package/dist/components/embeds/index.cjs +3 -3
  58. package/dist/components/embeds/index.js +2 -2
  59. package/dist/components/faq/index.cjs +3 -3
  60. package/dist/components/faq/index.js +2 -2
  61. package/dist/components/features/index.cjs +2 -2
  62. package/dist/components/features/index.js +1 -1
  63. package/dist/components/help-center-pages/index.cjs +20 -20
  64. package/dist/components/help-center-pages/index.js +11 -11
  65. package/dist/components/index.cjs +120 -130
  66. package/dist/components/index.cjs.map +1 -1
  67. package/dist/components/index.js +9 -19
  68. package/dist/components/index.js.map +1 -1
  69. package/dist/components/navigation/index.cjs +2 -2
  70. package/dist/components/navigation/index.js +1 -1
  71. package/dist/components/onboarding-guides/index.cjs +5 -5
  72. package/dist/components/onboarding-guides/index.js +4 -4
  73. package/dist/components/related-content/index.cjs +3 -3
  74. package/dist/components/related-content/index.js +2 -2
  75. package/dist/components/tickets/index.cjs +5 -5
  76. package/dist/components/tickets/index.js +4 -4
  77. package/dist/components/ui/index.cjs +2 -12
  78. package/dist/components/ui/index.cjs.map +1 -1
  79. package/dist/components/ui/index.js +1 -11
  80. package/dist/index.cjs +2 -12
  81. package/dist/index.cjs.map +1 -1
  82. package/dist/index.js +1 -11
  83. package/dist/tailwind.config.cjs +1 -8
  84. package/dist/tailwind.config.cjs.map +1 -1
  85. package/dist/tailwind.config.js +1 -8
  86. package/dist/tailwind.config.js.map +1 -1
  87. package/package.json +1 -1
  88. package/src/components/chat/chat-quick-action-row.tsx +14 -20
  89. package/src/components/chat/chat-quick-action.tsx +0 -6
  90. package/src/components/chat/embeddable-chat.tsx +6 -19
  91. package/src/components/chat/guide-welcome.tsx +9 -15
  92. package/src/components/chat/index.ts +0 -2
  93. package/src/components/chat/mingo-welcome.tsx +12 -7
  94. package/tailwind.config.ts +0 -7
  95. package/dist/chunk-5B2IOQXZ.js.map +0 -1
  96. package/dist/chunk-BQFUPAEY.cjs.map +0 -1
  97. package/dist/components/chat/quick-action-chip.d.ts +0 -70
  98. package/dist/components/chat/quick-action-chip.d.ts.map +0 -1
  99. package/dist/components/chat/quick-action-marquee.d.ts +0 -29
  100. package/dist/components/chat/quick-action-marquee.d.ts.map +0 -1
  101. package/src/components/chat/quick-action-chip.tsx +0 -155
  102. package/src/components/chat/quick-action-marquee.tsx +0 -92
  103. /package/dist/{chunk-IURUIQGY.js.map → chunk-2LTQEQWH.js.map} +0 -0
  104. /package/dist/{chunk-2T6BQFJN.js.map → chunk-5NHJC3GQ.js.map} +0 -0
  105. /package/dist/{chunk-RSBCKRRK.js.map → chunk-CBVU3DFH.js.map} +0 -0
  106. /package/dist/{chunk-BJ7NV7AO.js.map → chunk-DNJCIVD6.js.map} +0 -0
  107. /package/dist/{chunk-267JJUAP.js.map → chunk-E66A6UJC.js.map} +0 -0
  108. /package/dist/{chunk-AD2WYDPL.js.map → chunk-LUEVAFJP.js.map} +0 -0
  109. /package/dist/{chunk-MYP4I5B2.js.map → chunk-QPGENYQV.js.map} +0 -0
  110. /package/dist/{chunk-OIQEFSO4.js.map → chunk-XP7M5FPW.js.map} +0 -0
  111. /package/dist/{chunk-BC5I4C5V.js.map → chunk-XULFRLBZ.js.map} +0 -0
  112. /package/dist/{chunk-QTKCL36K.js.map → chunk-YA2LLBWQ.js.map} +0 -0
  113. /package/dist/{chunk-27T2PUJZ.js.map → chunk-YEB3R52B.js.map} +0 -0
@@ -1,70 +0,0 @@
1
- import * as React from 'react';
2
- import { type EntityIconValue } from '../icon-display';
3
- /** Accent tint for quick-action chip icons: a named brand token
4
- * (`'pink'`/`'cyan'`) or ANY CSS color value coming from admin config
5
- * (agent/persona `icon_props.color`). */
6
- export type QuickActionAccent = 'pink' | 'cyan' | (string & {});
7
- /**
8
- * FALLBACK-ONLY agent→accent mapping (fae→pink, mingo→cyan) for the built-in
9
- * agents when nothing is configured. A color configured on the entity itself —
10
- * the quick action's `iconProps.color`, or the agent/persona identity
11
- * `icon_props.color` — always wins over this map; callers must resolve the
12
- * configured value first and only fall back here. Never re-inline the slug
13
- * comparison elsewhere.
14
- */
15
- export declare function getAgentAccent(slug: string | null | undefined): QuickActionAccent | undefined;
16
- /** Admin-configured identity color (`icon_props.color` on the agent/persona
17
- * row) → chip accent. Undefined when the identity doesn't set one. */
18
- export declare function accentFromIdentityIcon(icon: {
19
- props?: Record<string, unknown> | null;
20
- } | null | undefined): QuickActionAccent | undefined;
21
- /**
22
- * Declarative icon for a quick-action chip, resolved 100% by `<EntityIcon>`
23
- * (url → fae/mingo `AgentMark` → icons-v2 glyph → file fallback):
24
- * - "agent format" — `{ name: 'fae' }` / `{ name: 'mingo' }` renders the
25
- * packaged agent mark (fills the chip's icon box; `accent` is ignored — the
26
- * marks carry their own colors).
27
- * - "config format" — `{ name, url, props, accent }` renders the
28
- * admin-configured icon; `accent` tints registry glyphs via a
29
- * `text-ods-flamingo-*` class on `currentColor`.
30
- *
31
- * If `props.color` is set it wins over `accent` — the accent is a class tint
32
- * on `currentColor`, the prop is an explicit fill (EntityIcon spreads `props`
33
- * onto the glyph last).
34
- */
35
- export interface QuickActionIconSpec extends EntityIconValue {
36
- accent?: QuickActionAccent;
37
- /** Glyph size in px. Defaults to 16 (the chip design's config-icon size);
38
- * agent marks size via the icon box instead. */
39
- size?: number;
40
- }
41
- /** Resolve a chip `icon` prop to a renderable node. Specs go through
42
- * `<EntityIcon>`; ReactNodes pass through untouched. */
43
- export declare function renderQuickActionIcon(icon: React.ReactNode | QuickActionIconSpec | undefined): React.ReactNode;
44
- export interface QuickActionChipButtonProps {
45
- label: React.ReactNode;
46
- /** Icon: a declarative {@link QuickActionIconSpec} (preferred — unified
47
- * EntityIcon resolution) or a pre-rendered ReactNode. */
48
- icon?: React.ReactNode | QuickActionIconSpec;
49
- /** `'primary'` = accent (yellow) chip, `'outline'` = bordered chip (default). */
50
- variant?: 'primary' | 'outline';
51
- onSelect?: () => void;
52
- /** Pointer/keyboard focus enters the chip — e.g. preview the full prompt. */
53
- onHoverStart?: () => void;
54
- /** Pointer/keyboard focus leaves the chip — e.g. restore the composer. */
55
- onHoverEnd?: () => void;
56
- /** `false` renders a plain non-focusable `<Tag>` (decorative use: marquee
57
- * strips, table cells). Default `true`. */
58
- interactive?: boolean;
59
- className?: string;
60
- }
61
- /**
62
- * The unified quick-action chip — Figma chip anatomy (card bg, border, mono
63
- * uppercase label) via the `Tag` outline/primary variants, with icon
64
- * resolution owned by `<EntityIcon>` in two formats (config icon w/ agent
65
- * accent, or fae/mingo agent mark). Used by every chat empty state
66
- * (guide / mingo / ai-agent), the marketing marquee strips, and the ROI
67
- * table task cells.
68
- */
69
- export declare function QuickActionChipButton({ label, icon, variant, onSelect, onHoverStart, onHoverEnd, interactive, className, }: QuickActionChipButtonProps): React.JSX.Element;
70
- //# sourceMappingURL=quick-action-chip.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"quick-action-chip.d.ts","sourceRoot":"","sources":["../../../src/components/chat/quick-action-chip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAMlE;;0CAE0C;AAC1C,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAE/D;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAI7F;AAED;uEACuE;AACvE,wBAAgB,sBAAsB,CACpC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAClE,iBAAiB,GAAG,SAAS,CAG/B;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B;qDACiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAOD;yDACyD;AACzD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,mBAAmB,GAAG,SAAS,GACtD,KAAK,CAAC,SAAS,CAuBjB;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB;8DAC0D;IAC1D,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,mBAAmB,CAAA;IAC5C,iFAAiF;IACjF,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;IAC/B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB;gDAC4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,IAAI,EACJ,OAAmB,EACnB,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,WAAkB,EAClB,SAAS,GACV,EAAE,0BAA0B,qBAqB5B"}
@@ -1,29 +0,0 @@
1
- import * as React from 'react';
2
- import { type QuickActionIconSpec } from './quick-action-chip';
3
- export interface QuickActionMarqueeItem {
4
- /** Stable key (suffixed per track copy internally). */
5
- id: string;
6
- label: string;
7
- icon?: React.ReactNode | QuickActionIconSpec;
8
- }
9
- export interface QuickActionMarqueeProps {
10
- items: ReadonlyArray<QuickActionMarqueeItem>;
11
- /** Scroll direction. `'right'` reverses the animation. Default `'left'`. */
12
- direction?: 'left' | 'right';
13
- /** Seconds per full loop. Default 40. */
14
- duration?: number;
15
- /** Pause the scroll while hovered. Default true. */
16
- pauseOnHover?: boolean;
17
- /** When provided chips are interactive buttons; omitted → decorative tags. */
18
- onSelect?: (item: QuickActionMarqueeItem) => void;
19
- className?: string;
20
- }
21
- /**
22
- * Endless horizontally-scrolling strip of quick-action chips (Figma fae/mingo
23
- * marquee rows). The item list is padded to at least {@link MIN_TRACK_ITEMS}
24
- * and rendered twice so the `qa-marquee` keyframe's `translateX(-50%)` loops
25
- * seamlessly; the second half is `aria-hidden`. Pauses on hover (optional)
26
- * and always under `prefers-reduced-motion`.
27
- */
28
- export declare function QuickActionMarquee({ items, direction, duration, pauseOnHover, onSelect, className, }: QuickActionMarqueeProps): React.JSX.Element | null;
29
- //# sourceMappingURL=quick-action-marquee.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"quick-action-marquee.d.ts","sourceRoot":"","sources":["../../../src/components/chat/quick-action-marquee.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAyB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAMrF,MAAM,WAAW,sBAAsB;IACrC,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,mBAAmB,CAAA;CAC7C;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAA;IAC5C,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC5B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oDAAoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,IAAI,CAAA;IACjD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAUD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,SAAkB,EAClB,QAAa,EACb,YAAmB,EACnB,QAAQ,EACR,SAAS,GACV,EAAE,uBAAuB,4BAuCzB"}
@@ -1,155 +0,0 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
- import { cn } from '../../utils/cn'
5
- import { Tag } from '../ui/tag'
6
- import { EntityIcon, type EntityIconValue } from '../icon-display'
7
-
8
- // =============================================================================
9
- // Types
10
- // =============================================================================
11
-
12
- /** Accent tint for quick-action chip icons: a named brand token
13
- * (`'pink'`/`'cyan'`) or ANY CSS color value coming from admin config
14
- * (agent/persona `icon_props.color`). */
15
- export type QuickActionAccent = 'pink' | 'cyan' | (string & {})
16
-
17
- /**
18
- * FALLBACK-ONLY agent→accent mapping (fae→pink, mingo→cyan) for the built-in
19
- * agents when nothing is configured. A color configured on the entity itself —
20
- * the quick action's `iconProps.color`, or the agent/persona identity
21
- * `icon_props.color` — always wins over this map; callers must resolve the
22
- * configured value first and only fall back here. Never re-inline the slug
23
- * comparison elsewhere.
24
- */
25
- export function getAgentAccent(slug: string | null | undefined): QuickActionAccent | undefined {
26
- if (slug === 'fae') return 'pink'
27
- if (slug === 'mingo') return 'cyan'
28
- return undefined
29
- }
30
-
31
- /** Admin-configured identity color (`icon_props.color` on the agent/persona
32
- * row) → chip accent. Undefined when the identity doesn't set one. */
33
- export function accentFromIdentityIcon(
34
- icon: { props?: Record<string, unknown> | null } | null | undefined,
35
- ): QuickActionAccent | undefined {
36
- const color = icon?.props?.color
37
- return typeof color === 'string' && color.length > 0 ? color : undefined
38
- }
39
-
40
- /**
41
- * Declarative icon for a quick-action chip, resolved 100% by `<EntityIcon>`
42
- * (url → fae/mingo `AgentMark` → icons-v2 glyph → file fallback):
43
- * - "agent format" — `{ name: 'fae' }` / `{ name: 'mingo' }` renders the
44
- * packaged agent mark (fills the chip's icon box; `accent` is ignored — the
45
- * marks carry their own colors).
46
- * - "config format" — `{ name, url, props, accent }` renders the
47
- * admin-configured icon; `accent` tints registry glyphs via a
48
- * `text-ods-flamingo-*` class on `currentColor`.
49
- *
50
- * If `props.color` is set it wins over `accent` — the accent is a class tint
51
- * on `currentColor`, the prop is an explicit fill (EntityIcon spreads `props`
52
- * onto the glyph last).
53
- */
54
- export interface QuickActionIconSpec extends EntityIconValue {
55
- accent?: QuickActionAccent
56
- /** Glyph size in px. Defaults to 16 (the chip design's config-icon size);
57
- * agent marks size via the icon box instead. */
58
- size?: number
59
- }
60
-
61
- const ACCENT_CLASS: Record<string, string> = {
62
- pink: 'text-ods-flamingo-pink',
63
- cyan: 'text-ods-flamingo-cyan',
64
- }
65
-
66
- /** Resolve a chip `icon` prop to a renderable node. Specs go through
67
- * `<EntityIcon>`; ReactNodes pass through untouched. */
68
- export function renderQuickActionIcon(
69
- icon: React.ReactNode | QuickActionIconSpec | undefined,
70
- ): React.ReactNode {
71
- // A spec is a plain data object, never a React element — so any non-element,
72
- // non-array object is a spec; strings, elements, fragments, and ReactNode
73
- // ARRAYS stay ReactNode.
74
- if (typeof icon !== 'object' || icon === null || Array.isArray(icon) || React.isValidElement(icon)) {
75
- return icon
76
- }
77
- const spec = icon as QuickActionIconSpec
78
- if (!spec.name && !spec.url) return undefined
79
- // Named brand tokens tint via a text class on `currentColor`; any other
80
- // accent value is an admin-configured CSS color, delivered as the glyph's
81
- // DEFAULT `color` prop — an explicit per-action `props.color` (spread after)
82
- // still wins.
83
- const accentClass = spec.accent ? ACCENT_CLASS[spec.accent] : undefined
84
- const props =
85
- spec.accent && !accentClass ? { color: spec.accent, ...(spec.props ?? {}) } : spec.props
86
- return (
87
- <EntityIcon
88
- icon={{ name: spec.name, url: spec.url, props }}
89
- size={spec.size ?? 16}
90
- className={accentClass}
91
- />
92
- )
93
- }
94
-
95
- export interface QuickActionChipButtonProps {
96
- label: React.ReactNode
97
- /** Icon: a declarative {@link QuickActionIconSpec} (preferred — unified
98
- * EntityIcon resolution) or a pre-rendered ReactNode. */
99
- icon?: React.ReactNode | QuickActionIconSpec
100
- /** `'primary'` = accent (yellow) chip, `'outline'` = bordered chip (default). */
101
- variant?: 'primary' | 'outline'
102
- onSelect?: () => void
103
- /** Pointer/keyboard focus enters the chip — e.g. preview the full prompt. */
104
- onHoverStart?: () => void
105
- /** Pointer/keyboard focus leaves the chip — e.g. restore the composer. */
106
- onHoverEnd?: () => void
107
- /** `false` renders a plain non-focusable `<Tag>` (decorative use: marquee
108
- * strips, table cells). Default `true`. */
109
- interactive?: boolean
110
- className?: string
111
- }
112
-
113
- // =============================================================================
114
- // Component
115
- // =============================================================================
116
-
117
- /**
118
- * The unified quick-action chip — Figma chip anatomy (card bg, border, mono
119
- * uppercase label) via the `Tag` outline/primary variants, with icon
120
- * resolution owned by `<EntityIcon>` in two formats (config icon w/ agent
121
- * accent, or fae/mingo agent mark). Used by every chat empty state
122
- * (guide / mingo / ai-agent), the marketing marquee strips, and the ROI
123
- * table task cells.
124
- */
125
- export function QuickActionChipButton({
126
- label,
127
- icon,
128
- variant = 'outline',
129
- onSelect,
130
- onHoverStart,
131
- onHoverEnd,
132
- interactive = true,
133
- className,
134
- }: QuickActionChipButtonProps) {
135
- const resolvedIcon = renderQuickActionIcon(icon)
136
- if (!interactive) {
137
- return <Tag variant={variant} icon={resolvedIcon} label={label} className={className} />
138
- }
139
- return (
140
- <button
141
- type="button"
142
- onClick={onSelect}
143
- onMouseEnter={onHoverStart}
144
- onMouseLeave={onHoverEnd}
145
- onFocus={onHoverStart}
146
- onBlur={onHoverEnd}
147
- className={cn(
148
- 'shrink-0 rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-ods-accent',
149
- className,
150
- )}
151
- >
152
- <Tag variant={variant} icon={resolvedIcon} label={label} />
153
- </button>
154
- )
155
- }
@@ -1,92 +0,0 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
- import { cn } from '../../utils/cn'
5
- import { QuickActionChipButton, type QuickActionIconSpec } from './quick-action-chip'
6
-
7
- // =============================================================================
8
- // Types
9
- // =============================================================================
10
-
11
- export interface QuickActionMarqueeItem {
12
- /** Stable key (suffixed per track copy internally). */
13
- id: string
14
- label: string
15
- icon?: React.ReactNode | QuickActionIconSpec
16
- }
17
-
18
- export interface QuickActionMarqueeProps {
19
- items: ReadonlyArray<QuickActionMarqueeItem>
20
- /** Scroll direction. `'right'` reverses the animation. Default `'left'`. */
21
- direction?: 'left' | 'right'
22
- /** Seconds per full loop. Default 40. */
23
- duration?: number
24
- /** Pause the scroll while hovered. Default true. */
25
- pauseOnHover?: boolean
26
- /** When provided chips are interactive buttons; omitted → decorative tags. */
27
- onSelect?: (item: QuickActionMarqueeItem) => void
28
- className?: string
29
- }
30
-
31
- // Heuristic: ~6 chips ≈ one 1280px viewport width, so the halved track always
32
- // fills the screen; bump if chips shrink.
33
- const MIN_TRACK_ITEMS = 6
34
-
35
- // =============================================================================
36
- // Component
37
- // =============================================================================
38
-
39
- /**
40
- * Endless horizontally-scrolling strip of quick-action chips (Figma fae/mingo
41
- * marquee rows). The item list is padded to at least {@link MIN_TRACK_ITEMS}
42
- * and rendered twice so the `qa-marquee` keyframe's `translateX(-50%)` loops
43
- * seamlessly; the second half is `aria-hidden`. Pauses on hover (optional)
44
- * and always under `prefers-reduced-motion`.
45
- */
46
- export function QuickActionMarquee({
47
- items,
48
- direction = 'left',
49
- duration = 40,
50
- pauseOnHover = true,
51
- onSelect,
52
- className,
53
- }: QuickActionMarqueeProps) {
54
- const { track, half } = React.useMemo(() => {
55
- const repeats = Math.max(1, Math.ceil(MIN_TRACK_ITEMS / Math.max(1, items.length)))
56
- const padded = Array.from({ length: repeats }, () => items).flat()
57
- return { track: [...padded, ...padded], half: padded.length }
58
- }, [items])
59
-
60
- if (items.length === 0) return null
61
-
62
- return (
63
- <div className={cn('group overflow-hidden', className)}>
64
- <div
65
- className={cn(
66
- 'flex w-max items-center gap-2 animate-qa-marquee motion-reduce:[animation-play-state:paused]',
67
- direction === 'right' && '[animation-direction:reverse]',
68
- pauseOnHover && 'group-hover:[animation-play-state:paused]',
69
- )}
70
- style={{ '--qa-marquee-duration': `${duration}s` } as React.CSSProperties}
71
- >
72
- {track.map((item, index) => {
73
- const isHiddenCopy = index >= half
74
- return (
75
- <span key={`${item.id}__${index}`} aria-hidden={isHiddenCopy || undefined}>
76
- {/* The aria-hidden loop copy must contain NO focusable elements
77
- (WCAG: no focusable descendants under aria-hidden) — its
78
- chips render as plain tags even when the strip is
79
- interactive. */}
80
- <QuickActionChipButton
81
- label={item.label}
82
- icon={item.icon}
83
- interactive={!!onSelect && !isHiddenCopy}
84
- onSelect={onSelect && !isHiddenCopy ? () => onSelect(item) : undefined}
85
- />
86
- </span>
87
- )
88
- })}
89
- </div>
90
- </div>
91
- )
92
- }