@semiont/react-ui 0.2.45 → 0.3.0

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 (220) hide show
  1. package/dist/{PdfAnnotationCanvas.client-COQREPXU.mjs → PdfAnnotationCanvas.client-PVTVPDBQ.mjs} +3 -4
  2. package/dist/PdfAnnotationCanvas.client-PVTVPDBQ.mjs.map +1 -0
  3. package/dist/{ar-7SUXNE34.mjs → ar-APUOG2AP.mjs} +46 -6
  4. package/dist/ar-APUOG2AP.mjs.map +1 -0
  5. package/dist/{bn-XOET3DOI.mjs → bn-EFK2LJGK.mjs} +46 -6
  6. package/dist/bn-EFK2LJGK.mjs.map +1 -0
  7. package/dist/{chunk-JH7BXE2P.mjs → chunk-7DW2P4UE.mjs} +45 -5
  8. package/dist/chunk-7DW2P4UE.mjs.map +1 -0
  9. package/dist/{chunk-Q2KV6Y2J.mjs → chunk-7GEYABC6.mjs} +32 -32
  10. package/dist/{chunk-3JTO27MH.mjs → chunk-D4GAAQMM.mjs} +2 -9
  11. package/dist/{cs-X63DXX7L.mjs → cs-A26MEEQE.mjs} +46 -6
  12. package/dist/cs-A26MEEQE.mjs.map +1 -0
  13. package/dist/{da-OWTCV57A.mjs → da-U3L2FHSZ.mjs} +46 -6
  14. package/dist/da-U3L2FHSZ.mjs.map +1 -0
  15. package/dist/{de-77BMFDVF.mjs → de-Y5BHEBT7.mjs} +46 -6
  16. package/dist/de-Y5BHEBT7.mjs.map +1 -0
  17. package/dist/dist-YLEIY3JJ.mjs +547 -0
  18. package/dist/dist-YLEIY3JJ.mjs.map +1 -0
  19. package/dist/{el-FIBNLH2V.mjs → el-HU7LAWQY.mjs} +46 -6
  20. package/dist/el-HU7LAWQY.mjs.map +1 -0
  21. package/dist/{en-XWEPVTB4.mjs → en-HAKDCFKL.mjs} +5 -3
  22. package/dist/{es-726NTS53.mjs → es-4BN64QH5.mjs} +46 -6
  23. package/dist/es-4BN64QH5.mjs.map +1 -0
  24. package/dist/{fa-3N4CIWE6.mjs → fa-6ELTBARU.mjs} +46 -6
  25. package/dist/fa-6ELTBARU.mjs.map +1 -0
  26. package/dist/{fi-JOM3M7Z4.mjs → fi-DJ4WGIFW.mjs} +46 -6
  27. package/dist/fi-DJ4WGIFW.mjs.map +1 -0
  28. package/dist/{fr-56QSXS7E.mjs → fr-23XM6H6H.mjs} +46 -6
  29. package/dist/fr-23XM6H6H.mjs.map +1 -0
  30. package/dist/{he-SNAXPJEK.mjs → he-JSWJC2XU.mjs} +46 -6
  31. package/dist/he-JSWJC2XU.mjs.map +1 -0
  32. package/dist/{hi-CRBRD5TB.mjs → hi-BENHG3OJ.mjs} +46 -6
  33. package/dist/hi-BENHG3OJ.mjs.map +1 -0
  34. package/dist/{id-BRCVLICF.mjs → id-4HHQJQNF.mjs} +46 -6
  35. package/dist/id-4HHQJQNF.mjs.map +1 -0
  36. package/dist/index.css +108 -12
  37. package/dist/index.css.map +1 -1
  38. package/dist/index.d.mts +399 -147
  39. package/dist/index.mjs +3573 -2226
  40. package/dist/index.mjs.map +1 -1
  41. package/dist/{it-M2Z27BNB.mjs → it-U6I5PDKU.mjs} +46 -6
  42. package/dist/it-U6I5PDKU.mjs.map +1 -0
  43. package/dist/{ja-TZUKW7HD.mjs → ja-K3YBDWDP.mjs} +46 -6
  44. package/dist/ja-K3YBDWDP.mjs.map +1 -0
  45. package/dist/{ko-NKBGGOL6.mjs → ko-KC2HXRXG.mjs} +46 -6
  46. package/dist/ko-KC2HXRXG.mjs.map +1 -0
  47. package/dist/{magic-string.es-7FJ3LUGB.mjs → magic-string.es-K77I4ZQN.mjs} +2 -2
  48. package/dist/{ms-XFXPN6RX.mjs → ms-KY5QGBNN.mjs} +46 -6
  49. package/dist/ms-KY5QGBNN.mjs.map +1 -0
  50. package/dist/{nl-MVYXAS5C.mjs → nl-6PZFLGY2.mjs} +46 -6
  51. package/dist/nl-6PZFLGY2.mjs.map +1 -0
  52. package/dist/{no-XOLO4JPV.mjs → no-5QR7PLVJ.mjs} +46 -6
  53. package/dist/no-5QR7PLVJ.mjs.map +1 -0
  54. package/dist/{pl-TRWLMMC4.mjs → pl-4GV2NQXE.mjs} +46 -6
  55. package/dist/pl-4GV2NQXE.mjs.map +1 -0
  56. package/dist/{pt-M3TE24UI.mjs → pt-F3F5QD2P.mjs} +46 -6
  57. package/dist/pt-F3F5QD2P.mjs.map +1 -0
  58. package/dist/{ro-QBFG2T64.mjs → ro-TFYL2IQB.mjs} +46 -6
  59. package/dist/ro-TFYL2IQB.mjs.map +1 -0
  60. package/dist/{sv-IUECBXWX.mjs → sv-PRVF2QLR.mjs} +46 -6
  61. package/dist/sv-PRVF2QLR.mjs.map +1 -0
  62. package/dist/test-utils.mjs +16994 -22140
  63. package/dist/test-utils.mjs.map +1 -1
  64. package/dist/{th-US7KIN5Q.mjs → th-SUQOQFUZ.mjs} +46 -6
  65. package/dist/th-SUQOQFUZ.mjs.map +1 -0
  66. package/dist/{tr-DWJ2FFUK.mjs → tr-AYUJZOFJ.mjs} +46 -6
  67. package/dist/tr-AYUJZOFJ.mjs.map +1 -0
  68. package/dist/{uk-M4ZE4DPZ.mjs → uk-YY5WGLBM.mjs} +46 -6
  69. package/dist/uk-YY5WGLBM.mjs.map +1 -0
  70. package/dist/{vi-FERZNPSH.mjs → vi-6RO77ITD.mjs} +46 -6
  71. package/dist/{vi-FERZNPSH.mjs.map → vi-6RO77ITD.mjs.map} +1 -1
  72. package/dist/{zh-3J2I3WYK.mjs → zh-L6GA65H6.mjs} +46 -6
  73. package/dist/zh-L6GA65H6.mjs.map +1 -0
  74. package/package.json +18 -14
  75. package/src/components/Button/Button.tsx +23 -25
  76. package/src/components/annotation/AnnotateToolbar.tsx +1 -1
  77. package/src/components/annotation-popups/SharedPopupElements.tsx +5 -7
  78. package/src/components/image-annotation/SvgDrawingCanvas.tsx +3 -4
  79. package/src/components/modals/ConfigureGenerationStep.tsx +190 -0
  80. package/src/components/modals/ConfigureSearchStep.tsx +105 -0
  81. package/src/components/modals/ContextSummary.tsx +183 -0
  82. package/src/components/modals/GatherContextStep.tsx +89 -0
  83. package/src/components/modals/KeyboardShortcutsHelpModal.tsx +4 -6
  84. package/src/components/modals/ProposeEntitiesModal.tsx +4 -6
  85. package/src/components/modals/ReferenceWizardModal.tsx +326 -0
  86. package/src/components/modals/ResourceSearchModal.tsx +4 -6
  87. package/src/components/modals/SearchModal.css +43 -0
  88. package/src/components/modals/SearchModal.tsx +4 -6
  89. package/src/components/modals/SearchResultsStep.tsx +126 -0
  90. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +3 -4
  91. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +36 -14
  92. package/src/components/resource/AnnotateView.tsx +4 -4
  93. package/src/components/resource/AnnotationHistory.tsx +2 -2
  94. package/src/components/resource/BrowseView.tsx +4 -4
  95. package/src/components/resource/ResourceViewer.tsx +5 -8
  96. package/src/components/resource/__tests__/AnnotationHistory.test.tsx +16 -16
  97. package/src/components/resource/__tests__/BrowseView.test.tsx +2 -2
  98. package/src/components/resource/__tests__/HistoryEvent.test.tsx +1 -1
  99. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +1 -1
  100. package/src/components/resource/panels/AssessmentEntry.tsx +9 -11
  101. package/src/components/resource/panels/AssessmentPanel.tsx +1 -1
  102. package/src/components/resource/panels/CommentEntry.tsx +10 -12
  103. package/src/components/resource/panels/CommentsPanel.tsx +1 -1
  104. package/src/components/resource/panels/HighlightEntry.tsx +9 -11
  105. package/src/components/resource/panels/HighlightPanel.tsx +2 -2
  106. package/src/components/resource/panels/ReferenceEntry.tsx +57 -104
  107. package/src/components/resource/panels/ReferencesPanel.css +85 -13
  108. package/src/components/resource/panels/ReferencesPanel.tsx +2 -3
  109. package/src/components/resource/panels/TagEntry.tsx +9 -11
  110. package/src/components/resource/panels/TaggingPanel.tsx +1 -1
  111. package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +4 -4
  112. package/src/components/resource/panels/__tests__/AssistSection.test.tsx +7 -7
  113. package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +3 -3
  114. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +2 -2
  115. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +64 -101
  116. package/src/components/resource/panels/__tests__/StatisticsPanel.test.tsx +1 -1
  117. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +7 -7
  118. package/src/components/viewers/ImageViewer.tsx +3 -6
  119. package/src/components/viewers/__tests__/ImageViewer.test.tsx +3 -3
  120. package/src/features/admin-devops/__tests__/AdminDevOpsPage.test.tsx +5 -5
  121. package/src/features/admin-exchange/__tests__/AdminExchangePage.test.tsx +141 -0
  122. package/src/features/admin-exchange/__tests__/ExportCard.test.tsx +41 -0
  123. package/src/features/admin-exchange/__tests__/ImportCard.test.tsx +148 -0
  124. package/src/features/admin-exchange/__tests__/ImportProgress.test.tsx +106 -0
  125. package/src/features/admin-exchange/components/AdminExchangePage.tsx +120 -0
  126. package/src/features/admin-exchange/components/ExportCard.tsx +35 -0
  127. package/src/features/admin-exchange/components/ImportCard.tsx +188 -0
  128. package/src/features/admin-exchange/components/ImportProgress.tsx +86 -0
  129. package/src/features/admin-security/__tests__/AdminSecurityPage.test.tsx +3 -3
  130. package/src/features/moderate-entity-tags/__tests__/EntityTagsPage.test.tsx +2 -2
  131. package/src/features/moderate-recent/__tests__/RecentDocumentsPage.test.tsx +4 -4
  132. package/src/features/moderate-tag-schemas/__tests__/TagSchemasPage.test.tsx +3 -3
  133. package/src/features/moderation-linked-data/__tests__/LinkedDataPage.test.tsx +117 -0
  134. package/src/features/moderation-linked-data/components/LinkedDataPage.tsx +121 -0
  135. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +5 -5
  136. package/src/features/resource-compose/components/ResourceComposePage.tsx +56 -1
  137. package/src/features/resource-discovery/__tests__/ResourceCard.test.tsx +1 -1
  138. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +2 -2
  139. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +14 -14
  140. package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +12 -11
  141. package/src/features/resource-viewer/__tests__/AnnotationProgressDismissal.test.tsx +2 -2
  142. package/src/features/resource-viewer/__tests__/BindFlowIntegration.test.tsx +22 -115
  143. package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +3 -3
  144. package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +20 -20
  145. package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +7 -7
  146. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +43 -20
  147. package/src/features/resource-viewer/__tests__/ToastNotifications.test.tsx +2 -2
  148. package/src/features/resource-viewer/__tests__/YieldFlowIntegration.test.tsx +45 -82
  149. package/src/features/resource-viewer/__tests__/annotation-progress-flow.test.tsx +4 -4
  150. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +151 -74
  151. package/src/integrations/tailwind-plugin.js +3 -3
  152. package/src/styles/core/buttons.css +31 -0
  153. package/src/styles/features/exchange.css +404 -0
  154. package/src/styles/index.css +1 -0
  155. package/translations/ar.json +42 -4
  156. package/translations/bn.json +42 -4
  157. package/translations/cs.json +42 -4
  158. package/translations/da.json +128 -90
  159. package/translations/de.json +122 -84
  160. package/translations/el.json +42 -4
  161. package/translations/en.json +42 -4
  162. package/translations/es.json +42 -4
  163. package/translations/fa.json +42 -4
  164. package/translations/fi.json +68 -30
  165. package/translations/fr.json +42 -4
  166. package/translations/he.json +42 -4
  167. package/translations/hi.json +42 -4
  168. package/translations/id.json +43 -5
  169. package/translations/it.json +62 -24
  170. package/translations/ja.json +43 -5
  171. package/translations/ko.json +42 -4
  172. package/translations/ms.json +43 -5
  173. package/translations/nl.json +41 -3
  174. package/translations/no.json +104 -66
  175. package/translations/pl.json +42 -4
  176. package/translations/pt.json +43 -5
  177. package/translations/ro.json +42 -4
  178. package/translations/sv.json +42 -4
  179. package/translations/th.json +42 -4
  180. package/translations/tr.json +42 -4
  181. package/translations/uk.json +42 -4
  182. package/translations/vi.json +42 -4
  183. package/translations/zh.json +42 -4
  184. package/dist/PdfAnnotationCanvas.client-COQREPXU.mjs.map +0 -1
  185. package/dist/ar-7SUXNE34.mjs.map +0 -1
  186. package/dist/bn-XOET3DOI.mjs.map +0 -1
  187. package/dist/chunk-JH7BXE2P.mjs.map +0 -1
  188. package/dist/cs-X63DXX7L.mjs.map +0 -1
  189. package/dist/da-OWTCV57A.mjs.map +0 -1
  190. package/dist/de-77BMFDVF.mjs.map +0 -1
  191. package/dist/el-FIBNLH2V.mjs.map +0 -1
  192. package/dist/es-726NTS53.mjs.map +0 -1
  193. package/dist/fa-3N4CIWE6.mjs.map +0 -1
  194. package/dist/fi-JOM3M7Z4.mjs.map +0 -1
  195. package/dist/fr-56QSXS7E.mjs.map +0 -1
  196. package/dist/he-SNAXPJEK.mjs.map +0 -1
  197. package/dist/hi-CRBRD5TB.mjs.map +0 -1
  198. package/dist/id-BRCVLICF.mjs.map +0 -1
  199. package/dist/it-M2Z27BNB.mjs.map +0 -1
  200. package/dist/ja-TZUKW7HD.mjs.map +0 -1
  201. package/dist/ko-NKBGGOL6.mjs.map +0 -1
  202. package/dist/ms-XFXPN6RX.mjs.map +0 -1
  203. package/dist/nl-MVYXAS5C.mjs.map +0 -1
  204. package/dist/no-XOLO4JPV.mjs.map +0 -1
  205. package/dist/pl-TRWLMMC4.mjs.map +0 -1
  206. package/dist/pt-M3TE24UI.mjs.map +0 -1
  207. package/dist/ro-QBFG2T64.mjs.map +0 -1
  208. package/dist/sv-IUECBXWX.mjs.map +0 -1
  209. package/dist/th-US7KIN5Q.mjs.map +0 -1
  210. package/dist/tr-DWJ2FFUK.mjs.map +0 -1
  211. package/dist/uk-M4ZE4DPZ.mjs.map +0 -1
  212. package/dist/zh-3J2I3WYK.mjs.map +0 -1
  213. package/src/examples/ButtonUsageExample.tsx +0 -242
  214. package/src/examples/button-css-modules.module.css +0 -164
  215. package/src/examples/button-styled-components.tsx +0 -215
  216. package/src/examples/button-tailwind.css +0 -51
  217. /package/dist/{chunk-Q2KV6Y2J.mjs.map → chunk-7GEYABC6.mjs.map} +0 -0
  218. /package/dist/{chunk-3JTO27MH.mjs.map → chunk-D4GAAQMM.mjs.map} +0 -0
  219. /package/dist/{en-XWEPVTB4.mjs.map → en-HAKDCFKL.mjs.map} +0 -0
  220. /package/dist/{magic-string.es-7FJ3LUGB.mjs.map → magic-string.es-K77I4ZQN.mjs.map} +0 -0
@@ -0,0 +1,190 @@
1
+ 'use client';
2
+
3
+ import React, { useState } from 'react';
4
+ import type { GatheredContext } from '@semiont/core';
5
+ import { LOCALES } from '@semiont/api-client';
6
+
7
+ export interface GenerationConfig {
8
+ title: string;
9
+ prompt?: string;
10
+ language: string;
11
+ temperature: number;
12
+ maxTokens: number;
13
+ context: GatheredContext;
14
+ }
15
+
16
+ export interface ConfigureGenerationStepProps {
17
+ defaultTitle: string;
18
+ locale: string;
19
+ context: GatheredContext;
20
+ onBack: () => void;
21
+ onCancel: () => void;
22
+ onGenerate: (config: GenerationConfig) => void;
23
+ translations: {
24
+ resourceTitle: string;
25
+ resourceTitlePlaceholder: string;
26
+ additionalInstructions: string;
27
+ additionalInstructionsPlaceholder: string;
28
+ language: string;
29
+ languageHelp: string;
30
+ creativity: string;
31
+ creativityFocused: string;
32
+ creativityCreative: string;
33
+ maxLength: string;
34
+ maxLengthHelp: string;
35
+ cancel: string;
36
+ back: string;
37
+ generate: string;
38
+ };
39
+ }
40
+
41
+ export function ConfigureGenerationStep({
42
+ defaultTitle,
43
+ locale,
44
+ context,
45
+ onBack,
46
+ onCancel,
47
+ onGenerate,
48
+ translations: t,
49
+ }: ConfigureGenerationStepProps) {
50
+ const [title, setTitle] = useState(defaultTitle);
51
+ const [prompt, setPrompt] = useState('');
52
+ const [language, setLanguage] = useState(locale);
53
+ const [temperature, setTemperature] = useState(0.7);
54
+ const [maxTokens, setMaxTokens] = useState(500);
55
+
56
+ const handleSubmit = (e: React.FormEvent) => {
57
+ e.preventDefault();
58
+ const trimmedPrompt = prompt.trim();
59
+ onGenerate({
60
+ title,
61
+ ...(trimmedPrompt ? { prompt: trimmedPrompt } : {}),
62
+ language,
63
+ temperature,
64
+ maxTokens,
65
+ context,
66
+ });
67
+ };
68
+
69
+ return (
70
+ <form onSubmit={handleSubmit} className="semiont-form">
71
+ {/* Resource Title */}
72
+ <div className="semiont-form__field">
73
+ <label htmlFor="wizard-title" className="semiont-form__label">
74
+ {t.resourceTitle}
75
+ </label>
76
+ <input
77
+ id="wizard-title"
78
+ type="text"
79
+ value={title}
80
+ onChange={(e) => setTitle(e.target.value)}
81
+ required
82
+ className="semiont-input"
83
+ placeholder={t.resourceTitlePlaceholder}
84
+ />
85
+ </div>
86
+
87
+ {/* Additional Instructions */}
88
+ <div className="semiont-form__field">
89
+ <label htmlFor="wizard-prompt" className="semiont-form__label">
90
+ {t.additionalInstructions}
91
+ </label>
92
+ <textarea
93
+ id="wizard-prompt"
94
+ value={prompt}
95
+ onChange={(e) => setPrompt(e.target.value)}
96
+ rows={3}
97
+ className="semiont-textarea"
98
+ placeholder={t.additionalInstructionsPlaceholder}
99
+ />
100
+ </div>
101
+
102
+ {/* Language Selection */}
103
+ <div className="semiont-form__field">
104
+ <label htmlFor="wizard-language" className="semiont-form__label">
105
+ {t.language}
106
+ </label>
107
+ <select
108
+ id="wizard-language"
109
+ value={language}
110
+ onChange={(e) => setLanguage(e.target.value)}
111
+ className="semiont-select"
112
+ >
113
+ {LOCALES.map((lang) => (
114
+ <option key={lang.code} value={lang.code}>
115
+ {lang.nativeName}
116
+ </option>
117
+ ))}
118
+ </select>
119
+ <p className="semiont-form__help">
120
+ {t.languageHelp}
121
+ </p>
122
+ </div>
123
+
124
+ {/* Temperature Slider */}
125
+ <div className="semiont-form__field">
126
+ <label htmlFor="wizard-temperature" className="semiont-form__label">
127
+ {t.creativity} ({temperature.toFixed(1)})
128
+ </label>
129
+ <input
130
+ id="wizard-temperature"
131
+ type="range"
132
+ min="0"
133
+ max="1"
134
+ step="0.1"
135
+ value={temperature}
136
+ onChange={(e) => setTemperature(parseFloat(e.target.value))}
137
+ className="semiont-slider"
138
+ />
139
+ <div className="semiont-slider__labels">
140
+ <span>{t.creativityFocused}</span>
141
+ <span>{t.creativityCreative}</span>
142
+ </div>
143
+ </div>
144
+
145
+ {/* Max Tokens Input */}
146
+ <div className="semiont-form__field">
147
+ <label htmlFor="wizard-maxTokens" className="semiont-form__label">
148
+ {t.maxLength}
149
+ </label>
150
+ <input
151
+ id="wizard-maxTokens"
152
+ type="number"
153
+ min="100"
154
+ max="4000"
155
+ step="100"
156
+ value={maxTokens}
157
+ onChange={(e) => setMaxTokens(parseInt(e.target.value))}
158
+ className="semiont-input"
159
+ />
160
+ <p className="semiont-form__help">
161
+ {t.maxLengthHelp}
162
+ </p>
163
+ </div>
164
+
165
+ {/* Action Buttons */}
166
+ <div className="semiont-modal__actions" style={{ paddingTop: '0.5rem' }}>
167
+ <button
168
+ type="button"
169
+ onClick={onCancel}
170
+ className="semiont-button--secondary semiont-button--flex"
171
+ >
172
+ ✕ {t.cancel}
173
+ </button>
174
+ <button
175
+ type="button"
176
+ onClick={onBack}
177
+ className="semiont-button--secondary semiont-button--flex"
178
+ >
179
+ ◀ {t.back}
180
+ </button>
181
+ <button
182
+ type="submit"
183
+ className="semiont-button--primary semiont-button--flex"
184
+ >
185
+ ✨ {t.generate}
186
+ </button>
187
+ </div>
188
+ </form>
189
+ );
190
+ }
@@ -0,0 +1,105 @@
1
+ 'use client';
2
+
3
+ import React, { useState } from 'react';
4
+
5
+ export interface SearchConfig {
6
+ limit: number;
7
+ useSemanticScoring: boolean;
8
+ }
9
+
10
+ export interface ConfigureSearchStepProps {
11
+ isSearching?: boolean;
12
+ onBack: () => void;
13
+ onCancel: () => void;
14
+ onSearch: (config: SearchConfig) => void;
15
+ translations: {
16
+ maxResults: string;
17
+ semanticScoring: string;
18
+ semanticScoringHelp: string;
19
+ cancel: string;
20
+ back: string;
21
+ search: string;
22
+ searching: string;
23
+ };
24
+ }
25
+
26
+ export function ConfigureSearchStep({
27
+ isSearching = false,
28
+ onBack,
29
+ onCancel,
30
+ onSearch,
31
+ translations: t,
32
+ }: ConfigureSearchStepProps) {
33
+ const [limit, setLimit] = useState(10);
34
+ const [useSemanticScoring, setUseSemanticScoring] = useState(true);
35
+
36
+ const handleSubmit = (e: React.FormEvent) => {
37
+ e.preventDefault();
38
+ onSearch({ limit, useSemanticScoring });
39
+ };
40
+
41
+ return (
42
+ <form onSubmit={handleSubmit} className="semiont-form">
43
+ {/* Max Results */}
44
+ <div className="semiont-form__field">
45
+ <label htmlFor="wizard-limit" className="semiont-form__label">
46
+ {t.maxResults}
47
+ </label>
48
+ <select
49
+ id="wizard-limit"
50
+ value={limit}
51
+ onChange={(e) => setLimit(parseInt(e.target.value))}
52
+ className="semiont-select"
53
+ >
54
+ <option value={1}>1</option>
55
+ <option value={5}>5</option>
56
+ <option value={10}>10</option>
57
+ <option value={20}>20</option>
58
+ </select>
59
+ </div>
60
+
61
+ {/* Semantic Scoring Toggle */}
62
+ <div className="semiont-form__field">
63
+ <label className="semiont-form__label" style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
64
+ <input
65
+ type="checkbox"
66
+ checked={useSemanticScoring}
67
+ onChange={(e) => setUseSemanticScoring(e.target.checked)}
68
+ />
69
+ {t.semanticScoring}
70
+ </label>
71
+ <p className="semiont-form__help">
72
+ {t.semanticScoringHelp}
73
+ </p>
74
+ </div>
75
+
76
+ {/* Action Buttons */}
77
+ <div className="semiont-modal__actions" style={{ paddingTop: '0.5rem' }}>
78
+ <button
79
+ type="button"
80
+ onClick={onCancel}
81
+ className="semiont-button--secondary semiont-button--flex"
82
+ disabled={isSearching}
83
+ >
84
+ ✕ {t.cancel}
85
+ </button>
86
+ <button
87
+ type="button"
88
+ onClick={onBack}
89
+ className="semiont-button--secondary semiont-button--flex"
90
+ disabled={isSearching}
91
+ >
92
+ ◀ {t.back}
93
+ </button>
94
+ <button
95
+ type="submit"
96
+ className="semiont-button--primary semiont-button--flex"
97
+ disabled={isSearching}
98
+ data-generating={isSearching ? 'true' : 'false'}
99
+ >
100
+ {isSearching ? `✨ ${t.searching}` : `🔍 ${t.search}`}
101
+ </button>
102
+ </div>
103
+ </form>
104
+ );
105
+ }
@@ -0,0 +1,183 @@
1
+ 'use client';
2
+
3
+ import type { GatheredContext } from '@semiont/core';
4
+
5
+ export interface ContextSummaryTranslations {
6
+ annotationLabel: string;
7
+ sourceResourceLabel: string;
8
+ motivationLabel: string;
9
+ sourceContextLabel: string;
10
+ entityTypesLabel: string;
11
+ graphContextLabel: string;
12
+ connectionsLabel: string;
13
+ citedByLabel: string;
14
+ siblingTypesLabel: string;
15
+ }
16
+
17
+ export interface ContextSummaryProps {
18
+ context: GatheredContext;
19
+ translations: ContextSummaryTranslations;
20
+ }
21
+
22
+ export function ContextSummary({ context, translations: t }: ContextSummaryProps) {
23
+ const annotation = context.annotation;
24
+ const sourceResource = context.sourceResource;
25
+ const sourceContext = context.sourceContext;
26
+ const graphContext = context.graphContext;
27
+ const entityTypes = context.metadata?.entityTypes ?? [];
28
+ const connections = graphContext?.connections ?? [];
29
+ const citedBy = graphContext?.citedBy ?? [];
30
+ const citedByCount = graphContext?.citedByCount ?? 0;
31
+ const siblingEntityTypes = graphContext?.siblingEntityTypes ?? [];
32
+
33
+ return (
34
+ <>
35
+ {/* Annotation & Source Resource */}
36
+ <div className="semiont-form__field">
37
+ <label className="semiont-form__label">
38
+ {t.annotationLabel}
39
+ </label>
40
+ <div style={{
41
+ padding: '0.5rem 0.75rem',
42
+ backgroundColor: 'var(--semiont-bg-secondary)',
43
+ borderRadius: 'var(--semiont-radius-md)',
44
+ border: '1px solid var(--semiont-border-primary)',
45
+ fontSize: 'var(--semiont-text-sm)',
46
+ display: 'flex',
47
+ flexDirection: 'column',
48
+ gap: '0.25rem',
49
+ }}>
50
+ <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
51
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>{t.motivationLabel}:</span>
52
+ <span className="semiont-chip" style={{ fontSize: 'var(--semiont-text-xs)', padding: '0.125rem 0.5rem' }}>
53
+ {annotation.motivation}
54
+ </span>
55
+ </div>
56
+ <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
57
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>{t.sourceResourceLabel}:</span>
58
+ <span style={{ color: 'var(--semiont-text-primary)' }}>{sourceResource.name}</span>
59
+ </div>
60
+ </div>
61
+ </div>
62
+
63
+ {/* Source Context Preview */}
64
+ {sourceContext && (
65
+ <div className="semiont-form__field">
66
+ <label className="semiont-form__label">
67
+ {t.sourceContextLabel}
68
+ </label>
69
+ <div style={{
70
+ padding: '0.75rem',
71
+ backgroundColor: 'var(--semiont-bg-secondary)',
72
+ borderRadius: 'var(--semiont-radius-md)',
73
+ border: '1px solid var(--semiont-border-primary)',
74
+ maxHeight: '200px',
75
+ overflowY: 'auto',
76
+ }}>
77
+ <div style={{ fontSize: 'var(--semiont-text-sm)', fontFamily: 'monospace', whiteSpace: 'pre-wrap', color: 'var(--semiont-text-secondary)' }}>
78
+ {sourceContext.before && <span>{sourceContext.before}</span>}
79
+ <span style={{
80
+ backgroundColor: 'var(--semiont-color-primary-100)',
81
+ padding: '0 0.25rem',
82
+ fontWeight: 600,
83
+ color: 'var(--semiont-color-primary-900)',
84
+ }}>
85
+ {sourceContext.selected}
86
+ </span>
87
+ {sourceContext.after && <span>{sourceContext.after}</span>}
88
+ </div>
89
+ </div>
90
+ </div>
91
+ )}
92
+
93
+ {/* Entity Types */}
94
+ {entityTypes.length > 0 && (
95
+ <div className="semiont-form__field">
96
+ <label className="semiont-form__label">
97
+ {t.entityTypesLabel}
98
+ </label>
99
+ <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.375rem' }}>
100
+ {entityTypes.map(et => (
101
+ <span key={et} className="semiont-chip" style={{ fontSize: 'var(--semiont-text-xs)', padding: '0.125rem 0.5rem' }}>
102
+ {et}
103
+ </span>
104
+ ))}
105
+ </div>
106
+ </div>
107
+ )}
108
+
109
+ {/* Graph Context */}
110
+ {graphContext && (connections.length > 0 || citedByCount > 0 || siblingEntityTypes.length > 0) && (
111
+ <div className="semiont-form__field">
112
+ <label className="semiont-form__label">
113
+ {t.graphContextLabel}
114
+ </label>
115
+ <div style={{
116
+ padding: '0.75rem',
117
+ backgroundColor: 'var(--semiont-bg-secondary)',
118
+ borderRadius: 'var(--semiont-radius-md)',
119
+ border: '1px solid var(--semiont-border-primary)',
120
+ fontSize: 'var(--semiont-text-sm)',
121
+ display: 'flex',
122
+ flexDirection: 'column',
123
+ gap: '0.5rem',
124
+ }}>
125
+ {/* Connections */}
126
+ {connections.length > 0 && (
127
+ <div>
128
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>{t.connectionsLabel}</span>
129
+ <ul style={{ marginTop: '0.25rem', display: 'flex', flexDirection: 'column', gap: '0.125rem', listStyle: 'none', padding: 0 }}>
130
+ {connections.map(conn => (
131
+ <li key={conn.resourceId} style={{ color: 'var(--semiont-text-secondary)', display: 'flex', alignItems: 'center', gap: '0.375rem' }}>
132
+ <span>{conn.resourceName}</span>
133
+ {conn.bidirectional && (
134
+ <span className="semiont-chip" style={{ fontSize: 'var(--semiont-text-xs)', padding: '0.125rem 0.375rem' }}>mutual</span>
135
+ )}
136
+ {conn.entityTypes && conn.entityTypes.length > 0 && (
137
+ <span style={{ fontSize: 'var(--semiont-text-xs)', color: 'var(--semiont-text-tertiary)' }}>
138
+ {conn.entityTypes.join(', ')}
139
+ </span>
140
+ )}
141
+ </li>
142
+ ))}
143
+ </ul>
144
+ </div>
145
+ )}
146
+
147
+ {/* Cited By */}
148
+ {citedByCount > 0 && (
149
+ <div>
150
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>
151
+ {t.citedByLabel} ({citedByCount})
152
+ </span>
153
+ {citedBy.length > 0 && (
154
+ <ul style={{ marginTop: '0.25rem', display: 'flex', flexDirection: 'column', gap: '0.125rem', listStyle: 'none', padding: 0 }}>
155
+ {citedBy.map(ref => (
156
+ <li key={ref.resourceId} style={{ color: 'var(--semiont-text-secondary)' }}>
157
+ {ref.resourceName}
158
+ </li>
159
+ ))}
160
+ </ul>
161
+ )}
162
+ </div>
163
+ )}
164
+
165
+ {/* Sibling Entity Types */}
166
+ {siblingEntityTypes.length > 0 && (
167
+ <div>
168
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>{t.siblingTypesLabel}</span>
169
+ <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.25rem', marginTop: '0.25rem' }}>
170
+ {siblingEntityTypes.map(et => (
171
+ <span key={et} className="semiont-chip" style={{ fontSize: 'var(--semiont-text-xs)', padding: '0.125rem 0.5rem' }}>
172
+ {et}
173
+ </span>
174
+ ))}
175
+ </div>
176
+ </div>
177
+ )}
178
+ </div>
179
+ </div>
180
+ )}
181
+ </>
182
+ );
183
+ }
@@ -0,0 +1,89 @@
1
+ 'use client';
2
+
3
+ import type { GatheredContext } from '@semiont/core';
4
+ import { ContextSummary } from './ContextSummary';
5
+ import type { ContextSummaryTranslations } from './ContextSummary';
6
+
7
+ export interface GatherContextStepProps {
8
+ context: GatheredContext | null;
9
+ contextLoading: boolean;
10
+ contextError: Error | null;
11
+ onCancel: () => void;
12
+ onBind: () => void;
13
+ onGenerate: () => void;
14
+ onCompose: () => void;
15
+ translations: {
16
+ title: string;
17
+ loadingContext: string;
18
+ failedContext: string;
19
+ cancel: string;
20
+ search: string;
21
+ generate: string;
22
+ compose: string;
23
+ } & ContextSummaryTranslations;
24
+ }
25
+
26
+ export function GatherContextStep({
27
+ context,
28
+ contextLoading,
29
+ contextError,
30
+ onCancel,
31
+ onBind,
32
+ onGenerate,
33
+ onCompose,
34
+ translations: t,
35
+ }: GatherContextStepProps) {
36
+ const contextReady = !contextLoading && !contextError && !!context;
37
+
38
+ return (
39
+ <>
40
+ {contextLoading && (
41
+ <div className="semiont-modal__empty-state" style={{ textAlign: 'center', padding: '1rem 0' }}>
42
+ {t.loadingContext}
43
+ </div>
44
+ )}
45
+ {!!contextError && (
46
+ <div style={{ textAlign: 'center', padding: '1rem 0', color: 'var(--semiont-color-red-600)' }}>
47
+ {t.failedContext}
48
+ </div>
49
+ )}
50
+
51
+ {context && <ContextSummary context={context} translations={t} />}
52
+
53
+ {/* Action Buttons */}
54
+ <div className="semiont-modal__actions" style={{ paddingTop: '0.5rem' }}>
55
+ <button
56
+ type="button"
57
+ onClick={onCancel}
58
+ className="semiont-button--secondary semiont-button--flex"
59
+ >
60
+ ✕ {t.cancel}
61
+ </button>
62
+ <button
63
+ type="button"
64
+ onClick={onBind}
65
+ disabled={!contextReady}
66
+ className="semiont-button--primary semiont-button--flex"
67
+ >
68
+ 🔍 {t.search}…
69
+ </button>
70
+ <button
71
+ type="button"
72
+ onClick={onGenerate}
73
+ disabled={!contextReady}
74
+ className="semiont-button--primary semiont-button--flex"
75
+ >
76
+ ✨ {t.generate}…
77
+ </button>
78
+ <button
79
+ type="button"
80
+ onClick={onCompose}
81
+ disabled={!contextReady}
82
+ className="semiont-button--secondary semiont-button--flex"
83
+ >
84
+ ✍️ {t.compose}
85
+ </button>
86
+ </div>
87
+ </>
88
+ );
89
+ }
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import React, { Fragment } from 'react';
3
+ import React from 'react';
4
4
  import { useTranslations } from '../../contexts/TranslationContext';
5
5
  import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild } from '@headlessui/react';
6
6
  import './modals.css';
@@ -91,12 +91,11 @@ export function KeyboardShortcutsHelpModal({ isOpen, onClose }: KeyboardShortcut
91
91
  const isMac = typeof window !== 'undefined' && navigator.platform.toUpperCase().indexOf('MAC') >= 0;
92
92
 
93
93
  return (
94
- <Transition appear show={isOpen} as={Fragment}>
94
+ <Transition appear show={isOpen}>
95
95
  <Dialog as="div" className="semiont-modal" onClose={onClose}>
96
96
  {/* Backdrop */}
97
97
  <TransitionChild
98
- as={Fragment}
99
- enter="ease-out duration-200"
98
+ enter="ease-out duration-200"
100
99
  enterFrom="opacity-0"
101
100
  enterTo="opacity-100"
102
101
  leave="ease-in duration-150"
@@ -110,8 +109,7 @@ export function KeyboardShortcutsHelpModal({ isOpen, onClose }: KeyboardShortcut
110
109
  <div className="semiont-modal__container">
111
110
  <div className="semiont-modal__wrapper">
112
111
  <TransitionChild
113
- as={Fragment}
114
- enter="ease-out duration-200"
112
+ enter="ease-out duration-200"
115
113
  enterFrom="opacity-0 scale-95"
116
114
  enterTo="opacity-100 scale-100"
117
115
  leave="ease-in duration-150"
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { useEffect, useState, Fragment } from 'react';
3
+ import { useEffect, useState } from 'react';
4
4
  import { Dialog, DialogPanel, DialogTitle, DialogDescription, Transition, TransitionChild } from '@headlessui/react';
5
5
  import { useEntityTypes } from '../../lib/api-hooks';
6
6
 
@@ -68,12 +68,11 @@ export function ProposeEntitiesModal({
68
68
  };
69
69
 
70
70
  return (
71
- <Transition appear show={isOpen} as={Fragment}>
71
+ <Transition appear show={isOpen}>
72
72
  <Dialog as="div" className="semiont-modal" onClose={onCancel}>
73
73
  {/* Backdrop */}
74
74
  <TransitionChild
75
- as={Fragment}
76
- enter="ease-out duration-200"
75
+ enter="ease-out duration-200"
77
76
  enterFrom="opacity-0"
78
77
  enterTo="opacity-100"
79
78
  leave="ease-in duration-150"
@@ -87,8 +86,7 @@ export function ProposeEntitiesModal({
87
86
  <div className="semiont-modal__container">
88
87
  <div className="semiont-modal__wrapper">
89
88
  <TransitionChild
90
- as={Fragment}
91
- enter="ease-out duration-200"
89
+ enter="ease-out duration-200"
92
90
  enterFrom="opacity-0 scale-95"
93
91
  enterTo="opacity-100 scale-100"
94
92
  leave="ease-in duration-150"