tw-react-components 0.0.135 → 0.0.137
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.cjs.js +536 -199
- package/index.css +101 -0
- package/index.esm.js +430 -100
- package/package.json +5 -2
- package/src/components/Form/controls/custom/date-time/DateSelector.d.ts +2 -2
- package/src/components/Form/controls/custom/date-time/DaysView.d.ts +2 -2
- package/src/components/Form/controls/custom/date-time/MonthsView.d.ts +2 -2
- package/src/components/Form/controls/custom/date-time/TimeSelector.d.ts +2 -2
- package/src/components/Form/controls/custom/date-time/YearsView.d.ts +2 -2
- package/src/components/Form/controls/custom/date-time/index.d.ts +4 -4
- package/src/components/Form/controls/custom/file.d.ts +11 -0
- package/src/components/Form/controls/custom/index.d.ts +1 -0
- package/src/components/Form/controls/custom/select/index.d.ts +1 -1
- package/src/components/Form/controls/primitive/BasicInput.d.ts +2 -3
- package/src/components/Form/controls/primitive/NumberInput.d.ts +7 -2
- package/src/components/Form/controls/with-form.d.ts +6 -1
- package/src/components/Layout/index.d.ts +23 -2
- package/src/components/Separator/index.d.ts +2 -0
- package/src/components/Sheet/index.d.ts +26 -0
- package/src/components/Sidebar/index.d.ts +82 -23
- package/src/components/Skeleton/index.d.ts +2 -0
- package/src/components/index.d.ts +3 -0
- package/src/contexts/LayoutContext.d.ts +0 -3
- package/src/hooks/index.d.ts +1 -0
- package/src/hooks/useIsMobile.d.ts +1 -0
- package/tailwindcss-plugin.cjs +88 -0
- package/src/components/Sidebar/SidebarItem.d.ts +0 -10
package/index.esm.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
2
3
|
import { forwardRef, useMemo, useState, useEffect, useId, useCallback, useRef, createContext, useContext } from 'react';
|
|
3
4
|
import { clsx } from 'clsx';
|
|
4
5
|
import { twMerge } from 'tailwind-merge';
|
|
5
6
|
import dayjs from 'dayjs';
|
|
6
7
|
import advancedFormat from 'dayjs/plugin/advancedFormat';
|
|
7
|
-
import { HelpCircle, XIcon, AtSignIcon, EyeIcon, EyeOffIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronDownIcon, CalendarIcon, ClockIcon, CheckIcon, CircleIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsDownUpIcon, ChevronsUpDownIcon, ArrowUpDownIcon, SortAscIcon, SortDescIcon, MinusIcon, PlusIcon,
|
|
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';
|
|
8
9
|
import localeData from 'dayjs/plugin/localeData';
|
|
9
10
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
10
11
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
@@ -14,8 +15,10 @@ import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, close
|
|
|
14
15
|
import { restrictToFirstScrollableAncestor } from '@dnd-kit/modifiers';
|
|
15
16
|
import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
16
17
|
import { CSS } from '@dnd-kit/utilities';
|
|
17
|
-
import * as Accordion from '@radix-ui/react-accordion';
|
|
18
18
|
import { Link, useLocation } from 'react-router-dom';
|
|
19
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
20
|
+
import { cva } from 'class-variance-authority';
|
|
21
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
19
22
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
20
23
|
import * as SwitchPrimitives from '@radix-ui/react-switch';
|
|
21
24
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
@@ -616,6 +619,21 @@ function useDays(locale = 'en') {
|
|
|
616
619
|
}, [locale]);
|
|
617
620
|
}
|
|
618
621
|
|
|
622
|
+
const MOBILE_BREAKPOINT = 768;
|
|
623
|
+
function useIsMobile() {
|
|
624
|
+
const [isMobile, setIsMobile] = useState(undefined);
|
|
625
|
+
useEffect(() => {
|
|
626
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
627
|
+
const onChange = () => {
|
|
628
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
629
|
+
};
|
|
630
|
+
mql.addEventListener('change', onChange);
|
|
631
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
632
|
+
return () => mql.removeEventListener('change', onChange);
|
|
633
|
+
}, []);
|
|
634
|
+
return !!isMobile;
|
|
635
|
+
}
|
|
636
|
+
|
|
619
637
|
function useLongPress(callback, ms = 100) {
|
|
620
638
|
const [startLongPress, setStartLongPress] = useState(false);
|
|
621
639
|
useEffect(() => {
|
|
@@ -745,7 +763,7 @@ const Label = ({ children, className, description, required, hasErrors, htmlFor,
|
|
|
745
763
|
return !children ? null : (jsxs("label", { className: cn('flex items-center gap-1 font-medium', {
|
|
746
764
|
'text-slate-700 dark:text-slate-100': !hasErrors,
|
|
747
765
|
'text-red-600 dark:text-red-500': hasErrors,
|
|
748
|
-
}, className), htmlFor: htmlFor, children: [
|
|
766
|
+
}, className), htmlFor: htmlFor, children: [children, description && (jsx(Tooltip, { content: jsx("div", { className: "max-w-xs", children: description }), placement: "top", asChild: true, children: jsx(HelpCircle, { className: "h-4 w-4" }) })), required && jsx("span", { className: "text-red-600", children: "*" })] }));
|
|
749
767
|
};
|
|
750
768
|
|
|
751
769
|
const inputClasses = {
|
|
@@ -837,7 +855,12 @@ const CheckboxInput = forwardRef((props, ref) => (jsx(BasicInput, Object.assign(
|
|
|
837
855
|
|
|
838
856
|
const EmailInput = forwardRef((props, ref) => (jsx(BasicInput, Object.assign({ type: "email" }, props, { suffixIcon: AtSignIcon, ref: ref }))));
|
|
839
857
|
|
|
840
|
-
const NumberInput = forwardRef((
|
|
858
|
+
const NumberInput = forwardRef((_a, ref) => {
|
|
859
|
+
var { unit } = _a, props = __rest(_a, ["unit"]);
|
|
860
|
+
return (jsx(BasicInput, Object.assign({ type: "number" }, props, { suffixIcon: unit
|
|
861
|
+
? ({ className }) => (jsx("div", { className: cn(className, 'flex w-min items-center'), onClick: props.onSuffixIconClick, children: unit }))
|
|
862
|
+
: props.suffixIcon, ref: ref })));
|
|
863
|
+
});
|
|
841
864
|
|
|
842
865
|
const PasswordInput = forwardRef((props, ref) => {
|
|
843
866
|
const [type, setType] = useState('password');
|
|
@@ -1092,7 +1115,7 @@ const DateTimeInput = forwardRef((_a, ref) => {
|
|
|
1092
1115
|
setIsOpen(false);
|
|
1093
1116
|
}
|
|
1094
1117
|
};
|
|
1095
|
-
return (jsxs("div", { className: cn('relative w-full', className), ref: ref, children: [jsx(BasicInput, Object.assign({}, props, { type: "text", readOnly: true, value: displayDate !== null && displayDate !== void 0 ? displayDate : '', hasErrors: hasErrors, onClick: handleOnClick, onKeyUp: handleOnKeyUp, clearable: clearable && !!displayDate, onClear: clearDate, suffixIcon: (type === null || type === void 0 ? void 0 : type.includes('date')) ? CalendarIcon : ClockIcon })), isOpen && (jsxs("div", { className: "absolute z-20 mt-2 flex origin-top-left flex-col rounded-md border bg-white shadow duration-200 dark:border-slate-700 dark:bg-slate-900 dark:text-white", tabIndex: 0, onBlur: handleOnBlur, ref: calendarRef, children: [(type === null || type === void 0 ? void 0 : type.includes('date')) && (jsx(DateSelector, { date: date, value: value, minDate: minDate, maxDate: maxDate, locale: displayLocale, calendarView: calendarView, setCalendarView: setCalendarView, setNewDate: setNewDate })), calendarView === 'days' && (jsxs("div", { className: "flex select-none items-center justify-end gap-2 px-3 py-2", children: [(type === null || type === void 0 ? void 0 : type.includes('time')) && (jsx(TimeSelector, { date: date, step: step, minDate: minDate, maxDate: maxDate, setNewDate: setNewDate })), jsx("div", { className: "cursor-pointer rounded-lg border border-transparent p-1 text-sm font-bold uppercase text-blue-600 transition duration-100 ease-in-out hover:bg-slate-100 dark:text-blue-500 dark:hover:bg-slate-700", onClick: () => setIsOpen(false), children: "OK" })] }))] }))] }));
|
|
1118
|
+
return (jsxs("div", { className: cn('relative w-full', className), ref: ref, children: [jsx(BasicInput, Object.assign({}, props, { type: "text", readOnly: true, value: displayDate !== null && displayDate !== void 0 ? displayDate : '', hasErrors: hasErrors, onClick: handleOnClick, onKeyUp: handleOnKeyUp, clearable: clearable && !!displayDate, onClear: clearDate, suffixIcon: (type === null || type === void 0 ? void 0 : type.includes('date')) ? CalendarIcon : ClockIcon, onSuffixIconClick: handleOnClick })), isOpen && (jsxs("div", { className: "absolute z-20 mt-2 flex origin-top-left flex-col rounded-md border bg-white shadow duration-200 dark:border-slate-700 dark:bg-slate-900 dark:text-white", tabIndex: 0, onBlur: handleOnBlur, ref: calendarRef, children: [(type === null || type === void 0 ? void 0 : type.includes('date')) && (jsx(DateSelector, { date: date, value: value, minDate: minDate, maxDate: maxDate, locale: displayLocale, calendarView: calendarView, setCalendarView: setCalendarView, setNewDate: setNewDate })), calendarView === 'days' && (jsxs("div", { className: "flex select-none items-center justify-end gap-2 px-3 py-2", children: [(type === null || type === void 0 ? void 0 : type.includes('time')) && (jsx(TimeSelector, { date: date, step: step, minDate: minDate, maxDate: maxDate, setNewDate: setNewDate })), jsx("div", { className: "cursor-pointer rounded-lg border border-transparent p-1 text-sm font-bold uppercase text-blue-600 transition duration-100 ease-in-out hover:bg-slate-100 dark:text-blue-500 dark:hover:bg-slate-700", onClick: () => setIsOpen(false), children: "OK" })] }))] }))] }));
|
|
1096
1119
|
});
|
|
1097
1120
|
|
|
1098
1121
|
const ListContent = forwardRef((_a, ref) => {
|
|
@@ -1273,16 +1296,31 @@ const SelectInput = forwardRef((_a, ref) => {
|
|
|
1273
1296
|
handleOnSelect(option.id);
|
|
1274
1297
|
}, children: jsx("span", { children: renderItem(option, !!selectedMap[option.id]) }) }));
|
|
1275
1298
|
}, [ItemComponent, handleOnSelect, multiple, renderItem, selectedMap]);
|
|
1276
|
-
return (jsxs(DropdownMenu, { open: open, onOpenChange: setOpen, children: [jsx(DropdownMenu.Trigger, { className: cn('w-full', className), children: jsx(TextInput, Object.assign({ className: "[&>div>*]:cursor-pointer", inputClassName: "text-left" }, props, { value: text !== null && text !== void 0 ? text : '', clearable: clearable && !!selectedItems.length, onClear: handleOnClear, suffixIcon: ChevronDownIcon, ref: ref, readOnly: true })) }), jsxs(DropdownMenu.Content, { className: "flex max-h-80 w-[calc(var(--radix-popper-anchor-width))] flex-col overflow-hidden", children: [search && (jsxs(Fragment, { children: [jsx(TextInput, { value: searchValue, placeholder: "Search...", size: props.size, onChange: handleOnSearchValueChange, clearable: !!searchValue.length, onClear: clearSearchValue }), jsx(DropdownMenu.Separator, { className: "w-full" })] })), filteredItems.length === 0 &&
|
|
1299
|
+
return (jsxs(DropdownMenu, { open: open, onOpenChange: setOpen, children: [jsx(DropdownMenu.Trigger, { className: cn('w-full', className), children: jsx(TextInput, Object.assign({ className: "[&>div>*]:cursor-pointer", inputClassName: "text-left" }, props, { value: text !== null && text !== void 0 ? text : '', clearable: clearable && !!selectedItems.length, onClear: handleOnClear, suffixIcon: ChevronDownIcon, onSuffixIconClick: () => setOpen((open) => !open), ref: ref, readOnly: true })) }), jsxs(DropdownMenu.Content, { className: "flex max-h-80 w-[calc(var(--radix-popper-anchor-width))] flex-col overflow-hidden", children: [search && (jsxs(Fragment, { children: [jsx(TextInput, { value: searchValue, placeholder: "Search...", size: props.size, onChange: handleOnSearchValueChange, clearable: !!searchValue.length, onClear: clearSearchValue }), jsx(DropdownMenu.Separator, { className: "w-full" })] })), filteredItems.length === 0 &&
|
|
1277
1300
|
(allowAddition && searchValue ? (jsxs("button", { className: "rounded bg-slate-100 text-center hover:bg-slate-200 dark:bg-slate-900/30 dark:hover:bg-slate-700/30", onClick: handleOnAddItemClicked, children: ["Add '", searchValue, "'"] })) : (jsx("div", { className: "text-center text-slate-500", children: "No items." }))), jsx(GroupComponent, { className: "flex flex-col gap-1 overflow-auto", value: !multiple && selectedItems.length ? String(selectedItems[0].id) : undefined, children: filteredItems.map((item, index) => item.group ? (jsxs(Flex, { className: "gap-1", direction: "column", fullWidth: true, children: [jsx(DropdownMenu.Label, { className: "sticky top-0 z-[51] w-full rounded-md border bg-white py-1 dark:bg-slate-900", children: item.label }), item.items.map((subItem) => (jsx(RenderOption, Object.assign({}, subItem), subItem.id))), index < filteredItems.length - 1 && (jsx("div", { className: "mb-1 h-px w-full bg-slate-200 dark:bg-slate-700" }))] }, item.id)) : (jsx(RenderOption, Object.assign({}, item), item.id))) })] })] }));
|
|
1278
1301
|
});
|
|
1279
1302
|
|
|
1303
|
+
const FileInput = forwardRef((_a, ref) => {
|
|
1304
|
+
var { className, value, onChange, onFileChange, accept } = _a, props = __rest(_a, ["className", "value", "onChange", "onFileChange", "accept"]);
|
|
1305
|
+
const fileInputRef = useRef(null);
|
|
1306
|
+
const handleFileChange = (_a) => __awaiter(void 0, [_a], void 0, function* ({ target: { files } }) {
|
|
1307
|
+
console.log(files);
|
|
1308
|
+
if (files && files.length > 0) {
|
|
1309
|
+
const file = files[0];
|
|
1310
|
+
console.log(file, file.name, onChange, onFileChange);
|
|
1311
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(file.name);
|
|
1312
|
+
onFileChange === null || onFileChange === void 0 ? void 0 : onFileChange(file);
|
|
1313
|
+
}
|
|
1314
|
+
});
|
|
1315
|
+
return (jsxs(Fragment, { children: [jsx(TextInput, Object.assign({ className: cn('[&>div>*]:cursor-pointer', className), inputClassName: "text-left" }, props, { value: value !== null && value !== void 0 ? value : '', onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, suffixIcon: CloudUploadIcon, onSuffixIconClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, ref: ref, readOnly: true })), jsx("input", { ref: (ref) => (fileInputRef.current = ref), type: "file", hidden: true, accept: accept, onChange: handleFileChange })] }));
|
|
1316
|
+
});
|
|
1317
|
+
|
|
1280
1318
|
const FormGroup = ({ className, label, children }) => (jsxs(Flex, { className: cn('relative !gap-4 rounded-lg border p-4 dark:border-slate-700', className), direction: "column", fullWidth: true, children: [jsx("div", { className: "absolute right-0 top-0 rounded-bl-lg rounded-tr-lg bg-slate-500 px-2 py-1 font-medium text-white dark:bg-slate-900 dark:text-white", children: label }), children] }));
|
|
1281
1319
|
|
|
1282
1320
|
function withForm(Component) {
|
|
1283
1321
|
return forwardRef((props, ref) => {
|
|
1284
1322
|
const _a = props, { name, pattern, validate } = _a, restProps = __rest(_a, ["name", "pattern", "validate"]);
|
|
1285
|
-
const { control } = useFormContext();
|
|
1323
|
+
const { control, formState } = useFormContext();
|
|
1286
1324
|
return (jsx(Controller, { name: name, control: control, rules: {
|
|
1287
1325
|
required: restProps.required,
|
|
1288
1326
|
min: restProps.min,
|
|
@@ -1293,7 +1331,8 @@ function withForm(Component) {
|
|
|
1293
1331
|
validate,
|
|
1294
1332
|
}, render: ({ field, fieldState }) => {
|
|
1295
1333
|
var _a, _b;
|
|
1296
|
-
return (jsx(Component, Object.assign({}, restProps, field, { value: (_a = field.value) !== null && _a !== void 0 ? _a : '', disabled: (_b = field.disabled) !== null && _b !== void 0 ? _b : restProps.disabled
|
|
1334
|
+
return (jsx(Component, Object.assign({}, restProps, field, { value: (_a = field.value) !== null && _a !== void 0 ? _a : '', disabled: ((_b = field.disabled) !== null && _b !== void 0 ? _b : restProps.disabled) ||
|
|
1335
|
+
formState.isSubmitting, hasErrors: fieldState.error, ref: mergeRefs([ref, field.ref]) })));
|
|
1297
1336
|
} }));
|
|
1298
1337
|
});
|
|
1299
1338
|
}
|
|
@@ -1306,6 +1345,7 @@ const FormInputs = {
|
|
|
1306
1345
|
Checkbox: withForm(CheckboxInput),
|
|
1307
1346
|
DateTime: withForm(DateTimeInput),
|
|
1308
1347
|
Select: withForm(SelectInput),
|
|
1348
|
+
File: withForm(FileInput),
|
|
1309
1349
|
};
|
|
1310
1350
|
|
|
1311
1351
|
const HintRoot = forwardRef(({ children }, ref) => (jsx(Block, { className: "relative", ref: ref, children: children })));
|
|
@@ -1503,7 +1543,7 @@ function DataTable({ className, columns, rows, sorting, pagination, actions = []
|
|
|
1503
1543
|
: undefined, children: [column.header, sorting &&
|
|
1504
1544
|
!column.noSorting &&
|
|
1505
1545
|
(((_b = sorting.sorting) === null || _b === void 0 ? void 0 : _b.field) !== column.field ? (jsx(ArrowUpDownIcon, { className: "absolute top-1/2 float-right ml-1 hidden h-4 w-4 -translate-y-1/2 group-hover:inline-block" })) : ((_c = sorting.sorting) === null || _c === void 0 ? void 0 : _c.direction) === 'asc' ? (jsx(SortAscIcon, { className: "absolute top-1/2 float-right ml-1 inline-block h-4 w-4 -translate-y-1/2" })) : (jsx(SortDescIcon, { className: "absolute top-1/2 float-right ml-1 inline-block h-4 w-4 -translate-y-1/2" })))] }, columnIndex));
|
|
1506
|
-
}), actions.length > 0 && jsx(Table.HeadCell, { align: "center", children: "Actions" })] }) }), jsxs(Table.Body, { className: "relative", children: [isLoading && (jsx(Table.Row, { children: jsx(Table.Cell, { className: cn('z-10 h-full w-full p-0', {
|
|
1546
|
+
}), actions.filter((action) => !action.hide).length > 0 && (jsx(Table.HeadCell, { align: "center", children: "Actions" }))] }) }), jsxs(Table.Body, { className: "relative", children: [isLoading && (jsx(Table.Row, { children: jsx(Table.Cell, { className: cn('z-10 h-full w-full p-0', {
|
|
1507
1547
|
absolute: rows.length,
|
|
1508
1548
|
}), colSpan: columnsLength, children: jsx(Spinner, { className: "bg-white/50 py-4 dark:bg-slate-700/50" }) }) })), !isLoading && !rows.length && (jsx(Table.Row, { children: jsx(Table.Cell, { colSpan: columnsLength, children: jsx(Flex, { className: "text-slate-500", justify: "center", children: noDataMessage !== null && noDataMessage !== void 0 ? noDataMessage : 'No data' }) }) })), rows.map((item, rowIndex) => [
|
|
1509
1549
|
jsxs(Table.Row, { className: cn({
|
|
@@ -1511,7 +1551,7 @@ function DataTable({ className, columns, rows, sorting, pagination, actions = []
|
|
|
1511
1551
|
}, rowClassName === null || rowClassName === void 0 ? void 0 : rowClassName(item, rowIndex)), onClick: handleRowClicked(item, rowIndex), children: [rowExtraContent && (jsx(Table.Cell, { className: "w-min", align: "center", children: jsx(ExpandButton, { folded: !expandedRows[rowExtraContent.idGetter(item)], foldComponent: MinusIcon, unfoldComponent: PlusIcon, onClick: handleExpandRow(rowExtraContent.idGetter(item)) }) })), _columns.map((column, columnIndex) => {
|
|
1512
1552
|
var _a, _b, _c;
|
|
1513
1553
|
return (jsx(Table.Cell, { className: column.className, align: (_a = column.align) !== null && _a !== void 0 ? _a : 'left', children: (_c = (_b = column.render) === null || _b === void 0 ? void 0 : _b.call(column, item, rowIndex)) !== null && _c !== void 0 ? _c : defaultRender(item, column.field) }, columnIndex));
|
|
1514
|
-
}), actions.length > 0 && (jsx(Table.Cell, { className: "py-3", children: jsx(Flex, { align: "center", justify: "center", children: actions
|
|
1554
|
+
}), actions.filter((action) => !action.hide).length > 0 && (jsx(Table.Cell, { className: "py-3", children: jsx(Flex, { align: "center", justify: "center", children: actions
|
|
1515
1555
|
.filter((action) => { var _a; return typeof action.hide === 'boolean' ? !action.hide : !((_a = action.hide) === null || _a === void 0 ? void 0 : _a.call(action, item)); })
|
|
1516
1556
|
.map((action, actionIndex) => {
|
|
1517
1557
|
var _a;
|
|
@@ -1634,107 +1674,356 @@ const PdfViewerDialog = ({ open, title, url, data, onClose }) => {
|
|
|
1634
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%" }))] }) }));
|
|
1635
1675
|
};
|
|
1636
1676
|
|
|
1637
|
-
const
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1677
|
+
const Separator = forwardRef((_a, ref) => {
|
|
1678
|
+
var { className, orientation = 'horizontal', decorative = true } = _a, props = __rest(_a, ["className", "orientation", "decorative"]);
|
|
1679
|
+
return (jsx(SeparatorPrimitive.Root, Object.assign({ ref: ref, decorative: decorative, orientation: orientation, className: cn('bg-border shrink-0', orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]', className) }, props)));
|
|
1680
|
+
});
|
|
1681
|
+
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
1682
|
+
|
|
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)));
|
|
1663
1713
|
};
|
|
1664
|
-
|
|
1665
|
-
|
|
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
|
+
const Skeleton = (_a) => {
|
|
1743
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1744
|
+
return (jsx("div", Object.assign({ className: cn('bg-muted animate-pulse rounded-md', className) }, props)));
|
|
1745
|
+
};
|
|
1746
|
+
Skeleton.displayName = 'Skeleton';
|
|
1747
|
+
|
|
1748
|
+
const SIDEBAR_COOKIE_NAME = 'sidebar:state';
|
|
1749
|
+
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
|
|
1750
|
+
const SIDEBAR_WIDTH = '16rem';
|
|
1751
|
+
const SIDEBAR_WIDTH_MOBILE = '18rem';
|
|
1752
|
+
const SIDEBAR_WIDTH_ICON = '3rem';
|
|
1753
|
+
const SIDEBAR_KEYBOARD_SHORTCUT = 'b';
|
|
1754
|
+
const SidebarContext = createContext(null);
|
|
1755
|
+
function useSidebar() {
|
|
1756
|
+
const context = useContext(SidebarContext);
|
|
1666
1757
|
if (!context) {
|
|
1667
|
-
throw new Error('
|
|
1758
|
+
throw new Error('useSidebar must be used within a SidebarProvider.');
|
|
1668
1759
|
}
|
|
1669
1760
|
return context;
|
|
1670
1761
|
}
|
|
1671
|
-
const
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
const
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1762
|
+
const SidebarContextProvider = forwardRef((_a, ref) => {
|
|
1763
|
+
var { defaultOpen = true, open: openProp, onOpenChange: setOpenProp, className, style, children } = _a, props = __rest(_a, ["defaultOpen", "open", "onOpenChange", "className", "style", "children"]);
|
|
1764
|
+
const isMobile = useIsMobile();
|
|
1765
|
+
const [openMobile, setOpenMobile] = useState(false);
|
|
1766
|
+
const screenRef = useRef(document.documentElement);
|
|
1767
|
+
// This is the internal state of the sidebar.
|
|
1768
|
+
// We use openProp and setOpenProp for control from outside the component.
|
|
1769
|
+
const [_open, _setOpen] = useState(defaultOpen);
|
|
1770
|
+
const open = openProp !== null && openProp !== void 0 ? openProp : _open;
|
|
1771
|
+
const setOpen = useCallback((value) => {
|
|
1772
|
+
if (setOpenProp) {
|
|
1773
|
+
return setOpenProp === null || setOpenProp === void 0 ? void 0 : setOpenProp(typeof value === 'function' ? value(open) : value);
|
|
1774
|
+
}
|
|
1775
|
+
_setOpen(value);
|
|
1776
|
+
// This sets the cookie to keep the sidebar state.
|
|
1777
|
+
document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
|
|
1778
|
+
}, [setOpenProp, open]);
|
|
1779
|
+
// Helper to toggle the sidebar.
|
|
1780
|
+
const toggleSidebar = useCallback(() => {
|
|
1781
|
+
return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
|
|
1782
|
+
}, [isMobile, setOpen, setOpenMobile]);
|
|
1783
|
+
// Add swipe gesture support for opening and closing the sidebar.
|
|
1784
|
+
useOnSwipe(screenRef, (direction) => direction === 'right' ? setOpen(true) : direction === 'left' && setOpen(false));
|
|
1785
|
+
// Adds a keyboard shortcut to toggle the sidebar.
|
|
1786
|
+
useEffect(() => {
|
|
1787
|
+
const handleKeyDown = (event) => {
|
|
1788
|
+
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
1789
|
+
event.preventDefault();
|
|
1790
|
+
toggleSidebar();
|
|
1791
|
+
}
|
|
1792
|
+
};
|
|
1793
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
1794
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
1795
|
+
}, [toggleSidebar]);
|
|
1796
|
+
// We add a state so that we can do data-state="expanded" or "collapsed".
|
|
1797
|
+
// This makes it easier to style the sidebar with Tailwind classes.
|
|
1798
|
+
const state = open ? 'expanded' : 'collapsed';
|
|
1799
|
+
const contextValue = useMemo(() => ({
|
|
1800
|
+
state,
|
|
1801
|
+
open,
|
|
1802
|
+
setOpen,
|
|
1803
|
+
isMobile,
|
|
1804
|
+
openMobile,
|
|
1805
|
+
setOpenMobile,
|
|
1806
|
+
toggleSidebar,
|
|
1807
|
+
}), [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]);
|
|
1808
|
+
return (jsx(SidebarContext.Provider, { value: contextValue, children: jsx("div", Object.assign({ style: Object.assign({ '--sidebar-width': SIDEBAR_WIDTH, '--sidebar-width-icon': SIDEBAR_WIDTH_ICON }, style), className: cn('group/sidebar-wrapper has-[[data-variant=inset]]:bg-sidebar flex min-h-svh w-full', className), ref: ref }, props, { children: children })) }));
|
|
1809
|
+
});
|
|
1810
|
+
SidebarContextProvider.displayName = 'SidebarContextProvider';
|
|
1811
|
+
const $Sidebar = forwardRef((_a, ref) => {
|
|
1812
|
+
var { side = 'left', variant = 'sidebar', collapsible = 'offcanvas', className, children } = _a, props = __rest(_a, ["side", "variant", "collapsible", "className", "children"]);
|
|
1813
|
+
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
|
1814
|
+
if (collapsible === 'none') {
|
|
1815
|
+
return (jsx("div", Object.assign({ className: cn('bg-sidebar text-sidebar-foreground flex h-full w-[--sidebar-width] flex-col', className), ref: ref }, props, { children: children })));
|
|
1816
|
+
}
|
|
1817
|
+
if (isMobile) {
|
|
1818
|
+
return (jsx(Sheet, Object.assign({ open: openMobile, onOpenChange: setOpenMobile }, props, { children: jsx(Sheet.Content, { "data-sidebar": "sidebar", "data-mobile": "true", className: "bg-sidebar text-sidebar-foreground w-[--sidebar-width] p-0 [&>button]:hidden", style: {
|
|
1819
|
+
'--sidebar-width': SIDEBAR_WIDTH_MOBILE,
|
|
1820
|
+
}, side: side, children: jsx("div", { className: "flex h-full w-full flex-col", children: children }) }) })));
|
|
1821
|
+
}
|
|
1822
|
+
return (jsxs("div", { ref: ref, className: "text-sidebar-foreground group peer hidden md:block", "data-state": state, "data-collapsible": state === 'collapsed' ? collapsible : '', "data-variant": variant, "data-side": side, children: [jsx("div", { className: cn('relative h-svh w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear', 'group-data-[collapsible=offcanvas]:w-0', 'group-data-[side=right]:rotate-180', variant === 'floating' || variant === 'inset'
|
|
1823
|
+
? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'
|
|
1824
|
+
: 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]') }), jsx("div", Object.assign({ className: cn('fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex', side === 'left'
|
|
1825
|
+
? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
|
|
1826
|
+
: 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
|
|
1827
|
+
// Adjust the padding for floating and inset variants.
|
|
1828
|
+
variant === 'floating' || variant === 'inset'
|
|
1829
|
+
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'
|
|
1830
|
+
: 'border-sidebar-border group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l', className) }, props, { children: jsx("div", { "data-sidebar": "sidebar", className: "bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow", children: children }) }))] }));
|
|
1831
|
+
});
|
|
1832
|
+
$Sidebar.displayName = 'Sidebar';
|
|
1833
|
+
const SidebarTrigger = forwardRef((_a, ref) => {
|
|
1834
|
+
var { className, onClick } = _a, props = __rest(_a, ["className", "onClick"]);
|
|
1835
|
+
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) => {
|
|
1837
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
1838
|
+
toggleSidebar();
|
|
1839
|
+
} }, props)));
|
|
1840
|
+
});
|
|
1841
|
+
SidebarTrigger.displayName = 'SidebarTrigger';
|
|
1842
|
+
const SidebarRail = forwardRef((_a, ref) => {
|
|
1843
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1844
|
+
const { toggleSidebar } = useSidebar();
|
|
1845
|
+
return (jsx("button", Object.assign({ ref: ref, "data-sidebar": "rail", "aria-label": "Toggle Sidebar", tabIndex: -1, onClick: toggleSidebar, title: "Toggle Sidebar", className: cn('hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex', '[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize', '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize', 'group-data-[collapsible=offcanvas]:hover:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full', '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2', '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2', className) }, props)));
|
|
1846
|
+
});
|
|
1847
|
+
SidebarRail.displayName = 'SidebarRail';
|
|
1848
|
+
const SidebarInset = forwardRef((_a, ref) => {
|
|
1849
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1850
|
+
return (jsx("main", Object.assign({ ref: ref, className: cn('bg-background relative flex min-h-svh flex-1 flex-col', 'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow', className) }, props)));
|
|
1851
|
+
});
|
|
1852
|
+
SidebarInset.displayName = 'SidebarInset';
|
|
1853
|
+
const SidebarInput = forwardRef((_a, ref) => {
|
|
1854
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1855
|
+
return (jsx(BasicInput, Object.assign({ ref: ref, "data-sidebar": "input", className: cn('focus-visible:ring-sidebar-ring focus-visible:ring-2', className) }, props)));
|
|
1856
|
+
});
|
|
1857
|
+
SidebarInput.displayName = 'SidebarInput';
|
|
1858
|
+
const SidebarHeader = forwardRef((_a, ref) => {
|
|
1859
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1860
|
+
return (jsx("div", Object.assign({ ref: ref, "data-sidebar": "header", className: cn('flex flex-col gap-2 p-2', className) }, props)));
|
|
1861
|
+
});
|
|
1862
|
+
SidebarHeader.displayName = 'SidebarHeader';
|
|
1863
|
+
const SidebarFooter = forwardRef((_a, ref) => {
|
|
1864
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1865
|
+
return (jsx("div", Object.assign({ ref: ref, "data-sidebar": "footer", className: cn('flex flex-col gap-2 p-2', className) }, props)));
|
|
1866
|
+
});
|
|
1867
|
+
SidebarFooter.displayName = 'SidebarFooter';
|
|
1868
|
+
const SidebarSeparator = forwardRef((_a, ref) => {
|
|
1869
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1870
|
+
return (jsx(Separator, Object.assign({ ref: ref, "data-sidebar": "separator", className: cn('bg-sidebar-border mx-2 w-auto', className) }, props)));
|
|
1871
|
+
});
|
|
1872
|
+
SidebarSeparator.displayName = 'SidebarSeparator';
|
|
1873
|
+
const SidebarContent = forwardRef((_a, ref) => {
|
|
1874
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1875
|
+
return (jsx("div", Object.assign({ ref: ref, "data-sidebar": "content", className: cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', className) }, props)));
|
|
1876
|
+
});
|
|
1877
|
+
SidebarContent.displayName = 'SidebarContent';
|
|
1878
|
+
const SidebarGroup = forwardRef((_a, ref) => {
|
|
1879
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1880
|
+
return (jsx("div", Object.assign({ ref: ref, "data-sidebar": "group", className: cn('relative flex w-full min-w-0 flex-col p-2', className) }, props)));
|
|
1881
|
+
});
|
|
1882
|
+
SidebarGroup.displayName = 'SidebarGroup';
|
|
1883
|
+
const SidebarGroupLabel = forwardRef((_a, ref) => {
|
|
1884
|
+
var { className, asChild = false } = _a, props = __rest(_a, ["className", "asChild"]);
|
|
1885
|
+
const Comp = asChild ? Slot : 'div';
|
|
1886
|
+
return (jsx(Comp, Object.assign({ ref: ref, "data-sidebar": "group-label", className: cn('text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-none transition-[margin,opa] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0', 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0', className) }, props)));
|
|
1887
|
+
});
|
|
1888
|
+
SidebarGroupLabel.displayName = 'SidebarGroupLabel';
|
|
1889
|
+
const SidebarGroupAction = forwardRef((_a, ref) => {
|
|
1890
|
+
var { className, asChild = false } = _a, props = __rest(_a, ["className", "asChild"]);
|
|
1891
|
+
const Comp = asChild ? Slot : 'button';
|
|
1892
|
+
return (jsx(Comp, Object.assign({ ref: ref, "data-sidebar": "group-action", className: cn('text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-none transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
|
|
1893
|
+
// Increases the hit area of the button on mobile.
|
|
1894
|
+
'after:absolute after:-inset-2 after:md:hidden', 'group-data-[collapsible=icon]:hidden', className) }, props)));
|
|
1895
|
+
});
|
|
1896
|
+
SidebarGroupAction.displayName = 'SidebarGroupAction';
|
|
1897
|
+
const SidebarGroupContent = forwardRef((_a, ref) => {
|
|
1898
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1899
|
+
return (jsx("div", Object.assign({ ref: ref, "data-sidebar": "group-content", className: cn('w-full text-sm', className) }, props)));
|
|
1900
|
+
});
|
|
1901
|
+
SidebarGroupContent.displayName = 'SidebarGroupContent';
|
|
1902
|
+
const SidebarMenu = forwardRef((_a, ref) => {
|
|
1903
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1904
|
+
return (jsx("ul", Object.assign({ ref: ref, "data-sidebar": "menu", className: cn('flex w-full min-w-0 flex-col gap-1', className) }, props)));
|
|
1905
|
+
});
|
|
1906
|
+
SidebarMenu.displayName = 'SidebarMenu';
|
|
1907
|
+
const SidebarMenuItem = forwardRef((_a, ref) => {
|
|
1908
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1909
|
+
return (jsx("li", Object.assign({ ref: ref, "data-sidebar": "menu-item", className: cn('group/menu-item relative', className) }, props)));
|
|
1910
|
+
});
|
|
1911
|
+
SidebarMenuItem.displayName = 'SidebarMenuItem';
|
|
1912
|
+
const sidebarMenuButtonVariants = cva('peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0', {
|
|
1913
|
+
variants: {
|
|
1914
|
+
variant: {
|
|
1915
|
+
default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
|
|
1916
|
+
outline: 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
|
|
1917
|
+
},
|
|
1918
|
+
size: {
|
|
1919
|
+
default: 'h-8 text-sm',
|
|
1920
|
+
sm: 'h-7 text-xs',
|
|
1921
|
+
lg: 'h-12 text-sm group-data-[collapsible=icon]:!p-0',
|
|
1922
|
+
},
|
|
1923
|
+
},
|
|
1924
|
+
defaultVariants: {
|
|
1925
|
+
variant: 'default',
|
|
1926
|
+
size: 'default',
|
|
1927
|
+
},
|
|
1928
|
+
});
|
|
1929
|
+
const SidebarMenuButton = forwardRef((_a, ref) => {
|
|
1930
|
+
var { asChild = false, isActive = false, variant = 'default', size = 'default', tooltip, className } = _a, props = __rest(_a, ["asChild", "isActive", "variant", "size", "tooltip", "className"]);
|
|
1931
|
+
const Comp = asChild ? Slot : 'button';
|
|
1932
|
+
const { isMobile, state } = useSidebar();
|
|
1933
|
+
const button = (jsx(Comp, Object.assign({ ref: ref, "data-sidebar": "menu-button", "data-size": size, "data-active": isActive, className: cn(sidebarMenuButtonVariants({ variant, size }), className) }, props)));
|
|
1934
|
+
if (!tooltip || state !== 'collapsed' || isMobile) {
|
|
1935
|
+
return button;
|
|
1936
|
+
}
|
|
1937
|
+
if (typeof tooltip === 'string') {
|
|
1938
|
+
tooltip = {
|
|
1939
|
+
content: tooltip,
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
return (jsx(Tooltip, Object.assign({ asChild: true, placement: "right" }, tooltip, { children: button })));
|
|
1943
|
+
});
|
|
1944
|
+
SidebarMenuButton.displayName = 'SidebarMenuButton';
|
|
1945
|
+
const SidebarMenuAction = forwardRef((_a, ref) => {
|
|
1946
|
+
var { className, asChild = false, showOnHover = false } = _a, props = __rest(_a, ["className", "asChild", "showOnHover"]);
|
|
1947
|
+
const Comp = asChild ? Slot : 'button';
|
|
1948
|
+
return (jsx(Comp, Object.assign({ ref: ref, "data-sidebar": "menu-action", className: cn('text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-none transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
|
|
1949
|
+
// Increases the hit area of the button on mobile.
|
|
1950
|
+
'after:absolute after:-inset-2 after:md:hidden', 'peer-data-[size=sm]/menu-button:top-1', 'peer-data-[size=default]/menu-button:top-1.5', 'peer-data-[size=lg]/menu-button:top-2.5', 'group-data-[collapsible=icon]:hidden', showOnHover &&
|
|
1951
|
+
'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0', className) }, props)));
|
|
1952
|
+
});
|
|
1953
|
+
SidebarMenuAction.displayName = 'SidebarMenuAction';
|
|
1954
|
+
const SidebarMenuBadge = forwardRef((_a, ref) => {
|
|
1955
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1956
|
+
return (jsx("div", Object.assign({ ref: ref, "data-sidebar": "menu-badge", className: cn('text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums', 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground', 'peer-data-[size=sm]/menu-button:top-1', 'peer-data-[size=default]/menu-button:top-1.5', 'peer-data-[size=lg]/menu-button:top-2.5', 'group-data-[collapsible=icon]:hidden', className) }, props)));
|
|
1957
|
+
});
|
|
1958
|
+
SidebarMenuBadge.displayName = 'SidebarMenuBadge';
|
|
1959
|
+
const SidebarMenuSkeleton = forwardRef((_a, ref) => {
|
|
1960
|
+
var { className, showIcon = false } = _a, props = __rest(_a, ["className", "showIcon"]);
|
|
1961
|
+
// Random width between 50 to 90%.
|
|
1962
|
+
const width = useMemo(() => {
|
|
1963
|
+
return `${Math.floor(Math.random() * 40) + 50}%`;
|
|
1964
|
+
}, []);
|
|
1965
|
+
return (jsxs("div", Object.assign({ ref: ref, "data-sidebar": "menu-skeleton", className: cn('flex h-8 items-center gap-2 rounded-md px-2', className) }, props, { children: [showIcon && jsx(Skeleton, { className: "size-4 rounded-md", "data-sidebar": "menu-skeleton-icon" }), jsx(Skeleton, { className: "h-4 max-w-[--skeleton-width] flex-1", "data-sidebar": "menu-skeleton-text", style: {
|
|
1966
|
+
'--skeleton-width': width,
|
|
1967
|
+
} })] })));
|
|
1968
|
+
});
|
|
1969
|
+
SidebarMenuSkeleton.displayName = 'SidebarMenuSkeleton';
|
|
1970
|
+
const SidebarMenuSub = forwardRef((_a, ref) => {
|
|
1971
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
1972
|
+
return (jsx("ul", Object.assign({ ref: ref, "data-sidebar": "menu-sub", className: cn('border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5', 'group-data-[collapsible=icon]:hidden', className) }, props)));
|
|
1973
|
+
});
|
|
1974
|
+
SidebarMenuSub.displayName = 'SidebarMenuSub';
|
|
1975
|
+
const SidebarMenuSubItem = forwardRef((_a, ref) => {
|
|
1976
|
+
var props = __rest(_a, []);
|
|
1977
|
+
return (jsx("li", Object.assign({ ref: ref }, props)));
|
|
1978
|
+
});
|
|
1979
|
+
SidebarMenuSubItem.displayName = 'SidebarMenuSubItem';
|
|
1980
|
+
const SidebarMenuSubButton = forwardRef((_a, ref) => {
|
|
1981
|
+
var { asChild = false, size = 'md', isActive, className } = _a, props = __rest(_a, ["asChild", "size", "isActive", "className"]);
|
|
1982
|
+
const Comp = asChild ? Slot : 'a';
|
|
1983
|
+
return (jsx(Comp, Object.assign({ ref: ref, "data-sidebar": "menu-sub-button", "data-size": size, "data-active": isActive, className: cn('text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0', 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground', size === 'sm' && 'text-xs', size === 'md' && 'text-sm', 'group-data-[collapsible=icon]:hidden', className) }, props)));
|
|
1984
|
+
});
|
|
1985
|
+
SidebarMenuSubButton.displayName = 'SidebarMenuSubButton';
|
|
1986
|
+
const Sidebar = Object.assign($Sidebar, {
|
|
1987
|
+
Content: SidebarContent,
|
|
1988
|
+
Footer: SidebarFooter,
|
|
1989
|
+
Group: SidebarGroup,
|
|
1990
|
+
GroupAction: SidebarGroupAction,
|
|
1991
|
+
GroupContent: SidebarGroupContent,
|
|
1992
|
+
GroupLabel: SidebarGroupLabel,
|
|
1993
|
+
Header: SidebarHeader,
|
|
1994
|
+
Input: SidebarInput,
|
|
1995
|
+
Inset: SidebarInset,
|
|
1996
|
+
Menu: SidebarMenu,
|
|
1997
|
+
MenuAction: SidebarMenuAction,
|
|
1998
|
+
MenuBadge: SidebarMenuBadge,
|
|
1999
|
+
MenuButton: SidebarMenuButton,
|
|
2000
|
+
MenuItem: SidebarMenuItem,
|
|
2001
|
+
MenuSkeleton: SidebarMenuSkeleton,
|
|
2002
|
+
MenuSub: SidebarMenuSub,
|
|
2003
|
+
MenuSubButton: SidebarMenuSubButton,
|
|
2004
|
+
MenuSubItem: SidebarMenuSubItem,
|
|
2005
|
+
Rail: SidebarRail,
|
|
2006
|
+
Separator: SidebarSeparator,
|
|
2007
|
+
Trigger: SidebarTrigger,
|
|
2008
|
+
});
|
|
1683
2009
|
|
|
1684
|
-
const Navbar = ({ leftSlot, rightSlot }) => {
|
|
1685
|
-
const { setSidebarOpen } = useLayoutContext();
|
|
1686
|
-
return (jsx(Block, { className: "border-b p-3 dark:border-slate-700", fullWidth: true, children: jsxs(Flex, { align: "center", justify: "between", children: [jsxs(Flex, { align: "center", children: [jsx(Button, { className: "xl:hidden", prefixIcon: MenuIcon, variant: "text", onClick: () => setSidebarOpen(true) }), leftSlot] }), rightSlot] }) }));
|
|
1687
|
-
};
|
|
2010
|
+
const Navbar = ({ leftSlot, rightSlot }) => (jsx(Block, { className: "border-b p-3 dark:border-slate-700", fullWidth: true, children: jsxs(Flex, { align: "center", justify: "between", children: [jsxs(Flex, { align: "center", children: [jsx(Sidebar.Trigger, {}), leftSlot] }), rightSlot] }) }));
|
|
1688
2011
|
|
|
1689
|
-
const
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
'dark:text-white': active,
|
|
1694
|
-
'bg-slate-100 dark:bg-slate-800': active && !isChild && !items,
|
|
1695
|
-
'bg-slate-200 dark:bg-slate-900': active && (isChild || items),
|
|
1696
|
-
'text-slate-500 dark:text-slate-400': !active,
|
|
1697
|
-
'hover:bg-slate-100 dark:hover:bg-slate-800': !active && !isChild,
|
|
1698
|
-
'hover:bg-slate-200 dark:hover:bg-slate-900': !active && isChild,
|
|
1699
|
-
}), to: [basePath, pathname].join('/').replace(/\/{2,}/g, '/'), onClick: onClick, children: [jsx(Icon, { className: "h-5 w-5 min-w-min", size: 16 }), jsxs("div", { className: "min-w-max", children: [title, jsx("div", { className: "ml-auto flex items-center space-x-2", children: label })] })] }));
|
|
1700
|
-
|
|
1701
|
-
const Sidebar = forwardRef(({ className, items, basePath = '/', smallLogo, fullLogo, footer }, ref) => {
|
|
2012
|
+
const Layout = ({ children, className, sidebarProps, navbarProps, }) => {
|
|
2013
|
+
return (jsxs(Flex, { className: "h-screen w-screen gap-0 text-black dark:bg-slate-900 dark:text-white", children: [jsxs(Sidebar, Object.assign({ collapsible: "icon" }, sidebarProps.root, { children: [jsx(Sidebar.Header, { children: sidebarProps.smallLogo && sidebarProps.fullLogo && (jsx("div", { className: "cursor-pointer overflow-hidden whitespace-nowrap py-2 text-center text-lg", children: jsxs(Link, { to: "/", children: [jsx("span", { className: "group-data-[state=collapsed]:hidden", children: sidebarProps.fullLogo }), jsx("span", { className: "group-data-[state=expanded]:hidden", children: sidebarProps.smallLogo })] }) })) }), jsx(Sidebar.Content, { className: "gap-0", children: sidebarProps.items.map((item, index) => item.type === 'item' ? (jsx(Sidebar.Group, { children: jsx(Sidebar.Menu, { children: jsx(RenderSideBarItem, Object.assign({ basePath: sidebarProps.basePath }, item)) }) }, index)) : (jsxs(Sidebar.Group, { children: [item.title && jsx(Sidebar.GroupLabel, { children: item.title }), jsx(Sidebar.GroupContent, { children: jsx(Sidebar.Menu, { children: item.items.map((item, index) => (jsx(RenderSideBarItem, Object.assign({ basePath: sidebarProps.basePath }, item), index))) }) })] }, index))) }), jsx(Sidebar.Rail, {})] })), jsxs(Flex, { className: "gap-0 overflow-hidden", direction: "column", fullHeight: true, fullWidth: true, children: [jsx(Navbar, Object.assign({}, navbarProps)), jsx(Flex, { className: cn('overflow-hidden p-3', className), direction: "column", fullWidth: true, fullHeight: true, children: children })] })] }));
|
|
2014
|
+
};
|
|
2015
|
+
const RenderSideBarItem = ({ basePath = '/', pathname, title, Icon, items, }) => {
|
|
1702
2016
|
const location = useLocation();
|
|
1703
|
-
const {
|
|
2017
|
+
const { open } = useSidebar();
|
|
1704
2018
|
const currentPath = useMemo(() => location.pathname.replace(basePath, '').replace(/^\/*/, ''), [basePath, location.pathname]);
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
return (jsxs(Fragment, { children: [jsx("div", { className: "absolute left-0 top-0 h-full w-full backdrop-blur-sm transition-opacity data-[open=true]:z-50 data-[open=false]:hidden data-[open=false]:opacity-0 data-[open=true]:opacity-100 xl:hidden", "data-open": sidebarOpen }), jsxs("nav", { className: cn('group/navbar fixed left-0 top-0 z-50 flex h-full w-56 shrink-0 flex-col bg-white p-2 transition-all duration-200 ease-in-out xl:relative dark:bg-slate-900', 'border-r data-[open=false]:-translate-x-full xl:data-[open=false]:w-16 xl:data-[open=true]:w-72 xl:data-[open=false]:translate-x-0 xl:data-[open=false]:hover:w-72 dark:border-slate-700', className), "data-open": sidebarOpen, ref: ref, children: [smallLogo && fullLogo && (jsx("div", { className: "mb-2 cursor-pointer overflow-hidden whitespace-nowrap p-2 py-3 text-center text-2xl", children: jsxs(Link, { to: "/", children: [jsx("span", { className: cn('group-hover/navbar:block', !sidebarOpen && 'hidden'), children: fullLogo }), jsx("span", { className: cn('group-hover/navbar:hidden', sidebarOpen && 'hidden'), children: smallLogo })] }) })), jsx(Accordion.Root, { className: "overflow-hidden", type: "single", value: parentTab, children: items.map((item, index) => {
|
|
1711
|
-
var _a;
|
|
1712
|
-
return !item.hidden &&
|
|
1713
|
-
(item.type === 'separator' ? (!item.title ? (jsx(Block, { className: "my-2 h-px bg-slate-300 dark:bg-slate-700" }, index)) : (jsx(Block, { className: "mb-2 mt-6 pl-2 text-sm font-bold text-slate-600 group-hover/navbar:block data-[open=false]:hidden dark:text-slate-500", "data-open": sidebarOpen, children: item.title }, index))) : (jsxs(Accordion.Item, { className: cn('flex flex-col rounded-md', {
|
|
1714
|
-
'bg-slate-100 dark:bg-slate-800': item.items && isLinkStartsWithPathname(currentPath, item.pathname),
|
|
1715
|
-
}), value: item.pathname, children: [jsx(Accordion.Header, { children: jsxs(Accordion.Trigger, { className: "relative w-full p-0.5 data-[state=open]:[--rotate-chevron:90deg]", children: [jsx(SidebarItemComp, Object.assign({}, item, { active: isLinkStartsWithPathname(currentPath, item.pathname) &&
|
|
1716
|
-
(!item.items ||
|
|
1717
|
-
item.items.every((subItem) => !isLinkStartsWithPathname(currentPath, `${item.pathname}/${subItem.pathname}`))), basePath: basePath, sidebarOpen: sidebarOpen, onClick: ((_a = item.items) === null || _a === void 0 ? void 0 : _a.length) ? undefined : () => setSidebarOpen(false) })), item.items && (jsx(ChevronRightIcon, { className: cn('absolute right-2 top-1/2 h-4 w-4 -translate-y-1/2 rotate-[var(--rotate-chevron,0deg)] transition-transform duration-200', !sidebarOpen && 'invisible', 'group-hover/navbar:visible') }))] }) }), item.items && (jsx(Accordion.Content, { className: "overflow-hidden data-[state=closed]:animate-[slideUp_200ms_ease-out] data-[state=open]:animate-[slideDown_200ms_ease-out]", children: jsx("div", { className: "flex flex-col gap-1 p-1 pt-0", children: item.items.map((subItem) => {
|
|
1718
|
-
const subPathname = `${item.pathname}/${subItem.pathname}`;
|
|
1719
|
-
return (!subItem.hidden && (jsx(SidebarItemComp, Object.assign({}, subItem, { pathname: subPathname, isChild: true, active: isLinkStartsWithPathname(currentPath, subPathname), basePath: basePath, sidebarOpen: sidebarOpen, onClick: () => setSidebarOpen(false) }), subPathname)));
|
|
1720
|
-
}) }) }))] }, item.pathname)));
|
|
1721
|
-
}) }), jsxs(Flex, { className: "mt-auto", direction: "column", fullWidth: true, children: [footer, jsx(Button, { className: "invisible w-full justify-center xl:visible", variant: "text", prefixIcon: OpenCloseIcon, onClick: () => setSidebarOpen(!sidebarOpen) })] })] })] }));
|
|
1722
|
-
});
|
|
2019
|
+
return (jsxs(Sidebar.MenuItem, { children: [jsx(Sidebar.MenuButton, { asChild: true, tooltip: title, isActive: isLinkStartsWithPathname(currentPath, pathname) &&
|
|
2020
|
+
(!items ||
|
|
2021
|
+
(!open &&
|
|
2022
|
+
items.some((item) => isLinkStartsWithPathname(currentPath, `${pathname}/${item.pathname}`)))), children: jsxs(Link, { to: pathname, className: "font-medium", children: [Icon && jsx(Icon, {}), title] }) }), items && (jsx(Sidebar.MenuSub, { children: items.map((subItem, index) => (jsx(Sidebar.MenuSubItem, { children: jsx(Sidebar.MenuSubButton, { asChild: true, isActive: isLinkStartsWithPathname(currentPath, `${pathname}/${subItem.pathname}`), children: jsx(Link, { to: `${pathname}/${subItem.pathname}`, children: subItem.title }) }) }, index))) }))] }));
|
|
2023
|
+
};
|
|
1723
2024
|
function isLinkStartsWithPathname(link, pathname) {
|
|
1724
2025
|
return pathname === '' ? link === pathname : link.startsWith(pathname);
|
|
1725
2026
|
}
|
|
1726
|
-
function isItem(item) {
|
|
1727
|
-
return item.type !== 'separator';
|
|
1728
|
-
}
|
|
1729
|
-
|
|
1730
|
-
const Layout = ({ children, className, sidebarProps, navbarProps, }) => {
|
|
1731
|
-
const { sidebarOpen, setSidebarOpen } = useLayoutContext();
|
|
1732
|
-
const screenRef = useRef(null);
|
|
1733
|
-
const sidebarRef = useRef(null);
|
|
1734
|
-
useOnSwipe(screenRef, (direction) => direction === 'right' ? setSidebarOpen(true) : direction === 'left' && setSidebarOpen(false));
|
|
1735
|
-
useOutsideClick(sidebarRef, () => sidebarOpen && window.document.documentElement.offsetWidth <= 1024 && setSidebarOpen(false));
|
|
1736
|
-
return (jsxs(Flex, { className: "h-screen gap-0 text-black dark:bg-slate-900 dark:text-white", ref: screenRef, children: [jsx(Sidebar, Object.assign({}, sidebarProps, { open: sidebarOpen, ref: sidebarRef })), jsxs(Flex, { className: "gap-0 overflow-hidden", direction: "column", fullHeight: true, fullWidth: true, children: [jsx(Navbar, Object.assign({}, navbarProps)), jsx(Flex, { className: cn('overflow-hidden p-3', className), direction: "column", fullWidth: true, fullHeight: true, children: children })] })] }));
|
|
1737
|
-
};
|
|
1738
2027
|
|
|
1739
2028
|
const $Popover = PopoverPrimitive.Root;
|
|
1740
2029
|
const PopoverTrigger = PopoverPrimitive.Trigger;
|
|
@@ -1776,6 +2065,47 @@ const Tabs = Object.assign($Tabs, {
|
|
|
1776
2065
|
Content: TabsContent,
|
|
1777
2066
|
});
|
|
1778
2067
|
|
|
2068
|
+
const LayoutContext = createContext(undefined);
|
|
2069
|
+
const LayoutContextProvider = ({ children }) => {
|
|
2070
|
+
const [theme, setTheme] = useState(getValueFromLocalStorage(THEME_KEY, 'light'));
|
|
2071
|
+
useEffect(() => {
|
|
2072
|
+
if (theme) {
|
|
2073
|
+
if (theme === 'dark') {
|
|
2074
|
+
document.documentElement.classList.add('dark');
|
|
2075
|
+
}
|
|
2076
|
+
else {
|
|
2077
|
+
document.documentElement.classList.remove('dark');
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
}, [theme]);
|
|
2081
|
+
const toggleTheme = () => {
|
|
2082
|
+
setTheme((theme) => {
|
|
2083
|
+
const newValue = theme === 'dark' ? 'light' : 'dark';
|
|
2084
|
+
window.localStorage.setItem(THEME_KEY, newValue);
|
|
2085
|
+
return newValue;
|
|
2086
|
+
});
|
|
2087
|
+
};
|
|
2088
|
+
return jsx(LayoutContext.Provider, { value: { theme, toggleTheme }, children: children });
|
|
2089
|
+
};
|
|
2090
|
+
function useLayoutContext() {
|
|
2091
|
+
const context = useContext(LayoutContext);
|
|
2092
|
+
if (!context) {
|
|
2093
|
+
throw new Error('Please use LayoutContextProvider!');
|
|
2094
|
+
}
|
|
2095
|
+
return context;
|
|
2096
|
+
}
|
|
2097
|
+
const THEME_KEY = 'tw-react-components__theme';
|
|
2098
|
+
function getValueFromLocalStorage(key, _default) {
|
|
2099
|
+
var _a;
|
|
2100
|
+
const transformers = {
|
|
2101
|
+
string: String,
|
|
2102
|
+
boolean: (value) => value === 'true',
|
|
2103
|
+
};
|
|
2104
|
+
return typeof window !== 'undefined'
|
|
2105
|
+
? transformers[typeof _default]((_a = window.localStorage.getItem(key)) !== null && _a !== void 0 ? _a : _default)
|
|
2106
|
+
: _default;
|
|
2107
|
+
}
|
|
2108
|
+
|
|
1779
2109
|
const ThemeSwitcher = ({ className }) => {
|
|
1780
2110
|
const { theme, toggleTheme } = useLayoutContext();
|
|
1781
2111
|
const darkMode = theme === 'dark';
|
|
@@ -1784,4 +2114,4 @@ const ThemeSwitcher = ({ className }) => {
|
|
|
1784
2114
|
} }));
|
|
1785
2115
|
};
|
|
1786
2116
|
|
|
1787
|
-
export { Badge, BasicInput, BasicInputExtension, Block, Button, Card, CheckboxInput, ConfirmDialog, DataTable, DateTimeInput, Dialog, DropdownMenu, EmailInput, Flex, FormDialog, FormGroup, FormInputs, Hint, Label, Layout, LayoutContext, LayoutContextProvider, List, ListSorter, ListSorterDialog, Navbar, NumberInput, Pagination, PasswordInput, PdfViewerDialog, Popover,
|
|
2117
|
+
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 };
|