@musecat/uikit 0.1.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 (180) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +51 -0
  3. package/index.ts +78 -0
  4. package/package.json +103 -0
  5. package/packages/Components/Box/Box.tsx +173 -0
  6. package/packages/Components/Box/Box.types.ts +48 -0
  7. package/packages/Components/Button/Button.tsx +275 -0
  8. package/packages/Components/Button/Button.types.ts +44 -0
  9. package/packages/Components/Card/Card.default.tsx +180 -0
  10. package/packages/Components/Card/Card.foldable.tsx +383 -0
  11. package/packages/Components/Card/Card.module.scss +23 -0
  12. package/packages/Components/Card/Card.tsx +8 -0
  13. package/packages/Components/Card/Card.types.ts +91 -0
  14. package/packages/Components/Card/Card.utils.ts +66 -0
  15. package/packages/Components/Checkbox/Checkbox.module.scss +11 -0
  16. package/packages/Components/Checkbox/Checkbox.tsx +104 -0
  17. package/packages/Components/Checkbox/Checkbox.types.ts +24 -0
  18. package/packages/Components/CodeBox/CodeBox.copy.tsx +43 -0
  19. package/packages/Components/CodeBox/CodeBox.module.scss +72 -0
  20. package/packages/Components/CodeBox/CodeBox.tsx +91 -0
  21. package/packages/Components/CodeBox/CodeBox.types.ts +17 -0
  22. package/packages/Components/ContextMenu/ContextMenu.module.scss +8 -0
  23. package/packages/Components/ContextMenu/ContextMenu.options.tsx +126 -0
  24. package/packages/Components/ContextMenu/ContextMenu.tsx +381 -0
  25. package/packages/Components/ContextMenu/ContextMenu.types.ts +46 -0
  26. package/packages/Components/ContributionGraph/ContributionGraph.module.scss +42 -0
  27. package/packages/Components/ContributionGraph/ContributionGraph.tsx +454 -0
  28. package/packages/Components/ContributionGraph/ContributionGraph.types.ts +27 -0
  29. package/packages/Components/DatePicker/DatePicker.calendar.tsx +161 -0
  30. package/packages/Components/DatePicker/DatePicker.core.tsx +582 -0
  31. package/packages/Components/DatePicker/DatePicker.module.scss +26 -0
  32. package/packages/Components/DatePicker/DatePicker.tsx +786 -0
  33. package/packages/Components/DatePicker/DatePicker.types.ts +36 -0
  34. package/packages/Components/DatePicker/DatePicker.utils.ts +80 -0
  35. package/packages/Components/DatePicker/hooks/useCalendar.ts +61 -0
  36. package/packages/Components/DatePicker/hooks/useSelection.ts +208 -0
  37. package/packages/Components/Divider/Divider.tsx +46 -0
  38. package/packages/Components/Divider/Divider.types.ts +12 -0
  39. package/packages/Components/Header/Header.module.scss +74 -0
  40. package/packages/Components/Header/Header.tsx +47 -0
  41. package/packages/Components/Header/Header.types.ts +8 -0
  42. package/packages/Components/Icon/Icon.group.tsx +122 -0
  43. package/packages/Components/Icon/Icon.group.types.ts +20 -0
  44. package/packages/Components/Icon/Icon.tsx +341 -0
  45. package/packages/Components/Icon/Icon.types.ts +59 -0
  46. package/packages/Components/Icon/SVG/data.tsx +232 -0
  47. package/packages/Components/Input/Input.module.scss +5 -0
  48. package/packages/Components/Input/Input.tsx +87 -0
  49. package/packages/Components/Input/Input.types.ts +14 -0
  50. package/packages/Components/Label/Label.module.scss +19 -0
  51. package/packages/Components/Label/Label.tsx +115 -0
  52. package/packages/Components/Label/Label.types.ts +28 -0
  53. package/packages/Components/Layout/Layout.docs.module.scss +42 -0
  54. package/packages/Components/Layout/Layout.docs.tsx +150 -0
  55. package/packages/Components/Layout/Layout.docs.types.ts +18 -0
  56. package/packages/Components/Layout/Layout.module.scss +91 -0
  57. package/packages/Components/Layout/Layout.tsx +306 -0
  58. package/packages/Components/Layout/Layout.types.ts +71 -0
  59. package/packages/Components/Maps/OSM/MapOSM.module.scss +11 -0
  60. package/packages/Components/Maps/OSM/MapOSM.shared.ts +121 -0
  61. package/packages/Components/Maps/OSM/MapOSM.tsx +279 -0
  62. package/packages/Components/Maps/OSM/MapOSM.types.ts +18 -0
  63. package/packages/Components/Nav/Nav.module.scss +137 -0
  64. package/packages/Components/Nav/Nav.tsx +304 -0
  65. package/packages/Components/Nav/Nav.types.ts +32 -0
  66. package/packages/Components/Nav/hooks/useNavDrag.ts +374 -0
  67. package/packages/Components/Nav/hooks/useNavIndicator.ts +137 -0
  68. package/packages/Components/Pagination/Pagination.tsx +254 -0
  69. package/packages/Components/Pagination/Pagination.types.ts +18 -0
  70. package/packages/Components/Pill/Pill.tsx +127 -0
  71. package/packages/Components/Pill/Pill.types.ts +33 -0
  72. package/packages/Components/Profile/Profile.shared.ts +74 -0
  73. package/packages/Components/Profile/Profile.tsx +382 -0
  74. package/packages/Components/Profile/Profile.types.ts +55 -0
  75. package/packages/Components/Progress/Progress.module.scss +15 -0
  76. package/packages/Components/Progress/Progress.tsx +88 -0
  77. package/packages/Components/Progress/Progress.types.ts +22 -0
  78. package/packages/Components/Radio/Radio.module.scss +11 -0
  79. package/packages/Components/Radio/Radio.tsx +121 -0
  80. package/packages/Components/Radio/Radio.types.ts +20 -0
  81. package/packages/Components/Select/Select.keyboard.tsx +76 -0
  82. package/packages/Components/Select/Select.trigger.tsx +88 -0
  83. package/packages/Components/Select/Select.tsx +11 -0
  84. package/packages/Components/Select/Select.types.ts +38 -0
  85. package/packages/Components/Select/Select.utils.ts +84 -0
  86. package/packages/Components/Select/hooks/useSelectNavigation.ts +461 -0
  87. package/packages/Components/Select/hooks/useSelectSelection.ts +142 -0
  88. package/packages/Components/Select/hooks/useSelectState.ts +314 -0
  89. package/packages/Components/Select/select.control.tsx +228 -0
  90. package/packages/Components/Select/select.inner.tsx +312 -0
  91. package/packages/Components/Skeleton/Skeleton.tsx +30 -0
  92. package/packages/Components/Skeleton/Skeleton.types.ts +12 -0
  93. package/packages/Components/Spinner/Spinner.module.scss +78 -0
  94. package/packages/Components/Spinner/Spinner.tsx +125 -0
  95. package/packages/Components/Spinner/Spinner.types.ts +19 -0
  96. package/packages/Components/Text/Text.module.scss +7 -0
  97. package/packages/Components/Text/Text.tsx +49 -0
  98. package/packages/Components/Text/Text.types.ts +33 -0
  99. package/packages/Components/TimePicker/TimePicker.core.tsx +448 -0
  100. package/packages/Components/TimePicker/TimePicker.module.scss +30 -0
  101. package/packages/Components/TimePicker/TimePicker.tsx +511 -0
  102. package/packages/Components/TimePicker/TimePicker.types.ts +22 -0
  103. package/packages/Components/Timeline/Timeline.tsx +111 -0
  104. package/packages/Components/Timeline/Timeline.types.ts +23 -0
  105. package/packages/Components/Title/Title.tsx +305 -0
  106. package/packages/Components/Title/Title.types.ts +64 -0
  107. package/packages/Components/Toggle/Toggle.module.scss +32 -0
  108. package/packages/Components/Toggle/Toggle.tsx +272 -0
  109. package/packages/Components/Toggle/Toggle.types.ts +17 -0
  110. package/packages/Components/Tooltip/Tooltip.module.scss +44 -0
  111. package/packages/Components/Tooltip/Tooltip.tsx +340 -0
  112. package/packages/Components/Tooltip/Tooltip.types.ts +38 -0
  113. package/packages/Frameworks/Dialog/Dialog.background.tsx +88 -0
  114. package/packages/Frameworks/Dialog/Dialog.boot.tsx +32 -0
  115. package/packages/Frameworks/Dialog/Dialog.store.ts +199 -0
  116. package/packages/Frameworks/Dialog/Dialog.tsx +185 -0
  117. package/packages/Frameworks/Dialog/Dialog.types.ts +264 -0
  118. package/packages/Frameworks/Dialog/Dialog.utils.ts +22 -0
  119. package/packages/Frameworks/Dialog/contents/Dialog.footer.tsx +79 -0
  120. package/packages/Frameworks/Dialog/contents/Dialog.funnel.tsx +260 -0
  121. package/packages/Frameworks/Dialog/contents/Dialog.header.tsx +137 -0
  122. package/packages/Frameworks/Dialog/hooks/useDialogPosition.ts +298 -0
  123. package/packages/Frameworks/Dialog/hooks/useSheetDrag.ts +325 -0
  124. package/packages/Frameworks/Dialog/hooks/useSheetGeometry.ts +201 -0
  125. package/packages/Frameworks/Dialog/hooks/useSheetProgressive.ts +98 -0
  126. package/packages/Frameworks/Dialog/renderers/renderModal.tsx +228 -0
  127. package/packages/Frameworks/Dialog/renderers/renderPopover.tsx +220 -0
  128. package/packages/Frameworks/Dialog/renderers/renderSheet.tsx +571 -0
  129. package/packages/Frameworks/EdgeEffect/EdgeEffect.tsx +52 -0
  130. package/packages/Frameworks/EdgeEffect/EdgeEffect.types.ts +5 -0
  131. package/packages/Frameworks/Motion/Motion.presets.ts +49 -0
  132. package/packages/Frameworks/Pressable/Pressable.module.scss +19 -0
  133. package/packages/Frameworks/Pressable/Pressable.tsx +651 -0
  134. package/packages/Frameworks/Pressable/Pressable.types.ts +73 -0
  135. package/packages/Frameworks/Squircle/Squircle.tsx +263 -0
  136. package/packages/Frameworks/Squircle/Squircle.types.ts +15 -0
  137. package/packages/Frameworks/Theme/Radius.types.ts +55 -0
  138. package/packages/Frameworks/Theme/Theme.types.ts +325 -0
  139. package/packages/Frameworks/Toaster/Toaster.boot.tsx +47 -0
  140. package/packages/Frameworks/Toaster/Toaster.module.scss +168 -0
  141. package/packages/Frameworks/Toaster/Toaster.types.ts +13 -0
  142. package/packages/Frameworks/View/DNDView/DNDView.module.scss +8 -0
  143. package/packages/Frameworks/View/DNDView/DNDView.tsx +470 -0
  144. package/packages/Frameworks/View/DNDView/DNDView.types.ts +61 -0
  145. package/packages/Frameworks/View/HScrollView/HScrollView.module.scss +59 -0
  146. package/packages/Frameworks/View/HScrollView/HScrollView.tsx +386 -0
  147. package/packages/Frameworks/View/HScrollView/HScrollView.types.ts +46 -0
  148. package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.counter.tsx +27 -0
  149. package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.footer.tsx +76 -0
  150. package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.header.tsx +49 -0
  151. package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.list.tsx +74 -0
  152. package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.slide.tsx +71 -0
  153. package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.tsx +175 -0
  154. package/packages/Frameworks/View/ImageView/Image.controls.tsx +39 -0
  155. package/packages/Frameworks/View/ImageView/Image.hooks.ts +82 -0
  156. package/packages/Frameworks/View/ImageView/Image.module.scss +7 -0
  157. package/packages/Frameworks/View/ImageView/Image.tsx +375 -0
  158. package/packages/Frameworks/View/ImageView/Image.types.ts +71 -0
  159. package/packages/Frameworks/View/ImageView/Image.utils.ts +79 -0
  160. package/packages/Frameworks/View/View.module.scss +34 -0
  161. package/packages/Frameworks/View/View.tsx +200 -0
  162. package/packages/Frameworks/View/View.types.ts +36 -0
  163. package/packages/Frameworks/_shared/Padding.types.ts +52 -0
  164. package/packages/Frameworks/_shared/StopParentInteraction.tsx +45 -0
  165. package/packages/Frameworks/_shared/Wind.types.ts +17 -0
  166. package/packages/Frameworks/_shared/bodyScrollLock.ts +127 -0
  167. package/packages/Frameworks/_shared/layer.constants.ts +8 -0
  168. package/packages/Frameworks/_shared/normalize.ts +39 -0
  169. package/packages/Frameworks/_shared/sizing.ts +55 -0
  170. package/packages/Frameworks/_shared/useControllableState.ts +29 -0
  171. package/packages/Styles/_animation.scss +42 -0
  172. package/packages/Styles/_color.scss +131 -0
  173. package/packages/Styles/_font.scss +30 -0
  174. package/packages/Styles/_icon.scss +782 -0
  175. package/packages/Styles/_importer.scss +9 -0
  176. package/packages/Styles/_system.scss +69 -0
  177. package/packages/Styles/_textstyle.scss +111 -0
  178. package/packages/Styles/_theme.scss +452 -0
  179. package/packages/Styles/_viewport-global.scss +99 -0
  180. package/packages/Styles/_viewport.scss +108 -0
@@ -0,0 +1,325 @@
1
+ export type ThemePreset =
2
+ | `${ThemeBaseColor}Full`
3
+ | `${ThemeBaseColor}Soft`
4
+ | `${ThemePaletteColor}Full`
5
+ | `${ThemePaletteColor}Soft`
6
+ | "UIPrimary"
7
+ | "UISecondary"
8
+ | "UIPrimaryReversed"
9
+ | "UISecondaryReversed"
10
+ | "ReversedUIPrimary"
11
+ | "ReversedUISecondary";
12
+
13
+ export type ThemePaletteColor =
14
+ | "Pink"
15
+ | "Red"
16
+ | "Brown"
17
+ | "Orange"
18
+ | "Yellow"
19
+ | "Green"
20
+ | "Mint"
21
+ | "Cyan"
22
+ | "Blue"
23
+ | "Indigo"
24
+ | "Purple"
25
+ | "Magenta";
26
+
27
+ export type ThemeBaseColor = "Base" | "BaseLight" | "BaseDark" | "Reversed";
28
+ export type ThemeColorName = ThemeBaseColor | ThemePaletteColor;
29
+
30
+ export type ThemeLevel = 1 | 2 | 3 | 4 | 5 | 6;
31
+
32
+ export type ThemeTPScale = 1 | 2 | 3 | 4 | 5 | 6;
33
+
34
+ export type ThemePaint =
35
+ | `${ThemeColorName}${ThemeLevel}`
36
+ | `${ThemeColorName}${ThemeLevel}TP${ThemeTPScale}`;
37
+ export type ThemeBackgroundPaint =
38
+ | ThemePaint
39
+ | readonly [ThemePaint]
40
+ | readonly [ThemePaint, ThemePaint, ThemePaint];
41
+ export type ThemeBorderWidth = "None" | "Light" | "Regular" | "Bold";
42
+
43
+ export type BlurScale =
44
+ | "ExtraLight"
45
+ | "Light"
46
+ | "Regular"
47
+ | "Bold"
48
+ | "ExtraBold"
49
+ | "Heavy";
50
+ export type BackgroundBlurValue = BlurScale | "None";
51
+ export type ThemeBorderWidthTuple =
52
+ | readonly [ThemeBorderWidth]
53
+ | readonly [ThemeBorderWidth, ThemeBorderWidth]
54
+ | readonly [ThemeBorderWidth, ThemeBorderWidth, ThemeBorderWidth]
55
+ | readonly [
56
+ ThemeBorderWidth,
57
+ ThemeBorderWidth,
58
+ ThemeBorderWidth,
59
+ ThemeBorderWidth,
60
+ ];
61
+ export type ThemeBorderPaint =
62
+ | "None"
63
+ | ThemeBorderWidth
64
+ | ThemeBorderWidthTuple
65
+ | ThemePaint
66
+ | readonly [ThemePaint, ThemeBorderWidth | ThemeBorderWidthTuple];
67
+
68
+ export type ShadowScale = "Light" | "Regular" | "Bold";
69
+ export type ThemeShadow = ShadowScale | "None";
70
+
71
+ export interface BorderProps {
72
+ border?: ThemeBorderPaint;
73
+ }
74
+
75
+ export interface ThemeSystemProps {
76
+ themePreset?: ThemePreset;
77
+ background?: ThemeBackgroundPaint;
78
+ color?: ThemePaint;
79
+ border?: ThemeBorderPaint;
80
+ shadow?: ThemeShadow;
81
+ themeInteractive?: boolean;
82
+ selected?: boolean;
83
+ disabled?: boolean;
84
+ readOnly?: boolean;
85
+ backgroundBlur?: BackgroundBlurValue;
86
+ }
87
+
88
+ const TOKEN_PATTERN =
89
+ /^(BaseLight|BaseDark|Base|Reversed|Pink|Red|Brown|Orange|Yellow|Green|Mint|Cyan|Blue|Indigo|Purple|Magenta)([1-6])(?:TP([1-6]))?$/;
90
+
91
+ function resolvePaintClass(
92
+ prefix: "ThemeBg" | "ThemeColor",
93
+ paint?: ThemePaint,
94
+ ) {
95
+ if (!paint) return undefined;
96
+ const match = TOKEN_PATTERN.exec(paint);
97
+ if (!match) return undefined;
98
+
99
+ const [, colorName, level, tp] = match;
100
+ return `${prefix}-${colorName}${level}${tp ? `TP${tp}` : ""}`;
101
+ }
102
+
103
+ function isBorderWidth(value: unknown): value is ThemeBorderWidth {
104
+ return (
105
+ value === "None" ||
106
+ value === "Light" ||
107
+ value === "Regular" ||
108
+ value === "Bold"
109
+ );
110
+ }
111
+
112
+ const BLUR_MAP: Record<BlurScale, string> = {
113
+ ExtraLight: "BackgroundBlur-ExtraLight",
114
+ Light: "BackgroundBlur-Light",
115
+ Regular: "BackgroundBlur-Regular",
116
+ Bold: "BackgroundBlur-Bold",
117
+ ExtraBold: "BackgroundBlur-ExtraBold",
118
+ Heavy: "BackgroundBlur-Heavy",
119
+ };
120
+
121
+ const SHADOW_MAP: Record<ShadowScale, string> = {
122
+ Light: "ThemeShadow-1",
123
+ Regular: "ThemeShadow-2",
124
+ Bold: "ThemeShadow-3",
125
+ };
126
+
127
+ export function Shadow(shadow?: ThemeShadow) {
128
+ if (!shadow || shadow === "None") return undefined;
129
+ return SHADOW_MAP[shadow];
130
+ }
131
+
132
+ export function BackgroundBlur(value?: BackgroundBlurValue) {
133
+ if (!value || value === "None") return undefined;
134
+ return BLUR_MAP[value];
135
+ }
136
+
137
+ export function Border(
138
+ border?: ThemeBorderPaint,
139
+ basePaint: ThemePaint = "Base6TP1",
140
+ ) {
141
+ if (!border) return undefined;
142
+ if (border === "None") return `ThemeBorder-${basePaint}-None`;
143
+
144
+ const [paint, widthValue] = Array.isArray(border)
145
+ ? isBorderWidth(border[0])
146
+ ? [basePaint, border]
147
+ : border
148
+ : isBorderWidth(border)
149
+ ? [basePaint, border]
150
+ : [border, "Regular"];
151
+ const borderClass = resolvePaintClass("ThemeColor", paint);
152
+ if (!borderClass) return undefined;
153
+
154
+ const paintClass = borderClass.replace("ThemeColor-", "");
155
+ if (!Array.isArray(widthValue)) {
156
+ return `ThemeBorder-${paintClass}-${widthValue}`;
157
+ }
158
+
159
+ return widthValue
160
+ .map((width, index) => `ThemeBorder${index + 1}-${paintClass}-${width}`)
161
+ .join(" ");
162
+ }
163
+
164
+ function resolveBackgroundClasses(
165
+ background?: ThemeBackgroundPaint,
166
+ canBeInteractive?: boolean,
167
+ ) {
168
+ if (!background) return [];
169
+ if (typeof background === "string") {
170
+ const backgroundClass = resolvePaintClass("ThemeBg", background);
171
+ return backgroundClass ? [backgroundClass] : [];
172
+ }
173
+
174
+ if (!Array.isArray(background)) return [];
175
+
176
+ const [idle, hover, active] = background;
177
+ const classes: string[] = [];
178
+ const idleClass = resolvePaintClass("ThemeBg", idle);
179
+ const hasForcedStates = background.length === 3 && canBeInteractive;
180
+ const hoverClass = hasForcedStates
181
+ ? resolvePaintClass("ThemeBg", hover)
182
+ : undefined;
183
+ const activeClass = hasForcedStates
184
+ ? resolvePaintClass("ThemeBg", active)
185
+ : undefined;
186
+
187
+ if (idleClass) classes.push(idleClass);
188
+ if (hoverClass) classes.push(hoverClass.replace("ThemeBg-", "ThemeBgHover-"));
189
+ if (activeClass)
190
+ classes.push(activeClass.replace("ThemeBg-", "ThemeBgActive-"));
191
+
192
+ return classes;
193
+ }
194
+
195
+ type ResolvedPreset = {
196
+ background: ThemeBackgroundPaint;
197
+ color: ThemePaint;
198
+ };
199
+
200
+ const PRESET_PATTERN =
201
+ /^(BaseLight|BaseDark|Base|Reversed|Pink|Red|Brown|Orange|Yellow|Green|Mint|Cyan|Blue|Indigo|Purple|Magenta)(Full|Soft)$/;
202
+
203
+ function resolvePreset(preset?: ThemePreset): ResolvedPreset | undefined {
204
+ if (!preset) return undefined;
205
+
206
+ if (preset === "UIPrimary") {
207
+ return {
208
+ background: ["Base1", "Base2", "Base3"],
209
+ color: "Base1",
210
+ };
211
+ }
212
+
213
+ if (preset === "UIPrimaryReversed" || preset === "ReversedUIPrimary") {
214
+ return {
215
+ background: ["Reversed1", "Reversed2", "Reversed3"],
216
+ color: "Reversed1",
217
+ };
218
+ }
219
+
220
+ if (preset === "UISecondary") {
221
+ return {
222
+ background: ["Base4", "Base5", "Base6"],
223
+ color: "Base1",
224
+ };
225
+ }
226
+
227
+ if (preset === "UISecondaryReversed" || preset === "ReversedUISecondary") {
228
+ return {
229
+ background: ["Reversed4", "Reversed5", "Reversed6"],
230
+ color: "Reversed1",
231
+ };
232
+ }
233
+
234
+ const match = PRESET_PATTERN.exec(preset);
235
+ if (!match) return undefined;
236
+
237
+ const colorName = match[1] as ThemeColorName;
238
+ const tone = match[2] as "Full" | "Soft";
239
+
240
+ if (tone === "Full") {
241
+ const fullColor =
242
+ colorName === "BaseDark" || !colorName.startsWith("Base")
243
+ ? "BaseLight1"
244
+ : "BaseDark1";
245
+
246
+ return {
247
+ background: [`${colorName}4TP1`, `${colorName}5TP1`, `${colorName}6TP1`],
248
+ color: fullColor,
249
+ };
250
+ }
251
+
252
+ return {
253
+ background: [`${colorName}1TP6`, `${colorName}2TP6`, `${colorName}3TP6`],
254
+ color: `${colorName}1TP1`,
255
+ };
256
+ }
257
+
258
+ export function resolveThemeClasses(
259
+ props: ThemeSystemProps & {
260
+ selected?: boolean;
261
+ disabled?: boolean;
262
+ readOnly?: boolean;
263
+ isInteractive?: boolean;
264
+ },
265
+ ) {
266
+ const {
267
+ themePreset,
268
+ background,
269
+ color,
270
+ border,
271
+ shadow,
272
+ themeInteractive,
273
+ selected,
274
+ disabled,
275
+ readOnly,
276
+ isInteractive,
277
+ } = props;
278
+
279
+ const classes: string[] = [];
280
+
281
+ const resolvedPreset = selected && !themePreset ? "UISecondary" : themePreset;
282
+ const preset = resolvePreset(resolvedPreset);
283
+ const resolvedBackground = background ?? preset?.background;
284
+ const resolvedColor = color ?? preset?.color;
285
+ const resolvedBorder = border;
286
+
287
+ const canBeInteractive =
288
+ (isInteractive || themeInteractive === true) && !disabled && !readOnly;
289
+ const isThemeInteractiveActive = themeInteractive ?? isInteractive;
290
+
291
+ const colorClass = resolvePaintClass("ThemeColor", resolvedColor);
292
+ classes.push(
293
+ ...resolveBackgroundClasses(resolvedBackground, canBeInteractive),
294
+ );
295
+ if (colorClass) classes.push(colorClass);
296
+ if (resolvedBorder) classes.push(Border(resolvedBorder) ?? "");
297
+ if (shadow) classes.push(Shadow(shadow) ?? "");
298
+
299
+ if (canBeInteractive && isThemeInteractiveActive) {
300
+ classes.push("ThemeInteractive");
301
+ }
302
+
303
+ if (disabled) {
304
+ classes.push("ThemeDisabled");
305
+ }
306
+
307
+ if (readOnly) {
308
+ classes.push("ThemeReadonly");
309
+ }
310
+
311
+ if (selected && themePreset) {
312
+ classes.push("ThemeSelected");
313
+ }
314
+
315
+ return classes;
316
+ }
317
+
318
+ export function resolveThemeHasBorder(props: {
319
+ border?: ThemeBorderPaint;
320
+ themePreset?: ThemePreset;
321
+ }): boolean {
322
+ const { border } = props;
323
+ if (!border || border === "None") return false;
324
+ return true;
325
+ }
@@ -0,0 +1,47 @@
1
+ "use client";
2
+
3
+ import Icon from "@/packages/Components/Icon/Icon";
4
+ import type { IconProps } from "@/packages/Components/Icon/Icon.types";
5
+ import styles from "@/packages/Frameworks/Toaster/Toaster.module.scss";
6
+ import type { ToasterBootstrapProps } from "@/packages/Frameworks/Toaster/Toaster.types";
7
+ import clsx from "clsx";
8
+ import { Toaster, toast } from "sonner";
9
+
10
+ export { toast };
11
+ export type { ToasterBootstrapProps };
12
+
13
+ const getToastIcon = (color: IconProps["color"]) => (
14
+ <Icon icon="iCircle" iconFill size={10} color={color} />
15
+ );
16
+
17
+ export default function ToasterBootstrap({
18
+ theme,
19
+ icon: _icon,
20
+ title: _title,
21
+ storage: _storage,
22
+ "data-color-mode": dataTheme,
23
+ }: ToasterBootstrapProps) {
24
+ return (
25
+ <Toaster
26
+ theme={theme}
27
+ toastOptions={{
28
+ unstyled: true,
29
+ className: clsx(
30
+ styles.Toaster,
31
+ "Footnote",
32
+ dataTheme && `color-mode-${dataTheme}`,
33
+ ),
34
+ classNames: {
35
+ loading: styles.Loading,
36
+ },
37
+ }}
38
+ icons={{
39
+ success: getToastIcon("Green1"),
40
+ error: getToastIcon("Red1"),
41
+ info: getToastIcon("Blue1"),
42
+ warning: getToastIcon("Yellow1"),
43
+ loading: getToastIcon("Yellow1"),
44
+ }}
45
+ />
46
+ );
47
+ }
@@ -0,0 +1,168 @@
1
+ .Toaster {
2
+ display: flex;
3
+ gap: 0.8rem;
4
+ width: max-content !important;
5
+ max-width: min(calc(100vw - 1.6rem), 56rem) !important;
6
+ align-self: flex-start;
7
+ background: color-mix(in srgb, var(--color-base-dark-6) 70%, transparent);
8
+ color: var(--color-text-base-dark);
9
+ border-radius: var(--radius-circle);
10
+ padding: 1rem 1.2rem;
11
+ -webkit-backdrop-filter: blur(8px);
12
+ backdrop-filter: blur(8px);
13
+ letter-spacing: 0.03rem;
14
+ font-weight: 400;
15
+ z-index: 999999;
16
+
17
+ :global([data-icon]) {
18
+ position: relative;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+
23
+ & > :global(.sonner-loader) {
24
+ position: absolute !important;
25
+ left: 50% !important;
26
+ top: 50% !important;
27
+ transform: translate(-50%, -50%) !important;
28
+
29
+ &[data-visible="false"] {
30
+ display: none !important;
31
+ opacity: 0 !important;
32
+ visibility: hidden !important;
33
+ }
34
+ }
35
+
36
+ & > :not(:global(.sonner-loader)) {
37
+ position: relative !important;
38
+ left: 0 !important;
39
+ transform: none !important;
40
+ z-index: 1;
41
+ }
42
+ }
43
+
44
+ :global([data-content]) {
45
+ max-width: 100%;
46
+ overflow-wrap: anywhere;
47
+ }
48
+
49
+ :global([data-title]) {
50
+ display: inline-flex;
51
+ align-items: baseline;
52
+ }
53
+ }
54
+
55
+ .Loading {
56
+ :global([data-icon]) {
57
+ animation: loading-dot-pulse 1.1s ease-in-out infinite;
58
+ }
59
+
60
+ :global([data-title]) {
61
+ opacity: 0.92;
62
+ animation: loading-text-breath 1.25s ease-in-out infinite;
63
+ }
64
+
65
+ :global([data-title])::after {
66
+ content: ".";
67
+ display: inline-block;
68
+ width: 1.8ch;
69
+ margin-left: 0.2rem;
70
+ white-space: nowrap;
71
+ vertical-align: baseline;
72
+ text-align: left;
73
+ color: rgb(255, 255, 255, 0.95);
74
+ text-shadow:
75
+ 0.6ch 0 rgb(255, 255, 255, 0.35),
76
+ 1.2ch 0 rgb(255, 255, 255, 0.2);
77
+ animation: loading-dots-sequential 1.35s cubic-bezier(0.4, 0, 0.2, 1)
78
+ infinite;
79
+ }
80
+ }
81
+
82
+ @keyframes loading-dots-sequential {
83
+ 0% {
84
+ color: rgb(255, 255, 255, 0.95);
85
+ text-shadow:
86
+ 0.6ch 0 rgb(255, 255, 255, 0.35),
87
+ 1.2ch 0 rgb(255, 255, 255, 0.2);
88
+ }
89
+
90
+ 18% {
91
+ color: rgb(255, 255, 255, 0.78);
92
+ text-shadow:
93
+ 0.6ch 0 rgb(255, 255, 255, 0.48),
94
+ 1.2ch 0 rgb(255, 255, 255, 0.24);
95
+ }
96
+
97
+ 33% {
98
+ color: rgb(255, 255, 255, 0.45);
99
+ text-shadow:
100
+ 0.6ch 0 rgb(255, 255, 255, 0.95),
101
+ 1.2ch 0 rgb(255, 255, 255, 0.32);
102
+ }
103
+
104
+ 52% {
105
+ color: rgb(255, 255, 255, 0.28);
106
+ text-shadow:
107
+ 0.6ch 0 rgb(255, 255, 255, 0.78),
108
+ 1.2ch 0 rgb(255, 255, 255, 0.48);
109
+ }
110
+
111
+ 66% {
112
+ color: rgb(255, 255, 255, 0.24);
113
+ text-shadow:
114
+ 0.6ch 0 rgb(255, 255, 255, 0.45),
115
+ 1.2ch 0 rgb(255, 255, 255, 0.95);
116
+ }
117
+
118
+ 84% {
119
+ color: rgb(255, 255, 255, 0.38);
120
+ text-shadow:
121
+ 0.6ch 0 rgb(255, 255, 255, 0.3),
122
+ 1.2ch 0 rgb(255, 255, 255, 0.78);
123
+ }
124
+
125
+ 100% {
126
+ color: rgb(255, 255, 255, 0.95);
127
+ text-shadow:
128
+ 0.6ch 0 rgb(255, 255, 255, 0.35),
129
+ 1.2ch 0 rgb(255, 255, 255, 0.2);
130
+ }
131
+ }
132
+
133
+ @keyframes loading-text-breath {
134
+ 0% {
135
+ opacity: 0.82;
136
+ }
137
+ 50% {
138
+ opacity: 1;
139
+ }
140
+ 100% {
141
+ opacity: 0.82;
142
+ }
143
+ }
144
+
145
+ @keyframes loading-dot-pulse {
146
+ 0% {
147
+ transform: scale(0.88);
148
+ opacity: 0.58;
149
+ }
150
+
151
+ 50% {
152
+ transform: scale(1);
153
+ opacity: 1;
154
+ }
155
+
156
+ 100% {
157
+ transform: scale(0.88);
158
+ opacity: 0.58;
159
+ }
160
+ }
161
+
162
+ @media (prefers-reduced-motion: reduce) {
163
+ .Loading :global([data-icon]),
164
+ .Loading :global([data-title]),
165
+ .Loading :global([data-title])::after {
166
+ animation: none !important;
167
+ }
168
+ }
@@ -0,0 +1,13 @@
1
+ import type { ToasterProps } from "sonner";
2
+ import type { IconProps } from "@/packages/Components/Icon/Icon.types";
3
+
4
+ export interface ToasterBootstrapProps extends ToasterProps {
5
+ "data-color-mode"?: string;
6
+ theme?: ToasterProps["theme"];
7
+ icon?: IconProps;
8
+ title?: React.ReactNode;
9
+ storage?: {
10
+ key?: string;
11
+ value?: string;
12
+ }[];
13
+ }
@@ -0,0 +1,8 @@
1
+ .Handle {
2
+ cursor: grab;
3
+ touch-action: none;
4
+ }
5
+
6
+ .Handle:active {
7
+ cursor: grabbing;
8
+ }