@ticketboothapp/booking 1.2.178 → 1.2.180

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ticketboothapp/booking",
3
- "version": "1.2.178",
3
+ "version": "1.2.180",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "**/*.css",
@@ -160,7 +160,14 @@ export function AddOnsSection({
160
160
  const price = (addOn.price ?? 0) + (variant.priceAdjustment ?? 0);
161
161
  return (
162
162
  <div key={variant.id} className="flex flex-wrap items-center gap-3 p-3 bg-stone-50 rounded-lg">
163
- <span className="text-sm text-stone-800 flex-1">{variant.label}</span>
163
+ <span className="min-w-0 flex-1">
164
+ <span className="block text-sm text-stone-800">{variant.label}</span>
165
+ {variant.description?.trim() ? (
166
+ <span className="mt-0.5 block text-xs leading-snug text-stone-500">
167
+ {variant.description.trim()}
168
+ </span>
169
+ ) : null}
170
+ </span>
164
171
  <span className="text-sm text-stone-500 shrink-0">
165
172
  {suppressPrices ? '—' : `${formatCurrencyAmount(price, currency, locale as 'en' | 'fr')} ea`}
166
173
  </span>
@@ -260,7 +267,14 @@ export function AddOnsSection({
260
267
  : 'border-stone-200 bg-stone-50 hover:border-stone-300'
261
268
  }`}
262
269
  >
263
- <span className="text-sm font-medium text-stone-800">{variant.label}</span>
270
+ <span className="min-w-0 flex-1">
271
+ <span className="block text-sm font-medium text-stone-800">{variant.label}</span>
272
+ {variant.description?.trim() ? (
273
+ <span className="mt-0.5 block text-xs font-normal leading-snug text-stone-500">
274
+ {variant.description.trim()}
275
+ </span>
276
+ ) : null}
277
+ </span>
264
278
  <span className="text-sm text-stone-500">
265
279
  {suppressPrices ? '—' : `+${formatCurrencyAmount(price, currency, locale as 'en' | 'fr')}`}
266
280
  </span>
@@ -45,7 +45,7 @@ export function canUseMealDrinkSelector(addOn: AddOn): boolean {
45
45
  * into step1 (meal types) and step2 (drink types) for a 2-step selection UI.
46
46
  */
47
47
  function parseTwoStepVariants(variants: AddOnVariant[]): {
48
- step1Options: { id: string; label: string }[];
48
+ step1Options: { id: string; label: string; description?: string }[];
49
49
  step2Options: { id: string; label: string }[];
50
50
  getVariantId: (step1Id: string, step2Id: string) => string | null;
51
51
  } | null {
@@ -55,6 +55,7 @@ function parseTwoStepVariants(variants: AddOnVariant[]): {
55
55
  const step1Options: { id: string; label: string }[] = [];
56
56
  const step2Options: { id: string; label: string }[] = [];
57
57
  const variantByKey = new Map<string, string>();
58
+ const step1Descriptions = new Map<string, string[]>();
58
59
 
59
60
  for (const v of variants) {
60
61
  const labelParts = v.label.split(/\s+\+\s+/);
@@ -76,6 +77,10 @@ function parseTwoStepVariants(variants: AddOnVariant[]): {
76
77
  if (!step1Options.some((o) => o.id === step1Id)) {
77
78
  step1Options.push({ id: step1Id, label: step1Label });
78
79
  }
80
+ step1Descriptions.set(step1Id, [
81
+ ...(step1Descriptions.get(step1Id) ?? []),
82
+ v.description?.trim() ?? '',
83
+ ]);
79
84
  if (!step2Options.some((o) => o.id === step2Id)) {
80
85
  step2Options.push({ id: step2Id, label: step2Label });
81
86
  }
@@ -85,9 +90,17 @@ function parseTwoStepVariants(variants: AddOnVariant[]): {
85
90
  const getVariantId = (s1: string, s2: string) => variantByKey.get(`${s1}:${s2}`) ?? null;
86
91
 
87
92
  if (step1Options.length < 2 || step2Options.length < 2) return null;
93
+ const describedStep1Options = step1Options.map((option) => {
94
+ const descriptions = step1Descriptions.get(option.id) ?? [];
95
+ const uniqueDescriptions = [...new Set(descriptions.filter(Boolean))];
96
+ const description = descriptions.length > 0 && descriptions.every(Boolean) && uniqueDescriptions.length === 1
97
+ ? uniqueDescriptions[0]
98
+ : undefined;
99
+ return { ...option, description };
100
+ });
88
101
  // Sort step2 so "water" comes first when reducing meals (cap water at total, rest to other)
89
102
  const sortedStep2 = [...step2Options].sort((a, b) => (a.id === 'water' ? -1 : b.id === 'water' ? 1 : 0));
90
- return { step1Options, step2Options: sortedStep2, getVariantId };
103
+ return { step1Options: describedStep1Options, step2Options: sortedStep2, getVariantId };
91
104
  }
92
105
 
93
106
  /**
@@ -243,7 +256,14 @@ export function MealDrinkAddOnSelector({
243
256
  const canDecrementTotal = totalStep1 > minimumTotal;
244
257
  return (
245
258
  <div key={opt.id} className="flex flex-wrap items-center gap-3 p-3 bg-stone-50 rounded-lg">
246
- <span className="font-medium text-stone-800 flex-1">{opt.label}</span>
259
+ <span className="min-w-0 flex-1">
260
+ <span className="block font-medium text-stone-800">{opt.label}</span>
261
+ {opt.description ? (
262
+ <span className="mt-0.5 block text-xs font-normal leading-snug text-stone-500">
263
+ {opt.description}
264
+ </span>
265
+ ) : null}
266
+ </span>
247
267
  <span className="text-sm text-stone-500 shrink-0">
248
268
  {suppressPrices ? '—' : `${formatCurrencyAmount(price, currency, locale)} ea`}
249
269
  </span>
@@ -9,7 +9,8 @@
9
9
  .section {
10
10
  padding-top: 1.5rem;
11
11
  margin-top: 1.5rem;
12
- border-top: 1px solid var(--booking-stone-200, #e7e5e4);
12
+ /* Keep this explicit: the scoped preflight resets borders on every child. */
13
+ border-top: 1px solid var(--booking-stone-200, #e7e5e4) !important;
13
14
  }
14
15
 
15
16
  .sectionLabel {
@@ -1007,11 +1007,9 @@
1007
1007
  border-top-color: var(--booking-stone-200, #e7e5e4) !important;
1008
1008
  }
1009
1009
 
1010
- /* Line above first receipt row (above ADULT etc.): CheckoutForm / private shuttle section wrappers */
1010
+ /* Line above first receipt row (above ADULT etc.): CheckoutForm section wrappers */
1011
1011
  .booking-flow-preflight [class*="CheckoutForm_section"],
1012
- .booking-flow-root [class*="CheckoutForm_section"],
1013
- .booking-flow-preflight [class*="PrivateShuttleBookingFlow_section"],
1014
- .booking-flow-root [class*="PrivateShuttleBookingFlow_section"] {
1012
+ .booking-flow-root [class*="CheckoutForm_section"] {
1015
1013
  border-top-width: 1px !important;
1016
1014
  border-top-style: solid !important;
1017
1015
  border-top-color: var(--booking-stone-200, #e7e5e4) !important;
@@ -802,6 +802,7 @@ export interface AddOnVariant {
802
802
  id: string;
803
803
  label: string;
804
804
  priceAdjustment: number;
805
+ description?: string | null;
805
806
  }
806
807
 
807
808
  export interface AddOn {