@hortonstudio/main 1.9.11 → 1.9.20

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 (120) hide show
  1. package/.prettierrc +8 -0
  2. package/README.md +146 -0
  3. package/eslint.config.js +32 -0
  4. package/index.ts +275 -0
  5. package/package.json +19 -2
  6. package/public/bootstrap.js +16 -0
  7. package/src/animations/animations.ts +93 -0
  8. package/src/animations/functions/counter/counter.ts +137 -0
  9. package/src/config.json +570 -0
  10. package/src/config.ts +105 -0
  11. package/src/modules/default/README.md +167 -0
  12. package/src/modules/default/default.ts +71 -0
  13. package/{autoInit → src/modules/default/functions}/accessibility/README.md +44 -12
  14. package/src/modules/default/functions/accessibility/accessibility.ts +54 -0
  15. package/src/modules/default/functions/accordion/README.md +451 -0
  16. package/src/modules/default/functions/accordion/accordion.ts +189 -0
  17. package/src/modules/default/functions/comparison/comparison.ts +424 -0
  18. package/src/modules/default/functions/marquee/marquee.ts +206 -0
  19. package/src/modules/default/functions/navbar/README.md +393 -0
  20. package/src/modules/default/functions/navbar/functions/arrow-navigation/arrow-navigation.ts +183 -0
  21. package/src/modules/default/functions/navbar/functions/dropdown/dropdown.ts +313 -0
  22. package/src/modules/default/functions/navbar/functions/menu/menu.ts +315 -0
  23. package/src/modules/default/functions/navbar/navbar.ts +51 -0
  24. package/{autoInit → src/modules/default/functions}/smooth-scroll/README.md +45 -14
  25. package/{autoInit/smooth-scroll/smooth-scroll.js → src/modules/default/functions/smooth-scroll/smooth-scroll.ts} +33 -38
  26. package/{autoInit → src/modules/default/functions}/transition/README.md +59 -32
  27. package/src/modules/default/functions/transition/transition.ts +290 -0
  28. package/src/modules/normalize/README.md +172 -0
  29. package/src/modules/normalize/functions/clickable/README.md +84 -0
  30. package/src/modules/normalize/functions/clickable/clickable.ts +43 -0
  31. package/src/modules/normalize/functions/clickable/functions/normalize/README.md +213 -0
  32. package/src/modules/normalize/functions/clickable/functions/normalize/normalize.ts +68 -0
  33. package/src/modules/normalize/functions/dupe/README.md +405 -0
  34. package/src/modules/normalize/functions/dupe/dupe.ts +197 -0
  35. package/src/modules/normalize/functions/sync/sync.ts +378 -0
  36. package/src/modules/normalize/normalize.ts +58 -0
  37. package/src/modules/structure/README.md +190 -0
  38. package/src/modules/structure/functions/form/README.md +94 -0
  39. package/src/modules/structure/functions/form/form.ts +54 -0
  40. package/src/modules/structure/functions/form/functions/honeypot/README.md +77 -0
  41. package/src/modules/structure/functions/form/functions/honeypot/honeypot.ts +37 -0
  42. package/src/modules/structure/functions/form/functions/range/README.md +410 -0
  43. package/src/modules/structure/functions/form/functions/range/range.ts +92 -0
  44. package/src/modules/structure/functions/form/functions/select/README.md +393 -0
  45. package/src/modules/structure/functions/form/functions/select/functions/custom-select/custom-select.ts +637 -0
  46. package/src/modules/structure/functions/form/functions/select/functions/states/states.ts +118 -0
  47. package/src/modules/structure/functions/form/functions/select/select.ts +48 -0
  48. package/src/modules/structure/functions/form/functions/test/test.ts +132 -0
  49. package/{autoInit/accessibility → src/modules/structure}/functions/pagination/README.md +147 -72
  50. package/{autoInit/accessibility/functions/pagination/pagination.js → src/modules/structure/functions/pagination/pagination.ts} +98 -50
  51. package/{autoInit → src/modules/structure/functions}/site-settings/README.md +57 -27
  52. package/{autoInit/site-settings/site-settings.js → src/modules/structure/functions/site-settings/site-settings.ts} +36 -32
  53. package/{autoInit/accessibility → src/modules/structure}/functions/toc/README.md +18 -15
  54. package/{autoInit/accessibility/functions/toc/toc.js → src/modules/structure/functions/toc/functions/heading-links/heading-links.ts} +43 -63
  55. package/src/modules/structure/functions/toc/functions/progress-bar/progress-bar.ts +101 -0
  56. package/src/modules/structure/functions/toc/toc.ts +35 -0
  57. package/{autoInit/accessibility → src/modules/structure}/functions/year-replacement/README.md +7 -6
  58. package/src/modules/structure/functions/year-replacement/year-replacement.ts +59 -0
  59. package/src/modules/structure/structure.ts +59 -0
  60. package/src/utils/attributeSelector.ts +78 -0
  61. package/src/utils/cssVariables.ts +24 -0
  62. package/src/utils/gsap.ts +198 -0
  63. package/src/utils/heightAnimator.ts +130 -0
  64. package/src/utils/modalManager.ts +150 -0
  65. package/src/utils.ts +54 -0
  66. package/tsconfig.json +24 -0
  67. package/vite.config.js +45 -0
  68. package/.claude/settings.local.json +0 -70
  69. package/archive/hero.js +0 -794
  70. package/archive/modal.js +0 -80
  71. package/archive/text.js +0 -628
  72. package/autoInit/accessibility/accessibility.js +0 -53
  73. package/autoInit/accessibility/functions/blog-remover/README.md +0 -61
  74. package/autoInit/accessibility/functions/blog-remover/blog-remover.js +0 -31
  75. package/autoInit/accessibility/functions/click-forwarding/README.md +0 -60
  76. package/autoInit/accessibility/functions/click-forwarding/click-forwarding.js +0 -82
  77. package/autoInit/accessibility/functions/dropdown/README.md +0 -212
  78. package/autoInit/accessibility/functions/dropdown/dropdown.js +0 -167
  79. package/autoInit/accessibility/functions/list-accessibility/README.md +0 -56
  80. package/autoInit/accessibility/functions/list-accessibility/list-accessibility.js +0 -23
  81. package/autoInit/accessibility/functions/text-synchronization/README.md +0 -62
  82. package/autoInit/accessibility/functions/text-synchronization/text-synchronization.js +0 -101
  83. package/autoInit/accessibility/functions/year-replacement/year-replacement.js +0 -43
  84. package/autoInit/button/README.md +0 -122
  85. package/autoInit/button/button.js +0 -51
  86. package/autoInit/counter/README.md +0 -274
  87. package/autoInit/counter/counter.js +0 -185
  88. package/autoInit/form/README.md +0 -338
  89. package/autoInit/form/form.js +0 -374
  90. package/autoInit/navbar/README.md +0 -366
  91. package/autoInit/navbar/navbar.js +0 -786
  92. package/autoInit/transition/transition.js +0 -116
  93. package/index.js +0 -305
  94. package/utils/before-after/README.md +0 -520
  95. package/utils/before-after/before-after.js +0 -653
  96. package/utils/css-animations/buttons/main/bgbasic/btn-main-bgbasic.html +0 -10
  97. package/utils/css-animations/buttons/main/bgfill/btn-main-bgfill.html +0 -29
  98. package/utils/css-animations/buttons/navbar/bgbasic/navbar-main-bgbasic.html +0 -17
  99. package/utils/css-animations/buttons/navbar/bgbasic/navbar-menu-bgbasic.html +0 -16
  100. package/utils/css-animations/buttons/navbar/bgfill/navbar-main-bgfill.html +0 -46
  101. package/utils/css-animations/buttons/navbar/bgfill/navbar-menu-bgfill.html +0 -39
  102. package/utils/css-animations/buttons/navbar/color/navbar-announce-color.html +0 -5
  103. package/utils/css-animations/buttons/navbar/color/navbar-main-color.html +0 -7
  104. package/utils/css-animations/buttons/navbar/color/navbar-menu-color.html +0 -7
  105. package/utils/css-animations/buttons/navbar/double-slide/navbar-announce-double-slide.html +0 -40
  106. package/utils/css-animations/buttons/navbar/double-slide/navbar-main-double-slide.html +0 -77
  107. package/utils/css-animations/buttons/navbar/scale/navbar-announce-scale.html +0 -6
  108. package/utils/css-animations/buttons/navbar/scale/navbar-main-scale.html +0 -9
  109. package/utils/css-animations/buttons/navbar/scale/navbar-menu-scale.html +0 -8
  110. package/utils/css-animations/buttons/navbar/underline/navbar-announce-underline.html +0 -32
  111. package/utils/css-animations/buttons/navbar/underline/navbar-main-underline.html +0 -56
  112. package/utils/css-animations/buttons/text/color/text-footer-color.html +0 -5
  113. package/utils/css-animations/buttons/text/color/text-main-color.html +0 -5
  114. package/utils/css-animations/buttons/text/double-slide/text-main-double-slide.html +0 -56
  115. package/utils/css-animations/buttons/text/scale/text-footer-scale.html +0 -6
  116. package/utils/css-animations/buttons/text/scale/text-main-scale.html +0 -6
  117. package/utils/css-animations/buttons/text/underline/text-footer-underline.html +0 -45
  118. package/utils/css-animations/buttons/text/underline/text-main-underline.html +0 -58
  119. package/utils/css-animations/cards/card-clickable.html +0 -11
  120. package/utils/css-animations/defaults.html +0 -69
@@ -1,116 +0,0 @@
1
- // Page Transition Module
2
- const API_NAME = "hsmain";
3
-
4
- export async function init() {
5
- // Store event handlers for cleanup
6
- let clickHandler = null;
7
- let resizeHandler = null;
8
- let pageShowHandler = null;
9
-
10
- const cleanup = () => {
11
- // Remove all event listeners
12
- if (clickHandler) {
13
- document.removeEventListener("click", clickHandler);
14
- clickHandler = null;
15
- }
16
- if (resizeHandler) {
17
- window.removeEventListener("resize", resizeHandler);
18
- resizeHandler = null;
19
- }
20
- if (pageShowHandler) {
21
- window.onpageshow = null;
22
- pageShowHandler = null;
23
- }
24
- };
25
-
26
- const initTransitions = () => {
27
- const transitionTrigger = document.querySelector('[data-hs-transition="trigger"]');
28
- const transitionElement = document.querySelector('[data-hs-transition="element"]');
29
-
30
- if (!transitionTrigger || !transitionElement) return;
31
-
32
- // Get exit time from data attribute (in seconds)
33
- const exitTimeAttr = transitionElement.getAttribute('data-hs-exit-time');
34
- const exitTime = exitTimeAttr ? parseFloat(exitTimeAttr) * 1000 : 0;
35
-
36
- // Get delay time for first load from data attribute (in seconds)
37
- const delayAttr = transitionElement.getAttribute('data-hs-delay');
38
- const delayTime = delayAttr ? parseFloat(delayAttr) * 1000 : 0;
39
-
40
- // Page Load - Trigger entrance animation
41
- // Check if this is the first page load of the session
42
- const isFirstLoad = !sessionStorage.getItem('transition-loaded');
43
-
44
- const triggerAnimation = () => {
45
- Webflow.push(function () {
46
- transitionTrigger.click();
47
- });
48
- };
49
-
50
- // If first load and delay is set, wait before triggering
51
- if (isFirstLoad && delayTime > 0) {
52
- setTimeout(triggerAnimation, delayTime);
53
- sessionStorage.setItem('transition-loaded', 'true');
54
- } else {
55
- // Subsequent loads or no delay: trigger immediately
56
- triggerAnimation();
57
- if (isFirstLoad) {
58
- sessionStorage.setItem('transition-loaded', 'true');
59
- }
60
- }
61
-
62
- // On Link Click
63
- clickHandler = function (e) {
64
- const link = e.target.closest("a");
65
-
66
- if (
67
- link &&
68
- link.hostname === window.location.hostname &&
69
- link.getAttribute("href") &&
70
- link.getAttribute("href").indexOf("#") === -1 &&
71
- link.getAttribute("target") !== "_blank"
72
- ) {
73
- e.preventDefault();
74
-
75
- let transitionURL = link.getAttribute("href");
76
-
77
- // Trigger exit animation
78
- transitionTrigger.click();
79
-
80
- // Wait for exit time, then navigate
81
- setTimeout(() => {
82
- window.location = transitionURL;
83
- }, exitTime);
84
- }
85
- };
86
- document.addEventListener("click", clickHandler);
87
-
88
- // On Back Button Tap
89
- pageShowHandler = function (event) {
90
- if (event.persisted) {
91
- window.location.reload();
92
- }
93
- };
94
- window.onpageshow = pageShowHandler;
95
-
96
- // Hide Transition on Window Width Resize
97
- resizeHandler = function () {
98
- if (transitionElement) {
99
- transitionElement.style.display = "none";
100
- }
101
- };
102
- window.addEventListener("resize", resizeHandler);
103
- };
104
-
105
- // Wait for Webflow to be ready before initializing transitions
106
- window[API_NAME].afterWebflowReady(() => {
107
- setTimeout(() => {
108
- initTransitions();
109
- }, 50);
110
- });
111
-
112
- return {
113
- result: "anim-transition initialized",
114
- destroy: cleanup
115
- };
116
- }
package/index.js DELETED
@@ -1,305 +0,0 @@
1
- const API_NAME = "hsmain";
2
-
3
- const initializeHsMain = async () => {
4
- if (
5
- window[API_NAME] &&
6
- !Array.isArray(window[API_NAME]) &&
7
- window[API_NAME].loaded
8
- ) {
9
- return;
10
- }
11
-
12
- // Add hs-main class to HTML element immediately
13
- document.documentElement.classList.add('hs-main');
14
-
15
- const queuedModules = Array.isArray(window[API_NAME]) ? window[API_NAME] : [];
16
-
17
- const animationModules = {};
18
-
19
- const utilityModules = {
20
- "data-hs-util-ba": true,
21
- };
22
-
23
- const allDataAttributes = { ...animationModules, ...utilityModules };
24
-
25
- const moduleMap = {
26
- transition: () => import("./autoInit/transition/transition.js"),
27
- "data-hs-util-ba": () => import("./utils/before-after/before-after.js"),
28
- "smooth-scroll": () => import("./autoInit/smooth-scroll/smooth-scroll.js"),
29
- navbar: () => import("./autoInit/navbar/navbar.js"),
30
- accessibility: () => import("./autoInit/accessibility/accessibility.js"),
31
- counter: () => import("./autoInit/counter/counter.js"),
32
- form: () => import("./autoInit/form/form.js"),
33
- "site-settings": () => import("./autoInit/site-settings/site-settings.js"),
34
- button: () => import("./autoInit/button/button.js"),
35
- };
36
-
37
- let scripts = [
38
- ...document.querySelectorAll(
39
- `script[type="module"][src="${import.meta.url}"]`,
40
- ),
41
- ];
42
-
43
- if (scripts.length === 0) {
44
- scripts = [
45
- ...document.querySelectorAll(
46
- 'script[type="module"][src*="@hortonstudio/main"]',
47
- ),
48
- ].filter((script) => {
49
- const scriptSrc = script.src;
50
- const currentSrc = import.meta.url;
51
- const scriptPackage = scriptSrc.match(
52
- /@hortonstudio\/main(@[\d.]+)?/,
53
- )?.[0];
54
- const currentPackage = currentSrc.match(
55
- /@hortonstudio\/main(@[\d.]+)?/,
56
- )?.[0];
57
- return (
58
- scriptPackage &&
59
- currentPackage &&
60
- scriptPackage.split("@")[0] === currentPackage.split("@")[0]
61
- );
62
- });
63
- }
64
-
65
- // Check if no-transition attribute is present on script tag
66
- const hasNoTransition = scripts[0]?.hasAttribute('no-transition');
67
-
68
- const autoInitModules = {
69
- "smooth-scroll": true,
70
- navbar: true,
71
- accessibility: true,
72
- counter: true,
73
- form: true,
74
- "site-settings": true,
75
- button: true,
76
- // Only include transition if no-transition attribute is NOT present
77
- ...(hasNoTransition ? {} : { transition: true }),
78
- };
79
-
80
- const loadModule = async (moduleName) => {
81
- const instance = window[API_NAME];
82
- if (instance.process.has(moduleName)) {
83
- return instance.modules[moduleName]?.loading;
84
- }
85
-
86
- instance.process.add(moduleName);
87
-
88
- const moduleData = instance.modules[moduleName] || {};
89
- instance.modules[moduleName] = moduleData;
90
-
91
- moduleData.loading = new Promise((resolve, reject) => {
92
- moduleData.resolve = resolve;
93
- moduleData.reject = reject;
94
- });
95
-
96
- try {
97
- const { init, version } = await moduleMap[moduleName]();
98
- const result = await init();
99
- const { result: initResult, destroy } = result || {};
100
-
101
- moduleData.version = version;
102
- moduleData.destroy = () => {
103
- destroy?.();
104
- instance.process.delete(moduleName);
105
- };
106
- moduleData.restart = () => {
107
- moduleData.destroy?.();
108
- instance.load(moduleName);
109
- };
110
-
111
- moduleData.resolve?.(initResult);
112
- delete moduleData.resolve;
113
- delete moduleData.reject;
114
-
115
- return initResult;
116
- } catch (error) {
117
- moduleData.reject?.(error);
118
- instance.process.delete(moduleName);
119
- throw error;
120
- }
121
- };
122
-
123
- const readyCallbacks = [];
124
-
125
- window[API_NAME] = {
126
- scripts,
127
- modules: {},
128
- process: new Set(),
129
- load: loadModule,
130
- loaded: false,
131
- barbaEnabled: false,
132
- embedScriptManager: null,
133
- barbaManager: null,
134
- push(...items) {
135
- for (const [moduleName, callback] of items) {
136
- if (typeof callback === "function") {
137
- this.modules[moduleName]?.loading?.then(callback);
138
- } else {
139
- this.load(moduleName);
140
- }
141
- }
142
- },
143
- destroy() {
144
- for (const moduleName in this.modules) {
145
- this.modules[moduleName]?.destroy?.();
146
- }
147
- },
148
- async reinitialize() {
149
- // Complete teardown and reinit
150
- this.loaded = false;
151
- this.destroy();
152
- this.modules = {};
153
- this.process = new Set();
154
-
155
- // Re-scan for modules including in w-embeds
156
- await this.scanForEmbedModules();
157
- processModules();
158
-
159
- // Wait for IX3 to be ready before marking as loaded
160
- await waitForIx3();
161
- this.loaded = true;
162
- },
163
- async scanForEmbedModules() {
164
- const embeds = document.querySelectorAll(".w-embed");
165
- embeds.forEach((embed) => {
166
- const scripts = embed.querySelectorAll("script[data-hs-module]");
167
- scripts.forEach((script) => {
168
- // Extract module info from data attributes
169
- const moduleType = script.getAttribute("data-hs-module-type");
170
- const moduleName = script.getAttribute("data-hs-module");
171
-
172
- if (moduleType && moduleName) {
173
- const moduleKey = `data-hs-${moduleType}-${moduleName}`;
174
- if (moduleMap[moduleKey]) {
175
- this.load(moduleKey);
176
- }
177
- }
178
- });
179
- });
180
- },
181
- async setBarbaMode(enabled) {
182
- this.barbaEnabled = enabled;
183
- if (enabled && !this.barbaManager) {
184
- try {
185
- const module = await import("./barba/barbaManager.js");
186
- this.barbaManager = module.initializeBarba();
187
- if (!this.barbaManager) {
188
- }
189
- } catch (error) {
190
- this.barbaEnabled = false;
191
- }
192
- }
193
- },
194
- enableBarba() {
195
- return this.setBarbaMode(true);
196
- },
197
- async initEmbedScriptManager() {
198
- if (!this.embedScriptManager) {
199
- const { EmbedScriptManager } = await import(
200
- "./barba/embedScriptManager.js"
201
- );
202
- this.embedScriptManager = new EmbedScriptManager();
203
- }
204
- return this.embedScriptManager;
205
- },
206
- afterReady(callback) {
207
- if (typeof callback === "function") {
208
- if (this.loaded) {
209
- callback();
210
- } else {
211
- readyCallbacks.push(callback);
212
- }
213
- }
214
- },
215
- afterWebflowReady(callback) {
216
- if (typeof callback === "function") {
217
- if (this.loaded) {
218
- callback();
219
- } else {
220
- readyCallbacks.push(callback);
221
- }
222
- }
223
- },
224
- status(moduleName) {
225
- if (moduleName) {
226
- return {
227
- loaded: !!this.modules[moduleName],
228
- loading: this.process.has(moduleName),
229
- };
230
- }
231
- return {
232
- loaded: Object.keys(this.modules),
233
- loading: [...this.process],
234
- animations: Object.keys(animationModules),
235
- utilities: Object.keys(utilityModules),
236
- autoInit: Object.keys(autoInitModules),
237
- barbaEnabled: this.barbaEnabled,
238
- };
239
- },
240
- };
241
-
242
- const processModules = () => {
243
- for (const script of scripts) {
244
- for (const attrName of Object.keys(allDataAttributes)) {
245
- if (script.hasAttribute(attrName)) {
246
- loadModule(attrName);
247
- }
248
- }
249
- }
250
-
251
- for (const moduleName of Object.keys(autoInitModules)) {
252
- loadModule(moduleName);
253
- }
254
-
255
- // Transition is now auto-loaded, so no need to hide transition elements
256
- };
257
-
258
- document.querySelectorAll(".w-richtext").forEach((richtext) => {
259
- richtext.querySelectorAll("img").forEach((img) => {
260
- img.loading = "eager";
261
- });
262
- });
263
-
264
- const waitForIx3 = async () => {
265
- const startTime = Date.now();
266
- const timeout = 2000; // 2 second timeout
267
-
268
- return new Promise((resolve) => {
269
- const checkIx3 = () => {
270
- const htmlElement = document.documentElement;
271
- const hasIx3 = htmlElement.classList.contains('w-mod-ix3');
272
-
273
- if (hasIx3) {
274
- resolve(true);
275
- } else if (Date.now() - startTime >= timeout) {
276
- console.warn('[hsmain] IX3 (w-mod-ix3) not detected after 2s timeout. Proceeding anyway, but Webflow interactions may not be fully loaded.');
277
- resolve(false);
278
- } else {
279
- setTimeout(checkIx3, 50);
280
- }
281
- };
282
- checkIx3();
283
- });
284
- };
285
-
286
- const finalize = async () => {
287
- processModules();
288
-
289
- // Wait for IX3 to be ready before firing callbacks
290
- await waitForIx3();
291
-
292
- window[API_NAME].loaded = true;
293
- readyCallbacks.forEach((callback) => {
294
- try {
295
- callback();
296
- } catch (error) {}
297
- });
298
- readyCallbacks.length = 0; // Clear array after execution
299
- };
300
-
301
- window[API_NAME].push(...queuedModules);
302
- finalize().catch(() => {});
303
- };
304
-
305
- initializeHsMain();