@flamingo-stack/openframe-frontend-core 0.0.222 → 0.0.223

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 (183) hide show
  1. package/dist/{chunk-AIKPR6BE.js → chunk-4VHWSAQR.js} +6069 -5235
  2. package/dist/chunk-4VHWSAQR.js.map +1 -0
  3. package/dist/{chunk-GMNE7P7V.cjs → chunk-4WBVMIKQ.cjs} +26 -26
  4. package/dist/{chunk-GMNE7P7V.cjs.map → chunk-4WBVMIKQ.cjs.map} +1 -1
  5. package/dist/{chunk-QYRV6MKX.js → chunk-53EA4QPZ.js} +13 -7
  6. package/dist/chunk-53EA4QPZ.js.map +1 -0
  7. package/dist/{chunk-4JOWZLEL.cjs → chunk-7TKYFZ3L.cjs} +7 -7
  8. package/dist/{chunk-4JOWZLEL.cjs.map → chunk-7TKYFZ3L.cjs.map} +1 -1
  9. package/dist/{chunk-IZA5WF44.cjs → chunk-ABBU7QOM.cjs} +12 -12
  10. package/dist/{chunk-IZA5WF44.cjs.map → chunk-ABBU7QOM.cjs.map} +1 -1
  11. package/dist/{chunk-KM4KK2A6.cjs → chunk-ENDUMC7Z.cjs} +2558 -1724
  12. package/dist/chunk-ENDUMC7Z.cjs.map +1 -0
  13. package/dist/{chunk-CCSEXVI4.js → chunk-GYYGA24C.js} +2 -2
  14. package/dist/{chunk-RMOHKAHA.js → chunk-ISWWP2BH.js} +3 -3
  15. package/dist/{chunk-QNYH3WUU.cjs → chunk-JUWPBMQM.cjs} +13 -7
  16. package/dist/chunk-JUWPBMQM.cjs.map +1 -0
  17. package/dist/{chunk-A2SFHYVF.cjs → chunk-KXLTWANQ.cjs} +10 -10
  18. package/dist/{chunk-A2SFHYVF.cjs.map → chunk-KXLTWANQ.cjs.map} +1 -1
  19. package/dist/{chunk-ND24XSVT.js → chunk-TA6Z2AKD.js} +3 -3
  20. package/dist/chunk-TA6Z2AKD.js.map +1 -0
  21. package/dist/{chunk-HRIAZQ5D.js → chunk-WOKB6RJ7.js} +3 -3
  22. package/dist/components/chat/chat-archive-page.d.ts.map +1 -1
  23. package/dist/components/chat/chat-composer.d.ts.map +1 -1
  24. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  25. package/dist/components/chat/chat-message-skeleton.d.ts +19 -4
  26. package/dist/components/chat/chat-message-skeleton.d.ts.map +1 -1
  27. package/dist/components/chat/chat-panel-header-mobile.d.ts +24 -0
  28. package/dist/components/chat/chat-panel-header-mobile.d.ts.map +1 -0
  29. package/dist/components/chat/chat-panel-header.d.ts +6 -0
  30. package/dist/components/chat/chat-panel-header.d.ts.map +1 -1
  31. package/dist/components/chat/chat-quick-action-row.d.ts +31 -0
  32. package/dist/components/chat/chat-quick-action-row.d.ts.map +1 -0
  33. package/dist/components/chat/embeddable-chat.d.ts +27 -0
  34. package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
  35. package/dist/components/chat/entity-cards/dispatch.d.ts +14 -0
  36. package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -1
  37. package/dist/components/chat/entity-cards/github-activity-card.d.ts +10 -1
  38. package/dist/components/chat/entity-cards/github-activity-card.d.ts.map +1 -1
  39. package/dist/components/chat/guide-welcome.d.ts.map +1 -1
  40. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +9 -0
  41. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  42. package/dist/components/chat/hooks/use-slash-commands.d.ts +26 -0
  43. package/dist/components/chat/hooks/use-slash-commands.d.ts.map +1 -1
  44. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +12 -1
  45. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  46. package/dist/components/chat/hooks/use-unified-chat.d.ts +12 -0
  47. package/dist/components/chat/hooks/use-unified-chat.d.ts.map +1 -1
  48. package/dist/components/chat/index.cjs +9 -3
  49. package/dist/components/chat/index.cjs.map +1 -1
  50. package/dist/components/chat/index.js +8 -2
  51. package/dist/components/chat/mingo-chat-history.d.ts +10 -0
  52. package/dist/components/chat/mingo-chat-history.d.ts.map +1 -1
  53. package/dist/components/chat/mingo-info-card.d.ts +63 -0
  54. package/dist/components/chat/mingo-info-card.d.ts.map +1 -0
  55. package/dist/components/chat/mingo-welcome.d.ts +14 -1
  56. package/dist/components/chat/mingo-welcome.d.ts.map +1 -1
  57. package/dist/components/chat/types/chat.types.d.ts +6 -0
  58. package/dist/components/chat/types/chat.types.d.ts.map +1 -1
  59. package/dist/components/chat/types/unified-chat-state.types.d.ts +30 -0
  60. package/dist/components/chat/types/unified-chat-state.types.d.ts.map +1 -1
  61. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  62. package/dist/components/contact/index.cjs +4 -4
  63. package/dist/components/contact/index.js +3 -3
  64. package/dist/components/features/index.cjs +3 -3
  65. package/dist/components/features/index.js +2 -2
  66. package/dist/components/index.cjs +110 -104
  67. package/dist/components/index.cjs.map +1 -1
  68. package/dist/components/index.js +36 -30
  69. package/dist/components/index.js.map +1 -1
  70. package/dist/components/navigation/app-layout-drawer.d.ts +7 -0
  71. package/dist/components/navigation/app-layout-drawer.d.ts.map +1 -1
  72. package/dist/components/navigation/index.cjs +3 -3
  73. package/dist/components/navigation/index.js +2 -2
  74. package/dist/components/onboarding-guides/index.cjs +26 -26
  75. package/dist/components/onboarding-guides/index.js +4 -4
  76. package/dist/components/tickets/index.cjs +67 -67
  77. package/dist/components/tickets/index.js +5 -5
  78. package/dist/components/ui/actions-menu.d.ts +9 -0
  79. package/dist/components/ui/actions-menu.d.ts.map +1 -1
  80. package/dist/components/ui/dropdown-button.d.ts +2 -2
  81. package/dist/components/ui/dropdown-button.d.ts.map +1 -1
  82. package/dist/components/ui/index.cjs +9 -3
  83. package/dist/components/ui/index.cjs.map +1 -1
  84. package/dist/components/ui/index.js +8 -2
  85. package/dist/components/ui/modal-v2.d.ts.map +1 -1
  86. package/dist/components/ui/more-actions-menu.d.ts +13 -0
  87. package/dist/components/ui/more-actions-menu.d.ts.map +1 -1
  88. package/dist/components/ui/square-avatar.d.ts +4 -0
  89. package/dist/components/ui/square-avatar.d.ts.map +1 -1
  90. package/dist/components/ui/textarea.d.ts.map +1 -1
  91. package/dist/hooks/index.cjs +2 -2
  92. package/dist/hooks/index.js +1 -1
  93. package/dist/hooks/ui/use-auto-limit-tags.d.ts +7 -1
  94. package/dist/hooks/ui/use-auto-limit-tags.d.ts.map +1 -1
  95. package/dist/index.cjs +9 -3
  96. package/dist/index.cjs.map +1 -1
  97. package/dist/index.js +8 -2
  98. package/package.json +1 -1
  99. package/src/components/chat/chat-archive-page.tsx +32 -7
  100. package/src/components/chat/chat-composer.tsx +6 -2
  101. package/src/components/chat/chat-message-enhanced.tsx +24 -7
  102. package/src/components/chat/chat-message-list.tsx +1 -1
  103. package/src/components/chat/chat-message-skeleton.tsx +60 -60
  104. package/src/components/chat/chat-panel-header-mobile.tsx +94 -0
  105. package/src/components/chat/chat-panel-header.tsx +78 -50
  106. package/src/components/chat/chat-quick-action-row.tsx +146 -0
  107. package/src/components/chat/embeddable-chat.tsx +140 -45
  108. package/src/components/chat/entity-cards/dispatch.tsx +770 -232
  109. package/src/components/chat/entity-cards/github-activity-card.tsx +9 -3
  110. package/src/components/chat/guide-welcome.tsx +11 -8
  111. package/src/components/chat/hooks/use-nats-chat-adapter.ts +80 -7
  112. package/src/components/chat/hooks/use-slash-commands.ts +39 -0
  113. package/src/components/chat/hooks/use-sse-chat-adapter.ts +49 -45
  114. package/src/components/chat/hooks/use-unified-chat.ts +31 -8
  115. package/src/components/chat/mingo-chat-history.tsx +118 -36
  116. package/src/components/chat/mingo-info-card.tsx +214 -0
  117. package/src/components/chat/mingo-welcome.tsx +89 -36
  118. package/src/components/chat/types/chat.types.ts +4 -0
  119. package/src/components/chat/types/unified-chat-state.types.ts +35 -0
  120. package/src/components/chat/utils/process-historical-messages.ts +8 -0
  121. package/src/components/content-loading-container.tsx +1 -1
  122. package/src/components/empty-state.tsx +3 -3
  123. package/src/components/faq-accordion.tsx +2 -2
  124. package/src/components/features/changelog-manager.tsx +2 -2
  125. package/src/components/features/highlight-config-section.tsx +2 -2
  126. package/src/components/features/og-editor-preview.tsx +3 -3
  127. package/src/components/features/release-media-manager.tsx +2 -2
  128. package/src/components/loading/card-skeleton.tsx +3 -3
  129. package/src/components/loading/device-card-skeleton.tsx +1 -1
  130. package/src/components/loading/margin-report-skeleton.tsx +2 -2
  131. package/src/components/loading/organization-card-skeleton.tsx +1 -1
  132. package/src/components/loading/organization-icon-skeleton.tsx +1 -1
  133. package/src/components/loading/page-layout-skeleton.tsx +9 -9
  134. package/src/components/loading/users-grid-skeleton.tsx +2 -2
  135. package/src/components/logs-list.tsx +1 -1
  136. package/src/components/media-carousel.tsx +1 -1
  137. package/src/components/navigation/app-layout-drawer.tsx +70 -6
  138. package/src/components/open-source-features.tsx +2 -2
  139. package/src/components/ui/actions-menu.tsx +36 -13
  140. package/src/components/ui/allowed-domains-input.tsx +3 -3
  141. package/src/components/ui/cursor-pagination.tsx +1 -1
  142. package/src/components/ui/dropdown-button.tsx +6 -6
  143. package/src/components/ui/info-row.tsx +2 -2
  144. package/src/components/ui/modal-v2.tsx +8 -1
  145. package/src/components/ui/more-actions-menu.tsx +13 -0
  146. package/src/components/ui/square-avatar.tsx +6 -1
  147. package/src/components/ui/tags-input.tsx +1 -1
  148. package/src/components/ui/textarea.tsx +18 -4
  149. package/src/components/vendor-icon.tsx +1 -1
  150. package/src/components/vendor-tag.tsx +1 -1
  151. package/src/components/why-it-matters.tsx +1 -1
  152. package/src/hooks/ui/use-auto-limit-tags.ts +22 -8
  153. package/src/stories/ActionsMenu.stories.tsx +256 -0
  154. package/src/stories/AppLayoutSidebar.stories.tsx +6 -0
  155. package/src/stories/Board.stories.tsx +1 -1
  156. package/src/stories/ChatMingoInfoCards.stories.tsx +748 -0
  157. package/src/stories/ChatTicketList.stories.tsx +1 -1
  158. package/src/stories/DataTable.stories.tsx +17 -13
  159. package/src/stories/EmbeddableChat.stories.tsx +233 -1
  160. package/src/stories/MingoInfoCard.stories.tsx +193 -0
  161. package/src/stories/MingoOnboardingCard.stories.tsx +1 -1
  162. package/src/stories/Modal.stories.tsx +1 -0
  163. package/src/stories/NotificationDrawer.stories.tsx +14 -3
  164. package/src/stories/PageActions.stories.tsx +4 -4
  165. package/src/stories/PageContainer.stories.tsx +5 -5
  166. package/src/stories/PageLayout.stories.tsx +1 -1
  167. package/src/stories/TabSelector.stories.tsx +2 -2
  168. package/src/stories/Tag.stories.tsx +10 -5
  169. package/src/stories/TicketInfoSection.stories.tsx +23 -11
  170. package/src/stories/Toaster.stories.tsx +5 -5
  171. package/src/stories/__fixtures__/chat-card-decorator.tsx +44 -0
  172. package/dist/chunk-AIKPR6BE.js.map +0 -1
  173. package/dist/chunk-KM4KK2A6.cjs.map +0 -1
  174. package/dist/chunk-ND24XSVT.js.map +0 -1
  175. package/dist/chunk-QNYH3WUU.cjs.map +0 -1
  176. package/dist/chunk-QYRV6MKX.js.map +0 -1
  177. package/src/stories/.TicketDescriptionViewer.stories.md +0 -39
  178. package/src/stories/.TicketKnowledgeBaseList.stories.md +0 -36
  179. package/src/stories/TicketDescriptionViewer.stories.tsx +0 -70
  180. package/src/stories/TicketKnowledgeBaseList.stories.tsx +0 -51
  181. /package/dist/{chunk-CCSEXVI4.js.map → chunk-GYYGA24C.js.map} +0 -0
  182. /package/dist/{chunk-RMOHKAHA.js.map → chunk-ISWWP2BH.js.map} +0 -0
  183. /package/dist/{chunk-HRIAZQ5D.js.map → chunk-WOKB6RJ7.js.map} +0 -0
@@ -234,7 +234,7 @@ export const VariantComparison: Story = {
234
234
  value={primaryValue}
235
235
  onValueChange={setPrimaryValue}
236
236
  items={fiveItems}
237
- variant="accent"
237
+ variant="primary"
238
238
  label="Primary"
239
239
  />
240
240
  <TabSelector
@@ -275,6 +275,6 @@ export const WithBadges: Story = {
275
275
  ),
276
276
  },
277
277
  ];
278
- return <TabSelector value={value} onValueChange={setValue} items={items} variant="accent" label="Plan" />;
278
+ return <TabSelector value={value} onValueChange={setValue} items={items} variant="primary" label="Plan" />;
279
279
  },
280
280
  };
@@ -70,9 +70,10 @@ export const WithIconAndClose: Story = {
70
70
  };
71
71
 
72
72
  export const AllVariants: Story = {
73
+ args: { label: 'Tag' },
73
74
  render: () => (
74
75
  <div className="flex flex-wrap gap-3">
75
- <Tag variant="accent" label="Primary" />
76
+ <Tag variant="primary" label="Primary" />
76
77
  <Tag variant="outline" label="Outline" />
77
78
  <Tag variant="success" label="Success" />
78
79
  <Tag variant="warning" label="Warning" />
@@ -84,9 +85,10 @@ export const AllVariants: Story = {
84
85
  };
85
86
 
86
87
  export const AllWithIcons: Story = {
88
+ args: { label: 'Tag' },
87
89
  render: () => (
88
90
  <div className="flex flex-wrap gap-3">
89
- <Tag variant="accent" icon={<Smile className="size-5" />} label="Primary" />
91
+ <Tag variant="primary" icon={<Smile className="size-5" />} label="Primary" />
90
92
  <Tag variant="outline" icon={<Smile className="size-5" />} label="Outline" />
91
93
  <Tag variant="success" icon={<Smile className="size-5" />} label="Success" />
92
94
  <Tag variant="warning" icon={<Smile className="size-5" />} label="Warning" />
@@ -98,9 +100,10 @@ export const AllWithIcons: Story = {
98
100
  };
99
101
 
100
102
  export const AllWithClose: Story = {
103
+ args: { label: 'Tag' },
101
104
  render: () => (
102
105
  <div className="flex flex-wrap gap-3">
103
- <Tag variant="accent" onClose={() => {}} label="Primary" />
106
+ <Tag variant="primary" onClose={() => {}} label="Primary" />
104
107
  <Tag variant="outline" onClose={() => {}} label="Outline" />
105
108
  <Tag variant="success" onClose={() => {}} label="Success" />
106
109
  <Tag variant="warning" onClose={() => {}} label="Warning" />
@@ -126,9 +129,10 @@ export const DisabledWithIconAndClose: Story = {
126
129
  };
127
130
 
128
131
  export const AllDisabled: Story = {
132
+ args: { label: 'Tag' },
129
133
  render: () => (
130
134
  <div className="flex flex-wrap gap-3">
131
- <Tag variant="accent" label="Primary" disabled />
135
+ <Tag variant="primary" label="Primary" disabled />
132
136
  <Tag variant="outline" label="Outline" disabled />
133
137
  <Tag variant="success" label="Success" disabled />
134
138
  <Tag variant="warning" label="Warning" disabled />
@@ -140,9 +144,10 @@ export const AllDisabled: Story = {
140
144
  };
141
145
 
142
146
  export const AllWithIconAndClose: Story = {
147
+ args: { label: 'Tag' },
143
148
  render: () => (
144
149
  <div className="flex flex-wrap gap-3">
145
- <Tag variant="accent" icon={<Smile className="size-5" />} onClose={() => {}} label="Primary" />
150
+ <Tag variant="primary" icon={<Smile className="size-5" />} onClose={() => {}} label="Primary" />
146
151
  <Tag variant="outline" icon={<Smile className="size-5" />} onClose={() => {}} label="Outline" />
147
152
  <Tag variant="success" icon={<Smile className="size-5" />} onClose={() => {}} label="Success" />
148
153
  <Tag variant="warning" icon={<Smile className="size-5" />} onClose={() => {}} label="Warning" />
@@ -57,12 +57,6 @@ const mockAttachments = [
57
57
  { id: '3', fileName: 'acme-teaser.mp4', fileSize: '5.6 MB', onDownload: () => {} },
58
58
  ];
59
59
 
60
- const mockArticles = [
61
- { id: '1', title: 'OpenFrame Initial Setup Guide', description: 'Complete platform configuration including SSO integration, API connections, and core settings.' },
62
- { id: '2', title: 'Data Migration Best Practices', description: 'Step-by-step process for transferring client data from existing MSP tools.' },
63
- { id: '3', title: 'Admin Training Certification Program', description: 'Structured learning modules and hands-on exercises to certify client administrators.' },
64
- ];
65
-
66
60
  /**
67
61
  * Collapsed state — default view.
68
62
  */
@@ -86,12 +80,18 @@ export const Expanded: Story = {
86
80
  device: { name: 'WIN-SERVER-01', icon: <Monitor className="size-4" /> },
87
81
  status: 'TECH_REQUIRED',
88
82
  expanded: true,
89
- assigned: { name: 'Roman Smith', statusTag: { label: 'Status', variant: 'primary' } },
83
+ assigned: {
84
+ currentAssignee: { id: 'u1', name: 'Roman Smith' },
85
+ options: [
86
+ { value: 'u1', label: 'Roman Smith' },
87
+ { value: 'u2', label: 'John Doe' },
88
+ ],
89
+ onAssign: (userId) => alert(`Assign: ${userId}`),
90
+ },
90
91
  createdAt: '2025/07/12, 22:27',
91
92
  description: 'Goal: Reduce new client onboarding from 4 weeks to 10 days while maintaining 95% satisfaction.\n\nCore Activities:\n- Platform setup and configuration\n- Data migration and SSO integration\n- Team training and certification\n- Go-live support',
92
93
  attachments: mockAttachments,
93
94
  tags: ['Client-onboarding', 'Process-management', 'Project-template'],
94
- knowledgeBaseArticles: mockArticles,
95
95
  notes: mockNotes,
96
96
  onAddNote: () => {},
97
97
  onEditNote: () => {},
@@ -116,12 +116,18 @@ export const Interactive: Story = {
116
116
  {...args}
117
117
  expanded={expanded}
118
118
  onExpand={() => setExpanded(prev => !prev)}
119
- assigned={{ name: 'Roman Smith' }}
119
+ assigned={{
120
+ currentAssignee: { id: 'u1', name: 'Roman Smith' },
121
+ options: [
122
+ { value: 'u1', label: 'Roman Smith' },
123
+ { value: 'u2', label: 'John Doe' },
124
+ ],
125
+ onAssign: (userId) => alert(`Assign: ${userId}`),
126
+ }}
120
127
  createdAt="2025/07/12, 22:27"
121
128
  description="This is a sample ticket description with **markdown** content."
122
129
  attachments={mockAttachments}
123
130
  tags={['Linux', 'Production', 'High-Risk']}
124
- knowledgeBaseArticles={mockArticles}
125
131
  notes={mockNotes}
126
132
  onAddNote={(text) => alert(`Add note: ${text}`)}
127
133
  onEditNote={(id) => alert(`Edit note: ${id}`)}
@@ -141,7 +147,13 @@ export const Minimal: Story = {
141
147
  device: { name: 'Unassigned' },
142
148
  status: 'ACTIVE',
143
149
  expanded: true,
144
- assigned: { name: 'Unassigned' },
150
+ assigned: {
151
+ options: [
152
+ { value: 'u1', label: 'Roman Smith' },
153
+ { value: 'u2', label: 'John Doe' },
154
+ ],
155
+ onAssign: (userId) => alert(`Assign: ${userId}`),
156
+ },
145
157
  createdAt: '2025/01/01, 00:00',
146
158
  },
147
159
  };
@@ -203,7 +203,7 @@ export const CommandApprovalLive: Story = {
203
203
  <div className="flex flex-col gap-4">
204
204
  <div className="flex flex-wrap gap-2">
205
205
  <Button
206
- variant="warning"
206
+ variant="outline"
207
207
  onClick={() =>
208
208
  showCommandApprovalToast({
209
209
  title: 'Tech Required',
@@ -220,7 +220,7 @@ export const CommandApprovalLive: Story = {
220
220
  Fire approval toast
221
221
  </Button>
222
222
  <Button
223
- variant="warning"
223
+ variant="outline"
224
224
  onClick={() =>
225
225
  showCommandApprovalToast({
226
226
  title: 'Tech Required',
@@ -264,7 +264,7 @@ export const LiveTriggers: Story = {
264
264
  Default
265
265
  </Button>
266
266
  <Button
267
- variant="success"
267
+ variant="accent"
268
268
  onClick={() =>
269
269
  toast({
270
270
  variant: 'success',
@@ -276,7 +276,7 @@ export const LiveTriggers: Story = {
276
276
  Success
277
277
  </Button>
278
278
  <Button
279
- variant="warning"
279
+ variant="outline"
280
280
  onClick={() =>
281
281
  toast({
282
282
  variant: 'warning',
@@ -301,7 +301,7 @@ export const LiveTriggers: Story = {
301
301
  Error
302
302
  </Button>
303
303
  <Button
304
- variant="info"
304
+ variant="transparent"
305
305
  onClick={() =>
306
306
  toast({
307
307
  variant: 'info',
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Shared Storybook decorator + helpers for chat entity-card stories.
3
+ *
4
+ * Chat entity-cards are designed to render inside the assistant's message
5
+ * column — a narrow, padded column over the chat background. This decorator
6
+ * reproduces that context so the cards lay out at their real width in
7
+ * isolation, without booting the chat runtime.
8
+ *
9
+ * `makeAnchorProps` builds the `{ href, onClick }` pair the cards expect for
10
+ * their inner `<a>`. In Storybook there is no router, so the click is
11
+ * neutralized with `preventDefault` to keep navigation from escaping the
12
+ * iframe while still exercising the anchor markup (hover, copy-link, etc.).
13
+ */
14
+
15
+ import type React from 'react'
16
+
17
+ /**
18
+ * Wraps a story in a chat-message-column-like container: constrained width,
19
+ * chat background, ODS padding. Matches the column the dispatch pipeline
20
+ * renders entity-cards into.
21
+ */
22
+ export function ChatColumnDecorator({ children }: { children: React.ReactNode }) {
23
+ return (
24
+ <div className="min-h-screen w-full bg-ods-bg p-6">
25
+ <div className="mx-auto w-full max-w-[420px]">{children}</div>
26
+ </div>
27
+ )
28
+ }
29
+
30
+ /**
31
+ * Anchor-prop pair for a card's inner `<a>`. Shape matches the per-card
32
+ * `*AnchorProps` interfaces (`{ href, target?, rel?, onClick? }`). The
33
+ * `onClick` prevents default so Storybook doesn't navigate away from the
34
+ * iframe when the card is clicked.
35
+ */
36
+ export function makeAnchorProps(href: string): {
37
+ href: string
38
+ onClick: (e: React.MouseEvent<HTMLAnchorElement>) => void
39
+ } {
40
+ return {
41
+ href,
42
+ onClick: (e) => e.preventDefault(),
43
+ }
44
+ }