the-foxy-library 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.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/dist/components/index.d.ts +33 -0
  4. package/dist/components/iv-accordion.d.ts +11 -0
  5. package/dist/components/iv-banner.d.ts +11 -0
  6. package/dist/components/iv-button.d.ts +11 -0
  7. package/dist/components/iv-card.d.ts +11 -0
  8. package/dist/components/iv-carousel.d.ts +11 -0
  9. package/dist/components/iv-dynamic-products-carousel.d.ts +11 -0
  10. package/dist/components/iv-dynamic-products.d.ts +11 -0
  11. package/dist/components/iv-filters.d.ts +11 -0
  12. package/dist/components/iv-layout.d.ts +11 -0
  13. package/dist/components/iv-link.d.ts +11 -0
  14. package/dist/components/iv-modal.d.ts +11 -0
  15. package/dist/components/iv-predictive-search.d.ts +11 -0
  16. package/dist/components/iv-recently-viewed.d.ts +11 -0
  17. package/dist/components/iv-sidebar.d.ts +11 -0
  18. package/dist/components/iv-spinner.d.ts +11 -0
  19. package/dist/components/iv-suggest.d.ts +11 -0
  20. package/dist/components/iv-tabs.d.ts +11 -0
  21. package/dist/components/iv-toast-container.d.ts +11 -0
  22. package/dist/components/iv-toast.d.ts +11 -0
  23. package/dist/components/iv-wishlist-view.d.ts +11 -0
  24. package/dist/components/iv-wishlist.d.ts +11 -0
  25. package/dist/components/sw-in-grid-content.d.ts +11 -0
  26. package/dist/components/sw-size-guide.d.ts +11 -0
  27. package/dist/intravenous/factory-1QinX-o0.js +275 -0
  28. package/dist/intravenous/factory-1QinX-o0.js.map +1 -0
  29. package/dist/intravenous/factory-JClanx-E.js +596 -0
  30. package/dist/intravenous/factory-JClanx-E.js.map +1 -0
  31. package/dist/intravenous/factory-mrqy6XUM.js +36 -0
  32. package/dist/intravenous/factory-mrqy6XUM.js.map +1 -0
  33. package/dist/intravenous/index-Py50VI8u.js +4761 -0
  34. package/dist/intravenous/index-Py50VI8u.js.map +1 -0
  35. package/dist/intravenous/index.esm.js +17 -0
  36. package/dist/intravenous/index.esm.js.map +1 -0
  37. package/dist/intravenous/intravenous.esm.js +48 -0
  38. package/dist/intravenous/intravenous.esm.js.map +1 -0
  39. package/dist/intravenous/iv-accordion.entry.esm.js.map +1 -0
  40. package/dist/intravenous/iv-accordion.entry.js +35 -0
  41. package/dist/intravenous/iv-banner.entry.esm.js.map +1 -0
  42. package/dist/intravenous/iv-banner.entry.js +28 -0
  43. package/dist/intravenous/iv-button.entry.esm.js.map +1 -0
  44. package/dist/intravenous/iv-button.entry.js +40 -0
  45. package/dist/intravenous/iv-card.entry.esm.js.map +1 -0
  46. package/dist/intravenous/iv-card.entry.js +82 -0
  47. package/dist/intravenous/iv-carousel.entry.esm.js.map +1 -0
  48. package/dist/intravenous/iv-carousel.entry.js +16 -0
  49. package/dist/intravenous/iv-dynamic-products-carousel.entry.esm.js.map +1 -0
  50. package/dist/intravenous/iv-dynamic-products-carousel.entry.js +114 -0
  51. package/dist/intravenous/iv-dynamic-products.entry.esm.js.map +1 -0
  52. package/dist/intravenous/iv-dynamic-products.entry.js +97 -0
  53. package/dist/intravenous/iv-filters.entry.esm.js.map +1 -0
  54. package/dist/intravenous/iv-filters.entry.js +19 -0
  55. package/dist/intravenous/iv-layout.entry.esm.js.map +1 -0
  56. package/dist/intravenous/iv-layout.entry.js +60 -0
  57. package/dist/intravenous/iv-link.entry.esm.js.map +1 -0
  58. package/dist/intravenous/iv-link.entry.js +25 -0
  59. package/dist/intravenous/iv-modal.entry.esm.js.map +1 -0
  60. package/dist/intravenous/iv-modal.entry.js +19 -0
  61. package/dist/intravenous/iv-predictive-search.entry.esm.js.map +1 -0
  62. package/dist/intravenous/iv-predictive-search.entry.js +311 -0
  63. package/dist/intravenous/iv-recently-viewed.entry.esm.js.map +1 -0
  64. package/dist/intravenous/iv-recently-viewed.entry.js +101 -0
  65. package/dist/intravenous/iv-sidebar.entry.esm.js.map +1 -0
  66. package/dist/intravenous/iv-sidebar.entry.js +24 -0
  67. package/dist/intravenous/iv-spinner.entry.esm.js.map +1 -0
  68. package/dist/intravenous/iv-spinner.entry.js +19 -0
  69. package/dist/intravenous/iv-suggest.entry.esm.js.map +1 -0
  70. package/dist/intravenous/iv-suggest.entry.js +72 -0
  71. package/dist/intravenous/iv-tabs.entry.esm.js.map +1 -0
  72. package/dist/intravenous/iv-tabs.entry.js +22 -0
  73. package/dist/intravenous/iv-toast-container.entry.esm.js.map +1 -0
  74. package/dist/intravenous/iv-toast-container.entry.js +44 -0
  75. package/dist/intravenous/iv-toast.entry.esm.js.map +1 -0
  76. package/dist/intravenous/iv-toast.entry.js +23 -0
  77. package/dist/intravenous/iv-wishlist-view.entry.esm.js.map +1 -0
  78. package/dist/intravenous/iv-wishlist-view.entry.js +21 -0
  79. package/dist/intravenous/iv-wishlist.entry.esm.js.map +1 -0
  80. package/dist/intravenous/iv-wishlist.entry.js +73 -0
  81. package/dist/intravenous/loader.esm.js.map +1 -0
  82. package/dist/intravenous/sw-in-grid-content.entry.esm.js.map +1 -0
  83. package/dist/intravenous/sw-in-grid-content.entry.js +18 -0
  84. package/dist/intravenous/sw-size-guide.entry.esm.js.map +1 -0
  85. package/dist/intravenous/sw-size-guide.entry.js +111 -0
  86. package/dist/types/components/iv-accordion/iv-accordion.d.ts +12 -0
  87. package/dist/types/components/iv-banner/iv-banner.d.ts +7 -0
  88. package/dist/types/components/iv-button/iv-button.d.ts +12 -0
  89. package/dist/types/components/iv-card/iv-card.d.ts +15 -0
  90. package/dist/types/components/iv-carousel/iv-carousel.d.ts +3 -0
  91. package/dist/types/components/iv-dynamic-products/iv-dynamic-products.d.ts +26 -0
  92. package/dist/types/components/iv-dynamic-products-carousel/iv-dynamic-products-carousel.d.ts +29 -0
  93. package/dist/types/components/iv-filters/iv-filters.d.ts +3 -0
  94. package/dist/types/components/iv-layout/iv-layout.d.ts +12 -0
  95. package/dist/types/components/iv-link/iv-link.d.ts +9 -0
  96. package/dist/types/components/iv-modal/iv-modal.d.ts +3 -0
  97. package/dist/types/components/iv-predictive-search/iv-predictive-search.d.ts +44 -0
  98. package/dist/types/components/iv-recently-viewed/iv-recently-viewed.d.ts +17 -0
  99. package/dist/types/components/iv-sidebar/iv-sidebar.d.ts +5 -0
  100. package/dist/types/components/iv-spinner/iv-spinner.d.ts +4 -0
  101. package/dist/types/components/iv-suggest/iv-suggest.d.ts +21 -0
  102. package/dist/types/components/iv-tabs/iv-tabs.d.ts +7 -0
  103. package/dist/types/components/iv-toast/iv-toast.d.ts +7 -0
  104. package/dist/types/components/iv-toast-container/iv-toast-container.d.ts +8 -0
  105. package/dist/types/components/iv-wishlist/iv-wishlist.d.ts +16 -0
  106. package/dist/types/components/iv-wishlist-view/iv-wishlist-view.d.ts +3 -0
  107. package/dist/types/components/sw-in-grid-content/sw-in-grid-content.d.ts +3 -0
  108. package/dist/types/components/sw-size-guide/sw-size-guide.d.ts +14 -0
  109. package/dist/types/components.d.ts +943 -0
  110. package/dist/types/global/app.d.ts +1 -0
  111. package/dist/types/index.d.ts +11 -0
  112. package/dist/types/stencil-public-runtime.d.ts +1746 -0
  113. package/dist/types/utils/caching/factory.d.ts +72 -0
  114. package/dist/types/utils/config/factory.d.ts +2 -0
  115. package/dist/types/utils/error_handling/factory.d.ts +58 -0
  116. package/dist/types/utils/helpers/factory.d.ts +6 -0
  117. package/dist/types/utils/store/store.d.ts +21 -0
  118. package/dist/types/utils/storefront_api/factory.d.ts +22 -0
  119. package/dist/types/utils/utils.d.ts +1 -0
  120. package/loader/cdn.js +1 -0
  121. package/loader/index.cjs.js +1 -0
  122. package/loader/index.d.ts +24 -0
  123. package/loader/index.es2017.js +1 -0
  124. package/loader/index.js +2 -0
  125. package/package.json +54 -0
@@ -0,0 +1,311 @@
1
+ import { r as registerInstance, f as createEvent, d as state, h } from './index-Py50VI8u.js';
2
+ import { f as formatMoney, g as getCurrencySymbol } from './factory-mrqy6XUM.js';
3
+
4
+ const ivPredictiveSearchCss = ".iv-predictive-search{box-sizing:border-box;width:var(--iv-predictive-width, 100%);max-width:var(--iv-predictive-max-width, 100%);margin:var(--iv-predictive-margin, 0);padding:var(--iv-predictive-padding, 0);position:relative;background:var(--iv-predictive-background, transparent);border:var(--iv-predictive-border, none);border-radius:var(--iv-predictive-border-radius, 0);box-shadow:var(--iv-predictive-box-shadow, none);font-family:var(--iv-predictive-font-family, inherit);font-size:var(--iv-predictive-font-size, 1rem);color:var(--iv-predictive-text-color, inherit);transition:var(--iv-predictive-transition, box-shadow 0.2s ease, border-color 0.2s ease)}.iv-predictive-search-wrapper{box-sizing:border-box;padding:var(--iv-predictive-wrapper-padding, 0);display:var(--iv-predictive-wrapper-display, block);gap:var(--iv-predictive-wrapper-gap, 0.5rem)}.iv-predictive-search-wrapper.label-top .iv-predictive-search-label{display:block}.iv-predictive-search-wrapper.label-inline{display:flex;align-items:center;gap:var(--iv-predictive-inline-gap, 0.5rem)}.iv-predictive-search-label{margin:var(--iv-predictive-label-margin, 0 0 0.25rem 0);font-size:var(--iv-predictive-label-font-size, 1rem);font-weight:var(--iv-predictive-label-font-weight, 500);color:var(--iv-predictive-label-color, inherit);line-height:var(--iv-predictive-label-line-height, 1.2)}.iv-predictive-search-input{box-sizing:border-box;width:100%;background:var(--iv-predictive-input-background, transparent);color:var(--iv-predictive-input-color, inherit);border:var(--iv-predictive-input-border, 1px solid currentColor);border-radius:var(--iv-predictive-input-border-radius, 0);padding:var(--iv-predictive-input-padding, 0.5rem 0.75rem);font-size:var(--iv-predictive-input-font-size, inherit);line-height:var(--iv-predictive-input-line-height, 1.2);outline:none;transition:var(--iv-predictive-input-transition, border-color 0.2s ease, box-shadow 0.2s ease)}.iv-predictive-search-input:focus{border:var(--iv-predictive-input-focus-border, var(--iv-predictive-input-border, 1px solid currentColor));box-shadow:var(--iv-predictive-input-focus-shadow, 0 0 0 2px rgba(0, 0, 0, 0.15))}.iv-predictive-search-results{position:var(--iv-predictive-results-position, absolute);top:var(--iv-predictive-results-top, 100%);left:var(--iv-predictive-results-left, 0);right:var(--iv-predictive-results-right, 0);z-index:var(--iv-predictive-results-z-index, 10);margin:var(--iv-predictive-results-margin, 0.5rem 0 0 0);padding:var(--iv-predictive-results-padding, 0.5rem);background:var(--iv-predictive-results-background, var(--iv-predictive-background, transparent));border:var(--iv-predictive-results-border, var(--iv-predictive-border, none));border-radius:var(--iv-predictive-results-border-radius, var(--iv-predictive-border-radius, 0));box-shadow:var(--iv-predictive-results-box-shadow, var(--iv-predictive-box-shadow, none));box-sizing:border-box}.iv-predictive-search-prediction-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--iv-predictive-list-gap, 0.5rem)}.iv-predictive-search-prediction-item{background:var(--iv-predictive-item-background, transparent);border-radius:var(--iv-predictive-item-border-radius, 0);transition:var(--iv-predictive-item-transition, background 0.2s ease, color 0.2s ease)}.iv-predictive-search-prediction-item:hover{background:var(--iv-predictive-item-hover-background, var(--iv-predictive-item-background, transparent))}.iv-predictive-search-prediction-link{display:flex;align-items:center;text-decoration:none;color:var(--iv-predictive-link-color, inherit);padding:var(--iv-predictive-link-padding, 0.25rem 0.5rem);border-radius:var(--iv-predictive-link-border-radius, 0);gap:var(--iv-predictive-link-gap, 0.5rem);background:var(--iv-predictive-link-background, transparent);transition:var(--iv-predictive-link-transition, background 0.2s ease, color 0.2s ease)}.iv-predictive-search-prediction-link:hover{color:var(--iv-predictive-link-hover-color, var(--iv-predictive-link-color, inherit));background:var(--iv-predictive-link-hover-background, var(--iv-predictive-link-background, transparent))}.iv-predictive-search-prediction-link .prediction-image{width:var(--iv-predictive-image-width, 48px);height:var(--iv-predictive-image-height, 48px);object-fit:var(--iv-predictive-image-object-fit, cover);border-radius:var(--iv-predictive-image-border-radius, 0);background:var(--iv-predictive-image-background, transparent);border:var(--iv-predictive-image-border, none);flex:0 0 auto}.iv-predictive-search-prediction-link .prediction-part{font-size:var(--iv-predictive-part-font-size, 1rem);color:var(--iv-predictive-part-color, inherit);margin-right:var(--iv-predictive-part-margin-right, 0)}.iv-predictive-search-no-results{padding:var(--iv-predictive-no-results-padding, 0.5rem);font-size:var(--iv-predictive-no-results-font-size, 0.875rem);color:var(--iv-predictive-no-results-color, inherit);text-align:var(--iv-predictive-no-results-text-align, center);opacity:var(--iv-predictive-no-results-opacity, 0.8)}.iv-predictive-search-see-all{margin-top:var(--iv-predictive-see-all-margin-top, 0.75rem);text-align:var(--iv-predictive-see-all-text-align, right)}@media (prefers-reduced-motion: reduce){.iv-predictive-search,.iv-predictive-search-input,.iv-predictive-search-prediction-item,.iv-predictive-search-prediction-link{transition:none}}";
5
+
6
+ const ALLOWED_FIELDS = [
7
+ 'featured_image', 'image', 'title', 'price', 'price_formatted', 'currency', 'description', 'vendor', 'url',
8
+ 'id', 'handle', 'author', 'published_at', 'product_type', 'type', 'tags'
9
+ ];
10
+ const ALLOWED_RESOURCES = ['page', 'collection', 'product', 'article'];
11
+ const FIELD_ALIASES = {
12
+ type: 'product_type',
13
+ img: 'image'
14
+ };
15
+ const BLOCK = 'iv-predictive-search';
16
+ const IvPredictiveSearch = class {
17
+ constructor(hostRef) {
18
+ registerInstance(this, hostRef);
19
+ this.searchTermsChanged = createEvent(this, "searchTermsChanged", 7);
20
+ }
21
+ searchlabel;
22
+ labelposition = 'top';
23
+ action;
24
+ method = 'get';
25
+ placeholder;
26
+ minchars = 3;
27
+ debounce = 300;
28
+ resultslimit = 5;
29
+ showspinner;
30
+ noresultstext = 'No results found';
31
+ requestedfields = 'title';
32
+ requestedresources = 'product,article,page,collection';
33
+ showallbuttontext;
34
+ querybuttontext;
35
+ clearbutton;
36
+ expandable = false;
37
+ tablayout;
38
+ gridlayout;
39
+ searchTerm;
40
+ searchReturnData = [];
41
+ noResults = false;
42
+ searchTermsChanged;
43
+ // Internals
44
+ debounceTimer;
45
+ abortController;
46
+ cache = new Map();
47
+ // Helpers
48
+ normalizeAction(a) {
49
+ return (a && a.trim() ? a : '/search').replace(/\/+$/, '');
50
+ }
51
+ ;
52
+ parseRequestedFields() {
53
+ const raw = (this.requestedfields || '')
54
+ .split(',')
55
+ .map(s => s.trim())
56
+ .filter(Boolean)
57
+ .map(f => FIELD_ALIASES[f] || f);
58
+ const fields = Array.from(new Set(raw.filter(f => ALLOWED_FIELDS.includes(f))));
59
+ if (!fields.includes('resource'))
60
+ fields.push('resource');
61
+ return fields;
62
+ }
63
+ ;
64
+ normalizeImageUrl(src) {
65
+ const s = typeof src === 'string' ? src : (src?.url || src?.src || undefined);
66
+ if (!s)
67
+ return undefined;
68
+ return s.startsWith('//') ? `https:${s}` : s;
69
+ }
70
+ ;
71
+ // Getters
72
+ get hasRenderableResults() {
73
+ return !!this.searchTerm && this.searchTerm.length >= this.minchars && this.searchReturnData.length > 0;
74
+ }
75
+ ;
76
+ get resultsListId() {
77
+ return `${BLOCK}-results`;
78
+ }
79
+ ;
80
+ get tabLabels() {
81
+ const resources = Array.from(new Set(this.searchReturnData.map(item => item.resource)));
82
+ return resources;
83
+ }
84
+ ;
85
+ get useGridLayout() {
86
+ return !!this.gridlayout;
87
+ }
88
+ ;
89
+ get gridTemplateAreas() {
90
+ return this.gridlayout
91
+ ? this.gridlayout.split(',').map(row => `"${row.trim()}"`).join(' ')
92
+ : '';
93
+ }
94
+ ;
95
+ get gridAreaNames() {
96
+ return Array.from(new Set(this.searchReturnData.map(item => item.resource)));
97
+ }
98
+ ;
99
+ // Methods
100
+ confirmRequestedResources() {
101
+ const resources = this.requestedresources
102
+ .split(',')
103
+ .map(r => r.trim())
104
+ .filter(Boolean)
105
+ .filter(r => ALLOWED_RESOURCES.includes(r));
106
+ if (resources.length === 0) {
107
+ console.warn('No valid resources specified, defaulting to "product,article,page,collection"');
108
+ return 'product,article,page,collection';
109
+ }
110
+ ;
111
+ return resources.join(',');
112
+ }
113
+ ;
114
+ async fetchPredictive(term) {
115
+ const trimmed = term.trim();
116
+ if (!trimmed || trimmed.length < this.minchars) {
117
+ this.searchReturnData = [];
118
+ this.noResults = false;
119
+ return;
120
+ }
121
+ ;
122
+ if (this.cache.has(trimmed)) {
123
+ this.searchReturnData = this.cache.get(trimmed);
124
+ this.noResults = (this.searchReturnData?.length ?? 0) === 0;
125
+ return;
126
+ }
127
+ ;
128
+ if (this.abortController)
129
+ this.abortController.abort();
130
+ this.abortController = new AbortController();
131
+ const base = this.normalizeAction(this.action);
132
+ const params = new URLSearchParams();
133
+ params.set('q', trimmed);
134
+ params.set('resources[type]', this.confirmRequestedResources());
135
+ params.set('resources[limit]', String(this.resultslimit));
136
+ const url = `${base}/suggest.json?${params.toString()}`;
137
+ state.loading = true;
138
+ try {
139
+ const res = await fetch(url, {
140
+ method: 'GET',
141
+ headers: {
142
+ Accept: 'application/json',
143
+ 'X-Requested-With': 'XMLHttpRequest',
144
+ 'Cache-Control': 'no-store',
145
+ },
146
+ cache: 'no-store',
147
+ signal: this.abortController.signal,
148
+ });
149
+ if (!res.ok)
150
+ throw new Error(`${res.status}: ${res.statusText}`);
151
+ const json = await res.json();
152
+ const normalized = this.normalizeShopifyResponse(json);
153
+ this.searchReturnData = normalized;
154
+ this.noResults = normalized.length === 0;
155
+ this.cache.set(trimmed, normalized);
156
+ }
157
+ catch (err) {
158
+ if (err?.name !== 'AbortError') {
159
+ console.error('Predictive search error:', err);
160
+ this.searchReturnData = [];
161
+ this.noResults = false;
162
+ }
163
+ ;
164
+ }
165
+ finally {
166
+ state.loading = false;
167
+ this.searchTermsChanged.emit(trimmed);
168
+ }
169
+ ;
170
+ }
171
+ ;
172
+ normalizeShopifyResponse(payload) {
173
+ const out = [];
174
+ const buckets = payload?.resources?.results ??
175
+ payload?.resources ??
176
+ {};
177
+ const mapType = (key) => key === 'products' ? 'product' :
178
+ key === 'collections' ? 'collection' :
179
+ key === 'articles' ? 'article' :
180
+ key === 'pages' ? 'page' : key;
181
+ const pushItems = (items, typeKey) => {
182
+ const resource = mapType(typeKey);
183
+ items.forEach(item => out.push(this.pickFieldsByResource(item, resource)));
184
+ };
185
+ ['products', 'collections', 'articles', 'pages'].forEach(typeKey => {
186
+ const list = buckets?.[typeKey] || [];
187
+ if (Array.isArray(list))
188
+ pushItems(list, typeKey);
189
+ });
190
+ return out;
191
+ }
192
+ ;
193
+ pickFieldsByResource(item, resource) {
194
+ const url = item?.url || item?.online_store_url || item?.path || '';
195
+ const handle = item?.handle || '';
196
+ const id = item?.id ?? item?.legacyResourceId ?? item?.legacy_resource_id ?? undefined;
197
+ const title = item?.title || item?.name || item?.page_title || '';
198
+ const description = item?.body ||
199
+ item?.body_html ||
200
+ item?.excerpt ||
201
+ item?.description ||
202
+ '';
203
+ const vendor = item?.vendor || item?.author || '';
204
+ const author = item?.author || '';
205
+ const published_at = item?.published_at || item?.created_at || '';
206
+ const product_type = item?.product_type || item?.type || '';
207
+ const image = this.normalizeImageUrl(item?.featured_image?.url ?? item?.featured_image) ||
208
+ this.normalizeImageUrl(item?.image?.url ?? item?.image?.src ?? item?.image) ||
209
+ this.normalizeImageUrl(Array.isArray(item?.images) ? item.images[0] : undefined);
210
+ const image_alt = (typeof item?.featured_image === 'object' && (item?.featured_image?.alt || item?.featured_image?.altText)) ||
211
+ (typeof item?.image === 'object' && (item?.image?.alt || item?.image?.altText)) ||
212
+ (Array.isArray(item?.images) && typeof item.images[0] === 'object' && (item.images[0]?.alt || item.images[0]?.altText)) ||
213
+ title || '';
214
+ const price = item?.price_min?.toString?.() ||
215
+ item?.price?.toString?.() ||
216
+ (Array.isArray(item?.variants) ? item.variants[0]?.price?.toString?.() : undefined);
217
+ const price_formatted = price ? formatMoney(Number(price), state.currencyCode) : undefined;
218
+ const normalized = {
219
+ resource, url, id, handle, title, image, featured_image: image, image_alt, price, description,
220
+ vendor, author, published_at, product_type,
221
+ tags: item?.tags || [],
222
+ currency: getCurrencySymbol(state.currencyCode),
223
+ price_formatted,
224
+ };
225
+ const requested = this.parseRequestedFields();
226
+ const renderable = requested
227
+ .map(f => (f === 'type' ? 'product_type' : f))
228
+ .filter(Boolean);
229
+ if (!renderable.includes('resource'))
230
+ renderable.push('resource');
231
+ if (!renderable.includes('url'))
232
+ renderable.push('url');
233
+ const result = {};
234
+ for (const key of renderable) {
235
+ if (normalized[key] !== undefined && normalized[key] !== null && normalized[key] !== '') {
236
+ result[key] = normalized[key];
237
+ }
238
+ ;
239
+ }
240
+ ;
241
+ if (normalized.image_alt)
242
+ result.image_alt = normalized.image_alt;
243
+ if (normalized.price) {
244
+ result.price_formatted = normalized.price_formatted ?? formatMoney(Number(normalized.price), state.currencyCode);
245
+ if (normalized.currency)
246
+ result.currency = normalized.currency;
247
+ }
248
+ ;
249
+ return result;
250
+ }
251
+ ;
252
+ handleSearchInput = (event) => {
253
+ const value = event.target.value || '';
254
+ this.searchTerm = value;
255
+ if (this.querybuttontext)
256
+ return;
257
+ clearTimeout(this.debounceTimer);
258
+ this.debounceTimer = setTimeout(() => {
259
+ this.fetchPredictive(value);
260
+ }, this.debounce);
261
+ };
262
+ handleSearchSubmit = (event) => {
263
+ event.preventDefault();
264
+ this.fetchPredictive(this.searchTerm);
265
+ };
266
+ renderResults(groupBy) {
267
+ if (!this.searchTerm || this.searchTerm.length < this.minchars)
268
+ return null;
269
+ return (h(h.Fragment, null, h("div", { class: "results-group-title" }, h("span", { class: "tertiary-title" }, groupBy)), h("ul", { id: this.resultsListId, class: `${BLOCK}-prediction-list`, role: "listbox" }, this.searchReturnData.map((result, idx) => (result.resource === groupBy && result.url && (h("li", { key: idx, class: `${BLOCK}-prediction-item`, role: "option" }, h("a", { class: `${BLOCK}-prediction-link`, href: result.url }, this.parseRequestedFields()
270
+ .filter(f => f !== 'resource' && f !== 'url')
271
+ .filter(field => field === 'image' || field === 'featured_image')
272
+ .map((field, fIdx) => {
273
+ const val = result[field];
274
+ if (val === undefined || val === null || val === '')
275
+ return null;
276
+ return h("img", { key: fIdx, class: "prediction-image", src: val, alt: result.image_alt || result.title || '' });
277
+ }), h("div", { class: `${BLOCK}-prediction-details` }, this.parseRequestedFields()
278
+ .filter(f => f !== 'resource' && f !== 'url')
279
+ .filter(field => field !== 'image' && field !== 'featured_image')
280
+ .map((field, fIdx) => {
281
+ const key = field === 'type' ? 'product_type' : field;
282
+ const val = result[key];
283
+ if (val === undefined || val === null || val === '')
284
+ return null;
285
+ if (key === 'price') {
286
+ const display = result.price_formatted ?? formatMoney(Number(val), state.currencyCode);
287
+ return h("span", { key: fIdx, class: `prediction-part prediction-${key}-span` }, display);
288
+ }
289
+ return h("span", { key: fIdx, class: `prediction-part prediction-${key}-span` }, val);
290
+ }))))))))));
291
+ }
292
+ ;
293
+ render() {
294
+ const hasResults = this.hasRenderableResults;
295
+ const base = this.normalizeAction(this.action);
296
+ const seeAllHref = `${base}?q=${encodeURIComponent(this.searchTerm || '')}`;
297
+ const shouldShowPanel = !!this.searchTerm && this.searchTerm.length >= this.minchars;
298
+ return (h("form", { key: '53a13e5cfeed19974906cddb3375d031906d5884', class: `${BLOCK}${this.expandable ? ' expandable' : ''}`, action: this.action, method: this.method, role: "search", onSubmit: this.handleSearchSubmit }, h("div", { key: '449f9cca8b63c6b7dfd506bf8e95c940c1137d44', class: `${BLOCK}-wrapper ${this.labelposition ? `label-${this.labelposition}` : ''}` }, this.searchlabel && (h("label", { key: '5d381e7e8d6c6677043eadc8a7de784dd1abc32b', class: `${BLOCK}-label`, htmlFor: "Search" }, this.searchlabel)), h("input", { key: '0ec212ebc3d235347ba6d2b5419e80ff76b5d5a4', id: "Search", class: `${BLOCK}-input`, type: "search", name: "q", value: this.searchTerm, onInput: this.handleSearchInput, role: "combobox", "aria-expanded": hasResults ? 'true' : 'false', "aria-owns": this.resultsListId, "aria-controls": this.resultsListId, "aria-haspopup": "listbox", "aria-autocomplete": "list", placeholder: this.placeholder }), this.querybuttontext && (h("iv-button", { key: 'f4265c04e21f321ed1ad01e61ca8f906b9ee0341', classmodifier: `${BLOCK}-submit`, type: "submit" }, h("span", { key: '6d38be0b4a07d79113f067e5c4e03a7688e69992', class: "inner-button", innerHTML: this.querybuttontext }))), this.clearbutton && (h("iv-button", { key: '2835f3512397af393663144f337709a29a80953a', classmodifier: `${BLOCK}-clear`, type: "button", onClick: () => {
299
+ this.searchTerm = '';
300
+ this.searchReturnData = [];
301
+ this.noResults = false;
302
+ this.searchTermsChanged.emit('');
303
+ } }, h("span", { key: 'e864cb7292ede8ae61d1c77943d2d55c3062c042', class: "inner-button", innerHTML: this.clearbutton })))), this.showspinner && h("iv-spinner", { key: 'c1457577e43f21d3c7b7dad4276f32b2be87dbfc', show: this.showspinner && state.loading }), h("div", { key: '17fc4685cd3ac323cc00065a1202870214413612', class: `${BLOCK}-results` }, shouldShowPanel && (this.searchReturnData.length > 0 ? (this.useGridLayout ? (h("iv-layout", { gridTemplateAreas: this.gridTemplateAreas, classModifier: BLOCK }, this.gridAreaNames.map(resource => (h("div", { slot: resource }, this.renderResults(resource)))))) : (h("iv-tabs", { classModifier: BLOCK, labels: this.tabLabels, tabLayout: this.tablayout }, this.tabLabels.map((label, index) => (h("div", { slot: `tab-content-${index}` }, this.renderResults(label))))))) : this.noResults && !state.loading ? (h("div", { class: `${BLOCK}-no-results` }, h("p", null, this.noresultstext))) : null)), this.showallbuttontext && hasResults && (h("div", { key: '106b9ee651fb58d7c9050101ad8c27b9d2a7f269', class: `${BLOCK}-see-all` }, h("a", { key: 'b860ba8c0e3e4e6b2402dc591181876acae69765', class: "btn btn-link", href: seeAllHref }, this.showallbuttontext)))));
304
+ }
305
+ ;
306
+ };
307
+ ;
308
+ IvPredictiveSearch.style = ivPredictiveSearchCss;
309
+
310
+ export { IvPredictiveSearch as iv_predictive_search };
311
+ //# sourceMappingURL=iv-predictive-search.entry.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iv-recently-viewed.entry.esm.js","sources":["src/components/iv-recently-viewed/iv-recently-viewed.scss?tag=iv-recently-viewed","src/components/iv-recently-viewed/iv-recently-viewed.tsx"],"sourcesContent":["// Base styles for iv-recently-viewed\n// All customizable values use the --iv-recently-viewed-* variable naming pattern with safe fallbacks.\n// Example override: .theme-dark { --iv-recently-viewed-background: #111; }\n\n.iv-recently-viewed {\n background: var(--iv-recently-viewed-background, none);\n padding: var(--iv-recently-viewed-padding, 1rem 0);\n margin: var(--iv-recently-viewed-margin, 0);\n border: var(--iv-recently-viewed-border, none);\n border-radius: var(--iv-recently-viewed-radius, 0);\n position: relative;\n box-sizing: border-box;\n width: 100%;\n display: block;\n}\n\n.iv-recently-viewed-title {\n margin: var(--iv-recently-viewed-title-margin, 0 0 0.75rem);\n font-size: var(--iv-recently-viewed-title-font-size, 1.25rem);\n line-height: var(--iv-recently-viewed-title-line-height, 1.2);\n font-weight: var(--iv-recently-viewed-title-weight, 600);\n color: var(--iv-recently-viewed-title-color, inherit);\n}\n\n.iv-recently-viewed__list,\n.iv-recently-viewed__items {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.iv-recently-viewed iv-layout,\n.iv-recently-viewed .iv-layout {\n --gap: var(--iv-recently-viewed-gap, 1rem);\n gap: var(--iv-recently-viewed-gap, 1rem);\n}\n\n.iv-recently-viewed iv-card,\n.iv-recently-viewed .iv-card {\n max-width: var(--iv-recently-viewed-card-max-width, 260px);\n width: 100%;\n}\n\n.iv-recently-viewed-no-history,\n.iv-recently-viewed__no-history,\n.iv-recently-viewed-no-history-message {\n font-size: var(--iv-recently-viewed-no-history-font-size, 0.875rem);\n color: var(--iv-recently-viewed-no-history-color, #666);\n padding: var(--iv-recently-viewed-no-history-padding, 0.5rem 0);\n}\n\n// Spacing utilities between internal blocks\n.iv-recently-viewed > * + * {\n margin-top: var(--iv-recently-viewed-stack-gap, 1rem);\n}\n\n@media (min-width: 640px) {\n .iv-recently-viewed {\n padding: var(--iv-recently-viewed-padding-md, var(--iv-recently-viewed-padding, 1.25rem 0));\n }\n .iv-recently-viewed-title {\n font-size: var(--iv-recently-viewed-title-font-size-md, 1.375rem);\n }\n}\n\n@media (min-width: 960px) {\n .iv-recently-viewed-title {\n font-size: var(--iv-recently-viewed-title-font-size-lg, 1.5rem);\n }\n}\n\n.iv-recently-viewed::after {\n content: var(--iv-recently-viewed-after-content, '');\n display: var(--iv-recently-viewed-after-display, none);\n position: absolute;\n left: 0; right: 0; bottom: 0;\n height: 1px;\n background: var(--iv-recently-viewed-after-border-color, currentColor);\n opacity: var(--iv-recently-viewed-after-opacity, 0.1);\n}\n\n.iv-recently-viewed[data-tight] {\n --iv-recently-viewed-gap: 0.5rem;\n --iv-recently-viewed-stack-gap: 0.75rem;\n}\n","import { Component, h, Prop, State } from '@stencil/core';\nimport { getIdFromHandle, fetchProductByID } from '../../utils/storefront_api/factory';\nimport { getProductHandle } from '../../utils/helpers/factory';\n\nconst BLOCK = 'iv-recently-viewed';\nconst STORAGE_KEY = 'iv:recentlyViewed';\n\n@Component({\n tag: 'iv-recently-viewed',\n styleUrl: 'iv-recently-viewed.scss',\n shadow: false\n})\n\nexport class IvRecentlyViewed {\n\n @Prop() componenttitle?: string;\n @Prop() titletag: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' = 'span';\n @Prop() numbertoshow: number = 4;\n @Prop() noviewhistory?: string;\n @Prop() requestedfields?: string = 'images,title,price';\n\n @State() items: any[] = [];\n\n private currentProductId: string | null = null;\n private historyAvailable: boolean;\n\n async componentWillLoad() {\n await this.trackCurrentProduct();\n await this.loadForRender();\n this.items.length > 0 ? this.historyAvailable = true : this.historyAvailable = false;\n };\n\n private safeParse(json: string | null): Record<string, any> | null {\n if(!json) return null;\n try { \n return JSON.parse(json); } \n catch { \n return null; \n };\n };\n\n private loadStorage(): Record<string, any> {\n if(typeof window === 'undefined') return {};\n return this.safeParse(localStorage.getItem(STORAGE_KEY)) || {};\n };\n\n private saveStorage(obj: Record<string, any>) {\n try { \n localStorage.setItem(STORAGE_KEY, JSON.stringify(obj)); \n } \n catch(e) { \n console.warn('Unable to persist recently viewed', e); \n };\n };\n\n private async trackCurrentProduct() {\n const handle = getProductHandle();\n if(!handle) return;\n const productId = await getIdFromHandle(handle);\n if(!productId) return;\n this.currentProductId = productId;\n const storeObj = this.loadStorage();\n if(storeObj[productId]) return; \n try {\n const fields = this.requestedfields;\n const product = await fetchProductByID(productId, fields);\n if(!product) return;\n storeObj[productId] = product;\n this.saveStorage(storeObj);\n } catch (e) {\n console.warn('Failed to fetch/store recently viewed product', e);\n };\n };\n\n private async loadForRender() {\n const storeObj = this.loadStorage();\n const values = Object.values(storeObj) as any[];\n const filtered = this.currentProductId ? values.filter(p => p.id !== this.currentProductId) : values;\n const ordered = [...filtered].reverse();\n this.items = ordered.slice(0, this.numbertoshow);\n };\n\n render() {\n const TAG = this.titletag as any;\n return (\n <div class={BLOCK}>\n {this.historyAvailable ? [\n this.componenttitle && <TAG class={`${BLOCK}-title`}>{this.componenttitle}</TAG>,\n <iv-layout classModifier={BLOCK}>\n {this.items.map(item => (\n <iv-card\n data={item}\n fields={this.requestedfields}\n classmodifier={BLOCK}\n calltoaction\n addtocarttext=\"Add to cart\"\n cardtype=\"products\">\n </iv-card>\n ))}\n </iv-layout>\n ] : (\n this.noviewhistory ? <div class={`${BLOCK}-no-history`}>{this.noviewhistory}</div> : null\n )}\n </div>\n );\n\n };\n\n};"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import { r as registerInstance, h } from './index-Py50VI8u.js';
2
+ import { g as getIdFromHandle, a as fetchProductByID } from './factory-1QinX-o0.js';
3
+ import { a as getProductHandle } from './factory-mrqy6XUM.js';
4
+
5
+ const ivRecentlyViewedCss = ".iv-recently-viewed{background:var(--iv-recently-viewed-background, none);padding:var(--iv-recently-viewed-padding, 1rem 0);margin:var(--iv-recently-viewed-margin, 0);border:var(--iv-recently-viewed-border, none);border-radius:var(--iv-recently-viewed-radius, 0);position:relative;box-sizing:border-box;width:100%;display:block}.iv-recently-viewed-title{margin:var(--iv-recently-viewed-title-margin, 0 0 0.75rem);font-size:var(--iv-recently-viewed-title-font-size, 1.25rem);line-height:var(--iv-recently-viewed-title-line-height, 1.2);font-weight:var(--iv-recently-viewed-title-weight, 600);color:var(--iv-recently-viewed-title-color, inherit)}.iv-recently-viewed__list,.iv-recently-viewed__items{list-style:none;margin:0;padding:0}.iv-recently-viewed iv-layout,.iv-recently-viewed .iv-layout{--gap:var(--iv-recently-viewed-gap, 1rem);gap:var(--iv-recently-viewed-gap, 1rem)}.iv-recently-viewed iv-card,.iv-recently-viewed .iv-card{max-width:var(--iv-recently-viewed-card-max-width, 260px);width:100%}.iv-recently-viewed-no-history,.iv-recently-viewed__no-history,.iv-recently-viewed-no-history-message{font-size:var(--iv-recently-viewed-no-history-font-size, 0.875rem);color:var(--iv-recently-viewed-no-history-color, #666);padding:var(--iv-recently-viewed-no-history-padding, 0.5rem 0)}.iv-recently-viewed>*+*{margin-top:var(--iv-recently-viewed-stack-gap, 1rem)}@media (min-width: 640px){.iv-recently-viewed{padding:var(--iv-recently-viewed-padding-md, var(--iv-recently-viewed-padding, 1.25rem 0))}.iv-recently-viewed-title{font-size:var(--iv-recently-viewed-title-font-size-md, 1.375rem)}}@media (min-width: 960px){.iv-recently-viewed-title{font-size:var(--iv-recently-viewed-title-font-size-lg, 1.5rem)}}.iv-recently-viewed::after{content:var(--iv-recently-viewed-after-content, \"\");display:var(--iv-recently-viewed-after-display, none);position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--iv-recently-viewed-after-border-color, currentColor);opacity:var(--iv-recently-viewed-after-opacity, 0.1)}.iv-recently-viewed[data-tight]{--iv-recently-viewed-gap:0.5rem;--iv-recently-viewed-stack-gap:0.75rem}";
6
+
7
+ const BLOCK = 'iv-recently-viewed';
8
+ const STORAGE_KEY = 'iv:recentlyViewed';
9
+ const IvRecentlyViewed = class {
10
+ constructor(hostRef) {
11
+ registerInstance(this, hostRef);
12
+ }
13
+ componenttitle;
14
+ titletag = 'span';
15
+ numbertoshow = 4;
16
+ noviewhistory;
17
+ requestedfields = 'images,title,price';
18
+ items = [];
19
+ currentProductId = null;
20
+ historyAvailable;
21
+ async componentWillLoad() {
22
+ await this.trackCurrentProduct();
23
+ await this.loadForRender();
24
+ this.items.length > 0 ? this.historyAvailable = true : this.historyAvailable = false;
25
+ }
26
+ ;
27
+ safeParse(json) {
28
+ if (!json)
29
+ return null;
30
+ try {
31
+ return JSON.parse(json);
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ ;
37
+ }
38
+ ;
39
+ loadStorage() {
40
+ if (typeof window === 'undefined')
41
+ return {};
42
+ return this.safeParse(localStorage.getItem(STORAGE_KEY)) || {};
43
+ }
44
+ ;
45
+ saveStorage(obj) {
46
+ try {
47
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(obj));
48
+ }
49
+ catch (e) {
50
+ console.warn('Unable to persist recently viewed', e);
51
+ }
52
+ ;
53
+ }
54
+ ;
55
+ async trackCurrentProduct() {
56
+ const handle = getProductHandle();
57
+ if (!handle)
58
+ return;
59
+ const productId = await getIdFromHandle(handle);
60
+ if (!productId)
61
+ return;
62
+ this.currentProductId = productId;
63
+ const storeObj = this.loadStorage();
64
+ if (storeObj[productId])
65
+ return;
66
+ try {
67
+ const fields = this.requestedfields;
68
+ const product = await fetchProductByID(productId, fields);
69
+ if (!product)
70
+ return;
71
+ storeObj[productId] = product;
72
+ this.saveStorage(storeObj);
73
+ }
74
+ catch (e) {
75
+ console.warn('Failed to fetch/store recently viewed product', e);
76
+ }
77
+ ;
78
+ }
79
+ ;
80
+ async loadForRender() {
81
+ const storeObj = this.loadStorage();
82
+ const values = Object.values(storeObj);
83
+ const filtered = this.currentProductId ? values.filter(p => p.id !== this.currentProductId) : values;
84
+ const ordered = [...filtered].reverse();
85
+ this.items = ordered.slice(0, this.numbertoshow);
86
+ }
87
+ ;
88
+ render() {
89
+ const TAG = this.titletag;
90
+ return (h("div", { key: '0c8ddb5c7e8bb7ac575821794568f540985f6ce2', class: BLOCK }, this.historyAvailable ? [
91
+ this.componenttitle && h(TAG, { class: `${BLOCK}-title` }, this.componenttitle),
92
+ h("iv-layout", { classModifier: BLOCK }, this.items.map(item => (h("iv-card", { data: item, fields: this.requestedfields, classmodifier: BLOCK, calltoaction: true, addtocarttext: "Add to cart", cardtype: "products" }))))
93
+ ] : (this.noviewhistory ? h("div", { class: `${BLOCK}-no-history` }, this.noviewhistory) : null)));
94
+ }
95
+ ;
96
+ };
97
+ ;
98
+ IvRecentlyViewed.style = ivRecentlyViewedCss;
99
+
100
+ export { IvRecentlyViewed as iv_recently_viewed };
101
+ //# sourceMappingURL=iv-recently-viewed.entry.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iv-sidebar.entry.esm.js","sources":["src/components/iv-sidebar/iv-sidebar.scss?tag=iv-sidebar","src/components/iv-sidebar/iv-sidebar.tsx"],"sourcesContent":["iv-sidebar {\n \n .iv-sidebar {\n position: fixed;\n top: 0;\n right: 0;\n left: auto;\n height: 100%;\n background-color: #fff;\n box-shadow: 2px 0 5px rgba(0,0,0,0.1);\n transform: translateX(100%);\n transition: transform 0.3s ease-in-out;\n z-index: 1001;\n padding: var(--iv-sidebar-padding-top, 2rem) var(--iv-sidebar-padding-right, 2rem) var(--iv-sidebar-padding-bottom, 2rem) var(--iv-sidebar-padding-left, 2rem);\n overflow-y: auto;\n max-height: 100vh;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n width: 40%;\n\n @media (max-width: 1024px) {\n width: 95%;\n }\n\n &.close {\n font-size: 2.25rem;\n font-weight: 400;\n pointer-events: none;\n user-select: none;\n line-height: 1;\n color: inherit;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n &.open {\n transform: translateX(0);\n }\n\n }\n\n .iv-sidebar-close-button {\n position: absolute;\n top: 1rem;\n right: 1rem;\n background: none;\n border: none;\n color: #111;\n font-size: 2.25rem;\n font-weight: 400;\n line-height: 1;\n cursor: pointer;\n padding: 0;\n width: 2.5rem;\n height: 2.5rem;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1002;\n transition: color 0.2s;\n &:hover {\n color: #000;\n }\n &:focus {\n outline: none;\n color: #000;\n }\n }\n\n .iv-sidebar-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n backdrop-filter: blur(8px);\n background-color: #0e0d0d80;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease-in-out, visibility 0.3s ease-in-out;\n z-index: 1000;\n\n &.open {\n opacity: 1;\n visibility: visible;\n }\n\n }\n\n\n [slot=\"header\"] {}\n\n [slot=\"footer\"] {}\n\n}","import { Component, Host, h, Prop, Listen } from '@stencil/core';\nimport { state, togglePullout } from '../../utils/store/store';\n\nconst BLOCK = 'iv-sidebar';\n\n@Component({\n tag: 'iv-sidebar',\n styleUrl: 'iv-sidebar.scss',\n shadow: false,\n})\n\nexport class IvSidebar {\n\n @Prop() closeicon: string = '×';\n\n @Listen('openPullout', { target: 'window' })\n handleOpenPullout(event: CustomEvent) {\n togglePullout(event.detail);\n };\n\n render() {\n \n return (\n <Host>\n <div class={`${BLOCK} ${ state.pulloutOpen ? 'open' : '' }`}>\n <iv-button class={`${BLOCK}-close-button`} onClick={() => togglePullout()}>\n <span class=\"inner-button close\">{this.closeicon}</span>\n </iv-button>\n <slot name=\"header\"></slot>\n {state.pulloutContent === 'wishlist' ? (\n <iv-wishlist-view />\n ) : (\n state.pulloutContent && <slot name={state.pulloutContent}></slot>\n )}\n <slot name=\"footer\"></slot>\n </div>\n <div class={`${BLOCK}-overlay ${state.pulloutOpen ? 'open' : ''}`} onClick={() => togglePullout()}></div>\n </Host>\n );\n\n };\n\n};"],"names":[],"mappings":";;AAAA,MAAM,YAAY,GAAG,++CAA++C;;ACGpgD,MAAM,KAAK,GAAG,YAAY;MAQb,SAAS,GAAA,MAAA;;;;IAEZ,SAAS,GAAW,GAAG;AAG/B,IAAA,iBAAiB,CAAC,KAAkB,EAAA;AAClC,QAAA,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC;;;IAG7B,MAAM,GAAA;QAEJ,QACE,EAAC,IAAI,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAA,EACH,CAAA,CAAA,KAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAK,KAAK,EAAE,GAAG,KAAK,CAAA,CAAA,EAAK,KAAK,CAAC,WAAW,GAAG,MAAM,GAAG,EAAG,CAAA,CAAE,EAAA,EACzD,CAAA,CAAA,WAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAW,KAAK,EAAE,CAAG,EAAA,KAAK,eAAe,EAAE,OAAO,EAAE,MAAM,aAAa,EAAE,EAAA,EACvE,CAAM,CAAA,MAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAA,KAAK,EAAC,oBAAoB,EAAA,EAAE,IAAI,CAAC,SAAS,CAAQ,CAC9C,EACZ,CAAM,CAAA,MAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAA,IAAI,EAAC,QAAQ,EAAQ,CAAA,EAC1B,KAAK,CAAC,cAAc,KAAK,UAAU,IAClC,CAAoB,CAAA,kBAAA,EAAA,IAAA,CAAA,KAEpB,KAAK,CAAC,cAAc,IAAI,CAAA,CAAA,MAAA,EAAA,EAAM,IAAI,EAAE,KAAK,CAAC,cAAc,EAAA,CAAS,CAClE,EACD,CAAA,CAAA,MAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAM,IAAI,EAAC,QAAQ,EAAA,CAAQ,CACvB,EACN,CAAA,CAAA,KAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAK,KAAK,EAAE,CAAA,EAAG,KAAK,CAAY,SAAA,EAAA,KAAK,CAAC,WAAW,GAAG,MAAM,GAAG,EAAE,CAAE,CAAA,EAAE,OAAO,EAAE,MAAM,aAAa,EAAE,EAAA,CAAQ,CACpG;;;;AAKZ;;;;;"}
@@ -0,0 +1,24 @@
1
+ import { r as registerInstance, i as togglePullout, h, a as Host, d as state } from './index-Py50VI8u.js';
2
+
3
+ const ivSidebarCss = "iv-sidebar .iv-sidebar{position:fixed;top:0;right:0;left:auto;height:100%;background-color:#fff;box-shadow:2px 0 5px rgba(0, 0, 0, 0.1);transform:translateX(100%);transition:transform 0.3s ease-in-out;z-index:1001;padding:var(--iv-sidebar-padding-top, 2rem) var(--iv-sidebar-padding-right, 2rem) var(--iv-sidebar-padding-bottom, 2rem) var(--iv-sidebar-padding-left, 2rem);overflow-y:auto;max-height:100vh;box-sizing:border-box;display:flex;flex-direction:column;width:40%}@media (max-width: 1024px){iv-sidebar .iv-sidebar{width:95%}}iv-sidebar .iv-sidebar.close{font-size:2.25rem;font-weight:400;pointer-events:none;user-select:none;line-height:1;color:inherit;display:flex;align-items:center;justify-content:center}iv-sidebar .iv-sidebar.open{transform:translateX(0)}iv-sidebar .iv-sidebar-close-button{position:absolute;top:1rem;right:1rem;background:none;border:none;color:#111;font-size:2.25rem;font-weight:400;line-height:1;cursor:pointer;padding:0;width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;z-index:1002;transition:color 0.2s}iv-sidebar .iv-sidebar-close-button:hover{color:#000}iv-sidebar .iv-sidebar-close-button:focus{outline:none;color:#000}iv-sidebar .iv-sidebar-overlay{position:fixed;top:0;left:0;width:100%;height:100%;backdrop-filter:blur(8px);background-color:rgba(14, 13, 13, 0.5019607843);opacity:0;visibility:hidden;transition:opacity 0.3s ease-in-out, visibility 0.3s ease-in-out;z-index:1000}iv-sidebar .iv-sidebar-overlay.open{opacity:1;visibility:visible}";
4
+
5
+ const BLOCK = 'iv-sidebar';
6
+ const IvSidebar = class {
7
+ constructor(hostRef) {
8
+ registerInstance(this, hostRef);
9
+ }
10
+ closeicon = '×';
11
+ handleOpenPullout(event) {
12
+ togglePullout(event.detail);
13
+ }
14
+ ;
15
+ render() {
16
+ return (h(Host, { key: 'ffe309e0c49891cc7af6e2355cfd6e779fc80860' }, h("div", { key: 'ee2537c76e404ee3a317c4d243019256e5249a57', class: `${BLOCK} ${state.pulloutOpen ? 'open' : ''}` }, h("iv-button", { key: '088461263e4d12089ffc0dc8bea4bf26b9e63a16', class: `${BLOCK}-close-button`, onClick: () => togglePullout() }, h("span", { key: 'b7b05f522f29f55f2d5ba9ce15238704938855a4', class: "inner-button close" }, this.closeicon)), h("slot", { key: 'e1e40c4e547ef6779fe07c404f9550946366af18', name: "header" }), state.pulloutContent === 'wishlist' ? (h("iv-wishlist-view", null)) : (state.pulloutContent && h("slot", { name: state.pulloutContent })), h("slot", { key: '4dfe738142021ce15bf2414401dd85f804876f7c', name: "footer" })), h("div", { key: '3028e89879af20146ceb46ff081cd305f7b541c1', class: `${BLOCK}-overlay ${state.pulloutOpen ? 'open' : ''}`, onClick: () => togglePullout() })));
17
+ }
18
+ ;
19
+ };
20
+ ;
21
+ IvSidebar.style = ivSidebarCss;
22
+
23
+ export { IvSidebar as iv_sidebar };
24
+ //# sourceMappingURL=iv-sidebar.entry.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iv-spinner.entry.esm.js","sources":["src/components/iv-spinner/iv-spinner.scss?tag=iv-spinner","src/components/iv-spinner/iv-spinner.tsx"],"sourcesContent":[":host {\n display: block;\n}\n","import { Component, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'iv-spinner',\n styleUrl: 'iv-spinner.scss',\n shadow: false,\n})\n\nexport class IvSpinner {\n\n @Prop() show: boolean = false;\n\n render() {\n return this.show ? (\n <div class=\"iv-spinner\">\n <span class=\"spinner\"></span>\n </div>\n ) : null;\n\n };\n\n};"],"names":[],"mappings":";;AAAA,MAAM,YAAY,GAAG,sBAAsB;;MCQ9B,SAAS,GAAA,MAAA;;;;IAEZ,IAAI,GAAY,KAAK;IAE7B,MAAM,GAAA;AACJ,QAAA,OAAO,IAAI,CAAC,IAAI,IACd,CAAA,CAAA,KAAA,EAAA,EAAK,KAAK,EAAC,YAAY,EAAA,EACrB,CAAM,CAAA,MAAA,EAAA,EAAA,KAAK,EAAC,SAAS,EAAQ,CAAA,CACzB,IACJ,IAAI;;;;AAIX;;;;;"}
@@ -0,0 +1,19 @@
1
+ import { r as registerInstance, h } from './index-Py50VI8u.js';
2
+
3
+ const ivSpinnerCss = ":host{display:block}";
4
+
5
+ const IvSpinner = class {
6
+ constructor(hostRef) {
7
+ registerInstance(this, hostRef);
8
+ }
9
+ show = false;
10
+ render() {
11
+ return this.show ? (h("div", { class: "iv-spinner" }, h("span", { class: "spinner" }))) : null;
12
+ }
13
+ ;
14
+ };
15
+ ;
16
+ IvSpinner.style = ivSpinnerCss;
17
+
18
+ export { IvSpinner as iv_spinner };
19
+ //# sourceMappingURL=iv-spinner.entry.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iv-suggest.entry.esm.js","sources":["src/components/iv-suggest/iv-suggest.scss?tag=iv-suggest","src/components/iv-suggest/iv-suggest.tsx"],"sourcesContent":["// Base iv-suggest styles with component-scoped CSS variables.\n// Override --iv-suggest-* externally (theme / section scope) without editing this file.\n\n.iv-suggest {\n box-sizing: border-box;\n width: var(--iv-suggest-width, 100%);\n max-width: var(--iv-suggest-max-width, 100%);\n margin: var(--iv-suggest-margin, 0);\n padding: var(--iv-suggest-padding, 0);\n background: var(--iv-suggest-bg, transparent);\n border: var(--iv-suggest-border, none);\n border-radius: var(--iv-suggest-radius, 0);\n box-shadow: var(--iv-suggest-shadow, none);\n color: var(--iv-suggest-color, inherit);\n --iv-layout-gap: var(--iv-suggest-layout-gap, 1.25rem); \n}\n\n.iv-suggest-queries,\n.iv-suggest-collections,\n.iv-suggest-products,\n.iv-suggest-banner {\n box-sizing: border-box;\n padding: var(--iv-suggest-section-padding, 0);\n margin: var(--iv-suggest-section-margin, 0);\n background: var(--iv-suggest-section-bg, transparent);\n border: var(--iv-suggest-section-border, none);\n border-radius: var(--iv-suggest-section-radius, 0);\n}\n\n.iv-suggest-queries-title,\n.iv-suggest-products-title,\n.iv-suggest-collections-title {\n display: block;\n margin: var(--iv-suggest-title-margin, 0 0 .75rem 0);\n font-size: var(--iv-suggest-title-font-size, 1rem);\n font-weight: var(--iv-suggest-title-font-weight, 600);\n line-height: var(--iv-suggest-title-line-height, 1.2);\n letter-spacing: var(--iv-suggest-title-letter-spacing, normal);\n}\n\n.iv-suggest-top-queries {\n display: flex;\n flex-wrap: wrap;\n gap: var(--iv-suggest-queries-gap, .5rem);\n}\n\n.iv-suggest-top-queries .iv-link {\n --iv-link-color: var(--iv-suggest-query-link-color, inherit);\n --iv-link-hover-color: var(--iv-suggest-query-link-hover-color, var(--iv-link-color, inherit));\n font-size: var(--iv-suggest-query-link-font-size, .875rem);\n background: var(--iv-suggest-query-link-bg, transparent);\n padding: var(--iv-suggest-query-link-padding, 0);\n border: var(--iv-suggest-query-link-border, none);\n border-radius: var(--iv-suggest-query-link-radius, 0);\n}\n\n.iv-suggest .iv-card {\n --iv-card-padding: var(--iv-suggest-card-padding, var(--iv-card-padding, 0));\n margin: var(--iv-suggest-card-margin, 0);\n}\n\n.iv-suggest-banner {\n position: relative;\n overflow: hidden;\n}\n\n.iv-suggest-banner-image img {\n display: block;\n width: 100%;\n height: auto;\n object-fit: var(--iv-suggest-banner-image-object-fit, cover);\n aspect-ratio: var(--iv-suggest-banner-image-aspect-ratio, auto);\n}\n\n.iv-suggest-no-data {\n font-size: var(--iv-suggest-empty-font-size, .8125rem);\n opacity: var(--iv-suggest-empty-opacity, .8);\n padding: var(--iv-suggest-empty-padding, 0);\n}\n\n.iv-suggest--scroll-x .iv-layout {\n display: flex !important;\n overflow-x: auto;\n scrollbar-width: var(--iv-suggest-scrollbar-width, thin);\n -webkit-overflow-scrolling: touch;\n}\n\n.iv-suggest--scroll-x .iv-layout > * { flex: 0 0 var(--iv-suggest-scroll-item-width, 70%); }\n\n@media (min-width: 40rem) {\n .iv-suggest { --iv-suggest-layout-gap: var(--iv-suggest-layout-gap-md, var(--iv-suggest-layout-gap, 1.25rem)); }\n}\n\n@media (min-width: 64rem) {\n .iv-suggest { --iv-suggest-layout-gap: var(--iv-suggest-layout-gap-lg, var(--iv-suggest-layout-gap, 1.25rem)); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .iv-suggest { scroll-behavior: auto; }\n}","import { Component, h, Prop } from '@stencil/core';\nimport { decodeJsonString } from '../../utils/helpers/factory';\n\nconst BLOCK = 'iv-suggest';\n\n@Component({\n tag: 'iv-suggest',\n styleUrl: 'iv-suggest.scss',\n shadow: false,\n})\n\nexport class IvSuggest {\n \n @Prop() topqueries?: string;\n @Prop() collections?: string;\n @Prop() products?: string;\n @Prop() banner?: string; \n @Prop() bannerurl?: string;\n @Prop() bannertitle?: string;\n @Prop() bannertitletag: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' = 'span';\n @Prop() bannerbuttontext?: string;\n @Prop() topquerytitle?: string;\n @Prop() productstitle?: string;\n @Prop() collectionstitle?: string;\n @Prop() gridlayout?: string;\n @Prop() requestfields?: string;\n\n private get suggestionElements(): string[] {\n return [\n this.topqueries && 'queries',\n this.collections && 'collections',\n this.products && 'products',\n this.banner && 'banner',\n ].filter(Boolean) as string[];\n };\n\n private renderQueries() {\n const queries = Array.from(new Set((this.topqueries || '').split(',').map(q => q.trim()).filter(Boolean)));\n return (\n <div class={`${BLOCK}-top-queries`}>\n {this.topquerytitle && <span class={`${BLOCK}-top-queries-title`}>{this.topquerytitle}</span>}\n {queries.map(query => (\n <iv-link \n classmodifier={BLOCK}\n linkhref={`/search?q=${encodeURIComponent(query)}`}>\n {query}\n </iv-link>\n ))}\n </div>\n );\n };\n\n private renderTiles(type: string) {\n let raw = type === 'collections' ? this.collections : this.products;\n let decoded = decodeJsonString(raw || '[]');\n let data: any[];\n try {\n data = JSON.parse(decoded);\n } catch {\n data = [];\n };\n return (\n <div class={`${BLOCK}-${type}`}>\n {(type === 'products' && this.productstitle) || (type === 'collections' && this.collectionstitle) ? (\n <span class={`${BLOCK}-${type}-title`}>\n {type === 'products' ? this.productstitle : this.collectionstitle}\n </span>\n ) : null}\n {data.length === 0 ? (\n <span class={`${BLOCK}-no-data`}>No {type} found.</span>\n ) : (\n data.map(collection => (\n <iv-card \n data={collection} \n classmodifier={BLOCK}\n {...(this.requestfields ? { fields: this.requestfields } : {})}/>\n ))\n )}\n </div>\n );\n };\n\n private renderBanner() {\n const Tag = this.bannertitletag as any;\n return (\n <iv-banner \n classmodifier={BLOCK}\n bannerurl={this.bannerurl || ''}\n bannerbuttontext={this.bannerbuttontext || ''}>\n {this.banner && (\n <div class={`${BLOCK}-banner-image`} slot=\"bannerimage\">\n <img \n src={this.banner || ''} \n alt=\"Promotional banner\"/>\n </div>\n )}\n {this.bannertitle && (\n <div slot=\"bannertitle\">\n <Tag class=\"iv-banner-title\">{this.bannertitle}</Tag>\n </div>\n )}\n {this.bannerbuttontext && (\n <div slot=\"bannerbutton\">\n <a href={this.bannerurl || ''} class=\"iv-button iv-button--primary\">\n {this.bannerbuttontext}\n </a>\n </div>\n )}\n </iv-banner>\n );\n };\n\n private renderers = {\n queries: () => this.renderQueries(),\n collections: () => this.renderTiles('collections'),\n products: () => this.renderTiles('products'),\n banner: () => this.renderBanner()\n };\n\n render() {\n\n return (\n <div class={BLOCK}>\n {this.gridlayout && (\n <iv-layout\n gridTemplateAreas={this.gridlayout}\n classModifier={BLOCK}>\n {this.suggestionElements.map(slot => (\n <div slot={slot}>\n {this.renderers[slot]?.()}\n </div>\n ))}\n </iv-layout>\n )}\n </div>\n\n );\n };\n\n};"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import { r as registerInstance, h } from './index-Py50VI8u.js';
2
+ import { d as decodeJsonString } from './factory-mrqy6XUM.js';
3
+
4
+ const ivSuggestCss = ".iv-suggest{box-sizing:border-box;width:var(--iv-suggest-width, 100%);max-width:var(--iv-suggest-max-width, 100%);margin:var(--iv-suggest-margin, 0);padding:var(--iv-suggest-padding, 0);background:var(--iv-suggest-bg, transparent);border:var(--iv-suggest-border, none);border-radius:var(--iv-suggest-radius, 0);box-shadow:var(--iv-suggest-shadow, none);color:var(--iv-suggest-color, inherit);--iv-layout-gap:var(--iv-suggest-layout-gap, 1.25rem)}.iv-suggest-queries,.iv-suggest-collections,.iv-suggest-products,.iv-suggest-banner{box-sizing:border-box;padding:var(--iv-suggest-section-padding, 0);margin:var(--iv-suggest-section-margin, 0);background:var(--iv-suggest-section-bg, transparent);border:var(--iv-suggest-section-border, none);border-radius:var(--iv-suggest-section-radius, 0)}.iv-suggest-queries-title,.iv-suggest-products-title,.iv-suggest-collections-title{display:block;margin:var(--iv-suggest-title-margin, 0 0 0.75rem 0);font-size:var(--iv-suggest-title-font-size, 1rem);font-weight:var(--iv-suggest-title-font-weight, 600);line-height:var(--iv-suggest-title-line-height, 1.2);letter-spacing:var(--iv-suggest-title-letter-spacing, normal)}.iv-suggest-top-queries{display:flex;flex-wrap:wrap;gap:var(--iv-suggest-queries-gap, 0.5rem)}.iv-suggest-top-queries .iv-link{--iv-link-color:var(--iv-suggest-query-link-color, inherit);--iv-link-hover-color:var(--iv-suggest-query-link-hover-color, var(--iv-link-color, inherit));font-size:var(--iv-suggest-query-link-font-size, 0.875rem);background:var(--iv-suggest-query-link-bg, transparent);padding:var(--iv-suggest-query-link-padding, 0);border:var(--iv-suggest-query-link-border, none);border-radius:var(--iv-suggest-query-link-radius, 0)}.iv-suggest .iv-card{--iv-card-padding:var(--iv-suggest-card-padding, var(--iv-card-padding, 0));margin:var(--iv-suggest-card-margin, 0)}.iv-suggest-banner{position:relative;overflow:hidden}.iv-suggest-banner-image img{display:block;width:100%;height:auto;object-fit:var(--iv-suggest-banner-image-object-fit, cover);aspect-ratio:var(--iv-suggest-banner-image-aspect-ratio, auto)}.iv-suggest-no-data{font-size:var(--iv-suggest-empty-font-size, 0.8125rem);opacity:var(--iv-suggest-empty-opacity, 0.8);padding:var(--iv-suggest-empty-padding, 0)}.iv-suggest--scroll-x .iv-layout{display:flex !important;overflow-x:auto;scrollbar-width:var(--iv-suggest-scrollbar-width, thin);-webkit-overflow-scrolling:touch}.iv-suggest--scroll-x .iv-layout>*{flex:0 0 var(--iv-suggest-scroll-item-width, 70%)}@media (min-width: 40rem){.iv-suggest{--iv-suggest-layout-gap:var(--iv-suggest-layout-gap-md, var(--iv-suggest-layout-gap, 1.25rem))}}@media (min-width: 64rem){.iv-suggest{--iv-suggest-layout-gap:var(--iv-suggest-layout-gap-lg, var(--iv-suggest-layout-gap, 1.25rem))}}@media (prefers-reduced-motion: reduce){.iv-suggest{scroll-behavior:auto}}";
5
+
6
+ const BLOCK = 'iv-suggest';
7
+ const IvSuggest = class {
8
+ constructor(hostRef) {
9
+ registerInstance(this, hostRef);
10
+ }
11
+ topqueries;
12
+ collections;
13
+ products;
14
+ banner;
15
+ bannerurl;
16
+ bannertitle;
17
+ bannertitletag = 'span';
18
+ bannerbuttontext;
19
+ topquerytitle;
20
+ productstitle;
21
+ collectionstitle;
22
+ gridlayout;
23
+ requestfields;
24
+ get suggestionElements() {
25
+ return [
26
+ this.topqueries && 'queries',
27
+ this.collections && 'collections',
28
+ this.products && 'products',
29
+ this.banner && 'banner',
30
+ ].filter(Boolean);
31
+ }
32
+ ;
33
+ renderQueries() {
34
+ const queries = Array.from(new Set((this.topqueries || '').split(',').map(q => q.trim()).filter(Boolean)));
35
+ return (h("div", { class: `${BLOCK}-top-queries` }, this.topquerytitle && h("span", { class: `${BLOCK}-top-queries-title` }, this.topquerytitle), queries.map(query => (h("iv-link", { classmodifier: BLOCK, linkhref: `/search?q=${encodeURIComponent(query)}` }, query)))));
36
+ }
37
+ ;
38
+ renderTiles(type) {
39
+ let raw = type === 'collections' ? this.collections : this.products;
40
+ let decoded = decodeJsonString(raw || '[]');
41
+ let data;
42
+ try {
43
+ data = JSON.parse(decoded);
44
+ }
45
+ catch {
46
+ data = [];
47
+ }
48
+ ;
49
+ return (h("div", { class: `${BLOCK}-${type}` }, (type === 'products' && this.productstitle) || (type === 'collections' && this.collectionstitle) ? (h("span", { class: `${BLOCK}-${type}-title` }, type === 'products' ? this.productstitle : this.collectionstitle)) : null, data.length === 0 ? (h("span", { class: `${BLOCK}-no-data` }, "No ", type, " found.")) : (data.map(collection => (h("iv-card", { data: collection, classmodifier: BLOCK, ...(this.requestfields ? { fields: this.requestfields } : {}) }))))));
50
+ }
51
+ ;
52
+ renderBanner() {
53
+ const Tag = this.bannertitletag;
54
+ return (h("iv-banner", { classmodifier: BLOCK, bannerurl: this.bannerurl || '', bannerbuttontext: this.bannerbuttontext || '' }, this.banner && (h("div", { class: `${BLOCK}-banner-image`, slot: "bannerimage" }, h("img", { src: this.banner || '', alt: "Promotional banner" }))), this.bannertitle && (h("div", { slot: "bannertitle" }, h(Tag, { class: "iv-banner-title" }, this.bannertitle))), this.bannerbuttontext && (h("div", { slot: "bannerbutton" }, h("a", { href: this.bannerurl || '', class: "iv-button iv-button--primary" }, this.bannerbuttontext)))));
55
+ }
56
+ ;
57
+ renderers = {
58
+ queries: () => this.renderQueries(),
59
+ collections: () => this.renderTiles('collections'),
60
+ products: () => this.renderTiles('products'),
61
+ banner: () => this.renderBanner()
62
+ };
63
+ render() {
64
+ return (h("div", { key: 'cba207123cb37650b1f8984e18081d1f6bab667e', class: BLOCK }, this.gridlayout && (h("iv-layout", { key: '8b8d617b9b78a96d0c48175db4151a8336ce211c', gridTemplateAreas: this.gridlayout, classModifier: BLOCK }, this.suggestionElements.map(slot => (h("div", { slot: slot }, this.renderers[slot]?.())))))));
65
+ }
66
+ ;
67
+ };
68
+ ;
69
+ IvSuggest.style = ivSuggestCss;
70
+
71
+ export { IvSuggest as iv_suggest };
72
+ //# sourceMappingURL=iv-suggest.entry.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iv-tabs.entry.esm.js","sources":["src/components/iv-tabs/iv-tabs.scss?tag=iv-tabs","src/components/iv-tabs/iv-tabs.tsx"],"sourcesContent":[":host {\n display: block;\n}\n","import { Component, Prop, State, h } from '@stencil/core';\n\n@Component({\n tag: 'iv-tabs',\n styleUrl: 'iv-tabs.scss',\n shadow: false,\n})\n\nexport class IvTabs {\n\n @Prop() labels: string[] = [];\n @Prop() classModifier?: string;\n @Prop() tabLayout: 'horizontal' | 'vertical' = 'horizontal';\n\n @State() activeTab: number = 0;\n\n render() {\n\n return (\n <div class={`iv-tabs iv-tabs--${this.classModifier} iv-tabs--${this.tabLayout}`}>\n <div class=\"iv-tabs__header\" role=\"tablist\">\n {this.labels.map((label, index) => (\n <button\n id={`tab-button-${index}`}\n class={`iv-tab ${this.activeTab === index ? 'active' : ''}`}\n onClick={() => this.activeTab = index}\n aria-selected={this.activeTab === index ? 'true' : 'false'}\n aria-controls={`tab-panel-${index}`}\n role=\"tab\"\n type=\"button\"\n tabindex={this.activeTab === index ? '0' : '-1'}>\n {label}\n </button>\n ))}\n </div>\n <div class=\"iv-tabs__content\">\n {this.labels.map((_, index) => (\n <div\n id={`tab-panel-${index}`}\n role='tabpanel'\n aria-labelledby={`tab-button-${index}`}\n hidden={this.activeTab !== index}>\n <slot name={`tab-content-${index}`}></slot>\n </div>\n ))}\n </div>\n </div>\n );\n\n };\n\n};"],"names":[],"mappings":";;AAAA,MAAM,SAAS,GAAG,sBAAsB;;MCQ3B,MAAM,GAAA,MAAA;;;;IAET,MAAM,GAAa,EAAE;AACrB,IAAA,aAAa;IACb,SAAS,GAA8B,YAAY;IAElD,SAAS,GAAW,CAAC;IAE9B,MAAM,GAAA;QAEJ,QACE,CAAA,CAAA,KAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAK,KAAK,EAAE,oBAAoB,IAAI,CAAC,aAAa,CAAA,UAAA,EAAa,IAAI,CAAC,SAAS,CAAE,CAAA,EAAA,EAC7E,CAAK,CAAA,KAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAA,KAAK,EAAC,iBAAiB,EAAC,IAAI,EAAC,SAAS,EACxC,EAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,MAC5B,CAAA,CAAA,QAAA,EAAA,EACE,EAAE,EAAE,cAAc,KAAK,CAAA,CAAE,EACzB,KAAK,EAAE,CAAA,OAAA,EAAU,IAAI,CAAC,SAAS,KAAK,KAAK,GAAG,QAAQ,GAAG,EAAE,CAAA,CAAE,EAC3D,OAAO,EAAE,MAAM,IAAI,CAAC,SAAS,GAAG,KAAK,EAAA,eAAA,EACtB,IAAI,CAAC,SAAS,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO,EAAA,eAAA,EAC3C,CAAa,UAAA,EAAA,KAAK,CAAE,CAAA,EACnC,IAAI,EAAC,KAAK,EACV,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,IAAI,CAAC,SAAS,KAAK,KAAK,GAAG,GAAG,GAAG,IAAI,IAC9C,KAAK,CACC,CACV,CAAC,CACE,EACN,CAAA,CAAA,KAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAK,KAAK,EAAC,kBAAkB,EAC1B,EAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,MACxB,CAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,aAAa,KAAK,CAAA,CAAE,EACxB,IAAI,EAAC,UAAU,EACE,iBAAA,EAAA,CAAc,WAAA,EAAA,KAAK,CAAE,CAAA,EACtC,MAAM,EAAE,IAAI,CAAC,SAAS,KAAK,KAAK,EAAA,EAC9B,CAAA,CAAA,MAAA,EAAA,EAAM,IAAI,EAAE,CAAA,YAAA,EAAe,KAAK,CAAA,CAAE,EAAA,CAAS,CACzC,CACP,CAAC,CACE,CACF;;;;AAKX;;;;;"}