@jsenv/navi 0.16.58 → 0.16.59
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/jsenv_navi.js +1357 -1284
- package/dist/jsenv_navi.js.map +136 -128
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { installImportMetaCss } from "./jsenv_navi_side_effects.js";
|
|
2
2
|
import { useErrorBoundary, useLayoutEffect, useEffect, useCallback, useRef, useState, useContext, useMemo, useImperativeHandle, useId } from "preact/hooks";
|
|
3
3
|
import { jsxs, jsx, Fragment } from "preact/jsx-runtime";
|
|
4
|
-
import { createIterableWeakSet, mergeOneStyle, stringifyStyle, createPubSub, mergeTwoStyles, normalizeStyles, createGroupTransitionController, getElementSignature, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition,
|
|
4
|
+
import { createIterableWeakSet, mergeOneStyle, stringifyStyle, createPubSub, mergeTwoStyles, normalizeStyles, createGroupTransitionController, getElementSignature, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, findBefore, findAfter, createValueEffect, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, allowWheelThrough, resolveCSSColor, createStyleController, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, hasCSSSizeUnit, resolveCSSSize, activeElementSignal, canInterceptKeys, pickLightOrDark, resolveColorLuminance, initFocusGroup, dragAfterThreshold, getScrollContainer, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement, elementIsFocusable } from "@jsenv/dom";
|
|
5
5
|
import { prefixFirstAndIndentRemainingLines } from "@jsenv/humanize";
|
|
6
6
|
import { effect, signal, computed, batch, useSignal } from "@preact/signals";
|
|
7
7
|
import { createValidity } from "@jsenv/validity";
|
|
@@ -1448,6 +1448,7 @@ const createAction = (callback, rootOptions = {}) => {
|
|
|
1448
1448
|
for (const key of keyArray) {
|
|
1449
1449
|
const signalForThisKey = signalMap.get(key);
|
|
1450
1450
|
if (signalForThisKey) {
|
|
1451
|
+
// eslint-disable-next-line signals/no-conditional-value-read
|
|
1451
1452
|
params[key] = signalForThisKey.value;
|
|
1452
1453
|
} else {
|
|
1453
1454
|
params[key] = staticParams[key];
|
|
@@ -12102,691 +12103,141 @@ const renderActionableComponent = (props, {
|
|
|
12102
12103
|
});
|
|
12103
12104
|
};
|
|
12104
12105
|
|
|
12105
|
-
|
|
12106
|
-
|
|
12107
|
-
|
|
12108
|
-
|
|
12109
|
-
|
|
12110
|
-
|
|
12111
|
-
|
|
12112
|
-
|
|
12113
|
-
|
|
12114
|
-
|
|
12115
|
-
|
|
12116
|
-
|
|
12117
|
-
|
|
12118
|
-
|
|
12119
|
-
|
|
12120
|
-
|
|
12121
|
-
|
|
12122
|
-
|
|
12123
|
-
|
|
12124
|
-
|
|
12125
|
-
|
|
12126
|
-
|
|
12127
|
-
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
}
|
|
12106
|
+
/**
|
|
12107
|
+
* Custom hook creating a stable callback that doesn't trigger re-renders.
|
|
12108
|
+
*
|
|
12109
|
+
* PROBLEM: Parent components often forget to use useCallback, causing library
|
|
12110
|
+
* components to re-render unnecessarily when receiving callback props.
|
|
12111
|
+
*
|
|
12112
|
+
* SOLUTION: Library components can use this hook to create stable callback
|
|
12113
|
+
* references internally, making them defensive against parents who don't
|
|
12114
|
+
* optimize their callbacks. This ensures library components don't force
|
|
12115
|
+
* consumers to think about useCallback.
|
|
12116
|
+
*
|
|
12117
|
+
* USAGE:
|
|
12118
|
+
* ```js
|
|
12119
|
+
* // Parent component (consumer) - no useCallback needed
|
|
12120
|
+
* const Parent = () => {
|
|
12121
|
+
* const [count, setCount] = useState(0);
|
|
12122
|
+
*
|
|
12123
|
+
* // Parent naturally creates new function reference each render
|
|
12124
|
+
* // (forgetting useCallback is common and shouldn't break performance)
|
|
12125
|
+
* return <LibraryButton onClick={(e) => setCount(count + 1)} />;
|
|
12126
|
+
* };
|
|
12127
|
+
*
|
|
12128
|
+
* // Library component - defensive against changing callbacks
|
|
12129
|
+
* const LibraryButton = ({ onClick }) => {
|
|
12130
|
+
* // ✅ Create stable reference from parent's potentially changing callback
|
|
12131
|
+
* const stableClick = useStableCallback(onClick);
|
|
12132
|
+
*
|
|
12133
|
+
* // Internal expensive components won't re-render when parent updates
|
|
12134
|
+
* return <ExpensiveInternalButton onClick={stableClick} />;
|
|
12135
|
+
* };
|
|
12136
|
+
*
|
|
12137
|
+
* // Deep internal component gets stable reference
|
|
12138
|
+
* const ExpensiveInternalButton = memo(({ onClick }) => {
|
|
12139
|
+
* // This won't re-render when Parent's count changes
|
|
12140
|
+
* // But onClick will always call the latest Parent callback
|
|
12141
|
+
* return <button onClick={onClick}>Click me</button>;
|
|
12142
|
+
* });
|
|
12143
|
+
* ```
|
|
12144
|
+
*
|
|
12145
|
+
* Perfect for library components that need performance without burdening consumers.
|
|
12146
|
+
*/
|
|
12134
12147
|
|
|
12135
|
-
const useNetworkSpeed = () => {
|
|
12136
|
-
return networkSpeedSignal.value;
|
|
12137
|
-
};
|
|
12138
12148
|
|
|
12139
|
-
const
|
|
12140
|
-
|
|
12141
|
-
|
|
12142
|
-
|
|
12149
|
+
const useStableCallback = (callback, mapper) => {
|
|
12150
|
+
const callbackRef = useRef();
|
|
12151
|
+
callbackRef.current = callback;
|
|
12152
|
+
const stableCallbackRef = useRef();
|
|
12143
12153
|
|
|
12144
|
-
|
|
12145
|
-
|
|
12146
|
-
|
|
12147
|
-
return "3g";
|
|
12148
|
-
}
|
|
12149
|
-
if (connection) {
|
|
12150
|
-
const effectiveType = connection.effectiveType;
|
|
12151
|
-
if (effectiveType) {
|
|
12152
|
-
return effectiveType; // "slow-2g", "2g", "3g", "4g", "5g"
|
|
12153
|
-
}
|
|
12154
|
-
const downlink = connection.downlink;
|
|
12155
|
-
if (downlink) {
|
|
12156
|
-
// downlink is in Mbps
|
|
12157
|
-
if (downlink < 1) return "slow-2g"; // < 1 Mbps
|
|
12158
|
-
if (downlink < 2.5) return "2g"; // 1-2.5 Mbps
|
|
12159
|
-
if (downlink < 10) return "3g"; // 2.5-10 Mbps
|
|
12160
|
-
return "4g"; // > 10 Mbps
|
|
12161
|
-
}
|
|
12154
|
+
// Return original falsy value directly when callback is not a function
|
|
12155
|
+
if (!callback) {
|
|
12156
|
+
return callback;
|
|
12162
12157
|
}
|
|
12163
|
-
return "3g";
|
|
12164
|
-
};
|
|
12165
|
-
|
|
12166
|
-
const updateNetworkSpeed = () => {
|
|
12167
|
-
networkSpeedSignal.value = getNetworkSpeed();
|
|
12168
|
-
};
|
|
12169
|
-
|
|
12170
|
-
const networkSpeedSignal = signal(getNetworkSpeed());
|
|
12171
|
-
|
|
12172
|
-
const setupNetworkMonitoring = () => {
|
|
12173
|
-
const cleanupFunctions = [];
|
|
12174
|
-
|
|
12175
|
-
// ✅ 1. Écouter les changements natifs
|
|
12176
12158
|
|
|
12177
|
-
|
|
12178
|
-
|
|
12179
|
-
|
|
12180
|
-
connection.removeEventListener("change", updateNetworkSpeed);
|
|
12181
|
-
});
|
|
12159
|
+
const existingStableCallback = stableCallbackRef.current;
|
|
12160
|
+
if (existingStableCallback) {
|
|
12161
|
+
return existingStableCallback;
|
|
12182
12162
|
}
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
cleanupFunctions.push(() => clearInterval(pollInterval));
|
|
12187
|
-
|
|
12188
|
-
// ✅ 3. Vérifier lors de la reprise d'activité
|
|
12189
|
-
const handleVisibilityChange = () => {
|
|
12190
|
-
if (!document.hidden) {
|
|
12191
|
-
updateNetworkSpeed();
|
|
12192
|
-
}
|
|
12193
|
-
};
|
|
12194
|
-
|
|
12195
|
-
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
12196
|
-
cleanupFunctions.push(() => {
|
|
12197
|
-
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
12198
|
-
});
|
|
12199
|
-
|
|
12200
|
-
// ✅ 4. Vérifier lors de la reprise de connexion
|
|
12201
|
-
const handleOnline = () => {
|
|
12202
|
-
updateNetworkSpeed();
|
|
12203
|
-
};
|
|
12204
|
-
|
|
12205
|
-
window.addEventListener("online", handleOnline);
|
|
12206
|
-
cleanupFunctions.push(() => {
|
|
12207
|
-
window.removeEventListener("online", handleOnline);
|
|
12208
|
-
});
|
|
12209
|
-
|
|
12210
|
-
// Cleanup global
|
|
12211
|
-
return () => {
|
|
12212
|
-
cleanupFunctions.forEach((cleanup) => cleanup());
|
|
12163
|
+
const stableCallback = (...args) => {
|
|
12164
|
+
const currentCallback = callbackRef.current;
|
|
12165
|
+
return currentCallback(...args);
|
|
12213
12166
|
};
|
|
12167
|
+
stableCallbackRef.current = stableCallback;
|
|
12168
|
+
return stableCallback;
|
|
12214
12169
|
};
|
|
12215
|
-
setupNetworkMonitoring();
|
|
12216
|
-
|
|
12217
|
-
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
12218
|
-
.navi_rectangle_loading {
|
|
12219
|
-
position: relative;
|
|
12220
|
-
display: flex;
|
|
12221
|
-
width: 100%;
|
|
12222
|
-
height: 100%;
|
|
12223
|
-
opacity: 0;
|
|
12224
|
-
}
|
|
12225
12170
|
|
|
12226
|
-
|
|
12227
|
-
|
|
12171
|
+
const DEBUG = {
|
|
12172
|
+
registration: false,
|
|
12173
|
+
// Element registration/unregistration
|
|
12174
|
+
interaction: false,
|
|
12175
|
+
// Click and keyboard interactions
|
|
12176
|
+
selection: false,
|
|
12177
|
+
// Selection state changes (set, add, remove, toggle)
|
|
12178
|
+
navigation: false,
|
|
12179
|
+
// Arrow key navigation and element finding
|
|
12180
|
+
valueExtraction: false // Value extraction from elements
|
|
12181
|
+
};
|
|
12182
|
+
const debug = (category, ...args) => {
|
|
12183
|
+
if (DEBUG[category]) {
|
|
12184
|
+
console.debug(`[selection:${category}]`, ...args);
|
|
12228
12185
|
}
|
|
12229
|
-
|
|
12230
|
-
const
|
|
12231
|
-
|
|
12232
|
-
|
|
12233
|
-
|
|
12234
|
-
|
|
12186
|
+
};
|
|
12187
|
+
const SelectionContext = createContext();
|
|
12188
|
+
const useSelectionController = ({
|
|
12189
|
+
elementRef,
|
|
12190
|
+
layout,
|
|
12191
|
+
value,
|
|
12192
|
+
onChange,
|
|
12193
|
+
multiple,
|
|
12194
|
+
selectAllName
|
|
12235
12195
|
}) => {
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
|
|
12196
|
+
if (!elementRef) {
|
|
12197
|
+
throw new Error("useSelectionController: elementRef is required");
|
|
12198
|
+
}
|
|
12199
|
+
onChange = useStableCallback(onChange);
|
|
12200
|
+
const currentValueRef = useRef(value);
|
|
12201
|
+
currentValueRef.current = value;
|
|
12202
|
+
const lastInternalValueRef = useRef(null);
|
|
12203
|
+
const selectionController = useMemo(() => {
|
|
12204
|
+
const innerOnChange = (newValue, ...args) => {
|
|
12205
|
+
lastInternalValueRef.current = newValue;
|
|
12206
|
+
onChange?.(newValue, ...args);
|
|
12207
|
+
};
|
|
12208
|
+
const getCurrentValue = () => currentValueRef.current;
|
|
12209
|
+
if (layout === "grid") {
|
|
12210
|
+
return createGridSelectionController({
|
|
12211
|
+
getCurrentValue,
|
|
12212
|
+
onChange: innerOnChange,
|
|
12213
|
+
enabled: Boolean(onChange),
|
|
12214
|
+
multiple,
|
|
12215
|
+
selectAllName
|
|
12216
|
+
});
|
|
12217
|
+
}
|
|
12218
|
+
return createLinearSelectionController({
|
|
12219
|
+
getCurrentValue,
|
|
12220
|
+
onChange: innerOnChange,
|
|
12221
|
+
layout,
|
|
12222
|
+
elementRef,
|
|
12223
|
+
multiple,
|
|
12224
|
+
enabled: Boolean(onChange),
|
|
12225
|
+
selectAllName
|
|
12226
|
+
});
|
|
12227
|
+
}, [layout, multiple, elementRef]);
|
|
12228
|
+
useEffect(() => {
|
|
12229
|
+
selectionController.element = elementRef.current;
|
|
12230
|
+
}, [selectionController]);
|
|
12239
12231
|
useLayoutEffect(() => {
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
setContainerHeight(height);
|
|
12250
|
-
let animationFrameId = null;
|
|
12251
|
-
// Create a resize observer to detect changes in the container's dimensions
|
|
12252
|
-
const resizeObserver = new ResizeObserver(entries => {
|
|
12253
|
-
// Use requestAnimationFrame to debounce updates
|
|
12254
|
-
if (animationFrameId) {
|
|
12255
|
-
cancelAnimationFrame(animationFrameId);
|
|
12256
|
-
}
|
|
12257
|
-
animationFrameId = requestAnimationFrame(() => {
|
|
12258
|
-
const [containerEntry] = entries;
|
|
12259
|
-
const {
|
|
12260
|
-
width,
|
|
12261
|
-
height
|
|
12262
|
-
} = containerEntry.contentRect;
|
|
12263
|
-
setContainerWidth(width);
|
|
12264
|
-
setContainerHeight(height);
|
|
12265
|
-
});
|
|
12266
|
-
});
|
|
12267
|
-
resizeObserver.observe(container);
|
|
12268
|
-
return () => {
|
|
12269
|
-
if (animationFrameId) {
|
|
12270
|
-
cancelAnimationFrame(animationFrameId);
|
|
12271
|
-
}
|
|
12272
|
-
resizeObserver.disconnect();
|
|
12273
|
-
};
|
|
12274
|
-
}, []);
|
|
12275
|
-
return jsx("span", {
|
|
12276
|
-
ref: containerRef,
|
|
12277
|
-
className: "navi_rectangle_loading",
|
|
12278
|
-
"data-visible": shouldShowSpinner ? "" : undefined,
|
|
12279
|
-
children: containerWidth > 0 && containerHeight > 0 && jsx(RectangleLoadingSvg, {
|
|
12280
|
-
radius: radius,
|
|
12281
|
-
color: color,
|
|
12282
|
-
width: containerWidth,
|
|
12283
|
-
height: containerHeight,
|
|
12284
|
-
strokeWidth: size
|
|
12285
|
-
})
|
|
12286
|
-
});
|
|
12287
|
-
};
|
|
12288
|
-
const RectangleLoadingSvg = ({
|
|
12289
|
-
width,
|
|
12290
|
-
height,
|
|
12291
|
-
color,
|
|
12292
|
-
radius,
|
|
12293
|
-
trailColor = "transparent",
|
|
12294
|
-
strokeWidth
|
|
12295
|
-
}) => {
|
|
12296
|
-
const margin = Math.max(2, Math.min(width, height) * 0.03);
|
|
12297
|
-
|
|
12298
|
-
// Calculate the drawable area
|
|
12299
|
-
const drawableWidth = width - margin * 2;
|
|
12300
|
-
const drawableHeight = height - margin * 2;
|
|
12301
|
-
|
|
12302
|
-
// ✅ Check if this should be a circle - only if width and height are nearly equal
|
|
12303
|
-
const maxPossibleRadius = Math.min(drawableWidth, drawableHeight) / 2;
|
|
12304
|
-
const actualRadius = Math.min(radius || Math.min(drawableWidth, drawableHeight) * 0.05, maxPossibleRadius // ✅ Limité au radius maximum possible
|
|
12305
|
-
);
|
|
12306
|
-
const aspectRatio = Math.max(drawableWidth, drawableHeight) / Math.min(drawableWidth, drawableHeight);
|
|
12307
|
-
const isNearlySquare = aspectRatio <= 1.2; // Allow some tolerance for nearly square shapes
|
|
12308
|
-
const isCircle = isNearlySquare && actualRadius >= maxPossibleRadius * 0.95;
|
|
12309
|
-
let pathLength;
|
|
12310
|
-
let rectPath;
|
|
12311
|
-
if (isCircle) {
|
|
12312
|
-
// ✅ Circle: perimeter = 2πr
|
|
12313
|
-
pathLength = 2 * Math.PI * actualRadius;
|
|
12314
|
-
|
|
12315
|
-
// ✅ Circle path centered in the drawable area
|
|
12316
|
-
const centerX = margin + drawableWidth / 2;
|
|
12317
|
-
const centerY = margin + drawableHeight / 2;
|
|
12318
|
-
rectPath = `
|
|
12319
|
-
M ${centerX + actualRadius},${centerY}
|
|
12320
|
-
A ${actualRadius},${actualRadius} 0 1 1 ${centerX - actualRadius},${centerY}
|
|
12321
|
-
A ${actualRadius},${actualRadius} 0 1 1 ${centerX + actualRadius},${centerY}
|
|
12322
|
-
`;
|
|
12323
|
-
} else {
|
|
12324
|
-
// ✅ Rectangle: calculate perimeter properly
|
|
12325
|
-
const straightEdges = 2 * (drawableWidth - 2 * actualRadius) + 2 * (drawableHeight - 2 * actualRadius);
|
|
12326
|
-
const cornerArcs = actualRadius > 0 ? 2 * Math.PI * actualRadius : 0;
|
|
12327
|
-
pathLength = straightEdges + cornerArcs;
|
|
12328
|
-
rectPath = `
|
|
12329
|
-
M ${margin + actualRadius},${margin}
|
|
12330
|
-
L ${margin + drawableWidth - actualRadius},${margin}
|
|
12331
|
-
A ${actualRadius},${actualRadius} 0 0 1 ${margin + drawableWidth},${margin + actualRadius}
|
|
12332
|
-
L ${margin + drawableWidth},${margin + drawableHeight - actualRadius}
|
|
12333
|
-
A ${actualRadius},${actualRadius} 0 0 1 ${margin + drawableWidth - actualRadius},${margin + drawableHeight}
|
|
12334
|
-
L ${margin + actualRadius},${margin + drawableHeight}
|
|
12335
|
-
A ${actualRadius},${actualRadius} 0 0 1 ${margin},${margin + drawableHeight - actualRadius}
|
|
12336
|
-
L ${margin},${margin + actualRadius}
|
|
12337
|
-
A ${actualRadius},${actualRadius} 0 0 1 ${margin + actualRadius},${margin}
|
|
12338
|
-
`;
|
|
12339
|
-
}
|
|
12340
|
-
|
|
12341
|
-
// Fixed segment size in pixels
|
|
12342
|
-
const maxSegmentSize = 40;
|
|
12343
|
-
const segmentLength = Math.min(maxSegmentSize, pathLength * 0.25);
|
|
12344
|
-
const gapLength = pathLength - segmentLength;
|
|
12345
|
-
|
|
12346
|
-
// Vitesse constante en pixels par seconde
|
|
12347
|
-
const networkSpeed = useNetworkSpeed();
|
|
12348
|
-
const pixelsPerSecond = {
|
|
12349
|
-
"slow-2g": 40,
|
|
12350
|
-
"2g": 60,
|
|
12351
|
-
"3g": 80,
|
|
12352
|
-
"4g": 120
|
|
12353
|
-
}[networkSpeed] || 80;
|
|
12354
|
-
const animationDuration = Math.max(1.5, pathLength / pixelsPerSecond);
|
|
12355
|
-
|
|
12356
|
-
// ✅ Calculate correct offset based on actual segment size
|
|
12357
|
-
const segmentRatio = segmentLength / pathLength;
|
|
12358
|
-
const circleOffset = -animationDuration * segmentRatio;
|
|
12359
|
-
return jsxs("svg", {
|
|
12360
|
-
width: "100%",
|
|
12361
|
-
height: "100%",
|
|
12362
|
-
viewBox: `0 0 ${width} ${height}`,
|
|
12363
|
-
preserveAspectRatio: "none",
|
|
12364
|
-
style: "overflow: visible",
|
|
12365
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
12366
|
-
"shape-rendering": "geometricPrecision",
|
|
12367
|
-
children: [isCircle ? jsx("circle", {
|
|
12368
|
-
cx: margin + drawableWidth / 2,
|
|
12369
|
-
cy: margin + drawableHeight / 2,
|
|
12370
|
-
r: actualRadius,
|
|
12371
|
-
fill: "none",
|
|
12372
|
-
stroke: trailColor,
|
|
12373
|
-
strokeWidth: strokeWidth
|
|
12374
|
-
}) : jsx("rect", {
|
|
12375
|
-
x: margin,
|
|
12376
|
-
y: margin,
|
|
12377
|
-
width: drawableWidth,
|
|
12378
|
-
height: drawableHeight,
|
|
12379
|
-
fill: "none",
|
|
12380
|
-
stroke: trailColor,
|
|
12381
|
-
strokeWidth: strokeWidth,
|
|
12382
|
-
rx: actualRadius
|
|
12383
|
-
}), jsx("path", {
|
|
12384
|
-
d: rectPath,
|
|
12385
|
-
fill: "none",
|
|
12386
|
-
stroke: color,
|
|
12387
|
-
strokeWidth: strokeWidth,
|
|
12388
|
-
strokeLinecap: "round",
|
|
12389
|
-
strokeDasharray: `${segmentLength} ${gapLength}`,
|
|
12390
|
-
pathLength: pathLength,
|
|
12391
|
-
children: jsx("animate", {
|
|
12392
|
-
attributeName: "stroke-dashoffset",
|
|
12393
|
-
from: pathLength,
|
|
12394
|
-
to: "0",
|
|
12395
|
-
dur: `${animationDuration}s`,
|
|
12396
|
-
repeatCount: "indefinite",
|
|
12397
|
-
begin: "0s"
|
|
12398
|
-
})
|
|
12399
|
-
}), jsx("circle", {
|
|
12400
|
-
r: strokeWidth,
|
|
12401
|
-
fill: color,
|
|
12402
|
-
children: jsx("animateMotion", {
|
|
12403
|
-
path: rectPath,
|
|
12404
|
-
dur: `${animationDuration}s`,
|
|
12405
|
-
repeatCount: "indefinite",
|
|
12406
|
-
rotate: "auto",
|
|
12407
|
-
begin: `${circleOffset}s`
|
|
12408
|
-
})
|
|
12409
|
-
})]
|
|
12410
|
-
});
|
|
12411
|
-
};
|
|
12412
|
-
|
|
12413
|
-
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
12414
|
-
.navi_loading_rectangle_wrapper {
|
|
12415
|
-
position: absolute;
|
|
12416
|
-
top: var(--rectangle-top, 0);
|
|
12417
|
-
right: var(--rectangle-right, 0);
|
|
12418
|
-
bottom: var(--rectangle-bottom, 0);
|
|
12419
|
-
left: var(--rectangle-left, 0);
|
|
12420
|
-
z-index: 1;
|
|
12421
|
-
opacity: 0;
|
|
12422
|
-
pointer-events: none;
|
|
12423
|
-
}
|
|
12424
|
-
.navi_loading_rectangle_wrapper[data-visible] {
|
|
12425
|
-
opacity: 1;
|
|
12426
|
-
}
|
|
12427
|
-
`;
|
|
12428
|
-
const LoaderBackground = ({
|
|
12429
|
-
loading,
|
|
12430
|
-
containerRef,
|
|
12431
|
-
targetSelector,
|
|
12432
|
-
color,
|
|
12433
|
-
inset = 0,
|
|
12434
|
-
spacingTop = 0,
|
|
12435
|
-
spacingLeft = 0,
|
|
12436
|
-
spacingBottom = 0,
|
|
12437
|
-
spacingRight = 0,
|
|
12438
|
-
children
|
|
12439
|
-
}) => {
|
|
12440
|
-
if (containerRef) {
|
|
12441
|
-
const container = containerRef.current;
|
|
12442
|
-
if (!container) {
|
|
12443
|
-
return children;
|
|
12444
|
-
}
|
|
12445
|
-
return createPortal(jsx(LoaderBackgroundWithPortal, {
|
|
12446
|
-
container: container,
|
|
12447
|
-
loading: loading,
|
|
12448
|
-
color: color,
|
|
12449
|
-
inset: inset,
|
|
12450
|
-
spacingTop: spacingTop,
|
|
12451
|
-
spacingLeft: spacingLeft,
|
|
12452
|
-
spacingBottom: spacingBottom,
|
|
12453
|
-
spacingRight: spacingRight,
|
|
12454
|
-
children: children
|
|
12455
|
-
}), container);
|
|
12456
|
-
}
|
|
12457
|
-
return jsx(LoaderBackgroundBasic, {
|
|
12458
|
-
targetSelector: targetSelector,
|
|
12459
|
-
loading: loading,
|
|
12460
|
-
color: color,
|
|
12461
|
-
inset: inset,
|
|
12462
|
-
spacingTop: spacingTop,
|
|
12463
|
-
spacingLeft: spacingLeft,
|
|
12464
|
-
spacingBottom: spacingBottom,
|
|
12465
|
-
spacingRight: spacingRight,
|
|
12466
|
-
children: children
|
|
12467
|
-
});
|
|
12468
|
-
};
|
|
12469
|
-
const LoaderBackgroundWithPortal = ({
|
|
12470
|
-
container,
|
|
12471
|
-
loading,
|
|
12472
|
-
color,
|
|
12473
|
-
inset,
|
|
12474
|
-
spacingTop,
|
|
12475
|
-
spacingLeft,
|
|
12476
|
-
spacingBottom,
|
|
12477
|
-
spacingRight,
|
|
12478
|
-
children
|
|
12479
|
-
}) => {
|
|
12480
|
-
const shouldShowSpinner = useDebounceTrue(loading, 300);
|
|
12481
|
-
if (!shouldShowSpinner) {
|
|
12482
|
-
return children;
|
|
12483
|
-
}
|
|
12484
|
-
container.style.position = "relative";
|
|
12485
|
-
let paddingTop = 0;
|
|
12486
|
-
if (container.nodeName === "DETAILS") {
|
|
12487
|
-
paddingTop = container.querySelector("summary").offsetHeight;
|
|
12488
|
-
}
|
|
12489
|
-
return jsxs(Fragment, {
|
|
12490
|
-
children: [jsx("div", {
|
|
12491
|
-
style: {
|
|
12492
|
-
position: "absolute",
|
|
12493
|
-
top: `${inset + paddingTop + spacingTop}px`,
|
|
12494
|
-
bottom: `${inset + spacingBottom}px`,
|
|
12495
|
-
left: `${inset + spacingLeft}px`,
|
|
12496
|
-
right: `${inset + spacingRight}px`
|
|
12497
|
-
},
|
|
12498
|
-
children: shouldShowSpinner && jsx(RectangleLoading, {
|
|
12499
|
-
color: color
|
|
12500
|
-
})
|
|
12501
|
-
}), children]
|
|
12502
|
-
});
|
|
12503
|
-
};
|
|
12504
|
-
const LoaderBackgroundBasic = ({
|
|
12505
|
-
loading,
|
|
12506
|
-
targetSelector,
|
|
12507
|
-
color,
|
|
12508
|
-
spacingTop,
|
|
12509
|
-
spacingLeft,
|
|
12510
|
-
spacingBottom,
|
|
12511
|
-
spacingRight,
|
|
12512
|
-
inset,
|
|
12513
|
-
children
|
|
12514
|
-
}) => {
|
|
12515
|
-
const shouldShowSpinner = useDebounceTrue(loading, 300);
|
|
12516
|
-
const rectangleRef = useRef(null);
|
|
12517
|
-
const [, setOutlineOffset] = useState(0);
|
|
12518
|
-
const [borderRadius, setBorderRadius] = useState(0);
|
|
12519
|
-
const [borderTopWidth, setBorderTopWidth] = useState(0);
|
|
12520
|
-
const [borderLeftWidth, setBorderLeftWidth] = useState(0);
|
|
12521
|
-
const [borderRightWidth, setBorderRightWidth] = useState(0);
|
|
12522
|
-
const [borderBottomWidth, setBorderBottomWidth] = useState(0);
|
|
12523
|
-
const [marginTop, setMarginTop] = useState(0);
|
|
12524
|
-
const [marginBottom, setMarginBottom] = useState(0);
|
|
12525
|
-
const [marginLeft, setMarginLeft] = useState(0);
|
|
12526
|
-
const [marginRight, setMarginRight] = useState(0);
|
|
12527
|
-
const [paddingTop, setPaddingTop] = useState(0);
|
|
12528
|
-
const [paddingLeft, setPaddingLeft] = useState(0);
|
|
12529
|
-
const [paddingRight, setPaddingRight] = useState(0);
|
|
12530
|
-
const [paddingBottom, setPaddingBottom] = useState(0);
|
|
12531
|
-
const [currentColor, setCurrentColor] = useState(color);
|
|
12532
|
-
useLayoutEffect(() => {
|
|
12533
|
-
let animationFrame;
|
|
12534
|
-
const updateStyles = () => {
|
|
12535
|
-
const rectangle = rectangleRef.current;
|
|
12536
|
-
if (!rectangle) {
|
|
12537
|
-
return;
|
|
12538
|
-
}
|
|
12539
|
-
const container = rectangle.parentElement;
|
|
12540
|
-
const containedElement = rectangle.nextElementSibling;
|
|
12541
|
-
const target = targetSelector ? container.querySelector(targetSelector) : containedElement;
|
|
12542
|
-
if (target) {
|
|
12543
|
-
const {
|
|
12544
|
-
width,
|
|
12545
|
-
height
|
|
12546
|
-
} = target.getBoundingClientRect();
|
|
12547
|
-
const containedComputedStyle = window.getComputedStyle(containedElement);
|
|
12548
|
-
const targetComputedStyle = window.getComputedStyle(target);
|
|
12549
|
-
const newBorderTopWidth = resolveCSSSize(targetComputedStyle.borderTopWidth);
|
|
12550
|
-
const newBorderLeftWidth = resolveCSSSize(targetComputedStyle.borderLeftWidth);
|
|
12551
|
-
const newBorderRightWidth = resolveCSSSize(targetComputedStyle.borderRightWidth);
|
|
12552
|
-
const newBorderBottomWidth = resolveCSSSize(targetComputedStyle.borderBottomWidth);
|
|
12553
|
-
const newBorderRadius = resolveCSSSize(targetComputedStyle.borderRadius, {
|
|
12554
|
-
availableSize: Math.min(width, height)
|
|
12555
|
-
});
|
|
12556
|
-
const newOutlineColor = targetComputedStyle.outlineColor;
|
|
12557
|
-
const newBorderColor = targetComputedStyle.borderColor;
|
|
12558
|
-
const newDetectedColor = targetComputedStyle.color;
|
|
12559
|
-
const newOutlineOffset = resolveCSSSize(targetComputedStyle.outlineOffset);
|
|
12560
|
-
const newMarginTop = resolveCSSSize(targetComputedStyle.marginTop);
|
|
12561
|
-
const newMarginBottom = resolveCSSSize(targetComputedStyle.marginBottom);
|
|
12562
|
-
const newMarginLeft = resolveCSSSize(targetComputedStyle.marginLeft);
|
|
12563
|
-
const newMarginRight = resolveCSSSize(targetComputedStyle.marginRight);
|
|
12564
|
-
const paddingTop = resolveCSSSize(containedComputedStyle.paddingTop);
|
|
12565
|
-
const paddingLeft = resolveCSSSize(containedComputedStyle.paddingLeft);
|
|
12566
|
-
const paddingRight = resolveCSSSize(containedComputedStyle.paddingRight);
|
|
12567
|
-
const paddingBottom = resolveCSSSize(containedComputedStyle.paddingBottom);
|
|
12568
|
-
setBorderTopWidth(newBorderTopWidth);
|
|
12569
|
-
setBorderLeftWidth(newBorderLeftWidth);
|
|
12570
|
-
setBorderRightWidth(newBorderRightWidth);
|
|
12571
|
-
setBorderBottomWidth(newBorderBottomWidth);
|
|
12572
|
-
setBorderRadius(newBorderRadius);
|
|
12573
|
-
setOutlineOffset(newOutlineOffset);
|
|
12574
|
-
setMarginTop(newMarginTop);
|
|
12575
|
-
setMarginBottom(newMarginBottom);
|
|
12576
|
-
setMarginLeft(newMarginLeft);
|
|
12577
|
-
setMarginRight(newMarginRight);
|
|
12578
|
-
setPaddingTop(paddingTop);
|
|
12579
|
-
setPaddingLeft(paddingLeft);
|
|
12580
|
-
setPaddingRight(paddingRight);
|
|
12581
|
-
setPaddingBottom(paddingBottom);
|
|
12582
|
-
if (color) {
|
|
12583
|
-
// const resolvedColor = resolveCSSColor(color, rectangle, "css");
|
|
12584
|
-
// console.log(resolvedColor);
|
|
12585
|
-
setCurrentColor(color);
|
|
12586
|
-
} else if (newOutlineColor && newOutlineColor !== "rgba(0, 0, 0, 0)" && (document.activeElement === containedElement || newBorderColor === "rgba(0, 0, 0, 0)")) {
|
|
12587
|
-
setCurrentColor(newOutlineColor);
|
|
12588
|
-
} else if (newBorderColor && newBorderColor !== "rgba(0, 0, 0, 0)") {
|
|
12589
|
-
setCurrentColor(newBorderColor);
|
|
12590
|
-
} else {
|
|
12591
|
-
setCurrentColor(newDetectedColor);
|
|
12592
|
-
}
|
|
12593
|
-
}
|
|
12594
|
-
// updateStyles is very cheap so we run it every frame
|
|
12595
|
-
animationFrame = requestAnimationFrame(updateStyles);
|
|
12596
|
-
};
|
|
12597
|
-
updateStyles();
|
|
12598
|
-
return () => {
|
|
12599
|
-
cancelAnimationFrame(animationFrame);
|
|
12600
|
-
};
|
|
12601
|
-
}, [color, targetSelector]);
|
|
12602
|
-
spacingTop += inset;
|
|
12603
|
-
// spacingTop += outlineOffset;
|
|
12604
|
-
// spacingTop -= borderTopWidth;
|
|
12605
|
-
spacingTop += marginTop;
|
|
12606
|
-
spacingLeft += inset;
|
|
12607
|
-
// spacingLeft += outlineOffset;
|
|
12608
|
-
// spacingLeft -= borderLeftWidth;
|
|
12609
|
-
spacingLeft += marginLeft;
|
|
12610
|
-
spacingRight += inset;
|
|
12611
|
-
// spacingRight += outlineOffset;
|
|
12612
|
-
// spacingRight -= borderRightWidth;
|
|
12613
|
-
spacingRight += marginRight;
|
|
12614
|
-
spacingBottom += inset;
|
|
12615
|
-
// spacingBottom += outlineOffset;
|
|
12616
|
-
// spacingBottom -= borderBottomWidth;
|
|
12617
|
-
spacingBottom += marginBottom;
|
|
12618
|
-
if (targetSelector) {
|
|
12619
|
-
// oversimplification that actually works
|
|
12620
|
-
// (simplified because it assumes the targeted element is a direct child of the contained element which may have padding)
|
|
12621
|
-
spacingTop += paddingTop;
|
|
12622
|
-
spacingLeft += paddingLeft;
|
|
12623
|
-
spacingRight += paddingRight;
|
|
12624
|
-
spacingBottom += paddingBottom;
|
|
12625
|
-
}
|
|
12626
|
-
const maxBorderWidth = Math.max(borderTopWidth, borderLeftWidth, borderRightWidth, borderBottomWidth);
|
|
12627
|
-
const halfMaxBorderSize = maxBorderWidth / 2;
|
|
12628
|
-
const size = halfMaxBorderSize < 2 ? 2 : halfMaxBorderSize;
|
|
12629
|
-
const lineHalfSize = size / 2;
|
|
12630
|
-
spacingTop -= lineHalfSize;
|
|
12631
|
-
spacingLeft -= lineHalfSize;
|
|
12632
|
-
spacingRight -= lineHalfSize;
|
|
12633
|
-
spacingBottom -= lineHalfSize;
|
|
12634
|
-
return jsxs(Fragment, {
|
|
12635
|
-
children: [jsx("span", {
|
|
12636
|
-
ref: rectangleRef,
|
|
12637
|
-
className: "navi_loading_rectangle_wrapper",
|
|
12638
|
-
"data-visible": shouldShowSpinner ? "" : undefined,
|
|
12639
|
-
style: {
|
|
12640
|
-
"--rectangle-top": `${spacingTop}px`,
|
|
12641
|
-
"--rectangle-left": `${spacingLeft}px`,
|
|
12642
|
-
"--rectangle-bottom": `${spacingBottom}px`,
|
|
12643
|
-
"--rectangle-right": `${spacingRight}px`
|
|
12644
|
-
},
|
|
12645
|
-
children: loading && jsx(RectangleLoading, {
|
|
12646
|
-
shouldShowSpinner: shouldShowSpinner,
|
|
12647
|
-
color: currentColor,
|
|
12648
|
-
radius: borderRadius,
|
|
12649
|
-
size: size
|
|
12650
|
-
})
|
|
12651
|
-
}), children]
|
|
12652
|
-
});
|
|
12653
|
-
};
|
|
12654
|
-
|
|
12655
|
-
/**
|
|
12656
|
-
* Custom hook creating a stable callback that doesn't trigger re-renders.
|
|
12657
|
-
*
|
|
12658
|
-
* PROBLEM: Parent components often forget to use useCallback, causing library
|
|
12659
|
-
* components to re-render unnecessarily when receiving callback props.
|
|
12660
|
-
*
|
|
12661
|
-
* SOLUTION: Library components can use this hook to create stable callback
|
|
12662
|
-
* references internally, making them defensive against parents who don't
|
|
12663
|
-
* optimize their callbacks. This ensures library components don't force
|
|
12664
|
-
* consumers to think about useCallback.
|
|
12665
|
-
*
|
|
12666
|
-
* USAGE:
|
|
12667
|
-
* ```js
|
|
12668
|
-
* // Parent component (consumer) - no useCallback needed
|
|
12669
|
-
* const Parent = () => {
|
|
12670
|
-
* const [count, setCount] = useState(0);
|
|
12671
|
-
*
|
|
12672
|
-
* // Parent naturally creates new function reference each render
|
|
12673
|
-
* // (forgetting useCallback is common and shouldn't break performance)
|
|
12674
|
-
* return <LibraryButton onClick={(e) => setCount(count + 1)} />;
|
|
12675
|
-
* };
|
|
12676
|
-
*
|
|
12677
|
-
* // Library component - defensive against changing callbacks
|
|
12678
|
-
* const LibraryButton = ({ onClick }) => {
|
|
12679
|
-
* // ✅ Create stable reference from parent's potentially changing callback
|
|
12680
|
-
* const stableClick = useStableCallback(onClick);
|
|
12681
|
-
*
|
|
12682
|
-
* // Internal expensive components won't re-render when parent updates
|
|
12683
|
-
* return <ExpensiveInternalButton onClick={stableClick} />;
|
|
12684
|
-
* };
|
|
12685
|
-
*
|
|
12686
|
-
* // Deep internal component gets stable reference
|
|
12687
|
-
* const ExpensiveInternalButton = memo(({ onClick }) => {
|
|
12688
|
-
* // This won't re-render when Parent's count changes
|
|
12689
|
-
* // But onClick will always call the latest Parent callback
|
|
12690
|
-
* return <button onClick={onClick}>Click me</button>;
|
|
12691
|
-
* });
|
|
12692
|
-
* ```
|
|
12693
|
-
*
|
|
12694
|
-
* Perfect for library components that need performance without burdening consumers.
|
|
12695
|
-
*/
|
|
12696
|
-
|
|
12697
|
-
|
|
12698
|
-
const useStableCallback = (callback, mapper) => {
|
|
12699
|
-
const callbackRef = useRef();
|
|
12700
|
-
callbackRef.current = callback;
|
|
12701
|
-
const stableCallbackRef = useRef();
|
|
12702
|
-
|
|
12703
|
-
// Return original falsy value directly when callback is not a function
|
|
12704
|
-
if (!callback) {
|
|
12705
|
-
return callback;
|
|
12706
|
-
}
|
|
12707
|
-
|
|
12708
|
-
const existingStableCallback = stableCallbackRef.current;
|
|
12709
|
-
if (existingStableCallback) {
|
|
12710
|
-
return existingStableCallback;
|
|
12711
|
-
}
|
|
12712
|
-
const stableCallback = (...args) => {
|
|
12713
|
-
const currentCallback = callbackRef.current;
|
|
12714
|
-
return currentCallback(...args);
|
|
12715
|
-
};
|
|
12716
|
-
stableCallbackRef.current = stableCallback;
|
|
12717
|
-
return stableCallback;
|
|
12718
|
-
};
|
|
12719
|
-
|
|
12720
|
-
const DEBUG = {
|
|
12721
|
-
registration: false,
|
|
12722
|
-
// Element registration/unregistration
|
|
12723
|
-
interaction: false,
|
|
12724
|
-
// Click and keyboard interactions
|
|
12725
|
-
selection: false,
|
|
12726
|
-
// Selection state changes (set, add, remove, toggle)
|
|
12727
|
-
navigation: false,
|
|
12728
|
-
// Arrow key navigation and element finding
|
|
12729
|
-
valueExtraction: false // Value extraction from elements
|
|
12730
|
-
};
|
|
12731
|
-
const debug = (category, ...args) => {
|
|
12732
|
-
if (DEBUG[category]) {
|
|
12733
|
-
console.debug(`[selection:${category}]`, ...args);
|
|
12734
|
-
}
|
|
12735
|
-
};
|
|
12736
|
-
const SelectionContext = createContext();
|
|
12737
|
-
const useSelectionController = ({
|
|
12738
|
-
elementRef,
|
|
12739
|
-
layout,
|
|
12740
|
-
value,
|
|
12741
|
-
onChange,
|
|
12742
|
-
multiple,
|
|
12743
|
-
selectAllName
|
|
12744
|
-
}) => {
|
|
12745
|
-
if (!elementRef) {
|
|
12746
|
-
throw new Error("useSelectionController: elementRef is required");
|
|
12747
|
-
}
|
|
12748
|
-
onChange = useStableCallback(onChange);
|
|
12749
|
-
const currentValueRef = useRef(value);
|
|
12750
|
-
currentValueRef.current = value;
|
|
12751
|
-
const lastInternalValueRef = useRef(null);
|
|
12752
|
-
const selectionController = useMemo(() => {
|
|
12753
|
-
const innerOnChange = (newValue, ...args) => {
|
|
12754
|
-
lastInternalValueRef.current = newValue;
|
|
12755
|
-
onChange?.(newValue, ...args);
|
|
12756
|
-
};
|
|
12757
|
-
const getCurrentValue = () => currentValueRef.current;
|
|
12758
|
-
if (layout === "grid") {
|
|
12759
|
-
return createGridSelectionController({
|
|
12760
|
-
getCurrentValue,
|
|
12761
|
-
onChange: innerOnChange,
|
|
12762
|
-
enabled: Boolean(onChange),
|
|
12763
|
-
multiple,
|
|
12764
|
-
selectAllName
|
|
12765
|
-
});
|
|
12766
|
-
}
|
|
12767
|
-
return createLinearSelectionController({
|
|
12768
|
-
getCurrentValue,
|
|
12769
|
-
onChange: innerOnChange,
|
|
12770
|
-
layout,
|
|
12771
|
-
elementRef,
|
|
12772
|
-
multiple,
|
|
12773
|
-
enabled: Boolean(onChange),
|
|
12774
|
-
selectAllName
|
|
12775
|
-
});
|
|
12776
|
-
}, [layout, multiple, elementRef]);
|
|
12777
|
-
useEffect(() => {
|
|
12778
|
-
selectionController.element = elementRef.current;
|
|
12779
|
-
}, [selectionController]);
|
|
12780
|
-
useLayoutEffect(() => {
|
|
12781
|
-
selectionController.enabled = Boolean(onChange);
|
|
12782
|
-
}, [selectionController, onChange]);
|
|
12783
|
-
|
|
12784
|
-
// Smart sync: only update selection when value changes externally
|
|
12785
|
-
useEffect(() => {
|
|
12786
|
-
// Check if this is an external change (not from our internal onChange)
|
|
12787
|
-
const isExternalChange = !compareTwoJsValues(value, lastInternalValueRef.current);
|
|
12788
|
-
if (isExternalChange) {
|
|
12789
|
-
selectionController.update(value);
|
|
12232
|
+
selectionController.enabled = Boolean(onChange);
|
|
12233
|
+
}, [selectionController, onChange]);
|
|
12234
|
+
|
|
12235
|
+
// Smart sync: only update selection when value changes externally
|
|
12236
|
+
useEffect(() => {
|
|
12237
|
+
// Check if this is an external change (not from our internal onChange)
|
|
12238
|
+
const isExternalChange = !compareTwoJsValues(value, lastInternalValueRef.current);
|
|
12239
|
+
if (isExternalChange) {
|
|
12240
|
+
selectionController.update(value);
|
|
12790
12241
|
}
|
|
12791
12242
|
}, [value, selectionController]);
|
|
12792
12243
|
return selectionController;
|
|
@@ -17271,636 +16722,1217 @@ const useConstraints = (elementRef, props, { targetSelector } = {}) => {
|
|
|
17271
16722
|
if (minLowerLetterMessage) {
|
|
17272
16723
|
setupCustomEvent(el, "min-lower-letter", minLowerLetterMessage);
|
|
17273
16724
|
}
|
|
17274
|
-
if (minUpperLetterMessage) {
|
|
17275
|
-
setupCustomEvent(el, "min-upper-letter", minUpperLetterMessage);
|
|
16725
|
+
if (minUpperLetterMessage) {
|
|
16726
|
+
setupCustomEvent(el, "min-upper-letter", minUpperLetterMessage);
|
|
16727
|
+
}
|
|
16728
|
+
if (minSpecialCharMessage) {
|
|
16729
|
+
setupCustomEvent(el, "min-special-char", minSpecialCharMessage);
|
|
16730
|
+
}
|
|
16731
|
+
if (availableMessage) {
|
|
16732
|
+
setupCustomEvent(el, "available", availableMessage);
|
|
16733
|
+
}
|
|
16734
|
+
return () => {
|
|
16735
|
+
for (const cleanupCallback of cleanupCallbackSet) {
|
|
16736
|
+
cleanupCallback();
|
|
16737
|
+
}
|
|
16738
|
+
};
|
|
16739
|
+
}, [
|
|
16740
|
+
disabledMessage,
|
|
16741
|
+
requiredMessage,
|
|
16742
|
+
patternMessage,
|
|
16743
|
+
minLengthMessage,
|
|
16744
|
+
maxLengthMessage,
|
|
16745
|
+
typeMessage,
|
|
16746
|
+
minMessage,
|
|
16747
|
+
maxMessage,
|
|
16748
|
+
singleSpaceMessage,
|
|
16749
|
+
sameAsMessage,
|
|
16750
|
+
minDigitMessage,
|
|
16751
|
+
minLowerLetterMessage,
|
|
16752
|
+
minUpperLetterMessage,
|
|
16753
|
+
minSpecialCharMessage,
|
|
16754
|
+
availableMessage,
|
|
16755
|
+
]);
|
|
16756
|
+
|
|
16757
|
+
return remainingProps;
|
|
16758
|
+
};
|
|
16759
|
+
|
|
16760
|
+
const useInitialTextSelection = (ref, textSelection) => {
|
|
16761
|
+
const deps = [];
|
|
16762
|
+
if (Array.isArray(textSelection)) {
|
|
16763
|
+
deps.push(...textSelection);
|
|
16764
|
+
} else {
|
|
16765
|
+
deps.push(textSelection);
|
|
16766
|
+
}
|
|
16767
|
+
useLayoutEffect(() => {
|
|
16768
|
+
const el = ref.current;
|
|
16769
|
+
if (!el || !textSelection) {
|
|
16770
|
+
return;
|
|
16771
|
+
}
|
|
16772
|
+
const range = document.createRange();
|
|
16773
|
+
const selection = window.getSelection();
|
|
16774
|
+
if (Array.isArray(textSelection)) {
|
|
16775
|
+
if (textSelection.length === 2) {
|
|
16776
|
+
const [start, end] = textSelection;
|
|
16777
|
+
if (typeof start === "number" && typeof end === "number") {
|
|
16778
|
+
// Format: [0, 10] - character indices
|
|
16779
|
+
selectByCharacterIndices(el, range, start, end);
|
|
16780
|
+
} else if (typeof start === "string" && typeof end === "string") {
|
|
16781
|
+
// Format: ["Click on the", "button to return"] - text strings
|
|
16782
|
+
selectByTextStrings(el, range, start, end);
|
|
16783
|
+
}
|
|
16784
|
+
}
|
|
16785
|
+
} else if (typeof textSelection === "string") {
|
|
16786
|
+
// Format: "some text" - select the entire string occurrence
|
|
16787
|
+
selectSingleTextString(el, range, textSelection);
|
|
16788
|
+
}
|
|
16789
|
+
selection.removeAllRanges();
|
|
16790
|
+
selection.addRange(range);
|
|
16791
|
+
}, deps);
|
|
16792
|
+
};
|
|
16793
|
+
const selectByCharacterIndices = (element, range, startIndex, endIndex) => {
|
|
16794
|
+
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false);
|
|
16795
|
+
let currentIndex = 0;
|
|
16796
|
+
let startNode = null;
|
|
16797
|
+
let startOffset = 0;
|
|
16798
|
+
let endNode = null;
|
|
16799
|
+
let endOffset = 0;
|
|
16800
|
+
while (walker.nextNode()) {
|
|
16801
|
+
const textContent = walker.currentNode.textContent;
|
|
16802
|
+
const nodeLength = textContent.length;
|
|
16803
|
+
|
|
16804
|
+
// Check if start position is in this text node
|
|
16805
|
+
if (!startNode && currentIndex + nodeLength > startIndex) {
|
|
16806
|
+
startNode = walker.currentNode;
|
|
16807
|
+
startOffset = startIndex - currentIndex;
|
|
16808
|
+
}
|
|
16809
|
+
|
|
16810
|
+
// Check if end position is in this text node
|
|
16811
|
+
if (currentIndex + nodeLength >= endIndex) {
|
|
16812
|
+
endNode = walker.currentNode;
|
|
16813
|
+
endOffset = endIndex - currentIndex;
|
|
16814
|
+
break;
|
|
16815
|
+
}
|
|
16816
|
+
currentIndex += nodeLength;
|
|
16817
|
+
}
|
|
16818
|
+
if (startNode && endNode) {
|
|
16819
|
+
range.setStart(startNode, startOffset);
|
|
16820
|
+
range.setEnd(endNode, endOffset);
|
|
16821
|
+
}
|
|
16822
|
+
};
|
|
16823
|
+
const selectSingleTextString = (element, range, text) => {
|
|
16824
|
+
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false);
|
|
16825
|
+
while (walker.nextNode()) {
|
|
16826
|
+
const textContent = walker.currentNode.textContent;
|
|
16827
|
+
const index = textContent.indexOf(text);
|
|
16828
|
+
if (index !== -1) {
|
|
16829
|
+
range.setStart(walker.currentNode, index);
|
|
16830
|
+
range.setEnd(walker.currentNode, index + text.length);
|
|
16831
|
+
return;
|
|
16832
|
+
}
|
|
16833
|
+
}
|
|
16834
|
+
};
|
|
16835
|
+
const selectByTextStrings = (element, range, startText, endText) => {
|
|
16836
|
+
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false);
|
|
16837
|
+
let startNode = null;
|
|
16838
|
+
let endNode = null;
|
|
16839
|
+
let foundStart = false;
|
|
16840
|
+
while (walker.nextNode()) {
|
|
16841
|
+
const textContent = walker.currentNode.textContent;
|
|
16842
|
+
if (!foundStart && textContent.includes(startText)) {
|
|
16843
|
+
startNode = walker.currentNode;
|
|
16844
|
+
foundStart = true;
|
|
16845
|
+
}
|
|
16846
|
+
if (foundStart && textContent.includes(endText)) {
|
|
16847
|
+
endNode = walker.currentNode;
|
|
16848
|
+
break;
|
|
16849
|
+
}
|
|
16850
|
+
}
|
|
16851
|
+
if (startNode && endNode) {
|
|
16852
|
+
const startOffset = startNode.textContent.indexOf(startText);
|
|
16853
|
+
const endOffset = endNode.textContent.indexOf(endText) + endText.length;
|
|
16854
|
+
range.setStart(startNode, startOffset);
|
|
16855
|
+
range.setEnd(endNode, endOffset);
|
|
16856
|
+
}
|
|
16857
|
+
};
|
|
16858
|
+
|
|
16859
|
+
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
16860
|
+
*[data-navi-space] {
|
|
16861
|
+
/* user-select: none; */
|
|
16862
|
+
}
|
|
16863
|
+
|
|
16864
|
+
.navi_text {
|
|
16865
|
+
position: relative;
|
|
16866
|
+
color: inherit;
|
|
16867
|
+
|
|
16868
|
+
&[data-has-absolute-child] {
|
|
16869
|
+
display: inline-block;
|
|
16870
|
+
}
|
|
16871
|
+
}
|
|
16872
|
+
|
|
16873
|
+
.navi_text_overflow {
|
|
16874
|
+
flex-wrap: wrap;
|
|
16875
|
+
text-overflow: ellipsis;
|
|
16876
|
+
overflow: hidden;
|
|
16877
|
+
}
|
|
16878
|
+
|
|
16879
|
+
.navi_text_overflow_wrapper {
|
|
16880
|
+
display: flex;
|
|
16881
|
+
width: 0;
|
|
16882
|
+
flex-grow: 1;
|
|
16883
|
+
gap: 0.3em;
|
|
16884
|
+
}
|
|
16885
|
+
|
|
16886
|
+
.navi_text_overflow_text {
|
|
16887
|
+
max-width: 100%;
|
|
16888
|
+
text-overflow: ellipsis;
|
|
16889
|
+
overflow: hidden;
|
|
16890
|
+
}
|
|
16891
|
+
|
|
16892
|
+
.navi_custom_space {
|
|
16893
|
+
}
|
|
16894
|
+
|
|
16895
|
+
.navi_text_bold_wrapper {
|
|
16896
|
+
position: relative;
|
|
16897
|
+
display: inline-block;
|
|
16898
|
+
}
|
|
16899
|
+
.navi_text_bold_clone {
|
|
16900
|
+
font-weight: bold;
|
|
16901
|
+
opacity: 0;
|
|
16902
|
+
}
|
|
16903
|
+
.navi_text_bold_foreground {
|
|
16904
|
+
position: absolute;
|
|
16905
|
+
inset: 0;
|
|
16906
|
+
}
|
|
16907
|
+
|
|
16908
|
+
.navi_text_bold_background {
|
|
16909
|
+
position: absolute;
|
|
16910
|
+
top: 0;
|
|
16911
|
+
left: 0;
|
|
16912
|
+
color: currentColor;
|
|
16913
|
+
font-weight: normal;
|
|
16914
|
+
background: currentColor;
|
|
16915
|
+
background-clip: text;
|
|
16916
|
+
-webkit-background-clip: text;
|
|
16917
|
+
transform-origin: center;
|
|
16918
|
+
-webkit-text-fill-color: transparent;
|
|
16919
|
+
opacity: 0;
|
|
16920
|
+
}
|
|
16921
|
+
|
|
16922
|
+
.navi_text[data-bold] {
|
|
16923
|
+
.navi_text_bold_background {
|
|
16924
|
+
opacity: 1;
|
|
16925
|
+
}
|
|
16926
|
+
}
|
|
16927
|
+
|
|
16928
|
+
.navi_text[data-bold-transition] {
|
|
16929
|
+
.navi_text_bold_foreground {
|
|
16930
|
+
transition-property: font-weight;
|
|
16931
|
+
transition-duration: 0.3s;
|
|
16932
|
+
transition-timing-function: ease;
|
|
16933
|
+
}
|
|
16934
|
+
|
|
16935
|
+
.navi_text_bold_background {
|
|
16936
|
+
transition-property: opacity;
|
|
16937
|
+
transition-duration: 0.3s;
|
|
16938
|
+
transition-timing-function: ease;
|
|
16939
|
+
}
|
|
16940
|
+
}
|
|
16941
|
+
`;
|
|
16942
|
+
const REGULAR_SPACE = jsx("span", {
|
|
16943
|
+
"data-navi-space": "",
|
|
16944
|
+
children: " "
|
|
16945
|
+
});
|
|
16946
|
+
const CustomWidthSpace = ({
|
|
16947
|
+
value
|
|
16948
|
+
}) => {
|
|
16949
|
+
return jsx("span", {
|
|
16950
|
+
className: "navi_custom_space",
|
|
16951
|
+
style: `padding-left: ${value}`,
|
|
16952
|
+
children: "\u200B"
|
|
16953
|
+
});
|
|
16954
|
+
};
|
|
16955
|
+
const applySpacingOnTextChildren = (children, spacing) => {
|
|
16956
|
+
if (spacing === "pre" || spacing === "0" || spacing === 0) {
|
|
16957
|
+
return children;
|
|
16958
|
+
}
|
|
16959
|
+
if (!children) {
|
|
16960
|
+
return children;
|
|
16961
|
+
}
|
|
16962
|
+
const childArray = toChildArray(children);
|
|
16963
|
+
const childCount = childArray.length;
|
|
16964
|
+
if (childCount <= 1) {
|
|
16965
|
+
return children;
|
|
16966
|
+
}
|
|
16967
|
+
let separator;
|
|
16968
|
+
if (spacing === undefined) {
|
|
16969
|
+
spacing = REGULAR_SPACE;
|
|
16970
|
+
} else if (typeof spacing === "string") {
|
|
16971
|
+
if (isSizeSpacingScaleKey(spacing)) {
|
|
16972
|
+
separator = jsx(CustomWidthSpace, {
|
|
16973
|
+
value: resolveSpacingSize(spacing)
|
|
16974
|
+
});
|
|
16975
|
+
} else if (hasCSSSizeUnit(spacing)) {
|
|
16976
|
+
separator = jsx(CustomWidthSpace, {
|
|
16977
|
+
value: resolveSpacingSize(spacing)
|
|
16978
|
+
});
|
|
16979
|
+
} else {
|
|
16980
|
+
separator = spacing;
|
|
16981
|
+
}
|
|
16982
|
+
} else if (typeof spacing === "number") {
|
|
16983
|
+
separator = jsx(CustomWidthSpace, {
|
|
16984
|
+
value: spacing
|
|
16985
|
+
});
|
|
16986
|
+
} else {
|
|
16987
|
+
separator = spacing;
|
|
16988
|
+
}
|
|
16989
|
+
const childrenWithGap = [];
|
|
16990
|
+
let i = 0;
|
|
16991
|
+
while (true) {
|
|
16992
|
+
const child = childArray[i];
|
|
16993
|
+
childrenWithGap.push(child);
|
|
16994
|
+
i++;
|
|
16995
|
+
if (i === childCount) {
|
|
16996
|
+
break;
|
|
17276
16997
|
}
|
|
17277
|
-
|
|
17278
|
-
|
|
16998
|
+
const currentChild = childArray[i - 1];
|
|
16999
|
+
const nextChild = childArray[i];
|
|
17000
|
+
if (endsWithWhitespace(currentChild)) {
|
|
17001
|
+
continue;
|
|
17279
17002
|
}
|
|
17280
|
-
if (
|
|
17281
|
-
|
|
17003
|
+
if (startsWithWhitespace(nextChild)) {
|
|
17004
|
+
continue;
|
|
17282
17005
|
}
|
|
17283
|
-
|
|
17284
|
-
|
|
17285
|
-
|
|
17286
|
-
}
|
|
17287
|
-
};
|
|
17288
|
-
}, [
|
|
17289
|
-
disabledMessage,
|
|
17290
|
-
requiredMessage,
|
|
17291
|
-
patternMessage,
|
|
17292
|
-
minLengthMessage,
|
|
17293
|
-
maxLengthMessage,
|
|
17294
|
-
typeMessage,
|
|
17295
|
-
minMessage,
|
|
17296
|
-
maxMessage,
|
|
17297
|
-
singleSpaceMessage,
|
|
17298
|
-
sameAsMessage,
|
|
17299
|
-
minDigitMessage,
|
|
17300
|
-
minLowerLetterMessage,
|
|
17301
|
-
minUpperLetterMessage,
|
|
17302
|
-
minSpecialCharMessage,
|
|
17303
|
-
availableMessage,
|
|
17304
|
-
]);
|
|
17305
|
-
|
|
17306
|
-
return remainingProps;
|
|
17006
|
+
childrenWithGap.push(separator);
|
|
17007
|
+
}
|
|
17008
|
+
return childrenWithGap;
|
|
17307
17009
|
};
|
|
17308
|
-
|
|
17309
|
-
|
|
17310
|
-
|
|
17311
|
-
if (Array.isArray(textSelection)) {
|
|
17312
|
-
deps.push(...textSelection);
|
|
17313
|
-
} else {
|
|
17314
|
-
deps.push(textSelection);
|
|
17010
|
+
const endsWithWhitespace = jsxChild => {
|
|
17011
|
+
if (typeof jsxChild === "string") {
|
|
17012
|
+
return /\s$/.test(jsxChild);
|
|
17315
17013
|
}
|
|
17316
|
-
|
|
17317
|
-
|
|
17318
|
-
|
|
17319
|
-
|
|
17320
|
-
|
|
17321
|
-
|
|
17322
|
-
|
|
17323
|
-
|
|
17324
|
-
|
|
17325
|
-
|
|
17326
|
-
|
|
17327
|
-
|
|
17328
|
-
|
|
17329
|
-
|
|
17330
|
-
|
|
17331
|
-
|
|
17332
|
-
|
|
17333
|
-
|
|
17334
|
-
|
|
17335
|
-
|
|
17336
|
-
|
|
17337
|
-
|
|
17338
|
-
|
|
17339
|
-
|
|
17340
|
-
|
|
17014
|
+
return false;
|
|
17015
|
+
};
|
|
17016
|
+
const startsWithWhitespace = jsxChild => {
|
|
17017
|
+
if (typeof jsxChild === "string") {
|
|
17018
|
+
return /^\s/.test(jsxChild);
|
|
17019
|
+
}
|
|
17020
|
+
return false;
|
|
17021
|
+
};
|
|
17022
|
+
const OverflowPinnedElementContext = createContext(null);
|
|
17023
|
+
const Text = props => {
|
|
17024
|
+
const {
|
|
17025
|
+
overflowEllipsis,
|
|
17026
|
+
...rest
|
|
17027
|
+
} = props;
|
|
17028
|
+
if (overflowEllipsis) {
|
|
17029
|
+
return jsx(TextOverflow, {
|
|
17030
|
+
...rest
|
|
17031
|
+
});
|
|
17032
|
+
}
|
|
17033
|
+
if (props.overflowPinned) {
|
|
17034
|
+
return jsx(TextOverflowPinned, {
|
|
17035
|
+
...props
|
|
17036
|
+
});
|
|
17037
|
+
}
|
|
17038
|
+
if (props.selectRange) {
|
|
17039
|
+
return jsx(TextWithSelectRange, {
|
|
17040
|
+
...props
|
|
17041
|
+
});
|
|
17042
|
+
}
|
|
17043
|
+
return jsx(TextBasic, {
|
|
17044
|
+
...props
|
|
17045
|
+
});
|
|
17046
|
+
};
|
|
17047
|
+
const TextOverflow = ({
|
|
17048
|
+
noWrap,
|
|
17049
|
+
children,
|
|
17050
|
+
...rest
|
|
17051
|
+
}) => {
|
|
17052
|
+
const [OverflowPinnedElement, setOverflowPinnedElement] = useState(null);
|
|
17053
|
+
return jsx(Text, {
|
|
17054
|
+
column: true,
|
|
17055
|
+
as: "div",
|
|
17056
|
+
nowWrap: noWrap,
|
|
17057
|
+
pre: !noWrap
|
|
17058
|
+
// For paragraph we prefer to keep lines and only hide unbreakable long sections
|
|
17059
|
+
,
|
|
17060
|
+
preLine: rest.as === "p",
|
|
17061
|
+
...rest,
|
|
17062
|
+
className: "navi_text_overflow",
|
|
17063
|
+
expandX: true,
|
|
17064
|
+
spacing: "pre",
|
|
17065
|
+
children: jsxs("span", {
|
|
17066
|
+
className: "navi_text_overflow_wrapper",
|
|
17067
|
+
children: [jsx(OverflowPinnedElementContext.Provider, {
|
|
17068
|
+
value: setOverflowPinnedElement,
|
|
17069
|
+
children: jsx(Text, {
|
|
17070
|
+
className: "navi_text_overflow_text",
|
|
17071
|
+
children: children
|
|
17072
|
+
})
|
|
17073
|
+
}), OverflowPinnedElement]
|
|
17074
|
+
})
|
|
17075
|
+
});
|
|
17076
|
+
};
|
|
17077
|
+
const TextOverflowPinned = ({
|
|
17078
|
+
overflowPinned,
|
|
17079
|
+
...props
|
|
17080
|
+
}) => {
|
|
17081
|
+
const setOverflowPinnedElement = useContext(OverflowPinnedElementContext);
|
|
17082
|
+
const text = jsx(Text, {
|
|
17083
|
+
...props
|
|
17084
|
+
});
|
|
17085
|
+
if (!setOverflowPinnedElement) {
|
|
17086
|
+
console.warn("<Text overflowPinned> declared outside a <Text overflowEllipsis>");
|
|
17087
|
+
return text;
|
|
17088
|
+
}
|
|
17089
|
+
if (overflowPinned) {
|
|
17090
|
+
setOverflowPinnedElement(text);
|
|
17091
|
+
return null;
|
|
17092
|
+
}
|
|
17093
|
+
setOverflowPinnedElement(null);
|
|
17094
|
+
return text;
|
|
17095
|
+
};
|
|
17096
|
+
const TextWithSelectRange = ({
|
|
17097
|
+
selectRange,
|
|
17098
|
+
...props
|
|
17099
|
+
}) => {
|
|
17100
|
+
const defaultRef = useRef();
|
|
17101
|
+
const ref = props.ref || defaultRef;
|
|
17102
|
+
useInitialTextSelection(ref, selectRange);
|
|
17103
|
+
return jsx(Text, {
|
|
17104
|
+
ref: ref,
|
|
17105
|
+
...props
|
|
17106
|
+
});
|
|
17107
|
+
};
|
|
17108
|
+
const TextBasic = ({
|
|
17109
|
+
spacing = " ",
|
|
17110
|
+
boldTransition,
|
|
17111
|
+
boldStable,
|
|
17112
|
+
preventBoldLayoutShift = boldTransition,
|
|
17113
|
+
children,
|
|
17114
|
+
...rest
|
|
17115
|
+
}) => {
|
|
17116
|
+
const boxProps = {
|
|
17117
|
+
"as": "span",
|
|
17118
|
+
"data-bold-transition": boldTransition ? "" : undefined,
|
|
17119
|
+
...rest,
|
|
17120
|
+
"baseClassName": withPropsClassName("navi_text", rest.baseClassName)
|
|
17121
|
+
};
|
|
17122
|
+
const shouldPreserveSpacing = rest.as === "pre" || rest.box || rest.column || rest.row;
|
|
17123
|
+
if (shouldPreserveSpacing) {
|
|
17124
|
+
boxProps.spacing = spacing;
|
|
17125
|
+
} else {
|
|
17126
|
+
children = applySpacingOnTextChildren(children, spacing);
|
|
17127
|
+
}
|
|
17128
|
+
if (boldStable) {
|
|
17129
|
+
const {
|
|
17130
|
+
bold
|
|
17131
|
+
} = boxProps;
|
|
17132
|
+
return jsxs(Box, {
|
|
17133
|
+
...boxProps,
|
|
17134
|
+
bold: undefined,
|
|
17135
|
+
"data-bold": bold ? "" : undefined,
|
|
17136
|
+
"data-has-absolute-child": "",
|
|
17137
|
+
children: [jsx("span", {
|
|
17138
|
+
className: "navi_text_bold_background",
|
|
17139
|
+
"aria-hidden": "true",
|
|
17140
|
+
children: children
|
|
17141
|
+
}), children]
|
|
17142
|
+
});
|
|
17143
|
+
}
|
|
17144
|
+
if (preventBoldLayoutShift) {
|
|
17145
|
+
const alignX = rest.alignX || rest.align || "start";
|
|
17146
|
+
|
|
17147
|
+
// La technique consiste a avoid un double gras qui force une taille
|
|
17148
|
+
// et la version light par dessus en position absolute
|
|
17149
|
+
// on la centre aussi pour donner l'impression que le gras s'applique depuis le centre
|
|
17150
|
+
// ne fonctionne que sur une seul ligne de texte (donc lorsque noWrap est actif)
|
|
17151
|
+
// on pourrait auto-active cela sur une prop genre boldCanChange
|
|
17152
|
+
return jsx(Box, {
|
|
17153
|
+
...boxProps,
|
|
17154
|
+
children: jsxs("span", {
|
|
17155
|
+
className: "navi_text_bold_wrapper",
|
|
17156
|
+
children: [jsx("span", {
|
|
17157
|
+
className: "navi_text_bold_clone",
|
|
17158
|
+
"aria-hidden": "true",
|
|
17159
|
+
children: children
|
|
17160
|
+
}), jsx("span", {
|
|
17161
|
+
className: "navi_text_bold_foreground",
|
|
17162
|
+
"data-align": alignX,
|
|
17163
|
+
children: children
|
|
17164
|
+
})]
|
|
17165
|
+
})
|
|
17166
|
+
});
|
|
17167
|
+
}
|
|
17168
|
+
return jsx(Box, {
|
|
17169
|
+
...boxProps,
|
|
17170
|
+
children: children
|
|
17171
|
+
});
|
|
17341
17172
|
};
|
|
17342
|
-
const selectByCharacterIndices = (element, range, startIndex, endIndex) => {
|
|
17343
|
-
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false);
|
|
17344
|
-
let currentIndex = 0;
|
|
17345
|
-
let startNode = null;
|
|
17346
|
-
let startOffset = 0;
|
|
17347
|
-
let endNode = null;
|
|
17348
|
-
let endOffset = 0;
|
|
17349
|
-
while (walker.nextNode()) {
|
|
17350
|
-
const textContent = walker.currentNode.textContent;
|
|
17351
|
-
const nodeLength = textContent.length;
|
|
17352
17173
|
|
|
17353
|
-
|
|
17354
|
-
|
|
17355
|
-
|
|
17356
|
-
|
|
17357
|
-
|
|
17174
|
+
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
17175
|
+
.navi_icon {
|
|
17176
|
+
display: inline-block;
|
|
17177
|
+
box-sizing: border-box;
|
|
17178
|
+
max-width: 100%;
|
|
17179
|
+
max-height: 100%;
|
|
17358
17180
|
|
|
17359
|
-
|
|
17360
|
-
|
|
17361
|
-
|
|
17362
|
-
|
|
17363
|
-
|
|
17181
|
+
&[data-flow-inline] {
|
|
17182
|
+
width: 1em;
|
|
17183
|
+
height: 1em;
|
|
17184
|
+
}
|
|
17185
|
+
&[data-icon-char] {
|
|
17186
|
+
flex-grow: 0 !important;
|
|
17187
|
+
line-height: normal;
|
|
17364
17188
|
}
|
|
17365
|
-
currentIndex += nodeLength;
|
|
17366
17189
|
}
|
|
17367
|
-
|
|
17368
|
-
|
|
17369
|
-
|
|
17190
|
+
|
|
17191
|
+
.navi_icon[data-interactive] {
|
|
17192
|
+
cursor: pointer;
|
|
17370
17193
|
}
|
|
17371
|
-
|
|
17372
|
-
|
|
17373
|
-
|
|
17374
|
-
|
|
17375
|
-
|
|
17376
|
-
const index = textContent.indexOf(text);
|
|
17377
|
-
if (index !== -1) {
|
|
17378
|
-
range.setStart(walker.currentNode, index);
|
|
17379
|
-
range.setEnd(walker.currentNode, index + text.length);
|
|
17380
|
-
return;
|
|
17381
|
-
}
|
|
17194
|
+
|
|
17195
|
+
.navi_icon_char_slot {
|
|
17196
|
+
opacity: 0;
|
|
17197
|
+
cursor: default;
|
|
17198
|
+
user-select: none;
|
|
17382
17199
|
}
|
|
17383
|
-
|
|
17384
|
-
|
|
17385
|
-
|
|
17386
|
-
let startNode = null;
|
|
17387
|
-
let endNode = null;
|
|
17388
|
-
let foundStart = false;
|
|
17389
|
-
while (walker.nextNode()) {
|
|
17390
|
-
const textContent = walker.currentNode.textContent;
|
|
17391
|
-
if (!foundStart && textContent.includes(startText)) {
|
|
17392
|
-
startNode = walker.currentNode;
|
|
17393
|
-
foundStart = true;
|
|
17394
|
-
}
|
|
17395
|
-
if (foundStart && textContent.includes(endText)) {
|
|
17396
|
-
endNode = walker.currentNode;
|
|
17397
|
-
break;
|
|
17398
|
-
}
|
|
17200
|
+
.navi_icon_foreground {
|
|
17201
|
+
position: absolute;
|
|
17202
|
+
inset: 0;
|
|
17399
17203
|
}
|
|
17400
|
-
|
|
17401
|
-
|
|
17402
|
-
|
|
17403
|
-
|
|
17404
|
-
|
|
17204
|
+
.navi_icon_foreground > .navi_text {
|
|
17205
|
+
display: flex;
|
|
17206
|
+
aspect-ratio: 1 / 1;
|
|
17207
|
+
min-width: 0;
|
|
17208
|
+
height: 100%;
|
|
17209
|
+
max-height: 1em;
|
|
17210
|
+
align-items: center;
|
|
17211
|
+
justify-content: center;
|
|
17405
17212
|
}
|
|
17406
|
-
};
|
|
17407
17213
|
|
|
17408
|
-
|
|
17409
|
-
|
|
17410
|
-
|
|
17214
|
+
.navi_icon > svg,
|
|
17215
|
+
.navi_icon > img {
|
|
17216
|
+
width: 100%;
|
|
17217
|
+
height: 100%;
|
|
17218
|
+
backface-visibility: hidden;
|
|
17219
|
+
}
|
|
17220
|
+
.navi_icon[data-has-width] > svg,
|
|
17221
|
+
.navi_icon[data-has-width] > img {
|
|
17222
|
+
width: 100%;
|
|
17223
|
+
height: auto;
|
|
17224
|
+
}
|
|
17225
|
+
.navi_icon[data-has-height] > svg,
|
|
17226
|
+
.navi_icon[data-has-height] > img {
|
|
17227
|
+
width: auto;
|
|
17228
|
+
height: 100%;
|
|
17229
|
+
}
|
|
17230
|
+
.navi_icon[data-has-width][data-has-height] > svg,
|
|
17231
|
+
.navi_icon[data-has-width][data-has-height] > img {
|
|
17232
|
+
width: 100%;
|
|
17233
|
+
height: 100%;
|
|
17411
17234
|
}
|
|
17412
17235
|
|
|
17413
|
-
.
|
|
17414
|
-
|
|
17415
|
-
|
|
17416
|
-
|
|
17417
|
-
|
|
17418
|
-
|
|
17236
|
+
.navi_icon[data-icon-char] svg,
|
|
17237
|
+
.navi_icon[data-icon-char] img {
|
|
17238
|
+
width: 100%;
|
|
17239
|
+
height: 100%;
|
|
17240
|
+
}
|
|
17241
|
+
.navi_icon[data-icon-char] svg {
|
|
17242
|
+
overflow: visible;
|
|
17243
|
+
}
|
|
17244
|
+
`;
|
|
17245
|
+
const Icon = ({
|
|
17246
|
+
href,
|
|
17247
|
+
children,
|
|
17248
|
+
charWidth = 1,
|
|
17249
|
+
// 0 (zéro) is the real char width
|
|
17250
|
+
// but 2 zéros gives too big icons
|
|
17251
|
+
// while 1 "W" gives a nice result
|
|
17252
|
+
baseChar = "W",
|
|
17253
|
+
decorative,
|
|
17254
|
+
onClick,
|
|
17255
|
+
...props
|
|
17256
|
+
}) => {
|
|
17257
|
+
const innerChildren = href ? jsx("svg", {
|
|
17258
|
+
width: "100%",
|
|
17259
|
+
height: "100%",
|
|
17260
|
+
children: jsx("use", {
|
|
17261
|
+
href: href
|
|
17262
|
+
})
|
|
17263
|
+
}) : children;
|
|
17264
|
+
let {
|
|
17265
|
+
box,
|
|
17266
|
+
width,
|
|
17267
|
+
height
|
|
17268
|
+
} = props;
|
|
17269
|
+
if (width === "auto") width = undefined;
|
|
17270
|
+
if (height === "auto") height = undefined;
|
|
17271
|
+
const hasExplicitWidth = width !== undefined;
|
|
17272
|
+
const hasExplicitHeight = height !== undefined;
|
|
17273
|
+
if (!hasExplicitWidth && !hasExplicitHeight) {
|
|
17274
|
+
if (decorative === undefined && !onClick) {
|
|
17275
|
+
decorative = true;
|
|
17419
17276
|
}
|
|
17277
|
+
} else {
|
|
17278
|
+
box = true;
|
|
17420
17279
|
}
|
|
17421
|
-
|
|
17422
|
-
|
|
17423
|
-
|
|
17424
|
-
|
|
17425
|
-
|
|
17280
|
+
const ariaProps = decorative ? {
|
|
17281
|
+
"aria-hidden": "true"
|
|
17282
|
+
} : {};
|
|
17283
|
+
if (typeof children === "string") {
|
|
17284
|
+
return jsx(Text, {
|
|
17285
|
+
...props,
|
|
17286
|
+
...ariaProps,
|
|
17287
|
+
"data-icon-text": "",
|
|
17288
|
+
children: children
|
|
17289
|
+
});
|
|
17290
|
+
}
|
|
17291
|
+
if (box) {
|
|
17292
|
+
return jsx(Box, {
|
|
17293
|
+
square: true,
|
|
17294
|
+
...props,
|
|
17295
|
+
...ariaProps,
|
|
17296
|
+
box: box,
|
|
17297
|
+
baseClassName: "navi_icon",
|
|
17298
|
+
"data-has-width": hasExplicitWidth ? "" : undefined,
|
|
17299
|
+
"data-has-height": hasExplicitHeight ? "" : undefined,
|
|
17300
|
+
"data-interactive": onClick ? "" : undefined,
|
|
17301
|
+
onClick: onClick,
|
|
17302
|
+
children: innerChildren
|
|
17303
|
+
});
|
|
17426
17304
|
}
|
|
17305
|
+
const invisibleText = baseChar.repeat(charWidth);
|
|
17306
|
+
return jsxs(Text, {
|
|
17307
|
+
...props,
|
|
17308
|
+
...ariaProps,
|
|
17309
|
+
className: withPropsClassName("navi_icon", props.className),
|
|
17310
|
+
spacing: "pre",
|
|
17311
|
+
"data-icon-char": "",
|
|
17312
|
+
"data-has-width": hasExplicitWidth ? "" : undefined,
|
|
17313
|
+
"data-has-height": hasExplicitHeight ? "" : undefined,
|
|
17314
|
+
"data-interactive": onClick ? "" : undefined,
|
|
17315
|
+
onClick: onClick,
|
|
17316
|
+
children: [jsx("span", {
|
|
17317
|
+
className: "navi_icon_char_slot",
|
|
17318
|
+
"aria-hidden": "true",
|
|
17319
|
+
children: invisibleText
|
|
17320
|
+
}), jsx(Text, {
|
|
17321
|
+
className: "navi_icon_foreground",
|
|
17322
|
+
spacing: "pre",
|
|
17323
|
+
children: innerChildren
|
|
17324
|
+
})]
|
|
17325
|
+
});
|
|
17326
|
+
};
|
|
17327
|
+
|
|
17328
|
+
const EmailSvg = () => {
|
|
17329
|
+
return jsxs("svg", {
|
|
17330
|
+
viewBox: "0 0 24 24",
|
|
17331
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
17332
|
+
children: [jsx("path", {
|
|
17333
|
+
d: "M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",
|
|
17334
|
+
fill: "none",
|
|
17335
|
+
stroke: "currentColor",
|
|
17336
|
+
"stroke-width": "2"
|
|
17337
|
+
}), jsx("path", {
|
|
17338
|
+
d: "m2 6 8 5 2 1.5 2-1.5 8-5",
|
|
17339
|
+
fill: "none",
|
|
17340
|
+
stroke: "currentColor",
|
|
17341
|
+
"stroke-width": "2",
|
|
17342
|
+
"stroke-linecap": "round",
|
|
17343
|
+
"stroke-linejoin": "round"
|
|
17344
|
+
})]
|
|
17345
|
+
});
|
|
17346
|
+
};
|
|
17347
|
+
|
|
17348
|
+
const LinkBlankTargetSvg = () => {
|
|
17349
|
+
return jsx("svg", {
|
|
17350
|
+
viewBox: "0 0 24 24",
|
|
17351
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
17352
|
+
children: jsx("path", {
|
|
17353
|
+
d: "M10.0002 5H8.2002C7.08009 5 6.51962 5 6.0918 5.21799C5.71547 5.40973 5.40973 5.71547 5.21799 6.0918C5 6.51962 5 7.08009 5 8.2002V15.8002C5 16.9203 5 17.4801 5.21799 17.9079C5.40973 18.2842 5.71547 18.5905 6.0918 18.7822C6.5192 19 7.07899 19 8.19691 19H15.8031C16.921 19 17.48 19 17.9074 18.7822C18.2837 18.5905 18.5905 18.2839 18.7822 17.9076C19 17.4802 19 16.921 19 15.8031V14M20 9V4M20 4H15M20 4L13 11",
|
|
17354
|
+
stroke: "currentColor",
|
|
17355
|
+
fill: "none",
|
|
17356
|
+
"stroke-width": "2",
|
|
17357
|
+
"stroke-linecap": "round",
|
|
17358
|
+
"stroke-linejoin": "round"
|
|
17359
|
+
})
|
|
17360
|
+
});
|
|
17361
|
+
};
|
|
17362
|
+
const LinkAnchorSvg = () => {
|
|
17363
|
+
return jsx("svg", {
|
|
17364
|
+
viewBox: "0 0 24 24",
|
|
17365
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
17366
|
+
children: jsxs("g", {
|
|
17367
|
+
children: [jsx("path", {
|
|
17368
|
+
d: "M13.2218 3.32234C15.3697 1.17445 18.8521 1.17445 21 3.32234C23.1479 5.47022 23.1479 8.95263 21 11.1005L17.4645 14.636C15.3166 16.7839 11.8342 16.7839 9.6863 14.636C9.48752 14.4373 9.30713 14.2271 9.14514 14.0075C8.90318 13.6796 8.97098 13.2301 9.25914 12.9419C9.73221 12.4688 10.5662 12.6561 11.0245 13.1435C11.0494 13.1699 11.0747 13.196 11.1005 13.2218C12.4673 14.5887 14.6834 14.5887 16.0503 13.2218L19.5858 9.6863C20.9526 8.31947 20.9526 6.10339 19.5858 4.73655C18.219 3.36972 16.0029 3.36972 14.636 4.73655L13.5754 5.79721C13.1849 6.18774 12.5517 6.18774 12.1612 5.79721C11.7706 5.40669 11.7706 4.77352 12.1612 4.383L13.2218 3.32234Z",
|
|
17369
|
+
fill: "currentColor"
|
|
17370
|
+
}), jsx("path", {
|
|
17371
|
+
d: "M6.85787 9.6863C8.90184 7.64233 12.2261 7.60094 14.3494 9.42268C14.7319 9.75083 14.7008 10.3287 14.3444 10.685C13.9253 11.1041 13.2317 11.0404 12.7416 10.707C11.398 9.79292 9.48593 9.88667 8.27209 11.1005L4.73655 14.636C3.36972 16.0029 3.36972 18.219 4.73655 19.5858C6.10339 20.9526 8.31947 20.9526 9.6863 19.5858L10.747 18.5251C11.1375 18.1346 11.7706 18.1346 12.1612 18.5251C12.5517 18.9157 12.5517 19.5488 12.1612 19.9394L11.1005 21C8.95263 23.1479 5.47022 23.1479 3.32234 21C1.17445 18.8521 1.17445 15.3697 3.32234 13.2218L6.85787 9.6863Z",
|
|
17372
|
+
fill: "currentColor"
|
|
17373
|
+
})]
|
|
17374
|
+
})
|
|
17375
|
+
});
|
|
17376
|
+
};
|
|
17427
17377
|
|
|
17428
|
-
|
|
17429
|
-
|
|
17430
|
-
|
|
17431
|
-
|
|
17432
|
-
|
|
17433
|
-
|
|
17378
|
+
const PhoneSvg = () => {
|
|
17379
|
+
return jsx("svg", {
|
|
17380
|
+
viewBox: "0 0 24 24",
|
|
17381
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
17382
|
+
children: jsx("path", {
|
|
17383
|
+
d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z",
|
|
17384
|
+
fill: "currentColor"
|
|
17385
|
+
})
|
|
17386
|
+
});
|
|
17387
|
+
};
|
|
17434
17388
|
|
|
17435
|
-
|
|
17436
|
-
|
|
17437
|
-
|
|
17438
|
-
overflow: hidden;
|
|
17439
|
-
}
|
|
17389
|
+
const useDebounceTrue = (value, delay = 300) => {
|
|
17390
|
+
const [debouncedTrue, setDebouncedTrue] = useState(false);
|
|
17391
|
+
const timerRef = useRef(null);
|
|
17440
17392
|
|
|
17441
|
-
|
|
17442
|
-
|
|
17393
|
+
useLayoutEffect(() => {
|
|
17394
|
+
// If value is true or becomes true, start a timer
|
|
17395
|
+
if (value) {
|
|
17396
|
+
timerRef.current = setTimeout(() => {
|
|
17397
|
+
setDebouncedTrue(true);
|
|
17398
|
+
}, delay);
|
|
17399
|
+
} else {
|
|
17400
|
+
// If value becomes false, clear any pending timer and immediately set to false
|
|
17401
|
+
if (timerRef.current) {
|
|
17402
|
+
clearTimeout(timerRef.current);
|
|
17403
|
+
timerRef.current = null;
|
|
17404
|
+
}
|
|
17405
|
+
setDebouncedTrue(false);
|
|
17406
|
+
}
|
|
17443
17407
|
|
|
17444
|
-
|
|
17445
|
-
|
|
17446
|
-
|
|
17447
|
-
|
|
17448
|
-
|
|
17449
|
-
|
|
17450
|
-
|
|
17451
|
-
}
|
|
17452
|
-
.navi_text_bold_foreground {
|
|
17453
|
-
position: absolute;
|
|
17454
|
-
inset: 0;
|
|
17455
|
-
}
|
|
17408
|
+
// Cleanup function
|
|
17409
|
+
return () => {
|
|
17410
|
+
if (timerRef.current) {
|
|
17411
|
+
clearTimeout(timerRef.current);
|
|
17412
|
+
}
|
|
17413
|
+
};
|
|
17414
|
+
}, [value, delay]);
|
|
17456
17415
|
|
|
17457
|
-
|
|
17458
|
-
|
|
17459
|
-
top: 0;
|
|
17460
|
-
left: 0;
|
|
17461
|
-
color: currentColor;
|
|
17462
|
-
font-weight: normal;
|
|
17463
|
-
background: currentColor;
|
|
17464
|
-
background-clip: text;
|
|
17465
|
-
-webkit-background-clip: text;
|
|
17466
|
-
transform-origin: center;
|
|
17467
|
-
-webkit-text-fill-color: transparent;
|
|
17468
|
-
opacity: 0;
|
|
17469
|
-
}
|
|
17416
|
+
return debouncedTrue;
|
|
17417
|
+
};
|
|
17470
17418
|
|
|
17471
|
-
|
|
17472
|
-
|
|
17473
|
-
|
|
17474
|
-
}
|
|
17475
|
-
}
|
|
17419
|
+
const useNetworkSpeed = () => {
|
|
17420
|
+
return networkSpeedSignal.value;
|
|
17421
|
+
};
|
|
17476
17422
|
|
|
17477
|
-
|
|
17478
|
-
|
|
17479
|
-
|
|
17480
|
-
|
|
17481
|
-
transition-timing-function: ease;
|
|
17482
|
-
}
|
|
17423
|
+
const connection =
|
|
17424
|
+
window.navigator.connection ||
|
|
17425
|
+
window.navigator.mozConnection ||
|
|
17426
|
+
window.navigator.webkitConnection;
|
|
17483
17427
|
|
|
17484
|
-
|
|
17485
|
-
|
|
17486
|
-
|
|
17487
|
-
|
|
17488
|
-
}
|
|
17489
|
-
}
|
|
17490
|
-
`;
|
|
17491
|
-
const REGULAR_SPACE = jsx("span", {
|
|
17492
|
-
"data-navi-space": "",
|
|
17493
|
-
children: " "
|
|
17494
|
-
});
|
|
17495
|
-
const CustomWidthSpace = ({
|
|
17496
|
-
value
|
|
17497
|
-
}) => {
|
|
17498
|
-
return jsx("span", {
|
|
17499
|
-
className: "navi_custom_space",
|
|
17500
|
-
style: `padding-left: ${value}`,
|
|
17501
|
-
children: "\u200B"
|
|
17502
|
-
});
|
|
17503
|
-
};
|
|
17504
|
-
const applySpacingOnTextChildren = (children, spacing) => {
|
|
17505
|
-
if (spacing === "pre" || spacing === "0" || spacing === 0) {
|
|
17506
|
-
return children;
|
|
17507
|
-
}
|
|
17508
|
-
if (!children) {
|
|
17509
|
-
return children;
|
|
17510
|
-
}
|
|
17511
|
-
const childArray = toChildArray(children);
|
|
17512
|
-
const childCount = childArray.length;
|
|
17513
|
-
if (childCount <= 1) {
|
|
17514
|
-
return children;
|
|
17515
|
-
}
|
|
17516
|
-
let separator;
|
|
17517
|
-
if (spacing === undefined) {
|
|
17518
|
-
spacing = REGULAR_SPACE;
|
|
17519
|
-
} else if (typeof spacing === "string") {
|
|
17520
|
-
if (isSizeSpacingScaleKey(spacing)) {
|
|
17521
|
-
separator = jsx(CustomWidthSpace, {
|
|
17522
|
-
value: resolveSpacingSize(spacing)
|
|
17523
|
-
});
|
|
17524
|
-
} else if (hasCSSSizeUnit(spacing)) {
|
|
17525
|
-
separator = jsx(CustomWidthSpace, {
|
|
17526
|
-
value: resolveSpacingSize(spacing)
|
|
17527
|
-
});
|
|
17528
|
-
} else {
|
|
17529
|
-
separator = spacing;
|
|
17530
|
-
}
|
|
17531
|
-
} else if (typeof spacing === "number") {
|
|
17532
|
-
separator = jsx(CustomWidthSpace, {
|
|
17533
|
-
value: spacing
|
|
17534
|
-
});
|
|
17535
|
-
} else {
|
|
17536
|
-
separator = spacing;
|
|
17428
|
+
const getNetworkSpeed = () => {
|
|
17429
|
+
// ✅ Network Information API (support moderne)
|
|
17430
|
+
if (!connection) {
|
|
17431
|
+
return "3g";
|
|
17537
17432
|
}
|
|
17538
|
-
|
|
17539
|
-
|
|
17540
|
-
|
|
17541
|
-
|
|
17542
|
-
childrenWithGap.push(child);
|
|
17543
|
-
i++;
|
|
17544
|
-
if (i === childCount) {
|
|
17545
|
-
break;
|
|
17546
|
-
}
|
|
17547
|
-
const currentChild = childArray[i - 1];
|
|
17548
|
-
const nextChild = childArray[i];
|
|
17549
|
-
if (endsWithWhitespace(currentChild)) {
|
|
17550
|
-
continue;
|
|
17433
|
+
if (connection) {
|
|
17434
|
+
const effectiveType = connection.effectiveType;
|
|
17435
|
+
if (effectiveType) {
|
|
17436
|
+
return effectiveType; // "slow-2g", "2g", "3g", "4g", "5g"
|
|
17551
17437
|
}
|
|
17552
|
-
|
|
17553
|
-
|
|
17438
|
+
const downlink = connection.downlink;
|
|
17439
|
+
if (downlink) {
|
|
17440
|
+
// downlink is in Mbps
|
|
17441
|
+
if (downlink < 1) return "slow-2g"; // < 1 Mbps
|
|
17442
|
+
if (downlink < 2.5) return "2g"; // 1-2.5 Mbps
|
|
17443
|
+
if (downlink < 10) return "3g"; // 2.5-10 Mbps
|
|
17444
|
+
return "4g"; // > 10 Mbps
|
|
17554
17445
|
}
|
|
17555
|
-
childrenWithGap.push(separator);
|
|
17556
|
-
}
|
|
17557
|
-
return childrenWithGap;
|
|
17558
|
-
};
|
|
17559
|
-
const endsWithWhitespace = jsxChild => {
|
|
17560
|
-
if (typeof jsxChild === "string") {
|
|
17561
|
-
return /\s$/.test(jsxChild);
|
|
17562
|
-
}
|
|
17563
|
-
return false;
|
|
17564
|
-
};
|
|
17565
|
-
const startsWithWhitespace = jsxChild => {
|
|
17566
|
-
if (typeof jsxChild === "string") {
|
|
17567
|
-
return /^\s/.test(jsxChild);
|
|
17568
17446
|
}
|
|
17569
|
-
return
|
|
17447
|
+
return "3g";
|
|
17570
17448
|
};
|
|
17571
|
-
|
|
17572
|
-
const
|
|
17573
|
-
|
|
17574
|
-
overflowEllipsis,
|
|
17575
|
-
...rest
|
|
17576
|
-
} = props;
|
|
17577
|
-
if (overflowEllipsis) {
|
|
17578
|
-
return jsx(TextOverflow, {
|
|
17579
|
-
...rest
|
|
17580
|
-
});
|
|
17581
|
-
}
|
|
17582
|
-
if (props.overflowPinned) {
|
|
17583
|
-
return jsx(TextOverflowPinned, {
|
|
17584
|
-
...props
|
|
17585
|
-
});
|
|
17586
|
-
}
|
|
17587
|
-
if (props.selectRange) {
|
|
17588
|
-
return jsx(TextWithSelectRange, {
|
|
17589
|
-
...props
|
|
17590
|
-
});
|
|
17591
|
-
}
|
|
17592
|
-
return jsx(TextBasic, {
|
|
17593
|
-
...props
|
|
17594
|
-
});
|
|
17449
|
+
|
|
17450
|
+
const updateNetworkSpeed = () => {
|
|
17451
|
+
networkSpeedSignal.value = getNetworkSpeed();
|
|
17595
17452
|
};
|
|
17596
|
-
|
|
17597
|
-
|
|
17598
|
-
|
|
17599
|
-
|
|
17600
|
-
|
|
17601
|
-
|
|
17602
|
-
|
|
17603
|
-
|
|
17604
|
-
|
|
17605
|
-
|
|
17606
|
-
|
|
17607
|
-
|
|
17608
|
-
|
|
17609
|
-
|
|
17610
|
-
|
|
17611
|
-
|
|
17612
|
-
|
|
17613
|
-
|
|
17614
|
-
|
|
17615
|
-
|
|
17616
|
-
|
|
17617
|
-
|
|
17618
|
-
|
|
17619
|
-
|
|
17620
|
-
|
|
17621
|
-
|
|
17622
|
-
|
|
17623
|
-
|
|
17453
|
+
|
|
17454
|
+
const networkSpeedSignal = signal(getNetworkSpeed());
|
|
17455
|
+
|
|
17456
|
+
const setupNetworkMonitoring = () => {
|
|
17457
|
+
const cleanupFunctions = [];
|
|
17458
|
+
|
|
17459
|
+
// ✅ 1. Écouter les changements natifs
|
|
17460
|
+
|
|
17461
|
+
if (connection) {
|
|
17462
|
+
connection.addEventListener("change", updateNetworkSpeed);
|
|
17463
|
+
cleanupFunctions.push(() => {
|
|
17464
|
+
connection.removeEventListener("change", updateNetworkSpeed);
|
|
17465
|
+
});
|
|
17466
|
+
}
|
|
17467
|
+
|
|
17468
|
+
// ✅ 2. Polling de backup (toutes les 60 secondes)
|
|
17469
|
+
const pollInterval = setInterval(updateNetworkSpeed, 60000);
|
|
17470
|
+
cleanupFunctions.push(() => clearInterval(pollInterval));
|
|
17471
|
+
|
|
17472
|
+
// ✅ 3. Vérifier lors de la reprise d'activité
|
|
17473
|
+
const handleVisibilityChange = () => {
|
|
17474
|
+
if (!document.hidden) {
|
|
17475
|
+
updateNetworkSpeed();
|
|
17476
|
+
}
|
|
17477
|
+
};
|
|
17478
|
+
|
|
17479
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
17480
|
+
cleanupFunctions.push(() => {
|
|
17481
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
17624
17482
|
});
|
|
17625
|
-
|
|
17626
|
-
|
|
17627
|
-
|
|
17628
|
-
|
|
17629
|
-
}
|
|
17630
|
-
|
|
17631
|
-
|
|
17632
|
-
|
|
17483
|
+
|
|
17484
|
+
// ✅ 4. Vérifier lors de la reprise de connexion
|
|
17485
|
+
const handleOnline = () => {
|
|
17486
|
+
updateNetworkSpeed();
|
|
17487
|
+
};
|
|
17488
|
+
|
|
17489
|
+
window.addEventListener("online", handleOnline);
|
|
17490
|
+
cleanupFunctions.push(() => {
|
|
17491
|
+
window.removeEventListener("online", handleOnline);
|
|
17633
17492
|
});
|
|
17634
|
-
|
|
17635
|
-
|
|
17636
|
-
|
|
17493
|
+
|
|
17494
|
+
// Cleanup global
|
|
17495
|
+
return () => {
|
|
17496
|
+
cleanupFunctions.forEach((cleanup) => cleanup());
|
|
17497
|
+
};
|
|
17498
|
+
};
|
|
17499
|
+
setupNetworkMonitoring();
|
|
17500
|
+
|
|
17501
|
+
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
17502
|
+
.navi_rectangle_loading {
|
|
17503
|
+
position: relative;
|
|
17504
|
+
display: flex;
|
|
17505
|
+
width: 100%;
|
|
17506
|
+
height: 100%;
|
|
17507
|
+
opacity: 0;
|
|
17637
17508
|
}
|
|
17638
|
-
|
|
17639
|
-
|
|
17640
|
-
|
|
17509
|
+
|
|
17510
|
+
.navi_rectangle_loading[data-visible] {
|
|
17511
|
+
opacity: 1;
|
|
17641
17512
|
}
|
|
17642
|
-
|
|
17643
|
-
|
|
17644
|
-
|
|
17645
|
-
|
|
17646
|
-
|
|
17647
|
-
|
|
17513
|
+
`;
|
|
17514
|
+
const RectangleLoading = ({
|
|
17515
|
+
shouldShowSpinner,
|
|
17516
|
+
color = "currentColor",
|
|
17517
|
+
radius = 0,
|
|
17518
|
+
size = 2
|
|
17648
17519
|
}) => {
|
|
17649
|
-
const
|
|
17650
|
-
const
|
|
17651
|
-
|
|
17652
|
-
|
|
17653
|
-
|
|
17654
|
-
|
|
17520
|
+
const containerRef = useRef(null);
|
|
17521
|
+
const [containerWidth, setContainerWidth] = useState(0);
|
|
17522
|
+
const [containerHeight, setContainerHeight] = useState(0);
|
|
17523
|
+
useLayoutEffect(() => {
|
|
17524
|
+
const container = containerRef.current;
|
|
17525
|
+
if (!container) {
|
|
17526
|
+
return null;
|
|
17527
|
+
}
|
|
17528
|
+
const {
|
|
17529
|
+
width,
|
|
17530
|
+
height
|
|
17531
|
+
} = container.getBoundingClientRect();
|
|
17532
|
+
setContainerWidth(width);
|
|
17533
|
+
setContainerHeight(height);
|
|
17534
|
+
let animationFrameId = null;
|
|
17535
|
+
// Create a resize observer to detect changes in the container's dimensions
|
|
17536
|
+
const resizeObserver = new ResizeObserver(entries => {
|
|
17537
|
+
// Use requestAnimationFrame to debounce updates
|
|
17538
|
+
if (animationFrameId) {
|
|
17539
|
+
cancelAnimationFrame(animationFrameId);
|
|
17540
|
+
}
|
|
17541
|
+
animationFrameId = requestAnimationFrame(() => {
|
|
17542
|
+
const [containerEntry] = entries;
|
|
17543
|
+
const {
|
|
17544
|
+
width,
|
|
17545
|
+
height
|
|
17546
|
+
} = containerEntry.contentRect;
|
|
17547
|
+
setContainerWidth(width);
|
|
17548
|
+
setContainerHeight(height);
|
|
17549
|
+
});
|
|
17550
|
+
});
|
|
17551
|
+
resizeObserver.observe(container);
|
|
17552
|
+
return () => {
|
|
17553
|
+
if (animationFrameId) {
|
|
17554
|
+
cancelAnimationFrame(animationFrameId);
|
|
17555
|
+
}
|
|
17556
|
+
resizeObserver.disconnect();
|
|
17557
|
+
};
|
|
17558
|
+
}, []);
|
|
17559
|
+
return jsx("span", {
|
|
17560
|
+
ref: containerRef,
|
|
17561
|
+
className: "navi_rectangle_loading",
|
|
17562
|
+
"data-visible": shouldShowSpinner ? "" : undefined,
|
|
17563
|
+
children: containerWidth > 0 && containerHeight > 0 && jsx(RectangleLoadingSvg, {
|
|
17564
|
+
radius: radius,
|
|
17565
|
+
color: color,
|
|
17566
|
+
width: containerWidth,
|
|
17567
|
+
height: containerHeight,
|
|
17568
|
+
strokeWidth: size
|
|
17569
|
+
})
|
|
17655
17570
|
});
|
|
17656
17571
|
};
|
|
17657
|
-
const
|
|
17658
|
-
|
|
17659
|
-
|
|
17660
|
-
|
|
17661
|
-
|
|
17662
|
-
|
|
17663
|
-
|
|
17572
|
+
const RectangleLoadingSvg = ({
|
|
17573
|
+
width,
|
|
17574
|
+
height,
|
|
17575
|
+
color,
|
|
17576
|
+
radius,
|
|
17577
|
+
trailColor = "transparent",
|
|
17578
|
+
strokeWidth
|
|
17664
17579
|
}) => {
|
|
17665
|
-
const
|
|
17666
|
-
|
|
17667
|
-
|
|
17668
|
-
|
|
17669
|
-
|
|
17670
|
-
|
|
17671
|
-
|
|
17672
|
-
|
|
17673
|
-
|
|
17580
|
+
const margin = Math.max(2, Math.min(width, height) * 0.03);
|
|
17581
|
+
|
|
17582
|
+
// Calculate the drawable area
|
|
17583
|
+
const drawableWidth = width - margin * 2;
|
|
17584
|
+
const drawableHeight = height - margin * 2;
|
|
17585
|
+
|
|
17586
|
+
// ✅ Check if this should be a circle - only if width and height are nearly equal
|
|
17587
|
+
const maxPossibleRadius = Math.min(drawableWidth, drawableHeight) / 2;
|
|
17588
|
+
const actualRadius = Math.min(radius || Math.min(drawableWidth, drawableHeight) * 0.05, maxPossibleRadius // ✅ Limité au radius maximum possible
|
|
17589
|
+
);
|
|
17590
|
+
const aspectRatio = Math.max(drawableWidth, drawableHeight) / Math.min(drawableWidth, drawableHeight);
|
|
17591
|
+
const isNearlySquare = aspectRatio <= 1.2; // Allow some tolerance for nearly square shapes
|
|
17592
|
+
const isCircle = isNearlySquare && actualRadius >= maxPossibleRadius * 0.95;
|
|
17593
|
+
let pathLength;
|
|
17594
|
+
let rectPath;
|
|
17595
|
+
if (isCircle) {
|
|
17596
|
+
// ✅ Circle: perimeter = 2πr
|
|
17597
|
+
pathLength = 2 * Math.PI * actualRadius;
|
|
17598
|
+
|
|
17599
|
+
// ✅ Circle path centered in the drawable area
|
|
17600
|
+
const centerX = margin + drawableWidth / 2;
|
|
17601
|
+
const centerY = margin + drawableHeight / 2;
|
|
17602
|
+
rectPath = `
|
|
17603
|
+
M ${centerX + actualRadius},${centerY}
|
|
17604
|
+
A ${actualRadius},${actualRadius} 0 1 1 ${centerX - actualRadius},${centerY}
|
|
17605
|
+
A ${actualRadius},${actualRadius} 0 1 1 ${centerX + actualRadius},${centerY}
|
|
17606
|
+
`;
|
|
17674
17607
|
} else {
|
|
17675
|
-
|
|
17676
|
-
|
|
17677
|
-
|
|
17678
|
-
|
|
17679
|
-
|
|
17680
|
-
|
|
17681
|
-
|
|
17682
|
-
|
|
17683
|
-
|
|
17684
|
-
|
|
17685
|
-
|
|
17686
|
-
|
|
17687
|
-
|
|
17688
|
-
|
|
17689
|
-
|
|
17690
|
-
}), children]
|
|
17691
|
-
});
|
|
17608
|
+
// ✅ Rectangle: calculate perimeter properly
|
|
17609
|
+
const straightEdges = 2 * (drawableWidth - 2 * actualRadius) + 2 * (drawableHeight - 2 * actualRadius);
|
|
17610
|
+
const cornerArcs = actualRadius > 0 ? 2 * Math.PI * actualRadius : 0;
|
|
17611
|
+
pathLength = straightEdges + cornerArcs;
|
|
17612
|
+
rectPath = `
|
|
17613
|
+
M ${margin + actualRadius},${margin}
|
|
17614
|
+
L ${margin + drawableWidth - actualRadius},${margin}
|
|
17615
|
+
A ${actualRadius},${actualRadius} 0 0 1 ${margin + drawableWidth},${margin + actualRadius}
|
|
17616
|
+
L ${margin + drawableWidth},${margin + drawableHeight - actualRadius}
|
|
17617
|
+
A ${actualRadius},${actualRadius} 0 0 1 ${margin + drawableWidth - actualRadius},${margin + drawableHeight}
|
|
17618
|
+
L ${margin + actualRadius},${margin + drawableHeight}
|
|
17619
|
+
A ${actualRadius},${actualRadius} 0 0 1 ${margin},${margin + drawableHeight - actualRadius}
|
|
17620
|
+
L ${margin},${margin + actualRadius}
|
|
17621
|
+
A ${actualRadius},${actualRadius} 0 0 1 ${margin + actualRadius},${margin}
|
|
17622
|
+
`;
|
|
17692
17623
|
}
|
|
17693
|
-
if (preventBoldLayoutShift) {
|
|
17694
|
-
const alignX = rest.alignX || rest.align || "start";
|
|
17695
17624
|
|
|
17696
|
-
|
|
17697
|
-
|
|
17698
|
-
|
|
17699
|
-
|
|
17700
|
-
|
|
17701
|
-
|
|
17702
|
-
|
|
17703
|
-
|
|
17704
|
-
|
|
17705
|
-
|
|
17706
|
-
|
|
17707
|
-
|
|
17708
|
-
|
|
17709
|
-
|
|
17710
|
-
|
|
17711
|
-
|
|
17712
|
-
|
|
17713
|
-
|
|
17625
|
+
// Fixed segment size in pixels
|
|
17626
|
+
const maxSegmentSize = 40;
|
|
17627
|
+
const segmentLength = Math.min(maxSegmentSize, pathLength * 0.25);
|
|
17628
|
+
const gapLength = pathLength - segmentLength;
|
|
17629
|
+
|
|
17630
|
+
// Vitesse constante en pixels par seconde
|
|
17631
|
+
const networkSpeed = useNetworkSpeed();
|
|
17632
|
+
const pixelsPerSecond = {
|
|
17633
|
+
"slow-2g": 40,
|
|
17634
|
+
"2g": 60,
|
|
17635
|
+
"3g": 80,
|
|
17636
|
+
"4g": 120
|
|
17637
|
+
}[networkSpeed] || 80;
|
|
17638
|
+
const animationDuration = Math.max(1.5, pathLength / pixelsPerSecond);
|
|
17639
|
+
|
|
17640
|
+
// ✅ Calculate correct offset based on actual segment size
|
|
17641
|
+
const segmentRatio = segmentLength / pathLength;
|
|
17642
|
+
const circleOffset = -animationDuration * segmentRatio;
|
|
17643
|
+
return jsxs("svg", {
|
|
17644
|
+
width: "100%",
|
|
17645
|
+
height: "100%",
|
|
17646
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
17647
|
+
preserveAspectRatio: "none",
|
|
17648
|
+
style: "overflow: visible",
|
|
17649
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
17650
|
+
"shape-rendering": "geometricPrecision",
|
|
17651
|
+
children: [isCircle ? jsx("circle", {
|
|
17652
|
+
cx: margin + drawableWidth / 2,
|
|
17653
|
+
cy: margin + drawableHeight / 2,
|
|
17654
|
+
r: actualRadius,
|
|
17655
|
+
fill: "none",
|
|
17656
|
+
stroke: trailColor,
|
|
17657
|
+
strokeWidth: strokeWidth
|
|
17658
|
+
}) : jsx("rect", {
|
|
17659
|
+
x: margin,
|
|
17660
|
+
y: margin,
|
|
17661
|
+
width: drawableWidth,
|
|
17662
|
+
height: drawableHeight,
|
|
17663
|
+
fill: "none",
|
|
17664
|
+
stroke: trailColor,
|
|
17665
|
+
strokeWidth: strokeWidth,
|
|
17666
|
+
rx: actualRadius
|
|
17667
|
+
}), jsx("path", {
|
|
17668
|
+
d: rectPath,
|
|
17669
|
+
fill: "none",
|
|
17670
|
+
stroke: color,
|
|
17671
|
+
strokeWidth: strokeWidth,
|
|
17672
|
+
strokeLinecap: "round",
|
|
17673
|
+
strokeDasharray: `${segmentLength} ${gapLength}`,
|
|
17674
|
+
pathLength: pathLength,
|
|
17675
|
+
children: jsx("animate", {
|
|
17676
|
+
attributeName: "stroke-dashoffset",
|
|
17677
|
+
from: pathLength,
|
|
17678
|
+
to: "0",
|
|
17679
|
+
dur: `${animationDuration}s`,
|
|
17680
|
+
repeatCount: "indefinite",
|
|
17681
|
+
begin: "0s"
|
|
17714
17682
|
})
|
|
17715
|
-
})
|
|
17716
|
-
|
|
17717
|
-
|
|
17718
|
-
|
|
17719
|
-
|
|
17683
|
+
}), jsx("circle", {
|
|
17684
|
+
r: strokeWidth,
|
|
17685
|
+
fill: color,
|
|
17686
|
+
children: jsx("animateMotion", {
|
|
17687
|
+
path: rectPath,
|
|
17688
|
+
dur: `${animationDuration}s`,
|
|
17689
|
+
repeatCount: "indefinite",
|
|
17690
|
+
rotate: "auto",
|
|
17691
|
+
begin: `${circleOffset}s`
|
|
17692
|
+
})
|
|
17693
|
+
})]
|
|
17720
17694
|
});
|
|
17721
17695
|
};
|
|
17722
17696
|
|
|
17723
17697
|
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
17724
|
-
.
|
|
17725
|
-
display: inline-block;
|
|
17726
|
-
box-sizing: border-box;
|
|
17727
|
-
max-width: 100%;
|
|
17728
|
-
max-height: 100%;
|
|
17729
|
-
|
|
17730
|
-
&[data-flow-inline] {
|
|
17731
|
-
width: 1em;
|
|
17732
|
-
height: 1em;
|
|
17733
|
-
}
|
|
17734
|
-
&[data-icon-char] {
|
|
17735
|
-
flex-grow: 0 !important;
|
|
17736
|
-
line-height: normal;
|
|
17737
|
-
}
|
|
17738
|
-
}
|
|
17739
|
-
|
|
17740
|
-
.navi_icon[data-interactive] {
|
|
17741
|
-
cursor: pointer;
|
|
17742
|
-
}
|
|
17743
|
-
|
|
17744
|
-
.navi_icon_char_slot {
|
|
17745
|
-
opacity: 0;
|
|
17746
|
-
cursor: default;
|
|
17747
|
-
user-select: none;
|
|
17748
|
-
}
|
|
17749
|
-
.navi_icon_foreground {
|
|
17698
|
+
.navi_loading_rectangle_wrapper {
|
|
17750
17699
|
position: absolute;
|
|
17751
|
-
|
|
17752
|
-
|
|
17753
|
-
|
|
17754
|
-
|
|
17755
|
-
|
|
17756
|
-
|
|
17757
|
-
|
|
17758
|
-
max-height: 1em;
|
|
17759
|
-
align-items: center;
|
|
17760
|
-
justify-content: center;
|
|
17761
|
-
}
|
|
17762
|
-
|
|
17763
|
-
.navi_icon > svg,
|
|
17764
|
-
.navi_icon > img {
|
|
17765
|
-
width: 100%;
|
|
17766
|
-
height: 100%;
|
|
17767
|
-
backface-visibility: hidden;
|
|
17768
|
-
}
|
|
17769
|
-
.navi_icon[data-has-width] > svg,
|
|
17770
|
-
.navi_icon[data-has-width] > img {
|
|
17771
|
-
width: 100%;
|
|
17772
|
-
height: auto;
|
|
17773
|
-
}
|
|
17774
|
-
.navi_icon[data-has-height] > svg,
|
|
17775
|
-
.navi_icon[data-has-height] > img {
|
|
17776
|
-
width: auto;
|
|
17777
|
-
height: 100%;
|
|
17778
|
-
}
|
|
17779
|
-
.navi_icon[data-has-width][data-has-height] > svg,
|
|
17780
|
-
.navi_icon[data-has-width][data-has-height] > img {
|
|
17781
|
-
width: 100%;
|
|
17782
|
-
height: 100%;
|
|
17783
|
-
}
|
|
17784
|
-
|
|
17785
|
-
.navi_icon[data-icon-char] svg,
|
|
17786
|
-
.navi_icon[data-icon-char] img {
|
|
17787
|
-
width: 100%;
|
|
17788
|
-
height: 100%;
|
|
17700
|
+
top: var(--rectangle-top, 0);
|
|
17701
|
+
right: var(--rectangle-right, 0);
|
|
17702
|
+
bottom: var(--rectangle-bottom, 0);
|
|
17703
|
+
left: var(--rectangle-left, 0);
|
|
17704
|
+
z-index: 1;
|
|
17705
|
+
opacity: 0;
|
|
17706
|
+
pointer-events: none;
|
|
17789
17707
|
}
|
|
17790
|
-
.
|
|
17791
|
-
|
|
17708
|
+
.navi_loading_rectangle_wrapper[data-visible] {
|
|
17709
|
+
opacity: 1;
|
|
17792
17710
|
}
|
|
17793
17711
|
`;
|
|
17794
|
-
const
|
|
17795
|
-
|
|
17796
|
-
|
|
17797
|
-
|
|
17798
|
-
|
|
17799
|
-
|
|
17800
|
-
|
|
17801
|
-
|
|
17802
|
-
|
|
17803
|
-
|
|
17804
|
-
|
|
17712
|
+
const LoaderBackground = ({
|
|
17713
|
+
loading,
|
|
17714
|
+
containerRef,
|
|
17715
|
+
targetSelector,
|
|
17716
|
+
color,
|
|
17717
|
+
inset = 0,
|
|
17718
|
+
spacingTop = 0,
|
|
17719
|
+
spacingLeft = 0,
|
|
17720
|
+
spacingBottom = 0,
|
|
17721
|
+
spacingRight = 0,
|
|
17722
|
+
children
|
|
17805
17723
|
}) => {
|
|
17806
|
-
|
|
17807
|
-
|
|
17808
|
-
|
|
17809
|
-
|
|
17810
|
-
href: href
|
|
17811
|
-
})
|
|
17812
|
-
}) : children;
|
|
17813
|
-
let {
|
|
17814
|
-
box,
|
|
17815
|
-
width,
|
|
17816
|
-
height
|
|
17817
|
-
} = props;
|
|
17818
|
-
if (width === "auto") width = undefined;
|
|
17819
|
-
if (height === "auto") height = undefined;
|
|
17820
|
-
const hasExplicitWidth = width !== undefined;
|
|
17821
|
-
const hasExplicitHeight = height !== undefined;
|
|
17822
|
-
if (!hasExplicitWidth && !hasExplicitHeight) {
|
|
17823
|
-
if (decorative === undefined && !onClick) {
|
|
17824
|
-
decorative = true;
|
|
17724
|
+
if (containerRef) {
|
|
17725
|
+
const container = containerRef.current;
|
|
17726
|
+
if (!container) {
|
|
17727
|
+
return children;
|
|
17825
17728
|
}
|
|
17826
|
-
|
|
17827
|
-
|
|
17828
|
-
|
|
17829
|
-
|
|
17830
|
-
|
|
17831
|
-
|
|
17832
|
-
|
|
17833
|
-
|
|
17834
|
-
|
|
17835
|
-
...ariaProps,
|
|
17836
|
-
"data-icon-text": "",
|
|
17729
|
+
return createPortal(jsx(LoaderBackgroundWithPortal, {
|
|
17730
|
+
container: container,
|
|
17731
|
+
loading: loading,
|
|
17732
|
+
color: color,
|
|
17733
|
+
inset: inset,
|
|
17734
|
+
spacingTop: spacingTop,
|
|
17735
|
+
spacingLeft: spacingLeft,
|
|
17736
|
+
spacingBottom: spacingBottom,
|
|
17737
|
+
spacingRight: spacingRight,
|
|
17837
17738
|
children: children
|
|
17838
|
-
});
|
|
17839
|
-
}
|
|
17840
|
-
if (box) {
|
|
17841
|
-
return jsx(Box, {
|
|
17842
|
-
square: true,
|
|
17843
|
-
...props,
|
|
17844
|
-
...ariaProps,
|
|
17845
|
-
box: box,
|
|
17846
|
-
baseClassName: "navi_icon",
|
|
17847
|
-
"data-has-width": hasExplicitWidth ? "" : undefined,
|
|
17848
|
-
"data-has-height": hasExplicitHeight ? "" : undefined,
|
|
17849
|
-
"data-interactive": onClick ? "" : undefined,
|
|
17850
|
-
onClick: onClick,
|
|
17851
|
-
children: innerChildren
|
|
17852
|
-
});
|
|
17739
|
+
}), container);
|
|
17853
17740
|
}
|
|
17854
|
-
|
|
17855
|
-
|
|
17856
|
-
|
|
17857
|
-
|
|
17858
|
-
|
|
17859
|
-
|
|
17860
|
-
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
|
|
17864
|
-
onClick: onClick,
|
|
17865
|
-
children: [jsx("span", {
|
|
17866
|
-
className: "navi_icon_char_slot",
|
|
17867
|
-
"aria-hidden": "true",
|
|
17868
|
-
children: invisibleText
|
|
17869
|
-
}), jsx(Text, {
|
|
17870
|
-
className: "navi_icon_foreground",
|
|
17871
|
-
spacing: "pre",
|
|
17872
|
-
children: innerChildren
|
|
17873
|
-
})]
|
|
17741
|
+
return jsx(LoaderBackgroundBasic, {
|
|
17742
|
+
targetSelector: targetSelector,
|
|
17743
|
+
loading: loading,
|
|
17744
|
+
color: color,
|
|
17745
|
+
inset: inset,
|
|
17746
|
+
spacingTop: spacingTop,
|
|
17747
|
+
spacingLeft: spacingLeft,
|
|
17748
|
+
spacingBottom: spacingBottom,
|
|
17749
|
+
spacingRight: spacingRight,
|
|
17750
|
+
children: children
|
|
17874
17751
|
});
|
|
17875
17752
|
};
|
|
17876
|
-
|
|
17877
|
-
|
|
17878
|
-
|
|
17879
|
-
|
|
17880
|
-
|
|
17881
|
-
|
|
17882
|
-
|
|
17883
|
-
|
|
17884
|
-
|
|
17885
|
-
|
|
17886
|
-
|
|
17887
|
-
|
|
17888
|
-
|
|
17753
|
+
const LoaderBackgroundWithPortal = ({
|
|
17754
|
+
container,
|
|
17755
|
+
loading,
|
|
17756
|
+
color,
|
|
17757
|
+
inset,
|
|
17758
|
+
spacingTop,
|
|
17759
|
+
spacingLeft,
|
|
17760
|
+
spacingBottom,
|
|
17761
|
+
spacingRight,
|
|
17762
|
+
children
|
|
17763
|
+
}) => {
|
|
17764
|
+
const shouldShowSpinner = useDebounceTrue(loading, 300);
|
|
17765
|
+
if (!shouldShowSpinner) {
|
|
17766
|
+
return children;
|
|
17767
|
+
}
|
|
17768
|
+
container.style.position = "relative";
|
|
17769
|
+
let paddingTop = 0;
|
|
17770
|
+
if (container.nodeName === "DETAILS") {
|
|
17771
|
+
paddingTop = container.querySelector("summary").offsetHeight;
|
|
17772
|
+
}
|
|
17773
|
+
return jsxs(Fragment, {
|
|
17774
|
+
children: [jsx("div", {
|
|
17775
|
+
style: {
|
|
17776
|
+
position: "absolute",
|
|
17777
|
+
top: `${inset + paddingTop + spacingTop}px`,
|
|
17778
|
+
bottom: `${inset + spacingBottom}px`,
|
|
17779
|
+
left: `${inset + spacingLeft}px`,
|
|
17780
|
+
right: `${inset + spacingRight}px`
|
|
17781
|
+
},
|
|
17782
|
+
children: shouldShowSpinner && jsx(RectangleLoading, {
|
|
17783
|
+
color: color
|
|
17784
|
+
})
|
|
17785
|
+
}), children]
|
|
17889
17786
|
});
|
|
17890
17787
|
};
|
|
17891
|
-
const
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
|
|
17903
|
-
|
|
17788
|
+
const LoaderBackgroundBasic = ({
|
|
17789
|
+
loading,
|
|
17790
|
+
targetSelector,
|
|
17791
|
+
color,
|
|
17792
|
+
spacingTop,
|
|
17793
|
+
spacingLeft,
|
|
17794
|
+
spacingBottom,
|
|
17795
|
+
spacingRight,
|
|
17796
|
+
inset,
|
|
17797
|
+
children
|
|
17798
|
+
}) => {
|
|
17799
|
+
const shouldShowSpinner = useDebounceTrue(loading, 300);
|
|
17800
|
+
const rectangleRef = useRef(null);
|
|
17801
|
+
const [, setOutlineOffset] = useState(0);
|
|
17802
|
+
const [borderRadius, setBorderRadius] = useState(0);
|
|
17803
|
+
const [borderTopWidth, setBorderTopWidth] = useState(0);
|
|
17804
|
+
const [borderLeftWidth, setBorderLeftWidth] = useState(0);
|
|
17805
|
+
const [borderRightWidth, setBorderRightWidth] = useState(0);
|
|
17806
|
+
const [borderBottomWidth, setBorderBottomWidth] = useState(0);
|
|
17807
|
+
const [marginTop, setMarginTop] = useState(0);
|
|
17808
|
+
const [marginBottom, setMarginBottom] = useState(0);
|
|
17809
|
+
const [marginLeft, setMarginLeft] = useState(0);
|
|
17810
|
+
const [marginRight, setMarginRight] = useState(0);
|
|
17811
|
+
const [paddingTop, setPaddingTop] = useState(0);
|
|
17812
|
+
const [paddingLeft, setPaddingLeft] = useState(0);
|
|
17813
|
+
const [paddingRight, setPaddingRight] = useState(0);
|
|
17814
|
+
const [paddingBottom, setPaddingBottom] = useState(0);
|
|
17815
|
+
const [currentColor, setCurrentColor] = useState(color);
|
|
17816
|
+
useLayoutEffect(() => {
|
|
17817
|
+
let animationFrame;
|
|
17818
|
+
const updateStyles = () => {
|
|
17819
|
+
const rectangle = rectangleRef.current;
|
|
17820
|
+
if (!rectangle) {
|
|
17821
|
+
return;
|
|
17822
|
+
}
|
|
17823
|
+
const container = rectangle.parentElement;
|
|
17824
|
+
const containedElement = rectangle.nextElementSibling;
|
|
17825
|
+
const target = targetSelector ? container.querySelector(targetSelector) : containedElement;
|
|
17826
|
+
if (target) {
|
|
17827
|
+
const {
|
|
17828
|
+
width,
|
|
17829
|
+
height
|
|
17830
|
+
} = target.getBoundingClientRect();
|
|
17831
|
+
const containedComputedStyle = window.getComputedStyle(containedElement);
|
|
17832
|
+
const targetComputedStyle = window.getComputedStyle(target);
|
|
17833
|
+
const newBorderTopWidth = resolveCSSSize(targetComputedStyle.borderTopWidth);
|
|
17834
|
+
const newBorderLeftWidth = resolveCSSSize(targetComputedStyle.borderLeftWidth);
|
|
17835
|
+
const newBorderRightWidth = resolveCSSSize(targetComputedStyle.borderRightWidth);
|
|
17836
|
+
const newBorderBottomWidth = resolveCSSSize(targetComputedStyle.borderBottomWidth);
|
|
17837
|
+
const newBorderRadius = resolveCSSSize(targetComputedStyle.borderRadius, {
|
|
17838
|
+
availableSize: Math.min(width, height)
|
|
17839
|
+
});
|
|
17840
|
+
const newOutlineColor = targetComputedStyle.outlineColor;
|
|
17841
|
+
const newBorderColor = targetComputedStyle.borderColor;
|
|
17842
|
+
const newDetectedColor = targetComputedStyle.color;
|
|
17843
|
+
const newOutlineOffset = resolveCSSSize(targetComputedStyle.outlineOffset);
|
|
17844
|
+
const newMarginTop = resolveCSSSize(targetComputedStyle.marginTop);
|
|
17845
|
+
const newMarginBottom = resolveCSSSize(targetComputedStyle.marginBottom);
|
|
17846
|
+
const newMarginLeft = resolveCSSSize(targetComputedStyle.marginLeft);
|
|
17847
|
+
const newMarginRight = resolveCSSSize(targetComputedStyle.marginRight);
|
|
17848
|
+
const paddingTop = resolveCSSSize(containedComputedStyle.paddingTop);
|
|
17849
|
+
const paddingLeft = resolveCSSSize(containedComputedStyle.paddingLeft);
|
|
17850
|
+
const paddingRight = resolveCSSSize(containedComputedStyle.paddingRight);
|
|
17851
|
+
const paddingBottom = resolveCSSSize(containedComputedStyle.paddingBottom);
|
|
17852
|
+
setBorderTopWidth(newBorderTopWidth);
|
|
17853
|
+
setBorderLeftWidth(newBorderLeftWidth);
|
|
17854
|
+
setBorderRightWidth(newBorderRightWidth);
|
|
17855
|
+
setBorderBottomWidth(newBorderBottomWidth);
|
|
17856
|
+
setBorderRadius(newBorderRadius);
|
|
17857
|
+
setOutlineOffset(newOutlineOffset);
|
|
17858
|
+
setMarginTop(newMarginTop);
|
|
17859
|
+
setMarginBottom(newMarginBottom);
|
|
17860
|
+
setMarginLeft(newMarginLeft);
|
|
17861
|
+
setMarginRight(newMarginRight);
|
|
17862
|
+
setPaddingTop(paddingTop);
|
|
17863
|
+
setPaddingLeft(paddingLeft);
|
|
17864
|
+
setPaddingRight(paddingRight);
|
|
17865
|
+
setPaddingBottom(paddingBottom);
|
|
17866
|
+
if (color) {
|
|
17867
|
+
// const resolvedColor = resolveCSSColor(color, rectangle, "css");
|
|
17868
|
+
// console.log(resolvedColor);
|
|
17869
|
+
setCurrentColor(color);
|
|
17870
|
+
} else if (newOutlineColor && newOutlineColor !== "rgba(0, 0, 0, 0)" && (document.activeElement === containedElement || newBorderColor === "rgba(0, 0, 0, 0)")) {
|
|
17871
|
+
setCurrentColor(newOutlineColor);
|
|
17872
|
+
} else if (newBorderColor && newBorderColor !== "rgba(0, 0, 0, 0)") {
|
|
17873
|
+
setCurrentColor(newBorderColor);
|
|
17874
|
+
} else {
|
|
17875
|
+
setCurrentColor(newDetectedColor);
|
|
17876
|
+
}
|
|
17877
|
+
}
|
|
17878
|
+
// updateStyles is very cheap so we run it every frame
|
|
17879
|
+
animationFrame = requestAnimationFrame(updateStyles);
|
|
17880
|
+
};
|
|
17881
|
+
updateStyles();
|
|
17882
|
+
return () => {
|
|
17883
|
+
cancelAnimationFrame(animationFrame);
|
|
17884
|
+
};
|
|
17885
|
+
}, [color, targetSelector]);
|
|
17886
|
+
spacingTop += inset;
|
|
17887
|
+
// spacingTop += outlineOffset;
|
|
17888
|
+
// spacingTop -= borderTopWidth;
|
|
17889
|
+
spacingTop += marginTop;
|
|
17890
|
+
spacingLeft += inset;
|
|
17891
|
+
// spacingLeft += outlineOffset;
|
|
17892
|
+
// spacingLeft -= borderLeftWidth;
|
|
17893
|
+
spacingLeft += marginLeft;
|
|
17894
|
+
spacingRight += inset;
|
|
17895
|
+
// spacingRight += outlineOffset;
|
|
17896
|
+
// spacingRight -= borderRightWidth;
|
|
17897
|
+
spacingRight += marginRight;
|
|
17898
|
+
spacingBottom += inset;
|
|
17899
|
+
// spacingBottom += outlineOffset;
|
|
17900
|
+
// spacingBottom -= borderBottomWidth;
|
|
17901
|
+
spacingBottom += marginBottom;
|
|
17902
|
+
if (targetSelector) {
|
|
17903
|
+
// oversimplification that actually works
|
|
17904
|
+
// (simplified because it assumes the targeted element is a direct child of the contained element which may have padding)
|
|
17905
|
+
spacingTop += paddingTop;
|
|
17906
|
+
spacingLeft += paddingLeft;
|
|
17907
|
+
spacingRight += paddingRight;
|
|
17908
|
+
spacingBottom += paddingBottom;
|
|
17909
|
+
}
|
|
17910
|
+
const maxBorderWidth = Math.max(borderTopWidth, borderLeftWidth, borderRightWidth, borderBottomWidth);
|
|
17911
|
+
const halfMaxBorderSize = maxBorderWidth / 2;
|
|
17912
|
+
const size = halfMaxBorderSize < 2 ? 2 : halfMaxBorderSize;
|
|
17913
|
+
const lineHalfSize = size / 2;
|
|
17914
|
+
spacingTop -= lineHalfSize;
|
|
17915
|
+
spacingLeft -= lineHalfSize;
|
|
17916
|
+
spacingRight -= lineHalfSize;
|
|
17917
|
+
spacingBottom -= lineHalfSize;
|
|
17918
|
+
return jsxs(Fragment, {
|
|
17919
|
+
children: [jsx("span", {
|
|
17920
|
+
ref: rectangleRef,
|
|
17921
|
+
className: "navi_loading_rectangle_wrapper",
|
|
17922
|
+
"data-visible": shouldShowSpinner ? "" : undefined,
|
|
17923
|
+
style: {
|
|
17924
|
+
"--rectangle-top": `${spacingTop}px`,
|
|
17925
|
+
"--rectangle-left": `${spacingLeft}px`,
|
|
17926
|
+
"--rectangle-bottom": `${spacingBottom}px`,
|
|
17927
|
+
"--rectangle-right": `${spacingRight}px`
|
|
17928
|
+
},
|
|
17929
|
+
children: loading && jsx(RectangleLoading, {
|
|
17930
|
+
shouldShowSpinner: shouldShowSpinner,
|
|
17931
|
+
color: currentColor,
|
|
17932
|
+
radius: borderRadius,
|
|
17933
|
+
size: size
|
|
17934
|
+
})
|
|
17935
|
+
}), children]
|
|
17904
17936
|
});
|
|
17905
17937
|
};
|
|
17906
17938
|
|
|
@@ -20069,16 +20101,6 @@ const LinkPlain = props => {
|
|
|
20069
20101
|
})]
|
|
20070
20102
|
});
|
|
20071
20103
|
};
|
|
20072
|
-
const PhoneSvg = () => {
|
|
20073
|
-
return jsx("svg", {
|
|
20074
|
-
viewBox: "0 0 24 24",
|
|
20075
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
20076
|
-
children: jsx("path", {
|
|
20077
|
-
d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z",
|
|
20078
|
-
fill: "currentColor"
|
|
20079
|
-
})
|
|
20080
|
-
});
|
|
20081
|
-
};
|
|
20082
20104
|
const SmsSvg = () => {
|
|
20083
20105
|
return jsx("svg", {
|
|
20084
20106
|
viewBox: "0 0 24 24",
|
|
@@ -20089,25 +20111,6 @@ const SmsSvg = () => {
|
|
|
20089
20111
|
})
|
|
20090
20112
|
});
|
|
20091
20113
|
};
|
|
20092
|
-
const EmailSvg = () => {
|
|
20093
|
-
return jsxs("svg", {
|
|
20094
|
-
viewBox: "0 0 24 24",
|
|
20095
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
20096
|
-
children: [jsx("path", {
|
|
20097
|
-
d: "M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",
|
|
20098
|
-
fill: "none",
|
|
20099
|
-
stroke: "currentColor",
|
|
20100
|
-
"stroke-width": "2"
|
|
20101
|
-
}), jsx("path", {
|
|
20102
|
-
d: "m2 6 8 5 2 1.5 2-1.5 8-5",
|
|
20103
|
-
fill: "none",
|
|
20104
|
-
stroke: "currentColor",
|
|
20105
|
-
"stroke-width": "2",
|
|
20106
|
-
"stroke-linecap": "round",
|
|
20107
|
-
"stroke-linejoin": "round"
|
|
20108
|
-
})]
|
|
20109
|
-
});
|
|
20110
|
-
};
|
|
20111
20114
|
const GithubSvg = () => {
|
|
20112
20115
|
return jsx("svg", {
|
|
20113
20116
|
viewBox: "0 0 24 24",
|
|
@@ -22825,6 +22828,10 @@ const InputTextualBasic = props => {
|
|
|
22825
22828
|
if (icon === undefined) {
|
|
22826
22829
|
if (type === "search") {
|
|
22827
22830
|
innerIcon = jsx(SearchSvg, {});
|
|
22831
|
+
} else if (type === "email") {
|
|
22832
|
+
innerIcon = jsx(EmailSvg, {});
|
|
22833
|
+
} else if (type === "tel") {
|
|
22834
|
+
innerIcon = jsx(PhoneSvg, {});
|
|
22828
22835
|
}
|
|
22829
22836
|
} else {
|
|
22830
22837
|
innerIcon = icon;
|
|
@@ -27389,6 +27396,69 @@ const Address = ({
|
|
|
27389
27396
|
});
|
|
27390
27397
|
};
|
|
27391
27398
|
|
|
27399
|
+
const LoadingDots = ({
|
|
27400
|
+
color = "FF156D"
|
|
27401
|
+
}) => {
|
|
27402
|
+
return jsxs("svg", {
|
|
27403
|
+
viewBox: "0 0 200 200",
|
|
27404
|
+
width: "100%",
|
|
27405
|
+
height: "100%",
|
|
27406
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
27407
|
+
children: [jsx("rect", {
|
|
27408
|
+
fill: color,
|
|
27409
|
+
stroke: color,
|
|
27410
|
+
"stroke-width": "15",
|
|
27411
|
+
width: "30",
|
|
27412
|
+
height: "30",
|
|
27413
|
+
x: "25",
|
|
27414
|
+
y: "85",
|
|
27415
|
+
children: jsx("animate", {
|
|
27416
|
+
attributeName: "opacity",
|
|
27417
|
+
calcMode: "spline",
|
|
27418
|
+
dur: "2",
|
|
27419
|
+
values: "1;0;1;",
|
|
27420
|
+
keySplines: ".5 0 .5 1;.5 0 .5 1",
|
|
27421
|
+
repeatCount: "indefinite",
|
|
27422
|
+
begin: "-.4"
|
|
27423
|
+
})
|
|
27424
|
+
}), jsx("rect", {
|
|
27425
|
+
fill: color,
|
|
27426
|
+
stroke: color,
|
|
27427
|
+
"stroke-width": "15",
|
|
27428
|
+
width: "30",
|
|
27429
|
+
height: "30",
|
|
27430
|
+
x: "85",
|
|
27431
|
+
y: "85",
|
|
27432
|
+
children: jsx("animate", {
|
|
27433
|
+
attributeName: "opacity",
|
|
27434
|
+
calcMode: "spline",
|
|
27435
|
+
dur: "2",
|
|
27436
|
+
values: "1;0;1;",
|
|
27437
|
+
keySplines: ".5 0 .5 1;.5 0 .5 1",
|
|
27438
|
+
repeatCount: "indefinite",
|
|
27439
|
+
begin: "-.2"
|
|
27440
|
+
})
|
|
27441
|
+
}), jsx("rect", {
|
|
27442
|
+
fill: color,
|
|
27443
|
+
stroke: color,
|
|
27444
|
+
"stroke-width": "15",
|
|
27445
|
+
width: "30",
|
|
27446
|
+
height: "30",
|
|
27447
|
+
x: "145",
|
|
27448
|
+
y: "85",
|
|
27449
|
+
children: jsx("animate", {
|
|
27450
|
+
attributeName: "opacity",
|
|
27451
|
+
calcMode: "spline",
|
|
27452
|
+
dur: "2",
|
|
27453
|
+
values: "1;0;1;",
|
|
27454
|
+
keySplines: ".5 0 .5 1;.5 0 .5 1",
|
|
27455
|
+
repeatCount: "indefinite",
|
|
27456
|
+
begin: "0"
|
|
27457
|
+
})
|
|
27458
|
+
})]
|
|
27459
|
+
});
|
|
27460
|
+
};
|
|
27461
|
+
|
|
27392
27462
|
const CSS_VAR_NAME = "--x-color-contrasting";
|
|
27393
27463
|
|
|
27394
27464
|
const useContrastingColor = (ref, backgroundElementSelector) => {
|
|
@@ -27556,10 +27626,11 @@ const BadgeCountCircle = ({
|
|
|
27556
27626
|
ref,
|
|
27557
27627
|
charCount,
|
|
27558
27628
|
hasOverflow,
|
|
27629
|
+
loading,
|
|
27559
27630
|
children,
|
|
27560
27631
|
...props
|
|
27561
27632
|
}) => {
|
|
27562
|
-
return
|
|
27633
|
+
return jsx(Text, {
|
|
27563
27634
|
ref: ref,
|
|
27564
27635
|
className: "navi_badge_count",
|
|
27565
27636
|
"data-circle": "",
|
|
@@ -27571,18 +27642,20 @@ const BadgeCountCircle = ({
|
|
|
27571
27642
|
...props,
|
|
27572
27643
|
styleCSSVars: BadgeStyleCSSVars,
|
|
27573
27644
|
spacing: "pre",
|
|
27574
|
-
children:
|
|
27575
|
-
|
|
27576
|
-
|
|
27577
|
-
|
|
27578
|
-
|
|
27579
|
-
|
|
27580
|
-
|
|
27581
|
-
|
|
27582
|
-
|
|
27583
|
-
|
|
27584
|
-
|
|
27585
|
-
|
|
27645
|
+
children: loading ? jsx(LoadingDots, {}) : jsxs(Fragment, {
|
|
27646
|
+
children: [jsx("span", {
|
|
27647
|
+
style: "user-select: none",
|
|
27648
|
+
children: "\u200B"
|
|
27649
|
+
}), jsx("span", {
|
|
27650
|
+
className: "navi_badge_count_frame"
|
|
27651
|
+
}), jsx("span", {
|
|
27652
|
+
className: "navi_badge_count_text",
|
|
27653
|
+
children: children
|
|
27654
|
+
}), jsx("span", {
|
|
27655
|
+
style: "user-select: none",
|
|
27656
|
+
children: "\u200B"
|
|
27657
|
+
})]
|
|
27658
|
+
})
|
|
27586
27659
|
});
|
|
27587
27660
|
};
|
|
27588
27661
|
const BadgeCountEllipse = ({
|