@planetaexo/design-system 0.4.11 → 0.4.13

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.cjs CHANGED
@@ -1209,7 +1209,7 @@ function CountrySearchField({
1209
1209
  type: "button",
1210
1210
  onClick: () => handleSelect(c.code),
1211
1211
  className: cn(
1212
- "flex w-full items-center px-3 py-2 text-sm font-ui text-left transition-colors hover:bg-muted",
1212
+ "flex w-full items-center px-3 py-2 text-sm font-ui text-left text-foreground transition-colors hover:bg-muted",
1213
1213
  c.code === value && "bg-primary/10 text-primary font-semibold"
1214
1214
  ),
1215
1215
  children: c.name
@@ -3424,8 +3424,12 @@ function TravellerFormInviteEmail({
3424
3424
  teamSignature,
3425
3425
  logoUrl,
3426
3426
  buttonLabel = "Preencher formul\xE1rio",
3427
- className
3427
+ className,
3428
+ tripDetails,
3429
+ tripDetailsLabels,
3430
+ bodyFooter
3428
3431
  }) {
3432
+ var _a, _b, _c, _d, _e;
3429
3433
  return /* @__PURE__ */ jsxRuntime.jsxs(
3430
3434
  "div",
3431
3435
  {
@@ -3476,6 +3480,29 @@ function TravellerFormInviteEmail({
3476
3480
  }
3477
3481
  )
3478
3482
  ] }, i)) }),
3483
+ tripDetails && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
3484
+ backgroundColor: "#f8fafc",
3485
+ border: "1px solid #e2e8f0",
3486
+ borderRadius: "8px",
3487
+ padding: "16px 20px",
3488
+ margin: "24px 0"
3489
+ }, children: [
3490
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontWeight: "600", margin: "0 0 12px 0", fontSize: "14px" }, children: (_a = tripDetailsLabels == null ? void 0 : tripDetailsLabels.title) != null ? _a : "\u{1F4DD} Trip details:" }),
3491
+ [
3492
+ [(_b = tripDetailsLabels == null ? void 0 : tripDetailsLabels.bookingNumber) != null ? _b : "Booking Number", tripDetails.bookingNumber],
3493
+ [(_c = tripDetailsLabels == null ? void 0 : tripDetailsLabels.adventure) != null ? _c : "Adventure", tripDetails.adventure],
3494
+ [(_d = tripDetailsLabels == null ? void 0 : tripDetailsLabels.startingDate) != null ? _d : "Starting Date", tripDetails.startingDate],
3495
+ ...tripDetails.partner ? [[(_e = tripDetailsLabels == null ? void 0 : tripDetailsLabels.partner) != null ? _e : "Partner", tripDetails.partner]] : []
3496
+ ].map(([label, value], i) => /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { margin: "4px 0", fontSize: "13px" }, children: [
3497
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
3498
+ label,
3499
+ ":"
3500
+ ] }),
3501
+ " ",
3502
+ value
3503
+ ] }, i))
3504
+ ] }),
3505
+ bodyFooter && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "14px", lineHeight: "1.6", margin: "0 0 16px" }, children: bodyFooter }),
3479
3506
  /* @__PURE__ */ jsxRuntime.jsx(
3480
3507
  "p",
3481
3508
  {
@@ -4232,6 +4259,83 @@ function FloatingTextarea({
4232
4259
  )
4233
4260
  ] });
4234
4261
  }
4262
+ function SelectField({ field, value, onChange, error }) {
4263
+ var _a, _b, _c;
4264
+ const [open, setOpen] = React21__namespace.useState(false);
4265
+ const containerRef = React21__namespace.useRef(null);
4266
+ const options = (_a = field.options) != null ? _a : [];
4267
+ const selectedOpt = (_b = options.find((o) => o.value === value)) != null ? _b : null;
4268
+ React21__namespace.useEffect(() => {
4269
+ if (!open) return;
4270
+ const handleOutside = (e) => {
4271
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
4272
+ setOpen(false);
4273
+ }
4274
+ };
4275
+ document.addEventListener("mousedown", handleOutside);
4276
+ return () => document.removeEventListener("mousedown", handleOutside);
4277
+ }, [open]);
4278
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: "relative w-full", children: [
4279
+ /* @__PURE__ */ jsxRuntime.jsxs(
4280
+ "button",
4281
+ {
4282
+ type: "button",
4283
+ onClick: () => setOpen((o) => !o),
4284
+ className: cn(
4285
+ "relative flex w-full items-center rounded-lg border border-border bg-background h-14 px-3 text-left transition-colors",
4286
+ open && "border-primary ring-1 ring-primary",
4287
+ error && !open && "border-destructive"
4288
+ ),
4289
+ children: [
4290
+ /* @__PURE__ */ jsxRuntime.jsxs(
4291
+ "span",
4292
+ {
4293
+ className: cn(
4294
+ "pointer-events-none absolute left-3 transition-all duration-150 font-ui",
4295
+ selectedOpt || open ? cn("top-2 text-xs", open ? "text-primary" : "text-muted-foreground") : "top-1/2 -translate-y-1/2 text-base text-muted-foreground"
4296
+ ),
4297
+ children: [
4298
+ field.label,
4299
+ field.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary ml-0.5", children: "*" })
4300
+ ]
4301
+ }
4302
+ ),
4303
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-1 pt-3 text-base font-ui truncate", selectedOpt ? "text-foreground" : "invisible"), children: (_c = selectedOpt == null ? void 0 : selectedOpt.label) != null ? _c : "\u2014" }),
4304
+ /* @__PURE__ */ jsxRuntime.jsx(
4305
+ "svg",
4306
+ {
4307
+ className: cn("h-4 w-4 shrink-0 text-muted-foreground transition-transform", open && "rotate-180"),
4308
+ viewBox: "0 0 24 24",
4309
+ fill: "none",
4310
+ stroke: "currentColor",
4311
+ strokeWidth: "2",
4312
+ strokeLinecap: "round",
4313
+ strokeLinejoin: "round",
4314
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 9 6 6 6-6" })
4315
+ }
4316
+ )
4317
+ ]
4318
+ }
4319
+ ),
4320
+ open && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-[calc(100%+4px)] left-0 right-0 z-50 rounded-xl border border-border bg-background shadow-lg overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-52 overflow-y-auto py-1", children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
4321
+ "button",
4322
+ {
4323
+ type: "button",
4324
+ onClick: () => {
4325
+ onChange(opt.value);
4326
+ setOpen(false);
4327
+ },
4328
+ className: cn(
4329
+ "flex w-full items-center px-3 py-2 text-sm font-ui text-left text-foreground transition-colors hover:bg-muted",
4330
+ opt.value === value && "bg-primary/10 text-primary font-semibold"
4331
+ ),
4332
+ children: opt.label
4333
+ },
4334
+ opt.value
4335
+ )) }) }),
4336
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-destructive font-ui", children: error })
4337
+ ] });
4338
+ }
4235
4339
  function FieldRenderer({
4236
4340
  field,
4237
4341
  value,
@@ -4240,7 +4344,7 @@ function FieldRenderer({
4240
4344
  labels,
4241
4345
  error
4242
4346
  }) {
4243
- var _a, _b, _c;
4347
+ var _a, _b;
4244
4348
  const fieldId = `rf-${field.id}`;
4245
4349
  if (field.type === "name") {
4246
4350
  const v = asName(value);
@@ -4354,24 +4458,18 @@ function FieldRenderer({
4354
4458
  );
4355
4459
  }
4356
4460
  if (field.type === "select") {
4357
- const options = (_a = field.options) != null ? _a : [];
4358
- return /* @__PURE__ */ jsxRuntime.jsxs(
4359
- FloatingSelect,
4461
+ return /* @__PURE__ */ jsxRuntime.jsx(
4462
+ SelectField,
4360
4463
  {
4361
- label: field.label,
4362
- required: field.required,
4464
+ field,
4363
4465
  value: typeof value === "string" ? value : "",
4364
- onChange: (e) => onChange(e.target.value),
4365
- error,
4366
- children: [
4367
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, hidden: true }),
4368
- options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
4369
- ]
4466
+ onChange: (v) => onChange(v),
4467
+ error
4370
4468
  }
4371
4469
  );
4372
4470
  }
4373
4471
  if (field.type === "radio") {
4374
- const options = (_b = field.options) != null ? _b : [];
4472
+ const options = (_a = field.options) != null ? _a : [];
4375
4473
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4376
4474
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mb-3 text-sm font-ui font-medium text-foreground", children: [
4377
4475
  field.label,
@@ -4406,11 +4504,12 @@ function FieldRenderer({
4406
4504
  opt.value
4407
4505
  ))
4408
4506
  }
4409
- )
4507
+ ),
4508
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-destructive font-ui", children: error })
4410
4509
  ] });
4411
4510
  }
4412
4511
  if (field.type === "checkbox") {
4413
- const options = (_c = field.options) != null ? _c : [];
4512
+ const options = (_b = field.options) != null ? _b : [];
4414
4513
  if (options.length === 0) {
4415
4514
  return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-h-9 cursor-pointer items-center gap-2.5 font-ui text-sm text-foreground", children: [
4416
4515
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4609,15 +4708,17 @@ function RegistrationForm({
4609
4708
  }
4610
4709
  }
4611
4710
  }
4711
+ const termsError = submitAttempted && termsEnabled && !termsAccepted;
4612
4712
  const firstErrorFieldId = Object.keys(fieldErrors)[0];
4713
+ const scrollTargetId = firstErrorFieldId ? `rf-${firstErrorFieldId}` : termsError ? "rf-terms" : null;
4613
4714
  React21__namespace.useEffect(() => {
4614
- if (!submitAttempted || !firstErrorFieldId) return;
4715
+ if (!submitAttempted || !scrollTargetId) return;
4615
4716
  const timer = setTimeout(() => {
4616
- const elem = document.getElementById(`rf-${firstErrorFieldId}`);
4717
+ const elem = document.getElementById(scrollTargetId);
4617
4718
  if (elem) elem.scrollIntoView({ behavior: "smooth", block: "center" });
4618
4719
  }, 50);
4619
4720
  return () => clearTimeout(timer);
4620
- }, [submitAttempted, firstErrorFieldId, validationErrors]);
4721
+ }, [submitAttempted, scrollTargetId]);
4621
4722
  return /* @__PURE__ */ jsxRuntime.jsxs(
4622
4723
  "form",
4623
4724
  {
@@ -4708,58 +4809,86 @@ function RegistrationForm({
4708
4809
  ((_a2 = field.helpText) == null ? void 0 : _a2.trim()) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground font-ui leading-relaxed", children: field.helpText.trim() })
4709
4810
  ] }, field.id);
4710
4811
  }) }),
4711
- termsEnabled && terms && /* @__PURE__ */ jsxRuntime.jsxs(FormSection2, { title: L.termsSectionTitle, children: [
4812
+ termsEnabled && terms && /* @__PURE__ */ jsxRuntime.jsx("div", { id: "rf-terms", children: /* @__PURE__ */ jsxRuntime.jsxs(FormSection2, { title: L.termsSectionTitle, children: [
4712
4813
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-72 overflow-y-auto rounded-lg border border-border bg-muted/30 p-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap text-sm leading-relaxed text-foreground font-ui", children: terms.markdown }) }),
4713
- acceptControl === "checkbox" ? /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex cursor-pointer items-start gap-2.5 font-ui text-sm text-foreground", children: [
4714
- /* @__PURE__ */ jsxRuntime.jsx(
4715
- "input",
4814
+ acceptControl === "checkbox" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
4815
+ /* @__PURE__ */ jsxRuntime.jsxs(
4816
+ "label",
4716
4817
  {
4717
- type: "checkbox",
4718
- checked: termsAccepted,
4719
- required: true,
4720
- onChange: (e) => setField(TERMS_ACCEPT_KEY, e.target.checked),
4721
- className: "mt-0.5 h-4 w-4 shrink-0 accent-primary cursor-pointer"
4722
- }
4723
- ),
4724
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: L.termsAccept })
4725
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(
4726
- "div",
4727
- {
4728
- role: "radiogroup",
4729
- "aria-label": L.termsSectionTitle,
4730
- className: "flex flex-wrap items-center gap-x-6 gap-y-3",
4731
- children: [
4732
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-h-9 cursor-pointer items-center gap-2.5 font-ui text-sm text-foreground", children: [
4818
+ className: cn(
4819
+ "flex cursor-pointer items-start gap-2.5 font-ui text-sm",
4820
+ termsError ? "text-destructive" : "text-foreground"
4821
+ ),
4822
+ children: [
4733
4823
  /* @__PURE__ */ jsxRuntime.jsx(
4734
4824
  "input",
4735
4825
  {
4736
- type: "radio",
4737
- name: "registration-terms-accept",
4826
+ type: "checkbox",
4738
4827
  checked: termsAccepted,
4739
4828
  required: true,
4740
- onChange: () => setField(TERMS_ACCEPT_KEY, true),
4741
- className: "h-4 w-4 shrink-0 accent-primary cursor-pointer"
4829
+ onChange: (e) => setField(TERMS_ACCEPT_KEY, e.target.checked),
4830
+ className: "mt-0.5 h-4 w-4 shrink-0 accent-primary cursor-pointer"
4742
4831
  }
4743
4832
  ),
4744
- L.termsAccept
4745
- ] }),
4746
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-h-9 cursor-pointer items-center gap-2.5 font-ui text-sm text-muted-foreground", children: [
4747
- /* @__PURE__ */ jsxRuntime.jsx(
4748
- "input",
4833
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4834
+ L.termsAccept,
4835
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary ml-0.5", children: "*" })
4836
+ ] })
4837
+ ]
4838
+ }
4839
+ ),
4840
+ termsError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive font-ui", children: L.requiredFieldError })
4841
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
4842
+ /* @__PURE__ */ jsxRuntime.jsxs(
4843
+ "div",
4844
+ {
4845
+ role: "radiogroup",
4846
+ "aria-label": L.termsSectionTitle,
4847
+ className: "flex flex-wrap items-center gap-x-6 gap-y-3",
4848
+ children: [
4849
+ /* @__PURE__ */ jsxRuntime.jsxs(
4850
+ "label",
4749
4851
  {
4750
- type: "radio",
4751
- name: "registration-terms-accept",
4752
- checked: current[TERMS_ACCEPT_KEY] === false,
4753
- onChange: () => setField(TERMS_ACCEPT_KEY, false),
4754
- className: "h-4 w-4 shrink-0 accent-primary cursor-pointer"
4852
+ className: cn(
4853
+ "flex min-h-9 cursor-pointer items-center gap-2.5 font-ui text-sm",
4854
+ termsError ? "text-destructive" : "text-foreground"
4855
+ ),
4856
+ children: [
4857
+ /* @__PURE__ */ jsxRuntime.jsx(
4858
+ "input",
4859
+ {
4860
+ type: "radio",
4861
+ name: "registration-terms-accept",
4862
+ checked: termsAccepted,
4863
+ required: true,
4864
+ onChange: () => setField(TERMS_ACCEPT_KEY, true),
4865
+ className: "h-4 w-4 shrink-0 accent-primary cursor-pointer"
4866
+ }
4867
+ ),
4868
+ L.termsAccept,
4869
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary ml-0.5", children: "*" })
4870
+ ]
4755
4871
  }
4756
4872
  ),
4757
- L.termsDecline
4758
- ] })
4759
- ]
4760
- }
4761
- )
4762
- ] }),
4873
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-h-9 cursor-pointer items-center gap-2.5 font-ui text-sm text-muted-foreground", children: [
4874
+ /* @__PURE__ */ jsxRuntime.jsx(
4875
+ "input",
4876
+ {
4877
+ type: "radio",
4878
+ name: "registration-terms-accept",
4879
+ checked: current[TERMS_ACCEPT_KEY] === false,
4880
+ onChange: () => setField(TERMS_ACCEPT_KEY, false),
4881
+ className: "h-4 w-4 shrink-0 accent-primary cursor-pointer"
4882
+ }
4883
+ ),
4884
+ L.termsDecline
4885
+ ] })
4886
+ ]
4887
+ }
4888
+ ),
4889
+ termsError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive font-ui", children: L.requiredFieldError })
4890
+ ] })
4891
+ ] }) }),
4763
4892
  error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive font-ui", children: error }),
4764
4893
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
4765
4894
  "button",