@enonic/ui 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -77
- package/dist/enonic-ui.cjs +1 -1
- package/dist/enonic-ui.es.js +124 -119
- package/dist/style.cjs +1 -0
- package/dist/style.es.js +1 -0
- package/dist/styles/preset.css +2 -2
- package/dist/styles/style.css +1 -1
- package/dist/styles/tokens.css +0 -2
- package/dist/types/components/app-root/app-root.d.ts +49 -0
- package/dist/types/components/app-root/index.d.ts +1 -0
- package/dist/types/components/combobox/combobox.d.ts +4 -3
- package/dist/types/components/context-menu/context-menu.d.ts +8 -1
- package/dist/types/components/date-picker/date-picker.d.ts +2 -2
- package/dist/types/components/dialog/dialog.d.ts +1 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/components/menu/menu.d.ts +2 -2
- package/dist/types/components/menubar/menubar.d.ts +4 -5
- package/dist/types/components/selector/selector.d.ts +3 -3
- package/dist/types/components/time-picker/time-picker.d.ts +2 -2
- package/dist/types/hooks/index.d.ts +1 -1
- package/dist/types/hooks/use-floating-position.d.ts +57 -10
- package/dist/types/hooks/use-portal-focus-container.d.ts +3 -2
- package/dist/types/hooks/use-radio-navigation.d.ts +2 -0
- package/dist/types/hooks/use-step-navigation.d.ts +2 -0
- package/dist/types/providers/combobox-provider.d.ts +3 -0
- package/dist/types/providers/index.d.ts +1 -0
- package/dist/types/providers/portal-provider.d.ts +21 -0
- package/dist/types/style.d.ts +8 -0
- package/dist/types/utils/dom.d.ts +22 -0
- package/package.json +31 -16
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react';
|
|
2
|
+
import { FloatingProps } from '../../hooks';
|
|
2
3
|
export type SelectorRootProps = {
|
|
3
4
|
children?: ReactNode;
|
|
4
5
|
value?: string;
|
|
@@ -48,13 +49,12 @@ export type SelectorIconProps = {
|
|
|
48
49
|
export type SelectorContentProps = {
|
|
49
50
|
className?: string;
|
|
50
51
|
children?: ReactNode;
|
|
51
|
-
|
|
52
|
-
/** Whether to render in a portal to document.body. Defaults to true. Set to false when used inside another portaled component (e.g., DatePicker/TimePicker inside Dialog). */
|
|
52
|
+
/** Whether to render in a portal. Defaults to true. Set to false when used inside another portaled component (e.g., DatePicker/TimePicker inside Dialog). */
|
|
53
53
|
portal?: boolean;
|
|
54
54
|
onEscapeKeyDown?: (event: KeyboardEvent) => void;
|
|
55
55
|
onPointerDownOutside?: (event: PointerEvent) => void;
|
|
56
56
|
onInteractOutside?: (event: Event) => void;
|
|
57
|
-
} & ComponentPropsWithoutRef<'div'>;
|
|
57
|
+
} & FloatingProps & ComponentPropsWithoutRef<'div'>;
|
|
58
58
|
export type SelectorViewportProps = {
|
|
59
59
|
className?: string;
|
|
60
60
|
children?: ReactNode;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, ReactElement, ReactNode, RefObject } from 'react';
|
|
2
|
+
import { FloatingProps } from '../../hooks';
|
|
2
3
|
export type TimePickerHourSelectProps = {
|
|
3
4
|
className?: string;
|
|
4
5
|
contentClassName?: string;
|
|
@@ -22,12 +23,11 @@ export type TimePickerTriggerProps = {
|
|
|
22
23
|
children?: ReactNode;
|
|
23
24
|
} & Omit<ComponentPropsWithoutRef<'button'>, 'className' | 'children'>;
|
|
24
25
|
export type TimePickerContentProps = {
|
|
25
|
-
align?: 'start' | 'end';
|
|
26
26
|
/** Optional reference to an anchor element for positioning (defaults to trigger) */
|
|
27
27
|
anchorRef?: RefObject<HTMLElement>;
|
|
28
28
|
className?: string;
|
|
29
29
|
children?: ReactNode;
|
|
30
|
-
} & Omit<ComponentPropsWithoutRef<'div'>, 'className' | 'children'>;
|
|
30
|
+
} & FloatingProps & Omit<ComponentPropsWithoutRef<'div'>, 'className' | 'children'>;
|
|
31
31
|
export type TimePickerRootProps = {
|
|
32
32
|
value?: string | null;
|
|
33
33
|
defaultValue?: string | null;
|
|
@@ -4,7 +4,7 @@ export { type UseBlinkAttentionConfig, useBlinkAttention } from './use-blink-att
|
|
|
4
4
|
export { type UseClickOutsideConfig, useClickOutside } from './use-click-outside';
|
|
5
5
|
export { useControlledState } from './use-controlled-state';
|
|
6
6
|
export { useControlledStateWithNull } from './use-controlled-state-with-null';
|
|
7
|
-
export { type FloatingPosition, type FloatingSide, type UseFloatingPositionConfig, useFloatingPosition, } from './use-floating-position';
|
|
7
|
+
export { type CollisionStrategy, type FloatingPosition, type FloatingProps, type FloatingSide, toFloatingStyle, type UseFloatingPositionConfig, useFloatingPosition, } from './use-floating-position';
|
|
8
8
|
export { type ActiveCell, type GridNavigationConfig, type UseGridNavigationReturn, useGridNavigation, } from './use-grid-navigation';
|
|
9
9
|
export { type ItemMetadata, type UseItemRegistryReturn, useItemRegistry } from './use-item-registry';
|
|
10
10
|
export { type UseItemTextRegistryReturn, useItemTextRegistry } from './use-item-text-registry';
|
|
@@ -1,11 +1,30 @@
|
|
|
1
|
-
import { RefObject } from 'react';
|
|
1
|
+
import { CSSProperties, RefObject } from 'react';
|
|
2
2
|
export type FloatingSide = 'top' | 'bottom' | 'left' | 'right';
|
|
3
|
+
export type CollisionStrategy = 'flip' | 'shrink';
|
|
3
4
|
export type FloatingPosition = {
|
|
4
5
|
top: number;
|
|
5
6
|
left?: number;
|
|
6
7
|
right?: number;
|
|
7
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* The side the popup is actually positioned on. Equals `preferredSide`
|
|
10
|
+
* unless `collisionStrategy` is `'flip'` and the popup was flipped to fit.
|
|
11
|
+
*/
|
|
8
12
|
side: FloatingSide;
|
|
13
|
+
/** The `side` requested via config — useful when `flipped` is true. */
|
|
14
|
+
preferredSide: FloatingSide;
|
|
15
|
+
/** True when the popup could not use `preferredSide`. */
|
|
16
|
+
flipped: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Maximum height the popup should be clamped to, in pixels. Set whenever
|
|
19
|
+
* `collisionStrategy` is `'shrink'`. Consumers apply it via inline style on
|
|
20
|
+
* the popup wrapper; it only takes effect when the content is taller.
|
|
21
|
+
*
|
|
22
|
+
* A popup whose items are direct children also needs `overflow-y-auto` to
|
|
23
|
+
* scroll. One that wraps a scrollable child (a listbox or viewport) must not:
|
|
24
|
+
* constraining the wrapper alone keeps the child the scroller, which is what
|
|
25
|
+
* scroll-active-into-view relies on.
|
|
26
|
+
*/
|
|
27
|
+
maxHeight?: number;
|
|
9
28
|
};
|
|
10
29
|
export type UseFloatingPositionConfig = {
|
|
11
30
|
/** Whether the floating element is open/visible */
|
|
@@ -15,8 +34,7 @@ export type UseFloatingPositionConfig = {
|
|
|
15
34
|
/** Reference to the floating content element */
|
|
16
35
|
contentRef: RefObject<HTMLElement> | null;
|
|
17
36
|
/**
|
|
18
|
-
* Preferred side relative to the anchor.
|
|
19
|
-
* the content would overflow the viewport.
|
|
37
|
+
* Preferred side relative to the anchor.
|
|
20
38
|
* @default 'bottom'
|
|
21
39
|
*/
|
|
22
40
|
side?: FloatingSide;
|
|
@@ -27,16 +45,45 @@ export type UseFloatingPositionConfig = {
|
|
|
27
45
|
* @default 'start'
|
|
28
46
|
*/
|
|
29
47
|
align?: 'start' | 'end';
|
|
48
|
+
/**
|
|
49
|
+
* How to react when the preferred side cannot fit the popup:
|
|
50
|
+
* - `'flip'` (default) — flip to the opposite side if it fits; else stay on
|
|
51
|
+
* the preferred side and overflow.
|
|
52
|
+
* - `'shrink'` — keep the preferred side and return the available space as
|
|
53
|
+
* `maxHeight`, which the consumer applies to enable internal scroll. Falls
|
|
54
|
+
* back to the opposite side when the preferred one is too cramped to use.
|
|
55
|
+
*
|
|
56
|
+
* @default 'flip'
|
|
57
|
+
*/
|
|
58
|
+
collisionStrategy?: CollisionStrategy;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Projects a position into an inline style, keeping the coordinate fields and
|
|
62
|
+
* dropping the descriptive ones (`side`, `preferredSide`, `flipped`) that would
|
|
63
|
+
* otherwise leak into the DOM as invalid CSS.
|
|
64
|
+
*/
|
|
65
|
+
export declare function toFloatingStyle(position: FloatingPosition | null): CSSProperties;
|
|
66
|
+
/**
|
|
67
|
+
* Shared prop surface for popup components that build on `useFloatingPosition`.
|
|
68
|
+
* Mix into a component's `*Props` type to expose consistent positioning controls
|
|
69
|
+
* across the library.
|
|
70
|
+
*/
|
|
71
|
+
export type FloatingProps = {
|
|
72
|
+
/** Preferred side relative to the anchor. @default 'bottom' */
|
|
73
|
+
side?: FloatingSide;
|
|
74
|
+
/** Alignment along the perpendicular axis. @default 'start' */
|
|
75
|
+
align?: 'start' | 'end';
|
|
76
|
+
/** Collision behavior when the preferred side does not fit. @default 'flip' */
|
|
77
|
+
collisionStrategy?: CollisionStrategy;
|
|
30
78
|
};
|
|
31
79
|
/**
|
|
32
80
|
* Calculates optimal position for floating elements (menus, dropdowns, submenus) relative
|
|
33
|
-
* to an anchor, with
|
|
81
|
+
* to an anchor, with viewport collision handling controlled by `collisionStrategy`.
|
|
34
82
|
*
|
|
35
|
-
* Supports four preferred sides (top/bottom/left/right).
|
|
36
|
-
*
|
|
37
|
-
* alignment is adjusted to keep the content within the viewport.
|
|
83
|
+
* Supports four preferred sides (top/bottom/left/right). Perpendicular-axis alignment is
|
|
84
|
+
* always adjusted to keep the content within the viewport, regardless of strategy.
|
|
38
85
|
*
|
|
39
86
|
* @param config - Configuration object for positioning behavior
|
|
40
|
-
* @returns Position object with
|
|
87
|
+
* @returns Position object with coordinates and side info, or null if not yet calculated
|
|
41
88
|
*/
|
|
42
|
-
export declare function useFloatingPosition({ enabled, anchorRef, contentRef, side: preferredSide, align, }: UseFloatingPositionConfig): FloatingPosition | null;
|
|
89
|
+
export declare function useFloatingPosition({ enabled, anchorRef, contentRef, side: preferredSide, align, collisionStrategy, }: UseFloatingPositionConfig): FloatingPosition | null;
|
|
@@ -11,11 +11,12 @@ import { RefObject } from 'react';
|
|
|
11
11
|
* ```tsx
|
|
12
12
|
* const contentRef = useRef<HTMLDivElement>(null);
|
|
13
13
|
* const [isPortalMode, setIsPortalMode] = useState(false);
|
|
14
|
+
* const portalContainer = usePortalContainer();
|
|
14
15
|
*
|
|
15
16
|
* useLayoutEffect(() => {
|
|
16
17
|
* if (!open || !contentRef.current) return;
|
|
17
|
-
* setIsPortalMode(contentRef.current.parentElement ===
|
|
18
|
-
* }, [open]);
|
|
18
|
+
* setIsPortalMode(contentRef.current.parentElement === portalContainer);
|
|
19
|
+
* }, [open, portalContainer]);
|
|
19
20
|
*
|
|
20
21
|
* usePortalFocusContainer(contentRef, isPortalMode);
|
|
21
22
|
* ```
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
1
2
|
export type RadioNavigationConfig = {
|
|
2
3
|
baseId: string;
|
|
3
4
|
getItems: () => string[];
|
|
4
5
|
getItemId?: (baseId: string, itemId: string) => string;
|
|
6
|
+
rootRef?: RefObject<HTMLElement>;
|
|
5
7
|
value: string | undefined;
|
|
6
8
|
onValueChange: (value: string) => void;
|
|
7
9
|
isItemDisabled: (id: string) => boolean;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
1
2
|
export type StepNavigationConfig = {
|
|
2
3
|
baseId: string;
|
|
3
4
|
getItems: () => string[];
|
|
4
5
|
getNextFocusable?: (baseId: string, itemId: string) => string;
|
|
6
|
+
rootRef?: RefObject<HTMLElement>;
|
|
5
7
|
value: string | undefined;
|
|
6
8
|
onValueChange: (value: string) => void;
|
|
7
9
|
isItemDisabled: (id: string) => boolean;
|
|
@@ -2,6 +2,8 @@ import { ReactElement, ReactNode, RefObject } from 'react';
|
|
|
2
2
|
export type ContentType = 'listbox' | 'tree' | 'auto';
|
|
3
3
|
export type ComboboxOpenOptions = {
|
|
4
4
|
restoreFocus?: boolean;
|
|
5
|
+
/** Whether this interaction should focus the input on open or restore it on close. */
|
|
6
|
+
focusInput?: boolean;
|
|
5
7
|
};
|
|
6
8
|
export type ComboboxContextValue = {
|
|
7
9
|
baseId: string;
|
|
@@ -10,6 +12,7 @@ export type ComboboxContextValue = {
|
|
|
10
12
|
applyRef: RefObject<HTMLButtonElement>;
|
|
11
13
|
popupRef: RefObject<HTMLDivElement>;
|
|
12
14
|
restoreFocusOnCloseRef: RefObject<boolean>;
|
|
15
|
+
inputFocusIntentRef: RefObject<boolean>;
|
|
13
16
|
ignoreFocusExitCloseRef: RefObject<boolean>;
|
|
14
17
|
open: boolean;
|
|
15
18
|
setOpen: (next: boolean, options?: ComboboxOpenOptions) => void;
|
|
@@ -12,6 +12,7 @@ export * from './listbox-provider';
|
|
|
12
12
|
export * from './menu-provider';
|
|
13
13
|
export * from './menubar-menu-provider';
|
|
14
14
|
export * from './menubar-provider';
|
|
15
|
+
export * from './portal-provider';
|
|
15
16
|
export * from './radio-provider';
|
|
16
17
|
export * from './search-field-provider';
|
|
17
18
|
export * from './selector-provider';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
|
+
export type PortalProviderProps = {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
/** The element every overlay in the subtree portals into. `null` falls back to `document.body`. */
|
|
5
|
+
container: HTMLElement | null;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Overrides where overlays (dialogs, menus, tooltips, popups) portal to. Without a provider they
|
|
9
|
+
* portal to `document.body`, which lies outside any shadow root.
|
|
10
|
+
*/
|
|
11
|
+
export declare const PortalProvider: {
|
|
12
|
+
({ children, container }: PortalProviderProps): ReactElement;
|
|
13
|
+
displayName: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Resolves the portal container: an explicit `container` prop wins, then the nearest
|
|
17
|
+
* `PortalProvider`, then `document.body`.
|
|
18
|
+
*
|
|
19
|
+
* `null` means there is no document (server render) — callers must not portal until it is set.
|
|
20
|
+
*/
|
|
21
|
+
export declare const usePortalContainer: (container?: HTMLElement | null) => HTMLElement | null;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The package's compiled stylesheet as text, for consumers without a Tailwind build rendering
|
|
3
|
+
* inside a shadow root: construct a sheet from it once and pass that to `AppRoot`'s `stylesheets`.
|
|
4
|
+
* With your own Tailwind v4 build, pass your compiled CSS instead — never both.
|
|
5
|
+
*/
|
|
6
|
+
export declare const styleText: string;
|
|
7
|
+
/** `styleText` as a constructed stylesheet, built once on first call. Browser-only. */
|
|
8
|
+
export declare const getStyleSheet: () => CSSStyleSheet;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a node is a shadow root. Checked by shape rather than `instanceof`, which only recognises
|
|
3
|
+
* the realm the library was loaded in — a root owned by an iframe document would not match.
|
|
4
|
+
*/
|
|
5
|
+
export declare const isShadowRoot: (node: Node | null | undefined) => node is ShadowRoot;
|
|
6
|
+
/**
|
|
7
|
+
* The document or shadow root a node lives in — the scope id and selector lookups must go through,
|
|
8
|
+
* since `document.getElementById` stops at a shadow boundary.
|
|
9
|
+
*
|
|
10
|
+
* `null` when there is nothing to resolve against: no node, and no document either, as on a server.
|
|
11
|
+
*/
|
|
12
|
+
export declare const getRoot: (node: Node | null | undefined) => Document | ShadowRoot | null;
|
|
13
|
+
/**
|
|
14
|
+
* The deeply focused element. From outside a shadow root `document.activeElement` reports the host
|
|
15
|
+
* rather than the focused element inside it. Stops at a closed root, whose `shadowRoot` is hidden.
|
|
16
|
+
*/
|
|
17
|
+
export declare const getActiveElement: () => Element | null;
|
|
18
|
+
/**
|
|
19
|
+
* Whether a container holds a node, crossing shadow boundaries. `Node.contains` stops at them, so a
|
|
20
|
+
* node focused inside a nested root reads as outside the host that holds it.
|
|
21
|
+
*/
|
|
22
|
+
export declare const containsDeep: (container: Node | null | undefined, node: Node | null | undefined) => boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enonic/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Enonic UI Component Library",
|
|
5
5
|
"author": "Enonic",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
"files": [
|
|
34
34
|
"dist/enonic-ui.es.js",
|
|
35
35
|
"dist/enonic-ui.cjs",
|
|
36
|
+
"dist/style.es.js",
|
|
37
|
+
"dist/style.cjs",
|
|
36
38
|
"dist/styles/",
|
|
37
39
|
"dist/types/"
|
|
38
40
|
],
|
|
@@ -42,6 +44,11 @@
|
|
|
42
44
|
"import": "./dist/enonic-ui.es.js",
|
|
43
45
|
"require": "./dist/enonic-ui.cjs"
|
|
44
46
|
},
|
|
47
|
+
"./style": {
|
|
48
|
+
"types": "./dist/types/style.d.ts",
|
|
49
|
+
"import": "./dist/style.es.js",
|
|
50
|
+
"require": "./dist/style.cjs"
|
|
51
|
+
},
|
|
45
52
|
"./style.css": "./dist/styles/style.css",
|
|
46
53
|
"./preset.css": "./dist/styles/preset.css",
|
|
47
54
|
"./tokens.css": "./dist/styles/tokens.css",
|
|
@@ -87,29 +94,33 @@
|
|
|
87
94
|
"@preact/preset-vite": "~2.10.6",
|
|
88
95
|
"@radix-ui/react-slot": "^1.3.3",
|
|
89
96
|
"@size-limit/preset-small-lib": "~13.0.3",
|
|
90
|
-
"@storybook/addon-a11y": "~10.
|
|
91
|
-
"@storybook/addon-docs": "~10.
|
|
92
|
-
"@storybook/addon-themes": "~10.
|
|
93
|
-
"@storybook/preact-vite": "~10.
|
|
97
|
+
"@storybook/addon-a11y": "~10.6.0",
|
|
98
|
+
"@storybook/addon-docs": "~10.6.0",
|
|
99
|
+
"@storybook/addon-themes": "~10.6.0",
|
|
100
|
+
"@storybook/preact-vite": "~10.6.0",
|
|
101
|
+
"@storybook/test-runner": "^0.24.4",
|
|
94
102
|
"@tailwindcss/vite": "~4.3.3",
|
|
95
|
-
"@types/node": "~
|
|
103
|
+
"@types/node": "~26.4.1",
|
|
96
104
|
"@types/react": "~19.2.18",
|
|
97
|
-
"@types/react-dom": "~19.2.
|
|
105
|
+
"@types/react-dom": "~19.2.7",
|
|
98
106
|
"@typescript/typescript6": "~6.0.2",
|
|
99
107
|
"focus-trap-react": "^12.0.3",
|
|
100
|
-
"
|
|
108
|
+
"http-server": "^14.1.1",
|
|
109
|
+
"lucide-preact": "~1.40.0",
|
|
110
|
+
"playwright": "^1.62.1",
|
|
101
111
|
"react-virtuoso": "^4.18.11",
|
|
102
|
-
"rollup-plugin-visualizer": "~7.
|
|
112
|
+
"rollup-plugin-visualizer": "~7.1.1",
|
|
103
113
|
"size-limit": "~13.0.3",
|
|
104
|
-
"storybook": "~10.
|
|
114
|
+
"storybook": "~10.6.0",
|
|
105
115
|
"tailwindcss": "~4.3.3",
|
|
106
|
-
"terser": "~5.
|
|
116
|
+
"terser": "~5.51.2",
|
|
107
117
|
"tw-animate-css": "^1.4.0",
|
|
108
118
|
"typescript": "~7.0.2",
|
|
109
|
-
"vite": "npm:@voidzero-dev/vite-plus-core@^0.
|
|
110
|
-
"vite-plugin-dts": "~5.0
|
|
119
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@^0.3.0",
|
|
120
|
+
"vite-plugin-dts": "~5.1.0",
|
|
111
121
|
"vite-plugin-environment": "~1.1.3",
|
|
112
|
-
"vite-plus": "^0.
|
|
122
|
+
"vite-plus": "^0.3.0",
|
|
123
|
+
"wait-on": "^9.1.0"
|
|
113
124
|
},
|
|
114
125
|
"engines": {
|
|
115
126
|
"node": ">=24.16.0",
|
|
@@ -128,6 +139,10 @@
|
|
|
128
139
|
"path": "dist/styles/style.css",
|
|
129
140
|
"limit": "15 KB"
|
|
130
141
|
},
|
|
142
|
+
{
|
|
143
|
+
"path": "dist/style.es.js",
|
|
144
|
+
"limit": "20 KB"
|
|
145
|
+
},
|
|
131
146
|
{
|
|
132
147
|
"path": "dist/styles/preset.css",
|
|
133
148
|
"limit": "2 KB"
|
|
@@ -151,9 +166,9 @@
|
|
|
151
166
|
"format:check": "vp fmt --check",
|
|
152
167
|
"test": "exit 0",
|
|
153
168
|
"test:ci": "exit 0",
|
|
169
|
+
"test:storybook": "test-storybook --includeTags interactions-smoke",
|
|
154
170
|
"release:dry": "pnpm publish --dry-run --no-git-checks",
|
|
155
171
|
"analyze": "pnpm build && open dist/stats.html",
|
|
156
|
-
"size": "size-limit"
|
|
157
|
-
"preview": "pnpm dlx serve . -p 4000"
|
|
172
|
+
"size": "size-limit"
|
|
158
173
|
}
|
|
159
174
|
}
|