@brijbyte/agentic-ui 0.0.1 → 0.0.2
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 +183 -111
- package/dist/accordion/accordion.css +6 -10
- package/dist/accordion/accordion.module.js.map +1 -1
- package/dist/alert-dialog/alert-dialog.css +84 -0
- package/dist/alert-dialog/alert-dialog.d.ts +44 -0
- package/dist/alert-dialog/alert-dialog.d.ts.map +1 -0
- package/dist/alert-dialog/alert-dialog.js +46 -0
- package/dist/alert-dialog/alert-dialog.js.map +1 -0
- package/dist/alert-dialog/alert-dialog.module.css.d.ts +2 -0
- package/dist/alert-dialog/alert-dialog.module.js +14 -0
- package/dist/alert-dialog/alert-dialog.module.js.map +1 -0
- package/dist/alert-dialog/index.d.ts +3 -0
- package/dist/alert-dialog/index.js +4 -0
- package/dist/alert-dialog/parts.d.ts +28 -0
- package/dist/alert-dialog/parts.d.ts.map +1 -0
- package/dist/alert-dialog/parts.js +62 -0
- package/dist/alert-dialog/parts.js.map +1 -0
- package/dist/badge/badge.css +3 -7
- package/dist/badge/badge.module.js.map +1 -1
- package/dist/button/button.css +14 -14
- package/dist/button/button.module.js.map +1 -1
- package/dist/card/card.css +5 -9
- package/dist/card/card.module.js.map +1 -1
- package/dist/checkbox/checkbox.css +3 -7
- package/dist/checkbox/checkbox.module.js.map +1 -1
- package/dist/collapsible/collapsible.css +7 -11
- package/dist/collapsible/collapsible.module.js.map +1 -1
- package/dist/context-menu/context-menu.css +151 -0
- package/dist/context-menu/context-menu.d.ts +36 -0
- package/dist/context-menu/context-menu.d.ts.map +1 -0
- package/dist/context-menu/context-menu.js +54 -0
- package/dist/context-menu/context-menu.js.map +1 -0
- package/dist/context-menu/context-menu.module.css.d.ts +2 -0
- package/dist/context-menu/context-menu.module.js +18 -0
- package/dist/context-menu/context-menu.module.js.map +1 -0
- package/dist/context-menu/index.d.ts +3 -0
- package/dist/context-menu/index.js +4 -0
- package/dist/context-menu/parts.d.ts +38 -0
- package/dist/context-menu/parts.d.ts.map +1 -0
- package/dist/context-menu/parts.js +91 -0
- package/dist/context-menu/parts.js.map +1 -0
- package/dist/dialog/dialog.css +27 -22
- package/dist/dialog/dialog.d.ts +8 -0
- package/dist/dialog/dialog.d.ts.map +1 -1
- package/dist/dialog/dialog.js +7 -4
- package/dist/dialog/dialog.js.map +1 -1
- package/dist/dialog/dialog.module.js +2 -0
- package/dist/dialog/dialog.module.js.map +1 -1
- package/dist/drawer/drawer.css +9 -13
- package/dist/drawer/drawer.module.js.map +1 -1
- package/dist/index.css +1630 -1353
- package/dist/index.d.ts +24 -18
- package/dist/index.js +10 -1
- package/dist/input/input.css +5 -9
- package/dist/input/input.module.js.map +1 -1
- package/dist/layer-order.css +22 -0
- package/dist/menu/menu.css +13 -17
- package/dist/menu/menu.module.js.map +1 -1
- package/dist/number-field/number-field.css +12 -16
- package/dist/number-field/number-field.module.js.map +1 -1
- package/dist/progress/progress.css +1 -5
- package/dist/progress/progress.module.js.map +1 -1
- package/dist/reset.css +6 -6
- package/dist/select/select.css +14 -16
- package/dist/select/select.d.ts +5 -2
- package/dist/select/select.d.ts.map +1 -1
- package/dist/select/select.js +11 -2
- package/dist/select/select.js.map +1 -1
- package/dist/select/select.module.js.map +1 -1
- package/dist/separator/separator.css +1 -5
- package/dist/separator/separator.module.js.map +1 -1
- package/dist/slider/index.d.ts +3 -0
- package/dist/slider/index.js +4 -0
- package/dist/slider/parts.d.ts +38 -0
- package/dist/slider/parts.d.ts.map +1 -0
- package/dist/slider/parts.js +69 -0
- package/dist/slider/parts.js.map +1 -0
- package/dist/slider/slider.css +97 -0
- package/dist/slider/slider.d.ts +38 -0
- package/dist/slider/slider.d.ts.map +1 -0
- package/dist/slider/slider.js +41 -0
- package/dist/slider/slider.js.map +1 -0
- package/dist/slider/slider.module.css.d.ts +2 -0
- package/dist/slider/slider.module.js +15 -0
- package/dist/slider/slider.module.js.map +1 -0
- package/dist/styles/reset.css +6 -6
- package/dist/styles/tokens.css +73 -71
- package/dist/switch/switch.css +2 -6
- package/dist/switch/switch.module.js.map +1 -1
- package/dist/tabs/tabs.css +5 -9
- package/dist/tabs/tabs.module.js.map +1 -1
- package/dist/tailwind-theme.css +23 -23
- package/dist/toast/toast.css +11 -15
- package/dist/toast/toast.module.js.map +1 -1
- package/dist/tokens.css +79 -75
- package/dist/tooltip/tooltip.css +7 -11
- package/dist/tooltip/tooltip.module.js.map +1 -1
- package/package.json +17 -1
- package/src/accordion/accordion.module.css +6 -20
- package/src/alert-dialog/alert-dialog.module.css +91 -0
- package/src/alert-dialog/alert-dialog.tsx +69 -0
- package/src/alert-dialog/index.ts +7 -0
- package/src/alert-dialog/parts.tsx +73 -0
- package/src/badge/badge.module.css +3 -13
- package/src/button/button.module.css +15 -51
- package/src/card/card.module.css +5 -16
- package/src/checkbox/checkbox.module.css +3 -14
- package/src/collapsible/collapsible.module.css +7 -20
- package/src/context-menu/context-menu.module.css +168 -0
- package/src/context-menu/context-menu.tsx +75 -0
- package/src/context-menu/index.ts +21 -0
- package/src/context-menu/parts.tsx +99 -0
- package/src/dialog/dialog.module.css +26 -33
- package/src/dialog/dialog.tsx +14 -1
- package/src/drawer/drawer.module.css +9 -58
- package/src/index.ts +48 -0
- package/src/input/input.module.css +5 -21
- package/src/menu/menu.module.css +13 -43
- package/src/number-field/number-field.module.css +12 -28
- package/src/progress/progress.module.css +1 -10
- package/src/select/select.module.css +14 -35
- package/src/select/select.tsx +14 -5
- package/src/separator/separator.module.css +1 -5
- package/src/slider/index.ts +14 -0
- package/src/slider/parts.tsx +90 -0
- package/src/slider/slider.module.css +110 -0
- package/src/slider/slider.tsx +68 -0
- package/src/styles/layer-order.css +22 -0
- package/src/styles/reset.css +6 -6
- package/src/styles/tailwind-theme.css +23 -23
- package/src/styles/tokens.css +79 -75
- package/src/switch/switch.module.css +2 -12
- package/src/tabs/tabs.module.css +5 -18
- package/src/toast/toast.module.css +11 -51
- package/src/tooltip/tooltip.module.css +7 -18
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.positioner {
|
|
3
|
+
outline: none;
|
|
4
|
+
z-index: var(--z-dropdown);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.popup {
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
padding: var(--space-1) 0;
|
|
10
|
+
border-radius: var(--radius-lg);
|
|
11
|
+
background-color: var(--color-overlay);
|
|
12
|
+
border: var(--border-width-base) solid var(--color-line);
|
|
13
|
+
box-shadow: var(--shadow-popover);
|
|
14
|
+
color: var(--color-primary);
|
|
15
|
+
font-family: var(--font-sans);
|
|
16
|
+
font-size: var(--font-size-md);
|
|
17
|
+
min-width: 220px;
|
|
18
|
+
transform-origin: var(--transform-origin);
|
|
19
|
+
outline: none;
|
|
20
|
+
transition:
|
|
21
|
+
opacity 150ms var(--easing-ease-out),
|
|
22
|
+
transform 150ms var(--easing-ease-out);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@supports (backdrop-filter: blur(20px)) {
|
|
26
|
+
.popup {
|
|
27
|
+
backdrop-filter: blur(20px) saturate(1.8);
|
|
28
|
+
-webkit-backdrop-filter: blur(20px) saturate(1.8);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.popup[data-starting-style] {
|
|
33
|
+
opacity: 0;
|
|
34
|
+
transform: scale(0.97);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.popup[data-ending-style] {
|
|
38
|
+
opacity: 0;
|
|
39
|
+
transform: scale(0.99);
|
|
40
|
+
transition:
|
|
41
|
+
opacity 75ms var(--easing-ease-in),
|
|
42
|
+
transform 75ms var(--easing-ease-in);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ─── Trigger area ───────────────────────────────────────────── */
|
|
46
|
+
|
|
47
|
+
.trigger {
|
|
48
|
+
display: block;
|
|
49
|
+
outline: none;
|
|
50
|
+
user-select: none;
|
|
51
|
+
-webkit-user-select: none;
|
|
52
|
+
cursor: default;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* ─── Item ───────────────────────────────────────────────────── */
|
|
56
|
+
|
|
57
|
+
.item {
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: var(--space-2);
|
|
61
|
+
/* Full-width — no inset margin */
|
|
62
|
+
padding: var(--space-1) var(--space-4);
|
|
63
|
+
font-family: var(--font-sans);
|
|
64
|
+
font-size: var(--font-size-md);
|
|
65
|
+
color: var(--color-primary);
|
|
66
|
+
cursor: default;
|
|
67
|
+
outline: none;
|
|
68
|
+
user-select: none;
|
|
69
|
+
position: relative;
|
|
70
|
+
transition: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.item[data-highlighted] {
|
|
74
|
+
background-color: var(--color-accent);
|
|
75
|
+
color: var(--color-on-accent);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.item[data-disabled] {
|
|
79
|
+
opacity: 0.36;
|
|
80
|
+
cursor: not-allowed;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* ─── Item internals ─────────────────────────────────────────── */
|
|
84
|
+
|
|
85
|
+
.item-icon {
|
|
86
|
+
width: 16px;
|
|
87
|
+
height: 16px;
|
|
88
|
+
flex-shrink: 0;
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
justify-content: center;
|
|
92
|
+
color: inherit;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.item-label {
|
|
96
|
+
flex: 1;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.item-shortcut {
|
|
100
|
+
margin-left: var(--space-8);
|
|
101
|
+
font-size: var(--font-size-sm);
|
|
102
|
+
color: var(--color-tertiary);
|
|
103
|
+
flex-shrink: 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.item[data-highlighted] .item-shortcut {
|
|
107
|
+
color: color-mix(in srgb, var(--color-on-accent) 60%, transparent);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.submenu-icon {
|
|
111
|
+
margin-left: auto;
|
|
112
|
+
color: var(--color-tertiary);
|
|
113
|
+
flex-shrink: 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.item[data-highlighted] .submenu-icon,
|
|
117
|
+
.submenu-trigger[data-highlighted] .submenu-icon {
|
|
118
|
+
color: color-mix(in srgb, var(--color-on-accent) 70%, transparent);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* ─── Submenu trigger ────────────────────────────────────────── */
|
|
122
|
+
|
|
123
|
+
.submenu-trigger {
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
gap: var(--space-2);
|
|
127
|
+
padding: var(--space-1) var(--space-4);
|
|
128
|
+
font-family: var(--font-sans);
|
|
129
|
+
font-size: var(--font-size-md);
|
|
130
|
+
color: var(--color-primary);
|
|
131
|
+
cursor: default;
|
|
132
|
+
outline: none;
|
|
133
|
+
user-select: none;
|
|
134
|
+
transition: none;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.submenu-trigger[data-highlighted],
|
|
138
|
+
.submenu-trigger[data-popup-open] {
|
|
139
|
+
background-color: var(--color-accent);
|
|
140
|
+
color: var(--color-on-accent);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.submenu-trigger[data-disabled] {
|
|
144
|
+
opacity: 0.36;
|
|
145
|
+
cursor: not-allowed;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* ─── Group label ────────────────────────────────────────────── */
|
|
149
|
+
|
|
150
|
+
.group-label {
|
|
151
|
+
padding: var(--space-1) var(--space-4) var(--space-0-5);
|
|
152
|
+
font-family: var(--font-sans);
|
|
153
|
+
font-size: var(--font-size-xs);
|
|
154
|
+
font-weight: var(--font-weight-semibold);
|
|
155
|
+
color: var(--color-tertiary);
|
|
156
|
+
text-transform: uppercase;
|
|
157
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
158
|
+
cursor: default;
|
|
159
|
+
user-select: none;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* ─── Separator ──────────────────────────────────────────────── */
|
|
163
|
+
.separator {
|
|
164
|
+
margin: var(--space-1) var(--space-4);
|
|
165
|
+
height: var(--border-width-base);
|
|
166
|
+
background-color: var(--color-line-subtle);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ReactNode, ReactElement } from "react";
|
|
2
|
+
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu";
|
|
3
|
+
import styles from "./context-menu.module.css";
|
|
4
|
+
|
|
5
|
+
export interface ContextMenuItemDef {
|
|
6
|
+
type?: "item";
|
|
7
|
+
label: ReactNode;
|
|
8
|
+
icon?: ReactNode;
|
|
9
|
+
shortcut?: string;
|
|
10
|
+
onSelect?: () => void;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ContextMenuSeparatorDef {
|
|
15
|
+
type: "separator";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ContextMenuGroupDef {
|
|
19
|
+
type: "group";
|
|
20
|
+
label?: ReactNode;
|
|
21
|
+
items: ContextMenuItemDef[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type ContextMenuEntry = ContextMenuItemDef | ContextMenuSeparatorDef | ContextMenuGroupDef;
|
|
25
|
+
|
|
26
|
+
export interface ContextMenuProps {
|
|
27
|
+
/** The element that can be right-clicked / long-pressed to open the menu. */
|
|
28
|
+
children: ReactElement;
|
|
29
|
+
items: ContextMenuEntry[];
|
|
30
|
+
className?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function RenderItem({ item, i }: { item: ContextMenuItemDef; i: number }) {
|
|
34
|
+
return (
|
|
35
|
+
<BaseContextMenu.Item key={i} className={styles.item} disabled={item.disabled} onClick={item.onSelect}>
|
|
36
|
+
{item.icon && <span className={styles["item-icon"]}>{item.icon}</span>}
|
|
37
|
+
<span className={styles["item-label"]}>{item.label}</span>
|
|
38
|
+
{item.shortcut && <span className={styles["item-shortcut"]}>{item.shortcut}</span>}
|
|
39
|
+
</BaseContextMenu.Item>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function ContextMenu({ children, items, className }: ContextMenuProps) {
|
|
44
|
+
return (
|
|
45
|
+
<BaseContextMenu.Root>
|
|
46
|
+
<BaseContextMenu.Trigger className={`${styles.trigger} ${className ?? ""}`} render={children} />
|
|
47
|
+
<BaseContextMenu.Portal>
|
|
48
|
+
<BaseContextMenu.Positioner className={styles.positioner}>
|
|
49
|
+
<BaseContextMenu.Popup className={styles.popup}>
|
|
50
|
+
{items.map((entry, i) => {
|
|
51
|
+
if (entry.type === "separator") {
|
|
52
|
+
return <BaseContextMenu.Separator key={i} className={styles.separator} />;
|
|
53
|
+
}
|
|
54
|
+
if (entry.type === "group") {
|
|
55
|
+
return (
|
|
56
|
+
<BaseContextMenu.Group key={i}>
|
|
57
|
+
{entry.label && (
|
|
58
|
+
<BaseContextMenu.GroupLabel className={styles["group-label"]}>{entry.label}</BaseContextMenu.GroupLabel>
|
|
59
|
+
)}
|
|
60
|
+
{entry.items.map((item, j) => (
|
|
61
|
+
<RenderItem key={j} item={item} i={j} />
|
|
62
|
+
))}
|
|
63
|
+
</BaseContextMenu.Group>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
return <RenderItem key={i} item={entry} i={i} />;
|
|
67
|
+
})}
|
|
68
|
+
</BaseContextMenu.Popup>
|
|
69
|
+
</BaseContextMenu.Positioner>
|
|
70
|
+
</BaseContextMenu.Portal>
|
|
71
|
+
</BaseContextMenu.Root>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { styles as ContextMenuStyles };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { ContextMenu } from "./context-menu";
|
|
2
|
+
export type { ContextMenuProps, ContextMenuEntry, ContextMenuItemDef, ContextMenuSeparatorDef, ContextMenuGroupDef } from "./context-menu";
|
|
3
|
+
|
|
4
|
+
export {
|
|
5
|
+
ContextMenuPopup,
|
|
6
|
+
ContextMenuItem,
|
|
7
|
+
ContextMenuSeparator,
|
|
8
|
+
ContextMenuGroup,
|
|
9
|
+
ContextMenuGroupLabel,
|
|
10
|
+
ContextMenuSubmenuTrigger,
|
|
11
|
+
} from "./parts";
|
|
12
|
+
export type {
|
|
13
|
+
ContextMenuPopupProps,
|
|
14
|
+
ContextMenuItemProps,
|
|
15
|
+
ContextMenuSeparatorProps,
|
|
16
|
+
ContextMenuGroupProps,
|
|
17
|
+
ContextMenuGroupLabelProps,
|
|
18
|
+
ContextMenuSubmenuTriggerProps,
|
|
19
|
+
} from "./parts";
|
|
20
|
+
|
|
21
|
+
export { ContextMenuStyles } from "./context-menu";
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Styled primitives for ContextMenu.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```tsx
|
|
6
|
+
* import { ContextMenu as BaseContextMenu } from '@base-ui/react/context-menu';
|
|
7
|
+
* import { ContextMenuPopup, ContextMenuItem, ContextMenuSeparator } from '@brijbyte/agentic-ui/context-menu';
|
|
8
|
+
*
|
|
9
|
+
* <BaseContextMenu.Root>
|
|
10
|
+
* <BaseContextMenu.Trigger render={<div>Right click me</div>} />
|
|
11
|
+
* <BaseContextMenu.Portal>
|
|
12
|
+
* <BaseContextMenu.Positioner>
|
|
13
|
+
* <ContextMenuPopup>
|
|
14
|
+
* <ContextMenuItem>Cut</ContextMenuItem>
|
|
15
|
+
* <ContextMenuItem>Copy</ContextMenuItem>
|
|
16
|
+
* <ContextMenuSeparator />
|
|
17
|
+
* <ContextMenuItem>Paste</ContextMenuItem>
|
|
18
|
+
* </ContextMenuPopup>
|
|
19
|
+
* </BaseContextMenu.Positioner>
|
|
20
|
+
* </BaseContextMenu.Portal>
|
|
21
|
+
* </BaseContextMenu.Root>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
import { forwardRef } from "react";
|
|
25
|
+
import type { ComponentRef, ComponentPropsWithoutRef } from "react";
|
|
26
|
+
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu";
|
|
27
|
+
import styles from "./context-menu.module.css";
|
|
28
|
+
|
|
29
|
+
type BasePopupProps = ComponentPropsWithoutRef<typeof BaseContextMenu.Popup>;
|
|
30
|
+
type BaseItemProps = ComponentPropsWithoutRef<typeof BaseContextMenu.Item>;
|
|
31
|
+
type BaseSeparatorProps = ComponentPropsWithoutRef<typeof BaseContextMenu.Separator>;
|
|
32
|
+
type BaseGroupProps = ComponentPropsWithoutRef<typeof BaseContextMenu.Group>;
|
|
33
|
+
type BaseGroupLabelProps = ComponentPropsWithoutRef<typeof BaseContextMenu.GroupLabel>;
|
|
34
|
+
type BaseSubmenuTriggerProps = ComponentPropsWithoutRef<typeof BaseContextMenu.SubmenuTrigger>;
|
|
35
|
+
|
|
36
|
+
export interface ContextMenuPopupProps extends Omit<BasePopupProps, "className"> {
|
|
37
|
+
className?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ContextMenuItemProps extends Omit<BaseItemProps, "className"> {
|
|
40
|
+
className?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ContextMenuSeparatorProps extends Omit<BaseSeparatorProps, "className"> {
|
|
43
|
+
className?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface ContextMenuGroupProps extends Omit<BaseGroupProps, "className"> {
|
|
46
|
+
className?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ContextMenuGroupLabelProps extends Omit<BaseGroupLabelProps, "className"> {
|
|
49
|
+
className?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface ContextMenuSubmenuTriggerProps extends Omit<BaseSubmenuTriggerProps, "className"> {
|
|
52
|
+
className?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const ContextMenuPopup = forwardRef<ComponentRef<typeof BaseContextMenu.Popup>, ContextMenuPopupProps>(function ContextMenuPopup(
|
|
56
|
+
{ className, ...props },
|
|
57
|
+
ref,
|
|
58
|
+
) {
|
|
59
|
+
return <BaseContextMenu.Popup ref={ref} className={`${styles.popup} ${className ?? ""}`} {...props} />;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
export const ContextMenuItem = forwardRef<ComponentRef<typeof BaseContextMenu.Item>, ContextMenuItemProps>(function ContextMenuItem(
|
|
63
|
+
{ className, ...props },
|
|
64
|
+
ref,
|
|
65
|
+
) {
|
|
66
|
+
return <BaseContextMenu.Item ref={ref} className={`${styles.item} ${className ?? ""}`} {...props} />;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
export const ContextMenuSeparator = forwardRef<ComponentRef<typeof BaseContextMenu.Separator>, ContextMenuSeparatorProps>(
|
|
70
|
+
function ContextMenuSeparator({ className, ...props }, ref) {
|
|
71
|
+
return <BaseContextMenu.Separator ref={ref} className={`${styles.separator} ${className ?? ""}`} {...props} />;
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
export const ContextMenuGroup = forwardRef<ComponentRef<typeof BaseContextMenu.Group>, ContextMenuGroupProps>(function ContextMenuGroup(
|
|
76
|
+
{ className, ...props },
|
|
77
|
+
ref,
|
|
78
|
+
) {
|
|
79
|
+
return <BaseContextMenu.Group ref={ref} className={className} {...props} />;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export const ContextMenuGroupLabel = forwardRef<ComponentRef<typeof BaseContextMenu.GroupLabel>, ContextMenuGroupLabelProps>(
|
|
83
|
+
function ContextMenuGroupLabel({ className, ...props }, ref) {
|
|
84
|
+
return <BaseContextMenu.GroupLabel ref={ref} className={`${styles["group-label"]} ${className ?? ""}`} {...props} />;
|
|
85
|
+
},
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
export const ContextMenuSubmenuTrigger = forwardRef<ComponentRef<typeof BaseContextMenu.SubmenuTrigger>, ContextMenuSubmenuTriggerProps>(
|
|
89
|
+
function ContextMenuSubmenuTrigger({ className, children, ...props }, ref) {
|
|
90
|
+
return (
|
|
91
|
+
<BaseContextMenu.SubmenuTrigger ref={ref} className={`${styles["submenu-trigger"]} ${className ?? ""}`} {...props}>
|
|
92
|
+
<span style={{ flex: 1 }}>{children}</span>
|
|
93
|
+
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" className={styles["submenu-icon"]}>
|
|
94
|
+
<path d="M3.5 9L7.5 5L3.5 1" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
95
|
+
</svg>
|
|
96
|
+
</BaseContextMenu.SubmenuTrigger>
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
);
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
@layer theme, base, components, utilities;
|
|
2
|
-
|
|
3
1
|
@layer components {
|
|
4
2
|
.backdrop {
|
|
5
3
|
position: fixed;
|
|
@@ -8,41 +6,36 @@
|
|
|
8
6
|
z-index: var(--z-overlay);
|
|
9
7
|
transition: opacity var(--duration-slow) var(--easing-standard);
|
|
10
8
|
}
|
|
11
|
-
|
|
12
9
|
.backdrop[data-starting-style],
|
|
13
10
|
.backdrop[data-ending-style] {
|
|
14
11
|
opacity: 0;
|
|
15
12
|
}
|
|
16
|
-
|
|
17
13
|
.popup {
|
|
18
14
|
position: fixed;
|
|
19
15
|
top: 50%;
|
|
20
16
|
left: 50%;
|
|
21
17
|
transform: translate(-50%, -50%);
|
|
22
18
|
z-index: var(--z-modal);
|
|
23
|
-
background-color: var(--color-
|
|
24
|
-
border: var(--border-width-base) solid var(--color-
|
|
19
|
+
background-color: var(--color-elevated);
|
|
20
|
+
border: var(--border-width-base) solid var(--color-line);
|
|
25
21
|
border-radius: var(--radius-2xl);
|
|
26
22
|
box-shadow: var(--shadow-xl);
|
|
27
|
-
padding: var(--space-6);
|
|
28
|
-
width: min(
|
|
23
|
+
padding: var(--space-5) var(--space-6) var(--space-5);
|
|
24
|
+
width: min(440px, calc(100vw - var(--space-8)));
|
|
29
25
|
max-height: min(640px, calc(100vh - var(--space-8)));
|
|
30
26
|
display: flex;
|
|
31
27
|
flex-direction: column;
|
|
32
|
-
gap: var(--space-
|
|
28
|
+
gap: var(--space-3);
|
|
33
29
|
outline: none;
|
|
34
30
|
overflow: hidden;
|
|
35
|
-
|
|
36
31
|
transition:
|
|
37
32
|
opacity 200ms var(--easing-ease-out),
|
|
38
33
|
transform 200ms var(--easing-spring);
|
|
39
34
|
}
|
|
40
|
-
|
|
41
35
|
.popup[data-starting-style] {
|
|
42
36
|
opacity: 0;
|
|
43
37
|
transform: translate(-50%, -48%) scale(0.96);
|
|
44
38
|
}
|
|
45
|
-
|
|
46
39
|
.popup[data-ending-style] {
|
|
47
40
|
opacity: 0;
|
|
48
41
|
transform: translate(-50%, -50%) scale(0.98);
|
|
@@ -50,30 +43,26 @@
|
|
|
50
43
|
opacity 150ms var(--easing-ease-in),
|
|
51
44
|
transform 150ms var(--easing-ease-in);
|
|
52
45
|
}
|
|
53
|
-
|
|
54
46
|
.header {
|
|
55
47
|
display: flex;
|
|
56
48
|
flex-direction: column;
|
|
57
|
-
gap: var(--space-
|
|
49
|
+
gap: var(--space-2);
|
|
50
|
+
text-align: center;
|
|
58
51
|
}
|
|
59
|
-
|
|
60
52
|
.title {
|
|
61
|
-
font-family: var(--font-
|
|
53
|
+
font-family: var(--font-sans);
|
|
62
54
|
font-size: var(--font-size-lg);
|
|
63
|
-
font-weight: var(--font-weight-
|
|
64
|
-
color: var(--color-
|
|
55
|
+
font-weight: var(--font-weight-bold);
|
|
56
|
+
color: var(--color-primary);
|
|
65
57
|
line-height: var(--line-height-tight);
|
|
66
58
|
letter-spacing: var(--letter-spacing-tight);
|
|
67
|
-
padding-right: var(--space-6);
|
|
68
59
|
}
|
|
69
|
-
|
|
70
60
|
.description {
|
|
71
|
-
font-family: var(--font-
|
|
72
|
-
font-size: var(--font-size-
|
|
73
|
-
color: var(--color-
|
|
61
|
+
font-family: var(--font-sans);
|
|
62
|
+
font-size: var(--font-size-md);
|
|
63
|
+
color: var(--color-secondary);
|
|
74
64
|
line-height: var(--line-height-relaxed);
|
|
75
65
|
}
|
|
76
|
-
|
|
77
66
|
.close {
|
|
78
67
|
position: absolute;
|
|
79
68
|
top: var(--space-4);
|
|
@@ -83,7 +72,7 @@
|
|
|
83
72
|
border-radius: var(--radius-sm);
|
|
84
73
|
border: none;
|
|
85
74
|
background: transparent;
|
|
86
|
-
color: var(--color-
|
|
75
|
+
color: var(--color-tertiary);
|
|
87
76
|
cursor: pointer;
|
|
88
77
|
display: flex;
|
|
89
78
|
align-items: center;
|
|
@@ -93,31 +82,35 @@
|
|
|
93
82
|
background-color var(--duration-fast) var(--easing-standard),
|
|
94
83
|
color var(--duration-fast) var(--easing-standard);
|
|
95
84
|
}
|
|
96
|
-
|
|
97
85
|
.close:hover {
|
|
98
|
-
background-color: var(--color-
|
|
99
|
-
color: var(--color-
|
|
86
|
+
background-color: var(--color-hover);
|
|
87
|
+
color: var(--color-primary);
|
|
100
88
|
}
|
|
101
|
-
|
|
102
89
|
.close:focus-visible {
|
|
103
90
|
box-shadow: var(--shadow-focus);
|
|
104
91
|
}
|
|
105
|
-
|
|
106
92
|
.body {
|
|
107
93
|
flex: 1;
|
|
108
94
|
overflow-y: auto;
|
|
109
95
|
font-family: var(--font-mono);
|
|
110
96
|
font-size: var(--font-size-sm);
|
|
111
|
-
color: var(--color-
|
|
97
|
+
color: var(--color-secondary);
|
|
112
98
|
line-height: var(--line-height-relaxed);
|
|
113
99
|
}
|
|
114
|
-
|
|
115
100
|
.footer {
|
|
116
101
|
display: flex;
|
|
117
102
|
align-items: center;
|
|
118
103
|
justify-content: flex-end;
|
|
119
104
|
gap: var(--space-2);
|
|
120
105
|
padding-top: var(--space-2);
|
|
121
|
-
|
|
106
|
+
}
|
|
107
|
+
/* When a footerStart slot is present, space-between pushes it left */
|
|
108
|
+
.footer-split {
|
|
109
|
+
justify-content: space-between;
|
|
110
|
+
}
|
|
111
|
+
.footer-end {
|
|
112
|
+
display: flex;
|
|
113
|
+
align-items: center;
|
|
114
|
+
gap: var(--space-2);
|
|
122
115
|
}
|
|
123
116
|
}
|
package/src/dialog/dialog.tsx
CHANGED
|
@@ -11,7 +11,14 @@ export interface DialogProps {
|
|
|
11
11
|
title?: ReactNode;
|
|
12
12
|
description?: ReactNode;
|
|
13
13
|
children?: ReactNode;
|
|
14
|
+
/** Buttons aligned to the right (cancel, confirm). */
|
|
14
15
|
footer?: ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Content anchored to the left of the footer — intended for a destructive
|
|
18
|
+
* action (e.g. Delete). When present the footer switches to space-between
|
|
19
|
+
* layout, matching the macOS dialog pattern.
|
|
20
|
+
*/
|
|
21
|
+
footerStart?: ReactNode;
|
|
15
22
|
className?: string;
|
|
16
23
|
dismissible?: boolean;
|
|
17
24
|
}
|
|
@@ -30,6 +37,7 @@ export function Dialog({
|
|
|
30
37
|
description,
|
|
31
38
|
children,
|
|
32
39
|
footer,
|
|
40
|
+
footerStart,
|
|
33
41
|
className,
|
|
34
42
|
dismissible = true,
|
|
35
43
|
onOpenChange,
|
|
@@ -50,7 +58,12 @@ export function Dialog({
|
|
|
50
58
|
</BaseDialog.Close>
|
|
51
59
|
)}
|
|
52
60
|
{children && <div className={styles.body}>{children}</div>}
|
|
53
|
-
{footer &&
|
|
61
|
+
{(footer || footerStart) && (
|
|
62
|
+
<div className={`${styles.footer} ${footerStart ? styles["footer-split"] : ""}`}>
|
|
63
|
+
{footerStart && <div>{footerStart}</div>}
|
|
64
|
+
{footer && <div className={styles["footer-end"]}>{footer}</div>}
|
|
65
|
+
</div>
|
|
66
|
+
)}
|
|
54
67
|
</BaseDialog.Popup>
|
|
55
68
|
</BaseDialog.Viewport>
|
|
56
69
|
</BaseDialog.Portal>
|