@hortonstudio/main 1.2.8 → 1.2.11

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.
@@ -1,5 +1,10 @@
1
1
  const API_NAME = 'hsmain';
2
2
 
3
+ // Check for reduced motion preference
4
+ const prefersReducedMotion = () => {
5
+ return window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
6
+ };
7
+
3
8
  // Animation timing (in seconds)
4
9
  const timing = {
5
10
  announce: 0,
@@ -119,12 +124,76 @@ function startHeroAnimations() {
119
124
  init();
120
125
  }
121
126
 
127
+ function showHeroElementsWithoutAnimation() {
128
+ // Simply show all hero elements without any animation or split text
129
+ const allHeroElements = [
130
+ ...document.querySelectorAll('[data-hs-hero="announce"]'),
131
+ ...document.querySelectorAll('[data-hs-hero="nav"]'),
132
+ ...document.querySelectorAll('[data-hs-hero="nav-menu"]'),
133
+ ...document.querySelectorAll('[data-hs-hero="nav-logo"]'),
134
+ ...document.querySelectorAll('[data-hs-hero="nav-button"] > *:first-child'),
135
+ ...document.querySelectorAll('[data-hs-hero="nav-list"] > * > *:first-child'),
136
+ ...document.querySelectorAll('[data-hs-hero="heading"] > *:first-child'),
137
+ ...document.querySelectorAll('[data-hs-hero="subheading"] > *:first-child'),
138
+ ...document.querySelectorAll('[data-hs-hero="tag"] > *:first-child'),
139
+ ...document.querySelectorAll('[data-hs-hero="button"] > *'),
140
+ ...document.querySelectorAll('[data-hs-hero="image"]'),
141
+ ...document.querySelectorAll('[data-hs-hero="appear"]')
142
+ ];
143
+
144
+ allHeroElements.forEach(element => {
145
+ if (element) {
146
+ gsap.set(element, {
147
+ autoAlpha: 1,
148
+ opacity: 1,
149
+ y: 0,
150
+ yPercent: 0
151
+ });
152
+ // Remove any pointer-events restrictions
153
+ element.style.pointerEvents = '';
154
+ }
155
+ });
156
+
157
+ // Restore page-wide tabbing
158
+ const allFocusableElements = document.querySelectorAll('[data-original-tabindex]');
159
+ allFocusableElements.forEach(el => {
160
+ el.style.pointerEvents = '';
161
+ const originalTabindex = el.getAttribute('data-original-tabindex');
162
+ if (originalTabindex === '0') {
163
+ el.removeAttribute('tabindex');
164
+ } else {
165
+ el.setAttribute('tabindex', originalTabindex);
166
+ }
167
+ el.removeAttribute('data-original-tabindex');
168
+ });
169
+ }
170
+
122
171
  export async function init() {
123
172
  if (typeof window.gsap === "undefined") {
124
173
  console.error('GSAP not found - hero animations disabled');
125
174
  return;
126
175
  }
127
176
 
177
+ if (prefersReducedMotion()) {
178
+ // For reduced motion, just show elements without animation
179
+ showHeroElementsWithoutAnimation();
180
+
181
+ // Still expose the API for consistency
182
+ window[API_NAME] = window[API_NAME] || {};
183
+ window[API_NAME].heroAnimations = {
184
+ config: config,
185
+ updateConfig: updateConfig,
186
+ start: startHeroAnimations,
187
+ kill: killHeroAnimations,
188
+ restart: () => {
189
+ killHeroAnimations();
190
+ startHeroAnimations();
191
+ }
192
+ };
193
+
194
+ return { result: 'anim-hero initialized (reduced motion)' };
195
+ }
196
+
128
197
  gsap.registerPlugin(ScrollTrigger, SplitText);
129
198
 
130
199
  // Element selection
@@ -1,5 +1,10 @@
1
1
  const API_NAME = 'hsmain';
2
2
 
3
+ // Check for reduced motion preference
4
+ const prefersReducedMotion = () => {
5
+ return window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
6
+ };
7
+
3
8
  const config = {
4
9
  global: {
5
10
  animationDelay: 0
@@ -62,6 +67,12 @@ function killTextAnimations() {
62
67
  }
63
68
 
64
69
  function startTextAnimations() {
70
+ if (prefersReducedMotion()) {
71
+ // For reduced motion, just show elements without animation
72
+ showElementsWithoutAnimation();
73
+ return;
74
+ }
75
+
65
76
  setInitialStates().then(() => {
66
77
  initAnimations();
67
78
  });
@@ -73,14 +84,36 @@ function waitForFonts() {
73
84
  return document.fonts.ready;
74
85
  }
75
86
 
87
+ function showElementsWithoutAnimation() {
88
+ // Simply show all text elements without any animation or split text
89
+ const allTextElements = [
90
+ ...document.querySelectorAll(".a-char-split > *:first-child"),
91
+ ...document.querySelectorAll(".a-word-split > *:first-child"),
92
+ ...document.querySelectorAll(".a-line-split > *:first-child"),
93
+ ...document.querySelectorAll('.a-appear')
94
+ ];
95
+
96
+ allTextElements.forEach(element => {
97
+ gsap.set(element, {
98
+ autoAlpha: 1,
99
+ y: 0,
100
+ yPercent: 0,
101
+ opacity: 1
102
+ });
103
+ });
104
+ }
105
+
76
106
  const CharSplitAnimations = {
77
107
  async initial() {
78
108
  await waitForFonts();
79
109
 
110
+ if (prefersReducedMotion()) {
111
+ return;
112
+ }
113
+
80
114
  const elements = document.querySelectorAll(".a-char-split > *:first-child");
81
115
 
82
- elements.forEach((textElement, index) => {
83
-
116
+ elements.forEach((textElement) => {
84
117
  const split = SplitText.create(textElement, {
85
118
  type: "chars",
86
119
  mask: "chars",
@@ -98,6 +131,10 @@ const CharSplitAnimations = {
98
131
  async animate() {
99
132
  await waitForFonts();
100
133
 
134
+ if (prefersReducedMotion()) {
135
+ return;
136
+ }
137
+
101
138
  document.querySelectorAll(".a-char-split > *:first-child").forEach((textElement) => {
102
139
  const chars = textElement.querySelectorAll('.char');
103
140
  const tl = gsap.timeline({
@@ -127,10 +164,13 @@ const WordSplitAnimations = {
127
164
  async initial() {
128
165
  await waitForFonts();
129
166
 
167
+ if (prefersReducedMotion()) {
168
+ return;
169
+ }
170
+
130
171
  const elements = document.querySelectorAll(".a-word-split > *:first-child");
131
172
 
132
- elements.forEach((textElement, index) => {
133
-
173
+ elements.forEach((textElement) => {
134
174
  const split = SplitText.create(textElement, {
135
175
  type: "words",
136
176
  mask: "words",
@@ -148,6 +188,10 @@ const WordSplitAnimations = {
148
188
  async animate() {
149
189
  await waitForFonts();
150
190
 
191
+ if (prefersReducedMotion()) {
192
+ return;
193
+ }
194
+
151
195
  document.querySelectorAll(".a-word-split > *:first-child").forEach((textElement) => {
152
196
  const words = textElement.querySelectorAll('.word');
153
197
  const tl = gsap.timeline({
@@ -177,10 +221,13 @@ const LineSplitAnimations = {
177
221
  async initial() {
178
222
  await waitForFonts();
179
223
 
224
+ if (prefersReducedMotion()) {
225
+ return;
226
+ }
227
+
180
228
  const elements = document.querySelectorAll(".a-line-split > *:first-child");
181
229
 
182
- elements.forEach((textElement, index) => {
183
-
230
+ elements.forEach((textElement) => {
184
231
  const split = SplitText.create(textElement, {
185
232
  type: "lines",
186
233
  mask: "lines",
@@ -198,6 +245,10 @@ const LineSplitAnimations = {
198
245
  async animate() {
199
246
  await waitForFonts();
200
247
 
248
+ if (prefersReducedMotion()) {
249
+ return;
250
+ }
251
+
201
252
  document.querySelectorAll(".a-line-split > *:first-child").forEach((textElement) => {
202
253
  const lines = textElement.querySelectorAll('.line');
203
254
  const tl = gsap.timeline({
@@ -227,6 +278,10 @@ const AppearAnimations = {
227
278
  async initial() {
228
279
  await waitForFonts();
229
280
 
281
+ if (prefersReducedMotion()) {
282
+ return;
283
+ }
284
+
230
285
  const elements = document.querySelectorAll('.a-appear');
231
286
  elements.forEach(element => {
232
287
  gsap.set(element, {
@@ -239,6 +294,10 @@ const AppearAnimations = {
239
294
  async animate() {
240
295
  await waitForFonts();
241
296
 
297
+ if (prefersReducedMotion()) {
298
+ return;
299
+ }
300
+
242
301
  document.querySelectorAll('.a-appear').forEach(element => {
243
302
  const tl = gsap.timeline({
244
303
  scrollTrigger: {
@@ -284,8 +343,13 @@ async function initAnimations() {
284
343
  }
285
344
 
286
345
  export async function init() {
287
- await setInitialStates();
288
- initAnimations();
346
+ if (prefersReducedMotion()) {
347
+ // For reduced motion, just show elements without animation
348
+ showElementsWithoutAnimation();
349
+ } else {
350
+ await setInitialStates();
351
+ initAnimations();
352
+ }
289
353
 
290
354
  window.addEventListener('resize', ScrollTrigger.refresh());
291
355
 
package/index.js CHANGED
@@ -1,16 +1,11 @@
1
- // ver 1.2.6
1
+ // ver 1.2.11
2
2
 
3
3
  const API_NAME = 'hsmain';
4
4
 
5
- console.log(`🟢 ${API_NAME} v1.2.6 initializing...`);
6
- console.log('🔍 DOM state:', document.readyState);
7
- console.log('🔍 Script URL:', import.meta.url);
8
-
9
5
  // Main initialization function
10
6
  const initializeHsMain = () => {
11
7
  // Handle existing API
12
8
  if (window[API_NAME] && !Array.isArray(window[API_NAME]) && window[API_NAME].loaded) {
13
- console.log('⚠️ API already loaded, skipping initialization');
14
9
  return;
15
10
  }
16
11
 
@@ -39,8 +34,6 @@ const initializeHsMain = () => {
39
34
 
40
35
  // Dynamic module loader (like Finsweet)
41
36
  const loadModule = async (moduleName) => {
42
- console.log(`📦 Loading module: ${moduleName}`);
43
-
44
37
  switch (moduleName) {
45
38
  case "data-hs-anim-text":
46
39
  return import(new URL('./animations/text.js', import.meta.url).href);
@@ -57,7 +50,6 @@ const initializeHsMain = () => {
57
50
  case "smooth-scroll":
58
51
  return import(new URL('./autoInit/smooth-scroll.js', import.meta.url).href);
59
52
  default:
60
- console.error(`❌ Unsupported module: ${moduleName}`);
61
53
  throw new Error(`${API_NAME} module "${moduleName}" is not supported.`);
62
54
  }
63
55
  };
@@ -83,22 +75,17 @@ const initializeHsMain = () => {
83
75
 
84
76
  // Find script tags (Finsweet approach)
85
77
  const scripts = [...document.querySelectorAll(`script[type="module"][src="${import.meta.url}"]`)];
86
- console.log(`📄 Found ${scripts.length} matching script tags`);
87
78
 
88
79
  // Module loading function
89
80
  const loadHsModule = async (moduleName) => {
90
- console.log(`🔄 loadHsModule called for: ${moduleName}`);
91
-
92
81
  const apiInstance = window[API_NAME];
93
82
 
94
83
  // Check if already processing
95
84
  if (apiInstance.process.has(moduleName)) {
96
- console.log(`⚠️ Module ${moduleName} already processing`);
97
85
  return apiInstance.modules[moduleName]?.loading;
98
86
  }
99
87
 
100
88
  // Add to processing set
101
- console.log(`➕ Adding ${moduleName} to process set`);
102
89
  apiInstance.process.add(moduleName);
103
90
 
104
91
  // Create module object
@@ -112,14 +99,9 @@ const initializeHsMain = () => {
112
99
  });
113
100
 
114
101
  try {
115
- console.log(`📦 Importing ${moduleName}...`);
116
102
  const { init, version } = await loadModule(moduleName);
117
- console.log(`✅ ${moduleName} imported, version: ${version}`);
118
-
119
- console.log(`🔧 Initializing ${moduleName}...`);
120
103
  const initResult = await init();
121
104
  const { result, destroy } = initResult || {};
122
- console.log(`✅ ${moduleName} initialized:`, result);
123
105
 
124
106
  moduleObj.version = version;
125
107
 
@@ -141,7 +123,6 @@ const initializeHsMain = () => {
141
123
  return result;
142
124
 
143
125
  } catch (error) {
144
- console.error(`❌ Failed to load ${moduleName}:`, error);
145
126
  moduleObj.reject?.(error);
146
127
  apiInstance.process.delete(moduleName);
147
128
  throw error;
@@ -219,19 +200,13 @@ const initializeHsMain = () => {
219
200
 
220
201
  // Process modules from script tags
221
202
  const processScriptModules = () => {
222
- console.log(`⚙️ Processing ${scripts.length} script tags`);
223
-
224
203
  for (const script of scripts) {
225
- console.log(`🏷️ Processing script:`, script.src);
226
-
227
204
  // Check for auto mode
228
205
  const autoMode = script.getAttribute('data-hs-auto') === 'true';
229
- console.log(`🔍 Auto mode: ${autoMode}`);
230
206
 
231
207
  // Load modules based on script attributes
232
208
  for (const moduleName of Object.keys(allModules)) {
233
209
  if (script.hasAttribute(moduleName)) {
234
- console.log(`✅ Found attribute for: ${moduleName}`);
235
210
  loadHsModule(moduleName);
236
211
  }
237
212
  }
@@ -239,7 +214,6 @@ const initializeHsMain = () => {
239
214
  // Auto-discovery mode
240
215
  if (autoMode) {
241
216
  waitDOMReady().then(() => {
242
- console.log(`🔍 Starting auto-discovery...`);
243
217
  const foundModules = new Set();
244
218
  const allElements = document.querySelectorAll('*');
245
219
 
@@ -253,7 +227,6 @@ const initializeHsMain = () => {
253
227
  }
254
228
  }
255
229
 
256
- console.log(`🔍 Auto-discovered modules:`, [...foundModules]);
257
230
  for (const moduleName of foundModules) {
258
231
  loadHsModule(moduleName);
259
232
  }
@@ -262,7 +235,6 @@ const initializeHsMain = () => {
262
235
  }
263
236
 
264
237
  // Always load auto-init modules
265
- console.log(`🔄 Loading auto-init modules:`, Object.keys(autoInitModules));
266
238
  for (const moduleName of Object.keys(autoInitModules)) {
267
239
  loadHsModule(moduleName);
268
240
  }
@@ -288,40 +260,31 @@ const initializeHsMain = () => {
288
260
 
289
261
  // Main initialization
290
262
  const initializeMain = async () => {
291
- console.log(`🚀 Starting main initialization...`);
292
-
293
263
  // Process script modules
294
264
  processScriptModules();
295
265
 
296
266
  // Wait for Webflow
297
- console.log(`⏳ Waiting for Webflow...`);
298
267
  await waitWebflowReady();
299
- console.log(`✅ Webflow ready`);
300
268
 
301
269
  // Mark as loaded
302
270
  window[API_NAME].loaded = true;
303
271
 
304
272
  // Run all registered post-Webflow callbacks
305
- console.log(`🔄 Running ${postWebflowCallbacks.length} post-Webflow callbacks`);
306
- postWebflowCallbacks.forEach((callback, index) => {
273
+ postWebflowCallbacks.forEach((callback) => {
307
274
  try {
308
- console.log(`📞 Executing callback ${index + 1}/${postWebflowCallbacks.length}`);
309
275
  callback();
310
276
  } catch (error) {
311
- console.error(`❌ Callback ${index + 1} failed:`, error);
277
+ // Silent fail for callbacks
312
278
  }
313
279
  });
314
-
315
- console.log(`🎉 ${API_NAME} fully loaded and ready!`);
316
280
  };
317
281
 
318
282
  // Process any early requests
319
- console.log(`📝 Processing ${existingRequests.length} early requests`);
320
283
  window[API_NAME].push(...existingRequests);
321
284
 
322
285
  // Start initialization
323
- initializeMain().catch(error => {
324
- console.error(`❌ Failed to initialize ${API_NAME}:`, error);
286
+ initializeMain().catch(() => {
287
+ // Silent fail for initialization
325
288
  });
326
289
  };
327
290
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hortonstudio/main",
3
- "version": "1.2.8",
3
+ "version": "1.2.11",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "scripts": {