@webdevarif/dashui 1.1.0 → 1.2.1

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.d.mts CHANGED
@@ -645,6 +645,29 @@ type ColorPickerFormatProps = HTMLAttributes<HTMLInputElement>;
645
645
  declare const ColorPickerFormat: ({ className, ...props }: ColorPickerFormatProps) => react_jsx_runtime.JSX.Element;
646
646
  declare const ColorPickerHexOutput: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => react_jsx_runtime.JSX.Element;
647
647
 
648
+ /**
649
+ * TiptapEditor — Rich text editor with live editing
650
+ *
651
+ * Presentation-only. Consumer handles:
652
+ * - Saving (getJSON() when ready)
653
+ * - Upload handling
654
+ * - Validation
655
+ *
656
+ * Props:
657
+ * - value: Record<string, any> | string | null — JSON content from editor.getJSON()
658
+ * - onChange: (json: Record<string, any>) => void — called on every change
659
+ * - placeholder?: string — placeholder text
660
+ * - disabled?: boolean
661
+ * - className?: string — wrapper classes
662
+ */
663
+ declare function TiptapEditor({ value, onChange, placeholder, disabled, className, }: {
664
+ value: Record<string, any> | string | null;
665
+ onChange: (json: Record<string, any>) => void;
666
+ placeholder?: string;
667
+ disabled?: boolean;
668
+ className?: string;
669
+ }): react_jsx_runtime.JSX.Element | null;
670
+
648
671
  declare function useDisclosure(initial?: boolean): {
649
672
  isOpen: boolean;
650
673
  open: () => void;
@@ -729,4 +752,4 @@ interface SkeletonProps {
729
752
  }
730
753
  declare function Skeleton({ width, height, rounded, style }: SkeletonProps): react_jsx_runtime.JSX.Element;
731
754
 
732
- export { Alert, type AlertProps, AppShell, type AppShellProps, AuthButton, AuthCard, AuthDivider, AuthField, AuthFootnote, AuthHeader, AuthLogo, AuthShell, Badge, type BadgeProps, type Breadcrumb, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColorPicker, ColorPickerAlpha, ColorPickerEyeDropper, ColorPickerFormat, ColorPickerHexOutput, ColorPickerHue, ColorPickerOutput, ColorPickerSelection, type Column, ConfirmDialog, type ConfirmDialogProps, DEVICES, DEVICE_ICONS, DashboardLayout, type DashboardLayoutProps, DataTable, type DataTableProps, type DeviceKey, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, FormField, type FormFieldProps, FormLayout, type FormLayoutProps, FormSection, type FormSectionProps, HslColorInput, ImagePickerField, Input, type InputProps, Label, LoadingSpinner, type LoadingSpinnerProps, LocalInput, MediaCard, type NavItem, NotificationBell, type NotificationBellProps, Page, type PageProps, PageSection, type PageSectionProps, Pagination, type PaginationProps, PlanBadge, type PlanBadgeProps, type PlanId, Popover, PopoverContent, PopoverTrigger, PostEditorShell, type PostEditorShellProps, PostFiltersBar, type PostFiltersBarProps, type PostListItem, PostListTable, type PostListTableProps, PostSidebarSection, type PostSidebarSectionProps, type PostStatus, PostStatusBadge, type PostStatusBadgeProps, ResponsiveSizeDeviceIcon, ResponsiveSizeField, SearchBar, type SearchBarProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sidebar, type SidebarItem, type SidebarProps, Skeleton, SlugInput, type SlugInputProps, type Stat, Stats, type StatsProps, StorageBar, type StorageBarProps, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, ThemeToggle, type ThemeToggleProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, type TopBarProps, type UploadProgressItem, UploadProgressPanel, UploadZone, badgeVariants, buttonVariants, cn, useColorPicker, useDisclosure, usePagination };
755
+ export { Alert, type AlertProps, AppShell, type AppShellProps, AuthButton, AuthCard, AuthDivider, AuthField, AuthFootnote, AuthHeader, AuthLogo, AuthShell, Badge, type BadgeProps, type Breadcrumb, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColorPicker, ColorPickerAlpha, ColorPickerEyeDropper, ColorPickerFormat, ColorPickerHexOutput, ColorPickerHue, ColorPickerOutput, ColorPickerSelection, type Column, ConfirmDialog, type ConfirmDialogProps, DEVICES, DEVICE_ICONS, DashboardLayout, type DashboardLayoutProps, DataTable, type DataTableProps, type DeviceKey, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, FormField, type FormFieldProps, FormLayout, type FormLayoutProps, FormSection, type FormSectionProps, HslColorInput, ImagePickerField, Input, type InputProps, Label, LoadingSpinner, type LoadingSpinnerProps, LocalInput, MediaCard, type NavItem, NotificationBell, type NotificationBellProps, Page, type PageProps, PageSection, type PageSectionProps, Pagination, type PaginationProps, PlanBadge, type PlanBadgeProps, type PlanId, Popover, PopoverContent, PopoverTrigger, PostEditorShell, type PostEditorShellProps, PostFiltersBar, type PostFiltersBarProps, type PostListItem, PostListTable, type PostListTableProps, PostSidebarSection, type PostSidebarSectionProps, type PostStatus, PostStatusBadge, type PostStatusBadgeProps, ResponsiveSizeDeviceIcon, ResponsiveSizeField, SearchBar, type SearchBarProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sidebar, type SidebarItem, type SidebarProps, Skeleton, SlugInput, type SlugInputProps, type Stat, Stats, type StatsProps, StorageBar, type StorageBarProps, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, ThemeToggle, type ThemeToggleProps, TiptapEditor, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, type TopBarProps, type UploadProgressItem, UploadProgressPanel, UploadZone, badgeVariants, buttonVariants, cn, useColorPicker, useDisclosure, usePagination };
package/dist/index.d.ts CHANGED
@@ -645,6 +645,29 @@ type ColorPickerFormatProps = HTMLAttributes<HTMLInputElement>;
645
645
  declare const ColorPickerFormat: ({ className, ...props }: ColorPickerFormatProps) => react_jsx_runtime.JSX.Element;
646
646
  declare const ColorPickerHexOutput: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => react_jsx_runtime.JSX.Element;
647
647
 
648
+ /**
649
+ * TiptapEditor — Rich text editor with live editing
650
+ *
651
+ * Presentation-only. Consumer handles:
652
+ * - Saving (getJSON() when ready)
653
+ * - Upload handling
654
+ * - Validation
655
+ *
656
+ * Props:
657
+ * - value: Record<string, any> | string | null — JSON content from editor.getJSON()
658
+ * - onChange: (json: Record<string, any>) => void — called on every change
659
+ * - placeholder?: string — placeholder text
660
+ * - disabled?: boolean
661
+ * - className?: string — wrapper classes
662
+ */
663
+ declare function TiptapEditor({ value, onChange, placeholder, disabled, className, }: {
664
+ value: Record<string, any> | string | null;
665
+ onChange: (json: Record<string, any>) => void;
666
+ placeholder?: string;
667
+ disabled?: boolean;
668
+ className?: string;
669
+ }): react_jsx_runtime.JSX.Element | null;
670
+
648
671
  declare function useDisclosure(initial?: boolean): {
649
672
  isOpen: boolean;
650
673
  open: () => void;
@@ -729,4 +752,4 @@ interface SkeletonProps {
729
752
  }
730
753
  declare function Skeleton({ width, height, rounded, style }: SkeletonProps): react_jsx_runtime.JSX.Element;
731
754
 
732
- export { Alert, type AlertProps, AppShell, type AppShellProps, AuthButton, AuthCard, AuthDivider, AuthField, AuthFootnote, AuthHeader, AuthLogo, AuthShell, Badge, type BadgeProps, type Breadcrumb, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColorPicker, ColorPickerAlpha, ColorPickerEyeDropper, ColorPickerFormat, ColorPickerHexOutput, ColorPickerHue, ColorPickerOutput, ColorPickerSelection, type Column, ConfirmDialog, type ConfirmDialogProps, DEVICES, DEVICE_ICONS, DashboardLayout, type DashboardLayoutProps, DataTable, type DataTableProps, type DeviceKey, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, FormField, type FormFieldProps, FormLayout, type FormLayoutProps, FormSection, type FormSectionProps, HslColorInput, ImagePickerField, Input, type InputProps, Label, LoadingSpinner, type LoadingSpinnerProps, LocalInput, MediaCard, type NavItem, NotificationBell, type NotificationBellProps, Page, type PageProps, PageSection, type PageSectionProps, Pagination, type PaginationProps, PlanBadge, type PlanBadgeProps, type PlanId, Popover, PopoverContent, PopoverTrigger, PostEditorShell, type PostEditorShellProps, PostFiltersBar, type PostFiltersBarProps, type PostListItem, PostListTable, type PostListTableProps, PostSidebarSection, type PostSidebarSectionProps, type PostStatus, PostStatusBadge, type PostStatusBadgeProps, ResponsiveSizeDeviceIcon, ResponsiveSizeField, SearchBar, type SearchBarProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sidebar, type SidebarItem, type SidebarProps, Skeleton, SlugInput, type SlugInputProps, type Stat, Stats, type StatsProps, StorageBar, type StorageBarProps, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, ThemeToggle, type ThemeToggleProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, type TopBarProps, type UploadProgressItem, UploadProgressPanel, UploadZone, badgeVariants, buttonVariants, cn, useColorPicker, useDisclosure, usePagination };
755
+ export { Alert, type AlertProps, AppShell, type AppShellProps, AuthButton, AuthCard, AuthDivider, AuthField, AuthFootnote, AuthHeader, AuthLogo, AuthShell, Badge, type BadgeProps, type Breadcrumb, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColorPicker, ColorPickerAlpha, ColorPickerEyeDropper, ColorPickerFormat, ColorPickerHexOutput, ColorPickerHue, ColorPickerOutput, ColorPickerSelection, type Column, ConfirmDialog, type ConfirmDialogProps, DEVICES, DEVICE_ICONS, DashboardLayout, type DashboardLayoutProps, DataTable, type DataTableProps, type DeviceKey, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, FormField, type FormFieldProps, FormLayout, type FormLayoutProps, FormSection, type FormSectionProps, HslColorInput, ImagePickerField, Input, type InputProps, Label, LoadingSpinner, type LoadingSpinnerProps, LocalInput, MediaCard, type NavItem, NotificationBell, type NotificationBellProps, Page, type PageProps, PageSection, type PageSectionProps, Pagination, type PaginationProps, PlanBadge, type PlanBadgeProps, type PlanId, Popover, PopoverContent, PopoverTrigger, PostEditorShell, type PostEditorShellProps, PostFiltersBar, type PostFiltersBarProps, type PostListItem, PostListTable, type PostListTableProps, PostSidebarSection, type PostSidebarSectionProps, type PostStatus, PostStatusBadge, type PostStatusBadgeProps, ResponsiveSizeDeviceIcon, ResponsiveSizeField, SearchBar, type SearchBarProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sidebar, type SidebarItem, type SidebarProps, Skeleton, SlugInput, type SlugInputProps, type Stat, Stats, type StatsProps, StorageBar, type StorageBarProps, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, ThemeToggle, type ThemeToggleProps, TiptapEditor, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, type TopBarProps, type UploadProgressItem, UploadProgressPanel, UploadZone, badgeVariants, buttonVariants, cn, useColorPicker, useDisclosure, usePagination };
package/dist/index.js CHANGED
@@ -138,6 +138,7 @@ __export(index_exports, {
138
138
  Textarea: () => Textarea,
139
139
  ThemeProvider: () => import_next_themes2.ThemeProvider,
140
140
  ThemeToggle: () => ThemeToggle,
141
+ TiptapEditor: () => TiptapEditor,
141
142
  Tooltip: () => Tooltip,
142
143
  TooltipContent: () => TooltipContent,
143
144
  TooltipProvider: () => TooltipProvider,
@@ -3708,10 +3709,170 @@ function HslColorInput({ value, onChange, className, inputClassName, disabled })
3708
3709
  ] });
3709
3710
  }
3710
3711
 
3712
+ // src/components/editors/tiptap-editor.tsx
3713
+ var import_react7 = require("@tiptap/react");
3714
+ var import_starter_kit = __toESM(require("@tiptap/starter-kit"));
3715
+ var import_extension_placeholder = __toESM(require("@tiptap/extension-placeholder"));
3716
+ var import_jsx_runtime55 = require("react/jsx-runtime");
3717
+ function TiptapEditor({
3718
+ value,
3719
+ onChange,
3720
+ placeholder = "Start writing\u2026",
3721
+ disabled = false,
3722
+ className = ""
3723
+ }) {
3724
+ const editor = (0, import_react7.useEditor)({
3725
+ immediatelyRender: false,
3726
+ extensions: [
3727
+ import_starter_kit.default.configure({
3728
+ heading: { levels: [1, 2, 3] }
3729
+ }),
3730
+ import_extension_placeholder.default.configure({ placeholder })
3731
+ ],
3732
+ content: value,
3733
+ editable: !disabled,
3734
+ editorProps: {
3735
+ attributes: {
3736
+ class: "prose prose-sm max-w-none min-h-[400px] p-4 outline-none focus:outline-none bg-white dark:bg-slate-900 text-slate-900 dark:text-white rounded-lg border border-gray-200 dark:border-slate-700"
3737
+ }
3738
+ },
3739
+ onUpdate: ({ editor: editor2 }) => {
3740
+ onChange(editor2.getJSON());
3741
+ }
3742
+ });
3743
+ if (!editor) return null;
3744
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: `tiptap-wrapper ${className}`.trim(), children: [
3745
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex gap-1 p-2 border-b border-gray-200 dark:border-slate-700 bg-gray-50 dark:bg-slate-800 rounded-t-lg", children: [
3746
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3747
+ ToolbarButton,
3748
+ {
3749
+ onClick: () => editor.chain().focus().toggleBold().run(),
3750
+ active: editor.isActive("bold"),
3751
+ title: "Bold (Ctrl+B)",
3752
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("strong", { children: "B" })
3753
+ }
3754
+ ),
3755
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3756
+ ToolbarButton,
3757
+ {
3758
+ onClick: () => editor.chain().focus().toggleItalic().run(),
3759
+ active: editor.isActive("italic"),
3760
+ title: "Italic (Ctrl+I)",
3761
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("em", { children: "I" })
3762
+ }
3763
+ ),
3764
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3765
+ ToolbarButton,
3766
+ {
3767
+ onClick: () => editor.chain().focus().toggleStrike().run(),
3768
+ active: editor.isActive("strike"),
3769
+ title: "Strikethrough",
3770
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("s", { children: "S" })
3771
+ }
3772
+ ),
3773
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "w-px bg-gray-300 dark:bg-slate-600 mx-1" }),
3774
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3775
+ ToolbarButton,
3776
+ {
3777
+ onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
3778
+ active: editor.isActive("heading", { level: 1 }),
3779
+ title: "Heading 1",
3780
+ children: "H1"
3781
+ }
3782
+ ),
3783
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3784
+ ToolbarButton,
3785
+ {
3786
+ onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
3787
+ active: editor.isActive("heading", { level: 2 }),
3788
+ title: "Heading 2",
3789
+ children: "H2"
3790
+ }
3791
+ ),
3792
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3793
+ ToolbarButton,
3794
+ {
3795
+ onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
3796
+ active: editor.isActive("heading", { level: 3 }),
3797
+ title: "Heading 3",
3798
+ children: "H3"
3799
+ }
3800
+ ),
3801
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "w-px bg-gray-300 dark:bg-slate-600 mx-1" }),
3802
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3803
+ ToolbarButton,
3804
+ {
3805
+ onClick: () => editor.chain().focus().toggleBulletList().run(),
3806
+ active: editor.isActive("bulletList"),
3807
+ title: "Bullet list",
3808
+ children: "\u2022"
3809
+ }
3810
+ ),
3811
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3812
+ ToolbarButton,
3813
+ {
3814
+ onClick: () => editor.chain().focus().toggleOrderedList().run(),
3815
+ active: editor.isActive("orderedList"),
3816
+ title: "Ordered list",
3817
+ children: "1."
3818
+ }
3819
+ ),
3820
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "w-px bg-gray-300 dark:bg-slate-600 mx-1" }),
3821
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3822
+ ToolbarButton,
3823
+ {
3824
+ onClick: () => editor.chain().focus().toggleCodeBlock().run(),
3825
+ active: editor.isActive("codeBlock"),
3826
+ title: "Code block",
3827
+ children: "<>"
3828
+ }
3829
+ ),
3830
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3831
+ ToolbarButton,
3832
+ {
3833
+ onClick: () => editor.chain().focus().toggleCode().run(),
3834
+ active: editor.isActive("code"),
3835
+ title: "Inline code",
3836
+ children: "`"
3837
+ }
3838
+ ),
3839
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "w-px bg-gray-300 dark:bg-slate-600 mx-1" }),
3840
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3841
+ ToolbarButton,
3842
+ {
3843
+ onClick: () => editor.chain().focus().setHorizontalRule().run(),
3844
+ title: "Horizontal rule",
3845
+ children: "\u2014"
3846
+ }
3847
+ )
3848
+ ] }),
3849
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react7.EditorContent, { editor })
3850
+ ] });
3851
+ }
3852
+ function ToolbarButton({
3853
+ onClick,
3854
+ active,
3855
+ title,
3856
+ children
3857
+ }) {
3858
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3859
+ "button",
3860
+ {
3861
+ onClick,
3862
+ title,
3863
+ className: `
3864
+ px-2 py-1 rounded text-sm font-medium transition-colors
3865
+ ${active ? "bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400" : "bg-transparent text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-slate-700"}
3866
+ `,
3867
+ children
3868
+ }
3869
+ );
3870
+ }
3871
+
3711
3872
  // src/hooks/index.ts
3712
- var import_react7 = require("react");
3873
+ var import_react8 = require("react");
3713
3874
  function useDisclosure(initial = false) {
3714
- const [isOpen, setIsOpen] = (0, import_react7.useState)(initial);
3875
+ const [isOpen, setIsOpen] = (0, import_react8.useState)(initial);
3715
3876
  return {
3716
3877
  isOpen,
3717
3878
  open: () => setIsOpen(true),
@@ -3721,15 +3882,15 @@ function useDisclosure(initial = false) {
3721
3882
  };
3722
3883
  }
3723
3884
  function usePagination(total, pageSize = 20) {
3724
- const [page, setPage] = (0, import_react7.useState)(1);
3885
+ const [page, setPage] = (0, import_react8.useState)(1);
3725
3886
  const totalPages = Math.ceil(total / pageSize);
3726
3887
  return { page, setPage, pageSize, total, totalPages };
3727
3888
  }
3728
3889
 
3729
3890
  // src/components/auth/AuthShell.tsx
3730
- var import_jsx_runtime55 = require("react/jsx-runtime");
3891
+ var import_jsx_runtime56 = require("react/jsx-runtime");
3731
3892
  function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
3732
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
3893
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
3733
3894
  "div",
3734
3895
  {
3735
3896
  style: {
@@ -3744,7 +3905,7 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
3744
3905
  overflow: "hidden"
3745
3906
  },
3746
3907
  children: [
3747
- pattern === "dots" && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3908
+ pattern === "dots" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
3748
3909
  "div",
3749
3910
  {
3750
3911
  "aria-hidden": true,
@@ -3758,7 +3919,7 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
3758
3919
  }
3759
3920
  }
3760
3921
  ),
3761
- pattern === "grid" && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3922
+ pattern === "grid" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
3762
3923
  "div",
3763
3924
  {
3764
3925
  "aria-hidden": true,
@@ -3772,16 +3933,16 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
3772
3933
  }
3773
3934
  }
3774
3935
  ),
3775
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { style: { position: "relative", zIndex: 1, width: "100%", maxWidth }, children })
3936
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { style: { position: "relative", zIndex: 1, width: "100%", maxWidth }, children })
3776
3937
  ]
3777
3938
  }
3778
3939
  );
3779
3940
  }
3780
3941
 
3781
3942
  // src/components/auth/AuthCard.tsx
3782
- var import_jsx_runtime56 = require("react/jsx-runtime");
3943
+ var import_jsx_runtime57 = require("react/jsx-runtime");
3783
3944
  function AuthCard({ children, padding = "24px 28px" }) {
3784
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
3945
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3785
3946
  "div",
3786
3947
  {
3787
3948
  style: {
@@ -3798,10 +3959,10 @@ function AuthCard({ children, padding = "24px 28px" }) {
3798
3959
  }
3799
3960
 
3800
3961
  // src/components/auth/AuthLogo.tsx
3801
- var import_jsx_runtime57 = require("react/jsx-runtime");
3962
+ var import_jsx_runtime58 = require("react/jsx-runtime");
3802
3963
  function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }) {
3803
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "10px", marginBottom: "28px" }, children: [
3804
- imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3964
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "10px", marginBottom: "28px" }, children: [
3965
+ imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
3805
3966
  "img",
3806
3967
  {
3807
3968
  src: imageUrl,
@@ -3810,7 +3971,7 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
3810
3971
  height: size,
3811
3972
  style: { borderRadius: "calc(var(--radius, 0.5rem) * 1.2)", flexShrink: 0, display: "block" }
3812
3973
  }
3813
- ) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3974
+ ) : /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
3814
3975
  "div",
3815
3976
  {
3816
3977
  style: {
@@ -3829,7 +3990,7 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
3829
3990
  children: letter
3830
3991
  }
3831
3992
  ),
3832
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3993
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
3833
3994
  "span",
3834
3995
  {
3835
3996
  style: {
@@ -3845,10 +4006,10 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
3845
4006
  }
3846
4007
 
3847
4008
  // src/components/auth/AuthHeader.tsx
3848
- var import_jsx_runtime58 = require("react/jsx-runtime");
4009
+ var import_jsx_runtime59 = require("react/jsx-runtime");
3849
4010
  function AuthHeader({ title, description }) {
3850
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
3851
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
4011
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
4012
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
3852
4013
  "h1",
3853
4014
  {
3854
4015
  style: {
@@ -3861,7 +4022,7 @@ function AuthHeader({ title, description }) {
3861
4022
  children: title
3862
4023
  }
3863
4024
  ),
3864
- description && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
4025
+ description && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
3865
4026
  "p",
3866
4027
  {
3867
4028
  style: {
@@ -3877,12 +4038,12 @@ function AuthHeader({ title, description }) {
3877
4038
  }
3878
4039
 
3879
4040
  // src/components/auth/AuthField.tsx
3880
- var import_jsx_runtime59 = require("react/jsx-runtime");
4041
+ var import_jsx_runtime60 = require("react/jsx-runtime");
3881
4042
  function AuthField({ label, error, hint, rightLabel, id, ...props }) {
3882
4043
  const fieldId = id ?? label.toLowerCase().replace(/\s+/g, "-");
3883
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
3884
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
3885
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
4044
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
4045
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
4046
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
3886
4047
  "label",
3887
4048
  {
3888
4049
  htmlFor: fieldId,
@@ -3894,9 +4055,9 @@ function AuthField({ label, error, hint, rightLabel, id, ...props }) {
3894
4055
  children: label
3895
4056
  }
3896
4057
  ),
3897
- rightLabel && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { style: { fontSize: "0.8125rem" }, children: rightLabel })
4058
+ rightLabel && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { style: { fontSize: "0.8125rem" }, children: rightLabel })
3898
4059
  ] }),
3899
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
4060
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
3900
4061
  "input",
3901
4062
  {
3902
4063
  id: fieldId,
@@ -3926,13 +4087,13 @@ function AuthField({ label, error, hint, rightLabel, id, ...props }) {
3926
4087
  ...props
3927
4088
  }
3928
4089
  ),
3929
- error && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--destructive)", margin: 0 }, children: error }),
3930
- hint && !error && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--muted-foreground)", margin: 0 }, children: hint })
4090
+ error && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--destructive)", margin: 0 }, children: error }),
4091
+ hint && !error && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--muted-foreground)", margin: 0 }, children: hint })
3931
4092
  ] });
3932
4093
  }
3933
4094
 
3934
4095
  // src/components/auth/AuthButton.tsx
3935
- var import_jsx_runtime60 = require("react/jsx-runtime");
4096
+ var import_jsx_runtime61 = require("react/jsx-runtime");
3936
4097
  function AuthButton({
3937
4098
  loading,
3938
4099
  variant = "primary",
@@ -3975,7 +4136,7 @@ function AuthButton({
3975
4136
  color: "var(--foreground)"
3976
4137
  }
3977
4138
  };
3978
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
4139
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
3979
4140
  "button",
3980
4141
  {
3981
4142
  disabled: loading || disabled,
@@ -3987,8 +4148,8 @@ function AuthButton({
3987
4148
  e.currentTarget.style.filter = "none";
3988
4149
  },
3989
4150
  ...props,
3990
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
3991
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
4151
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
4152
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
3992
4153
  "span",
3993
4154
  {
3994
4155
  style: {
@@ -4009,19 +4170,19 @@ function AuthButton({
4009
4170
  }
4010
4171
 
4011
4172
  // src/components/auth/AuthDivider.tsx
4012
- var import_jsx_runtime61 = require("react/jsx-runtime");
4173
+ var import_jsx_runtime62 = require("react/jsx-runtime");
4013
4174
  function AuthDivider({ label = "or" }) {
4014
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", margin: "20px 0" }, children: [
4015
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } }),
4016
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { style: { fontSize: "0.75rem", color: "var(--muted-foreground)", userSelect: "none" }, children: label }),
4017
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } })
4175
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", margin: "20px 0" }, children: [
4176
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } }),
4177
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { style: { fontSize: "0.75rem", color: "var(--muted-foreground)", userSelect: "none" }, children: label }),
4178
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } })
4018
4179
  ] });
4019
4180
  }
4020
4181
 
4021
4182
  // src/components/auth/AuthFootnote.tsx
4022
- var import_jsx_runtime62 = require("react/jsx-runtime");
4183
+ var import_jsx_runtime63 = require("react/jsx-runtime");
4023
4184
  function AuthFootnote({ text, linkText, linkHref }) {
4024
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("p", { style: {
4185
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("p", { style: {
4025
4186
  textAlign: "center",
4026
4187
  marginTop: "20px",
4027
4188
  fontSize: "0.8125rem",
@@ -4029,7 +4190,7 @@ function AuthFootnote({ text, linkText, linkHref }) {
4029
4190
  }, children: [
4030
4191
  text,
4031
4192
  " ",
4032
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
4193
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4033
4194
  "a",
4034
4195
  {
4035
4196
  href: linkHref,
@@ -4158,6 +4319,7 @@ var import_next_themes2 = require("next-themes");
4158
4319
  Textarea,
4159
4320
  ThemeProvider,
4160
4321
  ThemeToggle,
4322
+ TiptapEditor,
4161
4323
  Tooltip,
4162
4324
  TooltipContent,
4163
4325
  TooltipProvider,