@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,136 @@
1
+ "use client";
2
+ import {
3
+ __objRest,
4
+ __spreadValues
5
+ } from "../chunk-ORMEWXMH.js";
6
+ import { forwardRef, useId, useState } from "react";
7
+ import { Eye, EyeOff, X } from "lucide-react";
8
+ const SIZE = {
9
+ sm: { h: "h-control-sm", text: "text-caption", pad: "px-2.5", icon: 14, padIconL: "pl-8", padIconR: "pr-8", affix: "px-2.5" },
10
+ md: { h: "h-control-md", text: "text-label", pad: "px-3", icon: 16, padIconL: "pl-9", padIconR: "pr-9", affix: "px-3" },
11
+ lg: { h: "h-control-lg", text: "text-body", pad: "px-4", icon: 18, padIconL: "pl-11", padIconR: "pr-11", affix: "px-4" }
12
+ };
13
+ const Input = forwardRef(function Input2(_a, ref) {
14
+ var _b = _a, {
15
+ label,
16
+ helper,
17
+ error,
18
+ size = "md",
19
+ required,
20
+ optional,
21
+ iconLeft,
22
+ iconRight,
23
+ prefix,
24
+ suffix,
25
+ clearable,
26
+ onClear,
27
+ passwordReveal = true,
28
+ showCount,
29
+ className = "",
30
+ id,
31
+ type = "text",
32
+ value,
33
+ defaultValue,
34
+ maxLength
35
+ } = _b, props = __objRest(_b, [
36
+ "label",
37
+ "helper",
38
+ "error",
39
+ "size",
40
+ "required",
41
+ "optional",
42
+ "iconLeft",
43
+ "iconRight",
44
+ "prefix",
45
+ "suffix",
46
+ "clearable",
47
+ "onClear",
48
+ "passwordReveal",
49
+ "showCount",
50
+ "className",
51
+ "id",
52
+ "type",
53
+ "value",
54
+ "defaultValue",
55
+ "maxLength"
56
+ ]);
57
+ const generatedId = useId();
58
+ const inputId = id != null ? id : generatedId;
59
+ const [revealed, setRevealed] = useState(false);
60
+ const isPassword = type === "password";
61
+ const effectiveType = isPassword && passwordReveal && revealed ? "text" : type;
62
+ const hasValue = !!(value != null ? value : defaultValue);
63
+ const showClear = clearable && hasValue;
64
+ const showReveal = isPassword && passwordReveal;
65
+ const hasRightAdornment = showClear || showReveal || iconRight;
66
+ const sz = SIZE[size];
67
+ const hasAffix = !!(prefix || suffix);
68
+ const inputRadius = hasAffix ? prefix && suffix ? "rounded-none" : prefix ? "rounded-l-none rounded-r-(--radius-control)" : "rounded-l-(--radius-control) rounded-r-none" : "rounded-(--radius-control)";
69
+ const errorClass = error ? "border-danger focus:border-danger focus:ring-2 focus:ring-danger/20" : "border-stroke-control focus:border-stroke-focus focus:ring-2 focus:ring-stroke-focus/20";
70
+ const inputElement = /* @__PURE__ */ React.createElement("div", { className: "relative flex-1 inline-flex items-center" }, iconLeft && /* @__PURE__ */ React.createElement(
71
+ "span",
72
+ {
73
+ "aria-hidden": true,
74
+ className: "absolute left-0 inset-y-0 flex items-center pl-3 text-fg-muted pointer-events-none"
75
+ },
76
+ /* @__PURE__ */ React.createElement("span", { className: "[&_svg]:shrink-0", style: { width: sz.icon, height: sz.icon } }, iconLeft)
77
+ ), /* @__PURE__ */ React.createElement(
78
+ "input",
79
+ __spreadValues({
80
+ ref,
81
+ id: inputId,
82
+ type: effectiveType,
83
+ value,
84
+ defaultValue,
85
+ maxLength,
86
+ required,
87
+ className: [
88
+ "w-full bg-surface-default text-fg-primary placeholder:text-fg-placeholder",
89
+ "border transition-colors outline-none",
90
+ inputRadius,
91
+ sz.h,
92
+ sz.text,
93
+ sz.pad,
94
+ iconLeft ? sz.padIconL : "",
95
+ hasRightAdornment ? sz.padIconR : "",
96
+ errorClass,
97
+ "disabled:opacity-50 disabled:cursor-not-allowed",
98
+ className
99
+ ].filter(Boolean).join(" "),
100
+ "aria-invalid": error ? true : void 0,
101
+ "aria-describedby": error ? `${inputId}-error` : helper ? `${inputId}-helper` : void 0
102
+ }, props)
103
+ ), hasRightAdornment && /* @__PURE__ */ React.createElement("span", { className: "absolute right-0 inset-y-0 flex items-center pr-2 gap-1 pointer-events-none" }, iconRight && !showClear && !showReveal && /* @__PURE__ */ React.createElement("span", { className: "text-fg-muted" }, iconRight), showClear && /* @__PURE__ */ React.createElement(
104
+ "button",
105
+ {
106
+ type: "button",
107
+ onClick: onClear,
108
+ "aria-label": "Limpar",
109
+ className: "text-fg-muted hover:text-fg-primary p-0.5 rounded transition-colors pointer-events-auto"
110
+ },
111
+ /* @__PURE__ */ React.createElement(X, { size: sz.icon - 2 })
112
+ ), showReveal && /* @__PURE__ */ React.createElement(
113
+ "button",
114
+ {
115
+ type: "button",
116
+ onClick: () => setRevealed((r) => !r),
117
+ "aria-label": revealed ? "Ocultar senha" : "Mostrar senha",
118
+ className: "text-fg-muted hover:text-fg-primary p-1 rounded bg-surface-default transition-colors pointer-events-auto"
119
+ },
120
+ revealed ? /* @__PURE__ */ React.createElement(EyeOff, { size: sz.icon }) : /* @__PURE__ */ React.createElement(Eye, { size: sz.icon })
121
+ )));
122
+ const wrappedInput = hasAffix ? /* @__PURE__ */ React.createElement("div", { className: "inline-flex w-full items-stretch" }, prefix && /* @__PURE__ */ React.createElement("span", { className: [
123
+ "inline-flex items-center border border-r-0 border-stroke-control rounded-l-(--radius-control) bg-surface-raised text-fg-muted",
124
+ sz.text,
125
+ sz.affix
126
+ ].join(" ") }, prefix), inputElement, suffix && /* @__PURE__ */ React.createElement("span", { className: [
127
+ "inline-flex items-center border border-l-0 border-stroke-control rounded-r-(--radius-control) bg-surface-raised text-fg-muted",
128
+ sz.text,
129
+ sz.affix
130
+ ].join(" ") }, suffix)) : inputElement;
131
+ const currentLength = typeof value === "string" ? value.length : typeof defaultValue === "string" ? defaultValue.length : 0;
132
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-1.5 w-full" }, label && /* @__PURE__ */ React.createElement("label", { htmlFor: inputId, className: "inline-flex items-center gap-1 text-label font-medium text-fg-primary" }, /* @__PURE__ */ React.createElement("span", null, label), required && /* @__PURE__ */ React.createElement("span", { className: "text-danger", "aria-label": "obrigat\xF3rio" }, "*"), optional && !required && /* @__PURE__ */ React.createElement("span", { className: "text-fg-muted font-normal" }, "(opcional)")), wrappedInput, (error || helper || showCount && maxLength) && /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-3" }, error ? /* @__PURE__ */ React.createElement("p", { id: `${inputId}-error`, className: "text-caption text-danger-text flex-1" }, error) : helper ? /* @__PURE__ */ React.createElement("p", { id: `${inputId}-helper`, className: "text-caption text-fg-muted flex-1" }, helper) : /* @__PURE__ */ React.createElement("span", { className: "flex-1" }), showCount && maxLength && /* @__PURE__ */ React.createElement("span", { className: "text-caption text-fg-muted tabular-nums shrink-0" }, currentLength, "/", maxLength)));
133
+ });
134
+ export {
135
+ Input
136
+ };
@@ -0,0 +1,19 @@
1
+ import * as react from 'react';
2
+
3
+ type InsightCardType = 'alert' | 'opportunity' | 'tip';
4
+ interface InsightCardProps {
5
+ type: InsightCardType;
6
+ title: string;
7
+ description: string;
8
+ /** Optional numeric/text highlight, e.g. "+ R$ 450/mês" */
9
+ potential?: string;
10
+ /** CTA label */
11
+ action?: string;
12
+ /** CTA href — renders an <a> tag */
13
+ actionHref?: string;
14
+ /** CTA onClick — renders a <button> (takes precedence over actionHref when both provided) */
15
+ actionOnClick?: () => void;
16
+ }
17
+ declare function InsightCard({ type, title, description, potential, action, actionHref, actionOnClick, }: InsightCardProps): react.JSX.Element;
18
+
19
+ export { InsightCard, type InsightCardProps, type InsightCardType };
@@ -0,0 +1,27 @@
1
+ import "../chunk-ORMEWXMH.js";
2
+ const TYPE_VARS = {
3
+ alert: { card: "[border-color:var(--insight-alert-border)] [background:var(--insight-alert-bg)]", badge: "[background:var(--insight-alert-badge-bg)] [color:var(--insight-alert-badge-text)]" },
4
+ opportunity: { card: "[border-color:var(--insight-opportunity-border)] [background:var(--insight-opportunity-bg)]", badge: "[background:var(--insight-opportunity-badge-bg)] [color:var(--insight-opportunity-badge-text)]" },
5
+ tip: { card: "[border-color:var(--insight-tip-border)] [background:var(--insight-tip-bg)]", badge: "[background:var(--insight-tip-badge-bg)] [color:var(--insight-tip-badge-text)]" }
6
+ };
7
+ const TYPE_LABELS = {
8
+ alert: "Aten\xE7\xE3o",
9
+ opportunity: "Oportunidade",
10
+ tip: "Dica"
11
+ };
12
+ function InsightCard({
13
+ type,
14
+ title,
15
+ description,
16
+ potential,
17
+ action,
18
+ actionHref,
19
+ actionOnClick
20
+ }) {
21
+ const v = TYPE_VARS[type];
22
+ const ctaClass = "shrink-0 rounded-(--radius-card) px-3 py-1.5 text-caption font-medium whitespace-nowrap shadow-sm transition-colors [background:var(--insight-action-bg)] [border:1px_solid_var(--insight-action-border)] [color:var(--insight-action-text)] hover:[background:var(--insight-action-bg-hover)]";
23
+ return /* @__PURE__ */ React.createElement("div", { className: ["rounded-(--radius-card) border p-4", v.card].join(" ") }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("span", { className: ["inline-block text-[10px] font-semibold uppercase tracking-wide rounded px-1.5 py-0.5", v.badge].join(" ") }, TYPE_LABELS[type]), /* @__PURE__ */ React.createElement("div", { className: "mt-1.5 flex items-baseline gap-2 flex-wrap" }, /* @__PURE__ */ React.createElement("p", { className: "font-semibold text-label leading-tight [color:var(--insight-title-color)]" }, title), potential && /* @__PURE__ */ React.createElement("span", { className: "text-caption font-medium tabular-nums [color:var(--insight-potential-color)]" }, potential)), /* @__PURE__ */ React.createElement("p", { className: "mt-0.5 text-caption [color:var(--insight-description-color)]" }, description)), action && (actionOnClick ? /* @__PURE__ */ React.createElement("button", { type: "button", onClick: actionOnClick, className: ctaClass }, action) : actionHref ? /* @__PURE__ */ React.createElement("a", { href: actionHref, className: ctaClass }, action) : null)));
24
+ }
25
+ export {
26
+ InsightCard
27
+ };
@@ -0,0 +1,16 @@
1
+ import * as react from 'react';
2
+ import { LabelHTMLAttributes, ReactNode } from 'react';
3
+
4
+ interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {
5
+ /** Mostra `*` vermelho indicando obrigatório. */
6
+ required?: boolean;
7
+ /** Mostra `(opcional)` em cinza. */
8
+ optional?: boolean;
9
+ /** Tooltip helper — renderiza ícone "?" com title nativo. */
10
+ tooltip?: string;
11
+ size?: 'sm' | 'md';
12
+ children: ReactNode;
13
+ }
14
+ declare function Label({ required, optional, tooltip, size, className, children, ...rest }: LabelProps): react.JSX.Element;
15
+
16
+ export { Label, type LabelProps };
@@ -0,0 +1,43 @@
1
+ import {
2
+ __objRest,
3
+ __spreadValues
4
+ } from "../chunk-ORMEWXMH.js";
5
+ import { HelpCircle } from "lucide-react";
6
+ const SIZE_CLASS = {
7
+ sm: "text-caption",
8
+ md: "text-label"
9
+ };
10
+ function Label(_a) {
11
+ var _b = _a, {
12
+ required,
13
+ optional,
14
+ tooltip,
15
+ size = "md",
16
+ className = "",
17
+ children
18
+ } = _b, rest = __objRest(_b, [
19
+ "required",
20
+ "optional",
21
+ "tooltip",
22
+ "size",
23
+ "className",
24
+ "children"
25
+ ]);
26
+ return /* @__PURE__ */ React.createElement(
27
+ "label",
28
+ __spreadValues({
29
+ className: [
30
+ "inline-flex items-center gap-1.5 font-medium text-fg-primary leading-none",
31
+ SIZE_CLASS[size],
32
+ className
33
+ ].join(" ")
34
+ }, rest),
35
+ /* @__PURE__ */ React.createElement("span", null, children),
36
+ required && /* @__PURE__ */ React.createElement("span", { className: "text-danger", "aria-label": "obrigat\xF3rio" }, "*"),
37
+ optional && !required && /* @__PURE__ */ React.createElement("span", { className: "text-fg-muted font-normal" }, "(opcional)"),
38
+ tooltip && /* @__PURE__ */ React.createElement("span", { title: tooltip, className: "inline-flex text-fg-muted cursor-help", "aria-label": tooltip }, /* @__PURE__ */ React.createElement(HelpCircle, { size: 13 }))
39
+ );
40
+ }
41
+ export {
42
+ Label
43
+ };
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ /**
5
+ * MediaTile — miniatura de mídia (produto, imagem) com fallback e label opcional.
6
+ * Substitui o `<div className="rounded-xl border overflow-hidden">` + `<img>`/fallback
7
+ * reimplementado em listas/grids. Agnóstico de framework: usa `<img>` nativo
8
+ * (o consumidor que quiser next/image passa via `image` slot).
9
+ */
10
+ interface MediaTileProps {
11
+ src?: string | null;
12
+ alt?: string;
13
+ /** Conteúdo de imagem custom (ex: next/image). Tem precedência sobre `src`. */
14
+ image?: ReactNode;
15
+ label?: ReactNode;
16
+ /** Se passado, o tile vira um link de navegação. */
17
+ href?: string;
18
+ fallback?: ReactNode;
19
+ aspect?: 'square' | 'video';
20
+ className?: string;
21
+ }
22
+ declare function MediaTile({ src, alt, image, label, href, fallback, aspect, className }: MediaTileProps): react.JSX.Element;
23
+
24
+ export { MediaTile, type MediaTileProps };
@@ -0,0 +1,28 @@
1
+ import "../chunk-ORMEWXMH.js";
2
+ import { ImageOff } from "lucide-react";
3
+ const ASPECT = {
4
+ square: "aspect-square",
5
+ video: "aspect-video"
6
+ };
7
+ function MediaTile({ src, alt = "", image, label, href, fallback, aspect = "square", className = "" }) {
8
+ const Wrapper = href ? "a" : "div";
9
+ return /* @__PURE__ */ React.createElement(
10
+ Wrapper,
11
+ {
12
+ href,
13
+ className: [
14
+ "group flex flex-col rounded-(--radius-card) overflow-hidden border border-stroke-default bg-surface-default transition-all",
15
+ href ? "hover:shadow-md hover:ring-2 hover:ring-stroke-focus cursor-pointer" : "",
16
+ className
17
+ ].filter(Boolean).join(" ")
18
+ },
19
+ /* @__PURE__ */ React.createElement("div", { className: `relative w-full ${ASPECT[aspect]} bg-surface-raised overflow-hidden` }, image ? image : src ? (
20
+ // eslint-disable-next-line @next/next/no-img-element
21
+ /* @__PURE__ */ React.createElement("img", { src, alt, className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" })
22
+ ) : /* @__PURE__ */ React.createElement("div", { className: "w-full h-full flex items-center justify-center text-fg-disabled" }, fallback != null ? fallback : /* @__PURE__ */ React.createElement(ImageOff, { className: "size-5", strokeWidth: 1.5 }))),
23
+ label != null && /* @__PURE__ */ React.createElement("div", { className: "p-1.5" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-medium text-fg-primary line-clamp-2 leading-snug" }, label))
24
+ );
25
+ }
26
+ export {
27
+ MediaTile
28
+ };
@@ -0,0 +1,50 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ export { ChevronRight as MenuChevron } from 'lucide-react';
4
+ import { PopoverPlacement } from './popover.js';
5
+
6
+ /**
7
+ * Menu — popover de ações (DropdownMenu). Inspirado em M3 Menu / shadcn DropdownMenu.
8
+ *
9
+ * Uso:
10
+ * <Menu trigger={<IconButton icon={<MoreVertical />} aria-label="Ações" />}>
11
+ * {({ close }) => (
12
+ * <>
13
+ * <MenuItem icon={<Edit />} onClick={() => { edit(); close(); }}>Editar</MenuItem>
14
+ * <MenuItem icon={<Copy />} onClick={...}>Duplicar</MenuItem>
15
+ * <MenuSeparator />
16
+ * <MenuItem icon={<Trash />} variant="danger" onClick={...}>Excluir</MenuItem>
17
+ * </>
18
+ * )}
19
+ * </Menu>
20
+ */
21
+ interface MenuProps {
22
+ trigger: ReactNode;
23
+ children: ReactNode | ((api: {
24
+ close: () => void;
25
+ }) => ReactNode);
26
+ placement?: PopoverPlacement;
27
+ /** Largura mínima em px. default = 180. */
28
+ minWidth?: number;
29
+ className?: string;
30
+ open?: boolean;
31
+ onOpenChange?: (open: boolean) => void;
32
+ }
33
+ declare function Menu({ trigger, children, placement, minWidth, className, open, onOpenChange, }: MenuProps): react.JSX.Element;
34
+ interface MenuItemProps {
35
+ children: ReactNode;
36
+ icon?: ReactNode;
37
+ /** Ícone à direita (ex: ChevronRight pra submenu, atalho de teclado). */
38
+ trailing?: ReactNode;
39
+ variant?: 'default' | 'danger';
40
+ disabled?: boolean;
41
+ selected?: boolean;
42
+ onClick?: () => void;
43
+ }
44
+ declare function MenuItem({ children, icon, trailing, variant, disabled, selected, onClick, }: MenuItemProps): react.JSX.Element;
45
+ declare function MenuSeparator(): react.JSX.Element;
46
+ declare function MenuLabel({ children }: {
47
+ children: ReactNode;
48
+ }): react.JSX.Element;
49
+
50
+ export { Menu, MenuItem, type MenuItemProps, MenuLabel, type MenuProps, MenuSeparator };
@@ -0,0 +1,80 @@
1
+ "use client";
2
+ import "../chunk-ORMEWXMH.js";
3
+ import { Check, ChevronRight } from "lucide-react";
4
+ import { Popover } from "./popover.js";
5
+ function Menu({
6
+ trigger,
7
+ children,
8
+ placement = "bottom-start",
9
+ minWidth = 180,
10
+ className = "",
11
+ open,
12
+ onOpenChange
13
+ }) {
14
+ return /* @__PURE__ */ React.createElement(
15
+ Popover,
16
+ {
17
+ trigger,
18
+ placement,
19
+ open,
20
+ onOpenChange,
21
+ offset: 4
22
+ },
23
+ (api) => /* @__PURE__ */ React.createElement(
24
+ "div",
25
+ {
26
+ role: "menu",
27
+ className: [
28
+ "rounded-(--radius-card) border border-stroke-default bg-surface-default shadow-lg",
29
+ "py-1",
30
+ className
31
+ ].join(" "),
32
+ style: { minWidth }
33
+ },
34
+ typeof children === "function" ? children(api) : children
35
+ )
36
+ );
37
+ }
38
+ function MenuItem({
39
+ children,
40
+ icon,
41
+ trailing,
42
+ variant = "default",
43
+ disabled = false,
44
+ selected = false,
45
+ onClick
46
+ }) {
47
+ const colorClass = variant === "danger" ? "text-danger-text hover:bg-danger-soft" : "text-fg-primary hover:bg-surface-raised";
48
+ return /* @__PURE__ */ React.createElement(
49
+ "button",
50
+ {
51
+ type: "button",
52
+ role: "menuitem",
53
+ onClick: disabled ? void 0 : onClick,
54
+ disabled,
55
+ className: [
56
+ "w-full flex items-center gap-2.5 px-3 py-1.5 text-label text-left transition-colors",
57
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-stroke-focus focus-visible:ring-inset focus-visible:bg-surface-raised",
58
+ "disabled:cursor-not-allowed disabled:opacity-50",
59
+ colorClass
60
+ ].join(" ")
61
+ },
62
+ icon && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 [&_svg]:size-4" }, icon),
63
+ /* @__PURE__ */ React.createElement("span", { className: "flex-1 truncate" }, children),
64
+ selected && /* @__PURE__ */ React.createElement(Check, { size: 14, className: "shrink-0 text-fg-muted" }),
65
+ trailing && !selected && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 text-fg-muted" }, trailing)
66
+ );
67
+ }
68
+ function MenuSeparator() {
69
+ return /* @__PURE__ */ React.createElement("div", { role: "separator", className: "h-px bg-stroke-subtle my-1" });
70
+ }
71
+ function MenuLabel({ children }) {
72
+ return /* @__PURE__ */ React.createElement("div", { className: "px-3 py-1 text-[11px] font-semibold uppercase tracking-wider text-fg-muted" }, children);
73
+ }
74
+ export {
75
+ Menu,
76
+ ChevronRight as MenuChevron,
77
+ MenuItem,
78
+ MenuLabel,
79
+ MenuSeparator
80
+ };
@@ -0,0 +1,25 @@
1
+ import * as react from 'react';
2
+
3
+ interface ModalProps {
4
+ open: boolean;
5
+ onClose: () => void;
6
+ title?: React.ReactNode;
7
+ /** Subtítulo opcional abaixo do title. */
8
+ subtitle?: React.ReactNode;
9
+ children: React.ReactNode;
10
+ footer?: React.ReactNode;
11
+ /** Ação no canto direito do header (ex.: link ghost), renderizada antes do X. */
12
+ headerAction?: React.ReactNode;
13
+ size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
14
+ /** Fecha ao clicar no backdrop. default = true. */
15
+ closeOnBackdrop?: boolean;
16
+ /** Esconde o botão X do header. default = false. */
17
+ hideClose?: boolean;
18
+ className?: string;
19
+ /** Alvo do portal. default = document.body. Passe um elemento de um subtree TEMATIZADO (ex.: a
20
+ * raiz do tema da loja) pra o modal herdar tokens/mode/fonte daquele contexto em vez do global. */
21
+ container?: Element | null;
22
+ }
23
+ declare function Modal({ open, onClose, title, subtitle, children, footer, headerAction, size, closeOnBackdrop, hideClose, className, container }: ModalProps): react.ReactPortal | null;
24
+
25
+ export { Modal, type ModalProps };
@@ -0,0 +1,71 @@
1
+ "use client";
2
+ import "../chunk-ORMEWXMH.js";
3
+ import { useEffect, useId, useState } from "react";
4
+ import { X } from "lucide-react";
5
+ import { createPortal } from "react-dom";
6
+ import { useFocusTrap } from "./use-focus-trap.js";
7
+ const sizes = {
8
+ sm: "max-w-sm",
9
+ md: "max-w-lg",
10
+ lg: "max-w-2xl",
11
+ xl: "max-w-4xl",
12
+ full: "max-w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)]"
13
+ };
14
+ function Modal({ open, onClose, title, subtitle, children, footer, headerAction, size = "md", closeOnBackdrop = true, hideClose = false, className = "", container }) {
15
+ const titleId = useId();
16
+ const dialogRef = useFocusTrap(open);
17
+ const [mounted, setMounted] = useState(false);
18
+ useEffect(() => {
19
+ setMounted(true);
20
+ }, []);
21
+ useEffect(() => {
22
+ if (!open) return;
23
+ const prev = document.body.style.overflow;
24
+ document.body.style.overflow = "hidden";
25
+ const onKey = (e) => {
26
+ if (e.key === "Escape") onClose();
27
+ };
28
+ document.addEventListener("keydown", onKey);
29
+ return () => {
30
+ document.body.style.overflow = prev;
31
+ document.removeEventListener("keydown", onKey);
32
+ };
33
+ }, [open, onClose]);
34
+ if (!open) return null;
35
+ if (!mounted) return null;
36
+ return createPortal(
37
+ /* @__PURE__ */ React.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4" }, /* @__PURE__ */ React.createElement("div", { className: "fixed inset-0 [background:var(--overlay-scrim)]", onClick: closeOnBackdrop ? onClose : void 0, "aria-hidden": "true" }), /* @__PURE__ */ React.createElement(
38
+ "div",
39
+ {
40
+ ref: dialogRef,
41
+ role: "dialog",
42
+ "aria-modal": "true",
43
+ "aria-labelledby": title ? titleId : void 0,
44
+ tabIndex: -1,
45
+ className: [
46
+ "relative z-10 w-full rounded-(--radius-card) bg-surface-default shadow-xl",
47
+ "flex flex-col max-h-[90dvh]",
48
+ "focus:outline-none",
49
+ sizes[size],
50
+ className
51
+ ].join(" ")
52
+ },
53
+ (title || headerAction || !hideClose) && /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-4 px-6 py-4 border-b border-stroke-default shrink-0" }, /* @__PURE__ */ React.createElement("div", { className: "flex-1 min-w-0" }, title && /* @__PURE__ */ React.createElement("h2", { id: titleId, className: "text-body font-semibold text-fg-primary" }, title), subtitle && /* @__PURE__ */ React.createElement("p", { className: "text-label text-fg-muted mt-0.5" }, subtitle)), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 shrink-0" }, headerAction, !hideClose && /* @__PURE__ */ React.createElement(
54
+ "button",
55
+ {
56
+ type: "button",
57
+ onClick: onClose,
58
+ className: "text-fg-muted hover:text-fg-primary transition-colors rounded focus-visible:ring-2 focus-visible:ring-stroke-focus focus-visible:outline-none p-0.5",
59
+ "aria-label": "Fechar"
60
+ },
61
+ /* @__PURE__ */ React.createElement(X, { size: 20 })
62
+ ))),
63
+ /* @__PURE__ */ React.createElement("div", { className: "flex-1 overflow-y-auto px-6 py-4" }, children),
64
+ footer && /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-end gap-3 px-6 py-4 border-t border-stroke-default shrink-0" }, footer)
65
+ )),
66
+ container != null ? container : document.body
67
+ );
68
+ }
69
+ export {
70
+ Modal
71
+ };
@@ -0,0 +1,50 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, ComponentType } from 'react';
3
+
4
+ /**
5
+ * Notice — aviso contextual com escala de SEVERIDADE real. Unifica a linguagem visual
6
+ * que antes estava fatiada por ORIGEM (CopilotHint cinza vs PaywallBanner vermelho),
7
+ * o que invertia a hierarquia: o aviso mais grave (operacional) ficava no componente
8
+ * mais discreto. Aqui a cor segue a gravidade, não quem emitiu.
9
+ *
10
+ * Dois eixos ortogonais:
11
+ * - `severity` (perceptual): info | success | warning | critical → cor/ícone/peso.
12
+ * - `intent` (semântico): operational | commercial → só troca o ícone default
13
+ * (commercial = cadeado de plano) e a telemetria; NÃO muda a cor.
14
+ *
15
+ * Regra de severidade = CUSTO DE IGNORAR, não a fonte. "Loja não recebe pedidos"
16
+ * (trava a venda) é `critical`; "limite do plano" (a loja segue vendendo) é `warning`.
17
+ *
18
+ * Consome só a família semântica de feedback (danger/warning/info/success) do base.css
19
+ * — zero cor hardcoded. Acessível: role/aria-live por severidade + ícone (cor nunca é
20
+ * o único canal). Crítico é não-dispensável por definição.
21
+ */
22
+ type NoticeSeverity = 'info' | 'success' | 'warning' | 'critical';
23
+ type NoticeIntent = 'operational' | 'commercial';
24
+ interface NoticeProps {
25
+ severity: NoticeSeverity;
26
+ title: string;
27
+ description?: ReactNode;
28
+ intent?: NoticeIntent;
29
+ cta?: {
30
+ label: string;
31
+ href?: string;
32
+ onClick?: () => void;
33
+ };
34
+ /** Component de link (next/link em apps Next). */
35
+ linkAs?: ComponentType<{
36
+ href: string;
37
+ className?: string;
38
+ children: ReactNode;
39
+ }>;
40
+ /** Dispensável: ignorado quando severity='critical' (crítico nunca some). Precisa de `id`. */
41
+ dismissible?: boolean;
42
+ /** Chave de dispensa (localStorage). Re-key pela condição (ex: `zeroStock:7`) pra reaparecer quando piora. */
43
+ id?: string;
44
+ /** aria-label do botão dispensar (i18n pelo caller). */
45
+ dismissLabel?: string;
46
+ className?: string;
47
+ }
48
+ declare function Notice({ severity, title, description, intent, cta, linkAs: LinkAs, dismissible, id, dismissLabel, className, }: NoticeProps): react.JSX.Element | null;
49
+
50
+ export { Notice, type NoticeIntent, type NoticeProps, type NoticeSeverity };