@espressif/dashboard-ui-components 1.2.2 → 1.3.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.
Files changed (34) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +15 -6
  3. package/dist/{app-logo.props-TKCDuodn.d.ts → app-logo.props-Ct7QBdTd.d.ts} +1 -1
  4. package/dist/{chunk-F5P6S7K2.js → chunk-7BO76CNB.js} +75 -14
  5. package/dist/{chunk-JPMN2UMF.js → chunk-KCMVLNM5.js} +12 -12
  6. package/dist/{chunk-YWRID3U3.js → chunk-O5BFYRPY.js} +1541 -339
  7. package/dist/{chunk-XDY5H3S3.js → chunk-RCRU3JW2.js} +40 -28
  8. package/dist/{chunk-IEHT62YM.js → chunk-RKAFXJRD.js} +3 -3
  9. package/dist/{chunk-4J5RO6E2.js → chunk-TSNA6BHK.js} +30 -8
  10. package/dist/{chunk-KGOWRVSU.js → chunk-UHRNPXO5.js} +404 -225
  11. package/dist/common/index.d.ts +4 -4
  12. package/dist/common/index.js +6 -6
  13. package/dist/components/index.d.ts +201 -13
  14. package/dist/components/index.js +4 -4
  15. package/dist/core/index.d.ts +2 -2
  16. package/dist/core/index.js +2 -2
  17. package/dist/{index-Cv9vHALn.d.ts → index-BQANnKs9.d.ts} +1 -1
  18. package/dist/index.d.ts +6 -6
  19. package/dist/index.js +7 -7
  20. package/dist/layouts/index.d.ts +20 -7
  21. package/dist/layouts/index.js +4 -4
  22. package/dist/{list.props-DBDJt4C1.d.ts → list.props-x1j3CbcF.d.ts} +1 -1
  23. package/dist/{popover-CRznb4Q7.d.ts → popover-ByLD3-Qv.d.ts} +21 -3
  24. package/dist/{types-4i2wWAqP.d.ts → types-DtUxK-Am.d.ts} +2 -2
  25. package/dist/utils/index.d.ts +1 -1
  26. package/package.json +4 -1
  27. package/src/assets/logos/launchpad/launchpad-no-text-dm.svg +1 -0
  28. package/src/assets/logos/launchpad/launchpad-no-text.svg +1 -1
  29. package/src/assets/logos/launchpad/launchpad-with-text-dm.svg +1 -1
  30. package/src/assets/logos/launchpad/launchpad-with-text.svg +46 -1
  31. package/src/assets/logos/zerocode-ai/zerocode-ai-no-text.svg +1 -0
  32. package/src/assets/logos/zerocode-ai/zerocode-ai-with-text-dm.svg +186 -0
  33. package/src/assets/logos/zerocode-ai/zerocode-ai-with-text.svg +246 -0
  34. package/src/styles/globals.css +93 -15
@@ -1,11 +1,11 @@
1
- import { getStrictContext, Button, Avatar, AvatarImage, AvatarFallback, AvatarBadge, useControlledState, useIsMobile, Separator, Skeleton, useDataState, Collapsible, CollapsibleTrigger, CollapsibleContent } from './chunk-F5P6S7K2.js';
1
+ import { getStrictContext, Button, Avatar, AvatarImage, AvatarFallback, AvatarBadge, useControlledState, useIsMobile, Separator, Skeleton, useDataState, Collapsible, CollapsibleTrigger, CollapsibleContent } from './chunk-7BO76CNB.js';
2
2
  import { cn, resolveColor, isPresetColor } from './chunk-VU4CZ76T.js';
3
- import { LoaderCircle, EyeOffIcon, EyeIcon, User, CheckIcon, CircleIcon, ChevronRightIcon, ArrowUpRightIcon, CopyIcon, XIcon, PanelLeftIcon, X, ChevronDown, CircleDot, Circle, ChevronRight } from 'lucide-react';
3
+ import { LoaderCircle, EyeOffIcon, EyeIcon, User, CheckIcon, CircleIcon, ChevronRightIcon, ArrowUpRightIcon, ZapIcon, CopyIcon, XIcon, PanelLeftIcon, X, ChevronDown, CircleDot, Circle, ChevronRight } from 'lucide-react';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
  import * as React from 'react';
6
6
  import React__default, { useState, useMemo, useEffect, useRef } from 'react';
7
7
  import { Slot as Slot$2, DropdownMenu as DropdownMenu$1, Dialog } from 'radix-ui';
8
- import { motion, LayoutGroup, AnimatePresence, isMotionComponent, useInView } from 'motion/react';
8
+ import { motion, LayoutGroup, AnimatePresence, isMotionComponent, useAnimate, useInView } from 'motion/react';
9
9
  import * as motion5 from 'motion/react-client';
10
10
  import { FloatingArrow, useFloating, autoUpdate, offset, flip, shift, arrow, FloatingPortal } from '@floating-ui/react';
11
11
  import { motion as motion$1 } from 'framer-motion';
@@ -2123,6 +2123,39 @@ var Button3 = React.forwardRef(
2123
2123
  }
2124
2124
  );
2125
2125
  Button3.displayName = "Button";
2126
+ var craftButtonBgClasses = {
2127
+ primary: "bg-primary text-primary-foreground",
2128
+ secondary: "bg-secondary text-secondary-foreground",
2129
+ error: "bg-error text-error-foreground",
2130
+ info: "bg-info text-info-foreground",
2131
+ success: "bg-success text-success-foreground",
2132
+ warning: "bg-warning text-warning-foreground",
2133
+ disabled: "bg-disabled text-disabled-foreground",
2134
+ gray: "bg-gray text-gray-foreground",
2135
+ mist: "bg-mist text-mist-foreground"
2136
+ };
2137
+ var craftButtonDarkBorderClasses = {
2138
+ primary: "dark:hover:border-primary/30",
2139
+ secondary: "dark:hover:border-secondary/30",
2140
+ error: "dark:hover:border-error/30",
2141
+ info: "dark:hover:border-info/30",
2142
+ success: "dark:hover:border-success/30",
2143
+ warning: "dark:hover:border-warning/30",
2144
+ disabled: "dark:hover:border-disabled/30",
2145
+ gray: "dark:hover:border-gray/30",
2146
+ mist: "dark:hover:border-mist-border/30"
2147
+ };
2148
+ var craftIconColorClasses = {
2149
+ primary: "text-primary group-hover:bg-primary group-hover:text-primary-foreground",
2150
+ secondary: "text-secondary group-hover:bg-secondary group-hover:text-secondary-foreground",
2151
+ error: "text-error group-hover:bg-error group-hover:text-error-foreground",
2152
+ info: "text-info group-hover:bg-info group-hover:text-info-foreground",
2153
+ success: "text-success group-hover:bg-success group-hover:text-success-foreground",
2154
+ warning: "text-warning group-hover:bg-warning group-hover:text-warning-foreground",
2155
+ disabled: "text-disabled group-hover:bg-disabled group-hover:text-disabled-foreground",
2156
+ gray: "text-gray group-hover:bg-gray group-hover:text-gray-foreground",
2157
+ mist: "text-mist-foreground group-hover:bg-mist group-hover:text-mist-foreground"
2158
+ };
2126
2159
  var CraftButtonContext = React.createContext({});
2127
2160
  function CraftButtonLabel({ children, className }) {
2128
2161
  return /* @__PURE__ */ jsx(
@@ -2137,7 +2170,7 @@ function CraftButtonLabel({ children, className }) {
2137
2170
  );
2138
2171
  }
2139
2172
  function CraftButtonIcon({ children, className }) {
2140
- const { size } = React.useContext(CraftButtonContext);
2173
+ const { size, color = "primary" } = React.useContext(CraftButtonContext);
2141
2174
  const iconSize = size === "lg" ? "size-6" : size === "sm" ? "size-4" : "size-5";
2142
2175
  return /* @__PURE__ */ jsxs("span", { className: cn("relative z-1", iconSize, className), children: [
2143
2176
  /* @__PURE__ */ jsx(
@@ -2153,7 +2186,8 @@ function CraftButtonIcon({ children, className }) {
2153
2186
  "span",
2154
2187
  {
2155
2188
  className: cn(
2156
- "bg-background text-primary group-hover:bg-primary group-hover:text-background relative z-2 flex items-center justify-center rounded-full transition-all duration-500",
2189
+ "bg-background relative z-2 flex items-center justify-center rounded-full transition-all duration-500",
2190
+ craftIconColorClasses[color],
2157
2191
  iconSize
2158
2192
  ),
2159
2193
  children
@@ -2162,14 +2196,23 @@ function CraftButtonIcon({ children, className }) {
2162
2196
  ] });
2163
2197
  }
2164
2198
  function CraftButton(props) {
2165
- const { children, size, asChild = false, className, ...rest } = props;
2166
- return /* @__PURE__ */ jsx(CraftButtonContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx(
2199
+ const {
2200
+ children,
2201
+ size,
2202
+ color = "primary",
2203
+ asChild = false,
2204
+ className,
2205
+ ...rest
2206
+ } = props;
2207
+ return /* @__PURE__ */ jsx(CraftButtonContext.Provider, { value: { size, color }, children: /* @__PURE__ */ jsx(
2167
2208
  Button3,
2168
2209
  {
2169
2210
  size,
2170
2211
  asChild,
2171
2212
  className: cn(
2172
- "group hover:bg-background dark:hover:border-primary/30 relative cursor-pointer overflow-hidden rounded-full duration-500 hover:shadow-md dark:border dark:border-transparent",
2213
+ craftButtonBgClasses[color],
2214
+ "group hover:bg-background relative cursor-pointer overflow-hidden rounded-full duration-500 hover:shadow-md dark:border dark:border-transparent",
2215
+ craftButtonDarkBorderClasses[color],
2173
2216
  className
2174
2217
  ),
2175
2218
  ...rest,
@@ -2183,6 +2226,136 @@ function InvertButton({ label, icon, ...props }) {
2183
2226
  /* @__PURE__ */ jsx(CraftButtonIcon, { children: icon ?? /* @__PURE__ */ jsx(ArrowUpRightIcon, { className: "size-3 stroke-2 transition-transform duration-500 group-hover:rotate-45" }) })
2184
2227
  ] });
2185
2228
  }
2229
+ var flashButtonBgClasses = {
2230
+ primary: "bg-primary hover:bg-background text-primary-foreground",
2231
+ secondary: "bg-secondary hover:bg-background text-secondary-foreground",
2232
+ error: "bg-error hover:bg-background text-error-foreground",
2233
+ info: "bg-info hover:bg-background text-info-foreground",
2234
+ success: "bg-success hover:bg-background text-success-foreground",
2235
+ warning: "bg-warning hover:bg-background text-warning-foreground",
2236
+ disabled: "bg-disabled hover:bg-background text-disabled-foreground",
2237
+ gray: "bg-gray hover:bg-background text-gray-foreground",
2238
+ mist: "bg-mist hover:bg-background text-mist-foreground"
2239
+ };
2240
+ var flashOverlayClasses = {
2241
+ primary: "bg-primary",
2242
+ secondary: "bg-secondary",
2243
+ error: "bg-error",
2244
+ info: "bg-info",
2245
+ success: "bg-success",
2246
+ warning: "bg-warning",
2247
+ disabled: "bg-disabled",
2248
+ gray: "bg-gray",
2249
+ mist: "bg-mist"
2250
+ };
2251
+ var flashButtonDarkBorderClasses = {
2252
+ primary: "dark:hover:border-primary/30",
2253
+ secondary: "dark:hover:border-secondary/30",
2254
+ error: "dark:hover:border-error/30",
2255
+ info: "dark:hover:border-info/30",
2256
+ success: "dark:hover:border-success/30",
2257
+ warning: "dark:hover:border-warning/30",
2258
+ disabled: "dark:hover:border-disabled/30",
2259
+ gray: "dark:hover:border-gray/30",
2260
+ mist: "dark:hover:border-mist-border/30"
2261
+ };
2262
+ function FlashButton({
2263
+ label,
2264
+ icon,
2265
+ iconPosition = "end",
2266
+ hideIcon = false,
2267
+ size,
2268
+ color = "primary",
2269
+ className,
2270
+ onMouseEnter,
2271
+ onMouseLeave,
2272
+ ...props
2273
+ }) {
2274
+ const [scope, animate] = useAnimate();
2275
+ const isHovering = React.useRef(false);
2276
+ const flashLoop = React.useCallback(async () => {
2277
+ while (isHovering.current && scope.current) {
2278
+ const peakOpacity = 0.5 + Math.random() * 0.5;
2279
+ try {
2280
+ await animate(
2281
+ scope.current,
2282
+ { opacity: [0, peakOpacity, 0] },
2283
+ { duration: 0.08 + Math.random() * 0.14, ease: "easeOut" }
2284
+ );
2285
+ } catch {
2286
+ break;
2287
+ }
2288
+ if (!isHovering.current) break;
2289
+ const pause = 60 + Math.random() * 250;
2290
+ await new Promise((r) => setTimeout(r, pause));
2291
+ }
2292
+ }, [animate, scope]);
2293
+ const handleMouseEnter = React.useCallback(
2294
+ (e) => {
2295
+ isHovering.current = true;
2296
+ flashLoop();
2297
+ onMouseEnter?.(e);
2298
+ },
2299
+ [flashLoop, onMouseEnter]
2300
+ );
2301
+ const handleMouseLeave = React.useCallback(
2302
+ (e) => {
2303
+ isHovering.current = false;
2304
+ if (scope.current) {
2305
+ animate(scope.current, { opacity: 0 }, { duration: 0.05 });
2306
+ }
2307
+ onMouseLeave?.(e);
2308
+ },
2309
+ [animate, scope, onMouseLeave]
2310
+ );
2311
+ const iconSize = size === "lg" ? "size-4" : size === "sm" ? "size-2.5" : "size-3";
2312
+ return /* @__PURE__ */ jsxs(
2313
+ Button3,
2314
+ {
2315
+ size,
2316
+ className: cn(
2317
+ flashButtonBgClasses[color],
2318
+ "group relative cursor-pointer gap-1.5 overflow-hidden rounded-full transition-all duration-500 hover:shadow-md dark:border dark:border-transparent",
2319
+ flashButtonDarkBorderClasses[color],
2320
+ className
2321
+ ),
2322
+ onMouseEnter: handleMouseEnter,
2323
+ onMouseLeave: handleMouseLeave,
2324
+ ...props,
2325
+ children: [
2326
+ /* @__PURE__ */ jsx(
2327
+ "span",
2328
+ {
2329
+ ref: scope,
2330
+ className: cn(
2331
+ "pointer-events-none absolute inset-0 z-0 rounded-[inherit] opacity-0",
2332
+ flashOverlayClasses[color]
2333
+ )
2334
+ }
2335
+ ),
2336
+ !hideIcon && iconPosition === "start" && /* @__PURE__ */ jsx("span", { className: "relative z-[1]", children: icon ?? /* @__PURE__ */ jsx(
2337
+ ZapIcon,
2338
+ {
2339
+ className: cn(
2340
+ iconSize,
2341
+ "stroke-2 transition-all duration-500 group-hover:scale-110 group-hover:text-foreground"
2342
+ )
2343
+ }
2344
+ ) }),
2345
+ /* @__PURE__ */ jsx("span", { className: "relative z-[1] transition-colors duration-500 group-hover:text-foreground", children: label }),
2346
+ !hideIcon && iconPosition === "end" && /* @__PURE__ */ jsx("span", { className: "relative z-[1]", children: icon ?? /* @__PURE__ */ jsx(
2347
+ ZapIcon,
2348
+ {
2349
+ className: cn(
2350
+ iconSize,
2351
+ "stroke-2 transition-all duration-500 group-hover:scale-110 group-hover:text-foreground"
2352
+ )
2353
+ }
2354
+ ) })
2355
+ ]
2356
+ }
2357
+ );
2358
+ }
2186
2359
  function Button4({
2187
2360
  hoverScale = 1.05,
2188
2361
  tapScale = 0.95,
@@ -2336,215 +2509,6 @@ function Menu({
2336
2509
  )
2337
2510
  ] });
2338
2511
  }
2339
- var inputLabelClassName = "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50";
2340
- var sizeClasses2 = {
2341
- sm: "h-8 px-2 text-xs",
2342
- default: "h-10 px-3 py-2 text-base md:text-sm",
2343
- lg: "h-12 px-4 text-lg"
2344
- };
2345
- var Input = React.forwardRef(
2346
- ({
2347
- className,
2348
- type,
2349
- label,
2350
- size,
2351
- rounded,
2352
- startHelperContent,
2353
- endHelperContent,
2354
- hintContent,
2355
- error,
2356
- errorContent,
2357
- startIcon,
2358
- endIcon,
2359
- startAddOnContent,
2360
- endAddOnContent,
2361
- startAddOn,
2362
- endAddOn,
2363
- floatingLabel,
2364
- charLimit,
2365
- onChange,
2366
- value,
2367
- defaultValue,
2368
- id,
2369
- required,
2370
- placeholder,
2371
- ...restProps
2372
- }, ref) => {
2373
- const autoId = React.useId();
2374
- const inputId = id || autoId;
2375
- const [charCount, setCharCount] = React.useState(() => {
2376
- if (charLimit === void 0) return 0;
2377
- if (typeof value === "string") return value.length;
2378
- if (typeof defaultValue === "string") return defaultValue.length;
2379
- return 0;
2380
- });
2381
- React.useEffect(() => {
2382
- if (charLimit !== void 0 && typeof value === "string") {
2383
- setCharCount(value.length);
2384
- }
2385
- }, [value, charLimit]);
2386
- const hasEnhancedProps = label !== void 0 || size !== void 0 || rounded !== void 0 || startHelperContent !== void 0 || endHelperContent !== void 0 || hintContent !== void 0 || error !== void 0 || errorContent !== void 0 || startIcon !== void 0 || endIcon !== void 0 || startAddOnContent !== void 0 || endAddOnContent !== void 0 || startAddOn !== void 0 || endAddOn !== void 0 || floatingLabel !== void 0 || charLimit !== void 0;
2387
- if (!hasEnhancedProps) {
2388
- return /* @__PURE__ */ jsx(
2389
- "input",
2390
- {
2391
- type,
2392
- id,
2393
- className: cn(
2394
- "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background transition-[box-shadow,border-color] duration-200 ease-in-out file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 read-only:bg-muted md:text-sm",
2395
- className
2396
- ),
2397
- ref,
2398
- onChange,
2399
- value,
2400
- defaultValue,
2401
- required,
2402
- placeholder,
2403
- ...restProps
2404
- }
2405
- );
2406
- }
2407
- const effectiveSize = size || "default";
2408
- const hasError = error || !!errorContent;
2409
- const handleChange = (e) => {
2410
- if (charLimit !== void 0) {
2411
- setCharCount(e.target.value.length);
2412
- }
2413
- onChange?.(e);
2414
- };
2415
- const effectivePlaceholder = floatingLabel ? " " : placeholder;
2416
- const resolveAddOn = (content, text) => content != null && content !== false && content !== "" ? content : text || void 0;
2417
- const startAddOnNode = resolveAddOn(startAddOnContent, startAddOn);
2418
- const endAddOnNode = resolveAddOn(endAddOnContent, endAddOn);
2419
- const hasAddOn = startAddOnNode != null || endAddOnNode != null;
2420
- const hasOverlay = !!startIcon || !!endIcon || charLimit !== void 0 || !!floatingLabel;
2421
- const helperStartId = `${inputId}-helper-start`;
2422
- const helperEndId = `${inputId}-helper-end`;
2423
- const describedBy = [
2424
- errorContent && `${inputId}-error`,
2425
- startHelperContent && !errorContent && helperStartId,
2426
- endHelperContent && !errorContent && helperEndId
2427
- ].filter(Boolean).join(" ") || void 0;
2428
- const inputClasses = cn(
2429
- "flex w-full border border-input bg-background ring-offset-background transition-[box-shadow,border-color] duration-200 ease-in-out file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 read-only:bg-muted z-10",
2430
- floatingLabel ? "h-12 px-3 pt-4 pb-1 text-base md:text-sm" : sizeClasses2[effectiveSize],
2431
- rounded ? "rounded-full" : "rounded-md",
2432
- hasError && "border-destructive focus-visible:ring-destructive",
2433
- startIcon && "ps-9",
2434
- endIcon && "pe-9",
2435
- charLimit !== void 0 && !endIcon && "pe-14",
2436
- charLimit !== void 0 && endIcon && "pe-20",
2437
- startAddOnNode != null && "rounded-s-none shadow-none",
2438
- endAddOnNode != null && "rounded-e-none shadow-none",
2439
- // `peer` is a marker only; the overlay decorators are later siblings and
2440
- // rely on it for `peer-disabled:` / `peer-placeholder-shown:` variants.
2441
- "peer",
2442
- floatingLabel && "placeholder:text-transparent",
2443
- className
2444
- );
2445
- const inputElement = /* @__PURE__ */ jsx(
2446
- "input",
2447
- {
2448
- type,
2449
- id: inputId,
2450
- ref,
2451
- className: inputClasses,
2452
- required,
2453
- "aria-invalid": hasError || void 0,
2454
- "aria-describedby": describedBy,
2455
- onChange: handleChange,
2456
- value,
2457
- defaultValue,
2458
- maxLength: charLimit,
2459
- placeholder: effectivePlaceholder,
2460
- ...restProps
2461
- }
2462
- );
2463
- let inputContainer = inputElement;
2464
- if (hasOverlay) {
2465
- inputContainer = /* @__PURE__ */ jsxs("div", { className: "group relative min-w-0 flex-1", children: [
2466
- inputElement,
2467
- startIcon && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-muted-foreground/80 peer-disabled:opacity-50", children: startIcon }),
2468
- (endIcon || charLimit !== void 0) && /* @__PURE__ */ jsxs("div", { className: "pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center gap-2 pe-3 text-muted-foreground/80 peer-disabled:opacity-50", children: [
2469
- charLimit !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-xs tabular-nums text-muted-foreground", children: [
2470
- charCount,
2471
- "/",
2472
- charLimit
2473
- ] }),
2474
- endIcon
2475
- ] }),
2476
- floatingLabel && label && /* @__PURE__ */ jsxs(
2477
- "label",
2478
- {
2479
- htmlFor: inputId,
2480
- className: "absolute start-2 top-0 z-10 block -translate-y-1/2 bg-background px-2 text-xs font-medium text-foreground/70 transition-all peer-placeholder-shown:top-1/2 peer-placeholder-shown:text-sm peer-placeholder-shown:font-normal peer-focus:top-0 peer-focus:text-xs peer-focus:font-medium",
2481
- children: [
2482
- label,
2483
- required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: " *" })
2484
- ]
2485
- }
2486
- )
2487
- ] });
2488
- }
2489
- if (hasAddOn) {
2490
- inputContainer = /* @__PURE__ */ jsxs("div", { className: "flex rounded-lg", children: [
2491
- startAddOnNode != null && /* @__PURE__ */ jsx("span", { className: "-me-px inline-flex items-center rounded-s-lg border border-input bg-background px-3 text-sm text-muted-foreground", children: startAddOnNode }),
2492
- inputContainer,
2493
- endAddOnNode != null && /* @__PURE__ */ jsx("span", { className: "-ms-px inline-flex items-center rounded-e-lg border border-input bg-background px-3 text-sm text-muted-foreground", children: endAddOnNode })
2494
- ] });
2495
- }
2496
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2 flex-1", children: [
2497
- label && !floatingLabel && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
2498
- /* @__PURE__ */ jsxs("label", { htmlFor: inputId, className: inputLabelClassName, children: [
2499
- label,
2500
- required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" })
2501
- ] }),
2502
- hintContent && /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: hintContent })
2503
- ] }),
2504
- !label && hintContent && /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: hintContent }),
2505
- inputContainer,
2506
- errorContent && /* @__PURE__ */ jsx("div", { id: `${inputId}-error`, className: "text-sm text-destructive", children: errorContent }),
2507
- startHelperContent && !errorContent && /* @__PURE__ */ jsx("div", { id: helperStartId, className: "text-sm text-muted-foreground", children: startHelperContent }),
2508
- endHelperContent && !errorContent && /* @__PURE__ */ jsx(
2509
- "div",
2510
- {
2511
- id: helperEndId,
2512
- className: "text-sm text-end text-muted-foreground",
2513
- children: endHelperContent
2514
- }
2515
- )
2516
- ] });
2517
- }
2518
- );
2519
- Input.displayName = "Input";
2520
- var InputPassword = React.forwardRef(
2521
- ({ className, ...props }, ref) => {
2522
- const [isVisible, setIsVisible] = useState(false);
2523
- return /* @__PURE__ */ jsx(
2524
- Input,
2525
- {
2526
- ref,
2527
- type: isVisible ? "text" : "password",
2528
- className: cn("pr-9", className),
2529
- endIcon: /* @__PURE__ */ jsxs(
2530
- "button",
2531
- {
2532
- type: "button",
2533
- onClick: () => setIsVisible((prev) => !prev),
2534
- className: "pointer-events-auto cursor-pointer text-muted-foreground hover:text-foreground",
2535
- tabIndex: -1,
2536
- children: [
2537
- isVisible ? /* @__PURE__ */ jsx(EyeOffIcon, { size: 16 }) : /* @__PURE__ */ jsx(EyeIcon, { size: 16 }),
2538
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: isVisible ? "Hide password" : "Show password" })
2539
- ]
2540
- }
2541
- ),
2542
- ...props
2543
- }
2544
- );
2545
- }
2546
- );
2547
- InputPassword.displayName = "InputPassword";
2548
2512
  var [SheetProvider, useSheet] = getStrictContext("SheetContext");
2549
2513
  function Sheet(props) {
2550
2514
  const [isOpen, setIsOpen] = useControlledState({
@@ -2789,6 +2753,215 @@ function SheetDescription2({ className, ...props }) {
2789
2753
  }
2790
2754
  );
2791
2755
  }
2756
+ var inputLabelClassName = "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50";
2757
+ var sizeClasses2 = {
2758
+ sm: "h-8 px-2 text-xs",
2759
+ default: "h-10 px-3 py-2 text-base md:text-sm",
2760
+ lg: "h-12 px-4 text-lg"
2761
+ };
2762
+ var Input = React.forwardRef(
2763
+ ({
2764
+ className,
2765
+ type,
2766
+ label,
2767
+ size,
2768
+ rounded,
2769
+ startHelperContent,
2770
+ endHelperContent,
2771
+ hintContent,
2772
+ error,
2773
+ errorContent,
2774
+ startIcon,
2775
+ endIcon,
2776
+ startAddOnContent,
2777
+ endAddOnContent,
2778
+ startAddOn,
2779
+ endAddOn,
2780
+ floatingLabel,
2781
+ charLimit,
2782
+ onChange,
2783
+ value,
2784
+ defaultValue,
2785
+ id,
2786
+ required,
2787
+ placeholder,
2788
+ ...restProps
2789
+ }, ref) => {
2790
+ const autoId = React.useId();
2791
+ const inputId = id || autoId;
2792
+ const [charCount, setCharCount] = React.useState(() => {
2793
+ if (charLimit === void 0) return 0;
2794
+ if (typeof value === "string") return value.length;
2795
+ if (typeof defaultValue === "string") return defaultValue.length;
2796
+ return 0;
2797
+ });
2798
+ React.useEffect(() => {
2799
+ if (charLimit !== void 0 && typeof value === "string") {
2800
+ setCharCount(value.length);
2801
+ }
2802
+ }, [value, charLimit]);
2803
+ const hasEnhancedProps = label !== void 0 || size !== void 0 || rounded !== void 0 || startHelperContent !== void 0 || endHelperContent !== void 0 || hintContent !== void 0 || error !== void 0 || errorContent !== void 0 || startIcon !== void 0 || endIcon !== void 0 || startAddOnContent !== void 0 || endAddOnContent !== void 0 || startAddOn !== void 0 || endAddOn !== void 0 || floatingLabel !== void 0 || charLimit !== void 0;
2804
+ if (!hasEnhancedProps) {
2805
+ return /* @__PURE__ */ jsx(
2806
+ "input",
2807
+ {
2808
+ type,
2809
+ id,
2810
+ className: cn(
2811
+ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background transition-[box-shadow,border-color] duration-200 ease-in-out file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 read-only:bg-muted md:text-sm",
2812
+ className
2813
+ ),
2814
+ ref,
2815
+ onChange,
2816
+ value,
2817
+ defaultValue,
2818
+ required,
2819
+ placeholder,
2820
+ ...restProps
2821
+ }
2822
+ );
2823
+ }
2824
+ const effectiveSize = size || "default";
2825
+ const hasError = error || !!errorContent;
2826
+ const handleChange = (e) => {
2827
+ if (charLimit !== void 0) {
2828
+ setCharCount(e.target.value.length);
2829
+ }
2830
+ onChange?.(e);
2831
+ };
2832
+ const effectivePlaceholder = floatingLabel ? " " : placeholder;
2833
+ const resolveAddOn = (content, text) => content != null && content !== false && content !== "" ? content : text || void 0;
2834
+ const startAddOnNode = resolveAddOn(startAddOnContent, startAddOn);
2835
+ const endAddOnNode = resolveAddOn(endAddOnContent, endAddOn);
2836
+ const hasAddOn = startAddOnNode != null || endAddOnNode != null;
2837
+ const hasOverlay = !!startIcon || !!endIcon || charLimit !== void 0 || !!floatingLabel;
2838
+ const helperStartId = `${inputId}-helper-start`;
2839
+ const helperEndId = `${inputId}-helper-end`;
2840
+ const describedBy = [
2841
+ errorContent && `${inputId}-error`,
2842
+ startHelperContent && !errorContent && helperStartId,
2843
+ endHelperContent && !errorContent && helperEndId
2844
+ ].filter(Boolean).join(" ") || void 0;
2845
+ const inputClasses = cn(
2846
+ "flex w-full border border-input bg-background ring-offset-background transition-[box-shadow,border-color] duration-200 ease-in-out file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 read-only:bg-muted z-10",
2847
+ floatingLabel ? "h-12 px-3 pt-4 pb-1 text-base md:text-sm" : sizeClasses2[effectiveSize],
2848
+ rounded ? "rounded-full" : "rounded-md",
2849
+ hasError && "border-destructive focus-visible:ring-destructive",
2850
+ startIcon && "ps-9",
2851
+ endIcon && "pe-9",
2852
+ charLimit !== void 0 && !endIcon && "pe-14",
2853
+ charLimit !== void 0 && endIcon && "pe-20",
2854
+ startAddOnNode != null && "rounded-s-none shadow-none",
2855
+ endAddOnNode != null && "rounded-e-none shadow-none",
2856
+ // `peer` is a marker only; the overlay decorators are later siblings and
2857
+ // rely on it for `peer-disabled:` / `peer-placeholder-shown:` variants.
2858
+ "peer",
2859
+ floatingLabel && "placeholder:text-transparent",
2860
+ className
2861
+ );
2862
+ const inputElement = /* @__PURE__ */ jsx(
2863
+ "input",
2864
+ {
2865
+ type,
2866
+ id: inputId,
2867
+ ref,
2868
+ className: inputClasses,
2869
+ required,
2870
+ "aria-invalid": hasError || void 0,
2871
+ "aria-describedby": describedBy,
2872
+ onChange: handleChange,
2873
+ value,
2874
+ defaultValue,
2875
+ maxLength: charLimit,
2876
+ placeholder: effectivePlaceholder,
2877
+ ...restProps
2878
+ }
2879
+ );
2880
+ let inputContainer = inputElement;
2881
+ if (hasOverlay) {
2882
+ inputContainer = /* @__PURE__ */ jsxs("div", { className: "group relative min-w-0 flex-1", children: [
2883
+ inputElement,
2884
+ startIcon && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-muted-foreground/80 peer-disabled:opacity-50", children: startIcon }),
2885
+ (endIcon || charLimit !== void 0) && /* @__PURE__ */ jsxs("div", { className: "pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center gap-2 pe-3 text-muted-foreground/80 peer-disabled:opacity-50", children: [
2886
+ charLimit !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-xs tabular-nums text-muted-foreground", children: [
2887
+ charCount,
2888
+ "/",
2889
+ charLimit
2890
+ ] }),
2891
+ endIcon
2892
+ ] }),
2893
+ floatingLabel && label && /* @__PURE__ */ jsxs(
2894
+ "label",
2895
+ {
2896
+ htmlFor: inputId,
2897
+ className: "absolute start-2 top-0 z-10 block -translate-y-1/2 bg-background px-2 text-xs font-medium text-foreground/70 transition-all peer-placeholder-shown:top-1/2 peer-placeholder-shown:text-sm peer-placeholder-shown:font-normal peer-focus:top-0 peer-focus:text-xs peer-focus:font-medium",
2898
+ children: [
2899
+ label,
2900
+ required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: " *" })
2901
+ ]
2902
+ }
2903
+ )
2904
+ ] });
2905
+ }
2906
+ if (hasAddOn) {
2907
+ inputContainer = /* @__PURE__ */ jsxs("div", { className: "flex rounded-lg", children: [
2908
+ startAddOnNode != null && /* @__PURE__ */ jsx("span", { className: "-me-px inline-flex items-center rounded-s-lg border border-input bg-background px-3 text-sm text-muted-foreground", children: startAddOnNode }),
2909
+ inputContainer,
2910
+ endAddOnNode != null && /* @__PURE__ */ jsx("span", { className: "-ms-px inline-flex items-center rounded-e-lg border border-input bg-background px-3 text-sm text-muted-foreground", children: endAddOnNode })
2911
+ ] });
2912
+ }
2913
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2 flex-1", children: [
2914
+ label && !floatingLabel && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
2915
+ /* @__PURE__ */ jsxs("label", { htmlFor: inputId, className: inputLabelClassName, children: [
2916
+ label,
2917
+ required && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: "*" })
2918
+ ] }),
2919
+ hintContent && /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: hintContent })
2920
+ ] }),
2921
+ !label && hintContent && /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: hintContent }),
2922
+ inputContainer,
2923
+ errorContent && /* @__PURE__ */ jsx("div", { id: `${inputId}-error`, className: "text-sm text-destructive", children: errorContent }),
2924
+ startHelperContent && !errorContent && /* @__PURE__ */ jsx("div", { id: helperStartId, className: "text-sm text-muted-foreground", children: startHelperContent }),
2925
+ endHelperContent && !errorContent && /* @__PURE__ */ jsx(
2926
+ "div",
2927
+ {
2928
+ id: helperEndId,
2929
+ className: "text-sm text-end text-muted-foreground",
2930
+ children: endHelperContent
2931
+ }
2932
+ )
2933
+ ] });
2934
+ }
2935
+ );
2936
+ Input.displayName = "Input";
2937
+ var InputPassword = React.forwardRef(
2938
+ ({ className, ...props }, ref) => {
2939
+ const [isVisible, setIsVisible] = useState(false);
2940
+ return /* @__PURE__ */ jsx(
2941
+ Input,
2942
+ {
2943
+ ref,
2944
+ type: isVisible ? "text" : "password",
2945
+ className: cn("pr-9", className),
2946
+ endIcon: /* @__PURE__ */ jsxs(
2947
+ "button",
2948
+ {
2949
+ type: "button",
2950
+ onClick: () => setIsVisible((prev) => !prev),
2951
+ className: "pointer-events-auto cursor-pointer text-muted-foreground hover:text-foreground",
2952
+ tabIndex: -1,
2953
+ children: [
2954
+ isVisible ? /* @__PURE__ */ jsx(EyeOffIcon, { size: 16 }) : /* @__PURE__ */ jsx(EyeIcon, { size: 16 }),
2955
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: isVisible ? "Hide password" : "Show password" })
2956
+ ]
2957
+ }
2958
+ ),
2959
+ ...props
2960
+ }
2961
+ );
2962
+ }
2963
+ );
2964
+ InputPassword.displayName = "InputPassword";
2792
2965
  var SIDEBAR_COOKIE_NAME = "sidebar_state";
2793
2966
  var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
2794
2967
  var SIDEBAR_WIDTH = "var(--espd-sidebar-width)";
@@ -3445,7 +3618,7 @@ function ItemIcon({
3445
3618
  function GroupMenuItems({
3446
3619
  group,
3447
3620
  isSelected,
3448
- LinkComponent,
3621
+ linkComponent: LinkComponent,
3449
3622
  onItemClick
3450
3623
  }) {
3451
3624
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -3477,7 +3650,7 @@ function GroupMenuItems({
3477
3650
  function CollapsedSidebarGroup({
3478
3651
  group,
3479
3652
  isSelected,
3480
- LinkComponent
3653
+ linkComponent: LinkComponent
3481
3654
  }) {
3482
3655
  const [open, setOpen] = useState(false);
3483
3656
  return /* @__PURE__ */ jsx(SidebarGroup, { className: sidebarGroupClassName, children: /* @__PURE__ */ jsx(SidebarMenu, { className: "w-auto", children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(DropdownMenu2, { open, onOpenChange: setOpen, children: [
@@ -3495,7 +3668,7 @@ function CollapsedSidebarGroup({
3495
3668
  {
3496
3669
  group,
3497
3670
  isSelected,
3498
- LinkComponent,
3671
+ linkComponent: LinkComponent,
3499
3672
  onItemClick: () => setOpen(false)
3500
3673
  }
3501
3674
  )
@@ -3540,7 +3713,7 @@ function Sidebar2({
3540
3713
  header,
3541
3714
  headerHeight,
3542
3715
  footer,
3543
- LinkComponent,
3716
+ linkComponent: LinkComponent,
3544
3717
  collapsible = "icon",
3545
3718
  variant = "sidebar",
3546
3719
  focusActiveGroup = false
@@ -3598,8 +3771,8 @@ function Sidebar2({
3598
3771
  // Selected-row fill spelled out here rather than left to the primitive's
3599
3772
  // `data-[active=true]:bg-sidebar-accent`: that rule needs `data-active` on the
3600
3773
  // rendered element, and `asChild` hands the data attributes to the app's
3601
- // LinkComponent, which need not forward them. `className` is the one prop every
3602
- // LinkComponent takes, so it is the only reliable channel. `isActive` above
3774
+ // `linkComponent`, which need not forward them. `className` is the one prop every
3775
+ // `linkComponent` takes, so it is the only reliable channel. `isActive` above
3603
3776
  // still sets `data-active` for apps that do forward it, and for test selectors.
3604
3777
  active && "bg-sidebar-accent text-sidebar-accent-foreground",
3605
3778
  // Reserve room for the endAction. The primitive does this with
@@ -3635,7 +3808,7 @@ function Sidebar2({
3635
3808
  {
3636
3809
  group,
3637
3810
  isSelected,
3638
- LinkComponent
3811
+ linkComponent: LinkComponent
3639
3812
  },
3640
3813
  group.id
3641
3814
  );
@@ -3713,6 +3886,10 @@ var colorClasses = {
3713
3886
  warning: "px-2 h-8 text-sm font-medium text-warning hover:bg-warning/10",
3714
3887
  gray: "px-2 h-8 text-sm font-medium text-gray hover:bg-gray/10"
3715
3888
  };
3889
+ var variantClasses = {
3890
+ default: "",
3891
+ ghost: "h-auto hover:bg-transparent p-0"
3892
+ };
3716
3893
  var underlineClasses = "relative no-underline after:absolute after:-bottom-0.5 after:left-0 after:h-px after:w-full after:bg-current hover:after:animate-underline-slide";
3717
3894
  function renderIconSlot(icon) {
3718
3895
  if (icon == null) return null;
@@ -3725,6 +3902,7 @@ var Link = React.forwardRef(
3725
3902
  search,
3726
3903
  linkComponent,
3727
3904
  color = "primary",
3905
+ variant = "default",
3728
3906
  underline = false,
3729
3907
  startIcon,
3730
3908
  endIcon,
@@ -3735,6 +3913,7 @@ var Link = React.forwardRef(
3735
3913
  const merged = cn(
3736
3914
  baseClasses,
3737
3915
  color != null && colorClasses[color],
3916
+ variantClasses[variant],
3738
3917
  underline && underlineClasses,
3739
3918
  className
3740
3919
  );
@@ -4061,4 +4240,4 @@ function parseTextMarkup(text) {
4061
4240
  return parts;
4062
4241
  }
4063
4242
 
4064
- export { Avatar2 as Avatar, Button2 as Button, CopyButton, DropdownMenu2 as DropdownMenu, DropdownMenuCheckboxItem2 as DropdownMenuCheckboxItem, DropdownMenuContent2 as DropdownMenuContent, DropdownMenuGroup2 as DropdownMenuGroup, DropdownMenuItem2 as DropdownMenuItem, DropdownMenuLabel2 as DropdownMenuLabel, DropdownMenuRadioGroup2 as DropdownMenuRadioGroup, DropdownMenuRadioItem2 as DropdownMenuRadioItem, DropdownMenuSeparator2 as DropdownMenuSeparator, DropdownMenuShortcut2 as DropdownMenuShortcut, DropdownMenuSub2 as DropdownMenuSub, DropdownMenuSubContent2 as DropdownMenuSubContent, DropdownMenuSubTrigger2 as DropdownMenuSubTrigger, DropdownMenuTrigger2 as DropdownMenuTrigger, GlitchText, GradientText, Highlight, HighlightItem, HighlightText, Input, InputPassword, InvertButton, LIST_CLASS_NAMES, Link, List, Menu, ScrollArea, ScrollBar, Sheet2 as Sheet, SheetClose2 as SheetClose, SheetContent2 as SheetContent, SheetDescription2 as SheetDescription, SheetFooter2 as SheetFooter, SheetHeader2 as SheetHeader, SheetTitle2 as SheetTitle, SheetTrigger2 as SheetTrigger, ShimmeringText, Sidebar, Sidebar2, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Slot, Tooltip2 as Tooltip, Tooltip3 as Tooltip2, TooltipContent2 as TooltipContent, TooltipProvider2 as TooltipProvider, TooltipTrigger2 as TooltipTrigger, buttonVariants3 as buttonVariants, inputLabelClassName, isPathPrefixOf, isSidebarGroup, parseTextMarkup, useSidebar };
4243
+ export { Avatar2 as Avatar, Button2 as Button, CopyButton, DropdownMenu2 as DropdownMenu, DropdownMenuCheckboxItem2 as DropdownMenuCheckboxItem, DropdownMenuContent2 as DropdownMenuContent, DropdownMenuGroup2 as DropdownMenuGroup, DropdownMenuItem2 as DropdownMenuItem, DropdownMenuLabel2 as DropdownMenuLabel, DropdownMenuRadioGroup2 as DropdownMenuRadioGroup, DropdownMenuRadioItem2 as DropdownMenuRadioItem, DropdownMenuSeparator2 as DropdownMenuSeparator, DropdownMenuShortcut2 as DropdownMenuShortcut, DropdownMenuSub2 as DropdownMenuSub, DropdownMenuSubContent2 as DropdownMenuSubContent, DropdownMenuSubTrigger2 as DropdownMenuSubTrigger, DropdownMenuTrigger2 as DropdownMenuTrigger, FlashButton, GlitchText, GradientText, Highlight, HighlightItem, HighlightText, Input, InputPassword, InvertButton, LIST_CLASS_NAMES, Link, List, Menu, ScrollArea, ScrollBar, Sheet2 as Sheet, SheetClose2 as SheetClose, SheetContent2 as SheetContent, SheetDescription2 as SheetDescription, SheetFooter2 as SheetFooter, SheetHeader2 as SheetHeader, SheetTitle2 as SheetTitle, SheetTrigger2 as SheetTrigger, ShimmeringText, Sidebar, Sidebar2, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Slot, Tooltip2 as Tooltip, Tooltip3 as Tooltip2, TooltipContent2 as TooltipContent, TooltipProvider2 as TooltipProvider, TooltipTrigger2 as TooltipTrigger, buttonVariants3 as buttonVariants, inputLabelClassName, isPathPrefixOf, isSidebarGroup, parseTextMarkup, useSidebar };