@flamingo-stack/openframe-frontend-core 0.0.459 → 0.0.460-snapshot.20260721124036
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-6XYHSDCL.cjs → chunk-2T5MXXTK.cjs} +31 -31
- package/dist/{chunk-6XYHSDCL.cjs.map → chunk-2T5MXXTK.cjs.map} +1 -1
- package/dist/{chunk-O5E7ZWHK.cjs → chunk-3H5XD5UD.cjs} +7 -7
- package/dist/{chunk-O5E7ZWHK.cjs.map → chunk-3H5XD5UD.cjs.map} +1 -1
- package/dist/{chunk-AS5B343N.js → chunk-4TKGFC7I.js} +2 -2
- package/dist/{chunk-DMU3BSPR.cjs → chunk-5D3UPZIM.cjs} +59 -59
- package/dist/{chunk-DMU3BSPR.cjs.map → chunk-5D3UPZIM.cjs.map} +1 -1
- package/dist/{chunk-XVHNAMAL.cjs → chunk-6IA5TD7O.cjs} +15 -15
- package/dist/{chunk-XVHNAMAL.cjs.map → chunk-6IA5TD7O.cjs.map} +1 -1
- package/dist/{chunk-MRKRE54X.js → chunk-7NUTHK3A.js} +4 -4
- package/dist/{chunk-WVC627C7.cjs → chunk-BFEMQ2XC.cjs} +26 -26
- package/dist/{chunk-WVC627C7.cjs.map → chunk-BFEMQ2XC.cjs.map} +1 -1
- package/dist/{chunk-GSKLTMIY.js → chunk-CDARBFPL.js} +2 -2
- package/dist/{chunk-JGSBLQLE.js → chunk-EXSLPPEY.js} +4 -4
- package/dist/{chunk-X5TAAOE7.cjs → chunk-FQKLIGV3.cjs} +62 -62
- package/dist/{chunk-X5TAAOE7.cjs.map → chunk-FQKLIGV3.cjs.map} +1 -1
- package/dist/{chunk-JWXOZRZ6.js → chunk-FYIX7RTZ.js} +4 -4
- package/dist/{chunk-CBNHSXTR.js → chunk-HHKLSJ5Y.js} +2 -2
- package/dist/{chunk-A2RF7ZG6.cjs → chunk-HWJWRQGV.cjs} +5 -5
- package/dist/{chunk-A2RF7ZG6.cjs.map → chunk-HWJWRQGV.cjs.map} +1 -1
- package/dist/{chunk-KW33TBQX.js → chunk-IQU6ZIZR.js} +2 -2
- package/dist/{chunk-TP5MVWQ2.js → chunk-KUVFE5WC.js} +665 -625
- package/dist/chunk-KUVFE5WC.js.map +1 -0
- package/dist/{chunk-IG4QVZSP.cjs → chunk-NFILBHXY.cjs} +9 -9
- package/dist/{chunk-IG4QVZSP.cjs.map → chunk-NFILBHXY.cjs.map} +1 -1
- package/dist/{chunk-EFGFAVOI.js → chunk-PLJSN3SR.js} +4 -4
- package/dist/{chunk-T2EBDVMZ.cjs → chunk-QLLXI554.cjs} +26 -26
- package/dist/{chunk-T2EBDVMZ.cjs.map → chunk-QLLXI554.cjs.map} +1 -1
- package/dist/{chunk-LDVQIOS7.js → chunk-RTLYVFFQ.js} +2 -2
- package/dist/{chunk-RTQ57HC5.js → chunk-S2KZZVJF.js} +2 -2
- package/dist/{chunk-YFPZLP63.cjs → chunk-TFVBIOSB.cjs} +771 -731
- package/dist/chunk-TFVBIOSB.cjs.map +1 -0
- package/dist/{chunk-OFPHMNRL.cjs → chunk-UNGRKZ65.cjs} +11 -11
- package/dist/{chunk-OFPHMNRL.cjs.map → chunk-UNGRKZ65.cjs.map} +1 -1
- package/dist/{chunk-OJ5ROJSS.cjs → chunk-WHXYDEAM.cjs} +37 -37
- package/dist/{chunk-OJ5ROJSS.cjs.map → chunk-WHXYDEAM.cjs.map} +1 -1
- package/dist/{chunk-Q74TSDZY.js → chunk-ZYHO7WAW.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/guide-welcome.d.ts +5 -1
- package/dist/components/chat/guide-welcome.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/chat/mingo-welcome.d.ts +5 -1
- package/dist/components/chat/mingo-welcome.d.ts.map +1 -1
- package/dist/components/chat/quick-action-wall.d.ts +16 -6
- package/dist/components/chat/quick-action-wall.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 +129 -129
- 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/index.cjs +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/chat/embeddable-chat.tsx +6 -0
- package/src/components/chat/guide-welcome.tsx +6 -0
- package/src/components/chat/mingo-welcome.tsx +6 -0
- package/src/components/chat/quick-action-wall.tsx +99 -11
- package/src/stories/QuickActionWall.stories.tsx +89 -0
- package/dist/chunk-TP5MVWQ2.js.map +0 -1
- package/dist/chunk-YFPZLP63.cjs.map +0 -1
- /package/dist/{chunk-AS5B343N.js.map → chunk-4TKGFC7I.js.map} +0 -0
- /package/dist/{chunk-MRKRE54X.js.map → chunk-7NUTHK3A.js.map} +0 -0
- /package/dist/{chunk-GSKLTMIY.js.map → chunk-CDARBFPL.js.map} +0 -0
- /package/dist/{chunk-JGSBLQLE.js.map → chunk-EXSLPPEY.js.map} +0 -0
- /package/dist/{chunk-JWXOZRZ6.js.map → chunk-FYIX7RTZ.js.map} +0 -0
- /package/dist/{chunk-CBNHSXTR.js.map → chunk-HHKLSJ5Y.js.map} +0 -0
- /package/dist/{chunk-KW33TBQX.js.map → chunk-IQU6ZIZR.js.map} +0 -0
- /package/dist/{chunk-EFGFAVOI.js.map → chunk-PLJSN3SR.js.map} +0 -0
- /package/dist/{chunk-LDVQIOS7.js.map → chunk-RTLYVFFQ.js.map} +0 -0
- /package/dist/{chunk-RTQ57HC5.js.map → chunk-S2KZZVJF.js.map} +0 -0
- /package/dist/{chunk-Q74TSDZY.js.map → chunk-ZYHO7WAW.js.map} +0 -0
|
@@ -38,10 +38,30 @@ export function interleave<T>(a: ReadonlyArray<T>, b: ReadonlyArray<T>): T[] {
|
|
|
38
38
|
return out
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
// Brick-mode padding
|
|
42
|
-
// row copy overflows any sensible container, so the loop always engages.
|
|
41
|
+
// Brick-mode padding fallback: ~14 columns of chips per row (~3200px) — one
|
|
42
|
+
// row copy overflows any sensible container, so the loop always engages. Used
|
|
43
|
+
// as the row-count reference and until the container width has been measured;
|
|
44
|
+
// once measured, the per-row pad target adapts to that width (see MIN_CHIP_PX).
|
|
43
45
|
const DEFAULT_MIN_CHIPS_PER_ROW = 14
|
|
44
46
|
|
|
47
|
+
// Conservative floor for one chip's on-track footprint in px (icon + a short
|
|
48
|
+
// mono label + Tag padding + the copy gap). The adaptive pad target divides the
|
|
49
|
+
// measured container width by this, so it must stay AT OR BELOW the narrowest
|
|
50
|
+
// real chip — an over-estimate would under-pad and the row could stop scrolling
|
|
51
|
+
// on a wide surface. Realistic quick-action labels are far wider, so the padded
|
|
52
|
+
// copy overflows comfortably; the `+ADAPTIVE_PAD_MARGIN` covers the worst case.
|
|
53
|
+
const MIN_CHIP_PX = 72
|
|
54
|
+
const ADAPTIVE_PAD_MARGIN = 2
|
|
55
|
+
// The adaptive target is clamped to [MIN_ADAPTIVE_PAD, DEFAULT_MIN_CHIPS_PER_ROW]:
|
|
56
|
+
// it only ever REDUCES padding below the fixed default (for narrow composers) —
|
|
57
|
+
// never above it, so no wide surface pads more than it does today.
|
|
58
|
+
const MIN_ADAPTIVE_PAD = 4
|
|
59
|
+
|
|
60
|
+
// Chat-agent walls (fae/mingo) cap the brick stack at 2 rows so the quick
|
|
61
|
+
// actions never crowd the composer; every other surface keeps the caller's
|
|
62
|
+
// `rows` as its cap.
|
|
63
|
+
const AGENT_MAX_ROWS = 2
|
|
64
|
+
|
|
45
65
|
// =============================================================================
|
|
46
66
|
// Types
|
|
47
67
|
// =============================================================================
|
|
@@ -92,14 +112,24 @@ export interface QuickActionWallProps {
|
|
|
92
112
|
* walls where repeats would duplicate flip ids, need no padding). */
|
|
93
113
|
minChips?: number
|
|
94
114
|
/**
|
|
95
|
-
* BRICK-WALL mode:
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* of
|
|
99
|
-
*
|
|
115
|
+
* BRICK-WALL mode: the MAXIMUM number of stacked single-row marquees. The
|
|
116
|
+
* actual row count grows with the chip supply — `ceil(chips / 14)` capped at
|
|
117
|
+
* `rows` — so a short action set fills one row (padded with its own repeats)
|
|
118
|
+
* instead of spreading one chip per row. The originals are split evenly
|
|
119
|
+
* ACROSS the active rows first, THEN each row pads to a full course, so no
|
|
120
|
+
* row is ever all-duplicates while another holds the unique chips. Rows pack
|
|
121
|
+
* edge-to-edge like bricks (a grid would column-align mismatched widths and
|
|
122
|
+
* leave holes) and each loops on its own wrap. Horizontal only; the fades
|
|
100
123
|
* draw ONCE over the whole stack.
|
|
101
124
|
*/
|
|
102
125
|
rows?: number
|
|
126
|
+
/**
|
|
127
|
+
* Chat agent this wall belongs to (`'fae'` / `'mingo'`). When set to a
|
|
128
|
+
* built-in agent it caps the brick stack at {@link AGENT_MAX_ROWS} (2) so the
|
|
129
|
+
* actions stay compact above the composer; any other value (or unset) leaves
|
|
130
|
+
* the cap at `rows`. Optional — decorative/marketing walls omit it.
|
|
131
|
+
*/
|
|
132
|
+
agentSlug?: string
|
|
103
133
|
/** Draw skeleton chips instead of `chips` (the shared
|
|
104
134
|
* {@link QuickActionChipSkeleton} — 1:1 geometry with loaded chips).
|
|
105
135
|
* Callers own the policy (`loading` flag vs skeleton-when-empty). */
|
|
@@ -150,16 +180,36 @@ export function QuickActionWall({
|
|
|
150
180
|
copyGap,
|
|
151
181
|
minChips,
|
|
152
182
|
rows,
|
|
183
|
+
agentSlug,
|
|
153
184
|
loading = false,
|
|
154
185
|
skeletonCount = 24,
|
|
155
186
|
className,
|
|
156
187
|
contentClassName,
|
|
157
188
|
sync,
|
|
158
189
|
}: QuickActionWallProps) {
|
|
190
|
+
// Measure the brick container so the per-row pad target can adapt to its
|
|
191
|
+
// width (see MIN_CHIP_PX): a narrow chat composer needs only a handful of
|
|
192
|
+
// repeats to overflow, a wide wall needs many. Pre-measure / SSR falls back
|
|
193
|
+
// to the fixed default, which always overflows. Only used in brick mode.
|
|
194
|
+
const brickRef = React.useRef<HTMLDivElement>(null)
|
|
195
|
+
const [brickWidth, setBrickWidth] = React.useState(0)
|
|
196
|
+
React.useEffect(() => {
|
|
197
|
+
const el = brickRef.current
|
|
198
|
+
if (!el || typeof ResizeObserver === 'undefined') return
|
|
199
|
+
const ro = new ResizeObserver(entries => {
|
|
200
|
+
const w = entries[0]?.contentRect.width ?? 0
|
|
201
|
+
if (w > 0) setBrickWidth(w)
|
|
202
|
+
})
|
|
203
|
+
ro.observe(el)
|
|
204
|
+
return () => ro.disconnect()
|
|
205
|
+
}, [])
|
|
206
|
+
|
|
159
207
|
// Repeat-pad the track (stable suffixed keys; repeats keep the full chip —
|
|
160
208
|
// identical selected/interactive state, so every visible instance behaves
|
|
161
209
|
// the same and the clone copy stays geometry-identical by construction).
|
|
162
|
-
|
|
210
|
+
// Brick mode does its own per-row padding below, so this pads only the
|
|
211
|
+
// single-track (wrap / vertical) walls.
|
|
212
|
+
const padTarget = rows ? undefined : minChips
|
|
163
213
|
const track = React.useMemo(() => {
|
|
164
214
|
if (!padTarget || chips.length === 0 || chips.length >= padTarget) return chips
|
|
165
215
|
const repeats = Math.ceil(padTarget / chips.length)
|
|
@@ -198,10 +248,48 @@ export function QuickActionWall({
|
|
|
198
248
|
|
|
199
249
|
// ---- BRICK-WALL mode: stacked independent row marquees ---------------------
|
|
200
250
|
if (rows && rows > 0) {
|
|
201
|
-
|
|
202
|
-
|
|
251
|
+
// Chat-agent walls (fae/mingo) grow the stack with the chip supply and cap
|
|
252
|
+
// it at AGENT_MAX_ROWS (2) so the actions stay compact above the composer.
|
|
253
|
+
// Every other surface keeps exactly `rows` rows (marketing/onboarding walls
|
|
254
|
+
// are sized for their design and carry far fewer than a full course/row).
|
|
255
|
+
const agentCapped = agentSlug === 'fae' || agentSlug === 'mingo'
|
|
256
|
+
const rowCap = agentCapped ? Math.min(rows, AGENT_MAX_ROWS) : rows
|
|
257
|
+
const dataRows = agentCapped
|
|
258
|
+
? Math.min(Math.max(1, Math.ceil(chips.length / DEFAULT_MIN_CHIPS_PER_ROW)), rowCap)
|
|
259
|
+
: rows
|
|
260
|
+
// Skeletons hold the cap so the row count never jumps when real chips land.
|
|
261
|
+
const stackRows = loading ? rowCap : dataRows
|
|
262
|
+
// Per-row overflow target — how many chips one copy must hold to overflow
|
|
263
|
+
// the container (so the marquee loop engages). Priority: an explicit
|
|
264
|
+
// `minChips` budget wins; otherwise adapt to the MEASURED width (just enough
|
|
265
|
+
// repeats to overflow — no more, so a narrow composer isn't flooded with
|
|
266
|
+
// duplicates); before the first measure (or SSR) fall back to the fixed
|
|
267
|
+
// default, which overflows any width.
|
|
268
|
+
const adaptivePerRow =
|
|
269
|
+
brickWidth > 0
|
|
270
|
+
? Math.min(
|
|
271
|
+
Math.max(Math.ceil(brickWidth / MIN_CHIP_PX) + ADAPTIVE_PAD_MARGIN, MIN_ADAPTIVE_PAD),
|
|
272
|
+
DEFAULT_MIN_CHIPS_PER_ROW,
|
|
273
|
+
)
|
|
274
|
+
: DEFAULT_MIN_CHIPS_PER_ROW
|
|
275
|
+
const perRowTarget = minChips ? Math.ceil(minChips / stackRows) : adaptivePerRow
|
|
276
|
+
|
|
277
|
+
// Split the ORIGINAL chips evenly across the rows FIRST (each row holds
|
|
278
|
+
// distinct actions), THEN pad each row to a full course with repeats of its
|
|
279
|
+
// OWN chips — so a row is never all-duplicates while another carries the
|
|
280
|
+
// unique ones (the old pad-then-slice split did exactly that when the chip
|
|
281
|
+
// count lined up with the row count).
|
|
282
|
+
const rowLists = Array.from({ length: stackRows }, (_, r) => {
|
|
283
|
+
const base = chips.filter((_, i) => i % stackRows === r)
|
|
284
|
+
if (base.length === 0 || base.length >= perRowTarget) return base
|
|
285
|
+
const repeats = Math.ceil(perRowTarget / base.length)
|
|
286
|
+
return Array.from({ length: repeats }, (_, rep) =>
|
|
287
|
+
rep === 0 ? base : base.map(chip => ({ ...chip, id: `${chip.id}__r${rep}` })),
|
|
288
|
+
).flat()
|
|
289
|
+
})
|
|
290
|
+
const skelPerRow = Math.ceil(skeletonCount / stackRows)
|
|
203
291
|
return (
|
|
204
|
-
<div className={cn('relative flex flex-col overflow-hidden', className)} style={{ gap }}>
|
|
292
|
+
<div ref={brickRef} className={cn('relative flex flex-col overflow-hidden', className)} style={{ gap }}>
|
|
205
293
|
{rowLists.map((list, r) => (
|
|
206
294
|
<MarqueeWall
|
|
207
295
|
key={r}
|
|
@@ -127,3 +127,92 @@ export const Loading: Story = {
|
|
|
127
127
|
</div>
|
|
128
128
|
),
|
|
129
129
|
}
|
|
130
|
+
|
|
131
|
+
// Brick-mode chip set: enough distinct actions to fill more than two full
|
|
132
|
+
// courses, so the agent cap and the even split are both visible.
|
|
133
|
+
const BRICK_ACTIONS: ReadonlyArray<QuickActionChip> = [
|
|
134
|
+
...IT_ACTIONS,
|
|
135
|
+
...SEC_ACTIONS,
|
|
136
|
+
...FAE_ACTIONS.map((c) => ({ ...c, theme: FAE_THEME })),
|
|
137
|
+
].map((c) => ({ ...c, onSelect: () => console.log(c.id) }))
|
|
138
|
+
|
|
139
|
+
/** Brick, chat agent (`agentSlug="mingo"`): the stack grows with the chip
|
|
140
|
+
* supply but caps at 2 rows. Originals are split evenly across the two rows
|
|
141
|
+
* first, then each row pads to a full course — no row is all-duplicates. */
|
|
142
|
+
export const BrickAgentCapped: Story = {
|
|
143
|
+
render: () => (
|
|
144
|
+
<QuickActionWall
|
|
145
|
+
chips={BRICK_ACTIONS}
|
|
146
|
+
agentSlug="mingo"
|
|
147
|
+
rows={4}
|
|
148
|
+
pauseOnHover
|
|
149
|
+
dragScroll
|
|
150
|
+
fade={['left', 'right']}
|
|
151
|
+
fadeSize={{ left: 32 }}
|
|
152
|
+
fadeColor="var(--color-bg)"
|
|
153
|
+
copyGap="var(--spacing-system-xxs)"
|
|
154
|
+
className="max-h-44"
|
|
155
|
+
/>
|
|
156
|
+
),
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Brick, few actions (`agentSlug="fae"`, 3 chips): fewer than one course, so
|
|
160
|
+
* the stack collapses to a SINGLE row padded with its own repeats instead of
|
|
161
|
+
* spreading one chip per row. */
|
|
162
|
+
export const BrickFewActions: Story = {
|
|
163
|
+
render: () => (
|
|
164
|
+
<QuickActionWall
|
|
165
|
+
chips={FAE_ACTIONS.slice(0, 3).map((c) => ({ ...c, theme: FAE_THEME, onSelect: () => console.log(c.id) }))}
|
|
166
|
+
agentSlug="fae"
|
|
167
|
+
rows={4}
|
|
168
|
+
pauseOnHover
|
|
169
|
+
dragScroll
|
|
170
|
+
fade={['left', 'right']}
|
|
171
|
+
fadeSize={{ left: 32 }}
|
|
172
|
+
fadeColor="var(--color-bg)"
|
|
173
|
+
copyGap="var(--spacing-system-xxs)"
|
|
174
|
+
className="max-h-44"
|
|
175
|
+
/>
|
|
176
|
+
),
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Brick, narrow composer: the per-row pad target adapts to the measured
|
|
180
|
+
* container width, so a chat-composer-width wall repeats each action only as
|
|
181
|
+
* many times as it takes to overflow (far fewer duplicates than the fixed
|
|
182
|
+
* 14), while a wide wall keeps the full course. Constrained to ~420px here to
|
|
183
|
+
* show the reduced duplication. */
|
|
184
|
+
export const BrickNarrowComposer: Story = {
|
|
185
|
+
render: () => (
|
|
186
|
+
<div className="w-[420px] max-w-full rounded-md border border-ods-border bg-ods-card p-[var(--spacing-system-mf)]">
|
|
187
|
+
<QuickActionWall
|
|
188
|
+
chips={FAE_ACTIONS.slice(0, 3).map((c) => ({ ...c, theme: FAE_THEME, onSelect: () => console.log(c.id) }))}
|
|
189
|
+
agentSlug="fae"
|
|
190
|
+
rows={4}
|
|
191
|
+
pauseOnHover
|
|
192
|
+
dragScroll
|
|
193
|
+
fade={['left', 'right']}
|
|
194
|
+
fadeSize={{ left: 32 }}
|
|
195
|
+
fadeColor="var(--color-bg-card)"
|
|
196
|
+
copyGap="var(--spacing-system-xxs)"
|
|
197
|
+
className="max-h-44"
|
|
198
|
+
/>
|
|
199
|
+
</div>
|
|
200
|
+
),
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** Brick, non-agent (no `agentSlug`): keeps exactly `rows` rows (marketing /
|
|
204
|
+
* onboarding walls are sized for their design), still getting the even split
|
|
205
|
+
* so a row is never filled with only one repeated chip. */
|
|
206
|
+
export const BrickNonAgent: Story = {
|
|
207
|
+
render: () => (
|
|
208
|
+
<QuickActionWall
|
|
209
|
+
chips={BRICK_ACTIONS}
|
|
210
|
+
rows={4}
|
|
211
|
+
fade={['left', 'right']}
|
|
212
|
+
fadeSize={{ left: 32 }}
|
|
213
|
+
fadeColor="var(--color-bg)"
|
|
214
|
+
copyGap="var(--spacing-system-xxs)"
|
|
215
|
+
className="max-h-56"
|
|
216
|
+
/>
|
|
217
|
+
),
|
|
218
|
+
}
|