@inkra/react 0.3.0 → 0.4.3
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 +15 -3
- package/dist/Button.js +3 -2
- package/dist/PencilIcon.d.ts +10 -0
- package/dist/PencilIcon.js +83 -39
- package/dist/PencilLine.js +9 -1
- package/dist/PencilText.js +15 -9
- package/dist/accordion/Accordion.js +65 -5
- package/dist/alert-dialog/index.js +14 -4
- package/dist/audio-player/index.d.ts +2 -0
- package/dist/audio-player/index.js +126 -31
- package/dist/calendar/index.d.ts +4 -1
- package/dist/calendar/index.js +31 -12
- package/dist/carousel/index.js +13 -6
- package/dist/choice-grid/index.d.ts +6 -1
- package/dist/choice-grid/index.js +61 -33
- package/dist/color-picker/GradientEditor.d.ts +39 -0
- package/dist/color-picker/GradientEditor.js +63 -0
- package/dist/color-picker/gradient.d.ts +25 -0
- package/dist/color-picker/gradient.js +60 -0
- package/dist/color-picker/index.d.ts +27 -7
- package/dist/color-picker/index.js +134 -32
- package/dist/color-swatch/index.d.ts +10 -0
- package/dist/color-swatch/index.js +9 -0
- package/dist/command/index.js +27 -4
- package/dist/content/index.d.ts +5 -0
- package/dist/content/index.js +12 -3
- package/dist/context-menu/index.js +1 -1
- package/dist/data-table/index.d.ts +7 -1
- package/dist/data-table/index.js +64 -16
- package/dist/data-table/model.d.ts +2 -0
- package/dist/data-table/model.js +7 -0
- package/dist/date-picker/index.d.ts +2 -0
- package/dist/date-picker/index.js +10 -9
- package/dist/day-agenda/index.d.ts +6 -1
- package/dist/day-agenda/index.js +46 -21
- package/dist/day-agenda/layout.js +65 -9
- package/dist/display/ProgressRing.js +7 -3
- package/dist/display/index.d.ts +4 -1
- package/dist/display/index.js +3 -2
- package/dist/dockable-panel/index.js +5 -5
- package/dist/drawer/index.js +4 -3
- package/dist/editable/index.d.ts +24 -2
- package/dist/editable/index.js +142 -37
- package/dist/empty/illustrations.d.ts +8 -0
- package/dist/empty/illustrations.js +78 -0
- package/dist/empty/index.d.ts +6 -1
- package/dist/empty/index.js +11 -3
- package/dist/flip/index.js +28 -8
- package/dist/form/Field.js +11 -10
- package/dist/form/Textarea.d.ts +3 -1
- package/dist/form/Textarea.js +6 -4
- package/dist/hotkey/index.d.ts +1 -0
- package/dist/hotkey/index.js +6 -4
- package/dist/hover-card/index.js +1 -1
- package/dist/image-cropper/index.js +4 -2
- package/dist/image-viewer/VideoResource.d.ts +21 -0
- package/dist/image-viewer/VideoResource.js +194 -0
- package/dist/image-viewer/index.d.ts +14 -0
- package/dist/image-viewer/index.js +118 -65
- package/dist/image-viewer/lucideGeometry.d.ts +3 -0
- package/dist/image-viewer/lucideGeometry.js +19 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/input-number/index.js +9 -4
- package/dist/internal/cache.d.ts +4 -0
- package/dist/internal/cache.js +18 -1
- package/dist/internal/iconGeometry.d.ts +2 -0
- package/dist/internal/iconGeometry.js +32 -0
- package/dist/internal/renderTokens.d.ts +4 -0
- package/dist/internal/renderTokens.js +4 -0
- package/dist/internal/stroke.d.ts +7 -0
- package/dist/internal/stroke.js +63 -7
- package/dist/internal/surfaceBudget.d.ts +20 -0
- package/dist/internal/surfaceBudget.js +69 -0
- package/dist/internal/surfaceRenderer.js +87 -28
- package/dist/internal/surfaceVisibility.d.ts +3 -0
- package/dist/internal/surfaceVisibility.js +60 -0
- package/dist/internal/textRenderer.d.ts +2 -0
- package/dist/internal/textRenderer.js +3 -3
- package/dist/internal/usePencilSurface.js +17 -1
- package/dist/internal/wash.js +4 -3
- package/dist/journey-map/terrain.js +10 -5
- package/dist/layout/index.js +1 -1
- package/dist/log/index.js +29 -22
- package/dist/markdown/CodeBlock.d.ts +19 -0
- package/dist/markdown/CodeBlock.js +86 -0
- package/dist/markdown/Deletion.d.ts +2 -0
- package/dist/markdown/Deletion.js +69 -0
- package/dist/markdown/icons.d.ts +14 -0
- package/dist/markdown/icons.js +16 -0
- package/dist/markdown/index.d.ts +17 -0
- package/dist/markdown/index.js +175 -0
- package/dist/node-graph/index.d.ts +2 -0
- package/dist/node-graph/index.js +49 -25
- package/dist/number-ticker/precision.js +9 -2
- package/dist/overflow-list/index.js +5 -2
- package/dist/overlay/Overlay.js +1 -1
- package/dist/overlay/Popover.js +3 -3
- package/dist/overlay/themeBridge.js +14 -2
- package/dist/pagination/index.d.ts +10 -1
- package/dist/pagination/index.js +6 -4
- package/dist/pan-zoom/index.d.ts +2 -0
- package/dist/pan-zoom/index.js +7 -6
- package/dist/pencil.d.ts +1 -0
- package/dist/pencil.js +4 -4
- package/dist/radar/index.d.ts +2 -0
- package/dist/radar/index.js +40 -20
- package/dist/rating/index.d.ts +4 -0
- package/dist/rating/index.js +128 -24
- package/dist/resizable/index.js +1 -1
- package/dist/scroll-area/index.d.ts +1 -1
- package/dist/scroll-area/index.js +5 -2
- package/dist/select/MultipleSelect.js +5 -4
- package/dist/select/SearchableSelect.js +61 -6
- package/dist/select/Select.d.ts +1 -0
- package/dist/select/Select.js +3 -1
- package/dist/select/StepperSelect.d.ts +29 -0
- package/dist/select/StepperSelect.js +119 -0
- package/dist/select/index.d.ts +2 -0
- package/dist/select/index.js +1 -0
- package/dist/select/stepperModel.d.ts +7 -0
- package/dist/select/stepperModel.js +29 -0
- package/dist/selection/Checkbox.js +4 -3
- package/dist/selection/RadioGroup.js +29 -13
- package/dist/selection/Switch.js +4 -3
- package/dist/selection/useNativeChecked.d.ts +2 -1
- package/dist/selection/useNativeChecked.js +26 -8
- package/dist/slider/index.js +50 -6
- package/dist/sortable/index.js +6 -2
- package/dist/sparkline/index.js +17 -2
- package/dist/sparkline/model.js +11 -4
- package/dist/styles/accordion.css +228 -0
- package/dist/styles/alert-dialog.css +139 -0
- package/dist/styles/audio-player.css +22 -0
- package/dist/styles/base.css +638 -0
- package/dist/styles/breadcrumb.css +7 -0
- package/dist/styles/calendar.css +62 -0
- package/dist/styles/carousel.css +173 -0
- package/dist/styles/choice-grid.css +226 -0
- package/dist/styles/color-picker.css +281 -0
- package/dist/styles/color-swatch.css +47 -0
- package/dist/styles/command.css +52 -0
- package/dist/styles/content.css +79 -0
- package/dist/styles/context-menu.css +35 -0
- package/dist/styles/data-table.css +31 -0
- package/dist/styles/date-picker.css +107 -0
- package/dist/styles/day-agenda.css +30 -0
- package/dist/styles/display.css +304 -0
- package/dist/styles/dockable-panel.css +110 -0
- package/dist/styles/drawer.css +133 -0
- package/dist/styles/dropdown-menu.css +68 -0
- package/dist/styles/editable.css +145 -0
- package/dist/styles/empty.css +108 -0
- package/dist/styles/flip.css +101 -0
- package/dist/styles/form.css +634 -0
- package/dist/styles/heatmap.css +256 -0
- package/dist/styles/hotkey.css +189 -0
- package/dist/styles/hover-card.css +27 -0
- package/dist/styles/image-cropper.css +205 -0
- package/dist/styles/image-viewer.css +422 -0
- package/dist/styles/input-number.css +21 -0
- package/dist/styles/journey-map.css +19 -0
- package/dist/styles/keypad.css +92 -0
- package/dist/styles/layout.css +72 -0
- package/dist/styles/leaflet.css +661 -0
- package/dist/styles/log.css +203 -0
- package/dist/styles/markdown.css +379 -0
- package/dist/styles/node-graph.css +142 -0
- package/dist/styles/number-ticker.css +83 -0
- package/dist/styles/overflow-list.css +51 -0
- package/dist/styles/overlay.css +284 -0
- package/dist/styles/pagination.css +21 -0
- package/dist/styles/pan-zoom.css +136 -0
- package/dist/styles/radar.css +1 -0
- package/dist/styles/rating.css +121 -0
- package/dist/styles/resizable.css +108 -0
- package/dist/styles/scroll-area.css +122 -0
- package/dist/styles/select.css +557 -0
- package/dist/styles/selection.css +264 -0
- package/dist/styles/slider.css +145 -0
- package/dist/styles/slot.css +109 -0
- package/dist/styles/sortable.css +159 -0
- package/dist/styles/sparkline.css +24 -0
- package/dist/styles/steps.css +27 -0
- package/dist/styles/tabs.css +79 -0
- package/dist/styles/tag-input.css +213 -0
- package/dist/styles/time-picker.css +66 -0
- package/dist/styles/timeline.css +24 -0
- package/dist/styles/toast.css +160 -0
- package/dist/styles/toggle-group.css +107 -0
- package/dist/styles/tooltip.css +78 -0
- package/dist/styles/transfer.css +148 -0
- package/dist/styles/tree-select.css +131 -0
- package/dist/styles/tree.css +59 -0
- package/dist/styles/typewriter.css +62 -0
- package/dist/styles/upload.css +60 -0
- package/dist/styles/virtual-list.css +112 -0
- package/dist/styles.css +2094 -421
- package/dist/tabs/index.d.ts +9 -0
- package/dist/tabs/index.js +66 -16
- package/dist/tabs/useOverflow.d.ts +20 -0
- package/dist/tabs/useOverflow.js +145 -0
- package/dist/tag-input/index.d.ts +7 -2
- package/dist/tag-input/index.js +70 -26
- package/dist/time-picker/index.js +38 -20
- package/dist/toast/index.d.ts +19 -11
- package/dist/toast/index.js +48 -8
- package/dist/toast/manager.d.ts +42 -0
- package/dist/toast/manager.js +85 -0
- package/dist/toast/useToastNavigation.d.ts +3 -0
- package/dist/toast/useToastNavigation.js +75 -0
- package/dist/tokens.css +4 -0
- package/dist/tooltip/Tooltip.js +3 -3
- package/dist/transfer/index.d.ts +5 -0
- package/dist/transfer/index.js +93 -29
- package/dist/transfer/model.d.ts +4 -0
- package/dist/transfer/model.js +37 -11
- package/dist/tree/index.d.ts +5 -1
- package/dist/tree/index.js +5 -5
- package/dist/tree-select/index.js +67 -30
- package/dist/tree-select/model.d.ts +11 -5
- package/dist/tree-select/model.js +111 -83
- package/dist/typewriter/index.js +10 -10
- package/dist/upload/index.js +30 -16
- package/dist/virtual-list/index.js +7 -5
- package/package.json +413 -3
package/dist/form/Textarea.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useEffect, useId, useImperativeHandle, useRef, useState } from 'react';
|
|
3
3
|
import { PencilSurface } from '../PencilSurface.js';
|
|
4
|
+
import { PencilLine } from '../PencilLine.js';
|
|
4
5
|
import { PencilText } from '../PencilText.js';
|
|
5
6
|
import { PencilIcon } from '../PencilIcon.js';
|
|
6
7
|
import { Button } from '../Button.js';
|
|
7
8
|
import { Progress } from '../display/index.js';
|
|
8
9
|
import { useResolvedControlProps } from './controlProps.js';
|
|
9
10
|
import { EditablePencilText } from './EditablePencilText.js';
|
|
11
|
+
import { InputAction } from './InputAction.js';
|
|
10
12
|
const resizePaths = [{ d: 'M12 3v18M8 7l4-4 4 4M8 17l4 4 4-4' }];
|
|
11
13
|
const defaultCountLabel = ({ remaining }) => remaining < 0 ? `${-remaining} over limit` : `${remaining} remaining`;
|
|
12
|
-
export const Textarea = forwardRef(function Textarea({ 'aria-describedby': ariaDescribedBy, 'aria-errormessage': ariaErrorMessage, 'aria-invalid': ariaInvalid, className, disabled, id, invalid = false, readOnly, required, seed, size = 'md', countMode = 'remaining', countDisplay = 'auto', countThreshold = 0.8, getCountLabel = defaultCountLabel, resize = 'none', resizeLabel = 'Resize text area', ...props }, ref) {
|
|
14
|
+
export const Textarea = forwardRef(function Textarea({ 'aria-describedby': ariaDescribedBy, 'aria-errormessage': ariaErrorMessage, 'aria-invalid': ariaInvalid, className, disabled, id, invalid = false, readOnly, required, seed, size = 'md', variant = 'outline', endAction, countMode = 'remaining', countDisplay = 'auto', countThreshold = 0.8, getCountLabel = defaultCountLabel, resize = 'none', resizeLabel = 'Resize text area', ...props }, ref) {
|
|
13
15
|
const generatedId = useId();
|
|
14
16
|
const textareaRef = useRef(null);
|
|
15
17
|
const [uncontrolledCount, setUncontrolledCount] = useState(() => String(props.defaultValue ?? '').length);
|
|
@@ -69,11 +71,11 @@ export const Textarea = forwardRef(function Textarea({ 'aria-describedby': ariaD
|
|
|
69
71
|
});
|
|
70
72
|
const resolvedSeed = seed ?? `inkra-textarea-${state.id ?? generatedId}`;
|
|
71
73
|
const classes = ['inkra-textarea', className].filter(Boolean).join(' ');
|
|
72
|
-
return (_jsx("div", { className: "inkra-field-control-hit inkra-field-control-hit--textarea", "data-disabled": state.disabled || undefined, "data-invalid": state.invalid || undefined, "data-readonly": state.readOnly || undefined, "data-size": size, children: _jsxs(PencilSurface, { className: "inkra-field-control inkra-field-control--textarea", seed: resolvedSeed, variant: state.invalid ? 'danger' : 'outline', children: [_jsx("textarea", { ...props, "aria-describedby": [state.describedBy, showCount && countId].filter(Boolean).join(' ') || undefined, "aria-errormessage": state.errorMessage, "aria-invalid": state.ariaInvalid, className: classes, disabled: state.disabled, id: state.id, readOnly: state.readOnly, ref: textareaRef, required: state.required, style: { ...props.style, ...(resize === 'vertical' && height !== undefined ? { height } : {}), resize: 'none' }, onInput: event => {
|
|
74
|
+
return (_jsx("div", { className: "inkra-field-control-hit inkra-field-control-hit--textarea", "data-disabled": state.disabled || undefined, "data-invalid": state.invalid || undefined, "data-readonly": state.readOnly || undefined, "data-size": size, "data-variant": variant, "data-end-action": endAction != null || undefined, children: _jsxs(PencilSurface, { className: "inkra-field-control inkra-field-control--textarea", seed: resolvedSeed, variant: variant === 'underline' ? 'ghost' : state.invalid ? 'danger' : 'outline', children: [_jsx("textarea", { ...props, "aria-describedby": [state.describedBy, showCount && countId].filter(Boolean).join(' ') || undefined, "aria-errormessage": state.errorMessage, "aria-invalid": state.ariaInvalid, className: classes, disabled: state.disabled, id: state.id, readOnly: state.readOnly, ref: textareaRef, required: state.required, style: { ...props.style, ...(resize === 'vertical' && height !== undefined ? { height } : {}), resize: 'none' }, onInput: event => {
|
|
73
75
|
if (!controlled)
|
|
74
76
|
setUncontrolledCount(event.currentTarget.value.length);
|
|
75
77
|
props.onInput?.(event);
|
|
76
|
-
} }), _jsx(EditablePencilText, { controlRef: textareaRef, defaultValue: props.defaultValue, multiline: true, placeholder: props.placeholder, seed: `${resolvedSeed}-editable`, value: props.value }), (hasCount || resize === 'vertical') && _jsxs("div", { className: "inkra-textarea__footer", children: [hasCount && _jsxs("div", { className: "inkra-textarea__count", id: countId, "data-visible": showCount, "data-limit": remaining <= 0 ? 'reached' : 'near', "aria-hidden": !showCount || undefined, children: [countMode === 'progress' && _jsx(Progress, { size: "sm", value: maximum === 0 ? 1 : count, max: maximum === 0 ? 1 : maximum, "aria-label": countLabel, "aria-valuetext": countLabel }), _jsx(PencilText, { children: countMode === 'fraction' ? `${count} / ${maximum}` : countLabel })] }), resize === 'vertical' && _jsx(Button, { className: "inkra-textarea__resize", variant: "ghost", size: "icon", role: "slider", "aria-label": resizeLabel, title: resizeLabel, "aria-controls": state.id, "aria-orientation": "vertical", "aria-valuemin": minimumHeight, "aria-valuemax": 1200, "aria-valuenow": Math.round(measuredHeight ?? minimumHeight), disabled: state.disabled, onPointerDown: event => {
|
|
78
|
+
} }), _jsx(EditablePencilText, { controlRef: textareaRef, defaultValue: props.defaultValue, multiline: true, placeholder: props.placeholder, seed: `${resolvedSeed}-editable`, value: props.value }), endAction != null && _jsx("div", { className: "inkra-textarea__end-action", children: _jsx(InputAction, { disabled: Boolean(state.disabled), seed: `${resolvedSeed}-action`, children: endAction }) }), (hasCount || resize === 'vertical') && _jsxs("div", { className: "inkra-textarea__footer", children: [hasCount && _jsxs("div", { className: "inkra-textarea__count", id: countId, "data-visible": showCount, "data-limit": remaining <= 0 ? 'reached' : 'near', "aria-hidden": !showCount || undefined, children: [countMode === 'progress' && _jsx(Progress, { size: "sm", value: maximum === 0 ? 1 : count, max: maximum === 0 ? 1 : maximum, "aria-label": countLabel, "aria-valuetext": countLabel }), _jsx(PencilText, { children: countMode === 'fraction' ? `${count} / ${maximum}` : countLabel })] }), resize === 'vertical' && _jsx(Button, { className: "inkra-textarea__resize", variant: "ghost", size: "icon", role: "slider", "aria-label": resizeLabel, title: resizeLabel, "aria-controls": state.id, "aria-orientation": "vertical", "aria-valuemin": minimumHeight, "aria-valuemax": 1200, "aria-valuenow": Math.round(measuredHeight ?? minimumHeight), disabled: state.disabled, onPointerDown: event => {
|
|
77
79
|
if (event.button !== 0)
|
|
78
80
|
return;
|
|
79
81
|
drag.current = { y: event.clientY, height: textareaRef.current?.getBoundingClientRect().height ?? minimumHeight };
|
|
@@ -98,5 +100,5 @@ export const Textarea = forwardRef(function Textarea({ 'aria-describedby': ariaD
|
|
|
98
100
|
else
|
|
99
101
|
return;
|
|
100
102
|
event.preventDefault();
|
|
101
|
-
}, children: _jsx(PencilIcon, { paths: resizePaths, size: 22 }) })] })] }) }));
|
|
103
|
+
}, children: _jsx(PencilIcon, { paths: resizePaths, size: 22 }) })] }), variant === 'underline' && _jsx(PencilLine, { className: "inkra-textarea__underline", seed: `${resolvedSeed}-underline` })] }) }));
|
|
102
104
|
});
|
package/dist/hotkey/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export interface HotkeyInputProps extends Omit<InputHTMLAttributes<HTMLInputElem
|
|
|
25
25
|
conflictMessage?: string;
|
|
26
26
|
platform?: HotkeyPlatform;
|
|
27
27
|
placeholder?: string;
|
|
28
|
+
recordingLabel?: string;
|
|
28
29
|
clearable?: boolean;
|
|
29
30
|
clearButtonLabel?: string;
|
|
30
31
|
blurOnCapture?: boolean;
|
package/dist/hotkey/index.js
CHANGED
|
@@ -34,7 +34,7 @@ export const Hotkey = forwardRef(function Hotkey({ 'aria-label': ariaLabel, clas
|
|
|
34
34
|
const label = formatHotkey(normalized, resolvedPlatform);
|
|
35
35
|
return (_jsx("kbd", { ...props, "aria-label": ariaLabel ?? label, className: classes('inkra-hotkey', className), "data-platform": resolvedPlatform, "data-size": size, ref: ref, children: tokens.map((token, index) => (_jsxs("span", { className: "inkra-hotkey__part", children: [index > 0 && resolvedPlatform !== 'mac' ? (_jsx("span", { "aria-hidden": "true", className: "inkra-hotkey__separator", children: separator ?? '+' })) : null, _jsx(PencilSurface, { "aria-hidden": "true", as: "span", className: "inkra-hotkey__key", radius: 4, seed: `${hotkeySignature(normalized)}-${resolvedPlatform}-${index}`, variant: "quiet", children: _jsx(PencilText, { seed: `${hotkeySignature(normalized)}-${resolvedPlatform}-${index}-label`, children: token }) })] }, `${token}-${index}`))) }));
|
|
36
36
|
});
|
|
37
|
-
export const HotkeyInput = forwardRef(function HotkeyInput({ 'aria-describedby': ariaDescribedBy, 'aria-errormessage': ariaErrorMessage, 'aria-invalid': ariaInvalid, 'aria-label': ariaLabel, blurOnCapture = true, className, classNames = {}, clearable = true, clearButtonLabel = 'Clear shortcut', conflict, conflictMessage = 'Shortcut already assigned', defaultValue = null, disabled, id, invalid = false, onBlur, onCancel, onCompositionEnd, onCompositionStart, onConflict, onFocus, onKeyDown, onValueChange, placeholder = 'Press shortcut', platform = 'auto', readOnly, required, seed, size = 'md', validateHotkey, value, ...props }, forwardedRef) {
|
|
37
|
+
export const HotkeyInput = forwardRef(function HotkeyInput({ 'aria-describedby': ariaDescribedBy, 'aria-errormessage': ariaErrorMessage, 'aria-invalid': ariaInvalid, 'aria-label': ariaLabel, blurOnCapture = true, className, classNames = {}, clearable = true, clearButtonLabel = 'Clear shortcut', conflict, conflictMessage = 'Shortcut already assigned', defaultValue = null, disabled, id, invalid = false, onBlur, onCancel, onCompositionEnd, onCompositionStart, onConflict, onFocus, onKeyDown, onValueChange, placeholder = 'Press shortcut', platform = 'auto', readOnly, recordingLabel = 'Press a shortcut...', required, seed, size = 'md', validateHotkey, value, ...props }, forwardedRef) {
|
|
38
38
|
const generatedId = useId();
|
|
39
39
|
const inputRef = useRef(null);
|
|
40
40
|
const composingRef = useRef(false);
|
|
@@ -48,18 +48,20 @@ export const HotkeyInput = forwardRef(function HotkeyInput({ 'aria-describedby':
|
|
|
48
48
|
const currentSignature = hotkeySignature(currentValue);
|
|
49
49
|
const validationMessage = externalConflict ?? (localConflict?.signature === currentSignature ? localConflict.message : undefined);
|
|
50
50
|
const messageId = validationMessage ? `${id ?? generatedId}-hotkey-conflict` : undefined;
|
|
51
|
+
const statusId = `${id ?? generatedId}-hotkey-status`;
|
|
51
52
|
const state = useResolvedControlProps({
|
|
52
53
|
id,
|
|
53
54
|
required,
|
|
54
55
|
disabled,
|
|
55
56
|
readOnly,
|
|
56
57
|
invalid: invalid || Boolean(validationMessage),
|
|
57
|
-
'aria-describedby': [ariaDescribedBy, messageId].filter(Boolean).join(' ') || undefined,
|
|
58
|
+
'aria-describedby': [ariaDescribedBy, statusId, messageId].filter(Boolean).join(' ') || undefined,
|
|
58
59
|
'aria-errormessage': validationMessage ? messageId : ariaErrorMessage,
|
|
59
60
|
'aria-invalid': ariaInvalid,
|
|
60
61
|
});
|
|
61
62
|
const resolvedSeed = seed ?? `inkra-hotkey-input-${state.id ?? generatedId}`;
|
|
62
63
|
const displayValue = currentValue ? formatHotkey(currentValue, resolvedPlatform) : '';
|
|
64
|
+
const recording = focused && !state.disabled && !state.readOnly;
|
|
63
65
|
useImperativeHandle(forwardedRef, () => inputRef.current);
|
|
64
66
|
const updateValue = (nextValue, details) => {
|
|
65
67
|
if (!isControlled)
|
|
@@ -119,12 +121,12 @@ export const HotkeyInput = forwardRef(function HotkeyInput({ 'aria-describedby':
|
|
|
119
121
|
setFocused(false);
|
|
120
122
|
onBlur?.(event);
|
|
121
123
|
};
|
|
122
|
-
return (_jsxs("span", { className: classes('inkra-hotkey-input', classNames.root), "data-disabled": state.disabled || undefined, "data-focus-within": focused || undefined, "data-invalid": state.invalid || undefined, "data-readonly": state.readOnly || undefined, "data-size": size, children: [_jsxs(PencilSurface, { as: "span", className: classes('inkra-hotkey-input__control', classNames.control), clipContent: true, seed: resolvedSeed, variant: state.invalid ? 'danger' : 'outline', children: [_jsx("input", { ...props, "aria-describedby": state.describedBy, "aria-errormessage": state.errorMessage, "aria-invalid": state.ariaInvalid, "aria-label": ariaLabel, autoComplete: "off", className: classes('inkra-hotkey-input__native', className, classNames.input), disabled: state.disabled, id: state.id, inputMode: "none", onBlur: handleBlur, onChange: () => { }, onCompositionEnd: event => {
|
|
124
|
+
return (_jsxs("span", { className: classes('inkra-hotkey-input', classNames.root), "data-disabled": state.disabled || undefined, "data-focus-within": focused || undefined, "data-invalid": state.invalid || undefined, "data-recording": recording || undefined, "data-readonly": state.readOnly || undefined, "data-size": size, children: [_jsxs(PencilSurface, { as: "span", className: classes('inkra-hotkey-input__control', classNames.control), clipContent: true, seed: resolvedSeed, variant: state.invalid ? 'danger' : 'outline', children: [_jsx("input", { ...props, "aria-describedby": state.describedBy, "aria-errormessage": state.errorMessage, "aria-invalid": state.ariaInvalid, "aria-label": ariaLabel, autoComplete: "off", className: classes('inkra-hotkey-input__native', className, classNames.input), disabled: state.disabled, id: state.id, inputMode: "none", onBlur: handleBlur, onChange: () => { }, onCompositionEnd: event => {
|
|
123
125
|
composingRef.current = false;
|
|
124
126
|
onCompositionEnd?.(event);
|
|
125
127
|
}, onCompositionStart: event => {
|
|
126
128
|
composingRef.current = true;
|
|
127
129
|
onCompositionStart?.(event);
|
|
128
|
-
}, onFocus: handleFocus, onKeyDown: handleKeyDown, readOnly: state.readOnly, ref: inputRef, required: state.required, spellCheck: false, value: displayValue }), _jsx("span", { "aria-hidden": "true", className: classes('inkra-hotkey-input__value', classNames.value), children: currentValue ? _jsx(Hotkey, { value: currentValue, platform: resolvedPlatform, size: size }) : _jsx(PencilText, { className: "inkra-hotkey-input__placeholder", seed: `${resolvedSeed}-placeholder`, children: placeholder }) }), clearable && currentValue ? (_jsx("button", { "aria-label": clearButtonLabel, className: "inkra-hotkey-input__clear", disabled: state.disabled || state.readOnly, onClick: clear, onPointerDown: event => event.preventDefault(), title: clearButtonLabel, type: "button", children: _jsx(PencilIcon, { paths: clearPaths, seed: `${resolvedSeed}-clear`, size: size === 'sm' ? 18 : size === 'lg' ? 26 : 22, sourceSize: 24 }) })) : null] }), validationMessage ? (_jsx(PencilText, { as: "span", className: classes('inkra-hotkey-input__message', classNames.message), id: messageId, role: "alert", seed: `${resolvedSeed}-message`, children: validationMessage })) : null] }));
|
|
130
|
+
}, onFocus: handleFocus, onKeyDown: handleKeyDown, readOnly: state.readOnly, ref: inputRef, required: state.required, spellCheck: false, value: displayValue }), _jsx("span", { "aria-hidden": "true", className: classes('inkra-hotkey-input__value', classNames.value), children: recording ? (_jsx(PencilText, { className: "inkra-hotkey-input__recording", seed: `${resolvedSeed}-recording`, children: recordingLabel })) : currentValue ? (_jsx(Hotkey, { value: currentValue, platform: resolvedPlatform, size: size })) : (_jsx(PencilText, { className: "inkra-hotkey-input__placeholder", seed: `${resolvedSeed}-placeholder`, children: placeholder })) }), clearable && currentValue ? (_jsx("button", { "aria-label": clearButtonLabel, className: "inkra-hotkey-input__clear", disabled: state.disabled || state.readOnly, onClick: clear, onPointerDown: event => event.preventDefault(), title: clearButtonLabel, type: "button", children: _jsx(PencilIcon, { paths: clearPaths, seed: `${resolvedSeed}-clear`, size: size === 'sm' ? 18 : size === 'lg' ? 26 : 22, sourceSize: 24 }) })) : null, _jsx(PencilSurface, { "aria-hidden": "true", as: "span", className: "inkra-hotkey-input__focus-ring", seed: `${resolvedSeed}-focus`, variant: "outline" })] }), _jsx("span", { "aria-live": "polite", className: "inkra-hotkey-input__status", id: statusId, children: recording ? recordingLabel : '' }), validationMessage ? (_jsx(PencilText, { as: "span", className: classes('inkra-hotkey-input__message', classNames.message), id: messageId, role: "alert", seed: `${resolvedSeed}-message`, children: validationMessage })) : null] }));
|
|
129
131
|
});
|
|
130
132
|
export { detectHotkeyPlatform, formatHotkey, getHotkeyTokens, hotkeyFromKeyboardEvent, hotkeySignature, normalizeHotkey, };
|
package/dist/hover-card/index.js
CHANGED
|
@@ -131,7 +131,7 @@ export const HoverCardContent = forwardRef(function HoverCardContent({ avoidColl
|
|
|
131
131
|
export const HoverCardTitle = PopoverTitle;
|
|
132
132
|
export const HoverCardDescription = PopoverDescription;
|
|
133
133
|
export const HoverCardClose = PopoverClose;
|
|
134
|
-
export const HoverCard = Object.freeze({
|
|
134
|
+
export const HoverCard = /* @__PURE__ */ Object.freeze({
|
|
135
135
|
Root: HoverCardRoot,
|
|
136
136
|
Trigger: HoverCardTrigger,
|
|
137
137
|
Content: HoverCardContent,
|
|
@@ -124,8 +124,10 @@ export const ImageCropper = forwardRef(function ImageCropper({ alt, aspect = 1,
|
|
|
124
124
|
return undefined;
|
|
125
125
|
const update = () => {
|
|
126
126
|
const rect = stage.getBoundingClientRect();
|
|
127
|
-
if (rect.width > 0 && rect.height > 0)
|
|
128
|
-
setStageSize(
|
|
127
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
128
|
+
setStageSize(current => current.width === rect.width && current.height === rect.height
|
|
129
|
+
? current : { width: rect.width, height: rect.height });
|
|
130
|
+
}
|
|
129
131
|
};
|
|
130
132
|
update();
|
|
131
133
|
const observer = new ResizeObserver(update);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface VideoResourceLabels {
|
|
2
|
+
controls: string;
|
|
3
|
+
play: string;
|
|
4
|
+
pause: string;
|
|
5
|
+
seek: string;
|
|
6
|
+
mute: string;
|
|
7
|
+
unmute: string;
|
|
8
|
+
volume: string;
|
|
9
|
+
rate: string;
|
|
10
|
+
playbackError: string;
|
|
11
|
+
time: (current: number, duration: number) => string;
|
|
12
|
+
}
|
|
13
|
+
export interface VideoResourceProps {
|
|
14
|
+
src: string;
|
|
15
|
+
poster?: string;
|
|
16
|
+
alt: string;
|
|
17
|
+
labels?: Partial<VideoResourceLabels>;
|
|
18
|
+
onError?: () => void;
|
|
19
|
+
onLoad?: () => void;
|
|
20
|
+
}
|
|
21
|
+
export declare function VideoResource({ alt, labels: overrides, onError, onLoad, poster, src }: VideoResourceProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { __iconData as pauseIcon } from 'lucide-react/dist/esm/icons/pause.mjs';
|
|
3
|
+
import { __iconData as playIcon } from 'lucide-react/dist/esm/icons/play.mjs';
|
|
4
|
+
import { __iconData as volumeIcon } from 'lucide-react/dist/esm/icons/volume-2.mjs';
|
|
5
|
+
import { __iconData as muteIcon } from 'lucide-react/dist/esm/icons/volume-x.mjs';
|
|
6
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
7
|
+
import { Button } from '../Button.js';
|
|
8
|
+
import { PencilIcon } from '../PencilIcon.js';
|
|
9
|
+
import { PencilText } from '../PencilText.js';
|
|
10
|
+
import { Select } from '../select/index.js';
|
|
11
|
+
import { Slider } from '../slider/index.js';
|
|
12
|
+
function number(attributes, name) {
|
|
13
|
+
const value = Number(attributes[name]);
|
|
14
|
+
return Number.isFinite(value) ? value : 0;
|
|
15
|
+
}
|
|
16
|
+
function iconPaths(nodes) {
|
|
17
|
+
return nodes.flatMap(([tag, attributes]) => {
|
|
18
|
+
if (tag === 'path' && attributes.d)
|
|
19
|
+
return [{ d: attributes.d }];
|
|
20
|
+
if (tag === 'line')
|
|
21
|
+
return [{ d: `M${number(attributes, 'x1')} ${number(attributes, 'y1')}L${number(attributes, 'x2')} ${number(attributes, 'y2')}` }];
|
|
22
|
+
if (tag === 'rect') {
|
|
23
|
+
const x = number(attributes, 'x');
|
|
24
|
+
const y = number(attributes, 'y');
|
|
25
|
+
const width = number(attributes, 'width');
|
|
26
|
+
const height = number(attributes, 'height');
|
|
27
|
+
const radius = Math.min(number(attributes, 'rx'), width / 2, height / 2);
|
|
28
|
+
return [{ d: radius
|
|
29
|
+
? `M${x + radius} ${y}H${x + width - radius}Q${x + width} ${y} ${x + width} ${y + radius}V${y + height - radius}Q${x + width} ${y + height} ${x + width - radius} ${y + height}H${x + radius}Q${x} ${y + height} ${x} ${y + height - radius}V${y + radius}Q${x} ${y} ${x + radius} ${y}Z`
|
|
30
|
+
: `M${x} ${y}H${x + width}V${y + height}H${x}Z` }];
|
|
31
|
+
}
|
|
32
|
+
return [];
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const playPaths = iconPaths(playIcon.node);
|
|
36
|
+
const pausePaths = iconPaths(pauseIcon.node);
|
|
37
|
+
const volumePaths = iconPaths(volumeIcon.node);
|
|
38
|
+
const mutePaths = iconPaths(muteIcon.node);
|
|
39
|
+
const rates = [0.75, 1, 1.25, 1.5, 2];
|
|
40
|
+
const defaultLabels = {
|
|
41
|
+
controls: 'Video controls',
|
|
42
|
+
play: 'Play video',
|
|
43
|
+
pause: 'Pause video',
|
|
44
|
+
seek: 'Seek video',
|
|
45
|
+
mute: 'Mute video',
|
|
46
|
+
unmute: 'Unmute video',
|
|
47
|
+
volume: 'Video volume',
|
|
48
|
+
rate: 'Playback speed',
|
|
49
|
+
playbackError: 'Video playback could not start.',
|
|
50
|
+
time: (current, duration) => `${formatTime(current)} / ${formatTime(duration)}`,
|
|
51
|
+
};
|
|
52
|
+
function clamp(value, min, max) {
|
|
53
|
+
return Number.isFinite(value) ? Math.min(max, Math.max(min, value)) : min;
|
|
54
|
+
}
|
|
55
|
+
function formatTime(value) {
|
|
56
|
+
if (!Number.isFinite(value) || value < 0)
|
|
57
|
+
return '0:00';
|
|
58
|
+
const seconds = Math.floor(value);
|
|
59
|
+
return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')}`;
|
|
60
|
+
}
|
|
61
|
+
export function VideoResource({ alt, labels: overrides, onError, onLoad, poster, src }) {
|
|
62
|
+
const videoRef = useRef(null);
|
|
63
|
+
const sourceRef = useRef(src);
|
|
64
|
+
sourceRef.current = src;
|
|
65
|
+
const mountedRef = useRef(false);
|
|
66
|
+
const generationRef = useRef(0);
|
|
67
|
+
const playRequestRef = useRef(0);
|
|
68
|
+
const callbacksRef = useRef({ onError, onLoad });
|
|
69
|
+
callbacksRef.current = { onError, onLoad };
|
|
70
|
+
const [playing, setPlaying] = useState(false);
|
|
71
|
+
const [currentTime, setCurrentTime] = useState(0);
|
|
72
|
+
const [duration, setDuration] = useState(0);
|
|
73
|
+
const [volume, setVolumeState] = useState(1);
|
|
74
|
+
const [muted, setMutedState] = useState(false);
|
|
75
|
+
const [playbackRate, setPlaybackRateState] = useState(1);
|
|
76
|
+
const [playbackError, setPlaybackError] = useState(false);
|
|
77
|
+
const labels = { ...defaultLabels, ...overrides };
|
|
78
|
+
const sync = useCallback(() => {
|
|
79
|
+
const video = videoRef.current;
|
|
80
|
+
if (!video)
|
|
81
|
+
return;
|
|
82
|
+
setPlaying(!video.paused && !video.ended);
|
|
83
|
+
setCurrentTime(Number.isFinite(video.currentTime) ? video.currentTime : 0);
|
|
84
|
+
setDuration(Number.isFinite(video.duration) ? video.duration : 0);
|
|
85
|
+
setVolumeState(video.volume);
|
|
86
|
+
setMutedState(video.muted);
|
|
87
|
+
setPlaybackRateState(video.playbackRate);
|
|
88
|
+
}, []);
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
mountedRef.current = true;
|
|
91
|
+
return () => {
|
|
92
|
+
mountedRef.current = false;
|
|
93
|
+
generationRef.current += 1;
|
|
94
|
+
playRequestRef.current += 1;
|
|
95
|
+
videoRef.current?.pause();
|
|
96
|
+
};
|
|
97
|
+
}, []);
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
const video = videoRef.current;
|
|
100
|
+
if (!video)
|
|
101
|
+
return undefined;
|
|
102
|
+
const handlers = {
|
|
103
|
+
loadedmetadata: () => { sync(); callbacksRef.current.onLoad?.(); },
|
|
104
|
+
durationchange: sync,
|
|
105
|
+
timeupdate: sync,
|
|
106
|
+
play: sync,
|
|
107
|
+
pause: sync,
|
|
108
|
+
ended: sync,
|
|
109
|
+
volumechange: sync,
|
|
110
|
+
ratechange: sync,
|
|
111
|
+
emptied: sync,
|
|
112
|
+
error: () => { sync(); callbacksRef.current.onError?.(); },
|
|
113
|
+
};
|
|
114
|
+
Object.entries(handlers).forEach(([name, handler]) => video.addEventListener(name, handler));
|
|
115
|
+
return () => Object.entries(handlers).forEach(([name, handler]) => video.removeEventListener(name, handler));
|
|
116
|
+
}, [sync]);
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
const video = videoRef.current;
|
|
119
|
+
if (!video)
|
|
120
|
+
return undefined;
|
|
121
|
+
generationRef.current += 1;
|
|
122
|
+
playRequestRef.current += 1;
|
|
123
|
+
video.pause();
|
|
124
|
+
try {
|
|
125
|
+
video.currentTime = 0;
|
|
126
|
+
}
|
|
127
|
+
catch { /* A source may not have a timeline yet. */ }
|
|
128
|
+
setPlaying(false);
|
|
129
|
+
setCurrentTime(0);
|
|
130
|
+
setDuration(0);
|
|
131
|
+
setPlaybackError(false);
|
|
132
|
+
video.load();
|
|
133
|
+
return () => { video.pause(); };
|
|
134
|
+
}, [src]);
|
|
135
|
+
const togglePlay = async () => {
|
|
136
|
+
const video = videoRef.current;
|
|
137
|
+
if (!video)
|
|
138
|
+
return;
|
|
139
|
+
if (!video.paused) {
|
|
140
|
+
playRequestRef.current += 1;
|
|
141
|
+
video.pause();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const generation = generationRef.current;
|
|
145
|
+
const source = sourceRef.current;
|
|
146
|
+
const request = ++playRequestRef.current;
|
|
147
|
+
setPlaybackError(false);
|
|
148
|
+
try {
|
|
149
|
+
await video.play();
|
|
150
|
+
if (!mountedRef.current || generation !== generationRef.current || source !== sourceRef.current || request !== playRequestRef.current)
|
|
151
|
+
return;
|
|
152
|
+
sync();
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
if (!mountedRef.current || generation !== generationRef.current || source !== sourceRef.current || request !== playRequestRef.current)
|
|
156
|
+
return;
|
|
157
|
+
setPlaybackError(true);
|
|
158
|
+
sync();
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const seek = (next) => {
|
|
162
|
+
const video = videoRef.current;
|
|
163
|
+
if (!video || !Number.isFinite(next))
|
|
164
|
+
return;
|
|
165
|
+
video.currentTime = clamp(next, 0, Number.isFinite(video.duration) ? video.duration : Math.max(0, next));
|
|
166
|
+
sync();
|
|
167
|
+
};
|
|
168
|
+
const setVolume = (next) => {
|
|
169
|
+
const video = videoRef.current;
|
|
170
|
+
if (!video)
|
|
171
|
+
return;
|
|
172
|
+
video.volume = clamp(next, 0, 1);
|
|
173
|
+
if (video.muted && video.volume > 0)
|
|
174
|
+
video.muted = false;
|
|
175
|
+
sync();
|
|
176
|
+
};
|
|
177
|
+
const setMuted = (next) => {
|
|
178
|
+
const video = videoRef.current;
|
|
179
|
+
if (!video)
|
|
180
|
+
return;
|
|
181
|
+
video.muted = next;
|
|
182
|
+
sync();
|
|
183
|
+
};
|
|
184
|
+
const setRate = (next) => {
|
|
185
|
+
const video = videoRef.current;
|
|
186
|
+
if (!video)
|
|
187
|
+
return;
|
|
188
|
+
const rate = clamp(next, 0.25, 4);
|
|
189
|
+
video.defaultPlaybackRate = rate;
|
|
190
|
+
video.playbackRate = rate;
|
|
191
|
+
sync();
|
|
192
|
+
};
|
|
193
|
+
return _jsxs("div", { className: "inkra-image-viewer__video-resource", children: [_jsx("video", { "aria-label": alt, className: "inkra-image-viewer__video-media", controls: false, playsInline: true, poster: poster, preload: "metadata", ref: videoRef, src: src }), _jsxs("div", { "aria-label": labels.controls, className: "inkra-image-viewer__video-controls", role: "group", children: [playbackError ? _jsx(PencilText, { as: "p", className: "inkra-image-viewer__video-error", role: "alert", children: labels.playbackError }) : null, _jsx(Button, { "aria-label": playing ? labels.pause : labels.play, className: "inkra-image-viewer__video-play", onClick: () => void togglePlay(), size: "icon-sm", variant: "outline", children: _jsx(PencilIcon, { decorative: true, paths: playing ? pausePaths : playPaths, size: 22, sourceSize: 24 }) }), _jsx("div", { className: "inkra-image-viewer__video-seek", children: _jsx(Slider, { "aria-label": labels.seek, disabled: !duration, getValueLabel: value => labels.time(value, duration), max: duration || 0, min: 0, onValueChange: values => seek(values[0] ?? 0), size: "sm", step: 0.01, value: [currentTime], variant: "inset" }) }), _jsx(PencilText, { "aria-live": "off", as: "span", className: "inkra-image-viewer__video-time", dir: "auto", children: labels.time(currentTime, duration) }), _jsxs("div", { className: "inkra-image-viewer__video-settings", children: [_jsx(Button, { "aria-label": muted ? labels.unmute : labels.mute, className: "inkra-image-viewer__video-mute", onClick: () => setMuted(!muted), size: "icon-sm", variant: "ghost", children: _jsx(PencilIcon, { decorative: true, paths: muted ? mutePaths : volumePaths, size: 22, sourceSize: 24 }) }), _jsx("div", { className: "inkra-image-viewer__video-volume", children: _jsx(Slider, { "aria-label": labels.volume, getValueLabel: value => `${Math.round(value * 100)}%`, max: 1, min: 0, onValueChange: values => setVolume(values[0] ?? 0), size: "sm", step: 0.01, value: [muted ? 0 : volume], variant: "inset" }) }), _jsxs(Select.Root, { onValueChange: value => setRate(Number(value)), value: String(playbackRate), children: [_jsx(Select.Trigger, { "aria-label": labels.rate, fullWidth: false, size: "sm", children: _jsx(Select.Value, {}) }), _jsx(Select.Portal, { children: _jsx(Select.Content, { position: "popper", sideOffset: 4, children: _jsx(Select.Viewport, { children: rates.map(rate => _jsxs(Select.Item, { value: String(rate), children: [_jsx(Select.ItemText, { children: `${rate}x` }), _jsx(Select.ItemIndicator, {})] }, rate)) }) }) })] })] })] })] });
|
|
194
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { PanZoomWheelMode } from '../pan-zoom/index.js';
|
|
3
3
|
import type { OverlayContentProps, OverlayRootProps, OverlayTriggerProps } from '../overlay/index.js';
|
|
4
|
+
import type { VideoResourceLabels } from './VideoResource.js';
|
|
4
5
|
export interface ImageViewerItem {
|
|
5
6
|
id: string;
|
|
6
7
|
src: string;
|
|
7
8
|
alt: string;
|
|
9
|
+
type?: 'image' | 'video';
|
|
10
|
+
poster?: string;
|
|
8
11
|
thumbnailSrc?: string;
|
|
9
12
|
thumbnailAlt?: string;
|
|
10
13
|
width?: number;
|
|
@@ -68,6 +71,7 @@ export interface ImageViewerContentProps extends Omit<OverlayContentProps, 'chil
|
|
|
68
71
|
minScale?: number;
|
|
69
72
|
maxScale?: number;
|
|
70
73
|
wheel?: PanZoomWheelMode;
|
|
74
|
+
videoLabels?: Partial<VideoResourceLabels>;
|
|
71
75
|
}
|
|
72
76
|
export declare const ImageViewerContent: import("react").ForwardRefExoticComponent<ImageViewerContentProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
73
77
|
export declare const ImageViewer: Readonly<{
|
|
@@ -75,5 +79,15 @@ export declare const ImageViewer: Readonly<{
|
|
|
75
79
|
Trigger: import("react").ForwardRefExoticComponent<import("@radix-ui/react-dialog").DialogTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
76
80
|
Content: import("react").ForwardRefExoticComponent<ImageViewerContentProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
77
81
|
}>;
|
|
82
|
+
export declare const MediaViewer: Readonly<{
|
|
83
|
+
Root: typeof ImageViewerRoot;
|
|
84
|
+
Trigger: import("react").ForwardRefExoticComponent<import("@radix-ui/react-dialog").DialogTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
85
|
+
Content: import("react").ForwardRefExoticComponent<ImageViewerContentProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
86
|
+
}>;
|
|
87
|
+
export type MediaViewerItem = ImageViewerItem;
|
|
88
|
+
export type MediaViewerLabels = ImageViewerLabels;
|
|
89
|
+
export type MediaViewerRootProps = ImageViewerRootProps;
|
|
90
|
+
export type MediaViewerContentProps = ImageViewerContentProps;
|
|
91
|
+
export type { VideoResourceLabels } from './VideoResource.js';
|
|
78
92
|
export { nextImageViewerIndex, resolveImageViewerSelection } from './model.js';
|
|
79
93
|
export type { ImageViewerIdentifiable, ImageViewerSelection } from './model.js';
|