@semiont/react-ui 0.5.5 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -55
- package/dist/{PdfAnnotationCanvas.client-CN3C3S55.js → PdfAnnotationCanvas.client-NIMALXNZ.js} +7 -27
- package/dist/PdfAnnotationCanvas.client-NIMALXNZ.js.map +1 -0
- package/dist/{ar-U2EXWUMQ.js → ar-SONK6MON.js} +3 -7
- package/dist/ar-SONK6MON.js.map +1 -0
- package/dist/{bn-DRJGV772.js → bn-ZKPRITNG.js} +3 -7
- package/dist/bn-ZKPRITNG.js.map +1 -0
- package/dist/{chunk-3Q3TUKWP.js → chunk-Y2EEAOMZ.js} +29 -29
- package/dist/{cs-PTWDM23V.js → cs-LPXQ7NHQ.js} +3 -7
- package/dist/cs-LPXQ7NHQ.js.map +1 -0
- package/dist/{da-KSNIKYSS.js → da-6TKY7MCY.js} +6 -10
- package/dist/da-6TKY7MCY.js.map +1 -0
- package/dist/{de-F2XBEWFY.js → de-C3GNII74.js} +3 -7
- package/dist/de-C3GNII74.js.map +1 -0
- package/dist/{el-DLD2GWAP.js → el-UBCXQDJ7.js} +3 -7
- package/dist/el-UBCXQDJ7.js.map +1 -0
- package/dist/{es-WLPYWGB5.js → es-BQ23TRI7.js} +11 -15
- package/dist/es-BQ23TRI7.js.map +1 -0
- package/dist/{fa-BAXHSDZG.js → fa-AFTBZB77.js} +3 -7
- package/dist/fa-AFTBZB77.js.map +1 -0
- package/dist/{fi-FCHSYVOT.js → fi-WOYNLZC2.js} +3 -7
- package/dist/fi-WOYNLZC2.js.map +1 -0
- package/dist/{fr-3UERBSL6.js → fr-NDSMIFJM.js} +3 -7
- package/dist/fr-NDSMIFJM.js.map +1 -0
- package/dist/{he-F6F3FV2K.js → he-VJXVRDOY.js} +3 -7
- package/dist/he-VJXVRDOY.js.map +1 -0
- package/dist/{hi-4BK6IK7Q.js → hi-BF6PHIE2.js} +3 -7
- package/dist/hi-BF6PHIE2.js.map +1 -0
- package/dist/{id-7ECCWP3J.js → id-GXG5QCZY.js} +3 -7
- package/dist/id-GXG5QCZY.js.map +1 -0
- package/dist/index.css +103 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +271 -120
- package/dist/index.js +877 -698
- package/dist/index.js.map +1 -1
- package/dist/{it-234Z6XK6.js → it-XKHHCBAF.js} +3 -7
- package/dist/it-XKHHCBAF.js.map +1 -0
- package/dist/{ja-PJWQI4OQ.js → ja-TX7VM4XD.js} +3 -7
- package/dist/ja-TX7VM4XD.js.map +1 -0
- package/dist/{ko-APUEW2RS.js → ko-DNC7EQ7J.js} +3 -7
- package/dist/ko-DNC7EQ7J.js.map +1 -0
- package/dist/{ms-PJBZWZWD.js → ms-POZGBKPH.js} +3 -7
- package/dist/ms-POZGBKPH.js.map +1 -0
- package/dist/{nl-L4C3ZBCU.js → nl-IRMTKI7Z.js} +4 -11
- package/dist/nl-IRMTKI7Z.js.map +1 -0
- package/dist/{no-QE5N5KNG.js → no-ZUDJA4S6.js} +20 -24
- package/dist/no-ZUDJA4S6.js.map +1 -0
- package/dist/{pl-5Q2D23PD.js → pl-2NGAXL5U.js} +3 -7
- package/dist/pl-2NGAXL5U.js.map +1 -0
- package/dist/{pt-AIGUOIOC.js → pt-ABMCXZUM.js} +118 -122
- package/dist/pt-ABMCXZUM.js.map +1 -0
- package/dist/{ro-T56CSHTY.js → ro-VOJP6O5X.js} +3 -7
- package/dist/ro-VOJP6O5X.js.map +1 -0
- package/dist/{sv-L4TJQ2UH.js → sv-4HVFIIE5.js} +43 -47
- package/dist/sv-4HVFIIE5.js.map +1 -0
- package/dist/test-utils.js +2 -2
- package/dist/test-utils.js.map +1 -1
- package/dist/{th-6O7Y6O2Q.js → th-IFPZP3HQ.js} +3 -7
- package/dist/th-IFPZP3HQ.js.map +1 -0
- package/dist/{tr-D4CQCSNO.js → tr-2GYEAMJ4.js} +3 -7
- package/dist/tr-2GYEAMJ4.js.map +1 -0
- package/dist/{uk-2HMQG6ND.js → uk-XCJBVLLD.js} +3 -7
- package/dist/uk-XCJBVLLD.js.map +1 -0
- package/dist/{vi-XVJ4RUEJ.js → vi-4FR7CB2F.js} +3 -7
- package/dist/vi-4FR7CB2F.js.map +1 -0
- package/dist/{zh-K2KDPGHK.js → zh-NSKFOINB.js} +3 -7
- package/dist/zh-NSKFOINB.js.map +1 -0
- package/package.json +17 -13
- package/src/components/Button/__tests__/Button.test.tsx +0 -2
- package/src/components/CodeMirrorRenderer.tsx +2 -0
- package/src/components/ErrorBoundary.tsx +0 -9
- package/src/components/ProtectedErrorBoundary.css +119 -0
- package/src/components/ProtectedErrorBoundary.tsx +24 -15
- package/src/components/__tests__/AnnotateReferencesProgressWidget.test.tsx +0 -1
- package/src/components/__tests__/ErrorBoundary.test.tsx +20 -13
- package/src/components/__tests__/LiveRegion.hooks.test.tsx +1 -1
- package/src/components/__tests__/ProtectedErrorBoundary.test.tsx +2 -1
- package/src/components/__tests__/ResizeHandle.test.tsx +0 -1
- package/src/components/__tests__/SessionExpiryBanner.test.tsx +0 -1
- package/src/components/__tests__/StatusDisplay.test.tsx +0 -1
- package/src/components/__tests__/Toast.test.tsx +2 -3
- package/src/components/__tests__/Toolbar.test.tsx +0 -1
- package/src/components/annotation/annotations.css +14 -0
- package/src/components/annotation-popups/__tests__/JsonLdView.test.tsx +3 -5
- package/src/components/annotation-popups/__tests__/SharedPopupElements.test.tsx +0 -1
- package/src/components/branding/__tests__/SemiontBranding.test.tsx +1 -2
- package/src/components/layout/__tests__/LeftSidebar.test.tsx +5 -6
- package/src/components/layout/__tests__/PageLayout.test.tsx +1 -3
- package/src/components/layout/__tests__/SkipLinks.a11y.test.tsx +8 -8
- package/src/components/layout/__tests__/UnifiedHeader.test.tsx +12 -1
- package/src/components/modals/__tests__/KeyboardShortcutsHelpModal.test.tsx +0 -1
- package/src/components/modals/__tests__/PermissionDeniedModal.test.tsx +3 -4
- package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +1 -2
- package/src/components/modals/__tests__/SearchModal.basic.test.tsx +1 -1
- package/src/components/modals/__tests__/SearchModal.keyboard.test.tsx +0 -5
- package/src/components/modals/__tests__/SearchModal.search-wiring.test.tsx +1 -2
- package/src/components/modals/__tests__/SearchModal.visual.test.tsx +2 -2
- package/src/components/modals/__tests__/SessionExpiredModal.test.tsx +0 -1
- package/src/components/navigation/NavigationMenu.tsx +1 -1
- package/src/components/navigation/__tests__/Footer.a11y.test.tsx +4 -0
- package/src/components/navigation/__tests__/Footer.test.tsx +3 -6
- package/src/components/navigation/__tests__/NavigationMenu.a11y.test.tsx +1 -1
- package/src/components/navigation/__tests__/NavigationMenu.test.tsx +7 -9
- package/src/components/navigation/__tests__/ObservableLink.test.tsx +0 -1
- package/src/components/navigation/__tests__/SimpleNavigation.test.tsx +1 -2
- package/src/components/navigation/__tests__/SortableResourceTab.test.tsx +0 -1
- package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +6 -4
- package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +10 -19
- package/src/components/resource/AnnotateView.tsx +35 -37
- package/src/components/resource/BrowseView.tsx +31 -31
- package/src/components/resource/__tests__/AnnotationHistory.test.tsx +0 -1
- package/src/components/resource/__tests__/BrowseView.test.tsx +12 -14
- package/src/components/resource/__tests__/HistoryEvent.test.tsx +0 -5
- package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +4 -6
- package/src/components/resource/__tests__/event-formatting.test.ts +1 -1
- package/src/components/resource/panels/CollaborationPanel.tsx +1 -1
- package/src/components/resource/panels/JsonLdPanel.tsx +33 -16
- package/src/components/resource/panels/ReferencesPanel.tsx +1 -1
- package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +4 -5
- package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +8 -7
- package/src/components/resource/panels/__tests__/AssistSection.test.tsx +14 -10
- package/src/components/resource/panels/__tests__/CollaborationPanel.test.tsx +0 -1
- package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +31 -18
- package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +7 -6
- package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +5 -6
- package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +19 -13
- package/src/components/resource/panels/__tests__/JsonLdPanel.test.tsx +95 -426
- package/src/components/resource/panels/__tests__/PanelHeader.test.tsx +0 -1
- package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +5 -5
- package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +40 -7
- package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +4 -4
- package/src/components/resource/panels/__tests__/StatisticsPanel.test.tsx +30 -32
- package/src/components/resource/panels/__tests__/TagEntry.test.tsx +6 -6
- package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +7 -6
- package/src/components/settings/__tests__/SettingsPanel.test.tsx +0 -1
- package/src/components/viewers/__tests__/ImageViewer.test.tsx +0 -1
- package/src/features/admin-exchange/__tests__/AdminExchangePage.test.tsx +7 -10
- package/src/features/admin-exchange/__tests__/ImportProgress.test.tsx +38 -27
- package/src/features/admin-exchange/components/ImportProgress.tsx +28 -34
- package/src/features/auth/__tests__/SignInForm.a11y.test.tsx +2 -0
- package/src/features/auth/__tests__/SignUpForm.a11y.test.tsx +11 -12
- package/src/features/auth/__tests__/SignUpForm.test.tsx +3 -3
- package/src/features/moderate-tag-schemas/components/TagSchemasPage.tsx +1 -0
- package/src/features/moderation-linked-data/__tests__/LinkedDataPage.test.tsx +11 -9
- package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +2 -1
- package/src/features/resource-compose/components/ResourceComposePage.tsx +36 -9
- package/src/features/resource-compose/state/compose-page-state-unit.ts +5 -8
- package/src/features/resource-discovery/__tests__/ResourceCard.test.tsx +0 -1
- package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +33 -35
- package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +12 -11
- package/src/features/resource-discovery/state/__tests__/discover-state-unit.test.ts +204 -11
- package/src/features/resource-discovery/state/discover-state-unit.ts +70 -11
- package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +2 -2
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +10 -7
- package/src/features/resource-viewer/state/__tests__/resource-viewer-page-state-unit.test.ts +37 -1
- package/src/features/resource-viewer/state/resource-viewer-page-state-unit.ts +14 -7
- package/src/integrations/__tests__/css-modules-helper.test.tsx +2 -3
- package/src/integrations/__tests__/styled-components-theme.test.ts +1 -3
- package/src/styles/features/exchange.css +0 -30
- package/src/styles/index.css +1 -0
- package/translations/ar.json +1 -3
- package/translations/bn.json +1 -3
- package/translations/cs.json +1 -3
- package/translations/da.json +4 -6
- package/translations/de.json +1 -3
- package/translations/el.json +1 -3
- package/translations/es.json +9 -11
- package/translations/fa.json +1 -3
- package/translations/fi.json +1 -3
- package/translations/fr.json +1 -3
- package/translations/he.json +1 -3
- package/translations/hi.json +1 -3
- package/translations/id.json +1 -3
- package/translations/it.json +1 -3
- package/translations/ja.json +1 -3
- package/translations/ko.json +1 -3
- package/translations/ms.json +1 -3
- package/translations/nl.json +2 -7
- package/translations/no.json +18 -20
- package/translations/pl.json +1 -3
- package/translations/pt.json +116 -118
- package/translations/ro.json +1 -3
- package/translations/sv.json +41 -43
- package/translations/th.json +1 -3
- package/translations/tr.json +1 -3
- package/translations/uk.json +1 -3
- package/translations/vi.json +1 -3
- package/translations/zh.json +1 -3
- package/dist/PdfAnnotationCanvas.client-CN3C3S55.js.map +0 -1
- package/dist/ar-U2EXWUMQ.js.map +0 -1
- package/dist/bn-DRJGV772.js.map +0 -1
- package/dist/cs-PTWDM23V.js.map +0 -1
- package/dist/da-KSNIKYSS.js.map +0 -1
- package/dist/de-F2XBEWFY.js.map +0 -1
- package/dist/el-DLD2GWAP.js.map +0 -1
- package/dist/es-WLPYWGB5.js.map +0 -1
- package/dist/fa-BAXHSDZG.js.map +0 -1
- package/dist/fi-FCHSYVOT.js.map +0 -1
- package/dist/fr-3UERBSL6.js.map +0 -1
- package/dist/he-F6F3FV2K.js.map +0 -1
- package/dist/hi-4BK6IK7Q.js.map +0 -1
- package/dist/id-7ECCWP3J.js.map +0 -1
- package/dist/it-234Z6XK6.js.map +0 -1
- package/dist/ja-PJWQI4OQ.js.map +0 -1
- package/dist/ko-APUEW2RS.js.map +0 -1
- package/dist/ms-PJBZWZWD.js.map +0 -1
- package/dist/nl-L4C3ZBCU.js.map +0 -1
- package/dist/no-QE5N5KNG.js.map +0 -1
- package/dist/pl-5Q2D23PD.js.map +0 -1
- package/dist/pt-AIGUOIOC.js.map +0 -1
- package/dist/ro-T56CSHTY.js.map +0 -1
- package/dist/sv-L4TJQ2UH.js.map +0 -1
- package/dist/th-6O7Y6O2Q.js.map +0 -1
- package/dist/tr-D4CQCSNO.js.map +0 -1
- package/dist/uk-2HMQG6ND.js.map +0 -1
- package/dist/vi-XVJ4RUEJ.js.map +0 -1
- package/dist/zh-K2KDPGHK.js.map +0 -1
- /package/dist/{chunk-3Q3TUKWP.js.map → chunk-Y2EEAOMZ.js.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semiont/react-ui",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": ">=24.0.0"
|
|
6
|
+
},
|
|
4
7
|
"description": "React components and hooks for Semiont",
|
|
5
8
|
"type": "module",
|
|
6
9
|
"main": "./dist/index.js",
|
|
@@ -74,25 +77,26 @@
|
|
|
74
77
|
"test:split:coverage": "npm run test:coverage"
|
|
75
78
|
},
|
|
76
79
|
"peerDependencies": {
|
|
77
|
-
"react": "^
|
|
78
|
-
"react-dom": "^
|
|
80
|
+
"react": "^19.0.0",
|
|
81
|
+
"react-dom": "^19.0.0"
|
|
79
82
|
},
|
|
80
83
|
"devDependencies": {
|
|
81
84
|
"@testing-library/jest-dom": "^6.1.5",
|
|
82
85
|
"@testing-library/react": "^16.1.0",
|
|
83
|
-
"@types/react": "^19",
|
|
86
|
+
"@types/react": "^19.2.16",
|
|
84
87
|
"@types/react-dom": "^19",
|
|
85
|
-
"@vitest/coverage-v8": "^4.1.
|
|
86
|
-
"autoprefixer": "^10.
|
|
87
|
-
"axe-core": "^4.11.
|
|
88
|
-
"cssnano": "^
|
|
88
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
89
|
+
"autoprefixer": "^10.5.0",
|
|
90
|
+
"axe-core": "^4.11.4",
|
|
91
|
+
"cssnano": "^8.0.1",
|
|
89
92
|
"jest-axe": "^10.0.0",
|
|
90
|
-
"jsdom": "^
|
|
93
|
+
"jsdom": "^29.1.1",
|
|
91
94
|
"postcss-import": "^16.1.1",
|
|
92
|
-
"rollup": "^4.
|
|
95
|
+
"rollup": "^4.61.0",
|
|
93
96
|
"rollup-plugin-dts": "^6.4.1",
|
|
94
97
|
"tsup": "^8.0.1",
|
|
95
|
-
"typescript": "^6.0.2"
|
|
98
|
+
"typescript": "^6.0.2",
|
|
99
|
+
"vitest": "^4.1.8"
|
|
96
100
|
},
|
|
97
101
|
"publishConfig": {
|
|
98
102
|
"access": "public"
|
|
@@ -105,9 +109,9 @@
|
|
|
105
109
|
"directory": "packages/react-ui"
|
|
106
110
|
},
|
|
107
111
|
"dependencies": {
|
|
108
|
-
"@semiont/
|
|
112
|
+
"@semiont/http-transport": "*",
|
|
109
113
|
"@semiont/core": "*",
|
|
110
114
|
"@semiont/sdk": "*",
|
|
111
|
-
"react-error-boundary": "^
|
|
115
|
+
"react-error-boundary": "^6.1.2"
|
|
112
116
|
}
|
|
113
117
|
}
|
|
@@ -157,7 +157,6 @@ describe('Button Component', () => {
|
|
|
157
157
|
const icon = <span data-testid="left-icon">←</span>;
|
|
158
158
|
render(<Button leftIcon={icon}>Button</Button>);
|
|
159
159
|
|
|
160
|
-
const button = screen.getByRole('button');
|
|
161
160
|
const leftIcon = screen.getByTestId('left-icon');
|
|
162
161
|
const iconWrapper = leftIcon.parentElement;
|
|
163
162
|
|
|
@@ -169,7 +168,6 @@ describe('Button Component', () => {
|
|
|
169
168
|
const icon = <span data-testid="right-icon">→</span>;
|
|
170
169
|
render(<Button rightIcon={icon}>Button</Button>);
|
|
171
170
|
|
|
172
|
-
const button = screen.getByRole('button');
|
|
173
171
|
const rightIcon = screen.getByTestId('right-icon');
|
|
174
172
|
const iconWrapper = rightIcon.parentElement;
|
|
175
173
|
|
|
@@ -81,6 +81,8 @@ function buildAnnotationDecorations(
|
|
|
81
81
|
attributes: {
|
|
82
82
|
'data-annotation-id': meta.annotationId,
|
|
83
83
|
'data-annotation-type': meta.annotationType,
|
|
84
|
+
...(meta.strategy ? { 'data-anchor-strategy': meta.strategy } : {}),
|
|
85
|
+
...(meta.confidence ? { 'data-anchor-confidence': meta.confidence } : {}),
|
|
84
86
|
title: meta.tooltip,
|
|
85
87
|
},
|
|
86
88
|
});
|
|
@@ -11,7 +11,6 @@ interface Props {
|
|
|
11
11
|
interface State {
|
|
12
12
|
hasError: boolean;
|
|
13
13
|
error: Error | null;
|
|
14
|
-
errorInfo: ErrorInfo | null;
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
/**
|
|
@@ -24,7 +23,6 @@ export class ErrorBoundary extends Component<Props, State> {
|
|
|
24
23
|
this.state = {
|
|
25
24
|
hasError: false,
|
|
26
25
|
error: null,
|
|
27
|
-
errorInfo: null,
|
|
28
26
|
};
|
|
29
27
|
}
|
|
30
28
|
|
|
@@ -33,7 +31,6 @@ export class ErrorBoundary extends Component<Props, State> {
|
|
|
33
31
|
return {
|
|
34
32
|
hasError: true,
|
|
35
33
|
error,
|
|
36
|
-
errorInfo: null,
|
|
37
34
|
};
|
|
38
35
|
}
|
|
39
36
|
|
|
@@ -48,11 +45,6 @@ export class ErrorBoundary extends Component<Props, State> {
|
|
|
48
45
|
this.props.onError(error, errorInfo);
|
|
49
46
|
}
|
|
50
47
|
|
|
51
|
-
// Update state with error info
|
|
52
|
-
this.setState({
|
|
53
|
-
errorInfo,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
48
|
// In production, you might want to log to an error reporting service
|
|
57
49
|
// Example: logErrorToService(error, errorInfo);
|
|
58
50
|
}
|
|
@@ -61,7 +53,6 @@ export class ErrorBoundary extends Component<Props, State> {
|
|
|
61
53
|
this.setState({
|
|
62
54
|
hasError: false,
|
|
63
55
|
error: null,
|
|
64
|
-
errorInfo: null,
|
|
65
56
|
});
|
|
66
57
|
};
|
|
67
58
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
ProtectedErrorBoundary Component Styles
|
|
3
|
+
============================================ */
|
|
4
|
+
|
|
5
|
+
.semiont-protected-error-boundary-container {
|
|
6
|
+
min-height: 400px;
|
|
7
|
+
display: flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
padding: var(--semiont-spacing-md);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.semiont-protected-error-boundary-card {
|
|
14
|
+
max-width: 28rem;
|
|
15
|
+
width: 100%;
|
|
16
|
+
background-color: var(--semiont-color-white);
|
|
17
|
+
border-radius: var(--semiont-radius-lg);
|
|
18
|
+
box-shadow: var(--semiont-shadow-lg);
|
|
19
|
+
padding: var(--semiont-spacing-lg);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
[data-theme="dark"] .semiont-protected-error-boundary-card {
|
|
23
|
+
background-color: var(--semiont-color-gray-800);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.semiont-protected-error-boundary-header {
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
gap: 0.75rem;
|
|
30
|
+
margin-bottom: var(--semiont-spacing-md);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.semiont-protected-error-boundary-icon-wrapper {
|
|
34
|
+
flex-shrink: 0;
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
width: 2.5rem;
|
|
39
|
+
height: 2.5rem;
|
|
40
|
+
border-radius: var(--semiont-radius-full);
|
|
41
|
+
background-color: var(--semiont-color-red-100);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
[data-theme="dark"] .semiont-protected-error-boundary-icon-wrapper {
|
|
45
|
+
background-color: rgba(127, 29, 29, 0.3);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.semiont-protected-error-boundary-icon {
|
|
49
|
+
width: 1.5rem;
|
|
50
|
+
height: 1.5rem;
|
|
51
|
+
color: var(--semiont-color-red-600);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
[data-theme="dark"] .semiont-protected-error-boundary-icon {
|
|
55
|
+
color: var(--semiont-color-red-400);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.semiont-protected-error-boundary-title {
|
|
59
|
+
font-size: var(--semiont-text-xl);
|
|
60
|
+
font-weight: var(--semiont-font-semibold);
|
|
61
|
+
color: var(--semiont-color-gray-900);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
[data-theme="dark"] .semiont-protected-error-boundary-title {
|
|
65
|
+
color: var(--semiont-color-white);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.semiont-protected-error-boundary-message {
|
|
69
|
+
color: var(--semiont-color-gray-600);
|
|
70
|
+
margin-bottom: var(--semiont-spacing-lg);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
[data-theme="dark"] .semiont-protected-error-boundary-message {
|
|
74
|
+
color: var(--semiont-color-gray-300);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.semiont-protected-error-boundary-details {
|
|
78
|
+
margin-bottom: var(--semiont-spacing-md);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.semiont-protected-error-boundary-summary {
|
|
82
|
+
font-size: var(--semiont-text-sm);
|
|
83
|
+
color: var(--semiont-color-gray-500);
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.semiont-protected-error-boundary-summary:hover {
|
|
88
|
+
color: var(--semiont-color-gray-700);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
[data-theme="dark"] .semiont-protected-error-boundary-summary {
|
|
92
|
+
color: var(--semiont-color-gray-500);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
[data-theme="dark"] .semiont-protected-error-boundary-summary:hover {
|
|
96
|
+
color: var(--semiont-color-gray-300);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.semiont-protected-error-boundary-stack {
|
|
100
|
+
margin-top: var(--semiont-spacing-sm);
|
|
101
|
+
font-size: var(--semiont-text-xs);
|
|
102
|
+
background-color: var(--semiont-color-gray-100);
|
|
103
|
+
padding: var(--semiont-spacing-sm);
|
|
104
|
+
border-radius: var(--semiont-radius-sm);
|
|
105
|
+
overflow: auto;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
[data-theme="dark"] .semiont-protected-error-boundary-stack {
|
|
109
|
+
background-color: var(--semiont-color-gray-900);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.semiont-protected-error-boundary-actions {
|
|
113
|
+
display: flex;
|
|
114
|
+
gap: 0.75rem;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.semiont-protected-error-boundary-actions .semiont-button {
|
|
118
|
+
flex: 1 1 0;
|
|
119
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ErrorBoundary, type FallbackProps } from 'react-error-boundary';
|
|
3
|
+
import './ProtectedErrorBoundary.css';
|
|
3
4
|
|
|
4
5
|
interface ProtectedErrorBoundaryProps {
|
|
5
6
|
children: React.ReactNode;
|
|
@@ -45,46 +46,54 @@ export function ProtectedErrorBoundary({
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
function ProtectedErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
|
49
|
+
// react-error-boundary v6 types `error` as `unknown` — a thrown value can be
|
|
50
|
+
// anything, so narrow before reading Error fields.
|
|
51
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
52
|
+
const stack = error instanceof Error ? error.stack : undefined;
|
|
48
53
|
return (
|
|
49
|
-
<div className="
|
|
50
|
-
<div className="
|
|
51
|
-
<div className="
|
|
52
|
-
<div className="
|
|
53
|
-
<svg className="
|
|
54
|
+
<div className="semiont-protected-error-boundary-container">
|
|
55
|
+
<div className="semiont-protected-error-boundary-card">
|
|
56
|
+
<div className="semiont-protected-error-boundary-header">
|
|
57
|
+
<div className="semiont-protected-error-boundary-icon-wrapper">
|
|
58
|
+
<svg className="semiont-protected-error-boundary-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
54
59
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
|
55
60
|
</svg>
|
|
56
61
|
</div>
|
|
57
|
-
<h2 className="
|
|
62
|
+
<h2 className="semiont-protected-error-boundary-title">
|
|
58
63
|
Something went wrong
|
|
59
64
|
</h2>
|
|
60
65
|
</div>
|
|
61
66
|
|
|
62
|
-
<p className="
|
|
67
|
+
<p className="semiont-protected-error-boundary-message">
|
|
63
68
|
An unexpected error occurred. Try again, or refresh the page.
|
|
64
69
|
</p>
|
|
65
70
|
|
|
66
71
|
{process.env.NODE_ENV === 'development' && (
|
|
67
|
-
<details className="
|
|
68
|
-
<summary className="
|
|
72
|
+
<details className="semiont-protected-error-boundary-details">
|
|
73
|
+
<summary className="semiont-protected-error-boundary-summary">
|
|
69
74
|
Error details (development only)
|
|
70
75
|
</summary>
|
|
71
|
-
<pre className="
|
|
72
|
-
{
|
|
73
|
-
{
|
|
76
|
+
<pre className="semiont-protected-error-boundary-stack">
|
|
77
|
+
{message}
|
|
78
|
+
{stack}
|
|
74
79
|
</pre>
|
|
75
80
|
</details>
|
|
76
81
|
)}
|
|
77
82
|
|
|
78
|
-
<div className="
|
|
83
|
+
<div className="semiont-protected-error-boundary-actions">
|
|
79
84
|
<button
|
|
80
85
|
onClick={resetErrorBoundary}
|
|
81
|
-
className="
|
|
86
|
+
className="semiont-button"
|
|
87
|
+
data-variant="secondary"
|
|
88
|
+
data-size="md"
|
|
82
89
|
>
|
|
83
90
|
Try Again
|
|
84
91
|
</button>
|
|
85
92
|
<button
|
|
86
93
|
onClick={() => window.location.reload()}
|
|
87
|
-
className="
|
|
94
|
+
className="semiont-button"
|
|
95
|
+
data-variant="primary"
|
|
96
|
+
data-size="md"
|
|
88
97
|
>
|
|
89
98
|
Refresh Page
|
|
90
99
|
</button>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
3
|
import { render, screen, fireEvent } from '@testing-library/react';
|
|
4
4
|
import '@testing-library/jest-dom';
|
|
5
5
|
import { ErrorBoundary, AsyncErrorBoundary } from '../ErrorBoundary';
|
|
@@ -146,7 +146,7 @@ describe('ErrorBoundary Component', () => {
|
|
|
146
146
|
});
|
|
147
147
|
|
|
148
148
|
it('should not render default fallback when custom fallback is provided', () => {
|
|
149
|
-
const customFallback = (
|
|
149
|
+
const customFallback = () => <div>Custom Fallback</div>;
|
|
150
150
|
|
|
151
151
|
render(
|
|
152
152
|
<ErrorBoundary fallback={customFallback}>
|
|
@@ -223,7 +223,7 @@ describe('ErrorBoundary Component', () => {
|
|
|
223
223
|
|
|
224
224
|
it('should call custom reset handler in custom fallback', () => {
|
|
225
225
|
const resetHandler = vi.fn();
|
|
226
|
-
const customFallback = (
|
|
226
|
+
const customFallback = (_error: Error, reset: () => void) => (
|
|
227
227
|
<div>
|
|
228
228
|
<button onClick={() => { resetHandler(); reset(); }}>Reset</button>
|
|
229
229
|
</div>
|
|
@@ -242,9 +242,9 @@ describe('ErrorBoundary Component', () => {
|
|
|
242
242
|
});
|
|
243
243
|
|
|
244
244
|
it('should clear error state when reset is called', () => {
|
|
245
|
-
|
|
245
|
+
const resetRef: { current: (() => void) | null } = { current: null };
|
|
246
246
|
const customFallback = (error: Error, reset: () => void) => {
|
|
247
|
-
|
|
247
|
+
resetRef.current = reset;
|
|
248
248
|
return <div>Error: {error.message}</div>;
|
|
249
249
|
};
|
|
250
250
|
|
|
@@ -255,11 +255,11 @@ describe('ErrorBoundary Component', () => {
|
|
|
255
255
|
);
|
|
256
256
|
|
|
257
257
|
expect(screen.getByText('Error: Initial error')).toBeInTheDocument();
|
|
258
|
-
expect(
|
|
258
|
+
expect(resetRef.current).not.toBeNull();
|
|
259
259
|
|
|
260
260
|
// Call reset
|
|
261
|
-
if (
|
|
262
|
-
|
|
261
|
+
if (resetRef.current) {
|
|
262
|
+
resetRef.current();
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
// Rerender with non-throwing component after reset
|
|
@@ -286,8 +286,11 @@ describe('ErrorBoundary Component', () => {
|
|
|
286
286
|
|
|
287
287
|
it('should navigate to home when Go Home button clicked', () => {
|
|
288
288
|
const originalLocation = window.location;
|
|
289
|
-
|
|
290
|
-
|
|
289
|
+
Object.defineProperty(window, 'location', {
|
|
290
|
+
value: { href: '' },
|
|
291
|
+
writable: true,
|
|
292
|
+
configurable: true,
|
|
293
|
+
});
|
|
291
294
|
|
|
292
295
|
render(
|
|
293
296
|
<ErrorBoundary>
|
|
@@ -300,7 +303,11 @@ describe('ErrorBoundary Component', () => {
|
|
|
300
303
|
|
|
301
304
|
expect(window.location.href).toBe('/');
|
|
302
305
|
|
|
303
|
-
window
|
|
306
|
+
Object.defineProperty(window, 'location', {
|
|
307
|
+
value: originalLocation,
|
|
308
|
+
writable: true,
|
|
309
|
+
configurable: true,
|
|
310
|
+
});
|
|
304
311
|
});
|
|
305
312
|
});
|
|
306
313
|
|
|
@@ -336,7 +343,7 @@ describe('ErrorBoundary Component', () => {
|
|
|
336
343
|
|
|
337
344
|
describe('Edge Cases', () => {
|
|
338
345
|
it('should handle error with no message', () => {
|
|
339
|
-
function ThrowEmptyError() {
|
|
346
|
+
function ThrowEmptyError(): ReactNode {
|
|
340
347
|
throw new Error();
|
|
341
348
|
}
|
|
342
349
|
|
|
@@ -433,7 +440,7 @@ describe('AsyncErrorBoundary Component', () => {
|
|
|
433
440
|
});
|
|
434
441
|
|
|
435
442
|
it('should handle error with no message', () => {
|
|
436
|
-
function ThrowEmptyError() {
|
|
443
|
+
function ThrowEmptyError(): ReactNode {
|
|
437
444
|
throw new Error();
|
|
438
445
|
}
|
|
439
446
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { renderHook, act } from '@testing-library/react';
|
|
4
|
-
import { render
|
|
4
|
+
import { render } from '@testing-library/react';
|
|
5
5
|
import '@testing-library/jest-dom';
|
|
6
6
|
import {
|
|
7
7
|
LiveRegionProvider,
|
|
@@ -186,7 +186,8 @@ describe('ProtectedErrorBoundary', () => {
|
|
|
186
186
|
// Multiple console.error calls happen (React's own logs, plus ours).
|
|
187
187
|
// Look for the boundary's prefix specifically.
|
|
188
188
|
const ourCall = consoleErrorSpy.mock.calls.find(
|
|
189
|
-
call
|
|
189
|
+
(call: Parameters<typeof console.error>) =>
|
|
190
|
+
typeof call[0] === 'string' && call[0].includes('ProtectedErrorBoundary caught:')
|
|
190
191
|
);
|
|
191
192
|
expect(ourCall).toBeDefined();
|
|
192
193
|
} finally {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { render, screen
|
|
3
|
-
import
|
|
4
|
-
import { ToastProvider, useToast, ToastContainer, type ToastMessage } from '../Toast';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { ToastProvider, useToast } from '../Toast';
|
|
5
4
|
|
|
6
5
|
describe('Toast System', () => {
|
|
7
6
|
beforeEach(() => {
|
|
@@ -36,6 +36,20 @@
|
|
|
36
36
|
position: relative;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/* Low-confidence anchor affordance.
|
|
40
|
+
*
|
|
41
|
+
* Annotations whose anchor was resolved by something other than a clean
|
|
42
|
+
* fast-path or unique-occurrence match (i.e. `confidence !== 'high'`)
|
|
43
|
+
* get a dotted underline so operators can see at a glance which
|
|
44
|
+
* highlights were rescued by score-resolved tiebreaking, fuzzy matching,
|
|
45
|
+
* or a position-fallback. The hover tooltip (added by
|
|
46
|
+
* `getAnnotationDecorationMeta`) names the strategy. */
|
|
47
|
+
.annotation-low-confidence {
|
|
48
|
+
text-decoration: underline dotted var(--semiont-color-warning-500, #d97706);
|
|
49
|
+
text-decoration-thickness: 2px;
|
|
50
|
+
text-underline-offset: 2px;
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
/* Print styles */
|
|
40
54
|
@media print {
|
|
41
55
|
.annotation-highlight,
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
import { screen, fireEvent, waitFor } from '@testing-library/react';
|
|
4
3
|
import userEvent from '@testing-library/user-event';
|
|
5
4
|
import '@testing-library/jest-dom';
|
|
6
|
-
import type { components } from '@semiont/core';
|
|
7
5
|
|
|
8
|
-
import type { Annotation } from '@semiont/core';
|
|
6
|
+
import type { Annotation, AnnotationId } from '@semiont/core';
|
|
9
7
|
|
|
10
8
|
// Mock CodeMirror modules
|
|
11
9
|
vi.mock('@codemirror/view', () => {
|
|
@@ -57,10 +55,10 @@ import { JsonLdView } from '../JsonLdView';
|
|
|
57
55
|
|
|
58
56
|
const createMockAnnotation = (overrides?: Partial<Annotation>): Annotation => ({
|
|
59
57
|
'@context': 'http://www.w3.org/ns/anno.jsonld',
|
|
60
|
-
id: 'anno-1',
|
|
58
|
+
id: 'anno-1' as AnnotationId,
|
|
61
59
|
type: 'Annotation',
|
|
62
60
|
motivation: 'highlighting',
|
|
63
|
-
creator: { name: 'user@example.com' },
|
|
61
|
+
creator: { '@type': 'Person', name: 'user@example.com' },
|
|
64
62
|
created: '2024-01-01T10:00:00Z',
|
|
65
63
|
target: {
|
|
66
64
|
source: 'resource-1',
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
import { render, screen } from '@testing-library/react';
|
|
4
3
|
import '@testing-library/jest-dom';
|
|
5
4
|
import { SemiontBranding } from '../SemiontBranding';
|
|
@@ -305,7 +304,7 @@ describe('SemiontBranding Component', () => {
|
|
|
305
304
|
|
|
306
305
|
describe('Edge Cases', () => {
|
|
307
306
|
it('should handle missing translation gracefully', () => {
|
|
308
|
-
const emptyTranslate = vi.fn((
|
|
307
|
+
const emptyTranslate = vi.fn(() => '');
|
|
309
308
|
|
|
310
309
|
render(<SemiontBranding t={emptyTranslate} />);
|
|
311
310
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
import { render, screen, fireEvent } from '@testing-library/react';
|
|
4
3
|
import '@testing-library/jest-dom';
|
|
5
4
|
import { LeftSidebar } from '../LeftSidebar';
|
|
@@ -159,7 +158,7 @@ describe('LeftSidebar Component', () => {
|
|
|
159
158
|
});
|
|
160
159
|
|
|
161
160
|
it('should save collapsed state to localStorage', () => {
|
|
162
|
-
const mockChildren = vi.fn((
|
|
161
|
+
const mockChildren = vi.fn((_isCollapsed, toggleCollapsed) => (
|
|
163
162
|
<button onClick={toggleCollapsed} data-testid="toggle-btn">Toggle</button>
|
|
164
163
|
));
|
|
165
164
|
|
|
@@ -183,7 +182,7 @@ describe('LeftSidebar Component', () => {
|
|
|
183
182
|
});
|
|
184
183
|
|
|
185
184
|
it('should not collapse when collapsible is false', () => {
|
|
186
|
-
const mockChildren = vi.fn((
|
|
185
|
+
const mockChildren = vi.fn((_isCollapsed, toggleCollapsed) => (
|
|
187
186
|
<button onClick={toggleCollapsed} data-testid="toggle-btn">Toggle</button>
|
|
188
187
|
));
|
|
189
188
|
|
|
@@ -208,7 +207,7 @@ describe('LeftSidebar Component', () => {
|
|
|
208
207
|
});
|
|
209
208
|
|
|
210
209
|
it('should use default storage key', () => {
|
|
211
|
-
const mockChildren = vi.fn((
|
|
210
|
+
const mockChildren = vi.fn((_isCollapsed, toggleCollapsed) => (
|
|
212
211
|
<button onClick={toggleCollapsed} data-testid="toggle-btn">Toggle</button>
|
|
213
212
|
));
|
|
214
213
|
|
|
@@ -233,7 +232,7 @@ describe('LeftSidebar Component', () => {
|
|
|
233
232
|
|
|
234
233
|
describe('Navigation Menu Helper', () => {
|
|
235
234
|
it('should provide navigationMenu helper to function children', () => {
|
|
236
|
-
const mockChildren = vi.fn((
|
|
235
|
+
const mockChildren = vi.fn((_isCollapsed, _toggleCollapsed, navigationMenu) => {
|
|
237
236
|
// Test that navigationMenu helper returns NavigationMenu component
|
|
238
237
|
const menuElement = navigationMenu(() => {});
|
|
239
238
|
return <div data-testid="children-content">{menuElement}</div>;
|
|
@@ -259,7 +258,7 @@ describe('LeftSidebar Component', () => {
|
|
|
259
258
|
|
|
260
259
|
it('should pass onClose callback to NavigationMenu', () => {
|
|
261
260
|
const mockOnClose = vi.fn();
|
|
262
|
-
const mockChildren = vi.fn((
|
|
261
|
+
const mockChildren = vi.fn((_isCollapsed, _toggleCollapsed, navigationMenu) => {
|
|
263
262
|
const menuElement = navigationMenu(mockOnClose);
|
|
264
263
|
return <div>{menuElement}</div>;
|
|
265
264
|
});
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
import { render, screen } from '@testing-library/react';
|
|
4
3
|
import '@testing-library/jest-dom';
|
|
5
4
|
import { PageLayout } from '../PageLayout';
|
|
@@ -247,7 +246,6 @@ describe('PageLayout Component', () => {
|
|
|
247
246
|
);
|
|
248
247
|
|
|
249
248
|
// Real Footer renders copyright with dynamic year
|
|
250
|
-
const currentYear = new Date().getFullYear();
|
|
251
249
|
expect(screen.getByText(`translated.copyright`)).toBeInTheDocument();
|
|
252
250
|
});
|
|
253
251
|
});
|
|
@@ -270,7 +268,7 @@ describe('PageLayout Component', () => {
|
|
|
270
268
|
});
|
|
271
269
|
|
|
272
270
|
it('should render with CookiePreferences component', () => {
|
|
273
|
-
const MockCookiePreferences = ({
|
|
271
|
+
const MockCookiePreferences = ({ }: any) => (
|
|
274
272
|
<div data-testid="cookie-prefs">Cookie Preferences</div>
|
|
275
273
|
);
|
|
276
274
|
|