@hellotext/hellotext 2.5.7 → 2.5.8

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 (102) hide show
  1. package/README.md +0 -25
  2. package/dist/hellotext.js +1 -1
  3. package/index.d.ts +0 -6
  4. package/lib/api/acks.cjs +17 -31
  5. package/lib/api/acks.js +17 -42
  6. package/lib/api/businesses.cjs +14 -28
  7. package/lib/api/businesses.js +13 -36
  8. package/lib/api/events.cjs +26 -40
  9. package/lib/api/events.js +28 -52
  10. package/lib/api/forms.cjs +24 -40
  11. package/lib/api/forms.js +24 -57
  12. package/lib/api/identifications.cjs +15 -29
  13. package/lib/api/identifications.js +15 -40
  14. package/lib/api/index.cjs +25 -51
  15. package/lib/api/index.js +27 -54
  16. package/lib/api/push/identities.cjs +30 -46
  17. package/lib/api/push/identities.js +30 -63
  18. package/lib/api/response.cjs +30 -52
  19. package/lib/api/response.js +31 -60
  20. package/lib/api/submissions.cjs +18 -34
  21. package/lib/api/submissions.js +18 -48
  22. package/lib/api/webchat/messages.cjs +44 -64
  23. package/lib/api/webchat/messages.js +44 -80
  24. package/lib/api/webchats.cjs +37 -56
  25. package/lib/api/webchats.js +37 -65
  26. package/lib/api/whatsapp_widgets.cjs +49 -72
  27. package/lib/api/whatsapp_widgets.js +48 -91
  28. package/lib/builders/input_builder.cjs +36 -48
  29. package/lib/builders/input_builder.js +36 -48
  30. package/lib/builders/logo_builder.cjs +10 -29
  31. package/lib/builders/logo_builder.js +20 -28
  32. package/lib/channels/application_channel.cjs +136 -178
  33. package/lib/channels/application_channel.js +137 -180
  34. package/lib/channels/webchat_channel.cjs +125 -170
  35. package/lib/channels/webchat_channel.js +125 -170
  36. package/lib/controllers/form_controller.cjs +82 -121
  37. package/lib/controllers/form_controller.js +82 -130
  38. package/lib/controllers/message_controller.cjs +211 -282
  39. package/lib/controllers/message_controller.js +209 -284
  40. package/lib/controllers/mixins/usePopover.cjs +3 -6
  41. package/lib/controllers/mixins/usePopover.js +17 -22
  42. package/lib/controllers/webchat/emoji_picker_controller.cjs +106 -150
  43. package/lib/controllers/webchat/emoji_picker_controller.js +105 -170
  44. package/lib/controllers/webchat/useBehaviour.js +5 -5
  45. package/lib/controllers/webchat/useOpeningSequence.js +6 -6
  46. package/lib/controllers/webchat/useTeaser.js +9 -9
  47. package/lib/controllers/webchat_controller.cjs +916 -1088
  48. package/lib/controllers/webchat_controller.js +926 -1152
  49. package/lib/core/configuration/forms.cjs +21 -35
  50. package/lib/core/configuration/forms.js +20 -35
  51. package/lib/core/configuration/locale.cjs +36 -71
  52. package/lib/core/configuration/locale.js +36 -70
  53. package/lib/core/configuration/push.cjs +9 -21
  54. package/lib/core/configuration/push.js +8 -20
  55. package/lib/core/configuration/webchat.cjs +142 -182
  56. package/lib/core/configuration/webchat.js +145 -189
  57. package/lib/core/configuration/whatsapp.cjs +76 -102
  58. package/lib/core/configuration/whatsapp.js +76 -105
  59. package/lib/core/configuration.cjs +60 -78
  60. package/lib/core/configuration.js +59 -78
  61. package/lib/core/event.cjs +36 -59
  62. package/lib/core/event.js +35 -61
  63. package/lib/core/sanitize_html.js +4 -4
  64. package/lib/errors/invalid_event.cjs +5 -26
  65. package/lib/errors/invalid_event.js +5 -26
  66. package/lib/errors/not_initialized_error.cjs +5 -26
  67. package/lib/errors/not_initialized_error.js +5 -26
  68. package/lib/hellotext.cjs +185 -223
  69. package/lib/hellotext.js +188 -247
  70. package/lib/index.js +1 -1
  71. package/lib/models/business.cjs +114 -152
  72. package/lib/models/business.js +117 -162
  73. package/lib/models/cookies.cjs +34 -51
  74. package/lib/models/cookies.js +34 -51
  75. package/lib/models/fingerprint.cjs +8 -23
  76. package/lib/models/fingerprint.js +25 -58
  77. package/lib/models/form.cjs +106 -142
  78. package/lib/models/form.js +105 -153
  79. package/lib/models/form_collection.cjs +63 -101
  80. package/lib/models/form_collection.js +61 -107
  81. package/lib/models/page.cjs +106 -129
  82. package/lib/models/page.js +106 -131
  83. package/lib/models/push.cjs +278 -322
  84. package/lib/models/push.js +284 -357
  85. package/lib/models/query.cjs +21 -41
  86. package/lib/models/query.js +21 -41
  87. package/lib/models/session.cjs +33 -65
  88. package/lib/models/session.js +30 -63
  89. package/lib/models/user.cjs +29 -51
  90. package/lib/models/user.js +29 -51
  91. package/lib/models/utm.cjs +15 -27
  92. package/lib/models/utm.js +17 -32
  93. package/lib/models/webchat.cjs +52 -76
  94. package/lib/models/webchat.js +52 -90
  95. package/lib/models/whatsapp_widget.cjs +41 -59
  96. package/lib/models/whatsapp_widget.js +41 -73
  97. package/lib/vanilla.cjs +4 -7
  98. package/lib/vanilla.js +2 -1
  99. package/package.json +1 -9
  100. package/src/index.bundle.js +0 -1
  101. package/src/vanilla.js +2 -1
  102. package/styles/index.css +0 -30
@@ -7,290 +7,219 @@ exports.default = void 0;
7
7
  var _stimulus = require("@hotwired/stimulus");
8
8
  var _hellotext = _interopRequireDefault(require("../hellotext"));
9
9
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
11
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
12
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
13
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
14
- function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
15
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
16
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
17
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
18
- function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
19
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
20
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
22
- let _default = /*#__PURE__*/function (_Controller) {
23
- _inherits(_default, _Controller);
24
- var _super = _createSuper(_default);
25
- function _default() {
26
- _classCallCheck(this, _default);
27
- return _super.apply(this, arguments);
10
+ class _default extends _stimulus.Controller {
11
+ static values = {
12
+ fadeDistance: {
13
+ type: Number,
14
+ default: 64
15
+ },
16
+ id: String,
17
+ kind: String,
18
+ pageStartOffset: {
19
+ type: Number,
20
+ default: 0
21
+ },
22
+ utm: Object
23
+ };
24
+ static targets = ['carouselContainer', 'leftFade', 'rightFade', 'carouselCard'];
25
+ connect() {
26
+ this.updateFades();
27
+ this.observeContainerSize();
28
28
  }
29
- _createClass(_default, [{
30
- key: "connect",
31
- value: function connect() {
32
- this.updateFades();
33
- this.observeContainerSize();
34
- }
35
- }, {
36
- key: "disconnect",
37
- value: function disconnect() {
38
- var _this$resizeObserver;
39
- (_this$resizeObserver = this.resizeObserver) === null || _this$resizeObserver === void 0 ? void 0 : _this$resizeObserver.disconnect();
40
- }
41
- }, {
42
- key: "setId",
43
- value: function setId({
44
- detail: id
45
- }) {
46
- this.idValue = id;
47
- this.element.id = id;
48
- }
49
- }, {
50
- key: "onScroll",
51
- value: function onScroll() {
52
- this.updateFades();
53
- }
54
- }, {
55
- key: "quickReply",
56
- value: function quickReply({
57
- currentTarget
58
- }) {
59
- const card = currentTarget.closest('[data-hellotext--message-target="carouselCard"]');
60
- const messageElement = currentTarget.closest('[data-controller~="hellotext--message"]');
61
- const body = currentTarget.dataset.text || currentTarget.textContent.trim();
62
- this.dispatch('quickReply', {
63
- detail: {
64
- id: this.idValue,
65
- product: card === null || card === void 0 ? void 0 : card.dataset.id,
66
- buttonId: currentTarget.dataset.id,
67
- body,
68
- cardElement: card || messageElement || currentTarget
69
- }
70
- });
71
- }
72
- }, {
73
- key: "addToCart",
74
- value: function addToCart({
75
- currentTarget
76
- }) {
77
- const card = currentTarget.closest('[data-hellotext--message-target="carouselCard"]');
78
- const {
79
- id,
80
- reference,
81
- source
82
- } = card.dataset;
83
- const item = {
84
- product: id,
85
- quantity: 1
86
- };
87
- if (this.hasUtmValue) _hellotext.default.page.utm.save(this.utmValue);
88
- _hellotext.default.eventEmitter.dispatch('cart.added', {
89
- object_parameters: {
90
- items: [{
91
- ...item,
92
- ...(reference && {
93
- reference
94
- }),
95
- ...(source && {
96
- source
97
- })
98
- }]
99
- },
100
- source: {
101
- kind: this.kindValue,
102
- message_id: this.idValue,
103
- button_id: currentTarget.dataset.id
104
- }
105
- });
106
- }
107
- }, {
108
- key: "moveToLeft",
109
- value: function moveToLeft() {
110
- if (!this.hasCarouselContainerTarget) return;
111
- const nextScrollLeft = this.getPreviousPageScrollLeft();
112
- const scrollAmount = this.carouselContainerTarget.scrollLeft - nextScrollLeft;
113
- if (scrollAmount < 1) return;
114
- this.carouselContainerTarget.scrollBy({
115
- left: -scrollAmount,
116
- behavior: 'smooth'
117
- });
118
- }
119
- }, {
120
- key: "moveToRight",
121
- value: function moveToRight() {
122
- if (!this.hasCarouselContainerTarget) return;
123
- const nextScrollLeft = this.getNextPageScrollLeft();
124
- const scrollAmount = nextScrollLeft - this.carouselContainerTarget.scrollLeft;
125
- if (scrollAmount < 1) return;
126
- this.carouselContainerTarget.scrollBy({
127
- left: scrollAmount,
128
- behavior: 'smooth'
129
- });
130
- }
131
- }, {
132
- key: "getScrollAmount",
133
- value: function getScrollAmount() {
134
- return this.getCardScrollAmount();
135
- }
136
- }, {
137
- key: "getCardScrollAmount",
138
- value: function getCardScrollAmount() {
139
- const firstCard = this.carouselContainerTarget.querySelector('.message__carousel_card');
140
- if (!firstCard) {
141
- return 280; // Fallback to default desktop card width
142
- }
143
-
144
- const cardWidth = firstCard.offsetWidth;
145
- return cardWidth + this.getGap();
146
- }
147
- }, {
148
- key: "getPageScrollAmount",
149
- value: function getPageScrollAmount() {
150
- const scrollAmount = this.carouselContainerTarget.clientWidth - this.getGap();
151
- return scrollAmount > 0 ? scrollAmount : this.getCardScrollAmount();
152
- }
153
- }, {
154
- key: "getNextPageScrollLeft",
155
- value: function getNextPageScrollLeft() {
156
- const currentScrollLeft = this.getCurrentScrollLeft();
157
- const viewportRight = currentScrollLeft + this.carouselContainerTarget.clientWidth;
158
- const cardMetrics = this.getCardMetrics();
159
- const nextCard = cardMetrics.find(card => card.end > viewportRight + 1);
160
- const targetScrollLeft = nextCard ? this.getPageAlignedScrollLeft(nextCard.start) : currentScrollLeft + this.getPageScrollAmount();
161
- const fallbackScrollLeft = currentScrollLeft + this.getPageScrollAmount();
162
- return this.clampScrollLeft(targetScrollLeft > currentScrollLeft + 1 ? targetScrollLeft : fallbackScrollLeft);
163
- }
164
- }, {
165
- key: "getPreviousPageScrollLeft",
166
- value: function getPreviousPageScrollLeft() {
167
- const currentScrollLeft = this.getCurrentScrollLeft();
168
- if (currentScrollLeft <= 1) return 0;
169
- const targetThreshold = Math.max(currentScrollLeft - this.getPageScrollAmount(), 0);
170
- if (targetThreshold <= 1) return 0;
171
- const cardMetrics = this.getCardMetrics();
172
- const previousPageCard = cardMetrics.find(card => card.start >= targetThreshold - 1 && card.start < currentScrollLeft - 1);
173
- const previousCard = [...cardMetrics].reverse().find(card => card.start < currentScrollLeft - 1);
174
- return this.getPageAlignedScrollLeft((previousPageCard === null || previousPageCard === void 0 ? void 0 : previousPageCard.start) ?? (previousCard === null || previousCard === void 0 ? void 0 : previousCard.start) ?? 0);
175
- }
176
- }, {
177
- key: "getPageAlignedScrollLeft",
178
- value: function getPageAlignedScrollLeft(cardStart) {
179
- const pageStartOffset = this.getPageStartOffset();
180
- if (cardStart <= pageStartOffset + 1) return 0;
181
- return this.clampScrollLeft(cardStart - pageStartOffset);
182
- }
183
- }, {
184
- key: "getCardMetrics",
185
- value: function getCardMetrics() {
186
- return Array.from(this.carouselContainerTarget.querySelectorAll('.message__carousel_card')).map(card => {
187
- const start = this.getCardScrollLeft(card);
188
- return {
189
- start,
190
- end: start + card.offsetWidth
191
- };
192
- });
193
- }
194
- }, {
195
- key: "getCardScrollLeft",
196
- value: function getCardScrollLeft(card) {
197
- const cardRect = card.getBoundingClientRect();
198
- const containerRect = this.carouselContainerTarget.getBoundingClientRect();
199
- if (cardRect.left || cardRect.width || containerRect.left || containerRect.width) {
200
- return cardRect.left - containerRect.left + this.carouselContainerTarget.scrollLeft;
201
- }
202
- return card.offsetLeft || 0;
203
- }
204
- }, {
205
- key: "getCurrentScrollLeft",
206
- value: function getCurrentScrollLeft() {
207
- return this.clampScrollLeft(this.carouselContainerTarget.scrollLeft);
208
- }
209
- }, {
210
- key: "clampScrollLeft",
211
- value: function clampScrollLeft(scrollLeft) {
212
- const maxScroll = Math.max(this.carouselContainerTarget.scrollWidth - this.carouselContainerTarget.clientWidth, 0);
213
- return Math.min(Math.max(scrollLeft, 0), maxScroll);
214
- }
215
- }, {
216
- key: "getGap",
217
- value: function getGap() {
218
- const styles = window.getComputedStyle(this.carouselContainerTarget);
219
- const gap = Number.parseFloat(styles.columnGap || styles.gap);
220
- return Number.isFinite(gap) ? gap : 16;
221
- }
222
- }, {
223
- key: "getFadeDistance",
224
- value: function getFadeDistance() {
225
- return Number.isFinite(this.fadeDistanceValue) ? this.fadeDistanceValue : 64;
226
- }
227
- }, {
228
- key: "getPageStartOffset",
229
- value: function getPageStartOffset() {
230
- return Number.isFinite(this.pageStartOffsetValue) ? this.pageStartOffsetValue : 0;
231
- }
232
- }, {
233
- key: "observeContainerSize",
234
- value: function observeContainerSize() {
235
- if (!this.hasCarouselContainerTarget || !window.ResizeObserver) return;
236
- this.resizeObserver = new ResizeObserver(() => this.updateFades());
237
- this.resizeObserver.observe(this.carouselContainerTarget);
238
- }
239
- }, {
240
- key: "updateFades",
241
- value: function updateFades() {
242
- if (!this.hasCarouselContainerTarget) return;
243
- const maxScroll = Math.max(this.carouselContainerTarget.scrollWidth - this.carouselContainerTarget.clientWidth, 0);
244
- if (maxScroll <= 1) {
245
- this.hideFade(this.leftFadeTarget);
246
- this.hideFade(this.rightFadeTarget);
247
- return;
29
+ disconnect() {
30
+ this.resizeObserver?.disconnect();
31
+ }
32
+ setId({
33
+ detail: id
34
+ }) {
35
+ this.idValue = id;
36
+ this.element.id = id;
37
+ }
38
+ onScroll() {
39
+ this.updateFades();
40
+ }
41
+ quickReply({
42
+ currentTarget
43
+ }) {
44
+ const card = currentTarget.closest('[data-hellotext--message-target="carouselCard"]');
45
+ const messageElement = currentTarget.closest('[data-controller~="hellotext--message"]');
46
+ const body = currentTarget.dataset.text || currentTarget.textContent.trim();
47
+ this.dispatch('quickReply', {
48
+ detail: {
49
+ id: this.idValue,
50
+ product: card?.dataset.id,
51
+ buttonId: currentTarget.dataset.id,
52
+ body,
53
+ cardElement: card || messageElement || currentTarget
248
54
  }
249
- const scrollLeft = Math.min(Math.max(this.carouselContainerTarget.scrollLeft, 0), maxScroll);
250
- const fadeDistance = this.getFadeDistance();
251
- this.setFadeOpacity(this.leftFadeTarget, scrollLeft / fadeDistance);
252
- this.setFadeOpacity(this.rightFadeTarget, (maxScroll - scrollLeft) / fadeDistance);
253
- }
254
- }, {
255
- key: "setFadeOpacity",
256
- value: function setFadeOpacity(fadeTarget, opacity) {
257
- const clampedOpacity = Math.min(Math.max(opacity, 0), 1);
258
- if (clampedOpacity <= 0.05) {
259
- this.hideFade(fadeTarget);
260
- return;
55
+ });
56
+ }
57
+ addToCart({
58
+ currentTarget
59
+ }) {
60
+ const card = currentTarget.closest('[data-hellotext--message-target="carouselCard"]');
61
+ const {
62
+ id,
63
+ reference,
64
+ source
65
+ } = card.dataset;
66
+ const item = {
67
+ product: id,
68
+ quantity: 1
69
+ };
70
+ if (this.hasUtmValue) _hellotext.default.page.utm.save(this.utmValue);
71
+ _hellotext.default.eventEmitter.dispatch('cart.added', {
72
+ object_parameters: {
73
+ items: [{
74
+ ...item,
75
+ ...(reference && {
76
+ reference
77
+ }),
78
+ ...(source && {
79
+ source
80
+ })
81
+ }]
82
+ },
83
+ source: {
84
+ kind: this.kindValue,
85
+ message_id: this.idValue,
86
+ button_id: currentTarget.dataset.id
261
87
  }
262
- fadeTarget.classList.remove('hidden');
263
- fadeTarget.removeAttribute('disabled');
264
- fadeTarget.removeAttribute('tabindex');
265
- fadeTarget.setAttribute('aria-hidden', 'false');
266
- fadeTarget.style.opacity = clampedOpacity.toFixed(3);
267
- fadeTarget.style.pointerEvents = 'auto';
88
+ });
89
+ }
90
+ moveToLeft() {
91
+ if (!this.hasCarouselContainerTarget) return;
92
+ const nextScrollLeft = this.getPreviousPageScrollLeft();
93
+ const scrollAmount = this.carouselContainerTarget.scrollLeft - nextScrollLeft;
94
+ if (scrollAmount < 1) return;
95
+ this.carouselContainerTarget.scrollBy({
96
+ left: -scrollAmount,
97
+ behavior: 'smooth'
98
+ });
99
+ }
100
+ moveToRight() {
101
+ if (!this.hasCarouselContainerTarget) return;
102
+ const nextScrollLeft = this.getNextPageScrollLeft();
103
+ const scrollAmount = nextScrollLeft - this.carouselContainerTarget.scrollLeft;
104
+ if (scrollAmount < 1) return;
105
+ this.carouselContainerTarget.scrollBy({
106
+ left: scrollAmount,
107
+ behavior: 'smooth'
108
+ });
109
+ }
110
+ getScrollAmount() {
111
+ return this.getCardScrollAmount();
112
+ }
113
+ getCardScrollAmount() {
114
+ const firstCard = this.carouselContainerTarget.querySelector('.message__carousel_card');
115
+ if (!firstCard) {
116
+ return 280; // Fallback to default desktop card width
268
117
  }
269
- }, {
270
- key: "hideFade",
271
- value: function hideFade(fadeTarget) {
272
- fadeTarget.style.opacity = '0';
273
- fadeTarget.style.pointerEvents = 'none';
274
- fadeTarget.setAttribute('aria-hidden', 'true');
275
- fadeTarget.setAttribute('tabindex', '-1');
276
- if ('disabled' in fadeTarget) fadeTarget.disabled = true;
277
- fadeTarget.classList.add('hidden');
118
+
119
+ const cardWidth = firstCard.offsetWidth;
120
+ return cardWidth + this.getGap();
121
+ }
122
+ getPageScrollAmount() {
123
+ const scrollAmount = this.carouselContainerTarget.clientWidth - this.getGap();
124
+ return scrollAmount > 0 ? scrollAmount : this.getCardScrollAmount();
125
+ }
126
+ getNextPageScrollLeft() {
127
+ const currentScrollLeft = this.getCurrentScrollLeft();
128
+ const viewportRight = currentScrollLeft + this.carouselContainerTarget.clientWidth;
129
+ const cardMetrics = this.getCardMetrics();
130
+ const nextCard = cardMetrics.find(card => card.end > viewportRight + 1);
131
+ const targetScrollLeft = nextCard ? this.getPageAlignedScrollLeft(nextCard.start) : currentScrollLeft + this.getPageScrollAmount();
132
+ const fallbackScrollLeft = currentScrollLeft + this.getPageScrollAmount();
133
+ return this.clampScrollLeft(targetScrollLeft > currentScrollLeft + 1 ? targetScrollLeft : fallbackScrollLeft);
134
+ }
135
+ getPreviousPageScrollLeft() {
136
+ const currentScrollLeft = this.getCurrentScrollLeft();
137
+ if (currentScrollLeft <= 1) return 0;
138
+ const targetThreshold = Math.max(currentScrollLeft - this.getPageScrollAmount(), 0);
139
+ if (targetThreshold <= 1) return 0;
140
+ const cardMetrics = this.getCardMetrics();
141
+ const previousPageCard = cardMetrics.find(card => card.start >= targetThreshold - 1 && card.start < currentScrollLeft - 1);
142
+ const previousCard = [...cardMetrics].reverse().find(card => card.start < currentScrollLeft - 1);
143
+ return this.getPageAlignedScrollLeft(previousPageCard?.start ?? previousCard?.start ?? 0);
144
+ }
145
+ getPageAlignedScrollLeft(cardStart) {
146
+ const pageStartOffset = this.getPageStartOffset();
147
+ if (cardStart <= pageStartOffset + 1) return 0;
148
+ return this.clampScrollLeft(cardStart - pageStartOffset);
149
+ }
150
+ getCardMetrics() {
151
+ return Array.from(this.carouselContainerTarget.querySelectorAll('.message__carousel_card')).map(card => {
152
+ const start = this.getCardScrollLeft(card);
153
+ return {
154
+ start,
155
+ end: start + card.offsetWidth
156
+ };
157
+ });
158
+ }
159
+ getCardScrollLeft(card) {
160
+ const cardRect = card.getBoundingClientRect();
161
+ const containerRect = this.carouselContainerTarget.getBoundingClientRect();
162
+ if (cardRect.left || cardRect.width || containerRect.left || containerRect.width) {
163
+ return cardRect.left - containerRect.left + this.carouselContainerTarget.scrollLeft;
278
164
  }
279
- }]);
280
- return _default;
281
- }(_stimulus.Controller);
282
- exports.default = _default;
283
- _default.values = {
284
- fadeDistance: {
285
- type: Number,
286
- default: 64
287
- },
288
- id: String,
289
- kind: String,
290
- pageStartOffset: {
291
- type: Number,
292
- default: 0
293
- },
294
- utm: Object
295
- };
296
- _default.targets = ['carouselContainer', 'leftFade', 'rightFade', 'carouselCard'];
165
+ return card.offsetLeft || 0;
166
+ }
167
+ getCurrentScrollLeft() {
168
+ return this.clampScrollLeft(this.carouselContainerTarget.scrollLeft);
169
+ }
170
+ clampScrollLeft(scrollLeft) {
171
+ const maxScroll = Math.max(this.carouselContainerTarget.scrollWidth - this.carouselContainerTarget.clientWidth, 0);
172
+ return Math.min(Math.max(scrollLeft, 0), maxScroll);
173
+ }
174
+ getGap() {
175
+ const styles = window.getComputedStyle(this.carouselContainerTarget);
176
+ const gap = Number.parseFloat(styles.columnGap || styles.gap);
177
+ return Number.isFinite(gap) ? gap : 16;
178
+ }
179
+ getFadeDistance() {
180
+ return Number.isFinite(this.fadeDistanceValue) ? this.fadeDistanceValue : 64;
181
+ }
182
+ getPageStartOffset() {
183
+ return Number.isFinite(this.pageStartOffsetValue) ? this.pageStartOffsetValue : 0;
184
+ }
185
+ observeContainerSize() {
186
+ if (!this.hasCarouselContainerTarget || !window.ResizeObserver) return;
187
+ this.resizeObserver = new ResizeObserver(() => this.updateFades());
188
+ this.resizeObserver.observe(this.carouselContainerTarget);
189
+ }
190
+ updateFades() {
191
+ if (!this.hasCarouselContainerTarget) return;
192
+ const maxScroll = Math.max(this.carouselContainerTarget.scrollWidth - this.carouselContainerTarget.clientWidth, 0);
193
+ if (maxScroll <= 1) {
194
+ this.hideFade(this.leftFadeTarget);
195
+ this.hideFade(this.rightFadeTarget);
196
+ return;
197
+ }
198
+ const scrollLeft = Math.min(Math.max(this.carouselContainerTarget.scrollLeft, 0), maxScroll);
199
+ const fadeDistance = this.getFadeDistance();
200
+ this.setFadeOpacity(this.leftFadeTarget, scrollLeft / fadeDistance);
201
+ this.setFadeOpacity(this.rightFadeTarget, (maxScroll - scrollLeft) / fadeDistance);
202
+ }
203
+ setFadeOpacity(fadeTarget, opacity) {
204
+ const clampedOpacity = Math.min(Math.max(opacity, 0), 1);
205
+ if (clampedOpacity <= 0.05) {
206
+ this.hideFade(fadeTarget);
207
+ return;
208
+ }
209
+ fadeTarget.classList.remove('hidden');
210
+ fadeTarget.removeAttribute('disabled');
211
+ fadeTarget.removeAttribute('tabindex');
212
+ fadeTarget.setAttribute('aria-hidden', 'false');
213
+ fadeTarget.style.opacity = clampedOpacity.toFixed(3);
214
+ fadeTarget.style.pointerEvents = 'auto';
215
+ }
216
+ hideFade(fadeTarget) {
217
+ fadeTarget.style.opacity = '0';
218
+ fadeTarget.style.pointerEvents = 'none';
219
+ fadeTarget.setAttribute('aria-hidden', 'true');
220
+ fadeTarget.setAttribute('tabindex', '-1');
221
+ if ('disabled' in fadeTarget) fadeTarget.disabled = true;
222
+ fadeTarget.classList.add('hidden');
223
+ }
224
+ }
225
+ exports.default = _default;