@planetaexo/design-system 0.3.12 → 0.3.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.d.cts CHANGED
@@ -58,6 +58,8 @@ interface OfferAdventureItem {
58
58
  onRemove?: () => void;
59
59
  /** Extra rich content below the standard blocks (e.g. traveller table, HTML itinerary from the host app). */
60
60
  detailsSlot?: React.ReactNode;
61
+ /** Label shown above the itinerary/detailsSlot section. Defaults to "Itinerary". */
62
+ itineraryLabel?: string;
61
63
  }
62
64
  interface OfferDepositInfo {
63
65
  depositPercent: number;
@@ -914,13 +916,43 @@ declare const LIGHT: {
914
916
  };
915
917
  };
916
918
  };
919
+ /**
920
+ * Tokens opcionais resolvidos em runtime pelo host app.
921
+ *
922
+ * Como o Stripe Elements renderiza em iframe isolado, não consegue ler CSS vars
923
+ * da página host. Resolva os valores via `getComputedStyle` antes de passar:
924
+ *
925
+ * @example
926
+ * function resolveToken(v: string) {
927
+ * return getComputedStyle(document.documentElement).getPropertyValue(v).trim();
928
+ * }
929
+ * const appearance = getStripeAppearance(false, {
930
+ * primary: resolveToken("--primary"),
931
+ * background: resolveToken("--background"),
932
+ * card: resolveToken("--card"),
933
+ * foreground: resolveToken("--foreground"),
934
+ * muted: resolveToken("--muted-foreground"),
935
+ * border: resolveToken("--border"),
936
+ * destructive: resolveToken("--destructive"),
937
+ * });
938
+ */
939
+ interface ResolvedStripeTokens {
940
+ primary?: string;
941
+ background?: string;
942
+ card?: string;
943
+ foreground?: string;
944
+ muted?: string;
945
+ border?: string;
946
+ destructive?: string;
947
+ }
917
948
  /**
918
949
  * Retorna o objeto `appearance` para `<Elements>` do Stripe,
919
950
  * baseado no modo claro ou escuro do host app.
920
951
  *
921
- * @param isDark - true para modo escuro (padrão: false)
952
+ * @param isDark - true para modo escuro (padrão: false)
953
+ * @param tokens - valores CSS resolvidos em runtime (opcional; usa hex do DS como fallback)
922
954
  */
923
- declare function getStripeAppearance(isDark?: boolean): {
955
+ declare function getStripeAppearance(isDark?: boolean, tokens?: ResolvedStripeTokens): {
924
956
  theme: "none";
925
957
  variables: {
926
958
  colorPrimary: string;
package/dist/index.d.ts CHANGED
@@ -58,6 +58,8 @@ interface OfferAdventureItem {
58
58
  onRemove?: () => void;
59
59
  /** Extra rich content below the standard blocks (e.g. traveller table, HTML itinerary from the host app). */
60
60
  detailsSlot?: React.ReactNode;
61
+ /** Label shown above the itinerary/detailsSlot section. Defaults to "Itinerary". */
62
+ itineraryLabel?: string;
61
63
  }
62
64
  interface OfferDepositInfo {
63
65
  depositPercent: number;
@@ -914,13 +916,43 @@ declare const LIGHT: {
914
916
  };
915
917
  };
916
918
  };
919
+ /**
920
+ * Tokens opcionais resolvidos em runtime pelo host app.
921
+ *
922
+ * Como o Stripe Elements renderiza em iframe isolado, não consegue ler CSS vars
923
+ * da página host. Resolva os valores via `getComputedStyle` antes de passar:
924
+ *
925
+ * @example
926
+ * function resolveToken(v: string) {
927
+ * return getComputedStyle(document.documentElement).getPropertyValue(v).trim();
928
+ * }
929
+ * const appearance = getStripeAppearance(false, {
930
+ * primary: resolveToken("--primary"),
931
+ * background: resolveToken("--background"),
932
+ * card: resolveToken("--card"),
933
+ * foreground: resolveToken("--foreground"),
934
+ * muted: resolveToken("--muted-foreground"),
935
+ * border: resolveToken("--border"),
936
+ * destructive: resolveToken("--destructive"),
937
+ * });
938
+ */
939
+ interface ResolvedStripeTokens {
940
+ primary?: string;
941
+ background?: string;
942
+ card?: string;
943
+ foreground?: string;
944
+ muted?: string;
945
+ border?: string;
946
+ destructive?: string;
947
+ }
917
948
  /**
918
949
  * Retorna o objeto `appearance` para `<Elements>` do Stripe,
919
950
  * baseado no modo claro ou escuro do host app.
920
951
  *
921
- * @param isDark - true para modo escuro (padrão: false)
952
+ * @param isDark - true para modo escuro (padrão: false)
953
+ * @param tokens - valores CSS resolvidos em runtime (opcional; usa hex do DS como fallback)
922
954
  */
923
- declare function getStripeAppearance(isDark?: boolean): {
955
+ declare function getStripeAppearance(isDark?: boolean, tokens?: ResolvedStripeTokens): {
924
956
  theme: "none";
925
957
  variables: {
926
958
  colorPrimary: string;
package/dist/index.js CHANGED
@@ -478,8 +478,8 @@ var FloatingInput = React19.forwardRef(
478
478
  ref,
479
479
  placeholder: " ",
480
480
  className: cn(
481
- "peer block w-full rounded-lg border border-border bg-background",
482
- "px-3 pt-5 pb-2 text-base text-foreground font-ui",
481
+ "peer block w-full h-14 rounded-lg border border-border bg-background",
482
+ "px-3 pt-6 pb-2 text-base text-foreground font-ui",
483
483
  "transition-colors placeholder-transparent",
484
484
  "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
485
485
  error && "border-destructive focus:border-destructive focus:ring-destructive"
@@ -495,8 +495,8 @@ var FloatingInput = React19.forwardRef(
495
495
  "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2",
496
496
  "text-base text-muted-foreground font-ui transition-all duration-150",
497
497
  /* When peer has content or is focused, float up */
498
- "peer-focus:top-3 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary",
499
- "peer-not-placeholder-shown:top-3 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs peer-not-placeholder-shown:text-muted-foreground"
498
+ "peer-focus:top-2 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary",
499
+ "peer-not-placeholder-shown:top-2 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs peer-not-placeholder-shown:text-muted-foreground"
500
500
  ),
501
501
  children: [
502
502
  label,
@@ -520,8 +520,8 @@ var FloatingSelect = React19.forwardRef(
520
520
  id: inputId,
521
521
  ref,
522
522
  className: cn(
523
- "peer block w-full appearance-none rounded-lg border border-border bg-background",
524
- "px-3 pt-5 pb-2 text-base text-foreground font-ui",
523
+ "peer block w-full h-14 appearance-none rounded-lg border border-border bg-background",
524
+ "px-3 pt-6 pb-2 text-base text-foreground font-ui",
525
525
  "transition-colors",
526
526
  "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
527
527
  error && "border-destructive"
@@ -551,8 +551,8 @@ var FloatingSelect = React19.forwardRef(
551
551
  className: cn(
552
552
  "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2",
553
553
  "text-base text-muted-foreground font-ui transition-all duration-150",
554
- "peer-focus:top-3 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary",
555
- "peer-not-placeholder-shown:top-3 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs"
554
+ "peer-focus:top-2 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary",
555
+ "peer-not-placeholder-shown:top-2 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs"
556
556
  ),
557
557
  children: [
558
558
  label,
@@ -1089,8 +1089,27 @@ function CountrySearchField({
1089
1089
  ] })
1090
1090
  ] });
1091
1091
  }
1092
+ var VARIANT_STYLES = {
1093
+ error: "text-destructive border-destructive/30 bg-destructive/5",
1094
+ warning: "text-amber-400 border-amber-500/30 bg-amber-500/10",
1095
+ success: "text-primary border-primary/30 bg-primary/10",
1096
+ info: "text-muted-foreground border-primary/25 bg-primary/5"
1097
+ };
1098
+ function Alert({ variant = "info", children, className }) {
1099
+ return /* @__PURE__ */ jsx(
1100
+ "div",
1101
+ {
1102
+ className: cn(
1103
+ "rounded-lg border px-3 py-2 text-sm font-sans leading-snug",
1104
+ VARIANT_STYLES[variant],
1105
+ className
1106
+ ),
1107
+ children
1108
+ }
1109
+ );
1110
+ }
1092
1111
  function AdventureCard({ adventure }) {
1093
- var _a, _b, _c, _d, _e;
1112
+ var _a, _b, _c, _d, _e, _f;
1094
1113
  const isControlled = (_b = (_a = adventure.optionals) == null ? void 0 : _a.some((o) => o.onCheckedChange !== void 0)) != null ? _b : false;
1095
1114
  const [checkedInternal, setCheckedInternal] = React19.useState(
1096
1115
  new Set((_d = (_c = adventure.optionals) == null ? void 0 : _c.filter((o) => o.defaultChecked).map((o) => o.id)) != null ? _d : [])
@@ -1177,11 +1196,32 @@ function AdventureCard({ adventure }) {
1177
1196
  opt.id
1178
1197
  )) })
1179
1198
  ] }),
1180
- adventure.description && /* @__PURE__ */ jsxs(Fragment, { children: [
1199
+ (adventure.description || adventure.detailsSlot) && /* @__PURE__ */ jsxs(Fragment, { children: [
1181
1200
  /* @__PURE__ */ jsx(Separator, { className: "my-1" }),
1182
1201
  /* @__PURE__ */ jsxs("div", { children: [
1183
- /* @__PURE__ */ jsx("p", { className: "text-[10px] font-bold text-muted-foreground font-heading uppercase tracking-widest mb-2", children: "Itinerary" }),
1184
- /* @__PURE__ */ jsx("p", { className: "text-base text-foreground/80 leading-relaxed font-sans", children: adventure.description })
1202
+ /* @__PURE__ */ jsx("p", { className: "text-[10px] font-bold text-muted-foreground font-heading uppercase tracking-widest mb-3", children: (_f = adventure.itineraryLabel) != null ? _f : "Itinerary" }),
1203
+ adventure.description && !adventure.detailsSlot && /* @__PURE__ */ jsx("p", { className: "text-base text-foreground/80 leading-relaxed font-sans", children: adventure.description }),
1204
+ adventure.detailsSlot && /* @__PURE__ */ jsx("div", { className: cn(
1205
+ "text-foreground",
1206
+ // Base paragraph and heading styles
1207
+ "[&_p]:text-base [&_p]:text-foreground/80 [&_p]:leading-relaxed [&_p]:mb-2",
1208
+ "[&_h2]:text-xl [&_h2]:font-bold [&_h2]:text-foreground [&_h2]:mb-2 [&_h2]:mt-4",
1209
+ "[&_h3]:text-lg [&_h3]:font-semibold [&_h3]:text-foreground [&_h3]:mb-1 [&_h3]:mt-3",
1210
+ "[&_strong]:font-bold [&_strong]:text-foreground",
1211
+ "[&_em]:italic",
1212
+ "[&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2",
1213
+ "[&_blockquote]:border-l-2 [&_blockquote]:border-primary [&_blockquote]:pl-3 [&_blockquote]:italic [&_blockquote]:text-muted-foreground [&_blockquote]:my-2",
1214
+ // Standard lists
1215
+ "[&_ul:not(.list-check):not(.list-cross)]:list-disc [&_ul:not(.list-check):not(.list-cross)]:pl-5 [&_ul:not(.list-check):not(.list-cross)]:space-y-1",
1216
+ "[&_ol]:list-decimal [&_ol]:pl-5 [&_ol]:space-y-1",
1217
+ "[&_li]:text-base [&_li]:text-foreground/80 [&_li]:leading-relaxed",
1218
+ // Check list (✓)
1219
+ "[&_.list-check]:list-none [&_.list-check]:pl-5 [&_.list-check]:space-y-1",
1220
+ "[&_.list-check_li]:relative [&_.list-check_li]:before:absolute [&_.list-check_li]:before:-left-5 [&_.list-check_li]:before:content-['\u2713'] [&_.list-check_li]:before:text-primary [&_.list-check_li]:before:font-bold",
1221
+ // Cross list (✗)
1222
+ "[&_.list-cross]:list-none [&_.list-cross]:pl-5 [&_.list-cross]:space-y-1",
1223
+ "[&_.list-cross_li]:relative [&_.list-cross_li]:before:absolute [&_.list-cross_li]:before:-left-5 [&_.list-cross_li]:before:content-['\u2717'] [&_.list-cross_li]:before:text-destructive [&_.list-cross_li]:before:font-bold"
1224
+ ), children: adventure.detailsSlot })
1185
1225
  ] })
1186
1226
  ] }),
1187
1227
  adventure.included && adventure.included.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2.5 mt-1", children: [
@@ -1204,10 +1244,6 @@ function AdventureCard({ adventure }) {
1204
1244
  /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-primary shrink-0 mt-2.5" }),
1205
1245
  item
1206
1246
  ] }, i)) })
1207
- ] }),
1208
- adventure.detailsSlot && /* @__PURE__ */ jsxs(Fragment, { children: [
1209
- /* @__PURE__ */ jsx(Separator, { className: "my-1" }),
1210
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3 text-foreground", children: adventure.detailsSlot })
1211
1247
  ] })
1212
1248
  ] })
1213
1249
  ] });
@@ -1531,8 +1567,8 @@ function BookingShell({
1531
1567
  ] }),
1532
1568
  /* @__PURE__ */ jsxs("div", { className: "p-5 flex flex-col gap-5", children: [
1533
1569
  /* @__PURE__ */ jsx("div", { children }),
1534
- error && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive font-sans", children: error }),
1535
- successMessage && /* @__PURE__ */ jsx("div", { className: "text-sm font-sans rounded-lg px-3 py-2 bg-primary/10 border border-primary/30 text-primary", children: successMessage }),
1570
+ error && /* @__PURE__ */ jsx(Alert, { variant: "error", children: error }),
1571
+ successMessage && /* @__PURE__ */ jsx(Alert, { variant: "success", children: successMessage }),
1536
1572
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
1537
1573
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1538
1574
  currentStep > 0 && /* @__PURE__ */ jsxs(
@@ -1563,7 +1599,7 @@ function BookingShell({
1563
1599
  }
1564
1600
  )
1565
1601
  ] }),
1566
- nextDisabled && nextBlockedMessage && /* @__PURE__ */ jsx("div", { className: "text-xs text-amber-400 bg-amber-500/10 border border-amber-500/30 rounded-lg px-3 py-2", children: nextBlockedMessage }),
1602
+ nextDisabled && nextBlockedMessage && /* @__PURE__ */ jsx(Alert, { variant: "warning", children: nextBlockedMessage }),
1567
1603
  currentStep === 0 && onCancel && /* @__PURE__ */ jsx(
1568
1604
  "button",
1569
1605
  {
@@ -6444,25 +6480,6 @@ function ActivityCard({
6444
6480
  }
6445
6481
  );
6446
6482
  }
6447
- var VARIANT_STYLES = {
6448
- error: "text-destructive border-destructive/30 bg-destructive/5",
6449
- warning: "text-amber-400 border-amber-500/30 bg-amber-500/10",
6450
- success: "text-primary border-primary/30 bg-primary/10",
6451
- info: "text-muted-foreground border-primary/25 bg-primary/5"
6452
- };
6453
- function Alert({ variant = "info", children, className }) {
6454
- return /* @__PURE__ */ jsx(
6455
- "div",
6456
- {
6457
- className: cn(
6458
- "rounded-lg border px-3 py-2 text-sm font-sans leading-snug",
6459
- VARIANT_STYLES[variant],
6460
- className
6461
- ),
6462
- children
6463
- }
6464
- );
6465
- }
6466
6483
  function PaymentModalShell({
6467
6484
  open,
6468
6485
  title,
@@ -6691,8 +6708,75 @@ var DARK = {
6691
6708
  }
6692
6709
  }
6693
6710
  };
6694
- function getStripeAppearance(isDark = false) {
6695
- return isDark ? DARK : LIGHT;
6711
+ function getStripeAppearance(isDark = false, tokens) {
6712
+ var _a, _b, _c, _d, _e, _f, _g;
6713
+ const base = isDark ? DARK : LIGHT;
6714
+ if (!tokens) return base;
6715
+ const t = {
6716
+ primary: (_a = tokens.primary) != null ? _a : base.variables.colorPrimary,
6717
+ background: (_b = tokens.background) != null ? _b : base.variables.colorBackground,
6718
+ card: (_c = tokens.card) != null ? _c : base.variables.colorBackground,
6719
+ foreground: (_d = tokens.foreground) != null ? _d : base.variables.colorText,
6720
+ muted: (_e = tokens.muted) != null ? _e : base.variables.colorTextPlaceholder,
6721
+ border: (_f = tokens.border) != null ? _f : isDark ? "rgba(255,255,255,0.10)" : "#e3eeeb",
6722
+ destructive: (_g = tokens.destructive) != null ? _g : base.variables.colorDanger
6723
+ };
6724
+ return __spreadProps(__spreadValues({}, base), {
6725
+ variables: __spreadProps(__spreadValues({}, base.variables), {
6726
+ colorPrimary: t.primary,
6727
+ colorBackground: t.card,
6728
+ colorText: t.foreground,
6729
+ colorTextPlaceholder: t.muted,
6730
+ colorIcon: t.muted,
6731
+ colorIconTab: t.muted,
6732
+ colorIconTabSelected: t.primary,
6733
+ colorIconTabHover: t.foreground,
6734
+ colorDanger: t.destructive
6735
+ }),
6736
+ rules: __spreadProps(__spreadValues({}, base.rules), {
6737
+ ".Input": __spreadProps(__spreadValues({}, base.rules[".Input"]), {
6738
+ border: `1px solid ${t.border}`,
6739
+ backgroundColor: t.background,
6740
+ color: t.foreground
6741
+ }),
6742
+ ".Input:focus": {
6743
+ border: `1px solid ${t.primary}`,
6744
+ boxShadow: `0 0 0 2px color-mix(in srgb, ${t.primary} 20%, transparent)`,
6745
+ outline: "none"
6746
+ },
6747
+ ".Input--invalid": {
6748
+ border: `1px solid ${t.destructive}`,
6749
+ boxShadow: `0 0 0 2px color-mix(in srgb, ${t.destructive} 15%, transparent)`
6750
+ },
6751
+ ".Label": __spreadProps(__spreadValues({}, base.rules[".Label"]), {
6752
+ color: t.muted
6753
+ }),
6754
+ ".Error": {
6755
+ color: t.destructive,
6756
+ fontSize: "12px"
6757
+ },
6758
+ ".Tab": __spreadProps(__spreadValues({}, base.rules[".Tab"]), {
6759
+ border: `1px solid ${t.border}`,
6760
+ backgroundColor: t.background,
6761
+ color: t.muted
6762
+ }),
6763
+ ".Tab:hover": {
6764
+ color: t.foreground,
6765
+ border: `1px solid ${t.primary}`
6766
+ },
6767
+ ".Tab--selected": {
6768
+ border: `1px solid ${t.primary}`,
6769
+ backgroundColor: `color-mix(in srgb, ${t.primary} 8%, transparent)`,
6770
+ color: t.foreground,
6771
+ boxShadow: "none"
6772
+ },
6773
+ ".TabLabel--selected": { color: t.foreground },
6774
+ ".TabIcon--selected": { fill: t.primary },
6775
+ ".Block": __spreadProps(__spreadValues({}, base.rules[".Block"]), {
6776
+ border: `1px solid ${t.border}`
6777
+ })
6778
+ })
6779
+ });
6696
6780
  }
6697
6781
  var stripeAppearance = LIGHT;
6698
6782
  function Input(_a) {