@semiont/react-ui 0.2.46 → 0.3.1

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 (215) 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-5REA6P4J.mjs} +48 -6
  4. package/dist/ar-5REA6P4J.mjs.map +1 -0
  5. package/dist/{bn-XOET3DOI.mjs → bn-YHRYHHPD.mjs} +48 -6
  6. package/dist/bn-YHRYHHPD.mjs.map +1 -0
  7. package/dist/{chunk-3JTO27MH.mjs → chunk-D4GAAQMM.mjs} +2 -9
  8. package/dist/{chunk-Q2KV6Y2J.mjs → chunk-PFQYNPQJ.mjs} +32 -32
  9. package/dist/{chunk-JH7BXE2P.mjs → chunk-VVCCMJS7.mjs} +47 -5
  10. package/dist/chunk-VVCCMJS7.mjs.map +1 -0
  11. package/dist/{cs-X63DXX7L.mjs → cs-JTJXTX2T.mjs} +48 -6
  12. package/dist/cs-JTJXTX2T.mjs.map +1 -0
  13. package/dist/{da-OWTCV57A.mjs → da-MK37SJB6.mjs} +48 -6
  14. package/dist/da-MK37SJB6.mjs.map +1 -0
  15. package/dist/{de-77BMFDVF.mjs → de-LGBCWERA.mjs} +48 -6
  16. package/dist/de-LGBCWERA.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-FKJMFCWY.mjs} +48 -6
  20. package/dist/el-FKJMFCWY.mjs.map +1 -0
  21. package/dist/{en-XWEPVTB4.mjs → en-AOSMPC2M.mjs} +5 -3
  22. package/dist/{es-726NTS53.mjs → es-LVDPIXWU.mjs} +48 -6
  23. package/dist/es-LVDPIXWU.mjs.map +1 -0
  24. package/dist/{fa-3N4CIWE6.mjs → fa-3VA2PIUD.mjs} +48 -6
  25. package/dist/fa-3VA2PIUD.mjs.map +1 -0
  26. package/dist/{fi-JOM3M7Z4.mjs → fi-3WM75ZLR.mjs} +48 -6
  27. package/dist/fi-3WM75ZLR.mjs.map +1 -0
  28. package/dist/{fr-56QSXS7E.mjs → fr-NK4A72WA.mjs} +48 -6
  29. package/dist/fr-NK4A72WA.mjs.map +1 -0
  30. package/dist/{he-SNAXPJEK.mjs → he-IACZDZMB.mjs} +48 -6
  31. package/dist/he-IACZDZMB.mjs.map +1 -0
  32. package/dist/{hi-CRBRD5TB.mjs → hi-JZ7MGMMS.mjs} +48 -6
  33. package/dist/hi-JZ7MGMMS.mjs.map +1 -0
  34. package/dist/{id-BRCVLICF.mjs → id-P3KDQGNK.mjs} +48 -6
  35. package/dist/id-P3KDQGNK.mjs.map +1 -0
  36. package/dist/index.css +123 -12
  37. package/dist/index.css.map +1 -1
  38. package/dist/index.d.mts +353 -107
  39. package/dist/index.mjs +3139 -1811
  40. package/dist/index.mjs.map +1 -1
  41. package/dist/{it-M2Z27BNB.mjs → it-LQS33SUY.mjs} +48 -6
  42. package/dist/it-LQS33SUY.mjs.map +1 -0
  43. package/dist/{ja-TZUKW7HD.mjs → ja-G4FKZPWD.mjs} +48 -6
  44. package/dist/ja-G4FKZPWD.mjs.map +1 -0
  45. package/dist/{ko-NKBGGOL6.mjs → ko-2XWKQ7BA.mjs} +48 -6
  46. package/dist/ko-2XWKQ7BA.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-2SNONIUD.mjs} +48 -6
  49. package/dist/ms-2SNONIUD.mjs.map +1 -0
  50. package/dist/{nl-MVYXAS5C.mjs → nl-BMZUAJ7J.mjs} +48 -6
  51. package/dist/nl-BMZUAJ7J.mjs.map +1 -0
  52. package/dist/{no-XOLO4JPV.mjs → no-6J3WIZ6L.mjs} +48 -6
  53. package/dist/no-6J3WIZ6L.mjs.map +1 -0
  54. package/dist/{pl-TRWLMMC4.mjs → pl-QQ7DAUVK.mjs} +48 -6
  55. package/dist/pl-QQ7DAUVK.mjs.map +1 -0
  56. package/dist/{pt-M3TE24UI.mjs → pt-MU3GN7MW.mjs} +48 -6
  57. package/dist/pt-MU3GN7MW.mjs.map +1 -0
  58. package/dist/{ro-QBFG2T64.mjs → ro-6GBE72QK.mjs} +48 -6
  59. package/dist/ro-6GBE72QK.mjs.map +1 -0
  60. package/dist/{sv-IUECBXWX.mjs → sv-NQIL7PEM.mjs} +48 -6
  61. package/dist/sv-NQIL7PEM.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-6OCNZQBE.mjs} +48 -6
  65. package/dist/th-6OCNZQBE.mjs.map +1 -0
  66. package/dist/{tr-DWJ2FFUK.mjs → tr-XWJ5P3SC.mjs} +48 -6
  67. package/dist/tr-XWJ5P3SC.mjs.map +1 -0
  68. package/dist/{uk-M4ZE4DPZ.mjs → uk-AKSN6DGW.mjs} +48 -6
  69. package/dist/uk-AKSN6DGW.mjs.map +1 -0
  70. package/dist/{vi-FERZNPSH.mjs → vi-23GHQ45M.mjs} +48 -6
  71. package/dist/vi-23GHQ45M.mjs.map +1 -0
  72. package/dist/{zh-3J2I3WYK.mjs → zh-ITT4QBSN.mjs} +48 -6
  73. package/dist/zh-ITT4QBSN.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 +202 -0
  82. package/src/components/modals/GatherContextStep.tsx +93 -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 +338 -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 +4 -7
  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/CommentEntry.tsx +10 -12
  102. package/src/components/resource/panels/HighlightEntry.tsx +9 -11
  103. package/src/components/resource/panels/ReferenceEntry.tsx +57 -104
  104. package/src/components/resource/panels/ReferencesPanel.css +94 -13
  105. package/src/components/resource/panels/ReferencesPanel.tsx +1 -2
  106. package/src/components/resource/panels/TagEntry.tsx +9 -11
  107. package/src/components/resource/panels/__tests__/AssistSection.test.tsx +7 -7
  108. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +2 -2
  109. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +64 -101
  110. package/src/components/resource/panels/__tests__/StatisticsPanel.test.tsx +1 -1
  111. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +3 -3
  112. package/src/components/viewers/ImageViewer.tsx +3 -6
  113. package/src/components/viewers/__tests__/ImageViewer.test.tsx +3 -3
  114. package/src/features/admin-devops/__tests__/AdminDevOpsPage.test.tsx +5 -5
  115. package/src/features/admin-exchange/__tests__/AdminExchangePage.test.tsx +141 -0
  116. package/src/features/admin-exchange/__tests__/ExportCard.test.tsx +41 -0
  117. package/src/features/admin-exchange/__tests__/ImportCard.test.tsx +148 -0
  118. package/src/features/admin-exchange/__tests__/ImportProgress.test.tsx +106 -0
  119. package/src/features/admin-exchange/components/AdminExchangePage.tsx +120 -0
  120. package/src/features/admin-exchange/components/ExportCard.tsx +35 -0
  121. package/src/features/admin-exchange/components/ImportCard.tsx +188 -0
  122. package/src/features/admin-exchange/components/ImportProgress.tsx +86 -0
  123. package/src/features/admin-security/__tests__/AdminSecurityPage.test.tsx +3 -3
  124. package/src/features/moderate-entity-tags/__tests__/EntityTagsPage.test.tsx +2 -2
  125. package/src/features/moderate-recent/__tests__/RecentDocumentsPage.test.tsx +4 -4
  126. package/src/features/moderate-tag-schemas/__tests__/TagSchemasPage.test.tsx +3 -3
  127. package/src/features/moderation-linked-data/__tests__/LinkedDataPage.test.tsx +117 -0
  128. package/src/features/moderation-linked-data/components/LinkedDataPage.tsx +121 -0
  129. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +5 -5
  130. package/src/features/resource-compose/components/ResourceComposePage.tsx +56 -1
  131. package/src/features/resource-discovery/__tests__/ResourceCard.test.tsx +1 -1
  132. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +2 -2
  133. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +3 -3
  134. package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +11 -10
  135. package/src/features/resource-viewer/__tests__/AnnotationProgressDismissal.test.tsx +2 -2
  136. package/src/features/resource-viewer/__tests__/BindFlowIntegration.test.tsx +22 -115
  137. package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +3 -3
  138. package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +20 -20
  139. package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +7 -7
  140. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +5 -21
  141. package/src/features/resource-viewer/__tests__/ToastNotifications.test.tsx +2 -2
  142. package/src/features/resource-viewer/__tests__/YieldFlowIntegration.test.tsx +45 -82
  143. package/src/features/resource-viewer/__tests__/annotation-progress-flow.test.tsx +4 -4
  144. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +146 -72
  145. package/src/integrations/tailwind-plugin.js +3 -3
  146. package/src/styles/core/buttons.css +31 -0
  147. package/src/styles/features/exchange.css +404 -0
  148. package/src/styles/index.css +1 -0
  149. package/translations/ar.json +44 -4
  150. package/translations/bn.json +44 -4
  151. package/translations/cs.json +44 -4
  152. package/translations/da.json +130 -90
  153. package/translations/de.json +124 -84
  154. package/translations/el.json +44 -4
  155. package/translations/en.json +44 -4
  156. package/translations/es.json +44 -4
  157. package/translations/fa.json +44 -4
  158. package/translations/fi.json +70 -30
  159. package/translations/fr.json +44 -4
  160. package/translations/he.json +44 -4
  161. package/translations/hi.json +44 -4
  162. package/translations/id.json +45 -5
  163. package/translations/it.json +64 -24
  164. package/translations/ja.json +45 -5
  165. package/translations/ko.json +44 -4
  166. package/translations/ms.json +45 -5
  167. package/translations/nl.json +43 -3
  168. package/translations/no.json +106 -66
  169. package/translations/pl.json +44 -4
  170. package/translations/pt.json +45 -5
  171. package/translations/ro.json +44 -4
  172. package/translations/sv.json +44 -4
  173. package/translations/th.json +44 -4
  174. package/translations/tr.json +44 -4
  175. package/translations/uk.json +44 -4
  176. package/translations/vi.json +44 -4
  177. package/translations/zh.json +44 -4
  178. package/dist/PdfAnnotationCanvas.client-COQREPXU.mjs.map +0 -1
  179. package/dist/ar-7SUXNE34.mjs.map +0 -1
  180. package/dist/bn-XOET3DOI.mjs.map +0 -1
  181. package/dist/chunk-JH7BXE2P.mjs.map +0 -1
  182. package/dist/cs-X63DXX7L.mjs.map +0 -1
  183. package/dist/da-OWTCV57A.mjs.map +0 -1
  184. package/dist/de-77BMFDVF.mjs.map +0 -1
  185. package/dist/el-FIBNLH2V.mjs.map +0 -1
  186. package/dist/es-726NTS53.mjs.map +0 -1
  187. package/dist/fa-3N4CIWE6.mjs.map +0 -1
  188. package/dist/fi-JOM3M7Z4.mjs.map +0 -1
  189. package/dist/fr-56QSXS7E.mjs.map +0 -1
  190. package/dist/he-SNAXPJEK.mjs.map +0 -1
  191. package/dist/hi-CRBRD5TB.mjs.map +0 -1
  192. package/dist/id-BRCVLICF.mjs.map +0 -1
  193. package/dist/it-M2Z27BNB.mjs.map +0 -1
  194. package/dist/ja-TZUKW7HD.mjs.map +0 -1
  195. package/dist/ko-NKBGGOL6.mjs.map +0 -1
  196. package/dist/ms-XFXPN6RX.mjs.map +0 -1
  197. package/dist/nl-MVYXAS5C.mjs.map +0 -1
  198. package/dist/no-XOLO4JPV.mjs.map +0 -1
  199. package/dist/pl-TRWLMMC4.mjs.map +0 -1
  200. package/dist/pt-M3TE24UI.mjs.map +0 -1
  201. package/dist/ro-QBFG2T64.mjs.map +0 -1
  202. package/dist/sv-IUECBXWX.mjs.map +0 -1
  203. package/dist/th-US7KIN5Q.mjs.map +0 -1
  204. package/dist/tr-DWJ2FFUK.mjs.map +0 -1
  205. package/dist/uk-M4ZE4DPZ.mjs.map +0 -1
  206. package/dist/vi-FERZNPSH.mjs.map +0 -1
  207. package/dist/zh-3J2I3WYK.mjs.map +0 -1
  208. package/src/examples/ButtonUsageExample.tsx +0 -242
  209. package/src/examples/button-css-modules.module.css +0 -164
  210. package/src/examples/button-styled-components.tsx +0 -215
  211. package/src/examples/button-tailwind.css +0 -51
  212. /package/dist/{chunk-3JTO27MH.mjs.map → chunk-D4GAAQMM.mjs.map} +0 -0
  213. /package/dist/{chunk-Q2KV6Y2J.mjs.map → chunk-PFQYNPQJ.mjs.map} +0 -0
  214. /package/dist/{en-XWEPVTB4.mjs.map → en-AOSMPC2M.mjs.map} +0 -0
  215. /package/dist/{magic-string.es-7FJ3LUGB.mjs.map → magic-string.es-K77I4ZQN.mjs.map} +0 -0
@@ -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,202 @@
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
+ userHintLabel: string;
16
+ userHintPlaceholder: string;
17
+ }
18
+
19
+ export interface ContextSummaryProps {
20
+ context: GatheredContext;
21
+ userHint?: string;
22
+ onUserHintChange?: (value: string) => void;
23
+ translations: ContextSummaryTranslations;
24
+ }
25
+
26
+ export function ContextSummary({ context, userHint, onUserHintChange, translations: t }: ContextSummaryProps) {
27
+ const annotation = context.annotation;
28
+ const sourceResource = context.sourceResource;
29
+ const sourceContext = context.sourceContext;
30
+ const graphContext = context.graphContext;
31
+ const entityTypes = context.metadata?.entityTypes ?? [];
32
+ const connections = graphContext?.connections ?? [];
33
+ const citedBy = graphContext?.citedBy ?? [];
34
+ const citedByCount = graphContext?.citedByCount ?? 0;
35
+ const siblingEntityTypes = graphContext?.siblingEntityTypes ?? [];
36
+
37
+ return (
38
+ <>
39
+ {/* Annotation & Source Resource */}
40
+ <div className="semiont-form__field">
41
+ <label className="semiont-form__label">
42
+ {t.annotationLabel}
43
+ </label>
44
+ <div style={{
45
+ padding: '0.5rem 0.75rem',
46
+ backgroundColor: 'var(--semiont-bg-secondary)',
47
+ borderRadius: 'var(--semiont-radius-md)',
48
+ border: '1px solid var(--semiont-border-primary)',
49
+ fontSize: 'var(--semiont-text-sm)',
50
+ display: 'flex',
51
+ flexDirection: 'column',
52
+ gap: '0.25rem',
53
+ }}>
54
+ <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
55
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>{t.motivationLabel}:</span>
56
+ <span className="semiont-chip" style={{ fontSize: 'var(--semiont-text-xs)', padding: '0.125rem 0.5rem' }}>
57
+ {annotation.motivation}
58
+ </span>
59
+ </div>
60
+ <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
61
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>{t.sourceResourceLabel}:</span>
62
+ <span style={{ color: 'var(--semiont-text-primary)' }}>{sourceResource.name}</span>
63
+ </div>
64
+ </div>
65
+ </div>
66
+
67
+ {/* Source Context Preview */}
68
+ {sourceContext && (
69
+ <div className="semiont-form__field">
70
+ <label className="semiont-form__label">
71
+ {t.sourceContextLabel}
72
+ </label>
73
+ <div style={{
74
+ padding: '0.75rem',
75
+ backgroundColor: 'var(--semiont-bg-secondary)',
76
+ borderRadius: 'var(--semiont-radius-md)',
77
+ border: '1px solid var(--semiont-border-primary)',
78
+ maxHeight: '200px',
79
+ overflowY: 'auto',
80
+ }}>
81
+ <div style={{ fontSize: 'var(--semiont-text-sm)', fontFamily: 'monospace', whiteSpace: 'pre-wrap', color: 'var(--semiont-text-secondary)' }}>
82
+ {sourceContext.before && <span>{sourceContext.before}</span>}
83
+ <span style={{
84
+ backgroundColor: 'var(--semiont-color-primary-100)',
85
+ padding: '0 0.25rem',
86
+ fontWeight: 600,
87
+ color: 'var(--semiont-color-primary-900)',
88
+ }}>
89
+ {sourceContext.selected}
90
+ </span>
91
+ {sourceContext.after && <span>{sourceContext.after}</span>}
92
+ </div>
93
+ </div>
94
+ </div>
95
+ )}
96
+
97
+ {/* Entity Types */}
98
+ {entityTypes.length > 0 && (
99
+ <div className="semiont-form__field">
100
+ <label className="semiont-form__label">
101
+ {t.entityTypesLabel}
102
+ </label>
103
+ <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.375rem' }}>
104
+ {entityTypes.map(et => (
105
+ <span key={et} className="semiont-chip" style={{ fontSize: 'var(--semiont-text-xs)', padding: '0.125rem 0.5rem' }}>
106
+ {et}
107
+ </span>
108
+ ))}
109
+ </div>
110
+ </div>
111
+ )}
112
+
113
+ {/* Graph Context */}
114
+ {graphContext && (connections.length > 0 || citedByCount > 0 || siblingEntityTypes.length > 0) && (
115
+ <div className="semiont-form__field">
116
+ <label className="semiont-form__label">
117
+ {t.graphContextLabel}
118
+ </label>
119
+ <div style={{
120
+ padding: '0.75rem',
121
+ backgroundColor: 'var(--semiont-bg-secondary)',
122
+ borderRadius: 'var(--semiont-radius-md)',
123
+ border: '1px solid var(--semiont-border-primary)',
124
+ fontSize: 'var(--semiont-text-sm)',
125
+ display: 'flex',
126
+ flexDirection: 'column',
127
+ gap: '0.5rem',
128
+ }}>
129
+ {/* Connections */}
130
+ {connections.length > 0 && (
131
+ <div>
132
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>{t.connectionsLabel}</span>
133
+ <ul style={{ marginTop: '0.25rem', display: 'flex', flexDirection: 'column', gap: '0.125rem', listStyle: 'none', padding: 0 }}>
134
+ {connections.map(conn => (
135
+ <li key={conn.resourceId} style={{ color: 'var(--semiont-text-secondary)', display: 'flex', alignItems: 'center', gap: '0.375rem' }}>
136
+ <span>{conn.resourceName}</span>
137
+ {conn.bidirectional && (
138
+ <span className="semiont-chip" style={{ fontSize: 'var(--semiont-text-xs)', padding: '0.125rem 0.375rem' }}>mutual</span>
139
+ )}
140
+ {conn.entityTypes && conn.entityTypes.length > 0 && (
141
+ <span style={{ fontSize: 'var(--semiont-text-xs)', color: 'var(--semiont-text-tertiary)' }}>
142
+ {conn.entityTypes.join(', ')}
143
+ </span>
144
+ )}
145
+ </li>
146
+ ))}
147
+ </ul>
148
+ </div>
149
+ )}
150
+
151
+ {/* Cited By */}
152
+ {citedByCount > 0 && (
153
+ <div>
154
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>
155
+ {t.citedByLabel} ({citedByCount})
156
+ </span>
157
+ {citedBy.length > 0 && (
158
+ <ul style={{ marginTop: '0.25rem', display: 'flex', flexDirection: 'column', gap: '0.125rem', listStyle: 'none', padding: 0 }}>
159
+ {citedBy.map(ref => (
160
+ <li key={ref.resourceId} style={{ color: 'var(--semiont-text-secondary)' }}>
161
+ {ref.resourceName}
162
+ </li>
163
+ ))}
164
+ </ul>
165
+ )}
166
+ </div>
167
+ )}
168
+
169
+ {/* Sibling Entity Types */}
170
+ {siblingEntityTypes.length > 0 && (
171
+ <div>
172
+ <span style={{ fontWeight: 500, color: 'var(--semiont-text-secondary)' }}>{t.siblingTypesLabel}</span>
173
+ <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.25rem', marginTop: '0.25rem' }}>
174
+ {siblingEntityTypes.map(et => (
175
+ <span key={et} className="semiont-chip" style={{ fontSize: 'var(--semiont-text-xs)', padding: '0.125rem 0.5rem' }}>
176
+ {et}
177
+ </span>
178
+ ))}
179
+ </div>
180
+ </div>
181
+ )}
182
+ </div>
183
+ </div>
184
+ )}
185
+
186
+ {/* User Hint */}
187
+ <div className="semiont-form__field">
188
+ <label className="semiont-form__label">
189
+ {t.userHintLabel}
190
+ </label>
191
+ <input
192
+ type="text"
193
+ value={userHint ?? ''}
194
+ onChange={onUserHintChange ? (e) => onUserHintChange(e.target.value) : undefined}
195
+ readOnly={!onUserHintChange}
196
+ placeholder={t.userHintPlaceholder}
197
+ className="semiont-search-modal__search-input"
198
+ />
199
+ </div>
200
+ </>
201
+ );
202
+ }
@@ -0,0 +1,93 @@
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
+ userHint: string;
12
+ onUserHintChange: (value: string) => void;
13
+ onCancel: () => void;
14
+ onBind: () => void;
15
+ onGenerate: () => void;
16
+ onCompose: () => void;
17
+ translations: {
18
+ title: string;
19
+ loadingContext: string;
20
+ failedContext: string;
21
+ cancel: string;
22
+ search: string;
23
+ generate: string;
24
+ compose: string;
25
+ } & ContextSummaryTranslations;
26
+ }
27
+
28
+ export function GatherContextStep({
29
+ context,
30
+ contextLoading,
31
+ contextError,
32
+ userHint,
33
+ onUserHintChange,
34
+ onCancel,
35
+ onBind,
36
+ onGenerate,
37
+ onCompose,
38
+ translations: t,
39
+ }: GatherContextStepProps) {
40
+ const contextReady = !contextLoading && !contextError && !!context;
41
+
42
+ return (
43
+ <>
44
+ {contextLoading && (
45
+ <div className="semiont-modal__empty-state" style={{ textAlign: 'center', padding: '1rem 0' }}>
46
+ {t.loadingContext}
47
+ </div>
48
+ )}
49
+ {!!contextError && (
50
+ <div style={{ textAlign: 'center', padding: '1rem 0', color: 'var(--semiont-color-red-600)' }}>
51
+ {t.failedContext}
52
+ </div>
53
+ )}
54
+
55
+ {context && <ContextSummary context={context} userHint={userHint} onUserHintChange={onUserHintChange} translations={t} />}
56
+
57
+ {/* Action Buttons */}
58
+ <div className="semiont-modal__actions" style={{ paddingTop: '0.5rem' }}>
59
+ <button
60
+ type="button"
61
+ onClick={onCancel}
62
+ className="semiont-button--secondary semiont-button--flex"
63
+ >
64
+ ✕ {t.cancel}
65
+ </button>
66
+ <button
67
+ type="button"
68
+ onClick={onBind}
69
+ disabled={!contextReady}
70
+ className="semiont-button--primary semiont-button--flex"
71
+ >
72
+ 🔍 {t.search}…
73
+ </button>
74
+ <button
75
+ type="button"
76
+ onClick={onGenerate}
77
+ disabled={!contextReady}
78
+ className="semiont-button--primary semiont-button--flex"
79
+ >
80
+ ✨ {t.generate}…
81
+ </button>
82
+ <button
83
+ type="button"
84
+ onClick={onCompose}
85
+ disabled={!contextReady}
86
+ className="semiont-button--secondary semiont-button--flex"
87
+ >
88
+ ✍️ {t.compose}
89
+ </button>
90
+ </div>
91
+ </>
92
+ );
93
+ }
@@ -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"