@jameskabz/nextcraft-ui 0.7.5 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/components/craft-data-table-filters.cjs +184 -0
  2. package/dist/components/craft-data-table-filters.cjs.map +1 -0
  3. package/dist/components/craft-data-table-filters.d.cts +58 -0
  4. package/dist/components/craft-data-table-filters.d.ts +58 -0
  5. package/dist/components/craft-data-table-filters.js +160 -0
  6. package/dist/components/craft-data-table-filters.js.map +1 -0
  7. package/dist/components/craft-data-table-header.cjs +1 -1
  8. package/dist/components/craft-data-table-header.cjs.map +1 -1
  9. package/dist/components/craft-data-table-header.js +1 -1
  10. package/dist/components/craft-data-table-header.js.map +1 -1
  11. package/dist/components/craft-data-table.cjs +8 -5
  12. package/dist/components/craft-data-table.cjs.map +1 -1
  13. package/dist/components/craft-data-table.js +8 -5
  14. package/dist/components/craft-data-table.js.map +1 -1
  15. package/dist/components/craft-filter-bar.cjs +75 -5
  16. package/dist/components/craft-filter-bar.cjs.map +1 -1
  17. package/dist/components/craft-filter-bar.d.cts +29 -3
  18. package/dist/components/craft-filter-bar.d.ts +29 -3
  19. package/dist/components/craft-filter-bar.js +75 -5
  20. package/dist/components/craft-filter-bar.js.map +1 -1
  21. package/dist/components/craft-toast.cjs +40 -56
  22. package/dist/components/craft-toast.cjs.map +1 -1
  23. package/dist/components/craft-toast.d.cts +3 -23
  24. package/dist/components/craft-toast.d.ts +3 -23
  25. package/dist/components/craft-toast.js +41 -45
  26. package/dist/components/craft-toast.js.map +1 -1
  27. package/dist/craft-toast-BcscwgO3.d.ts +56 -0
  28. package/dist/craft-toast-C7rMmROV.d.cts +56 -0
  29. package/dist/index.cjs +11 -4
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +2 -1
  32. package/dist/index.d.ts +2 -1
  33. package/dist/index.js +7 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/styles.css +16 -5
  36. package/package.json +1 -1
@@ -25,17 +25,44 @@ module.exports = __toCommonJS(craft_filter_bar_exports);
25
25
  var import_jsx_runtime = require("react/jsx-runtime");
26
26
  var import_cn = require("../utils/cn");
27
27
  var import_craft_input = require("../components/craft-input");
28
+ var import_craft_select = require("../components/craft-select");
29
+ var import_craft_button = require("../components/craft-button");
28
30
  function CraftFilterBar({
29
31
  title,
30
32
  description,
31
33
  searchValue,
32
34
  onSearchChange,
33
35
  searchPlaceholder = "Search...",
36
+ showSearch = true,
34
37
  actions,
35
- filters,
38
+ selectFilters,
39
+ onSelectFiltersChange,
40
+ dateFilters,
41
+ onDateFiltersChange,
42
+ showFilters = true,
43
+ showClear = true,
44
+ clearLabel = "Clear filters",
45
+ onClearFilters,
36
46
  tone,
37
47
  className
38
48
  }) {
49
+ const hasSelects = Boolean(selectFilters && selectFilters.length > 0);
50
+ const hasDates = Boolean(dateFilters && dateFilters.length > 0);
51
+ const hasFilters = showFilters && (hasSelects || hasDates);
52
+ const updateSelectFilter = (index, value) => {
53
+ if (!selectFilters || !onSelectFiltersChange) return;
54
+ const next = selectFilters.map(
55
+ (filter, idx) => idx === index ? { ...filter, value } : filter
56
+ );
57
+ onSelectFiltersChange(next);
58
+ };
59
+ const updateDateFilter = (index, key, value) => {
60
+ if (!dateFilters || !onDateFiltersChange) return;
61
+ const next = dateFilters.map(
62
+ (filter, idx) => idx === index ? { ...filter, [key]: value } : filter
63
+ );
64
+ onDateFiltersChange(next);
65
+ };
39
66
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
40
67
  "div",
41
68
  {
@@ -50,10 +77,13 @@ function CraftFilterBar({
50
77
  title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-lg font-semibold", children: title }),
51
78
  description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
52
79
  ] }),
53
- actions && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center gap-3", children: actions })
80
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-3", children: [
81
+ actions,
82
+ showClear && onClearFilters ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_craft_button.CraftButton, { type: "button", variant: "ghost", onClick: onClearFilters, children: clearLabel }) : null
83
+ ] })
54
84
  ] }),
55
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-4 grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]", children: [
56
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
85
+ (showSearch || hasFilters) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-4 grid gap-4", children: [
86
+ showSearch && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
57
87
  import_craft_input.CraftInput,
58
88
  {
59
89
  type: "search",
@@ -63,7 +93,47 @@ function CraftFilterBar({
63
93
  tone
64
94
  }
65
95
  ),
66
- filters && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-wrap items-center gap-3", children: filters })
96
+ hasFilters && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-end gap-3", children: [
97
+ selectFilters == null ? void 0 : selectFilters.map((filter, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "grid gap-2 text-xs", children: [
98
+ filter.label ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: filter.label }) : null,
99
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
100
+ import_craft_select.CraftSelect,
101
+ {
102
+ value: filter.value,
103
+ disabled: filter.disabled,
104
+ onChange: (event) => updateSelectFilter(index, event.target.value),
105
+ children: [
106
+ filter.placeholder ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: filter.placeholder }) : null,
107
+ filter.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: option.value, children: option.label }, String(option.value)))
108
+ ]
109
+ }
110
+ )
111
+ ] }, filter.key)),
112
+ dateFilters == null ? void 0 : dateFilters.map((filter, index) => {
113
+ var _a, _b;
114
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid gap-2 text-xs", children: [
115
+ filter.label ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: filter.label }) : null,
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
118
+ import_craft_input.CraftInput,
119
+ {
120
+ type: "date",
121
+ value: (_a = filter.from) != null ? _a : "",
122
+ onChange: (event) => updateDateFilter(index, "from", event.target.value)
123
+ }
124
+ ),
125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
126
+ import_craft_input.CraftInput,
127
+ {
128
+ type: "date",
129
+ value: (_b = filter.to) != null ? _b : "",
130
+ onChange: (event) => updateDateFilter(index, "to", event.target.value)
131
+ }
132
+ )
133
+ ] })
134
+ ] }, filter.key);
135
+ })
136
+ ] })
67
137
  ] })
68
138
  ]
69
139
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/craft-filter-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\nimport { CraftInput } from \"@/components/craft-input\";\n\nexport type CraftFilterBarProps = {\n title?: React.ReactNode;\n description?: React.ReactNode;\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n searchPlaceholder?: string;\n actions?: React.ReactNode;\n filters?: React.ReactNode;\n tone?: ThemeName;\n className?: string;\n};\n\nexport function CraftFilterBar({\n title,\n description,\n searchValue,\n onSearchChange,\n searchPlaceholder = \"Search...\",\n actions,\n filters,\n tone,\n className,\n}: CraftFilterBarProps) {\n return (\n <div\n className={cn(\n \"rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_12px_36px_rgba(0,0,0,0.2)] backdrop-blur-2xl\",\n className\n )}\n data-nc-theme={tone}\n >\n <div className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n {title && <h3 className=\"text-lg font-semibold\">{title}</h3>}\n {description && (\n <p className=\"text-sm text-[rgb(var(--nc-fg-muted))]\">\n {description}\n </p>\n )}\n </div>\n {actions && <div className=\"flex items-center gap-3\">{actions}</div>}\n </div>\n <div className=\"mt-4 grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]\">\n <CraftInput\n type=\"search\"\n placeholder={searchPlaceholder}\n value={searchValue ?? \"\"}\n onChange={(event) => onSearchChange?.(event.target.value)}\n tone={tone}\n />\n {filters && <div className=\"flex flex-wrap items-center gap-3\">{filters}</div>}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwCQ;AApCR,gBAAmB;AAEnB,yBAA2B;AAcpB,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,iBAAe;AAAA,MAEf;AAAA,qDAAC,SAAI,WAAU,qDACb;AAAA,uDAAC,SACE;AAAA,qBAAS,4CAAC,QAAG,WAAU,yBAAyB,iBAAM;AAAA,YACtD,eACC,4CAAC,OAAE,WAAU,0CACV,uBACH;AAAA,aAEJ;AAAA,UACC,WAAW,4CAAC,SAAI,WAAU,2BAA2B,mBAAQ;AAAA,WAChE;AAAA,QACA,6CAAC,SAAI,WAAU,qDACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,aAAa;AAAA,cACb,OAAO,oCAAe;AAAA,cACtB,UAAU,CAAC,UAAU,iDAAiB,MAAM,OAAO;AAAA,cACnD;AAAA;AAAA,UACF;AAAA,UACC,WAAW,4CAAC,SAAI,WAAU,qCAAqC,mBAAQ;AAAA,WAC1E;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/craft-filter-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\nimport { CraftInput } from \"@/components/craft-input\";\nimport { CraftSelect } from \"@/components/craft-select\";\nimport { CraftButton } from \"@/components/craft-button\";\n\nexport type CraftFilterSelectOption = {\n label: React.ReactNode;\n value: string;\n};\n\nexport type CraftFilterSelect = {\n key: string;\n label?: React.ReactNode;\n value: string;\n placeholder?: string;\n options: CraftFilterSelectOption[];\n disabled?: boolean;\n};\n\nexport type CraftFilterDate = {\n key: string;\n label?: React.ReactNode;\n from?: string;\n to?: string;\n};\n\nexport type CraftFilterBarProps = {\n title?: React.ReactNode;\n description?: React.ReactNode;\n\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n searchPlaceholder?: string;\n showSearch?: boolean;\n\n actions?: React.ReactNode;\n\n selectFilters?: CraftFilterSelect[];\n onSelectFiltersChange?: (filters: CraftFilterSelect[]) => void;\n\n dateFilters?: CraftFilterDate[];\n onDateFiltersChange?: (filters: CraftFilterDate[]) => void;\n\n showFilters?: boolean;\n showClear?: boolean;\n clearLabel?: React.ReactNode;\n onClearFilters?: () => void;\n\n tone?: ThemeName;\n className?: string;\n};\n\nexport function CraftFilterBar({\n title,\n description,\n searchValue,\n onSearchChange,\n searchPlaceholder = \"Search...\",\n showSearch = true,\n actions,\n selectFilters,\n onSelectFiltersChange,\n dateFilters,\n onDateFiltersChange,\n showFilters = true,\n showClear = true,\n clearLabel = \"Clear filters\",\n onClearFilters,\n tone,\n className,\n}: CraftFilterBarProps) {\n const hasSelects = Boolean(selectFilters && selectFilters.length > 0);\n const hasDates = Boolean(dateFilters && dateFilters.length > 0);\n const hasFilters = showFilters && (hasSelects || hasDates);\n\n const updateSelectFilter = (index: number, value: string) => {\n if (!selectFilters || !onSelectFiltersChange) return;\n const next = selectFilters.map((filter, idx) =>\n idx === index ? { ...filter, value } : filter\n );\n onSelectFiltersChange(next);\n };\n\n const updateDateFilter = (\n index: number,\n key: \"from\" | \"to\",\n value: string\n ) => {\n if (!dateFilters || !onDateFiltersChange) return;\n const next = dateFilters.map((filter, idx) =>\n idx === index ? { ...filter, [key]: value } : filter\n );\n onDateFiltersChange(next);\n };\n\n return (\n <div\n className={cn(\n \"rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_12px_36px_rgba(0,0,0,0.2)] backdrop-blur-2xl\",\n className\n )}\n data-nc-theme={tone}\n >\n <div className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n {title && <h3 className=\"text-lg font-semibold\">{title}</h3>}\n {description && (\n <p className=\"text-sm text-[rgb(var(--nc-fg-muted))]\">\n {description}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-3\">\n {actions}\n {showClear && onClearFilters ? (\n <CraftButton type=\"button\" variant=\"ghost\" onClick={onClearFilters}>\n {clearLabel}\n </CraftButton>\n ) : null}\n </div>\n </div>\n\n {(showSearch || hasFilters) && (\n <div className=\"mt-4 grid gap-4\">\n {showSearch && (\n <CraftInput\n type=\"search\"\n placeholder={searchPlaceholder}\n value={searchValue ?? \"\"}\n onChange={(event) => onSearchChange?.(event.target.value)}\n tone={tone}\n />\n )}\n\n {hasFilters && (\n <div className=\"flex flex-wrap items-end gap-3\">\n {selectFilters?.map((filter, index) => (\n <label key={filter.key} className=\"grid gap-2 text-xs\">\n {filter.label ? (\n <span className=\"text-[rgb(var(--nc-fg-muted))]\">\n {filter.label}\n </span>\n ) : null}\n <CraftSelect\n value={filter.value}\n disabled={filter.disabled}\n onChange={(event) =>\n updateSelectFilter(index, event.target.value)\n }\n >\n {filter.placeholder ? (\n <option value=\"\">{filter.placeholder}</option>\n ) : null}\n {filter.options.map((option) => (\n <option key={String(option.value)} value={option.value}>\n {option.label}\n </option>\n ))}\n </CraftSelect>\n </label>\n ))}\n\n {dateFilters?.map((filter, index) => (\n <div key={filter.key} className=\"grid gap-2 text-xs\">\n {filter.label ? (\n <span className=\"text-[rgb(var(--nc-fg-muted))]\">\n {filter.label}\n </span>\n ) : null}\n <div className=\"flex items-center gap-2\">\n <CraftInput\n type=\"date\"\n value={filter.from ?? \"\"}\n onChange={(event) =>\n updateDateFilter(index, \"from\", event.target.value)\n }\n />\n <CraftInput\n type=\"date\"\n value={filter.to ?? \"\"}\n onChange={(event) =>\n updateDateFilter(index, \"to\", event.target.value)\n }\n />\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -2,17 +2,43 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import { ThemeName } from '../theme/theme-context.cjs';
4
4
 
5
+ type CraftFilterSelectOption = {
6
+ label: React.ReactNode;
7
+ value: string;
8
+ };
9
+ type CraftFilterSelect = {
10
+ key: string;
11
+ label?: React.ReactNode;
12
+ value: string;
13
+ placeholder?: string;
14
+ options: CraftFilterSelectOption[];
15
+ disabled?: boolean;
16
+ };
17
+ type CraftFilterDate = {
18
+ key: string;
19
+ label?: React.ReactNode;
20
+ from?: string;
21
+ to?: string;
22
+ };
5
23
  type CraftFilterBarProps = {
6
24
  title?: React.ReactNode;
7
25
  description?: React.ReactNode;
8
26
  searchValue?: string;
9
27
  onSearchChange?: (value: string) => void;
10
28
  searchPlaceholder?: string;
29
+ showSearch?: boolean;
11
30
  actions?: React.ReactNode;
12
- filters?: React.ReactNode;
31
+ selectFilters?: CraftFilterSelect[];
32
+ onSelectFiltersChange?: (filters: CraftFilterSelect[]) => void;
33
+ dateFilters?: CraftFilterDate[];
34
+ onDateFiltersChange?: (filters: CraftFilterDate[]) => void;
35
+ showFilters?: boolean;
36
+ showClear?: boolean;
37
+ clearLabel?: React.ReactNode;
38
+ onClearFilters?: () => void;
13
39
  tone?: ThemeName;
14
40
  className?: string;
15
41
  };
16
- declare function CraftFilterBar({ title, description, searchValue, onSearchChange, searchPlaceholder, actions, filters, tone, className, }: CraftFilterBarProps): react_jsx_runtime.JSX.Element;
42
+ declare function CraftFilterBar({ title, description, searchValue, onSearchChange, searchPlaceholder, showSearch, actions, selectFilters, onSelectFiltersChange, dateFilters, onDateFiltersChange, showFilters, showClear, clearLabel, onClearFilters, tone, className, }: CraftFilterBarProps): react_jsx_runtime.JSX.Element;
17
43
 
18
- export { CraftFilterBar, type CraftFilterBarProps };
44
+ export { CraftFilterBar, type CraftFilterBarProps, type CraftFilterDate, type CraftFilterSelect, type CraftFilterSelectOption };
@@ -2,17 +2,43 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import { ThemeName } from '../theme/theme-context.js';
4
4
 
5
+ type CraftFilterSelectOption = {
6
+ label: React.ReactNode;
7
+ value: string;
8
+ };
9
+ type CraftFilterSelect = {
10
+ key: string;
11
+ label?: React.ReactNode;
12
+ value: string;
13
+ placeholder?: string;
14
+ options: CraftFilterSelectOption[];
15
+ disabled?: boolean;
16
+ };
17
+ type CraftFilterDate = {
18
+ key: string;
19
+ label?: React.ReactNode;
20
+ from?: string;
21
+ to?: string;
22
+ };
5
23
  type CraftFilterBarProps = {
6
24
  title?: React.ReactNode;
7
25
  description?: React.ReactNode;
8
26
  searchValue?: string;
9
27
  onSearchChange?: (value: string) => void;
10
28
  searchPlaceholder?: string;
29
+ showSearch?: boolean;
11
30
  actions?: React.ReactNode;
12
- filters?: React.ReactNode;
31
+ selectFilters?: CraftFilterSelect[];
32
+ onSelectFiltersChange?: (filters: CraftFilterSelect[]) => void;
33
+ dateFilters?: CraftFilterDate[];
34
+ onDateFiltersChange?: (filters: CraftFilterDate[]) => void;
35
+ showFilters?: boolean;
36
+ showClear?: boolean;
37
+ clearLabel?: React.ReactNode;
38
+ onClearFilters?: () => void;
13
39
  tone?: ThemeName;
14
40
  className?: string;
15
41
  };
16
- declare function CraftFilterBar({ title, description, searchValue, onSearchChange, searchPlaceholder, actions, filters, tone, className, }: CraftFilterBarProps): react_jsx_runtime.JSX.Element;
42
+ declare function CraftFilterBar({ title, description, searchValue, onSearchChange, searchPlaceholder, showSearch, actions, selectFilters, onSelectFiltersChange, dateFilters, onDateFiltersChange, showFilters, showClear, clearLabel, onClearFilters, tone, className, }: CraftFilterBarProps): react_jsx_runtime.JSX.Element;
17
43
 
18
- export { CraftFilterBar, type CraftFilterBarProps };
44
+ export { CraftFilterBar, type CraftFilterBarProps, type CraftFilterDate, type CraftFilterSelect, type CraftFilterSelectOption };
@@ -2,17 +2,44 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { cn } from "../utils/cn";
4
4
  import { CraftInput } from "../components/craft-input";
5
+ import { CraftSelect } from "../components/craft-select";
6
+ import { CraftButton } from "../components/craft-button";
5
7
  function CraftFilterBar({
6
8
  title,
7
9
  description,
8
10
  searchValue,
9
11
  onSearchChange,
10
12
  searchPlaceholder = "Search...",
13
+ showSearch = true,
11
14
  actions,
12
- filters,
15
+ selectFilters,
16
+ onSelectFiltersChange,
17
+ dateFilters,
18
+ onDateFiltersChange,
19
+ showFilters = true,
20
+ showClear = true,
21
+ clearLabel = "Clear filters",
22
+ onClearFilters,
13
23
  tone,
14
24
  className
15
25
  }) {
26
+ const hasSelects = Boolean(selectFilters && selectFilters.length > 0);
27
+ const hasDates = Boolean(dateFilters && dateFilters.length > 0);
28
+ const hasFilters = showFilters && (hasSelects || hasDates);
29
+ const updateSelectFilter = (index, value) => {
30
+ if (!selectFilters || !onSelectFiltersChange) return;
31
+ const next = selectFilters.map(
32
+ (filter, idx) => idx === index ? { ...filter, value } : filter
33
+ );
34
+ onSelectFiltersChange(next);
35
+ };
36
+ const updateDateFilter = (index, key, value) => {
37
+ if (!dateFilters || !onDateFiltersChange) return;
38
+ const next = dateFilters.map(
39
+ (filter, idx) => idx === index ? { ...filter, [key]: value } : filter
40
+ );
41
+ onDateFiltersChange(next);
42
+ };
16
43
  return /* @__PURE__ */ jsxs(
17
44
  "div",
18
45
  {
@@ -27,10 +54,13 @@ function CraftFilterBar({
27
54
  title && /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold", children: title }),
28
55
  description && /* @__PURE__ */ jsx("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
29
56
  ] }),
30
- actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: actions })
57
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
58
+ actions,
59
+ showClear && onClearFilters ? /* @__PURE__ */ jsx(CraftButton, { type: "button", variant: "ghost", onClick: onClearFilters, children: clearLabel }) : null
60
+ ] })
31
61
  ] }),
32
- /* @__PURE__ */ jsxs("div", { className: "mt-4 grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]", children: [
33
- /* @__PURE__ */ jsx(
62
+ (showSearch || hasFilters) && /* @__PURE__ */ jsxs("div", { className: "mt-4 grid gap-4", children: [
63
+ showSearch && /* @__PURE__ */ jsx(
34
64
  CraftInput,
35
65
  {
36
66
  type: "search",
@@ -40,7 +70,47 @@ function CraftFilterBar({
40
70
  tone
41
71
  }
42
72
  ),
43
- filters && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-3", children: filters })
73
+ hasFilters && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-end gap-3", children: [
74
+ selectFilters == null ? void 0 : selectFilters.map((filter, index) => /* @__PURE__ */ jsxs("label", { className: "grid gap-2 text-xs", children: [
75
+ filter.label ? /* @__PURE__ */ jsx("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: filter.label }) : null,
76
+ /* @__PURE__ */ jsxs(
77
+ CraftSelect,
78
+ {
79
+ value: filter.value,
80
+ disabled: filter.disabled,
81
+ onChange: (event) => updateSelectFilter(index, event.target.value),
82
+ children: [
83
+ filter.placeholder ? /* @__PURE__ */ jsx("option", { value: "", children: filter.placeholder }) : null,
84
+ filter.options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, String(option.value)))
85
+ ]
86
+ }
87
+ )
88
+ ] }, filter.key)),
89
+ dateFilters == null ? void 0 : dateFilters.map((filter, index) => {
90
+ var _a, _b;
91
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-2 text-xs", children: [
92
+ filter.label ? /* @__PURE__ */ jsx("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: filter.label }) : null,
93
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
94
+ /* @__PURE__ */ jsx(
95
+ CraftInput,
96
+ {
97
+ type: "date",
98
+ value: (_a = filter.from) != null ? _a : "",
99
+ onChange: (event) => updateDateFilter(index, "from", event.target.value)
100
+ }
101
+ ),
102
+ /* @__PURE__ */ jsx(
103
+ CraftInput,
104
+ {
105
+ type: "date",
106
+ value: (_b = filter.to) != null ? _b : "",
107
+ onChange: (event) => updateDateFilter(index, "to", event.target.value)
108
+ }
109
+ )
110
+ ] })
111
+ ] }, filter.key);
112
+ })
113
+ ] })
44
114
  ] })
45
115
  ]
46
116
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/craft-filter-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\nimport { CraftInput } from \"@/components/craft-input\";\n\nexport type CraftFilterBarProps = {\n title?: React.ReactNode;\n description?: React.ReactNode;\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n searchPlaceholder?: string;\n actions?: React.ReactNode;\n filters?: React.ReactNode;\n tone?: ThemeName;\n className?: string;\n};\n\nexport function CraftFilterBar({\n title,\n description,\n searchValue,\n onSearchChange,\n searchPlaceholder = \"Search...\",\n actions,\n filters,\n tone,\n className,\n}: CraftFilterBarProps) {\n return (\n <div\n className={cn(\n \"rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_12px_36px_rgba(0,0,0,0.2)] backdrop-blur-2xl\",\n className\n )}\n data-nc-theme={tone}\n >\n <div className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n {title && <h3 className=\"text-lg font-semibold\">{title}</h3>}\n {description && (\n <p className=\"text-sm text-[rgb(var(--nc-fg-muted))]\">\n {description}\n </p>\n )}\n </div>\n {actions && <div className=\"flex items-center gap-3\">{actions}</div>}\n </div>\n <div className=\"mt-4 grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]\">\n <CraftInput\n type=\"search\"\n placeholder={searchPlaceholder}\n value={searchValue ?? \"\"}\n onChange={(event) => onSearchChange?.(event.target.value)}\n tone={tone}\n />\n {filters && <div className=\"flex flex-wrap items-center gap-3\">{filters}</div>}\n </div>\n </div>\n );\n}\n"],"mappings":";AAwCQ,SACY,KADZ;AApCR,SAAS,UAAU;AAEnB,SAAS,kBAAkB;AAcpB,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,iBAAe;AAAA,MAEf;AAAA,6BAAC,SAAI,WAAU,qDACb;AAAA,+BAAC,SACE;AAAA,qBAAS,oBAAC,QAAG,WAAU,yBAAyB,iBAAM;AAAA,YACtD,eACC,oBAAC,OAAE,WAAU,0CACV,uBACH;AAAA,aAEJ;AAAA,UACC,WAAW,oBAAC,SAAI,WAAU,2BAA2B,mBAAQ;AAAA,WAChE;AAAA,QACA,qBAAC,SAAI,WAAU,qDACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,aAAa;AAAA,cACb,OAAO,oCAAe;AAAA,cACtB,UAAU,CAAC,UAAU,iDAAiB,MAAM,OAAO;AAAA,cACnD;AAAA;AAAA,UACF;AAAA,UACC,WAAW,oBAAC,SAAI,WAAU,qCAAqC,mBAAQ;AAAA,WAC1E;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/craft-filter-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\nimport { CraftInput } from \"@/components/craft-input\";\nimport { CraftSelect } from \"@/components/craft-select\";\nimport { CraftButton } from \"@/components/craft-button\";\n\nexport type CraftFilterSelectOption = {\n label: React.ReactNode;\n value: string;\n};\n\nexport type CraftFilterSelect = {\n key: string;\n label?: React.ReactNode;\n value: string;\n placeholder?: string;\n options: CraftFilterSelectOption[];\n disabled?: boolean;\n};\n\nexport type CraftFilterDate = {\n key: string;\n label?: React.ReactNode;\n from?: string;\n to?: string;\n};\n\nexport type CraftFilterBarProps = {\n title?: React.ReactNode;\n description?: React.ReactNode;\n\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n searchPlaceholder?: string;\n showSearch?: boolean;\n\n actions?: React.ReactNode;\n\n selectFilters?: CraftFilterSelect[];\n onSelectFiltersChange?: (filters: CraftFilterSelect[]) => void;\n\n dateFilters?: CraftFilterDate[];\n onDateFiltersChange?: (filters: CraftFilterDate[]) => void;\n\n showFilters?: boolean;\n showClear?: boolean;\n clearLabel?: React.ReactNode;\n onClearFilters?: () => void;\n\n tone?: ThemeName;\n className?: string;\n};\n\nexport function CraftFilterBar({\n title,\n description,\n searchValue,\n onSearchChange,\n searchPlaceholder = \"Search...\",\n showSearch = true,\n actions,\n selectFilters,\n onSelectFiltersChange,\n dateFilters,\n onDateFiltersChange,\n showFilters = true,\n showClear = true,\n clearLabel = \"Clear filters\",\n onClearFilters,\n tone,\n className,\n}: CraftFilterBarProps) {\n const hasSelects = Boolean(selectFilters && selectFilters.length > 0);\n const hasDates = Boolean(dateFilters && dateFilters.length > 0);\n const hasFilters = showFilters && (hasSelects || hasDates);\n\n const updateSelectFilter = (index: number, value: string) => {\n if (!selectFilters || !onSelectFiltersChange) return;\n const next = selectFilters.map((filter, idx) =>\n idx === index ? { ...filter, value } : filter\n );\n onSelectFiltersChange(next);\n };\n\n const updateDateFilter = (\n index: number,\n key: \"from\" | \"to\",\n value: string\n ) => {\n if (!dateFilters || !onDateFiltersChange) return;\n const next = dateFilters.map((filter, idx) =>\n idx === index ? { ...filter, [key]: value } : filter\n );\n onDateFiltersChange(next);\n };\n\n return (\n <div\n className={cn(\n \"rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_12px_36px_rgba(0,0,0,0.2)] backdrop-blur-2xl\",\n className\n )}\n data-nc-theme={tone}\n >\n <div className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n {title && <h3 className=\"text-lg font-semibold\">{title}</h3>}\n {description && (\n <p className=\"text-sm text-[rgb(var(--nc-fg-muted))]\">\n {description}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-3\">\n {actions}\n {showClear && onClearFilters ? (\n <CraftButton type=\"button\" variant=\"ghost\" onClick={onClearFilters}>\n {clearLabel}\n </CraftButton>\n ) : null}\n </div>\n </div>\n\n {(showSearch || hasFilters) && (\n <div className=\"mt-4 grid gap-4\">\n {showSearch && (\n <CraftInput\n type=\"search\"\n placeholder={searchPlaceholder}\n value={searchValue ?? \"\"}\n onChange={(event) => onSearchChange?.(event.target.value)}\n tone={tone}\n />\n )}\n\n {hasFilters && (\n <div className=\"flex flex-wrap items-end gap-3\">\n {selectFilters?.map((filter, index) => (\n <label key={filter.key} className=\"grid gap-2 text-xs\">\n {filter.label ? (\n <span className=\"text-[rgb(var(--nc-fg-muted))]\">\n {filter.label}\n </span>\n ) : null}\n <CraftSelect\n value={filter.value}\n disabled={filter.disabled}\n onChange={(event) =>\n updateSelectFilter(index, event.target.value)\n }\n >\n {filter.placeholder ? (\n <option value=\"\">{filter.placeholder}</option>\n ) : null}\n {filter.options.map((option) => (\n <option key={String(option.value)} value={option.value}>\n {option.label}\n </option>\n ))}\n </CraftSelect>\n </label>\n ))}\n\n {dateFilters?.map((filter, index) => (\n <div key={filter.key} className=\"grid gap-2 text-xs\">\n {filter.label ? (\n <span className=\"text-[rgb(var(--nc-fg-muted))]\">\n {filter.label}\n </span>\n ) : null}\n <div className=\"flex items-center gap-2\">\n <CraftInput\n type=\"date\"\n value={filter.from ?? \"\"}\n onChange={(event) =>\n updateDateFilter(index, \"from\", event.target.value)\n }\n />\n <CraftInput\n type=\"date\"\n value={filter.to ?? \"\"}\n onChange={(event) =>\n updateDateFilter(index, \"to\", event.target.value)\n }\n />\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +1,8 @@
1
1
  "use strict";
2
2
  "use client";
3
- var __create = Object.create;
4
3
  var __defProp = Object.defineProperty;
5
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
7
  var __export = (target, all) => {
10
8
  for (var name in all)
@@ -18,81 +16,67 @@ var __copyProps = (to, from, except, desc) => {
18
16
  }
19
17
  return to;
20
18
  };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
20
  var craft_toast_exports = {};
31
21
  __export(craft_toast_exports, {
32
- CraftToastHost: () => CraftToastHost,
33
- useCraftToast: () => useCraftToast
22
+ CraftToaster: () => CraftToaster,
23
+ toast: () => import_toast2.toast,
24
+ useCraftToast: () => import_toast2.useCraftToast,
25
+ useToaster: () => import_toast2.useToaster
34
26
  });
35
27
  module.exports = __toCommonJS(craft_toast_exports);
36
28
  var import_jsx_runtime = require("react/jsx-runtime");
37
- var React = __toESM(require("react"), 1);
38
29
  var import_cn = require("../utils/cn");
30
+ var import_toast = require("@/lib/toast");
31
+ var import_toast2 = require("@/lib/toast");
39
32
  const variantClasses = {
40
33
  info: "border-[color:rgb(var(--nc-accent-1)/0.4)]",
41
34
  success: "border-emerald-400/40",
42
35
  warning: "border-amber-400/40",
43
36
  error: "border-rose-400/40"
44
37
  };
45
- function useCraftToast() {
46
- const [toasts, setToasts] = React.useState([]);
47
- const push = React.useCallback((toast) => {
48
- const id = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
49
- setToasts((prev) => [...prev, { ...toast, id }]);
50
- return id;
51
- }, []);
52
- const remove = React.useCallback((id) => {
53
- setToasts((prev) => prev.filter((toast) => toast.id !== id));
54
- }, []);
55
- return { toasts, push, remove };
56
- }
57
- function CraftToastHost({ toasts, onDismiss, tone }) {
38
+ function CraftToaster({ tone, className }) {
39
+ const toasts = (0, import_toast.useToaster)();
58
40
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
59
41
  "div",
60
42
  {
61
- className: "fixed right-6 top-6 z-50 flex w-full max-w-sm flex-col gap-3",
43
+ className: (0, import_cn.cn)(
44
+ "fixed right-6 top-6 z-50 flex w-full max-w-sm flex-col gap-3",
45
+ className
46
+ ),
62
47
  "data-nc-theme": tone,
63
- children: toasts.map((toast) => {
64
- var _a;
65
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
66
- "div",
67
- {
68
- className: (0, import_cn.cn)(
69
- "rounded-2xl border bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_15px_35px_rgba(0,0,0,0.35)] backdrop-blur-xl",
70
- variantClasses[(_a = toast.variant) != null ? _a : "info"]
71
- ),
72
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
73
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
74
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold", children: toast.title }),
75
- toast.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: toast.description })
76
- ] }),
77
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
- "button",
79
- {
80
- className: "text-[rgb(var(--nc-fg-soft))] hover:text-[rgb(var(--nc-fg))]",
81
- onClick: () => onDismiss(toast.id),
82
- children: "\u2715"
83
- }
84
- )
85
- ] })
86
- },
87
- toast.id
88
- );
89
- })
48
+ children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
49
+ "div",
50
+ {
51
+ className: (0, import_cn.cn)(
52
+ "rounded-2xl border bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_15px_35px_rgba(0,0,0,0.35)] backdrop-blur-xl",
53
+ variantClasses[(0, import_toast.normalizeVariant)(toast2.variant)]
54
+ ),
55
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
56
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "min-w-0 flex-1", children: toast2.custom ? toast2.custom : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
57
+ toast2.title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold", children: toast2.title }),
58
+ toast2.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: toast2.description })
59
+ ] }) }),
60
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
61
+ "button",
62
+ {
63
+ className: "text-[rgb(var(--nc-fg-soft))] hover:text-[rgb(var(--nc-fg))]",
64
+ onClick: () => (0, import_toast.removeToast)(toast2.id),
65
+ children: "\u2715"
66
+ }
67
+ )
68
+ ] })
69
+ },
70
+ toast2.id
71
+ ))
90
72
  }
91
73
  );
92
74
  }
93
75
  // Annotate the CommonJS export names for ESM import in node:
94
76
  0 && (module.exports = {
95
- CraftToastHost,
96
- useCraftToast
77
+ CraftToaster,
78
+ toast,
79
+ useCraftToast,
80
+ useToaster
97
81
  });
98
82
  //# sourceMappingURL=craft-toast.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/craft-toast.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\n\nexport type CraftToastVariant = \"info\" | \"success\" | \"warning\" | \"error\";\n\nexport type CraftToast = {\n id: string;\n title: string;\n description?: string;\n variant?: CraftToastVariant;\n};\n\nconst variantClasses: Record<CraftToastVariant, string> = {\n info: \"border-[color:rgb(var(--nc-accent-1)/0.4)]\",\n success: \"border-emerald-400/40\",\n warning: \"border-amber-400/40\",\n error: \"border-rose-400/40\",\n};\n\nexport function useCraftToast() {\n const [toasts, setToasts] = React.useState<CraftToast[]>([]);\n\n const push = React.useCallback((toast: Omit<CraftToast, \"id\">) => {\n const id = `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n setToasts((prev) => [...prev, { ...toast, id }]);\n return id;\n }, []);\n\n const remove = React.useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n return { toasts, push, remove };\n}\n\nexport type CraftToastHostProps = {\n toasts: CraftToast[];\n onDismiss: (id: string) => void;\n tone?: ThemeName;\n};\n\nexport function CraftToastHost({ toasts, onDismiss, tone }: CraftToastHostProps) {\n return (\n <div\n className=\"fixed right-6 top-6 z-50 flex w-full max-w-sm flex-col gap-3\"\n data-nc-theme={tone}\n >\n {toasts.map((toast) => (\n <div\n key={toast.id}\n className={cn(\n \"rounded-2xl border bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_15px_35px_rgba(0,0,0,0.35)] backdrop-blur-xl\",\n variantClasses[toast.variant ?? \"info\"]\n )}\n >\n <div className=\"flex items-start justify-between gap-4\">\n <div>\n <p className=\"text-sm font-semibold\">{toast.title}</p>\n {toast.description && (\n <p className=\"text-xs text-[rgb(var(--nc-fg-muted))]\">{toast.description}</p>\n )}\n </div>\n <button\n className=\"text-[rgb(var(--nc-fg-soft))] hover:text-[rgb(var(--nc-fg))]\"\n onClick={() => onDismiss(toast.id)}\n >\n ✕\n </button>\n </div>\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4DY;AA1DZ,YAAuB;AAEvB,gBAAmB;AAYnB,MAAM,iBAAoD;AAAA,EACxD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACT;AAEO,SAAS,gBAAgB;AAC9B,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAuB,CAAC,CAAC;AAE3D,QAAM,OAAO,MAAM,YAAY,CAAC,UAAkC;AAChE,UAAM,KAAK,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,cAAU,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC;AAC/C,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,SAAS,MAAM,YAAY,CAAC,OAAe;AAC/C,cAAU,CAAC,SAAS,KAAK,OAAO,CAAC,UAAU,MAAM,OAAO,EAAE,CAAC;AAAA,EAC7D,GAAG,CAAC,CAAC;AAEL,SAAO,EAAE,QAAQ,MAAM,OAAO;AAChC;AAQO,SAAS,eAAe,EAAE,QAAQ,WAAW,KAAK,GAAwB;AAC/E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,iBAAe;AAAA,MAEd,iBAAO,IAAI,CAAC,UAAO;AAnD1B;AAoDQ;AAAA,UAAC;AAAA;AAAA,YAEC,eAAW;AAAA,cACT;AAAA,cACA,gBAAe,WAAM,YAAN,YAAiB,MAAM;AAAA,YACxC;AAAA,YAEA,uDAAC,SAAI,WAAU,0CACb;AAAA,2DAAC,SACC;AAAA,4DAAC,OAAE,WAAU,yBAAyB,gBAAM,OAAM;AAAA,gBACjD,MAAM,eACL,4CAAC,OAAE,WAAU,0CAA0C,gBAAM,aAAY;AAAA,iBAE7E;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,SAAS,MAAM,UAAU,MAAM,EAAE;AAAA,kBAClC;AAAA;AAAA,cAED;AAAA,eACF;AAAA;AAAA,UAnBK,MAAM;AAAA,QAoBb;AAAA,OACD;AAAA;AAAA,EACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/craft-toast.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\nimport {\n normalizeVariant,\n removeToast,\n useToaster,\n type CraftToastCustomOptions,\n type CraftToastOptions,\n type CraftToastVariant,\n} from \"@/lib/toast\";\n\nexport { useCraftToast, useToaster, toast } from \"@/lib/toast\";\nexport type { CraftToastOptions, CraftToastCustomOptions, CraftToastVariant };\n\nconst variantClasses: Record<Exclude<CraftToastVariant, \"danger\">, string> = {\n info: \"border-[color:rgb(var(--nc-accent-1)/0.4)]\",\n success: \"border-emerald-400/40\",\n warning: \"border-amber-400/40\",\n error: \"border-rose-400/40\",\n};\n\nexport type CraftToasterProps = {\n tone?: ThemeName;\n className?: string;\n};\n\nexport function CraftToaster({ tone, className }: CraftToasterProps) {\n const toasts = useToaster();\n\n return (\n <div\n className={cn(\n \"fixed right-6 top-6 z-50 flex w-full max-w-sm flex-col gap-3\",\n className\n )}\n data-nc-theme={tone}\n >\n {toasts.map((toast) => (\n <div\n key={toast.id}\n className={cn(\n \"rounded-2xl border bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_15px_35px_rgba(0,0,0,0.35)] backdrop-blur-xl\",\n variantClasses[normalizeVariant(toast.variant)]\n )}\n >\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0 flex-1\">\n {toast.custom ? (\n toast.custom\n ) : (\n <>\n {toast.title && <p className=\"text-sm font-semibold\">{toast.title}</p>}\n {toast.description && (\n <p className=\"text-xs text-[rgb(var(--nc-fg-muted))]\">\n {toast.description}\n </p>\n )}\n </>\n )}\n </div>\n <button\n className=\"text-[rgb(var(--nc-fg-soft))] hover:text-[rgb(var(--nc-fg))]\"\n onClick={() => removeToast(toast.id)}\n >\n ✕\n </button>\n </div>\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsDgB;AAlDhB,gBAAmB;AAEnB,mBAOO;AAEP,IAAAA,gBAAiD;AAGjD,MAAM,iBAAuE;AAAA,EAC3E,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACT;AAOO,SAAS,aAAa,EAAE,MAAM,UAAU,GAAsB;AACnE,QAAM,aAAS,yBAAW;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,iBAAe;AAAA,MAEd,iBAAO,IAAI,CAACC,WACX;AAAA,QAAC;AAAA;AAAA,UAEC,eAAW;AAAA,YACT;AAAA,YACA,mBAAe,+BAAiBA,OAAM,OAAO,CAAC;AAAA,UAChD;AAAA,UAEA,uDAAC,SAAI,WAAU,0CACb;AAAA,wDAAC,SAAI,WAAU,kBACZ,UAAAA,OAAM,SACLA,OAAM,SAEN,4EACG;AAAA,cAAAA,OAAM,SAAS,4CAAC,OAAE,WAAU,yBAAyB,UAAAA,OAAM,OAAM;AAAA,cACjEA,OAAM,eACL,4CAAC,OAAE,WAAU,0CACV,UAAAA,OAAM,aACT;AAAA,eAEJ,GAEJ;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,SAAS,UAAM,0BAAYA,OAAM,EAAE;AAAA,gBACpC;AAAA;AAAA,YAED;AAAA,aACF;AAAA;AAAA,QA3BKA,OAAM;AAAA,MA4Bb,CACD;AAAA;AAAA,EACH;AAEJ;","names":["import_toast","toast"]}
@@ -1,24 +1,4 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ThemeName } from '../theme/theme-context.cjs';
1
+ import 'react/jsx-runtime';
2
+ import '../theme/theme-context.cjs';
3
+ export { a as CraftToastCustomOptions, b as CraftToastOptions, c as CraftToastVariant, d as CraftToaster, e as CraftToasterProps, t as toast, u as useCraftToast, f as useToaster } from '../craft-toast-C7rMmROV.cjs';
3
4
  import 'react';
4
-
5
- type CraftToastVariant = "info" | "success" | "warning" | "error";
6
- type CraftToast = {
7
- id: string;
8
- title: string;
9
- description?: string;
10
- variant?: CraftToastVariant;
11
- };
12
- declare function useCraftToast(): {
13
- toasts: CraftToast[];
14
- push: (toast: Omit<CraftToast, "id">) => string;
15
- remove: (id: string) => void;
16
- };
17
- type CraftToastHostProps = {
18
- toasts: CraftToast[];
19
- onDismiss: (id: string) => void;
20
- tone?: ThemeName;
21
- };
22
- declare function CraftToastHost({ toasts, onDismiss, tone }: CraftToastHostProps): react_jsx_runtime.JSX.Element;
23
-
24
- export { type CraftToast, CraftToastHost, type CraftToastHostProps, type CraftToastVariant, useCraftToast };
@@ -1,24 +1,4 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ThemeName } from '../theme/theme-context.js';
1
+ import 'react/jsx-runtime';
2
+ import '../theme/theme-context.js';
3
+ export { a as CraftToastCustomOptions, b as CraftToastOptions, c as CraftToastVariant, d as CraftToaster, e as CraftToasterProps, t as toast, u as useCraftToast, f as useToaster } from '../craft-toast-BcscwgO3.js';
3
4
  import 'react';
4
-
5
- type CraftToastVariant = "info" | "success" | "warning" | "error";
6
- type CraftToast = {
7
- id: string;
8
- title: string;
9
- description?: string;
10
- variant?: CraftToastVariant;
11
- };
12
- declare function useCraftToast(): {
13
- toasts: CraftToast[];
14
- push: (toast: Omit<CraftToast, "id">) => string;
15
- remove: (id: string) => void;
16
- };
17
- type CraftToastHostProps = {
18
- toasts: CraftToast[];
19
- onDismiss: (id: string) => void;
20
- tone?: ThemeName;
21
- };
22
- declare function CraftToastHost({ toasts, onDismiss, tone }: CraftToastHostProps): react_jsx_runtime.JSX.Element;
23
-
24
- export { type CraftToast, CraftToastHost, type CraftToastHostProps, type CraftToastVariant, useCraftToast };