@zvk/ui 0.1.3 → 0.1.6
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 +41 -0
- package/README.md +5 -5
- package/dist/components/accordion/accordion.js +4 -4
- package/dist/components/alert/alert.d.ts +5 -0
- package/dist/components/alert/alert.js +8 -4
- package/dist/components/alert/index.d.ts +1 -1
- package/dist/components/alert-dialog/alert-dialog.d.ts +8 -5
- package/dist/components/alert-dialog/alert-dialog.js +26 -13
- package/dist/components/avatar/avatar.js +1 -1
- package/dist/components/badge/badge.js +1 -1
- package/dist/components/breadcrumbs/breadcrumbs.js +3 -3
- package/dist/components/button/button.d.ts +3 -2
- package/dist/components/button/button.js +50 -2
- package/dist/components/calendar/calendar.d.ts +40 -5
- package/dist/components/calendar/calendar.js +17 -5
- package/dist/components/calendar/index.d.ts +1 -1
- package/dist/components/card/card.d.ts +5 -0
- package/dist/components/card/card.js +11 -7
- package/dist/components/card/index.d.ts +1 -1
- package/dist/components/carousel/carousel.js +7 -7
- package/dist/components/checkbox/checkbox.js +4 -4
- package/dist/components/code-block/code-block.js +2 -2
- package/dist/components/collapsible/collapsible.d.ts +3 -2
- package/dist/components/collapsible/collapsible.js +8 -4
- package/dist/components/combobox/combobox.js +6 -5
- package/dist/components/command/command-filter.d.ts +0 -1
- package/dist/components/command/command-filter.js +0 -3
- package/dist/components/command/command.d.ts +11 -4
- package/dist/components/command/command.js +28 -17
- package/dist/components/command/index.d.ts +1 -1
- package/dist/components/context-menu/context-menu.d.ts +17 -6
- package/dist/components/context-menu/context-menu.js +142 -39
- package/dist/components/conversation/conversation.js +11 -11
- package/dist/components/copy-button/copy-button.js +2 -2
- package/dist/components/date-picker/date-picker.js +1 -1
- package/dist/components/dialog/dialog.d.ts +6 -4
- package/dist/components/dialog/dialog.js +22 -12
- package/dist/components/dropdown-menu/dropdown-menu.d.ts +13 -7
- package/dist/components/dropdown-menu/dropdown-menu.js +137 -78
- package/dist/components/empty-state/empty-state.js +1 -1
- package/dist/components/error-boundary/error-boundary.js +1 -1
- package/dist/components/field/field.js +4 -4
- package/dist/components/file-upload-input/file-upload-input.js +2 -2
- package/dist/components/form/form.js +6 -6
- package/dist/components/hover-card/hover-card.d.ts +8 -2
- package/dist/components/hover-card/hover-card.js +13 -7
- package/dist/components/icon-button/icon-button.js +19 -1
- package/dist/components/index.d.ts +10 -10
- package/dist/components/index.js +1 -1
- package/dist/components/input/input.js +1 -1
- package/dist/components/label/label.js +1 -1
- package/dist/components/menubar/menubar.d.ts +24 -5
- package/dist/components/menubar/menubar.js +186 -37
- package/dist/components/pagination/pagination.js +12 -12
- package/dist/components/popover/popover.d.ts +8 -3
- package/dist/components/popover/popover.js +40 -8
- package/dist/components/progress/progress.js +3 -3
- package/dist/components/radio-group/radio-group.js +3 -3
- package/dist/components/responsive-container/responsive-container.js +1 -1
- package/dist/components/scroll-area/scroll-area.js +4 -4
- package/dist/components/sectioned-sidebar-nav/sectioned-sidebar-nav.js +7 -7
- package/dist/components/select/select.js +66 -13
- package/dist/components/separator/separator.js +1 -1
- package/dist/components/sheet/sheet.d.ts +6 -4
- package/dist/components/sheet/sheet.js +29 -16
- package/dist/components/sidebar-shell/sidebar-shell.js +6 -6
- package/dist/components/skeleton/skeleton.js +1 -1
- package/dist/components/slider/slider.js +1 -1
- package/dist/components/spinner/spinner.js +1 -1
- package/dist/components/stat/stat.js +1 -1
- package/dist/components/switch/switch.js +3 -3
- package/dist/components/table/index.d.ts +1 -1
- package/dist/components/table/table.d.ts +5 -0
- package/dist/components/table/table.js +12 -8
- package/dist/components/tabs/tabs.js +4 -4
- package/dist/components/tabs-with-sidebar/tabs-with-sidebar.js +3 -3
- package/dist/components/textarea/textarea.js +1 -1
- package/dist/components/toast/index.d.ts +2 -2
- package/dist/components/toast/index.js +1 -1
- package/dist/components/toast/toast.d.ts +16 -2
- package/dist/components/toast/toast.js +49 -7
- package/dist/components/toggle/toggle.js +1 -1
- package/dist/components/toggle-group/toggle-group.js +1 -1
- package/dist/components/tooltip/tooltip.d.ts +8 -2
- package/dist/components/tooltip/tooltip.js +12 -6
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/use-composed-refs.d.ts +2 -2
- package/dist/hooks/use-controllable-state.d.ts +2 -2
- package/dist/internal/floating/compute-position.js +13 -8
- package/dist/internal/floating/floating-types.d.ts +1 -0
- package/dist/internal/floating/index.d.ts +1 -0
- package/dist/internal/floating/placement-aliases.d.ts +7 -0
- package/dist/internal/floating/placement-aliases.js +13 -0
- package/dist/internal/floating/use-floating-position.js +6 -4
- package/dist/internal/overlay-stack/overlay-stack.js +4 -1
- package/dist/internal/slot/index.d.ts +2 -0
- package/dist/internal/slot/index.js +1 -0
- package/dist/internal/slot/slot.d.ts +6 -0
- package/dist/internal/slot/slot.js +53 -0
- package/dist/styles.css +2079 -2015
- package/dist/tokens/index.d.ts +2 -2
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/token-types.d.ts +5 -5
- package/dist/tokens/tokens.d.ts +16 -10
- package/dist/tokens/tokens.js +16 -10
- package/dist/utils/cn.d.ts +2 -2
- package/dist/utils/index.d.ts +1 -1
- package/package.json +13 -12
|
@@ -21,7 +21,7 @@ export function Switch({ "aria-describedby": ariaDescribedBy, className, descrip
|
|
|
21
21
|
const descriptionId = hasDescription ? `${switchId}-description` : undefined;
|
|
22
22
|
const errorId = hasError ? `${switchId}-error` : undefined;
|
|
23
23
|
const describedBy = joinIds(ariaDescribedBy, descriptionId, errorId);
|
|
24
|
-
const input = (_jsx("input", { ...props, ref: ref, "aria-describedby": describedBy, "aria-invalid": invalidState ? true : undefined, className: "
|
|
25
|
-
const content = (_jsxs(_Fragment, { children: [input, _jsx("span", { className: "
|
|
26
|
-
return (_jsxs(Field, { disabled: Boolean(disabled), invalid: invalidState, required: Boolean(required), children: [_jsx("label", { className: cn("
|
|
24
|
+
const input = (_jsx("input", { ...props, ref: ref, "aria-describedby": describedBy, "aria-invalid": invalidState ? true : undefined, className: "zvk-ui-switch__input", "data-disabled": disabled ? "true" : undefined, "data-invalid": invalidState ? "true" : undefined, "data-required": required ? "true" : undefined, disabled: disabled, id: switchId, required: required, role: "switch", type: "checkbox" }));
|
|
25
|
+
const content = (_jsxs(_Fragment, { children: [input, _jsx("span", { className: "zvk-ui-switch__track", "aria-hidden": "true", children: _jsx("span", { className: "zvk-ui-switch__thumb" }) }), hasLabel ? _jsx("span", { className: "zvk-ui-switch__label", children: label }) : null] }));
|
|
26
|
+
return (_jsxs(Field, { disabled: Boolean(disabled), invalid: invalidState, required: Boolean(required), children: [_jsx("label", { className: cn("zvk-ui-switch", className), "data-size": size, "data-disabled": disabled ? "true" : undefined, "data-invalid": invalidState ? "true" : undefined, "data-required": required ? "true" : undefined, children: content }), hasDescription ? _jsx(Field.Description, { id: descriptionId, children: description }) : null, hasError ? _jsx(Field.Error, { id: errorId, children: error }) : null] }));
|
|
27
27
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Table } from "./table.js";
|
|
2
|
-
export type { TableBodyProps, TableCaptionProps, TableCellProps, TableFooterProps, TableHeadProps, TableHeaderProps, TableProps, TableRowProps } from "./table.js";
|
|
2
|
+
export type { TableBodyProps, TableCaptionProps, TableCellProps, TableContainerProps, TableFooterProps, TableHeadProps, TableHeaderProps, TableProps, TableRowProps } from "./table.js";
|
|
@@ -4,6 +4,9 @@ export interface TableProps extends React.TableHTMLAttributes<HTMLTableElement>
|
|
|
4
4
|
variant?: "plain" | "surface";
|
|
5
5
|
ref?: React.Ref<HTMLTableElement>;
|
|
6
6
|
}
|
|
7
|
+
export interface TableContainerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
8
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
9
|
+
}
|
|
7
10
|
export interface TableCaptionProps extends React.HTMLAttributes<HTMLTableCaptionElement> {
|
|
8
11
|
ref?: React.Ref<HTMLTableCaptionElement>;
|
|
9
12
|
}
|
|
@@ -33,7 +36,9 @@ declare function TableFooter({ className, ref, ...props }: TableFooterProps): Re
|
|
|
33
36
|
declare function TableRow({ className, ref, ...props }: TableRowProps): React.JSX.Element;
|
|
34
37
|
declare function TableHead({ className, ref, scope, ...props }: TableHeadProps): React.JSX.Element;
|
|
35
38
|
declare function TableCell({ className, ref, ...props }: TableCellProps): React.JSX.Element;
|
|
39
|
+
declare function TableContainer({ className, ref, ...props }: TableContainerProps): React.JSX.Element;
|
|
36
40
|
export declare const Table: typeof TableRoot & {
|
|
41
|
+
Container: typeof TableContainer;
|
|
37
42
|
Caption: typeof TableCaption;
|
|
38
43
|
Header: typeof TableHeader;
|
|
39
44
|
Body: typeof TableBody;
|
|
@@ -2,30 +2,34 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { cn } from "../../utils/cn.js";
|
|
4
4
|
function TableRoot({ className, density = "default", ref, variant = "plain", ...props }) {
|
|
5
|
-
return (_jsx("table", { ...props, ref: ref, className: cn("
|
|
5
|
+
return (_jsx("table", { ...props, ref: ref, className: cn("zvk-ui-table", className), "data-density": density, "data-variant": variant }));
|
|
6
6
|
}
|
|
7
7
|
function TableCaption({ className, ref, ...props }) {
|
|
8
|
-
return _jsx("caption", { ...props, ref: ref, className: cn("
|
|
8
|
+
return _jsx("caption", { ...props, ref: ref, className: cn("zvk-ui-table__caption", className) });
|
|
9
9
|
}
|
|
10
10
|
function TableHeader({ className, ref, ...props }) {
|
|
11
|
-
return _jsx("thead", { ...props, ref: ref, className: cn("
|
|
11
|
+
return _jsx("thead", { ...props, ref: ref, className: cn("zvk-ui-table__header", className) });
|
|
12
12
|
}
|
|
13
13
|
function TableBody({ className, ref, ...props }) {
|
|
14
|
-
return _jsx("tbody", { ...props, ref: ref, className: cn("
|
|
14
|
+
return _jsx("tbody", { ...props, ref: ref, className: cn("zvk-ui-table__body", className) });
|
|
15
15
|
}
|
|
16
16
|
function TableFooter({ className, ref, ...props }) {
|
|
17
|
-
return _jsx("tfoot", { ...props, ref: ref, className: cn("
|
|
17
|
+
return _jsx("tfoot", { ...props, ref: ref, className: cn("zvk-ui-table__footer", className) });
|
|
18
18
|
}
|
|
19
19
|
function TableRow({ className, ref, ...props }) {
|
|
20
|
-
return _jsx("tr", { ...props, ref: ref, className: cn("
|
|
20
|
+
return _jsx("tr", { ...props, ref: ref, className: cn("zvk-ui-table__row", className) });
|
|
21
21
|
}
|
|
22
22
|
function TableHead({ className, ref, scope = "col", ...props }) {
|
|
23
|
-
return _jsx("th", { ...props, ref: ref, scope: scope, className: cn("
|
|
23
|
+
return _jsx("th", { ...props, ref: ref, scope: scope, className: cn("zvk-ui-table__head", className) });
|
|
24
24
|
}
|
|
25
25
|
function TableCell({ className, ref, ...props }) {
|
|
26
|
-
return _jsx("td", { ...props, ref: ref, className: cn("
|
|
26
|
+
return _jsx("td", { ...props, ref: ref, className: cn("zvk-ui-table__cell", className) });
|
|
27
|
+
}
|
|
28
|
+
function TableContainer({ className, ref, ...props }) {
|
|
29
|
+
return _jsx("div", { ...props, ref: ref, className: cn("zvk-ui-table-container", className) });
|
|
27
30
|
}
|
|
28
31
|
export const Table = Object.assign(TableRoot, {
|
|
32
|
+
Container: TableContainer,
|
|
29
33
|
Caption: TableCaption,
|
|
30
34
|
Header: TableHeader,
|
|
31
35
|
Body: TableBody,
|
|
@@ -127,11 +127,11 @@ function TabsRoot({ children, className, defaultValue = "", disabled = false, re
|
|
|
127
127
|
setValue: setCurrentValue,
|
|
128
128
|
unregisterTrigger,
|
|
129
129
|
value: currentValue
|
|
130
|
-
}, children: _jsx("div", { ...props, ref: ref, className: cn("
|
|
130
|
+
}, children: _jsx("div", { ...props, ref: ref, className: cn("zvk-ui-tabs", className), "data-orientation": orientation, "data-state": activationMode, "data-disabled": disabled ? "true" : undefined, children: children }) }));
|
|
131
131
|
}
|
|
132
132
|
function TabsList({ className, ref, ...props }) {
|
|
133
133
|
const context = useTabsContext("Tabs.List");
|
|
134
|
-
return (_jsx("div", { ...props, ref: ref, role: "tablist", className: cn("
|
|
134
|
+
return (_jsx("div", { ...props, ref: ref, role: "tablist", className: cn("zvk-ui-tabs__list", className), "aria-orientation": context.orientation === "vertical" ? "vertical" : "horizontal" }));
|
|
135
135
|
}
|
|
136
136
|
function TabsTrigger({ className, onClick, onKeyDown, ref, value, ...props }) {
|
|
137
137
|
const context = useTabsContext("Tabs.Trigger");
|
|
@@ -200,7 +200,7 @@ function TabsTrigger({ className, onClick, onKeyDown, ref, value, ...props }) {
|
|
|
200
200
|
else if (ref) {
|
|
201
201
|
ref.current = node;
|
|
202
202
|
}
|
|
203
|
-
}, id: triggerId, role: "tab", "aria-controls": contentId, "aria-selected": isSelected, className: cn("
|
|
203
|
+
}, id: triggerId, role: "tab", "aria-controls": contentId, "aria-selected": isSelected, className: cn("zvk-ui-tabs__trigger", className), "data-state": isSelected ? "active" : "inactive", "data-disabled": isDisabled ? "true" : undefined, disabled: isDisabled, onClick: composeEventHandlers(onClick, () => {
|
|
204
204
|
if (!isDisabled && !context.disabled) {
|
|
205
205
|
context.setValue(value);
|
|
206
206
|
}
|
|
@@ -224,7 +224,7 @@ function TabsContent({ className, forceMount = false, ref, value, ...props }) {
|
|
|
224
224
|
if (!forceMount && !isSelected) {
|
|
225
225
|
return null;
|
|
226
226
|
}
|
|
227
|
-
return (_jsx(TabsTriggerContext.Provider, { value: { value }, children: _jsx("div", { ...props, id: props.id ?? contentId, ref: ref, role: "tabpanel", "aria-labelledby": triggerId, className: cn("
|
|
227
|
+
return (_jsx(TabsTriggerContext.Provider, { value: { value }, children: _jsx("div", { ...props, id: props.id ?? contentId, ref: ref, role: "tabpanel", "aria-labelledby": triggerId, className: cn("zvk-ui-tabs__content", className), "data-state": isSelected ? "open" : "closed", hidden: !isSelected ? true : undefined }) }));
|
|
228
228
|
}
|
|
229
229
|
export const Tabs = Object.assign(TabsRoot, {
|
|
230
230
|
List: TabsList,
|
|
@@ -4,13 +4,13 @@ import * as React from "react";
|
|
|
4
4
|
import { Tabs } from "../tabs/tabs.js";
|
|
5
5
|
import { cn } from "../../utils/cn.js";
|
|
6
6
|
function TabsWithSidebarRoot({ className, orientation = "vertical", ref, sidebarWidth = "md", ...props }) {
|
|
7
|
-
return (_jsx(Tabs, { ...props, ...(ref ? { ref } : {}), className: cn("
|
|
7
|
+
return (_jsx(Tabs, { ...props, ...(ref ? { ref } : {}), className: cn("zvk-ui-tabs-with-sidebar", className), "data-sidebar-width": sidebarWidth, orientation: orientation }));
|
|
8
8
|
}
|
|
9
9
|
function TabsWithSidebarSidebar({ className, ref, sidebarWidth = "md", ...props }) {
|
|
10
|
-
return (_jsx("div", { ...props, ref: ref, className: cn("
|
|
10
|
+
return (_jsx("div", { ...props, ref: ref, className: cn("zvk-ui-tabs-with-sidebar__sidebar", className), "data-sidebar-width": sidebarWidth }));
|
|
11
11
|
}
|
|
12
12
|
function TabsWithSidebarPanel({ className, ref, ...props }) {
|
|
13
|
-
return _jsx("div", { ...props, ref: ref, className: cn("
|
|
13
|
+
return _jsx("div", { ...props, ref: ref, className: cn("zvk-ui-tabs-with-sidebar__panel", className) });
|
|
14
14
|
}
|
|
15
15
|
export const TabsWithSidebar = Object.assign(TabsWithSidebarRoot, {
|
|
16
16
|
Sidebar: TabsWithSidebarSidebar,
|
|
@@ -20,7 +20,7 @@ export function Textarea({ "aria-describedby": ariaDescribedBy, className, descr
|
|
|
20
20
|
const descriptionId = hasDescription ? `${inputId}-description` : undefined;
|
|
21
21
|
const errorId = hasError ? `${inputId}-error` : undefined;
|
|
22
22
|
const describedBy = joinIds(ariaDescribedBy, descriptionId, errorId);
|
|
23
|
-
const textarea = (_jsx("textarea", { ...props, ref: ref, "aria-describedby": describedBy, "aria-invalid": invalidState ? true : undefined, className: cn("
|
|
23
|
+
const textarea = (_jsx("textarea", { ...props, ref: ref, "aria-describedby": describedBy, "aria-invalid": invalidState ? true : undefined, className: cn("zvk-ui-textarea", className), "data-disabled": disabled ? "true" : undefined, "data-invalid": invalidState ? "true" : undefined, "data-required": required ? "true" : undefined, "data-size": size, disabled: disabled, id: inputId, required: required, rows: rows }));
|
|
24
24
|
if (!hasLabel && !hasDescription && !hasError) {
|
|
25
25
|
return textarea;
|
|
26
26
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { createToastController, Toast, ToastProvider, ToastViewport, useToast } from "./toast.js";
|
|
2
|
-
export type { ToastActionProps, ToastCloseProps, ToastController, ToastInput, ToastOptions, ToastPlacement, ToastProviderProps, ToastProps, ToastTextProps, ToastTone, ToastViewportProps } from "./toast.js";
|
|
1
|
+
export { createToastController, toast, Toast, Toaster, ToastProvider, ToastViewport, useToast } from "./toast.js";
|
|
2
|
+
export type { ToasterPosition, ToasterProps, ToastActionInput, ToastActionProps, ToastCloseProps, ToastController, ToastInput, ToastOptions, ToastPlacement, ToastProviderProps, ToastProps, ToastTextProps, ToastTone, ToastViewportProps } from "./toast.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { createToastController, Toast, ToastProvider, ToastViewport, useToast } from "./toast.js";
|
|
2
|
+
export { createToastController, toast, Toast, Toaster, ToastProvider, ToastViewport, useToast } from "./toast.js";
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
export type ToastTone = "neutral" | "success" | "warning" | "destructive" | "info";
|
|
3
3
|
export type ToastPlacement = "top-right" | "top-left" | "bottom-right" | "bottom-left";
|
|
4
|
+
export type ToasterPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
4
5
|
export type ToastInput = string | {
|
|
5
6
|
title?: React.ReactNode;
|
|
6
7
|
description?: React.ReactNode;
|
|
7
8
|
};
|
|
9
|
+
export type ToastActionInput = React.ReactNode | {
|
|
10
|
+
label: React.ReactNode;
|
|
11
|
+
onClick: () => void;
|
|
12
|
+
};
|
|
8
13
|
export type ToastOptions = {
|
|
9
14
|
id?: string;
|
|
10
15
|
description?: React.ReactNode;
|
|
11
16
|
duration?: number;
|
|
12
|
-
action?:
|
|
13
|
-
cancel?:
|
|
17
|
+
action?: ToastActionInput;
|
|
18
|
+
cancel?: ToastActionInput;
|
|
14
19
|
};
|
|
15
20
|
export type ToastController = {
|
|
16
21
|
(input: ToastInput, options?: ToastOptions): string;
|
|
@@ -41,10 +46,19 @@ export interface ToastProviderProps extends Omit<ToastViewportProps, "children">
|
|
|
41
46
|
children?: React.ReactNode;
|
|
42
47
|
controller?: ToastController;
|
|
43
48
|
}
|
|
49
|
+
export interface ToasterProps extends Omit<ToastProviderProps, "placement"> {
|
|
50
|
+
position?: ToasterPosition;
|
|
51
|
+
richColors?: boolean;
|
|
52
|
+
expand?: boolean;
|
|
53
|
+
offset?: number | string;
|
|
54
|
+
toastOptions?: ToastOptions;
|
|
55
|
+
}
|
|
44
56
|
export declare function ToastViewport({ className, placement, ref, ...props }: ToastViewportProps): React.ReactElement;
|
|
45
57
|
export declare function createToastController(): ToastController;
|
|
58
|
+
export declare const toast: ToastController;
|
|
46
59
|
export declare function useToast(): ToastController;
|
|
47
60
|
export declare function ToastProvider({ children, controller, placement, ref, ...viewportProps }: ToastProviderProps): React.ReactElement;
|
|
61
|
+
export declare function Toaster({ controller, expand: _expand, offset, position, richColors: _richColors, style, toastOptions: _toastOptions, ...props }: ToasterProps): React.ReactElement;
|
|
48
62
|
declare function ToastRoot({ className, ref, role, tone, ...props }: ToastProps): React.JSX.Element;
|
|
49
63
|
declare function ToastTitle({ className, ref, ...props }: ToastTextProps): React.JSX.Element;
|
|
50
64
|
declare function ToastDescription({ className, ref, ...props }: ToastTextProps): React.JSX.Element;
|
|
@@ -27,8 +27,38 @@ function resolveToastContent(input, options) {
|
|
|
27
27
|
description: options.description ?? input.description
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
|
+
function mapToPlacement(position) {
|
|
31
|
+
if (position === "top-center") {
|
|
32
|
+
return "top-right";
|
|
33
|
+
}
|
|
34
|
+
if (position === "bottom-center") {
|
|
35
|
+
return "bottom-right";
|
|
36
|
+
}
|
|
37
|
+
return position;
|
|
38
|
+
}
|
|
39
|
+
function toastTypeFromTone(tone) {
|
|
40
|
+
if (tone === "destructive") {
|
|
41
|
+
return "error";
|
|
42
|
+
}
|
|
43
|
+
if (tone === "neutral") {
|
|
44
|
+
return "default";
|
|
45
|
+
}
|
|
46
|
+
return tone;
|
|
47
|
+
}
|
|
48
|
+
function isToastActionObject(input) {
|
|
49
|
+
return typeof input === "object" && input !== null && !React.isValidElement(input) && "label" in input && "onClick" in input;
|
|
50
|
+
}
|
|
51
|
+
function renderToastControl(input) {
|
|
52
|
+
if (input === undefined) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
if (isToastActionObject(input)) {
|
|
56
|
+
return _jsx(Toast.Action, { onClick: input.onClick, children: input.label });
|
|
57
|
+
}
|
|
58
|
+
return input;
|
|
59
|
+
}
|
|
30
60
|
export function ToastViewport({ className, placement = "top-right", ref, ...props }) {
|
|
31
|
-
return (_jsx("div", { ...props, ref: ref, "aria-label": props["aria-label"] ?? "Notifications", className: cn("
|
|
61
|
+
return (_jsx("div", { ...props, ref: ref, "aria-label": props["aria-label"] ?? "Notifications", className: cn("zvk-ui-toast-viewport", className), "data-placement": placement, role: "region" }));
|
|
32
62
|
}
|
|
33
63
|
export function createToastController() {
|
|
34
64
|
const listeners = new Set();
|
|
@@ -76,6 +106,7 @@ export function createToastController() {
|
|
|
76
106
|
});
|
|
77
107
|
return controller;
|
|
78
108
|
}
|
|
109
|
+
export const toast = createToastController();
|
|
79
110
|
export function useToast() {
|
|
80
111
|
const controller = React.useContext(ToastControllerContext);
|
|
81
112
|
if (!controller) {
|
|
@@ -94,6 +125,16 @@ export function ToastProvider({ children, controller, placement = "top-right", r
|
|
|
94
125
|
const viewportRefProps = ref ? { ref } : {};
|
|
95
126
|
return (_jsxs(ToastControllerContext.Provider, { value: activeController, children: [children, _jsx(ToastViewport, { ...viewportProps, ...viewportRefProps, placement: placement, children: toasts.map((toast) => (_jsx(ToastProviderItem, { toast: toast, onDismiss: dismissToast }, toast.id))) })] }));
|
|
96
127
|
}
|
|
128
|
+
export function Toaster({ controller = toast, expand: _expand, offset, position = "top-right", richColors: _richColors, style, toastOptions: _toastOptions, ...props }) {
|
|
129
|
+
const placement = mapToPlacement(position);
|
|
130
|
+
const offsetStyle = offset === undefined
|
|
131
|
+
? style
|
|
132
|
+
: {
|
|
133
|
+
...style,
|
|
134
|
+
"--zvk-ui-toast-viewport-inset": typeof offset === "number" ? `${offset}px` : offset
|
|
135
|
+
};
|
|
136
|
+
return (_jsx(ToastProvider, { ...props, controller: controller, placement: placement, ...(offsetStyle === undefined ? {} : { style: offsetStyle }) }));
|
|
137
|
+
}
|
|
97
138
|
function ToastProviderItem({ onDismiss, toast }) {
|
|
98
139
|
React.useEffect(() => {
|
|
99
140
|
if (toast.duration === Infinity) {
|
|
@@ -102,22 +143,23 @@ function ToastProviderItem({ onDismiss, toast }) {
|
|
|
102
143
|
const timeout = window.setTimeout(() => onDismiss(toast.id), toast.duration);
|
|
103
144
|
return () => window.clearTimeout(timeout);
|
|
104
145
|
}, [onDismiss, toast.duration, toast.id, toast.version]);
|
|
105
|
-
return (_jsxs(Toast, { tone: toast.tone, children: [(toast.title || toast.description) && (_jsxs("div", { className: "
|
|
146
|
+
return (_jsxs(Toast, { tone: toast.tone, children: [(toast.title || toast.description) && (_jsxs("div", { className: "zvk-ui-toast__content", children: [toast.title && _jsx(Toast.Title, { children: toast.title }), toast.description && _jsx(Toast.Description, { children: toast.description })] })), (toast.action || toast.cancel) && (_jsxs("div", { className: "zvk-ui-toast__controls", children: [renderToastControl(toast.action), renderToastControl(toast.cancel)] })), _jsx(Toast.Close, { "aria-label": "Dismiss notification", onClick: () => onDismiss(toast.id) })] }));
|
|
106
147
|
}
|
|
107
148
|
function ToastRoot({ className, ref, role, tone = "neutral", ...props }) {
|
|
108
|
-
|
|
149
|
+
const toastType = toastTypeFromTone(tone);
|
|
150
|
+
return (_jsx("div", { ...props, ref: ref, className: cn("zvk-ui-toast", className), "data-sonner-toast": "", "data-tone": tone, "data-type": toastType, "data-visible": "true", role: role ?? (tone === "destructive" ? "alert" : "status") }));
|
|
109
151
|
}
|
|
110
152
|
function ToastTitle({ className, ref, ...props }) {
|
|
111
|
-
return _jsx("div", { ...props, ref: ref, className: cn("
|
|
153
|
+
return _jsx("div", { ...props, ref: ref, className: cn("zvk-ui-toast__title", className) });
|
|
112
154
|
}
|
|
113
155
|
function ToastDescription({ className, ref, ...props }) {
|
|
114
|
-
return _jsx("div", { ...props, ref: ref, className: cn("
|
|
156
|
+
return _jsx("div", { ...props, ref: ref, className: cn("zvk-ui-toast__description", className) });
|
|
115
157
|
}
|
|
116
158
|
function ToastAction({ className, ref, type = "button", ...props }) {
|
|
117
|
-
return _jsx("button", { ...props, ref: ref, className: cn("
|
|
159
|
+
return _jsx("button", { ...props, ref: ref, className: cn("zvk-ui-toast__action", className), type: type });
|
|
118
160
|
}
|
|
119
161
|
function ToastClose({ children = "×", className, ref, type = "button", ...props }) {
|
|
120
|
-
return (_jsx("button", { ...props, ref: ref, className: cn("
|
|
162
|
+
return (_jsx("button", { ...props, ref: ref, className: cn("zvk-ui-toast__close", className), type: type, children: children }));
|
|
121
163
|
}
|
|
122
164
|
export const Toast = Object.assign(ToastRoot, {
|
|
123
165
|
Title: ToastTitle,
|
|
@@ -10,7 +10,7 @@ export function Toggle({ "aria-pressed": ariaPressed, className, defaultPressed
|
|
|
10
10
|
defaultValue: defaultPressed,
|
|
11
11
|
...(onPressedChange ? { onChange: onPressedChange } : {})
|
|
12
12
|
});
|
|
13
|
-
return (_jsx("button", { ...props, ref: ref, "aria-pressed": ariaPressed ?? currentPressed, className: cn("
|
|
13
|
+
return (_jsx("button", { ...props, ref: ref, "aria-pressed": ariaPressed ?? currentPressed, className: cn("zvk-ui-toggle", className), "data-disabled": disabled ? "true" : undefined, "data-size": size, "data-state": currentPressed ? "on" : "off", "data-variant": variant, disabled: disabled, onClick: composeEventHandlers(onClick, () => {
|
|
14
14
|
if (!disabled) {
|
|
15
15
|
setPressed((value) => !value);
|
|
16
16
|
}
|
|
@@ -50,7 +50,7 @@ function ToggleGroupRoot(props) {
|
|
|
50
50
|
toggleValue
|
|
51
51
|
}), [disabled, isPressed, orientation, toggleValue]);
|
|
52
52
|
const { children: _children, className: _className, defaultValue: _defaultValue, disabled: _disabled, onValueChange: _onValueChange, orientation: _orientation, type: _type, value: _value, ...domProps } = props;
|
|
53
|
-
return (_jsx(ToggleGroupContext.Provider, { value: context, children: _jsx("div", { ...domProps, className: cn("
|
|
53
|
+
return (_jsx(ToggleGroupContext.Provider, { value: context, children: _jsx("div", { ...domProps, className: cn("zvk-ui-toggle-group", className), "data-disabled": disabled ? "true" : undefined, "data-orientation": orientation, role: "group", children: children }) }));
|
|
54
54
|
}
|
|
55
55
|
function ToggleGroupItem({ disabled, onClick, value, ...props }) {
|
|
56
56
|
const context = useToggleGroupContext("ToggleGroup.Item");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { PortalProps } from "../../internal/portal/index.js";
|
|
3
3
|
import type { FloatingPlacement } from "../../internal/floating/index.js";
|
|
4
|
+
import type { FloatingAlign, FloatingSide } from "../../internal/floating/placement-aliases.js";
|
|
4
5
|
export interface TooltipProps {
|
|
5
6
|
children: React.ReactElement;
|
|
6
7
|
content: React.ReactNode;
|
|
@@ -23,9 +24,14 @@ export interface TooltipRootProps {
|
|
|
23
24
|
onOpenChange?: (open: boolean) => void;
|
|
24
25
|
}
|
|
25
26
|
export interface TooltipTriggerProps {
|
|
27
|
+
asChild?: boolean;
|
|
26
28
|
children: React.ReactElement;
|
|
27
29
|
}
|
|
28
30
|
export interface TooltipContentProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
31
|
+
placement?: FloatingPlacement;
|
|
32
|
+
side?: FloatingSide;
|
|
33
|
+
align?: FloatingAlign;
|
|
34
|
+
alignOffset?: number;
|
|
29
35
|
sideOffset?: number;
|
|
30
36
|
collisionPadding?: number;
|
|
31
37
|
forceMount?: boolean;
|
|
@@ -34,8 +40,8 @@ export interface TooltipContentProps extends React.HTMLAttributes<HTMLSpanElemen
|
|
|
34
40
|
}
|
|
35
41
|
declare function TooltipProvider({ children, delayDuration }: TooltipProviderProps): React.JSX.Element;
|
|
36
42
|
declare function TooltipRoot({ children, defaultOpen, delay, disabled, onOpenChange, open: openProp, placement }: TooltipRootProps): React.JSX.Element;
|
|
37
|
-
declare function TooltipTrigger({ children }: TooltipTriggerProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
38
|
-
declare function TooltipContent({ children, className, collisionPadding, container, forceMount, ref, sideOffset, style, ...props }: TooltipContentProps): React.JSX.Element | null;
|
|
43
|
+
declare function TooltipTrigger({ children, asChild: _asChild }: TooltipTriggerProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
44
|
+
declare function TooltipContent({ align, alignOffset, children, className, collisionPadding, container, forceMount, placement, ref, side, sideOffset, style, ...props }: TooltipContentProps): React.JSX.Element | null;
|
|
39
45
|
declare function TooltipWrapper({ children, content, delay, disabled, placement }: TooltipProps): React.JSX.Element;
|
|
40
46
|
export declare const Tooltip: typeof TooltipWrapper & {
|
|
41
47
|
Content: typeof TooltipContent;
|
|
@@ -3,11 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { Portal } from "../../internal/portal/index.js";
|
|
5
5
|
import { useFloatingPosition } from "../../internal/floating/index.js";
|
|
6
|
+
import { placementFromSideAlign } from "../../internal/floating/placement-aliases.js";
|
|
6
7
|
import { useControllableState } from "../../hooks/use-controllable-state.js";
|
|
7
8
|
import { composeEventHandlers } from "../../utils/compose-event-handlers.js";
|
|
8
9
|
import { cn } from "../../utils/cn.js";
|
|
9
10
|
const defaultContentPositioning = {
|
|
10
11
|
sideOffset: 8,
|
|
12
|
+
alignOffset: 0,
|
|
11
13
|
collisionPadding: 0
|
|
12
14
|
};
|
|
13
15
|
const TooltipProviderContext = React.createContext({
|
|
@@ -27,7 +29,7 @@ function composeRefs(...refs) {
|
|
|
27
29
|
if (typeof ref === "function") {
|
|
28
30
|
ref(node);
|
|
29
31
|
}
|
|
30
|
-
else if (ref !== undefined) {
|
|
32
|
+
else if (ref !== undefined && ref !== null) {
|
|
31
33
|
ref.current = node;
|
|
32
34
|
}
|
|
33
35
|
}
|
|
@@ -59,8 +61,9 @@ function TooltipRoot({ children, defaultOpen = false, delay, disabled = false, o
|
|
|
59
61
|
const openTimeoutRef = React.useRef(null);
|
|
60
62
|
const { floatingRef, floatingStyle, placement: resolvedPlacement, referenceRef, updatePosition } = useFloatingPosition({
|
|
61
63
|
open,
|
|
62
|
-
placement,
|
|
64
|
+
placement: contentPositioning.placement ?? placement,
|
|
63
65
|
offset: contentPositioning.sideOffset,
|
|
66
|
+
alignmentOffset: contentPositioning.alignOffset,
|
|
64
67
|
collisionPadding: contentPositioning.collisionPadding,
|
|
65
68
|
flip: true,
|
|
66
69
|
shift: true
|
|
@@ -137,7 +140,7 @@ function TooltipRoot({ children, defaultOpen = false, delay, disabled = false, o
|
|
|
137
140
|
]);
|
|
138
141
|
return (_jsx(TooltipRootContext.Provider, { value: contextValue, children: children }));
|
|
139
142
|
}
|
|
140
|
-
function TooltipTrigger({ children }) {
|
|
143
|
+
function TooltipTrigger({ children, asChild: _asChild = false }) {
|
|
141
144
|
const context = useTooltipRootContext("Tooltip.Trigger");
|
|
142
145
|
if (!React.isValidElement(children) || context.disabled) {
|
|
143
146
|
return children;
|
|
@@ -164,20 +167,23 @@ function TooltipTrigger({ children }) {
|
|
|
164
167
|
}, { checkDefaultPrevented: false })
|
|
165
168
|
});
|
|
166
169
|
}
|
|
167
|
-
function TooltipContent({ children, className, collisionPadding = defaultContentPositioning.collisionPadding, container, forceMount = false, ref, sideOffset = defaultContentPositioning.sideOffset, style, ...props }) {
|
|
170
|
+
function TooltipContent({ align, alignOffset = defaultContentPositioning.alignOffset, children, className, collisionPadding = defaultContentPositioning.collisionPadding, container, forceMount = false, placement, ref, side, sideOffset = defaultContentPositioning.sideOffset, style, ...props }) {
|
|
168
171
|
const context = useTooltipRootContext("Tooltip.Content");
|
|
169
172
|
React.useEffect(() => {
|
|
173
|
+
const resolvedPlacement = side === undefined ? placement : placementFromSideAlign(side, align, placement ?? "bottom");
|
|
170
174
|
context.setContentPositioning({
|
|
175
|
+
...(resolvedPlacement === undefined ? {} : { placement: resolvedPlacement }),
|
|
171
176
|
sideOffset,
|
|
177
|
+
alignOffset,
|
|
172
178
|
collisionPadding
|
|
173
179
|
});
|
|
174
180
|
return () => context.setContentPositioning(defaultContentPositioning);
|
|
175
|
-
}, [collisionPadding, context, sideOffset]);
|
|
181
|
+
}, [align, alignOffset, collisionPadding, context, placement, side, sideOffset]);
|
|
176
182
|
if (!context.open && !forceMount) {
|
|
177
183
|
return null;
|
|
178
184
|
}
|
|
179
185
|
const placementParts = getPlacementParts(context.resolvedPlacement);
|
|
180
|
-
const content = (_jsx("span", { ...props, ref: composeRefs(ref, context.floatingRef), id: context.contentId, className: cn("
|
|
186
|
+
const content = (_jsx("span", { ...props, ref: composeRefs(ref, context.floatingRef), id: context.contentId, className: cn("zvk-ui-tooltip", className), "data-align": placementParts.align, "data-side": placementParts.side, hidden: context.open ? undefined : true, role: "tooltip", style: { ...context.floatingStyle, ...style }, children: children }));
|
|
181
187
|
return (_jsx(Portal, { ...(container === undefined ? {} : { container }), children: content }));
|
|
182
188
|
}
|
|
183
189
|
function TooltipWrapper({ children, content, delay = 0, disabled = false, placement = "bottom" }) {
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { useComposedRefs } from "./use-composed-refs.js";
|
|
2
|
-
export type {
|
|
2
|
+
export type { ZvkUiPossibleRef } from "./use-composed-refs.js";
|
|
3
3
|
export { useControllableState } from "./use-controllable-state.js";
|
|
4
|
-
export type {
|
|
4
|
+
export type { ZvkUiSetStateAction, UseControllableStateOptions } from "./use-controllable-state.js";
|
|
5
5
|
export { useDisclosure } from "./use-disclosure.js";
|
|
6
6
|
export type { UseDisclosureOptions, UseDisclosureReturn } from "./use-disclosure.js";
|
|
7
7
|
export { useEvent } from "./use-event.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
export type
|
|
3
|
-
export declare function useComposedRefs<Value>(...refs:
|
|
2
|
+
export type ZvkUiPossibleRef<Value> = React.Ref<Value> | undefined;
|
|
3
|
+
export declare function useComposedRefs<Value>(...refs: ZvkUiPossibleRef<Value>[]): React.RefCallback<Value>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type ZvkUiSetStateAction<Value> = Value | ((previous: Value) => Value);
|
|
2
2
|
export interface UseControllableStateOptions<Value> {
|
|
3
3
|
value?: Value;
|
|
4
4
|
defaultValue: Value;
|
|
5
5
|
onChange?: (value: Value) => void;
|
|
6
6
|
}
|
|
7
|
-
export declare function useControllableState<Value>({ value, defaultValue, onChange }: UseControllableStateOptions<Value>): readonly [Value, (next:
|
|
7
|
+
export declare function useControllableState<Value>({ value, defaultValue, onChange }: UseControllableStateOptions<Value>): readonly [Value, (next: ZvkUiSetStateAction<Value>) => void];
|
|
@@ -3,7 +3,10 @@ import { detectOverflow } from "./detect-overflow.js";
|
|
|
3
3
|
function getCenteredOffset(referenceSize, floatingSize) {
|
|
4
4
|
return (referenceSize - floatingSize) / 2;
|
|
5
5
|
}
|
|
6
|
-
function
|
|
6
|
+
function applyAlignmentOffset(value, align, offset) {
|
|
7
|
+
return align === "end" ? value - offset : value + offset;
|
|
8
|
+
}
|
|
9
|
+
function getPlacementCoords(placement, reference, floating, offset, alignmentOffset) {
|
|
7
10
|
const { side, align } = parsePlacement(placement);
|
|
8
11
|
if (side === "top" || side === "bottom") {
|
|
9
12
|
const baseY = side === "top" ? reference.y - floating.height - offset : reference.y + reference.height + offset;
|
|
@@ -17,6 +20,7 @@ function getPlacementCoords(placement, reference, floating, offset) {
|
|
|
17
20
|
else {
|
|
18
21
|
x = reference.x + getCenteredOffset(reference.width, floating.width);
|
|
19
22
|
}
|
|
23
|
+
x = applyAlignmentOffset(x, align, alignmentOffset);
|
|
20
24
|
return { x, y: baseY };
|
|
21
25
|
}
|
|
22
26
|
const baseX = side === "left" ? reference.x - floating.width - offset : reference.x + reference.width + offset;
|
|
@@ -30,10 +34,11 @@ function getPlacementCoords(placement, reference, floating, offset) {
|
|
|
30
34
|
else {
|
|
31
35
|
y = reference.y + getCenteredOffset(reference.height, floating.height);
|
|
32
36
|
}
|
|
37
|
+
y = applyAlignmentOffset(y, align, alignmentOffset);
|
|
33
38
|
return { x: baseX, y };
|
|
34
39
|
}
|
|
35
|
-
function getOverflowForPlacement(placement, reference, floating, boundary, offset, collisionPadding) {
|
|
36
|
-
const { x, y } = getPlacementCoords(placement, reference, floating, offset);
|
|
40
|
+
function getOverflowForPlacement(placement, reference, floating, boundary, offset, alignmentOffset, collisionPadding) {
|
|
41
|
+
const { x, y } = getPlacementCoords(placement, reference, floating, offset, alignmentOffset);
|
|
37
42
|
return detectOverflow({
|
|
38
43
|
boundary,
|
|
39
44
|
collisionPadding,
|
|
@@ -46,22 +51,22 @@ function getOverflowForPlacement(placement, reference, floating, boundary, offse
|
|
|
46
51
|
});
|
|
47
52
|
}
|
|
48
53
|
export function computeFloatingPosition(options) {
|
|
49
|
-
const { reference, floating, boundary, placement: rawPlacement = "bottom", strategy = "absolute", offset = 0, collisionPadding = 0, matchReferenceWidth = false, maxHeight, flip = true, shift = true } = options;
|
|
54
|
+
const { reference, floating, boundary, placement: rawPlacement = "bottom", strategy = "absolute", offset = 0, alignmentOffset = 0, collisionPadding = 0, matchReferenceWidth = false, maxHeight, flip = true, shift = true } = options;
|
|
50
55
|
const parsed = parsePlacement(rawPlacement);
|
|
51
56
|
const defaultPlacement = buildPlacement(parsed.side, parsed.align);
|
|
52
57
|
let currentPlacement = defaultPlacement;
|
|
53
|
-
let basePlacement = getPlacementCoords(currentPlacement, reference, floating, offset);
|
|
58
|
+
let basePlacement = getPlacementCoords(currentPlacement, reference, floating, offset, alignmentOffset);
|
|
54
59
|
if (flip) {
|
|
55
|
-
const overflow = getOverflowForPlacement(currentPlacement, reference, floating, boundary, offset, collisionPadding);
|
|
60
|
+
const overflow = getOverflowForPlacement(currentPlacement, reference, floating, boundary, offset, alignmentOffset, collisionPadding);
|
|
56
61
|
const { side: currentSide } = parsePlacement(currentPlacement);
|
|
57
62
|
const overflowSide = overflow[currentSide];
|
|
58
63
|
if (overflowSide > 0) {
|
|
59
64
|
const oppositeSide = getOppositeSide(currentSide);
|
|
60
65
|
const oppositePlacement = buildPlacement(oppositeSide, parsed.align);
|
|
61
|
-
const oppositeOverflow = getOverflowForPlacement(oppositePlacement, reference, floating, boundary, offset, collisionPadding);
|
|
66
|
+
const oppositeOverflow = getOverflowForPlacement(oppositePlacement, reference, floating, boundary, offset, alignmentOffset, collisionPadding);
|
|
62
67
|
if (oppositeOverflow[oppositeSide] < overflowSide) {
|
|
63
68
|
currentPlacement = oppositePlacement;
|
|
64
|
-
basePlacement = getPlacementCoords(currentPlacement, reference, floating, offset);
|
|
69
|
+
basePlacement = getPlacementCoords(currentPlacement, reference, floating, offset, alignmentOffset);
|
|
65
70
|
}
|
|
66
71
|
}
|
|
67
72
|
}
|
|
@@ -6,6 +6,7 @@ export type UseFloatingPositionOptions = {
|
|
|
6
6
|
placement?: import("./floating-types.js").FloatingPlacement;
|
|
7
7
|
strategy?: import("./floating-types.js").FloatingStrategy;
|
|
8
8
|
offset?: number;
|
|
9
|
+
alignmentOffset?: number;
|
|
9
10
|
collisionPadding?: number;
|
|
10
11
|
matchReferenceWidth?: boolean;
|
|
11
12
|
maxHeight?: number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FloatingAlign, FloatingPlacement, FloatingSide } from "./floating-types.js";
|
|
2
|
+
export type { FloatingAlign, FloatingSide } from "./floating-types.js";
|
|
3
|
+
export declare function placementFromSideAlign(side: FloatingSide | undefined, align: FloatingAlign | undefined, fallback: FloatingPlacement): FloatingPlacement;
|
|
4
|
+
export declare function placementParts(placement: FloatingPlacement): {
|
|
5
|
+
side: FloatingSide;
|
|
6
|
+
align: FloatingAlign;
|
|
7
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function placementFromSideAlign(side, align, fallback) {
|
|
2
|
+
if (side === undefined) {
|
|
3
|
+
return fallback;
|
|
4
|
+
}
|
|
5
|
+
if (align === undefined || align === "center") {
|
|
6
|
+
return side;
|
|
7
|
+
}
|
|
8
|
+
return `${side}-${align}`;
|
|
9
|
+
}
|
|
10
|
+
export function placementParts(placement) {
|
|
11
|
+
const [side, align = "center"] = placement.split("-");
|
|
12
|
+
return { side, align };
|
|
13
|
+
}
|
|
@@ -3,7 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import { computeFloatingPosition } from "./compute-position.js";
|
|
4
4
|
import { autoUpdateFloating } from "./auto-update.js";
|
|
5
5
|
export function useFloatingPosition(options) {
|
|
6
|
-
const { open, placement = "bottom", strategy = "absolute", offset = 0, collisionPadding = 0, matchReferenceWidth = false, maxHeight, flip = true, shift = true, boundary } = options;
|
|
6
|
+
const { open, placement = "bottom", strategy = "absolute", offset = 0, alignmentOffset = 0, collisionPadding = 0, matchReferenceWidth = false, maxHeight, flip = true, shift = true, boundary } = options;
|
|
7
7
|
const [referenceEl, setReferenceEl] = React.useState(null);
|
|
8
8
|
const [floatingEl, setFloatingEl] = React.useState(null);
|
|
9
9
|
const [style, setStyle] = React.useState({
|
|
@@ -62,6 +62,7 @@ export function useFloatingPosition(options) {
|
|
|
62
62
|
placement: placement,
|
|
63
63
|
strategy: strategy,
|
|
64
64
|
offset,
|
|
65
|
+
alignmentOffset,
|
|
65
66
|
collisionPadding,
|
|
66
67
|
matchReferenceWidth,
|
|
67
68
|
...(maxHeight === undefined ? {} : { maxHeight }),
|
|
@@ -73,9 +74,9 @@ export function useFloatingPosition(options) {
|
|
|
73
74
|
left: `${computed.x}px`,
|
|
74
75
|
top: `${computed.y}px`,
|
|
75
76
|
width: matchReferenceWidth ? `${referenceEl?.offsetWidth ?? computed.referenceWidth}px` : "auto",
|
|
76
|
-
"--
|
|
77
|
-
"--
|
|
78
|
-
"--
|
|
77
|
+
"--zvk-ui-floating-reference-width": `${computed.referenceWidth}px`,
|
|
78
|
+
"--zvk-ui-floating-available-width": `${computed.availableWidth}px`,
|
|
79
|
+
"--zvk-ui-floating-available-height": `${computed.availableHeight}px`
|
|
79
80
|
});
|
|
80
81
|
setResolvedPlacement(computed.placement);
|
|
81
82
|
}, [
|
|
@@ -83,6 +84,7 @@ export function useFloatingPosition(options) {
|
|
|
83
84
|
placement,
|
|
84
85
|
strategy,
|
|
85
86
|
offset,
|
|
87
|
+
alignmentOffset,
|
|
86
88
|
collisionPadding,
|
|
87
89
|
matchReferenceWidth,
|
|
88
90
|
maxHeight,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const overlayStack = [];
|
|
2
|
+
let nextOverlayId = 1;
|
|
2
3
|
export function pushOverlay(node) {
|
|
3
|
-
const id = `
|
|
4
|
+
const id = `zvk-ui-overlay-${nextOverlayId}`;
|
|
5
|
+
nextOverlayId += 1;
|
|
4
6
|
overlayStack.push({ id, node });
|
|
5
7
|
return id;
|
|
6
8
|
}
|
|
@@ -35,6 +37,7 @@ export function isInOverlayStack(node) {
|
|
|
35
37
|
}
|
|
36
38
|
export function resetOverlayStackForTests() {
|
|
37
39
|
overlayStack.length = 0;
|
|
40
|
+
nextOverlayId = 1;
|
|
38
41
|
}
|
|
39
42
|
export function getOverlayStackLength() {
|
|
40
43
|
return overlayStack.length;
|