tw-react-components 0.0.138 → 0.0.140

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/index.css CHANGED
@@ -13,8 +13,8 @@
13
13
  --popover: 0 0% 100%;
14
14
  --popover-foreground: 222.2 47.4% 11.2%;
15
15
 
16
- --border: 214.3 31.8% 91.4%;
17
- --input: 214.3 31.8% 91.4%;
16
+ --border: 220 13% 91%;
17
+ --input: 220 13% 91%;
18
18
 
19
19
  --card: 0 0% 100%;
20
20
  --card-foreground: 222.2 47.4% 11.2%;
@@ -58,8 +58,8 @@
58
58
  --popover: 224 71% 4%;
59
59
  --popover-foreground: 215 20.2% 65.1%;
60
60
 
61
- --border: 216 34% 17%;
62
- --input: 216 34% 17%;
61
+ --border: 215 25% 27%;
62
+ --input: 215 25% 27%;
63
63
 
64
64
  --card: 224 71% 4%;
65
65
  --card-foreground: 213 31% 91%;
@@ -92,6 +92,7 @@
92
92
  * {
93
93
  @apply border-border;
94
94
  }
95
+
95
96
  body {
96
97
  @apply bg-background text-foreground;
97
98
  font-feature-settings:
package/index.esm.js CHANGED
@@ -1,23 +1,22 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import * as React from 'react';
3
2
  import { forwardRef, useMemo, useState, useEffect, useId, useCallback, useRef, createContext, useContext } from 'react';
4
3
  import { clsx } from 'clsx';
5
4
  import { twMerge } from 'tailwind-merge';
6
5
  import dayjs from 'dayjs';
7
6
  import advancedFormat from 'dayjs/plugin/advancedFormat';
8
- import { HelpCircle, XIcon, AtSignIcon, EyeIcon, EyeOffIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronDownIcon, CalendarIcon, ClockIcon, CheckIcon, CircleIcon, CloudUploadIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsDownUpIcon, ChevronsUpDownIcon, ArrowUpDownIcon, SortAscIcon, SortDescIcon, MinusIcon, PlusIcon, X, PanelLeft, MoonIcon, SunIcon } from 'lucide-react';
7
+ import { HelpCircle, XIcon, AtSignIcon, EyeIcon, EyeOffIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronDownIcon, CalendarIcon, ClockIcon, CheckIcon, CircleIcon, CloudUploadIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsDownUpIcon, ChevronsUpDownIcon, ArrowUpDownIcon, SortAscIcon, SortDescIcon, MinusIcon, PlusIcon, PanelLeft, MoonIcon, SunIcon, MonitorIcon } from 'lucide-react';
9
8
  import localeData from 'dayjs/plugin/localeData';
10
9
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
11
10
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
12
11
  import { useFormContext, Controller, FormProvider } from 'react-hook-form';
13
12
  import * as DialogPrimitive from '@radix-ui/react-dialog';
13
+ import { cva } from 'class-variance-authority';
14
14
  import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
15
15
  import { restrictToFirstScrollableAncestor } from '@dnd-kit/modifiers';
16
16
  import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
17
17
  import { CSS } from '@dnd-kit/utilities';
18
18
  import { Link, useLocation } from 'react-router-dom';
19
19
  import { Slot } from '@radix-ui/react-slot';
20
- import { cva } from 'class-variance-authority';
21
20
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
22
21
  import * as PopoverPrimitive from '@radix-ui/react-popover';
23
22
  import * as SwitchPrimitives from '@radix-ui/react-switch';
@@ -97,6 +96,19 @@ function getDisplayDate(date, format, locale) {
97
96
  return (locale ? dayjs(date).locale(locale) : dayjs(date)).format(format);
98
97
  }
99
98
 
99
+ function getValueFromCookie(key, _default) {
100
+ var _a, _b;
101
+ const transformers = {
102
+ string: String,
103
+ boolean: (value) => value === 'true',
104
+ };
105
+ return typeof window !== 'undefined'
106
+ ? transformers[typeof _default]((_b = (_a = document.cookie
107
+ .split('; ')
108
+ .find((row) => row.startsWith(key))) === null || _a === void 0 ? void 0 : _a.split('=')[1]) !== null && _b !== void 0 ? _b : _default)
109
+ : _default;
110
+ }
111
+
100
112
  function isEmpty(s) {
101
113
  if (Array.isArray(s))
102
114
  return s.length === 0;
@@ -560,10 +572,10 @@ const sizeClassNames = {
560
572
  },
561
573
  };
562
574
  const Button = forwardRef((_a, ref) => {
563
- var { children, className, size = 'medium', color = 'slate', variant = 'filled', rounded, prefixIcon: PrefixIcon, suffixIcon: SuffixIcon } = _a, props = __rest(_a, ["children", "className", "size", "color", "variant", "rounded", "prefixIcon", "suffixIcon"]);
575
+ var { children, className, size = 'medium', color = 'slate', variant = 'filled', rounded, prefixIcon: PrefixIcon, suffixIcon: SuffixIcon, unstyled } = _a, props = __rest(_a, ["children", "className", "size", "color", "variant", "rounded", "prefixIcon", "suffixIcon", "unstyled"]);
564
576
  return (jsxs("button", Object.assign({ className: cn('relative flex aspect-square items-center font-medium duration-200', sizeClassNames[size].base, variantClassNames[variant][color].base, rounded ? 'rounded-full' : 'rounded-md', props.disabled
565
577
  ? 'cursor-not-allowed opacity-50'
566
- : props.onClick
578
+ : !unstyled
567
579
  ? `${variantClassNames[variant][color].hover} ${variantClassNames[variant][color].focus} ${variantClassNames[variant][color].active}`
568
580
  : 'cursor-default', children ? `${sizeClassNames[size].withChildren} aspect-[initial]` : 'justify-center', className), type: "button" }, props, { ref: ref, children: [PrefixIcon && (jsx(PrefixIcon, { className: children ? sizeClassNames[size].icon.withChildren : sizeClassNames[size].icon.base })), children, SuffixIcon && (jsx(SuffixIcon, { className: children ? sizeClassNames[size].icon.withChildren : sizeClassNames[size].icon.base }))] })));
569
581
  });
@@ -1571,18 +1583,19 @@ const ExpandButton = ({ folded, foldComponent, unfoldComponent, onClick, }) => {
1571
1583
  return (jsx(Icon, { className: "h-6 w-6 cursor-pointer rounded p-1 hover:bg-slate-300 hover:dark:bg-slate-600", onClick: onClick }));
1572
1584
  };
1573
1585
 
1574
- const $Dialog = DialogPrimitive.Root;
1586
+ const $Dialog = (props) => (jsx(DialogPrimitive.Root, Object.assign({}, props)));
1587
+ $Dialog.displayName = DialogPrimitive.Root.displayName;
1575
1588
  const DialogTrigger = DialogPrimitive.Trigger;
1576
1589
  const DialogPortal = DialogPrimitive.Portal;
1577
1590
  const DialogClose = DialogPrimitive.Close;
1578
1591
  const DialogOverlay = forwardRef((_a, ref) => {
1579
1592
  var { className } = _a, props = __rest(_a, ["className"]);
1580
- return (jsx(DialogPrimitive.Overlay, Object.assign({ ref: ref, className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 backdrop-blur-sm', className) }, props)));
1593
+ return (jsx(DialogPrimitive.Overlay, Object.assign({ ref: ref, className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className) }, props)));
1581
1594
  });
1582
1595
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
1583
1596
  const DialogContent = forwardRef((_a, ref) => {
1584
1597
  var { className, fullScreen, children } = _a, props = __rest(_a, ["className", "fullScreen", "children"]);
1585
- return (jsxs(DialogPortal, { children: [jsx(DialogOverlay, {}), jsxs(DialogPrimitive.Content, Object.assign({ ref: ref, className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]', 'fixed left-[50%] top-[50%] z-50 flex w-full max-w-lg translate-x-[-50%] translate-y-[-50%] flex-col gap-3 rounded-lg border bg-white p-3 shadow-md duration-200 xl:gap-4 xl:p-4 dark:border-slate-700 dark:bg-slate-900 dark:text-white', className, fullScreen && 'h-full max-h-none w-full max-w-none rounded-none') }, props, { children: [children, jsx(DialogPrimitive.Close, { className: "!absolute right-1 top-1 opacity-70 ring-offset-white transition-opacity hover:opacity-100 disabled:pointer-events-none xl:right-2 xl:top-2", asChild: true, children: jsx(Button, { prefixIcon: XIcon, size: "small", variant: "text" }) })] }))] }));
1598
+ return (jsxs(DialogPortal, { children: [jsx(DialogOverlay, {}), jsxs(DialogPrimitive.Content, Object.assign({ ref: ref, className: cn('bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]', 'fixed left-[50%] top-[50%] z-50 flex max-h-[95dvh] w-full max-w-lg translate-x-[-50%] translate-y-[-50%] flex-col gap-4 rounded-lg border p-4 shadow-lg duration-200', className, fullScreen && 'h-full max-h-none w-full max-w-none rounded-none'), "aria-describedby": "dialog-content" }, props, { children: [children, jsx(DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-2 top-2 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none", asChild: true, children: jsx(Button, { prefixIcon: XIcon, size: "small", variant: "text" }) }), jsx(DialogPrimitive.Description, { className: "hidden" })] }))] }));
1586
1599
  });
1587
1600
  DialogContent.displayName = DialogPrimitive.Content.displayName;
1588
1601
  const DialogHeader = (_a) => {
@@ -1597,12 +1610,12 @@ const DialogFooter = (_a) => {
1597
1610
  DialogFooter.displayName = 'DialogFooter';
1598
1611
  const DialogTitle = forwardRef((_a, ref) => {
1599
1612
  var { className } = _a, props = __rest(_a, ["className"]);
1600
- return (jsx(DialogPrimitive.Title, Object.assign({ ref: ref, className: cn('text-lg font-semibold leading-none tracking-tight', className) }, props)));
1613
+ return (jsx(DialogPrimitive.Title, Object.assign({ ref: ref, className: cn('text-foreground text-lg font-semibold', className) }, props)));
1601
1614
  });
1602
1615
  DialogTitle.displayName = DialogPrimitive.Title.displayName;
1603
1616
  const DialogDescription = forwardRef((_a, ref) => {
1604
1617
  var { className } = _a, props = __rest(_a, ["className"]);
1605
- return (jsx(DialogPrimitive.Description, Object.assign({ ref: ref, className: cn('text-sm text-slate-600 dark:text-slate-400', className) }, props)));
1618
+ return (jsx(DialogPrimitive.Description, Object.assign({ ref: ref, className: cn('text-muted-foreground text-sm', className) }, props)));
1606
1619
  });
1607
1620
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
1608
1621
  const Dialog = Object.assign($Dialog, {
@@ -1617,9 +1630,69 @@ const Dialog = Object.assign($Dialog, {
1617
1630
  Description: DialogDescription,
1618
1631
  });
1619
1632
 
1620
- const ConfirmDialog = ({ open, title, children, yesLabel, noLabel, onConfirm, onClose, }) => (jsx(Dialog, { open: open, onOpenChange: (value) => !value && onClose(), children: jsxs(Dialog.Content, { onPointerDownOutside: (event) => event.preventDefault(), children: [jsx(Dialog.Header, { children: jsx(Dialog.Title, { children: title }) }), children, jsxs(Dialog.Footer, { children: [jsx(Dialog.Close, { asChild: true, children: jsx(Button, { color: "red", children: noLabel !== null && noLabel !== void 0 ? noLabel : 'No' }) }), jsx(Dialog.Close, { asChild: true, children: jsx(Button, { color: "green", onClick: onConfirm, children: yesLabel !== null && yesLabel !== void 0 ? yesLabel : 'Yes' }) })] })] }) }));
1633
+ const ConfirmDialog = ({ open, title, children, yesLabel, noLabel, onConfirm, onClose, }) => (jsx(Dialog, { open: open, onOpenChange: (value) => !value && onClose(), children: jsxs(Dialog.Content, { children: [jsx(Dialog.Header, { children: jsx(Dialog.Title, { children: title }) }), children, jsxs(Dialog.Footer, { children: [jsx(Dialog.Close, { asChild: true, children: jsx(Button, { color: "red", children: noLabel !== null && noLabel !== void 0 ? noLabel : 'No' }) }), jsx(Dialog.Close, { asChild: true, children: jsx(Button, { color: "green", onClick: onConfirm, children: yesLabel !== null && yesLabel !== void 0 ? yesLabel : 'Yes' }) })] })] }) }));
1634
+
1635
+ const $Sheet = (props) => (jsx(DialogPrimitive.Root, Object.assign({}, props)));
1636
+ $Sheet.displayName = DialogPrimitive.Root.displayName;
1637
+ const SheetTrigger = DialogPrimitive.Trigger;
1638
+ const SheetClose = DialogPrimitive.Close;
1639
+ const SheetPortal = DialogPrimitive.Portal;
1640
+ const SheetOverlay = forwardRef((_a, ref) => {
1641
+ var { className } = _a, props = __rest(_a, ["className"]);
1642
+ return (jsx(DialogPrimitive.Overlay, Object.assign({ className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className) }, props, { ref: ref })));
1643
+ });
1644
+ SheetOverlay.displayName = DialogPrimitive.Overlay.displayName;
1645
+ const sheetVariants = cva('fixed flex flex-col z-50 gap-4 bg-background p-4 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500', {
1646
+ variants: {
1647
+ side: {
1648
+ top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',
1649
+ bottom: 'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
1650
+ left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',
1651
+ right: 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',
1652
+ },
1653
+ },
1654
+ defaultVariants: {
1655
+ side: 'right',
1656
+ },
1657
+ });
1658
+ const SheetContent = forwardRef((_a, ref) => {
1659
+ var { side = 'right', className, children } = _a, props = __rest(_a, ["side", "className", "children"]);
1660
+ return (jsxs(SheetPortal, { children: [jsx(SheetOverlay, {}), jsxs(DialogPrimitive.Content, Object.assign({ ref: ref, className: cn(sheetVariants({ side }), className) }, props, { children: [children, jsx(DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-2 top-2 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none", asChild: true, children: jsx(Button, { prefixIcon: XIcon, size: "small", variant: "text" }) }), jsx(DialogPrimitive.Description, { className: "hidden" })] }))] }));
1661
+ });
1662
+ SheetContent.displayName = DialogPrimitive.Content.displayName;
1663
+ const SheetHeader = (_a) => {
1664
+ var { className } = _a, props = __rest(_a, ["className"]);
1665
+ return (jsx("div", Object.assign({ className: cn('flex flex-col space-y-2 text-center sm:text-left', className) }, props)));
1666
+ };
1667
+ SheetHeader.displayName = 'SheetHeader';
1668
+ const SheetFooter = (_a) => {
1669
+ var { className } = _a, props = __rest(_a, ["className"]);
1670
+ return (jsx("div", Object.assign({ className: cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className) }, props)));
1671
+ };
1672
+ SheetFooter.displayName = 'SheetFooter';
1673
+ const SheetTitle = forwardRef((_a, ref) => {
1674
+ var { className } = _a, props = __rest(_a, ["className"]);
1675
+ return (jsx(DialogPrimitive.Title, Object.assign({ ref: ref, className: cn('text-foreground text-lg font-semibold', className) }, props)));
1676
+ });
1677
+ SheetTitle.displayName = DialogPrimitive.Title.displayName;
1678
+ const SheetDescription = forwardRef((_a, ref) => {
1679
+ var { className } = _a, props = __rest(_a, ["className"]);
1680
+ return (jsx(DialogPrimitive.Description, Object.assign({ ref: ref, className: cn('text-muted-foreground text-sm', className) }, props)));
1681
+ });
1682
+ SheetDescription.displayName = DialogPrimitive.Description.displayName;
1683
+ const Sheet = Object.assign($Sheet, {
1684
+ Portal: SheetPortal,
1685
+ Overlay: SheetOverlay,
1686
+ Trigger: SheetTrigger,
1687
+ Close: SheetClose,
1688
+ Content: SheetContent,
1689
+ Header: SheetHeader,
1690
+ Footer: SheetFooter,
1691
+ Title: SheetTitle,
1692
+ Description: SheetDescription,
1693
+ });
1621
1694
 
1622
- const FormDialog = ({ className, open, title, form, children, submitLabel = 'Submit', cancelLabel = 'Cancel', extraAction, onSubmit, onInvalid, onClose, }) => {
1695
+ const FormDialog = ({ className, formClassName, open, title, form, children, submitLabel = 'Submit', cancelLabel = 'Cancel', extraAction, as: As = Sheet, onSubmit, onInvalid, onClose, }) => {
1623
1696
  const id = useId();
1624
1697
  const handleSubmit = (data, event) => __awaiter(void 0, void 0, void 0, function* () {
1625
1698
  try {
@@ -1629,7 +1702,7 @@ const FormDialog = ({ className, open, title, form, children, submitLabel = 'Sub
1629
1702
  // do nothering
1630
1703
  }
1631
1704
  });
1632
- return (jsx(Dialog, { open: open, onOpenChange: (value) => !value && onClose(), children: jsxs(Dialog.Content, { className: className, onPointerDownOutside: (event) => event.preventDefault(), children: [jsx(Dialog.Header, { children: jsx(Dialog.Title, { children: title }) }), jsx(FormProvider, Object.assign({}, form, { children: jsx("form", { id: `form-${id}`, onSubmit: form.handleSubmit(handleSubmit, onInvalid), children: children }) })), jsxs(Dialog.Footer, { className: "w-full sm:justify-between", children: [extraAction, jsxs(Dialog.Footer, { className: "ml-auto", children: [jsx(Dialog.Close, { asChild: true, children: jsx(Button, { color: "red", children: cancelLabel }) }), jsx(Button, { color: "green", type: "submit", form: `form-${id}`, disabled: form.formState.isSubmitting, children: submitLabel })] })] })] }) }));
1705
+ return (jsx(As, { open: open, onOpenChange: (value) => !value && onClose(), children: jsxs(As.Content, { className: className, children: [jsx(As.Header, { children: jsx(As.Title, { children: title }) }), jsx(FormProvider, Object.assign({}, form, { children: jsx("form", { id: `form-${id}`, className: cn('flex h-full w-full flex-col gap-3 overflow-auto', formClassName), onSubmit: form.handleSubmit(handleSubmit, onInvalid), children: children }) })), jsxs(As.Footer, { className: "w-full sm:justify-between", children: [extraAction, jsxs(As.Footer, { className: "ml-auto", children: [jsx(As.Close, { asChild: true, children: jsx(Button, { color: "red", children: cancelLabel }) }), jsx(Button, { color: "green", type: "submit", form: `form-${id}`, disabled: form.formState.isSubmitting, children: submitLabel })] })] })] }) }));
1633
1706
  };
1634
1707
 
1635
1708
  function ListSorter({ className, items, idResolver, renderer, onChange, }) {
@@ -1667,11 +1740,11 @@ function ListSorterDialog({ className, open, title, items, idResolver, renderer,
1667
1740
  }, [items]);
1668
1741
  const preFinish = () => onSubmit(sortedItems);
1669
1742
  const customRenderer = (item, index, listeners) => (jsxs(Flex, { align: "center", className: "gap-4 p-4 focus:outline-none dark:bg-slate-900 hover:dark:bg-slate-800", children: [jsx(Flex, Object.assign({ align: "center", justify: "center", className: "cursor-move rounded-lg p-2 hover:bg-slate-200 dark:hover:bg-slate-700" }, listeners, { children: jsx(ArrowUpDownIcon, { className: "h-5 w-5" }) })), renderer(item, index, listeners)] }));
1670
- return (jsx(Dialog, { open: open, onOpenChange: (value) => !value && onClose(), children: jsxs(Dialog.Content, { className: cn('max-h-[90dvh]', className), onPointerDownOutside: (event) => event.preventDefault(), children: [jsx(Dialog.Header, { children: title }), jsx(ListSorter, { className: "divide-y overflow-auto rounded-lg border dark:divide-slate-700 dark:border-slate-700 dark:text-white", items: sortedItems, idResolver: idResolver, renderer: customRenderer, onChange: setSortedItems }), jsxs(Dialog.Footer, { children: [jsx(Dialog.Close, { asChild: true, children: jsx(Button, { color: "red", children: cancelLabel !== null && cancelLabel !== void 0 ? cancelLabel : 'Cancel' }) }), jsx(Button, { color: "green", onClick: preFinish, children: submitLabel !== null && submitLabel !== void 0 ? submitLabel : 'Submit' })] })] }) }));
1743
+ return (jsx(Dialog, { open: open, onOpenChange: (value) => !value && onClose(), children: jsxs(Dialog.Content, { className: className, onPointerDownOutside: (event) => event.preventDefault(), children: [jsx(Dialog.Header, { children: jsx(Dialog.Title, { children: title }) }), jsx(ListSorter, { className: "divide-y overflow-auto rounded-lg border dark:divide-slate-700 dark:border-slate-700 dark:text-white", items: sortedItems, idResolver: idResolver, renderer: customRenderer, onChange: setSortedItems }), jsxs(Dialog.Footer, { children: [jsx(Dialog.Close, { asChild: true, children: jsx(Button, { color: "red", children: cancelLabel !== null && cancelLabel !== void 0 ? cancelLabel : 'Cancel' }) }), jsx(Button, { color: "green", onClick: preFinish, children: submitLabel !== null && submitLabel !== void 0 ? submitLabel : 'Submit' })] })] }) }));
1671
1744
  }
1672
1745
 
1673
1746
  const PdfViewerDialog = ({ open, title, url, data, onClose }) => {
1674
- return !(url || data) ? null : (jsx(Dialog, { open: open, onOpenChange: (value) => !value && onClose(), children: jsxs(Dialog.Content, { className: "h-[90dvh] max-w-[90dvw]", children: [jsx(Dialog.Header, { children: title }), (url || data) && (jsx("embed", { className: "rounded-lg", src: url !== null && url !== void 0 ? url : `data:application/pdf;base64,${data}`, type: "application/pdf", width: "100%", height: "100%" }))] }) }));
1747
+ return !(url || data) ? null : (jsx(Dialog, { open: open, onOpenChange: (value) => !value && onClose(), children: jsxs(Dialog.Content, { className: "h-[95dvh] max-w-[95dvw]", children: [jsx(Dialog.Header, { children: jsx(Dialog.Title, { children: title }) }), (url || data) && (jsx("embed", { className: "rounded-lg", src: url !== null && url !== void 0 ? url : `data:application/pdf;base64,${data}`, type: "application/pdf", width: "100%", height: "100%" }))] }) }));
1675
1748
  };
1676
1749
 
1677
1750
  const Separator = forwardRef((_a, ref) => {
@@ -1680,65 +1753,6 @@ const Separator = forwardRef((_a, ref) => {
1680
1753
  });
1681
1754
  Separator.displayName = SeparatorPrimitive.Root.displayName;
1682
1755
 
1683
- const $Sheet = DialogPrimitive.Root;
1684
- const SheetTrigger = DialogPrimitive.Trigger;
1685
- const SheetClose = DialogPrimitive.Close;
1686
- const SheetPortal = DialogPrimitive.Portal;
1687
- const SheetOverlay = React.forwardRef((_a, ref) => {
1688
- var { className } = _a, props = __rest(_a, ["className"]);
1689
- return (jsx(DialogPrimitive.Overlay, Object.assign({ className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className) }, props, { ref: ref })));
1690
- });
1691
- SheetOverlay.displayName = DialogPrimitive.Overlay.displayName;
1692
- const sheetVariants = cva('fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500', {
1693
- variants: {
1694
- side: {
1695
- top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',
1696
- bottom: 'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
1697
- left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',
1698
- right: 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',
1699
- },
1700
- },
1701
- defaultVariants: {
1702
- side: 'right',
1703
- },
1704
- });
1705
- const SheetContent = React.forwardRef((_a, ref) => {
1706
- var { side = 'right', className, children } = _a, props = __rest(_a, ["side", "className", "children"]);
1707
- return (jsxs(SheetPortal, { children: [jsx(SheetOverlay, {}), jsxs(DialogPrimitive.Content, Object.assign({ ref: ref, className: cn(sheetVariants({ side }), className) }, props, { children: [children, jsxs(DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none", children: [jsx(X, { className: "h-4 w-4" }), jsx("span", { className: "sr-only", children: "Close" })] })] }))] }));
1708
- });
1709
- SheetContent.displayName = DialogPrimitive.Content.displayName;
1710
- const SheetHeader = (_a) => {
1711
- var { className } = _a, props = __rest(_a, ["className"]);
1712
- return (jsx("div", Object.assign({ className: cn('flex flex-col space-y-2 text-center sm:text-left', className) }, props)));
1713
- };
1714
- SheetHeader.displayName = 'SheetHeader';
1715
- const SheetFooter = (_a) => {
1716
- var { className } = _a, props = __rest(_a, ["className"]);
1717
- return (jsx("div", Object.assign({ className: cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className) }, props)));
1718
- };
1719
- SheetFooter.displayName = 'SheetFooter';
1720
- const SheetTitle = React.forwardRef((_a, ref) => {
1721
- var { className } = _a, props = __rest(_a, ["className"]);
1722
- return (jsx(DialogPrimitive.Title, Object.assign({ ref: ref, className: cn('text-foreground text-lg font-semibold', className) }, props)));
1723
- });
1724
- SheetTitle.displayName = DialogPrimitive.Title.displayName;
1725
- const SheetDescription = React.forwardRef((_a, ref) => {
1726
- var { className } = _a, props = __rest(_a, ["className"]);
1727
- return (jsx(DialogPrimitive.Description, Object.assign({ ref: ref, className: cn('text-muted-foreground text-sm', className) }, props)));
1728
- });
1729
- SheetDescription.displayName = DialogPrimitive.Description.displayName;
1730
- const Sheet = Object.assign($Sheet, {
1731
- Portal: SheetPortal,
1732
- Overlay: SheetOverlay,
1733
- Trigger: SheetTrigger,
1734
- Close: SheetClose,
1735
- Content: SheetContent,
1736
- Header: SheetHeader,
1737
- Footer: SheetFooter,
1738
- Title: SheetTitle,
1739
- Description: SheetDescription,
1740
- });
1741
-
1742
1756
  const Skeleton = (_a) => {
1743
1757
  var { className } = _a, props = __rest(_a, ["className"]);
1744
1758
  return (jsx("div", Object.assign({ className: cn('bg-muted animate-pulse rounded-md', className) }, props)));
@@ -1766,15 +1780,16 @@ const SidebarContextProvider = forwardRef((_a, ref) => {
1766
1780
  const screenRef = useRef(document.documentElement);
1767
1781
  // This is the internal state of the sidebar.
1768
1782
  // We use openProp and setOpenProp for control from outside the component.
1769
- const [_open, _setOpen] = useState(defaultOpen);
1783
+ const [_open, _setOpen] = useState(getValueFromCookie(SIDEBAR_COOKIE_NAME, defaultOpen));
1770
1784
  const open = openProp !== null && openProp !== void 0 ? openProp : _open;
1771
1785
  const setOpen = useCallback((value) => {
1772
1786
  if (setOpenProp) {
1773
1787
  return setOpenProp === null || setOpenProp === void 0 ? void 0 : setOpenProp(typeof value === 'function' ? value(open) : value);
1774
1788
  }
1775
- _setOpen(value);
1789
+ const newValue = typeof value === 'function' ? value(open) : value;
1790
+ _setOpen(newValue);
1776
1791
  // This sets the cookie to keep the sidebar state.
1777
- document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
1792
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${newValue}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
1778
1793
  }, [setOpenProp, open]);
1779
1794
  // Helper to toggle the sidebar.
1780
1795
  const toggleSidebar = useCallback(() => {
@@ -1833,7 +1848,7 @@ $Sidebar.displayName = 'Sidebar';
1833
1848
  const SidebarTrigger = forwardRef((_a, ref) => {
1834
1849
  var { className, onClick } = _a, props = __rest(_a, ["className", "onClick"]);
1835
1850
  const { toggleSidebar } = useSidebar();
1836
- return (jsx(Button, Object.assign({ ref: ref, "data-sidebar": "trigger", variant: "text", suffixIcon: PanelLeft, className: cn('h-7 w-7', className), onClick: (event) => {
1851
+ return (jsx(Button, Object.assign({ ref: ref, "data-sidebar": "trigger", variant: "text", suffixIcon: PanelLeft, className: className, onClick: (event) => {
1837
1852
  onClick === null || onClick === void 0 ? void 0 : onClick(event);
1838
1853
  toggleSidebar();
1839
1854
  } }, props)));
@@ -2007,7 +2022,7 @@ const Sidebar = Object.assign($Sidebar, {
2007
2022
  Trigger: SidebarTrigger,
2008
2023
  });
2009
2024
 
2010
- const Navbar = ({ className, leftSlot, rightSlot }) => (jsx(Block, { className: cn('border-b p-3 dark:border-slate-700', className), fullWidth: true, children: jsxs(Flex, { align: "center", justify: "between", children: [jsxs(Flex, { align: "center", children: [jsx(Sidebar.Trigger, {}), leftSlot] }), rightSlot] }) }));
2025
+ const Navbar = ({ className, sidebarTriggerClassName, leftSlot, rightSlot, }) => (jsx(Block, { className: cn('border-b p-3 dark:border-slate-700', className), fullWidth: true, children: jsxs(Flex, { align: "center", justify: "between", children: [jsxs(Flex, { align: "center", children: [jsx(Sidebar.Trigger, { className: sidebarTriggerClassName }), leftSlot] }), rightSlot] }) }));
2011
2026
 
2012
2027
  const Layout = (_a) => {
2013
2028
  var { children, className } = _a, _b = _a.sidebarProps, { basePath, smallLogo, fullLogo, items } = _b, sidebarProps = __rest(_b, ["basePath", "smallLogo", "fullLogo", "items"]), { navbarProps } = _a;
@@ -2067,26 +2082,37 @@ const Tabs = Object.assign($Tabs, {
2067
2082
  });
2068
2083
 
2069
2084
  const LayoutContext = createContext(undefined);
2085
+ const THEME_MEDIA_QUERY = '(prefers-color-scheme: dark)';
2086
+ const THEME_COOKIE_NAME = 'theme:state';
2087
+ const THEME_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
2070
2088
  const LayoutContextProvider = ({ children }) => {
2071
- const [theme, setTheme] = useState(getValueFromLocalStorage(THEME_KEY, 'light'));
2089
+ const [theme, _setTheme] = useState(getValueFromCookie(THEME_COOKIE_NAME, 'system'));
2090
+ const [resolvedTheme, setResolvedTheme] = useState(() => theme === 'system' ? getSystemTheme() : theme);
2072
2091
  useEffect(() => {
2073
- if (theme) {
2074
- if (theme === 'dark') {
2075
- document.documentElement.classList.add('dark');
2076
- }
2077
- else {
2078
- document.documentElement.classList.remove('dark');
2079
- }
2092
+ if (resolvedTheme === 'dark') {
2093
+ document.documentElement.classList.add('dark');
2094
+ }
2095
+ else {
2096
+ document.documentElement.classList.remove('dark');
2097
+ }
2098
+ }, [resolvedTheme]);
2099
+ useEffect(() => {
2100
+ if (theme !== 'system') {
2101
+ setResolvedTheme(theme);
2102
+ return;
2080
2103
  }
2104
+ setResolvedTheme(getSystemTheme());
2105
+ const handleMediaQuery = (e) => setResolvedTheme(getSystemTheme(e));
2106
+ const mediaQuery = window.matchMedia(THEME_MEDIA_QUERY);
2107
+ mediaQuery.addEventListener('change', handleMediaQuery);
2108
+ return () => mediaQuery.removeEventListener('change', handleMediaQuery);
2081
2109
  }, [theme]);
2082
- const toggleTheme = () => {
2083
- setTheme((theme) => {
2084
- const newValue = theme === 'dark' ? 'light' : 'dark';
2085
- window.localStorage.setItem(THEME_KEY, newValue);
2086
- return newValue;
2087
- });
2110
+ const setTheme = (theme) => {
2111
+ _setTheme(theme);
2112
+ // This sets the cookie to keep the theme state.
2113
+ document.cookie = `${THEME_COOKIE_NAME}=${theme}; path=/; max-age=${THEME_COOKIE_MAX_AGE}`;
2088
2114
  };
2089
- return jsx(LayoutContext.Provider, { value: { theme, toggleTheme }, children: children });
2115
+ return (jsx(LayoutContext.Provider, { value: { theme, resolvedTheme, setTheme }, children: children }));
2090
2116
  };
2091
2117
  function useLayoutContext() {
2092
2118
  const context = useContext(LayoutContext);
@@ -2095,24 +2121,15 @@ function useLayoutContext() {
2095
2121
  }
2096
2122
  return context;
2097
2123
  }
2098
- const THEME_KEY = 'tw-react-components__theme';
2099
- function getValueFromLocalStorage(key, _default) {
2100
- var _a;
2101
- const transformers = {
2102
- string: String,
2103
- boolean: (value) => value === 'true',
2104
- };
2105
- return typeof window !== 'undefined'
2106
- ? transformers[typeof _default]((_a = window.localStorage.getItem(key)) !== null && _a !== void 0 ? _a : _default)
2107
- : _default;
2124
+ function getSystemTheme(e) {
2125
+ if (!e)
2126
+ e = window.matchMedia(THEME_MEDIA_QUERY);
2127
+ return e.matches ? 'dark' : 'light';
2108
2128
  }
2109
2129
 
2110
- const ThemeSwitcher = ({ className }) => {
2111
- const { theme, toggleTheme } = useLayoutContext();
2112
- const darkMode = theme === 'dark';
2113
- return (jsx(Switch, { className: className, checked: darkMode, onCheckedChange: toggleTheme, thumbProps: {
2114
- children: darkMode ? (jsx(MoonIcon, { className: "h-6 w-6 rounded-full bg-slate-900 p-1 text-white" })) : (jsx(SunIcon, { className: "h-6 w-6 rounded-full bg-white p-1 text-black" })),
2115
- } }));
2130
+ const ThemeSelector = ({ className }) => {
2131
+ const { resolvedTheme, setTheme } = useLayoutContext();
2132
+ return (jsxs(DropdownMenu, { children: [jsx(DropdownMenu.Trigger, { asChild: true, children: jsx(Button, { prefixIcon: resolvedTheme === 'dark' ? MoonIcon : SunIcon, className: className, variant: "text" }) }), jsxs(DropdownMenu.Content, { children: [jsxs(DropdownMenu.Item, { onClick: () => setTheme('light'), children: [jsx(DropdownMenu.Icon, { icon: SunIcon }), "Light"] }), jsxs(DropdownMenu.Item, { onClick: () => setTheme('dark'), children: [jsx(DropdownMenu.Icon, { icon: MoonIcon }), "Dark"] }), jsxs(DropdownMenu.Item, { onClick: () => setTheme('system'), children: [jsx(DropdownMenu.Icon, { icon: MonitorIcon }), "System"] })] })] }));
2116
2133
  };
2117
2134
 
2118
- export { Badge, BasicInput, BasicInputExtension, Block, Button, Card, CheckboxInput, ConfirmDialog, DataTable, DateTimeInput, Dialog, DropdownMenu, EmailInput, FileInput, Flex, FormDialog, FormGroup, FormInputs, Hint, Label, Layout, LayoutContext, LayoutContextProvider, List, ListSorter, ListSorterDialog, Navbar, NumberInput, Pagination, PasswordInput, PdfViewerDialog, Popover, SelectInput, Separator, Sheet, Sidebar, SidebarContext, SidebarContextProvider, Skeleton, Spinner, Switch, THEME_KEY, Table, Tabs, TextInput, TextareaInput, ThemeSwitcher, Tooltip, cn, compareDates, generalComparator, getDisplayDate, isEmpty, mergeRefs, resolveTargetObject, useDays, useIsMobile, useLayoutContext, useLongPress, useMonths, useOnSwipe, useOutsideClick, usePagination, useSidebar };
2135
+ export { Badge, BasicInput, BasicInputExtension, Block, Button, Card, CheckboxInput, ConfirmDialog, DataTable, DateTimeInput, Dialog, DropdownMenu, EmailInput, FileInput, Flex, FormDialog, FormGroup, FormInputs, Hint, Label, Layout, LayoutContext, LayoutContextProvider, List, ListSorter, ListSorterDialog, Navbar, NumberInput, Pagination, PasswordInput, PdfViewerDialog, Popover, SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME, SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON, SIDEBAR_WIDTH_MOBILE, SelectInput, Separator, Sheet, Sidebar, SidebarContext, SidebarContextProvider, Skeleton, Spinner, Switch, THEME_COOKIE_MAX_AGE, THEME_COOKIE_NAME, THEME_MEDIA_QUERY, Table, Tabs, TextInput, TextareaInput, ThemeSelector, Tooltip, cn, compareDates, generalComparator, getDisplayDate, getValueFromCookie, isEmpty, mergeRefs, resolveTargetObject, useDays, useIsMobile, useLayoutContext, useLongPress, useMonths, useOnSwipe, useOutsideClick, usePagination, useSidebar };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tw-react-components",
3
3
  "description": "A set of React components build with TailwindCSS to make a nice dashboard.",
4
- "version": "0.0.138",
4
+ "version": "0.0.140",
5
5
  "license": "MIT",
6
6
  "homepage": "https://bacali95.github.io/tw-react-components",
7
7
  "author": {
@@ -9,6 +9,7 @@ export type ButtonProps = PropsWithoutRef<ComponentProps<'button'>> & {
9
9
  rounded?: boolean;
10
10
  prefixIcon?: LucideIcon;
11
11
  suffixIcon?: LucideIcon;
12
+ unstyled?: boolean;
12
13
  };
13
14
  export declare const Button: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
14
15
  size?: Size;
@@ -17,4 +18,5 @@ export declare const Button: import("react").ForwardRefExoticComponent<Omit<impo
17
18
  rounded?: boolean;
18
19
  prefixIcon?: LucideIcon;
19
20
  suffixIcon?: LucideIcon;
21
+ unstyled?: boolean;
20
22
  } & import("react").RefAttributes<HTMLButtonElement>>;
@@ -1,7 +1,7 @@
1
1
  import * as DialogPrimitive from '@radix-ui/react-dialog';
2
- import { HTMLAttributes } from 'react';
3
- export declare const Dialog: import("react").FC<DialogPrimitive.DialogProps> & {
4
- Portal: import("react").FC<DialogPrimitive.DialogPortalProps>;
2
+ import { FC, HTMLAttributes } from 'react';
3
+ export declare const Dialog: FC<DialogPrimitive.DialogProps> & {
4
+ Portal: FC<DialogPrimitive.DialogPortalProps>;
5
5
  Overlay: import("react").ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & import("react").RefAttributes<HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
6
6
  Close: import("react").ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & import("react").RefAttributes<HTMLButtonElement>>;
7
7
  Trigger: import("react").ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
@@ -1,16 +1,20 @@
1
1
  import { PropsWithChildren, ReactNode } from 'react';
2
2
  import { FieldValues, SubmitErrorHandler, SubmitHandler, UseFormReturn } from 'react-hook-form';
3
+ import { Sheet } from '../Sheet';
4
+ import { Dialog } from './Dialog';
3
5
  type Props<T extends FieldValues> = {
4
6
  className?: string;
7
+ formClassName?: string;
5
8
  open: boolean;
6
9
  title: ReactNode;
7
10
  form: UseFormReturn<T>;
8
11
  submitLabel?: string;
9
12
  cancelLabel?: string;
10
13
  extraAction?: ReactNode;
14
+ as?: typeof Dialog | typeof Sheet;
11
15
  onSubmit: SubmitHandler<T>;
12
16
  onInvalid?: SubmitErrorHandler<T>;
13
17
  onClose: () => void;
14
18
  };
15
- export declare const FormDialog: <T extends FieldValues>({ className, open, title, form, children, submitLabel, cancelLabel, extraAction, onSubmit, onInvalid, onClose, }: PropsWithChildren<Props<T>>) => import("react/jsx-runtime").JSX.Element;
19
+ export declare const FormDialog: <T extends FieldValues>({ className, formClassName, open, title, form, children, submitLabel, cancelLabel, extraAction, as: As, onSubmit, onInvalid, onClose, }: PropsWithChildren<Props<T>>) => import("react/jsx-runtime").JSX.Element;
16
20
  export {};
@@ -1,6 +1,7 @@
1
1
  import { FC, ReactNode } from 'react';
2
2
  export type NavbarProps = {
3
3
  className?: string;
4
+ sidebarTriggerClassName?: string;
4
5
  leftSlot?: ReactNode;
5
6
  rightSlot?: ReactNode;
6
7
  };
@@ -1,26 +1,26 @@
1
1
  import * as SheetPrimitive from '@radix-ui/react-dialog';
2
2
  import { type VariantProps } from 'class-variance-authority';
3
- import * as React from 'react';
3
+ import { ComponentPropsWithoutRef, FC, HTMLAttributes } from 'react';
4
4
  declare const sheetVariants: (props?: ({
5
5
  side?: "top" | "bottom" | "left" | "right" | null | undefined;
6
6
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
7
- interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
7
+ interface SheetContentProps extends ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
8
8
  }
9
- export declare const Sheet: React.FC<SheetPrimitive.DialogProps> & {
10
- Portal: React.FC<SheetPrimitive.DialogPortalProps>;
11
- Overlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
12
- Trigger: React.ForwardRefExoticComponent<SheetPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
13
- Close: React.ForwardRefExoticComponent<SheetPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
14
- Content: React.ForwardRefExoticComponent<SheetContentProps & React.RefAttributes<HTMLDivElement>>;
9
+ export declare const Sheet: FC<SheetPrimitive.DialogProps> & {
10
+ Portal: FC<SheetPrimitive.DialogPortalProps>;
11
+ Overlay: import("react").ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & import("react").RefAttributes<HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
12
+ Trigger: import("react").ForwardRefExoticComponent<SheetPrimitive.DialogTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
13
+ Close: import("react").ForwardRefExoticComponent<SheetPrimitive.DialogCloseProps & import("react").RefAttributes<HTMLButtonElement>>;
14
+ Content: import("react").ForwardRefExoticComponent<SheetContentProps & import("react").RefAttributes<HTMLDivElement>>;
15
15
  Header: {
16
- ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
16
+ ({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
17
17
  displayName: string;
18
18
  };
19
19
  Footer: {
20
- ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
20
+ ({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
21
21
  displayName: string;
22
22
  };
23
- Title: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
24
- Description: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
23
+ Title: import("react").ForwardRefExoticComponent<Omit<SheetPrimitive.DialogTitleProps & import("react").RefAttributes<HTMLHeadingElement>, "ref"> & import("react").RefAttributes<HTMLHeadingElement>>;
24
+ Description: import("react").ForwardRefExoticComponent<Omit<SheetPrimitive.DialogDescriptionProps & import("react").RefAttributes<HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
25
25
  };
26
26
  export {};
@@ -1,6 +1,12 @@
1
1
  import { type VariantProps } from 'class-variance-authority';
2
2
  import { ComponentProps } from 'react';
3
3
  import { Tooltip } from '../Tooltip';
4
+ export declare const SIDEBAR_COOKIE_NAME = "sidebar:state";
5
+ export declare const SIDEBAR_COOKIE_MAX_AGE: number;
6
+ export declare const SIDEBAR_WIDTH = "16rem";
7
+ export declare const SIDEBAR_WIDTH_MOBILE = "18rem";
8
+ export declare const SIDEBAR_WIDTH_ICON = "3rem";
9
+ export declare const SIDEBAR_KEYBOARD_SHORTCUT = "b";
4
10
  export type SidebarContext = {
5
11
  state: 'expanded' | 'collapsed';
6
12
  open: boolean;
@@ -81,5 +87,6 @@ export declare const Sidebar: import("react").ForwardRefExoticComponent<Omit<imp
81
87
  rounded?: boolean;
82
88
  prefixIcon?: import("lucide-react").LucideIcon;
83
89
  suffixIcon?: import("lucide-react").LucideIcon;
90
+ unstyled?: boolean;
84
91
  } & import("react").RefAttributes<HTMLButtonElement>, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
85
92
  };
@@ -2,5 +2,5 @@ import { FC } from 'react';
2
2
  type Props = {
3
3
  className?: string;
4
4
  };
5
- export declare const ThemeSwitcher: FC<Props>;
5
+ export declare const ThemeSelector: FC<Props>;
6
6
  export {};
@@ -22,6 +22,6 @@ export * from './Spinner';
22
22
  export * from './Switch';
23
23
  export * from './Table';
24
24
  export * from './Tabs';
25
- export * from './ThemeSwitcher';
25
+ export * from './ThemeSelector';
26
26
  export * from './Tooltip';
27
27
  export * from './types';
@@ -1,10 +1,13 @@
1
1
  import { FC, PropsWithChildren } from 'react';
2
+ export type ThemeState = 'dark' | 'light' | 'system';
2
3
  export type LayoutContext = {
3
4
  theme: ThemeState;
4
- toggleTheme: () => void;
5
+ resolvedTheme: Exclude<ThemeState, 'system'>;
6
+ setTheme: (theme: ThemeState) => void;
5
7
  };
6
8
  export declare const LayoutContext: import("react").Context<LayoutContext | undefined>;
9
+ export declare const THEME_MEDIA_QUERY = "(prefers-color-scheme: dark)";
10
+ export declare const THEME_COOKIE_NAME = "theme:state";
11
+ export declare const THEME_COOKIE_MAX_AGE: number;
7
12
  export declare const LayoutContextProvider: FC<PropsWithChildren>;
8
13
  export declare function useLayoutContext(): LayoutContext;
9
- export type ThemeState = 'dark' | 'light';
10
- export declare const THEME_KEY = "tw-react-components__theme";
@@ -0,0 +1 @@
1
+ export declare function getValueFromCookie<T extends string | boolean>(key: string, _default: T): T;
@@ -2,6 +2,7 @@ export * from './cn';
2
2
  export * from './compareDates';
3
3
  export * from './generalComparator';
4
4
  export * from './getDisplayDate';
5
+ export * from './getValueFromCookie';
5
6
  export * from './isEmpty';
6
7
  export * from './mergeRefs';
7
8
  export * from './resolveTargetObject';