@webdevarif/dashui 0.3.1 → 0.3.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/index.mjs CHANGED
@@ -3164,10 +3164,126 @@ function PostSidebarSection({
3164
3164
  ] });
3165
3165
  }
3166
3166
 
3167
+ // src/components/ui/hsl-color-input.tsx
3168
+ import { useState as useState7, useRef as useRef4, useEffect as useEffect5, useCallback } from "react";
3169
+ import { HslColorPicker } from "react-colorful";
3170
+ import { jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
3171
+ function parseHsl(value) {
3172
+ if (!value) return { h: 0, s: 0, l: 0 };
3173
+ const parts = value.trim().split(/\s+/);
3174
+ const h = parseFloat(parts[0]) || 0;
3175
+ const s = parseFloat(parts[1]) || 0;
3176
+ const l = parseFloat(parts[2]) || 0;
3177
+ return { h, s, l };
3178
+ }
3179
+ function formatHsl(color) {
3180
+ return `${Math.round(color.h)} ${Math.round(color.s)}% ${Math.round(color.l)}%`;
3181
+ }
3182
+ function HslColorInput({
3183
+ value,
3184
+ onChange,
3185
+ className,
3186
+ inputClassName,
3187
+ disabled
3188
+ }) {
3189
+ const [open, setOpen] = useState7(false);
3190
+ const [inputVal, setInputVal] = useState7(value);
3191
+ const containerRef = useRef4(null);
3192
+ useEffect5(() => {
3193
+ setInputVal(value);
3194
+ }, [value]);
3195
+ useEffect5(() => {
3196
+ if (!open) return;
3197
+ const handler = (e) => {
3198
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
3199
+ setOpen(false);
3200
+ }
3201
+ };
3202
+ document.addEventListener("mousedown", handler);
3203
+ return () => document.removeEventListener("mousedown", handler);
3204
+ }, [open]);
3205
+ const hslColor = parseHsl(value);
3206
+ const cssColor = value ? `hsl(${value})` : "transparent";
3207
+ const handlePickerChange = useCallback((color) => {
3208
+ const formatted = formatHsl(color);
3209
+ setInputVal(formatted);
3210
+ onChange(formatted);
3211
+ }, [onChange]);
3212
+ const handleInputChange = (e) => {
3213
+ const v = e.target.value;
3214
+ setInputVal(v);
3215
+ if (/^\d+\s+\d+%?\s+\d+%?$/.test(v.trim()) || /^\d+(\.\d+)?\s+\d+(\.\d+)?%\s+\d+(\.\d+)?%$/.test(v.trim())) {
3216
+ onChange(v);
3217
+ }
3218
+ };
3219
+ const handleInputBlur = () => {
3220
+ setInputVal(value);
3221
+ };
3222
+ return /* @__PURE__ */ jsxs33("div", { ref: containerRef, className: cn("relative flex items-center gap-1.5", className), children: [
3223
+ /* @__PURE__ */ jsx49(
3224
+ "button",
3225
+ {
3226
+ type: "button",
3227
+ disabled,
3228
+ onClick: () => setOpen((o) => !o),
3229
+ className: cn(
3230
+ "w-5 h-5 rounded border border-white/10 shrink-0 transition-all",
3231
+ "hover:scale-110 hover:border-white/30 focus:outline-none focus:ring-1 focus:ring-white/20",
3232
+ disabled && "opacity-50 cursor-not-allowed"
3233
+ ),
3234
+ style: { background: cssColor },
3235
+ title: value,
3236
+ "aria-label": "Open color picker"
3237
+ }
3238
+ ),
3239
+ /* @__PURE__ */ jsx49(
3240
+ "input",
3241
+ {
3242
+ type: "text",
3243
+ value: inputVal,
3244
+ onChange: handleInputChange,
3245
+ onBlur: handleInputBlur,
3246
+ disabled,
3247
+ placeholder: "0 0% 0%",
3248
+ className: cn(
3249
+ "w-28 bg-white/5 border border-white/10 rounded px-1.5 py-0.5",
3250
+ "text-xs text-white/70 font-mono outline-none",
3251
+ "focus:border-white/30 placeholder:text-white/20",
3252
+ "disabled:opacity-50 disabled:cursor-not-allowed",
3253
+ inputClassName
3254
+ )
3255
+ }
3256
+ ),
3257
+ open && /* @__PURE__ */ jsxs33("div", { className: cn(
3258
+ "absolute z-50 top-full left-0 mt-2",
3259
+ "bg-[#1a1c2e] border border-white/10 rounded-xl shadow-2xl p-3",
3260
+ "flex flex-col gap-3"
3261
+ ), children: [
3262
+ /* @__PURE__ */ jsx49(
3263
+ HslColorPicker,
3264
+ {
3265
+ color: hslColor,
3266
+ onChange: handlePickerChange
3267
+ }
3268
+ ),
3269
+ /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-2", children: [
3270
+ /* @__PURE__ */ jsx49(
3271
+ "div",
3272
+ {
3273
+ className: "w-6 h-6 rounded border border-white/10 shrink-0",
3274
+ style: { background: cssColor }
3275
+ }
3276
+ ),
3277
+ /* @__PURE__ */ jsx49("span", { className: "text-xs font-mono text-white/50 truncate", children: value || "none" })
3278
+ ] })
3279
+ ] })
3280
+ ] });
3281
+ }
3282
+
3167
3283
  // src/hooks/index.ts
3168
- import { useState as useState7 } from "react";
3284
+ import { useState as useState8 } from "react";
3169
3285
  function useDisclosure(initial = false) {
3170
- const [isOpen, setIsOpen] = useState7(initial);
3286
+ const [isOpen, setIsOpen] = useState8(initial);
3171
3287
  return {
3172
3288
  isOpen,
3173
3289
  open: () => setIsOpen(true),
@@ -3177,15 +3293,15 @@ function useDisclosure(initial = false) {
3177
3293
  };
3178
3294
  }
3179
3295
  function usePagination(total, pageSize = 20) {
3180
- const [page, setPage] = useState7(1);
3296
+ const [page, setPage] = useState8(1);
3181
3297
  const totalPages = Math.ceil(total / pageSize);
3182
3298
  return { page, setPage, pageSize, total, totalPages };
3183
3299
  }
3184
3300
 
3185
3301
  // src/components/auth/AuthShell.tsx
3186
- import { jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
3302
+ import { jsx as jsx50, jsxs as jsxs34 } from "react/jsx-runtime";
3187
3303
  function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
3188
- return /* @__PURE__ */ jsxs33(
3304
+ return /* @__PURE__ */ jsxs34(
3189
3305
  "div",
3190
3306
  {
3191
3307
  style: {
@@ -3200,7 +3316,7 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
3200
3316
  overflow: "hidden"
3201
3317
  },
3202
3318
  children: [
3203
- pattern === "dots" && /* @__PURE__ */ jsx49(
3319
+ pattern === "dots" && /* @__PURE__ */ jsx50(
3204
3320
  "div",
3205
3321
  {
3206
3322
  "aria-hidden": true,
@@ -3214,7 +3330,7 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
3214
3330
  }
3215
3331
  }
3216
3332
  ),
3217
- pattern === "grid" && /* @__PURE__ */ jsx49(
3333
+ pattern === "grid" && /* @__PURE__ */ jsx50(
3218
3334
  "div",
3219
3335
  {
3220
3336
  "aria-hidden": true,
@@ -3228,16 +3344,16 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
3228
3344
  }
3229
3345
  }
3230
3346
  ),
3231
- /* @__PURE__ */ jsx49("div", { style: { position: "relative", zIndex: 1, width: "100%", maxWidth }, children })
3347
+ /* @__PURE__ */ jsx50("div", { style: { position: "relative", zIndex: 1, width: "100%", maxWidth }, children })
3232
3348
  ]
3233
3349
  }
3234
3350
  );
3235
3351
  }
3236
3352
 
3237
3353
  // src/components/auth/AuthCard.tsx
3238
- import { jsx as jsx50 } from "react/jsx-runtime";
3354
+ import { jsx as jsx51 } from "react/jsx-runtime";
3239
3355
  function AuthCard({ children, padding = "24px 28px" }) {
3240
- return /* @__PURE__ */ jsx50(
3356
+ return /* @__PURE__ */ jsx51(
3241
3357
  "div",
3242
3358
  {
3243
3359
  style: {
@@ -3254,10 +3370,10 @@ function AuthCard({ children, padding = "24px 28px" }) {
3254
3370
  }
3255
3371
 
3256
3372
  // src/components/auth/AuthLogo.tsx
3257
- import { jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
3373
+ import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
3258
3374
  function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }) {
3259
- return /* @__PURE__ */ jsxs34("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "10px", marginBottom: "28px" }, children: [
3260
- imageUrl ? /* @__PURE__ */ jsx51(
3375
+ return /* @__PURE__ */ jsxs35("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "10px", marginBottom: "28px" }, children: [
3376
+ imageUrl ? /* @__PURE__ */ jsx52(
3261
3377
  "img",
3262
3378
  {
3263
3379
  src: imageUrl,
@@ -3266,7 +3382,7 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
3266
3382
  height: size,
3267
3383
  style: { borderRadius: "calc(var(--radius, 0.5rem) * 1.2)", flexShrink: 0, display: "block" }
3268
3384
  }
3269
- ) : /* @__PURE__ */ jsx51(
3385
+ ) : /* @__PURE__ */ jsx52(
3270
3386
  "div",
3271
3387
  {
3272
3388
  style: {
@@ -3285,7 +3401,7 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
3285
3401
  children: letter
3286
3402
  }
3287
3403
  ),
3288
- /* @__PURE__ */ jsx51(
3404
+ /* @__PURE__ */ jsx52(
3289
3405
  "span",
3290
3406
  {
3291
3407
  style: {
@@ -3301,10 +3417,10 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
3301
3417
  }
3302
3418
 
3303
3419
  // src/components/auth/AuthHeader.tsx
3304
- import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
3420
+ import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
3305
3421
  function AuthHeader({ title, description }) {
3306
- return /* @__PURE__ */ jsxs35("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
3307
- /* @__PURE__ */ jsx52(
3422
+ return /* @__PURE__ */ jsxs36("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
3423
+ /* @__PURE__ */ jsx53(
3308
3424
  "h1",
3309
3425
  {
3310
3426
  style: {
@@ -3317,7 +3433,7 @@ function AuthHeader({ title, description }) {
3317
3433
  children: title
3318
3434
  }
3319
3435
  ),
3320
- description && /* @__PURE__ */ jsx52(
3436
+ description && /* @__PURE__ */ jsx53(
3321
3437
  "p",
3322
3438
  {
3323
3439
  style: {
@@ -3333,12 +3449,12 @@ function AuthHeader({ title, description }) {
3333
3449
  }
3334
3450
 
3335
3451
  // src/components/auth/AuthField.tsx
3336
- import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
3452
+ import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
3337
3453
  function AuthField({ label, error, hint, rightLabel, id, ...props }) {
3338
3454
  const fieldId = id ?? label.toLowerCase().replace(/\s+/g, "-");
3339
- return /* @__PURE__ */ jsxs36("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
3340
- /* @__PURE__ */ jsxs36("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
3341
- /* @__PURE__ */ jsx53(
3455
+ return /* @__PURE__ */ jsxs37("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
3456
+ /* @__PURE__ */ jsxs37("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
3457
+ /* @__PURE__ */ jsx54(
3342
3458
  "label",
3343
3459
  {
3344
3460
  htmlFor: fieldId,
@@ -3350,9 +3466,9 @@ function AuthField({ label, error, hint, rightLabel, id, ...props }) {
3350
3466
  children: label
3351
3467
  }
3352
3468
  ),
3353
- rightLabel && /* @__PURE__ */ jsx53("span", { style: { fontSize: "0.8125rem" }, children: rightLabel })
3469
+ rightLabel && /* @__PURE__ */ jsx54("span", { style: { fontSize: "0.8125rem" }, children: rightLabel })
3354
3470
  ] }),
3355
- /* @__PURE__ */ jsx53(
3471
+ /* @__PURE__ */ jsx54(
3356
3472
  "input",
3357
3473
  {
3358
3474
  id: fieldId,
@@ -3382,13 +3498,13 @@ function AuthField({ label, error, hint, rightLabel, id, ...props }) {
3382
3498
  ...props
3383
3499
  }
3384
3500
  ),
3385
- error && /* @__PURE__ */ jsx53("p", { style: { fontSize: "0.8rem", color: "var(--destructive)", margin: 0 }, children: error }),
3386
- hint && !error && /* @__PURE__ */ jsx53("p", { style: { fontSize: "0.8rem", color: "var(--muted-foreground)", margin: 0 }, children: hint })
3501
+ error && /* @__PURE__ */ jsx54("p", { style: { fontSize: "0.8rem", color: "var(--destructive)", margin: 0 }, children: error }),
3502
+ hint && !error && /* @__PURE__ */ jsx54("p", { style: { fontSize: "0.8rem", color: "var(--muted-foreground)", margin: 0 }, children: hint })
3387
3503
  ] });
3388
3504
  }
3389
3505
 
3390
3506
  // src/components/auth/AuthButton.tsx
3391
- import { Fragment as Fragment5, jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
3507
+ import { Fragment as Fragment5, jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
3392
3508
  function AuthButton({
3393
3509
  loading,
3394
3510
  variant = "primary",
@@ -3431,7 +3547,7 @@ function AuthButton({
3431
3547
  color: "var(--foreground)"
3432
3548
  }
3433
3549
  };
3434
- return /* @__PURE__ */ jsx54(
3550
+ return /* @__PURE__ */ jsx55(
3435
3551
  "button",
3436
3552
  {
3437
3553
  disabled: loading || disabled,
@@ -3443,8 +3559,8 @@ function AuthButton({
3443
3559
  e.currentTarget.style.filter = "none";
3444
3560
  },
3445
3561
  ...props,
3446
- children: loading ? /* @__PURE__ */ jsxs37(Fragment5, { children: [
3447
- /* @__PURE__ */ jsx54(
3562
+ children: loading ? /* @__PURE__ */ jsxs38(Fragment5, { children: [
3563
+ /* @__PURE__ */ jsx55(
3448
3564
  "span",
3449
3565
  {
3450
3566
  style: {
@@ -3465,19 +3581,19 @@ function AuthButton({
3465
3581
  }
3466
3582
 
3467
3583
  // src/components/auth/AuthDivider.tsx
3468
- import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
3584
+ import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
3469
3585
  function AuthDivider({ label = "or" }) {
3470
- return /* @__PURE__ */ jsxs38("div", { style: { display: "flex", alignItems: "center", gap: "12px", margin: "20px 0" }, children: [
3471
- /* @__PURE__ */ jsx55("div", { style: { flex: 1, height: 1, background: "var(--border)" } }),
3472
- /* @__PURE__ */ jsx55("span", { style: { fontSize: "0.75rem", color: "var(--muted-foreground)", userSelect: "none" }, children: label }),
3473
- /* @__PURE__ */ jsx55("div", { style: { flex: 1, height: 1, background: "var(--border)" } })
3586
+ return /* @__PURE__ */ jsxs39("div", { style: { display: "flex", alignItems: "center", gap: "12px", margin: "20px 0" }, children: [
3587
+ /* @__PURE__ */ jsx56("div", { style: { flex: 1, height: 1, background: "var(--border)" } }),
3588
+ /* @__PURE__ */ jsx56("span", { style: { fontSize: "0.75rem", color: "var(--muted-foreground)", userSelect: "none" }, children: label }),
3589
+ /* @__PURE__ */ jsx56("div", { style: { flex: 1, height: 1, background: "var(--border)" } })
3474
3590
  ] });
3475
3591
  }
3476
3592
 
3477
3593
  // src/components/auth/AuthFootnote.tsx
3478
- import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
3594
+ import { jsx as jsx57, jsxs as jsxs40 } from "react/jsx-runtime";
3479
3595
  function AuthFootnote({ text, linkText, linkHref }) {
3480
- return /* @__PURE__ */ jsxs39("p", { style: {
3596
+ return /* @__PURE__ */ jsxs40("p", { style: {
3481
3597
  textAlign: "center",
3482
3598
  marginTop: "20px",
3483
3599
  fontSize: "0.8125rem",
@@ -3485,7 +3601,7 @@ function AuthFootnote({ text, linkText, linkHref }) {
3485
3601
  }, children: [
3486
3602
  text,
3487
3603
  " ",
3488
- /* @__PURE__ */ jsx56(
3604
+ /* @__PURE__ */ jsx57(
3489
3605
  "a",
3490
3606
  {
3491
3607
  href: linkHref,
@@ -3556,6 +3672,7 @@ export {
3556
3672
  FormField,
3557
3673
  FormLayout,
3558
3674
  FormSection,
3675
+ HslColorInput,
3559
3676
  ImagePickerField,
3560
3677
  Input,
3561
3678
  Label2 as Label,