@ttoss/components 2.10.2 → 2.11.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 (42) hide show
  1. package/dist/Accordion/index.d.ts +16 -0
  2. package/dist/DatePicker/index.d.ts +19 -0
  3. package/dist/Drawer/index.d.ts +12 -0
  4. package/dist/FileUploader/index.d.ts +55 -0
  5. package/dist/InstallPwa/index.d.ts +10 -0
  6. package/dist/JsonEditor/index.d.ts +2 -0
  7. package/dist/JsonView/index.d.ts +1 -0
  8. package/dist/List/index.d.ts +13 -0
  9. package/dist/Markdown/index.d.ts +11 -0
  10. package/dist/Menu/index.d.ts +11 -0
  11. package/dist/Modal/index.d.ts +10 -0
  12. package/dist/NavList/index.d.ts +55 -0
  13. package/dist/NotificationCard/index.d.ts +21 -0
  14. package/dist/NotificationsMenu/index.d.ts +21 -0
  15. package/dist/Search/index.d.ts +11 -0
  16. package/dist/SpotlightCard/index.d.ts +27 -0
  17. package/dist/Table/index.d.ts +16 -0
  18. package/dist/Tabs/index.d.ts +18 -0
  19. package/dist/Toast/index.d.ts +8 -0
  20. package/dist/esm/Accordion/index.js +49 -0
  21. package/dist/esm/DatePicker/index.js +2476 -0
  22. package/dist/esm/Drawer/index.js +59 -0
  23. package/dist/esm/FileUploader/index.js +401 -0
  24. package/dist/esm/InstallPwa/index.js +61 -0
  25. package/dist/esm/JsonEditor/index.js +6 -0
  26. package/dist/esm/JsonView/index.js +6 -0
  27. package/dist/esm/List/index.js +30 -0
  28. package/dist/esm/Markdown/index.js +23 -0
  29. package/dist/esm/Menu/index.js +131 -0
  30. package/dist/esm/Modal/index.js +65 -0
  31. package/dist/esm/NavList/index.js +246 -0
  32. package/dist/esm/NotificationCard/index.js +5 -0
  33. package/dist/esm/NotificationsMenu/index.js +205 -0
  34. package/dist/esm/Search/index.js +29 -0
  35. package/dist/esm/SpotlightCard/index.js +212 -0
  36. package/dist/esm/Table/index.js +63 -0
  37. package/dist/esm/Tabs/index.js +75 -0
  38. package/dist/esm/Toast/index.js +38 -0
  39. package/dist/esm/chunk-6LHIQ5YP.js +156 -0
  40. package/dist/esm/chunk-V4MHYKRI.js +7 -0
  41. package/dist/esm/chunk-WT55GXBD.js +2176 -0
  42. package/package.json +3 -3
@@ -0,0 +1,131 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import { Icon } from "../chunk-WT55GXBD.js";
3
+ import { __name } from "../chunk-V4MHYKRI.js";
4
+
5
+ // src/components/Menu/Menu.tsx
6
+ import { Box, Flex } from "@ttoss/ui";
7
+ import * as React from "react";
8
+ var Menu = /* @__PURE__ */__name(({
9
+ children,
10
+ sx,
11
+ menuIcon = "menu-open"
12
+ }) => {
13
+ const [isOpen, setIsOpen] = React.useState(false);
14
+ const [stylePos, setStylePos] = React.useState({});
15
+ const triggerRef = React.useRef(null);
16
+ const panelRef = React.useRef(null);
17
+ const toggle = /* @__PURE__ */__name(() => {
18
+ return setIsOpen(v => {
19
+ return !v;
20
+ });
21
+ }, "toggle");
22
+ React.useEffect(() => {
23
+ if (!isOpen) return;
24
+ const onDocClick = /* @__PURE__ */__name(e => {
25
+ const t = e.target;
26
+ if (panelRef.current && !panelRef.current.contains(t) && triggerRef.current && !triggerRef.current.contains(t)) {
27
+ setIsOpen(false);
28
+ }
29
+ }, "onDocClick");
30
+ document.addEventListener("mousedown", onDocClick);
31
+ return () => {
32
+ return document.removeEventListener("mousedown", onDocClick);
33
+ };
34
+ }, [isOpen]);
35
+ React.useLayoutEffect(() => {
36
+ if (!isOpen) return;
37
+ let rafId = 0;
38
+ const getWidth = /* @__PURE__ */__name(() => {
39
+ const w = sx?.width ?? sx?.maxWidth ?? sx?.minWidth;
40
+ return Array.isArray(w) ? w[w.length - 1] : w;
41
+ }, "getWidth");
42
+ const compute = /* @__PURE__ */__name(() => {
43
+ const trigger = triggerRef.current;
44
+ const panel2 = panelRef.current;
45
+ if (!trigger || !panel2) return;
46
+ const width = getWidth();
47
+ if (width) panel2.style.width = typeof width === "number" ? `${width}px` : String(width);
48
+ const tr = trigger.getBoundingClientRect();
49
+ const pr = panel2.getBoundingClientRect();
50
+ const vw = window.innerWidth,
51
+ vh = window.innerHeight,
52
+ m = 8;
53
+ if (pr.width === 0) {
54
+ rafId = requestAnimationFrame(compute);
55
+ return;
56
+ }
57
+ const left = Math.max(m, Math.min(tr.left + tr.width / 2 - pr.width / 2, vw - pr.width - m));
58
+ const top = vh - tr.bottom < pr.height + m ? Math.max(m, tr.top - pr.height - m) : tr.bottom + m;
59
+ setStylePos({
60
+ position: "fixed",
61
+ left: `${left}px`,
62
+ top: `${top}px`,
63
+ zIndex: 9999,
64
+ ...(width && {
65
+ width: typeof width === "number" ? `${width}px` : String(width)
66
+ })
67
+ });
68
+ }, "compute");
69
+ rafId = requestAnimationFrame(compute);
70
+ const onResizeScroll = /* @__PURE__ */__name(() => {
71
+ return rafId = requestAnimationFrame(compute);
72
+ }, "onResizeScroll");
73
+ window.addEventListener("resize", onResizeScroll);
74
+ window.addEventListener("scroll", onResizeScroll, true);
75
+ return () => {
76
+ cancelAnimationFrame(rafId);
77
+ window.removeEventListener("resize", onResizeScroll);
78
+ window.removeEventListener("scroll", onResizeScroll, true);
79
+ };
80
+ }, [isOpen, sx]);
81
+ const panel = isOpen ? /* @__PURE__ */React.createElement(Flex, {
82
+ ref: panelRef,
83
+ sx: {
84
+ width: ["280px", "320px"],
85
+ maxHeight: "400px",
86
+ flexDirection: "column",
87
+ gap: "3",
88
+ padding: "3",
89
+ backgroundColor: "input.background.muted.default",
90
+ borderRadius: "xl",
91
+ boxShadow: "xl",
92
+ overflowY: "auto",
93
+ border: "md",
94
+ borderColor: "display.border.muted.default",
95
+ ...sx
96
+ },
97
+ style: {
98
+ pointerEvents: "auto",
99
+ ...stylePos
100
+ }
101
+ }, /* @__PURE__ */React.createElement(Box, {
102
+ as: "nav"
103
+ }, children)) : null;
104
+ return /* @__PURE__ */React.createElement(Flex, {
105
+ sx: {
106
+ position: "relative",
107
+ display: "inline-block"
108
+ }
109
+ }, /* @__PURE__ */React.createElement(Box, {
110
+ sx: {
111
+ position: "relative"
112
+ }
113
+ }, /* @__PURE__ */React.createElement("button", {
114
+ ref: triggerRef,
115
+ onClick: toggle,
116
+ "aria-haspopup": "true",
117
+ "aria-expanded": isOpen,
118
+ style: {
119
+ background: "transparent",
120
+ border: 0,
121
+ padding: 4,
122
+ cursor: "pointer",
123
+ display: "inline-flex",
124
+ alignItems: "center",
125
+ justifyContent: "center"
126
+ }
127
+ }, /* @__PURE__ */React.createElement(Icon, {
128
+ icon: menuIcon
129
+ })), isOpen && panel));
130
+ }, "Menu");
131
+ export { Menu };
@@ -0,0 +1,65 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import * as React from 'react';
3
+ import { __name } from "../chunk-V4MHYKRI.js";
4
+
5
+ // src/components/Modal/Modal.tsx
6
+ import { css as transformStyleObject } from "@theme-ui/css";
7
+ import { useResponsiveValue, useTheme } from "@ttoss/ui";
8
+ import ReactModal from "react-modal";
9
+ ReactModal.defaultStyles = {
10
+ overlay: {},
11
+ content: {}
12
+ };
13
+ var Modal = /* @__PURE__ */__name(props => {
14
+ const {
15
+ theme
16
+ } = useTheme();
17
+ const space = theme.space;
18
+ const padding = useResponsiveValue([space?.["4"], space?.["5"], space?.["5"]]) || 0;
19
+ const style = {
20
+ overlay: transformStyleObject({
21
+ position: "fixed",
22
+ top: 0,
23
+ left: 0,
24
+ right: 0,
25
+ bottom: 0,
26
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
27
+ display: "flex",
28
+ justifyContent: "center",
29
+ alignItems: "center",
30
+ zIndex: "modal",
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ ...props.style?.overlay
33
+ })(theme),
34
+ content: transformStyleObject({
35
+ /**
36
+ * Theme
37
+ */
38
+ backgroundColor: "surface",
39
+ padding,
40
+ border: "default",
41
+ borderColor: "surface",
42
+ borderRadius: "default",
43
+ /**
44
+ * General
45
+ */
46
+ WebkitOverflowScrolling: "touch",
47
+ overflow: "auto",
48
+ position: "relative",
49
+ top: "0px",
50
+ left: "0px",
51
+ right: "0px",
52
+ bottom: "0px",
53
+ maxHeight: "90%",
54
+ maxWidth: "90%",
55
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
+ ...props.style?.content
57
+ })(theme)
58
+ };
59
+ return /* @__PURE__ */React.createElement(ReactModal, {
60
+ ...props,
61
+ style
62
+ });
63
+ }, "Modal");
64
+ Modal.setAppElement = ReactModal.setAppElement;
65
+ export { Modal };
@@ -0,0 +1,246 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import { Icon } from "../chunk-WT55GXBD.js";
3
+ import { __name } from "../chunk-V4MHYKRI.js";
4
+
5
+ // src/components/NavList/NavList.tsx
6
+ import { Divider, Flex, Link, Text } from "@ttoss/ui";
7
+ import * as React from "react";
8
+ var getVariantStyles = /* @__PURE__ */__name(variant => {
9
+ switch (variant) {
10
+ case "sidebar":
11
+ return {
12
+ container: {
13
+ flexDirection: "column",
14
+ gap: "1",
15
+ width: "full"
16
+ },
17
+ item: {
18
+ backgroundColor: "transparent",
19
+ padding: "3",
20
+ borderRadius: "none",
21
+ fontSize: "md",
22
+ transition: "background-color 0.15s ease",
23
+ "&:hover": {
24
+ backgroundColor: "navigation.background.muted.hover",
25
+ textDecoration: "none"
26
+ }
27
+ },
28
+ activeItem: {
29
+ backgroundColor: "navigation.background.muted.default",
30
+ borderLeft: "4px solid",
31
+ borderColor: "navigation.border.primary.default",
32
+ paddingLeft: "calc(0.75rem - 4px)"
33
+ },
34
+ icon: {
35
+ size: 20
36
+ },
37
+ groupLabel: {
38
+ fontSize: "xs",
39
+ fontWeight: "bold",
40
+ color: "navigation.text.muted.default",
41
+ textTransform: "uppercase",
42
+ marginBottom: "2",
43
+ marginTop: "4"
44
+ }
45
+ };
46
+ case "menu":
47
+ return {
48
+ container: {
49
+ flexDirection: "column",
50
+ gap: "1",
51
+ width: "full"
52
+ },
53
+ item: {
54
+ backgroundColor: "transparent",
55
+ borderRadius: "md",
56
+ padding: "2",
57
+ fontSize: "md",
58
+ transition: "all 0.2s ease",
59
+ "&:hover": {
60
+ backgroundColor: "navigation.background.muted.hover",
61
+ transform: "translateX(4px)",
62
+ textDecoration: "none"
63
+ }
64
+ },
65
+ activeItem: {
66
+ backgroundColor: "navigation.background.muted.default",
67
+ fontWeight: "bold"
68
+ },
69
+ icon: {
70
+ size: 18
71
+ },
72
+ groupLabel: {
73
+ fontSize: "sm",
74
+ fontWeight: "semibold",
75
+ color: "display.text.secondary.default",
76
+ marginBottom: "2",
77
+ marginTop: "3"
78
+ }
79
+ };
80
+ case "dropdown":
81
+ return {
82
+ container: {
83
+ flexDirection: "column",
84
+ gap: "1",
85
+ width: "full"
86
+ },
87
+ item: {
88
+ backgroundColor: "transparent",
89
+ padding: "2",
90
+ fontSize: "sm",
91
+ borderBottom: "sm",
92
+ borderColor: "display.border.muted.default",
93
+ transition: "background-color 0.1s ease",
94
+ "&:hover": {
95
+ backgroundColor: "navigation.background.muted.hover",
96
+ textDecoration: "none"
97
+ }
98
+ },
99
+ activeItem: {
100
+ backgroundColor: "navigation.background.muted.default",
101
+ fontWeight: "semibold"
102
+ },
103
+ icon: {
104
+ size: 16
105
+ },
106
+ groupLabel: {
107
+ fontSize: "xs",
108
+ fontWeight: "medium",
109
+ color: "display.text.secondary.default",
110
+ marginBottom: "1",
111
+ marginTop: "2",
112
+ paddingX: "2"
113
+ }
114
+ };
115
+ default:
116
+ return getVariantStyles("menu");
117
+ }
118
+ }, "getVariantStyles");
119
+ var NavListItemComponent = /* @__PURE__ */__name(({
120
+ item,
121
+ onItemClick,
122
+ variantStyles,
123
+ iconSize,
124
+ LinkComponent = Link,
125
+ showDivider = false
126
+ }) => {
127
+ const handleClick = /* @__PURE__ */__name(event => {
128
+ if (item.disabled) {
129
+ event.preventDefault();
130
+ return;
131
+ }
132
+ item.onClick?.(event);
133
+ onItemClick?.(item);
134
+ }, "handleClick");
135
+ const itemStyles = {
136
+ ...variantStyles.item,
137
+ ...(item.active ? variantStyles.activeItem : {}),
138
+ ...(item.disabled ? {
139
+ opacity: 0.5,
140
+ cursor: "not-allowed",
141
+ pointerEvents: "none"
142
+ } : {})
143
+ };
144
+ const isDefaultLink = LinkComponent === Link;
145
+ const linkContent = /* @__PURE__ */React.createElement(Flex, {
146
+ sx: {
147
+ alignItems: "center",
148
+ gap: "2",
149
+ color: "navigation.text.primary.default"
150
+ }
151
+ }, item.icon && /* @__PURE__ */React.createElement(Icon, {
152
+ icon: item.icon,
153
+ width: iconSize ?? variantStyles.icon.size,
154
+ height: iconSize ?? variantStyles.icon.size
155
+ }), /* @__PURE__ */React.createElement(Text, null, item.label));
156
+ return /* @__PURE__ */React.createElement(React.Fragment, null, isDefaultLink ? /* @__PURE__ */React.createElement(LinkComponent, {
157
+ href: item.href,
158
+ onClick: handleClick,
159
+ sx: itemStyles,
160
+ "aria-disabled": item.disabled,
161
+ "aria-current": item.active ? "page" : void 0,
162
+ quiet: true
163
+ }, linkContent) : /* @__PURE__ */React.createElement(Link, {
164
+ as: LinkComponent,
165
+ href: item.href,
166
+ onClick: handleClick,
167
+ sx: itemStyles,
168
+ "aria-disabled": item.disabled,
169
+ "aria-current": item.active ? "page" : void 0,
170
+ quiet: true
171
+ }, linkContent), showDivider && /* @__PURE__ */React.createElement(Divider, {
172
+ sx: {
173
+ marginY: "2"
174
+ }
175
+ }));
176
+ }, "NavListItemComponent");
177
+ var NavList = /* @__PURE__ */__name(({
178
+ items = [],
179
+ groups = [],
180
+ variant = "menu",
181
+ onItemClick,
182
+ sx,
183
+ iconSize,
184
+ LinkComponent
185
+ }) => {
186
+ const variantStyles = getVariantStyles(variant);
187
+ const processedGroups = React.useMemo(() => {
188
+ if (groups.length > 0) {
189
+ return groups;
190
+ }
191
+ if (items.length > 0) {
192
+ const groupedItems = items.reduce((acc, item) => {
193
+ const groupKey = item.group || "__ungrouped__";
194
+ if (!acc[groupKey]) {
195
+ acc[groupKey] = [];
196
+ }
197
+ acc[groupKey].push(item);
198
+ return acc;
199
+ }, {});
200
+ return Object.entries(groupedItems).map(([key, groupItems]) => {
201
+ return {
202
+ id: key,
203
+ label: key === "__ungrouped__" ? void 0 : key,
204
+ items: groupItems,
205
+ divider: false
206
+ };
207
+ });
208
+ }
209
+ return [];
210
+ }, [items, groups]);
211
+ return /* @__PURE__ */React.createElement(Flex, {
212
+ as: "nav",
213
+ sx: {
214
+ ...variantStyles.container,
215
+ ...sx
216
+ },
217
+ role: "navigation"
218
+ }, processedGroups.map((group, groupIndex) => {
219
+ return /* @__PURE__ */React.createElement(React.Fragment, {
220
+ key: group.id || `group-${groupIndex}`
221
+ }, group.label && /* @__PURE__ */React.createElement(Text, {
222
+ sx: variantStyles.groupLabel,
223
+ as: "div",
224
+ role: "heading"
225
+ }, group.label), /* @__PURE__ */React.createElement(Flex, {
226
+ sx: {
227
+ flexDirection: "column",
228
+ gap: variantStyles.container.gap
229
+ }
230
+ }, group.items.map((item, itemIndex) => {
231
+ const isLastItem = itemIndex === group.items.length - 1;
232
+ const showDivider = item.divider || isLastItem && group.divider;
233
+ return /* @__PURE__ */React.createElement(NavListItemComponent, {
234
+ key: item.id || `${group.id}-item-${itemIndex}`,
235
+ item,
236
+ onItemClick,
237
+ variantStyles,
238
+ iconSize,
239
+ LinkComponent,
240
+ showDivider
241
+ });
242
+ })));
243
+ }));
244
+ }, "NavList");
245
+ NavList.displayName = "NavList";
246
+ export { NavList };
@@ -0,0 +1,5 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import { NotificationCard } from "../chunk-6LHIQ5YP.js";
3
+ import "../chunk-WT55GXBD.js";
4
+ import "../chunk-V4MHYKRI.js";
5
+ export { NotificationCard };
@@ -0,0 +1,205 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import { NotificationCard } from "../chunk-6LHIQ5YP.js";
3
+ import { Icon } from "../chunk-WT55GXBD.js";
4
+ import { __name } from "../chunk-V4MHYKRI.js";
5
+
6
+ // src/components/NotificationsMenu/NotificationsMenu.tsx
7
+ import { Box, Button, Card, Flex, IconButton, Text } from "@ttoss/ui";
8
+ import * as React from "react";
9
+ var NotificationsMenu = /* @__PURE__ */__name(({
10
+ notifications,
11
+ defaultOpen = false,
12
+ hasMore = false,
13
+ onLoadMore,
14
+ onOpenChange,
15
+ count,
16
+ onClose,
17
+ onClearAll
18
+ }) => {
19
+ const [isOpen, setIsOpen] = React.useState(defaultOpen);
20
+ const [openToLeft, setOpenToLeft] = React.useState(false);
21
+ const buttonRef = React.useRef(null);
22
+ const containerRef = React.useRef(null);
23
+ const loadMoreRef = React.useRef(null);
24
+ const [showCount, setShowCount] = React.useState(true);
25
+ const togglePanel = /* @__PURE__ */__name(() => {
26
+ setIsOpen(prev => {
27
+ const next = !prev;
28
+ onOpenChange?.(next);
29
+ return next;
30
+ });
31
+ }, "togglePanel");
32
+ React.useEffect(() => {
33
+ if (!isOpen || !buttonRef.current) return;
34
+ const rect = buttonRef.current.getBoundingClientRect();
35
+ const spaceRight = window.innerWidth - rect.right;
36
+ const spaceLeft = rect.left;
37
+ setShowCount(false);
38
+ setOpenToLeft(spaceRight < 500 && spaceLeft > spaceRight);
39
+ }, [isOpen]);
40
+ React.useEffect(() => {
41
+ if (!hasMore || !onLoadMore || !loadMoreRef.current) return;
42
+ const observer = new IntersectionObserver(entries => {
43
+ if (entries[0].isIntersecting) {
44
+ onLoadMore();
45
+ }
46
+ }, {
47
+ root: null,
48
+ rootMargin: "0px",
49
+ threshold: 1
50
+ });
51
+ observer.observe(loadMoreRef.current);
52
+ return () => {
53
+ if (loadMoreRef.current) {
54
+ observer.unobserve(loadMoreRef.current);
55
+ }
56
+ };
57
+ }, [hasMore, onLoadMore, notifications.length]);
58
+ React.useEffect(() => {
59
+ if (!isOpen) return;
60
+ const handleClickOutside = /* @__PURE__ */__name(event => {
61
+ if (containerRef.current && !containerRef.current.contains(event.target) && buttonRef.current && !buttonRef.current.contains(event.target)) {
62
+ setIsOpen(false);
63
+ onOpenChange?.(false);
64
+ onClose?.();
65
+ }
66
+ }, "handleClickOutside");
67
+ document.addEventListener("mousedown", handleClickOutside);
68
+ return () => {
69
+ document.removeEventListener("mousedown", handleClickOutside);
70
+ };
71
+ }, [isOpen, onOpenChange, onClose]);
72
+ return /* @__PURE__ */React.createElement(Flex, {
73
+ sx: {
74
+ position: "relative",
75
+ justifyContent: "flex-start"
76
+ }
77
+ }, /* @__PURE__ */React.createElement(Box, {
78
+ sx: {
79
+ position: "relative"
80
+ }
81
+ }, /* @__PURE__ */React.createElement(IconButton, {
82
+ ref: buttonRef,
83
+ variant: "ghost",
84
+ sx: {
85
+ position: "relative",
86
+ borderRadius: "full",
87
+ padding: 1,
88
+ transition: "background-color 0.3s ease",
89
+ "&:hover": {
90
+ backgroundColor: "action.background.muted.default"
91
+ }
92
+ },
93
+ onClick: togglePanel
94
+ }, /* @__PURE__ */React.createElement(Box, {
95
+ sx: {
96
+ color: "display.text.muted.default"
97
+ }
98
+ }, /* @__PURE__ */React.createElement(Icon, {
99
+ icon: "mdi:bell-outline",
100
+ width: 22,
101
+ height: 22
102
+ })), count > 0 && showCount && /* @__PURE__ */React.createElement(Box, {
103
+ sx: {
104
+ position: "absolute",
105
+ top: "-2px",
106
+ right: "-2px",
107
+ minWidth: "14px",
108
+ height: "14px",
109
+ paddingX: 1,
110
+ borderRadius: "full",
111
+ backgroundColor: "action.background.negative.default",
112
+ color: "feedback.text.primary.default",
113
+ fontSize: "10px",
114
+ fontWeight: "bold",
115
+ display: "flex",
116
+ alignItems: "center",
117
+ justifyContent: "center",
118
+ lineHeight: 1
119
+ }
120
+ }, count > 99 ? "99+" : count)), isOpen && /* @__PURE__ */React.createElement("div", {
121
+ ref: containerRef
122
+ }, /* @__PURE__ */React.createElement(Card, {
123
+ sx: {
124
+ position: "absolute",
125
+ top: "calc(100% + 8px)",
126
+ left: openToLeft ? "auto" : 0,
127
+ right: openToLeft ? 0 : "auto",
128
+ width: notifications.length === 0 ? ["60vw", "300px"] : ["90vw", "600px"],
129
+ maxHeight: "550px",
130
+ overflowY: "auto",
131
+ zIndex: "modal",
132
+ padding: 0,
133
+ boxShadow: "xl",
134
+ borderRadius: "2xl",
135
+ backgroundColor: "display.background.secondary.default"
136
+ }
137
+ }, /* @__PURE__ */React.createElement(Box, {
138
+ sx: {
139
+ width: "100%"
140
+ }
141
+ }, /* @__PURE__ */React.createElement(Flex, {
142
+ sx: {
143
+ flexDirection: "column",
144
+ gap: 4
145
+ }
146
+ }, notifications.length > 0 && onClearAll && /* @__PURE__ */React.createElement(Flex, {
147
+ sx: {
148
+ justifyContent: "flex-end",
149
+ p: 2,
150
+ marginBottom: -2
151
+ }
152
+ }, /* @__PURE__ */React.createElement(Button, {
153
+ variant: "ghost",
154
+ sx: {
155
+ borderRadius: "md",
156
+ padding: 1,
157
+ paddingLeft: 10,
158
+ paddingRight: 10,
159
+ fontSize: "md",
160
+ color: "display.text.muted.default",
161
+ border: "1px solid",
162
+ borderColor: "display.border.default",
163
+ transition: "all 0.2s ease",
164
+ display: "flex",
165
+ alignItems: "center",
166
+ "&:hover": {
167
+ backgroundColor: "action.background.muted.default",
168
+ color: "display.text.default",
169
+ borderColor: "action.border.default"
170
+ }
171
+ },
172
+ onClick: onClearAll
173
+ }, /* @__PURE__ */React.createElement(Icon, {
174
+ icon: "delete",
175
+ width: 16,
176
+ height: 16
177
+ }), /* @__PURE__ */React.createElement(Text, {
178
+ sx: {
179
+ ml: -1,
180
+ marginTop: -0.4,
181
+ fontSize: "sm"
182
+ }
183
+ }, "Limpar Tudo"))), notifications.length === 0 ? /* @__PURE__ */React.createElement(Text, {
184
+ sx: {
185
+ color: "display.text.muted.default",
186
+ textAlign: "center",
187
+ p: 4
188
+ }
189
+ }, "Nenhuma notifica\xE7\xE3o") : notifications.map(notification => {
190
+ return /* @__PURE__ */React.createElement(NotificationCard, {
191
+ key: notification.id,
192
+ ...notification,
193
+ onClose: /* @__PURE__ */__name(() => {
194
+ notification.onClose?.();
195
+ onClose?.();
196
+ }, "onClose")
197
+ });
198
+ }), hasMore && /* @__PURE__ */React.createElement("div", {
199
+ ref: loadMoreRef,
200
+ style: {
201
+ height: 1
202
+ }
203
+ })))))));
204
+ }, "NotificationsMenu");
205
+ export { NotificationsMenu };
@@ -0,0 +1,29 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import { __name } from "../chunk-V4MHYKRI.js";
3
+
4
+ // src/components/Search/Search.tsx
5
+ import * as React from "react";
6
+ import { Input } from "@ttoss/ui";
7
+ import { useDebounce } from "@ttoss/react-hooks";
8
+ var Search = /* @__PURE__ */__name(({
9
+ value,
10
+ defaultValue,
11
+ loading,
12
+ onChange,
13
+ ...props
14
+ }) => {
15
+ const [text, setText] = React.useState(value ?? defaultValue);
16
+ const debouncedValue = useDebounce(text, 500);
17
+ React.useEffect(() => {
18
+ onChange(debouncedValue);
19
+ }, [debouncedValue, onChange]);
20
+ return /* @__PURE__ */React.createElement(Input, {
21
+ leadingIcon: loading ? "loading" : "search",
22
+ defaultValue: text,
23
+ onChange: /* @__PURE__ */__name(e => {
24
+ return setText(e.target.value);
25
+ }, "onChange"),
26
+ ...props
27
+ });
28
+ }, "Search");
29
+ export { Search };