@planetaexo/design-system 0.12.7 → 0.13.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.
package/dist/index.d.cts CHANGED
@@ -30,6 +30,26 @@ interface OfferOptionalItem {
30
30
  checked?: boolean;
31
31
  /** Controlled: chamado ao marcar/desmarcar. Ignorado se `checked` não for passado. */
32
32
  onCheckedChange?: (id: string, checked: boolean) => void;
33
+ /** Quantidade atual (controlled). Quando ausente, o stepper não aparece. */
34
+ quantity?: number;
35
+ /** Chamado ao alterar a quantidade via stepper. Necessário para que o stepper apareça. */
36
+ onQuantityChange?: (id: string, next: number) => void;
37
+ /**
38
+ * Esconde explicitamente o stepper mesmo quando `quantity`/`onQuantityChange` estão presentes
39
+ * (ex.: opcional com billingType=VALOR_TOTAL onde a quantidade não impacta o preço).
40
+ * Default: `true` (stepper aparece quando `checked && quantity != null`).
41
+ */
42
+ showQuantityControl?: boolean;
43
+ /** Quantidade mínima permitida no stepper. Default: 1. */
44
+ minQuantity?: number;
45
+ /** Quantidade máxima permitida no stepper. Default: 50. */
46
+ maxQuantity?: number;
47
+ /** Texto pré-formatado da data agendada para exibição read-only (ex.: "10/05/2026"). */
48
+ scheduledAtLabel?: string;
49
+ /** aria-label para o botão de decrementar quantidade. Default: "Decrease quantity". */
50
+ decreaseQuantityLabel?: string;
51
+ /** aria-label para o botão de incrementar quantidade. Default: "Increase quantity". */
52
+ increaseQuantityLabel?: string;
33
53
  }
34
54
  interface OfferAdventureItem {
35
55
  id: string;
package/dist/index.d.ts CHANGED
@@ -30,6 +30,26 @@ interface OfferOptionalItem {
30
30
  checked?: boolean;
31
31
  /** Controlled: chamado ao marcar/desmarcar. Ignorado se `checked` não for passado. */
32
32
  onCheckedChange?: (id: string, checked: boolean) => void;
33
+ /** Quantidade atual (controlled). Quando ausente, o stepper não aparece. */
34
+ quantity?: number;
35
+ /** Chamado ao alterar a quantidade via stepper. Necessário para que o stepper apareça. */
36
+ onQuantityChange?: (id: string, next: number) => void;
37
+ /**
38
+ * Esconde explicitamente o stepper mesmo quando `quantity`/`onQuantityChange` estão presentes
39
+ * (ex.: opcional com billingType=VALOR_TOTAL onde a quantidade não impacta o preço).
40
+ * Default: `true` (stepper aparece quando `checked && quantity != null`).
41
+ */
42
+ showQuantityControl?: boolean;
43
+ /** Quantidade mínima permitida no stepper. Default: 1. */
44
+ minQuantity?: number;
45
+ /** Quantidade máxima permitida no stepper. Default: 50. */
46
+ maxQuantity?: number;
47
+ /** Texto pré-formatado da data agendada para exibição read-only (ex.: "10/05/2026"). */
48
+ scheduledAtLabel?: string;
49
+ /** aria-label para o botão de decrementar quantidade. Default: "Decrease quantity". */
50
+ decreaseQuantityLabel?: string;
51
+ /** aria-label para o botão de incrementar quantidade. Default: "Increase quantity". */
52
+ increaseQuantityLabel?: string;
33
53
  }
34
54
  interface OfferAdventureItem {
35
55
  id: string;
package/dist/index.js CHANGED
@@ -1321,16 +1321,22 @@ function AdventureCard({ adventure }) {
1321
1321
  ] }),
1322
1322
  adventure.optionals && adventure.optionals.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-2 rounded-xl border border-border bg-muted/30 p-4 flex flex-col gap-3", children: [
1323
1323
  /* @__PURE__ */ jsx("p", { className: "text-[10px] font-bold text-muted-foreground font-heading uppercase tracking-widest", children: "Available optionals" }),
1324
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: adventure.optionals.map((opt) => /* @__PURE__ */ jsxs(
1325
- "label",
1326
- {
1327
- className: "flex items-center gap-3 cursor-pointer group",
1328
- children: [
1324
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: adventure.optionals.map((opt) => {
1325
+ var _a2, _b2, _c2, _d2, _e2;
1326
+ const checked = isChecked(opt);
1327
+ const minQty = (_a2 = opt.minQuantity) != null ? _a2 : 1;
1328
+ const maxQty = (_b2 = opt.maxQuantity) != null ? _b2 : 50;
1329
+ const showStepper = checked && opt.showQuantityControl !== false && opt.quantity != null && typeof opt.onQuantityChange === "function";
1330
+ const currentQty = (_c2 = opt.quantity) != null ? _c2 : minQty;
1331
+ const canDec = currentQty > minQty;
1332
+ const canInc = currentQty < maxQty;
1333
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1.5", children: [
1334
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 cursor-pointer group", children: [
1329
1335
  /* @__PURE__ */ jsx(
1330
1336
  "input",
1331
1337
  {
1332
1338
  type: "checkbox",
1333
- checked: isChecked(opt),
1339
+ checked,
1334
1340
  onChange: () => toggleOptional(opt),
1335
1341
  className: "h-4 w-4 shrink-0 rounded border-border accent-primary cursor-pointer"
1336
1342
  }
@@ -1344,10 +1350,52 @@ function AdventureCard({ adventure }) {
1344
1350
  ")"
1345
1351
  ] })
1346
1352
  ] })
1347
- ]
1348
- },
1349
- opt.id
1350
- )) })
1353
+ ] }),
1354
+ showStepper && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 ml-auto", children: [
1355
+ /* @__PURE__ */ jsx(
1356
+ "button",
1357
+ {
1358
+ type: "button",
1359
+ onClick: () => {
1360
+ var _a3;
1361
+ return canDec && ((_a3 = opt.onQuantityChange) == null ? void 0 : _a3.call(opt, opt.id, currentQty - 1));
1362
+ },
1363
+ disabled: !canDec,
1364
+ "aria-label": (_d2 = opt.decreaseQuantityLabel) != null ? _d2 : "Decrease quantity",
1365
+ className: cn(
1366
+ "h-7 w-7 rounded border border-border flex items-center justify-center text-sm font-semibold",
1367
+ "transition-colors",
1368
+ canDec ? "hover:bg-muted cursor-pointer text-foreground" : "opacity-40 cursor-not-allowed text-muted-foreground"
1369
+ ),
1370
+ children: "\u2212"
1371
+ }
1372
+ ),
1373
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-sans tabular-nums w-6 text-center text-foreground", children: currentQty }),
1374
+ /* @__PURE__ */ jsx(
1375
+ "button",
1376
+ {
1377
+ type: "button",
1378
+ onClick: () => {
1379
+ var _a3;
1380
+ return canInc && ((_a3 = opt.onQuantityChange) == null ? void 0 : _a3.call(opt, opt.id, currentQty + 1));
1381
+ },
1382
+ disabled: !canInc,
1383
+ "aria-label": (_e2 = opt.increaseQuantityLabel) != null ? _e2 : "Increase quantity",
1384
+ className: cn(
1385
+ "h-7 w-7 rounded border border-border flex items-center justify-center text-sm font-semibold",
1386
+ "transition-colors",
1387
+ canInc ? "hover:bg-muted cursor-pointer text-foreground" : "opacity-40 cursor-not-allowed text-muted-foreground"
1388
+ ),
1389
+ children: "+"
1390
+ }
1391
+ )
1392
+ ] }),
1393
+ opt.scheduledAtLabel && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground font-sans", children: [
1394
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "w-3 h-3 text-primary shrink-0" }),
1395
+ opt.scheduledAtLabel
1396
+ ] })
1397
+ ] }, opt.id);
1398
+ }) })
1351
1399
  ] }),
1352
1400
  (adventure.description || adventure.detailsSlot) && /* @__PURE__ */ jsxs(Fragment, { children: [
1353
1401
  /* @__PURE__ */ jsx(Separator, { className: "my-1" }),