@phpsoftbox/react-softbox 0.1.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 (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +271 -0
  3. package/dist/components/Alert/Alert.d.ts +11 -0
  4. package/dist/components/Alert/Alert.js +15 -0
  5. package/dist/components/Alert/Alert.js.map +1 -0
  6. package/dist/components/Alert/Alert.module.css +73 -0
  7. package/dist/components/Badge/Badge.d.ts +8 -0
  8. package/dist/components/Badge/Badge.js +15 -0
  9. package/dist/components/Badge/Badge.js.map +1 -0
  10. package/dist/components/Badge/Badge.module.css +47 -0
  11. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +24 -0
  12. package/dist/components/Breadcrumbs/Breadcrumbs.js +15 -0
  13. package/dist/components/Breadcrumbs/Breadcrumbs.js.map +1 -0
  14. package/dist/components/Breadcrumbs/Breadcrumbs.module.css +55 -0
  15. package/dist/components/Button/Button.d.ts +10 -0
  16. package/dist/components/Button/Button.js +37 -0
  17. package/dist/components/Button/Button.js.map +1 -0
  18. package/dist/components/Button/Button.module.css +130 -0
  19. package/dist/components/Card/Card.d.ts +15 -0
  20. package/dist/components/Card/Card.js +26 -0
  21. package/dist/components/Card/Card.js.map +1 -0
  22. package/dist/components/Card/Card.module.css +55 -0
  23. package/dist/components/CollapseButton/CollapseButton.d.ts +9 -0
  24. package/dist/components/CollapseButton/CollapseButton.js +11 -0
  25. package/dist/components/CollapseButton/CollapseButton.js.map +1 -0
  26. package/dist/components/CollapseButton/CollapseButton.module.css +57 -0
  27. package/dist/components/Drawer/Drawer.d.ts +19 -0
  28. package/dist/components/Drawer/Drawer.js +42 -0
  29. package/dist/components/Drawer/Drawer.js.map +1 -0
  30. package/dist/components/Drawer/Drawer.module.css +104 -0
  31. package/dist/components/Flex/Flex.module.css +11 -0
  32. package/dist/components/Flex/Row.d.ts +9 -0
  33. package/dist/components/Flex/Row.js +14 -0
  34. package/dist/components/Flex/Row.js.map +1 -0
  35. package/dist/components/Flex/Stack.d.ts +8 -0
  36. package/dist/components/Flex/Stack.js +13 -0
  37. package/dist/components/Flex/Stack.js.map +1 -0
  38. package/dist/components/Grid/Grid.d.ts +11 -0
  39. package/dist/components/Grid/Grid.js +16 -0
  40. package/dist/components/Grid/Grid.js.map +1 -0
  41. package/dist/components/Grid/Grid.module.css +32 -0
  42. package/dist/components/Input/DatePicker.d.ts +6 -0
  43. package/dist/components/Input/DatePicker.js +6 -0
  44. package/dist/components/Input/DatePicker.js.map +1 -0
  45. package/dist/components/Input/DateRangePicker.d.ts +16 -0
  46. package/dist/components/Input/DateRangePicker.js +16 -0
  47. package/dist/components/Input/DateRangePicker.js.map +1 -0
  48. package/dist/components/Input/Field.d.ts +5 -0
  49. package/dist/components/Input/Field.js +25 -0
  50. package/dist/components/Input/Field.js.map +1 -0
  51. package/dist/components/Input/FloatLabel/FloatLabel.d.ts +9 -0
  52. package/dist/components/Input/FloatLabel/FloatLabel.js +22 -0
  53. package/dist/components/Input/FloatLabel/FloatLabel.js.map +1 -0
  54. package/dist/components/Input/FloatLabel/FloatLabel.module.css +41 -0
  55. package/dist/components/Input/FormField/FormField.d.ts +29 -0
  56. package/dist/components/Input/FormField/FormField.js +60 -0
  57. package/dist/components/Input/FormField/FormField.js.map +1 -0
  58. package/dist/components/Input/FormField/FormField.module.css +30 -0
  59. package/dist/components/Input/Input.d.ts +59 -0
  60. package/dist/components/Input/Input.js +34 -0
  61. package/dist/components/Input/Input.js.map +1 -0
  62. package/dist/components/Input/Input.module.css +31 -0
  63. package/dist/components/Input/InputGroup.d.ts +11 -0
  64. package/dist/components/Input/InputGroup.js +25 -0
  65. package/dist/components/Input/InputGroup.js.map +1 -0
  66. package/dist/components/Input/InputGroup.module.css +38 -0
  67. package/dist/components/Input/MaskedInput.d.ts +9 -0
  68. package/dist/components/Input/MaskedInput.js +82 -0
  69. package/dist/components/Input/MaskedInput.js.map +1 -0
  70. package/dist/components/Input/NumberInput.d.ts +10 -0
  71. package/dist/components/Input/NumberInput.js +44 -0
  72. package/dist/components/Input/NumberInput.js.map +1 -0
  73. package/dist/components/Input/Radio/Radio.d.ts +7 -0
  74. package/dist/components/Input/Radio/Radio.js +9 -0
  75. package/dist/components/Input/Radio/Radio.js.map +1 -0
  76. package/dist/components/Input/Radio/Radio.module.css +83 -0
  77. package/dist/components/Input/Select/Select.d.ts +38 -0
  78. package/dist/components/Input/Select/Select.js +200 -0
  79. package/dist/components/Input/Select/Select.js.map +1 -0
  80. package/dist/components/Input/Select/Select.module.css +194 -0
  81. package/dist/components/Input/Switch/Switch.d.ts +6 -0
  82. package/dist/components/Input/Switch/Switch.js +9 -0
  83. package/dist/components/Input/Switch/Switch.js.map +1 -0
  84. package/dist/components/Input/Switch/Switch.module.css +62 -0
  85. package/dist/components/Input/Textarea/Textarea.d.ts +6 -0
  86. package/dist/components/Input/Textarea/Textarea.js +21 -0
  87. package/dist/components/Input/Textarea/Textarea.js.map +1 -0
  88. package/dist/components/Input/Textarea/Textarea.module.css +39 -0
  89. package/dist/components/Input/TimePicker.d.ts +4 -0
  90. package/dist/components/Input/TimePicker.js +6 -0
  91. package/dist/components/Input/TimePicker.js.map +1 -0
  92. package/dist/components/Menu/Dropdown.d.ts +13 -0
  93. package/dist/components/Menu/Dropdown.js +58 -0
  94. package/dist/components/Menu/Dropdown.js.map +1 -0
  95. package/dist/components/Menu/Menu.d.ts +31 -0
  96. package/dist/components/Menu/Menu.js +161 -0
  97. package/dist/components/Menu/Menu.js.map +1 -0
  98. package/dist/components/Menu/Menu.module.css +240 -0
  99. package/dist/components/Modal/Modal.d.ts +12 -0
  100. package/dist/components/Modal/Modal.js +31 -0
  101. package/dist/components/Modal/Modal.js.map +1 -0
  102. package/dist/components/Modal/Modal.module.css +90 -0
  103. package/dist/components/Notifier/Notifier.d.ts +17 -0
  104. package/dist/components/Notifier/Notifier.js +210 -0
  105. package/dist/components/Notifier/Notifier.js.map +1 -0
  106. package/dist/components/Notifier/Notifier.module.css +182 -0
  107. package/dist/components/Pagination/Pagination.d.ts +28 -0
  108. package/dist/components/Pagination/Pagination.js +70 -0
  109. package/dist/components/Pagination/Pagination.js.map +1 -0
  110. package/dist/components/Pagination/Pagination.module.css +93 -0
  111. package/dist/components/Progress/Progress.d.ts +16 -0
  112. package/dist/components/Progress/Progress.js +32 -0
  113. package/dist/components/Progress/Progress.js.map +1 -0
  114. package/dist/components/Progress/Progress.module.css +110 -0
  115. package/dist/components/Tabs/Tabs.d.ts +20 -0
  116. package/dist/components/Tabs/Tabs.js +115 -0
  117. package/dist/components/Tabs/Tabs.js.map +1 -0
  118. package/dist/components/Tabs/Tabs.module.css +101 -0
  119. package/dist/components/Typography/Heading.d.ts +13 -0
  120. package/dist/components/Typography/Heading.js +38 -0
  121. package/dist/components/Typography/Heading.js.map +1 -0
  122. package/dist/components/Typography/Text.d.ts +20 -0
  123. package/dist/components/Typography/Text.js +43 -0
  124. package/dist/components/Typography/Text.js.map +1 -0
  125. package/dist/components/Typography/Typography.module.css +132 -0
  126. package/dist/foundations/index.css +3 -0
  127. package/dist/foundations/layout.css +78 -0
  128. package/dist/foundations/tokens.css +236 -0
  129. package/dist/foundations/typography.css +49 -0
  130. package/dist/hooks/useDropdownPosition.d.ts +14 -0
  131. package/dist/hooks/useDropdownPosition.js +61 -0
  132. package/dist/hooks/useDropdownPosition.js.map +1 -0
  133. package/dist/hooks/useMediaQuery.d.ts +1 -0
  134. package/dist/hooks/useMediaQuery.js +33 -0
  135. package/dist/hooks/useMediaQuery.js.map +1 -0
  136. package/dist/index.d.ts +30 -0
  137. package/dist/index.js +29 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/theme.d.ts +12 -0
  140. package/dist/theme.js +133 -0
  141. package/dist/theme.js.map +1 -0
  142. package/dist/types.d.ts +1 -0
  143. package/dist/types.js +2 -0
  144. package/dist/types.js.map +1 -0
  145. package/docs/README.md +40 -0
  146. package/docs/breadcrumbs.md +47 -0
  147. package/docs/card.md +18 -0
  148. package/docs/feedback.md +38 -0
  149. package/docs/forms.md +166 -0
  150. package/docs/layout.md +39 -0
  151. package/docs/navigation.md +80 -0
  152. package/docs/overlays.md +31 -0
  153. package/docs/pagination.md +50 -0
  154. package/docs/progress.md +18 -0
  155. package/docs/tabs.md +34 -0
  156. package/docs/theme.md +49 -0
  157. package/docs/typography.md +26 -0
  158. package/package.json +49 -0
@@ -0,0 +1,240 @@
1
+ .menu {
2
+ display: flex;
3
+ gap: 6px;
4
+ }
5
+
6
+ .vertical {
7
+ flex-direction: column;
8
+ align-items: stretch;
9
+ }
10
+
11
+ .horizontal {
12
+ flex-direction: row;
13
+ align-items: center;
14
+ }
15
+
16
+ .item {
17
+ display: inline-flex;
18
+ align-items: center;
19
+ gap: 10px;
20
+ padding: 10px 12px;
21
+ border-radius: 10px;
22
+ border: 1px solid transparent;
23
+ background: transparent;
24
+ color: var(--color-text);
25
+ cursor: pointer;
26
+ font-weight: 600;
27
+ font-size: 14px;
28
+ transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
29
+ }
30
+
31
+ .item:hover {
32
+ border-color: rgba(79, 230, 163, 0.35);
33
+ background: rgba(79, 230, 163, 0.08);
34
+ }
35
+
36
+ .item:focus-visible {
37
+ outline: none;
38
+ border-color: rgba(20, 201, 214, 0.8);
39
+ box-shadow: 0 0 0 3px rgba(20, 201, 214, 0.2);
40
+ }
41
+
42
+ .active {
43
+ border-color: rgba(20, 201, 214, 0.6);
44
+ color: var(--color-teal);
45
+ background: rgba(20, 201, 214, 0.12);
46
+ }
47
+
48
+ .disabled {
49
+ opacity: 0.5;
50
+ cursor: not-allowed;
51
+ }
52
+
53
+ .divider {
54
+ height: 1px;
55
+ background: var(--color-divider);
56
+ margin: 6px 0;
57
+ }
58
+
59
+ .horizontal .divider {
60
+ width: 1px;
61
+ height: 22px;
62
+ margin: 0 6px;
63
+ }
64
+
65
+ .dropdownMenu .divider {
66
+ width: 100%;
67
+ height: 1px;
68
+ margin: 6px 0;
69
+ }
70
+
71
+ .group {
72
+ display: flex;
73
+ flex-direction: column;
74
+ gap: 8px;
75
+ }
76
+
77
+ .dropdownItem {
78
+ position: relative;
79
+ display: inline-flex;
80
+ align-items: center;
81
+ }
82
+
83
+ .groupButton {
84
+ justify-content: space-between;
85
+ }
86
+
87
+ .chevron {
88
+ width: 8px;
89
+ height: 8px;
90
+ border-right: 2px solid currentColor;
91
+ border-bottom: 2px solid currentColor;
92
+ transform: rotate(45deg);
93
+ transition: transform 0.2s ease;
94
+ margin-left: auto;
95
+ }
96
+
97
+ .chevronOpen {
98
+ transform: rotate(225deg);
99
+ }
100
+
101
+ .submenu {
102
+ margin-left: 14px;
103
+ max-height: 0;
104
+ opacity: 0;
105
+ transform: translateY(-4px);
106
+ overflow: hidden;
107
+ pointer-events: none;
108
+ visibility: hidden;
109
+ border-left: 0;
110
+ padding-left: 0;
111
+ transition: max-height 0.22s ease, opacity 0.22s ease, transform 0.22s ease, padding-left 0.22s ease,
112
+ border-color 0.22s ease;
113
+ }
114
+
115
+ .submenuOpen {
116
+ max-height: 560px;
117
+ opacity: 1;
118
+ transform: translateY(0);
119
+ pointer-events: auto;
120
+ visibility: visible;
121
+ border-left: 1px dashed var(--color-divider);
122
+ padding-left: 12px;
123
+ }
124
+
125
+ .submenuList {
126
+ gap: 4px;
127
+ }
128
+
129
+ .icon {
130
+ width: 16px;
131
+ height: 16px;
132
+ display: inline-flex;
133
+ align-items: center;
134
+ justify-content: center;
135
+ }
136
+
137
+ .dropdown {
138
+ position: relative;
139
+ display: inline-flex;
140
+ align-items: center;
141
+ }
142
+
143
+ .dropdownFull {
144
+ width: 100%;
145
+ }
146
+
147
+ .dropdownAnchor {
148
+ display: inline-flex;
149
+ align-items: center;
150
+ }
151
+
152
+ .dropdownAnchorFull {
153
+ width: 100%;
154
+ }
155
+
156
+ .dropdownAnchorFull > * {
157
+ width: 100%;
158
+ }
159
+
160
+ .dropdownTrigger {
161
+ border: 1px solid rgba(30, 99, 233, 0.3);
162
+ background: var(--surface-control);
163
+ color: var(--color-text);
164
+ padding: 8px 12px;
165
+ border-radius: 999px;
166
+ cursor: pointer;
167
+ display: inline-flex;
168
+ align-items: center;
169
+ gap: 8px;
170
+ }
171
+
172
+ .dropdown:global(.rsb-group-item) .dropdownTrigger {
173
+ border-radius: 0;
174
+ width: 100%;
175
+ }
176
+
177
+ .dropdownTriggerFull {
178
+ width: 100%;
179
+ justify-content: space-between;
180
+ }
181
+
182
+ .dropdownMenu {
183
+ position: absolute;
184
+ top: calc(100% + 8px);
185
+ min-width: 180px;
186
+ max-width: calc(100vw - 24px);
187
+ background: var(--surface-panel);
188
+ border: 1px solid var(--color-line);
189
+ border-radius: var(--radius-md);
190
+ padding: 8px;
191
+ box-shadow: var(--shadow-soft);
192
+ z-index: 10;
193
+ transform-origin: top right;
194
+ animation: dropdown-in 0.18s ease;
195
+ box-sizing: border-box;
196
+ white-space: normal;
197
+ overflow-wrap: anywhere;
198
+ }
199
+
200
+ .align-left {
201
+ left: 0;
202
+ }
203
+
204
+ .align-right {
205
+ right: 0;
206
+ }
207
+
208
+ @media (max-width: 820px) {
209
+ .horizontal {
210
+ flex-wrap: wrap;
211
+ row-gap: 8px;
212
+ }
213
+ }
214
+
215
+ @media (max-width: 720px) {
216
+ .dropdownMenu {
217
+ width: calc(100vw - 24px);
218
+ }
219
+ }
220
+
221
+ @keyframes dropdown-in {
222
+ from {
223
+ opacity: 0;
224
+ transform: translateY(-6px) scale(0.98);
225
+ }
226
+
227
+ to {
228
+ opacity: 1;
229
+ transform: translateY(0) scale(1);
230
+ }
231
+ }
232
+
233
+ @media (prefers-reduced-motion: reduce) {
234
+ .submenu,
235
+ .submenuOpen,
236
+ .dropdownMenu {
237
+ transition: none;
238
+ animation: none;
239
+ }
240
+ }
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ type Props = {
3
+ open: boolean;
4
+ title?: string;
5
+ children: React.ReactNode;
6
+ footer?: React.ReactNode;
7
+ size?: 'sm' | 'md' | 'lg';
8
+ closeOnBackdrop?: boolean;
9
+ onClose: () => void;
10
+ };
11
+ export default function Modal({ open, title, children, footer, size, closeOnBackdrop, onClose, }: Props): React.ReactPortal | null;
12
+ export {};
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { createPortal } from 'react-dom';
4
+ import styles from './Modal.module.css';
5
+ export default function Modal({ open, title, children, footer, size = 'md', closeOnBackdrop = true, onClose, }) {
6
+ React.useEffect(() => {
7
+ if (!open) {
8
+ return;
9
+ }
10
+ const handleKeyDown = (event) => {
11
+ if (event.key === 'Escape') {
12
+ onClose();
13
+ }
14
+ };
15
+ document.addEventListener('keydown', handleKeyDown);
16
+ return () => document.removeEventListener('keydown', handleKeyDown);
17
+ }, [open, onClose]);
18
+ if (!open) {
19
+ return null;
20
+ }
21
+ const handleBackdropClick = (event) => {
22
+ if (!closeOnBackdrop) {
23
+ return;
24
+ }
25
+ if (event.target === event.currentTarget) {
26
+ onClose();
27
+ }
28
+ };
29
+ return createPortal(_jsx("div", { className: styles.overlay, onMouseDown: handleBackdropClick, children: _jsxs("div", { className: [styles.modal, styles[size]].filter(Boolean).join(' '), role: "dialog", "aria-modal": "true", children: [_jsxs("header", { className: styles.header, children: [title ? _jsx("h3", { children: title }) : _jsx("span", {}), _jsx("button", { type: "button", className: styles.close, onClick: onClose, "aria-label": "\u0417\u0430\u043A\u0440\u044B\u0442\u044C", children: "\u00D7" })] }), _jsx("div", { className: styles.body, children: children }), footer ? _jsx("footer", { className: styles.footer, children: footer }) : null] }) }), document.body);
30
+ }
31
+ //# sourceMappingURL=Modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../../src/components/Modal/Modal.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAYxC,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,MAAM,EACN,IAAI,GAAG,IAAI,EACX,eAAe,GAAG,IAAI,EACtB,OAAO,GACD;IACN,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC7C,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC3B,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC;QAEF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACpD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACtE,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAEpB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,mBAAmB,GAAG,CAAC,KAAuC,EAAE,EAAE;QACtE,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa,EAAE,CAAC;YACzC,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,YAAY,CACjB,cAAK,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,mBAAmB,YAC9D,eAAK,SAAS,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAC,QAAQ,gBAAY,MAAM,aACrG,kBAAQ,SAAS,EAAE,MAAM,CAAC,MAAM,aAC7B,KAAK,CAAC,CAAC,CAAC,uBAAK,KAAK,GAAM,CAAC,CAAC,CAAC,gBAAQ,EACpC,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,gBAAa,4CAAS,uBAE5E,IACF,EACT,cAAK,SAAS,EAAE,MAAM,CAAC,IAAI,YAAG,QAAQ,GAAO,EAC5C,MAAM,CAAC,CAAC,CAAC,iBAAQ,SAAS,EAAE,MAAM,CAAC,MAAM,YAAG,MAAM,GAAU,CAAC,CAAC,CAAC,IAAI,IAChE,GACF,EACN,QAAQ,CAAC,IAAI,CACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,90 @@
1
+ .overlay {
2
+ position: fixed;
3
+ inset: 0;
4
+ background: var(--overlay-strong);
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ padding: var(--spacing-7);
9
+ z-index: 50;
10
+ animation: overlay-fade-in 0.2s ease;
11
+ }
12
+
13
+ .modal {
14
+ width: min(560px, 100%);
15
+ background: var(--surface-panel);
16
+ border: 1px solid var(--color-line);
17
+ border-radius: var(--radius-lg);
18
+ box-shadow: var(--shadow-soft);
19
+ display: flex;
20
+ flex-direction: column;
21
+ gap: var(--spacing-4);
22
+ padding: var(--spacing-6);
23
+ animation: modal-pop-in 0.22s ease;
24
+ }
25
+
26
+ .sm {
27
+ width: min(420px, 100%);
28
+ }
29
+
30
+ .lg {
31
+ width: min(720px, 100%);
32
+ }
33
+
34
+ .header {
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: space-between;
38
+ }
39
+
40
+ .header h3 {
41
+ margin: 0;
42
+ font-size: 18px;
43
+ }
44
+
45
+ .close {
46
+ border: none;
47
+ background: transparent;
48
+ color: var(--color-muted);
49
+ font-size: 24px;
50
+ cursor: pointer;
51
+ }
52
+
53
+ .body {
54
+ color: var(--color-muted);
55
+ }
56
+
57
+ .footer {
58
+ display: flex;
59
+ justify-content: flex-end;
60
+ gap: var(--spacing-3);
61
+ }
62
+
63
+ @keyframes overlay-fade-in {
64
+ from {
65
+ opacity: 0;
66
+ }
67
+
68
+ to {
69
+ opacity: 1;
70
+ }
71
+ }
72
+
73
+ @keyframes modal-pop-in {
74
+ from {
75
+ opacity: 0;
76
+ transform: translateY(8px) scale(0.98);
77
+ }
78
+
79
+ to {
80
+ opacity: 1;
81
+ transform: translateY(0) scale(1);
82
+ }
83
+ }
84
+
85
+ @media (prefers-reduced-motion: reduce) {
86
+ .overlay,
87
+ .modal {
88
+ animation: none;
89
+ }
90
+ }
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import type { UiVariant } from '../../types';
3
+ export type NotifierItem = {
4
+ id: string;
5
+ title?: React.ReactNode;
6
+ message?: React.ReactNode;
7
+ variant?: UiVariant;
8
+ duration?: number;
9
+ actions?: React.ReactNode;
10
+ };
11
+ type Props = {
12
+ items: NotifierItem[];
13
+ onDismiss: (id: string) => void;
14
+ position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
15
+ };
16
+ export default function Notifier({ items, onDismiss, position }: Props): import("react/jsx-runtime").JSX.Element | null;
17
+ export {};
@@ -0,0 +1,210 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import styles from './Notifier.module.css';
4
+ const positionClass = {
5
+ 'top-right': styles.topRight,
6
+ 'top-left': styles.topLeft,
7
+ 'bottom-right': styles.bottomRight,
8
+ 'bottom-left': styles.bottomLeft,
9
+ };
10
+ const variantClass = {
11
+ default: styles.default,
12
+ primary: styles.primary,
13
+ info: styles.info,
14
+ success: styles.success,
15
+ warning: styles.warning,
16
+ danger: styles.danger,
17
+ };
18
+ export default function Notifier({ items, onDismiss, position = 'top-right' }) {
19
+ const timersRef = React.useRef({});
20
+ const closingRef = React.useRef({});
21
+ const [closingIds, setClosingIds] = React.useState({});
22
+ const [pausedIds, setPausedIds] = React.useState({});
23
+ const [visibilityPaused, setVisibilityPaused] = React.useState(() => {
24
+ if (typeof document === 'undefined') {
25
+ return false;
26
+ }
27
+ const hasFocus = typeof document.hasFocus === 'function' ? document.hasFocus() : true;
28
+ return document.hidden || !hasFocus;
29
+ });
30
+ const exitDuration = 220;
31
+ const clearTimer = React.useCallback((id) => {
32
+ const timer = timersRef.current[id];
33
+ if (!timer) {
34
+ return;
35
+ }
36
+ if (timer.timeoutId !== null) {
37
+ window.clearTimeout(timer.timeoutId);
38
+ }
39
+ delete timersRef.current[id];
40
+ }, []);
41
+ const startClose = React.useCallback((id) => {
42
+ if (closingRef.current[id]) {
43
+ return;
44
+ }
45
+ clearTimer(id);
46
+ setClosingIds((prev) => ({ ...prev, [id]: true }));
47
+ closingRef.current[id] = window.setTimeout(() => {
48
+ delete closingRef.current[id];
49
+ onDismiss(id);
50
+ }, exitDuration);
51
+ }, [clearTimer, onDismiss, exitDuration]);
52
+ const pauseTimer = React.useCallback((id) => {
53
+ const timer = timersRef.current[id];
54
+ if (!timer || timer.timeoutId === null) {
55
+ return;
56
+ }
57
+ const elapsed = Date.now() - timer.startedAt;
58
+ timer.remaining = Math.max(0, timer.remaining - elapsed);
59
+ window.clearTimeout(timer.timeoutId);
60
+ timer.timeoutId = null;
61
+ }, []);
62
+ const resumeTimer = React.useCallback((id) => {
63
+ const timer = timersRef.current[id];
64
+ if (!timer || timer.timeoutId !== null) {
65
+ return;
66
+ }
67
+ if (timer.remaining <= 0) {
68
+ startClose(id);
69
+ return;
70
+ }
71
+ timer.startedAt = Date.now();
72
+ timer.timeoutId = window.setTimeout(() => startClose(id), timer.remaining);
73
+ }, [startClose]);
74
+ React.useEffect(() => {
75
+ items.forEach((item) => {
76
+ if (!item.duration || timersRef.current[item.id]) {
77
+ return;
78
+ }
79
+ timersRef.current[item.id] = {
80
+ timeoutId: null,
81
+ remaining: item.duration,
82
+ startedAt: Date.now(),
83
+ };
84
+ });
85
+ Object.keys(timersRef.current).forEach((id) => {
86
+ if (!items.find((item) => item.id === id)) {
87
+ clearTimer(id);
88
+ }
89
+ });
90
+ setClosingIds((prev) => {
91
+ const next = { ...prev };
92
+ Object.keys(next).forEach((id) => {
93
+ if (!items.find((item) => item.id === id)) {
94
+ delete next[id];
95
+ if (closingRef.current[id]) {
96
+ window.clearTimeout(closingRef.current[id]);
97
+ delete closingRef.current[id];
98
+ }
99
+ }
100
+ });
101
+ return next;
102
+ });
103
+ setPausedIds((prev) => {
104
+ const next = { ...prev };
105
+ Object.keys(next).forEach((id) => {
106
+ if (!items.find((item) => item.id === id)) {
107
+ delete next[id];
108
+ }
109
+ });
110
+ return next;
111
+ });
112
+ }, [items, clearTimer]);
113
+ React.useEffect(() => {
114
+ items.forEach((item) => {
115
+ if (!item.duration) {
116
+ return;
117
+ }
118
+ if (closingIds[item.id]) {
119
+ return;
120
+ }
121
+ if (visibilityPaused || pausedIds[item.id]) {
122
+ pauseTimer(item.id);
123
+ return;
124
+ }
125
+ resumeTimer(item.id);
126
+ });
127
+ }, [items, closingIds, pausedIds, visibilityPaused, pauseTimer, resumeTimer]);
128
+ React.useEffect(() => {
129
+ const pauseAll = () => {
130
+ setVisibilityPaused(true);
131
+ items.forEach((item) => pauseTimer(item.id));
132
+ };
133
+ const resumeAll = () => {
134
+ const hasFocus = typeof document.hasFocus === 'function' ? document.hasFocus() : true;
135
+ if (document.hidden || !hasFocus) {
136
+ return;
137
+ }
138
+ setVisibilityPaused(false);
139
+ items.forEach((item) => {
140
+ if (!pausedIds[item.id]) {
141
+ resumeTimer(item.id);
142
+ }
143
+ });
144
+ };
145
+ const handleVisibility = () => {
146
+ if (document.hidden) {
147
+ pauseAll();
148
+ }
149
+ else {
150
+ resumeAll();
151
+ }
152
+ };
153
+ document.addEventListener('visibilitychange', handleVisibility);
154
+ window.addEventListener('blur', pauseAll);
155
+ window.addEventListener('focus', resumeAll);
156
+ window.addEventListener('pagehide', pauseAll);
157
+ window.addEventListener('pageshow', resumeAll);
158
+ return () => {
159
+ document.removeEventListener('visibilitychange', handleVisibility);
160
+ window.removeEventListener('blur', pauseAll);
161
+ window.removeEventListener('focus', resumeAll);
162
+ window.removeEventListener('pagehide', pauseAll);
163
+ window.removeEventListener('pageshow', resumeAll);
164
+ };
165
+ }, [items, pauseTimer, resumeTimer, pausedIds]);
166
+ React.useEffect(() => () => {
167
+ Object.values(timersRef.current).forEach((timer) => {
168
+ if (timer.timeoutId !== null) {
169
+ window.clearTimeout(timer.timeoutId);
170
+ }
171
+ });
172
+ timersRef.current = {};
173
+ Object.values(closingRef.current).forEach((timer) => window.clearTimeout(timer));
174
+ closingRef.current = {};
175
+ }, []);
176
+ if (items.length === 0) {
177
+ return null;
178
+ }
179
+ return (_jsx("div", { className: [styles.container, positionClass[position]].filter(Boolean).join(' '), role: "region", "aria-live": "polite", children: items.map((item) => {
180
+ const variant = item.variant ?? 'info';
181
+ const isPaused = Boolean(pausedIds[item.id] || visibilityPaused);
182
+ const isClosing = Boolean(closingIds[item.id]);
183
+ return (_jsxs("div", { className: [
184
+ styles.toast,
185
+ variantClass[variant],
186
+ isClosing ? styles.toastClosing : null,
187
+ ]
188
+ .filter(Boolean)
189
+ .join(' '), "data-paused": isPaused ? 'true' : undefined, onMouseEnter: () => {
190
+ if (!item.duration) {
191
+ return;
192
+ }
193
+ pauseTimer(item.id);
194
+ setPausedIds((prev) => ({ ...prev, [item.id]: true }));
195
+ }, onMouseLeave: () => {
196
+ if (!item.duration) {
197
+ return;
198
+ }
199
+ setPausedIds((prev) => {
200
+ const next = { ...prev };
201
+ delete next[item.id];
202
+ return next;
203
+ });
204
+ if (!visibilityPaused) {
205
+ resumeTimer(item.id);
206
+ }
207
+ }, children: [_jsxs("div", { className: styles.content, children: [item.title ? _jsx("div", { className: styles.title, children: item.title }) : null, item.message ? _jsx("div", { className: styles.message, children: item.message }) : null, item.actions ? _jsx("div", { className: styles.actions, children: item.actions }) : null] }), _jsx("button", { type: "button", className: styles.close, onClick: () => startClose(item.id), "aria-label": "\u0417\u0430\u043A\u0440\u044B\u0442\u044C", children: "\u00D7" }), item.duration ? (_jsx("span", { className: styles.timer, style: { '--toast-duration': `${item.duration}ms` }, "aria-hidden": "true", "data-testid": "notifier-timer" })) : null] }, item.id));
208
+ }) }));
209
+ }
210
+ //# sourceMappingURL=Notifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Notifier.js","sourceRoot":"","sources":["../../../src/components/Notifier/Notifier.tsx"],"names":[],"mappings":"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"}