@grahlnn/comps 0.1.3 → 0.1.5

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/index.js CHANGED
@@ -2931,6 +2931,15 @@ function getDomMeasurementRequestKey(text, renderText, layoutContext, useContent
2931
2931
  }
2932
2932
  return `dom\x00${inlineSizeMode}\x00${text}\x00${renderText}\x00${layoutContext.measurementVersion}\x00${getMorphMeasurementEpoch()}`;
2933
2933
  }
2934
+ function needsMeasurementLayer(measurementBackend, renderText) {
2935
+ if (measurementBackend === "pretext") {
2936
+ return false;
2937
+ }
2938
+ return renderText.length > 0;
2939
+ }
2940
+ function canCacheMeasurementLayerSnapshot(measurementBackend) {
2941
+ return measurementBackend === "dom";
2942
+ }
2934
2943
  function readCachedMorphSnapshot(cache, cacheKey) {
2935
2944
  const cached = cache.get(cacheKey);
2936
2945
  if (cached === undefined) {
@@ -3118,7 +3127,7 @@ function createMorphMeasurementRequest({
3118
3127
  segments = EMPTY_SEGMENTS;
3119
3128
  }
3120
3129
  let domMeasurementKey = null;
3121
- if (measurementBackend === "dom" && renderText.length > 0) {
3130
+ if (needsMeasurementLayer(measurementBackend, renderText)) {
3122
3131
  domMeasurementKey = getDomMeasurementRequestKey(text, renderText, layoutContext, useContentInlineSize);
3123
3132
  }
3124
3133
  return {
@@ -3190,17 +3199,19 @@ function measureFromNodes({
3190
3199
  pretextSnapshot = measureMorphSnapshotWithPretext(text, measurementLayoutContext);
3191
3200
  }
3192
3201
  let domSnapshot = null;
3193
- if (measurementBackend === "dom") {
3194
- domSnapshot = measureMorphSnapshotFromLayer(text, renderText, segments, layer);
3195
- } else if (measurementBackend !== "pretext") {
3196
- domSnapshot = measureMorphSnapshotWithDomService({
3197
- root,
3198
- layoutContext,
3199
- text,
3200
- renderText,
3201
- segments,
3202
- useContentInlineSize
3203
- });
3202
+ if (measurementBackend !== "pretext") {
3203
+ if (layer !== null) {
3204
+ domSnapshot = measureMorphSnapshotFromLayer(text, renderText, segments, layer);
3205
+ } else {
3206
+ domSnapshot = measureMorphSnapshotWithDomService({
3207
+ root,
3208
+ layoutContext,
3209
+ text,
3210
+ renderText,
3211
+ segments,
3212
+ useContentInlineSize
3213
+ });
3214
+ }
3204
3215
  }
3205
3216
  if (measurementBackend === "probe" && pretextSnapshot !== null && domSnapshot !== null) {
3206
3217
  const trusted = areSnapshotsEquivalentForPretextTrust(pretextSnapshot, domSnapshot);
@@ -3690,6 +3701,9 @@ function resolveActivationBootstrapText(isActivated, previousText, nextText) {
3690
3701
  }
3691
3702
  return null;
3692
3703
  }
3704
+ function shouldDeferTargetMeasurement(committedMeasurement, pendingBootstrapText, text) {
3705
+ return committedMeasurement === null && pendingBootstrapText !== null && pendingBootstrapText !== text;
3706
+ }
3693
3707
  function getOverlayStyle(plan) {
3694
3708
  return {
3695
3709
  ...OVERLAY_STYLE,
@@ -3795,17 +3809,23 @@ function useMorphTransition(text, className, bootstrapText = null) {
3795
3809
  if (sessionRef.current.animating) {
3796
3810
  measurementHint = sessionRef.current.target ?? sessionRef.current.committed;
3797
3811
  }
3798
- const measurementRequest = useMemo(() => createMorphMeasurementRequest({
3799
- text,
3800
- layoutContext,
3801
- layoutHint: measurementHint
3802
- }), [text, layoutContext, measurementHint]);
3803
3812
  let pendingBootstrapText = null;
3804
3813
  if (sessionRef.current.committed === null) {
3805
3814
  pendingBootstrapText = pendingBootstrapTextRef.current;
3806
3815
  }
3816
+ const isBootstrapping = shouldDeferTargetMeasurement(sessionRef.current.committed, pendingBootstrapText, text);
3817
+ const measurementRequest = useMemo(() => {
3818
+ if (isBootstrapping) {
3819
+ return null;
3820
+ }
3821
+ return createMorphMeasurementRequest({
3822
+ text,
3823
+ layoutContext,
3824
+ layoutHint: measurementHint
3825
+ });
3826
+ }, [text, layoutContext, measurementHint, isBootstrapping]);
3807
3827
  const bootstrapMeasurementRequest = useMemo(() => {
3808
- if (pendingBootstrapText === null) {
3828
+ if (!isBootstrapping || pendingBootstrapText === null) {
3809
3829
  return null;
3810
3830
  }
3811
3831
  return createMorphMeasurementRequest({
@@ -3813,13 +3833,13 @@ function useMorphTransition(text, className, bootstrapText = null) {
3813
3833
  layoutContext,
3814
3834
  layoutHint: null
3815
3835
  });
3816
- }, [pendingBootstrapText, layoutContext]);
3836
+ }, [pendingBootstrapText, layoutContext, isBootstrapping]);
3817
3837
  const renderText = measurementRequest?.renderText ?? text;
3818
3838
  const useContentInlineSize = measurementRequest?.useContentInlineSize ?? false;
3819
3839
  const measurementBackend = measurementRequest?.measurementBackend ?? null;
3820
3840
  const segments = measurementRequest?.segments ?? EMPTY_SEGMENTS;
3821
3841
  const domMeasurementKey = measurementRequest?.domMeasurementKey ?? null;
3822
- const shouldRenderBootstrapSourceMeasurementLayer = bootstrapMeasurementRequest?.measurementBackend === "dom" && bootstrapMeasurementRequest.renderText.length > 0;
3842
+ const shouldRenderBootstrapSourceMeasurementLayer = bootstrapMeasurementRequest?.domMeasurementKey !== null;
3823
3843
  useLayoutEffect(() => {
3824
3844
  if (ref.current === null || layoutContext === null) {
3825
3845
  completedDomMeasurementKeyRef.current = null;
@@ -3841,9 +3861,9 @@ function useMorphTransition(text, className, bootstrapText = null) {
3841
3861
  });
3842
3862
  return;
3843
3863
  }
3844
- if (pendingBootstrapText !== null && pendingBootstrapText !== text && bootstrapMeasurementRequest !== null && measurementRequest !== null) {
3864
+ if (isBootstrapping && bootstrapMeasurementRequest !== null) {
3845
3865
  let bootstrapDomSnapshot = null;
3846
- if (bootstrapMeasurementRequest.domMeasurementKey !== null) {
3866
+ if (bootstrapMeasurementRequest.domMeasurementKey !== null && canCacheMeasurementLayerSnapshot(bootstrapMeasurementRequest.measurementBackend)) {
3847
3867
  bootstrapDomSnapshot = readCachedMorphSnapshot(domMeasurementSnapshotCacheRef.current, bootstrapMeasurementRequest.domMeasurementKey);
3848
3868
  }
3849
3869
  if (bootstrapMeasurementRequest.domMeasurementKey !== null && bootstrapDomSnapshot === null && bootstrapMeasurementLayerRef.current === null) {
@@ -3860,7 +3880,7 @@ function useMorphTransition(text, className, bootstrapText = null) {
3860
3880
  renderText: bootstrapMeasurementRequest.renderText,
3861
3881
  segments: bootstrapMeasurementRequest.segments
3862
3882
  });
3863
- if (bootstrapMeasurementRequest.domMeasurementKey !== null && bootstrapDomSnapshot === null) {
3883
+ if (bootstrapMeasurementRequest.domMeasurementKey !== null && bootstrapDomSnapshot === null && canCacheMeasurementLayerSnapshot(bootstrapMeasurementRequest.measurementBackend)) {
3864
3884
  rememberCachedMorphSnapshot(domMeasurementSnapshotCacheRef.current, bootstrapMeasurementRequest.domMeasurementKey, bootstrapMeasurement.snapshot);
3865
3885
  }
3866
3886
  completedDomMeasurementKeyRef.current = null;
@@ -3872,7 +3892,10 @@ function useMorphTransition(text, className, bootstrapText = null) {
3872
3892
  return;
3873
3893
  }
3874
3894
  if (domMeasurementKey !== null) {
3875
- const cachedSnapshot = readCachedMorphSnapshot(domMeasurementSnapshotCacheRef.current, domMeasurementKey);
3895
+ let cachedSnapshot = null;
3896
+ if (canCacheMeasurementLayerSnapshot(measurementBackend)) {
3897
+ cachedSnapshot = readCachedMorphSnapshot(domMeasurementSnapshotCacheRef.current, domMeasurementKey);
3898
+ }
3876
3899
  if (cachedSnapshot !== null) {
3877
3900
  completedDomMeasurementKeyRef.current = domMeasurementKey;
3878
3901
  if (domMeasurementRequestKey !== null) {
@@ -3915,7 +3938,9 @@ function useMorphTransition(text, className, bootstrapText = null) {
3915
3938
  setState
3916
3939
  });
3917
3940
  if (nextMeasurement !== null) {
3918
- rememberCachedMorphSnapshot(domMeasurementSnapshotCacheRef.current, domMeasurementKey, nextMeasurement.snapshot);
3941
+ if (canCacheMeasurementLayerSnapshot(measurementBackend)) {
3942
+ rememberCachedMorphSnapshot(domMeasurementSnapshotCacheRef.current, domMeasurementKey, nextMeasurement.snapshot);
3943
+ }
3919
3944
  }
3920
3945
  completedDomMeasurementKeyRef.current = domMeasurementKey;
3921
3946
  if (domMeasurementRequestKey !== null) {
@@ -3952,6 +3977,7 @@ function useMorphTransition(text, className, bootstrapText = null) {
3952
3977
  layoutContext,
3953
3978
  measurementBackend,
3954
3979
  measurementRequest,
3980
+ isBootstrapping,
3955
3981
  pendingBootstrapText,
3956
3982
  bootstrapMeasurementRequest,
3957
3983
  domMeasurementKey,
@@ -4026,7 +4052,7 @@ function ActiveTorph({
4026
4052
  } = useMorphTransition(text, className, bootstrapText);
4027
4053
  const plan = state.plan;
4028
4054
  const shouldRenderOverlay = state.stage !== "idle" && plan !== null;
4029
- const shouldRenderMeasurementLayer = measurementBackend === "dom" && domMeasurementRequestKey !== null;
4055
+ const shouldRenderMeasurementLayer = domMeasurementRequestKey !== null;
4030
4056
  const flowText = resolveVisibleFlowText(pendingBootstrapText, committedMeasurement, state.measurement, text);
4031
4057
  let bootstrapMeasurementLayer = null;
4032
4058
  if (shouldRenderBootstrapSourceMeasurementLayer && bootstrapMeasurementRequest !== null) {
@@ -4105,11 +4131,13 @@ function Torph({
4105
4131
  }
4106
4132
  export {
4107
4133
  supportsIntrinsicWidthLock,
4134
+ shouldDeferTargetMeasurement,
4108
4135
  resolveVisibleFlowText,
4109
4136
  resolveMorphFrameBounds,
4110
4137
  resolveFlowText,
4111
4138
  resolveActivationBootstrapText,
4112
4139
  pairMorphCharacters,
4140
+ needsMeasurementLayer,
4113
4141
  measureMorphSnapshotFromLayer,
4114
4142
  getRootStyle,
4115
4143
  getRootDisplay,
@@ -1,4 +1,5 @@
1
1
  import { type CSSProperties } from "react";
2
+ import { type PretextMorphMeasurementBackend } from "../utils/text-layout/pretextMorph";
2
3
  export type SupportedWhiteSpace = "normal" | "nowrap" | "pre-wrap";
3
4
  export type MorphCharacterLayout = {
4
5
  glyph: string;
@@ -76,6 +77,7 @@ type GlyphExit = {
76
77
  from: MorphCharacterLayout;
77
78
  };
78
79
  type GlyphPairing = GlyphMove | GlyphEnter | GlyphExit;
80
+ export declare function needsMeasurementLayer(measurementBackend: PretextMorphMeasurementBackend, renderText: string): boolean;
79
81
  export declare function measureMorphSnapshotFromLayer(text: string, renderText: string, segments: readonly MorphSegment[], layer: HTMLElement | null): MorphSnapshot;
80
82
  export declare function pairMorphCharacters(previous: MorphCharacterLayout[], next: MorphCharacterLayout[]): GlyphPairing[];
81
83
  export declare function resolveMorphFrameBounds(previous: MorphSnapshot, next: MorphSnapshot): {
@@ -95,6 +97,7 @@ export declare function getMeasurementLayerStyle(layoutContext: LayoutContext |
95
97
  export declare function resolveFlowText(committedMeasurement: MorphMeasurement | null, stateMeasurement: MorphMeasurement | null, text: string): string;
96
98
  export declare function resolveVisibleFlowText(pendingBootstrapText: string | null, committedMeasurement: MorphMeasurement | null, stateMeasurement: MorphMeasurement | null, text: string): string;
97
99
  export declare function resolveActivationBootstrapText(isActivated: boolean, previousText: string, nextText: string): string | null;
100
+ export declare function shouldDeferTargetMeasurement(committedMeasurement: MorphMeasurement | null, pendingBootstrapText: string | null, text: string): boolean;
98
101
  export declare function Torph({ text, className, }: {
99
102
  text: string;
100
103
  className?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grahlnn/comps",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "React components from grahlnn/comps.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",