@rojaostudio/ds 1.0.0 → 1.0.2

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 (134) hide show
  1. package/dist/components/accordion.js +43 -37
  2. package/dist/components/alert.js +35 -28
  3. package/dist/components/avatar.js +41 -34
  4. package/dist/components/badge.js +21 -14
  5. package/dist/components/blocker-card.js +11 -2
  6. package/dist/components/bottom-sheet.js +60 -53
  7. package/dist/components/breadcrumb.js +32 -22
  8. package/dist/components/button.js +18 -11
  9. package/dist/components/card.js +24 -9
  10. package/dist/components/chat-bubble.js +6 -5
  11. package/dist/components/checkbox.js +61 -48
  12. package/dist/components/chip-input.js +98 -81
  13. package/dist/components/chips.js +36 -29
  14. package/dist/components/choice-card.js +48 -42
  15. package/dist/components/choice-carousel.js +79 -74
  16. package/dist/components/choice-preview-card.js +17 -6
  17. package/dist/components/color-input.js +41 -35
  18. package/dist/components/combobox.js +97 -75
  19. package/dist/components/context-menu.js +17 -13
  20. package/dist/components/copilot-hint.js +40 -31
  21. package/dist/components/copy-field.js +8 -5
  22. package/dist/components/currency-input.js +40 -32
  23. package/dist/components/danger-zone.js +19 -9
  24. package/dist/components/data-table-header.js +185 -135
  25. package/dist/components/date-picker.js +114 -95
  26. package/dist/components/divider.js +11 -8
  27. package/dist/components/drawer.js +40 -28
  28. package/dist/components/dropzone.js +23 -20
  29. package/dist/components/empty-state.js +26 -23
  30. package/dist/components/fab.js +38 -26
  31. package/dist/components/filter-chip.js +20 -16
  32. package/dist/components/floating-stepper.js +42 -32
  33. package/dist/components/form-card-header.js +9 -1
  34. package/dist/components/icon-button.js +19 -13
  35. package/dist/components/image-crop-modal.js +69 -48
  36. package/dist/components/image-upload.js +172 -128
  37. package/dist/components/input.js +90 -62
  38. package/dist/components/insight-card.js +12 -1
  39. package/dist/components/label.js +12 -7
  40. package/dist/components/media-tile.js +11 -8
  41. package/dist/components/menu.js +28 -25
  42. package/dist/components/modal.js +43 -28
  43. package/dist/components/notice.js +34 -16
  44. package/dist/components/option-tile.js +55 -49
  45. package/dist/components/page-shell.js +13 -6
  46. package/dist/components/page-skeleton.js +32 -2
  47. package/dist/components/page-tabs.js +39 -26
  48. package/dist/components/pagination.js +38 -33
  49. package/dist/components/paywall-banner.js +19 -3
  50. package/dist/components/paywall.js +18 -8
  51. package/dist/components/phone-frame.js +5 -4
  52. package/dist/components/phone-input.js +50 -31
  53. package/dist/components/pix-icon.js +11 -6
  54. package/dist/components/popover.js +27 -23
  55. package/dist/components/pricing-card.js +16 -1
  56. package/dist/components/qr-display.js +16 -11
  57. package/dist/components/radio.js +73 -56
  58. package/dist/components/row-actions.js +61 -53
  59. package/dist/components/saving-bar-context.js +35 -29
  60. package/dist/components/saving-bar.js +36 -33
  61. package/dist/components/search.js +49 -44
  62. package/dist/components/section-card.js +43 -35
  63. package/dist/components/section-header.js +11 -1
  64. package/dist/components/select.js +83 -62
  65. package/dist/components/selectable-card.js +10 -3
  66. package/dist/components/setting-row.js +11 -1
  67. package/dist/components/settings-list.js +9 -5
  68. package/dist/components/skeleton.js +6 -5
  69. package/dist/components/slider.js +52 -38
  70. package/dist/components/spinner.js +18 -12
  71. package/dist/components/step-progress.js +11 -10
  72. package/dist/components/summary-bar.js +33 -28
  73. package/dist/components/table.js +20 -15
  74. package/dist/components/textarea.js +40 -24
  75. package/dist/components/themed.d.ts +1 -1
  76. package/dist/components/themed.js +2 -1
  77. package/dist/components/time-picker.js +117 -97
  78. package/dist/components/toaster.js +80 -74
  79. package/dist/components/toggle-card-compact.js +79 -71
  80. package/dist/components/toggle-card.js +61 -53
  81. package/dist/components/toggle-group.js +35 -29
  82. package/dist/components/toggle.js +46 -36
  83. package/dist/components/tooltip.js +30 -25
  84. package/dist/components/typing-indicator.js +10 -7
  85. package/dist/targets/native/components/accordion.js +31 -25
  86. package/dist/targets/native/components/alert.js +22 -16
  87. package/dist/targets/native/components/avatar.js +36 -29
  88. package/dist/targets/native/components/badge.js +4 -3
  89. package/dist/targets/native/components/button.js +11 -4
  90. package/dist/targets/native/components/card.js +2 -1
  91. package/dist/targets/native/components/checkbox.js +18 -15
  92. package/dist/targets/native/components/chips.js +19 -16
  93. package/dist/targets/native/components/choice-card.js +29 -23
  94. package/dist/targets/native/components/context-menu.js +13 -9
  95. package/dist/targets/native/components/currency-input.js +28 -25
  96. package/dist/targets/native/components/danger-zone.js +10 -4
  97. package/dist/targets/native/components/date-picker.js +86 -70
  98. package/dist/targets/native/components/divider.js +3 -2
  99. package/dist/targets/native/components/empty-state.js +6 -1
  100. package/dist/targets/native/components/fab.js +32 -26
  101. package/dist/targets/native/components/filter-chip.js +9 -8
  102. package/dist/targets/native/components/form-field.js +20 -10
  103. package/dist/targets/native/components/form-screen.js +50 -45
  104. package/dist/targets/native/components/google-icon.js +31 -25
  105. package/dist/targets/native/components/icon-button.js +6 -4
  106. package/dist/targets/native/components/icon.js +2 -1
  107. package/dist/targets/native/components/image-upload.js +59 -50
  108. package/dist/targets/native/components/input.js +41 -34
  109. package/dist/targets/native/components/list-item.js +29 -23
  110. package/dist/targets/native/components/menu.js +12 -10
  111. package/dist/targets/native/components/modal.js +41 -32
  112. package/dist/targets/native/components/paywall-banner.js +13 -4
  113. package/dist/targets/native/components/paywall.js +11 -1
  114. package/dist/targets/native/components/radio.js +19 -16
  115. package/dist/targets/native/components/search.js +41 -38
  116. package/dist/targets/native/components/select.js +71 -63
  117. package/dist/targets/native/components/sheet.js +36 -30
  118. package/dist/targets/native/components/skeleton.js +6 -5
  119. package/dist/targets/native/components/slider.js +51 -43
  120. package/dist/targets/native/components/spinner.js +2 -1
  121. package/dist/targets/native/components/stepper.js +14 -9
  122. package/dist/targets/native/components/switch.js +15 -14
  123. package/dist/targets/native/components/text.js +2 -1
  124. package/dist/targets/native/components/textarea.js +2 -1
  125. package/dist/targets/native/components/theme.js +2 -1
  126. package/dist/targets/native/components/toaster.js +24 -21
  127. package/dist/targets/native/index.d.ts +1 -1
  128. package/dist/targets/native/index.js +1 -3
  129. package/package.json +190 -194
  130. package/styles/base.css +3 -3
  131. package/brand/rojao-black-on-white.png +0 -0
  132. package/brand/rojao-black.png +0 -0
  133. package/brand/rojao-white-on-black.png +0 -0
  134. package/brand/rojao-white.png +0 -0
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import "../chunk-ORMEWXMH.js";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
4
  import { useEffect, useRef, useState } from "react";
4
5
  import ReactCrop, { centerCrop } from "react-image-crop";
5
6
  import "react-image-crop/dist/ReactCrop.css";
@@ -10,16 +11,16 @@ function RatioIcon({ w, h }) {
10
11
  const box = 16;
11
12
  const rw = w >= h ? box : w / h * box;
12
13
  const rh = h >= w ? box : h / w * box;
13
- return /* @__PURE__ */ React.createElement("svg", { width: "16", height: "16", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, className: "shrink-0" }, /* @__PURE__ */ React.createElement("rect", { x: (18 - rw) / 2, y: (18 - rh) / 2, width: rw, height: rh, rx: "1.5", stroke: "currentColor", strokeWidth: "1.6" }));
14
+ return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, className: "shrink-0", children: /* @__PURE__ */ jsx("rect", { x: (18 - rw) / 2, y: (18 - rh) / 2, width: rw, height: rh, rx: "1.5", stroke: "currentColor", strokeWidth: "1.6" }) });
14
15
  }
15
16
  function FreeIcon() {
16
- return /* @__PURE__ */ React.createElement("svg", { width: "16", height: "16", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, className: "shrink-0" }, /* @__PURE__ */ React.createElement("rect", { x: "2.5", y: "2.5", width: "13", height: "13", rx: "1.5", stroke: "currentColor", strokeWidth: "1.6", strokeDasharray: "2.5 2.2" }));
17
+ return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, className: "shrink-0", children: /* @__PURE__ */ jsx("rect", { x: "2.5", y: "2.5", width: "13", height: "13", rx: "1.5", stroke: "currentColor", strokeWidth: "1.6", strokeDasharray: "2.5 2.2" }) });
17
18
  }
18
19
  const DEFAULT_PRESETS = [
19
- { id: "square", label: "1:1", aspect: 1, icon: /* @__PURE__ */ React.createElement(RatioIcon, { w: 1, h: 1 }) },
20
- { id: "portrait", label: "4:5", aspect: 4 / 5, icon: /* @__PURE__ */ React.createElement(RatioIcon, { w: 4, h: 5 }) },
21
- { id: "landscape", label: "16:9", aspect: 16 / 9, icon: /* @__PURE__ */ React.createElement(RatioIcon, { w: 16, h: 9 }) },
22
- { id: "free", label: "Livre", icon: /* @__PURE__ */ React.createElement(FreeIcon, null) }
20
+ { id: "square", label: "1:1", aspect: 1, icon: /* @__PURE__ */ jsx(RatioIcon, { w: 1, h: 1 }) },
21
+ { id: "portrait", label: "4:5", aspect: 4 / 5, icon: /* @__PURE__ */ jsx(RatioIcon, { w: 4, h: 5 }) },
22
+ { id: "landscape", label: "16:9", aspect: 16 / 9, icon: /* @__PURE__ */ jsx(RatioIcon, { w: 16, h: 9 }) },
23
+ { id: "free", label: "Livre", icon: /* @__PURE__ */ jsx(FreeIcon, {}) }
23
24
  ];
24
25
  const DEFAULT_MIN_ASPECT = 0.5;
25
26
  const DEFAULT_MAX_ASPECT = 2;
@@ -185,54 +186,74 @@ function ImageCropModal({
185
186
  setBusy(false);
186
187
  }
187
188
  }
188
- return /* @__PURE__ */ React.createElement(
189
+ return /* @__PURE__ */ jsx(
189
190
  Modal,
190
191
  {
191
192
  open,
192
193
  onClose: onCancel,
193
194
  size: "lg",
194
195
  title: position ? `${title} \xB7 ${position}` : title,
195
- footer: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Button, { variant: "ghost", onClick: onCancel }, "Cancelar"), /* @__PURE__ */ React.createElement(Button, { onClick: handleConfirm, disabled: busy || !completedCrop || !!aspectError, loading: busy }, busy ? "Aplicando\u2026" : confirmLabel))
196
- },
197
- /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, presets.length > 1 && /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-1 rounded-(--radius-control) bg-surface-raised p-1" }, presets.map((p) => /* @__PURE__ */ React.createElement(
198
- "button",
199
- {
200
- key: p.id,
201
- type: "button",
202
- onClick: () => applyPreset(p),
203
- className: [
204
- "flex flex-1 min-w-[80px] items-center justify-center gap-1.5 rounded-(--radius-control) px-3 py-1.5 text-caption font-medium transition-colors",
205
- preset.id === p.id ? "bg-surface-default text-fg-primary shadow-sm" : "text-fg-muted hover:text-fg-primary"
206
- ].join(" ")
207
- },
208
- p.icon,
209
- p.label
210
- ))), /* @__PURE__ */ React.createElement("div", { className: "relative rounded-(--radius-control) bg-surface-overlay overflow-hidden flex items-center justify-center min-h-[300px] max-h-[60vh] p-4" }, src && /* @__PURE__ */ React.createElement(
211
- ReactCrop,
212
- {
213
- crop,
214
- onChange: (_, percentCrop) => setCrop(percentCrop),
215
- onComplete: (c) => {
216
- setCompletedCrop(c);
217
- validateFreeAspect(c);
218
- },
219
- aspect: preset.aspect,
220
- keepSelection: true,
221
- minWidth: 50,
222
- minHeight: 50,
223
- className: "max-h-[60vh] max-w-full"
224
- },
225
- /* @__PURE__ */ React.createElement(
226
- "img",
227
- {
228
- ref: imgRef,
229
- src,
230
- alt: "",
231
- onLoad: handleImageLoad,
232
- className: "max-h-full max-w-full"
233
- }
234
- )
235
- ), !imgLoaded && /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none" }, /* @__PURE__ */ React.createElement(Spinner, { size: "lg", color: "inverse" })), busy && /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 z-10 flex items-center justify-center bg-black/40" }, /* @__PURE__ */ React.createElement(Spinner, { size: "lg", color: "inverse" }))), aspectError && /* @__PURE__ */ React.createElement("p", { className: "rounded-(--radius-control) bg-danger-soft px-3 py-2 text-caption text-danger-text" }, aspectError), !aspectError && preset.id === "free" && /* @__PURE__ */ React.createElement("p", { className: "text-caption text-fg-muted" }, "Livre: propor\xE7\xE3o entre ", minAspect.toFixed(1), " (vertical) e ", maxAspect.toFixed(1), " (horizontal)."))
196
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
197
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: onCancel, children: "Cancelar" }),
198
+ /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, disabled: busy || !completedCrop || !!aspectError, loading: busy, children: busy ? "Aplicando\u2026" : confirmLabel })
199
+ ] }),
200
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
201
+ presets.length > 1 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1 rounded-(--radius-control) bg-surface-raised p-1", children: presets.map((p) => /* @__PURE__ */ jsxs(
202
+ "button",
203
+ {
204
+ type: "button",
205
+ onClick: () => applyPreset(p),
206
+ className: [
207
+ "flex flex-1 min-w-[80px] items-center justify-center gap-1.5 rounded-(--radius-control) px-3 py-1.5 text-caption font-medium transition-colors",
208
+ preset.id === p.id ? "bg-surface-default text-fg-primary shadow-sm" : "text-fg-muted hover:text-fg-primary"
209
+ ].join(" "),
210
+ children: [
211
+ p.icon,
212
+ p.label
213
+ ]
214
+ },
215
+ p.id
216
+ )) }),
217
+ /* @__PURE__ */ jsxs("div", { className: "relative rounded-(--radius-control) bg-surface-overlay overflow-hidden flex items-center justify-center min-h-[300px] max-h-[60vh] p-4", children: [
218
+ src && /* @__PURE__ */ jsx(
219
+ ReactCrop,
220
+ {
221
+ crop,
222
+ onChange: (_, percentCrop) => setCrop(percentCrop),
223
+ onComplete: (c) => {
224
+ setCompletedCrop(c);
225
+ validateFreeAspect(c);
226
+ },
227
+ aspect: preset.aspect,
228
+ keepSelection: true,
229
+ minWidth: 50,
230
+ minHeight: 50,
231
+ className: "max-h-[60vh] max-w-full",
232
+ children: /* @__PURE__ */ jsx(
233
+ "img",
234
+ {
235
+ ref: imgRef,
236
+ src,
237
+ alt: "",
238
+ onLoad: handleImageLoad,
239
+ className: "max-h-full max-w-full"
240
+ }
241
+ )
242
+ }
243
+ ),
244
+ !imgLoaded && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsx(Spinner, { size: "lg", color: "inverse" }) }),
245
+ busy && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center bg-black/40", children: /* @__PURE__ */ jsx(Spinner, { size: "lg", color: "inverse" }) })
246
+ ] }),
247
+ aspectError && /* @__PURE__ */ jsx("p", { className: "rounded-(--radius-control) bg-danger-soft px-3 py-2 text-caption text-danger-text", children: aspectError }),
248
+ !aspectError && preset.id === "free" && /* @__PURE__ */ jsxs("p", { className: "text-caption text-fg-muted", children: [
249
+ "Livre: propor\xE7\xE3o entre ",
250
+ minAspect.toFixed(1),
251
+ " (vertical) e ",
252
+ maxAspect.toFixed(1),
253
+ " (horizontal)."
254
+ ] })
255
+ ] })
256
+ }
236
257
  );
237
258
  }
238
259
  export {
@@ -2,6 +2,7 @@
2
2
  import {
3
3
  __spreadValues
4
4
  } from "../chunk-ORMEWXMH.js";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
6
  import { useRef, useState } from "react";
6
7
  import { Upload, X } from "lucide-react";
7
8
  import { Button } from "./button.js";
@@ -98,7 +99,7 @@ function ImageUpload({
98
99
  const file = (_a = e.dataTransfer.files) == null ? void 0 : _a[0];
99
100
  if (file) await selectFile(file);
100
101
  }
101
- const cropModal = crop ? /* @__PURE__ */ React.createElement(
102
+ const cropModal = crop ? /* @__PURE__ */ jsx(
102
103
  ImageCropModal,
103
104
  {
104
105
  open: !!pendingFile,
@@ -117,55 +118,106 @@ function ImageUpload({
117
118
  var _a;
118
119
  if (!uploading) (_a = inputRef.current) == null ? void 0 : _a.click();
119
120
  };
120
- const hiddenInputs = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("input", { type: "hidden", name, value }), /* @__PURE__ */ React.createElement(
121
- "input",
122
- {
123
- ref: inputRef,
124
- type: "file",
125
- accept,
126
- onChange: handleFileInput,
127
- className: "hidden"
128
- }
129
- ));
121
+ const hiddenInputs = /* @__PURE__ */ jsxs(Fragment, { children: [
122
+ /* @__PURE__ */ jsx("input", { type: "hidden", name, value }),
123
+ /* @__PURE__ */ jsx(
124
+ "input",
125
+ {
126
+ ref: inputRef,
127
+ type: "file",
128
+ accept,
129
+ onChange: handleFileInput,
130
+ className: "hidden"
131
+ }
132
+ )
133
+ ] });
130
134
  if (variant === "tile") {
131
- return /* @__PURE__ */ React.createElement("div", { className: ["space-y-2", className].join(" ") }, label && /* @__PURE__ */ React.createElement("p", { className: "text-label font-medium text-fg-primary" }, label), value ? (
132
- // Preenchido: o tile É o preview. Trocar/Remover são botões-ícone SEMPRE visíveis no
133
- // canto (não dependem de hover — a11y/baixa visão), sobre um scrim pra legibilidade.
134
- /* @__PURE__ */ React.createElement(
135
- "div",
136
- {
137
- className: [
138
- "relative overflow-hidden rounded-(--radius-control) border border-stroke-default bg-surface-raised",
139
- "flex items-center justify-center p-2",
140
- TILE_BOX[aspect],
141
- previewWrapperClassName
142
- ].filter(Boolean).join(" ")
143
- },
144
- /* @__PURE__ */ React.createElement("img", { src: value, alt: "preview", className: previewClassName != null ? previewClassName : "max-h-full max-w-full object-contain" }),
145
- /* @__PURE__ */ React.createElement("div", { className: "absolute top-1 right-1 flex gap-1" }, /* @__PURE__ */ React.createElement(Tooltip, { content: L.change }, /* @__PURE__ */ React.createElement(
146
- "button",
135
+ return /* @__PURE__ */ jsxs("div", { className: ["space-y-2", className].join(" "), children: [
136
+ label && /* @__PURE__ */ jsx("p", { className: "text-label font-medium text-fg-primary", children: label }),
137
+ value ? (
138
+ // Preenchido: o tile É o preview. Trocar/Remover são botões-ícone SEMPRE visíveis no
139
+ // canto (não dependem de hover — a11y/baixa visão), sobre um scrim pra legibilidade.
140
+ /* @__PURE__ */ jsxs(
141
+ "div",
147
142
  {
148
- type: "button",
149
- "aria-label": L.change,
150
- onClick: openPicker,
151
- disabled: uploading,
152
- className: "flex items-center justify-center size-7 rounded-md bg-surface-default border border-stroke-default text-fg-secondary shadow-sm hover:bg-surface-raised hover:text-fg-primary disabled:opacity-50 transition-colors cursor-pointer"
153
- },
154
- /* @__PURE__ */ React.createElement(Upload, { size: 14 })
155
- )), /* @__PURE__ */ React.createElement(Tooltip, { content: L.remove }, /* @__PURE__ */ React.createElement(
156
- "button",
143
+ className: [
144
+ "relative overflow-hidden rounded-(--radius-control) border border-stroke-default bg-surface-raised",
145
+ "flex items-center justify-center p-2",
146
+ TILE_BOX[aspect],
147
+ previewWrapperClassName
148
+ ].filter(Boolean).join(" "),
149
+ children: [
150
+ /* @__PURE__ */ jsx("img", { src: value, alt: "preview", className: previewClassName != null ? previewClassName : "max-h-full max-w-full object-contain" }),
151
+ /* @__PURE__ */ jsxs("div", { className: "absolute top-1 right-1 flex gap-1", children: [
152
+ /* @__PURE__ */ jsx(Tooltip, { content: L.change, children: /* @__PURE__ */ jsx(
153
+ "button",
154
+ {
155
+ type: "button",
156
+ "aria-label": L.change,
157
+ onClick: openPicker,
158
+ disabled: uploading,
159
+ className: "flex items-center justify-center size-7 rounded-md bg-surface-default border border-stroke-default text-fg-secondary shadow-sm hover:bg-surface-raised hover:text-fg-primary disabled:opacity-50 transition-colors cursor-pointer",
160
+ children: /* @__PURE__ */ jsx(Upload, { size: 14 })
161
+ }
162
+ ) }),
163
+ /* @__PURE__ */ jsx(Tooltip, { content: L.remove, children: /* @__PURE__ */ jsx(
164
+ "button",
165
+ {
166
+ type: "button",
167
+ "aria-label": L.remove,
168
+ onClick: () => onChange(""),
169
+ className: "flex items-center justify-center size-7 rounded-md bg-surface-default border border-stroke-default text-fg-secondary shadow-sm hover:bg-danger-soft hover:text-danger-text transition-colors cursor-pointer",
170
+ children: /* @__PURE__ */ jsx(X, { size: 14 })
171
+ }
172
+ ) })
173
+ ] })
174
+ ]
175
+ }
176
+ )
177
+ ) : (
178
+ // Vazio: o tile inteiro é o alvo de clique/drop.
179
+ /* @__PURE__ */ jsxs(
180
+ "div",
157
181
  {
158
- type: "button",
159
- "aria-label": L.remove,
160
- onClick: () => onChange(""),
161
- className: "flex items-center justify-center size-7 rounded-md bg-surface-default border border-stroke-default text-fg-secondary shadow-sm hover:bg-danger-soft hover:text-danger-text transition-colors cursor-pointer"
162
- },
163
- /* @__PURE__ */ React.createElement(X, { size: 14 })
164
- )))
165
- )
166
- ) : (
167
- // Vazio: o tile inteiro é o alvo de clique/drop.
168
- /* @__PURE__ */ React.createElement(
182
+ role: "button",
183
+ tabIndex: 0,
184
+ "aria-label": label != null ? label : L.aria,
185
+ onClick: openPicker,
186
+ onKeyDown: (e) => {
187
+ if (e.key === "Enter" || e.key === " ") {
188
+ e.preventDefault();
189
+ openPicker();
190
+ }
191
+ },
192
+ onDragOver: (e) => {
193
+ e.preventDefault();
194
+ setDragging(true);
195
+ },
196
+ onDragLeave: () => setDragging(false),
197
+ onDrop: handleDrop,
198
+ className: [
199
+ "rounded-(--radius-control) border-2 border-dashed cursor-pointer transition-colors p-2",
200
+ "flex flex-col items-center justify-center gap-1.5 text-center",
201
+ TILE_BOX[aspect],
202
+ dragging ? "border-brand-primary bg-[color-mix(in_srgb,var(--brand-primary)_8%,transparent)]" : "border-stroke-default bg-surface-page hover:border-stroke-strong hover:bg-surface-raised"
203
+ ].join(" "),
204
+ children: [
205
+ /* @__PURE__ */ jsx(Upload, { size: 18, className: "text-brand-primary shrink-0" }),
206
+ /* @__PURE__ */ jsx("span", { className: "text-caption font-medium text-fg-secondary leading-tight", children: uploading ? L.uploading : L.select })
207
+ ]
208
+ }
209
+ )
210
+ ),
211
+ error && /* @__PURE__ */ jsx("p", { className: "text-caption text-danger-text", children: error }),
212
+ hint && /* @__PURE__ */ jsx("p", { className: "text-caption text-fg-muted", children: hint }),
213
+ hiddenInputs,
214
+ cropModal
215
+ ] });
216
+ }
217
+ if (variant === "dropzone") {
218
+ return /* @__PURE__ */ jsxs("div", { className: ["space-y-3", className].join(" "), children: [
219
+ label && /* @__PURE__ */ jsx("p", { className: "text-label font-medium text-fg-primary", children: label }),
220
+ /* @__PURE__ */ jsx(
169
221
  "div",
170
222
  {
171
223
  role: "button",
@@ -173,10 +225,8 @@ function ImageUpload({
173
225
  "aria-label": label != null ? label : L.aria,
174
226
  onClick: openPicker,
175
227
  onKeyDown: (e) => {
176
- if (e.key === "Enter" || e.key === " ") {
177
- e.preventDefault();
178
- openPicker();
179
- }
228
+ var _a;
229
+ if (e.key === "Enter" || e.key === " ") (_a = inputRef.current) == null ? void 0 : _a.click();
180
230
  },
181
231
  onDragOver: (e) => {
182
232
  e.preventDefault();
@@ -185,86 +235,80 @@ function ImageUpload({
185
235
  onDragLeave: () => setDragging(false),
186
236
  onDrop: handleDrop,
187
237
  className: [
188
- "rounded-(--radius-control) border-2 border-dashed cursor-pointer transition-colors p-2",
189
- "flex flex-col items-center justify-center gap-1.5 text-center",
190
- TILE_BOX[aspect],
238
+ "rounded-(--radius-control) border-2 border-dashed cursor-pointer transition-colors p-4",
191
239
  dragging ? "border-brand-primary bg-[color-mix(in_srgb,var(--brand-primary)_8%,transparent)]" : "border-stroke-default bg-surface-page hover:border-stroke-strong hover:bg-surface-raised"
192
- ].join(" ")
193
- },
194
- /* @__PURE__ */ React.createElement(Upload, { size: 18, className: "text-brand-primary shrink-0" }),
195
- /* @__PURE__ */ React.createElement("span", { className: "text-caption font-medium text-fg-secondary leading-tight" }, uploading ? L.uploading : L.select)
196
- )
197
- ), error && /* @__PURE__ */ React.createElement("p", { className: "text-caption text-danger-text" }, error), hint && /* @__PURE__ */ React.createElement("p", { className: "text-caption text-fg-muted" }, hint), hiddenInputs, cropModal);
198
- }
199
- if (variant === "dropzone") {
200
- return /* @__PURE__ */ React.createElement("div", { className: ["space-y-3", className].join(" ") }, label && /* @__PURE__ */ React.createElement("p", { className: "text-label font-medium text-fg-primary" }, label), /* @__PURE__ */ React.createElement(
201
- "div",
202
- {
203
- role: "button",
204
- tabIndex: 0,
205
- "aria-label": label != null ? label : L.aria,
206
- onClick: openPicker,
207
- onKeyDown: (e) => {
208
- var _a;
209
- if (e.key === "Enter" || e.key === " ") (_a = inputRef.current) == null ? void 0 : _a.click();
210
- },
211
- onDragOver: (e) => {
212
- e.preventDefault();
213
- setDragging(true);
214
- },
215
- onDragLeave: () => setDragging(false),
216
- onDrop: handleDrop,
217
- className: [
218
- "rounded-(--radius-control) border-2 border-dashed cursor-pointer transition-colors p-4",
219
- dragging ? "border-brand-primary bg-[color-mix(in_srgb,var(--brand-primary)_8%,transparent)]" : "border-stroke-default bg-surface-page hover:border-stroke-strong hover:bg-surface-raised"
220
- ].join(" ")
221
- },
222
- value ? /* @__PURE__ */ React.createElement("div", { className: ["flex items-center justify-center transition-colors", previewWrapperClassName].filter(Boolean).join(" ") }, /* @__PURE__ */ React.createElement("img", { src: value, alt: "preview", className: previewClassName != null ? previewClassName : DROPZONE_PREVIEW[aspect] })) : /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-center py-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col items-center gap-2 min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "size-10 rounded-full bg-[color-mix(in_srgb,var(--brand-primary)_10%,transparent)] flex items-center justify-center" }, /* @__PURE__ */ React.createElement(Upload, { size: 18, className: "text-brand-primary" })), /* @__PURE__ */ React.createElement("p", { className: "text-label font-medium text-fg-primary text-center" }, uploading ? L.uploading : L.dropTitle), /* @__PURE__ */ React.createElement("p", { className: "text-caption text-fg-muted text-center" }, L.dropHint)))
223
- ), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement(
224
- Button,
225
- {
226
- type: "button",
227
- size: "sm",
228
- loading: uploading,
229
- onClick: () => {
230
- var _a;
231
- return (_a = inputRef.current) == null ? void 0 : _a.click();
240
+ ].join(" "),
241
+ children: value ? /* @__PURE__ */ jsx("div", { className: ["flex items-center justify-center transition-colors", previewWrapperClassName].filter(Boolean).join(" "), children: /* @__PURE__ */ jsx("img", { src: value, alt: "preview", className: previewClassName != null ? previewClassName : DROPZONE_PREVIEW[aspect] }) }) : /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 min-w-0", children: [
242
+ /* @__PURE__ */ jsx("div", { className: "size-10 rounded-full bg-[color-mix(in_srgb,var(--brand-primary)_10%,transparent)] flex items-center justify-center", children: /* @__PURE__ */ jsx(Upload, { size: 18, className: "text-brand-primary" }) }),
243
+ /* @__PURE__ */ jsx("p", { className: "text-label font-medium text-fg-primary text-center", children: uploading ? L.uploading : L.dropTitle }),
244
+ /* @__PURE__ */ jsx("p", { className: "text-caption text-fg-muted text-center", children: L.dropHint })
245
+ ] }) })
232
246
  }
233
- },
234
- value ? L.change : L.select
235
- ), value && /* @__PURE__ */ React.createElement(
236
- "button",
237
- {
238
- type: "button",
239
- onClick: () => onChange(""),
240
- className: "text-label text-fg-muted hover:text-danger-text transition-colors"
241
- },
242
- L.remove
243
- )), error && /* @__PURE__ */ React.createElement("p", { className: "text-caption text-danger-text" }, error), hint && /* @__PURE__ */ React.createElement("p", { className: "text-caption text-fg-muted" }, hint), hiddenInputs, cropModal);
247
+ ),
248
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
249
+ /* @__PURE__ */ jsx(
250
+ Button,
251
+ {
252
+ type: "button",
253
+ size: "sm",
254
+ loading: uploading,
255
+ onClick: () => {
256
+ var _a;
257
+ return (_a = inputRef.current) == null ? void 0 : _a.click();
258
+ },
259
+ children: value ? L.change : L.select
260
+ }
261
+ ),
262
+ value && /* @__PURE__ */ jsx(
263
+ "button",
264
+ {
265
+ type: "button",
266
+ onClick: () => onChange(""),
267
+ className: "text-label text-fg-muted hover:text-danger-text transition-colors",
268
+ children: L.remove
269
+ }
270
+ )
271
+ ] }),
272
+ error && /* @__PURE__ */ jsx("p", { className: "text-caption text-danger-text", children: error }),
273
+ hint && /* @__PURE__ */ jsx("p", { className: "text-caption text-fg-muted", children: hint }),
274
+ hiddenInputs,
275
+ cropModal
276
+ ] });
244
277
  }
245
- return /* @__PURE__ */ React.createElement("div", { className: ["space-y-2", className].join(" ") }, label && /* @__PURE__ */ React.createElement("p", { className: "block text-caption font-medium text-fg-secondary" }, label), value && // eslint-disable-next-line @next/next/no-img-element
246
- /* @__PURE__ */ React.createElement("img", { src: value, alt: "preview", className: BUTTON_PREVIEW[aspect] }), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement(
247
- Button,
248
- {
249
- type: "button",
250
- size: "sm",
251
- variant: "outline",
252
- onClick: () => {
253
- var _a;
254
- return (_a = inputRef.current) == null ? void 0 : _a.click();
255
- },
256
- disabled: uploading
257
- },
258
- uploading ? L.uploading : value ? L.change : L.select
259
- ), value && /* @__PURE__ */ React.createElement(
260
- "button",
261
- {
262
- type: "button",
263
- onClick: () => onChange(""),
264
- className: "text-caption text-fg-muted hover:text-danger-text transition-colors"
265
- },
266
- L.remove
267
- )), error && /* @__PURE__ */ React.createElement("p", { className: "text-caption text-danger-text" }, error), hint && /* @__PURE__ */ React.createElement("p", { className: "text-caption text-fg-muted" }, hint), hiddenInputs, cropModal);
278
+ return /* @__PURE__ */ jsxs("div", { className: ["space-y-2", className].join(" "), children: [
279
+ label && /* @__PURE__ */ jsx("p", { className: "block text-caption font-medium text-fg-secondary", children: label }),
280
+ value && // eslint-disable-next-line @next/next/no-img-element
281
+ /* @__PURE__ */ jsx("img", { src: value, alt: "preview", className: BUTTON_PREVIEW[aspect] }),
282
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
283
+ /* @__PURE__ */ jsx(
284
+ Button,
285
+ {
286
+ type: "button",
287
+ size: "sm",
288
+ variant: "outline",
289
+ onClick: () => {
290
+ var _a;
291
+ return (_a = inputRef.current) == null ? void 0 : _a.click();
292
+ },
293
+ disabled: uploading,
294
+ children: uploading ? L.uploading : value ? L.change : L.select
295
+ }
296
+ ),
297
+ value && /* @__PURE__ */ jsx(
298
+ "button",
299
+ {
300
+ type: "button",
301
+ onClick: () => onChange(""),
302
+ className: "text-caption text-fg-muted hover:text-danger-text transition-colors",
303
+ children: L.remove
304
+ }
305
+ )
306
+ ] }),
307
+ error && /* @__PURE__ */ jsx("p", { className: "text-caption text-danger-text", children: error }),
308
+ hint && /* @__PURE__ */ jsx("p", { className: "text-caption text-fg-muted", children: hint }),
309
+ hiddenInputs,
310
+ cropModal
311
+ ] });
268
312
  }
269
313
  export {
270
314
  ImageUpload