@photon-ai/pho-ui 0.1.1 → 0.2.0
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/chunks/button-GQALfaly.js +325 -0
- package/dist/chunks/button-GQALfaly.js.map +1 -0
- package/dist/chunks/{close-button-CbQNfpxU.js → close-button-DKaNIndU.js} +6 -6
- package/dist/chunks/{close-button-CbQNfpxU.js.map → close-button-DKaNIndU.js.map} +1 -1
- package/dist/chunks/{cn-D6jQqeRj.js → cn-7uGUzCOM.js} +2 -3
- package/dist/chunks/{cn-D6jQqeRj.js.map → cn-7uGUzCOM.js.map} +1 -1
- package/dist/chunks/{dialog-BSBF1Wyq.js → dialog-CyyL5VCc.js} +13 -13
- package/dist/chunks/dialog-CyyL5VCc.js.map +1 -0
- package/dist/chunks/{input-aZqjjV_m.js → input-DX7d5MlS.js} +3 -3
- package/dist/chunks/input-DX7d5MlS.js.map +1 -0
- package/dist/chunks/menu-BfaNHnOp.js +101 -0
- package/dist/chunks/menu-BfaNHnOp.js.map +1 -0
- package/dist/components/accordion.js +1 -1
- package/dist/components/alert-dialog.js +5 -5
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/autocomplete.js +7 -7
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/avatar.js +1 -1
- package/dist/components/badge.js +2 -2
- package/dist/components/badge.js.map +1 -1
- package/dist/components/button.js +10 -11
- package/dist/components/checkbox.js +2 -2
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/collapsible.js +1 -1
- package/dist/components/combobox.js +53 -53
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/context-menu.js +11 -11
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/dialog.js +1 -1
- package/dist/components/drawer.js +2 -2
- package/dist/components/drawer.js.map +1 -1
- package/dist/components/field.js +26 -26
- package/dist/components/field.js.map +1 -1
- package/dist/components/fieldset.js +1 -1
- package/dist/components/form.js +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/kbd.js +8 -8
- package/dist/components/kbd.js.map +1 -1
- package/dist/components/menu.js +1 -1
- package/dist/components/menubar.js +5 -5
- package/dist/components/menubar.js.map +1 -1
- package/dist/components/meter.js +1 -1
- package/dist/components/navigation-menu.js +34 -34
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/notification.js +16 -16
- package/dist/components/notification.js.map +1 -1
- package/dist/components/number-field.js +18 -18
- package/dist/components/number-field.js.map +1 -1
- package/dist/components/otp-field.js +6 -6
- package/dist/components/otp-field.js.map +1 -1
- package/dist/components/popover.js +9 -9
- package/dist/components/popover.js.map +1 -1
- package/dist/components/preview-card.js +12 -12
- package/dist/components/preview-card.js.map +1 -1
- package/dist/components/progress.js +1 -1
- package/dist/components/radio-group.js +9 -9
- package/dist/components/radio-group.js.map +1 -1
- package/dist/components/scroll-area.js +1 -1
- package/dist/components/select.js +10 -10
- package/dist/components/select.js.map +1 -1
- package/dist/components/separator.js +1 -1
- package/dist/components/slider.js +16 -16
- package/dist/components/slider.js.map +1 -1
- package/dist/components/switch.js +11 -11
- package/dist/components/switch.js.map +1 -1
- package/dist/components/tabs.js +15 -15
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/toast.js +6 -6
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.js +1 -1
- package/dist/components/toggle.js +6 -6
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/toolbar.js +7 -7
- package/dist/components/toolbar.js.map +1 -1
- package/dist/components/tooltip.js +14 -14
- package/dist/components/tooltip.js.map +1 -1
- package/dist/index.js +17 -18
- package/dist/src/components/button/button.d.ts +12 -35
- package/dist/src/components/button/index.d.ts +1 -1
- package/dist/src/components/menu/menu.d.ts +2 -2
- package/dist/utils.js +1 -1
- package/package.json +1 -1
- package/src/styles/fonts.css +22 -0
- package/src/styles/theme.css +166 -169
- package/dist/chunks/button-DjjSiLYz.js +0 -334
- package/dist/chunks/button-DjjSiLYz.js.map +0 -1
- package/dist/chunks/dialog-BSBF1Wyq.js.map +0 -1
- package/dist/chunks/input-aZqjjV_m.js.map +0 -1
- package/dist/chunks/menu-BkzDbNuX.js +0 -101
- package/dist/chunks/menu-BkzDbNuX.js.map +0 -1
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { t as l } from "./cn-7uGUzCOM.js";
|
|
3
|
+
import { n as S, r as w } from "./link-provider-9TFNyDqO.js";
|
|
4
|
+
import { t as f } from "./resolve-variant-CcD8iG5l.js";
|
|
5
|
+
import { isValidElement as _, useMemo as I } from "react";
|
|
6
|
+
import { Fragment as k, jsx as n, jsxs as x } from "react/jsx-runtime";
|
|
7
|
+
import { motion as y } from "motion/react";
|
|
8
|
+
var R = l("group relative inline-flex h-max cursor-pointer items-center justify-center whitespace-nowrap outline-pho-brand transition duration-100 ease-linear focus-visible:outline-2 focus-visible:outline-offset-2", "disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none"), q = {
|
|
9
|
+
sm: {
|
|
10
|
+
classes: "gap-1 px-3.5 py-1.5 text-sm font-medium data-svg-only:p-2",
|
|
11
|
+
description: "Small — compact rows, tables, and toolbars"
|
|
12
|
+
},
|
|
13
|
+
md: {
|
|
14
|
+
classes: "gap-1 px-4 py-2 text-sm font-medium data-svg-only:p-2.5",
|
|
15
|
+
description: "Medium — the default"
|
|
16
|
+
},
|
|
17
|
+
lg: {
|
|
18
|
+
classes: "gap-1.5 px-5 py-2.5 text-md font-medium data-svg-only:p-3",
|
|
19
|
+
description: "Large — prominent and marketing actions"
|
|
20
|
+
}
|
|
21
|
+
}, A = {
|
|
22
|
+
rounded: {
|
|
23
|
+
classes: "rounded-full",
|
|
24
|
+
description: "Pill — the default; every button on photon.codes"
|
|
25
|
+
},
|
|
26
|
+
square: {
|
|
27
|
+
classes: "rounded-lg",
|
|
28
|
+
description: "Gently rounded corners for dense app chrome"
|
|
29
|
+
},
|
|
30
|
+
circle: {
|
|
31
|
+
classes: "rounded-full",
|
|
32
|
+
description: "Circular — pair with svgOnly for round icon buttons"
|
|
33
|
+
}
|
|
34
|
+
}, M = {
|
|
35
|
+
primary: {
|
|
36
|
+
classes: "bg-pho-brand-solid text-pho-on-brand hover:bg-pho-brand-solid-hover data-loading:bg-pho-brand-solid-hover *:data-icon:opacity-60 hover:*:data-icon:opacity-75",
|
|
37
|
+
description: "High-emphasis primary action (default)"
|
|
38
|
+
},
|
|
39
|
+
secondary: {
|
|
40
|
+
classes: "bg-pho-primary text-pho-secondary ring-1 ring-pho-secondary ring-inset hover:bg-pho-primary-hover hover:text-pho-secondary-hover data-loading:bg-pho-primary-hover *:data-icon:text-fg-pho-quaternary hover:*:data-icon:text-fg-pho-quaternary-hover",
|
|
41
|
+
description: "Neutral, supporting action"
|
|
42
|
+
},
|
|
43
|
+
tertiary: {
|
|
44
|
+
classes: "text-pho-tertiary hover:bg-pho-ghost-hover hover:text-pho-tertiary-hover data-loading:bg-pho-ghost-hover *:data-icon:text-fg-pho-quaternary hover:*:data-icon:text-fg-pho-quaternary-hover",
|
|
45
|
+
description: "Low-emphasis, borderless action"
|
|
46
|
+
},
|
|
47
|
+
error: {
|
|
48
|
+
classes: "bg-pho-error-solid text-white outline-pho-error hover:bg-pho-error-solid-hover data-loading:bg-pho-error-solid-hover *:data-icon:opacity-70 hover:*:data-icon:opacity-85",
|
|
49
|
+
description: "Destructive confirmation"
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
function T(e) {
|
|
53
|
+
const { variant: t = "primary", size: o = "md", shape: i = "rounded", className: r } = e ?? {};
|
|
54
|
+
return l(R, f(A, i), f(q, o), f(M, t), r);
|
|
55
|
+
}
|
|
56
|
+
var z = "transition-inherit-all pointer-events-none inline-flex shrink-0 items-center [&>svg]:size-5 [&>svg]:shrink-0";
|
|
57
|
+
function v({ position: e, children: t }) {
|
|
58
|
+
return /* @__PURE__ */ n("span", {
|
|
59
|
+
"data-icon": e,
|
|
60
|
+
className: z,
|
|
61
|
+
children: t
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function m() {
|
|
65
|
+
return /* @__PURE__ */ x("svg", {
|
|
66
|
+
fill: "none",
|
|
67
|
+
viewBox: "0 0 20 20",
|
|
68
|
+
"aria-hidden": "true",
|
|
69
|
+
children: [/* @__PURE__ */ n("circle", {
|
|
70
|
+
className: "stroke-current opacity-30",
|
|
71
|
+
cx: "10",
|
|
72
|
+
cy: "10",
|
|
73
|
+
r: "8",
|
|
74
|
+
fill: "none",
|
|
75
|
+
strokeWidth: "2"
|
|
76
|
+
}), /* @__PURE__ */ n("circle", {
|
|
77
|
+
className: "origin-center animate-spin stroke-current",
|
|
78
|
+
cx: "10",
|
|
79
|
+
cy: "10",
|
|
80
|
+
r: "8",
|
|
81
|
+
fill: "none",
|
|
82
|
+
strokeWidth: "2",
|
|
83
|
+
strokeDasharray: "12.5 50",
|
|
84
|
+
strokeLinecap: "round"
|
|
85
|
+
})]
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function g(e, t) {
|
|
89
|
+
return e == null || e === !1 ? null : w(e) ? /* @__PURE__ */ n(v, {
|
|
90
|
+
position: t,
|
|
91
|
+
children: /* @__PURE__ */ n(e, {})
|
|
92
|
+
}) : _(e) ? /* @__PURE__ */ n(v, {
|
|
93
|
+
position: t,
|
|
94
|
+
children: e
|
|
95
|
+
}) : null;
|
|
96
|
+
}
|
|
97
|
+
function B({ svgOnly: e, loading: t, prefix: o, suffix: i, children: r }) {
|
|
98
|
+
return e ? t ? /* @__PURE__ */ n(m, {}) : r : /* @__PURE__ */ x(k, { children: [
|
|
99
|
+
t ? /* @__PURE__ */ n(v, {
|
|
100
|
+
position: "loading",
|
|
101
|
+
children: /* @__PURE__ */ n(m, {})
|
|
102
|
+
}) : g(o, "prefix"),
|
|
103
|
+
r != null && r !== !1 && /* @__PURE__ */ n("span", {
|
|
104
|
+
"data-text": !0,
|
|
105
|
+
className: "transition-inherit-all px-0.5",
|
|
106
|
+
children: r
|
|
107
|
+
}),
|
|
108
|
+
g(i, "suffix")
|
|
109
|
+
] });
|
|
110
|
+
}
|
|
111
|
+
function b(e, t) {
|
|
112
|
+
e && !t && typeof process < "u" && process.env.NODE_ENV !== "production" && console.warn("Button: `svgOnly` buttons require an `aria-label` that names the action.");
|
|
113
|
+
}
|
|
114
|
+
function H({ variant: e, size: t, shape: o, prefix: i, suffix: r, svgOnly: a, loading: s, children: p, className: u, ref: d, ...c }) {
|
|
115
|
+
return b(a, c["aria-label"]), /* @__PURE__ */ n("button", {
|
|
116
|
+
ref: d,
|
|
117
|
+
type: "button",
|
|
118
|
+
...c,
|
|
119
|
+
"aria-busy": s || void 0,
|
|
120
|
+
"data-loading": s ? "true" : void 0,
|
|
121
|
+
"data-svg-only": a ? "true" : void 0,
|
|
122
|
+
className: l(T({
|
|
123
|
+
variant: e,
|
|
124
|
+
size: t,
|
|
125
|
+
shape: o
|
|
126
|
+
}), s && "pointer-events-none", a && "[&>svg]:size-5 [&>svg]:shrink-0", u),
|
|
127
|
+
children: B({
|
|
128
|
+
svgOnly: a,
|
|
129
|
+
loading: s,
|
|
130
|
+
prefix: i,
|
|
131
|
+
suffix: r,
|
|
132
|
+
children: p
|
|
133
|
+
})
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
H.displayName = "Button";
|
|
137
|
+
function j({ variant: e, size: t, shape: o, prefix: i, suffix: r, svgOnly: a, loading: s, disabled: p, href: u, children: d, className: c, ...h }) {
|
|
138
|
+
return b(a, h["aria-label"]), /* @__PURE__ */ n(S(), {
|
|
139
|
+
href: u,
|
|
140
|
+
...h,
|
|
141
|
+
"aria-disabled": p || s || void 0,
|
|
142
|
+
"aria-busy": s || void 0,
|
|
143
|
+
"data-loading": s ? "true" : void 0,
|
|
144
|
+
"data-svg-only": a ? "true" : void 0,
|
|
145
|
+
className: l(T({
|
|
146
|
+
variant: e,
|
|
147
|
+
size: t,
|
|
148
|
+
shape: o
|
|
149
|
+
}), s && "pointer-events-none", a && "[&>svg]:size-5 [&>svg]:shrink-0", c),
|
|
150
|
+
children: B({
|
|
151
|
+
svgOnly: a,
|
|
152
|
+
loading: s,
|
|
153
|
+
prefix: i,
|
|
154
|
+
suffix: r,
|
|
155
|
+
children: d
|
|
156
|
+
})
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
j.displayName = "ButtonLink";
|
|
160
|
+
var O = l("squircle relative inline-flex h-max cursor-pointer items-center justify-center overflow-hidden rounded-full border font-medium whitespace-nowrap", "border-pho-on-brand bg-pho-brand-solid text-pho-on-brand", "outline-pho-brand focus-visible:outline-2 focus-visible:outline-offset-2", "disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:cursor-not-allowed aria-disabled:opacity-50"), F = {
|
|
161
|
+
type: "spring",
|
|
162
|
+
stiffness: 200,
|
|
163
|
+
damping: 30,
|
|
164
|
+
mass: 0.1
|
|
165
|
+
}, P = l("[--pho-sheen:light-dark(rgba(255,255,255,0.5),rgba(0,0,0,0.12))]", "shadow-[inset_0_var(--pho-sheen-y,0px)_var(--pho-sheen-blur,5px)_var(--pho-sheen-spread,2px)_var(--pho-sheen)]"), U = {
|
|
166
|
+
"--pho-sheen-y": "0px",
|
|
167
|
+
"--pho-sheen-blur": "5px",
|
|
168
|
+
"--pho-sheen-spread": "2px"
|
|
169
|
+
}, D = {
|
|
170
|
+
sm: {
|
|
171
|
+
"--pho-sheen-y": "-3px",
|
|
172
|
+
"--pho-sheen-blur": "8px",
|
|
173
|
+
"--pho-sheen-spread": "2px",
|
|
174
|
+
gap: 0
|
|
175
|
+
},
|
|
176
|
+
md: {
|
|
177
|
+
"--pho-sheen-y": "-6px",
|
|
178
|
+
"--pho-sheen-blur": "14px",
|
|
179
|
+
"--pho-sheen-spread": "1px",
|
|
180
|
+
gap: 4
|
|
181
|
+
}
|
|
182
|
+
}, W = {
|
|
183
|
+
sm: {
|
|
184
|
+
classes: "p-2 text-sm data-svg-only:p-2",
|
|
185
|
+
description: "Small — the compact 'Variant 2' (14px label, 8px padding)"
|
|
186
|
+
},
|
|
187
|
+
md: {
|
|
188
|
+
classes: "px-4 py-3 text-md data-svg-only:p-3",
|
|
189
|
+
description: "Medium — the 'Variant 1' (16px label, 12×16 padding)"
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
function C(e) {
|
|
193
|
+
const { size: t = "md", fullWidth: o, className: i } = e ?? {};
|
|
194
|
+
return l(O, P, f(W, t), o && "w-full", i);
|
|
195
|
+
}
|
|
196
|
+
function G(e) {
|
|
197
|
+
return {
|
|
198
|
+
rest: {
|
|
199
|
+
...U,
|
|
200
|
+
gap: 0
|
|
201
|
+
},
|
|
202
|
+
hover: { ...D[e] }
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
var Z = {
|
|
206
|
+
rest: {
|
|
207
|
+
opacity: 0,
|
|
208
|
+
width: 1,
|
|
209
|
+
height: 10
|
|
210
|
+
},
|
|
211
|
+
hover: {
|
|
212
|
+
opacity: 1,
|
|
213
|
+
width: 20,
|
|
214
|
+
height: 21
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
function E({ position: e, children: t }) {
|
|
218
|
+
return /* @__PURE__ */ n(y.span, {
|
|
219
|
+
"data-icon": e,
|
|
220
|
+
variants: Z,
|
|
221
|
+
transition: F,
|
|
222
|
+
style: {
|
|
223
|
+
display: "inline-flex",
|
|
224
|
+
flex: "none",
|
|
225
|
+
alignItems: "center",
|
|
226
|
+
overflow: "hidden"
|
|
227
|
+
},
|
|
228
|
+
className: "pointer-events-none [&>svg]:block [&>svg]:size-full",
|
|
229
|
+
children: t
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
function N(e, t) {
|
|
233
|
+
return e == null || e === !1 ? null : w(e) ? /* @__PURE__ */ n(E, {
|
|
234
|
+
position: t,
|
|
235
|
+
children: /* @__PURE__ */ n(e, {})
|
|
236
|
+
}) : _(e) ? /* @__PURE__ */ n(E, {
|
|
237
|
+
position: t,
|
|
238
|
+
children: e
|
|
239
|
+
}) : null;
|
|
240
|
+
}
|
|
241
|
+
function L({ svgOnly: e, loading: t, prefix: o, suffix: i, children: r }) {
|
|
242
|
+
return e ? t ? /* @__PURE__ */ n(m, {}) : r : /* @__PURE__ */ x(k, { children: [
|
|
243
|
+
t ? /* @__PURE__ */ n(v, {
|
|
244
|
+
position: "loading",
|
|
245
|
+
children: /* @__PURE__ */ n(m, {})
|
|
246
|
+
}) : N(o, "prefix"),
|
|
247
|
+
r != null && r !== !1 && /* @__PURE__ */ n("span", {
|
|
248
|
+
"data-text": !0,
|
|
249
|
+
className: "px-0.5",
|
|
250
|
+
children: r
|
|
251
|
+
}),
|
|
252
|
+
N(i, "suffix")
|
|
253
|
+
] });
|
|
254
|
+
}
|
|
255
|
+
function V(e, t) {
|
|
256
|
+
return {
|
|
257
|
+
initial: !1,
|
|
258
|
+
animate: "rest",
|
|
259
|
+
whileHover: t ? void 0 : "hover",
|
|
260
|
+
variants: G(e),
|
|
261
|
+
transition: F
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function J({ size: e = "md", fullWidth: t, prefix: o, suffix: i, svgOnly: r, loading: a, children: s, className: p, ref: u, ...d }) {
|
|
265
|
+
return b(r, d["aria-label"]), /* @__PURE__ */ n(y.button, {
|
|
266
|
+
ref: u,
|
|
267
|
+
type: "button",
|
|
268
|
+
...V(e, d.disabled || a),
|
|
269
|
+
...d,
|
|
270
|
+
"aria-busy": a || void 0,
|
|
271
|
+
"data-loading": a ? "true" : void 0,
|
|
272
|
+
"data-svg-only": r ? "true" : void 0,
|
|
273
|
+
className: l(C({
|
|
274
|
+
size: e,
|
|
275
|
+
fullWidth: t
|
|
276
|
+
}), a && "pointer-events-none", r && "[&>svg]:size-5 [&>svg]:shrink-0", p),
|
|
277
|
+
children: L({
|
|
278
|
+
svgOnly: r,
|
|
279
|
+
loading: a,
|
|
280
|
+
prefix: o,
|
|
281
|
+
suffix: i,
|
|
282
|
+
children: s
|
|
283
|
+
})
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
J.displayName = "EffectButton";
|
|
287
|
+
function K({ size: e = "md", fullWidth: t, prefix: o, suffix: i, svgOnly: r, loading: a, disabled: s, href: p, children: u, className: d, ...c }) {
|
|
288
|
+
b(r, c["aria-label"]);
|
|
289
|
+
const h = S();
|
|
290
|
+
return /* @__PURE__ */ n(I(() => y.create(h), [h]), {
|
|
291
|
+
href: p,
|
|
292
|
+
...V(e, s || a),
|
|
293
|
+
...c,
|
|
294
|
+
"aria-disabled": s || a || void 0,
|
|
295
|
+
"aria-busy": a || void 0,
|
|
296
|
+
"data-loading": a ? "true" : void 0,
|
|
297
|
+
"data-svg-only": r ? "true" : void 0,
|
|
298
|
+
className: l(C({
|
|
299
|
+
size: e,
|
|
300
|
+
fullWidth: t
|
|
301
|
+
}), a && "pointer-events-none", r && "[&>svg]:size-5 [&>svg]:shrink-0", d),
|
|
302
|
+
children: L({
|
|
303
|
+
svgOnly: r,
|
|
304
|
+
loading: a,
|
|
305
|
+
prefix: o,
|
|
306
|
+
suffix: i,
|
|
307
|
+
children: u
|
|
308
|
+
})
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
K.displayName = "EffectButtonLink";
|
|
312
|
+
export {
|
|
313
|
+
j as a,
|
|
314
|
+
K as c,
|
|
315
|
+
H as i,
|
|
316
|
+
T as l,
|
|
317
|
+
q as n,
|
|
318
|
+
W as o,
|
|
319
|
+
M as r,
|
|
320
|
+
J as s,
|
|
321
|
+
A as t,
|
|
322
|
+
C as u
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
//# sourceMappingURL=button-GQALfaly.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button-GQALfaly.js","names":[],"sources":["../../src/components/button/button.tsx"],"sourcesContent":["import {\n isValidElement,\n useMemo,\n type AnchorHTMLAttributes,\n type ButtonHTMLAttributes,\n type FC,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { motion, type HTMLMotionProps } from \"motion/react\";\nimport { cn } from \"../../utils/cn\";\nimport { resolveVariant, type VariantMap } from \"../../utils/resolve-variant\";\nimport { isReactComponent } from \"../../utils/is-react-component\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\n\n/**\n * Design notes (Geist-aligned):\n * - ONE emphasis axis, kept deliberately small. `variant` is a closed,\n * semantic set — a single high-emphasis default plus the supporting and\n * intent variants you actually reach for. There is no `ghost`, no `link`,\n * and no second destructive: navigation belongs to `ButtonLink`, and an\n * inline text link is an anchor, not a button.\n * - THREE sizes (`sm` / `md` / `lg`, default `md`). No `xs` / `xl`.\n * - `prefix` / `suffix` are generic slots (icon, spinner, count…), not\n * icon-only props. `svgOnly` makes an icon button and *requires* an\n * `aria-label`. `loading` is declarative. There is no `shadow`: buttons\n * are flat on photon.codes — elevation belongs to floating layers.\n */\n\nconst COMMON_ROOT = cn(\n \"group relative inline-flex h-max cursor-pointer items-center justify-center whitespace-nowrap outline-pho-brand transition duration-100 ease-linear focus-visible:outline-2 focus-visible:outline-offset-2\",\n // Disabled (native `disabled` on <button>, `aria-disabled` on links).\n \"disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none\",\n);\n\n/** Size axis — padding, text size, and icon-only (svgOnly) padding. */\nexport const BUTTON_SIZES = {\n sm: {\n classes: \"gap-1 px-3.5 py-1.5 text-sm font-medium data-svg-only:p-2\",\n description: \"Small — compact rows, tables, and toolbars\",\n },\n md: {\n classes: \"gap-1 px-4 py-2 text-sm font-medium data-svg-only:p-2.5\",\n description: \"Medium — the default\",\n },\n lg: {\n classes: \"gap-1.5 px-5 py-2.5 text-md font-medium data-svg-only:p-3\",\n description: \"Large — prominent and marketing actions\",\n },\n} satisfies VariantMap;\n\n/** Shape axis — corner treatment. Pills are the photon.codes default. */\nexport const BUTTON_SHAPES = {\n rounded: {\n classes: \"rounded-full\",\n description: \"Pill — the default; every button on photon.codes\",\n },\n square: {\n classes: \"rounded-lg\",\n description: \"Gently rounded corners for dense app chrome\",\n },\n circle: {\n classes: \"rounded-full\",\n description: \"Circular — pair with svgOnly for round icon buttons\",\n },\n} satisfies VariantMap;\n\n/** Emphasis axis — a tight, semantic set. `primary` is the default. */\nexport const BUTTON_VARIANTS = {\n primary: {\n classes:\n \"bg-pho-brand-solid text-pho-on-brand hover:bg-pho-brand-solid-hover data-loading:bg-pho-brand-solid-hover *:data-icon:opacity-60 hover:*:data-icon:opacity-75\",\n description: \"High-emphasis primary action (default)\",\n },\n secondary: {\n classes:\n \"bg-pho-primary text-pho-secondary ring-1 ring-pho-secondary ring-inset hover:bg-pho-primary-hover hover:text-pho-secondary-hover data-loading:bg-pho-primary-hover *:data-icon:text-fg-pho-quaternary hover:*:data-icon:text-fg-pho-quaternary-hover\",\n description: \"Neutral, supporting action\",\n },\n tertiary: {\n classes:\n \"text-pho-tertiary hover:bg-pho-ghost-hover hover:text-pho-tertiary-hover data-loading:bg-pho-ghost-hover *:data-icon:text-fg-pho-quaternary hover:*:data-icon:text-fg-pho-quaternary-hover\",\n description: \"Low-emphasis, borderless action\",\n },\n error: {\n classes:\n \"bg-pho-error-solid text-white outline-pho-error hover:bg-pho-error-solid-hover data-loading:bg-pho-error-solid-hover *:data-icon:opacity-70 hover:*:data-icon:opacity-85\",\n description: \"Destructive confirmation\",\n },\n} satisfies VariantMap;\n\nexport type ButtonSize = keyof typeof BUTTON_SIZES;\nexport type ButtonShape = keyof typeof BUTTON_SHAPES;\nexport type ButtonVariant = keyof typeof BUTTON_VARIANTS;\n\n/** Compose the full class string for a button — exported for reuse/testing. */\nexport function buttonVariants(opts?: {\n variant?: ButtonVariant;\n size?: ButtonSize;\n shape?: ButtonShape;\n className?: string;\n}): string {\n const {\n variant = \"primary\",\n size = \"md\",\n shape = \"rounded\",\n className,\n } = opts ?? {};\n return cn(\n COMMON_ROOT,\n resolveVariant(BUTTON_SHAPES, shape),\n resolveVariant(BUTTON_SIZES, size),\n resolveVariant(BUTTON_VARIANTS, variant),\n className,\n );\n}\n\n/** An icon/element slot rendered before or after the label. */\ntype Slottable = ReactNode | FC<{ className?: string }>;\n\ninterface ButtonBaseProps {\n /** Emphasis variant. @default \"primary\" */\n variant?: ButtonVariant;\n /** Size variant. @default \"md\" */\n size?: ButtonSize;\n /** Corner shape. @default \"rounded\" */\n shape?: ButtonShape;\n /** Slot before the label — a component (`Plus`) or element (`<Plus />`). */\n prefix?: Slottable;\n /** Slot after the label. */\n suffix?: Slottable;\n /** Render as an icon-only button. Requires an `aria-label`. */\n svgOnly?: boolean;\n /** Show a spinner and block interaction while staying readable. */\n loading?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\nexport interface ButtonProps\n extends\n ButtonBaseProps,\n Omit<ButtonHTMLAttributes<HTMLButtonElement>, keyof ButtonBaseProps> {\n ref?: Ref<HTMLButtonElement>;\n}\n\nexport interface ButtonLinkProps\n extends\n ButtonBaseProps,\n Omit<AnchorHTMLAttributes<HTMLAnchorElement>, keyof ButtonBaseProps> {\n /** Navigate to this URL (rendered via the host's `LinkProvider`). */\n href: string;\n /** Visually and semantically disable the link. */\n disabled?: boolean;\n}\n\nconst SLOT_CLASS =\n \"transition-inherit-all pointer-events-none inline-flex shrink-0 items-center [&>svg]:size-5 [&>svg]:shrink-0\";\n\nfunction Slot({\n position,\n children,\n}: {\n position: \"prefix\" | \"suffix\" | \"loading\";\n children: ReactNode;\n}) {\n return (\n <span data-icon={position} className={SLOT_CLASS}>\n {children}\n </span>\n );\n}\n\nfunction Spinner() {\n return (\n <svg fill=\"none\" viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <circle\n className=\"stroke-current opacity-30\"\n cx=\"10\"\n cy=\"10\"\n r=\"8\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n <circle\n className=\"origin-center animate-spin stroke-current\"\n cx=\"10\"\n cy=\"10\"\n r=\"8\"\n fill=\"none\"\n strokeWidth=\"2\"\n strokeDasharray=\"12.5 50\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\nfunction renderSlot(icon: Slottable, position: \"prefix\" | \"suffix\") {\n if (icon == null || icon === false) return null;\n if (isReactComponent(icon)) {\n const Icon = icon;\n return (\n <Slot position={position}>\n <Icon />\n </Slot>\n );\n }\n if (isValidElement(icon)) return <Slot position={position}>{icon}</Slot>;\n return null;\n}\n\nfunction buttonInner({\n svgOnly,\n loading,\n prefix,\n suffix,\n children,\n}: Pick<\n ButtonBaseProps,\n \"svgOnly\" | \"loading\" | \"prefix\" | \"suffix\" | \"children\"\n>) {\n if (svgOnly) {\n return loading ? <Spinner /> : children;\n }\n return (\n <>\n {loading ? (\n <Slot position=\"loading\">\n <Spinner />\n </Slot>\n ) : (\n renderSlot(prefix, \"prefix\")\n )}\n {children != null && children !== false && (\n <span data-text className=\"transition-inherit-all px-0.5\">\n {children}\n </span>\n )}\n {renderSlot(suffix, \"suffix\")}\n </>\n );\n}\n\nfunction warnMissingLabel(svgOnly: boolean | undefined, label: unknown) {\n if (\n svgOnly &&\n !label &&\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.warn(\n \"Button: `svgOnly` buttons require an `aria-label` that names the action.\",\n );\n }\n}\n\n/**\n * Button — triggers an action that mutates state (submit, save, delete).\n * For navigation that changes the URL, use {@link ButtonLink}.\n */\nexport function Button({\n variant,\n size,\n shape,\n prefix,\n suffix,\n svgOnly,\n loading,\n children,\n className,\n ref,\n ...props\n}: ButtonProps) {\n warnMissingLabel(svgOnly, props[\"aria-label\"]);\n return (\n <button\n ref={ref}\n type=\"button\"\n {...props}\n aria-busy={loading || undefined}\n data-loading={loading ? \"true\" : undefined}\n data-svg-only={svgOnly ? \"true\" : undefined}\n className={cn(\n buttonVariants({ variant, size, shape }),\n loading && \"pointer-events-none\",\n svgOnly && \"[&>svg]:size-5 [&>svg]:shrink-0\",\n className,\n )}\n >\n {buttonInner({ svgOnly, loading, prefix, suffix, children })}\n </button>\n );\n}\n\nButton.displayName = \"Button\";\n\n/**\n * ButtonLink — a link styled as a button, for navigation that changes the URL.\n * Shares every visual prop with {@link Button}; renders the host router's link\n * via `LinkProvider`.\n */\nexport function ButtonLink({\n variant,\n size,\n shape,\n prefix,\n suffix,\n svgOnly,\n loading,\n disabled,\n href,\n children,\n className,\n ...props\n}: ButtonLinkProps) {\n warnMissingLabel(svgOnly, props[\"aria-label\"]);\n const Link = useLinkComponent();\n return (\n <Link\n href={href}\n {...props}\n aria-disabled={disabled || loading || undefined}\n aria-busy={loading || undefined}\n data-loading={loading ? \"true\" : undefined}\n data-svg-only={svgOnly ? \"true\" : undefined}\n className={cn(\n buttonVariants({ variant, size, shape }),\n loading && \"pointer-events-none\",\n svgOnly && \"[&>svg]:size-5 [&>svg]:shrink-0\",\n className,\n )}\n >\n {buttonInner({ svgOnly, loading, prefix, suffix, children })}\n </Link>\n );\n}\n\nButtonLink.displayName = \"ButtonLink\";\n\n/* ============================= Effect button ============================= */\n\n/**\n * A frame-exact port of Photon's Framer \"Button - Effect\", driven by Motion\n * (the same engine Framer renders with) so every frame matches the source — not\n * a CSS approximation. On hover, three things spring together on the *identical*\n * transition (`spring-physics 200 30 0.1` → stiffness 200 / damping 30 / mass\n * 0.1): a glossy inset sheen (mode-aware: white gloss on the black pill,\n * dark shading on dark mode's white pill) reshapes toward the bottom edge,\n * the gap eases open (md), and any icon grows and fades in from nothing.\n *\n * Because it's a real spring — not a fixed-duration tween — it's also velocity-\n * correct: hovering out mid-animation continues from the current velocity,\n * exactly like Framer.\n *\n * Fill and stroke are STATIC (the source keeps them identical between the base\n * and hover variants): the contrast pill (black in light mode, white in dark —\n * photon.codes' button fill) with the glossy sheen. There is deliberately no\n * variant axis — an EffectButton without its sheen is just a pill-shaped\n * `Button`; reach for `<Button variant=\"secondary\">` for supporting/OAuth\n * actions. `size` maps to the two source variants: `md` = \"Variant 1\"\n * (16px label, 12×16 padding), `sm` = \"Variant 2\" (14px label, 8px padding).\n */\nconst EFFECT_ROOT = cn(\n // The 1px border keeps the pill geometry stable; fill/text are the static\n // contrast treatment the sheen is designed for.\n \"squircle relative inline-flex h-max cursor-pointer items-center justify-center overflow-hidden rounded-full border font-medium whitespace-nowrap\",\n \"border-pho-on-brand bg-pho-brand-solid text-pho-on-brand\",\n \"outline-pho-brand focus-visible:outline-2 focus-visible:outline-offset-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:cursor-not-allowed aria-disabled:opacity-50\",\n);\n\n/** The exact source transition: `spring-physics 200 30 0.1` (stiffness/damping/mass). */\nconst EFFECT_SPRING = {\n type: \"spring\",\n stiffness: 200,\n damping: 30,\n mass: 0.1,\n} as const;\n\n/**\n * The sheen is drawn by a CSS box-shadow that reads three custom properties\n * (offset-y / blur / spread) — Motion springs the *properties*, not an inline\n * box-shadow string, so the sheen COLOR can stay mode-aware in CSS:\n * white gloss on the black pill in light mode, a soft dark shading on the\n * white pill in dark mode (where a white glow would be invisible).\n * Geometry values are sampled 1:1 from the Framer source variants.\n */\nconst EFFECT_SHEEN_CLASSES = cn(\n \"[--pho-sheen:light-dark(rgba(255,255,255,0.5),rgba(0,0,0,0.12))]\",\n \"shadow-[inset_0_var(--pho-sheen-y,0px)_var(--pho-sheen-blur,5px)_var(--pho-sheen-spread,2px)_var(--pho-sheen)]\",\n);\n\nconst EFFECT_SHEEN_REST = {\n \"--pho-sheen-y\": \"0px\",\n \"--pho-sheen-blur\": \"5px\",\n \"--pho-sheen-spread\": \"2px\",\n} as const;\n\n/** Per-size hover targets (sheen geometry + gap), from the source variants. */\nconst EFFECT_HOVER = {\n sm: {\n \"--pho-sheen-y\": \"-3px\",\n \"--pho-sheen-blur\": \"8px\",\n \"--pho-sheen-spread\": \"2px\",\n gap: 0,\n },\n md: {\n \"--pho-sheen-y\": \"-6px\",\n \"--pho-sheen-blur\": \"14px\",\n \"--pho-sheen-spread\": \"1px\",\n gap: 4,\n },\n} as const;\n\n/** Size axis for {@link EffectButton} — padding + label size per source variant. */\nexport const EFFECT_BUTTON_SIZES = {\n sm: {\n classes: \"p-2 text-sm data-svg-only:p-2\",\n description: \"Small — the compact 'Variant 2' (14px label, 8px padding)\",\n },\n md: {\n classes: \"px-4 py-3 text-md data-svg-only:p-3\",\n description: \"Medium — the 'Variant 1' (16px label, 12×16 padding)\",\n },\n} satisfies VariantMap;\n\nexport type EffectButtonSize = keyof typeof EFFECT_BUTTON_SIZES;\n\n/** Compose the static class string for an effect button — exported for reuse. */\nexport function effectButtonVariants(opts?: {\n size?: EffectButtonSize;\n fullWidth?: boolean;\n className?: string;\n}): string {\n const { size = \"md\", fullWidth, className } = opts ?? {};\n return cn(\n EFFECT_ROOT,\n EFFECT_SHEEN_CLASSES,\n resolveVariant(EFFECT_BUTTON_SIZES, size),\n fullWidth && \"w-full\",\n className,\n );\n}\n\n/** Motion variants for the pill root — the sheen (+ gap on md) spring on hover. */\nfunction effectRootVariants(size: EffectButtonSize) {\n return {\n rest: { ...EFFECT_SHEEN_REST, gap: 0 },\n hover: { ...EFFECT_HOVER[size] },\n };\n}\n\n/**\n * Icon reveal — a 1:1 port of the source \"Arrow Right\" instance: collapsed and\n * invisible at rest (opacity 0, 1×10px), grown to full size on hover (opacity 1,\n * 20×21px). The child inherits the pill's `rest`/`hover` variant label, so it\n * springs in perfect lockstep with the sheen and gap.\n */\nconst EFFECT_ICON_VARIANTS = {\n rest: { opacity: 0, width: 1, height: 10 },\n hover: { opacity: 1, width: 20, height: 21 },\n} as const;\n\nfunction EffectSlot({\n position,\n children,\n}: {\n position: \"prefix\" | \"suffix\";\n children: ReactNode;\n}) {\n return (\n <motion.span\n data-icon={position}\n variants={EFFECT_ICON_VARIANTS}\n transition={EFFECT_SPRING}\n style={{\n display: \"inline-flex\",\n flex: \"none\",\n alignItems: \"center\",\n overflow: \"hidden\",\n }}\n className=\"pointer-events-none [&>svg]:block [&>svg]:size-full\"\n >\n {children}\n </motion.span>\n );\n}\n\nfunction renderEffectSlot(icon: Slottable, position: \"prefix\" | \"suffix\") {\n if (icon == null || icon === false) return null;\n if (isReactComponent(icon)) {\n const Icon = icon;\n return (\n <EffectSlot position={position}>\n <Icon />\n </EffectSlot>\n );\n }\n if (isValidElement(icon))\n return <EffectSlot position={position}>{icon}</EffectSlot>;\n return null;\n}\n\nfunction effectButtonInner({\n svgOnly,\n loading,\n prefix,\n suffix,\n children,\n}: Pick<\n EffectButtonBaseProps,\n \"svgOnly\" | \"loading\" | \"prefix\" | \"suffix\" | \"children\"\n>) {\n // An icon-only button keeps its icon always visible (nothing to reveal).\n if (svgOnly) return loading ? <Spinner /> : children;\n return (\n <>\n {loading ? (\n <Slot position=\"loading\">\n <Spinner />\n </Slot>\n ) : (\n renderEffectSlot(prefix, \"prefix\")\n )}\n {children != null && children !== false && (\n <span data-text className=\"px-0.5\">\n {children}\n </span>\n )}\n {renderEffectSlot(suffix, \"suffix\")}\n </>\n );\n}\n\n/** Motion props (initial/animate/hover/variants/transition) shared by both roots. */\nfunction effectMotionProps(size: EffectButtonSize, inert: boolean | undefined) {\n return {\n initial: false as const,\n animate: \"rest\",\n // Browsers still dispatch pointerenter on a disabled <button>, so Motion's\n // hover gesture would run the sheen / gap / icon-reveal springs on a pill\n // that must read as inert. Omitting `whileHover` while disabled or loading\n // is Motion's intended off-switch: the gesture never engages (no inline\n // styles mutate), an in-flight hover springs back to `rest`, and restoring\n // the prop re-arms hover in place — no remount, no rest-state change.\n whileHover: inert ? undefined : \"hover\",\n variants: effectRootVariants(size),\n transition: EFFECT_SPRING,\n };\n}\n\n// Motion redefines these DOM handlers; drop them from our public props so\n// spreading onto a motion element type-checks cleanly.\ntype MotionConflicts =\n | \"onAnimationStart\"\n | \"onAnimationEnd\"\n | \"onAnimationIteration\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onDragEnter\"\n | \"onDragExit\"\n | \"onDragLeave\"\n | \"onDragOver\"\n | \"onDrop\"\n | \"style\";\n\ninterface EffectButtonBaseProps {\n /** Size variant. @default \"md\" */\n size?: EffectButtonSize;\n /** Stretch to the container's full width (stacked login / OAuth pills). */\n fullWidth?: boolean;\n /** Slot before the label — a component (`Plus`) or element (`<Plus />`). */\n prefix?: Slottable;\n /** Slot after the label. */\n suffix?: Slottable;\n /** Render as an icon-only button. Requires an `aria-label`. */\n svgOnly?: boolean;\n /** Show a spinner and block interaction while staying readable. */\n loading?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\nexport interface EffectButtonProps\n extends\n EffectButtonBaseProps,\n Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n keyof EffectButtonBaseProps | MotionConflicts\n > {\n ref?: Ref<HTMLButtonElement>;\n}\n\nexport interface EffectButtonLinkProps\n extends\n EffectButtonBaseProps,\n Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof EffectButtonBaseProps | MotionConflicts\n > {\n /** Navigate to this URL (rendered via the host's `LinkProvider`). */\n href: string;\n /** Visually and semantically disable the link. */\n disabled?: boolean;\n}\n\n/**\n * EffectButton — the glossy, springy pill ported frame-for-frame from Photon's\n * Framer \"Button - Effect\", driven by Motion. `fullWidth` stretches the pill\n * across its container. There is no variant axis — for a supporting/OAuth\n * pill without the sheen, use `<Button variant=\"secondary\">`.\n * Triggers an action; for navigation use {@link EffectButtonLink}.\n */\nexport function EffectButton({\n size = \"md\",\n fullWidth,\n prefix,\n suffix,\n svgOnly,\n loading,\n children,\n className,\n ref,\n ...props\n}: EffectButtonProps) {\n warnMissingLabel(svgOnly, props[\"aria-label\"]);\n return (\n <motion.button\n ref={ref}\n type=\"button\"\n {...effectMotionProps(size, props.disabled || loading)}\n {...props}\n aria-busy={loading || undefined}\n data-loading={loading ? \"true\" : undefined}\n data-svg-only={svgOnly ? \"true\" : undefined}\n className={cn(\n effectButtonVariants({ size, fullWidth }),\n loading && \"pointer-events-none\",\n svgOnly && \"[&>svg]:size-5 [&>svg]:shrink-0\",\n className,\n )}\n >\n {effectButtonInner({ svgOnly, loading, prefix, suffix, children })}\n </motion.button>\n );\n}\n\nEffectButton.displayName = \"EffectButton\";\n\n/**\n * EffectButtonLink — {@link EffectButton} as a link, for navigation that changes\n * the URL. Renders the host router's link (via `LinkProvider`) wrapped by Motion,\n * so the pill animates identically to the button.\n */\nexport function EffectButtonLink({\n size = \"md\",\n fullWidth,\n prefix,\n suffix,\n svgOnly,\n loading,\n disabled,\n href,\n children,\n className,\n ...props\n}: EffectButtonLinkProps) {\n warnMissingLabel(svgOnly, props[\"aria-label\"]);\n const Link = useLinkComponent();\n // Wrap the host link once per link identity so Motion can drive the DOM node.\n const MotionLink = useMemo(() => motion.create(Link), [Link]);\n return (\n <MotionLink\n href={href}\n {...effectMotionProps(size, disabled || loading)}\n {...(props as HTMLMotionProps<\"a\">)}\n aria-disabled={disabled || loading || undefined}\n aria-busy={loading || undefined}\n data-loading={loading ? \"true\" : undefined}\n data-svg-only={svgOnly ? \"true\" : undefined}\n className={cn(\n effectButtonVariants({ size, fullWidth }),\n loading && \"pointer-events-none\",\n svgOnly && \"[&>svg]:size-5 [&>svg]:shrink-0\",\n className,\n )}\n >\n {effectButtonInner({ svgOnly, loading, prefix, suffix, children })}\n </MotionLink>\n );\n}\n\nEffectButtonLink.displayName = \"EffectButtonLink\";\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as
|
|
2
|
+
import { t as r } from "./cn-7uGUzCOM.js";
|
|
3
3
|
import { t as n } from "./resolve-variant-CcD8iG5l.js";
|
|
4
4
|
import "react";
|
|
5
5
|
import { jsx as e } from "react/jsx-runtime";
|
|
@@ -9,12 +9,12 @@ var l = {
|
|
|
9
9
|
md: { classes: "size-10 *:size-5" },
|
|
10
10
|
lg: { classes: "size-11 *:size-6" }
|
|
11
11
|
};
|
|
12
|
-
function u({ size:
|
|
12
|
+
function u({ size: t = "sm", label: s, className: i, ...o }) {
|
|
13
13
|
return /* @__PURE__ */ e("button", {
|
|
14
14
|
type: "button",
|
|
15
|
-
"aria-label":
|
|
16
|
-
...
|
|
17
|
-
className:
|
|
15
|
+
"aria-label": s || "Close",
|
|
16
|
+
...o,
|
|
17
|
+
className: r("squircle text-fg-pho-quaternary outline-pho-brand hover:bg-pho-ghost-hover hover:text-fg-pho-quaternary-hover inline-flex cursor-pointer items-center justify-center rounded-md p-2 transition duration-100 ease-linear focus-visible:outline-2 focus-visible:outline-offset-2", n(l, t), i),
|
|
18
18
|
children: /* @__PURE__ */ e(a, {
|
|
19
19
|
"aria-hidden": "true",
|
|
20
20
|
weight: "bold",
|
|
@@ -27,4 +27,4 @@ export {
|
|
|
27
27
|
u as t
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
//# sourceMappingURL=close-button-
|
|
30
|
+
//# sourceMappingURL=close-button-DKaNIndU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"close-button-
|
|
1
|
+
{"version":3,"file":"close-button-DKaNIndU.js","names":[],"sources":["../../src/components/button/close-button.tsx"],"sourcesContent":["import { type ButtonHTMLAttributes } from \"react\";\nimport { X } from \"@phosphor-icons/react\";\nimport { cn } from \"../../utils/cn\";\nimport { resolveVariant, type VariantMap } from \"../../utils/resolve-variant\";\n\nconst CLOSE_SIZES = {\n sm: { classes: \"size-9 *:size-5\" },\n md: { classes: \"size-10 *:size-5\" },\n lg: { classes: \"size-11 *:size-6\" },\n} satisfies VariantMap;\n\nexport interface CloseButtonProps extends Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"color\"\n> {\n /** Size variant. @default \"sm\" */\n size?: keyof typeof CLOSE_SIZES;\n /** Accessible label. @default \"Close\" */\n label?: string;\n}\n\n/**\n * Icon-only dismiss control — a squircle chip that fills on hover. Adapts to\n * light/dark automatically via semantic tokens. Used by Dialog and dismissible\n * surfaces.\n */\nexport function CloseButton({\n size = \"sm\",\n label,\n className,\n ...props\n}: CloseButtonProps) {\n return (\n <button\n type=\"button\"\n aria-label={label || \"Close\"}\n {...props}\n className={cn(\n \"squircle text-fg-pho-quaternary outline-pho-brand hover:bg-pho-ghost-hover hover:text-fg-pho-quaternary-hover inline-flex cursor-pointer items-center justify-center rounded-md p-2 transition duration-100 ease-linear focus-visible:outline-2 focus-visible:outline-offset-2\",\n resolveVariant(CLOSE_SIZES, size),\n className,\n )}\n >\n <X\n aria-hidden=\"true\"\n weight=\"bold\"\n className=\"transition-inherit-all shrink-0\"\n />\n </button>\n );\n}\n\nCloseButton.displayName = \"CloseButton\";\n"],"mappings":";;;;;;AAKA,IAAM,IAAc;AAAA,EAClB,IAAI,EAAE,SAAS,kBAAkB;AAAA,EACjC,IAAI,EAAE,SAAS,mBAAmB;AAAA,EAClC,IAAI,EAAE,SAAS,mBAAmB;AACpC;AAiBA,SAAgB,EAAY,EAC1B,MAAA,IAAO,MACP,OAAA,GACA,WAAA,GACA,GAAG,EAAA,GACgB;AACnB,SACE,gBAAA,EAAC,UAAD;AAAA,IACE,MAAK;AAAA,IACL,cAAY,KAAS;AAAA,IACrB,GAAI;AAAA,IACJ,WAAW,EACT,kRACA,EAAe,GAAa,CAAI,GAChC,CACF;AAAA,cAEA,gBAAA,EAAC,GAAD;AAAA,MACE,eAAY;AAAA,MACZ,QAAO;AAAA,MACP,WAAU;AAAA,IACX,CAAA;AAAA,EACK,CAAA;AAEZ;AAEA,EAAY,cAAc"}
|
|
@@ -1749,8 +1749,7 @@ var $e = (e, t) => {
|
|
|
1749
1749
|
"display-sm",
|
|
1750
1750
|
"display-md",
|
|
1751
1751
|
"display-lg",
|
|
1752
|
-
"display-xl"
|
|
1753
|
-
"display-2xl"
|
|
1752
|
+
"display-xl"
|
|
1754
1753
|
] } } });
|
|
1755
1754
|
function Nr(...e) {
|
|
1756
1755
|
return Lr(Be(e));
|
|
@@ -1759,4 +1758,4 @@ export {
|
|
|
1759
1758
|
Nr as t
|
|
1760
1759
|
};
|
|
1761
1760
|
|
|
1762
|
-
//# sourceMappingURL=cn-
|
|
1761
|
+
//# sourceMappingURL=cn-7uGUzCOM.js.map
|