@flamingo-stack/openframe-frontend-core 0.0.361 → 0.0.362
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-IURUIQGY.js → chunk-25VKZ2QM.js} +2 -2
- package/dist/{chunk-AD2WYDPL.js → chunk-33CU7BKK.js} +4 -4
- package/dist/{chunk-BJ7NV7AO.js → chunk-3L34VSKP.js} +2 -2
- package/dist/{chunk-5B2IOQXZ.js → chunk-4ZHXIY5J.js} +12 -7
- package/dist/chunk-4ZHXIY5J.js.map +1 -0
- package/dist/{chunk-4RXV4UBA.cjs → chunk-57ZLSUWZ.cjs} +56 -56
- package/dist/{chunk-4RXV4UBA.cjs.map → chunk-57ZLSUWZ.cjs.map} +1 -1
- package/dist/{chunk-HR4PF6FJ.cjs → chunk-5EFJJBU5.cjs} +31 -31
- package/dist/{chunk-HR4PF6FJ.cjs.map → chunk-5EFJJBU5.cjs.map} +1 -1
- package/dist/{chunk-LNXM2OQ6.cjs → chunk-5PO6CQVE.cjs} +62 -62
- package/dist/{chunk-LNXM2OQ6.cjs.map → chunk-5PO6CQVE.cjs.map} +1 -1
- package/dist/{chunk-QTKCL36K.js → chunk-ACAVASHV.js} +2 -2
- package/dist/{chunk-MYP4I5B2.js → chunk-BLUIJE4A.js} +4 -4
- package/dist/{chunk-267JJUAP.js → chunk-CDQY7PJI.js} +4 -4
- package/dist/{chunk-2T6BQFJN.js → chunk-ECK3O7S7.js} +2 -2
- package/dist/{chunk-IOHKIL7O.cjs → chunk-IU3ADZVS.cjs} +7 -7
- package/dist/{chunk-IOHKIL7O.cjs.map → chunk-IU3ADZVS.cjs.map} +1 -1
- package/dist/{chunk-27T2PUJZ.js → chunk-KCJS6HWH.js} +4 -4
- package/dist/{chunk-KQXR27VF.cjs → chunk-KKZMWFCK.cjs} +25 -25
- package/dist/{chunk-KQXR27VF.cjs.map → chunk-KKZMWFCK.cjs.map} +1 -1
- package/dist/{chunk-BC5I4C5V.js → chunk-LI4WU5DO.js} +2 -2
- package/dist/{chunk-ODDTSUU7.cjs → chunk-MLWAQ3QJ.cjs} +37 -37
- package/dist/{chunk-ODDTSUU7.cjs.map → chunk-MLWAQ3QJ.cjs.map} +1 -1
- package/dist/{chunk-K6XWRBOV.cjs → chunk-NOJCRTFP.cjs} +5 -5
- package/dist/{chunk-K6XWRBOV.cjs.map → chunk-NOJCRTFP.cjs.map} +1 -1
- package/dist/{chunk-OIQEFSO4.js → chunk-O4J55Q6W.js} +2 -2
- package/dist/{chunk-JREHVZBN.cjs → chunk-PREABAGF.cjs} +12 -12
- package/dist/{chunk-JREHVZBN.cjs.map → chunk-PREABAGF.cjs.map} +1 -1
- package/dist/{chunk-RPLL2CTZ.cjs → chunk-PU7UCMSL.cjs} +15 -15
- package/dist/{chunk-RPLL2CTZ.cjs.map → chunk-PU7UCMSL.cjs.map} +1 -1
- package/dist/{chunk-BQFUPAEY.cjs → chunk-R27F2P55.cjs} +12 -7
- package/dist/chunk-R27F2P55.cjs.map +1 -0
- package/dist/{chunk-5WXXFSRE.cjs → chunk-SXM5YHP2.cjs} +26 -26
- package/dist/{chunk-5WXXFSRE.cjs.map → chunk-SXM5YHP2.cjs.map} +1 -1
- package/dist/{chunk-7W7C66KK.cjs → chunk-TSNXAJOJ.cjs} +9 -9
- package/dist/{chunk-7W7C66KK.cjs.map → chunk-TSNXAJOJ.cjs.map} +1 -1
- package/dist/{chunk-RSBCKRRK.js → chunk-U3LE33OX.js} +2 -2
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/chat-input.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +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 -120
- package/dist/components/index.js +9 -9
- 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 -2
- package/dist/components/ui/index.js +1 -1
- package/dist/components/ui/tab-navigation.d.ts.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/chat/chat-input.tsx +16 -9
- package/src/components/ui/tab-navigation.tsx +8 -2
- package/src/stories/EmbeddableChat.stories.tsx +75 -0
- package/src/stories/QuickActionChip.stories.tsx +149 -0
- package/src/stories/QuickActionMarquee.stories.tsx +114 -0
- package/dist/chunk-5B2IOQXZ.js.map +0 -1
- package/dist/chunk-BQFUPAEY.cjs.map +0 -1
- /package/dist/{chunk-IURUIQGY.js.map → chunk-25VKZ2QM.js.map} +0 -0
- /package/dist/{chunk-AD2WYDPL.js.map → chunk-33CU7BKK.js.map} +0 -0
- /package/dist/{chunk-BJ7NV7AO.js.map → chunk-3L34VSKP.js.map} +0 -0
- /package/dist/{chunk-QTKCL36K.js.map → chunk-ACAVASHV.js.map} +0 -0
- /package/dist/{chunk-MYP4I5B2.js.map → chunk-BLUIJE4A.js.map} +0 -0
- /package/dist/{chunk-267JJUAP.js.map → chunk-CDQY7PJI.js.map} +0 -0
- /package/dist/{chunk-2T6BQFJN.js.map → chunk-ECK3O7S7.js.map} +0 -0
- /package/dist/{chunk-27T2PUJZ.js.map → chunk-KCJS6HWH.js.map} +0 -0
- /package/dist/{chunk-BC5I4C5V.js.map → chunk-LI4WU5DO.js.map} +0 -0
- /package/dist/{chunk-OIQEFSO4.js.map → chunk-O4J55Q6W.js.map} +0 -0
- /package/dist/{chunk-RSBCKRRK.js.map → chunk-U3LE33OX.js.map} +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
|
2
|
+
import {
|
|
3
|
+
QuickActionChipButton,
|
|
4
|
+
type QuickActionIconSpec,
|
|
5
|
+
} from '../components/chat/quick-action-chip'
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof QuickActionChipButton> = {
|
|
8
|
+
title: 'Chat/QuickActionChip',
|
|
9
|
+
component: QuickActionChipButton,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'centered',
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component:
|
|
15
|
+
'The unified quick-action chip (`QuickActionChipButton`) used by every chat empty state (guide / mingo / ai-agent), the marketing marquee strips, and the ROI table task cells. Icon resolution is owned entirely by `<EntityIcon>` in two `QuickActionIconSpec` formats: the **agent format** (`{ name: \'fae\' | \'mingo\' }`) renders the packaged agent mark, and the **config format** (`{ name, url, props, accent }`) renders an admin-configured glyph tinted via `accent` (`pink` → flamingo-pink, `cyan` → flamingo-cyan, or any CSS color). An explicit `props.color` wins over `accent`.',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
argTypes: {
|
|
20
|
+
label: { control: 'text' },
|
|
21
|
+
variant: { control: 'inline-radio', options: ['outline', 'primary'] },
|
|
22
|
+
interactive: { control: 'boolean' },
|
|
23
|
+
icon: { control: false },
|
|
24
|
+
onSelect: { control: false },
|
|
25
|
+
onHoverStart: { control: false },
|
|
26
|
+
onHoverEnd: { control: false },
|
|
27
|
+
},
|
|
28
|
+
decorators: [
|
|
29
|
+
(Story) => (
|
|
30
|
+
<div className="flex items-center justify-center bg-ods-bg p-8">
|
|
31
|
+
<Story />
|
|
32
|
+
</div>
|
|
33
|
+
),
|
|
34
|
+
],
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default meta
|
|
38
|
+
type Story = StoryObj<typeof QuickActionChipButton>
|
|
39
|
+
|
|
40
|
+
// Config-format icon specs — resolved by <EntityIcon> against the icons-v2
|
|
41
|
+
// library, tinted by `accent`.
|
|
42
|
+
const SEARCH_ICON: QuickActionIconSpec = { name: 'search', accent: 'pink' }
|
|
43
|
+
const BUG_ICON: QuickActionIconSpec = { name: 'bug', accent: 'cyan' }
|
|
44
|
+
|
|
45
|
+
/** Default bordered (`outline`) chip with a config glyph tinted flamingo-pink. */
|
|
46
|
+
export const Default: Story = {
|
|
47
|
+
args: {
|
|
48
|
+
label: 'How to start',
|
|
49
|
+
icon: SEARCH_ICON,
|
|
50
|
+
variant: 'outline',
|
|
51
|
+
onSelect: () => console.log('select'),
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Accent (`primary`, yellow) chip variant. */
|
|
56
|
+
export const Primary: Story = {
|
|
57
|
+
args: {
|
|
58
|
+
label: 'Run scripts',
|
|
59
|
+
icon: { name: 'rocket' },
|
|
60
|
+
variant: 'primary',
|
|
61
|
+
onSelect: () => console.log('select'),
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Config glyphs tinted via `accent` — `pink` and `cyan` brand tokens. */
|
|
66
|
+
export const AccentTints: Story = {
|
|
67
|
+
render: () => (
|
|
68
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
69
|
+
<QuickActionChipButton label="Search docs" icon={SEARCH_ICON} onSelect={() => {}} />
|
|
70
|
+
<QuickActionChipButton label="Report a bug" icon={BUG_ICON} onSelect={() => {}} />
|
|
71
|
+
<QuickActionChipButton
|
|
72
|
+
label="Custom color"
|
|
73
|
+
icon={{ name: 'compass', accent: '#8b5cf6' }}
|
|
74
|
+
onSelect={() => {}}
|
|
75
|
+
/>
|
|
76
|
+
</div>
|
|
77
|
+
),
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Agent-format icons — `{ name: 'fae' }` / `{ name: 'mingo' }` render the
|
|
82
|
+
* packaged agent marks (they carry their own colors; `accent` is ignored).
|
|
83
|
+
*/
|
|
84
|
+
export const AgentMarks: Story = {
|
|
85
|
+
render: () => (
|
|
86
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
87
|
+
<QuickActionChipButton label="Ask fae" icon={{ name: 'fae' }} onSelect={() => {}} />
|
|
88
|
+
<QuickActionChipButton label="Ask mingo" icon={{ name: 'mingo' }} onSelect={() => {}} />
|
|
89
|
+
</div>
|
|
90
|
+
),
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** No icon — label only. */
|
|
94
|
+
export const NoIcon: Story = {
|
|
95
|
+
args: {
|
|
96
|
+
label: 'Find device',
|
|
97
|
+
onSelect: () => console.log('select'),
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* `interactive={false}` renders a plain, non-focusable `<Tag>` (decorative use:
|
|
103
|
+
* marquee strips, ROI table cells) — no button, no hover callbacks.
|
|
104
|
+
*/
|
|
105
|
+
export const NonInteractive: Story = {
|
|
106
|
+
args: {
|
|
107
|
+
label: 'Decorative',
|
|
108
|
+
icon: SEARCH_ICON,
|
|
109
|
+
interactive: false,
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* `onHoverStart` / `onHoverEnd` fire on pointer AND keyboard focus — used to
|
|
115
|
+
* preview the full prompt in the composer, then restore it. Hover or tab the
|
|
116
|
+
* chip and watch the Actions/console panel.
|
|
117
|
+
*/
|
|
118
|
+
export const HoverCallbacks: Story = {
|
|
119
|
+
args: {
|
|
120
|
+
label: 'Preview prompt',
|
|
121
|
+
icon: { name: 'fae' },
|
|
122
|
+
onSelect: () => console.log('select'),
|
|
123
|
+
onHoverStart: () => console.log('hover start → preview prompt'),
|
|
124
|
+
onHoverEnd: () => console.log('hover end → restore composer'),
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** All variants side by side. */
|
|
129
|
+
export const Gallery: Story = {
|
|
130
|
+
render: () => (
|
|
131
|
+
<div className="flex flex-col gap-4">
|
|
132
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
133
|
+
<QuickActionChipButton label="Outline" icon={SEARCH_ICON} onSelect={() => {}} />
|
|
134
|
+
<QuickActionChipButton
|
|
135
|
+
label="Primary"
|
|
136
|
+
icon={{ name: 'rocket' }}
|
|
137
|
+
variant="primary"
|
|
138
|
+
onSelect={() => {}}
|
|
139
|
+
/>
|
|
140
|
+
<QuickActionChipButton label="No icon" onSelect={() => {}} />
|
|
141
|
+
</div>
|
|
142
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
143
|
+
<QuickActionChipButton label="fae" icon={{ name: 'fae' }} onSelect={() => {}} />
|
|
144
|
+
<QuickActionChipButton label="mingo" icon={{ name: 'mingo' }} onSelect={() => {}} />
|
|
145
|
+
<QuickActionChipButton label="Decorative" icon={BUG_ICON} interactive={false} />
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
),
|
|
149
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
|
2
|
+
import {
|
|
3
|
+
QuickActionMarquee,
|
|
4
|
+
type QuickActionMarqueeItem,
|
|
5
|
+
} from '../components/chat/quick-action-marquee'
|
|
6
|
+
|
|
7
|
+
// fae-row items (config glyphs tinted pink) and mingo-row items (tinted cyan) —
|
|
8
|
+
// mirrors the Figma fae/mingo marquee rows.
|
|
9
|
+
const FAE_ITEMS: ReadonlyArray<QuickActionMarqueeItem> = [
|
|
10
|
+
{ id: 'how-to-start', label: 'How to start', icon: { name: 'fae' } },
|
|
11
|
+
{ id: 'connect-device', label: 'Connect device', icon: { name: 'search', accent: 'pink' } },
|
|
12
|
+
{ id: 'find-device', label: 'Find device', icon: { name: 'compass', accent: 'pink' } },
|
|
13
|
+
{ id: 'remote-connection', label: 'Remote connection', icon: { name: 'rocket', accent: 'pink' } },
|
|
14
|
+
{ id: 'run-scripts', label: 'Run scripts', icon: { name: 'bracket-curly', accent: 'pink' } },
|
|
15
|
+
{ id: 'device-software', label: 'Device software', icon: { name: 'package', accent: 'pink' } },
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
const MINGO_ITEMS: ReadonlyArray<QuickActionMarqueeItem> = [
|
|
19
|
+
{ id: 'roi', label: 'Calculate ROI', icon: { name: 'mingo' } },
|
|
20
|
+
{ id: 'ticket', label: 'Open ticket', icon: { name: 'ticket', accent: 'cyan' } },
|
|
21
|
+
{ id: 'report-bug', label: 'Report a bug', icon: { name: 'bug', accent: 'cyan' } },
|
|
22
|
+
{ id: 'docs', label: 'Read docs', icon: { name: 'book', accent: 'cyan' } },
|
|
23
|
+
{ id: 'chat', label: 'Start a chat', icon: { name: 'chats', accent: 'cyan' } },
|
|
24
|
+
{ id: 'news', label: "What's new", icon: { name: 'newspaper', accent: 'cyan' } },
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const meta: Meta<typeof QuickActionMarquee> = {
|
|
28
|
+
title: 'Chat/QuickActionMarquee',
|
|
29
|
+
component: QuickActionMarquee,
|
|
30
|
+
parameters: {
|
|
31
|
+
layout: 'fullscreen',
|
|
32
|
+
docs: {
|
|
33
|
+
description: {
|
|
34
|
+
component:
|
|
35
|
+
'Endless horizontally-scrolling strip of quick-action chips (Figma fae/mingo marquee rows). The item list is padded to ≥6 chips and rendered twice so the `qa-marquee` keyframe’s `translateX(-50%)` loops seamlessly; the duplicate half is `aria-hidden` and never focusable. Pauses on hover (`pauseOnHover`, default on) and always under `prefers-reduced-motion`. Pass `onSelect` to make chips interactive buttons; omit it for a purely decorative strip.',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
argTypes: {
|
|
40
|
+
items: { control: false },
|
|
41
|
+
direction: { control: 'inline-radio', options: ['left', 'right'] },
|
|
42
|
+
duration: { control: { type: 'number', min: 5, max: 120, step: 5 } },
|
|
43
|
+
pauseOnHover: { control: 'boolean' },
|
|
44
|
+
onSelect: { control: false },
|
|
45
|
+
},
|
|
46
|
+
decorators: [
|
|
47
|
+
(Story) => (
|
|
48
|
+
<div className="bg-ods-bg py-8">
|
|
49
|
+
<Story />
|
|
50
|
+
</div>
|
|
51
|
+
),
|
|
52
|
+
],
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default meta
|
|
56
|
+
type Story = StoryObj<typeof QuickActionMarquee>
|
|
57
|
+
|
|
58
|
+
/** Single fae row scrolling left, interactive chips. */
|
|
59
|
+
export const Default: Story = {
|
|
60
|
+
args: {
|
|
61
|
+
items: FAE_ITEMS,
|
|
62
|
+
onSelect: (item) => console.log('select', item.id),
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The two Figma rows: fae (left) over mingo (right, reversed). */
|
|
67
|
+
export const TwoRows: Story = {
|
|
68
|
+
render: () => (
|
|
69
|
+
<div className="flex flex-col gap-4">
|
|
70
|
+
<QuickActionMarquee items={FAE_ITEMS} direction="left" onSelect={(i) => console.log(i.id)} />
|
|
71
|
+
<QuickActionMarquee items={MINGO_ITEMS} direction="right" onSelect={(i) => console.log(i.id)} />
|
|
72
|
+
</div>
|
|
73
|
+
),
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Reversed scroll direction. */
|
|
77
|
+
export const ScrollRight: Story = {
|
|
78
|
+
args: {
|
|
79
|
+
items: MINGO_ITEMS,
|
|
80
|
+
direction: 'right',
|
|
81
|
+
onSelect: (item) => console.log('select', item.id),
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* No `onSelect` → chips render as plain, non-focusable tags (decorative
|
|
87
|
+
* marketing strip). Nothing is clickable or tabbable.
|
|
88
|
+
*/
|
|
89
|
+
export const Decorative: Story = {
|
|
90
|
+
args: {
|
|
91
|
+
items: FAE_ITEMS,
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Fewer than 6 items — the track is auto-repeated up to the `MIN_TRACK_ITEMS`
|
|
97
|
+
* heuristic so the halved loop still fills the viewport with no visible gap.
|
|
98
|
+
*/
|
|
99
|
+
export const FewItems: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
items: FAE_ITEMS.slice(0, 2),
|
|
102
|
+
onSelect: (item) => console.log('select', item.id),
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Faster loop (`duration={15}`) and hover-pause disabled. */
|
|
107
|
+
export const FastNoPause: Story = {
|
|
108
|
+
args: {
|
|
109
|
+
items: FAE_ITEMS,
|
|
110
|
+
duration: 15,
|
|
111
|
+
pauseOnHover: false,
|
|
112
|
+
onSelect: (item) => console.log('select', item.id),
|
|
113
|
+
},
|
|
114
|
+
}
|