@jini-ai/ui 0.6.15-rc.2 → 0.6.15
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/dist/browser/useDismissOnOutsideOrEscape.js +1 -1
- package/dist/browser/useGlobalKeydown.js +2 -2
- package/dist/browser/useModalWindowDragGuard.js +1 -1
- package/dist/core/theme/css-name.d.ts +3 -0
- package/dist/core/theme/css-name.js +5 -0
- package/dist/core/theme/stylesheet.js +2 -1
- package/dist/core/theme/validation.js +15 -4
- package/dist/features/about/rules.js +2 -1
- package/dist/features/admin-widgets/components/InfoTip.hooks.js +22 -12
- package/dist/features/admin-widgets/components/Lightbox/Lightbox.hooks.js +1 -1
- package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.hooks.js +1 -1
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.hooks.js +2 -2
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.js +4 -2
- package/dist/features/admin-widgets/components/Select/Select.hooks.js +2 -1
- package/dist/features/admin-widgets/components/Select/Select.js +2 -1
- package/dist/features/admin-widgets/components/SuggestInput/SuggestInput.js +4 -2
- package/dist/features/admin-widgets/components/useDebouncedHtmlPreview.hooks.js +3 -2
- package/dist/features/asset-grid/react/components/AssetGrid.js +8 -3
- package/dist/features/asset-grid/react/hooks/useAssetGridKeyboardShortcuts.js +7 -6
- package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.js +8 -10
- package/dist/features/asset-grid/react/hooks/useRubberBandDrag.js +1 -1
- package/dist/features/asset-tree-browser/react/components/AssetTreeFileRow.js +6 -8
- package/dist/features/asset-tree-browser/react/hooks/useAssetTreeRowMenu.js +1 -1
- package/dist/features/asset-tree-browser/rules.js +1 -3
- package/dist/features/browser-chrome/rules.js +10 -8
- package/dist/features/charts/browser.js +2 -1
- package/dist/features/charts/react.js +3 -1
- package/dist/features/connectors/ConnectorsBrowser.js +3 -1
- package/dist/features/connectors/hooks/useConnectorAuthorization.js +1 -1
- package/dist/features/connectors/hooks/useConnectorCatalog.js +2 -2
- package/dist/features/connectors/rules.js +10 -14
- package/dist/features/execution/react/components/AgentDiagnosticRow.js +2 -0
- package/dist/features/execution/react/components/ByokProviderForm.js +1 -3
- package/dist/features/execution/react/components/LocalCliAgentSettings.js +2 -1
- package/dist/features/execution/react/hooks/use-byok-field-validation.hooks.js +6 -2
- package/dist/features/execution/react/hooks/useExecutionTab.js +9 -5
- package/dist/features/execution/react/hooks/useLocalCliAgentCard.js +3 -6
- package/dist/features/execution/react/hooks/useReasoningControl.js +3 -3
- package/dist/features/execution/rules.js +23 -18
- package/dist/features/external-mcp/react/components/ExternalMcpTab.js +10 -1
- package/dist/features/file-dropzone/rules.js +3 -2
- package/dist/features/html-editor/canvas-embed-placeholders.js +2 -3
- package/dist/features/html-editor/css.js +7 -5
- package/dist/features/html-editor/editor-blocks.js +60 -6
- package/dist/features/html-editor/protected-elements.js +5 -3
- package/dist/features/html-editor/react/hooks/useInteractiveHtmlEditor.js +3 -3
- package/dist/features/html-editor/source-splice.js +6 -4
- package/dist/features/iframe-pool/react/components/IframeKeepAliveProvider.js +5 -5
- package/dist/features/iframe-pool/react/dom-sync.js +2 -2
- package/dist/features/integrations/react/components/IntegrationsTab.js +3 -1
- package/dist/features/integrations/rules.js +6 -4
- package/dist/features/interactive-ui/providers/shadcn/data-table.js +10 -5
- package/dist/features/interactive-ui/table-data.js +1 -1
- package/dist/features/lexical-rich-text-editor/deserialize.js +2 -2
- package/dist/features/lexical-rich-text-editor/mention-parser.js +4 -4
- package/dist/features/lexical-rich-text-editor/react/components/RichTextInput.js +2 -1
- package/dist/features/lexical-rich-text-editor/react/hooks/useCaretFloatingLayerPosition.js +1 -1
- package/dist/features/lexical-rich-text-editor/react/hooks/useMentionColorStamping.js +1 -1
- package/dist/features/lexical-rich-text-editor/serialize.js +13 -10
- package/dist/features/list-detail-panel/react/components/ListDetailPanel.js +1 -1
- package/dist/features/mcp-ui/confirmation-store.js +3 -6
- package/dist/features/mcp-ui/surfaces/confirmation.d.ts +5 -0
- package/dist/features/mcp-ui/surfaces/confirmation.js +1 -0
- package/dist/features/mcp-ui/surfaces/document.d.ts +3 -15
- package/dist/features/mcp-ui/surfaces/document.js +37 -6
- package/dist/features/mcp-ui/surfaces/fields.js +2 -0
- package/dist/features/mcp-ui/surfaces/host-theme.js +2 -1
- package/dist/features/mcp-ui/surfaces/index.d.ts +1 -0
- package/dist/features/mcp-ui/surfaces/index.js +1 -0
- package/dist/features/mcp-ui/surfaces/outcome.js +1 -1
- package/dist/features/mcp-ui/surfaces/select.js +2 -1
- package/dist/features/mcp-ui/surfaces/structured-details.d.ts +40 -0
- package/dist/features/mcp-ui/surfaces/structured-details.js +159 -0
- package/dist/features/mcp-ui/surfaces/text-input.js +1 -1
- package/dist/features/mcp-ui/surfaces/tool-approval.d.ts +21 -0
- package/dist/features/mcp-ui/surfaces/tool-approval.js +41 -0
- package/dist/features/media-providers/react/hooks/useMediaProvidersTab.js +2 -1
- package/dist/features/memory/async-commit-guard.js +4 -1
- package/dist/features/memory/formatters.js +5 -1
- package/dist/features/memory/react/components/MemoryConnectedPanel.js +3 -1
- package/dist/features/memory/react/components/MemoryEntryCard.js +1 -1
- package/dist/features/memory/react/components/MemorySettingsPanel.js +3 -1
- package/dist/features/memory/react/hooks/useMemoryConfig.hooks.js +12 -10
- package/dist/features/memory/react/hooks/useMemoryConnectors.hooks.js +2 -5
- package/dist/features/memory/react/hooks/useMemoryConnectors.rules.js +10 -9
- package/dist/features/memory/react/hooks/useMemoryEntries.hooks.js +4 -2
- package/dist/features/memory/react/hooks/useMemoryFlash.hooks.js +1 -1
- package/dist/features/memory/rules.js +2 -1
- package/dist/features/panel-kit/fetch-query/adapter.react.js +3 -2
- package/dist/features/panel-kit/fetch-query/adapter.tanstack.js +3 -2
- package/dist/features/panel-kit/fetch-query/binding.react.js +2 -1
- package/dist/features/panel-kit/helpers/standing-draft-recovery-message.js +13 -4
- package/dist/features/panel-kit/hooks/use-dirty-guard.hooks.js +1 -1
- package/dist/features/panel-kit/hooks/use-focus-trap.hooks.js +1 -1
- package/dist/features/panel-kit/hooks/use-settings-slice.hooks.js +14 -10
- package/dist/features/panel-kit/hooks/use-standing-draft-autosave.hooks.js +2 -2
- package/dist/features/progress-card/components/ProgressCard.d.ts +1 -1
- package/dist/features/progress-card/reference-adapters.js +23 -13
- package/dist/features/progress-card/rules.d.ts +0 -1
- package/dist/features/progress-card/rules.js +14 -20
- package/dist/features/progress-card/types.d.ts +1 -1
- package/dist/features/project-locations/dependencies.js +6 -1
- package/dist/features/project-locations/react/components/ProjectLocationsTab.js +2 -1
- package/dist/features/project-locations/rules.js +2 -1
- package/dist/features/resource-dashboard/react/components/ResourceBoardToolbar.js +8 -1
- package/dist/features/resource-dashboard/react/components/ResourceCardParts.js +2 -1
- package/dist/features/resource-dashboard/react/components/ResourceRowListItem.js +3 -1
- package/dist/features/resource-dashboard/react/components/ResourceRowListItemParts.js +2 -1
- package/dist/features/resource-dashboard/react/components/ResourceRowListView.js +1 -1
- package/dist/features/resource-dashboard/react/hooks/useResourceBoard.js +1 -1
- package/dist/features/schedule-picker/rules.js +13 -7
- package/dist/features/sketch-editor/constants.d.ts +0 -6
- package/dist/features/sketch-editor/constants.js +17 -15
- package/dist/features/sketch-editor/dom.js +4 -7
- package/dist/features/sketch-editor/react/components/SketchMainMenu.js +2 -1
- package/dist/features/sketch-editor/react/components/SketchSaveStateBadge.js +2 -1
- package/dist/features/sketch-editor/react/hooks/useSketchDomEnhancements.js +1 -1
- package/dist/features/sketch-editor/rules.js +13 -12
- package/dist/features/skills/dependencies.js +9 -4
- package/dist/features/skills/react/components/SkillRow.js +2 -1
- package/dist/features/skills/react/components/SkillsTab.js +2 -1
- package/dist/features/skills/rules.js +3 -3
- package/dist/features/source-config-list/agent-handles.js +4 -3
- package/dist/features/source-config-list/react/components/SourceConfigItemCard.js +3 -1
- package/dist/features/tab-strip/react/components/TabBar.hooks.js +4 -2
- package/dist/features/version-manager/react/components/VersionPreviewFrame.js +4 -1
- package/dist/features/version-manager/react/components/VersionSidebar.js +8 -6
- package/dist/features/version-manager/react/hooks/usePreviewCanvasSize.js +1 -1
- package/dist/features/version-manager/react/hooks/useVersionManager.js +5 -7
- package/dist/features/version-manager/rules.js +3 -5
- package/dist/features/viewer-shell/react/components/CommentSidePanel.js +2 -1
- package/dist/features/viewer-shell/react/components/SegmentedToggle.js +2 -1
- package/dist/features/viewer-shell/react/components/ViewerShell.js +2 -1
- package/dist/features/viewer-shell/rules.js +8 -7
- package/dist/react/components/BrandLogo.js +10 -2
- package/dist/react/components/CustomSelect.js +1 -1
- package/dist/react/components/EditorIcon.js +17 -14
- package/dist/react/components/Loading.js +2 -1
- package/dist/react/components/OnboardingChipField.js +5 -1
- package/dist/react/components/OnboardingDropdown.js +6 -4
- package/dist/react/components/PaletteTweaks.js +7 -6
- package/dist/react/components/PillButton.js +2 -1
- package/dist/react/components/PopoverMenu.js +2 -1
- package/dist/react/components/RemixIcon.js +2 -1
- package/dist/react/components/SecretInput.hooks.d.ts +2 -25
- package/dist/react/components/SecretInput.hooks.js +2 -24
- package/dist/react/components/SecretInput.js +5 -4
- package/dist/react/components/Toast.js +4 -2
- package/dist/react/components/TooltipLayer.js +4 -1
- package/dist/react/components/WorkingDirPicker.js +5 -4
- package/dist/react/components/remixicon-font-recovery.js +9 -1
- package/dist/react/components/select-popover.js +2 -2
- package/dist/react/hooks/useBrandFonts.js +1 -1
- package/dist/react/hooks/useEdgeAutoScroll.js +1 -1
- package/dist/react/hooks/useInView.js +9 -9
- package/dist/react/hooks/useResizableSplitPane.js +12 -20
- package/dist/react/mcp-ui/useHostSurfaceTokens.js +1 -1
- package/dist/renderers/annotation-canvas/react/components/AnnotationCanvas.js +7 -1
- package/dist/renderers/annotation-canvas/react/hooks/useAnnotationCanvas.controller.js +4 -2
- package/dist/renderers/annotation-canvas/react/hooks/useAnnotationCanvas.js +9 -5
- package/dist/renderers/annotation-canvas/rules.js +9 -13
- package/dist/renderers/annotation-canvas/theme.js +5 -2
- package/dist/renderers/renderers/index.js +1 -1
- package/dist/renderers/renderers/markdown.js +4 -6
- package/dist/theme/apply.js +7 -3
- package/dist/utils/class-names.d.ts +3 -0
- package/dist/utils/class-names.js +5 -0
- package/dist/utils/design-md.js +3 -3
- package/dist/utils/ime-composing.d.ts +1 -1
- package/dist/utils/ime-composing.js +1 -2
- package/dist/utils/localized-url.js +2 -11
- package/dist/utils/markdown-scroll-sync.js +1 -1
- package/dist/utils/omit-keys.d.ts +3 -0
- package/dist/utils/omit-keys.js +8 -0
- package/dist/utils/polygon-selection.js +1 -1
- package/dist/utils/sse.js +3 -0
- package/dist/utils/trim-chars.d.ts +13 -0
- package/dist/utils/trim-chars.js +30 -0
- package/dist/utils/unhandled-case.d.ts +10 -0
- package/dist/utils/unhandled-case.js +12 -0
- package/dist/utils/unit-bezier.js +1 -3
- package/dist/utils/zip.js +6 -10
- package/package.json +10 -9
|
@@ -26,7 +26,7 @@ export function useHostSurfaceTokens(ref) {
|
|
|
26
26
|
const view = element?.ownerDocument.defaultView;
|
|
27
27
|
if (element === null || element === undefined || view === null || view === undefined) {
|
|
28
28
|
setTokens({});
|
|
29
|
-
return;
|
|
29
|
+
return undefined;
|
|
30
30
|
}
|
|
31
31
|
let last;
|
|
32
32
|
const read = () => {
|
|
@@ -16,6 +16,12 @@ import { useT } from '../../../react/i18n.js';
|
|
|
16
16
|
function maybePortal(node, host) {
|
|
17
17
|
return host ? createPortal(node, host) : node;
|
|
18
18
|
}
|
|
19
|
+
/** Crosshair for drawing tools, an I-beam for the text tool, the default pointer while inactive. */
|
|
20
|
+
function annotationCursor(active, markTool) {
|
|
21
|
+
if (!active)
|
|
22
|
+
return 'default';
|
|
23
|
+
return markTool === 'text' ? 'text' : 'crosshair';
|
|
24
|
+
}
|
|
19
25
|
export function AnnotationCanvas(props) {
|
|
20
26
|
const { children, toolbarHost, icons: iconOverrides, className } = props;
|
|
21
27
|
const icons = { ...DEFAULT_ANNOTATION_CANVAS_ICONS, ...iconOverrides };
|
|
@@ -39,7 +45,7 @@ function DrawingCanvas({ c, active }) {
|
|
|
39
45
|
position: 'absolute',
|
|
40
46
|
inset: 0,
|
|
41
47
|
pointerEvents: active ? 'auto' : 'none',
|
|
42
|
-
cursor: active
|
|
48
|
+
cursor: annotationCursor(active, c.markTool),
|
|
43
49
|
visibility: c.chromeHidden ? 'hidden' : 'visible',
|
|
44
50
|
touchAction: 'none',
|
|
45
51
|
userSelect: 'none',
|
|
@@ -19,7 +19,8 @@ export function deriveUndoRedoAvailability(input) {
|
|
|
19
19
|
/** Shared by the hook's `canSubmit` value and `send()`'s own gate — both computed the identical chain before this extraction. */
|
|
20
20
|
export function deriveSendGate(input) {
|
|
21
21
|
const { hasInk, hasBox, hasText, hasCaptureTarget, captureViewport, noteTrimmed, extraFilesCount } = input;
|
|
22
|
-
const
|
|
22
|
+
const hasAnnotation = hasInk || hasBox || hasText;
|
|
23
|
+
const shouldCapture = hasAnnotation || hasCaptureTarget || captureViewport;
|
|
23
24
|
const canSubmitNow = shouldCapture || Boolean(noteTrimmed) || extraFilesCount > 0;
|
|
24
25
|
return { shouldCapture, canSubmitNow };
|
|
25
26
|
}
|
|
@@ -35,7 +36,8 @@ export function canAttemptSend(input) {
|
|
|
35
36
|
/** Picks which of the two "no screenshot" warnings applies — the whole-viewport-request wording, or the mark-specific one. */
|
|
36
37
|
export function selectNoScreenshotMessage(input, t) {
|
|
37
38
|
const { captureViewport, hasInk, hasBox, hasCaptureTarget } = input;
|
|
38
|
-
|
|
39
|
+
const hasMark = hasInk || hasBox || hasCaptureTarget;
|
|
40
|
+
return captureViewport && !hasMark
|
|
39
41
|
? t('No screenshot was captured for this annotation.')
|
|
40
42
|
: t('No screenshot was captured for this mark.');
|
|
41
43
|
}
|
|
@@ -25,6 +25,8 @@ const DEFAULT_DOCKED_STYLE = {
|
|
|
25
25
|
maxWidth: 'min(760px, calc(100% - 144px))',
|
|
26
26
|
};
|
|
27
27
|
const SUBMIT_TIMEOUT_MS = 60_000;
|
|
28
|
+
/** The analytics toolbar element each mark tool reports as. */
|
|
29
|
+
const TOOLBAR_TOOL_FOR_MARK_TOOL = { box: 'rect', text: 'text' };
|
|
28
30
|
export function useAnnotationCanvas(options) {
|
|
29
31
|
const { active, onActiveChange, captureViewport = false, captureTarget = null, filePath, sendDisabled = false, hideChrome = false, onToolbarClick, port } = options;
|
|
30
32
|
const t = useT();
|
|
@@ -155,7 +157,7 @@ export function useAnnotationCanvas(options) {
|
|
|
155
157
|
}
|
|
156
158
|
window.addEventListener('keydown', onKey);
|
|
157
159
|
return () => window.removeEventListener('keydown', onKey);
|
|
158
|
-
//
|
|
160
|
+
// Dependency list intentionally follows the lifecycle rationale above.
|
|
159
161
|
}, [active, onActiveChange, sending]);
|
|
160
162
|
// Keyboard shortcut #2: Escape closes the staged-image preview modal first (capture phase).
|
|
161
163
|
useEffect(() => {
|
|
@@ -368,7 +370,7 @@ export function useAnnotationCanvas(options) {
|
|
|
368
370
|
syncHistoryState();
|
|
369
371
|
redraw();
|
|
370
372
|
bumpLayoutRevision();
|
|
371
|
-
//
|
|
373
|
+
// Dependency list intentionally follows the lifecycle rationale above.
|
|
372
374
|
}, [active, redraw]);
|
|
373
375
|
const autosizeTextArea = useCallback((el) => {
|
|
374
376
|
if (!el)
|
|
@@ -509,7 +511,7 @@ export function useAnnotationCanvas(options) {
|
|
|
509
511
|
};
|
|
510
512
|
}, [extraFiles]);
|
|
511
513
|
function selectMarkTool(nextTool) {
|
|
512
|
-
onToolbarClick?.(nextTool
|
|
514
|
+
onToolbarClick?.(TOOLBAR_TOOL_FOR_MARK_TOOL[nextTool] ?? 'pen');
|
|
513
515
|
setMarkTool(nextTool);
|
|
514
516
|
setMarkToolMenuOpen(false);
|
|
515
517
|
}
|
|
@@ -598,7 +600,9 @@ export function useAnnotationCanvas(options) {
|
|
|
598
600
|
}
|
|
599
601
|
function waitForOverlayHidden() {
|
|
600
602
|
return new Promise((resolve) => {
|
|
601
|
-
|
|
603
|
+
const finish = () => resolve();
|
|
604
|
+
const afterNextFrame = () => requestAnimationFrame(finish);
|
|
605
|
+
requestAnimationFrame(afterNextFrame);
|
|
602
606
|
});
|
|
603
607
|
}
|
|
604
608
|
async function requestSnapshot() {
|
|
@@ -735,7 +739,7 @@ export function useAnnotationCanvas(options) {
|
|
|
735
739
|
anchor,
|
|
736
740
|
});
|
|
737
741
|
setDockPlacement((current) => (dockPlacementEquals(current, next) ? current : next));
|
|
738
|
-
//
|
|
742
|
+
// Dependency list intentionally follows the lifecycle rationale above.
|
|
739
743
|
}, [active, captureTarget, layoutRevision, imagePreviews.length, captureWarning?.message]);
|
|
740
744
|
useLayoutEffect(() => {
|
|
741
745
|
if (!active || typeof ResizeObserver === 'undefined')
|
|
@@ -22,13 +22,10 @@ export function normalizedRectFromPoints(a, b) {
|
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
export function dockPlacementEquals(a, b) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
a.style.bottom === b.style.bottom &&
|
|
30
|
-
a.style.transform === b.style.transform &&
|
|
31
|
-
a.style.maxWidth === b.style.maxWidth);
|
|
25
|
+
if (a.layout !== b.layout || a.side !== b.side)
|
|
26
|
+
return false;
|
|
27
|
+
const samePosition = a.style.left === b.style.left && a.style.top === b.style.top && a.style.bottom === b.style.bottom;
|
|
28
|
+
return samePosition && a.style.transform === b.style.transform && a.style.maxWidth === b.style.maxWidth;
|
|
32
29
|
}
|
|
33
30
|
export const DRAW_DOCK_GAP = 12;
|
|
34
31
|
export const DRAW_DOCK_MARGIN = 16;
|
|
@@ -47,12 +44,11 @@ export function computeDockPlacement(input) {
|
|
|
47
44
|
const { hostRect, wrapRect, dockRect, anchor } = input;
|
|
48
45
|
if (!anchor)
|
|
49
46
|
return docked;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
dockRect.height
|
|
54
|
-
|
|
55
|
-
hostRect.height < Math.max(DRAW_DOCK_MIN_HEIGHT, dockRect.height) + DRAW_DOCK_MARGIN * 2) {
|
|
47
|
+
const hostTooSmall = hostRect.width <= DRAW_DOCK_MARGIN * 2 || hostRect.height <= DRAW_DOCK_MARGIN * 2;
|
|
48
|
+
const dockEmpty = dockRect.width <= 0 || dockRect.height <= 0;
|
|
49
|
+
const dockDoesNotFit = hostRect.width < Math.max(DRAW_DOCK_MIN_WIDTH, dockRect.width) + DRAW_DOCK_MARGIN * 2
|
|
50
|
+
|| hostRect.height < Math.max(DRAW_DOCK_MIN_HEIGHT, dockRect.height) + DRAW_DOCK_MARGIN * 2;
|
|
51
|
+
if (hostTooSmall || dockEmpty || dockDoesNotFit) {
|
|
56
52
|
return docked;
|
|
57
53
|
}
|
|
58
54
|
const anchorInHost = {
|
|
@@ -2,8 +2,11 @@ import { defaultAdminTheme } from '../../theme/default.js';
|
|
|
2
2
|
/** Canvas requires resolved colors rather than var() strings. Its injected canvas owns the DOM. */
|
|
3
3
|
export function resolveAnnotationTheme({ canvas }, { getComputedStyle } = {}) {
|
|
4
4
|
const document = canvas?.ownerDocument;
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const view = document?.defaultView;
|
|
6
|
+
const readStyle = getComputedStyle ?? view?.getComputedStyle.bind(view);
|
|
7
|
+
let style;
|
|
8
|
+
if (document && readStyle)
|
|
9
|
+
style = readStyle(canvas?.isConnected ? canvas : document.documentElement);
|
|
7
10
|
const read = (name, fallback) => style?.getPropertyValue(name).trim() || fallback;
|
|
8
11
|
return {
|
|
9
12
|
stroke: read('--jini-danger', defaultAdminTheme.light.danger),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RendererRegistry } from '../registry.js';
|
|
2
2
|
import { HtmlRenderer } from './html.js';
|
|
3
|
-
import { MarkdownRenderer
|
|
3
|
+
import { MarkdownRenderer } from './markdown.js';
|
|
4
4
|
import { SvgRenderer } from './svg.js';
|
|
5
5
|
import { ReactComponentRenderer } from './react-component.js';
|
|
6
6
|
export { HtmlRenderer } from './html.js';
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { micromark } from 'micromark';
|
|
9
9
|
import { gfm, gfmHtml } from 'micromark-extension-gfm';
|
|
10
10
|
import { resolveArtifactManifest } from '../registry.js';
|
|
11
|
+
import { trimTrailingWhere } from '../../utils/trim-chars.js';
|
|
11
12
|
export function renderMarkdownToSafeHtml(markdown) {
|
|
12
13
|
return postProcessMarkdownHtml(micromark(escapeTableCodePipes(markdown), {
|
|
13
14
|
extensions: [gfm()],
|
|
@@ -56,7 +57,7 @@ function isTableDelimiter(line) {
|
|
|
56
57
|
function escapeCodeSpanPipes(line) {
|
|
57
58
|
if (!line.includes('|') || !line.includes('`'))
|
|
58
59
|
return line;
|
|
59
|
-
return line.replace(/`([
|
|
60
|
+
return line.replace(/`([^`|]*\|[^`]*)`/g, (_match, code) => `\`${code.replace(/\|/g, '\\|')}\``);
|
|
60
61
|
}
|
|
61
62
|
function postProcessMarkdownHtml(html) {
|
|
62
63
|
let out = html.trim();
|
|
@@ -78,11 +79,8 @@ function postProcessMarkdownHtml(html) {
|
|
|
78
79
|
}
|
|
79
80
|
function normalizeSafeHref(href) {
|
|
80
81
|
const decoded = decodeHref(href);
|
|
81
|
-
const stripped = decoded
|
|
82
|
-
if (stripped.startsWith(
|
|
83
|
-
stripped.startsWith('/') ||
|
|
84
|
-
stripped.startsWith('./') ||
|
|
85
|
-
stripped.startsWith('../') ||
|
|
82
|
+
const stripped = trimTrailingWhere(decoded, (char) => /[!"')}\],.;:\s]/.test(char));
|
|
83
|
+
if (['#', '/', './', '../'].some(prefix => stripped.startsWith(prefix)) ||
|
|
86
84
|
/^https?:\/\//i.test(stripped) ||
|
|
87
85
|
/^mailto:/i.test(stripped)) {
|
|
88
86
|
return stripped;
|
package/dist/theme/apply.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defaultAdminTheme } from '../core/theme/default.js';
|
|
2
|
+
import { kebabThemeKey } from '../core/theme/css-name.js';
|
|
2
3
|
import { adminThemeColorKeys, validateAdminTheme } from '../core/theme/validation.js';
|
|
3
4
|
const fontLeases = new WeakMap();
|
|
4
5
|
function acquireFont(document, href) {
|
|
@@ -20,17 +21,20 @@ function acquireFont(document, href) {
|
|
|
20
21
|
}
|
|
21
22
|
const held = lease;
|
|
22
23
|
held.users++;
|
|
23
|
-
return () => {
|
|
24
|
+
return () => {
|
|
25
|
+
held.users -= 1;
|
|
26
|
+
if (held.users !== 0)
|
|
27
|
+
return;
|
|
24
28
|
if (held.owned)
|
|
25
29
|
held.link.remove();
|
|
26
30
|
leases.delete(absolute);
|
|
27
|
-
}
|
|
31
|
+
};
|
|
28
32
|
}
|
|
29
33
|
function themeValues({ theme }, _options = {}) {
|
|
30
34
|
const values = {};
|
|
31
35
|
for (const scheme of ['light', 'dark'])
|
|
32
36
|
for (const key of adminThemeColorKeys) {
|
|
33
|
-
values[`--jini-theme-${scheme}-${key
|
|
37
|
+
values[`--jini-theme-${scheme}-${kebabThemeKey(key)}`] = theme[scheme][key];
|
|
34
38
|
}
|
|
35
39
|
values['--jini-font-body'] = theme.fonts.body;
|
|
36
40
|
values['--jini-font-heading'] = theme.fonts.heading;
|
package/dist/utils/design-md.js
CHANGED
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
// heading's text — the same fuzzy match a hand-edited doc's headings need to
|
|
7
7
|
// keep matching after a human renames "Color Palette" to "Palette", etc.
|
|
8
8
|
export function designMdHeadings(body, startOffset) {
|
|
9
|
-
return [...body.slice(startOffset).matchAll(/^##\s+(
|
|
9
|
+
return [...body.slice(startOffset).matchAll(/^##\s+(\S.*|.)$/gm)].map((match) => {
|
|
10
10
|
// `RegExpMatchArray.index` and a capture group are typed as possibly
|
|
11
11
|
// `undefined` because the JS regex API can't express "always set for a
|
|
12
12
|
// `matchAll` result" / "always set for a mandatory capture group" — for
|
|
13
13
|
// this specific pattern (an unanchored global match, one non-optional
|
|
14
|
-
//
|
|
14
|
+
// title group) both are always defined whenever a match exists.
|
|
15
15
|
const start = startOffset + match.index;
|
|
16
16
|
return {
|
|
17
17
|
start,
|
|
18
|
-
title: match[1],
|
|
18
|
+
title: match[1].trimEnd() || match[1],
|
|
19
19
|
};
|
|
20
20
|
});
|
|
21
21
|
}
|
|
@@ -11,5 +11,5 @@ import type { KeyboardEvent as ReactKeyboardEvent } from 'react';
|
|
|
11
11
|
*
|
|
12
12
|
* @overallScore 100
|
|
13
13
|
*/
|
|
14
|
-
export declare function isImeComposing(
|
|
14
|
+
export declare function isImeComposing(_event: ReactKeyboardEvent<HTMLInputElement | HTMLTextAreaElement>, composing: boolean): boolean;
|
|
15
15
|
//# sourceMappingURL=ime-composing.d.ts.map
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
// e.g. for linking out to a marketing/docs site in the reader's language.
|
|
3
|
-
//
|
|
4
|
-
// Ported from an origin helper that hardcoded one product's own marketing
|
|
5
|
-
// domain and locale table inline — that's product identity, not reusable
|
|
6
|
-
// logic, so it's dropped here. What's actually generic and worth keeping is
|
|
7
|
-
// the resolution algorithm: map the active locale to a URL segment (falling
|
|
8
|
-
// back to no segment — i.e. the base's default language — for locales the
|
|
9
|
-
// target site doesn't support), then join it onto the base. `baseUrl` and
|
|
10
|
-
// `localeSegments` are supplied by the caller.
|
|
1
|
+
import { trimTrailingChars } from './trim-chars.js';
|
|
11
2
|
export function buildLocalizedUrl(locale, options) {
|
|
12
|
-
const base = options.baseUrl
|
|
3
|
+
const base = trimTrailingChars(options.baseUrl, '/');
|
|
13
4
|
const segment = options.localeSegments?.[locale];
|
|
14
5
|
return segment ? `${base}/${segment}/` : `${base}/`;
|
|
15
6
|
}
|
|
@@ -160,7 +160,7 @@ function buildMirrorMarkup({ blockLines, text }) {
|
|
|
160
160
|
// is escaped, so it cannot inject one), so each index is a valid block index.
|
|
161
161
|
function readMarkerOffsets({ mirror, blockCount }) {
|
|
162
162
|
document.body.appendChild(mirror);
|
|
163
|
-
const offsets =
|
|
163
|
+
const offsets = Array.from({ length: blockCount }, () => 0);
|
|
164
164
|
try {
|
|
165
165
|
for (const marker of Array.from(mirror.querySelectorAll('span[data-md-block]'))) {
|
|
166
166
|
offsets[Number(marker.getAttribute('data-md-block'))] = marker.offsetTop;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** A shallow copy of `value` without `keys` — the rest-destructuring "omit" idiom, minus the unused bindings. */
|
|
2
|
+
export function omitKeys(value, keys) {
|
|
3
|
+
const copy = { ...value };
|
|
4
|
+
for (const key of keys)
|
|
5
|
+
Reflect.deleteProperty(copy, key);
|
|
6
|
+
return copy;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=omit-keys.js.map
|
|
@@ -55,7 +55,7 @@ export function lineIntersectsLine(a1, a2, b1, b2) {
|
|
|
55
55
|
/** Standard even-odd-rule ray-casting point-in-polygon test. */
|
|
56
56
|
export function pointInPolygon(point, polygon) {
|
|
57
57
|
let inside = false;
|
|
58
|
-
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i
|
|
58
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i, i += 1) {
|
|
59
59
|
const pi = polygon[i];
|
|
60
60
|
const pj = polygon[j];
|
|
61
61
|
// No `|| Number.EPSILON` divide-by-zero guard on `(pj.y - pi.y)`: the
|
package/dist/utils/sse.js
CHANGED
|
@@ -15,6 +15,9 @@ function applySseLine({ fields, line }) {
|
|
|
15
15
|
else if (line.startsWith('data: ')) {
|
|
16
16
|
fields.dataLines.push(line.slice(6));
|
|
17
17
|
}
|
|
18
|
+
else {
|
|
19
|
+
// Any other field (e.g. `retry:`) or a malformed line is ignored.
|
|
20
|
+
}
|
|
18
21
|
}
|
|
19
22
|
/** Build the result for a frame that carried no `data:` lines. */
|
|
20
23
|
function dataLessFrame({ comments }) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear-time trimming of a set of characters, in place of `value.replace(/[…]+$/, '')`-style
|
|
3
|
+
* regexes whose engine retries the run from every start position (quadratic on long runs).
|
|
4
|
+
* `chars` is a set of single UTF-16 code units, matched exactly like a non-`u` regex class.
|
|
5
|
+
*/
|
|
6
|
+
export declare function trimTrailingChars(value: string, chars: string): string;
|
|
7
|
+
/** Leading counterpart of {@link trimTrailingChars}. */
|
|
8
|
+
export declare function trimLeadingChars(value: string, chars: string): string;
|
|
9
|
+
/** Both ends — the linear form of `value.replace(/^[…]+|[…]+$/g, '')`. */
|
|
10
|
+
export declare function trimChars(value: string, chars: string): string;
|
|
11
|
+
/** {@link trimTrailingChars} for a character class a plain list cannot spell (e.g. one including `\s`). */
|
|
12
|
+
export declare function trimTrailingWhere(value: string, isTrimmed: (char: string) => boolean): string;
|
|
13
|
+
//# sourceMappingURL=trim-chars.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear-time trimming of a set of characters, in place of `value.replace(/[…]+$/, '')`-style
|
|
3
|
+
* regexes whose engine retries the run from every start position (quadratic on long runs).
|
|
4
|
+
* `chars` is a set of single UTF-16 code units, matched exactly like a non-`u` regex class.
|
|
5
|
+
*/
|
|
6
|
+
export function trimTrailingChars(value, chars) {
|
|
7
|
+
let end = value.length;
|
|
8
|
+
while (end > 0 && chars.includes(value[end - 1]))
|
|
9
|
+
end -= 1;
|
|
10
|
+
return value.slice(0, end);
|
|
11
|
+
}
|
|
12
|
+
/** Leading counterpart of {@link trimTrailingChars}. */
|
|
13
|
+
export function trimLeadingChars(value, chars) {
|
|
14
|
+
let start = 0;
|
|
15
|
+
while (start < value.length && chars.includes(value[start]))
|
|
16
|
+
start += 1;
|
|
17
|
+
return value.slice(start);
|
|
18
|
+
}
|
|
19
|
+
/** Both ends — the linear form of `value.replace(/^[…]+|[…]+$/g, '')`. */
|
|
20
|
+
export function trimChars(value, chars) {
|
|
21
|
+
return trimLeadingChars(trimTrailingChars(value, chars), chars);
|
|
22
|
+
}
|
|
23
|
+
/** {@link trimTrailingChars} for a character class a plain list cannot spell (e.g. one including `\s`). */
|
|
24
|
+
export function trimTrailingWhere(value, isTrimmed) {
|
|
25
|
+
let end = value.length;
|
|
26
|
+
while (end > 0 && isTrimmed(value[end - 1]))
|
|
27
|
+
end -= 1;
|
|
28
|
+
return value.slice(0, end);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=trim-chars.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Closes an exhaustive `switch` over a closed union.
|
|
3
|
+
*
|
|
4
|
+
* `value` is typed `never`, so the compiler still flags any union member the
|
|
5
|
+
* switch forgot. At runtime a value outside the declared union yields
|
|
6
|
+
* `undefined` — exactly what falling off the end of the switch did before — so
|
|
7
|
+
* ending a switch with `return unhandledCase(x)` changes no behaviour.
|
|
8
|
+
*/
|
|
9
|
+
export declare function unhandledCase(_value: never): never;
|
|
10
|
+
//# sourceMappingURL=unhandled-case.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Closes an exhaustive `switch` over a closed union.
|
|
3
|
+
*
|
|
4
|
+
* `value` is typed `never`, so the compiler still flags any union member the
|
|
5
|
+
* switch forgot. At runtime a value outside the declared union yields
|
|
6
|
+
* `undefined` — exactly what falling off the end of the switch did before — so
|
|
7
|
+
* ending a switch with `return unhandledCase(x)` changes no behaviour.
|
|
8
|
+
*/
|
|
9
|
+
export function unhandledCase(_value) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=unhandled-case.js.map
|
|
@@ -21,14 +21,12 @@ export function unitBezier(x1, y1, x2, y2) {
|
|
|
21
21
|
let t = x;
|
|
22
22
|
for (let i = 0; i < 8; i += 1) {
|
|
23
23
|
const err = sampleX(t) - x;
|
|
24
|
-
if (Math.abs(err) < 1e-6)
|
|
25
|
-
break;
|
|
26
24
|
const d = sampleDX(t);
|
|
27
25
|
// A flat x-derivative would make the Newton step divide by ~0. For smooth-scroll-to-top's
|
|
28
26
|
// fixed ease-out curve sampleDX stays at least about 0.6095 over [0, 1], so it never fires
|
|
29
27
|
// there; it does for degenerate control points (e.g. x1 = x2 = 0 near x = 0), where the
|
|
30
28
|
// current estimate is kept rather than stepping to Infinity/NaN.
|
|
31
|
-
if (Math.abs(d) < 1e-6)
|
|
29
|
+
if (Math.abs(err) < 1e-6 || Math.abs(d) < 1e-6)
|
|
32
30
|
break;
|
|
33
31
|
t -= err / d;
|
|
34
32
|
}
|
package/dist/utils/zip.js
CHANGED
|
@@ -3,17 +3,13 @@
|
|
|
3
3
|
// few MB — skipping deflate keeps the implementation small and
|
|
4
4
|
// dependency-free, which matters for a package meant to run in any host
|
|
5
5
|
// (browser or Node) without pulling in a compression library.
|
|
6
|
-
const CRC_TABLE = (() => {
|
|
7
|
-
|
|
8
|
-
for (let
|
|
9
|
-
|
|
10
|
-
for (let k = 0; k < 8; k++) {
|
|
11
|
-
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
12
|
-
}
|
|
13
|
-
t[n] = c >>> 0;
|
|
6
|
+
const CRC_TABLE = Array.from({ length: 256 }, (_, n) => {
|
|
7
|
+
let c = n;
|
|
8
|
+
for (let k = 0; k < 8; k++) {
|
|
9
|
+
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
14
10
|
}
|
|
15
|
-
return
|
|
16
|
-
})
|
|
11
|
+
return c >>> 0;
|
|
12
|
+
});
|
|
17
13
|
function crc32(bytes) {
|
|
18
14
|
let c = 0xffffffff;
|
|
19
15
|
for (let i = 0; i < bytes.length; i++) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/ui",
|
|
3
|
-
"version": "0.6.15
|
|
3
|
+
"version": "0.6.15",
|
|
4
4
|
"description": "Generic, product-neutral React UI primitives and feature domains. Framework-free types, decision rules, catalogs, and host port contracts live behind ./core (no React, no DOM). The Excalidraw and Lexical editors live behind ./sketch-editor and ./lexical-rich-text-editor; the GrapesJS-backed inline HTML editor lives behind ./html-editor.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -243,14 +243,15 @@
|
|
|
243
243
|
"shiki": "^1.24.4",
|
|
244
244
|
"tailwind-merge": "^2.6.0",
|
|
245
245
|
"zod": "^3.25.76",
|
|
246
|
-
"@jini-ai/agent-runtime": "^0.6.15
|
|
247
|
-
"@jini-ai/integrations": "^0.6.15
|
|
248
|
-
"@jini-ai/
|
|
249
|
-
"@jini-ai/core": "^0.6.15
|
|
250
|
-
"@jini-ai/
|
|
246
|
+
"@jini-ai/agent-runtime": "^0.6.15",
|
|
247
|
+
"@jini-ai/integrations": "^0.6.15",
|
|
248
|
+
"@jini-ai/agentic": "^0.6.15",
|
|
249
|
+
"@jini-ai/core": "^0.6.15",
|
|
250
|
+
"@jini-ai/platform": "^0.6.15"
|
|
251
251
|
},
|
|
252
252
|
"dependencies": {
|
|
253
|
-
"@jini-ai/
|
|
253
|
+
"@jini-ai/ui-kit": "^0.6.15",
|
|
254
|
+
"@jini-ai/core": "^0.6.15"
|
|
254
255
|
},
|
|
255
256
|
"peerDependencies": {
|
|
256
257
|
"@tanstack/react-query": "^5.0.0",
|
|
@@ -267,8 +268,8 @@
|
|
|
267
268
|
"lexical": "0.36.2",
|
|
268
269
|
"react": "^18.3.0 || ^19.0.0",
|
|
269
270
|
"react-dom": "^18.3.0 || ^19.0.0",
|
|
270
|
-
"@jini-ai/platform": "^0.6.
|
|
271
|
-
"@jini-ai/agentic": "^0.6.
|
|
271
|
+
"@jini-ai/platform": "^0.6.10",
|
|
272
|
+
"@jini-ai/agentic": "^0.6.10",
|
|
272
273
|
"class-variance-authority": "^0.7.1",
|
|
273
274
|
"clsx": "^2.1.1",
|
|
274
275
|
"micromark": "^4.0.0",
|