@ticketlayer/elements 0.3.3 → 1.0.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/README.md +3 -2
- package/dist/cjs/{index-BpfoKd9Q.js → index-DanPUX0s.js} +1 -1
- package/dist/cjs/index.cjs.js +2 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/ticket-selector-BYVL13k_.js +3623 -0
- package/dist/cjs/ticketlayer-elements.cjs.js +2 -2
- package/dist/cjs/tl-buy-modal.cjs.entry.js +4 -4
- package/dist/cjs/tl-buy-tickets-button.cjs.entry.js +89 -71
- package/dist/cjs/tl-buy-tickets-wrapper.cjs.entry.js +62 -31
- package/dist/cjs/tl-cart-badge.cjs.entry.js +75 -62
- package/dist/cjs/tl-cart-drawer.cjs.entry.js +52 -24
- package/dist/cjs/tl-cart.cjs.entry.js +72 -98
- package/dist/cjs/tl-checkout-wrapper.cjs.entry.js +52 -30
- package/dist/cjs/tl-event-card.cjs.entry.js +44 -105
- package/dist/cjs/tl-event-list.cjs.entry.js +73 -36
- package/dist/cjs/tl-login.cjs.entry.js +75 -141
- package/dist/cjs/tl-my-orders.cjs.entry.js +53 -92
- package/dist/cjs/tl-occurrence-selector_2.cjs.entry.js +205 -641
- package/dist/cjs/tl-order-confirmation.cjs.entry.js +72 -105
- package/dist/cjs/tl-order-tickets_2.cjs.entry.js +50 -76
- package/dist/cjs/tl-promo-code.cjs.entry.js +51 -47
- package/dist/cjs/tl-seat-map.cjs.entry.js +4 -4
- package/dist/cjs/web-query-Ce73jB4k.js +16 -0
- package/dist/collection/components/tl-buy-modal/tl-buy-modal.css +12 -19
- package/dist/collection/components/tl-buy-modal/tl-buy-modal.js +2 -2
- package/dist/collection/components/tl-buy-tickets-button/tl-buy-tickets-button.css +41 -4
- package/dist/collection/components/tl-buy-tickets-button/tl-buy-tickets-button.js +105 -76
- package/dist/collection/components/tl-buy-tickets-wrapper/tl-buy-tickets-wrapper.css +2 -2
- package/dist/collection/components/tl-buy-tickets-wrapper/tl-buy-tickets-wrapper.js +73 -30
- package/dist/collection/components/tl-cart/tl-cart.css +52 -51
- package/dist/collection/components/tl-cart/tl-cart.js +82 -101
- package/dist/collection/components/tl-cart-badge/tl-cart-badge.css +11 -11
- package/dist/collection/components/tl-cart-badge/tl-cart-badge.js +62 -62
- package/dist/collection/components/tl-cart-drawer/tl-cart-drawer.css +6 -6
- package/dist/collection/components/tl-cart-drawer/tl-cart-drawer.js +56 -24
- package/dist/collection/components/tl-checkout-wrapper/tl-checkout-wrapper.css +2 -2
- package/dist/collection/components/tl-checkout-wrapper/tl-checkout-wrapper.js +61 -29
- package/dist/collection/components/tl-event-card/event-card-adapter.js +11 -23
- package/dist/collection/components/tl-event-card/tl-event-card.css +22 -22
- package/dist/collection/components/tl-event-card/tl-event-card.js +51 -84
- package/dist/collection/components/tl-event-list/tl-event-list.css +17 -17
- package/dist/collection/components/tl-event-list/tl-event-list.js +82 -38
- package/dist/collection/components/tl-login/tl-login.css +26 -26
- package/dist/collection/components/tl-login/tl-login.js +83 -147
- package/dist/collection/components/tl-my-orders/tl-my-orders.css +40 -40
- package/dist/collection/components/tl-my-orders/tl-my-orders.js +58 -96
- package/dist/collection/components/tl-occurrence-selector/tl-occurrence-selector.css +54 -65
- package/dist/collection/components/tl-occurrence-selector/tl-occurrence-selector.js +137 -516
- package/dist/collection/components/tl-order-confirmation/tl-order-confirmation.css +38 -38
- package/dist/collection/components/tl-order-confirmation/tl-order-confirmation.js +81 -113
- package/dist/collection/components/tl-order-tickets/tl-order-tickets.css +9 -9
- package/dist/collection/components/tl-order-tickets/tl-order-tickets.js +57 -92
- package/dist/collection/components/tl-promo-code/tl-promo-code.css +25 -25
- package/dist/collection/components/tl-promo-code/tl-promo-code.js +55 -50
- package/dist/collection/components/tl-seat-map/tl-seat-map.css +10 -10
- package/dist/collection/components/tl-seat-map/tl-seat-map.js +2 -2
- package/dist/collection/components/tl-ticket/tl-ticket.css +13 -13
- package/dist/collection/components/tl-ticket-selector/tl-ticket-selector.css +74 -49
- package/dist/collection/components/tl-ticket-selector/tl-ticket-selector.js +95 -135
- package/dist/collection/utils/cart-totals.js +9 -0
- package/dist/collection/utils/order-summary.js +15 -99
- package/dist/collection/utils/testing/deep-text.js +29 -0
- package/dist/collection/utils/testing/fixtures.js +290 -0
- package/dist/collection/utils/testing/mock-sdk.js +13 -2
- package/dist/collection/utils/web-query.js +12 -0
- package/dist/collection/utils/web-storage.js +22 -0
- package/dist/components/ticket-selector.js +1 -0
- package/dist/components/tl-buy-modal.js +1 -1
- package/dist/components/tl-buy-tickets-button.js +1 -1
- package/dist/components/tl-buy-tickets-wrapper2.js +1 -1
- package/dist/components/tl-cart-badge.js +1 -1
- package/dist/components/tl-cart-drawer.js +1 -1
- package/dist/components/tl-cart2.js +1 -1
- package/dist/components/tl-checkout-wrapper2.js +1 -1
- package/dist/components/tl-event-card2.js +1 -1
- package/dist/components/tl-event-list.js +1 -1
- package/dist/components/tl-login2.js +1 -1
- package/dist/components/tl-my-orders.js +1 -1
- package/dist/components/tl-occurrence-selector2.js +1 -1
- package/dist/components/tl-order-confirmation.js +1 -1
- package/dist/components/tl-order-tickets2.js +1 -1
- package/dist/components/tl-promo-code.js +1 -1
- package/dist/components/tl-seat-map.js +1 -1
- package/dist/components/tl-ticket-selector2.js +1 -1
- package/dist/components/tl-ticket2.js +1 -1
- package/dist/components/web-query.js +1 -0
- package/dist/elements.docs.json +36 -36
- package/dist/esm/{index-CNX8hZa8.js → index-imfxp765.js} +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/ticket-selector-BwChnHVC.js +3606 -0
- package/dist/esm/ticketlayer-elements.js +3 -3
- package/dist/esm/tl-buy-modal.entry.js +4 -4
- package/dist/esm/tl-buy-tickets-button.entry.js +90 -72
- package/dist/esm/tl-buy-tickets-wrapper.entry.js +63 -32
- package/dist/esm/tl-cart-badge.entry.js +76 -63
- package/dist/esm/tl-cart-drawer.entry.js +53 -25
- package/dist/esm/tl-cart.entry.js +73 -99
- package/dist/esm/tl-checkout-wrapper.entry.js +53 -31
- package/dist/esm/tl-event-card.entry.js +45 -106
- package/dist/esm/tl-event-list.entry.js +74 -37
- package/dist/esm/tl-login.entry.js +76 -142
- package/dist/esm/tl-my-orders.entry.js +54 -93
- package/dist/esm/tl-occurrence-selector_2.entry.js +206 -642
- package/dist/esm/tl-order-confirmation.entry.js +73 -106
- package/dist/esm/tl-order-tickets_2.entry.js +51 -77
- package/dist/esm/tl-promo-code.entry.js +52 -48
- package/dist/esm/tl-seat-map.entry.js +4 -4
- package/dist/esm/web-query-Bdbb2lk5.js +14 -0
- package/dist/ticketlayer-elements/index.esm.js +1 -1
- package/dist/ticketlayer-elements/p-45923d2c.entry.js +1 -0
- package/dist/ticketlayer-elements/p-492adc77.entry.js +1 -0
- package/dist/ticketlayer-elements/p-4cfc9e53.entry.js +1 -0
- package/dist/ticketlayer-elements/p-5135630e.entry.js +1 -0
- package/dist/ticketlayer-elements/p-5bbce3b5.entry.js +1 -0
- package/dist/ticketlayer-elements/p-7d547721.entry.js +1 -0
- package/dist/ticketlayer-elements/p-7fe7b6ba.entry.js +1 -0
- package/dist/ticketlayer-elements/p-8122f0c1.entry.js +1 -0
- package/dist/ticketlayer-elements/p-98d40869.entry.js +1 -0
- package/dist/ticketlayer-elements/p-Bdbb2lk5.js +1 -0
- package/dist/ticketlayer-elements/p-BwChnHVC.js +1 -0
- package/dist/ticketlayer-elements/p-abec290a.entry.js +1 -0
- package/dist/ticketlayer-elements/p-ac79a3f6.entry.js +1 -0
- package/dist/ticketlayer-elements/p-d01f4429.entry.js +1 -0
- package/dist/ticketlayer-elements/p-d7ffaf46.entry.js +1 -0
- package/dist/ticketlayer-elements/p-e7170f3c.entry.js +1 -0
- package/dist/ticketlayer-elements/p-e787e862.entry.js +1 -0
- package/dist/ticketlayer-elements/p-f1ff931f.entry.js +1 -0
- package/dist/ticketlayer-elements/p-imfxp765.js +3 -0
- package/dist/ticketlayer-elements/ticketlayer-elements.css +1 -1
- package/dist/ticketlayer-elements/ticketlayer-elements.esm.js +1 -1
- package/dist/types/components/tl-buy-tickets-button/tl-buy-tickets-button.d.ts +40 -8
- package/dist/types/components/tl-buy-tickets-wrapper/tl-buy-tickets-wrapper.d.ts +20 -1
- package/dist/types/components/tl-cart/tl-cart.d.ts +40 -32
- package/dist/types/components/tl-cart-badge/tl-cart-badge.d.ts +22 -7
- package/dist/types/components/tl-cart-drawer/tl-cart-drawer.d.ts +28 -5
- package/dist/types/components/tl-checkout-wrapper/tl-checkout-wrapper.d.ts +18 -1
- package/dist/types/components/tl-event-card/event-card-adapter.d.ts +9 -20
- package/dist/types/components/tl-event-card/tl-event-card.d.ts +25 -28
- package/dist/types/components/tl-event-list/tl-event-list.d.ts +46 -6
- package/dist/types/components/tl-login/tl-login.d.ts +68 -22
- package/dist/types/components/tl-my-orders/tl-my-orders.d.ts +30 -12
- package/dist/types/components/tl-occurrence-selector/tl-occurrence-selector.d.ts +73 -161
- package/dist/types/components/tl-order-confirmation/tl-order-confirmation.d.ts +48 -15
- package/dist/types/components/tl-order-tickets/tl-order-tickets.d.ts +29 -31
- package/dist/types/components/tl-promo-code/tl-promo-code.d.ts +28 -10
- package/dist/types/components/tl-ticket/tl-ticket.d.ts +2 -11
- package/dist/types/components/tl-ticket-selector/tl-ticket-selector.d.ts +61 -32
- package/dist/types/components.d.ts +302 -62
- package/dist/types/utils/cart-totals.d.ts +10 -0
- package/dist/types/utils/order-summary.d.ts +16 -65
- package/dist/types/utils/testing/deep-text.d.ts +13 -0
- package/dist/types/utils/testing/fixtures.d.ts +225 -0
- package/dist/types/utils/testing/mock-sdk.d.ts +14 -1
- package/dist/types/utils/web-query.d.ts +18 -0
- package/dist/types/utils/web-storage.d.ts +16 -0
- package/elements.catalogue.json +676 -55
- package/package.json +14 -6
- package/dist/cjs/order-summary-ZMkJ5bez.js +0 -116
- package/dist/components/order-summary.js +0 -1
- package/dist/esm/order-summary-BGekdjN9.js +0 -103
- package/dist/ticketlayer-elements/p-0b1d16f8.entry.js +0 -1
- package/dist/ticketlayer-elements/p-1471f6d8.entry.js +0 -1
- package/dist/ticketlayer-elements/p-1c51cbc1.entry.js +0 -1
- package/dist/ticketlayer-elements/p-5169f68b.entry.js +0 -1
- package/dist/ticketlayer-elements/p-895ba1f3.entry.js +0 -1
- package/dist/ticketlayer-elements/p-8d5722e1.entry.js +0 -1
- package/dist/ticketlayer-elements/p-917d8e09.entry.js +0 -1
- package/dist/ticketlayer-elements/p-9629029a.entry.js +0 -1
- package/dist/ticketlayer-elements/p-BGekdjN9.js +0 -1
- package/dist/ticketlayer-elements/p-CNX8hZa8.js +0 -3
- package/dist/ticketlayer-elements/p-a22714d0.entry.js +0 -1
- package/dist/ticketlayer-elements/p-bf73044b.entry.js +0 -1
- package/dist/ticketlayer-elements/p-e02079fa.entry.js +0 -1
- package/dist/ticketlayer-elements/p-e04ace15.entry.js +0 -1
- package/dist/ticketlayer-elements/p-e6fab1d5.entry.js +0 -1
- package/dist/ticketlayer-elements/p-f826b753.entry.js +0 -1
- package/dist/ticketlayer-elements/p-fa639d88.entry.js +0 -1
- package/dist/ticketlayer-elements/p-fbaca948.entry.js +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The text an element actually shows, shadow roots included.
|
|
3
|
+
*
|
|
4
|
+
* `textContent` stops at a shadow boundary, and every element here renders
|
|
5
|
+
* into one (and several compose others: `tl-cart-drawer` holds a `tl-cart`,
|
|
6
|
+
* `tl-order-tickets` a grid of `tl-ticket`). A check that an element rendered
|
|
7
|
+
* something has to see through that, or it reads an empty string from an
|
|
8
|
+
* element that is perfectly full.
|
|
9
|
+
*
|
|
10
|
+
* Used by the stories' `expectRendered` in the browser and by
|
|
11
|
+
* story-coverage.spec.tsx in jsdom, so both are asking the same question.
|
|
12
|
+
*/
|
|
13
|
+
export function deepText(node) {
|
|
14
|
+
if (!node)
|
|
15
|
+
return '';
|
|
16
|
+
const parts = [];
|
|
17
|
+
const walk = (current) => {
|
|
18
|
+
if (current.nodeType === 3) {
|
|
19
|
+
parts.push(current.nodeValue ?? '');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const shadow = current.shadowRoot;
|
|
23
|
+
if (shadow)
|
|
24
|
+
walk(shadow);
|
|
25
|
+
current.childNodes.forEach(walk);
|
|
26
|
+
};
|
|
27
|
+
walk(node);
|
|
28
|
+
return parts.join(' ').replace(/\s+/g, ' ').trim();
|
|
29
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
export const FIXTURE_CUSTOMER = {
|
|
2
|
+
id: 'cus_ada',
|
|
3
|
+
email: 'ada@example.com',
|
|
4
|
+
firstName: 'Ada',
|
|
5
|
+
lastName: 'Lovelace',
|
|
6
|
+
};
|
|
7
|
+
/** `events.list` items, i.e. what a card is handed by `tl-event-list`. */
|
|
8
|
+
export const FIXTURE_EVENT_CARDS = [
|
|
9
|
+
{
|
|
10
|
+
id: 'evt_midnight',
|
|
11
|
+
name: 'Midnight Quartet',
|
|
12
|
+
shortDescription: 'Late night strings in the Old Hall',
|
|
13
|
+
availabilityStatus: 'available',
|
|
14
|
+
venue: { id: 'ven_old_hall', name: 'The Old Hall', city: 'Bristol' },
|
|
15
|
+
nextOccurrence: { startsAt: '2030-06-14T19:30:00Z' },
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'evt_gala',
|
|
19
|
+
name: 'Summer Gala',
|
|
20
|
+
shortDescription: 'The season closes with the full orchestra',
|
|
21
|
+
availabilityStatus: 'limited',
|
|
22
|
+
venue: { id: 'ven_pavilion', name: 'Riverside Pavilion', city: 'Bath' },
|
|
23
|
+
nextOccurrence: { startsAt: '2030-07-05T18:00:00Z' },
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 'evt_lates',
|
|
27
|
+
name: 'Gallery Lates',
|
|
28
|
+
shortDescription: 'Music after hours among the paintings',
|
|
29
|
+
availabilityStatus: 'sold_out',
|
|
30
|
+
venue: { id: 'ven_gallery', name: 'City Gallery', city: 'Bristol' },
|
|
31
|
+
nextOccurrence: { startsAt: '2030-08-02T20:00:00Z' },
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
/** The occurrences of `evt_midnight`: enough dates for the calendar view. */
|
|
35
|
+
const MIDNIGHT_OCCURRENCES = [
|
|
36
|
+
{
|
|
37
|
+
id: 'evoc_1',
|
|
38
|
+
startsAt: '2030-06-14T19:30:00Z',
|
|
39
|
+
endsAt: '2030-06-14T21:30:00Z',
|
|
40
|
+
availabilityStatus: 'available',
|
|
41
|
+
availableCapacity: 120,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: 'evoc_2',
|
|
45
|
+
startsAt: '2030-06-15T19:30:00Z',
|
|
46
|
+
endsAt: '2030-06-15T21:30:00Z',
|
|
47
|
+
availabilityStatus: 'available',
|
|
48
|
+
availableCapacity: 40,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'evoc_3',
|
|
52
|
+
startsAt: '2030-06-21T19:30:00Z',
|
|
53
|
+
endsAt: '2030-06-21T21:30:00Z',
|
|
54
|
+
availabilityStatus: 'sold_out',
|
|
55
|
+
availableCapacity: 0,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
/** `events.get` details, keyed by event id. */
|
|
59
|
+
export const FIXTURE_EVENT_DETAILS = {
|
|
60
|
+
evt_midnight: {
|
|
61
|
+
id: 'evt_midnight',
|
|
62
|
+
name: 'Midnight Quartet',
|
|
63
|
+
status: 'on_sale',
|
|
64
|
+
shortDescription: 'Late night strings in the Old Hall',
|
|
65
|
+
venueId: 'ven_old_hall',
|
|
66
|
+
venueName: 'The Old Hall',
|
|
67
|
+
venueCity: 'Bristol',
|
|
68
|
+
occurrences: MIDNIGHT_OCCURRENCES,
|
|
69
|
+
},
|
|
70
|
+
evt_gala: {
|
|
71
|
+
id: 'evt_gala',
|
|
72
|
+
name: 'Summer Gala',
|
|
73
|
+
status: 'on_sale',
|
|
74
|
+
shortDescription: 'The season closes with the full orchestra',
|
|
75
|
+
venueId: 'ven_pavilion',
|
|
76
|
+
venueName: 'Riverside Pavilion',
|
|
77
|
+
venueCity: 'Bath',
|
|
78
|
+
occurrences: [
|
|
79
|
+
{
|
|
80
|
+
id: 'evoc_gala',
|
|
81
|
+
startsAt: '2030-07-05T18:00:00Z',
|
|
82
|
+
endsAt: '2030-07-05T22:00:00Z',
|
|
83
|
+
availabilityStatus: 'available',
|
|
84
|
+
availableCapacity: 300,
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
/** `events.getTicketTypes` for `evoc_1`. */
|
|
90
|
+
export const FIXTURE_TICKET_TYPES = [
|
|
91
|
+
{
|
|
92
|
+
id: 'tkt_adult',
|
|
93
|
+
occurrenceId: 'evoc_1',
|
|
94
|
+
name: 'Adult',
|
|
95
|
+
description: 'Standing, unreserved',
|
|
96
|
+
price: 2500,
|
|
97
|
+
currency: 'GBP',
|
|
98
|
+
availableQuantity: 120,
|
|
99
|
+
maxPerOrder: 6,
|
|
100
|
+
minPerOrder: 0,
|
|
101
|
+
availabilityStatus: 'available',
|
|
102
|
+
sortOrder: 1,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'tkt_concession',
|
|
106
|
+
occurrenceId: 'evoc_1',
|
|
107
|
+
name: 'Concession',
|
|
108
|
+
description: 'Students and over 65s',
|
|
109
|
+
price: 1500,
|
|
110
|
+
currency: 'GBP',
|
|
111
|
+
availableQuantity: 20,
|
|
112
|
+
maxPerOrder: 4,
|
|
113
|
+
minPerOrder: 0,
|
|
114
|
+
availabilityStatus: 'limited',
|
|
115
|
+
sortOrder: 2,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: 'tkt_gallery',
|
|
119
|
+
occurrenceId: 'evoc_1',
|
|
120
|
+
name: 'Gallery',
|
|
121
|
+
description: 'Seated, upper level',
|
|
122
|
+
price: 4000,
|
|
123
|
+
currency: 'GBP',
|
|
124
|
+
availableQuantity: 0,
|
|
125
|
+
maxPerOrder: 4,
|
|
126
|
+
minPerOrder: 0,
|
|
127
|
+
availabilityStatus: 'sold_out',
|
|
128
|
+
sortOrder: 3,
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
/** A cart with lines, a fee the surface quoted and a discount. */
|
|
132
|
+
export const FIXTURE_CART = {
|
|
133
|
+
items: [
|
|
134
|
+
{
|
|
135
|
+
id: 'ci_adult',
|
|
136
|
+
ticketTypeId: 'tkt_adult',
|
|
137
|
+
ticketTypeName: 'Adult',
|
|
138
|
+
eventName: 'Midnight Quartet',
|
|
139
|
+
occurrenceDate: '2030-06-14T19:30:00Z',
|
|
140
|
+
quantity: 2,
|
|
141
|
+
unitPrice: 2500,
|
|
142
|
+
totalPrice: 5000,
|
|
143
|
+
subtotal: 5000,
|
|
144
|
+
currency: 'GBP',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: 'ci_concession',
|
|
148
|
+
ticketTypeId: 'tkt_concession',
|
|
149
|
+
ticketTypeName: 'Concession',
|
|
150
|
+
eventName: 'Midnight Quartet',
|
|
151
|
+
occurrenceDate: '2030-06-14T19:30:00Z',
|
|
152
|
+
quantity: 1,
|
|
153
|
+
unitPrice: 1500,
|
|
154
|
+
totalPrice: 1500,
|
|
155
|
+
subtotal: 1500,
|
|
156
|
+
currency: 'GBP',
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
itemCount: 3,
|
|
160
|
+
subtotal: 6500,
|
|
161
|
+
fees: 325,
|
|
162
|
+
discount: 500,
|
|
163
|
+
total: 6325,
|
|
164
|
+
hasFees: true,
|
|
165
|
+
feeLabel: 'Booking fee',
|
|
166
|
+
currency: 'GBP',
|
|
167
|
+
};
|
|
168
|
+
/** An empty cart, for the states an element only reaches with nothing in it. */
|
|
169
|
+
export const FIXTURE_EMPTY_CART = {
|
|
170
|
+
items: [],
|
|
171
|
+
itemCount: 0,
|
|
172
|
+
subtotal: 0,
|
|
173
|
+
fees: 0,
|
|
174
|
+
discount: 0,
|
|
175
|
+
total: 0,
|
|
176
|
+
hasFees: false,
|
|
177
|
+
feeLabel: null,
|
|
178
|
+
currency: 'GBP',
|
|
179
|
+
};
|
|
180
|
+
/** Passes on the order: what `tl-ticket` renders and `tl-order-tickets` grids. */
|
|
181
|
+
export const FIXTURE_TICKETS = [
|
|
182
|
+
{
|
|
183
|
+
id: 'pas_adult_1',
|
|
184
|
+
barcode: 'TLQ-3H7K-9F2D-0001',
|
|
185
|
+
type: 'ticket',
|
|
186
|
+
status: 'active',
|
|
187
|
+
holderName: 'Ada Lovelace',
|
|
188
|
+
name: 'Adult - Midnight Quartet',
|
|
189
|
+
admissionStatus: 'not_redeemed',
|
|
190
|
+
eventOccurrenceId: 'evoc_1',
|
|
191
|
+
seatLabel: 'Stalls C12',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
id: 'pas_adult_2',
|
|
195
|
+
barcode: 'TLQ-3H7K-9F2D-0002',
|
|
196
|
+
type: 'ticket',
|
|
197
|
+
status: 'active',
|
|
198
|
+
holderName: 'Ada Lovelace',
|
|
199
|
+
name: 'Adult - Midnight Quartet',
|
|
200
|
+
admissionStatus: 'fully_redeemed',
|
|
201
|
+
eventOccurrenceId: 'evoc_1',
|
|
202
|
+
seatLabel: 'Stalls C13',
|
|
203
|
+
},
|
|
204
|
+
];
|
|
205
|
+
export const FIXTURE_ORDER = {
|
|
206
|
+
id: 'ord_midnight',
|
|
207
|
+
orderNumber: 'ORD-MQ7841',
|
|
208
|
+
status: 'confirmed',
|
|
209
|
+
paymentStatus: 'paid',
|
|
210
|
+
currency: 'GBP',
|
|
211
|
+
items: [
|
|
212
|
+
{
|
|
213
|
+
name: 'Midnight Quartet - Adult',
|
|
214
|
+
description: null,
|
|
215
|
+
type: 'ticket',
|
|
216
|
+
quantity: 2,
|
|
217
|
+
unitPrice: 2500,
|
|
218
|
+
subtotal: 5000,
|
|
219
|
+
},
|
|
220
|
+
{ name: 'Booking fee', description: null, type: 'fee', quantity: 1, unitPrice: 250, subtotal: 250 },
|
|
221
|
+
],
|
|
222
|
+
subtotal: 5000,
|
|
223
|
+
totalFees: 250,
|
|
224
|
+
totalTax: 0,
|
|
225
|
+
total: 5250,
|
|
226
|
+
tickets: FIXTURE_TICKETS,
|
|
227
|
+
expiresAt: null,
|
|
228
|
+
createdAt: '2030-05-02T10:15:00Z',
|
|
229
|
+
};
|
|
230
|
+
const OLDER_ORDER = {
|
|
231
|
+
id: 'ord_gala',
|
|
232
|
+
orderNumber: 'ORD-SG1290',
|
|
233
|
+
status: 'confirmed',
|
|
234
|
+
paymentStatus: 'paid',
|
|
235
|
+
currency: 'GBP',
|
|
236
|
+
items: [
|
|
237
|
+
{
|
|
238
|
+
name: 'Summer Gala - Concession',
|
|
239
|
+
description: null,
|
|
240
|
+
type: 'ticket',
|
|
241
|
+
quantity: 1,
|
|
242
|
+
unitPrice: 1500,
|
|
243
|
+
subtotal: 1500,
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
subtotal: 1500,
|
|
247
|
+
totalFees: 0,
|
|
248
|
+
totalTax: 0,
|
|
249
|
+
total: 1500,
|
|
250
|
+
tickets: [],
|
|
251
|
+
expiresAt: null,
|
|
252
|
+
createdAt: '2030-04-11T09:00:00Z',
|
|
253
|
+
};
|
|
254
|
+
export const FIXTURE_ORDERS = [FIXTURE_ORDER, OLDER_ORDER];
|
|
255
|
+
/** The managers every dataset shares: the channel's catalogue and its orders. */
|
|
256
|
+
const catalogue = {
|
|
257
|
+
events: {
|
|
258
|
+
list: async () => ({ items: FIXTURE_EVENT_CARDS }),
|
|
259
|
+
get: async (id) => FIXTURE_EVENT_DETAILS[id] ?? FIXTURE_EVENT_DETAILS.evt_midnight,
|
|
260
|
+
getTicketTypes: async () => FIXTURE_TICKET_TYPES,
|
|
261
|
+
},
|
|
262
|
+
orders: {
|
|
263
|
+
mine: async () => FIXTURE_ORDERS,
|
|
264
|
+
get: async (orderId) => FIXTURE_ORDERS.find((o) => o.id === orderId) ?? FIXTURE_ORDER,
|
|
265
|
+
ticketPdf: async () => new Blob(['%PDF-1.4 fixture'], { type: 'application/pdf' }),
|
|
266
|
+
},
|
|
267
|
+
presale: {
|
|
268
|
+
redeem: async () => ({ benefit: 'Presale unlocked', alreadyHeld: false }),
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* The datasets a story may ask for by name, through
|
|
273
|
+
* `parameters.ticketlayer.dataset`. Keep the set small: a dataset is a state
|
|
274
|
+
* of the whole channel, not a per-element fixture.
|
|
275
|
+
*/
|
|
276
|
+
export const FIXTURE_DATASETS = {
|
|
277
|
+
/** Signed in, three events on sale, a cart with lines and two orders. */
|
|
278
|
+
default: {
|
|
279
|
+
...catalogue,
|
|
280
|
+
cart: { get: async () => FIXTURE_CART },
|
|
281
|
+
authState: { customer: FIXTURE_CUSTOMER, authenticated: true },
|
|
282
|
+
},
|
|
283
|
+
/** Nobody signed in and nothing in the cart. */
|
|
284
|
+
'signed-out': {
|
|
285
|
+
...catalogue,
|
|
286
|
+
cart: { get: async () => FIXTURE_EMPTY_CART },
|
|
287
|
+
authState: { customer: null, authenticated: false },
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
export const FIXTURE_DATASET_NAMES = Object.keys(FIXTURE_DATASETS);
|
|
@@ -58,17 +58,28 @@ export function createMockSDK(opts = {}) {
|
|
|
58
58
|
redeem: async () => ({ benefit: 'presale.test', alreadyHeld: false }),
|
|
59
59
|
...opts.presale,
|
|
60
60
|
};
|
|
61
|
+
const modalCalls = [];
|
|
61
62
|
const sdk = {
|
|
62
63
|
getEventsManager: () => eventsManager,
|
|
63
64
|
getCartManager: () => cartManager,
|
|
64
65
|
getOrdersManager: () => ordersManager,
|
|
65
66
|
on,
|
|
66
67
|
off,
|
|
67
|
-
event: () => ({
|
|
68
|
-
|
|
68
|
+
event: (eventId) => ({
|
|
69
|
+
openModal: (options = {}) => {
|
|
70
|
+
modalCalls.push({ kind: 'event', eventId, options });
|
|
71
|
+
},
|
|
72
|
+
}),
|
|
73
|
+
checkout: {
|
|
74
|
+
openModal: (options = {}) => {
|
|
75
|
+
modalCalls.push({ kind: 'checkout', options });
|
|
76
|
+
},
|
|
77
|
+
closeModal: () => undefined,
|
|
78
|
+
},
|
|
69
79
|
closeModal: () => undefined,
|
|
70
80
|
emit,
|
|
71
81
|
authState,
|
|
82
|
+
modalCalls,
|
|
72
83
|
};
|
|
73
84
|
if (!opts.withoutAuth)
|
|
74
85
|
sdk.getAuthManager = () => authManager;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const webStorage = {
|
|
2
|
+
get(key) {
|
|
3
|
+
if (typeof window === 'undefined')
|
|
4
|
+
return null;
|
|
5
|
+
try {
|
|
6
|
+
return window.localStorage.getItem(key);
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
set(key, value) {
|
|
13
|
+
if (typeof window === 'undefined')
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
window.localStorage.setItem(key, value);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// localStorage may be unavailable.
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={get:()=>null,set:()=>{}},t={get:()=>null},r=["discovery","purchase","cart","checkout","account","tickets"],n=["web","native"];function o(e){const t=t=>{throw new Error(`[elements-core] ${e.tag||"<no tag>"}: ${t}`)};/^tl-[a-z0-9]+(-[a-z0-9]+)*$/.test(e.tag)||t("tag must look like tl-something"),r.includes(e.category)||t(`category must be one of ${r.join(", ")}`),e.runtimes.length&&!e.runtimes.some((e=>!n.includes(e)))||t(`runtimes must be a non-empty subset of ${n.join(", ")}`),new Set(e.tokens).size!==e.tokens.length&&t("tokens must not repeat"),e.statuses.length||t("statuses must not be empty");for(const[r,n]of Object.entries(e.events))/^tl[A-Z]/.test(r)||t(`event ${r} must be named tlSomething`),n.detail||t(`event ${r} must state its detail type`);for(const[r,n]of Object.entries(e.props))n.required&&void 0!==n.default&&t(`prop ${r} is required and has a default`);return Object.freeze({...e})}function a(r,n={}){const o={};for(const[e,t]of Object.entries(r.props))void 0!==t.default&&(o[e]=t.default);let a={...o,...n.props??{}};const i={...r.strings,...n.strings??{}},d=n.locale??"en-GB",l=n.currency??"GBP";let c=s(n.client),u=r.state(a),g=!1;const m=new Set,p=new Set,y=(e,t)=>new Intl.NumberFormat(d,{style:"currency",currency:t||l}).format(e/100),f=n.storage??e,h=n.query??t,b=()=>{const e={props:a,state:u,strings:i,formatMoney:y};return{status:r.status(e),props:a,state:u,strings:i,derived:r.derive(e)}},w=()=>{if(g)return;const e=b();for(const t of[...p])t(e)},v={get props(){return a},get state(){return u},strings:i,formatMoney:y,setState(e){if(g)return;const t="function"==typeof e?e(u):e;u={...u,...t},w()},emit(e,t){if(!r.events[e])throw new Error(`[elements-core] ${r.tag}: ${e} is not a declared event`);n.emit?.(e,t)},client(){const e=c();if(!e)throw new Error(`[elements-core] ${r.tag}: no client. A harness hands the core the client the host published.`);return e},optionalClient(){try{return c()}catch{return null}},storage:f,query:h,whenClient:async()=>{n.clientReady&&await n.clientReady();const e=c();if(!e)throw new Error(`[elements-core] ${r.tag}: no client. A harness hands the core the client the host published.`);return e},after(e,t){if(g)return;const r=setTimeout((()=>{m.delete(r),g||t()}),e);m.add(r)}},k=r.actions(v);let E=null,C=[];const T=e=>{if(E!==e)return;E=null;const t=C;C=[];for(const e of t.reverse())e()};return{core:r,get props(){return a},get state(){return u},get view(){return b()},actions:k,setProps(e){g||(a={...a,...e},w())},setClient(e){c=s(e)},subscribe:e=>(p.add(e),()=>{p.delete(e)}),mount:()=>{if(g)return()=>{};E&&T(E);const e={};E=e;const t=()=>E===e&&!g,n=r.mount?.({...v,get props(){return a},get state(){return u},actions:k,active:t,onTeardown(e){t()?C.push(e):e()}});return"function"==typeof n&&(t()?C.push(n):n()),()=>T(e)},get mounted(){return null!==E},destroy(){E&&T(E),g=!0;for(const e of m)clearTimeout(e);m.clear(),p.clear()}}}function s(e){return"function"==typeof e?e:()=>e??null}const i="Booking fee";function d(e){return"number"==typeof e?Number.isInteger(e)?e:null:"string"==typeof e&&/^-?\d+$/.test(e)?Number(e):null}function l(e,t){return null===e?t:e>0||t}const c=e=>e.type||"ticket";function u(e,t="GBP"){if(null==e||""===e)return"";const r=new Intl.NumberFormat("en-GB",{style:"currency",currency:t});if("number"==typeof e)return r.format(e/100);const n=Number(e);return Number.isNaN(n)?String(e):r.format(n)}function g(e){return(e.items??[]).filter((e=>!e.type||"ticket"===e.type))}function m(e){return e.eventName||g(e)[0]?.name||e.items?.[0]?.name||null}function p(e){switch(e){case"confirmed":return"success";case"completed":case"fulfilled":return"info";case"pending":case"processing":return"warning";case"cancelled":case"expired":case"failed":return"error";default:return"muted"}}function y(e,t){return e instanceof Error&&e.message?e.message:t}const f={available:"state-available",soldOut:"state-sold-out",waitlist:"state-waitlist",comingSoon:"state-coming-soon"},h=["soldOut","comingSoon"],b=e=>!e.disabled&&!h.includes(e.state);function w(e,t){const r=e/100,n=r%1!=0;return new Intl.NumberFormat("en-GB",{style:"currency",currency:t,minimumFractionDigits:n?2:0,maximumFractionDigits:n?2:0}).format(r)}const v=o({tag:"tl-buy-tickets-button",docs:"A buy-tickets button in one of four sale states, which opens the purchase modal.",category:"purchase",runtimes:["web"],tokens:["error","error-foreground","font-family","info","info-foreground","primary","primary-foreground","radius-lg","radius-md","radius-sm","warning","warning-foreground"],sdkMethods:["event.openModal"],props:{eventId:{type:"string",attr:"event-id",required:!0,docs:"Event ID to purchase tickets for"},occurrenceId:{type:"string",tsType:"string | undefined",attr:"occurrence-id",docs:"Optional pre-selected occurrence ID"},state:{type:"string",tsType:'"available" | "comingSoon" | "soldOut" | "waitlist"',attr:"state",default:"available",docs:"Button state - determines colour, label, and icon"},label:{type:"string",tsType:"string | undefined",attr:"label",docs:"Button label override (default depends on state)"},variant:{type:"string",tsType:'"outline" | "primary" | "secondary"',attr:"variant",default:"primary",docs:"Button variant"},size:{type:"string",tsType:'"lg" | "md" | "sm"',attr:"size",default:"md",docs:"Button size"},fullWidth:{type:"boolean",attr:"full-width",default:!1,docs:"Full width button"},price:{type:"number",tsType:"number | undefined",attr:"price",docs:"Price to display (in minor units e.g. pence)"},currency:{type:"string",attr:"currency",default:"GBP",docs:"Currency code for price formatting"},pricePrefix:{type:"string",attr:"price-prefix",default:"From",docs:"Show price prefix text"},disabled:{type:"boolean",attr:"disabled",default:!1,docs:"Disabled state"}},events:{tlClick:{detail:"{ eventId: string; occurrenceId?: string | undefined; }",docs:"Emitted when button is clicked (before modal opens)"}},strings:{available:"Buy Tickets",soldOut:"Sold Out",waitlist:"Join Waitlist",comingSoon:"On Sale Soon"},statuses:["ready","disabled"],state:()=>({}),status:({props:e})=>b(e)?"ready":"disabled",derive:({props:e,strings:t})=>({interactive:b(e),buttonLabel:e.label||t[e.state],stateClass:f[e.state],priceLabel:void 0===e.price?null:w(e.price,e.currency)}),actions:e=>({activate(){if(!b(e.props))return;e.emit("tlClick",{eventId:e.props.eventId,occurrenceId:e.props.occurrenceId});const t=e.optionalClient();if(t&&t.event)try{t.event(e.props.eventId).openModal({occurrenceId:e.props.occurrenceId})}catch{}}})}),k=o({tag:"tl-buy-tickets-wrapper",docs:"Wrap any content and open the purchase modal when it is activated.",category:"purchase",runtimes:["web"],tokens:["radius-sm","ring"],sdkMethods:["event.openModal"],props:{eventId:{type:"string",attr:"event-id",required:!0,docs:"The event ID to purchase tickets for"},occurrenceId:{type:"string",tsType:"string | undefined",attr:"occurrence-id",docs:"Optional specific occurrence ID (skips occurrence selector)"},disabled:{type:"boolean",attr:"disabled",default:!1,docs:"Whether the wrapper is disabled"}},events:{tlComplete:{detail:"OrderResult",docs:"Emitted when purchase completes successfully"},tlError:{detail:"{ message: string; }",docs:"Emitted when an error occurs"},tlClose:{detail:"void",docs:"Emitted when the modal closes"}},strings:{noClient:"SDK not initialized",notAvailable:"Tickets are not available"},statuses:["ready","disabled"],state:()=>({}),status:({props:e})=>e.disabled?"disabled":"ready",derive:({props:e})=>({interactive:!e.disabled}),actions:e=>({activate(){if(e.props.disabled)return;const t=e.optionalClient();t?t.event?t.event(e.props.eventId).openModal({occurrenceId:e.props.occurrenceId,onComplete:t=>e.emit("tlComplete",t),onError:t=>e.emit("tlError",{message:t.message}),onClose:()=>e.emit("tlClose",void 0)}):e.emit("tlError",{message:e.strings.notAvailable}):e.emit("tlError",{message:e.strings.noClient})}})}),E=o({tag:"tl-cart",docs:"The buyer's cart: its lines, the money rows the surface reported and a checkout button.",category:"cart",runtimes:["web","native"],tokens:["background","border","error","error-bg","font-family","foreground","muted","muted-foreground","primary","primary-foreground","radius-md","radius-sm","spacing-1","spacing-2","spacing-3","spacing-4","spacing-8"],sdkMethods:["cart.get","cart.on","cart.removeItem"],props:{showCheckoutButton:{type:"boolean",attr:"show-checkout-button",default:!0,docs:"Show checkout button"},checkoutLabel:{type:"string",attr:"checkout-label",default:"Checkout",docs:"Checkout button label"},showRemoveButtons:{type:"boolean",attr:"show-remove-buttons",default:!0,docs:"Show remove item buttons"},compact:{type:"boolean",attr:"compact",default:!1,docs:"Compact mode - hides some details"}},events:{tlCheckout:{detail:"{ cart: TlCartData; }",docs:"Emitted when checkout is clicked"},tlItemRemoved:{detail:"{ itemId: string; }",docs:"Emitted when item is removed"},tlCartUpdated:{detail:"{ cart: TlCartData; }",docs:"Emitted when cart is updated"},tlError:{detail:"{ message: string; }",docs:"Emitted on error"}},strings:{emptyTitle:"Your cart is empty",emptyMessage:"Add tickets to get started",subtotalRow:"Subtotal",discountRow:"Discount",totalRow:"Total",removeItem:"Remove item",quantityPrefix:"Qty: ",loadFailed:"Failed to load cart",removeFailed:"Failed to remove item"},statuses:["loading","empty","ready"],state:()=>({cart:null,loading:!0,error:null,removingItemId:null}),mount:e=>{(async()=>{let t;try{t=await e.whenClient()}catch(t){if(!e.active())return;return void e.actions.connectFailed(t instanceof Error?t.message:e.strings.loadFailed)}if(!e.active())return;const r=t.getCartManager?.(),n=r?.on?.("cart:updated",(t=>{e.actions.cartUpdated(t)}));"function"==typeof n&&e.onTeardown(n),await e.actions.load()})()},status:({state:e})=>e.loading?"loading":e.cart&&0!==e.cart.items.length?"ready":"empty",derive:e=>{const{state:t,strings:r,props:n,formatMoney:o}=e,a=function(e){const t=e||{},r=Array.isArray(t.items)?t.items:[],n=r.filter((e=>"fee"===c(e))),o=r.filter((e=>"discount"===c(e))),a=d(t.itemsSubtotal)??d(t.subtotal)??r.filter((e=>!["fee","tax","discount"].includes(c(e)))).reduce(((e,t)=>e+(d(t.subtotal)??0)),0),s=n.length?n.reduce(((e,t)=>e+(d(t.subtotal)??0)),0):null,u=d(t.totalFees)??d(t.fees)??s,g=o.length?o.reduce(((e,t)=>e+Math.abs(d(t.subtotal)??0)),0):null,m=d(t.totalDiscounts)??d(t.discount)??g,p=d(t.totalTax)??0,y="string"==typeof t.feeLabel&&!!t.feeLabel||n.some((e=>"string"==typeof e.name&&!!e.name)),f="string"==typeof t.feeLabel&&t.feeLabel||n.map((e=>e.name)).find((e=>"string"==typeof e&&!!e))||i;return{currency:t.currency||"GBP",subtotal:a,fees:u??0,discount:m??0,total:d(t.total)??a+(u??0)+p-(m??0),showFee:"boolean"==typeof t.hasFees?t.hasFees:l(u,y),feeLabel:f}}(t.cart),s=a.currency,u=t.cart?.items??[];return{rows:u.map((e=>{return{id:e.id,name:e.ticketTypeName,eventName:e.eventName,dateLabel:e.occurrenceDate?(a=e.occurrenceDate,new Date(a).toLocaleDateString("en-GB",{weekday:"short",day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"})):null,quantityLabel:`${r.quantityPrefix}${e.quantity}`,priceLabel:o(e.totalPrice,e.currency),removing:t.removingItemId===e.id,showEvent:!n.compact,showDate:!n.compact&&!!e.occurrenceDate};var a})),totals:a,subtotalLabel:o(a.subtotal,s),feeAmountLabel:o(a.fees,s),discountLabel:o(a.discount,s),totalLabel:o(a.total,s),showSubtotalRow:!n.compact,showFeeRow:a.showFee&&!n.compact,showDiscountRow:a.discount>0&&!n.compact,checkoutDisabled:0===u.length}},actions:e=>({async load(){try{e.setState({loading:!0,error:null});const t=e.optionalClient()?.getCartManager?.();if(t){const r=t.get?.bind(t);if(!r)throw new TypeError("cartManager.get is not a function");e.setState({cart:await r()??null})}}catch(t){const r=t instanceof Error?t.message:e.strings.loadFailed;e.setState({error:r}),e.emit("tlError",{message:r})}finally{e.setState({loading:!1})}},cartUpdated(t){e.setState({cart:t}),e.emit("tlCartUpdated",{cart:t})},async removeItem(t){if(e.optionalClient()){e.setState({removingItemId:t});try{const r=e.client().getCartManager?.();if(r){const n=r.removeItem?.bind(r);if(!n)throw new TypeError("cartManager.removeItem is not a function");await n(t),e.emit("tlItemRemoved",{itemId:t})}}catch(t){const r=t instanceof Error?t.message:e.strings.removeFailed;e.setState({error:r}),e.emit("tlError",{message:r})}finally{e.setState({removingItemId:null})}}},checkout(){const t=e.state.cart;t&&t.items.length>0&&e.emit("tlCheckout",{cart:t})},connectFailed(t){const r=t||e.strings.loadFailed;e.setState({error:r,loading:!1}),e.emit("tlError",{message:r})}})}),C="tl_cart_count",T=e=>{const t=e;return"number"==typeof t?.itemCount?t.itemCount:0},I=o({tag:"tl-cart-badge",docs:"A cart icon carrying the number of items in the cart, kept current from the cart bus.",category:"cart",runtimes:["web"],tokens:["font-family","foreground","muted","primary","primary-foreground","radius-md","spacing-1","spacing-2","spacing-3"],sdkMethods:["cart.get","cart.on"],props:{showEmpty:{type:"boolean",attr:"show-empty",default:!1,docs:"Show the badge even when count is 0"},icon:{type:"string",tsType:"string | undefined",attr:"icon",docs:"Custom icon (emoji or text). If not provided, uses cart SVG"},size:{type:"string",tsType:'"lg" | "md" | "sm"',attr:"size",default:"md",docs:"Size variant"},badgeOnly:{type:"boolean",attr:"badge-only",default:!1,docs:"Badge only mode - only shows the count bubble, no icon or button"}},events:{tlClick:{detail:"{ itemCount: number; }",docs:"Emitted when the badge is clicked"}},strings:{ariaPrefix:"Cart with ",ariaSuffix:" items",overflow:"99+"},statuses:["ready"],state:()=>({itemCount:0}),mount:e=>{e.actions.hydrate(),(async()=>{let t;try{t=await e.whenClient()}catch{return}if(!e.active())return;const r=t.getCartManager?.();if(!r)return;const n=r.on?.("cart:updated",(t=>{e.actions.countChanged(T(t))}));"function"==typeof n&&e.onTeardown(n);try{const t=r.get?.bind(r);if(!t)return;const n=await t();if(!e.active())return;e.actions.countChanged(T(n))}catch{}})()},status:()=>"ready",derive:({state:e,props:t,strings:r})=>({displayCount:e.itemCount>99?r.overflow:e.itemCount.toString(),showBadge:e.itemCount>0,renderNothing:t.badgeOnly&&0===e.itemCount,ariaLabel:`${r.ariaPrefix}${e.itemCount}${r.ariaSuffix}`,sizeClass:`size-${t.size}`}),actions:e=>({countChanged(t){e.setState({itemCount:t}),e.storage.set(C,String(t))},hydrate(){const t=e.storage.get(C);e.setState({itemCount:(t?parseInt(t,10):0)||0})},click(){e.emit("tlClick",{itemCount:e.state.itemCount})}})}),S=o({tag:"tl-cart-drawer",docs:"A slide-in panel holding the cart, opened by the cart intent on the client bus.",category:"cart",runtimes:["web"],tokens:["background","border","font-family","foreground","muted","muted-foreground"],sdkMethods:["client.on"],props:{side:{type:"string",tsType:'"left" | "right"',attr:"side",default:"right",docs:"Edge the panel slides in from."},heading:{type:"string",attr:"heading",default:"Your cart",docs:"Heading shown at the top of the panel."},open:{type:"boolean",attr:"open",default:!1,docs:"Controlled open state (also driven by the `ui:cart-requested` intent)."}},events:{tlOpen:{detail:"void",docs:""},tlClose:{detail:"void",docs:""}},strings:{close:"Close cart",privacy:"Privacy Policy",privacyHref:"https://ticketlayer.com/privacy",reportAbuse:"Report Abuse",reportAbuseHref:"https://ticketlayer.com/report-abuse",poweredBy:"Powered by",brand:"ticketlayer",brandHref:"https://ticketlayer.com"},statuses:["open","closed"],state:e=>({visible:e.open}),mount:e=>{e.actions.openChanged(e.props.open),(async()=>{let t;try{t=await e.whenClient()}catch{return}if(!e.active())return;const r=t.on?.("ui:cart-requested",(()=>e.actions.setOpen(!0)));"function"==typeof r&&e.onTeardown(r);const n=t.on?.("ui:modal-close-requested",(()=>e.actions.setOpen(!1)));"function"==typeof n&&e.onTeardown(n)})()},status:({state:e})=>e.visible?"open":"closed",derive:({state:e,props:t})=>({visible:e.visible,sideClass:`panel--${t.side}`,ariaHidden:e.visible?"false":"true"}),actions:e=>({setOpen(t){e.state.visible!==t&&(e.setState({visible:t}),e.emit(t?"tlOpen":"tlClose",void 0))},openChanged(t){e.state.visible!==t&&e.setState({visible:t})}})}),D=o({tag:"tl-checkout-wrapper",docs:"Wrap any content and open the checkout modal when it is activated.",category:"checkout",runtimes:["web"],tokens:["radius-sm","ring"],sdkMethods:["checkout.openModal"],props:{disabled:{type:"boolean",attr:"disabled",default:!1,docs:"Whether the wrapper is disabled"}},events:{tlComplete:{detail:"OrderResult",docs:"Emitted when checkout completes successfully"},tlError:{detail:"{ message: string; }",docs:"Emitted when an error occurs"},tlClose:{detail:"void",docs:"Emitted when the modal closes"}},strings:{noClient:"SDK not initialized",notAvailable:"Checkout is not available"},statuses:["ready","disabled"],state:()=>({}),status:({props:e})=>e.disabled?"disabled":"ready",derive:({props:e})=>({interactive:!e.disabled}),actions:e=>({activate(){if(e.props.disabled)return;const t=e.optionalClient();t?t.checkout?t.checkout.openModal({onComplete:t=>e.emit("tlComplete",t),onError:t=>e.emit("tlError",{message:t.message}),onClose:()=>e.emit("tlClose",void 0)}):e.emit("tlError",{message:e.strings.notAvailable}):e.emit("tlError",{message:e.strings.noClient})}})});function L(e){const t=e.occurrences??[],r=t.map((e=>e.startsAt)).filter((e=>!!e)).sort(),n=Date.now(),o=r.find((e=>new Date(e).getTime()>=n))??r[0],a="sold_out"===e.status||t.length>0&&t.every((e=>"sold_out"===e.status));return{id:e.id,name:e.name,...e.shortDescription?{shortDescription:e.shortDescription}:{},...e.imageUrl?{imageUrl:e.imageUrl}:{},...e.venueName?{venue:{id:e.venueId??"",name:e.venueName,city:e.venueCity??""}}:{},...o?{nextOccurrence:{startsAt:o}}:{},availabilityStatus:a?"sold_out":"available"}}const O=o({tag:"tl-event-card",docs:"One event as a card: its image, name, next date, venue and how it is selling.",category:"discovery",runtimes:["web","native"],tokens:["error","error-foreground","font-family","foreground","muted","muted-foreground","primary","radius-lg","radius-sm","secondary","spacing-4","success","success-foreground","warning","warning-foreground"],sdkMethods:["events.get"],props:{event:{type:"object",tsType:"TlEventCardEvent | undefined",attr:null,docs:"Event data to display (tl-event-list passes this)"},eventId:{type:"string",tsType:"string | undefined",attr:"event-id",docs:"Load the event from the SDK by id when no `event` is given, so a single\ncard works standalone (e.g. on a Webflow page)."}},events:{tlClick:{detail:"{ eventId: string; }",docs:"Emitted when the card is clicked"},tlError:{detail:"{ message: string; }",docs:"Emitted when the event could not be loaded by id"}},strings:{available:"Available",limited:"Limited",soldOut:"Sold Out",notFound:"Event not found",loadFailed:"Failed to load event"},statuses:["loading","error","empty","ready"],state:()=>({loadedEvent:null,loading:!1,error:null}),mount:e=>{!e.props.event&&e.props.eventId&&(e.setState({loading:!0,error:null}),(async()=>{try{await e.whenClient()}catch(t){if(!e.active())return;return void e.actions.loadFailed(t instanceof Error&&t.message?t.message:e.strings.loadFailed)}e.active()&&await e.actions.load()})())},status:({state:e,props:t})=>e.loading?"loading":e.error?"error":t.event||e.loadedEvent?"ready":"empty",derive:({state:e,props:t,strings:r})=>{const n=t.event??e.loadedEvent,o=e=>`status-badge ${e}`,a=n?.availabilityStatus;return{event:n,image:n&&(n.thumbnailUrl||n.imageUrl)||null,statusBadgeClass:"available"===a?o("status-available"):"limited"===a?o("status-limited"):"sold_out"===a?o("status-sold-out"):"status-badge",statusLabel:"available"===a?r.available:"limited"===a?r.limited:"sold_out"===a?r.soldOut:"",dateLabel:n?.nextOccurrence?(s=n.nextOccurrence.startsAt,new Date(s).toLocaleDateString("en-GB",{weekday:"short",day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"})):null,venueLabel:n?.venue?`${n.venue.name}, ${n.venue.city}`:null};var s},actions:e=>({async load(){if(!e.props.event&&e.props.eventId)try{e.setState({loading:!0,error:null});const t=e.client().getEventsManager(),r=t.get?.bind(t);if(!r)throw new TypeError("eventsManager.get is not a function");const n=await r(e.props.eventId);if(!n)throw new Error(e.strings.notFound);e.setState({loadedEvent:L(n)})}catch(t){const r=t instanceof Error&&t.message?t.message:e.strings.loadFailed;e.setState({error:r}),e.emit("tlError",{message:r})}finally{e.setState({loading:!1})}},loadFailed(t){const r=t||e.strings.loadFailed;e.setState({error:r,loading:!1}),e.emit("tlError",{message:r})},click(){const t=e.props.event??e.state.loadedEvent;t&&e.emit("tlClick",{eventId:t.id})}})}),M=o({tag:"tl-event-list",docs:"What the channel is selling, as a grid of event cards, optionally narrowed to one category.",category:"discovery",runtimes:["web","native"],tokens:["error","font-family","foreground","muted","muted-foreground","radius-lg","radius-sm","secondary","spacing-4","spacing-6","spacing-8"],sdkMethods:["events.list"],props:{limit:{type:"number",attr:"limit",default:12,docs:"Maximum number of events to display"},category:{type:"string",tsType:"string | undefined",attr:"category",docs:"Category filter"},columns:{type:"number",attr:"columns",default:3,docs:"Columns for grid layout (1, 2, 3, or 4)"}},events:{tlEventClick:{detail:"{ eventId: string; }",docs:"Emitted when an event card is clicked"}},strings:{errorTitle:"Error loading events",emptyTitle:"No events available",emptyMessage:"Check back later for upcoming events.",loadFailed:"Failed to load events",noListing:"Events are not available"},statuses:["loading","error","empty","ready"],state:()=>({events:[],loading:!0,error:null}),mount:e=>{e.actions.load()},status:({state:e})=>e.loading?"loading":e.error?"error":0===e.events.length?"empty":"ready",derive:({state:e,props:t})=>({events:e.events,columns:Math.min(Math.max(t.columns,1),4)}),actions:e=>({async load(){try{e.setState({loading:!0,error:null});const t=(await e.whenClient()).getEventsManager();if(!t?.list)throw new TypeError(e.strings.noListing);const r=await t.list({limit:e.props.limit,category:e.props.category});e.setState({events:r?.items??[]})}catch(t){e.setState({error:t instanceof Error?t.message:e.strings.loadFailed})}finally{e.setState({loading:!1})}}})}),A=o({tag:"tl-login",docs:"Magic-link sign-in: an email in, a link or a six-digit code back, and a session. No password is ever handled.",category:"account",runtimes:["web","native"],tokens:["background","border","error","font-family","font-family-mono","foreground","muted-foreground","primary","primary-foreground","radius-lg","radius-md","secondary","spacing-3","spacing-4","spacing-6","success"],sdkMethods:["auth.requestMagicLink","auth.exchange","auth.logout","on"],props:{heading:{type:"string",attr:"heading",default:"Sign in",docs:"Heading for the email step."},allowCodeEntry:{type:"boolean",attr:"allow-code-entry",default:!0,docs:'Offer a "enter the code" path alongside the emailed link (default true).'}},events:{tlAuthChanged:{detail:"TlAuthChanged",docs:"signed in or out ({ customer, authenticated })"},tlMagicLinkSent:{detail:"{ email: string; }",docs:"a link was requested for an email"},tlError:{detail:"{ message: string; }",docs:"request or code exchange failed"}},strings:{signedInPrefix:"Signed in as ",fallbackAccount:"your account",signOut:"Sign out",verifyingTitle:"Signing you in…",verifyingLead:"Just a moment.",sentTitle:"Check your inbox",sentLeadBefore:"We've sent a sign-in link to ",sentLeadAfter:". Open it on this device to continue.",sentAgain:"Sent again. Check your inbox.",resendLink:"Resend link",resending:"Sending…",enterCodeInstead:"Enter the code instead",differentEmail:"Use a different email",codeTitle:"Enter your code",codeLeadBefore:"Type the 6-digit code from the email we sent to ",codeLeadAfter:".",codeLabel:"Code",codePlaceholder:"123456",codeSubmit:"Sign in",checking:"Checking…",back:"Back",emailLead:"Enter your email and we'll send you a secure sign-in link. No password needed.",emailLabel:"Email address",emailPlaceholder:"you@example.com",emailSubmit:"Email me a sign-in link",sendingLink:"Sending link…",enterEmail:"Enter your email address",enterCode:"Enter the code from your email",codeRejected:"That code did not work. Check it and try again, or request a new link.",requestFailed:"Could not send your sign-in link",unavailable:"Sign-in is not available right now",unsupported:"Sign-in is not available with this SDK"},statuses:["email","sent","code","verifying","signed-in"],state:()=>({phase:"email",email:"",code:"",busy:!1,error:null,notice:null,customer:null,authAvailable:!1,urlCodeUsed:!1}),mount:e=>{(async()=>{let t;try{t=await e.whenClient()}catch{if(!e.active())return;return void e.actions.connectFailed()}if(!e.active())return;const r=t.getAuthManager?.();if(!r)return void e.actions.unsupported();e.setState({authAvailable:!0}),e.actions.syncFromClient();for(const r of["auth:changed","session:changed"]){const n=t.on?.(r,(()=>e.actions.syncFromClient()));"function"==typeof n&&e.onTeardown(n)}const n=e.state.urlCodeUsed?null:e.query.get("code");n&&(e.setState({urlCodeUsed:!0}),r.authenticated||await e.actions.exchange(n))})()},status:({state:e})=>e.phase,derive:({state:e,strings:t,props:r})=>({signedInEmail:e.customer?.email??t.fallbackAccount,inputsDisabled:e.busy||!e.authAvailable,emailSubmitLabel:e.busy?t.sendingLink:t.emailSubmit,resendLabel:e.busy?t.resending:t.resendLink,codeSubmitLabel:e.busy?t.checking:t.codeSubmit,showCodeEntry:r.allowCodeEntry}),actions:e=>{const t=()=>e.optionalClient()?.getAuthManager?.()??null,r={setEmail(t){e.setState({email:t,error:null})},setCode(t){e.setState({code:t,error:null})},async requestLink(r=!1){const n=e.state.email.trim();if(!n)return void e.setState({error:e.strings.enterEmail});const o=t();if(o){e.setState({busy:!0,error:null,notice:null});try{await o.requestMagicLink({email:n}),e.setState({phase:"sent",notice:r?e.strings.sentAgain:null}),e.emit("tlMagicLinkSent",{email:n})}catch(t){const r=y(t,e.strings.requestFailed);e.setState({error:r}),e.emit("tlError",{message:r})}finally{e.setState({busy:!1})}}},async submitCode(){await r.exchange(e.state.code.trim())},async exchange(r){if(!r)return void e.setState({error:e.strings.enterCode});const n=t();if(!n)return;const o=e.state.phase;e.setState({busy:!0,error:null,phase:"verifying"});try{const t=await n.exchange(r),o=n.customer??t?.customer??null;e.setState({customer:o,phase:"signed-in",code:""}),e.emit("tlAuthChanged",{customer:o,authenticated:!0})}catch{e.setState({phase:"verifying"===o||"email"===o?"email":"code",error:e.strings.codeRejected}),e.emit("tlError",{message:e.strings.codeRejected})}finally{e.setState({busy:!1})}},async signOut(){const r=t();if(r){e.setState({busy:!0});try{await r.logout()}catch{}finally{e.setState({busy:!1,customer:null,phase:"email"}),e.emit("tlAuthChanged",{customer:null,authenticated:!1})}}},goTo(t){e.setState({phase:t})},syncFromClient(){const r=t();r&&(r.authenticated?e.setState({customer:r.customer??null,phase:"signed-in"}):"signed-in"===e.state.phase&&e.setState({customer:null,phase:"email"}))},connectFailed(){e.setState({error:e.strings.unavailable})},unsupported(){e.setState({error:e.strings.unsupported})}};return r}});function F(e){return!(!e||"object"!=typeof e||401!==e.status&&403!==e.status&&"NO_SESSION"!==e.code&&"NOT_AUTHENTICATED"!==e.code)}const x=o({tag:"tl-promo-code",docs:"Redeem a presale or promo code for the current cart.",category:"purchase",runtimes:["web"],tokens:["background","border","error","font-family","font-family-mono","foreground","muted","muted-foreground","primary","primary-foreground","radius-md","spacing-2","spacing-3","spacing-4","success"],sdkMethods:["cart.get","presale.redeem"],props:{placeholder:{type:"string",attr:"placeholder",default:"Promo or presale code",docs:"Input placeholder."},buttonLabel:{type:"string",attr:"button-label",default:"Apply",docs:"Apply button label."}},events:{tlPromoApplied:{detail:"TlPromoApplied",docs:""},tlError:{detail:"{ message: string; }",docs:""}},strings:{applying:"Applying…",codePrefix:"Code ",appliedSuffix:" applied",alreadyHeldSuffix:" was already applied",useDifferent:"Use a different code",enterCode:"Enter a code",notAvailable:"Promo codes are not available",signIn:"Sign in to use this code",rejected:"That code could not be applied"},statuses:["idle","applied"],state:()=>({code:"",applying:!1,applied:null,error:null}),status:({state:e})=>e.applied?"applied":"idle",derive:({state:e,props:t,strings:r})=>({actionLabel:e.applying?r.applying:t.buttonLabel,disabled:e.applying,appliedCode:e.applied?.code??null,appliedSuffix:e.applied?.alreadyHeld?r.alreadyHeldSuffix:r.appliedSuffix}),actions:e=>({setCode(t){e.setState({code:t,error:null})},async apply(){const t=e.state.code.trim();if(t){e.setState({applying:!0,error:null});try{const r=await e.whenClient(),n=r.getPresaleManager?.();if(!n)throw new Error(e.strings.notAvailable);const o=await n.redeem(t),a=await(r.getCartManager?.()?.get?.().catch((()=>null)))??null,s={code:t.toUpperCase(),...o,cart:a};e.setState({applied:s,code:""}),e.emit("tlPromoApplied",s)}catch(t){const r=F(t)?e.strings.signIn:t instanceof Error&&t.message?t.message:e.strings.rejected;e.setState({error:r}),e.emit("tlError",{message:r})}finally{e.setState({applying:!1})}}else e.setState({error:e.strings.enterCode})},reset(){e.setState({applied:null,error:null})}})}),$=o({tag:"tl-my-orders",docs:"The signed-in customer's orders: event, date, ticket count, total and status, each row expanding to its tickets.",category:"account",runtimes:["web","native"],tokens:["background","border","error","error-foreground","font-family","foreground","muted-foreground","primary","primary-foreground","radius-lg","secondary","secondary-foreground","spacing-1","spacing-3","spacing-4","spacing-8","success","success-foreground","warning","warning-foreground"],sdkMethods:["orders.mine","auth.authenticated","on"],props:{emptyMessage:{type:"string",attr:"empty-message",default:"When you buy tickets they'll show up here, ready to view and download.",docs:"Copy for the empty state."},columns:{type:"number",attr:"columns",default:2,docs:"Columns for the expanded ticket grid."}},events:{tlOrderSelect:{detail:"{ orderId: string; }",docs:"a row was expanded ({ orderId })"},tlError:{detail:"{ message: string; }",docs:"the orders could not be loaded"}},strings:{signInTitle:"Sign in to see your orders",signInText:"Your tickets and order history live in your account.",errorTitle:"Could not load your orders",emptyTitle:"No orders yet",orderPrefix:"Order ",unnamedEvent:"Order",ticketSingular:"ticket",ticketPlural:"tickets",unavailable:"Orders are not available right now",noOrdersManager:"Orders are not available",loadFailed:"Failed to load your orders"},statuses:["loading","signed-out","error","empty","ready"],state:()=>({orders:[],authenticated:!1,loading:!0,error:null,expandedId:null}),mount:e=>{(async()=>{let t;try{t=await e.whenClient()}catch{if(!e.active())return;return void e.actions.connectFailed()}if(!e.active())return;const r=t.getAuthManager?.();e.setState({authenticated:!r||r.authenticated});for(const r of["auth:changed","session:changed"]){const n=t.on?.(r,(()=>e.actions.syncAuth()));"function"==typeof n&&e.onTeardown(n)}e.state.authenticated?await e.actions.load():e.setState({loading:!1})})()},status:({state:e})=>e.loading?"loading":e.authenticated?e.error?"error":0===e.orders.length?"empty":"ready":"signed-out",derive:({state:e,strings:t})=>({rows:e.orders.map((r=>{const n=function(e){return g(e).reduce(((e,t)=>e+(Number(t.quantity)||0)),0)||e.tickets?.length||0}(r);return{id:r.id,numberLabel:`${t.orderPrefix}${r.orderNumber}`,eventName:m(r)??t.unnamedEvent,dateLabel:r.createdAt?(a=r.createdAt,new Date(a).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"})):null,countLabel:`${n} ${1===n?t.ticketSingular:t.ticketPlural}`,totalLabel:u(r.total,r.currency),statusLabel:(o=r.status,o?o.replace(/_/g," ").replace(/^\w/,(e=>e.toUpperCase())):""),statusTone:p(r.status),expanded:e.expandedId===r.id};var o,a}))}),actions:e=>{const t={async load(){const t=e.optionalClient();if(t)try{e.setState({loading:!0,error:null});const r=t.getOrdersManager?.();if(!r)throw new Error(e.strings.noOrdersManager);const n=await r.mine();e.setState({orders:n??[],authenticated:!0})}catch(t){if(F(t))e.setState({authenticated:!1,orders:[]});else{const r=y(t,e.strings.loadFailed);e.setState({error:r}),e.emit("tlError",{message:r})}}finally{e.setState({loading:!1})}},syncAuth(){const r=e.optionalClient()?.getAuthManager?.();if(!r)return;const n=e.state.authenticated;e.setState({authenticated:r.authenticated}),r.authenticated&&!n?t.load():!r.authenticated&&n&&e.setState({orders:[],expandedId:null})},toggle(t){const r=e.state.expandedId!==t;e.setState({expandedId:r?t:null}),r&&e.emit("tlOrderSelect",{orderId:t})},connectFailed(){e.setState({loading:!1,error:e.strings.unavailable})}};return t}});function B(e){const t=new Date(e);return t.setHours(0,0,0,0),t}function P(e){return e.toDateString()}function q(e){const t=new Date(e),r=t.getDay();return t.setDate(t.getDate()-(0===r?6:r-1)),t.setHours(0,0,0,0),t}function R(e){return new Date(e.getFullYear(),e.getMonth(),1)}const N=e=>new Date(e.startsAt).getTime(),z=(e,t)=>N(e)-N(t),G=e=>!!e.soldOut||0===e.availableCapacity;function W(e){const t=new Map;for(const r of e){const e=P(B(new Date(r.startsAt))),n=t.get(e);n?n.push(r):t.set(e,[r])}return t}function j(e){if(!e.length)return null;let t=new Date(e[0].startsAt),r=new Date(e[0].startsAt);for(const n of e){const e=new Date(n.startsAt);e<t&&(t=e),e>r&&(r=e)}return{first:t,last:r}}function _(e){const t=j(e);return!!t&&t.first.getMonth()===t.last.getMonth()&&t.first.getFullYear()===t.last.getFullYear()}function U(e){if(!e.length)return null;const t=B(new Date),r=Array.from(W(e).keys()).sort();let n=null;for(const e of r){const r=new Date(e);if(r>=t){n=r;break}}return!n&&r.length&&(n=new Date(r[r.length-1])),n?{selectedDate:n,currentMonth:R(n)}:null}function Y(e){return e.toLocaleDateString("en-GB",{weekday:"long",day:"numeric",month:"long",year:"numeric"})}function H(e){return new Date(e).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"})}function Q(e){return{id:e.id,startsAt:e.startsAt,endsAt:e.endsAt,status:e.availabilityStatus,availableCapacity:e.availableCapacity,soldOut:"sold_out"===e.availabilityStatus}}const K=o({tag:"tl-occurrence-selector",docs:"A smart occurrence selector component that fetches and displays event occurrences from the Ticketlayer API.",category:"discovery",runtimes:["web"],tokens:["background","border","font-family","foreground","muted","muted-foreground","primary","primary-foreground","radius-md"],sdkMethods:["events.get"],props:{eventId:{type:"string",attr:"event-id",required:!0,docs:"Event ID to fetch occurrences for"},displayMode:{type:"string",tsType:'"calendar" | "list" | "slots" | undefined',attr:"display-mode",docs:"Force a specific display mode (auto-detected if not set)"},orientation:{type:"string",tsType:'"auto" | "horizontal" | "vertical"',attr:"orientation",default:"auto",docs:"Layout orientation (auto = horizontal on desktop, vertical on mobile)"},theme:{type:"object",tsType:"TlOccurrenceSelectorTheme | undefined",attr:null,docs:"Theme configuration"}},events:{tlSelect:{detail:"{ occurrence: TlOccurrence; }",docs:"Emitted when an occurrence is selected"}},strings:{noEventId:"Event ID is required",noClient:"SDK not initialized.",notFound:"Event not found",loadFailed:"Failed to load occurrences",empty:"No dates available for this event.",retry:"Retry",soldOut:"Sold Out",available:"available",selectADate:"Select a date to see available times",previousMonth:"Previous month",nextMonth:"Next month",weekdayMon:"Mon",weekdayTue:"Tue",weekdayWed:"Wed",weekdayThu:"Thu",weekdayFri:"Fri",weekdaySat:"Sat",weekdaySun:"Sun"},statuses:["loading","error","empty","ready"],state:()=>({loading:!0,error:null,occurrences:[],currentMonth:new Date,selectedDate:null,containerWidth:0}),mount:e=>{e.props.eventId?(async()=>{try{await e.whenClient()}catch(t){if(!e.active())return;return void e.actions.loadFailed(t instanceof Error?t.message:e.strings.noClient)}e.active()&&await e.actions.load()})():e.actions.loadFailed(e.strings.noEventId)},status:({state:e})=>e.loading?"loading":e.error?"error":0===e.occurrences.length?"empty":"ready",derive:({state:e,props:t,strings:r})=>{const{occurrences:n,selectedDate:o}=e,a=W(n),s=j(n),i=t.displayMode?t.displayMode:n.length<=5?"list":1===a.size?"slots":"calendar",d="horizontal"===t.orientation||"vertical"!==t.orientation&&e.containerWidth>=768,l=e=>{const t=G(e),n=H(e.startsAt);return{id:e.id,dateLabel:Y(new Date(e.startsAt)),timeLabel:e.endsAt?`${n} - ${H(e.endsAt)}`:n,startLabel:n,soldOut:t,capacityLabel:e.availableCapacity?`${e.availableCapacity} ${r.available}`:null,statusKind:t?"soldOut":e.availableCapacity?"available":"arrow"}},c=[...n].sort(z),u=o?P(o):null,g=u?[...a.get(u)??[]].sort(z):[],m=B(new Date),p=s?R(s.first):null,y=s?R(s.last):null,f=function(e,t){const r=[];if(function(e){const t=j(e);if(!t)return!1;const r=new Date(q(t.first));return r.setDate(r.getDate()+6),r.setHours(23,59,59,999),t.last<=r}(e)){const t=j(e);if(!t)return r;const n=q(t.first);for(let e=0;e<7;e+=1)r.push(new Date(n)),n.setDate(n.getDate()+1);return r}const n=t.getFullYear(),o=t.getMonth(),a=new Date(n,o,1),s=new Date(n,o+1,0),i=a.getDay(),d=new Date(a);d.setDate(d.getDate()-(0===i?6:i-1));const l=s.getDay(),c=new Date(s);c.setDate(c.getDate()+(0===l?0:7-l));const u=new Date(d);for(;u<=c;)r.push(new Date(u)),u.setDate(u.getDate()+1);return r}(n,e.currentMonth).map((t=>{const r=P(t),n=a.get(r),o=!!n,s=o&&n.every(G),i=t.getMonth()!==e.currentMonth.getMonth(),d=u===r,l=r===P(m),c=t<m;return{key:r,dayNumber:String(t.getDate()),otherMonth:i,hasOccurrences:o,soldOut:s,selected:d,today:l,past:c,selectable:o,className:["calendar-day",i?"other-month":"",o?"has-occurrences":"",s?"sold-out":"",d?"selected":"",l?"today":"",c?"past":""].filter(Boolean).join(" ")}}));return{mode:i,horizontal:d,viewClass:"calendar-view "+(d?"horizontal":"vertical"),rows:n.map(l),slots:c.map(l),slotsDateLabel:c.length?Y(new Date(c[0].startsAt)):null,monthLabel:(h=e.currentMonth,h.toLocaleDateString("en-GB",{month:"long",year:"numeric"})),showMonthNav:!_(n),canGoBack:!!p&&e.currentMonth>p,canGoForward:!!y&&e.currentMonth<y,weekdayLabels:[r.weekdayMon,r.weekdayTue,r.weekdayWed,r.weekdayThu,r.weekdayFri,r.weekdaySat,r.weekdaySun],days:f,selectedDateLabel:o&&g.length?Y(o):null,selectedSlots:g.map(l)};var h},actions:e=>({async load(){e.setState({loading:!0,error:null});try{const t=e.client().getEventsManager(),r=t.get?.bind(t);if(!r)throw new TypeError("eventsManager.get is not a function");const n=await r(e.props.eventId);if(!n)throw new Error(e.strings.notFound);const o=(n.occurrences??[]).map(Q);e.setState({occurrences:o,...U(o)??{}})}catch(t){e.setState({error:t instanceof Error?t.message:e.strings.loadFailed,occurrences:[]})}finally{e.setState({loading:!1})}},loadFailed(t){e.setState({error:t,loading:!1})},select(t){const r=e.state.occurrences.find((e=>e.id===t));r&&!G(r)&&e.emit("tlSelect",{occurrence:r})},selectDate(t){if(!W(e.state.occurrences).has(t))return;const r=new Date(t);if(Number.isNaN(r.getTime()))return;const{currentMonth:n}=e.state,o=r.getMonth()!==n.getMonth()||r.getFullYear()!==n.getFullYear();e.setState({selectedDate:r,...o?{currentMonth:R(r)}:{}})},previousMonth(){const t=j(e.state.occurrences);if(!t)return;const r=new Date(e.state.currentMonth);r.setMonth(r.getMonth()-1),r>=R(t.first)&&e.setState({currentMonth:r})},nextMonth(){const t=j(e.state.occurrences);if(!t)return;const r=new Date(e.state.currentMonth);r.setMonth(r.getMonth()+1),r<=R(t.last)&&e.setState({currentMonth:r})},resized(t){t!==e.state.containerWidth&&e.setState({containerWidth:t})}})}),J=o({tag:"tl-order-confirmation",docs:"The thank-you block: order reference, email, event and date, the ticket lines, the money rows and the tickets.",category:"checkout",runtimes:["web","native"],tokens:["border","error","font-family","font-family-mono","foreground","muted","muted-foreground","radius-lg","radius-md","secondary","spacing-1","spacing-2","spacing-3","spacing-4","spacing-6","success","success-foreground"],sdkMethods:["orders.get","events.list","events.get","auth.customer","on"],props:{orderId:{type:"string",tsType:"string | undefined",attr:"order-id",docs:"The order to show. Falls back to `?orderId=` in the page URL."},customerEmail:{type:"string",tsType:"string | undefined",attr:"customer-email",docs:"Email to show when the order view carries none (a host that collected it at checkout)."},showTickets:{type:"boolean",attr:"show-tickets",default:!0,docs:"Mount tl-order-tickets under the summary (default true)."},columns:{type:"number",attr:"columns",default:2,docs:"Columns for the ticket grid."}},events:{tlOrderLoaded:{detail:"{ order: TlOrderData; }",docs:"the order was loaded"},tlError:{detail:"{ message: string; }",docs:"the order could not be loaded"}},strings:{paymentFailedTitle:"Payment not completed",paymentFailedLead:"Your payment wasn't completed. Your cart is still saved, so you can try again.",title:"You're going!",leadPrefix:"Order ",leadSuffix:" is confirmed. Your tickets are on their way to your email.",leadGeneric:"Your order is confirmed. Your tickets are on their way to your email.",errorPrefix:"We couldn't load your order details yet. ",rowReference:"Order reference",rowEmail:"Email",rowEvent:"Event",rowDate:"Date",subtotalRow:"Subtotal",taxRow:"Tax",discountRow:"Discount",totalRow:"Total",ticketsTitle:"Your tickets",ticketsHint:"Show these QR codes at the door for entry. Use Download PDF on a ticket to save it.",noOrdersManager:"Orders are not available",notFound:"Order not found",loadFailed:"Failed to load your order"},statuses:["payment-failed","idle","loading","ready"],state:()=>({order:null,resolvedOrderId:null,loading:!1,error:null,paymentFailed:!1,occurrence:null,signedInCustomer:null}),mount:e=>{(async()=>{const t=e.query.get("redirect_status");e.setState({paymentFailed:!!t&&"succeeded"!==t,resolvedOrderId:e.props.orderId||e.query.get("orderId")||null});const r=e.state.resolvedOrderId&&!e.state.paymentFailed?e.actions.load():Promise.resolve();let n=null;try{n=await e.whenClient()}catch{n=null}if(n&&e.active()){const t=n.on?.("checkout:completed",(t=>{e.actions.checkoutCompleted(t)}));"function"==typeof t&&e.onTeardown(t)}await r})()},status:({state:e})=>e.paymentFailed?"payment-failed":e.resolvedOrderId||e.order?e.loading?"loading":"ready":"idle",derive:({state:e,props:t,strings:r})=>{const n=e.order,o=function(e){const t=e||{},r=Array.isArray(t.items)?t.items:[],n=r.filter((e=>"fee"===e.type)),o=r.filter((e=>"discount"===e.type)),a=g(t),s=n.length?n.reduce(((e,t)=>e+(d(t.subtotal)??0)),0):null,c=s??d(t.totalFees)??0,u=d(t.subtotal),m=a.length?a.reduce(((e,t)=>e+(d(t.subtotal)??0)),0):(u??0)-c,p=o.length?o.reduce(((e,t)=>e+Math.abs(d(t.subtotal)??0)),0):null,y=d(t.totalDiscounts)??p??0,f=d(t.totalTax)??0,h=n.some((e=>"string"==typeof e.name&&!!e.name));return{currency:t.currency||"GBP",subtotal:m,fees:c,feeLabel:n.map((e=>e.name)).find((e=>!!e))||i,showFee:l(s??d(t.totalFees),h),tax:f,discount:y,total:d(t.total)??m+c+f-y}}(n),a=o.currency,s=t.customerEmail||function(e,t){const r=e?.customerEmail||e?.customer?.email;if(r)return r;const n=t;return n?.email||null}(n,e.signedInCustomer),c=e.occurrence?.eventName||(n?m(n):null),p=e.occurrence?.startsAt,y=[];var f;return n&&y.push({label:r.rowReference,value:n.orderNumber,reference:!0}),s&&y.push({label:r.rowEmail,value:s,reference:!1}),c&&y.push({label:r.rowEvent,value:c,reference:!1}),p&&y.push({label:r.rowDate,value:(f=p,new Date(f).toLocaleDateString("en-GB",{weekday:"short",day:"numeric",month:"short",year:"numeric",hour:"2-digit",minute:"2-digit"})),reference:!1}),{leadText:n?.orderNumber?`${r.leadPrefix}${n.orderNumber}${r.leadSuffix}`:r.leadGeneric,rows:y,lines:n?g(n).map((e=>({label:`${e.quantity} x ${e.name}`,priceLabel:u(e.subtotal,n.currency)}))):[],totals:o,subtotalLabel:u(o.subtotal,a),feeAmountLabel:u(o.fees,a),taxLabel:u(o.tax,a),discountLabel:u(o.discount,a),totalLabel:u(o.total,a),showTaxRow:o.tax>0,showDiscountRow:o.discount>0,showSummary:!!n&&Array.isArray(n.items),showError:!!e.error&&!n,showTickets:t.showTickets&&!!n,ticketsOrderId:n?.id||e.resolvedOrderId||""}},actions:e=>{const t={async load(){const t=e.state.resolvedOrderId;if(t)try{e.setState({loading:!e.state.order,error:null});const r=await e.whenClient(),n=r.getOrdersManager?.();if(!n)throw new Error(e.strings.noOrdersManager);const o=await n.get(t);if(!o)throw new Error(e.strings.notFound);e.setState({order:o,signedInCustomer:r.getAuthManager?.()?.customer??null}),e.emit("tlOrderLoaded",{order:o}),(async(t,r)=>{const n=r.tickets?.find((e=>e.eventOccurrenceId))?.eventOccurrenceId;if(n)try{const o=await async function(e,t,r=12){const n=e.getEventsManager();if(!n?.list||!n.get)return null;const o=await n.list({limit:r}),a=(o?.items??[]).slice(0,r);for(const e of a){const r=await n.get(e.id).catch((()=>null)),o=r?.occurrences?.find((e=>e.id===t));if(o)return{eventId:r?.id??e.id,eventName:r?.name??e.name??"",startsAt:o.startsAt??null}}return null}(t,n);o&&e.state.order?.id===r.id&&e.setState({occurrence:o})}catch{}})(r,o)}catch(t){const r=y(t,e.strings.loadFailed);e.setState({error:r}),e.emit("tlError",{message:r})}finally{e.setState({loading:!1})}},orderIdChanged(){e.setState({resolvedOrderId:e.props.orderId||e.query.get("orderId")||null}),t.load()},checkoutCompleted(r){r?.id&&(e.setState({paymentFailed:!1,order:r,resolvedOrderId:r.id}),e.emit("tlOrderLoaded",{order:r}),t.load())}};return t}}),V=[1e3,1500,2e3,3e3,4e3,5e3,6e3,8e3,1e4,12e3],Z=o({tag:"tl-order-tickets",docs:"Every ticket in an order as a scannable card, waiting out issuance rather than reporting an empty order as empty.",category:"tickets",runtimes:["web","native"],tokens:["border","error","font-family","muted-foreground","primary","spacing-2","spacing-4","spacing-6"],sdkMethods:["orders.get"],props:{orderId:{type:"string",attr:"order-id",required:!0,docs:"The order whose tickets to show."},columns:{type:"number",attr:"columns",default:2,docs:"Columns in the grid (default 2)."}},events:{},strings:{loading:"Loading tickets…",preparing:"Preparing your tickets…",delayed:"Your tickets are taking longer than usual. They will be emailed to you as soon as they are ready.",notAvailable:"Tickets are not available",loadFailed:"Failed to load tickets"},statuses:["loading","error","issuing","delayed","ready"],state:()=>({tickets:[],loading:!0,error:null,issuing:!1}),mount:e=>{e.onTeardown((()=>e.actions.stopPolling())),e.actions.load()},status:({state:e})=>e.loading?"loading":e.error?"error":e.tickets.length>0?"ready":e.issuing?"issuing":"delayed",derive:({state:e,props:t})=>({tickets:e.tickets,columns:t.columns,orderId:t.orderId}),actions:e=>{let t=0,r=0;const n={async load(){try{e.setState({error:null});const o=await e.whenClient(),a=o.getOrdersManager?.();if(!a)throw new Error(e.strings.notAvailable);const s=await a.get(e.props.orderId),i=s?.tickets??[];if(e.setState({tickets:i}),i.length>0)e.setState({issuing:!1}),n.stopPolling();else{const o=V[r];if(e.setState({issuing:void 0!==o}),void 0!==o){r+=1,n.stopPolling();const a=t;e.after(o,(()=>{a===t&&n.load()}))}}}catch(t){n.stopPolling(),e.setState({issuing:!1,error:t instanceof Error?t.message:e.strings.loadFailed})}finally{e.setState({loading:!1})}},orderIdChanged(){n.stopPolling(),r=0,e.setState({tickets:[],issuing:!1}),n.load()},stopPolling(){t+=1}};return n}}),X=e=>function(e,t=null){const r=(e||[]).reduce(((e,t)=>e+(d(t.price)??0)*(Math.max(0,Math.trunc(t.quantity||0))||0)),0),n=t?d(t.amount):null;return{subtotal:r,fees:n??0,total:r+(n??0),showFee:!!t&&l(n,!!t?.label),feeLabel:t?.label||i}}(e.state.ticketTypes.map((t=>({price:t.price,quantity:e.state.quantities[t.id]||0}))),e.state.feeQuote),ee=o({tag:"tl-ticket-selector",docs:"Pick quantities of the ticket types on sale for one occurrence, and add them to the cart.",category:"purchase",runtimes:["web","native"],tokens:["background","border","border-hover","error","error-bg","font-family","foreground","muted","muted-foreground","primary","primary-foreground","radius-md","radius-sm","spacing-1","spacing-2","spacing-3","spacing-4","success","warning","warning-bg"],sdkMethods:["cart.addItem","events.getTicketTypes"],props:{eventId:{type:"string",attr:"event-id",required:!0,docs:"Event ID"},occurrenceId:{type:"string",attr:"occurrence-id",required:!0,docs:"Occurrence ID"},showButton:{type:"boolean",attr:"show-button",default:!0,docs:"Show add to cart button"},buttonLabel:{type:"string",attr:"button-label",default:"Add to Cart",docs:"Button label"}},events:{tlAddToCart:{detail:"{ items: AddToCartItem[]; }",docs:"Emitted when items are added to cart"},tlQuantityChange:{detail:"{ ticketTypeId: string; quantity: number; total: number; }",docs:"Emitted when quantity changes"},tlError:{detail:"{ message: string; }",docs:"Emitted on error"}},strings:{selectTickets:"Select Tickets",adding:"Adding...",added:"Added to cart!",limited:"Limited",soldOut:"Sold Out",ticketsRow:"Tickets",totalRow:"Total",decrease:"Decrease quantity",increase:"Increase quantity",loadFailed:"Failed to load tickets",addFailed:"Failed to add to cart",noClient:"SDK not initialized."},statuses:["loading","error","ready"],state:()=>({ticketTypes:[],quantities:{},loading:!0,error:null,adding:!1,addSuccess:!1,feeQuote:null}),mount:e=>{e.props.eventId&&e.props.occurrenceId&&(async()=>{try{if(await e.whenClient(),!e.active())return;await e.actions.load()}catch(t){if(!e.active())return;e.actions.connectFailed(t instanceof Error?t.message:e.strings.noClient)}})()},status:({state:e})=>e.loading?"loading":e.error?"error":"ready",derive:e=>{const{state:t,strings:r,props:n,formatMoney:o}=e,a=X(e),s=(e=>Object.values(e.quantities).reduce(((e,t)=>e+t),0))(t),i=t.ticketTypes[0]?.currency;return{rows:t.ticketTypes.map((e=>{const r=t.quantities[e.id]||0,n="sold_out"===e.availabilityStatus;return{id:e.id,name:e.name,description:e.description??null,priceLabel:o(e.price,e.currency),quantity:r,soldOut:n,limited:"limited"===e.availabilityStatus,canDecrease:!n&&r>0,canIncrease:!n&&r<e.maxPerOrder}})),totals:a,totalItems:s,currency:i,subtotalLabel:o(a.subtotal,i),feeLabel:o(a.fees,i),totalLabel:o(a.total,i),showTotals:a.showFee&&s>0,actionLabel:t.adding?r.adding:0===s?r.selectTickets:`${n.buttonLabel} - ${o(a.total)}`,actionDisabled:0===s||t.adding}},actions:e=>({async load(){try{e.setState({loading:!0,error:null});const t=await e.client().getEventsManager().getTicketTypes(e.props.eventId,e.props.occurrenceId),r={};for(const e of t)r[e.id]=0;e.setState({ticketTypes:t,quantities:r})}catch(t){const r=t instanceof Error?t.message:e.strings.loadFailed;e.setState({error:r}),e.emit("tlError",{message:r})}finally{e.setState({loading:!1})}},changeQuantity(t,r){const n=e.state.ticketTypes.find((e=>e.id===t));if(!n)return;const o=Math.max(0,Math.min(n.maxPerOrder,(e.state.quantities[t]||0)+r));e.setState((e=>({quantities:{...e.quantities,[t]:o}}))),e.emit("tlQuantityChange",{ticketTypeId:t,quantity:o,total:X(e).total})},async addToCart(){const t=Object.entries(e.state.quantities).filter((([,e])=>e>0)).map((([e,t])=>({ticketTypeId:e,quantity:t})));if(0!==t.length){e.setState({adding:!0,addSuccess:!1});try{const r=e.optionalClient()?.getCartManager?.();if(r)for(const n of t)await r.addItem(n.ticketTypeId,n.quantity,e.props.occurrenceId);const n={};for(const t of e.state.ticketTypes)n[t.id]=0;e.setState({quantities:n,addSuccess:!0}),e.after(3e3,(()=>e.setState({addSuccess:!1}))),e.emit("tlAddToCart",{items:t})}catch(t){const r=t instanceof Error?t.message:e.strings.addFailed;e.setState({error:r}),e.emit("tlError",{message:r})}finally{e.setState({adding:!1})}}},setFeeQuote(t){e.setState({feeQuote:t})},connectFailed(t){e.setState({error:t||e.strings.noClient,loading:!1})}})});export{E as a,k as b,a as c,D as d,O as e,Z as f,v as g,S as h,M as i,J as j,I as k,A as l,$ as m,K as o,x as p,ee as t}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxyCustomElement as e,HTMLElement as t,createEvent as r,h as a,Host as i,transformTag as o}from"@stencil/core/internal/client";import{w as s,g as c}from"./sdk-connector.js";import{d}from"./tl-occurrence-selector2.js";import{d as n}from"./tl-ticket-selector2.js";const l=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.tlClose=r(this,"tlClose",7),this.tlCheckout=r(this,"tlCheckout",7),this.tlError=r(this,"tlError",7),this.step="loading",this.eventName="",this.imageUrl="",this.venueLabel="",this.dateSummary="",this.selectedOccurrenceId=null,this.occurrenceCount=0,this.occurrenceLabel="",this.error=null,this.handleOccurrenceSelect=e=>{const t=e.detail.occurrence;this.selectedOccurrenceId=t.id,this.occurrenceLabel=this.labelFor(t),this.step="tickets"},this.handleAdded=()=>{this.step="done"},this.backToDates=()=>{this.selectedOccurrenceId=null,this.step="occurrence"},this.close=()=>this.tlClose.emit(),this.goCheckout=()=>this.tlCheckout.emit()}async componentWillLoad(){if(this.eventId)try{await s();const e=await c().getEventsManager().get(this.eventId);this.eventName=e?.name??"Tickets",this.imageUrl=e?.imageUrl||e?.heroImageUrl||"",this.venueLabel=[e?.venueName,e?.venueCity].filter(Boolean).join(", ");const t=e?.occurrences??[];this.occurrenceCount=t.length,this.dateSummary=this.summariseDates(t);const r=this.occurrenceId??(1===t.length?t[0]?.id:null);r?(this.selectedOccurrenceId=r,this.occurrenceLabel=this.labelFor(t.find((e=>e.id===r))),this.step="tickets"):this.step="occurrence"}catch(e){this.fail(e instanceof Error?e.message:"Could not load this event")}else this.fail("No event specified")}fail(e){this.error=e,this.step="error",this.tlError.emit({message:e})}summariseDates(e){const t=e.map((e=>e.startsAt)).filter((e=>!!e)).sort();if(0===t.length)return"";const r=e=>new Date(e).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"});if(1===t.length)return new Date(t[0]).toLocaleDateString("en-GB",{weekday:"short",day:"numeric",month:"short",year:"numeric"});const a=r(t[0]),i=r(t[t.length-1]);return`${a===i?a:`${a} - ${i}`} · ${t.length} dates`}labelFor(e){return e?.startsAt?new Date(e.startsAt).toLocaleString("en-GB",{weekday:"short",day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"}):""}stepKicker(){switch(this.step){case"occurrence":return"Choose a date";case"tickets":return"Select tickets";case"done":return"Nice one";default:return"Tickets"}}render(){return a(i,{key:"1245e518c2b5232f4d9dba091cf808cd3867fbef"},a("div",{key:"4e770fccdd785444f1cc87df4adab5a5dc1bf58a",class:"overlay",onClick:e=>{e.target===e.currentTarget&&this.close()}},a("div",{key:"57b13dac690028aeebd6a601acfba07f00854c40",class:{panel:!0,"panel--wide":"occurrence"===this.step},role:"dialog","aria-modal":"true","aria-label":this.eventName},a("header",{key:"881e9cc70a0ca25947f272b9ebcb2e6d4b4268f2",class:"panel-header"},this.imageUrl&&a("div",{key:"753f7df1b5118dfacbbc6b89b4e5d7ba114f6cdf",class:"event-thumb",style:{backgroundImage:`url(${this.imageUrl})`}}),a("div",{key:"9aaa32d1add90fabd1b0ea0c100f198962f4e6a5",class:"titles"},a("span",{key:"538032bdf2338206ad763417386852ff97cc472f",class:"kicker"},this.stepKicker()),a("h2",{key:"71429804179e7fbbea1fa90a2937a065517092f5",class:"event-name"},this.eventName),this.venueLabel&&a("p",{key:"dd968b397deab890df3a4fbdff33226e82bd9660",class:"event-meta"},this.venueLabel),this.dateSummary&&a("p",{key:"f40e6049d09b06c9f599e7d14d6fbb43b39b22fd",class:"event-meta"},this.dateSummary)),a("button",{key:"dbe0908f8cd8544654b627921f68cc4961802b77",class:"close-btn","aria-label":"Close",onClick:this.close},a("svg",{key:"23a750830e6e16d28cbcd5025507d25848aaadf7",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2"},a("path",{key:"e81b8763a5c781f72c1ca8a2113482948e3ba8cc",d:"M6 6l12 12M18 6L6 18","stroke-linecap":"round"})))),a("div",{key:"da71e610f907cf53e78246d2065aaf526d5ceffd",class:"panel-body"},"loading"===this.step&&a("div",{key:"28cbb9a98c7b08fa8dcb9d8d5dfbf3bec93fe38d",class:"state-msg"},a("span",{key:"915c8de87cbdc7da1ccf0622ce6c0f02fccf2cad",class:"spinner"})," Loading…"),"error"===this.step&&a("div",{key:"5785578bfef6f1ee81d938d91ffd3ded975f8c12",class:"state-msg error"},this.error),"occurrence"===this.step&&a("tl-occurrence-selector",{key:"eeb853eab141c3c103015e82d221a140f6a3a109",eventId:this.eventId,onTlSelect:this.handleOccurrenceSelect}),"tickets"===this.step&&this.selectedOccurrenceId&&a("div",{key:"f608f592ba651eb431375433eb4ff9393863ade5",class:"tickets-step"},this.occurrenceCount>1&&a("button",{key:"84adfbdbeaceb2cf4238c6ffd09558b4499ca940",class:"back-link",onClick:this.backToDates},"← Change date"),this.occurrenceLabel&&a("p",{key:"0317e9194049608711e8c622142c3ad2c0a5dc12",class:"occ-label"},this.occurrenceLabel),a("tl-ticket-selector",{key:"27b1e05d9d92fb8d519375e2b27d4b5ea0a4890a",eventId:this.eventId,occurrenceId:this.selectedOccurrenceId,onTlAddToCart:this.handleAdded})),"done"===this.step&&a("div",{key:"0853088206988c66d489f8804df7899821d49e64",class:"done-step"},a("div",{key:"c2955b893c4dffaadcdfd27bee96ef2724a131a6",class:"done-mark"},"🎟️"),a("p",{key:"370c30dfcbc0c25b4794d984dd261a3a5779a9dc",class:"done-title"},"Added to your cart"),a("p",{key:"c462f3c9292740e2fd2c74b173484f80a5dc1a30",class:"done-sub"},"Held for you while you check out."),a("button",{key:"484991f79572e3213ad6413a1af87599880c3643",class:"primary-btn",onClick:this.goCheckout},"Go to checkout"),a("button",{key:"5b4ba5a472b794e8f5af0f131dad1c8c11b869f5",class:"ghost-btn",onClick:this.close},"Keep browsing")))),a("div",{key:"9acdd36744d363f41f0bed7938ecea33322362d1",class:"powered-by"},a("div",{key:"f45545a8fc625336618352f0c0e9e84a1babce96",class:"pb-links"},a("a",{key:"dd929b12419b8353d9a09ad242a9f351dfd699e2",href:"https://ticketlayer.com/privacy",target:"_blank",rel:"noopener noreferrer"},"Privacy Policy"),a("a",{key:"859be221bdc76602defaebdb89a997778cda6a91",href:"https://ticketlayer.com/report-abuse",target:"_blank",rel:"noopener noreferrer"},"Report Abuse")),a("a",{key:"d4e1f44b3b084160d2df8b9d15e075ddc5e05363",class:"pb-brand",href:"https://ticketlayer.com",target:"_blank",rel:"noopener noreferrer"},a("span",{key:"fe7fd86576a4e9772daa2c4c449da060f20fa143",class:"pb-pre"},"Powered by"),a("svg",{key:"19412bd9e5522f0af9f847fe8fda6aa0f0004a3a",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":"true"},a("path",{key:"c159efd1b8fce42b8c0fd5bac21792b4dc2728ce",d:"M4 7.5A1.5 1.5 0 0 1 5.5 6h13A1.5 1.5 0 0 1 20 7.5v2a2 2 0 0 0 0 5v2a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 4 16.5v-2a2 2 0 0 0 0-5v-2Z",fill:"currentColor"}),a("path",{key:"283956eead27e5919301c30882da6eaa7b093a1a",d:"M13 7v10",stroke:"var(--tl-pb-perforation, var(--tl-background, #fff))","stroke-width":"1.2","stroke-dasharray":"1.5 1.8","stroke-linecap":"round"})),a("span",{key:"bc045fda144885737b88bf81b4f9000ec8d333be",class:"pb-word"},"Ticketlayer")))))}static get style(){return":host{--_bg:var(--tl-background, #ffffff);--_fg:var(--tl-foreground, #111827);--_muted:var(--tl-muted, #f3f4f6);--_muted-fg:var(--tl-muted-foreground, #6b7280);--_border:var(--tl-border, #e5e7eb);--_primary:var(--tl-primary, #6366f1);--_primary-fg:var(--tl-primary-foreground, #ffffff);--_radius:var(--tl-radius-lg, var(--tl-radius, 0.75rem));--_font:var(--tl-font-family, system-ui, -apple-system, sans-serif);font-family:var(--_font)}.overlay{position:fixed;inset:0;z-index:2147483646;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:16px;background:rgba(8, 8, 16, 0.6);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);animation:tl-fade 0.18s ease-out}.panel{width:100%;max-width:460px;max-height:86vh;display:flex;flex-direction:column;overflow:hidden;background:var(--_bg);color:var(--_fg);border:1px solid var(--_border);border-radius:var(--_radius);box-shadow:0 24px 64px rgba(0, 0, 0, 0.45);animation:tl-rise 0.22s cubic-bezier(0.16, 1, 0.3, 1);transition:max-width 0.25s cubic-bezier(0.16, 1, 0.3, 1)}.panel--wide{max-width:720px}.powered-by{--tl-pb-perforation:rgba(8, 8, 16, 0.6);width:100%;max-width:460px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 4px;font-size:12px;font-weight:500;color:rgba(255, 255, 255, 0.78);animation:tl-fade 0.3s ease-out}.powered-by a{color:inherit;text-decoration:none;opacity:0.85;transition:opacity 0.15s ease}.powered-by a:hover{opacity:1}.powered-by .pb-links{display:flex;gap:16px;align-items:center}.powered-by .pb-brand{display:inline-flex;align-items:center;gap:6px;opacity:0.92}.powered-by .pb-brand svg{display:block}.powered-by .pb-pre{opacity:0.7}.powered-by .pb-word{font-weight:700;letter-spacing:0.01em}.panel-header{display:flex;align-items:center;gap:14px;padding:16px 18px;border-bottom:1px solid var(--_border)}.event-thumb{flex:none;width:56px;height:56px;border-radius:12px;background-size:cover;background-position:center;background-color:var(--_muted);border:1px solid var(--_border)}.titles{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}.event-meta{margin:0;font-size:0.8rem;color:var(--_muted-fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kicker{font-size:0.72rem;font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:var(--_primary)}.event-name{margin:0;font-size:1.18rem;font-weight:700;line-height:1.25;color:var(--_fg);overflow:hidden;text-overflow:ellipsis}.close-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border:0;border-radius:999px;background:var(--_muted);color:var(--_muted-fg);cursor:pointer;transition:color 0.15s, background 0.15s}.close-btn:hover{color:var(--_fg)}.close-btn svg{width:16px;height:16px}.panel-body{padding:18px 22px 22px;overflow-y:auto}.state-msg{display:flex;align-items:center;justify-content:center;gap:10px;padding:40px 0;color:var(--_muted-fg)}.state-msg.error{color:#b91c1c}.spinner{width:16px;height:16px;border:2px solid var(--_border);border-top-color:var(--_primary);border-radius:999px;animation:tl-spin 0.7s linear infinite}.tickets-step{display:flex;flex-direction:column;gap:6px}.back-link{align-self:flex-start;padding:0;border:0;background:none;color:var(--_primary);font-size:0.85rem;font-weight:500;cursor:pointer}.back-link:hover{text-decoration:underline}.occ-label{margin:2px 0 8px;font-size:0.9rem;font-weight:600;color:var(--_fg)}.done-step{display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px;padding:16px 0 4px}.done-mark{font-size:2.4rem;line-height:1;margin-bottom:6px}.done-title{margin:0;font-size:1.1rem;font-weight:700;color:var(--_fg)}.done-sub{margin:0 0 14px;font-size:0.9rem;color:var(--_muted-fg)}.primary-btn{width:100%;padding:13px;border:0;border-radius:var(--tl-radius-md, 0.5rem);background:var(--_primary);color:var(--_primary-fg);font-size:0.98rem;font-weight:600;cursor:pointer;transition:opacity 0.15s}.primary-btn:hover{opacity:0.9}.ghost-btn{width:100%;margin-top:8px;padding:12px;border:1px solid var(--_border);border-radius:var(--tl-radius-md, 0.5rem);background:transparent;color:var(--_fg);font-size:0.95rem;font-weight:500;cursor:pointer;transition:background 0.15s}.ghost-btn:hover{background:var(--_muted)}@keyframes tl-fade{from{opacity:0}}@keyframes tl-rise{from{opacity:0;transform:translateY(12px) scale(0.98)}}@keyframes tl-spin{to{transform:rotate(360deg)}}"}},[1,"tl-buy-modal",{eventId:[1,"event-id"],occurrenceId:[1,"occurrence-id"],step:[32],eventName:[32],imageUrl:[32],venueLabel:[32],dateSummary:[32],selectedOccurrenceId:[32],occurrenceCount:[32],occurrenceLabel:[32],error:[32]}]),f=l,b=function(){"undefined"!=typeof customElements&&["tl-buy-modal","tl-occurrence-selector","tl-ticket-selector"].forEach((e=>{switch(e){case"tl-buy-modal":customElements.get(o(e))||customElements.define(o(e),l);break;case"tl-occurrence-selector":customElements.get(o(e))||d();break;case"tl-ticket-selector":customElements.get(o(e))||n()}}))};export{f as TlBuyModal,b as defineCustomElement}
|
|
1
|
+
import{proxyCustomElement as e,HTMLElement as t,createEvent as r,h as a,Host as i,transformTag as o}from"@stencil/core/internal/client";import{w as c,g as s}from"./sdk-connector.js";import{d as n}from"./tl-occurrence-selector2.js";import{d}from"./tl-ticket-selector2.js";const l=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.tlClose=r(this,"tlClose",7),this.tlCheckout=r(this,"tlCheckout",7),this.tlError=r(this,"tlError",7),this.step="loading",this.eventName="",this.imageUrl="",this.venueLabel="",this.dateSummary="",this.selectedOccurrenceId=null,this.occurrenceCount=0,this.occurrenceLabel="",this.error=null,this.handleOccurrenceSelect=e=>{const t=e.detail.occurrence;this.selectedOccurrenceId=t.id,this.occurrenceLabel=this.labelFor(t),this.step="tickets"},this.handleAdded=()=>{this.step="done"},this.backToDates=()=>{this.selectedOccurrenceId=null,this.step="occurrence"},this.close=()=>this.tlClose.emit(),this.goCheckout=()=>this.tlCheckout.emit()}async componentWillLoad(){if(this.eventId)try{await c();const e=await s().getEventsManager().get(this.eventId);this.eventName=e?.name??"Tickets",this.imageUrl=e?.imageUrl||e?.heroImageUrl||"",this.venueLabel=[e?.venueName,e?.venueCity].filter(Boolean).join(", ");const t=e?.occurrences??[];this.occurrenceCount=t.length,this.dateSummary=this.summariseDates(t);const r=this.occurrenceId??(1===t.length?t[0]?.id:null);r?(this.selectedOccurrenceId=r,this.occurrenceLabel=this.labelFor(t.find((e=>e.id===r))),this.step="tickets"):this.step="occurrence"}catch(e){this.fail(e instanceof Error?e.message:"Could not load this event")}else this.fail("No event specified")}fail(e){this.error=e,this.step="error",this.tlError.emit({message:e})}summariseDates(e){const t=e.map((e=>e.startsAt)).filter((e=>!!e)).sort();if(0===t.length)return"";const r=e=>new Date(e).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"});if(1===t.length)return new Date(t[0]).toLocaleDateString("en-GB",{weekday:"short",day:"numeric",month:"short",year:"numeric"});const a=r(t[0]),i=r(t[t.length-1]);return`${a===i?a:`${a} - ${i}`} · ${t.length} dates`}labelFor(e){return e?.startsAt?new Date(e.startsAt).toLocaleString("en-GB",{weekday:"short",day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"}):""}stepKicker(){switch(this.step){case"occurrence":return"Choose a date";case"tickets":return"Select tickets";case"done":return"Nice one";default:return"Tickets"}}render(){return a(i,{key:"f28be761216b4a84904c1e325dc34d848625db14"},a("div",{key:"0f36708a6b52d19ee987b211588e759aaf82ac03",class:"overlay",onClick:e=>{e.target===e.currentTarget&&this.close()}},a("div",{key:"0b2bc062c89e8b821763e163bdedc44047571390",class:{panel:!0,"panel--wide":"occurrence"===this.step},role:"dialog","aria-modal":"true","aria-label":this.eventName},a("header",{key:"c9e3cc54615dace1842ceed226acff23ed0dc0d3",class:"panel-header"},this.imageUrl&&a("div",{key:"18ffd6168344f65231fa40252361b03ac65ae91a",class:"event-thumb",style:{backgroundImage:`url(${this.imageUrl})`}}),a("div",{key:"4ccbf9a0477948bcb4202310f80cceb1d6e5ad0f",class:"titles"},a("span",{key:"1a72eb71baaf9eff16aabc5d20c22b02e9b5cc99",class:"kicker"},this.stepKicker()),a("h2",{key:"f7dbc184bb016652c1ffe2fe24a551207f226942",class:"event-name"},this.eventName),this.venueLabel&&a("p",{key:"db7ebd34f688b36b5610aa6adf0d8ab766f00ac2",class:"event-meta"},this.venueLabel),this.dateSummary&&a("p",{key:"00812c8b7b9abf85343f3d6bda433251468da1d9",class:"event-meta"},this.dateSummary)),a("button",{key:"e3f7252979794959d6e5070d549010567c0aa349",class:"close-btn","aria-label":"Close",onClick:this.close},a("svg",{key:"d692c47bb8c614b41e19866c5fe4a65b0e083686",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2"},a("path",{key:"cbb9a7bd3ce4ed2685a781729110bccd36b425a9",d:"M6 6l12 12M18 6L6 18","stroke-linecap":"round"})))),a("div",{key:"c14af096c9e1cfd9bcead143c1b8a106a4b28018",class:"panel-body"},"loading"===this.step&&a("div",{key:"108d1073d572f841f1945147a787b8bdea66cfba",class:"state-msg"},a("span",{key:"27c2b7473c6edb14ade3b7104f728136c0a2b052",class:"spinner"})," Loading…"),"error"===this.step&&a("div",{key:"0e3f927f626d51dffc30bb7da7093b6a7cd90a2a",class:"state-msg error"},this.error),"occurrence"===this.step&&a("tl-occurrence-selector",{key:"bfab02d294de3eb1bce39d3e39c21f450b474c99",eventId:this.eventId,onTlSelect:this.handleOccurrenceSelect}),"tickets"===this.step&&this.selectedOccurrenceId&&a("div",{key:"109be73c93b0b604b435cbbd540d5dd5c48eacfe",class:"tickets-step"},this.occurrenceCount>1&&a("button",{key:"2769d896476487e1412ac37309cd2e162b4bd275",class:"back-link",onClick:this.backToDates},"← Change date"),this.occurrenceLabel&&a("p",{key:"0c709ed8ba75b9e13a141ae755353fc694532935",class:"occ-label"},this.occurrenceLabel),a("tl-ticket-selector",{key:"cdf66533a591e89dc265532a2578c30327fd06c8",eventId:this.eventId,occurrenceId:this.selectedOccurrenceId,onTlAddToCart:this.handleAdded})),"done"===this.step&&a("div",{key:"6c4b294a4b9412e643a230f4064d15a587f79383",class:"done-step"},a("div",{key:"ba0e663e731402192675db509c886c2ce6a2418b",class:"done-mark"},"🎟️"),a("p",{key:"8d0f07758d3978080177a99e580f59fbcfefb611",class:"done-title"},"Added to your cart"),a("p",{key:"bbf4bd073f021a2f516f91528311d494c40faa85",class:"done-sub"},"Held for you while you check out."),a("button",{key:"71c90ad945ced314321d964795beed8301c989ac",class:"primary-btn",onClick:this.goCheckout},"Go to checkout"),a("button",{key:"b37ad6f8adeb1edb7c786b33974b845c31b963f2",class:"ghost-btn",onClick:this.close},"Keep browsing")))),a("div",{key:"5a175094620f6837ae91a5a394f16c79df94c859",class:"powered-by"},a("div",{key:"63c095dc7e954042c5fb36ccd8ca92a33d7b6632",class:"pb-links"},a("a",{key:"875fa14d6218853b96d4d817a243701b228b20f0",href:"https://ticketlayer.com/privacy",target:"_blank",rel:"noopener noreferrer"},"Privacy Policy"),a("a",{key:"7de77189ecd8277acade45437819b4fa9ef2002b",href:"https://ticketlayer.com/report-abuse",target:"_blank",rel:"noopener noreferrer"},"Report Abuse")),a("a",{key:"5f62bbe303398e9ad09703fbd706953502f441a1",class:"pb-brand",href:"https://ticketlayer.com",target:"_blank",rel:"noopener noreferrer"},a("span",{key:"0101948057126320d180a452870eade9f540b119",class:"pb-pre"},"Powered by"),a("svg",{key:"c93e4184b3bd8bbb89b5909ec886b22d22322bb1",width:"14",height:"14",viewBox:"0 0 50 50",fill:"none","aria-hidden":"true"},a("g",{key:"5461e514631e1cb670e974b47ecc144e1a62e7a3",transform:"matrix(0.0129 0 0 -0.0129 25.4752 25.4752)"},a("path",{key:"af6f137d33f09ef4befb9a4b31834d6d2f04ab3d",fill:"currentColor",transform:"translate(-1781.5, -1759.4003)",d:"M 41 2973 c 1 -285 5 -734 9 -998 c 7 -444 9 -488 30 -580 c 81 -364 235 -634 512 -900 c 135 -130 263 -220 423 -299 c 156 -77 249 -109 409 -143 c 110 -23 142 -25 354 -24 c 230 1 310 8 427 37 c 241 60 453 162 640 309 c 82 64 252 234 317 315 c 210 264 340 604 355 926 l 6 121 l -69 6 c -86 8 -706 9 -755 1 l -36 -6 l -21 -125 c -34 -191 -98 -317 -236 -462 c -111 -115 -249 -198 -396 -238 c -98 -27 -356 -24 -463 5 c -100 27 -183 69 -273 137 c -226 173 -353 409 -354 660 c 0 44 -5 120 -10 169 c -6 49 -8 91 -6 94 c 3 3 65 -22 138 -55 c 140 -64 251 -103 358 -127 c 71 -17 295 -46 347 -46 l 33 0 l 0 434 l 0 434 l -67 7 c -147 14 -269 56 -393 133 c -222 139 -378 393 -397 648 l -6 71 l -75 7 c -41 3 -239 6 -439 6 l -363 0 l 1 -517 z"}))),a("span",{key:"d4f15a3fb911e2f78eb203fdd5079d3119ee9803",class:"pb-word"},"ticketlayer")))))}static get style(){return":host{--_bg:var(--tl-background);--_fg:var(--tl-foreground);--_muted:var(--tl-muted);--_muted-fg:var(--tl-muted-foreground);--_border:var(--tl-border);--_primary:var(--tl-primary);--_primary-fg:var(--tl-primary-foreground);--_radius:var(--tl-radius-lg);--_font:var(--tl-font-family);font-family:var(--_font)}.overlay{position:fixed;inset:0;z-index:2147483646;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:16px;background:rgba(8, 8, 16, 0.6);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);animation:tl-fade 0.18s ease-out}.panel{width:100%;max-width:460px;max-height:86vh;display:flex;flex-direction:column;overflow:hidden;background:var(--_bg);color:var(--_fg);border:1px solid var(--_border);border-radius:var(--_radius);box-shadow:0 24px 64px rgba(0, 0, 0, 0.45);animation:tl-rise 0.22s cubic-bezier(0.16, 1, 0.3, 1);transition:max-width 0.25s cubic-bezier(0.16, 1, 0.3, 1)}.panel--wide{max-width:720px}.powered-by{width:100%;max-width:460px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 4px;font-size:12px;font-weight:500;color:rgba(255, 255, 255, 0.78);animation:tl-fade 0.3s ease-out}.powered-by a{color:inherit;text-decoration:none;opacity:0.85;transition:opacity 0.15s ease}.powered-by a:hover{opacity:1}.powered-by .pb-links{display:flex;gap:16px;align-items:center}.powered-by .pb-brand{display:inline-flex;align-items:center;gap:6px;opacity:0.92}.powered-by .pb-brand svg{display:block}.powered-by .pb-pre{opacity:0.7}.powered-by .pb-word{font-weight:700;letter-spacing:0.01em}.panel-header{display:flex;align-items:center;gap:14px;padding:16px 18px;border-bottom:1px solid var(--_border)}.event-thumb{flex:none;width:56px;height:56px;border-radius:12px;background-size:cover;background-position:center;background-color:var(--_muted);border:1px solid var(--_border)}.titles{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}.event-meta{margin:0;font-size:0.8rem;color:var(--_muted-fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kicker{font-size:0.72rem;font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:var(--_primary)}.event-name{margin:0;font-size:1.18rem;font-weight:700;line-height:1.25;color:var(--_fg);overflow:hidden;text-overflow:ellipsis}.close-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border:0;border-radius:999px;background:var(--_muted);color:var(--_muted-fg);cursor:pointer;transition:color 0.15s, background 0.15s}.close-btn:hover{color:var(--_fg)}.close-btn svg{width:16px;height:16px}.panel-body{padding:18px 22px 22px;overflow-y:auto}.state-msg{display:flex;align-items:center;justify-content:center;gap:10px;padding:40px 0;color:var(--_muted-fg)}.state-msg.error{color:#b91c1c}.spinner{width:16px;height:16px;border:2px solid var(--_border);border-top-color:var(--_primary);border-radius:999px;animation:tl-spin 0.7s linear infinite}.tickets-step{display:flex;flex-direction:column;gap:6px}.back-link{align-self:flex-start;padding:0;border:0;background:none;color:var(--_primary);font-size:0.85rem;font-weight:500;cursor:pointer}.back-link:hover{text-decoration:underline}.occ-label{margin:2px 0 8px;font-size:0.9rem;font-weight:600;color:var(--_fg)}.done-step{display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px;padding:16px 0 4px}.done-mark{font-size:2.4rem;line-height:1;margin-bottom:6px}.done-title{margin:0;font-size:1.1rem;font-weight:700;color:var(--_fg)}.done-sub{margin:0 0 14px;font-size:0.9rem;color:var(--_muted-fg)}.primary-btn{width:100%;padding:13px;border:0;border-radius:var(--tl-radius-md);background:var(--_primary);color:var(--_primary-fg);font-size:0.98rem;font-weight:600;cursor:pointer;transition:opacity 0.15s}.primary-btn:hover{opacity:0.9}.ghost-btn{width:100%;margin-top:8px;padding:12px;border:1px solid var(--_border);border-radius:var(--tl-radius-md);background:transparent;color:var(--_fg);font-size:0.95rem;font-weight:500;cursor:pointer;transition:background 0.15s}.ghost-btn:hover{background:var(--_muted)}@keyframes tl-fade{from{opacity:0}}@keyframes tl-rise{from{opacity:0;transform:translateY(12px) scale(0.98)}}@keyframes tl-spin{to{transform:rotate(360deg)}}"}},[1,"tl-buy-modal",{eventId:[1,"event-id"],occurrenceId:[1,"occurrence-id"],step:[32],eventName:[32],imageUrl:[32],venueLabel:[32],dateSummary:[32],selectedOccurrenceId:[32],occurrenceCount:[32],occurrenceLabel:[32],error:[32]}]),b=l,f=function(){"undefined"!=typeof customElements&&["tl-buy-modal","tl-occurrence-selector","tl-ticket-selector"].forEach((e=>{switch(e){case"tl-buy-modal":customElements.get(o(e))||customElements.define(o(e),l);break;case"tl-occurrence-selector":customElements.get(o(e))||n();break;case"tl-ticket-selector":customElements.get(o(e))||d()}}))};export{b as TlBuyModal,f as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxyCustomElement as t,HTMLElement as
|
|
1
|
+
import{proxyCustomElement as t,HTMLElement as r,createEvent as e,h as o,Host as i,transformTag as n}from"@stencil/core/internal/client";import{w as s,g as a}from"./sdk-connector.js";import{c,g as l}from"./ticket-selector.js";const d=t(class extends r{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.tlClick=e(this,"tlClick",7),this.state="available",this.variant="primary",this.size="md",this.fullWidth=!1,this.currency="GBP",this.pricePrefix="From",this.disabled=!1,this.isHovered=!1,this.element=c(l,{client:()=>a(),clientReady:()=>s(),emit:(t,r)=>this.forward(t,r)}),this.view=this.element.view,this.handleClick=()=>{this.element.actions.activate()}}syncProps(){this.element.setProps({eventId:this.eventId,occurrenceId:this.occurrenceId,state:this.state,label:this.label,variant:this.variant,size:this.size,fullWidth:this.fullWidth,price:this.price,currency:this.currency,pricePrefix:this.pricePrefix,disabled:this.disabled})}connectedCallback(){this.syncProps(),this.unsubscribe??(this.unsubscribe=this.element.subscribe((t=>{this.view=t}))),this.view=this.element.view,this.teardown=this.element.mount()}disconnectedCallback(){this.teardown?.(),this.teardown=void 0,this.unsubscribe?.(),this.unsubscribe=void 0}forward(t,r){"tlClick"===t&&this.tlClick.emit(r)}render(){const{interactive:t,buttonLabel:r,stateClass:e,priceLabel:n}=this.view.derived;return o(i,{key:"6d5dddb3fc486c5a877a3718fecbee80a648b274",class:{"full-width":this.fullWidth}},o("button",{key:"88f7f0688fb42e97eb2ce352f316b2a085c3bab5",type:"button",class:{"buy-button":!0,[e]:!0,["variant-"+this.variant]:!0,["size-"+this.size]:!0,disabled:!t,hovered:this.isHovered&&t},disabled:!t,onClick:this.handleClick,onMouseEnter:()=>this.isHovered=!0,onMouseLeave:()=>this.isHovered=!1},o("span",{key:"e88c2f05c7bc782d08d78fc8ab53b213ab3c833f",class:"icon"},"soldOut"===this.state&&this.renderSoldOutIcon(),"waitlist"===this.state&&this.renderWaitlistIcon(),"comingSoon"===this.state&&this.renderComingSoonIcon(),"available"===this.state&&this.renderTicketIcon()),o("span",{key:"7290a58779e884886f26e64c405fd319811613a1",class:"label"},r),null!==n&&o("span",{key:"bdf3bcdbfa29d4799f7a64bc0072a4c06c09c393",class:"price"},o("span",{key:"32b075fc6793ef21e9a2cd188058992f95c10680",class:"price-prefix"},this.pricePrefix),o("span",{key:"ff3805b660b2af72a94fabc315507ce063ff02d2",class:"price-value"},n))))}renderTicketIcon(){return o("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},o("path",{d:"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"}),o("path",{d:"M13 5v2"}),o("path",{d:"M13 17v2"}),o("path",{d:"M13 11v2"}))}renderSoldOutIcon(){return o("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},o("circle",{cx:"12",cy:"12",r:"10"}),o("path",{d:"m15 9-6 6"}),o("path",{d:"m9 9 6 6"}))}renderWaitlistIcon(){return o("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},o("circle",{cx:"12",cy:"12",r:"10"}),o("polyline",{points:"12 6 12 12 16 14"}))}renderComingSoonIcon(){return o("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},o("path",{d:"M12 2v4"}),o("path",{d:"m16.2 7.8 2.9-2.9"}),o("path",{d:"M18 12h4"}),o("path",{d:"m16.2 16.2 2.9 2.9"}),o("path",{d:"M12 18v4"}),o("path",{d:"m4.9 19.1 2.9-2.9"}),o("path",{d:"M2 12h4"}),o("path",{d:"m4.9 4.9 2.9 2.9"}))}static get watchers(){return{eventId:[{syncProps:0}],occurrenceId:[{syncProps:0}],state:[{syncProps:0}],label:[{syncProps:0}],variant:[{syncProps:0}],size:[{syncProps:0}],fullWidth:[{syncProps:0}],price:[{syncProps:0}],currency:[{syncProps:0}],pricePrefix:[{syncProps:0}],disabled:[{syncProps:0}]}}static get style(){return":host{display:inline-block;font-family:var(--tl-font-family)}:host(.full-width){display:block;width:100%}:host(.full-width) .buy-button{width:100%}.state-available{--button-color:var(--tl-primary);--button-hover-color:color-mix(in srgb, var(--tl-primary) 90%, black);--button-foreground:var(--tl-primary-foreground)}.state-sold-out{--button-color:var(--tl-error);--button-hover-color:color-mix(in srgb, var(--tl-error) 90%, black);--button-foreground:var(--tl-error-foreground)}.state-waitlist{--button-color:var(--tl-info);--button-hover-color:color-mix(in srgb, var(--tl-info) 90%, black);--button-foreground:var(--tl-info-foreground)}.state-coming-soon{--button-color:var(--tl-warning);--button-hover-color:color-mix(in srgb, var(--tl-warning) 90%, black);--button-foreground:var(--tl-warning-foreground)}.buy-button{display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;font-weight:600;border:none;cursor:pointer;text-decoration:none;outline:none;transition:all 0.2s ease;white-space:nowrap}.buy-button.variant-primary{background:var(--button-color);color:var(--button-foreground)}.buy-button.variant-secondary{background:color-mix(in srgb, var(--button-color) 15%, transparent);color:var(--button-color)}.buy-button.variant-outline{background:transparent;color:var(--button-color);border:2px solid var(--button-color)}.buy-button.size-sm{padding:0.5rem 1rem;font-size:0.875rem;border-radius:var(--tl-radius-sm)}.buy-button.size-md{padding:0.75rem 1.5rem;font-size:1rem;border-radius:var(--tl-radius-md)}.buy-button.size-lg{padding:1rem 2rem;font-size:1.125rem;border-radius:var(--tl-radius-lg);min-height:51px}.buy-button.hovered:not(.disabled){opacity:0.9;transform:translateY(-1px)}.buy-button.hovered.variant-primary{background:var(--button-hover-color)}.buy-button.disabled{opacity:0.7;cursor:not-allowed}.icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.icon svg{width:1em;height:1em}.label{flex-shrink:0}.price{display:inline-flex;align-items:center;gap:0.25rem;margin-left:0.5rem;white-space:nowrap;opacity:0.9}.price-prefix{opacity:0.7}.price-value{font-weight:700}"}},[1,"tl-buy-tickets-button",{eventId:[1,"event-id"],occurrenceId:[1,"occurrence-id"],state:[1],label:[1],variant:[1],size:[1],fullWidth:[4,"full-width"],price:[2],currency:[1],pricePrefix:[1,"price-prefix"],disabled:[4],isHovered:[32],view:[32]},void 0,{eventId:[{syncProps:0}],occurrenceId:[{syncProps:0}],state:[{syncProps:0}],label:[{syncProps:0}],variant:[{syncProps:0}],size:[{syncProps:0}],fullWidth:[{syncProps:0}],price:[{syncProps:0}],currency:[{syncProps:0}],pricePrefix:[{syncProps:0}],disabled:[{syncProps:0}]}]),u=d,h=function(){"undefined"!=typeof customElements&&["tl-buy-tickets-button"].forEach((t=>{"tl-buy-tickets-button"===t&&(customElements.get(n(t))||customElements.define(n(t),d))}))};export{u as TlBuyTicketsButton,h as defineCustomElement}
|