@ticketlayer/elements 0.2.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.
Files changed (195) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +55 -0
  3. package/dist/cjs/index-DfzcrE9-.js +3598 -0
  4. package/dist/cjs/index.cjs.js +16 -0
  5. package/dist/cjs/loader.cjs.js +12 -0
  6. package/dist/cjs/order-summary-ZMkJ5bez.js +116 -0
  7. package/dist/cjs/sdk-connector-ClDF3013.js +108 -0
  8. package/dist/cjs/ticketlayer-elements.cjs.js +24 -0
  9. package/dist/cjs/tl-buy-modal.cjs.entry.js +127 -0
  10. package/dist/cjs/tl-buy-tickets-button.cjs.entry.js +131 -0
  11. package/dist/cjs/tl-buy-tickets-wrapper.cjs.entry.js +58 -0
  12. package/dist/cjs/tl-cart-badge.cjs.entry.js +109 -0
  13. package/dist/cjs/tl-cart-drawer.cjs.entry.js +67 -0
  14. package/dist/cjs/tl-cart.cjs.entry.js +148 -0
  15. package/dist/cjs/tl-checkout-wrapper.cjs.entry.js +57 -0
  16. package/dist/cjs/tl-event-card.cjs.entry.js +140 -0
  17. package/dist/cjs/tl-event-list.cjs.entry.js +80 -0
  18. package/dist/cjs/tl-login.cjs.entry.js +184 -0
  19. package/dist/cjs/tl-my-orders.cjs.entry.js +123 -0
  20. package/dist/cjs/tl-occurrence-selector_2.cjs.entry.js +754 -0
  21. package/dist/cjs/tl-order-confirmation.cjs.entry.js +146 -0
  22. package/dist/cjs/tl-order-tickets_2.cjs.entry.js +3198 -0
  23. package/dist/cjs/tl-promo-code.cjs.entry.js +75 -0
  24. package/dist/cjs/tl-seat-map.cjs.entry.js +147 -0
  25. package/dist/collection/collection-manifest.json +29 -0
  26. package/dist/collection/components/tl-buy-modal/tl-buy-modal.css +264 -0
  27. package/dist/collection/components/tl-buy-modal/tl-buy-modal.js +249 -0
  28. package/dist/collection/components/tl-buy-tickets-button/tl-buy-tickets-button.css +120 -0
  29. package/dist/collection/components/tl-buy-tickets-button/tl-buy-tickets-button.js +412 -0
  30. package/dist/collection/components/tl-buy-tickets-wrapper/tl-buy-tickets-wrapper.css +23 -0
  31. package/dist/collection/components/tl-buy-tickets-wrapper/tl-buy-tickets-wrapper.js +192 -0
  32. package/dist/collection/components/tl-cart/tl-cart.css +251 -0
  33. package/dist/collection/components/tl-cart/tl-cart.js +314 -0
  34. package/dist/collection/components/tl-cart-badge/tl-cart-badge.css +138 -0
  35. package/dist/collection/components/tl-cart-badge/tl-cart-badge.js +217 -0
  36. package/dist/collection/components/tl-cart-drawer/tl-cart-drawer.css +98 -0
  37. package/dist/collection/components/tl-cart-drawer/tl-cart-drawer.js +185 -0
  38. package/dist/collection/components/tl-checkout-wrapper/tl-checkout-wrapper.css +23 -0
  39. package/dist/collection/components/tl-checkout-wrapper/tl-checkout-wrapper.js +148 -0
  40. package/dist/collection/components/tl-event-card/event-card-adapter.js +23 -0
  41. package/dist/collection/components/tl-event-card/tl-event-card.css +175 -0
  42. package/dist/collection/components/tl-event-card/tl-event-card.js +205 -0
  43. package/dist/collection/components/tl-event-list/tl-event-list.css +134 -0
  44. package/dist/collection/components/tl-event-list/tl-event-list.js +171 -0
  45. package/dist/collection/components/tl-login/tl-login.css +133 -0
  46. package/dist/collection/components/tl-login/tl-login.js +309 -0
  47. package/dist/collection/components/tl-my-orders/tl-my-orders.css +204 -0
  48. package/dist/collection/components/tl-my-orders/tl-my-orders.js +221 -0
  49. package/dist/collection/components/tl-occurrence-selector/tl-occurrence-selector.css +658 -0
  50. package/dist/collection/components/tl-occurrence-selector/tl-occurrence-selector.js +707 -0
  51. package/dist/collection/components/tl-order-confirmation/tl-order-confirmation.css +176 -0
  52. package/dist/collection/components/tl-order-confirmation/tl-order-confirmation.js +298 -0
  53. package/dist/collection/components/tl-order-tickets/tl-order-tickets.css +30 -0
  54. package/dist/collection/components/tl-order-tickets/tl-order-tickets.js +122 -0
  55. package/dist/collection/components/tl-promo-code/tl-promo-code.css +106 -0
  56. package/dist/collection/components/tl-promo-code/tl-promo-code.js +181 -0
  57. package/dist/collection/components/tl-seat-map/tl-seat-map.css +85 -0
  58. package/dist/collection/components/tl-seat-map/tl-seat-map.js +366 -0
  59. package/dist/collection/components/tl-ticket/tl-ticket.css +90 -0
  60. package/dist/collection/components/tl-ticket/tl-ticket.js +129 -0
  61. package/dist/collection/components/tl-ticket-selector/tl-ticket-selector.css +205 -0
  62. package/dist/collection/components/tl-ticket-selector/tl-ticket-selector.js +332 -0
  63. package/dist/collection/index.js +10 -0
  64. package/dist/collection/utils/order-summary.js +101 -0
  65. package/dist/collection/utils/sdk-connector.js +100 -0
  66. package/dist/collection/utils/testing/mock-sdk.js +95 -0
  67. package/dist/components/index.d.ts +35 -0
  68. package/dist/components/index.js +1 -0
  69. package/dist/components/order-summary.js +1 -0
  70. package/dist/components/sdk-connector.js +1 -0
  71. package/dist/components/tl-buy-modal.d.ts +11 -0
  72. package/dist/components/tl-buy-modal.js +1 -0
  73. package/dist/components/tl-buy-tickets-button.d.ts +11 -0
  74. package/dist/components/tl-buy-tickets-button.js +1 -0
  75. package/dist/components/tl-buy-tickets-wrapper.d.ts +11 -0
  76. package/dist/components/tl-buy-tickets-wrapper.js +1 -0
  77. package/dist/components/tl-buy-tickets-wrapper2.js +1 -0
  78. package/dist/components/tl-cart-badge.d.ts +11 -0
  79. package/dist/components/tl-cart-badge.js +1 -0
  80. package/dist/components/tl-cart-drawer.d.ts +11 -0
  81. package/dist/components/tl-cart-drawer.js +1 -0
  82. package/dist/components/tl-cart.d.ts +11 -0
  83. package/dist/components/tl-cart.js +1 -0
  84. package/dist/components/tl-cart2.js +1 -0
  85. package/dist/components/tl-checkout-wrapper.d.ts +11 -0
  86. package/dist/components/tl-checkout-wrapper.js +1 -0
  87. package/dist/components/tl-checkout-wrapper2.js +1 -0
  88. package/dist/components/tl-event-card.d.ts +11 -0
  89. package/dist/components/tl-event-card.js +1 -0
  90. package/dist/components/tl-event-card2.js +1 -0
  91. package/dist/components/tl-event-list.d.ts +11 -0
  92. package/dist/components/tl-event-list.js +1 -0
  93. package/dist/components/tl-login.d.ts +11 -0
  94. package/dist/components/tl-login.js +1 -0
  95. package/dist/components/tl-login2.js +1 -0
  96. package/dist/components/tl-my-orders.d.ts +11 -0
  97. package/dist/components/tl-my-orders.js +1 -0
  98. package/dist/components/tl-occurrence-selector.d.ts +11 -0
  99. package/dist/components/tl-occurrence-selector.js +1 -0
  100. package/dist/components/tl-occurrence-selector2.js +1 -0
  101. package/dist/components/tl-order-confirmation.d.ts +11 -0
  102. package/dist/components/tl-order-confirmation.js +1 -0
  103. package/dist/components/tl-order-tickets.d.ts +11 -0
  104. package/dist/components/tl-order-tickets.js +1 -0
  105. package/dist/components/tl-order-tickets2.js +1 -0
  106. package/dist/components/tl-promo-code.d.ts +11 -0
  107. package/dist/components/tl-promo-code.js +1 -0
  108. package/dist/components/tl-seat-map.d.ts +11 -0
  109. package/dist/components/tl-seat-map.js +1 -0
  110. package/dist/components/tl-ticket-selector.d.ts +11 -0
  111. package/dist/components/tl-ticket-selector.js +1 -0
  112. package/dist/components/tl-ticket-selector2.js +1 -0
  113. package/dist/components/tl-ticket.d.ts +11 -0
  114. package/dist/components/tl-ticket.js +1 -0
  115. package/dist/components/tl-ticket2.js +1 -0
  116. package/dist/elements.docs.d.ts +454 -0
  117. package/dist/elements.docs.json +3008 -0
  118. package/dist/esm/index-Ba-RZTFI.js +3588 -0
  119. package/dist/esm/index.js +4 -0
  120. package/dist/esm/loader.js +10 -0
  121. package/dist/esm/order-summary-BGekdjN9.js +103 -0
  122. package/dist/esm/sdk-connector-CqhvfyKV.js +102 -0
  123. package/dist/esm/ticketlayer-elements.js +20 -0
  124. package/dist/esm/tl-buy-modal.entry.js +125 -0
  125. package/dist/esm/tl-buy-tickets-button.entry.js +129 -0
  126. package/dist/esm/tl-buy-tickets-wrapper.entry.js +56 -0
  127. package/dist/esm/tl-cart-badge.entry.js +107 -0
  128. package/dist/esm/tl-cart-drawer.entry.js +65 -0
  129. package/dist/esm/tl-cart.entry.js +146 -0
  130. package/dist/esm/tl-checkout-wrapper.entry.js +55 -0
  131. package/dist/esm/tl-event-card.entry.js +138 -0
  132. package/dist/esm/tl-event-list.entry.js +78 -0
  133. package/dist/esm/tl-login.entry.js +182 -0
  134. package/dist/esm/tl-my-orders.entry.js +121 -0
  135. package/dist/esm/tl-occurrence-selector_2.entry.js +751 -0
  136. package/dist/esm/tl-order-confirmation.entry.js +144 -0
  137. package/dist/esm/tl-order-tickets_2.entry.js +3195 -0
  138. package/dist/esm/tl-promo-code.entry.js +73 -0
  139. package/dist/esm/tl-seat-map.entry.js +145 -0
  140. package/dist/index.cjs.js +1 -0
  141. package/dist/index.js +1 -0
  142. package/dist/ticketlayer-elements/index.esm.js +1 -0
  143. package/dist/ticketlayer-elements/p-0291df4c.entry.js +1 -0
  144. package/dist/ticketlayer-elements/p-10f01a1f.entry.js +1 -0
  145. package/dist/ticketlayer-elements/p-11273f8f.entry.js +1 -0
  146. package/dist/ticketlayer-elements/p-340ab4f5.entry.js +1 -0
  147. package/dist/ticketlayer-elements/p-41d22d7c.entry.js +1 -0
  148. package/dist/ticketlayer-elements/p-82752e3b.entry.js +1 -0
  149. package/dist/ticketlayer-elements/p-976770f3.entry.js +1 -0
  150. package/dist/ticketlayer-elements/p-9a903ff6.entry.js +1 -0
  151. package/dist/ticketlayer-elements/p-9c9072c8.entry.js +1 -0
  152. package/dist/ticketlayer-elements/p-9d8163d6.entry.js +1 -0
  153. package/dist/ticketlayer-elements/p-BGekdjN9.js +1 -0
  154. package/dist/ticketlayer-elements/p-Ba-RZTFI.js +2 -0
  155. package/dist/ticketlayer-elements/p-CqhvfyKV.js +1 -0
  156. package/dist/ticketlayer-elements/p-a5c90b68.entry.js +1 -0
  157. package/dist/ticketlayer-elements/p-b6d479ad.entry.js +1 -0
  158. package/dist/ticketlayer-elements/p-dd43f015.entry.js +1 -0
  159. package/dist/ticketlayer-elements/p-eb640760.entry.js +1 -0
  160. package/dist/ticketlayer-elements/p-ee3aa227.entry.js +1 -0
  161. package/dist/ticketlayer-elements/p-fb9444c4.entry.js +1 -0
  162. package/dist/ticketlayer-elements/ticketlayer-elements.css +1 -0
  163. package/dist/ticketlayer-elements/ticketlayer-elements.esm.js +1 -0
  164. package/dist/types/components/tl-buy-modal/tl-buy-modal.d.ts +54 -0
  165. package/dist/types/components/tl-buy-tickets-button/tl-buy-tickets-button.d.ts +61 -0
  166. package/dist/types/components/tl-buy-tickets-wrapper/tl-buy-tickets-wrapper.d.ts +52 -0
  167. package/dist/types/components/tl-cart/tl-cart.d.ts +80 -0
  168. package/dist/types/components/tl-cart-badge/tl-cart-badge.d.ts +36 -0
  169. package/dist/types/components/tl-cart-drawer/tl-cart-drawer.d.ts +35 -0
  170. package/dist/types/components/tl-checkout-wrapper/tl-checkout-wrapper.d.ts +39 -0
  171. package/dist/types/components/tl-event-card/event-card-adapter.d.ts +23 -0
  172. package/dist/types/components/tl-event-card/tl-event-card.d.ts +55 -0
  173. package/dist/types/components/tl-event-list/tl-event-list.d.ts +30 -0
  174. package/dist/types/components/tl-login/tl-login.d.ts +59 -0
  175. package/dist/types/components/tl-my-orders/tl-my-orders.d.ts +39 -0
  176. package/dist/types/components/tl-occurrence-selector/tl-occurrence-selector.d.ts +208 -0
  177. package/dist/types/components/tl-order-confirmation/tl-order-confirmation.d.ts +54 -0
  178. package/dist/types/components/tl-order-tickets/tl-order-tickets.d.ts +21 -0
  179. package/dist/types/components/tl-promo-code/tl-promo-code.d.ts +39 -0
  180. package/dist/types/components/tl-seat-map/tl-seat-map.d.ts +68 -0
  181. package/dist/types/components/tl-ticket/tl-ticket.d.ts +28 -0
  182. package/dist/types/components/tl-ticket-selector/tl-ticket-selector.d.ts +78 -0
  183. package/dist/types/components.d.ts +1629 -0
  184. package/dist/types/index.d.ts +14 -0
  185. package/dist/types/stencil-public-runtime.d.ts +1839 -0
  186. package/dist/types/utils/order-summary.d.ts +67 -0
  187. package/dist/types/utils/sdk-connector.d.ts +113 -0
  188. package/dist/types/utils/testing/mock-sdk.d.ts +36 -0
  189. package/elements.catalogue.json +968 -0
  190. package/loader/cdn.js +1 -0
  191. package/loader/index.cjs.js +1 -0
  192. package/loader/index.d.ts +24 -0
  193. package/loader/index.es2017.js +1 -0
  194. package/loader/index.js +2 -0
  195. package/package.json +101 -0
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ var sdkConnector = require('./sdk-connector-ClDF3013.js');
4
+ var tlBuyTicketsWrapper_entry = require('./tl-buy-tickets-wrapper.entry.cjs.js');
5
+ var tlCheckoutWrapper_entry = require('./tl-checkout-wrapper.entry.cjs.js');
6
+ require('./index-DfzcrE9-.js');
7
+
8
+
9
+
10
+ exports.getSDK = sdkConnector.getSDK;
11
+ exports.hasSDK = sdkConnector.hasSDK;
12
+ exports.onSDKEvent = sdkConnector.onSDKEvent;
13
+ exports.setSDK = sdkConnector.setSDK;
14
+ exports.whenSDK = sdkConnector.whenSDK;
15
+ exports.TlBuyTicketsWrapper = tlBuyTicketsWrapper_entry.tl_buy_tickets_wrapper;
16
+ exports.TlCheckoutWrapper = tlCheckoutWrapper_entry.tl_checkout_wrapper;
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-DfzcrE9-.js');
4
+
5
+ const defineCustomElements = async (win, options) => {
6
+ if (typeof window === 'undefined') return undefined;
7
+ await index.globalScripts();
8
+ return index.bootstrapLazy([["tl-my-orders.cjs",[[1,"tl-my-orders",{"emptyMessage":[1,"empty-message"],"columns":[2],"orders":[32],"authenticated":[32],"loading":[32],"error":[32],"expandedId":[32]}]]],["tl-buy-modal.cjs",[[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]}]]],["tl-order-confirmation.cjs",[[1,"tl-order-confirmation",{"orderId":[1,"order-id"],"customerEmail":[1,"customer-email"],"showTickets":[4,"show-tickets"],"columns":[2],"order":[32],"resolvedOrderId":[32],"loading":[32],"error":[32],"paymentFailed":[32],"occurrence":[32],"signedInCustomer":[32]},null,{"orderId":[{"watchOrderId":0}]}]]],["tl-cart-drawer.cjs",[[1,"tl-cart-drawer",{"side":[1],"heading":[1],"open":[1028],"visible":[32]},null,{"open":[{"onOpenProp":0}]}]]],["tl-event-list.cjs",[[1,"tl-event-list",{"limit":[2],"category":[1],"columns":[2],"events":[32],"loading":[32],"error":[32]},null,{"limit":[{"watchFiltersChange":0}],"category":[{"watchFiltersChange":0}]}]]],["tl-buy-tickets-button.cjs",[[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]}]]],["tl-buy-tickets-wrapper.cjs",[[260,"tl-buy-tickets-wrapper",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"disabled":[4]}]]],["tl-cart-badge.cjs",[[1,"tl-cart-badge",{"showEmpty":[4,"show-empty"],"icon":[1],"size":[1],"badgeOnly":[4,"badge-only"],"itemCount":[32]}]]],["tl-checkout-wrapper.cjs",[[260,"tl-checkout-wrapper",{"disabled":[4]}]]],["tl-promo-code.cjs",[[1,"tl-promo-code",{"placeholder":[1],"buttonLabel":[1,"button-label"],"code":[32],"applying":[32],"applied":[32],"error":[32]}]]],["tl-seat-map.cjs",[[1,"tl-seat-map",{"occurrenceId":[1,"occurrence-id"],"hboUrl":[1,"hbo-url"],"apiUrl":[1,"api-url"],"height":[1],"width":[1],"isReady":[32],"isLoading":[32],"error":[32],"seatsInCart":[32]},null,{"occurrenceId":[{"watchOccurrenceId":0}]}]]],["tl-cart.cjs",[[1,"tl-cart",{"showCheckoutButton":[4,"show-checkout-button"],"checkoutLabel":[1,"checkout-label"],"showRemoveButtons":[4,"show-remove-buttons"],"compact":[4],"cart":[32],"loading":[32],"error":[32],"removingItemId":[32]}]]],["tl-event-card.cjs",[[1,"tl-event-card",{"event":[16],"eventId":[1,"event-id"],"loadedEvent":[32],"loading":[32],"error":[32]},null,{"eventId":[{"watchEventId":0}]}]]],["tl-login.cjs",[[1,"tl-login",{"heading":[1],"allowCodeEntry":[4,"allow-code-entry"],"phase":[32],"email":[32],"code":[32],"busy":[32],"error":[32],"notice":[32],"customer":[32]}]]],["tl-occurrence-selector_2.cjs",[[1,"tl-occurrence-selector",{"eventId":[1,"event-id"],"displayMode":[1,"display-mode"],"orientation":[1],"theme":[16],"loading":[32],"error":[32],"occurrences":[32],"currentMonth":[32],"selectedDate":[32],"computedDisplayMode":[32],"containerWidth":[32]},null,{"eventId":[{"onEventIdChange":0}]}],[1,"tl-ticket-selector",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"showButton":[4,"show-button"],"buttonLabel":[1,"button-label"],"ticketTypes":[32],"quantities":[32],"loading":[32],"error":[32],"adding":[32],"addSuccess":[32]},null,{"eventId":[{"watchPropsChange":0}],"occurrenceId":[{"watchPropsChange":0}]}]]],["tl-order-tickets_2.cjs",[[1,"tl-order-tickets",{"orderId":[1,"order-id"],"columns":[2],"tickets":[32],"loading":[32],"error":[32]},null,{"orderId":[{"watchOrder":0}]}],[1,"tl-ticket",{"ticket":[16],"orderId":[1,"order-id"],"qrSvg":[32],"downloading":[32]},null,{"ticket":[{"generateQr":0}]}]]]], options);
9
+ };
10
+
11
+ exports.setNonce = index.setNonce;
12
+ exports.defineCustomElements = defineCustomElements;
@@ -0,0 +1,116 @@
1
+ 'use strict';
2
+
3
+ /** Money arrives as minor-unit integers or decimal strings ("50.00"). */
4
+ function formatPrice(value, currency = 'GBP') {
5
+ if (value === null || value === undefined || value === '')
6
+ return '';
7
+ const fmt = new Intl.NumberFormat('en-GB', { style: 'currency', currency });
8
+ if (typeof value === 'number')
9
+ return fmt.format(value / 100);
10
+ const n = Number(value);
11
+ return Number.isNaN(n) ? String(value) : fmt.format(n);
12
+ }
13
+ function formatDateTime(iso) {
14
+ return new Date(iso).toLocaleDateString('en-GB', {
15
+ weekday: 'short',
16
+ day: 'numeric',
17
+ month: 'short',
18
+ year: 'numeric',
19
+ hour: '2-digit',
20
+ minute: '2-digit',
21
+ });
22
+ }
23
+ function formatDate(iso) {
24
+ return new Date(iso).toLocaleDateString('en-GB', {
25
+ day: 'numeric',
26
+ month: 'short',
27
+ year: 'numeric',
28
+ });
29
+ }
30
+ /** Line items that are tickets (fees, taxes and discounts have their own type). */
31
+ function ticketItems(order) {
32
+ return (order.items ?? []).filter((i) => !i.type || i.type === 'ticket');
33
+ }
34
+ function ticketCount(order) {
35
+ const fromItems = ticketItems(order).reduce((sum, i) => sum + (Number(i.quantity) || 0), 0);
36
+ return fromItems || order.tickets?.length || 0;
37
+ }
38
+ /** Event name as the order view exposes it: the first ticket line's name. */
39
+ function orderEventName(order) {
40
+ return order.eventName || ticketItems(order)[0]?.name || order.items?.[0]?.name || null;
41
+ }
42
+ function orderCustomerEmail(order, customer) {
43
+ const fromOrder = order?.customerEmail || order?.customer?.email;
44
+ if (fromOrder)
45
+ return fromOrder;
46
+ const c = customer;
47
+ return c?.email || null;
48
+ }
49
+ function statusLabel(status) {
50
+ if (!status)
51
+ return '';
52
+ return status.replace(/_/g, ' ').replace(/^\w/, (m) => m.toUpperCase());
53
+ }
54
+ function statusTone(status) {
55
+ switch (status) {
56
+ case 'confirmed':
57
+ return 'success';
58
+ case 'completed':
59
+ case 'fulfilled':
60
+ return 'info';
61
+ case 'pending':
62
+ case 'processing':
63
+ return 'warning';
64
+ case 'cancelled':
65
+ case 'expired':
66
+ case 'failed':
67
+ return 'error';
68
+ default:
69
+ return 'muted';
70
+ }
71
+ }
72
+ function errorMessage(err, fallback) {
73
+ return err instanceof Error && err.message ? err.message : fallback;
74
+ }
75
+ /** True for the "not signed in" family of API errors (401/403, NO_SESSION, NOT_AUTHENTICATED). */
76
+ function isAuthError(err) {
77
+ const e = err;
78
+ if (!e || typeof e !== 'object')
79
+ return false;
80
+ return e.status === 401 || e.status === 403 || e.code === 'NO_SESSION' || e.code === 'NOT_AUTHENTICATED';
81
+ }
82
+ /**
83
+ * Find the event and start time for an occurrence id. The order view only
84
+ * carries the occurrence id, so this walks the channel's listings (cached by
85
+ * live-api) until one owns the occurrence. Best effort: null when not found.
86
+ */
87
+ async function resolveOccurrence(sdk, occurrenceId, maxEvents = 12) {
88
+ const events = sdk.getEventsManager();
89
+ const listing = await events.list({ limit: maxEvents });
90
+ const candidates = listing.items.slice(0, maxEvents);
91
+ for (const candidate of candidates) {
92
+ const detail = (await events.get(candidate.id).catch(() => null));
93
+ const occ = detail?.occurrences?.find((o) => o.id === occurrenceId);
94
+ if (occ) {
95
+ return {
96
+ eventId: detail?.id ?? candidate.id,
97
+ eventName: detail?.name ?? candidate.name ?? '',
98
+ startsAt: occ.startsAt ?? null,
99
+ };
100
+ }
101
+ }
102
+ return null;
103
+ }
104
+
105
+ exports.errorMessage = errorMessage;
106
+ exports.formatDate = formatDate;
107
+ exports.formatDateTime = formatDateTime;
108
+ exports.formatPrice = formatPrice;
109
+ exports.isAuthError = isAuthError;
110
+ exports.orderCustomerEmail = orderCustomerEmail;
111
+ exports.orderEventName = orderEventName;
112
+ exports.resolveOccurrence = resolveOccurrence;
113
+ exports.statusLabel = statusLabel;
114
+ exports.statusTone = statusTone;
115
+ exports.ticketCount = ticketCount;
116
+ exports.ticketItems = ticketItems;
@@ -0,0 +1,108 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * SDK Connector
5
+ *
6
+ * Utility to connect external SDK instances to Elements components.
7
+ */
8
+ // The SDK is shared between bundles via the `window.Ticketlayer` registry that
9
+ // @ticketlayer/live publishes (createLiveClient → publishClient). Elements never
10
+ // import the SDK; they read this global and bind to its connector view.
11
+ const READY_EVENT = 'ticketlayer:ready';
12
+ // Back-compat slot for hosts that install a connector manually via setSDK().
13
+ const MANUAL_SLOT = '__TICKETLAYER_SDK__';
14
+ function readGlobalSDK() {
15
+ if (typeof window === 'undefined')
16
+ return null;
17
+ const win = window;
18
+ const reg = win.Ticketlayer;
19
+ return (reg?.getSDK?.() ?? reg?.sdk ?? win[MANUAL_SLOT]) || null;
20
+ }
21
+ /**
22
+ * Manually install an SDK/connector instance (escape hatch). The normal path is
23
+ * for the host to call createLiveClient(), which auto-publishes on the registry.
24
+ */
25
+ function setSDK(sdk) {
26
+ if (typeof window === 'undefined')
27
+ return;
28
+ window[MANUAL_SLOT] = sdk;
29
+ // Wake any components already awaiting whenSDK().
30
+ window.dispatchEvent(new CustomEvent(READY_EVENT, { detail: sdk }));
31
+ }
32
+ /**
33
+ * Get the SDK instance synchronously. Throws if not yet available - prefer
34
+ * whenSDK() in lifecycle methods so mounting before Live is ready isn't an error.
35
+ */
36
+ function getSDK() {
37
+ const sdk = readGlobalSDK();
38
+ if (!sdk) {
39
+ throw new Error('[Ticketlayer Elements] SDK not ready. Create a Live client (createLiveClient) ' +
40
+ 'or await whenSDK() before using Elements.');
41
+ }
42
+ return sdk;
43
+ }
44
+ /** True if a client is currently registered. */
45
+ function hasSDK() {
46
+ return readGlobalSDK() !== null;
47
+ }
48
+ /**
49
+ * Resolve when the SDK is available - immediately if Live is already up, else
50
+ * on the `ticketlayer:ready` event. Replaces busy-wait polling in components.
51
+ */
52
+ function whenSDK(timeoutMs = 15000) {
53
+ const existing = readGlobalSDK();
54
+ if (existing)
55
+ return Promise.resolve(existing);
56
+ if (typeof window === 'undefined') {
57
+ return Promise.reject(new Error('[Ticketlayer Elements] No window; SDK unavailable.'));
58
+ }
59
+ return new Promise((resolve, reject) => {
60
+ let settled = false;
61
+ const finish = () => {
62
+ const sdk = readGlobalSDK();
63
+ if (sdk && !settled) {
64
+ settled = true;
65
+ cleanup();
66
+ resolve(sdk);
67
+ }
68
+ };
69
+ const cleanup = () => {
70
+ window.removeEventListener(READY_EVENT, finish);
71
+ clearTimeout(timer);
72
+ };
73
+ const timer = setTimeout(() => {
74
+ if (settled)
75
+ return;
76
+ settled = true;
77
+ cleanup();
78
+ reject(new Error('[Ticketlayer Elements] SDK not initialized. Create a Live client before using Elements.'));
79
+ }, timeoutMs);
80
+ window.addEventListener(READY_EVENT, finish);
81
+ // Late-publish race guard: re-check once listener is attached.
82
+ finish();
83
+ });
84
+ }
85
+ /**
86
+ * Subscribe to SDK events (waits for the SDK, returns an unsubscribe function).
87
+ */
88
+ function onSDKEvent(event, callback) {
89
+ let off = null;
90
+ let cancelled = false;
91
+ whenSDK()
92
+ .then((sdk) => {
93
+ if (cancelled)
94
+ return;
95
+ off = sdk.on(event, callback);
96
+ })
97
+ .catch(() => undefined);
98
+ return () => {
99
+ cancelled = true;
100
+ off?.();
101
+ };
102
+ }
103
+
104
+ exports.getSDK = getSDK;
105
+ exports.hasSDK = hasSDK;
106
+ exports.onSDKEvent = onSDKEvent;
107
+ exports.setSDK = setSDK;
108
+ exports.whenSDK = whenSDK;
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-DfzcrE9-.js');
4
+
5
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
6
+ /*
7
+ Stencil Client Patch Browser v4.41.1 | MIT Licensed | https://stenciljs.com
8
+ */
9
+
10
+ var patchBrowser = () => {
11
+ const importMeta = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('ticketlayer-elements.cjs.js', document.baseURI).href));
12
+ const opts = {};
13
+ if (importMeta !== "") {
14
+ opts.resourcesUrl = new URL(".", importMeta).href;
15
+ }
16
+ return index.promiseResolve(opts);
17
+ };
18
+
19
+ patchBrowser().then(async (options) => {
20
+ await index.globalScripts();
21
+ return index.bootstrapLazy([["tl-my-orders.cjs",[[1,"tl-my-orders",{"emptyMessage":[1,"empty-message"],"columns":[2],"orders":[32],"authenticated":[32],"loading":[32],"error":[32],"expandedId":[32]}]]],["tl-buy-modal.cjs",[[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]}]]],["tl-order-confirmation.cjs",[[1,"tl-order-confirmation",{"orderId":[1,"order-id"],"customerEmail":[1,"customer-email"],"showTickets":[4,"show-tickets"],"columns":[2],"order":[32],"resolvedOrderId":[32],"loading":[32],"error":[32],"paymentFailed":[32],"occurrence":[32],"signedInCustomer":[32]},null,{"orderId":[{"watchOrderId":0}]}]]],["tl-cart-drawer.cjs",[[1,"tl-cart-drawer",{"side":[1],"heading":[1],"open":[1028],"visible":[32]},null,{"open":[{"onOpenProp":0}]}]]],["tl-event-list.cjs",[[1,"tl-event-list",{"limit":[2],"category":[1],"columns":[2],"events":[32],"loading":[32],"error":[32]},null,{"limit":[{"watchFiltersChange":0}],"category":[{"watchFiltersChange":0}]}]]],["tl-buy-tickets-button.cjs",[[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]}]]],["tl-buy-tickets-wrapper.cjs",[[260,"tl-buy-tickets-wrapper",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"disabled":[4]}]]],["tl-cart-badge.cjs",[[1,"tl-cart-badge",{"showEmpty":[4,"show-empty"],"icon":[1],"size":[1],"badgeOnly":[4,"badge-only"],"itemCount":[32]}]]],["tl-checkout-wrapper.cjs",[[260,"tl-checkout-wrapper",{"disabled":[4]}]]],["tl-promo-code.cjs",[[1,"tl-promo-code",{"placeholder":[1],"buttonLabel":[1,"button-label"],"code":[32],"applying":[32],"applied":[32],"error":[32]}]]],["tl-seat-map.cjs",[[1,"tl-seat-map",{"occurrenceId":[1,"occurrence-id"],"hboUrl":[1,"hbo-url"],"apiUrl":[1,"api-url"],"height":[1],"width":[1],"isReady":[32],"isLoading":[32],"error":[32],"seatsInCart":[32]},null,{"occurrenceId":[{"watchOccurrenceId":0}]}]]],["tl-cart.cjs",[[1,"tl-cart",{"showCheckoutButton":[4,"show-checkout-button"],"checkoutLabel":[1,"checkout-label"],"showRemoveButtons":[4,"show-remove-buttons"],"compact":[4],"cart":[32],"loading":[32],"error":[32],"removingItemId":[32]}]]],["tl-event-card.cjs",[[1,"tl-event-card",{"event":[16],"eventId":[1,"event-id"],"loadedEvent":[32],"loading":[32],"error":[32]},null,{"eventId":[{"watchEventId":0}]}]]],["tl-login.cjs",[[1,"tl-login",{"heading":[1],"allowCodeEntry":[4,"allow-code-entry"],"phase":[32],"email":[32],"code":[32],"busy":[32],"error":[32],"notice":[32],"customer":[32]}]]],["tl-occurrence-selector_2.cjs",[[1,"tl-occurrence-selector",{"eventId":[1,"event-id"],"displayMode":[1,"display-mode"],"orientation":[1],"theme":[16],"loading":[32],"error":[32],"occurrences":[32],"currentMonth":[32],"selectedDate":[32],"computedDisplayMode":[32],"containerWidth":[32]},null,{"eventId":[{"onEventIdChange":0}]}],[1,"tl-ticket-selector",{"eventId":[1,"event-id"],"occurrenceId":[1,"occurrence-id"],"showButton":[4,"show-button"],"buttonLabel":[1,"button-label"],"ticketTypes":[32],"quantities":[32],"loading":[32],"error":[32],"adding":[32],"addSuccess":[32]},null,{"eventId":[{"watchPropsChange":0}],"occurrenceId":[{"watchPropsChange":0}]}]]],["tl-order-tickets_2.cjs",[[1,"tl-order-tickets",{"orderId":[1,"order-id"],"columns":[2],"tickets":[32],"loading":[32],"error":[32]},null,{"orderId":[{"watchOrder":0}]}],[1,"tl-ticket",{"ticket":[16],"orderId":[1,"order-id"],"qrSvg":[32],"downloading":[32]},null,{"ticket":[{"generateQr":0}]}]]]], options);
22
+ });
23
+
24
+ exports.setNonce = index.setNonce;
@@ -0,0 +1,127 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-DfzcrE9-.js');
4
+ var sdkConnector = require('./sdk-connector-ClDF3013.js');
5
+
6
+ const tlBuyModalCss = () => `: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;align-items:center;justify-content:center;padding:16px;background:rgba(8, 8, 16, 0.72);backdrop-filter:blur(4px);animation:tl-fade 0.18s ease-out}.panel{width:100%;max-width:460px;max-height:90vh;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}.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)}}`;
7
+
8
+ const TlBuyModal = class {
9
+ constructor(hostRef) {
10
+ index.registerInstance(this, hostRef);
11
+ this.tlClose = index.createEvent(this, "tlClose");
12
+ this.tlCheckout = index.createEvent(this, "tlCheckout");
13
+ this.tlError = index.createEvent(this, "tlError");
14
+ this.step = 'loading';
15
+ this.eventName = '';
16
+ this.imageUrl = '';
17
+ this.venueLabel = '';
18
+ this.dateSummary = '';
19
+ this.selectedOccurrenceId = null;
20
+ this.occurrenceCount = 0;
21
+ this.occurrenceLabel = '';
22
+ this.error = null;
23
+ this.handleOccurrenceSelect = (e) => {
24
+ const occ = e.detail.occurrence;
25
+ this.selectedOccurrenceId = occ.id;
26
+ this.occurrenceLabel = this.labelFor(occ);
27
+ this.step = 'tickets';
28
+ };
29
+ this.handleAdded = () => {
30
+ this.step = 'done';
31
+ };
32
+ this.backToDates = () => {
33
+ this.selectedOccurrenceId = null;
34
+ this.step = 'occurrence';
35
+ };
36
+ this.close = () => this.tlClose.emit();
37
+ this.goCheckout = () => this.tlCheckout.emit();
38
+ }
39
+ async componentWillLoad() {
40
+ if (!this.eventId) {
41
+ this.fail('No event specified');
42
+ return;
43
+ }
44
+ try {
45
+ await sdkConnector.whenSDK();
46
+ const ev = (await sdkConnector.getSDK().getEventsManager().get(this.eventId));
47
+ this.eventName = ev?.name ?? 'Tickets';
48
+ this.imageUrl = ev?.imageUrl || ev?.heroImageUrl || '';
49
+ this.venueLabel = [ev?.venueName, ev?.venueCity].filter(Boolean).join(', ');
50
+ const occs = ev?.occurrences ?? [];
51
+ this.occurrenceCount = occs.length;
52
+ this.dateSummary = this.summariseDates(occs);
53
+ // Skip the date step when one was preselected or there's only one date.
54
+ const initial = this.occurrenceId ?? (occs.length === 1 ? occs[0]?.id : null);
55
+ if (initial) {
56
+ this.selectedOccurrenceId = initial;
57
+ this.occurrenceLabel = this.labelFor(occs.find((o) => o.id === initial));
58
+ this.step = 'tickets';
59
+ }
60
+ else {
61
+ this.step = 'occurrence';
62
+ }
63
+ }
64
+ catch (err) {
65
+ this.fail(err instanceof Error ? err.message : 'Could not load this event');
66
+ }
67
+ }
68
+ fail(message) {
69
+ this.error = message;
70
+ this.step = 'error';
71
+ this.tlError.emit({ message });
72
+ }
73
+ /** A compact date line for the header: a single date, or a range across many. */
74
+ summariseDates(occs) {
75
+ const times = occs
76
+ .map((o) => o.startsAt)
77
+ .filter((s) => !!s)
78
+ .sort();
79
+ if (times.length === 0)
80
+ return '';
81
+ const day = (s) => new Date(s).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' });
82
+ if (times.length === 1) {
83
+ return new Date(times[0]).toLocaleDateString('en-GB', {
84
+ weekday: 'short',
85
+ day: 'numeric',
86
+ month: 'short',
87
+ year: 'numeric',
88
+ });
89
+ }
90
+ const first = day(times[0]);
91
+ const last = day(times[times.length - 1]);
92
+ const range = first === last ? first : `${first} – ${last}`;
93
+ return `${range} · ${times.length} dates`;
94
+ }
95
+ labelFor(occ) {
96
+ if (!occ?.startsAt)
97
+ return '';
98
+ return new Date(occ.startsAt).toLocaleString('en-GB', {
99
+ weekday: 'short',
100
+ day: 'numeric',
101
+ month: 'short',
102
+ hour: '2-digit',
103
+ minute: '2-digit',
104
+ });
105
+ }
106
+ stepKicker() {
107
+ switch (this.step) {
108
+ case 'occurrence':
109
+ return 'Choose a date';
110
+ case 'tickets':
111
+ return 'Select tickets';
112
+ case 'done':
113
+ return 'Nice one';
114
+ default:
115
+ return 'Tickets';
116
+ }
117
+ }
118
+ render() {
119
+ return (index.h(index.Host, { key: '1245e518c2b5232f4d9dba091cf808cd3867fbef' }, index.h("div", { key: '4e770fccdd785444f1cc87df4adab5a5dc1bf58a', class: "overlay", onClick: (e) => {
120
+ if (e.target === e.currentTarget)
121
+ this.close();
122
+ } }, index.h("div", { key: '57b13dac690028aeebd6a601acfba07f00854c40', class: { panel: true, 'panel--wide': this.step === 'occurrence' }, role: "dialog", "aria-modal": "true", "aria-label": this.eventName }, index.h("header", { key: '881e9cc70a0ca25947f272b9ebcb2e6d4b4268f2', class: "panel-header" }, this.imageUrl && (index.h("div", { key: '753f7df1b5118dfacbbc6b89b4e5d7ba114f6cdf', class: "event-thumb", style: { backgroundImage: `url(${this.imageUrl})` } })), index.h("div", { key: '9aaa32d1add90fabd1b0ea0c100f198962f4e6a5', class: "titles" }, index.h("span", { key: '538032bdf2338206ad763417386852ff97cc472f', class: "kicker" }, this.stepKicker()), index.h("h2", { key: '71429804179e7fbbea1fa90a2937a065517092f5', class: "event-name" }, this.eventName), this.venueLabel && index.h("p", { key: 'dd968b397deab890df3a4fbdff33226e82bd9660', class: "event-meta" }, this.venueLabel), this.dateSummary && index.h("p", { key: 'f40e6049d09b06c9f599e7d14d6fbb43b39b22fd', class: "event-meta" }, this.dateSummary)), index.h("button", { key: 'dbe0908f8cd8544654b627921f68cc4961802b77', class: "close-btn", "aria-label": "Close", onClick: this.close }, index.h("svg", { key: '23a750830e6e16d28cbcd5025507d25848aaadf7', viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("path", { key: 'e81b8763a5c781f72c1ca8a2113482948e3ba8cc', d: "M6 6l12 12M18 6L6 18", "stroke-linecap": "round" })))), index.h("div", { key: 'da71e610f907cf53e78246d2065aaf526d5ceffd', class: "panel-body" }, this.step === 'loading' && (index.h("div", { key: '28cbb9a98c7b08fa8dcb9d8d5dfbf3bec93fe38d', class: "state-msg" }, index.h("span", { key: '915c8de87cbdc7da1ccf0622ce6c0f02fccf2cad', class: "spinner" }), " Loading\u2026")), this.step === 'error' && index.h("div", { key: '5785578bfef6f1ee81d938d91ffd3ded975f8c12', class: "state-msg error" }, this.error), this.step === 'occurrence' && (index.h("tl-occurrence-selector", { key: 'eeb853eab141c3c103015e82d221a140f6a3a109', eventId: this.eventId, onTlSelect: this.handleOccurrenceSelect })), this.step === 'tickets' && this.selectedOccurrenceId && (index.h("div", { key: 'f608f592ba651eb431375433eb4ff9393863ade5', class: "tickets-step" }, this.occurrenceCount > 1 && (index.h("button", { key: '84adfbdbeaceb2cf4238c6ffd09558b4499ca940', class: "back-link", onClick: this.backToDates }, "\u2190 Change date")), this.occurrenceLabel && index.h("p", { key: '0317e9194049608711e8c622142c3ad2c0a5dc12', class: "occ-label" }, this.occurrenceLabel), index.h("tl-ticket-selector", { key: '27b1e05d9d92fb8d519375e2b27d4b5ea0a4890a', eventId: this.eventId, occurrenceId: this.selectedOccurrenceId, onTlAddToCart: this.handleAdded }))), this.step === 'done' && (index.h("div", { key: '0853088206988c66d489f8804df7899821d49e64', class: "done-step" }, index.h("div", { key: 'c2955b893c4dffaadcdfd27bee96ef2724a131a6', class: "done-mark" }, "\uD83C\uDF9F\uFE0F"), index.h("p", { key: '370c30dfcbc0c25b4794d984dd261a3a5779a9dc', class: "done-title" }, "Added to your cart"), index.h("p", { key: 'c462f3c9292740e2fd2c74b173484f80a5dc1a30', class: "done-sub" }, "Held for you while you check out."), index.h("button", { key: '484991f79572e3213ad6413a1af87599880c3643', class: "primary-btn", onClick: this.goCheckout }, "Go to checkout"), index.h("button", { key: '5b4ba5a472b794e8f5af0f131dad1c8c11b869f5', class: "ghost-btn", onClick: this.close }, "Keep browsing"))))))));
123
+ }
124
+ };
125
+ TlBuyModal.style = tlBuyModalCss();
126
+
127
+ exports.tl_buy_modal = TlBuyModal;
@@ -0,0 +1,131 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-DfzcrE9-.js');
4
+ var sdkConnector = require('./sdk-connector-ClDF3013.js');
5
+
6
+ const tlBuyTicketsButtonCss = () => `:host{display:inline-block;font-family:var(--tl-font-family, system-ui, -apple-system, sans-serif)}:host(.full-width){display:block;width:100%}:host(.full-width) .buy-button{width:100%}.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, 0.375rem)}.buy-button.size-md{padding:0.75rem 1.5rem;font-size:1rem;border-radius:var(--tl-radius-md, 0.5rem)}.buy-button.size-lg{padding:1rem 2rem;font-size:1.125rem;border-radius:var(--tl-radius-lg, 0.625rem);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}`;
7
+
8
+ // State configurations
9
+ const STATE_CONFIGS = {
10
+ available: {
11
+ defaultLabel: 'Buy Tickets',
12
+ color: 'var(--tl-primary, #e64b12)',
13
+ hoverColor: 'var(--tl-primary, #d4440f)',
14
+ foreground: 'var(--tl-primary-foreground, #ffffff)',
15
+ },
16
+ soldOut: {
17
+ defaultLabel: 'Sold Out',
18
+ color: '#dc2626',
19
+ hoverColor: '#b91c1c',
20
+ foreground: '#ffffff',
21
+ },
22
+ waitlist: {
23
+ defaultLabel: 'Join Waitlist',
24
+ color: '#2563eb',
25
+ hoverColor: '#1d4ed8',
26
+ foreground: '#ffffff',
27
+ },
28
+ comingSoon: {
29
+ defaultLabel: 'On Sale Soon',
30
+ color: '#d97706',
31
+ hoverColor: '#b45309',
32
+ foreground: '#ffffff',
33
+ },
34
+ };
35
+ const TlBuyTicketsButton = class {
36
+ constructor(hostRef) {
37
+ index.registerInstance(this, hostRef);
38
+ this.tlClick = index.createEvent(this, "tlClick");
39
+ /** Button state - determines colour, label, and icon */
40
+ this.state = 'available';
41
+ /** Button variant */
42
+ this.variant = 'primary';
43
+ /** Button size */
44
+ this.size = 'md';
45
+ /** Full width button */
46
+ this.fullWidth = false;
47
+ /** Currency code for price formatting */
48
+ this.currency = 'GBP';
49
+ /** Show price prefix text */
50
+ this.pricePrefix = 'From';
51
+ /** Disabled state */
52
+ this.disabled = false;
53
+ // -------------------------------------------------------------------------
54
+ // State
55
+ // -------------------------------------------------------------------------
56
+ this.isHovered = false;
57
+ // -------------------------------------------------------------------------
58
+ // Methods
59
+ // -------------------------------------------------------------------------
60
+ this.handleClick = () => {
61
+ // Check if button should be interactive
62
+ if (this.disabled || this.state === 'soldOut' || this.state === 'comingSoon') {
63
+ return;
64
+ }
65
+ // Emit click event
66
+ this.tlClick.emit({ eventId: this.eventId, occurrenceId: this.occurrenceId });
67
+ // Open modal via SDK if available
68
+ if (sdkConnector.hasSDK()) {
69
+ try {
70
+ const sdk = sdkConnector.getSDK();
71
+ sdk.event(this.eventId).openModal({
72
+ occurrenceId: this.occurrenceId,
73
+ });
74
+ }
75
+ catch (err) {
76
+ console.error('[tl-buy-tickets-button] Failed to open modal:', err);
77
+ }
78
+ }
79
+ };
80
+ }
81
+ formatPrice(priceInMinorUnits) {
82
+ const amount = priceInMinorUnits / 100;
83
+ const hasDecimals = amount % 1 !== 0;
84
+ return new Intl.NumberFormat('en-GB', {
85
+ style: 'currency',
86
+ currency: this.currency,
87
+ minimumFractionDigits: hasDecimals ? 2 : 0,
88
+ maximumFractionDigits: hasDecimals ? 2 : 0,
89
+ }).format(amount);
90
+ }
91
+ getStateConfig() {
92
+ return STATE_CONFIGS[this.state];
93
+ }
94
+ isInteractive() {
95
+ return !this.disabled && this.state !== 'soldOut' && this.state !== 'comingSoon';
96
+ }
97
+ // -------------------------------------------------------------------------
98
+ // Render
99
+ // -------------------------------------------------------------------------
100
+ render() {
101
+ const config = this.getStateConfig();
102
+ const buttonLabel = this.label || config.defaultLabel;
103
+ const isInteractive = this.isInteractive();
104
+ return (index.h(index.Host, { key: '10c8c36d12223afcfd13c9807c2ef6b0f4c34266', class: { 'full-width': this.fullWidth } }, index.h("button", { key: 'c7f6a39a837c90ced0176b5d017687afabf99a5a', type: "button", class: {
105
+ 'buy-button': true,
106
+ [`variant-${this.variant}`]: true,
107
+ [`size-${this.size}`]: true,
108
+ 'disabled': !isInteractive,
109
+ 'hovered': this.isHovered && isInteractive,
110
+ }, style: {
111
+ '--button-color': config.color,
112
+ '--button-hover-color': config.hoverColor,
113
+ '--button-foreground': config.foreground,
114
+ }, disabled: !isInteractive, onClick: this.handleClick, onMouseEnter: () => (this.isHovered = true), onMouseLeave: () => (this.isHovered = false) }, index.h("span", { key: 'e2bc1edc9fbd2a9c81da8cc3293170b1c4275125', class: "icon" }, this.state === 'soldOut' && this.renderSoldOutIcon(), this.state === 'waitlist' && this.renderWaitlistIcon(), this.state === 'comingSoon' && this.renderComingSoonIcon(), this.state === 'available' && this.renderTicketIcon()), index.h("span", { key: '8371c85dcc24c5ac040744edefe80618421025ef', class: "label" }, buttonLabel), this.price !== undefined && (index.h("span", { key: 'c02cb5b646ade8866deafb9b3e698115abec5708', class: "price" }, index.h("span", { key: 'cb0ab272460115a5edebd674362c83711735a70d', class: "price-prefix" }, this.pricePrefix), index.h("span", { key: 'e28ba56d3928076b624513de95682351f3e0d92b', class: "price-value" }, this.formatPrice(this.price)))))));
115
+ }
116
+ renderTicketIcon() {
117
+ return (index.h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, index.h("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" }), index.h("path", { d: "M13 5v2" }), index.h("path", { d: "M13 17v2" }), index.h("path", { d: "M13 11v2" })));
118
+ }
119
+ renderSoldOutIcon() {
120
+ return (index.h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, index.h("circle", { cx: "12", cy: "12", r: "10" }), index.h("path", { d: "m15 9-6 6" }), index.h("path", { d: "m9 9 6 6" })));
121
+ }
122
+ renderWaitlistIcon() {
123
+ return (index.h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, index.h("circle", { cx: "12", cy: "12", r: "10" }), index.h("polyline", { points: "12 6 12 12 16 14" })));
124
+ }
125
+ renderComingSoonIcon() {
126
+ return (index.h("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, index.h("path", { d: "M12 2v4" }), index.h("path", { d: "m16.2 7.8 2.9-2.9" }), index.h("path", { d: "M18 12h4" }), index.h("path", { d: "m16.2 16.2 2.9 2.9" }), index.h("path", { d: "M12 18v4" }), index.h("path", { d: "m4.9 19.1 2.9-2.9" }), index.h("path", { d: "M2 12h4" }), index.h("path", { d: "m4.9 4.9 2.9 2.9" })));
127
+ }
128
+ };
129
+ TlBuyTicketsButton.style = tlBuyTicketsButtonCss();
130
+
131
+ exports.tl_buy_tickets_button = TlBuyTicketsButton;
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-DfzcrE9-.js');
4
+ var sdkConnector = require('./sdk-connector-ClDF3013.js');
5
+
6
+ const tlBuyTicketsWrapperCss = () => `tl-buy-tickets-wrapper,.tl-buy-tickets-wrapper{display:inline-block;cursor:pointer}tl-buy-tickets-wrapper:focus,.tl-buy-tickets-wrapper:focus{outline:2px solid var(--tl-ring, #3b82f6);outline-offset:2px;border-radius:var(--tl-radius-sm, 0.25rem)}tl-buy-tickets-wrapper[disabled],tl-buy-tickets-wrapper.tl-buy-tickets-wrapper--disabled,.tl-buy-tickets-wrapper--disabled{cursor:not-allowed;opacity:0.5}`;
7
+
8
+ const TlBuyTicketsWrapper = class {
9
+ constructor(hostRef) {
10
+ index.registerInstance(this, hostRef);
11
+ this.tlComplete = index.createEvent(this, "tl-complete");
12
+ this.tlError = index.createEvent(this, "tl-error");
13
+ this.tlClose = index.createEvent(this, "tl-close");
14
+ /**
15
+ * Whether the wrapper is disabled
16
+ */
17
+ this.disabled = false;
18
+ this.handleClick = () => {
19
+ if (this.disabled)
20
+ return;
21
+ if (!sdkConnector.hasSDK()) {
22
+ console.error('[tl-buy-tickets-wrapper] SDK not initialized. Call setSDK(ticketlayer) first.');
23
+ this.tlError.emit({ message: 'SDK not initialized' });
24
+ return;
25
+ }
26
+ const sdk = sdkConnector.getSDK();
27
+ // Open the modal via SDK
28
+ sdk.event(this.eventId).openModal({
29
+ occurrenceId: this.occurrenceId,
30
+ onComplete: (order) => {
31
+ this.tlComplete.emit(order);
32
+ },
33
+ onError: (err) => {
34
+ this.tlError.emit({ message: err.message });
35
+ },
36
+ onClose: () => {
37
+ this.tlClose.emit();
38
+ },
39
+ });
40
+ };
41
+ this.handleKeyDown = (e) => {
42
+ if (e.key === 'Enter' || e.key === ' ') {
43
+ e.preventDefault();
44
+ this.handleClick();
45
+ }
46
+ };
47
+ }
48
+ render() {
49
+ return (index.h(index.Host, { key: 'd6ef81ac9bc1a1194eda1603cbb2a75b355a212e', class: {
50
+ 'tl-buy-tickets-wrapper': true,
51
+ 'tl-buy-tickets-wrapper--disabled': this.disabled,
52
+ }, onClick: this.handleClick, onKeyDown: this.handleKeyDown, role: "button", tabindex: this.disabled ? -1 : 0, "aria-disabled": this.disabled ? 'true' : null }, index.h("slot", { key: 'faef5aaad20deaf5e442d688c69105e45f9ee26f' })));
53
+ }
54
+ get el() { return index.getElement(this); }
55
+ };
56
+ TlBuyTicketsWrapper.style = tlBuyTicketsWrapperCss();
57
+
58
+ exports.tl_buy_tickets_wrapper = TlBuyTicketsWrapper;