@ctrl-ui/react 0.8.1 → 0.8.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/dist/email/email.js +12 -3
- package/dist/email/length.d.ts +4 -0
- package/dist/email/length.js +34 -0
- package/dist/email/templates.js +5 -5
- package/dist/email/theme.d.ts +12 -0
- package/dist/email/theme.js +21 -6
- package/dist/styles/index.css +1 -0
- package/dist/styles/recipes/sidebar-menu.css +156 -0
- package/dist/styles/recipes/sidebar.css +0 -93
- package/dist/ui/color-picker.js +1 -1
- package/dist/ui/combobox.d.ts +2 -0
- package/dist/ui/dropdown-menu.d.ts +26 -18
- package/dist/ui/dropdown-menu.js +111 -6
- package/dist/ui/sidebar-menu.d.ts +11 -1
- package/dist/ui/sidebar-menu.js +26 -1
- package/dist/ui/sidebar.d.ts +2 -2
- package/dist/ui/sidebar.js +2 -2
- package/package.json +1 -1
package/dist/email/email.js
CHANGED
|
@@ -6,11 +6,20 @@ function tailwindTheme(theme) {
|
|
|
6
6
|
presets: [pixelBasedPreset],
|
|
7
7
|
theme: { extend: {
|
|
8
8
|
colors: theme.colors,
|
|
9
|
+
borderRadius: theme.radii,
|
|
10
|
+
minHeight: { control: theme.button.height },
|
|
11
|
+
padding: {
|
|
12
|
+
"control-x": theme.button.paddingInline,
|
|
13
|
+
"control-y": theme.button.paddingBlock
|
|
14
|
+
},
|
|
9
15
|
fontFamily: {
|
|
10
16
|
body: theme.fonts.body,
|
|
11
17
|
display: theme.fonts.display
|
|
12
18
|
},
|
|
13
|
-
fontSize:
|
|
19
|
+
fontSize: {
|
|
20
|
+
...Object.fromEntries(Object.entries(theme.text).map(([name, { fontSize, ...options }]) => [name, [fontSize, options]])),
|
|
21
|
+
control: [theme.button.fontSize, { lineHeight: theme.button.lineHeight }]
|
|
22
|
+
}
|
|
14
23
|
} }
|
|
15
24
|
};
|
|
16
25
|
}
|
|
@@ -23,7 +32,7 @@ function EmailLayout({ theme, preview, children, head, lang = "en", dir = "ltr"
|
|
|
23
32
|
children: [/* @__PURE__ */ jsx(Head, { children: head }), /* @__PURE__ */ jsxs(Body, {
|
|
24
33
|
className: "m-0 bg-background p-4 font-body text-body text-foreground",
|
|
25
34
|
children: [/* @__PURE__ */ jsx(Preview, { children: preview }), /* @__PURE__ */ jsx(Container, {
|
|
26
|
-
className: "mx-auto w-full max-w-[600px] bg-card p-6 text-card-foreground",
|
|
35
|
+
className: "mx-auto w-full max-w-[600px] rounded-panel bg-card p-6 text-card-foreground",
|
|
27
36
|
children
|
|
28
37
|
})]
|
|
29
38
|
})]
|
|
@@ -57,7 +66,7 @@ function EmailText({ tone = "default", className = "", style, ...props }) {
|
|
|
57
66
|
function EmailButton({ className = "", ...props }) {
|
|
58
67
|
return /* @__PURE__ */ jsx(Button, {
|
|
59
68
|
...props,
|
|
60
|
-
className: `box-border bg-primary px-
|
|
69
|
+
className: `box-border min-h-control rounded-control bg-primary px-control-x py-control-y text-center font-body text-control font-medium text-primary-foreground no-underline ${className}`
|
|
61
70
|
});
|
|
62
71
|
}
|
|
63
72
|
function EmailLink({ className = "", ...props }) {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/email/length.ts
|
|
2
|
+
function parseLengthQuantity(value, rootFontSize) {
|
|
3
|
+
const match = /^(-?\d*\.?\d+)(px|rem)?$/.exec(value.trim());
|
|
4
|
+
if (!match) return null;
|
|
5
|
+
return {
|
|
6
|
+
amount: Number(match[1]) * (match[2] === "rem" ? rootFontSize : 1),
|
|
7
|
+
unit: match[2] ? "px" : ""
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function calculateLengthExpression(expression, rootFontSize) {
|
|
11
|
+
const match = /^\s*(-?\d*\.?\d+(?:px|rem)?)\s*([+*/-])\s*(-?\d*\.?\d+(?:px|rem)?)\s*$/.exec(expression);
|
|
12
|
+
if (!match) return null;
|
|
13
|
+
const left = parseLengthQuantity(match[1], rootFontSize);
|
|
14
|
+
const right = parseLengthQuantity(match[3], rootFontSize);
|
|
15
|
+
if (!left || !right) return null;
|
|
16
|
+
const operator = match[2];
|
|
17
|
+
if ((operator === "+" || operator === "-") && left.unit === right.unit) return `${left.amount + (operator === "+" ? right.amount : -right.amount)}${left.unit}`;
|
|
18
|
+
if (operator === "*" && !(left.unit && right.unit)) return `${left.amount * right.amount}${left.unit || right.unit}`;
|
|
19
|
+
if (operator === "/" && !right.unit && right.amount !== 0) return `${left.amount / right.amount}${left.unit}`;
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
function emailLengthPixels(name, value, rootFontSize, allowZero = false) {
|
|
23
|
+
let resolved = value;
|
|
24
|
+
for (let depth = 0; depth < 16 && resolved.includes("calc("); depth++) {
|
|
25
|
+
const simplified = resolved.replace(/calc\(([^()]*)\)/g, (original, expression) => calculateLengthExpression(expression, rootFontSize) ?? original);
|
|
26
|
+
if (simplified === resolved) break;
|
|
27
|
+
resolved = simplified;
|
|
28
|
+
}
|
|
29
|
+
const result = parseLengthQuantity(resolved, rootFontSize);
|
|
30
|
+
if (!(result && (result.unit === "px" || result.amount === 0) && Number.isFinite(result.amount) && (allowZero ? result.amount >= 0 : result.amount > 0))) throw new Error(`Email theme: ${name} must resolve to a ${allowZero ? "non-negative" : "positive"} px/rem length, received ${value}.`);
|
|
31
|
+
return result.amount;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { emailLengthPixels };
|
package/dist/email/templates.js
CHANGED
|
@@ -35,7 +35,7 @@ function InvitationEmail({ theme, brand, footer, inviter, workspace, inviteUrl }
|
|
|
35
35
|
". Bring your work, share a little inspiration, and make something together."
|
|
36
36
|
] }),
|
|
37
37
|
/* @__PURE__ */ jsxs(Section, {
|
|
38
|
-
className: "my-6 bg-muted p-5",
|
|
38
|
+
className: "my-6 rounded-panel bg-muted p-5",
|
|
39
39
|
children: [/* @__PURE__ */ jsx(EmailHeading, {
|
|
40
40
|
as: "h3",
|
|
41
41
|
children: "Your team is waiting"
|
|
@@ -69,7 +69,7 @@ function ProductEmail({ theme, brand, footer, title, description, imageUrl, imag
|
|
|
69
69
|
src: imageUrl,
|
|
70
70
|
alt: imageAlt,
|
|
71
71
|
width: "552",
|
|
72
|
-
className: "mb-6 block h-auto w-full"
|
|
72
|
+
className: "mb-6 block h-auto w-full rounded-scene"
|
|
73
73
|
}),
|
|
74
74
|
/* @__PURE__ */ jsx(EmailHeading, { children: title }),
|
|
75
75
|
/* @__PURE__ */ jsx(EmailText, { children: description }),
|
|
@@ -102,7 +102,7 @@ function EditorialEmail({ theme, brand, footer, title, description, imageUrl, im
|
|
|
102
102
|
src: imageUrl,
|
|
103
103
|
alt: imageAlt,
|
|
104
104
|
width: "198",
|
|
105
|
-
className: "block h-auto w-full"
|
|
105
|
+
className: "block h-auto w-full rounded-scene"
|
|
106
106
|
})
|
|
107
107
|
}), /* @__PURE__ */ jsxs(Column, {
|
|
108
108
|
width: "64%",
|
|
@@ -148,7 +148,7 @@ function NewsletterEmail({ theme, brand, footer, articles, unsubscribeUrl }) {
|
|
|
148
148
|
src: article.imageUrl,
|
|
149
149
|
alt: article.imageAlt,
|
|
150
150
|
width: "552",
|
|
151
|
-
className: "mb-4 block h-auto w-full"
|
|
151
|
+
className: "mb-4 block h-auto w-full rounded-scene"
|
|
152
152
|
}),
|
|
153
153
|
/* @__PURE__ */ jsx(EmailHeading, {
|
|
154
154
|
as: "h2",
|
|
@@ -190,7 +190,7 @@ function SummaryEmail({ theme, brand, footer, period, metrics, details, dashboar
|
|
|
190
190
|
/* @__PURE__ */ jsx(EmailHeading, { children: "Good work adds up." }),
|
|
191
191
|
/* @__PURE__ */ jsx(EmailText, { children: "Here’s what your team moved forward this week." }),
|
|
192
192
|
/* @__PURE__ */ jsx(Section, {
|
|
193
|
-
className: "my-6 bg-muted p-4",
|
|
193
|
+
className: "my-6 rounded-panel bg-muted p-4",
|
|
194
194
|
children: /* @__PURE__ */ jsx(Row, {
|
|
195
195
|
className: "table-fixed",
|
|
196
196
|
children: metrics.map((metric) => /* @__PURE__ */ jsxs(Column, {
|
package/dist/email/theme.d.ts
CHANGED
|
@@ -15,6 +15,18 @@ type EmailTheme = {
|
|
|
15
15
|
body: string;
|
|
16
16
|
display: string;
|
|
17
17
|
};
|
|
18
|
+
radii: {
|
|
19
|
+
control: string;
|
|
20
|
+
panel: string;
|
|
21
|
+
scene: string;
|
|
22
|
+
};
|
|
23
|
+
button: {
|
|
24
|
+
height: string;
|
|
25
|
+
paddingInline: string;
|
|
26
|
+
paddingBlock: string;
|
|
27
|
+
fontSize: string;
|
|
28
|
+
lineHeight: string;
|
|
29
|
+
};
|
|
18
30
|
text: Record<EmailHeadingSize | "body" | "caption", EmailTypeStyle>;
|
|
19
31
|
};
|
|
20
32
|
declare function createEmailTheme(tokens: ReadonlyMap<string, string>, rootFontSize?: number): EmailTheme;
|
package/dist/email/theme.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { emailLengthPixels } from "./length.js";
|
|
1
2
|
import { composite, resolveColor, tokenMaps } from "../scripts/contrast-eval.js";
|
|
2
3
|
//#region src/email/theme.ts
|
|
3
4
|
function resolveVariables(value, tokens, chain = []) {
|
|
@@ -17,12 +18,7 @@ function tokenValue(name, tokens, fallback) {
|
|
|
17
18
|
return resolved;
|
|
18
19
|
}
|
|
19
20
|
function pixelSize(name, tokens, rootFontSize) {
|
|
20
|
-
|
|
21
|
-
const match = /^(\d*\.?\d+)(px|rem)$/.exec(value);
|
|
22
|
-
if (!match) throw new Error(`Email theme: ${name} must resolve to px or rem, received ${value}.`);
|
|
23
|
-
const pixels = Number(match[1]) * (match[2] === "rem" ? rootFontSize : 1);
|
|
24
|
-
if (pixels <= 0) throw new Error(`Email theme: ${name} must be positive.`);
|
|
25
|
-
return `${pixels}px`;
|
|
21
|
+
return `${emailLengthPixels(name, tokenValue(name, tokens), rootFontSize)}px`;
|
|
26
22
|
}
|
|
27
23
|
function numericStyle(name, tokens, fallback) {
|
|
28
24
|
const value = tokenValue(name, tokens, fallback);
|
|
@@ -31,6 +27,13 @@ function numericStyle(name, tokens, fallback) {
|
|
|
31
27
|
}
|
|
32
28
|
function createEmailTheme(tokens, rootFontSize = 16) {
|
|
33
29
|
if (!Number.isFinite(rootFontSize) || rootFontSize <= 0) throw new Error("Email theme: rootFontSize must be a positive pixel value.");
|
|
30
|
+
function lengthPixels(name, allowZero = false) {
|
|
31
|
+
return emailLengthPixels(name, tokenValue(name, tokens), rootFontSize, allowZero);
|
|
32
|
+
}
|
|
33
|
+
const buttonHeight = lengthPixels("--control-h-md");
|
|
34
|
+
const buttonFontSize = lengthPixels("--text-body");
|
|
35
|
+
const reactEmailButtonLineHeight = buttonFontSize * 1.2;
|
|
36
|
+
const buttonPaddingBlock = Math.max(0, (buttonHeight - reactEmailButtonLineHeight) / 2);
|
|
34
37
|
function color(name) {
|
|
35
38
|
const result = resolveColor(`var(--${name})`, tokens);
|
|
36
39
|
if ("unresolved" in result) throw new Error(`Email theme: --${name}: ${result.unresolved}.`);
|
|
@@ -71,6 +74,18 @@ function createEmailTheme(tokens, rootFontSize = 16) {
|
|
|
71
74
|
body: tokenValue("--font-body", tokens),
|
|
72
75
|
display: tokenValue("--font-display", tokens)
|
|
73
76
|
},
|
|
77
|
+
radii: {
|
|
78
|
+
control: `${lengthPixels("--radius-control", true)}px`,
|
|
79
|
+
panel: `${lengthPixels("--radius-panel", true)}px`,
|
|
80
|
+
scene: `${lengthPixels("--radius-scene", true)}px`
|
|
81
|
+
},
|
|
82
|
+
button: {
|
|
83
|
+
height: `${buttonHeight}px`,
|
|
84
|
+
paddingInline: `${lengthPixels("--padding-x", true)}px`,
|
|
85
|
+
paddingBlock: `${buttonPaddingBlock}px`,
|
|
86
|
+
fontSize: `${buttonFontSize}px`,
|
|
87
|
+
lineHeight: `${reactEmailButtonLineHeight}px`
|
|
88
|
+
},
|
|
74
89
|
text: {
|
|
75
90
|
body: {
|
|
76
91
|
fontSize: pixelSize("--text-body-lg", tokens, rootFontSize),
|
package/dist/styles/index.css
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
@import "./recipes/code-block-editor.css";
|
|
34
34
|
@import "./recipes/code-diff.css";
|
|
35
35
|
@import "./recipes/sidebar.css";
|
|
36
|
+
@import "./recipes/sidebar-menu.css";
|
|
36
37
|
@import "./recipes/color-picker.css";
|
|
37
38
|
@import "./recipes/color-picker-details.css";
|
|
38
39
|
@import "./recipes/color-picker-values.css";
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
:where([data-control-family="sidebar"][data-slot="group-label"]) {
|
|
3
|
+
gap: calc(var(--spacing) * 2);
|
|
4
|
+
padding-inline: calc(var(--spacing) * 2);
|
|
5
|
+
border-radius: var(--radius-md);
|
|
6
|
+
color: var(--cui-sidebar-group-label-foreground);
|
|
7
|
+
font-size: var(--text-caption);
|
|
8
|
+
font-weight: var(--font-weight-medium);
|
|
9
|
+
outline: none;
|
|
10
|
+
transition-property: margin, opacity;
|
|
11
|
+
transition-duration: var(--duration-base);
|
|
12
|
+
transition-timing-function: var(--ease-standard);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"]),
|
|
16
|
+
:where([data-control-family="sidebar"][data-slot="menu-action"]) {
|
|
17
|
+
gap: calc(var(--spacing) * 1.5);
|
|
18
|
+
block-size: var(--control-h-md);
|
|
19
|
+
border-radius: var(--cui-sidebar-menu-button-radius);
|
|
20
|
+
padding-inline: var(--padding-x);
|
|
21
|
+
font-size: var(--text-body);
|
|
22
|
+
background-color: transparent;
|
|
23
|
+
color: var(--cui-sidebar-menu-button-foreground);
|
|
24
|
+
outline: none;
|
|
25
|
+
transition-property: width, height, padding, color, background-color, box-shadow;
|
|
26
|
+
transition-duration: var(--duration-base);
|
|
27
|
+
transition-timing-function: var(--ease-standard);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-size="sm"]) {
|
|
31
|
+
block-size: var(--control-h-sm);
|
|
32
|
+
padding-inline: calc(var(--padding-x) * 0.75);
|
|
33
|
+
font-size: var(--text-label);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-size="lg"]) {
|
|
37
|
+
gap: calc(var(--spacing) * 2);
|
|
38
|
+
block-size: var(--control-h-lg);
|
|
39
|
+
padding-inline: calc(var(--padding-x) * 1.25);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@media (hover: hover) {
|
|
43
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"]:hover),
|
|
44
|
+
:where([data-control-family="sidebar"][data-slot="menu-action"]:hover) {
|
|
45
|
+
background-color: var(--cui-sidebar-menu-button-hover-background);
|
|
46
|
+
color: var(--cui-sidebar-menu-button-hover-foreground);
|
|
47
|
+
box-shadow: var(--cui-sidebar-menu-button-hover-shadow);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-state="open"]:hover) {
|
|
51
|
+
background-color: var(--cui-sidebar-menu-button-active-background);
|
|
52
|
+
color: var(--cui-sidebar-menu-button-active-foreground);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
:where([data-control-family="sidebar"][data-slot="menu-action"]:is(:active, [data-popup-open])),
|
|
57
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"]:active),
|
|
58
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-active]) {
|
|
59
|
+
background-color: var(--cui-sidebar-menu-button-active-background);
|
|
60
|
+
color: var(--cui-sidebar-menu-button-active-foreground);
|
|
61
|
+
box-shadow: var(--cui-sidebar-menu-button-active-shadow);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-active]) {
|
|
65
|
+
font-weight: var(--font-weight-medium);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-variant="outline"]) {
|
|
69
|
+
background-color: var(--background);
|
|
70
|
+
box-shadow: 0 0 0 1px var(--sidebar-border);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@media (hover: hover) {
|
|
74
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-variant="outline"]:hover) {
|
|
75
|
+
box-shadow: 0 0 0 1px oklch(from var(--foreground) l c h / 0.08);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
:where(
|
|
80
|
+
[data-control-family="sidebar"][data-indicator="slide"]
|
|
81
|
+
[data-control-family="sidebar"][data-slot="menu-button"]:is(:hover, :active, [data-active], [data-popup-open])
|
|
82
|
+
) {
|
|
83
|
+
background-color: transparent;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@media (hover: hover) {
|
|
87
|
+
:where([data-control-family="sidebar"][data-indicator="hover"] [data-slot="menu-button"]:hover:not([data-active])) {
|
|
88
|
+
background-color: transparent;
|
|
89
|
+
box-shadow: none;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
:where([data-control-family="sidebar"][data-slot="menu-action"]:is(:disabled, [aria-disabled="true"])),
|
|
94
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"]:disabled),
|
|
95
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][aria-disabled="true"]) {
|
|
96
|
+
opacity: 0.5;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
:where([data-control-family="sidebar"][data-slot="group-content"]) {
|
|
100
|
+
font-size: var(--text-body);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
:where([data-control-family="sidebar"][data-slot="menu-action"]) {
|
|
104
|
+
inset-block-start: calc(var(--control-h-md) / 2);
|
|
105
|
+
padding: 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-size="sm"] ~ [data-slot="menu-action"]) {
|
|
109
|
+
inset-block-start: calc(var(--control-h-sm) / 2);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-size="lg"] ~ [data-slot="menu-action"]) {
|
|
113
|
+
inset-block-start: calc(var(--control-h-lg) / 2);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"]:has(~ [data-slot="menu-action"])) {
|
|
117
|
+
padding-inline-end: calc(var(--spacing) * 8);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
:where([data-control-family="sidebar"][data-slot="menu-action"]:focus-visible) {
|
|
121
|
+
outline: 2px solid var(--sidebar-ring);
|
|
122
|
+
outline-offset: 2px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@media (hover: hover) and (pointer: fine) {
|
|
126
|
+
:where([data-control-family="sidebar"][data-slot="menu-action"][data-show-on-hover]) {
|
|
127
|
+
opacity: 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
:where([data-control-family="sidebar"][data-slot="menu-item"]:is(:hover, :focus-within) [data-slot="menu-action"]),
|
|
131
|
+
:where([data-control-family="sidebar"][data-slot="menu-action"][data-popup-open]) {
|
|
132
|
+
opacity: 1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@media (pointer: coarse) {
|
|
137
|
+
:where([data-control-family="sidebar"][data-slot="menu-action"]) {
|
|
138
|
+
min-inline-size: 44px;
|
|
139
|
+
min-block-size: 44px;
|
|
140
|
+
inset-inline-end: 0;
|
|
141
|
+
inset-block-start: max(22px, calc(var(--control-h-md) / 2));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-size="sm"] ~ [data-slot="menu-action"]) {
|
|
145
|
+
inset-block-start: max(22px, calc(var(--control-h-sm) / 2));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"][data-size="lg"] ~ [data-slot="menu-action"]) {
|
|
149
|
+
inset-block-start: max(22px, calc(var(--control-h-lg) / 2));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
:where([data-control-family="sidebar"][data-slot="menu-button"]:has(~ [data-slot="menu-action"])) {
|
|
153
|
+
padding-inline-end: calc(var(--spacing) * 12);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -176,99 +176,6 @@
|
|
|
176
176
|
--cui-track-highlight-radius: var(--cui-sidebar-menu-button-radius);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
:where([data-control-family="sidebar"][data-slot="group-label"]) {
|
|
180
|
-
gap: calc(var(--spacing) * 2);
|
|
181
|
-
padding-inline: calc(var(--spacing) * 2);
|
|
182
|
-
border-radius: var(--radius-md);
|
|
183
|
-
color: var(--cui-sidebar-group-label-foreground);
|
|
184
|
-
font-size: var(--text-caption);
|
|
185
|
-
font-weight: var(--font-weight-medium);
|
|
186
|
-
outline: none;
|
|
187
|
-
transition-property: margin, opacity;
|
|
188
|
-
transition-duration: var(--duration-base);
|
|
189
|
-
transition-timing-function: var(--ease-standard);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"]) {
|
|
193
|
-
gap: calc(var(--spacing) * 1.5);
|
|
194
|
-
block-size: var(--control-h-md);
|
|
195
|
-
border-radius: var(--cui-sidebar-menu-button-radius);
|
|
196
|
-
padding-inline: var(--padding-x);
|
|
197
|
-
font-size: var(--text-body);
|
|
198
|
-
background-color: transparent;
|
|
199
|
-
color: var(--cui-sidebar-menu-button-foreground);
|
|
200
|
-
outline: none;
|
|
201
|
-
transition-property: width, height, padding, color, background-color, box-shadow;
|
|
202
|
-
transition-duration: var(--duration-base);
|
|
203
|
-
transition-timing-function: var(--ease-standard);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"][data-size="sm"]) {
|
|
207
|
-
block-size: var(--control-h-sm);
|
|
208
|
-
padding-inline: calc(var(--padding-x) * 0.75);
|
|
209
|
-
font-size: var(--text-label);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"][data-size="lg"]) {
|
|
213
|
-
gap: calc(var(--spacing) * 2);
|
|
214
|
-
block-size: var(--control-h-lg);
|
|
215
|
-
padding-inline: calc(var(--padding-x) * 1.25);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
@media (hover: hover) {
|
|
219
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"]:hover) {
|
|
220
|
-
background-color: var(--cui-sidebar-menu-button-hover-background);
|
|
221
|
-
color: var(--cui-sidebar-menu-button-hover-foreground);
|
|
222
|
-
box-shadow: var(--cui-sidebar-menu-button-hover-shadow);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"][data-state="open"]:hover) {
|
|
226
|
-
background-color: var(--cui-sidebar-menu-button-active-background);
|
|
227
|
-
color: var(--cui-sidebar-menu-button-active-foreground);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"]:active),
|
|
232
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"][data-active]) {
|
|
233
|
-
background-color: var(--cui-sidebar-menu-button-active-background);
|
|
234
|
-
color: var(--cui-sidebar-menu-button-active-foreground);
|
|
235
|
-
box-shadow: var(--cui-sidebar-menu-button-active-shadow);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"][data-active]) {
|
|
239
|
-
font-weight: var(--font-weight-medium);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"][data-variant="outline"]) {
|
|
243
|
-
background-color: var(--background);
|
|
244
|
-
box-shadow: 0 0 0 1px var(--sidebar-border);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
@media (hover: hover) {
|
|
248
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"][data-variant="outline"]:hover) {
|
|
249
|
-
box-shadow: 0 0 0 1px oklch(from var(--foreground) l c h / 0.08);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
:where(
|
|
254
|
-
[data-control-family="sidebar"][data-indicator="slide"]
|
|
255
|
-
[data-control-family="sidebar"][data-slot="menu-button"]:is(:hover, :active, [data-active], [data-popup-open])
|
|
256
|
-
) {
|
|
257
|
-
background-color: transparent;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
@media (hover: hover) {
|
|
261
|
-
:where([data-control-family="sidebar"][data-indicator="hover"] [data-slot="menu-button"]:hover:not([data-active])) {
|
|
262
|
-
background-color: transparent;
|
|
263
|
-
box-shadow: none;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"]:disabled),
|
|
268
|
-
:where([data-control-family="sidebar"][data-slot="menu-button"][aria-disabled="true"]) {
|
|
269
|
-
opacity: 0.5;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
179
|
:where([data-control-family="sidebar"][data-slot="root"][data-side="right"] [data-control-family="sidebar"][data-slot="gap"]) {
|
|
273
180
|
rotate: 180deg;
|
|
274
181
|
}
|
package/dist/ui/color-picker.js
CHANGED
|
@@ -3,9 +3,9 @@ import { cn } from "../lib/cn.js";
|
|
|
3
3
|
import { skinEffects, skinId } from "../skin.js";
|
|
4
4
|
import { Button } from "./button.js";
|
|
5
5
|
import { Input } from "./input.js";
|
|
6
|
-
import { useColorArea } from "../hooks/use-color-area.js";
|
|
7
6
|
import { formatColor, getChannels, hsvaToRgba, parseColor, pointToHueSat, pointToSaturationValue, setChannel } from "../lib/color.js";
|
|
8
7
|
import { TARGET_RATIO, contrastOf, fixColorForContrast, nextFixLevel, wcagLevels } from "../lib/contrast.js";
|
|
8
|
+
import { useColorArea } from "../hooks/use-color-area.js";
|
|
9
9
|
import { NumberField, NumberFieldGroup, NumberFieldInput } from "./number-field.js";
|
|
10
10
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select.js";
|
|
11
11
|
import { createContext, useContext, useEffect, useRef, useState, useSyncExternalStore } from "react";
|
package/dist/ui/combobox.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { ControlSize } from "../control-variants.js";
|
|
|
3
3
|
import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
|
|
4
4
|
import { FieldKnobStyle } from "../knob-contracts/field-knobs.js";
|
|
5
5
|
import { CSSProperties, ComponentProps, ReactNode } from "react";
|
|
6
|
+
import { Combobox as Combobox$1 } from "@base-ui/react/combobox";
|
|
6
7
|
//#region src/ui/combobox.d.ts
|
|
7
8
|
type ComboboxProps<Value = string> = {
|
|
8
9
|
children?: ReactNode;
|
|
@@ -23,6 +24,7 @@ type ComboboxProps<Value = string> = {
|
|
|
23
24
|
autoHighlight?: boolean;
|
|
24
25
|
itemToStringLabel?: (itemValue: Value) => string;
|
|
25
26
|
isItemEqualToValue?: (itemValue: Value, value: Value) => boolean;
|
|
27
|
+
filter?: Combobox$1.Root.Props<Value>["filter"];
|
|
26
28
|
};
|
|
27
29
|
type ComboboxInputProps = Omit<Omit<ComponentProps<"input">, "size">, "style"> & {
|
|
28
30
|
style?: CSSProperties & FieldKnobStyle;
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { OpenChangeEventDetails } from "../control-props.js";
|
|
2
1
|
import { ControlSize } from "../control-variants.js";
|
|
3
2
|
import { ButtonKnobStyle } from "../knob-contracts/button-knobs.js";
|
|
4
3
|
import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
|
|
5
|
-
import { CSSProperties, ComponentProps
|
|
4
|
+
import { CSSProperties, ComponentProps } from "react";
|
|
6
5
|
import { Menu } from "@base-ui/react/menu";
|
|
7
6
|
//#region src/ui/dropdown-menu.d.ts
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
defaultOpen?: boolean;
|
|
12
|
-
onOpenChange?: (open: boolean, eventDetails: OpenChangeEventDetails) => void;
|
|
7
|
+
type DropdownMenuStyledProps<PrimitiveProps> = Omit<PrimitiveProps, "className" | "style"> & {
|
|
8
|
+
className?: string;
|
|
9
|
+
style?: CSSProperties & PopupKnobStyle;
|
|
13
10
|
};
|
|
11
|
+
type DropdownMenuProps = Menu.Root.Props;
|
|
14
12
|
declare const dropdownMenuTriggerVariants: readonly ["surface", "ghost"];
|
|
15
13
|
type DropdownMenuTriggerVariant = (typeof dropdownMenuTriggerVariants)[number];
|
|
16
14
|
type DropdownMenuTriggerProps = Omit<ComponentProps<"button">, "style"> & Pick<ComponentProps<typeof Menu.Trigger>, "nativeButton" | "render"> & {
|
|
@@ -20,15 +18,16 @@ type DropdownMenuTriggerProps = Omit<ComponentProps<"button">, "style"> & Pick<C
|
|
|
20
18
|
iconOnly?: boolean;
|
|
21
19
|
variant?: DropdownMenuTriggerVariant;
|
|
22
20
|
};
|
|
23
|
-
type DropdownMenuContentProps =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
type
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
type DropdownMenuContentProps = DropdownMenuStyledProps<Menu.Popup.Props> & Pick<Menu.Positioner.Props, "side" | "sideOffset" | "align" | "alignOffset" | "collisionBoundary" | "collisionPadding" | "collisionAvoidance">;
|
|
22
|
+
type DropdownMenuItemProps = DropdownMenuStyledProps<Menu.Item.Props>;
|
|
23
|
+
type DropdownMenuGroupProps = DropdownMenuStyledProps<Menu.Group.Props>;
|
|
24
|
+
type DropdownMenuCheckboxItemProps = DropdownMenuStyledProps<Menu.CheckboxItem.Props>;
|
|
25
|
+
type DropdownMenuRadioGroupProps = DropdownMenuStyledProps<Menu.RadioGroup.Props>;
|
|
26
|
+
type DropdownMenuRadioItemProps = DropdownMenuStyledProps<Menu.RadioItem.Props>;
|
|
27
|
+
type DropdownMenuSubProps = Menu.SubmenuRoot.Props;
|
|
28
|
+
type DropdownMenuSubTriggerProps = DropdownMenuStyledProps<Menu.SubmenuTrigger.Props>;
|
|
29
|
+
type DropdownMenuSubContentProps = DropdownMenuContentProps;
|
|
30
|
+
type DropdownMenuShortcutProps = DropdownMenuStyledProps<ComponentProps<"span">>;
|
|
32
31
|
type DropdownMenuSeparatorProps = Omit<ComponentProps<"div">, "style"> & {
|
|
33
32
|
style?: CSSProperties & PopupKnobStyle;
|
|
34
33
|
};
|
|
@@ -37,9 +36,18 @@ type DropdownMenuLabelProps = Omit<ComponentProps<"div">, "style"> & {
|
|
|
37
36
|
};
|
|
38
37
|
declare function DropdownMenu({ children, ...props }: DropdownMenuProps): import("react").JSX.Element;
|
|
39
38
|
declare function DropdownMenuTrigger({ size, iconOnly, variant, className, children, disabled, ...props }: DropdownMenuTriggerProps): import("react").JSX.Element;
|
|
40
|
-
declare function DropdownMenuContent({ className, children, ...props }: DropdownMenuContentProps): import("react").JSX.Element;
|
|
39
|
+
declare function DropdownMenuContent({ className, children, side, sideOffset, align, alignOffset, collisionBoundary, collisionPadding, collisionAvoidance, ...props }: DropdownMenuContentProps): import("react").JSX.Element;
|
|
41
40
|
declare function DropdownMenuItem({ className, ...props }: DropdownMenuItemProps): import("react").JSX.Element;
|
|
42
41
|
declare function DropdownMenuSeparator({ className, ...props }: DropdownMenuSeparatorProps): import("react").JSX.Element;
|
|
43
42
|
declare function DropdownMenuLabel({ className, ...props }: DropdownMenuLabelProps): import("react").JSX.Element;
|
|
43
|
+
declare function DropdownMenuPortal(props: Menu.Portal.Props): import("react").JSX.Element;
|
|
44
|
+
declare function DropdownMenuGroup(props: DropdownMenuGroupProps): import("react").JSX.Element;
|
|
45
|
+
declare function DropdownMenuCheckboxItem({ className, children, ...props }: DropdownMenuCheckboxItemProps): import("react").JSX.Element;
|
|
46
|
+
declare function DropdownMenuRadioGroup(props: DropdownMenuRadioGroupProps): import("react").JSX.Element;
|
|
47
|
+
declare function DropdownMenuRadioItem({ className, children, ...props }: DropdownMenuRadioItemProps): import("react").JSX.Element;
|
|
48
|
+
declare function DropdownMenuSub(props: DropdownMenuSubProps): import("react").JSX.Element;
|
|
49
|
+
declare function DropdownMenuSubTrigger({ className, children, ...props }: DropdownMenuSubTriggerProps): import("react").JSX.Element;
|
|
50
|
+
declare function DropdownMenuSubContent(props: DropdownMenuSubContentProps): import("react").JSX.Element;
|
|
51
|
+
declare function DropdownMenuShortcut(props: DropdownMenuShortcutProps): import("react").JSX.Element;
|
|
44
52
|
//#endregion
|
|
45
|
-
export { DropdownMenu, DropdownMenuContent, DropdownMenuContentProps, DropdownMenuItem, DropdownMenuItemProps, DropdownMenuLabel, DropdownMenuLabelProps, DropdownMenuProps, DropdownMenuSeparator, DropdownMenuSeparatorProps, DropdownMenuTrigger, DropdownMenuTriggerProps, DropdownMenuTriggerVariant, dropdownMenuTriggerVariants };
|
|
53
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuCheckboxItemProps, DropdownMenuContent, DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuGroupProps, DropdownMenuItem, DropdownMenuItemProps, DropdownMenuLabel, DropdownMenuLabelProps, DropdownMenuPortal, DropdownMenuProps, DropdownMenuRadioGroup, DropdownMenuRadioGroupProps, DropdownMenuRadioItem, DropdownMenuRadioItemProps, DropdownMenuSeparator, DropdownMenuSeparatorProps, DropdownMenuShortcut, DropdownMenuShortcutProps, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubContentProps, DropdownMenuSubProps, DropdownMenuSubTrigger, DropdownMenuSubTriggerProps, DropdownMenuTrigger, DropdownMenuTriggerProps, DropdownMenuTriggerVariant, dropdownMenuTriggerVariants };
|
package/dist/ui/dropdown-menu.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { skinEffects, skinId } from "../skin.js";
|
|
4
4
|
import { popupItemStructureClasses } from "../surface-variants.js";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { Menu } from "@base-ui/react/menu";
|
|
7
7
|
//#region src/ui/dropdown-menu.tsx
|
|
8
8
|
const dropdownMenuTriggerVariants = ["surface", "ghost"];
|
|
@@ -29,13 +29,17 @@ function DropdownMenuTrigger({ size = "sm", iconOnly = false, variant = "surface
|
|
|
29
29
|
children
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
-
function DropdownMenuContent({ className, children, ...props }) {
|
|
32
|
+
function DropdownMenuContent({ className, children, side = "bottom", sideOffset = 6, align = "start", alignOffset, collisionBoundary, collisionPadding, collisionAvoidance, ...props }) {
|
|
33
33
|
return /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
|
|
34
34
|
"data-skin": skinId(),
|
|
35
35
|
"data-effects": skinEffects(),
|
|
36
|
-
side
|
|
37
|
-
align
|
|
38
|
-
sideOffset
|
|
36
|
+
side,
|
|
37
|
+
align,
|
|
38
|
+
sideOffset,
|
|
39
|
+
alignOffset,
|
|
40
|
+
collisionBoundary,
|
|
41
|
+
collisionPadding,
|
|
42
|
+
collisionAvoidance,
|
|
39
43
|
className: "z-[80]",
|
|
40
44
|
children: /* @__PURE__ */ jsx(Menu.Popup, {
|
|
41
45
|
"data-control-ui": "dropdown-menu",
|
|
@@ -79,5 +83,106 @@ function DropdownMenuLabel({ className, ...props }) {
|
|
|
79
83
|
...props
|
|
80
84
|
});
|
|
81
85
|
}
|
|
86
|
+
function DropdownMenuPortal(props) {
|
|
87
|
+
return /* @__PURE__ */ jsx(Menu.Portal, { ...props });
|
|
88
|
+
}
|
|
89
|
+
function DropdownMenuGroup(props) {
|
|
90
|
+
return /* @__PURE__ */ jsx(Menu.Group, {
|
|
91
|
+
"data-control-ui": "dropdown-menu",
|
|
92
|
+
"data-control-family": "popup",
|
|
93
|
+
"data-slot": "group",
|
|
94
|
+
...props
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function DropdownMenuCheckboxItem({ className, children, ...props }) {
|
|
98
|
+
return /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
|
|
99
|
+
"data-control-ui": "dropdown-menu",
|
|
100
|
+
"data-control-family": "popup",
|
|
101
|
+
"data-popup-part": "item",
|
|
102
|
+
"data-slot": "checkbox-item",
|
|
103
|
+
className: cn("relative", popupItemStructureClasses, className),
|
|
104
|
+
...props,
|
|
105
|
+
children: [/* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, {
|
|
106
|
+
className: "pointer-events-none absolute start-2 flex size-4 items-center justify-center",
|
|
107
|
+
children: /* @__PURE__ */ jsx(DropdownMenuCheck, {})
|
|
108
|
+
}), children]
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function DropdownMenuRadioGroup(props) {
|
|
112
|
+
return /* @__PURE__ */ jsx(Menu.RadioGroup, {
|
|
113
|
+
"data-control-ui": "dropdown-menu",
|
|
114
|
+
"data-control-family": "popup",
|
|
115
|
+
"data-slot": "radio-group",
|
|
116
|
+
...props
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function DropdownMenuRadioItem({ className, children, ...props }) {
|
|
120
|
+
return /* @__PURE__ */ jsxs(Menu.RadioItem, {
|
|
121
|
+
"data-control-ui": "dropdown-menu",
|
|
122
|
+
"data-control-family": "popup",
|
|
123
|
+
"data-popup-part": "item",
|
|
124
|
+
"data-slot": "radio-item",
|
|
125
|
+
className: cn("relative", popupItemStructureClasses, className),
|
|
126
|
+
...props,
|
|
127
|
+
children: [/* @__PURE__ */ jsx(Menu.RadioItemIndicator, {
|
|
128
|
+
className: "pointer-events-none absolute start-2 flex size-4 items-center justify-center",
|
|
129
|
+
children: /* @__PURE__ */ jsx(DropdownMenuCheck, {})
|
|
130
|
+
}), children]
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function DropdownMenuCheck() {
|
|
134
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
135
|
+
viewBox: "0 0 12 12",
|
|
136
|
+
className: "size-3",
|
|
137
|
+
"aria-hidden": "true",
|
|
138
|
+
fill: "none",
|
|
139
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
140
|
+
d: "M2.5 6.5 5 9l4.5-5",
|
|
141
|
+
stroke: "currentColor",
|
|
142
|
+
strokeWidth: "1.6",
|
|
143
|
+
strokeLinecap: "round",
|
|
144
|
+
strokeLinejoin: "round"
|
|
145
|
+
})
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function DropdownMenuSub(props) {
|
|
149
|
+
return /* @__PURE__ */ jsx(Menu.SubmenuRoot, { ...props });
|
|
150
|
+
}
|
|
151
|
+
function DropdownMenuSubTrigger({ className, children, ...props }) {
|
|
152
|
+
return /* @__PURE__ */ jsxs(Menu.SubmenuTrigger, {
|
|
153
|
+
"data-control-ui": "dropdown-menu",
|
|
154
|
+
"data-control-family": "popup",
|
|
155
|
+
"data-popup-part": "item",
|
|
156
|
+
"data-slot": "sub-trigger",
|
|
157
|
+
className: cn(popupItemStructureClasses, className),
|
|
158
|
+
...props,
|
|
159
|
+
children: [children, /* @__PURE__ */ jsx("span", {
|
|
160
|
+
"data-control-ui": "dropdown-menu",
|
|
161
|
+
"data-control-family": "popup",
|
|
162
|
+
"data-slot": "sub-trigger-indicator",
|
|
163
|
+
"aria-hidden": "true",
|
|
164
|
+
children: "›"
|
|
165
|
+
})]
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function DropdownMenuSubContent(props) {
|
|
169
|
+
return /* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
170
|
+
"data-control-ui": "dropdown-menu",
|
|
171
|
+
"data-slot": "sub-content",
|
|
172
|
+
side: "right",
|
|
173
|
+
sideOffset: 0,
|
|
174
|
+
alignOffset: -3,
|
|
175
|
+
...props
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
function DropdownMenuShortcut(props) {
|
|
179
|
+
return /* @__PURE__ */ jsx("span", {
|
|
180
|
+
"data-control-ui": "dropdown-menu",
|
|
181
|
+
"data-control-family": "popup",
|
|
182
|
+
"data-popup-part": "shortcut",
|
|
183
|
+
"data-slot": "shortcut",
|
|
184
|
+
...props
|
|
185
|
+
});
|
|
186
|
+
}
|
|
82
187
|
//#endregion
|
|
83
|
-
export { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, dropdownMenuTriggerVariants };
|
|
188
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, dropdownMenuTriggerVariants };
|
|
@@ -11,6 +11,16 @@ type SidebarGroupLabelProps = Omit<ComponentProps<"div">, "style"> & {
|
|
|
11
11
|
} & {
|
|
12
12
|
render?: RenderProp<ComponentProps<"div">>;
|
|
13
13
|
};
|
|
14
|
+
type SidebarGroupContentProps = Omit<ComponentProps<"div">, "style"> & {
|
|
15
|
+
style?: CSSProperties & SidebarKnobStyle;
|
|
16
|
+
};
|
|
17
|
+
type SidebarMenuActionProps = Omit<ComponentProps<"button">, "style"> & {
|
|
18
|
+
render?: RenderProp<ComponentProps<"button">>;
|
|
19
|
+
showOnHover?: boolean;
|
|
20
|
+
style?: CSSProperties & SidebarKnobStyle;
|
|
21
|
+
};
|
|
22
|
+
declare function SidebarGroupContent({ className, ...props }: SidebarGroupContentProps): import("react").JSX.Element;
|
|
23
|
+
declare function SidebarMenuAction({ className, render, showOnHover, children, ...props }: SidebarMenuActionProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
14
24
|
type SidebarMenuButtonProps = Omit<ComponentProps<"button">, "style"> & {
|
|
15
25
|
style?: CSSProperties & SidebarKnobStyle;
|
|
16
26
|
} & {
|
|
@@ -36,4 +46,4 @@ declare function SidebarMenuItem({ className, ...props }: ComponentProps<"li"> &
|
|
|
36
46
|
declare function SidebarMenuButton({ render, isActive, variant, size, tooltip, className, children, ...props }: SidebarMenuButtonProps): import("react").JSX.Element;
|
|
37
47
|
declare function SidebarMenuSub({ className, ...props }: ComponentProps<typeof SidebarMenu>): import("react").JSX.Element;
|
|
38
48
|
//#endregion
|
|
39
|
-
export { SidebarGroup, SidebarGroupLabel, SidebarGroupLabelProps, SidebarMenu, SidebarMenuButton, SidebarMenuButtonProps, SidebarMenuButtonSize, SidebarMenuButtonVariant, SidebarMenuItem, SidebarMenuSub, SidebarSelectionIndicator, sidebarMenuButtonSizes, sidebarMenuButtonVariants };
|
|
49
|
+
export { SidebarGroup, SidebarGroupContent, SidebarGroupContentProps, SidebarGroupLabel, SidebarGroupLabelProps, SidebarMenu, SidebarMenuAction, SidebarMenuActionProps, SidebarMenuButton, SidebarMenuButtonProps, SidebarMenuButtonSize, SidebarMenuButtonVariant, SidebarMenuItem, SidebarMenuSub, SidebarSelectionIndicator, sidebarMenuButtonSizes, sidebarMenuButtonVariants };
|
package/dist/ui/sidebar-menu.js
CHANGED
|
@@ -15,6 +15,31 @@ const sidebarMenuButtonSizes = [
|
|
|
15
15
|
"sm",
|
|
16
16
|
"lg"
|
|
17
17
|
];
|
|
18
|
+
function SidebarGroupContent({ className, ...props }) {
|
|
19
|
+
return /* @__PURE__ */ jsx("div", {
|
|
20
|
+
"data-control-ui": "sidebar",
|
|
21
|
+
"data-control-family": "sidebar",
|
|
22
|
+
"data-slot": "group-content",
|
|
23
|
+
className: cn("w-full", className),
|
|
24
|
+
...props
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function SidebarMenuAction({ className, render, showOnHover = false, children, ...props }) {
|
|
28
|
+
return useRender({
|
|
29
|
+
defaultTagName: "button",
|
|
30
|
+
render,
|
|
31
|
+
props: {
|
|
32
|
+
type: "button",
|
|
33
|
+
...props,
|
|
34
|
+
"data-control-ui": "sidebar",
|
|
35
|
+
"data-control-family": "sidebar",
|
|
36
|
+
"data-slot": "menu-action",
|
|
37
|
+
"data-show-on-hover": showOnHover || void 0,
|
|
38
|
+
className: cn("end-1 flex size-5 items-center justify-center -translate-y-1/2 disabled:pointer-events-none group-data-[collapsible=icon]:hidden [&>svg]:size-4 [&>svg]:shrink-0", className, "absolute"),
|
|
39
|
+
children
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
18
43
|
function SidebarGroup({ className, ...props }) {
|
|
19
44
|
return /* @__PURE__ */ jsx("div", {
|
|
20
45
|
"data-control-ui": "sidebar",
|
|
@@ -132,4 +157,4 @@ function SidebarMenuSub({ className, ...props }) {
|
|
|
132
157
|
});
|
|
133
158
|
}
|
|
134
159
|
//#endregion
|
|
135
|
-
export { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, sidebarMenuButtonSizes, sidebarMenuButtonVariants };
|
|
160
|
+
export { SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, sidebarMenuButtonSizes, sidebarMenuButtonVariants };
|
package/dist/ui/sidebar.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Button } from "./button.js";
|
|
2
2
|
import { SidebarKnobStyle } from "../knob-contracts/sidebar-knobs.js";
|
|
3
|
-
import { SidebarGroup, SidebarGroupLabel, SidebarGroupLabelProps, SidebarMenu, SidebarMenuButton, SidebarMenuButtonProps, SidebarMenuButtonSize, SidebarMenuButtonVariant, SidebarMenuItem, SidebarMenuSub, SidebarSelectionIndicator, sidebarMenuButtonSizes, sidebarMenuButtonVariants } from "./sidebar-menu.js";
|
|
3
|
+
import { SidebarGroup, SidebarGroupContent, SidebarGroupContentProps, SidebarGroupLabel, SidebarGroupLabelProps, SidebarMenu, SidebarMenuAction, SidebarMenuActionProps, SidebarMenuButton, SidebarMenuButtonProps, SidebarMenuButtonSize, SidebarMenuButtonVariant, SidebarMenuItem, SidebarMenuSub, SidebarSelectionIndicator, sidebarMenuButtonSizes, sidebarMenuButtonVariants } from "./sidebar-menu.js";
|
|
4
4
|
import { SidebarProvider, SidebarProviderProps, SidebarStyle, useSidebar } from "./sidebar-provider.js";
|
|
5
5
|
import { CSSProperties, ComponentProps } from "react";
|
|
6
6
|
//#region src/ui/sidebar.d.ts
|
|
@@ -28,4 +28,4 @@ declare function SidebarFooter({ className, ...props }: ComponentProps<"div"> &
|
|
|
28
28
|
}): import("react").JSX.Element;
|
|
29
29
|
declare function SidebarContent({ className, children, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
30
30
|
//#endregion
|
|
31
|
-
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, type SidebarGroupLabelProps, SidebarHeader, SidebarInset, SidebarInsetProps, SidebarMenu, SidebarMenuButton, type SidebarMenuButtonProps, type SidebarMenuButtonSize, type SidebarMenuButtonVariant, SidebarMenuItem, SidebarMenuSub, SidebarProvider, type SidebarProviderProps, SidebarRail, SidebarRailProps, type SidebarSelectionIndicator, type SidebarStyle, SidebarTrigger, sidebarMenuButtonSizes, sidebarMenuButtonVariants, useSidebar };
|
|
31
|
+
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, type SidebarGroupContentProps, SidebarGroupLabel, type SidebarGroupLabelProps, SidebarHeader, SidebarInset, SidebarInsetProps, SidebarMenu, SidebarMenuAction, type SidebarMenuActionProps, SidebarMenuButton, type SidebarMenuButtonProps, type SidebarMenuButtonSize, type SidebarMenuButtonVariant, SidebarMenuItem, SidebarMenuSub, SidebarProvider, type SidebarProviderProps, SidebarRail, SidebarRailProps, type SidebarSelectionIndicator, type SidebarStyle, SidebarTrigger, sidebarMenuButtonSizes, sidebarMenuButtonVariants, useSidebar };
|
package/dist/ui/sidebar.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Button } from "./button.js";
|
|
|
5
5
|
import { ScrollArea } from "./scroll-area.js";
|
|
6
6
|
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "./sheet.js";
|
|
7
7
|
import { SidebarProvider, useSidebar } from "./sidebar-provider.js";
|
|
8
|
-
import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, sidebarMenuButtonSizes, sidebarMenuButtonVariants } from "./sidebar-menu.js";
|
|
8
|
+
import { SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, sidebarMenuButtonSizes, sidebarMenuButtonVariants } from "./sidebar-menu.js";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { PanelLeftIcon } from "lucide-react";
|
|
11
11
|
//#region src/ui/sidebar.tsx
|
|
@@ -180,4 +180,4 @@ function SidebarContent({ className, children, ...props }) {
|
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
182
|
//#endregion
|
|
183
|
-
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarProvider, SidebarRail, SidebarTrigger, sidebarMenuButtonSizes, sidebarMenuButtonVariants, useSidebar };
|
|
183
|
+
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarProvider, SidebarRail, SidebarTrigger, sidebarMenuButtonSizes, sidebarMenuButtonVariants, useSidebar };
|