@nexub/react 5.4.0 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/accessibility.json +34 -1
  2. package/dist/components/AlertDialog/AlertDialog.d.ts +17 -0
  3. package/dist/components/AlertDialog/AlertDialog.js +40 -5
  4. package/dist/components/AlertDialog/index.d.ts +1 -0
  5. package/dist/components/DateRangePicker/DateRangePicker.d.ts +17 -0
  6. package/dist/components/DateRangePicker/DateRangePicker.js +123 -71
  7. package/dist/components/DateRangePicker/index.d.ts +2 -1
  8. package/dist/components/DateRangePicker/index.js +3 -1
  9. package/dist/components/EmptyState/EmptyStatePreset.d.ts +14 -0
  10. package/dist/components/EmptyState/EmptyStatePreset.js +23 -0
  11. package/dist/components/EmptyState/index.d.ts +2 -0
  12. package/dist/components/EmptyState/index.js +3 -1
  13. package/dist/components/FileUpload/FileUpload.d.ts +10 -3
  14. package/dist/components/FileUpload/FileUpload.js +13 -4
  15. package/dist/components/FileUpload/index.d.ts +1 -1
  16. package/dist/components/FilterBuilder/FilterBuilder.d.ts +50 -0
  17. package/dist/components/FilterBuilder/FilterBuilder.js +164 -0
  18. package/dist/components/FilterBuilder/index.d.ts +2 -0
  19. package/dist/components/FilterBuilder/index.js +8 -0
  20. package/dist/components/OTPInput/OTPInput.d.ts +28 -0
  21. package/dist/components/OTPInput/OTPInput.js +107 -0
  22. package/dist/components/OTPInput/index.d.ts +2 -0
  23. package/dist/components/OTPInput/index.js +4 -0
  24. package/dist/components/SavedViews/SavedViews.d.ts +26 -0
  25. package/dist/components/SavedViews/SavedViews.js +65 -0
  26. package/dist/components/SavedViews/index.d.ts +2 -0
  27. package/dist/components/SavedViews/index.js +4 -0
  28. package/dist/index.d.ts +12 -3
  29. package/dist/index.js +14 -1
  30. package/dist/styles.css +1 -1
  31. package/package.json +6 -6
@@ -0,0 +1,164 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Plus, X } from "@nexub/icons";
5
+ import { cn } from "../../utils/cn.js";
6
+ import { useControllableState } from "../../hooks/useControllableState.js";
7
+ import { useNexubMessages } from "../NexubProvider/NexubProvider.js";
8
+ import { Button } from "../Button/Button.js";
9
+ import { IconButton } from "../IconButton/IconButton.js";
10
+ import { Input } from "../Input/Input.js";
11
+ import { Select } from "../Select/Select.js";
12
+ import { SegmentedControl } from "../SegmentedControl/SegmentedControl.js";
13
+ const filterOperators = {
14
+ text: ["contains", "equals", "notEquals", "startsWith", "isEmpty"],
15
+ number: ["equals", "notEquals", "greaterThan", "lessThan"],
16
+ select: ["equals", "notEquals"],
17
+ date: ["equals", "before", "after"]
18
+ };
19
+ const isFilterGroup = (r) => "rules" in r;
20
+ let seq = 0;
21
+ const uid = () => `f${(++seq).toString(36)}${Math.random().toString(36).slice(2, 6)}`;
22
+ const emptyFilter = () => ({ id: uid(), combinator: "and", rules: [] });
23
+ function countFilters(group) {
24
+ return group.rules.reduce(
25
+ (n, r) => n + (isFilterGroup(r) ? countFilters(r) : r.operator === "isEmpty" || r.value !== "" ? 1 : 0),
26
+ 0
27
+ );
28
+ }
29
+ function FilterBuilder({ fields, value: valueProp, defaultValue, onValueChange, maxDepth = 1, className }) {
30
+ const [value = emptyFilter(), setValue] = useControllableState({
31
+ value: valueProp,
32
+ defaultValue: defaultValue ?? emptyFilter(),
33
+ onChange: onValueChange
34
+ });
35
+ return /* @__PURE__ */ jsx(
36
+ GroupView,
37
+ {
38
+ group: value,
39
+ fields,
40
+ depth: 0,
41
+ maxDepth,
42
+ onChange: setValue,
43
+ className
44
+ }
45
+ );
46
+ }
47
+ FilterBuilder.displayName = "FilterBuilder";
48
+ function GroupView({ group, fields, depth, maxDepth, onChange, onRemove, className }) {
49
+ const t = useNexubMessages();
50
+ const first = fields[0];
51
+ const setRules = (rules) => onChange({ ...group, rules });
52
+ const newRule = () => ({
53
+ id: uid(),
54
+ field: first?.id ?? "",
55
+ operator: filterOperators[first?.type ?? "text"][0],
56
+ value: ""
57
+ });
58
+ return /* @__PURE__ */ jsxs(
59
+ "div",
60
+ {
61
+ role: "group",
62
+ "aria-label": t.filterGroup(group.combinator),
63
+ className: cn(
64
+ "flex flex-col gap-2",
65
+ depth > 0 && "rounded-shape-container border border-[var(--color-outline-variant)] p-3",
66
+ className
67
+ ),
68
+ children: [
69
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
70
+ /* @__PURE__ */ jsxs(
71
+ SegmentedControl.Root,
72
+ {
73
+ size: "sm",
74
+ "aria-label": t.filterGroup(group.combinator),
75
+ value: group.combinator,
76
+ onValueChange: (v) => v && onChange({ ...group, combinator: v }),
77
+ children: [
78
+ /* @__PURE__ */ jsx(SegmentedControl.Item, { value: "and", children: t.matchAll }),
79
+ /* @__PURE__ */ jsx(SegmentedControl.Item, { value: "or", children: t.matchAny })
80
+ ]
81
+ }
82
+ ),
83
+ onRemove && /* @__PURE__ */ jsx(IconButton, { label: t.removeGroup, variant: "ghost", size: "sm", className: "ms-auto", onClick: onRemove, children: /* @__PURE__ */ jsx(X, { size: "sm", "aria-hidden": "true" }) })
84
+ ] }),
85
+ group.rules.map((r, i) => {
86
+ const replace = (next) => setRules(group.rules.map((x, j) => j === i ? next : x));
87
+ const remove = () => setRules(group.rules.filter((_, j) => j !== i));
88
+ return isFilterGroup(r) ? /* @__PURE__ */ jsx(GroupView, { group: r, fields, depth: depth + 1, maxDepth, onChange: replace, onRemove: remove }, r.id) : /* @__PURE__ */ jsx(RuleRow, { rule: r, fields, onChange: replace, onRemove: remove }, r.id);
89
+ }),
90
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
91
+ /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setRules([...group.rules, newRule()]), disabled: !first, children: [
92
+ /* @__PURE__ */ jsx(Plus, { size: "sm", "aria-hidden": "true" }),
93
+ t.addFilter
94
+ ] }),
95
+ depth < maxDepth && /* @__PURE__ */ jsxs(
96
+ Button,
97
+ {
98
+ variant: "ghost",
99
+ size: "sm",
100
+ onClick: () => setRules([...group.rules, { id: uid(), combinator: "and", rules: [newRule()] }]),
101
+ disabled: !first,
102
+ children: [
103
+ /* @__PURE__ */ jsx(Plus, { size: "sm", "aria-hidden": "true" }),
104
+ t.addGroup
105
+ ]
106
+ }
107
+ )
108
+ ] })
109
+ ]
110
+ }
111
+ );
112
+ }
113
+ function RuleRow({
114
+ rule,
115
+ fields,
116
+ onChange,
117
+ onRemove
118
+ }) {
119
+ const t = useNexubMessages();
120
+ const field = fields.find((f) => f.id === rule.field) ?? fields[0];
121
+ const ops = filterOperators[field?.type ?? "text"];
122
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
123
+ /* @__PURE__ */ jsxs(
124
+ Select.Root,
125
+ {
126
+ value: field?.id,
127
+ onValueChange: (id) => {
128
+ const f = fields.find((x) => x.id === id);
129
+ const nextOps = filterOperators[f?.type ?? "text"];
130
+ onChange({ ...rule, field: id, operator: nextOps.includes(rule.operator) ? rule.operator : nextOps[0], value: "" });
131
+ },
132
+ children: [
133
+ /* @__PURE__ */ jsx(Select.Trigger, { "aria-label": t.filterField, className: "w-auto min-w-36", children: /* @__PURE__ */ jsx(Select.Value, {}) }),
134
+ /* @__PURE__ */ jsx(Select.Content, { children: fields.map((f) => /* @__PURE__ */ jsx(Select.Item, { value: f.id, children: f.label }, f.id)) })
135
+ ]
136
+ }
137
+ ),
138
+ /* @__PURE__ */ jsxs(Select.Root, { value: rule.operator, onValueChange: (op) => onChange({ ...rule, operator: op }), children: [
139
+ /* @__PURE__ */ jsx(Select.Trigger, { "aria-label": t.filterOperator, className: "w-auto min-w-32", children: /* @__PURE__ */ jsx(Select.Value, {}) }),
140
+ /* @__PURE__ */ jsx(Select.Content, { children: ops.map((op) => /* @__PURE__ */ jsx(Select.Item, { value: op, children: t.filterOperators[op] }, op)) })
141
+ ] }),
142
+ rule.operator !== "isEmpty" && (field?.type === "select" ? /* @__PURE__ */ jsxs(Select.Root, { value: rule.value || void 0, onValueChange: (v) => onChange({ ...rule, value: v }), children: [
143
+ /* @__PURE__ */ jsx(Select.Trigger, { "aria-label": t.filterValue, className: "w-auto min-w-36", children: /* @__PURE__ */ jsx(Select.Value, {}) }),
144
+ /* @__PURE__ */ jsx(Select.Content, { children: field.options?.map((o) => /* @__PURE__ */ jsx(Select.Item, { value: o.value, children: o.label }, o.value)) })
145
+ ] }) : /* @__PURE__ */ jsx(
146
+ Input,
147
+ {
148
+ "aria-label": t.filterValue,
149
+ type: field?.type === "number" ? "number" : field?.type === "date" ? "date" : "text",
150
+ value: rule.value,
151
+ onChange: (e) => onChange({ ...rule, value: e.target.value }),
152
+ wrapperClassName: "w-auto min-w-36 flex-1"
153
+ }
154
+ )),
155
+ /* @__PURE__ */ jsx(IconButton, { label: t.removeFilter, variant: "ghost", size: "sm", onClick: onRemove, children: /* @__PURE__ */ jsx(X, { size: "sm", "aria-hidden": "true" }) })
156
+ ] });
157
+ }
158
+ export {
159
+ FilterBuilder,
160
+ countFilters,
161
+ emptyFilter,
162
+ filterOperators,
163
+ isFilterGroup
164
+ };
@@ -0,0 +1,2 @@
1
+ export { FilterBuilder, filterOperators, isFilterGroup, emptyFilter, countFilters } from './FilterBuilder.js';
2
+ export type { FilterBuilderProps, FilterField, FilterFieldType, FilterOperator, FilterRule, FilterGroup } from './FilterBuilder.js';
@@ -0,0 +1,8 @@
1
+ import { FilterBuilder, filterOperators, isFilterGroup, emptyFilter, countFilters } from "./FilterBuilder.js";
2
+ export {
3
+ FilterBuilder,
4
+ countFilters,
5
+ emptyFilter,
6
+ filterOperators,
7
+ isFilterGroup
8
+ };
@@ -0,0 +1,28 @@
1
+ import * as React from 'react';
2
+ export interface OTPInputProps {
3
+ /** Number of characters. Default 6. */
4
+ length?: number;
5
+ value?: string;
6
+ defaultValue?: string;
7
+ onValueChange?: (value: string) => void;
8
+ /** Called once every box is filled. */
9
+ onComplete?: (value: string) => void;
10
+ /** `numeric` (default) accepts digits only; `alphanumeric` accepts letters too. */
11
+ mode?: 'numeric' | 'alphanumeric';
12
+ disabled?: boolean;
13
+ invalid?: boolean;
14
+ /** Group name; defaults to "Verification code". */
15
+ 'aria-label'?: string;
16
+ className?: string;
17
+ /** Submits with a form under this name. */
18
+ name?: string;
19
+ }
20
+ /**
21
+ * One box per character. Typing moves on, Backspace moves back, paste and
22
+ * the OS's one-time-code suggestion fill every box. The value has no gaps:
23
+ * focusing a box past the end jumps to the first empty one.
24
+ */
25
+ export declare function OTPInput({ length, value: valueProp, defaultValue, onValueChange, onComplete, mode, disabled, invalid, 'aria-label': ariaLabel, className, name, }: OTPInputProps): React.JSX.Element;
26
+ export declare namespace OTPInput {
27
+ var displayName: string;
28
+ }
@@ -0,0 +1,107 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../../utils/cn.js";
5
+ import { field, fieldFocusVisible, fieldInvalid } from "../../utils/control.js";
6
+ import { useControllableState } from "../../hooks/useControllableState.js";
7
+ import { useIsomorphicLayoutEffect } from "../../hooks/useIsomorphicLayoutEffect.js";
8
+ import { useNexubMessages } from "../NexubProvider/NexubProvider.js";
9
+ function OTPInput({
10
+ length = 6,
11
+ value: valueProp,
12
+ defaultValue,
13
+ onValueChange,
14
+ onComplete,
15
+ mode = "numeric",
16
+ disabled,
17
+ invalid,
18
+ "aria-label": ariaLabel,
19
+ className,
20
+ name
21
+ }) {
22
+ const t = useNexubMessages();
23
+ const [value = "", setValue] = useControllableState({
24
+ value: valueProp,
25
+ defaultValue: defaultValue ?? "",
26
+ onChange: onValueChange
27
+ });
28
+ const refs = React.useRef([]);
29
+ const filled = React.useRef(value.length);
30
+ useIsomorphicLayoutEffect(() => {
31
+ filled.current = value.length;
32
+ });
33
+ const clean = (s) => (s.match(mode === "numeric" ? /\d/g : /[a-z0-9]/gi) ?? []).join("");
34
+ const commit = (next) => {
35
+ const v = next.slice(0, length);
36
+ filled.current = v.length;
37
+ setValue(v);
38
+ if (v.length === length) onComplete?.(v);
39
+ };
40
+ const focus = (i) => refs.current[Math.max(0, Math.min(length - 1, i))]?.focus();
41
+ const writeAt = (i, chars) => {
42
+ commit(value.slice(0, i) + chars + value.slice(i + chars.length));
43
+ focus(i + chars.length);
44
+ };
45
+ return /* @__PURE__ */ jsxs("div", { role: "group", "aria-label": ariaLabel ?? t.verificationCode, className: cn("flex gap-2", className), children: [
46
+ Array.from({ length }, (_, i) => /* @__PURE__ */ jsx(
47
+ "input",
48
+ {
49
+ ref: (el) => {
50
+ refs.current[i] = el;
51
+ },
52
+ "aria-label": t.codeDigit(i + 1, length),
53
+ autoComplete: i === 0 ? "one-time-code" : "off",
54
+ inputMode: mode === "numeric" ? "numeric" : "text",
55
+ pattern: mode === "numeric" ? "[0-9]*" : void 0,
56
+ maxLength: i === 0 ? length : 2,
57
+ disabled,
58
+ "aria-invalid": invalid || void 0,
59
+ value: value[i] ?? "",
60
+ onFocus: (e) => {
61
+ if (i > filled.current) focus(filled.current);
62
+ else e.target.select();
63
+ },
64
+ onChange: (e) => {
65
+ const raw = clean(e.target.value);
66
+ const typed = raw.length === 2 && value[i] && raw.startsWith(value[i]) ? raw.slice(1) : raw;
67
+ if (typed) writeAt(Math.min(i, value.length), typed);
68
+ },
69
+ onPaste: (e) => {
70
+ const pasted = clean(e.clipboardData.getData("text"));
71
+ if (!pasted) return;
72
+ e.preventDefault();
73
+ writeAt(Math.min(i, value.length), pasted);
74
+ },
75
+ onKeyDown: (e) => {
76
+ if (e.key === "Backspace") {
77
+ e.preventDefault();
78
+ if (value[i]) commit(value.slice(0, i) + value.slice(i + 1));
79
+ else if (i > 0) {
80
+ commit(value.slice(0, i - 1) + value.slice(i));
81
+ focus(i - 1);
82
+ }
83
+ } else if (e.key === "ArrowLeft") {
84
+ e.preventDefault();
85
+ focus(i - 1);
86
+ } else if (e.key === "ArrowRight") {
87
+ e.preventDefault();
88
+ focus(i + 1);
89
+ }
90
+ },
91
+ className: cn(
92
+ field,
93
+ fieldFocusVisible,
94
+ invalid && fieldInvalid,
95
+ "h-12 w-10 text-center text-title-md tabular-nums",
96
+ "disabled:cursor-not-allowed disabled:border-[var(--color-outline-variant)] disabled:bg-[var(--color-surface-container-low)] disabled:text-[var(--color-text-disabled)]"
97
+ )
98
+ },
99
+ i
100
+ )),
101
+ name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value })
102
+ ] });
103
+ }
104
+ OTPInput.displayName = "OTPInput";
105
+ export {
106
+ OTPInput
107
+ };
@@ -0,0 +1,2 @@
1
+ export { OTPInput } from './OTPInput.js';
2
+ export type { OTPInputProps } from './OTPInput.js';
@@ -0,0 +1,4 @@
1
+ import { OTPInput } from "./OTPInput.js";
2
+ export {
3
+ OTPInput
4
+ };
@@ -0,0 +1,26 @@
1
+ import * as React from 'react';
2
+ export interface SavedView {
3
+ id: string;
4
+ name: string;
5
+ }
6
+ export interface SavedViewsProps {
7
+ views: SavedView[];
8
+ /** The view in use; its name shows on the button. */
9
+ activeId?: string;
10
+ onSelect: (id: string) => void;
11
+ /** "Save as new view…": asks for a name, then calls this. Your app stores the view. */
12
+ onSave?: (name: string) => void;
13
+ /** "Update ‹view›": overwrite the active view with the current filters. */
14
+ onUpdate?: (id: string) => void;
15
+ /** "Delete ‹view›": remove the active view. */
16
+ onDelete?: (id: string) => void;
17
+ className?: string;
18
+ }
19
+ /**
20
+ * A menu of saved filter views. UI only: your app keeps the views and what
21
+ * each one restores (filters, sort, columns).
22
+ */
23
+ export declare function SavedViews({ views, activeId, onSelect, onSave, onUpdate, onDelete, className }: SavedViewsProps): React.JSX.Element;
24
+ export declare namespace SavedViews {
25
+ var displayName: string;
26
+ }
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Bookmark, ChevronDown } from "@nexub/icons";
5
+ import { useNexubMessages } from "../NexubProvider/NexubProvider.js";
6
+ import { Button } from "../Button/Button.js";
7
+ import { DropdownMenu } from "../DropdownMenu/DropdownMenu.js";
8
+ import { Dialog } from "../Dialog/Dialog.js";
9
+ import { Input } from "../Input/Input.js";
10
+ function SavedViews({ views, activeId, onSelect, onSave, onUpdate, onDelete, className }) {
11
+ const t = useNexubMessages();
12
+ const [naming, setNaming] = React.useState(false);
13
+ const [name, setName] = React.useState("");
14
+ const active = views.find((v) => v.id === activeId);
15
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
16
+ /* @__PURE__ */ jsxs(DropdownMenu.Root, { children: [
17
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className, children: [
18
+ /* @__PURE__ */ jsx(Bookmark, { size: "sm", "aria-hidden": "true" }),
19
+ active?.name ?? t.views,
20
+ /* @__PURE__ */ jsx(ChevronDown, { size: "sm", "aria-hidden": "true" })
21
+ ] }) }),
22
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { align: "start", children: [
23
+ views.length > 0 && /* @__PURE__ */ jsx(DropdownMenu.RadioGroup, { value: activeId ?? "", onValueChange: onSelect, children: views.map((v) => /* @__PURE__ */ jsx(DropdownMenu.RadioItem, { value: v.id, children: v.name }, v.id)) }),
24
+ views.length > 0 && (onSave || active && (onUpdate || onDelete)) && /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
25
+ onSave && /* @__PURE__ */ jsx(
26
+ DropdownMenu.Item,
27
+ {
28
+ onSelect: () => {
29
+ setName("");
30
+ setNaming(true);
31
+ },
32
+ children: t.saveView
33
+ }
34
+ ),
35
+ active && onUpdate && /* @__PURE__ */ jsx(DropdownMenu.Item, { onSelect: () => onUpdate(active.id), children: t.updateView(active.name) }),
36
+ active && onDelete && /* @__PURE__ */ jsx(DropdownMenu.Item, { onSelect: () => onDelete(active.id), className: "text-[var(--color-error)]", children: t.deleteView(active.name) })
37
+ ] })
38
+ ] }),
39
+ onSave && /* @__PURE__ */ jsx(Dialog.Root, { open: naming, onOpenChange: setNaming, children: /* @__PURE__ */ jsx(Dialog.Content, { className: "max-w-sm", children: /* @__PURE__ */ jsxs(
40
+ "form",
41
+ {
42
+ onSubmit: (e) => {
43
+ e.preventDefault();
44
+ const n = name.trim();
45
+ if (!n) return;
46
+ onSave(n);
47
+ setNaming(false);
48
+ },
49
+ className: "flex flex-col gap-4",
50
+ children: [
51
+ /* @__PURE__ */ jsx(Dialog.Header, { children: /* @__PURE__ */ jsx(Dialog.Title, { children: t.saveView.replace(/…$/, "") }) }),
52
+ /* @__PURE__ */ jsx(Input, { "aria-label": t.viewName, placeholder: t.viewName, value: name, onChange: (e) => setName(e.target.value), autoFocus: true }),
53
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
54
+ /* @__PURE__ */ jsx(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", children: t.cancel }) }),
55
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled: !name.trim(), children: t.save })
56
+ ] })
57
+ ]
58
+ }
59
+ ) }) })
60
+ ] });
61
+ }
62
+ SavedViews.displayName = "SavedViews";
63
+ export {
64
+ SavedViews
65
+ };
@@ -0,0 +1,2 @@
1
+ export { SavedViews } from './SavedViews.js';
2
+ export type { SavedViewsProps, SavedView } from './SavedViews.js';
@@ -0,0 +1,4 @@
1
+ import { SavedViews } from "./SavedViews.js";
2
+ export {
3
+ SavedViews
4
+ };
package/dist/index.d.ts CHANGED
@@ -144,6 +144,7 @@ export { KeyboardShortcut } from './components/KeyboardShortcut/index.js';
144
144
  export type { KeyboardShortcutProps } from './components/KeyboardShortcut/index.js';
145
145
  export { Dialog } from './components/Dialog/index.js';
146
146
  export { AlertDialog } from './components/AlertDialog/index.js';
147
+ export type { AlertDialogConfirmProps } from './components/AlertDialog/index.js';
147
148
  export { Popover } from './components/Popover/index.js';
148
149
  export { Tooltip } from './components/Tooltip/index.js';
149
150
  export { Provider as TooltipProvider } from './components/Tooltip/index.js';
@@ -161,6 +162,10 @@ export { Combobox } from './components/Combobox/index.js';
161
162
  export { Autocomplete } from './components/Autocomplete/index.js';
162
163
  export type { AutocompleteOption, AutocompleteProps } from './components/Autocomplete/index.js';
163
164
  export { MultiSelect } from './components/MultiSelect/index.js';
165
+ export { FilterBuilder, filterOperators, isFilterGroup, emptyFilter, countFilters } from './components/FilterBuilder/index.js';
166
+ export type { FilterBuilderProps, FilterField, FilterFieldType, FilterOperator, FilterRule, FilterGroup } from './components/FilterBuilder/index.js';
167
+ export { SavedViews } from './components/SavedViews/index.js';
168
+ export type { SavedViewsProps, SavedView } from './components/SavedViews/index.js';
164
169
  export type { MultiSelectOption, MultiSelectProps } from './components/MultiSelect/index.js';
165
170
  export { Switch } from './components/Switch/index.js';
166
171
  export type { SwitchProps } from './components/Switch/index.js';
@@ -201,15 +206,19 @@ export type { CommandPaletteRootProps } from './components/CommandPalette/index.
201
206
  export { Table } from './components/Table/index.js';
202
207
  export { DataTable } from './components/DataTable/index.js';
203
208
  export type { DataTableProps, DataTableDensity } from './components/DataTable/index.js';
204
- export { EmptyState } from './components/EmptyState/index.js';
209
+ export { EmptyState, EmptyStatePreset } from './components/EmptyState/index.js';
210
+ export type { EmptyStatePresetProps, EmptyStateKind } from './components/EmptyState/index.js';
205
211
  export { ErrorState } from './components/ErrorState/index.js';
206
212
  export type { ErrorStateProps } from './components/ErrorState/index.js';
207
213
  export { FileUpload, fileAccepted } from './components/FileUpload/index.js';
208
- export type { FileUploadRootProps, FileRejection } from './components/FileUpload/index.js';
214
+ export type { FileUploadRootProps, FileUploadItemProps, FileRejection } from './components/FileUpload/index.js';
215
+ export { OTPInput } from './components/OTPInput/index.js';
216
+ export type { OTPInputProps } from './components/OTPInput/index.js';
209
217
  export { DatePicker } from './components/DatePicker/index.js';
210
218
  export type { DatePickerProps } from './components/DatePicker/index.js';
211
219
  export { DateRangePicker } from './components/DateRangePicker/index.js';
212
- export type { DateRangePickerProps, DateRange } from './components/DateRangePicker/index.js';
220
+ export { todayIn } from './components/DateRangePicker/index.js';
221
+ export type { DateRangePickerProps, DateRange, DateRangePreset } from './components/DateRangePicker/index.js';
213
222
  export { ThemeProvider, ThemeScript, useTheme } from './components/ThemeProvider/index.js';
214
223
  export type { ThemeMode, GlassMode, ThemeContextValue, ThemeProviderProps, ThemeScriptProps } from './components/ThemeProvider/index.js';
215
224
  export { Fade, Slide, Scale, Collapse, ListTransition, SkeletonSwap, usePrefersReducedMotion, Reveal, Float, Marquee } from './components/Motion/index.js';
package/dist/index.js CHANGED
@@ -90,6 +90,8 @@ import { Select } from "./components/Select/index.js";
90
90
  import { Combobox } from "./components/Combobox/index.js";
91
91
  import { Autocomplete } from "./components/Autocomplete/index.js";
92
92
  import { MultiSelect } from "./components/MultiSelect/index.js";
93
+ import { FilterBuilder, filterOperators, isFilterGroup, emptyFilter, countFilters } from "./components/FilterBuilder/index.js";
94
+ import { SavedViews } from "./components/SavedViews/index.js";
93
95
  import { Switch } from "./components/Switch/index.js";
94
96
  import { Checkbox } from "./components/Checkbox/index.js";
95
97
  import { RadioGroup } from "./components/RadioGroup/index.js";
@@ -114,11 +116,13 @@ import { Pagination } from "./components/Pagination/index.js";
114
116
  import { CommandPalette } from "./components/CommandPalette/index.js";
115
117
  import { Table } from "./components/Table/index.js";
116
118
  import { DataTable } from "./components/DataTable/index.js";
117
- import { EmptyState } from "./components/EmptyState/index.js";
119
+ import { EmptyState, EmptyStatePreset } from "./components/EmptyState/index.js";
118
120
  import { ErrorState } from "./components/ErrorState/index.js";
119
121
  import { FileUpload, fileAccepted } from "./components/FileUpload/index.js";
122
+ import { OTPInput } from "./components/OTPInput/index.js";
120
123
  import { DatePicker } from "./components/DatePicker/index.js";
121
124
  import { DateRangePicker } from "./components/DateRangePicker/index.js";
125
+ import { todayIn } from "./components/DateRangePicker/index.js";
122
126
  import { ThemeProvider, ThemeScript, useTheme } from "./components/ThemeProvider/index.js";
123
127
  import { Fade, Slide, Scale, Collapse, ListTransition, SkeletonSwap, usePrefersReducedMotion, Reveal, Float, Marquee } from "./components/Motion/index.js";
124
128
  export {
@@ -167,10 +171,12 @@ export {
167
171
  Drawer,
168
172
  DropdownMenu,
169
173
  EmptyState,
174
+ EmptyStatePreset,
170
175
  ErrorState,
171
176
  EyebrowChip,
172
177
  Fade,
173
178
  FileUpload,
179
+ FilterBuilder,
174
180
  FilterChip,
175
181
  Flag,
176
182
  Flex,
@@ -208,6 +214,7 @@ export {
208
214
  NexubProvider,
209
215
  NumberInput,
210
216
  NumberTicker,
217
+ OTPInput,
211
218
  PageHeader,
212
219
  Pagination,
213
220
  PasswordInput,
@@ -220,6 +227,7 @@ export {
220
227
  RadioGroup,
221
228
  Rating,
222
229
  Reveal,
230
+ SavedViews,
223
231
  Scale,
224
232
  ScrollArea,
225
233
  ScrollProgress,
@@ -271,13 +279,17 @@ export {
271
279
  chipVariants,
272
280
  cn,
273
281
  containerVariants,
282
+ countFilters,
274
283
  defaultMessageStrings,
275
284
  defaultMessages,
285
+ emptyFilter,
276
286
  fileAccepted,
287
+ filterOperators,
277
288
  headingVariants,
278
289
  iconButtonVariants,
279
290
  inputVariants,
280
291
  inputWrapperVariants,
292
+ isFilterGroup,
281
293
  labelVariants,
282
294
  linkVariants,
283
295
  logoVariants,
@@ -295,6 +307,7 @@ export {
295
307
  textVariants,
296
308
  textareaVariants,
297
309
  toast,
310
+ todayIn,
298
311
  toggleVariants,
299
312
  transitionName,
300
313
  useControllableState,