@rojaostudio/ds 1.0.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 (291) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +89 -0
  3. package/brand/rojao-black-on-white.png +0 -0
  4. package/brand/rojao-black.png +0 -0
  5. package/brand/rojao-white-on-black.png +0 -0
  6. package/brand/rojao-white.png +0 -0
  7. package/dist/chunk-ORMEWXMH.js +37 -0
  8. package/dist/compat/generate.d.ts +6 -0
  9. package/dist/compat/generate.js +1 -0
  10. package/dist/compat/recipes.d.ts +1 -0
  11. package/dist/compat/recipes.js +1 -0
  12. package/dist/compat/themes.d.ts +1 -0
  13. package/dist/compat/themes.js +1 -0
  14. package/dist/compat/tokens.d.ts +1 -0
  15. package/dist/compat/tokens.js +1 -0
  16. package/dist/components/accordion.d.ts +35 -0
  17. package/dist/components/accordion.js +95 -0
  18. package/dist/components/alert.d.ts +24 -0
  19. package/dist/components/alert.js +72 -0
  20. package/dist/components/avatar.d.ts +45 -0
  21. package/dist/components/avatar.js +97 -0
  22. package/dist/components/badge.d.ts +45 -0
  23. package/dist/components/badge.js +114 -0
  24. package/dist/components/blocker-card.d.ts +42 -0
  25. package/dist/components/blocker-card.js +45 -0
  26. package/dist/components/bottom-sheet.d.ts +31 -0
  27. package/dist/components/bottom-sheet.js +120 -0
  28. package/dist/components/breadcrumb.d.ts +28 -0
  29. package/dist/components/breadcrumb.js +52 -0
  30. package/dist/components/button.d.ts +27 -0
  31. package/dist/components/button.js +124 -0
  32. package/dist/components/card.d.ts +27 -0
  33. package/dist/components/card.js +52 -0
  34. package/dist/components/chat-bubble.d.ts +16 -0
  35. package/dist/components/chat-bubble.js +55 -0
  36. package/dist/components/checkbox.d.ts +14 -0
  37. package/dist/components/checkbox.js +78 -0
  38. package/dist/components/chip-input.d.ts +26 -0
  39. package/dist/components/chip-input.js +182 -0
  40. package/dist/components/chips.d.ts +22 -0
  41. package/dist/components/chips.js +94 -0
  42. package/dist/components/choice-card.d.ts +16 -0
  43. package/dist/components/choice-card.js +60 -0
  44. package/dist/components/choice-carousel.d.ts +16 -0
  45. package/dist/components/choice-carousel.js +154 -0
  46. package/dist/components/choice-preview-card.d.ts +37 -0
  47. package/dist/components/choice-preview-card.js +39 -0
  48. package/dist/components/color-input.d.ts +20 -0
  49. package/dist/components/color-input.js +79 -0
  50. package/dist/components/combobox.d.ts +70 -0
  51. package/dist/components/combobox.js +213 -0
  52. package/dist/components/context-menu.d.ts +33 -0
  53. package/dist/components/context-menu.js +70 -0
  54. package/dist/components/copilot-hint.d.ts +18 -0
  55. package/dist/components/copilot-hint.js +63 -0
  56. package/dist/components/copy-field.d.ts +16 -0
  57. package/dist/components/copy-field.js +41 -0
  58. package/dist/components/currency-input.d.ts +32 -0
  59. package/dist/components/currency-input.js +138 -0
  60. package/dist/components/danger-zone.d.ts +20 -0
  61. package/dist/components/danger-zone.js +21 -0
  62. package/dist/components/data-table-header.d.ts +43 -0
  63. package/dist/components/data-table-header.js +205 -0
  64. package/dist/components/date-picker.d.ts +40 -0
  65. package/dist/components/date-picker.js +252 -0
  66. package/dist/components/divider.d.ts +20 -0
  67. package/dist/components/divider.js +47 -0
  68. package/dist/components/drawer.d.ts +26 -0
  69. package/dist/components/drawer.js +82 -0
  70. package/dist/components/dropzone.d.ts +19 -0
  71. package/dist/components/dropzone.js +65 -0
  72. package/dist/components/empty-state.d.ts +48 -0
  73. package/dist/components/empty-state.js +91 -0
  74. package/dist/components/fab.d.ts +38 -0
  75. package/dist/components/fab.js +100 -0
  76. package/dist/components/filter-chip.d.ts +54 -0
  77. package/dist/components/filter-chip.js +66 -0
  78. package/dist/components/floating-stepper.d.ts +44 -0
  79. package/dist/components/floating-stepper.js +53 -0
  80. package/dist/components/form-card-header.d.ts +13 -0
  81. package/dist/components/form-card-header.js +8 -0
  82. package/dist/components/icon-button.d.ts +17 -0
  83. package/dist/components/icon-button.js +80 -0
  84. package/dist/components/image-crop-modal.d.ts +59 -0
  85. package/dist/components/image-crop-modal.js +240 -0
  86. package/dist/components/image-upload.d.ts +72 -0
  87. package/dist/components/image-upload.js +271 -0
  88. package/dist/components/index.d.ts +85 -0
  89. package/dist/components/index.js +200 -0
  90. package/dist/components/input.d.ts +25 -0
  91. package/dist/components/input.js +136 -0
  92. package/dist/components/insight-card.d.ts +19 -0
  93. package/dist/components/insight-card.js +27 -0
  94. package/dist/components/label.d.ts +16 -0
  95. package/dist/components/label.js +43 -0
  96. package/dist/components/media-tile.d.ts +24 -0
  97. package/dist/components/media-tile.js +28 -0
  98. package/dist/components/menu.d.ts +50 -0
  99. package/dist/components/menu.js +80 -0
  100. package/dist/components/modal.d.ts +25 -0
  101. package/dist/components/modal.js +71 -0
  102. package/dist/components/notice.d.ts +50 -0
  103. package/dist/components/notice.js +103 -0
  104. package/dist/components/option-tile.d.ts +60 -0
  105. package/dist/components/option-tile.js +144 -0
  106. package/dist/components/page-shell.d.ts +29 -0
  107. package/dist/components/page-shell.js +36 -0
  108. package/dist/components/page-skeleton.d.ts +35 -0
  109. package/dist/components/page-skeleton.js +12 -0
  110. package/dist/components/page-tabs.d.ts +35 -0
  111. package/dist/components/page-tabs.js +55 -0
  112. package/dist/components/pagination.d.ts +31 -0
  113. package/dist/components/pagination.js +80 -0
  114. package/dist/components/paywall-banner.d.ts +37 -0
  115. package/dist/components/paywall-banner.js +42 -0
  116. package/dist/components/paywall.d.ts +44 -0
  117. package/dist/components/paywall.js +55 -0
  118. package/dist/components/phone-frame.d.ts +9 -0
  119. package/dist/components/phone-frame.js +18 -0
  120. package/dist/components/phone-input.d.ts +24 -0
  121. package/dist/components/phone-input.js +92 -0
  122. package/dist/components/pix-icon.d.ts +8 -0
  123. package/dist/components/pix-icon.js +24 -0
  124. package/dist/components/popover.d.ts +44 -0
  125. package/dist/components/popover.js +140 -0
  126. package/dist/components/pricing-card.d.ts +42 -0
  127. package/dist/components/pricing-card.js +29 -0
  128. package/dist/components/qr-display.d.ts +19 -0
  129. package/dist/components/qr-display.js +24 -0
  130. package/dist/components/radio.d.ts +33 -0
  131. package/dist/components/radio.js +97 -0
  132. package/dist/components/row-actions.d.ts +24 -0
  133. package/dist/components/row-actions.js +76 -0
  134. package/dist/components/saving-bar-context.d.ts +40 -0
  135. package/dist/components/saving-bar-context.js +125 -0
  136. package/dist/components/saving-bar.d.ts +18 -0
  137. package/dist/components/saving-bar.js +72 -0
  138. package/dist/components/search.d.ts +30 -0
  139. package/dist/components/search.js +81 -0
  140. package/dist/components/section-card.d.ts +14 -0
  141. package/dist/components/section-card.js +49 -0
  142. package/dist/components/section-header.d.ts +29 -0
  143. package/dist/components/section-header.js +7 -0
  144. package/dist/components/select.d.ts +21 -0
  145. package/dist/components/select.js +140 -0
  146. package/dist/components/selectable-card.d.ts +35 -0
  147. package/dist/components/selectable-card.js +27 -0
  148. package/dist/components/setting-row.d.ts +33 -0
  149. package/dist/components/setting-row.js +19 -0
  150. package/dist/components/settings-list.d.ts +25 -0
  151. package/dist/components/settings-list.js +22 -0
  152. package/dist/components/skeleton.d.ts +24 -0
  153. package/dist/components/skeleton.js +49 -0
  154. package/dist/components/slider.d.ts +32 -0
  155. package/dist/components/slider.js +79 -0
  156. package/dist/components/spinner.d.ts +14 -0
  157. package/dist/components/spinner.js +36 -0
  158. package/dist/components/step-progress.d.ts +12 -0
  159. package/dist/components/step-progress.js +24 -0
  160. package/dist/components/summary-bar.d.ts +31 -0
  161. package/dist/components/summary-bar.js +54 -0
  162. package/dist/components/table.d.ts +23 -0
  163. package/dist/components/table.js +80 -0
  164. package/dist/components/textarea.d.ts +21 -0
  165. package/dist/components/textarea.js +95 -0
  166. package/dist/components/themed.d.ts +36 -0
  167. package/dist/components/themed.js +22 -0
  168. package/dist/components/time-picker.d.ts +34 -0
  169. package/dist/components/time-picker.js +213 -0
  170. package/dist/components/toaster.d.ts +84 -0
  171. package/dist/components/toaster.js +284 -0
  172. package/dist/components/toggle-card-compact.d.ts +21 -0
  173. package/dist/components/toggle-card-compact.js +99 -0
  174. package/dist/components/toggle-card.d.ts +15 -0
  175. package/dist/components/toggle-card.js +76 -0
  176. package/dist/components/toggle-group.d.ts +67 -0
  177. package/dist/components/toggle-group.js +80 -0
  178. package/dist/components/toggle.d.ts +13 -0
  179. package/dist/components/toggle.js +64 -0
  180. package/dist/components/tooltip.d.ts +17 -0
  181. package/dist/components/tooltip.js +89 -0
  182. package/dist/components/typing-indicator.d.ts +8 -0
  183. package/dist/components/typing-indicator.js +27 -0
  184. package/dist/components/use-dismiss.d.ts +9 -0
  185. package/dist/components/use-dismiss.js +28 -0
  186. package/dist/components/use-focus-trap.d.ts +5 -0
  187. package/dist/components/use-focus-trap.js +54 -0
  188. package/dist/icons/index.d.ts +1 -0
  189. package/dist/icons/index.js +89 -0
  190. package/dist/targets/native/components/accordion.d.ts +18 -0
  191. package/dist/targets/native/components/accordion.js +122 -0
  192. package/dist/targets/native/components/alert.d.ts +16 -0
  193. package/dist/targets/native/components/alert.js +58 -0
  194. package/dist/targets/native/components/avatar.d.ts +25 -0
  195. package/dist/targets/native/components/avatar.js +88 -0
  196. package/dist/targets/native/components/badge.d.ts +27 -0
  197. package/dist/targets/native/components/badge.js +59 -0
  198. package/dist/targets/native/components/button.d.ts +18 -0
  199. package/dist/targets/native/components/button.js +84 -0
  200. package/dist/targets/native/components/card.d.ts +6 -0
  201. package/dist/targets/native/components/card.js +36 -0
  202. package/dist/targets/native/components/checkbox.d.ts +12 -0
  203. package/dist/targets/native/components/checkbox.js +59 -0
  204. package/dist/targets/native/components/chips.d.ts +17 -0
  205. package/dist/targets/native/components/chips.js +77 -0
  206. package/dist/targets/native/components/choice-card.d.ts +11 -0
  207. package/dist/targets/native/components/choice-card.js +52 -0
  208. package/dist/targets/native/components/context-menu.d.ts +11 -0
  209. package/dist/targets/native/components/context-menu.js +19 -0
  210. package/dist/targets/native/components/currency-input.d.ts +22 -0
  211. package/dist/targets/native/components/currency-input.js +105 -0
  212. package/dist/targets/native/components/danger-zone.d.ts +13 -0
  213. package/dist/targets/native/components/danger-zone.js +27 -0
  214. package/dist/targets/native/components/date-picker.d.ts +13 -0
  215. package/dist/targets/native/components/date-picker.js +185 -0
  216. package/dist/targets/native/components/divider.d.ts +9 -0
  217. package/dist/targets/native/components/divider.js +36 -0
  218. package/dist/targets/native/components/empty-state.d.ts +13 -0
  219. package/dist/targets/native/components/empty-state.js +10 -0
  220. package/dist/targets/native/components/fab.d.ts +25 -0
  221. package/dist/targets/native/components/fab.js +112 -0
  222. package/dist/targets/native/components/filter-chip.d.ts +22 -0
  223. package/dist/targets/native/components/filter-chip.js +70 -0
  224. package/dist/targets/native/components/form-field.d.ts +13 -0
  225. package/dist/targets/native/components/form-field.js +29 -0
  226. package/dist/targets/native/components/form-screen.d.ts +19 -0
  227. package/dist/targets/native/components/form-screen.js +88 -0
  228. package/dist/targets/native/components/google-icon.d.ts +8 -0
  229. package/dist/targets/native/components/google-icon.js +32 -0
  230. package/dist/targets/native/components/icon-button.d.ts +18 -0
  231. package/dist/targets/native/components/icon-button.js +80 -0
  232. package/dist/targets/native/components/icon.d.ts +11 -0
  233. package/dist/targets/native/components/icon.js +9 -0
  234. package/dist/targets/native/components/image-upload.d.ts +12 -0
  235. package/dist/targets/native/components/image-upload.js +95 -0
  236. package/dist/targets/native/components/index.d.ts +45 -0
  237. package/dist/targets/native/components/index.js +100 -0
  238. package/dist/targets/native/components/input.d.ts +17 -0
  239. package/dist/targets/native/components/input.js +103 -0
  240. package/dist/targets/native/components/list-item.d.ts +20 -0
  241. package/dist/targets/native/components/list-item.js +71 -0
  242. package/dist/targets/native/components/menu.d.ts +24 -0
  243. package/dist/targets/native/components/menu.js +71 -0
  244. package/dist/targets/native/components/modal.d.ts +15 -0
  245. package/dist/targets/native/components/modal.js +110 -0
  246. package/dist/targets/native/components/paywall-banner.d.ts +11 -0
  247. package/dist/targets/native/components/paywall-banner.js +46 -0
  248. package/dist/targets/native/components/paywall.d.ts +18 -0
  249. package/dist/targets/native/components/paywall.js +61 -0
  250. package/dist/targets/native/components/radio.d.ts +20 -0
  251. package/dist/targets/native/components/radio.js +71 -0
  252. package/dist/targets/native/components/search.d.ts +22 -0
  253. package/dist/targets/native/components/search.js +92 -0
  254. package/dist/targets/native/components/select.d.ts +17 -0
  255. package/dist/targets/native/components/select.js +86 -0
  256. package/dist/targets/native/components/sheet.d.ts +11 -0
  257. package/dist/targets/native/components/sheet.js +51 -0
  258. package/dist/targets/native/components/skeleton.d.ts +18 -0
  259. package/dist/targets/native/components/skeleton.js +52 -0
  260. package/dist/targets/native/components/slider.d.ts +18 -0
  261. package/dist/targets/native/components/slider.js +153 -0
  262. package/dist/targets/native/components/spinner.d.ts +7 -0
  263. package/dist/targets/native/components/spinner.js +10 -0
  264. package/dist/targets/native/components/stepper.d.ts +10 -0
  265. package/dist/targets/native/components/stepper.js +33 -0
  266. package/dist/targets/native/components/switch.d.ts +20 -0
  267. package/dist/targets/native/components/switch.js +68 -0
  268. package/dist/targets/native/components/text.d.ts +12 -0
  269. package/dist/targets/native/components/text.js +31 -0
  270. package/dist/targets/native/components/textarea.d.ts +13 -0
  271. package/dist/targets/native/components/textarea.js +92 -0
  272. package/dist/targets/native/components/theme.d.ts +18 -0
  273. package/dist/targets/native/components/theme.js +20 -0
  274. package/dist/targets/native/components/toaster.d.ts +35 -0
  275. package/dist/targets/native/components/toaster.js +159 -0
  276. package/dist/targets/native/fonts.d.ts +9 -0
  277. package/dist/targets/native/fonts.js +10 -0
  278. package/dist/targets/native/icons.d.ts +1 -0
  279. package/dist/targets/native/icons.js +1 -0
  280. package/dist/targets/native/index.d.ts +3 -0
  281. package/dist/targets/native/index.js +11 -0
  282. package/dist/targets/native/preset.cjs +69 -0
  283. package/dist/targets/native/resolve.d.ts +22 -0
  284. package/dist/targets/native/resolve.js +85 -0
  285. package/dist/targets/native/theme.css +118 -0
  286. package/dist/targets/native/theme.d.ts +117 -0
  287. package/dist/targets/native/theme.js +118 -0
  288. package/package.json +194 -0
  289. package/styles/_primitives.generated.css +284 -0
  290. package/styles/base.css +950 -0
  291. package/styles/themes/rojao.css +107 -0
@@ -0,0 +1,84 @@
1
+ import * as react from 'react';
2
+
3
+ /**
4
+ * Toaster — comportamento de snackbar M3, visual de notification card.
5
+ *
6
+ * Comportamento (M3):
7
+ * • Um por vez (novo substitui o anterior).
8
+ * • Action label OU close icon — não os dois.
9
+ * • Duração: 4s sem action, 7s com action; persistente em loading.
10
+ * • Posição default: bottom-center.
11
+ * • Motion: 150ms ease-out enter, 75ms ease-in exit, slide vertical + fade.
12
+ * • Não rouba foco. aria-live="polite" default, "assertive" pra erro.
13
+ *
14
+ * Visual (notification card):
15
+ * • Card escuro nos DOIS themes (inverse surface, tokens --toast-*).
16
+ * • Feedback variants: tint da cor semântica entra pela esquerda (gradiente)
17
+ * + badge circular sólido com halo — ícone em tom escuro da própria cor.
18
+ * • Título (message) + description opcional em --toast-text-muted.
19
+ * • default/loading: card neutro sem tint nem badge.
20
+ *
21
+ * API:
22
+ * import { toast } from '@rojaostudio/ds/components';
23
+ * toast('Salvo');
24
+ * toast.success('Salvo', { description: 'Pedido #1042 confirmado.' });
25
+ * toast.error('...'), toast.warning('...'), toast.info('...'), toast.loading('...');
26
+ * toast.dismiss(id?);
27
+ * toast.promise(p, { loading, success, error });
28
+ */
29
+ type ToastVariant = 'default' | 'success' | 'error' | 'warning' | 'info' | 'loading';
30
+ type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
31
+ interface ToastOptions {
32
+ variant?: ToastVariant;
33
+ /** Linha secundária — message vira título (semibold) quando presente. */
34
+ description?: string;
35
+ /** ms até auto-dismiss. Omitido → fallback do Material (1500 curto · 2750 com ação/erro · 0 loading). */
36
+ duration?: number;
37
+ action?: {
38
+ label: string;
39
+ onClick: () => void;
40
+ };
41
+ id?: string;
42
+ }
43
+ interface ToastFn {
44
+ (message: string, options?: ToastOptions): string;
45
+ success: (msg: string, opts?: Omit<ToastOptions, 'variant'>) => string;
46
+ error: (msg: string, opts?: Omit<ToastOptions, 'variant'>) => string;
47
+ warning: (msg: string, opts?: Omit<ToastOptions, 'variant'>) => string;
48
+ info: (msg: string, opts?: Omit<ToastOptions, 'variant'>) => string;
49
+ loading: (msg: string, opts?: Omit<ToastOptions, 'variant' | 'duration'>) => string;
50
+ dismiss: (id?: string) => void;
51
+ promise: <T>(promise: Promise<T>, msgs: {
52
+ loading: string;
53
+ success: string | ((data: T) => string);
54
+ error: string | ((err: unknown) => string);
55
+ }) => Promise<T>;
56
+ }
57
+ declare const toast: ToastFn;
58
+ interface ToastVisualProps {
59
+ message: string;
60
+ /** Linha secundária — message vira título (semibold) quando presente. */
61
+ description?: string;
62
+ variant?: ToastVariant;
63
+ action?: {
64
+ label: string;
65
+ onClick?: () => void;
66
+ };
67
+ /** Quando true, renderiza a animação de entrada. default = false. */
68
+ animate?: boolean;
69
+ /** Top vs bottom afeta a direção da animação enter. default = 'bottom'. */
70
+ origin?: 'top' | 'bottom';
71
+ /** Mostra o botão de close (X). default = true se não houver action; M3
72
+ * prescreve action OU close, não ambos. */
73
+ dismissible?: boolean;
74
+ /** Handler do close (opcional). Sem handler, o X aparece mas é decorativo. */
75
+ onDismiss?: () => void;
76
+ }
77
+ declare function ToastVisual({ message, description, variant, action, animate, origin, dismissible, onDismiss, }: ToastVisualProps): react.JSX.Element;
78
+ interface ToasterProps {
79
+ /** Posição. default = bottom-center (M3 recomenda bottom). */
80
+ position?: ToastPosition;
81
+ }
82
+ declare function Toaster({ position }?: ToasterProps): react.ReactPortal | null;
83
+
84
+ export { type ToastOptions, type ToastPosition, type ToastVariant, ToastVisual, type ToastVisualProps, Toaster, type ToasterProps, toast };
@@ -0,0 +1,284 @@
1
+ "use client";
2
+ import {
3
+ __spreadProps,
4
+ __spreadValues
5
+ } from "../chunk-ORMEWXMH.js";
6
+ import { useEffect, useRef, useState, useCallback } from "react";
7
+ import { createPortal } from "react-dom";
8
+ import { Loader2, X, Check, AlertTriangle, Info } from "lucide-react";
9
+ const listeners = /* @__PURE__ */ new Set();
10
+ function emit(a) {
11
+ for (const l of listeners) l(a);
12
+ }
13
+ let counter = 0;
14
+ function genId() {
15
+ counter += 1;
16
+ return `t${Date.now()}_${counter}`;
17
+ }
18
+ function defaultDuration(variant, hasAction) {
19
+ if (variant === "loading") return 0;
20
+ if (hasAction || variant === "error") return 2750;
21
+ return 1500;
22
+ }
23
+ function show(message, options = {}) {
24
+ var _a, _b, _c;
25
+ const id = (_a = options.id) != null ? _a : genId();
26
+ const variant = (_b = options.variant) != null ? _b : "default";
27
+ const hasAction = !!options.action;
28
+ emit({
29
+ type: "show",
30
+ toast: {
31
+ id,
32
+ message,
33
+ description: options.description,
34
+ variant,
35
+ duration: (_c = options.duration) != null ? _c : defaultDuration(variant, hasAction),
36
+ action: options.action
37
+ }
38
+ });
39
+ return id;
40
+ }
41
+ const base = (msg, opts) => show(msg, opts);
42
+ const toast = Object.assign(base, {
43
+ success: (m, o) => show(m, __spreadProps(__spreadValues({}, o), { variant: "success" })),
44
+ error: (m, o) => show(m, __spreadProps(__spreadValues({}, o), { variant: "error" })),
45
+ warning: (m, o) => show(m, __spreadProps(__spreadValues({}, o), { variant: "warning" })),
46
+ info: (m, o) => show(m, __spreadProps(__spreadValues({}, o), { variant: "info" })),
47
+ loading: (m, o) => show(m, __spreadProps(__spreadValues({}, o), { variant: "loading" })),
48
+ dismiss: (id) => {
49
+ if (id) emit({ type: "dismiss", id });
50
+ else listeners.forEach((l) => l({ type: "dismiss", id: "*" }));
51
+ },
52
+ promise: async (promise, msgs) => {
53
+ const id = show(msgs.loading, { variant: "loading" });
54
+ try {
55
+ const data = await promise;
56
+ const m = typeof msgs.success === "function" ? msgs.success(data) : msgs.success;
57
+ emit({ type: "update", id, patch: { variant: "success", message: m, duration: defaultDuration("success", false) } });
58
+ return data;
59
+ } catch (err) {
60
+ const m = typeof msgs.error === "function" ? msgs.error(err) : msgs.error;
61
+ emit({ type: "update", id, patch: { variant: "error", message: m, duration: defaultDuration("error", false) } });
62
+ throw err;
63
+ }
64
+ }
65
+ });
66
+ const VARIANT_COLOR = {
67
+ success: "var(--success)",
68
+ error: "var(--danger)",
69
+ warning: "var(--warning)",
70
+ info: "var(--info)"
71
+ };
72
+ function containerStyle(variant) {
73
+ const c = VARIANT_COLOR[variant];
74
+ return {
75
+ background: c ? `linear-gradient(105deg, color-mix(in srgb, ${c} 16%, var(--toast-bg)) 0%, var(--toast-bg) 60%)` : "var(--toast-bg)",
76
+ color: "var(--toast-text)"
77
+ };
78
+ }
79
+ const VARIANT_ICON = {
80
+ default: null,
81
+ success: Check,
82
+ error: X,
83
+ warning: AlertTriangle,
84
+ info: Info,
85
+ loading: Loader2
86
+ };
87
+ function ToastVisual({
88
+ message,
89
+ description,
90
+ variant = "default",
91
+ action,
92
+ animate = false,
93
+ origin = "bottom",
94
+ dismissible,
95
+ onDismiss
96
+ }) {
97
+ const isError = variant === "error";
98
+ const isLoading = variant === "loading";
99
+ const hasAction = !!action;
100
+ const showClose = dismissible != null ? dismissible : !hasAction && !isLoading;
101
+ const animClass = animate ? origin === "top" ? "rojao-toast--enter-top" : "rojao-toast--enter-bottom" : "";
102
+ return /* @__PURE__ */ React.createElement(
103
+ "div",
104
+ {
105
+ role: isError ? "alert" : "status",
106
+ className: [
107
+ "rojao-toast",
108
+ "flex items-center gap-3 px-4 py-3 shadow-lg",
109
+ "min-w-[344px] max-w-[min(560px,calc(100vw-2rem))]",
110
+ animClass
111
+ ].join(" "),
112
+ style: __spreadProps(__spreadValues({}, containerStyle(variant)), {
113
+ border: "1px solid var(--toast-border)",
114
+ borderRadius: "var(--radius-toast)",
115
+ minHeight: "56px",
116
+ fontFamily: "var(--font-family)"
117
+ })
118
+ },
119
+ (() => {
120
+ const Icon = VARIANT_ICON[variant];
121
+ if (!Icon) return null;
122
+ if (isLoading) {
123
+ return /* @__PURE__ */ React.createElement(
124
+ Icon,
125
+ {
126
+ size: 18,
127
+ className: "shrink-0 animate-spin",
128
+ style: { color: "var(--toast-text-muted)" }
129
+ }
130
+ );
131
+ }
132
+ const c = VARIANT_COLOR[variant];
133
+ return /* @__PURE__ */ React.createElement(
134
+ "span",
135
+ {
136
+ "aria-hidden": "true",
137
+ className: "grid place-items-center rounded-full shrink-0 size-9",
138
+ style: {
139
+ background: c,
140
+ color: `color-mix(in srgb, ${c} 30%, black)`,
141
+ boxShadow: `0 0 0 5px color-mix(in srgb, ${c} 18%, transparent)`
142
+ }
143
+ },
144
+ /* @__PURE__ */ React.createElement(Icon, { size: 18, strokeWidth: 2.75 })
145
+ );
146
+ })(),
147
+ /* @__PURE__ */ React.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React.createElement("p", { className: description ? "text-[0.9375rem] font-semibold leading-snug" : "text-label leading-snug" }, message), description && /* @__PURE__ */ React.createElement("p", { className: "text-label leading-snug mt-0.5", style: { color: "var(--toast-text-muted)" } }, description)),
148
+ hasAction ? /* @__PURE__ */ React.createElement(
149
+ "button",
150
+ {
151
+ type: "button",
152
+ onClick: action.onClick,
153
+ className: "shrink-0 text-label font-medium px-2 -mr-1 transition-opacity hover:opacity-80",
154
+ style: { color: "currentColor" }
155
+ },
156
+ action.label
157
+ ) : showClose && /* @__PURE__ */ React.createElement(
158
+ "button",
159
+ {
160
+ type: "button",
161
+ onClick: onDismiss,
162
+ "aria-label": "Fechar",
163
+ className: "shrink-0 opacity-60 hover:opacity-100 transition-opacity",
164
+ style: { color: "currentColor" }
165
+ },
166
+ /* @__PURE__ */ React.createElement(X, { size: 16 })
167
+ )
168
+ );
169
+ }
170
+ const POSITION_CLASS = {
171
+ "top-left": "top-4 left-4",
172
+ "top-center": "top-4 left-1/2 -translate-x-1/2",
173
+ "top-right": "top-4 right-4",
174
+ "bottom-left": "bottom-4 left-4",
175
+ "bottom-center": "bottom-4 left-1/2 -translate-x-1/2",
176
+ "bottom-right": "bottom-4 right-4"
177
+ };
178
+ function Toaster({ position = "bottom-center" } = {}) {
179
+ const [current, setCurrent] = useState(null);
180
+ const [mounted, setMounted] = useState(false);
181
+ const timerRef = useRef(null);
182
+ useEffect(() => {
183
+ setMounted(true);
184
+ }, []);
185
+ const clearTimer = useCallback(() => {
186
+ if (timerRef.current) {
187
+ clearTimeout(timerRef.current);
188
+ timerRef.current = null;
189
+ }
190
+ }, []);
191
+ const startExit = useCallback((id) => {
192
+ clearTimer();
193
+ setCurrent((prev) => prev && prev.id === id ? __spreadProps(__spreadValues({}, prev), { exiting: true }) : prev);
194
+ setTimeout(() => {
195
+ setCurrent((prev) => prev && prev.id === id ? null : prev);
196
+ }, 75);
197
+ }, [clearTimer]);
198
+ const scheduleDismiss = useCallback((t2) => {
199
+ if (t2.duration <= 0) return;
200
+ timerRef.current = setTimeout(() => startExit(t2.id), t2.duration);
201
+ }, [startExit]);
202
+ const currentRef = useRef(null);
203
+ currentRef.current = current;
204
+ useEffect(() => {
205
+ const listener = (action) => {
206
+ var _a, _b, _c;
207
+ if (action.type === "show") {
208
+ clearTimer();
209
+ setCurrent(action.toast);
210
+ scheduleDismiss(action.toast);
211
+ } else if (action.type === "update") {
212
+ setCurrent((prev) => {
213
+ if (!prev || prev.id !== action.id) return prev;
214
+ const next = __spreadProps(__spreadValues(__spreadValues({}, prev), action.patch), { exiting: false });
215
+ clearTimer();
216
+ if (next.duration > 0) {
217
+ timerRef.current = setTimeout(() => startExit(next.id), next.duration);
218
+ }
219
+ return next;
220
+ });
221
+ } else if (action.type === "dismiss") {
222
+ if (action.id === "*") startExit((_b = (_a = currentRef.current) == null ? void 0 : _a.id) != null ? _b : "");
223
+ else if (((_c = currentRef.current) == null ? void 0 : _c.id) === action.id) startExit(action.id);
224
+ }
225
+ };
226
+ listeners.add(listener);
227
+ return () => {
228
+ listeners.delete(listener);
229
+ clearTimer();
230
+ };
231
+ }, [clearTimer, scheduleDismiss, startExit]);
232
+ const handleMouseEnter = () => clearTimer();
233
+ const handleMouseLeave = () => {
234
+ if (current && !current.exiting) scheduleDismiss(current);
235
+ };
236
+ if (!mounted || !current) return null;
237
+ const t = current;
238
+ const isError = t.variant === "error";
239
+ const ariaLive = isError ? "assertive" : "polite";
240
+ const isTop = position.startsWith("top-");
241
+ const exitClass = t.exiting ? isTop ? "rojao-toast--exit-top" : "rojao-toast--exit-bottom" : "";
242
+ return createPortal(
243
+ /* @__PURE__ */ React.createElement(
244
+ "div",
245
+ {
246
+ "aria-live": ariaLive,
247
+ "aria-atomic": "true",
248
+ className: ["fixed z-[9999] pointer-events-none", POSITION_CLASS[position]].join(" ")
249
+ },
250
+ /* @__PURE__ */ React.createElement(
251
+ "div",
252
+ {
253
+ onMouseEnter: handleMouseEnter,
254
+ onMouseLeave: handleMouseLeave,
255
+ className: ["pointer-events-auto", exitClass].join(" ")
256
+ },
257
+ /* @__PURE__ */ React.createElement(
258
+ ToastVisual,
259
+ {
260
+ message: t.message,
261
+ description: t.description,
262
+ variant: t.variant,
263
+ action: t.action ? {
264
+ label: t.action.label,
265
+ onClick: () => {
266
+ t.action.onClick();
267
+ startExit(t.id);
268
+ }
269
+ } : void 0,
270
+ animate: !t.exiting,
271
+ origin: isTop ? "top" : "bottom",
272
+ onDismiss: () => startExit(t.id)
273
+ }
274
+ )
275
+ )
276
+ ),
277
+ document.body
278
+ );
279
+ }
280
+ export {
281
+ ToastVisual,
282
+ Toaster,
283
+ toast
284
+ };
@@ -0,0 +1,21 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface ToggleCardCompactProps {
5
+ icon?: ReactNode;
6
+ label: string;
7
+ /** Texto mostrado quando OFF. Substituído por `summary` quando ON. */
8
+ description?: ReactNode;
9
+ /** Texto mostrado quando ON (geralmente um resumo da config aplicada). */
10
+ summary?: ReactNode;
11
+ checked: boolean;
12
+ onCheckedChange?: (checked: boolean) => void;
13
+ /** Botão de edição (pencil). Só aparece quando ON. Use para abrir modal de config. */
14
+ onEdit?: () => void;
15
+ editLabel?: string;
16
+ /** Hidden input name — quando presente, submete em forms nativos. */
17
+ name?: string;
18
+ }
19
+ declare function ToggleCardCompact({ icon, label, description, summary, checked, onCheckedChange, onEdit, editLabel, name, }: ToggleCardCompactProps): react.JSX.Element;
20
+
21
+ export { ToggleCardCompact, type ToggleCardCompactProps };
@@ -0,0 +1,99 @@
1
+ "use client";
2
+ import "../chunk-ORMEWXMH.js";
3
+ import { Pencil } from "lucide-react";
4
+ function ToggleCardCompact({
5
+ icon,
6
+ label,
7
+ description,
8
+ summary,
9
+ checked,
10
+ onCheckedChange,
11
+ onEdit,
12
+ editLabel = "Editar",
13
+ name
14
+ }) {
15
+ return /* @__PURE__ */ React.createElement(
16
+ "div",
17
+ {
18
+ className: [
19
+ "rounded-(--radius-card) overflow-hidden transition-colors border",
20
+ checked ? "[border-color:var(--section-card-border-active)]" : "[border-color:var(--section-card-border)]"
21
+ ].join(" ")
22
+ },
23
+ name && /* @__PURE__ */ React.createElement("input", { type: "hidden", name, value: checked ? "on" : "" }),
24
+ /* @__PURE__ */ React.createElement(
25
+ "div",
26
+ {
27
+ className: [
28
+ "flex items-center gap-3 px-4 py-3 transition-colors",
29
+ checked ? "[background:var(--section-card-header-bg-active)]" : ""
30
+ ].join(" ")
31
+ },
32
+ icon && /* @__PURE__ */ React.createElement(
33
+ "span",
34
+ {
35
+ className: [
36
+ "shrink-0",
37
+ checked ? "[color:var(--section-card-label-active)] opacity-80" : "text-(--text-disabled)"
38
+ ].join(" ")
39
+ },
40
+ icon
41
+ ),
42
+ /* @__PURE__ */ React.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React.createElement(
43
+ "p",
44
+ {
45
+ className: [
46
+ "text-caption font-semibold uppercase tracking-wide",
47
+ checked ? "[color:var(--section-card-label-active)]" : "[color:var(--section-card-label)]"
48
+ ].join(" ")
49
+ },
50
+ label
51
+ ), (checked ? summary : description) && /* @__PURE__ */ React.createElement(
52
+ "p",
53
+ {
54
+ className: [
55
+ "text-caption leading-snug mt-0.5 truncate",
56
+ checked ? "[color:var(--section-card-badge-active)]" : "[color:var(--section-card-badge)]"
57
+ ].join(" ")
58
+ },
59
+ checked ? summary : description
60
+ )),
61
+ checked && onEdit && /* @__PURE__ */ React.createElement(
62
+ "button",
63
+ {
64
+ type: "button",
65
+ onClick: onEdit,
66
+ "aria-label": editLabel,
67
+ className: "shrink-0 [color:var(--section-card-label-active)] opacity-70 hover:opacity-100 transition-opacity p-1 -m-1 rounded focus:outline-none focus-visible:ring-2 focus-visible:ring-white/40"
68
+ },
69
+ /* @__PURE__ */ React.createElement(Pencil, { size: 14 })
70
+ ),
71
+ /* @__PURE__ */ React.createElement(
72
+ "button",
73
+ {
74
+ type: "button",
75
+ role: "switch",
76
+ "aria-checked": checked,
77
+ "aria-label": label,
78
+ onClick: () => onCheckedChange == null ? void 0 : onCheckedChange(!checked),
79
+ className: [
80
+ "relative inline-flex shrink-0 h-5 w-9 rounded-full transition-colors focus:outline-none focus-visible:ring-2",
81
+ checked ? "bg-(--surface-default)/30 focus-visible:ring-white/40" : "bg-(--surface-raised) border border-stroke-default focus-visible:ring-stroke-focus/30"
82
+ ].join(" ")
83
+ },
84
+ /* @__PURE__ */ React.createElement(
85
+ "span",
86
+ {
87
+ className: [
88
+ "absolute top-0.5 inline-block h-4 w-4 rounded-full bg-(--surface-default) shadow-sm transition-transform",
89
+ checked ? "translate-x-[18px]" : "translate-x-0.5"
90
+ ].join(" ")
91
+ }
92
+ )
93
+ )
94
+ )
95
+ );
96
+ }
97
+ export {
98
+ ToggleCardCompact
99
+ };
@@ -0,0 +1,15 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface ToggleCardProps {
5
+ label: string;
6
+ description?: string;
7
+ checked: boolean;
8
+ onCheckedChange: (checked: boolean) => void;
9
+ /** Hidden input name — when present, renders a hidden input so the value submits with native forms. */
10
+ name?: string;
11
+ children?: ReactNode;
12
+ }
13
+ declare function ToggleCard({ label, description, checked, onCheckedChange, name, children, }: ToggleCardProps): react.JSX.Element;
14
+
15
+ export { ToggleCard, type ToggleCardProps };
@@ -0,0 +1,76 @@
1
+ "use client";
2
+ import "../chunk-ORMEWXMH.js";
3
+ function ToggleCard({
4
+ label,
5
+ description,
6
+ checked,
7
+ onCheckedChange,
8
+ name,
9
+ children
10
+ }) {
11
+ return /* @__PURE__ */ React.createElement(
12
+ "div",
13
+ {
14
+ className: [
15
+ "rounded-(--radius-card) overflow-hidden transition-colors border",
16
+ checked ? "[border-color:var(--section-card-border-active)]" : "[border-color:var(--section-card-border)]"
17
+ ].join(" ")
18
+ },
19
+ name && /* @__PURE__ */ React.createElement("input", { type: "hidden", name, value: checked ? "on" : "" }),
20
+ /* @__PURE__ */ React.createElement(
21
+ "button",
22
+ {
23
+ type: "button",
24
+ role: "switch",
25
+ "aria-checked": checked,
26
+ onClick: () => onCheckedChange(!checked),
27
+ className: [
28
+ "w-full flex items-center justify-between gap-3 px-4 py-3 text-left transition-colors",
29
+ checked ? "[background:var(--section-card-header-bg-active)]" : "hover:[background:var(--section-card-header-bg-hover)]"
30
+ ].join(" ")
31
+ },
32
+ /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-0.5 min-w-0 flex-1" }, /* @__PURE__ */ React.createElement(
33
+ "span",
34
+ {
35
+ className: [
36
+ "text-caption font-semibold uppercase tracking-wide",
37
+ checked ? "[color:var(--section-card-label-active)]" : "[color:var(--section-card-label)]"
38
+ ].join(" ")
39
+ },
40
+ label
41
+ ), description && /* @__PURE__ */ React.createElement(
42
+ "span",
43
+ {
44
+ className: [
45
+ "text-caption leading-snug",
46
+ checked ? "[color:var(--section-card-badge-active)]" : "[color:var(--section-card-badge)]"
47
+ ].join(" ")
48
+ },
49
+ description
50
+ )),
51
+ /* @__PURE__ */ React.createElement(
52
+ "span",
53
+ {
54
+ "aria-hidden": true,
55
+ className: [
56
+ "relative inline-flex shrink-0 h-5 w-9 rounded-full transition-colors",
57
+ checked ? "bg-(--surface-default)/30" : "bg-(--surface-raised) border border-stroke-default"
58
+ ].join(" ")
59
+ },
60
+ /* @__PURE__ */ React.createElement(
61
+ "span",
62
+ {
63
+ className: [
64
+ "absolute top-0.5 inline-block h-4 w-4 rounded-full bg-(--surface-default) shadow-sm transition-transform",
65
+ checked ? "translate-x-[18px]" : "translate-x-0.5"
66
+ ].join(" ")
67
+ }
68
+ )
69
+ )
70
+ ),
71
+ checked && children && /* @__PURE__ */ React.createElement("div", { className: "px-4 pb-4 pt-4 space-y-4 [border-top:1px_solid_var(--section-card-divider)] [background:var(--surface-default)]" }, children)
72
+ );
73
+ }
74
+ export {
75
+ ToggleCard
76
+ };
@@ -0,0 +1,67 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ /**
5
+ * ToggleGroup — botões segmentados (M3 segmented buttons / shadcn ToggleGroup).
6
+ *
7
+ * Uso (single):
8
+ * <ToggleGroup value={view} onChange={setView} options={[
9
+ * { value: 'day', label: 'Dia' },
10
+ * { value: 'week', label: 'Semana' },
11
+ * { value: 'month', label: 'Mês' },
12
+ * ]} />
13
+ *
14
+ * Uso (multi):
15
+ * <ToggleGroup type="multi" value={selected} onChange={setSelected} options={[
16
+ * { value: 'bold', icon: <Bold /> },
17
+ * { value: 'italic', icon: <Italic /> },
18
+ * ]} />
19
+ */
20
+ interface ToggleOption<T extends string = string> {
21
+ value: T;
22
+ label?: string;
23
+ icon?: ReactNode;
24
+ /** Estilos inline aplicados ao botão — use para fontFamily por opção, etc. */
25
+ style?: React.CSSProperties;
26
+ disabled?: boolean;
27
+ }
28
+ interface ToggleGroupSingleProps<T extends string> {
29
+ type?: 'single';
30
+ /** Label renderada acima do controle (mesmo padrão do Input do DS). */
31
+ label?: ReactNode;
32
+ value: T | null;
33
+ /** null quando allowDeselect=true e o item ativo é clicado novamente. */
34
+ onChange: (value: T | null) => void;
35
+ options: ToggleOption<T>[];
36
+ size?: 'sm' | 'md' | 'lg';
37
+ /** Cor do item selecionado. 'brand' (default) pinta com a cor da marca; 'neutral'
38
+ * usa tinta neutra de alto contraste (surface-invert) — para controles utilitários
39
+ * que não devem vestir a paleta da loja. */
40
+ selectedTone?: 'brand' | 'neutral';
41
+ /** Se permite desselecionar o ativo (clica de novo = null). default = false. */
42
+ allowDeselect?: boolean;
43
+ /** Botões crescem para preencher toda a largura do container. */
44
+ stretch?: boolean;
45
+ className?: string;
46
+ 'aria-label'?: string;
47
+ }
48
+ interface ToggleGroupMultiProps<T extends string> {
49
+ type: 'multi';
50
+ /** Label renderada acima do controle (mesmo padrão do Input do DS). */
51
+ label?: ReactNode;
52
+ value: T[];
53
+ onChange: (value: T[]) => void;
54
+ options: ToggleOption<T>[];
55
+ size?: 'sm' | 'md' | 'lg';
56
+ /** Cor do item selecionado. 'brand' (default) pinta com a cor da marca; 'neutral'
57
+ * usa tinta neutra de alto contraste (surface-invert). */
58
+ selectedTone?: 'brand' | 'neutral';
59
+ /** Botões crescem para preencher toda a largura do container. */
60
+ stretch?: boolean;
61
+ className?: string;
62
+ 'aria-label'?: string;
63
+ }
64
+ type ToggleGroupProps<T extends string = string> = ToggleGroupSingleProps<T> | ToggleGroupMultiProps<T>;
65
+ declare function ToggleGroup<T extends string = string>(props: ToggleGroupProps<T>): react.JSX.Element;
66
+
67
+ export { ToggleGroup, type ToggleGroupProps, type ToggleOption };