@qoretechnologies/reqraft 0.10.20 → 0.10.26

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 (139) hide show
  1. package/.claude/CLAUDE.md +11 -8
  2. package/dist/components/composer/Composer.d.ts +108 -0
  3. package/dist/components/composer/Composer.d.ts.map +1 -0
  4. package/dist/components/composer/Composer.js +238 -0
  5. package/dist/components/composer/Composer.js.map +1 -0
  6. package/dist/components/composer/helpers.d.ts +21 -0
  7. package/dist/components/composer/helpers.d.ts.map +1 -0
  8. package/dist/components/composer/helpers.js +75 -0
  9. package/dist/components/composer/helpers.js.map +1 -0
  10. package/dist/components/composer/index.d.ts +3 -0
  11. package/dist/components/composer/index.d.ts.map +1 -0
  12. package/dist/components/composer/index.js +19 -0
  13. package/dist/components/composer/index.js.map +1 -0
  14. package/dist/components/form/engine/FormEngine.d.ts +1 -1
  15. package/dist/components/imageLightbox/ImageLightbox.d.ts +21 -0
  16. package/dist/components/imageLightbox/ImageLightbox.d.ts.map +1 -0
  17. package/dist/components/imageLightbox/ImageLightbox.js +169 -0
  18. package/dist/components/imageLightbox/ImageLightbox.js.map +1 -0
  19. package/dist/components/imageLightbox/index.d.ts +2 -0
  20. package/dist/components/imageLightbox/index.d.ts.map +1 -0
  21. package/dist/components/imageLightbox/index.js +18 -0
  22. package/dist/components/imageLightbox/index.js.map +1 -0
  23. package/dist/components/searchFilterBar/SearchFilterBar.d.ts +33 -0
  24. package/dist/components/searchFilterBar/SearchFilterBar.d.ts.map +1 -0
  25. package/dist/components/searchFilterBar/SearchFilterBar.js +76 -0
  26. package/dist/components/searchFilterBar/SearchFilterBar.js.map +1 -0
  27. package/dist/components/searchFilterBar/index.d.ts +2 -0
  28. package/dist/components/searchFilterBar/index.d.ts.map +1 -0
  29. package/dist/components/searchFilterBar/index.js +18 -0
  30. package/dist/components/searchFilterBar/index.js.map +1 -0
  31. package/dist/components/supportTicket/AttachmentChips.d.ts +10 -0
  32. package/dist/components/supportTicket/AttachmentChips.d.ts.map +1 -0
  33. package/dist/components/supportTicket/AttachmentChips.js +122 -0
  34. package/dist/components/supportTicket/AttachmentChips.js.map +1 -0
  35. package/dist/components/supportTicket/InterfaceReferenceTags.d.ts +43 -0
  36. package/dist/components/supportTicket/InterfaceReferenceTags.d.ts.map +1 -0
  37. package/dist/components/supportTicket/InterfaceReferenceTags.js +31 -0
  38. package/dist/components/supportTicket/InterfaceReferenceTags.js.map +1 -0
  39. package/dist/components/supportTicket/ReferencePicker.d.ts +87 -0
  40. package/dist/components/supportTicket/ReferencePicker.d.ts.map +1 -0
  41. package/dist/components/supportTicket/ReferencePicker.js +295 -0
  42. package/dist/components/supportTicket/ReferencePicker.js.map +1 -0
  43. package/dist/components/supportTicket/TicketHeader.d.ts +86 -0
  44. package/dist/components/supportTicket/TicketHeader.d.ts.map +1 -0
  45. package/dist/components/supportTicket/TicketHeader.js +149 -0
  46. package/dist/components/supportTicket/TicketHeader.js.map +1 -0
  47. package/dist/components/supportTicket/TicketMetaTags.d.ts +32 -0
  48. package/dist/components/supportTicket/TicketMetaTags.d.ts.map +1 -0
  49. package/dist/components/supportTicket/TicketMetaTags.js +21 -0
  50. package/dist/components/supportTicket/TicketMetaTags.js.map +1 -0
  51. package/dist/components/supportTicket/TicketReplyBox.d.ts +63 -0
  52. package/dist/components/supportTicket/TicketReplyBox.d.ts.map +1 -0
  53. package/dist/components/supportTicket/TicketReplyBox.js +115 -0
  54. package/dist/components/supportTicket/TicketReplyBox.js.map +1 -0
  55. package/dist/components/supportTicket/attachmentAccess.d.ts +37 -0
  56. package/dist/components/supportTicket/attachmentAccess.d.ts.map +1 -0
  57. package/dist/components/supportTicket/attachmentAccess.js +132 -0
  58. package/dist/components/supportTicket/attachmentAccess.js.map +1 -0
  59. package/dist/components/supportTicket/fileToAttachment.d.ts +9 -0
  60. package/dist/components/supportTicket/fileToAttachment.d.ts.map +1 -0
  61. package/dist/components/supportTicket/fileToAttachment.js +28 -0
  62. package/dist/components/supportTicket/fileToAttachment.js.map +1 -0
  63. package/dist/components/supportTicket/index.d.ts +11 -0
  64. package/dist/components/supportTicket/index.d.ts.map +1 -0
  65. package/dist/components/supportTicket/index.js +27 -0
  66. package/dist/components/supportTicket/index.js.map +1 -0
  67. package/dist/components/supportTicket/meta.d.ts +71 -0
  68. package/dist/components/supportTicket/meta.d.ts.map +1 -0
  69. package/dist/components/supportTicket/meta.js +115 -0
  70. package/dist/components/supportTicket/meta.js.map +1 -0
  71. package/dist/components/supportTicket/ticketModel.d.ts +102 -0
  72. package/dist/components/supportTicket/ticketModel.d.ts.map +1 -0
  73. package/dist/components/supportTicket/ticketModel.js +3 -0
  74. package/dist/components/supportTicket/ticketModel.js.map +1 -0
  75. package/dist/components/ticketReferences/TicketReferences.d.ts +52 -0
  76. package/dist/components/ticketReferences/TicketReferences.d.ts.map +1 -0
  77. package/dist/components/ticketReferences/TicketReferences.js +492 -0
  78. package/dist/components/ticketReferences/TicketReferences.js.map +1 -0
  79. package/dist/components/ticketReferences/index.d.ts +3 -0
  80. package/dist/components/ticketReferences/index.d.ts.map +1 -0
  81. package/dist/components/ticketReferences/index.js +6 -0
  82. package/dist/components/ticketReferences/index.js.map +1 -0
  83. package/dist/components/ticketThread/TicketThread.d.ts +57 -0
  84. package/dist/components/ticketThread/TicketThread.d.ts.map +1 -0
  85. package/dist/components/ticketThread/TicketThread.js +299 -0
  86. package/dist/components/ticketThread/TicketThread.js.map +1 -0
  87. package/dist/components/ticketThread/index.d.ts +3 -0
  88. package/dist/components/ticketThread/index.d.ts.map +1 -0
  89. package/dist/components/ticketThread/index.js +7 -0
  90. package/dist/components/ticketThread/index.js.map +1 -0
  91. package/dist/helpers/common.d.ts +5 -0
  92. package/dist/helpers/common.d.ts.map +1 -1
  93. package/dist/helpers/common.js +20 -1
  94. package/dist/helpers/common.js.map +1 -1
  95. package/dist/helpers/scrollbar.d.ts +2 -0
  96. package/dist/helpers/scrollbar.d.ts.map +1 -0
  97. package/dist/helpers/scrollbar.js +25 -0
  98. package/dist/helpers/scrollbar.js.map +1 -0
  99. package/dist/index.d.ts +8 -1
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +10 -1
  102. package/dist/index.js.map +1 -1
  103. package/package.json +1 -1
  104. package/src/components/composer/Composer.stories.tsx +238 -0
  105. package/src/components/composer/Composer.tsx +545 -0
  106. package/src/components/composer/helpers.ts +74 -0
  107. package/src/components/composer/index.ts +2 -0
  108. package/src/components/imageLightbox/ImageLightbox.stories.tsx +238 -0
  109. package/src/components/imageLightbox/ImageLightbox.tsx +236 -0
  110. package/src/components/imageLightbox/index.ts +1 -0
  111. package/src/components/searchFilterBar/SearchFilterBar.tsx +131 -0
  112. package/src/components/searchFilterBar/index.ts +1 -0
  113. package/src/components/supportTicket/AttachmentChips.stories.tsx +171 -0
  114. package/src/components/supportTicket/AttachmentChips.tsx +147 -0
  115. package/src/components/supportTicket/InterfaceReferenceTags.stories.tsx +171 -0
  116. package/src/components/supportTicket/InterfaceReferenceTags.tsx +96 -0
  117. package/src/components/supportTicket/ReferencePicker.stories.tsx +519 -0
  118. package/src/components/supportTicket/ReferencePicker.tsx +563 -0
  119. package/src/components/supportTicket/TicketConversation.stories.tsx +121 -0
  120. package/src/components/supportTicket/TicketHeader.stories.tsx +183 -0
  121. package/src/components/supportTicket/TicketHeader.tsx +247 -0
  122. package/src/components/supportTicket/TicketMetaTags.stories.tsx +103 -0
  123. package/src/components/supportTicket/TicketMetaTags.tsx +85 -0
  124. package/src/components/supportTicket/TicketReplyBox.stories.tsx +351 -0
  125. package/src/components/supportTicket/TicketReplyBox.tsx +146 -0
  126. package/src/components/supportTicket/attachmentAccess.ts +97 -0
  127. package/src/components/supportTicket/fileToAttachment.ts +24 -0
  128. package/src/components/supportTicket/index.ts +10 -0
  129. package/src/components/supportTicket/meta.ts +185 -0
  130. package/src/components/supportTicket/ticketModel.ts +131 -0
  131. package/src/components/ticketReferences/TicketReferences.stories.tsx +315 -0
  132. package/src/components/ticketReferences/TicketReferences.tsx +886 -0
  133. package/src/components/ticketReferences/index.ts +2 -0
  134. package/src/components/ticketThread/TicketThread.stories.tsx +828 -0
  135. package/src/components/ticketThread/TicketThread.tsx +704 -0
  136. package/src/components/ticketThread/index.ts +6 -0
  137. package/src/helpers/common.ts +19 -0
  138. package/src/helpers/scrollbar.ts +32 -0
  139. package/src/index.tsx +8 -1
@@ -0,0 +1,238 @@
1
+ import { ReqoreButton, ReqoreTag, ReqoreUIProvider } from '@qoretechnologies/reqore';
2
+ import { StoryObj } from '@storybook/react-vite';
3
+ import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
4
+ import { StoryMeta } from '../../types';
5
+ import { Composer } from './Composer';
6
+
7
+ const meta = {
8
+ component: Composer,
9
+ title: 'Components/Composer',
10
+ args: {
11
+ onSend: fn(),
12
+ },
13
+ } as StoryMeta<typeof Composer>;
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof meta>;
17
+
18
+ /**
19
+ * The default: the rich, Qonsole-style editor (`ReqoreRichTextEditor`). It renders
20
+ * a Slate contenteditable (not a `<textarea>`), an attach button, and Send.
21
+ */
22
+ export const Rich: Story = {
23
+ parameters: {
24
+ docs: {
25
+ description: {
26
+ story:
27
+ 'Renders the default rich editor — a Slate contenteditable (not a textarea) with an attach button and Send, seeded with a multi-line draft.',
28
+ },
29
+ },
30
+ },
31
+ args: {
32
+ placeholder: 'Write a message…',
33
+ defaultText: 'A rich, multi-line draft.\nSecond paragraph survives as a newline.',
34
+ },
35
+ async play({ canvasElement }) {
36
+ await expect(canvasElement.querySelector('[contenteditable="true"]')).not.toBeNull();
37
+ await expect(canvasElement.querySelector('textarea')).toBeNull();
38
+ await expect(within(canvasElement).getByText('Send')).toBeInTheDocument();
39
+ },
40
+ };
41
+
42
+ /**
43
+ * The `plain` variant — a `ReqoreTextarea`, used where a simple text field is
44
+ * enough (and for deterministic tests). Typing enables Send; clicking it calls
45
+ * `onSend` with the plain body and the staged files.
46
+ */
47
+ export const Plain: Story = {
48
+ parameters: {
49
+ docs: {
50
+ description: {
51
+ story:
52
+ 'Renders the plain textarea variant, where typing enables Send and clicking it calls onSend with the plain body and the staged files.',
53
+ },
54
+ },
55
+ },
56
+ args: { editor: 'plain' },
57
+ async play({ canvasElement, args }) {
58
+ const canvas = within(canvasElement);
59
+ const textarea = canvasElement.querySelector('textarea');
60
+ await expect(textarea).not.toBeNull();
61
+
62
+ await userEvent.type(textarea!, 'hello there');
63
+ await userEvent.click(canvas.getByText('Send'));
64
+ await waitFor(() =>
65
+ expect(args.onSend).toHaveBeenCalledWith(
66
+ 'hello there',
67
+ expect.objectContaining({ files: [] })
68
+ )
69
+ );
70
+ },
71
+ };
72
+
73
+ /**
74
+ * Multiple `sendActions` split the send button — a primary button plus a caret
75
+ * dropdown. The primary is the first action; its `id` is echoed back to `onSend`.
76
+ */
77
+ export const SplitSend: Story = {
78
+ parameters: {
79
+ docs: {
80
+ description: {
81
+ story:
82
+ "Renders the composer with multiple sendActions, splitting Send into a primary Publish button plus a caret dropdown — sending echoes the chosen action's id back to onSend.",
83
+ },
84
+ },
85
+ },
86
+ args: {
87
+ editor: 'plain',
88
+ sendActions: [
89
+ { id: 'publish', label: 'Publish', icon: 'SendPlane2Line' },
90
+ { id: 'draft', label: 'Save draft', icon: 'FileLine' },
91
+ ],
92
+ },
93
+ async play({ canvasElement, args }) {
94
+ const canvas = within(canvasElement);
95
+ const textarea = canvasElement.querySelector('textarea');
96
+ await userEvent.type(textarea!, 'ship it');
97
+ await userEvent.click(canvas.getByText('Publish'));
98
+ await waitFor(() =>
99
+ expect(args.onSend).toHaveBeenCalledWith(
100
+ 'ship it',
101
+ expect.objectContaining({ action: 'publish' })
102
+ )
103
+ );
104
+ },
105
+ };
106
+
107
+ /**
108
+ * A map of the composer's injection slots. The same Composer becomes the Qonsole
109
+ * input or the helpdesk reply box by filling these — so here every slot renders a
110
+ * tag naming itself, to show exactly where each one lands:
111
+ *
112
+ * - `attachMenuItems` — turns the `+` into a dropdown (open it for the entry)
113
+ * - `toolbarStart` — after `+` on the left
114
+ * - `footerActions` — after `toolbarStart`
115
+ * - `rightActions` — just left of Send
116
+ * - `aboveInput` — on top of the editor, inside the bar (Qonsole's reference chips)
117
+ * - `belowInput` — under the whole bar
118
+ */
119
+ const slotTag = (name: string) => <ReqoreTag label={name} size='small' intent='info' />;
120
+
121
+ export const WithSlots: Story = {
122
+ parameters: {
123
+ docs: {
124
+ description: {
125
+ story:
126
+ 'Renders every composer injection slot — attachMenuItems, toolbarStart, footerActions, rightActions, aboveInput, and belowInput — each filled with a self-naming tag, so the story reads as a legible map of where each slot lands.',
127
+ },
128
+ },
129
+ },
130
+ args: {
131
+ editor: 'plain',
132
+ attachMenuItems: () => [
133
+ { label: 'attachMenuItems entry', icon: 'CameraAiLine', onClick: fn() },
134
+ ],
135
+ toolbarStart: slotTag('toolbarStart'),
136
+ footerActions: slotTag('footerActions'),
137
+ rightActions: slotTag('rightActions'),
138
+ aboveInput: slotTag('aboveInput'),
139
+ belowInput: slotTag('belowInput'),
140
+ },
141
+ async play({ canvasElement }) {
142
+ const canvas = within(canvasElement);
143
+ // every slot renders its own marker, so the story is a legible slot map
144
+ for (const slot of [
145
+ 'toolbarStart',
146
+ 'footerActions',
147
+ 'rightActions',
148
+ 'aboveInput',
149
+ 'belowInput',
150
+ ]) {
151
+ await expect(canvas.getByText(slot)).toBeInTheDocument();
152
+ }
153
+ },
154
+ };
155
+
156
+ /**
157
+ * Proof that the composer is configurable enough to *be* the qorus-ide Qonsole
158
+ * input — no fork. Wrapped in qorus-ide's Reqore theme (`main #121212`,
159
+ * `custom1 #762f7e`) and given the same effect + controls the real QonsoleInput
160
+ * uses: the `custom1:darken` gradient bar, an icon-only `custom1` send, and the
161
+ * `+` / `/` / compass controls in the slots. Compare against
162
+ * :6006 story `qonsole-ui-components--business-impact`.
163
+ */
164
+ export const QonsoleReplica: Story = {
165
+ parameters: {
166
+ docs: {
167
+ description: {
168
+ story:
169
+ "Renders the composer configured to replicate qorus-ide's QonsoleInput — a dark custom1 theme, gradient bar, icon-only send, and the slash-commands and design-session compass controls in its slots.",
170
+ },
171
+ },
172
+ },
173
+ decorators: [
174
+ (Story) => (
175
+ <ReqoreUIProvider theme={{ main: '#121212', intents: { custom1: '#762f7e' } }}>
176
+ <div style={{ padding: 20, background: '#121212' }}>
177
+ <Story />
178
+ </div>
179
+ </ReqoreUIProvider>
180
+ ),
181
+ ],
182
+ args: {
183
+ placeholder: "Tell Qorus what you're trying to do…",
184
+ // the exact QonsoleInput bar effect (a custom1 gradient border + fill)
185
+ effect: { gradient: { direction: 'to bottom right', colors: 'custom1:darken:1:0.9' } },
186
+ // icon-only, custom1-themed, minimal — the Qonsole send
187
+ sendActions: [{ id: 'send', icon: 'SendPlane2Line', customTheme: { main: 'custom1' }, minimal: true }],
188
+ // `+` becomes a dropdown once it has extra items (screenshot / capture), like Qonsole
189
+ attachMenuItems: () => [
190
+ { label: 'Take screenshot', icon: 'CameraAiLine', onClick: fn() },
191
+ { label: 'Capture area', icon: 'CropLine', onClick: fn() },
192
+ ],
193
+ // the `/` slash-commands control (a stand-in for the Qonsole completions dropdown)
194
+ toolbarStart: (
195
+ <ReqoreButton
196
+ icon='SlashCommands2'
197
+ minimal
198
+ flat
199
+ size='small'
200
+ customTheme={{ main: 'custom1' }}
201
+ tooltip='Slash commands'
202
+ />
203
+ ),
204
+ // the design-session compass, left of send — exactly where QonsoleInput puts it
205
+ rightActions: (
206
+ <ReqoreButton
207
+ icon='Compass3Line'
208
+ minimal
209
+ flat
210
+ size='small'
211
+ customTheme={{ main: 'custom1' }}
212
+ tooltip='Start a design session'
213
+ />
214
+ ),
215
+ },
216
+ async play({ canvasElement }) {
217
+ // rich editor + the icon-only send (no "Send" label) render
218
+ await expect(canvasElement.querySelector('[contenteditable="true"]')).not.toBeNull();
219
+ await expect(within(canvasElement).queryByText('Send')).not.toBeInTheDocument();
220
+ },
221
+ };
222
+
223
+ /** `disabled` replaces the whole composer with a muted notice. */
224
+ export const Disabled: Story = {
225
+ parameters: {
226
+ docs: {
227
+ description: {
228
+ story:
229
+ 'Renders the disabled state, where the whole composer is replaced by a muted notice showing the disabledReason.',
230
+ },
231
+ },
232
+ },
233
+ args: { disabled: true, disabledReason: 'This channel is read-only.' },
234
+ async play({ canvasElement }) {
235
+ await expect(within(canvasElement).getByText('This channel is read-only.')).toBeInTheDocument();
236
+ await expect(canvasElement.querySelector('textarea')).toBeNull();
237
+ },
238
+ };