@zvk/ui 0.1.6 → 0.1.8
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/CHANGELOG.md +19 -0
- package/README.md +2 -2
- package/dist/components/context-menu/context-menu.d.ts +3 -1
- package/dist/components/context-menu/context-menu.js +57 -3
- package/dist/components/context-menu/index.d.ts +1 -1
- package/dist/components/index.d.ts +2 -2
- package/dist/components/menubar/index.d.ts +1 -1
- package/dist/components/menubar/menubar.d.ts +1 -1
- package/dist/components/menubar/menubar.js +31 -3
- package/dist/internal/floating/auto-update.js +21 -9
- package/dist/styles.css +0 -1
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.8](https://github.com/brandon-schabel/zvk/compare/v0.1.7...v0.1.8) (2026-06-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add composite component package ([dc0920f](https://github.com/brandon-schabel/zvk/commit/dc0920fe77dd2bd63015a40b3d7675fe8f1d0067))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* restore preview source aliases ([6fd494a](https://github.com/brandon-schabel/zvk/commit/6fd494af071bc4dd3fe1685bce9cd5c44aa22bd6))
|
|
14
|
+
|
|
15
|
+
## [0.1.7](https://github.com/brandon-schabel/zvk/compare/v0.1.6...v0.1.7) (2026-06-15)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* harden popup positioning ([efb8c8a](https://github.com/brandon-schabel/zvk/commit/efb8c8a98c2b759f4e84a60f5ae292b1e8900907))
|
|
21
|
+
|
|
3
22
|
## [0.1.6](https://github.com/brandon-schabel/zvk/compare/v0.1.5...v0.1.6) (2026-06-12)
|
|
4
23
|
|
|
5
24
|
|
package/README.md
CHANGED
|
@@ -22,8 +22,8 @@ import "@zvk/ui/styles.css";
|
|
|
22
22
|
|
|
23
23
|
GitHub Actions runs `bun run preflight` before release publishing. Release Please opens
|
|
24
24
|
reviewable version-bump PRs from conventional commits; merging a release PR creates the
|
|
25
|
-
GitHub release and publishes `@zvk/ui
|
|
26
|
-
`npm-publish` environment.
|
|
25
|
+
GitHub release and publishes any package with a created release, including `@zvk/ui`, to npm
|
|
26
|
+
through trusted publishing in the protected `npm-publish` environment.
|
|
27
27
|
|
|
28
28
|
## Component Surface
|
|
29
29
|
|
|
@@ -14,6 +14,8 @@ export interface ContextMenuContentProps extends React.HTMLAttributes<HTMLDivEle
|
|
|
14
14
|
side?: FloatingSide;
|
|
15
15
|
align?: FloatingAlign;
|
|
16
16
|
alignOffset?: number;
|
|
17
|
+
sideOffset?: number;
|
|
18
|
+
collisionPadding?: number;
|
|
17
19
|
ref?: React.Ref<HTMLDivElement>;
|
|
18
20
|
}
|
|
19
21
|
export interface ContextMenuItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
@@ -38,7 +40,7 @@ export interface ContextMenuRadioItemProps extends ContextMenuItemProps {
|
|
|
38
40
|
}
|
|
39
41
|
declare function ContextMenuRoot({ children, className, defaultOpen, onOpenChange, open: openProp, ref, ...props }: ContextMenuProps): React.JSX.Element;
|
|
40
42
|
declare function ContextMenuTrigger({ asChild, children, className, onContextMenu, onKeyDown, ref, ...props }: ContextMenuTriggerProps): React.JSX.Element;
|
|
41
|
-
declare function ContextMenuContent({ align, alignOffset
|
|
43
|
+
declare function ContextMenuContent({ align, alignOffset, children, className, collisionPadding, onKeyDown, ref, side, sideOffset, style, ...props }: ContextMenuContentProps): React.JSX.Element | null;
|
|
42
44
|
declare function ContextMenuItem({ asChild, children, className, disabled, onClick, onKeyDown, onSelect, ref, tone, type, ...props }: ContextMenuItemProps): React.JSX.Element;
|
|
43
45
|
declare function ContextMenuLabel({ className, ref, ...props }: ContextMenuLabelProps): React.JSX.Element;
|
|
44
46
|
declare function ContextMenuCheckboxItem({ asChild, checked, children, className, defaultChecked, disabled, onCheckedChange, onClick, onKeyDown, onSelect, ref, tone, type, ...props }: ContextMenuCheckboxItemProps): React.JSX.Element;
|
|
@@ -6,6 +6,7 @@ import { cn } from "../../utils/cn.js";
|
|
|
6
6
|
import { useControllableState } from "../../hooks/use-controllable-state.js";
|
|
7
7
|
import { createCollection } from "../../internal/collection/index.js";
|
|
8
8
|
import { DismissableLayer } from "../../internal/dismissable-layer/index.js";
|
|
9
|
+
import { clamp, computeFloatingPosition } from "../../internal/floating/index.js";
|
|
9
10
|
import { placementFromSideAlign, placementParts } from "../../internal/floating/placement-aliases.js";
|
|
10
11
|
import { Portal } from "../../internal/portal/index.js";
|
|
11
12
|
import { Slot } from "../../internal/slot/index.js";
|
|
@@ -114,20 +115,73 @@ function currentIndex(items) {
|
|
|
114
115
|
const enabled = items.filter((item) => item.data.disabled !== true && item.data.ref !== null);
|
|
115
116
|
return enabled.findIndex((item) => item.data.ref === document.activeElement);
|
|
116
117
|
}
|
|
117
|
-
function ContextMenuContent({ align, alignOffset
|
|
118
|
+
function ContextMenuContent({ align, alignOffset = 0, children, className, collisionPadding = 4, onKeyDown, ref, side, sideOffset = 0, style, ...props }) {
|
|
118
119
|
const { close, contentId, getItems, open, point } = useContextMenuContext("ContextMenu.Content");
|
|
119
120
|
const contentPlacement = placementFromSideAlign(side, align, "bottom-start");
|
|
120
|
-
const
|
|
121
|
+
const [contentStyle, setContentStyle] = React.useState({});
|
|
122
|
+
const [resolvedPlacement, setResolvedPlacement] = React.useState(contentPlacement);
|
|
123
|
+
const contentRef = React.useRef(null);
|
|
124
|
+
const updatePosition = React.useCallback(() => {
|
|
125
|
+
const node = contentRef.current;
|
|
126
|
+
if (node === null || typeof window === "undefined") {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const rect = node.getBoundingClientRect();
|
|
130
|
+
const computed = computeFloatingPosition({
|
|
131
|
+
reference: { x: point.x, y: point.y, width: 0, height: 0 },
|
|
132
|
+
floating: { x: 0, y: 0, width: rect.width, height: rect.height },
|
|
133
|
+
boundary: { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight },
|
|
134
|
+
placement: contentPlacement,
|
|
135
|
+
strategy: "fixed",
|
|
136
|
+
offset: sideOffset,
|
|
137
|
+
alignmentOffset: alignOffset,
|
|
138
|
+
collisionPadding,
|
|
139
|
+
flip: true,
|
|
140
|
+
shift: true
|
|
141
|
+
});
|
|
142
|
+
const minX = collisionPadding;
|
|
143
|
+
const minY = collisionPadding;
|
|
144
|
+
const maxX = Math.max(minX, window.innerWidth - collisionPadding - rect.width);
|
|
145
|
+
const maxY = Math.max(minY, window.innerHeight - collisionPadding - rect.height);
|
|
146
|
+
setContentStyle({
|
|
147
|
+
position: computed.strategy,
|
|
148
|
+
left: `${clamp(computed.x, minX, maxX)}px`,
|
|
149
|
+
top: `${clamp(computed.y, minY, maxY)}px`
|
|
150
|
+
});
|
|
151
|
+
setResolvedPlacement(computed.placement);
|
|
152
|
+
}, [alignOffset, collisionPadding, contentPlacement, point.x, point.y, sideOffset]);
|
|
153
|
+
const schedulePositionUpdate = React.useCallback(() => {
|
|
154
|
+
if (typeof queueMicrotask === "function") {
|
|
155
|
+
queueMicrotask(updatePosition);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
window.setTimeout(updatePosition, 0);
|
|
159
|
+
}, [updatePosition]);
|
|
121
160
|
React.useLayoutEffect(() => {
|
|
122
161
|
if (!open) {
|
|
123
162
|
return;
|
|
124
163
|
}
|
|
125
164
|
queueMicrotask(() => focusItem(getItems(), 0));
|
|
126
165
|
}, [getItems, open]);
|
|
166
|
+
React.useLayoutEffect(() => {
|
|
167
|
+
if (!open) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
updatePosition();
|
|
171
|
+
window.addEventListener("resize", updatePosition);
|
|
172
|
+
return () => {
|
|
173
|
+
window.removeEventListener("resize", updatePosition);
|
|
174
|
+
};
|
|
175
|
+
}, [open, updatePosition]);
|
|
127
176
|
if (!open) {
|
|
128
177
|
return null;
|
|
129
178
|
}
|
|
130
|
-
return (_jsx(Portal, { children: _jsx(DismissableLayer, { open: open, onDismiss: close, children: _jsx("div", { ...props, ref:
|
|
179
|
+
return (_jsx(Portal, { children: _jsx(DismissableLayer, { open: open, onDismiss: close, children: _jsx("div", { ...props, ref: (node) => {
|
|
180
|
+
setComposedRef(contentRef, ref, node);
|
|
181
|
+
if (node !== null) {
|
|
182
|
+
schedulePositionUpdate();
|
|
183
|
+
}
|
|
184
|
+
}, id: contentId, role: "menu", className: cn("zvk-ui-context-menu__content", className), "data-align": placementParts(resolvedPlacement).align, "data-side": placementParts(resolvedPlacement).side, style: { ...style, ...contentStyle }, onKeyDown: composeEventHandlers(onKeyDown, (event) => {
|
|
131
185
|
const items = getItems();
|
|
132
186
|
const index = currentIndex(items);
|
|
133
187
|
if (event.key === "ArrowDown") {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { ContextMenu } from "./context-menu.js";
|
|
2
|
-
export type { ContextMenuCheckboxItemProps, ContextMenuContentProps, ContextMenuItemProps, ContextMenuLabelProps, ContextMenuProps, ContextMenuSeparatorProps, ContextMenuTriggerProps } from "./context-menu.js";
|
|
2
|
+
export type { ContextMenuCheckboxItemProps, ContextMenuContentProps, ContextMenuItemProps, ContextMenuLabelProps, ContextMenuProps, ContextMenuRadioItemProps, ContextMenuSeparatorProps, ContextMenuTriggerProps } from "./context-menu.js";
|
|
@@ -41,9 +41,9 @@ export type { CommandDialogProps, CommandEmptyProps, CommandGroupProps, CommandI
|
|
|
41
41
|
export { Combobox } from "./combobox/index.js";
|
|
42
42
|
export type { ComboboxOption, ComboboxProps } from "./combobox/index.js";
|
|
43
43
|
export { ContextMenu } from "./context-menu/index.js";
|
|
44
|
-
export type { ContextMenuCheckboxItemProps, ContextMenuContentProps, ContextMenuItemProps, ContextMenuLabelProps, ContextMenuProps, ContextMenuSeparatorProps, ContextMenuTriggerProps } from "./context-menu/index.js";
|
|
44
|
+
export type { ContextMenuCheckboxItemProps, ContextMenuContentProps, ContextMenuItemProps, ContextMenuLabelProps, ContextMenuProps, ContextMenuRadioItemProps, ContextMenuSeparatorProps, ContextMenuTriggerProps } from "./context-menu/index.js";
|
|
45
45
|
export { Menubar } from "./menubar/index.js";
|
|
46
|
-
export type { MenubarContentProps, MenubarItemProps, MenubarLabelProps, MenubarMenuProps, MenubarProps, MenubarSeparatorProps, MenubarShortcutProps, MenubarTriggerProps } from "./menubar/index.js";
|
|
46
|
+
export type { MenubarCheckboxItemProps, MenubarContentProps, MenubarItemProps, MenubarLabelProps, MenubarMenuProps, MenubarProps, MenubarRadioItemProps, MenubarSeparatorProps, MenubarShortcutProps, MenubarTriggerProps } from "./menubar/index.js";
|
|
47
47
|
export { EmptyState } from "./empty-state/index.js";
|
|
48
48
|
export type { EmptyStateAlign, EmptyStateProps, EmptyStateSize } from "./empty-state/index.js";
|
|
49
49
|
export { ErrorBoundary, ErrorFallback } from "./error-boundary/index.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Menubar } from "./menubar.js";
|
|
2
|
-
export type { MenubarContentProps, MenubarItemProps, MenubarLabelProps, MenubarMenuProps, MenubarProps, MenubarSeparatorProps, MenubarShortcutProps, MenubarTriggerProps } from "./menubar.js";
|
|
2
|
+
export type { MenubarCheckboxItemProps, MenubarContentProps, MenubarItemProps, MenubarLabelProps, MenubarMenuProps, MenubarProps, MenubarRadioItemProps, MenubarSeparatorProps, MenubarShortcutProps, MenubarTriggerProps } from "./menubar.js";
|
|
@@ -46,7 +46,7 @@ export interface MenubarShortcutProps extends React.HTMLAttributes<HTMLSpanEleme
|
|
|
46
46
|
declare function MenubarRoot({ children, className, defaultValue, onKeyDown, onValueChange, ref, value, ...props }: MenubarProps): React.JSX.Element;
|
|
47
47
|
declare function MenubarMenu({ children, value }: MenubarMenuProps): React.JSX.Element;
|
|
48
48
|
declare function MenubarTrigger({ asChild, children, className, disabled, onClick, onKeyDown, ref, type, ...props }: MenubarTriggerProps): React.JSX.Element;
|
|
49
|
-
declare function MenubarContent({ align, alignOffset
|
|
49
|
+
declare function MenubarContent({ align, alignOffset, children, className, onKeyDown, ref, side, sideOffset, style, ...props }: MenubarContentProps): React.JSX.Element | null;
|
|
50
50
|
declare function MenubarItem({ asChild, children, className, disabled, onClick, onKeyDown, onSelect, ref, type, ...props }: MenubarItemProps): React.JSX.Element;
|
|
51
51
|
declare function MenubarCheckboxItem({ asChild, checked, children, className, defaultChecked, disabled, onCheckedChange, onClick, onKeyDown, onSelect, ref, type, ...props }: MenubarCheckboxItemProps): React.JSX.Element;
|
|
52
52
|
declare function MenubarRadioItem({ asChild, checked, children, className, disabled, onClick, onKeyDown, onSelect, ref, type, ...props }: MenubarRadioItemProps): React.JSX.Element;
|
|
@@ -6,6 +6,7 @@ import { cn } from "../../utils/cn.js";
|
|
|
6
6
|
import { useControllableState } from "../../hooks/use-controllable-state.js";
|
|
7
7
|
import { createCollection } from "../../internal/collection/index.js";
|
|
8
8
|
import { DismissableLayer } from "../../internal/dismissable-layer/index.js";
|
|
9
|
+
import { useFloatingPosition } from "../../internal/floating/index.js";
|
|
9
10
|
import { placementFromSideAlign, placementParts } from "../../internal/floating/placement-aliases.js";
|
|
10
11
|
import { Portal } from "../../internal/portal/index.js";
|
|
11
12
|
import { Slot } from "../../internal/slot/index.js";
|
|
@@ -55,6 +56,14 @@ function setComposedRef(internalRef, externalRef, node) {
|
|
|
55
56
|
externalRef.current = node;
|
|
56
57
|
}
|
|
57
58
|
}
|
|
59
|
+
function setForwardedRef(externalRef, node) {
|
|
60
|
+
if (typeof externalRef === "function") {
|
|
61
|
+
externalRef(node);
|
|
62
|
+
}
|
|
63
|
+
else if (externalRef !== undefined && externalRef !== null) {
|
|
64
|
+
externalRef.current = node;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
58
67
|
function isActivationKey(key) {
|
|
59
68
|
return key === "Enter" || key === " " || key === "Space" || key === "Spacebar";
|
|
60
69
|
}
|
|
@@ -172,15 +181,34 @@ function MenubarTrigger({ asChild = false, children, className, disabled, onClic
|
|
|
172
181
|
setComposedRef(triggerRef, ref, node);
|
|
173
182
|
}, id: menu.triggerId, type: type, role: "menuitem", disabled: disabled, "aria-controls": menu.contentId, "aria-expanded": menu.open ? "true" : "false", "aria-haspopup": "menu", className: cn("zvk-ui-menubar__trigger", className), "data-disabled": disabled ? "true" : undefined, "data-state": menu.open ? "open" : "closed", onClick: triggerProps.onClick, onKeyDown: triggerProps.onKeyDown, children: children }));
|
|
174
183
|
}
|
|
175
|
-
function MenubarContent({ align, alignOffset
|
|
184
|
+
function MenubarContent({ align, alignOffset = 0, children, className, onKeyDown, ref, side, sideOffset = 4, style, ...props }) {
|
|
176
185
|
const menubar = useMenubarContext("Menubar.Content");
|
|
177
186
|
const menu = useMenuContext("Menubar.Content");
|
|
178
187
|
const contentPlacement = placementFromSideAlign(side, align, "bottom-start");
|
|
179
|
-
const
|
|
188
|
+
const { floatingRef, floatingStyle, placement: resolvedPlacement, referenceRef } = useFloatingPosition({
|
|
189
|
+
open: menu.open,
|
|
190
|
+
placement: contentPlacement,
|
|
191
|
+
strategy: "fixed",
|
|
192
|
+
offset: sideOffset,
|
|
193
|
+
alignmentOffset: alignOffset,
|
|
194
|
+
collisionPadding: 4
|
|
195
|
+
});
|
|
196
|
+
React.useLayoutEffect(() => {
|
|
197
|
+
if (!menu.open) {
|
|
198
|
+
referenceRef(null);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const activeTrigger = menubar.getTriggers().find((trigger) => trigger.data.value === menu.value);
|
|
202
|
+
referenceRef(activeTrigger?.data.ref ?? null);
|
|
203
|
+
return () => referenceRef(null);
|
|
204
|
+
}, [menubar, menu.open, menu.value, referenceRef]);
|
|
180
205
|
if (!menu.open) {
|
|
181
206
|
return null;
|
|
182
207
|
}
|
|
183
|
-
return (_jsx(Portal, { children: _jsx(DismissableLayer, { open: menu.open, onDismiss: () => menubar.setOpenValue(undefined), children: _jsx("div", { ...props, ref:
|
|
208
|
+
return (_jsx(Portal, { children: _jsx(DismissableLayer, { open: menu.open, onDismiss: () => menubar.setOpenValue(undefined), children: _jsx("div", { ...props, ref: (node) => {
|
|
209
|
+
floatingRef(node);
|
|
210
|
+
setForwardedRef(ref, node);
|
|
211
|
+
}, id: menu.contentId, role: "menu", "aria-label": menu.label, "aria-labelledby": menu.triggerId, className: cn("zvk-ui-menubar__content", className), style: { ...style, ...floatingStyle }, "data-align": placementParts(resolvedPlacement).align, "data-side": placementParts(resolvedPlacement).side, onKeyDown: composeEventHandlers(onKeyDown, (event) => {
|
|
184
212
|
const items = menu.getItems();
|
|
185
213
|
const index = activeIndex(items);
|
|
186
214
|
if (event.key === "ArrowDown") {
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
function hasBrowserApis() {
|
|
2
2
|
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
3
3
|
}
|
|
4
|
+
function scheduleFrame(callback) {
|
|
5
|
+
if (typeof window.requestAnimationFrame === "function") {
|
|
6
|
+
const frame = window.requestAnimationFrame(callback);
|
|
7
|
+
return () => {
|
|
8
|
+
if (typeof window.cancelAnimationFrame === "function") {
|
|
9
|
+
window.cancelAnimationFrame(frame);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const timeout = window.setTimeout(callback, 0);
|
|
14
|
+
return () => {
|
|
15
|
+
window.clearTimeout(timeout);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
4
18
|
export function autoUpdateFloating(params) {
|
|
5
19
|
const { enabled, reference, floating, update } = params;
|
|
6
20
|
if (!hasBrowserApis() || !enabled || reference === null || floating === null) {
|
|
7
21
|
return () => { };
|
|
8
22
|
}
|
|
9
|
-
let
|
|
23
|
+
let cancelScheduledUpdate = null;
|
|
10
24
|
const scheduleUpdate = () => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
frameRequest = window.requestAnimationFrame(() => {
|
|
15
|
-
frameRequest = null;
|
|
25
|
+
cancelScheduledUpdate?.();
|
|
26
|
+
cancelScheduledUpdate = scheduleFrame(() => {
|
|
27
|
+
cancelScheduledUpdate = null;
|
|
16
28
|
update();
|
|
17
29
|
});
|
|
18
30
|
};
|
|
@@ -40,9 +52,9 @@ export function autoUpdateFloating(params) {
|
|
|
40
52
|
for (const cleanup of cleanupFns) {
|
|
41
53
|
cleanup();
|
|
42
54
|
}
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
if (cancelScheduledUpdate !== null) {
|
|
56
|
+
cancelScheduledUpdate();
|
|
57
|
+
cancelScheduledUpdate = null;
|
|
46
58
|
}
|
|
47
59
|
};
|
|
48
60
|
}
|
package/dist/styles.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zvk/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "A polished, zero-runtime-dependency React component library for ZvkUi applications.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -258,6 +258,7 @@
|
|
|
258
258
|
},
|
|
259
259
|
"scripts": {
|
|
260
260
|
"clean": "bun run scripts/clean.mjs",
|
|
261
|
+
"dev": "bun run preview",
|
|
261
262
|
"build:types": "tsc -p tsconfig.build.json",
|
|
262
263
|
"build:css": "bun run scripts/build-css.mjs",
|
|
263
264
|
"build": "bun run clean && bun run build:types && bun run build:css",
|
|
@@ -270,13 +271,14 @@
|
|
|
270
271
|
"test:ssr": "vitest run tests/ssr --environment node",
|
|
271
272
|
"test:exports": "vitest run tests/exports --environment node",
|
|
272
273
|
"test:accessibility": "vitest run tests/accessibility",
|
|
274
|
+
"test:browser": "playwright test --config playwright.config.ts",
|
|
273
275
|
"test:types": "tsd",
|
|
274
276
|
"docs:lint": "bun run scripts/lint-docs.mjs",
|
|
275
277
|
"verify:style-contract": "bun run scripts/verify-style-contract.mjs",
|
|
276
278
|
"validate:exports": "bun run scripts/validate-exports.mjs",
|
|
277
279
|
"tarball:inspect": "bun run scripts/check-tarball.mjs",
|
|
278
280
|
"pack:dry": "npm pack --dry-run",
|
|
279
|
-
"preflight": "bun run typecheck && bun run build && bun run test:unit && bun run test:ssr && bun run test:types && bun run test:exports && bun run test:accessibility && bun run docs:lint && bun run verify:style-contract && bun run validate:exports && bun run tarball:inspect && bun run pack:dry"
|
|
281
|
+
"preflight": "bun run typecheck && bun run build && bun run test:unit && bun run test:ssr && bun run test:types && bun run test:exports && bun run test:accessibility && bun run test:browser && bun run docs:lint && bun run verify:style-contract && bun run validate:exports && bun run tarball:inspect && bun run pack:dry"
|
|
280
282
|
},
|
|
281
283
|
"peerDependencies": {
|
|
282
284
|
"react": "^19.0.0",
|
|
@@ -287,6 +289,7 @@
|
|
|
287
289
|
"directory": "tests/types"
|
|
288
290
|
},
|
|
289
291
|
"devDependencies": {
|
|
292
|
+
"@playwright/test": "^1.60.0",
|
|
290
293
|
"@testing-library/jest-dom": "^6.9.1",
|
|
291
294
|
"@testing-library/react": "^16.3.2",
|
|
292
295
|
"@testing-library/user-event": "^14.6.1",
|