unframer 4.1.2 → 4.1.3

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.
package/dist/framer.js CHANGED
@@ -12407,7 +12407,7 @@ function ReorderItemComponent({
12407
12407
  }
12408
12408
  var ReorderItem = /* @__PURE__ */ forwardRef(ReorderItemComponent,);
12409
12409
 
12410
- // /:https://app.framerstatic.com/framer.EHXVWJCS.mjs
12410
+ // /:https://app.framerstatic.com/framer.URNEVXQW.mjs
12411
12411
 
12412
12412
  import React42 from 'react';
12413
12413
  import { startTransition as startTransition2, } from 'react';
@@ -15072,8 +15072,20 @@ function fillPathVariables(path, variables,) {
15072
15072
  return encodeURIComponent(value,);
15073
15073
  },);
15074
15074
  }
15075
- function forwardCurrentQueryParams(href,) {
15076
- const queryParamsString = typeof __unframerWindow2 !== 'undefined' ? __unframerWindow2.location.search : '';
15075
+ function forwardCurrentQueryParams(href, ignoreBackAnchor = false,) {
15076
+ let queryParamsString = '';
15077
+ if (typeof __unframerWindow2 !== 'undefined') {
15078
+ if (ignoreBackAnchor) {
15079
+ queryParamsString = __unframerWindow2.location.search;
15080
+ } else {
15081
+ const backAnchor = __unframerWindow2.history?.state?.queryParamBackAnchorSearch;
15082
+ if (backAnchor === void 0) {
15083
+ queryParamsString = __unframerWindow2.location.search;
15084
+ } else {
15085
+ queryParamsString = backAnchor === '' ? '' : `?${backAnchor}`;
15086
+ }
15087
+ }
15088
+ }
15077
15089
  if (!queryParamsString) {
15078
15090
  return href;
15079
15091
  }
@@ -15198,7 +15210,7 @@ async function getLocalizedNavigationPath({
15198
15210
  result.path = '/' + nextLocale.slug + result.path;
15199
15211
  }
15200
15212
  if (preserveQueryParams && result.path) {
15201
- result.path = forwardCurrentQueryParams(result.path,);
15213
+ result.path = forwardCurrentQueryParams(result.path, true,);
15202
15214
  }
15203
15215
  return result;
15204
15216
  }
@@ -15820,9 +15832,13 @@ function useReplaceInitialState({
15820
15832
  useLayoutEffect(() => {
15821
15833
  if (disabled) return;
15822
15834
  performance.mark('framer-history-set-initial-state',);
15835
+ const currentState = isObject2(__unframerWindow2.history.state,) ? __unframerWindow2.history.state : {};
15836
+ const initialHash = __unframerWindow2.location.hash ? __unframerWindow2.location.hash.slice(1,) : void 0;
15823
15837
  replaceHistoryState(
15824
15838
  {
15839
+ ...currentState,
15825
15840
  routeId,
15841
+ hash: initialHash,
15826
15842
  pathVariables: initialPathVariables,
15827
15843
  localeId: initialLocaleId,
15828
15844
  },
@@ -15937,7 +15953,7 @@ function getPathForRoute(route, {
15937
15953
  if (pathVariables) {
15938
15954
  path = path.replace(pathVariablesRegExp, (m2, p1,) => String(pathVariables[p1] || m2,),);
15939
15955
  }
15940
- const isSamePageHashNavigation = currentPath === path && resolvedHash;
15956
+ const isSamePageHashNavigation = Boolean(currentPath === path && resolvedHash,);
15941
15957
  if (relative2) {
15942
15958
  if (customNotFoundPagePaths.has(currentPath,) && typeof __unframerWindow2 !== 'undefined') {
15943
15959
  const sitePrefix = getSitePrefix(siteCanonicalURL,);
@@ -15947,7 +15963,7 @@ function getPathForRoute(route, {
15947
15963
  }
15948
15964
  }
15949
15965
  if (preserveQueryParams || isSamePageHashNavigation) {
15950
- path = forwardCurrentQueryParams(path,);
15966
+ path = forwardCurrentQueryParams(path, isSamePageHashNavigation,);
15951
15967
  }
15952
15968
  if (resolvedHash) {
15953
15969
  path = `${path}#${resolvedHash}`;
@@ -22662,6 +22678,7 @@ var ControlType = /* @__PURE__ */ ((ControlType2) => {
22662
22678
  ControlType2['TrackingId'] = 'trackingid';
22663
22679
  ControlType2['VectorSetItem'] = 'vectorsetitem';
22664
22680
  ControlType2['LinkRelValues'] = 'linkrelvalues';
22681
+ ControlType2['Location'] = 'location';
22665
22682
  return ControlType2;
22666
22683
  })(ControlType || {},);
22667
22684
  function getNavigator() {
@@ -23307,7 +23324,7 @@ function useCustomValidity(onValid, onInvalid, onChange, onBlur, onFocus,) {
23307
23324
  }, [handleInvalid, handleChange, handleBlur, onFocus,],);
23308
23325
  }
23309
23326
  var rightIconSpacing = 10;
23310
- var leftIconSpacing = 8;
23327
+ var iconSpacing = 8;
23311
23328
  var iconSize = 16;
23312
23329
  var iconImageCSS = /* @__PURE__ */ (() => ({
23313
23330
  backgroundRepeat: 'no-repeat',
@@ -24508,6 +24525,7 @@ function getControlDefaultValue(control,) {
24508
24525
  case 'border':
24509
24526
  return isObject2(control.defaultValue,) ? control.defaultValue : void 0;
24510
24527
  case 'font':
24528
+ case 'location':
24511
24529
  return isObject2(control.defaultValue,) ? control.defaultValue : void 0;
24512
24530
  case 'linkrelvalues':
24513
24531
  return isArray(control.defaultValue,) ? control.defaultValue : void 0;
@@ -36882,9 +36900,15 @@ var CustomCursorComponent = /* @__PURE__ */ memo2(function CustomCursorComponent
36882
36900
  document.body.classList.toggle(replaceCursorClassName, replaceNativeCursor,);
36883
36901
  }, [replaceNativeCursor, hasHoverCapability,],);
36884
36902
  const Cursor = cursor?.component;
36885
- const spring2 = cursor?.transition ?? {
36903
+ const springRaw = cursor?.transition ?? {
36886
36904
  duration: 0,
36887
36905
  };
36906
+ const spring2 = springRaw.duration !== void 0
36907
+ ? {
36908
+ ...springRaw,
36909
+ duration: springRaw.duration * 1e3,
36910
+ }
36911
+ : springRaw;
36888
36912
  const sprungX = useSpring(pointerX, spring2,);
36889
36913
  const sprungY = useSpring(pointerY, spring2,);
36890
36914
  const x = useTransform(() => sprungX.get() + (cursor?.offset?.x ?? 0));
@@ -39044,19 +39068,21 @@ var HoneypotInput = ({
39044
39068
  'data-bwignore': true,
39045
39069
  },);
39046
39070
  };
39047
- function useHoneypotFields() {
39071
+ function useHoneypotFields(isEnabled,) {
39048
39072
  const framerSiteId = React42.useContext(FormContext,);
39049
39073
  const states = React42.useMemo(() =>
39050
- COMMON_FIELD_NAMES.map((fieldName) => {
39051
- return {
39052
- inputRef: React42.createRef(),
39053
- originalName: fieldName,
39054
- methodsUsed: {
39055
- setAttribute: false,
39056
- valueProperty: false,
39057
- },
39058
- };
39059
- },), [],);
39074
+ isEnabled
39075
+ ? COMMON_FIELD_NAMES.map((fieldName) => {
39076
+ return {
39077
+ inputRef: React42.createRef(),
39078
+ originalName: fieldName,
39079
+ methodsUsed: {
39080
+ setAttribute: false,
39081
+ valueProperty: false,
39082
+ },
39083
+ };
39084
+ },)
39085
+ : [], [isEnabled,],);
39060
39086
  const convertHoneypotFieldsForSubmission = React42.useCallback(() => {
39061
39087
  states.forEach((state) => {
39062
39088
  const currentHoneypotInput = state.inputRef.current;
@@ -39066,6 +39092,7 @@ function useHoneypotFields() {
39066
39092
  },);
39067
39093
  }, [states,],);
39068
39094
  const replaceHoneypotWithMetadata = React42.useCallback((formData) => {
39095
+ if (!isEnabled) return;
39069
39096
  const honeypotCount = states.length;
39070
39097
  let honeypotFilled = 0;
39071
39098
  const filledFieldsData = [];
@@ -39097,7 +39124,7 @@ function useHoneypotFields() {
39097
39124
  formData.append(`${HONEYPOT_FIELD_NAME}_${METADATA_KEYS_ENUM.hpVersion}`, HONEYPOT_VERSION,);
39098
39125
  formData.append(`${HONEYPOT_FIELD_NAME}_${METADATA_KEYS_ENUM.siteId}`, framerSiteId || '',);
39099
39126
  formData.append(`${HONEYPOT_FIELD_NAME}_${METADATA_KEYS_ENUM.timeToSubmissionSinceModuleLoad}`, getTimeSinceModuleLoadInSeconds(),);
39100
- }, [states, framerSiteId,],);
39127
+ }, [isEnabled, states, framerSiteId,],);
39101
39128
  return {
39102
39129
  states,
39103
39130
  convertHoneypotFieldsForSubmission,
@@ -39204,15 +39231,18 @@ var FormContainer = /* @__PURE__ */ React42.forwardRef(function FormContainer2({
39204
39231
  onLoading,
39205
39232
  submitTrackingId,
39206
39233
  nodeId,
39234
+ formCaptchaProvider,
39235
+ formCaptchaSiteKey,
39207
39236
  ...props
39208
39237
  }, forwardedRef,) {
39209
39238
  const fallbackRef = React42.useRef(null,);
39210
39239
  const ref = forwardedRef ?? fallbackRef;
39240
+ const shouldUseHoneypot = !(formCaptchaProvider && formCaptchaSiteKey);
39211
39241
  const {
39212
39242
  states: honeypotStateRefs,
39213
39243
  convertHoneypotFieldsForSubmission,
39214
39244
  replaceHoneypotWithMetadata,
39215
- } = useHoneypotFields();
39245
+ } = useHoneypotFields(shouldUseHoneypot,);
39216
39246
  const router = useRouter();
39217
39247
  const currentRoute = useCurrentRoute();
39218
39248
  const implicitPathVariables = useImplicitPathVariables();
@@ -39348,7 +39378,7 @@ var FormContainer = /* @__PURE__ */ React42.forwardRef(function FormContainer2({
39348
39378
  ref,
39349
39379
  children: [
39350
39380
  children(state,),
39351
- /* @__PURE__ */ jsx(HoneypotFields, {
39381
+ shouldUseHoneypot && /* @__PURE__ */ jsx(HoneypotFields, {
39352
39382
  states: honeypotStateRefs,
39353
39383
  },),
39354
39384
  ],
@@ -39623,7 +39653,7 @@ var TriggerState = class {
39623
39653
  if (!triggerEntry || triggerEntry.status !== 'pending') return;
39624
39654
  const handler = (eventPayload) => {
39625
39655
  if (triggerEntry?.status !== 'pending') return;
39626
- this.evaulateAndInvoke(triggerId, eventPayload,);
39656
+ this.evaluateAndInvoke(triggerId, eventPayload,);
39627
39657
  };
39628
39658
  let state = this.events.get(event,);
39629
39659
  if (!state) {
@@ -39651,7 +39681,7 @@ var TriggerState = class {
39651
39681
  reevaluatePendingTriggers() {
39652
39682
  for (const [triggerId, triggerEntry,] of this.triggers.entries()) {
39653
39683
  if (triggerEntry.status === 'pending') {
39654
- this.evaulateAndInvoke(triggerId,);
39684
+ this.evaluateAndInvoke(triggerId,);
39655
39685
  }
39656
39686
  }
39657
39687
  }
@@ -39771,7 +39801,7 @@ var TriggerState = class {
39771
39801
  if (schedule.endAt && /* @__PURE__ */ new Date(`${schedule.endAt}${schedule.endAtOffset ?? ''}`,) < now2) return false;
39772
39802
  return true;
39773
39803
  }
39774
- evaulateAndInvoke(triggerId, eventPayload,) {
39804
+ evaluateAndInvoke(triggerId, eventPayload,) {
39775
39805
  if (this.evaluate(triggerId, eventPayload,)) {
39776
39806
  this.invoke(triggerId,);
39777
39807
  }
@@ -39811,7 +39841,7 @@ var TriggerState = class {
39811
39841
  this.delayTimeouts.set(
39812
39842
  triggerId,
39813
39843
  setTimeout(() => {
39814
- this.evaulateAndInvoke(triggerId,);
39844
+ this.evaluateAndInvoke(triggerId,);
39815
39845
  }, initial + condition.delayMs - Date.now(),),
39816
39846
  );
39817
39847
  }
@@ -40726,48 +40756,50 @@ function Router({
40726
40756
  value: localeInfo,
40727
40757
  children: /* @__PURE__ */ jsx(LayoutDirectionContext.Provider, {
40728
40758
  value: layoutDirection,
40729
- children: /* @__PURE__ */ jsx(URLSearchParamsProvider, {
40730
- children: /* @__PURE__ */ jsxs(TriggerStateProvider, {
40731
- currentRoutePath: pathWithFilledVariables,
40732
- routerAPI: api,
40733
- children: [
40734
- EditorBar && /* @__PURE__ */ jsx(EditorBarLauncher, {
40735
- EditorBar,
40736
- fast: true,
40737
- },),
40738
- /* @__PURE__ */ jsx(SynchronousSuspenseErrorBoundary, {
40739
- children: /* @__PURE__ */ jsxs(SuspenseThatPreservesDom, {
40740
- children: [
40741
- /* @__PURE__ */ jsxs(NotFoundErrorBoundary, {
40742
- notFoundPage,
40743
- defaultPageStyle,
40744
- forceUpdateKey: dep,
40745
- children: [
40746
- /* @__PURE__ */ jsx(MarkSuspenseEffects.Start, {},),
40747
- /* @__PURE__ */ jsx(WithLayoutTemplate, {
40748
- LayoutTemplate,
40749
- webPageId: currentRoute?.abTestingVariantId ?? currentRouteId,
40750
- style: defaultPageStyle,
40751
- children: (inLayoutTemplate) => {
40752
- return /* @__PURE__ */ jsx(Fragment, {
40753
- children: pageExistsInCurrentLocale
40754
- ? renderPage(currentRoute.page, inLayoutTemplate ? templatePageStyle : defaultPageStyle,)
40755
- : // LAYOUT_TEMPLATE @TODO: display: content for not found page?
40756
- notFoundPage && renderPage(notFoundPage, defaultPageStyle,),
40757
- }, remountKey,);
40758
- },
40759
- },),
40760
- ],
40761
- },),
40762
- EditorBar && /* @__PURE__ */ jsx(EditorBarLauncher, {
40763
- EditorBar,
40764
- },),
40765
- /* @__PURE__ */ jsx(TurnOnReactEventHandling, {},),
40766
- /* @__PURE__ */ jsx(MarkSuspenseEffects.End, {},),
40767
- ],
40759
+ children: /* @__PURE__ */ jsx(CustomCursorHost, {
40760
+ children: /* @__PURE__ */ jsx(URLSearchParamsProvider, {
40761
+ children: /* @__PURE__ */ jsxs(TriggerStateProvider, {
40762
+ currentRoutePath: pathWithFilledVariables,
40763
+ routerAPI: api,
40764
+ children: [
40765
+ EditorBar && /* @__PURE__ */ jsx(EditorBarLauncher, {
40766
+ EditorBar,
40767
+ fast: true,
40768
40768
  },),
40769
- },),
40770
- ],
40769
+ /* @__PURE__ */ jsx(SynchronousSuspenseErrorBoundary, {
40770
+ children: /* @__PURE__ */ jsxs(SuspenseThatPreservesDom, {
40771
+ children: [
40772
+ /* @__PURE__ */ jsxs(NotFoundErrorBoundary, {
40773
+ notFoundPage,
40774
+ defaultPageStyle,
40775
+ forceUpdateKey: dep,
40776
+ children: [
40777
+ /* @__PURE__ */ jsx(MarkSuspenseEffects.Start, {},),
40778
+ /* @__PURE__ */ jsx(WithLayoutTemplate, {
40779
+ LayoutTemplate,
40780
+ webPageId: currentRoute?.abTestingVariantId ?? currentRouteId,
40781
+ style: defaultPageStyle,
40782
+ children: (inLayoutTemplate) => {
40783
+ return /* @__PURE__ */ jsx(Fragment, {
40784
+ children: pageExistsInCurrentLocale
40785
+ ? renderPage(currentRoute.page, inLayoutTemplate ? templatePageStyle : defaultPageStyle,)
40786
+ : // LAYOUT_TEMPLATE @TODO: display: content for not found page?
40787
+ notFoundPage && renderPage(notFoundPage, defaultPageStyle,),
40788
+ }, remountKey,);
40789
+ },
40790
+ },),
40791
+ ],
40792
+ },),
40793
+ EditorBar && /* @__PURE__ */ jsx(EditorBarLauncher, {
40794
+ EditorBar,
40795
+ },),
40796
+ /* @__PURE__ */ jsx(TurnOnReactEventHandling, {},),
40797
+ /* @__PURE__ */ jsx(MarkSuspenseEffects.End, {},),
40798
+ ],
40799
+ },),
40800
+ },),
40801
+ ],
40802
+ },),
40771
40803
  },),
40772
40804
  },),
40773
40805
  },),
@@ -41309,31 +41341,29 @@ function PageRoot(props,) {
41309
41341
  children: /* @__PURE__ */ jsx(CollectionUtilsCacheProvider, {
41310
41342
  collectionUtils,
41311
41343
  children: /* @__PURE__ */ jsx(FetchClientProvider, {
41312
- children: /* @__PURE__ */ jsx(CustomCursorHost, {
41313
- children: /* @__PURE__ */ jsx(FormContext.Provider, {
41314
- value: framerSiteId,
41315
- children: /* @__PURE__ */ jsx(SnippetsProvider, {
41316
- loadSnippetsModule,
41317
- children: /* @__PURE__ */ jsx(Router, {
41318
- initialRoute: routeId,
41319
- initialPathVariables: pathVariables,
41320
- initialLocaleId: localeId,
41321
- initialCollectionItemId,
41322
- routes,
41323
- collectionUtils,
41324
- notFoundPage,
41325
- locales,
41326
- defaultPageStyle: defaultPageStyle ?? {
41327
- minHeight: '100vh',
41328
- width: 'auto',
41329
- },
41330
- preserveQueryParams,
41331
- EditorBar,
41332
- disableHistory,
41333
- LayoutTemplate,
41334
- siteCanonicalURL,
41335
- adaptLayoutToTextDirection,
41336
- },),
41344
+ children: /* @__PURE__ */ jsx(FormContext.Provider, {
41345
+ value: framerSiteId,
41346
+ children: /* @__PURE__ */ jsx(SnippetsProvider, {
41347
+ loadSnippetsModule,
41348
+ children: /* @__PURE__ */ jsx(Router, {
41349
+ initialRoute: routeId,
41350
+ initialPathVariables: pathVariables,
41351
+ initialLocaleId: localeId,
41352
+ initialCollectionItemId,
41353
+ routes,
41354
+ collectionUtils,
41355
+ notFoundPage,
41356
+ locales,
41357
+ defaultPageStyle: defaultPageStyle ?? {
41358
+ minHeight: '100vh',
41359
+ width: 'auto',
41360
+ },
41361
+ preserveQueryParams,
41362
+ EditorBar,
41363
+ disableHistory,
41364
+ LayoutTemplate,
41365
+ siteCanonicalURL,
41366
+ adaptLayoutToTextDirection,
41337
41367
  },),
41338
41368
  },),
41339
41369
  },),
@@ -47159,8 +47189,8 @@ function useLoadMorePagination(totalSize, pageSize, hash2, paginateWithSuspended
47159
47189
  continueAfter: 'paint',
47160
47190
  },);
47161
47191
  if (currentPageRef.current >= totalPages) return;
47162
- const renderNextPage = (startTransition222) => {
47163
- startTransition222(() => {
47192
+ const renderNextPage = (startTransition23) => {
47193
+ startTransition23(() => {
47164
47194
  setCurrentPage((_currentPage) => {
47165
47195
  const nextPage = Math.min(_currentPage + 1, totalPages,);
47166
47196
  currentPageRef.current = nextPage;
@@ -48922,8 +48952,9 @@ var builtInUniforms = {
48922
48952
  },
48923
48953
  };
48924
48954
  var webGLContextLostEvent = 'webglcontextlost';
48955
+ var noop5 = () => {};
48925
48956
  var WebGL2ShaderRenderer = class {
48926
- constructor(canvas, vertexSource, fragmentSource, resolutionScale,) {
48957
+ constructor(canvas, vertexSource, fragmentSource, resolutionScale, onContextLostHandler = noop5,) {
48927
48958
  __publicField(this, 'gl',);
48928
48959
  __publicField(this, 'program',);
48929
48960
  __publicField(this, 'vao',);
@@ -48937,9 +48968,11 @@ var WebGL2ShaderRenderer = class {
48937
48968
  __publicField(this, 'pixelRatio', typeof __unframerWindow2 !== 'undefined' ? __unframerWindow2.devicePixelRatio : 1,);
48938
48969
  __publicField(this, 'resolutionScale',);
48939
48970
  __publicField(this, 'lastBufferWidth', 0,);
48971
+ __publicField(this, 'onContextLost',);
48940
48972
  __publicField(this, 'lastBufferHeight', 0,);
48941
48973
  this.resolutionScale = resolutionScale;
48942
48974
  this.canvas = canvas;
48975
+ this.onContextLost = onContextLostHandler;
48943
48976
  const gl = canvas.getContext('webgl2', {
48944
48977
  alpha: true,
48945
48978
  premultipliedAlpha: false,
@@ -48984,6 +49017,7 @@ var WebGL2ShaderRenderer = class {
48984
49017
  this.contextLostHandler = (event) => {
48985
49018
  event.preventDefault();
48986
49019
  this.dispose();
49020
+ this.onContextLost?.();
48987
49021
  };
48988
49022
  canvas.addEventListener(webGLContextLostEvent, this.contextLostHandler,);
48989
49023
  }
@@ -49030,9 +49064,8 @@ var WebGL2ShaderRenderer = class {
49030
49064
  if (canvas instanceof OffscreenCanvas) {
49031
49065
  throw new Error('resize() is not supported for OffscreenCanvas.',);
49032
49066
  }
49033
- const rect = canvas.getBoundingClientRect();
49034
- const cssWidth = Math.min(rect.width, canvas.offsetWidth,);
49035
- const cssHeight = Math.min(rect.height, canvas.offsetHeight,);
49067
+ const cssWidth = canvas.offsetWidth;
49068
+ const cssHeight = canvas.offsetHeight;
49036
49069
  const dpr = __unframerWindow2.devicePixelRatio;
49037
49070
  const effectiveDpr = Math.max(dpr * this.resolutionScale, 1,);
49038
49071
  this.pixelRatio = effectiveDpr;
@@ -49358,16 +49391,73 @@ var ShaderFallbackImage = /* @__PURE__ */ memo2(function ShaderFallbackImage2({
49358
49391
  alt: '',
49359
49392
  },);
49360
49393
  },);
49394
+ function parseCSSVarRange(input, from = 0,) {
49395
+ const varIndex = input.indexOf('var(', from,);
49396
+ if (varIndex === -1) return null;
49397
+ const start2 = varIndex + 4;
49398
+ let parens = 1;
49399
+ let commaIndex;
49400
+ for (let index = start2; index < input.length; index++) {
49401
+ if (input[index] === '(') {
49402
+ parens++;
49403
+ } else if (input[index] === ')') {
49404
+ parens--;
49405
+ if (parens === 0) {
49406
+ return {
49407
+ start: varIndex,
49408
+ end: index + 1,
49409
+ commaIndex,
49410
+ };
49411
+ }
49412
+ } else if (commaIndex === void 0 && input[index] === ',') {
49413
+ commaIndex = index;
49414
+ }
49415
+ }
49416
+ return null;
49417
+ }
49418
+ function tokenFromVarRange(string, range,) {
49419
+ if (!range) return {};
49420
+ const {
49421
+ start: start2,
49422
+ end,
49423
+ commaIndex,
49424
+ } = range;
49425
+ const metadata = string.substring(end,).trim();
49426
+ if (!commaIndex) {
49427
+ return {
49428
+ customProperty: string.substring(start2 + 4, end - 1,),
49429
+ metadata,
49430
+ };
49431
+ }
49432
+ return {
49433
+ customProperty: string.substring(start2 + 4, commaIndex,),
49434
+ fallback: string.substring(commaIndex + 1, end - 1,).trim(),
49435
+ metadata,
49436
+ };
49437
+ }
49438
+ function parseCSSVariable2(token,) {
49439
+ const range = parseCSSVarRange(token,);
49440
+ return tokenFromVarRange(token, range,);
49441
+ }
49361
49442
  var overlayStyle = {
49362
49443
  position: 'absolute',
49363
49444
  inset: 0,
49364
- zIndex: 1,
49365
49445
  width: '100%',
49366
49446
  height: '100%',
49367
49447
  };
49368
49448
  var timeMultiplier = 1e-3;
49369
- function colorToVec4(color2,) {
49370
- const rgba2 = Color.toRgb(Color(color2,),);
49449
+ function resolveCSSVariableColor(color2, element,) {
49450
+ const parsed = parseCSSVariable2(color2,);
49451
+ if (!parsed.customProperty) return color2;
49452
+ if (element) {
49453
+ const resolved = getComputedStyle(element,).getPropertyValue(parsed.customProperty,).trim();
49454
+ if (resolved) return P3Color.srgbFromValue(resolved,);
49455
+ }
49456
+ return P3Color.srgbFromValue(parsed.fallback ?? color2,);
49457
+ }
49458
+ function colorToVec4(color2, element,) {
49459
+ const resolved = resolveCSSVariableColor(color2, element,);
49460
+ const rgba2 = Color.toRgb(Color(resolved,),);
49371
49461
  return [rgba2.r / 255, rgba2.g / 255, rgba2.b / 255, rgba2.a,];
49372
49462
  }
49373
49463
  async function loadTexture(url,) {
@@ -49376,7 +49466,7 @@ async function loadTexture(url,) {
49376
49466
  const blob = await response.blob();
49377
49467
  return createImageBitmap(blob,);
49378
49468
  }
49379
- async function resolveUniform(uniform,) {
49469
+ async function resolveUniform(uniform, element,) {
49380
49470
  switch (uniform.type) {
49381
49471
  case 'number':
49382
49472
  case 'enum':
@@ -49392,7 +49482,7 @@ async function resolveUniform(uniform,) {
49392
49482
  case 'color':
49393
49483
  return {
49394
49484
  type: 'vec4',
49395
- value: colorToVec4(uniform.value,),
49485
+ value: colorToVec4(uniform.value, element,),
49396
49486
  };
49397
49487
  case 'responsiveimage': {
49398
49488
  let url;
@@ -49411,16 +49501,16 @@ async function resolveUniform(uniform,) {
49411
49501
  case 'array':
49412
49502
  return {
49413
49503
  type: 'vec4[]',
49414
- value: uniform.value.map(colorToVec4,),
49504
+ value: uniform.value.map((color2) => colorToVec4(color2, element,)),
49415
49505
  };
49416
49506
  default:
49417
49507
  assertNever(uniform,);
49418
49508
  }
49419
49509
  }
49420
- async function resolveUniforms(uniforms,) {
49510
+ async function resolveUniforms(uniforms, element,) {
49421
49511
  const result = {};
49422
49512
  for (const [name, uniform,] of Object.entries(uniforms,)) {
49423
- const resolved = await resolveUniform(uniform,);
49513
+ const resolved = await resolveUniform(uniform, element,);
49424
49514
  if (!resolved) continue;
49425
49515
  result[name] = resolved;
49426
49516
  if (uniform.type === 'array') {
@@ -49470,10 +49560,25 @@ var sandboxFallbackContainerStyle = {
49470
49560
  var ShaderSandboxFallbackImage = /* @__PURE__ */ memo2(function ShaderSandboxFallbackImage2({
49471
49561
  src,
49472
49562
  hidden = false,
49563
+ onDisplaySrcChange,
49473
49564
  },) {
49474
49565
  const [displaySrc, setDisplaySrc,] = useState(src,);
49475
49566
  const [previousSrc, setPreviousSrc,] = useState(void 0,);
49476
49567
  const fadeRef = useRef(null,);
49568
+ const onDisplaySrcChangeRef = useRef(onDisplaySrcChange,);
49569
+ useLayoutEffect(() => {
49570
+ onDisplaySrcChangeRef.current = onDisplaySrcChange;
49571
+ }, [onDisplaySrcChange,],);
49572
+ const isInitialMountRef = useRef(true,);
49573
+ useLayoutEffect(() => {
49574
+ if (isInitialMountRef.current) {
49575
+ isInitialMountRef.current = false;
49576
+ return;
49577
+ }
49578
+ if (!prevDisplayRef.current) {
49579
+ onDisplaySrcChangeRef.current?.();
49580
+ }
49581
+ }, [displaySrc,],);
49477
49582
  useEffect(() => {
49478
49583
  if (src === displaySrc) return;
49479
49584
  let isActive = true;
@@ -49514,7 +49619,10 @@ var ShaderSandboxFallbackImage = /* @__PURE__ */ memo2(function ShaderSandboxFal
49514
49619
  fill: 'forwards',
49515
49620
  },);
49516
49621
  animation.onfinish = () => {
49517
- if (!cancelled) startTransition2(() => setPreviousSrc(void 0,));
49622
+ if (!cancelled) {
49623
+ startTransition2(() => setPreviousSrc(void 0,));
49624
+ onDisplaySrcChangeRef.current?.();
49625
+ }
49518
49626
  };
49519
49627
  return () => {
49520
49628
  cancelled = true;
@@ -49535,7 +49643,7 @@ var ShaderSandboxFallbackImage = /* @__PURE__ */ memo2(function ShaderSandboxFal
49535
49643
  decoding: 'async',
49536
49644
  style: sandboxFallbackImageStyle,
49537
49645
  alt: '',
49538
- }, previousSrc,),
49646
+ }, `prev-${previousSrc}`,),
49539
49647
  /* @__PURE__ */ jsx('div', {
49540
49648
  ref: previousSrc ? fadeRef : void 0,
49541
49649
  style: sandboxFallbackContainerStyle,
@@ -49572,12 +49680,24 @@ void main() {
49572
49680
  fragColor = vec4(0.0);
49573
49681
  }
49574
49682
  `;
49575
- function useResolvedUniforms(uniforms,) {
49683
+ var slotStatus = {
49684
+ /** No WebGL context slot allocated — show fallback image. */
49685
+ noSlot: 0,
49686
+ /** Slot allocated, render a single frame at t=0 and re-render on change. */
49687
+ singleFrame: 1,
49688
+ /** Slot allocated, run continuous rAF animation. */
49689
+ animate: 2,
49690
+ };
49691
+ var ShaderPoolContext = /* @__PURE__ */ createContext(null,);
49692
+ function useShaderPoolContext() {
49693
+ return useContext(ShaderPoolContext,);
49694
+ }
49695
+ function useResolvedUniforms(uniforms, canvasRef,) {
49576
49696
  const [resolvedUniforms, setResolvedUniforms,] = useState({},);
49577
49697
  useEffect(() => {
49578
49698
  if (!uniforms) return;
49579
49699
  let isCancelled = false;
49580
- resolveUniforms(uniforms,).then((resolved) => {
49700
+ resolveUniforms(uniforms, canvasRef.current,).then((resolved) => {
49581
49701
  if (!isCancelled) {
49582
49702
  startTransition2(() => setResolvedUniforms(resolved,));
49583
49703
  } else {
@@ -49587,7 +49707,7 @@ function useResolvedUniforms(uniforms,) {
49587
49707
  return () => {
49588
49708
  isCancelled = true;
49589
49709
  };
49590
- }, [uniforms,],);
49710
+ }, [uniforms, canvasRef,],);
49591
49711
  return resolvedUniforms;
49592
49712
  }
49593
49713
  function useCanvasResize(canvasRef, resizeHandler,) {
@@ -49617,20 +49737,60 @@ function useOnDprChange(callback,) {
49617
49737
  };
49618
49738
  }, [callback,],);
49619
49739
  }
49620
- function useWhenBrowserIdle(enabled = true,) {
49621
- const [isIdle, setIsIdle,] = useState(!enabled,);
49622
- useEffect(() => {
49623
- if (!enabled) return;
49624
- const requestIdleCallback2 = supportsRequestIdleCallback ? safeWindow.requestIdleCallback : (callback) => setTimeout(callback, 1,);
49625
- const id3 = requestIdleCallback2(() => {
49626
- startTransition2(() => setIsIdle(true,));
49627
- },);
49740
+ function useShaderRenderState(poolSlot, isSelected, isMultiSelected, isIntersecting, mode, animated, fallbackImage, shouldReduceMotion,) {
49741
+ let isFallbackOnly;
49742
+ let effectiveAnimated;
49743
+ let effectiveSingleFrame;
49744
+ let effectiveMode;
49745
+ if (poolSlot !== null) {
49746
+ const hasSlot = poolSlot !== slotStatus.noSlot;
49747
+ isFallbackOnly = !hasSlot || !!shouldReduceMotion && !!fallbackImage;
49748
+ effectiveAnimated = isSelected && !isMultiSelected;
49749
+ effectiveSingleFrame = hasSlot && !effectiveAnimated;
49750
+ effectiveMode = 'instant';
49751
+ } else {
49752
+ isFallbackOnly = mode === 'fallback' || !!shouldReduceMotion && !!fallbackImage || !isIntersecting;
49753
+ effectiveAnimated = animated ?? true;
49754
+ effectiveSingleFrame = false;
49755
+ effectiveMode = mode;
49756
+ }
49757
+ const [contextLost, setContextLost,] = useState(false,);
49758
+ const onContextLost = useCallback2(() => {
49759
+ startTransition2(() => setContextLost(true,));
49760
+ }, [],);
49761
+ useLayoutEffect(() => {
49762
+ if (contextLost && isSelected) {
49763
+ startTransition2(() => setContextLost(false,));
49764
+ }
49765
+ }, [contextLost, isSelected,],);
49766
+ if (contextLost) {
49767
+ isFallbackOnly = true;
49768
+ }
49769
+ return {
49770
+ isFallbackOnly,
49771
+ effectiveAnimated,
49772
+ effectiveSingleFrame,
49773
+ effectiveMode,
49774
+ onContextLost,
49775
+ };
49776
+ }
49777
+ var SHADER_REVEAL_DELAY_MS = 300;
49778
+ function usePatchDelayShaderRender(enabled = true,) {
49779
+ const [mayRender, setMayRender,] = useState(!enabled,);
49780
+ useIsomorphicLayoutEffect2(() => {
49781
+ if (!enabled) {
49782
+ startTransition2(() => setMayRender(true,));
49783
+ return;
49784
+ }
49785
+ startTransition2(() => setMayRender(false,));
49786
+ const timeoutId = __unframerWindow2.setTimeout(() => {
49787
+ startTransition2(() => setMayRender(true,));
49788
+ }, SHADER_REVEAL_DELAY_MS,);
49628
49789
  return () => {
49629
- if (supportsRequestIdleCallback) cancelIdleCallback(id3,);
49630
- else clearTimeout(id3,);
49790
+ clearTimeout(timeoutId,);
49631
49791
  };
49632
49792
  }, [enabled,],);
49633
- return isIdle;
49793
+ return mayRender;
49634
49794
  }
49635
49795
  var canvasStyle = {
49636
49796
  display: 'block',
@@ -49645,7 +49805,8 @@ function ShaderCanvas({
49645
49805
  uniforms,
49646
49806
  onError,
49647
49807
  onReady,
49648
- paused = false,
49808
+ onContextLost,
49809
+ singleFrame: singleFrame2 = false,
49649
49810
  },) {
49650
49811
  const canvasRef = useRef(null,);
49651
49812
  const rendererRef = useRef(null,);
@@ -49656,83 +49817,120 @@ function ShaderCanvas({
49656
49817
  useLayoutEffect(() => {
49657
49818
  onReadyRef.current = onReady;
49658
49819
  }, [onReady,],);
49659
- const resolvedUniforms = useResolvedUniforms(uniforms,);
49660
- const resolvedUniformsRef = useRef(resolvedUniforms,);
49820
+ const onContextLostRef = useRef(onContextLost,);
49661
49821
  useLayoutEffect(() => {
49662
- resolvedUniformsRef.current = resolvedUniforms;
49663
- }, [resolvedUniforms,],);
49822
+ onContextLostRef.current = onContextLost;
49823
+ }, [onContextLost,],);
49824
+ const resolvedUniforms = useResolvedUniforms(uniforms, canvasRef,);
49825
+ const uniformsPropRef = useRef(uniforms,);
49826
+ useLayoutEffect(() => {
49827
+ uniformsPropRef.current = uniforms;
49828
+ }, [uniforms,],);
49829
+ const resolvedUniformsRef = useRef(resolvedUniforms,);
49664
49830
  const animatedRef = useRef(animated,);
49665
49831
  useLayoutEffect(() => {
49666
49832
  animatedRef.current = animated;
49667
49833
  }, [animated,],);
49668
- const pausedRef = useRef(paused,);
49834
+ const singleFrameRef = useRef(singleFrame2,);
49669
49835
  useLayoutEffect(() => {
49670
- pausedRef.current = paused;
49671
- }, [paused,],);
49836
+ singleFrameRef.current = singleFrame2;
49837
+ }, [singleFrame2,],);
49838
+ const readySignalledRef = useRef(false,);
49839
+ const signalReadyIfNeeded = useCallback2(() => {
49840
+ if (readySignalledRef.current) return;
49841
+ const hasCustomUniforms = uniformsPropRef.current && Object.keys(uniformsPropRef.current,).length > 0;
49842
+ const hasResolvedUniforms = Object.keys(resolvedUniformsRef.current,).length > 0;
49843
+ if (!hasCustomUniforms || hasResolvedUniforms) {
49844
+ readySignalledRef.current = true;
49845
+ onReadyRef.current?.();
49846
+ }
49847
+ }, [],);
49672
49848
  const animate3 = useCallback2((time2) => {
49673
49849
  const renderer = rendererRef.current;
49674
49850
  if (!renderer) return;
49851
+ if (singleFrameRef.current) {
49852
+ renderer.resize();
49853
+ renderer.render(0, 0, resolvedUniformsRef.current,);
49854
+ return;
49855
+ }
49675
49856
  renderer.resize();
49676
- if (pausedRef.current) {
49677
- const elapsedTime = lastTimeRef.current - startTimeRef.current;
49678
- renderer.render(elapsedTime, 0, resolvedUniformsRef.current,);
49679
- } else {
49680
- const {
49681
- currentTime,
49682
- elapsedTime,
49683
- deltaTime,
49684
- } = getShaderTiming(time2, startTimeRef.current, lastTimeRef.current,);
49685
- lastTimeRef.current = currentTime;
49686
- renderer.render(elapsedTime, deltaTime, resolvedUniformsRef.current,);
49687
- }
49688
- if (animatedRef.current || pausedRef.current) {
49857
+ const {
49858
+ currentTime,
49859
+ elapsedTime,
49860
+ deltaTime,
49861
+ } = getShaderTiming(time2, startTimeRef.current, lastTimeRef.current,);
49862
+ lastTimeRef.current = currentTime;
49863
+ renderer.render(elapsedTime, deltaTime, resolvedUniformsRef.current,);
49864
+ signalReadyIfNeeded();
49865
+ if (!singleFrameRef.current && animatedRef.current) {
49689
49866
  animationFrameRef.current = requestAnimationFrame(animate3,);
49690
49867
  }
49691
- }, [],);
49868
+ }, [signalReadyIfNeeded,],);
49869
+ const renderSingleFrame = useCallback2(() => {
49870
+ const renderer = rendererRef.current;
49871
+ if (!renderer) return;
49872
+ renderer.resize();
49873
+ renderer.render(0, 0, resolvedUniformsRef.current,);
49874
+ signalReadyIfNeeded();
49875
+ }, [signalReadyIfNeeded,],);
49876
+ useLayoutEffect(() => {
49877
+ resolvedUniformsRef.current = resolvedUniforms;
49878
+ if (singleFrameRef.current && rendererRef.current) {
49879
+ renderSingleFrame();
49880
+ }
49881
+ }, [resolvedUniforms, renderSingleFrame,],);
49692
49882
  useEffect(() => {
49693
49883
  const canvas = canvasRef.current;
49694
49884
  if (!canvas) return;
49695
- let cancelled = false;
49885
+ readySignalledRef.current = false;
49696
49886
  try {
49697
- const renderer = new WebGL2ShaderRenderer(canvas, vertexShader, fragmentShader, resolveResolutionScale(resolutionScale,),);
49887
+ const renderer = new WebGL2ShaderRenderer(
49888
+ canvas,
49889
+ vertexShader,
49890
+ fragmentShader,
49891
+ resolveResolutionScale(resolutionScale,),
49892
+ onContextLostRef.current,
49893
+ );
49698
49894
  rendererRef.current = renderer;
49699
49895
  renderer.resize();
49700
49896
  startTimeRef.current = performance.now() * timeMultiplier;
49701
49897
  lastTimeRef.current = startTimeRef.current;
49702
- animationFrameRef.current = requestAnimationFrame(animate3,);
49703
- requestAnimationFrame(() => {
49704
- if (!cancelled) onReadyRef.current?.();
49705
- },);
49898
+ if (singleFrameRef.current) {
49899
+ renderSingleFrame();
49900
+ } else {
49901
+ animationFrameRef.current = requestAnimationFrame(animate3,);
49902
+ }
49706
49903
  } catch (error) {
49707
49904
  if (onError && error instanceof Error) {
49708
49905
  onError(error,);
49709
49906
  }
49710
49907
  }
49711
49908
  return () => {
49712
- cancelled = true;
49713
49909
  cancelAnimationFrame(animationFrameRef.current,);
49714
49910
  rendererRef.current?.dispose();
49715
49911
  rendererRef.current = null;
49716
49912
  };
49717
- }, [vertexShader, fragmentShader, resolutionScale, animate3, onError,],);
49913
+ }, [vertexShader, fragmentShader, resolutionScale, animate3, renderSingleFrame, onError,],);
49718
49914
  const wasAnimatedRef = useRef(animated,);
49915
+ const wasReactiveRef = useRef(singleFrame2,);
49719
49916
  useEffect(() => {
49720
- if (animated && !wasAnimatedRef.current && rendererRef.current) {
49721
- animationFrameRef.current = requestAnimationFrame(animate3,);
49722
- }
49723
- wasAnimatedRef.current = animated;
49724
- }, [animated, animate3,],);
49725
- const wasPausedRef = useRef(paused,);
49726
- useLayoutEffect(() => {
49727
- if (wasPausedRef.current && !paused) {
49917
+ const becameAnimated = animated && !wasAnimatedRef.current;
49918
+ const leftReactive = !singleFrame2 && wasReactiveRef.current;
49919
+ if ((becameAnimated || leftReactive) && rendererRef.current) {
49728
49920
  startTimeRef.current = performance.now() * timeMultiplier;
49729
49921
  lastTimeRef.current = startTimeRef.current;
49922
+ animationFrameRef.current = requestAnimationFrame(animate3,);
49730
49923
  }
49731
- wasPausedRef.current = paused;
49732
- }, [paused,],);
49924
+ wasAnimatedRef.current = animated;
49925
+ wasReactiveRef.current = singleFrame2;
49926
+ }, [animated, singleFrame2, animate3,],);
49733
49927
  const handleResize = useCallback2(() => {
49734
49928
  const renderer = rendererRef.current;
49735
49929
  if (!renderer) return;
49930
+ if (singleFrameRef.current) {
49931
+ renderSingleFrame();
49932
+ return;
49933
+ }
49736
49934
  renderer.resize();
49737
49935
  const {
49738
49936
  currentTime,
@@ -49741,7 +49939,7 @@ function ShaderCanvas({
49741
49939
  } = getShaderTiming(performance.now(), startTimeRef.current, lastTimeRef.current,);
49742
49940
  lastTimeRef.current = currentTime;
49743
49941
  renderer.render(elapsedTime, deltaTime, resolvedUniformsRef.current,);
49744
- }, [],);
49942
+ }, [renderSingleFrame,],);
49745
49943
  useCanvasResize(canvasRef, handleResize,);
49746
49944
  return /* @__PURE__ */ jsx('canvas', {
49747
49945
  ref: canvasRef,
@@ -49752,7 +49950,7 @@ var SHADER_PLAY_DELAY = 250;
49752
49950
  var ShaderWithFallbackOverlay = /* @__PURE__ */ memo2(function ShaderWithFallbackOverlay2({
49753
49951
  mode,
49754
49952
  fallbackImage,
49755
- optimiseSwitching,
49953
+ skipInitialFallback,
49756
49954
  vertexShader,
49757
49955
  fragmentShader,
49758
49956
  animated,
@@ -49760,11 +49958,16 @@ var ShaderWithFallbackOverlay = /* @__PURE__ */ memo2(function ShaderWithFallbac
49760
49958
  uniforms,
49761
49959
  onError,
49762
49960
  onReady,
49961
+ singleFrame: singleFrame2,
49962
+ onContextLost,
49763
49963
  },) {
49764
- const isProgressive = mode === 'progressive';
49765
- const isIdle = useWhenBrowserIdle(isProgressive,);
49766
49964
  const [isShaderReady, setIsShaderReady,] = useState(false,);
49767
49965
  const [shouldPlay, setShouldPlay,] = useState(false,);
49966
+ const isProgressive = mode === 'progressive';
49967
+ const hasFallbackImage = Boolean(fallbackImage,);
49968
+ const shouldSkipInitialFallback = Boolean(skipInitialFallback && hasFallbackImage,);
49969
+ const isFallbackShown = isProgressive && hasFallbackImage && !shouldSkipInitialFallback;
49970
+ const isRevealDelayComplete = usePatchDelayShaderRender(isFallbackShown,);
49768
49971
  const onReadyRef = useRef(onReady,);
49769
49972
  useLayoutEffect(() => {
49770
49973
  onReadyRef.current = onReady;
@@ -49774,46 +49977,85 @@ var ShaderWithFallbackOverlay = /* @__PURE__ */ memo2(function ShaderWithFallbac
49774
49977
  onReadyRef.current?.();
49775
49978
  }, [],);
49776
49979
  useEffect(() => {
49777
- if (!isProgressive || !isShaderReady) return;
49778
- let timeout;
49779
- if (SHADER_PLAY_DELAY) {
49780
- timeout = __unframerWindow2.setTimeout(() => {
49781
- startTransition2(() => setShouldPlay(true,));
49782
- }, SHADER_PLAY_DELAY,);
49783
- } else {
49980
+ if (!isProgressive) return;
49981
+ if (!isShaderReady || !isRevealDelayComplete) return;
49982
+ const timeout = __unframerWindow2.setTimeout(() => {
49784
49983
  startTransition2(() => setShouldPlay(true,));
49785
- }
49786
- return () => SHADER_PLAY_DELAY ? clearTimeout(timeout,) : void 0;
49787
- }, [isProgressive, isShaderReady,],);
49788
- const paused = isProgressive && !shouldPlay;
49984
+ }, SHADER_PLAY_DELAY,);
49985
+ return () => {
49986
+ clearTimeout(timeout,);
49987
+ };
49988
+ }, [isProgressive, isRevealDelayComplete, isShaderReady,],);
49989
+ const shouldHideCanvas = isFallbackShown && !isRevealDelayComplete;
49990
+ const isWaitingForPlayback = isProgressive && !shouldPlay;
49991
+ const effectiveSingleFrame = singleFrame2 || shouldHideCanvas || isWaitingForPlayback;
49992
+ const shouldShowFallback = hasFallbackImage && !shouldSkipInitialFallback && (!isRevealDelayComplete || !isShaderReady);
49789
49993
  return /* @__PURE__ */ jsxs(Fragment, {
49790
49994
  children: [
49791
- isIdle && /* @__PURE__ */ jsx(ShaderCanvas, {
49792
- vertexShader,
49793
- fragmentShader,
49794
- animated,
49795
- resolutionScale,
49796
- paused,
49797
- uniforms,
49798
- onError,
49799
- onReady: handleReady,
49995
+ /* @__PURE__ */ jsx('div', {
49996
+ style: {
49997
+ ...overlayStyle,
49998
+ opacity: shouldHideCanvas ? 0 : 1,
49999
+ },
50000
+ children: /* @__PURE__ */ jsx(ShaderCanvas, {
50001
+ vertexShader,
50002
+ fragmentShader,
50003
+ animated,
50004
+ resolutionScale,
50005
+ singleFrame: effectiveSingleFrame,
50006
+ uniforms,
50007
+ onError,
50008
+ onReady: handleReady,
50009
+ onContextLost,
50010
+ },),
49800
50011
  },),
49801
- !isShaderReady && fallbackImage && /* @__PURE__ */ jsx('div', {
49802
- style: overlayStyle,
49803
- children: optimiseSwitching
49804
- ? /* @__PURE__ */ jsx(ShaderSandboxFallbackImage, {
49805
- src: fallbackImage,
49806
- },)
49807
- : /* @__PURE__ */ jsx(ShaderFallbackImage, {
49808
- src: fallbackImage,
49809
- },),
50012
+ fallbackImage && /* @__PURE__ */ jsx('div', {
50013
+ style: {
50014
+ ...overlayStyle,
50015
+ opacity: shouldShowFallback ? 1 : 0,
50016
+ transition: 'opacity 200ms ease-in-out',
50017
+ pointerEvents: 'none',
50018
+ },
50019
+ children: /* @__PURE__ */ jsx(ShaderFallbackImage, {
50020
+ src: fallbackImage,
50021
+ },),
49810
50022
  },),
49811
50023
  ],
49812
50024
  },);
49813
50025
  },);
50026
+ var shaderPriority = {
50027
+ low: 0,
50028
+ medium: 1,
50029
+ high: 2,
50030
+ };
50031
+ function useShaderPoolSlot(id3, isSelected, isVisible,) {
50032
+ const pool = useShaderPoolContext();
50033
+ const priority = isSelected ? shaderPriority.high : isVisible ? shaderPriority.medium : shaderPriority.low;
50034
+ const [status, setStatus,] = useState(slotStatus.noSlot,);
50035
+ useEffect(() => {
50036
+ if (!pool || !id3) return;
50037
+ pool.register(id3, priority,);
50038
+ startTransition2(() => setStatus(pool.getSlotStatus(id3,),));
50039
+ const unsub = pool.subscribe(id3, () => {
50040
+ startTransition2(() => setStatus(pool.getSlotStatus(id3,),));
50041
+ },);
50042
+ return () => {
50043
+ unsub();
50044
+ };
50045
+ }, [pool, id3, priority,],);
50046
+ useEffect(() => {
50047
+ if (!pool || !id3) return;
50048
+ return () => {
50049
+ pool.deregister(id3,);
50050
+ };
50051
+ }, [pool, id3,],);
50052
+ if (!pool) return null;
50053
+ return status;
50054
+ }
49814
50055
  var Shader = /* @__PURE__ */ forwardRef(function Shader2({
49815
50056
  mode = 'instant',
49816
50057
  fallbackImage,
50058
+ skipInitialFallback,
49817
50059
  optimiseSwitching,
49818
50060
  style: style2,
49819
50061
  width,
@@ -49825,6 +50067,10 @@ var Shader = /* @__PURE__ */ forwardRef(function Shader2({
49825
50067
  onError,
49826
50068
  onReady,
49827
50069
  resolutionScale,
50070
+ onFallbackDisplayChange,
50071
+ poolId,
50072
+ isSelected = false,
50073
+ isMultiSelected = false,
49828
50074
  ...rest
49829
50075
  }, ref,) {
49830
50076
  const observerRef = useObserverRef(ref,);
@@ -49836,29 +50082,40 @@ var Shader = /* @__PURE__ */ forwardRef(function Shader2({
49836
50082
  threshold: 0,
49837
50083
  enabled: true,
49838
50084
  },);
50085
+ const autoId = useId();
50086
+ const id3 = poolId ?? autoId;
50087
+ const poolSlot = useShaderPoolSlot(id3, isSelected, isIntersecting,);
49839
50088
  const shouldReduceMotion = useReducedMotionConfig();
49840
- const isFallbackOnly = mode === 'fallback' || shouldReduceMotion && !!fallbackImage || !isIntersecting;
49841
- const shaderProps = {
49842
- vertexShader,
49843
- fragmentShader,
49844
- animated,
49845
- uniforms,
49846
- resolutionScale,
49847
- onError,
49848
- };
50089
+ const shouldSkipInitialFallback = Boolean(skipInitialFallback && fallbackImage,);
50090
+ const {
50091
+ isFallbackOnly,
50092
+ effectiveAnimated,
50093
+ effectiveSingleFrame,
50094
+ effectiveMode,
50095
+ onContextLost,
50096
+ } = useShaderRenderState(poolSlot, isSelected, isMultiSelected, isIntersecting, mode, animated, fallbackImage, shouldReduceMotion,);
49849
50097
  const [isShaderReady, setIsShaderReady,] = useState(false,);
49850
50098
  useLayoutEffect(() => {
49851
- if (isFallbackOnly) setIsShaderReady(false,);
50099
+ if (isFallbackOnly) startTransition2(() => setIsShaderReady(false,));
49852
50100
  }, [isFallbackOnly,],);
49853
50101
  const handleShaderReady = useCallback2(() => {
49854
50102
  startTransition2(() => setIsShaderReady(true,));
49855
50103
  onReady?.();
49856
50104
  }, [onReady,],);
49857
- const hideFallback = !isFallbackOnly && isShaderReady;
50105
+ const hideFallback = !isFallbackOnly && (shouldSkipInitialFallback || isShaderReady);
50106
+ const shaderProps = {
50107
+ vertexShader,
50108
+ fragmentShader,
50109
+ uniforms,
50110
+ resolutionScale,
50111
+ onError,
50112
+ onContextLost,
50113
+ };
49858
50114
  return /* @__PURE__ */ jsx(FrameWithMotion2, {
49859
50115
  ref: observerRef,
49860
50116
  __fromCanvasComponent: true,
49861
50117
  style: {
50118
+ borderRadius: 'inherit',
49862
50119
  ...style2,
49863
50120
  overflow: 'hidden',
49864
50121
  },
@@ -49869,13 +50126,17 @@ var Shader = /* @__PURE__ */ forwardRef(function Shader2({
49869
50126
  ? /* @__PURE__ */ jsxs(Fragment, {
49870
50127
  children: [
49871
50128
  !isFallbackOnly && /* @__PURE__ */ jsx(ShaderWithFallbackOverlay, {
49872
- mode,
50129
+ mode: effectiveMode,
50130
+ skipInitialFallback: shouldSkipInitialFallback,
49873
50131
  onReady: handleShaderReady,
49874
50132
  ...shaderProps,
50133
+ animated: effectiveAnimated,
50134
+ singleFrame: effectiveSingleFrame,
49875
50135
  },),
49876
50136
  /* @__PURE__ */ jsx(ShaderSandboxFallbackImage, {
49877
50137
  src: fallbackImage,
49878
50138
  hidden: hideFallback,
50139
+ onDisplaySrcChange: onFallbackDisplayChange,
49879
50140
  },),
49880
50141
  ],
49881
50142
  },)
@@ -49884,10 +50145,13 @@ var Shader = /* @__PURE__ */ forwardRef(function Shader2({
49884
50145
  src: fallbackImage,
49885
50146
  },)
49886
50147
  : /* @__PURE__ */ jsx(ShaderWithFallbackOverlay, {
49887
- mode,
50148
+ mode: effectiveMode,
49888
50149
  fallbackImage,
50150
+ skipInitialFallback: shouldSkipInitialFallback,
49889
50151
  onReady,
49890
50152
  ...shaderProps,
50153
+ animated: effectiveAnimated,
50154
+ singleFrame: effectiveSingleFrame,
49891
50155
  },),
49892
50156
  },);
49893
50157
  },);
@@ -51498,7 +51762,7 @@ function getAssetOwnerType(asset,) {
51498
51762
  async function loadFontsWithOpenType(source,) {
51499
51763
  switch (source) {
51500
51764
  case 'google': {
51501
- const supportedFonts = await import('./framer-chunks/google-OH6PJH7O-YVQLVNW6.js');
51765
+ const supportedFonts = await import('./framer-chunks/google-654GT66W-6S5WZWNS.js');
51502
51766
  return supportedFonts.default;
51503
51767
  }
51504
51768
  case 'fontshare': {
@@ -51512,7 +51776,7 @@ async function loadFontsWithOpenType(source,) {
51512
51776
  async function loadFontToOpenTypeFeatures(source,) {
51513
51777
  switch (source) {
51514
51778
  case 'google': {
51515
- const features = await import('./framer-chunks/google-2FSYEIRJ-BBUVVSSM.js');
51779
+ const features = await import('./framer-chunks/google-HHQRBNOM-DLREIKWB.js');
51516
51780
  return features.default;
51517
51781
  }
51518
51782
  case 'fontshare': {
@@ -52064,7 +52328,7 @@ function loadVariationAxes(source,) {
52064
52328
  const axes = (async () => {
52065
52329
  switch (source) {
52066
52330
  case 'google': {
52067
- return (await import('./framer-chunks/google-IYRURLPW-NANSF7W2.js')).default;
52331
+ return (await import('./framer-chunks/google-MNOHFPXZ-52SQ3ETO.js')).default;
52068
52332
  }
52069
52333
  case 'fontshare': {
52070
52334
  return (await import('./framer-chunks/fontshare-MHXFPDHS-VQYPAYVC.js')).default;
@@ -52533,6 +52797,11 @@ var PlainTextInput = /* @__PURE__ */ forwardRef(function FormPlainTextInput(prop
52533
52797
  }
52534
52798
  }, [onClear, setOptimisticValue,],);
52535
52799
  const eventHandlers = useCustomValidity(onValid, onInvalid, handleChange, onBlur, onFocus,);
52800
+ const handleWrapperClick = useCallback2((e) => {
52801
+ if (e.target === e.currentTarget) {
52802
+ setInputRef.current?.focus();
52803
+ }
52804
+ }, [setInputRef,],);
52536
52805
  if (type === 'hidden') {
52537
52806
  return /* @__PURE__ */ jsx(motion.input, {
52538
52807
  type: 'hidden',
@@ -52543,16 +52812,18 @@ var PlainTextInput = /* @__PURE__ */ forwardRef(function FormPlainTextInput(prop
52543
52812
  const dataProps = autofillEnabled === false ? passwordManagerIgnoreDataProps : void 0;
52544
52813
  const hasValue = !!optimisticValue;
52545
52814
  const showClear = !!onClear && hasValue;
52815
+ const wrapperClassName = cx(
52816
+ textInputWrapperClassName,
52817
+ inputWrapperClassName,
52818
+ className2,
52819
+ type === 'text' && textInputTypeWrapperClassName,
52820
+ type === 'textarea' && textareaInputTypeWrapperClassName,
52821
+ );
52546
52822
  return /* @__PURE__ */ jsxs(motion.div, {
52547
52823
  ref,
52824
+ onClick: handleWrapperClick,
52548
52825
  style: style2,
52549
- className: cx(
52550
- textInputWrapperClassName,
52551
- inputWrapperClassName,
52552
- className2,
52553
- type === 'text' && textInputTypeWrapperClassName,
52554
- onClear && hasClearButtonClassName,
52555
- ),
52826
+ className: wrapperClassName,
52556
52827
  ...rest,
52557
52828
  children: [
52558
52829
  type === 'textarea'
@@ -52617,8 +52888,8 @@ function ClearIcon() {
52617
52888
  }
52618
52889
  var textInputWrapperClassName = 'framer-form-text-input';
52619
52890
  var textInputTypeWrapperClassName = 'framer-form-text-input-type';
52891
+ var textareaInputTypeWrapperClassName = 'framer-form-textarea-input-type';
52620
52892
  var clearButtonClassName = 'framer-form-text-input-clear';
52621
- var hasClearButtonClassName = 'framer-form-text-input-has-clear-button';
52622
52893
  var defaultTextareaResizerIcon =
52623
52894
  `<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"><path d="m1.5 8 7-7M9 5.5l-3 3" stroke="%23999" stroke-width="1.5" stroke-linecap="round"></path></svg>`;
52624
52895
  var defaultTextareaResizerIconFlipped =
@@ -52654,6 +52925,28 @@ var styles = /* @__PURE__ */ (() => [
52654
52925
  color: css2.variable('--framer-input-placeholder-color',/* PlaceholderColor */
52655
52926
  ),
52656
52927
  },),
52928
+ css2(`.${textInputWrapperClassName}`, {
52929
+ display: 'flex',
52930
+ alignItems: 'center',
52931
+ padding: css2.variable('--framer-input-padding',/* Padding */
52932
+ ),
52933
+ },),
52934
+ css2(`.${textInputWrapperClassName} .${inputClassName}`, {
52935
+ flex: 1,
52936
+ minWidth: 0,
52937
+ width: 'auto',
52938
+ padding: 0,
52939
+ },),
52940
+ // Textarea can't have an icon - so paddings don't need to be on wrapper.
52941
+ // Plus we have to deal with native resizer handle in webkit
52942
+ css2(`.${textInputWrapperClassName}.${textareaInputTypeWrapperClassName}`, {
52943
+ padding: 0,
52944
+ },),
52945
+ css2(`.${textInputWrapperClassName}.${textareaInputTypeWrapperClassName} textarea.${inputClassName}`, {
52946
+ width: '100%',
52947
+ padding: css2.variable('--framer-input-padding',/* Padding */
52948
+ ),
52949
+ },),
52657
52950
  css2(`.${textInputWrapperClassName} .${inputClassName}[type="date"], .${textInputWrapperClassName} .${inputClassName}[type="time"]`, {
52658
52951
  '-webkit-appearance': 'none',
52659
52952
  appearance: 'none',
@@ -52705,6 +52998,21 @@ var styles = /* @__PURE__ */ (() => [
52705
52998
  ),
52706
52999
  overflow: 'visible',
52707
53000
  },),
53001
+ css2(`.${textInputWrapperClassName}.${textInputTypeWrapperClassName}::before`, {
53002
+ content: css2.variable('--framer-input-icon-content', 'none',),
53003
+ display: 'block',
53004
+ flexShrink: 0,
53005
+ width: `${iconSize}px`,
53006
+ height: `${iconSize}px`,
53007
+ marginRight: `${iconSpacing}px`,
53008
+ ...iconImageCSS,
53009
+ backgroundPosition: 'center',
53010
+ maskPosition: 'center',
53011
+ maskImage: css2.variable('--framer-input-icon-mask-image',/* IconMaskImage */
53012
+ ),
53013
+ backgroundImage: css2.variable('--framer-input-icon-image',/* IconBackgroundImage */
53014
+ ),
53015
+ },),
52708
53016
  // Date/time input right-positioned input icon
52709
53017
  css2(
52710
53018
  `.${textInputWrapperClassName} .${inputClassName}[type="date"]::before, .${textInputWrapperClassName} .${inputClassName}[type="time"]::before`,
@@ -52725,35 +53033,6 @@ var styles = /* @__PURE__ */ (() => [
52725
53033
  backgroundImage: css2.variable('--framer-input-icon-image',/* IconBackgroundImage */
52726
53034
  ),
52727
53035
  },),
52728
- // type="text" input might have a left-positioned icon so we need to apply the padding to the wrapper
52729
- // and make icon statically positioned
52730
- css2(`.${textInputWrapperClassName}.${textInputTypeWrapperClassName}`, {
52731
- display: 'flex',
52732
- alignItems: 'center',
52733
- padding: css2.variable('--framer-input-padding',/* Padding */
52734
- ),
52735
- },),
52736
- css2(`.${textInputWrapperClassName} .${inputClassName}[type="text"]`, {
52737
- flex: 1,
52738
- minWidth: 0,
52739
- width: 'auto',
52740
- padding: 0,
52741
- },),
52742
- css2(`.${textInputWrapperClassName}.${textInputTypeWrapperClassName}::before`, {
52743
- content: css2.variable('--framer-input-icon-content', 'none',),
52744
- display: 'block',
52745
- flexShrink: 0,
52746
- width: `${iconSize}px`,
52747
- height: `${iconSize}px`,
52748
- marginRight: `${leftIconSpacing}px`,
52749
- ...iconImageCSS,
52750
- backgroundPosition: 'center',
52751
- maskPosition: 'center',
52752
- maskImage: css2.variable('--framer-input-icon-mask-image',/* IconMaskImage */
52753
- ),
52754
- backgroundImage: css2.variable('--framer-input-icon-image',/* IconBackgroundImage */
52755
- ),
52756
- },),
52757
53036
  // Hide the native date picker icon, but still align it with the custom icon, allowing user to click it to show the
52758
53037
  // date/time picker.
52759
53038
  css2(`.${textInputWrapperClassName} .${inputClassName}::-webkit-calendar-picker-indicator`, {
@@ -52784,14 +53063,15 @@ var styles = /* @__PURE__ */ (() => [
52784
53063
  borderWidth: css2.variable('--framer-input-focused-border-width', inputBorderAllSides,),
52785
53064
  },),
52786
53065
  css2(`.${clearButtonClassName}`, {
52787
- position: 'absolute',
52788
- right: 0,
52789
- top: 0,
52790
- bottom: 0,
53066
+ display: 'flex',
53067
+ order: 2,
53068
+ alignItems: 'center',
53069
+ justifyContent: 'center',
53070
+ flexShrink: 0,
52791
53071
  width: `${iconSize}px`,
52792
- boxSizing: 'content-box',
52793
- padding: css2.variable('--framer-input-padding',/* Padding */
52794
- ),
53072
+ height: `${iconSize}px`,
53073
+ marginLeft: `${iconSpacing}px`,
53074
+ padding: 0,
52795
53075
  border: 'none',
52796
53076
  background: 'transparent',
52797
53077
  cursor: 'pointer',
@@ -52804,12 +53084,6 @@ var styles = /* @__PURE__ */ (() => [
52804
53084
  color: css2.variable('--framer-input-font-color',/* FontColor */
52805
53085
  ),
52806
53086
  },),
52807
- css2(`.${textInputWrapperClassName}.${hasClearButtonClassName} .${inputClassName}`, {
52808
- paddingRight: `calc(${
52809
- css2.variable('--framer-input-padding',/* Padding */
52810
- )
52811
- } + ${iconSize}px + ${rightIconSpacing}px)`,
52812
- },),
52813
53087
  ])();
52814
53088
  var FormPlainTextInput2 = /* @__PURE__ */ withCSS(PlainTextInput, styles, 'framer-lib-form-plain-text-input',);
52815
53089
  var className = 'framer-form-boolean-input';
@@ -57464,7 +57738,7 @@ var package_default = {
57464
57738
  eslint: '^8.57.1',
57465
57739
  'eslint-plugin-framer-studio': 'workspace:*',
57466
57740
  'framer-motion': '12.34.3',
57467
- immutable: '^3.8.2',
57741
+ immutable: '^3.8.3',
57468
57742
  jest: '29.4.1',
57469
57743
  'jest-diff': '^29.3.1',
57470
57744
  'jest-environment-jsdom': '^29.3.1',