@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.
- package/dist/{chunk-KQXR27VF.cjs → chunk-2GLO2HEJ.cjs} +25 -25
- package/dist/{chunk-KQXR27VF.cjs.map → chunk-2GLO2HEJ.cjs.map} +1 -1
- package/dist/{chunk-IURUIQGY.js → chunk-2LTQEQWH.js} +2 -2
- package/dist/{chunk-7W7C66KK.cjs → chunk-35E52Q3L.cjs} +9 -9
- package/dist/{chunk-7W7C66KK.cjs.map → chunk-35E52Q3L.cjs.map} +1 -1
- package/dist/{chunk-JREHVZBN.cjs → chunk-4NGPMJK6.cjs} +12 -12
- package/dist/{chunk-JREHVZBN.cjs.map → chunk-4NGPMJK6.cjs.map} +1 -1
- package/dist/{chunk-2T6BQFJN.js → chunk-5NHJC3GQ.js} +2 -2
- package/dist/{chunk-RSBCKRRK.js → chunk-CBVU3DFH.js} +2 -2
- package/dist/{chunk-BJ7NV7AO.js → chunk-DNJCIVD6.js} +2 -2
- package/dist/{chunk-267JJUAP.js → chunk-E66A6UJC.js} +4 -4
- package/dist/{chunk-K6XWRBOV.cjs → chunk-EJSVHG4X.cjs} +5 -5
- package/dist/{chunk-K6XWRBOV.cjs.map → chunk-EJSVHG4X.cjs.map} +1 -1
- package/dist/{chunk-5B2IOQXZ.js → chunk-KMYPDZEO.js} +3852 -3971
- package/dist/chunk-KMYPDZEO.js.map +1 -0
- package/dist/{chunk-5WXXFSRE.cjs → chunk-LGQ4L3SX.cjs} +26 -26
- package/dist/{chunk-5WXXFSRE.cjs.map → chunk-LGQ4L3SX.cjs.map} +1 -1
- package/dist/{chunk-HR4PF6FJ.cjs → chunk-LTALFWHU.cjs} +31 -31
- package/dist/{chunk-HR4PF6FJ.cjs.map → chunk-LTALFWHU.cjs.map} +1 -1
- package/dist/{chunk-AD2WYDPL.js → chunk-LUEVAFJP.js} +4 -4
- package/dist/{chunk-BQFUPAEY.cjs → chunk-MGQVVGQV.cjs} +1058 -1177
- package/dist/chunk-MGQVVGQV.cjs.map +1 -0
- package/dist/{chunk-MYP4I5B2.js → chunk-QPGENYQV.js} +4 -4
- package/dist/{chunk-IOHKIL7O.cjs → chunk-QZ3KUDFG.cjs} +7 -7
- package/dist/{chunk-IOHKIL7O.cjs.map → chunk-QZ3KUDFG.cjs.map} +1 -1
- package/dist/{chunk-ODDTSUU7.cjs → chunk-TRUNSPFD.cjs} +37 -37
- package/dist/{chunk-ODDTSUU7.cjs.map → chunk-TRUNSPFD.cjs.map} +1 -1
- package/dist/{chunk-LNXM2OQ6.cjs → chunk-VS4EZRU3.cjs} +62 -62
- package/dist/{chunk-LNXM2OQ6.cjs.map → chunk-VS4EZRU3.cjs.map} +1 -1
- package/dist/{chunk-OIQEFSO4.js → chunk-XP7M5FPW.js} +2 -2
- package/dist/{chunk-BC5I4C5V.js → chunk-XULFRLBZ.js} +2 -2
- package/dist/{chunk-QTKCL36K.js → chunk-YA2LLBWQ.js} +2 -2
- package/dist/{chunk-27T2PUJZ.js → chunk-YEB3R52B.js} +4 -4
- package/dist/{chunk-RPLL2CTZ.cjs → chunk-YUZ25NHF.cjs} +15 -15
- package/dist/{chunk-RPLL2CTZ.cjs.map → chunk-YUZ25NHF.cjs.map} +1 -1
- package/dist/{chunk-4RXV4UBA.cjs → chunk-ZPY53IWK.cjs} +56 -56
- package/dist/{chunk-4RXV4UBA.cjs.map → chunk-ZPY53IWK.cjs.map} +1 -1
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/chat-quick-action-row.d.ts +1 -4
- package/dist/components/chat/chat-quick-action-row.d.ts.map +1 -1
- package/dist/components/chat/chat-quick-action.d.ts +0 -6
- package/dist/components/chat/chat-quick-action.d.ts.map +1 -1
- package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
- package/dist/components/chat/guide-welcome.d.ts +0 -3
- package/dist/components/chat/guide-welcome.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +2 -12
- package/dist/components/chat/index.cjs.map +1 -1
- package/dist/components/chat/index.d.ts +0 -2
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +1 -11
- package/dist/components/chat/mingo-welcome.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +20 -20
- package/dist/components/help-center-pages/index.js +11 -11
- package/dist/components/index.cjs +120 -130
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +9 -19
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +5 -5
- package/dist/components/tickets/index.js +4 -4
- package/dist/components/ui/index.cjs +2 -12
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.js +1 -11
- package/dist/index.cjs +2 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -11
- package/dist/tailwind.config.cjs +1 -8
- package/dist/tailwind.config.cjs.map +1 -1
- package/dist/tailwind.config.js +1 -8
- package/dist/tailwind.config.js.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/chat-quick-action-row.tsx +14 -20
- package/src/components/chat/chat-quick-action.tsx +0 -6
- package/src/components/chat/embeddable-chat.tsx +6 -19
- package/src/components/chat/guide-welcome.tsx +9 -15
- package/src/components/chat/index.ts +0 -2
- package/src/components/chat/mingo-welcome.tsx +12 -7
- package/tailwind.config.ts +0 -7
- package/dist/chunk-5B2IOQXZ.js.map +0 -1
- package/dist/chunk-BQFUPAEY.cjs.map +0 -1
- package/dist/components/chat/quick-action-chip.d.ts +0 -70
- package/dist/components/chat/quick-action-chip.d.ts.map +0 -1
- package/dist/components/chat/quick-action-marquee.d.ts +0 -29
- package/dist/components/chat/quick-action-marquee.d.ts.map +0 -1
- package/src/components/chat/quick-action-chip.tsx +0 -155
- package/src/components/chat/quick-action-marquee.tsx +0 -92
- /package/dist/{chunk-IURUIQGY.js.map → chunk-2LTQEQWH.js.map} +0 -0
- /package/dist/{chunk-2T6BQFJN.js.map → chunk-5NHJC3GQ.js.map} +0 -0
- /package/dist/{chunk-RSBCKRRK.js.map → chunk-CBVU3DFH.js.map} +0 -0
- /package/dist/{chunk-BJ7NV7AO.js.map → chunk-DNJCIVD6.js.map} +0 -0
- /package/dist/{chunk-267JJUAP.js.map → chunk-E66A6UJC.js.map} +0 -0
- /package/dist/{chunk-AD2WYDPL.js.map → chunk-LUEVAFJP.js.map} +0 -0
- /package/dist/{chunk-MYP4I5B2.js.map → chunk-QPGENYQV.js.map} +0 -0
- /package/dist/{chunk-OIQEFSO4.js.map → chunk-XP7M5FPW.js.map} +0 -0
- /package/dist/{chunk-BC5I4C5V.js.map → chunk-XULFRLBZ.js.map} +0 -0
- /package/dist/{chunk-QTKCL36K.js.map → chunk-YA2LLBWQ.js.map} +0 -0
- /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
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|