@jsenv/navi 0.16.58 → 0.16.60
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 +1788 -1699
- package/dist/jsenv_navi.js.map +137 -129
- 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;
|
|
@@ -16862,1045 +16313,1626 @@ const installCustomConstraintValidation = (
|
|
|
16862
16313
|
// an other button is explicitly submitting the form, this one would not submit it
|
|
16863
16314
|
return null;
|
|
16864
16315
|
}
|
|
16865
|
-
// this is the only button inside the form without type attribute, so it defaults to type="submit"
|
|
16866
|
-
return button;
|
|
16867
|
-
};
|
|
16868
|
-
const formSubmitTarget = determineClosestFormSubmitTargetForClickEvent();
|
|
16869
|
-
if (formSubmitTarget) {
|
|
16870
|
-
clickEvent.preventDefault();
|
|
16316
|
+
// this is the only button inside the form without type attribute, so it defaults to type="submit"
|
|
16317
|
+
return button;
|
|
16318
|
+
};
|
|
16319
|
+
const formSubmitTarget = determineClosestFormSubmitTargetForClickEvent();
|
|
16320
|
+
if (formSubmitTarget) {
|
|
16321
|
+
clickEvent.preventDefault();
|
|
16322
|
+
}
|
|
16323
|
+
dispatchActionRequestedCustomEvent(elementWithAction, {
|
|
16324
|
+
event: clickEvent,
|
|
16325
|
+
requester: formSubmitTarget || button,
|
|
16326
|
+
});
|
|
16327
|
+
};
|
|
16328
|
+
element.addEventListener("click", onclick);
|
|
16329
|
+
addTeardown(() => {
|
|
16330
|
+
element.removeEventListener("click", onclick);
|
|
16331
|
+
});
|
|
16332
|
+
}
|
|
16333
|
+
|
|
16334
|
+
request_on_input_change: {
|
|
16335
|
+
const isInput =
|
|
16336
|
+
element.tagName === "INPUT" || element.tagName === "TEXTAREA";
|
|
16337
|
+
if (!isInput) {
|
|
16338
|
+
break request_on_input_change;
|
|
16339
|
+
}
|
|
16340
|
+
const stop = listenInputChange(element, (e) => {
|
|
16341
|
+
const elementWithAction = closestElementWithAction(element);
|
|
16342
|
+
if (!elementWithAction) {
|
|
16343
|
+
return;
|
|
16344
|
+
}
|
|
16345
|
+
dispatchActionRequestedCustomEvent(elementWithAction, {
|
|
16346
|
+
event: e,
|
|
16347
|
+
requester: element,
|
|
16348
|
+
});
|
|
16349
|
+
});
|
|
16350
|
+
addTeardown(() => {
|
|
16351
|
+
stop();
|
|
16352
|
+
});
|
|
16353
|
+
}
|
|
16354
|
+
|
|
16355
|
+
request_on_checkbox_change: {
|
|
16356
|
+
const isCheckbox =
|
|
16357
|
+
element.tagName === "INPUT" && element.type === "checkbox";
|
|
16358
|
+
if (!isCheckbox) {
|
|
16359
|
+
break request_on_checkbox_change;
|
|
16360
|
+
}
|
|
16361
|
+
const onchange = (e) => {
|
|
16362
|
+
if (element.parentNode.hasAttribute("data-action")) {
|
|
16363
|
+
dispatchActionRequestedCustomEvent(element, {
|
|
16364
|
+
event: e,
|
|
16365
|
+
requester: element,
|
|
16366
|
+
});
|
|
16367
|
+
return;
|
|
16368
|
+
}
|
|
16369
|
+
};
|
|
16370
|
+
element.addEventListener("change", onchange);
|
|
16371
|
+
addTeardown(() => {
|
|
16372
|
+
element.removeEventListener("change", onchange);
|
|
16373
|
+
});
|
|
16374
|
+
}
|
|
16375
|
+
|
|
16376
|
+
execute_on_form_submit: {
|
|
16377
|
+
if (!isForm) {
|
|
16378
|
+
break execute_on_form_submit;
|
|
16379
|
+
}
|
|
16380
|
+
// We will dispatch "action" when "submit" occurs (code called from.submit() to bypass validation)
|
|
16381
|
+
const form = element;
|
|
16382
|
+
const removeListener = addEventListener(form, "submit", (e) => {
|
|
16383
|
+
e.preventDefault();
|
|
16384
|
+
const actionCustomEvent = new CustomEvent("action", {
|
|
16385
|
+
detail: {
|
|
16386
|
+
action: null,
|
|
16387
|
+
event: e,
|
|
16388
|
+
method: "rerun",
|
|
16389
|
+
requester: form,
|
|
16390
|
+
meta: {
|
|
16391
|
+
isSubmit: true,
|
|
16392
|
+
},
|
|
16393
|
+
},
|
|
16394
|
+
});
|
|
16395
|
+
form.dispatchEvent(actionCustomEvent);
|
|
16396
|
+
});
|
|
16397
|
+
addTeardown(() => {
|
|
16398
|
+
removeListener();
|
|
16399
|
+
});
|
|
16400
|
+
}
|
|
16401
|
+
|
|
16402
|
+
{
|
|
16403
|
+
const onkeydown = (e) => {
|
|
16404
|
+
if (e.key === "Escape") {
|
|
16405
|
+
if (!closeElementValidationMessage("escape_key")) {
|
|
16406
|
+
dispatchCancelCustomEvent({ detail: { reason: "escape_key" } });
|
|
16407
|
+
}
|
|
16408
|
+
}
|
|
16409
|
+
};
|
|
16410
|
+
element.addEventListener("keydown", onkeydown);
|
|
16411
|
+
addTeardown(() => {
|
|
16412
|
+
element.removeEventListener("keydown", onkeydown);
|
|
16413
|
+
});
|
|
16414
|
+
}
|
|
16415
|
+
|
|
16416
|
+
{
|
|
16417
|
+
const onblur = () => {
|
|
16418
|
+
if (element.value === "") {
|
|
16419
|
+
dispatchCancelCustomEvent({
|
|
16420
|
+
detail: {
|
|
16421
|
+
reason: "blur_empty",
|
|
16422
|
+
},
|
|
16423
|
+
});
|
|
16424
|
+
return;
|
|
16425
|
+
}
|
|
16426
|
+
// if we have failed constraint, we cancel too
|
|
16427
|
+
if (failedConstraintInfo) {
|
|
16428
|
+
dispatchCancelCustomEvent({
|
|
16429
|
+
detail: {
|
|
16430
|
+
reason: "blur_invalid",
|
|
16431
|
+
failedConstraintInfo,
|
|
16432
|
+
},
|
|
16433
|
+
});
|
|
16434
|
+
return;
|
|
16435
|
+
}
|
|
16436
|
+
};
|
|
16437
|
+
element.addEventListener("blur", onblur);
|
|
16438
|
+
addTeardown(() => {
|
|
16439
|
+
element.removeEventListener("blur", onblur);
|
|
16440
|
+
});
|
|
16441
|
+
}
|
|
16442
|
+
|
|
16443
|
+
return validationInterface;
|
|
16444
|
+
};
|
|
16445
|
+
|
|
16446
|
+
// When interacting with an element we want to find the closest element
|
|
16447
|
+
// eventually handling the action
|
|
16448
|
+
// 1. <button> itself has an action
|
|
16449
|
+
// 2. <button> is inside a <form> with an action
|
|
16450
|
+
// 3. <button> is inside a wrapper <div> with an action (data-action is not necessarly on the interactive element itself, it can be on a wrapper, we want to support that)
|
|
16451
|
+
// 4. <button> is inside a <fieldset> or any element that catches the action like a <form> would
|
|
16452
|
+
// In examples above <button> can also be <input> etc..
|
|
16453
|
+
const closestElementWithAction = (el) => {
|
|
16454
|
+
if (el.hasAttribute("data-action")) {
|
|
16455
|
+
return el;
|
|
16456
|
+
}
|
|
16457
|
+
const closestDataActionElement = el.closest("[data-action]");
|
|
16458
|
+
if (!closestDataActionElement) {
|
|
16459
|
+
return null;
|
|
16460
|
+
}
|
|
16461
|
+
const visualSelector = closestDataActionElement.getAttribute(
|
|
16462
|
+
"data-visual-selector",
|
|
16463
|
+
);
|
|
16464
|
+
if (!visualSelector) {
|
|
16465
|
+
return closestDataActionElement;
|
|
16466
|
+
}
|
|
16467
|
+
const visualElement = closestDataActionElement.querySelector(visualSelector);
|
|
16468
|
+
return visualElement;
|
|
16469
|
+
};
|
|
16470
|
+
|
|
16471
|
+
const pickConstraint = (a, b) => {
|
|
16472
|
+
const aPrio = getConstraintPriority(a);
|
|
16473
|
+
const bPrio = getConstraintPriority(b);
|
|
16474
|
+
if (aPrio > bPrio) {
|
|
16475
|
+
return a;
|
|
16476
|
+
}
|
|
16477
|
+
return b;
|
|
16478
|
+
};
|
|
16479
|
+
const getConstraintPriority = (constraint) => {
|
|
16480
|
+
if (constraint.name === "required") {
|
|
16481
|
+
return 100;
|
|
16482
|
+
}
|
|
16483
|
+
if (STANDARD_CONSTRAINT_SET.has(constraint)) {
|
|
16484
|
+
return 10;
|
|
16485
|
+
}
|
|
16486
|
+
return 1;
|
|
16487
|
+
};
|
|
16488
|
+
|
|
16489
|
+
const getFirstButtonSubmittingForm = (form) => {
|
|
16490
|
+
return form.querySelector(
|
|
16491
|
+
`button[type="submit"], input[type="submit"], input[type="image"]`,
|
|
16492
|
+
);
|
|
16493
|
+
};
|
|
16494
|
+
|
|
16495
|
+
const dispatchActionRequestedCustomEvent = (
|
|
16496
|
+
elementWithAction,
|
|
16497
|
+
{ actionOrigin = "action_prop", event, requester },
|
|
16498
|
+
) => {
|
|
16499
|
+
const actionRequestedCustomEvent = new CustomEvent("actionrequested", {
|
|
16500
|
+
cancelable: true,
|
|
16501
|
+
detail: {
|
|
16502
|
+
actionOrigin,
|
|
16503
|
+
event,
|
|
16504
|
+
requester,
|
|
16505
|
+
},
|
|
16506
|
+
});
|
|
16507
|
+
elementWithAction.dispatchEvent(actionRequestedCustomEvent);
|
|
16508
|
+
};
|
|
16509
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Constraint_validation
|
|
16510
|
+
const requestSubmit = HTMLFormElement.prototype.requestSubmit;
|
|
16511
|
+
HTMLFormElement.prototype.requestSubmit = function (submitter) {
|
|
16512
|
+
const form = this;
|
|
16513
|
+
const isInstrumented = formInstrumentedWeakSet.has(form);
|
|
16514
|
+
if (!isInstrumented) {
|
|
16515
|
+
requestSubmit.call(form, submitter);
|
|
16516
|
+
return;
|
|
16517
|
+
}
|
|
16518
|
+
const programmaticEvent = new CustomEvent("programmatic_requestsubmit", {
|
|
16519
|
+
cancelable: true,
|
|
16520
|
+
detail: {
|
|
16521
|
+
submitter,
|
|
16522
|
+
},
|
|
16523
|
+
});
|
|
16524
|
+
dispatchActionRequestedCustomEvent(form, {
|
|
16525
|
+
event: programmaticEvent,
|
|
16526
|
+
requester: submitter,
|
|
16527
|
+
});
|
|
16528
|
+
|
|
16529
|
+
// When all fields are valid calling the native requestSubmit would let browser go through the
|
|
16530
|
+
// standard form validation steps leading to form submission.
|
|
16531
|
+
// We don't want that because we have our own action system to handle forms
|
|
16532
|
+
// If we did that the form submission would happen in parallel of our action system
|
|
16533
|
+
// and because we listen to "submit" event to dispatch "action" event
|
|
16534
|
+
// we would end up with two actions being executed.
|
|
16535
|
+
//
|
|
16536
|
+
// In case we have discrepencies in our implementation compared to the browser standard
|
|
16537
|
+
// this also prevent the native validation message to show up.
|
|
16538
|
+
|
|
16539
|
+
// requestSubmit.call(this, submitter);
|
|
16540
|
+
};
|
|
16541
|
+
|
|
16542
|
+
// const submit = HTMLFormElement.prototype.submit;
|
|
16543
|
+
// HTMLFormElement.prototype.submit = function (...args) {
|
|
16544
|
+
// const form = this;
|
|
16545
|
+
// if (form.hasAttribute("data-method")) {
|
|
16546
|
+
// console.warn("You must use form.requestSubmit() instead of form.submit()");
|
|
16547
|
+
// return form.requestSubmit();
|
|
16548
|
+
// }
|
|
16549
|
+
// return submit.apply(this, args);
|
|
16550
|
+
// };
|
|
16551
|
+
|
|
16552
|
+
const addEventListener = (element, event, callback) => {
|
|
16553
|
+
element.addEventListener(event, callback);
|
|
16554
|
+
return () => {
|
|
16555
|
+
element.removeEventListener(event, callback);
|
|
16556
|
+
};
|
|
16557
|
+
};
|
|
16558
|
+
|
|
16559
|
+
const useCustomValidationRef = (elementRef, targetSelector) => {
|
|
16560
|
+
const customValidationRef = useRef();
|
|
16561
|
+
|
|
16562
|
+
useLayoutEffect(() => {
|
|
16563
|
+
const element = elementRef.current;
|
|
16564
|
+
if (!element) {
|
|
16565
|
+
console.warn(
|
|
16566
|
+
"useCustomValidationRef: elementRef.current is null, make sure to pass a ref to an element",
|
|
16567
|
+
);
|
|
16568
|
+
/* can happen if the component does this for instance:
|
|
16569
|
+
const Component = () => {
|
|
16570
|
+
const ref = useRef(null)
|
|
16571
|
+
|
|
16572
|
+
if (something) {
|
|
16573
|
+
return <input ref={ref} />
|
|
16574
|
+
}
|
|
16575
|
+
return <span></span>
|
|
16871
16576
|
}
|
|
16872
|
-
dispatchActionRequestedCustomEvent(elementWithAction, {
|
|
16873
|
-
event: clickEvent,
|
|
16874
|
-
requester: formSubmitTarget || button,
|
|
16875
|
-
});
|
|
16876
|
-
};
|
|
16877
|
-
element.addEventListener("click", onclick);
|
|
16878
|
-
addTeardown(() => {
|
|
16879
|
-
element.removeEventListener("click", onclick);
|
|
16880
|
-
});
|
|
16881
|
-
}
|
|
16882
16577
|
|
|
16883
|
-
|
|
16884
|
-
|
|
16885
|
-
|
|
16886
|
-
if (!isInput) {
|
|
16887
|
-
break request_on_input_change;
|
|
16578
|
+
usually it's better to split the component in two but hey
|
|
16579
|
+
*/
|
|
16580
|
+
return null;
|
|
16888
16581
|
}
|
|
16889
|
-
|
|
16890
|
-
|
|
16891
|
-
|
|
16892
|
-
|
|
16582
|
+
let target;
|
|
16583
|
+
if (targetSelector) {
|
|
16584
|
+
target = element.querySelector(targetSelector);
|
|
16585
|
+
if (!target) {
|
|
16586
|
+
console.warn(
|
|
16587
|
+
`useCustomValidationRef: targetSelector "${targetSelector}" did not match in element`,
|
|
16588
|
+
);
|
|
16589
|
+
return null;
|
|
16893
16590
|
}
|
|
16894
|
-
|
|
16895
|
-
|
|
16896
|
-
|
|
16897
|
-
|
|
16898
|
-
|
|
16899
|
-
|
|
16900
|
-
|
|
16901
|
-
|
|
16591
|
+
} else {
|
|
16592
|
+
target = element;
|
|
16593
|
+
}
|
|
16594
|
+
const unsubscribe = subscribe(element, target);
|
|
16595
|
+
const validationInterface = element.__validationInterface__;
|
|
16596
|
+
customValidationRef.current = validationInterface;
|
|
16597
|
+
return () => {
|
|
16598
|
+
unsubscribe();
|
|
16599
|
+
};
|
|
16600
|
+
}, [targetSelector]);
|
|
16601
|
+
|
|
16602
|
+
return customValidationRef;
|
|
16603
|
+
};
|
|
16604
|
+
|
|
16605
|
+
const subscribeCountWeakMap = new WeakMap();
|
|
16606
|
+
const subscribe = (element, target) => {
|
|
16607
|
+
if (element.__validationInterface__) {
|
|
16608
|
+
let subscribeCount = subscribeCountWeakMap.get(element);
|
|
16609
|
+
subscribeCountWeakMap.set(element, subscribeCount + 1);
|
|
16610
|
+
} else {
|
|
16611
|
+
installCustomConstraintValidation(element, target);
|
|
16612
|
+
subscribeCountWeakMap.set(element, 1);
|
|
16902
16613
|
}
|
|
16614
|
+
return () => {
|
|
16615
|
+
unsubscribe(element);
|
|
16616
|
+
};
|
|
16617
|
+
};
|
|
16903
16618
|
|
|
16904
|
-
|
|
16905
|
-
|
|
16906
|
-
|
|
16907
|
-
|
|
16908
|
-
|
|
16619
|
+
const unsubscribe = (element) => {
|
|
16620
|
+
const subscribeCount = subscribeCountWeakMap.get(element);
|
|
16621
|
+
if (subscribeCount === 1) {
|
|
16622
|
+
element.__validationInterface__.uninstall();
|
|
16623
|
+
subscribeCountWeakMap.delete(element);
|
|
16624
|
+
} else {
|
|
16625
|
+
subscribeCountWeakMap.set(element, subscribeCount - 1);
|
|
16626
|
+
}
|
|
16627
|
+
};
|
|
16628
|
+
|
|
16629
|
+
const NO_CONSTRAINTS = [];
|
|
16630
|
+
const useConstraints = (elementRef, props, { targetSelector } = {}) => {
|
|
16631
|
+
const {
|
|
16632
|
+
constraints = NO_CONSTRAINTS,
|
|
16633
|
+
disabledMessage,
|
|
16634
|
+
requiredMessage,
|
|
16635
|
+
patternMessage,
|
|
16636
|
+
minLengthMessage,
|
|
16637
|
+
maxLengthMessage,
|
|
16638
|
+
typeMessage,
|
|
16639
|
+
minMessage,
|
|
16640
|
+
maxMessage,
|
|
16641
|
+
singleSpaceMessage,
|
|
16642
|
+
sameAsMessage,
|
|
16643
|
+
minDigitMessage,
|
|
16644
|
+
minLowerLetterMessage,
|
|
16645
|
+
minUpperLetterMessage,
|
|
16646
|
+
minSpecialCharMessage,
|
|
16647
|
+
availableMessage,
|
|
16648
|
+
...remainingProps
|
|
16649
|
+
} = props;
|
|
16650
|
+
|
|
16651
|
+
const customValidationRef = useCustomValidationRef(
|
|
16652
|
+
elementRef,
|
|
16653
|
+
targetSelector,
|
|
16654
|
+
);
|
|
16655
|
+
useLayoutEffect(() => {
|
|
16656
|
+
const customValidation = customValidationRef.current;
|
|
16657
|
+
const cleanupCallbackSet = new Set();
|
|
16658
|
+
for (const constraint of constraints) {
|
|
16659
|
+
const unregister = customValidation.registerConstraint(constraint);
|
|
16660
|
+
cleanupCallbackSet.add(unregister);
|
|
16909
16661
|
}
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
|
|
16913
|
-
event: e,
|
|
16914
|
-
requester: element,
|
|
16915
|
-
});
|
|
16916
|
-
return;
|
|
16662
|
+
return () => {
|
|
16663
|
+
for (const cleanupCallback of cleanupCallbackSet) {
|
|
16664
|
+
cleanupCallback();
|
|
16917
16665
|
}
|
|
16918
16666
|
};
|
|
16919
|
-
|
|
16920
|
-
addTeardown(() => {
|
|
16921
|
-
element.removeEventListener("change", onchange);
|
|
16922
|
-
});
|
|
16923
|
-
}
|
|
16667
|
+
}, constraints);
|
|
16924
16668
|
|
|
16925
|
-
|
|
16926
|
-
|
|
16927
|
-
|
|
16669
|
+
useLayoutEffect(() => {
|
|
16670
|
+
const el = elementRef.current;
|
|
16671
|
+
if (!el) {
|
|
16672
|
+
return null;
|
|
16928
16673
|
}
|
|
16929
|
-
|
|
16930
|
-
const
|
|
16931
|
-
|
|
16932
|
-
|
|
16933
|
-
|
|
16934
|
-
|
|
16935
|
-
|
|
16936
|
-
|
|
16937
|
-
|
|
16938
|
-
|
|
16939
|
-
|
|
16940
|
-
|
|
16941
|
-
},
|
|
16942
|
-
},
|
|
16674
|
+
const cleanupCallbackSet = new Set();
|
|
16675
|
+
const setupCustomEvent = (el, constraintName, Component) => {
|
|
16676
|
+
const attrName = `data-${constraintName}-message-event`;
|
|
16677
|
+
const customEventName = `${constraintName}_message_jsx`;
|
|
16678
|
+
el.setAttribute(attrName, customEventName);
|
|
16679
|
+
const onCustomEvent = (e) => {
|
|
16680
|
+
e.detail.render(Component);
|
|
16681
|
+
};
|
|
16682
|
+
el.addEventListener(customEventName, onCustomEvent);
|
|
16683
|
+
cleanupCallbackSet.add(() => {
|
|
16684
|
+
el.removeEventListener(customEventName, onCustomEvent);
|
|
16685
|
+
el.removeAttribute(attrName);
|
|
16943
16686
|
});
|
|
16944
|
-
form.dispatchEvent(actionCustomEvent);
|
|
16945
|
-
});
|
|
16946
|
-
addTeardown(() => {
|
|
16947
|
-
removeListener();
|
|
16948
|
-
});
|
|
16949
|
-
}
|
|
16950
|
-
|
|
16951
|
-
{
|
|
16952
|
-
const onkeydown = (e) => {
|
|
16953
|
-
if (e.key === "Escape") {
|
|
16954
|
-
if (!closeElementValidationMessage("escape_key")) {
|
|
16955
|
-
dispatchCancelCustomEvent({ detail: { reason: "escape_key" } });
|
|
16956
|
-
}
|
|
16957
|
-
}
|
|
16958
16687
|
};
|
|
16959
|
-
element.addEventListener("keydown", onkeydown);
|
|
16960
|
-
addTeardown(() => {
|
|
16961
|
-
element.removeEventListener("keydown", onkeydown);
|
|
16962
|
-
});
|
|
16963
|
-
}
|
|
16964
16688
|
|
|
16965
|
-
|
|
16966
|
-
|
|
16967
|
-
|
|
16968
|
-
|
|
16969
|
-
|
|
16970
|
-
|
|
16971
|
-
|
|
16972
|
-
|
|
16973
|
-
|
|
16974
|
-
|
|
16975
|
-
|
|
16976
|
-
|
|
16977
|
-
|
|
16978
|
-
|
|
16979
|
-
|
|
16980
|
-
|
|
16981
|
-
|
|
16982
|
-
|
|
16983
|
-
|
|
16689
|
+
if (disabledMessage) {
|
|
16690
|
+
setupCustomEvent(el, "disabled", disabledMessage);
|
|
16691
|
+
}
|
|
16692
|
+
if (requiredMessage) {
|
|
16693
|
+
setupCustomEvent(el, "required", requiredMessage);
|
|
16694
|
+
}
|
|
16695
|
+
if (patternMessage) {
|
|
16696
|
+
setupCustomEvent(el, "pattern", patternMessage);
|
|
16697
|
+
}
|
|
16698
|
+
if (minLengthMessage) {
|
|
16699
|
+
setupCustomEvent(el, "min-length", minLengthMessage);
|
|
16700
|
+
}
|
|
16701
|
+
if (maxLengthMessage) {
|
|
16702
|
+
setupCustomEvent(el, "max-length", maxLengthMessage);
|
|
16703
|
+
}
|
|
16704
|
+
if (typeMessage) {
|
|
16705
|
+
setupCustomEvent(el, "type", typeMessage);
|
|
16706
|
+
}
|
|
16707
|
+
if (minMessage) {
|
|
16708
|
+
setupCustomEvent(el, "min", minMessage);
|
|
16709
|
+
}
|
|
16710
|
+
if (maxMessage) {
|
|
16711
|
+
setupCustomEvent(el, "max", maxMessage);
|
|
16712
|
+
}
|
|
16713
|
+
if (singleSpaceMessage) {
|
|
16714
|
+
setupCustomEvent(el, "single-space", singleSpaceMessage);
|
|
16715
|
+
}
|
|
16716
|
+
if (sameAsMessage) {
|
|
16717
|
+
setupCustomEvent(el, "same-as", sameAsMessage);
|
|
16718
|
+
}
|
|
16719
|
+
if (minDigitMessage) {
|
|
16720
|
+
setupCustomEvent(el, "min-digit", minDigitMessage);
|
|
16721
|
+
}
|
|
16722
|
+
if (minLowerLetterMessage) {
|
|
16723
|
+
setupCustomEvent(el, "min-lower-letter", minLowerLetterMessage);
|
|
16724
|
+
}
|
|
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();
|
|
16984
16737
|
}
|
|
16985
16738
|
};
|
|
16986
|
-
|
|
16987
|
-
|
|
16988
|
-
|
|
16989
|
-
|
|
16990
|
-
|
|
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
|
+
]);
|
|
16991
16756
|
|
|
16992
|
-
return
|
|
16757
|
+
return remainingProps;
|
|
16993
16758
|
};
|
|
16994
16759
|
|
|
16995
|
-
|
|
16996
|
-
|
|
16997
|
-
|
|
16998
|
-
|
|
16999
|
-
|
|
17000
|
-
|
|
17001
|
-
// In examples above <button> can also be <input> etc..
|
|
17002
|
-
const closestElementWithAction = (el) => {
|
|
17003
|
-
if (el.hasAttribute("data-action")) {
|
|
17004
|
-
return el;
|
|
17005
|
-
}
|
|
17006
|
-
const closestDataActionElement = el.closest("[data-action]");
|
|
17007
|
-
if (!closestDataActionElement) {
|
|
17008
|
-
return null;
|
|
17009
|
-
}
|
|
17010
|
-
const visualSelector = closestDataActionElement.getAttribute(
|
|
17011
|
-
"data-visual-selector",
|
|
17012
|
-
);
|
|
17013
|
-
if (!visualSelector) {
|
|
17014
|
-
return closestDataActionElement;
|
|
16760
|
+
const useInitialTextSelection = (ref, textSelection) => {
|
|
16761
|
+
const deps = [];
|
|
16762
|
+
if (Array.isArray(textSelection)) {
|
|
16763
|
+
deps.push(...textSelection);
|
|
16764
|
+
} else {
|
|
16765
|
+
deps.push(textSelection);
|
|
17015
16766
|
}
|
|
17016
|
-
|
|
17017
|
-
|
|
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);
|
|
17018
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;
|
|
17019
16803
|
|
|
17020
|
-
|
|
17021
|
-
|
|
17022
|
-
|
|
17023
|
-
|
|
17024
|
-
|
|
17025
|
-
|
|
17026
|
-
|
|
17027
|
-
|
|
17028
|
-
|
|
17029
|
-
|
|
17030
|
-
|
|
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;
|
|
17031
16817
|
}
|
|
17032
|
-
if (
|
|
17033
|
-
|
|
16818
|
+
if (startNode && endNode) {
|
|
16819
|
+
range.setStart(startNode, startOffset);
|
|
16820
|
+
range.setEnd(endNode, endOffset);
|
|
17034
16821
|
}
|
|
17035
|
-
return 1;
|
|
17036
|
-
};
|
|
17037
|
-
|
|
17038
|
-
const getFirstButtonSubmittingForm = (form) => {
|
|
17039
|
-
return form.querySelector(
|
|
17040
|
-
`button[type="submit"], input[type="submit"], input[type="image"]`,
|
|
17041
|
-
);
|
|
17042
16822
|
};
|
|
17043
|
-
|
|
17044
|
-
const
|
|
17045
|
-
|
|
17046
|
-
|
|
17047
|
-
|
|
17048
|
-
|
|
17049
|
-
|
|
17050
|
-
|
|
17051
|
-
|
|
17052
|
-
|
|
17053
|
-
requester,
|
|
17054
|
-
},
|
|
17055
|
-
});
|
|
17056
|
-
elementWithAction.dispatchEvent(actionRequestedCustomEvent);
|
|
17057
|
-
};
|
|
17058
|
-
// https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Constraint_validation
|
|
17059
|
-
const requestSubmit = HTMLFormElement.prototype.requestSubmit;
|
|
17060
|
-
HTMLFormElement.prototype.requestSubmit = function (submitter) {
|
|
17061
|
-
const form = this;
|
|
17062
|
-
const isInstrumented = formInstrumentedWeakSet.has(form);
|
|
17063
|
-
if (!isInstrumented) {
|
|
17064
|
-
requestSubmit.call(form, submitter);
|
|
17065
|
-
return;
|
|
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
|
+
}
|
|
17066
16833
|
}
|
|
17067
|
-
const programmaticEvent = new CustomEvent("programmatic_requestsubmit", {
|
|
17068
|
-
cancelable: true,
|
|
17069
|
-
detail: {
|
|
17070
|
-
submitter,
|
|
17071
|
-
},
|
|
17072
|
-
});
|
|
17073
|
-
dispatchActionRequestedCustomEvent(form, {
|
|
17074
|
-
event: programmaticEvent,
|
|
17075
|
-
requester: submitter,
|
|
17076
|
-
});
|
|
17077
|
-
|
|
17078
|
-
// When all fields are valid calling the native requestSubmit would let browser go through the
|
|
17079
|
-
// standard form validation steps leading to form submission.
|
|
17080
|
-
// We don't want that because we have our own action system to handle forms
|
|
17081
|
-
// If we did that the form submission would happen in parallel of our action system
|
|
17082
|
-
// and because we listen to "submit" event to dispatch "action" event
|
|
17083
|
-
// we would end up with two actions being executed.
|
|
17084
|
-
//
|
|
17085
|
-
// In case we have discrepencies in our implementation compared to the browser standard
|
|
17086
|
-
// this also prevent the native validation message to show up.
|
|
17087
|
-
|
|
17088
|
-
// requestSubmit.call(this, submitter);
|
|
17089
16834
|
};
|
|
17090
|
-
|
|
17091
|
-
|
|
17092
|
-
|
|
17093
|
-
|
|
17094
|
-
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
|
|
17102
|
-
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
}
|
|
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
|
+
}
|
|
17106
16857
|
};
|
|
17107
16858
|
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
|
|
17111
|
-
|
|
17112
|
-
|
|
17113
|
-
|
|
17114
|
-
|
|
17115
|
-
|
|
17116
|
-
|
|
17117
|
-
|
|
17118
|
-
|
|
17119
|
-
const ref = useRef(null)
|
|
17120
|
-
|
|
17121
|
-
if (something) {
|
|
17122
|
-
return <input ref={ref} />
|
|
17123
|
-
}
|
|
17124
|
-
return <span></span>
|
|
17125
|
-
}
|
|
17126
|
-
|
|
17127
|
-
usually it's better to split the component in two but hey
|
|
17128
|
-
*/
|
|
17129
|
-
return null;
|
|
17130
|
-
}
|
|
17131
|
-
let target;
|
|
17132
|
-
if (targetSelector) {
|
|
17133
|
-
target = element.querySelector(targetSelector);
|
|
17134
|
-
if (!target) {
|
|
17135
|
-
console.warn(
|
|
17136
|
-
`useCustomValidationRef: targetSelector "${targetSelector}" did not match in element`,
|
|
17137
|
-
);
|
|
17138
|
-
return null;
|
|
17139
|
-
}
|
|
17140
|
-
} else {
|
|
17141
|
-
target = element;
|
|
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;
|
|
17142
16870
|
}
|
|
17143
|
-
|
|
17144
|
-
const validationInterface = element.__validationInterface__;
|
|
17145
|
-
customValidationRef.current = validationInterface;
|
|
17146
|
-
return () => {
|
|
17147
|
-
unsubscribe();
|
|
17148
|
-
};
|
|
17149
|
-
}, [targetSelector]);
|
|
16871
|
+
}
|
|
17150
16872
|
|
|
17151
|
-
|
|
17152
|
-
|
|
16873
|
+
.navi_text_overflow {
|
|
16874
|
+
flex-wrap: wrap;
|
|
16875
|
+
text-overflow: ellipsis;
|
|
16876
|
+
overflow: hidden;
|
|
16877
|
+
}
|
|
17153
16878
|
|
|
17154
|
-
|
|
17155
|
-
|
|
17156
|
-
|
|
17157
|
-
|
|
17158
|
-
|
|
17159
|
-
} else {
|
|
17160
|
-
installCustomConstraintValidation(element, target);
|
|
17161
|
-
subscribeCountWeakMap.set(element, 1);
|
|
16879
|
+
.navi_text_overflow_wrapper {
|
|
16880
|
+
display: flex;
|
|
16881
|
+
width: 0;
|
|
16882
|
+
flex-grow: 1;
|
|
16883
|
+
gap: 0.3em;
|
|
17162
16884
|
}
|
|
17163
|
-
return () => {
|
|
17164
|
-
unsubscribe(element);
|
|
17165
|
-
};
|
|
17166
|
-
};
|
|
17167
16885
|
|
|
17168
|
-
|
|
17169
|
-
|
|
17170
|
-
|
|
17171
|
-
|
|
17172
|
-
subscribeCountWeakMap.delete(element);
|
|
17173
|
-
} else {
|
|
17174
|
-
subscribeCountWeakMap.set(element, subscribeCount - 1);
|
|
16886
|
+
.navi_text_overflow_text {
|
|
16887
|
+
max-width: 100%;
|
|
16888
|
+
text-overflow: ellipsis;
|
|
16889
|
+
overflow: hidden;
|
|
17175
16890
|
}
|
|
17176
|
-
};
|
|
17177
16891
|
|
|
17178
|
-
|
|
17179
|
-
|
|
17180
|
-
const {
|
|
17181
|
-
constraints = NO_CONSTRAINTS,
|
|
17182
|
-
disabledMessage,
|
|
17183
|
-
requiredMessage,
|
|
17184
|
-
patternMessage,
|
|
17185
|
-
minLengthMessage,
|
|
17186
|
-
maxLengthMessage,
|
|
17187
|
-
typeMessage,
|
|
17188
|
-
minMessage,
|
|
17189
|
-
maxMessage,
|
|
17190
|
-
singleSpaceMessage,
|
|
17191
|
-
sameAsMessage,
|
|
17192
|
-
minDigitMessage,
|
|
17193
|
-
minLowerLetterMessage,
|
|
17194
|
-
minUpperLetterMessage,
|
|
17195
|
-
minSpecialCharMessage,
|
|
17196
|
-
availableMessage,
|
|
17197
|
-
...remainingProps
|
|
17198
|
-
} = props;
|
|
16892
|
+
.navi_custom_space {
|
|
16893
|
+
}
|
|
17199
16894
|
|
|
17200
|
-
|
|
17201
|
-
|
|
17202
|
-
|
|
17203
|
-
|
|
17204
|
-
|
|
17205
|
-
|
|
17206
|
-
|
|
17207
|
-
|
|
17208
|
-
|
|
17209
|
-
|
|
17210
|
-
|
|
17211
|
-
|
|
17212
|
-
for (const cleanupCallback of cleanupCallbackSet) {
|
|
17213
|
-
cleanupCallback();
|
|
17214
|
-
}
|
|
17215
|
-
};
|
|
17216
|
-
}, constraints);
|
|
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
|
+
}
|
|
17217
16907
|
|
|
17218
|
-
|
|
17219
|
-
|
|
17220
|
-
|
|
17221
|
-
|
|
17222
|
-
|
|
17223
|
-
|
|
17224
|
-
|
|
17225
|
-
|
|
17226
|
-
|
|
17227
|
-
|
|
17228
|
-
|
|
17229
|
-
|
|
17230
|
-
|
|
17231
|
-
el.addEventListener(customEventName, onCustomEvent);
|
|
17232
|
-
cleanupCallbackSet.add(() => {
|
|
17233
|
-
el.removeEventListener(customEventName, onCustomEvent);
|
|
17234
|
-
el.removeAttribute(attrName);
|
|
17235
|
-
});
|
|
17236
|
-
};
|
|
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
|
+
}
|
|
17237
16921
|
|
|
17238
|
-
|
|
17239
|
-
|
|
17240
|
-
|
|
17241
|
-
if (requiredMessage) {
|
|
17242
|
-
setupCustomEvent(el, "required", requiredMessage);
|
|
17243
|
-
}
|
|
17244
|
-
if (patternMessage) {
|
|
17245
|
-
setupCustomEvent(el, "pattern", patternMessage);
|
|
17246
|
-
}
|
|
17247
|
-
if (minLengthMessage) {
|
|
17248
|
-
setupCustomEvent(el, "min-length", minLengthMessage);
|
|
17249
|
-
}
|
|
17250
|
-
if (maxLengthMessage) {
|
|
17251
|
-
setupCustomEvent(el, "max-length", maxLengthMessage);
|
|
17252
|
-
}
|
|
17253
|
-
if (typeMessage) {
|
|
17254
|
-
setupCustomEvent(el, "type", typeMessage);
|
|
17255
|
-
}
|
|
17256
|
-
if (minMessage) {
|
|
17257
|
-
setupCustomEvent(el, "min", minMessage);
|
|
17258
|
-
}
|
|
17259
|
-
if (maxMessage) {
|
|
17260
|
-
setupCustomEvent(el, "max", maxMessage);
|
|
17261
|
-
}
|
|
17262
|
-
if (singleSpaceMessage) {
|
|
17263
|
-
setupCustomEvent(el, "single-space", singleSpaceMessage);
|
|
16922
|
+
.navi_text[data-bold] {
|
|
16923
|
+
.navi_text_bold_background {
|
|
16924
|
+
opacity: 1;
|
|
17264
16925
|
}
|
|
17265
|
-
|
|
17266
|
-
|
|
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;
|
|
17267
16933
|
}
|
|
17268
|
-
|
|
17269
|
-
|
|
16934
|
+
|
|
16935
|
+
.navi_text_bold_background {
|
|
16936
|
+
transition-property: opacity;
|
|
16937
|
+
transition-duration: 0.3s;
|
|
16938
|
+
transition-timing-function: ease;
|
|
17270
16939
|
}
|
|
17271
|
-
|
|
17272
|
-
|
|
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;
|
|
17273
16981
|
}
|
|
17274
|
-
|
|
17275
|
-
|
|
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
|
-
const el = ref.current;
|
|
17318
|
-
if (!el || !textSelection) {
|
|
17319
|
-
return;
|
|
17320
|
-
}
|
|
17321
|
-
const range = document.createRange();
|
|
17322
|
-
const selection = window.getSelection();
|
|
17323
|
-
if (Array.isArray(textSelection)) {
|
|
17324
|
-
if (textSelection.length === 2) {
|
|
17325
|
-
const [start, end] = textSelection;
|
|
17326
|
-
if (typeof start === "number" && typeof end === "number") {
|
|
17327
|
-
// Format: [0, 10] - character indices
|
|
17328
|
-
selectByCharacterIndices(el, range, start, end);
|
|
17329
|
-
} else if (typeof start === "string" && typeof end === "string") {
|
|
17330
|
-
// Format: ["Click on the", "button to return"] - text strings
|
|
17331
|
-
selectByTextStrings(el, range, start, end);
|
|
17332
|
-
}
|
|
17333
|
-
}
|
|
17334
|
-
} else if (typeof textSelection === "string") {
|
|
17335
|
-
// Format: "some text" - select the entire string occurrence
|
|
17336
|
-
selectSingleTextString(el, range, textSelection);
|
|
17337
|
-
}
|
|
17338
|
-
selection.removeAllRanges();
|
|
17339
|
-
selection.addRange(range);
|
|
17340
|
-
}, deps);
|
|
17014
|
+
return false;
|
|
17341
17015
|
};
|
|
17342
|
-
const
|
|
17343
|
-
|
|
17344
|
-
|
|
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
|
-
|
|
17353
|
-
// Check if start position is in this text node
|
|
17354
|
-
if (!startNode && currentIndex + nodeLength > startIndex) {
|
|
17355
|
-
startNode = walker.currentNode;
|
|
17356
|
-
startOffset = startIndex - currentIndex;
|
|
17357
|
-
}
|
|
17358
|
-
|
|
17359
|
-
// Check if end position is in this text node
|
|
17360
|
-
if (currentIndex + nodeLength >= endIndex) {
|
|
17361
|
-
endNode = walker.currentNode;
|
|
17362
|
-
endOffset = endIndex - currentIndex;
|
|
17363
|
-
break;
|
|
17364
|
-
}
|
|
17365
|
-
currentIndex += nodeLength;
|
|
17016
|
+
const startsWithWhitespace = jsxChild => {
|
|
17017
|
+
if (typeof jsxChild === "string") {
|
|
17018
|
+
return /^\s/.test(jsxChild);
|
|
17366
17019
|
}
|
|
17367
|
-
|
|
17368
|
-
|
|
17369
|
-
|
|
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
|
+
});
|
|
17370
17042
|
}
|
|
17043
|
+
return jsx(TextBasic, {
|
|
17044
|
+
...props
|
|
17045
|
+
});
|
|
17371
17046
|
};
|
|
17372
|
-
const
|
|
17373
|
-
|
|
17374
|
-
|
|
17375
|
-
|
|
17376
|
-
|
|
17377
|
-
|
|
17378
|
-
|
|
17379
|
-
|
|
17380
|
-
|
|
17381
|
-
|
|
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;
|
|
17382
17092
|
}
|
|
17093
|
+
setOverflowPinnedElement(null);
|
|
17094
|
+
return text;
|
|
17383
17095
|
};
|
|
17384
|
-
const
|
|
17385
|
-
|
|
17386
|
-
|
|
17387
|
-
|
|
17388
|
-
|
|
17389
|
-
|
|
17390
|
-
|
|
17391
|
-
|
|
17392
|
-
|
|
17393
|
-
|
|
17394
|
-
|
|
17395
|
-
|
|
17396
|
-
|
|
17397
|
-
|
|
17398
|
-
|
|
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);
|
|
17399
17127
|
}
|
|
17400
|
-
if (
|
|
17401
|
-
const
|
|
17402
|
-
|
|
17403
|
-
|
|
17404
|
-
|
|
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
|
+
});
|
|
17405
17167
|
}
|
|
17168
|
+
return jsx(Box, {
|
|
17169
|
+
...boxProps,
|
|
17170
|
+
children: children
|
|
17171
|
+
});
|
|
17406
17172
|
};
|
|
17407
17173
|
|
|
17408
17174
|
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
17409
|
-
|
|
17410
|
-
|
|
17411
|
-
|
|
17412
|
-
|
|
17413
|
-
|
|
17414
|
-
position: relative;
|
|
17415
|
-
color: inherit;
|
|
17175
|
+
.navi_icon {
|
|
17176
|
+
display: inline-block;
|
|
17177
|
+
box-sizing: border-box;
|
|
17178
|
+
max-width: 100%;
|
|
17179
|
+
max-height: 100%;
|
|
17416
17180
|
|
|
17417
|
-
&[data-
|
|
17418
|
-
|
|
17181
|
+
&[data-flow-inline] {
|
|
17182
|
+
width: 1em;
|
|
17183
|
+
height: 1em;
|
|
17184
|
+
}
|
|
17185
|
+
&[data-icon-char] {
|
|
17186
|
+
flex-grow: 0 !important;
|
|
17187
|
+
line-height: normal;
|
|
17419
17188
|
}
|
|
17420
17189
|
}
|
|
17421
17190
|
|
|
17422
|
-
.
|
|
17423
|
-
|
|
17424
|
-
text-overflow: ellipsis;
|
|
17425
|
-
overflow: hidden;
|
|
17191
|
+
.navi_icon[data-interactive] {
|
|
17192
|
+
cursor: pointer;
|
|
17426
17193
|
}
|
|
17427
17194
|
|
|
17428
|
-
.
|
|
17429
|
-
|
|
17430
|
-
|
|
17431
|
-
|
|
17432
|
-
gap: 0.3em;
|
|
17195
|
+
.navi_icon_char_slot {
|
|
17196
|
+
opacity: 0;
|
|
17197
|
+
cursor: default;
|
|
17198
|
+
user-select: none;
|
|
17433
17199
|
}
|
|
17434
|
-
|
|
17435
|
-
|
|
17436
|
-
|
|
17437
|
-
text-overflow: ellipsis;
|
|
17438
|
-
overflow: hidden;
|
|
17200
|
+
.navi_icon_foreground {
|
|
17201
|
+
position: absolute;
|
|
17202
|
+
inset: 0;
|
|
17439
17203
|
}
|
|
17440
|
-
|
|
17441
|
-
|
|
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;
|
|
17442
17212
|
}
|
|
17443
17213
|
|
|
17444
|
-
.
|
|
17445
|
-
|
|
17446
|
-
|
|
17214
|
+
.navi_icon > svg,
|
|
17215
|
+
.navi_icon > img {
|
|
17216
|
+
width: 100%;
|
|
17217
|
+
height: 100%;
|
|
17218
|
+
backface-visibility: hidden;
|
|
17447
17219
|
}
|
|
17448
|
-
.
|
|
17449
|
-
|
|
17450
|
-
|
|
17220
|
+
.navi_icon[data-has-width] > svg,
|
|
17221
|
+
.navi_icon[data-has-width] > img {
|
|
17222
|
+
width: 100%;
|
|
17223
|
+
height: auto;
|
|
17451
17224
|
}
|
|
17452
|
-
.
|
|
17453
|
-
|
|
17454
|
-
|
|
17225
|
+
.navi_icon[data-has-height] > svg,
|
|
17226
|
+
.navi_icon[data-has-height] > img {
|
|
17227
|
+
width: auto;
|
|
17228
|
+
height: 100%;
|
|
17455
17229
|
}
|
|
17456
|
-
|
|
17457
|
-
.
|
|
17458
|
-
|
|
17459
|
-
|
|
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;
|
|
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%;
|
|
17469
17234
|
}
|
|
17470
17235
|
|
|
17471
|
-
.
|
|
17472
|
-
|
|
17473
|
-
|
|
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;
|
|
17474
17276
|
}
|
|
17277
|
+
} else {
|
|
17278
|
+
box = true;
|
|
17279
|
+
}
|
|
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
|
+
});
|
|
17475
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
|
+
};
|
|
17476
17327
|
|
|
17477
|
-
|
|
17478
|
-
|
|
17479
|
-
|
|
17480
|
-
|
|
17481
|
-
|
|
17482
|
-
|
|
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
|
+
};
|
|
17483
17377
|
|
|
17484
|
-
|
|
17485
|
-
|
|
17486
|
-
|
|
17487
|
-
|
|
17488
|
-
|
|
17489
|
-
|
|
17490
|
-
|
|
17491
|
-
|
|
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"
|
|
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
|
+
})
|
|
17502
17386
|
});
|
|
17503
17387
|
};
|
|
17504
|
-
|
|
17505
|
-
|
|
17506
|
-
|
|
17507
|
-
|
|
17508
|
-
|
|
17509
|
-
|
|
17510
|
-
|
|
17511
|
-
|
|
17512
|
-
|
|
17513
|
-
|
|
17514
|
-
|
|
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
|
-
});
|
|
17388
|
+
|
|
17389
|
+
const useDebounceTrue = (value, delay = 300) => {
|
|
17390
|
+
const [debouncedTrue, setDebouncedTrue] = useState(false);
|
|
17391
|
+
const timerRef = useRef(null);
|
|
17392
|
+
|
|
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);
|
|
17528
17399
|
} else {
|
|
17529
|
-
|
|
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);
|
|
17530
17406
|
}
|
|
17531
|
-
|
|
17532
|
-
|
|
17533
|
-
|
|
17534
|
-
|
|
17535
|
-
|
|
17536
|
-
|
|
17407
|
+
|
|
17408
|
+
// Cleanup function
|
|
17409
|
+
return () => {
|
|
17410
|
+
if (timerRef.current) {
|
|
17411
|
+
clearTimeout(timerRef.current);
|
|
17412
|
+
}
|
|
17413
|
+
};
|
|
17414
|
+
}, [value, delay]);
|
|
17415
|
+
|
|
17416
|
+
return debouncedTrue;
|
|
17417
|
+
};
|
|
17418
|
+
|
|
17419
|
+
const useNetworkSpeed = () => {
|
|
17420
|
+
return networkSpeedSignal.value;
|
|
17421
|
+
};
|
|
17422
|
+
|
|
17423
|
+
const connection =
|
|
17424
|
+
window.navigator.connection ||
|
|
17425
|
+
window.navigator.mozConnection ||
|
|
17426
|
+
window.navigator.webkitConnection;
|
|
17427
|
+
|
|
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
17446
|
}
|
|
17557
|
-
return
|
|
17558
|
-
};
|
|
17559
|
-
const endsWithWhitespace = jsxChild => {
|
|
17560
|
-
if (typeof jsxChild === "string") {
|
|
17561
|
-
return /\s$/.test(jsxChild);
|
|
17562
|
-
}
|
|
17563
|
-
return false;
|
|
17447
|
+
return "3g";
|
|
17564
17448
|
};
|
|
17565
|
-
|
|
17566
|
-
|
|
17567
|
-
|
|
17568
|
-
}
|
|
17569
|
-
return false;
|
|
17449
|
+
|
|
17450
|
+
const updateNetworkSpeed = () => {
|
|
17451
|
+
networkSpeedSignal.value = getNetworkSpeed();
|
|
17570
17452
|
};
|
|
17571
|
-
|
|
17572
|
-
const
|
|
17573
|
-
|
|
17574
|
-
|
|
17575
|
-
|
|
17576
|
-
|
|
17577
|
-
|
|
17578
|
-
|
|
17579
|
-
|
|
17580
|
-
|
|
17581
|
-
|
|
17582
|
-
|
|
17583
|
-
return jsx(TextOverflowPinned, {
|
|
17584
|
-
...props
|
|
17585
|
-
});
|
|
17586
|
-
}
|
|
17587
|
-
if (props.selectRange) {
|
|
17588
|
-
return jsx(TextWithSelectRange, {
|
|
17589
|
-
...props
|
|
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);
|
|
17590
17465
|
});
|
|
17591
17466
|
}
|
|
17592
|
-
|
|
17593
|
-
|
|
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);
|
|
17594
17482
|
});
|
|
17595
|
-
|
|
17596
|
-
|
|
17597
|
-
|
|
17598
|
-
|
|
17599
|
-
|
|
17600
|
-
|
|
17601
|
-
|
|
17602
|
-
|
|
17603
|
-
|
|
17604
|
-
as: "div",
|
|
17605
|
-
nowWrap: noWrap,
|
|
17606
|
-
pre: !noWrap
|
|
17607
|
-
// For paragraph we prefer to keep lines and only hide unbreakable long sections
|
|
17608
|
-
,
|
|
17609
|
-
preLine: rest.as === "p",
|
|
17610
|
-
...rest,
|
|
17611
|
-
className: "navi_text_overflow",
|
|
17612
|
-
expandX: true,
|
|
17613
|
-
spacing: "pre",
|
|
17614
|
-
children: jsxs("span", {
|
|
17615
|
-
className: "navi_text_overflow_wrapper",
|
|
17616
|
-
children: [jsx(OverflowPinnedElementContext.Provider, {
|
|
17617
|
-
value: setOverflowPinnedElement,
|
|
17618
|
-
children: jsx(Text, {
|
|
17619
|
-
className: "navi_text_overflow_text",
|
|
17620
|
-
children: children
|
|
17621
|
-
})
|
|
17622
|
-
}), OverflowPinnedElement]
|
|
17623
|
-
})
|
|
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);
|
|
17624
17492
|
});
|
|
17493
|
+
|
|
17494
|
+
// Cleanup global
|
|
17495
|
+
return () => {
|
|
17496
|
+
cleanupFunctions.forEach((cleanup) => cleanup());
|
|
17497
|
+
};
|
|
17625
17498
|
};
|
|
17626
|
-
|
|
17627
|
-
|
|
17628
|
-
|
|
17629
|
-
|
|
17630
|
-
|
|
17631
|
-
|
|
17632
|
-
|
|
17633
|
-
|
|
17634
|
-
|
|
17635
|
-
console.warn("<Text overflowPinned> declared outside a <Text overflowEllipsis>");
|
|
17636
|
-
return text;
|
|
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
|
-
});
|
|
17739
|
+
}), container);
|
|
17839
17740
|
}
|
|
17840
|
-
|
|
17841
|
-
|
|
17842
|
-
|
|
17843
|
-
|
|
17844
|
-
|
|
17845
|
-
|
|
17846
|
-
|
|
17847
|
-
|
|
17848
|
-
|
|
17849
|
-
|
|
17850
|
-
|
|
17851
|
-
|
|
17852
|
-
|
|
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
|
|
17751
|
+
});
|
|
17752
|
+
};
|
|
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]
|
|
17786
|
+
});
|
|
17787
|
+
};
|
|
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;
|
|
17853
17909
|
}
|
|
17854
|
-
const
|
|
17855
|
-
|
|
17856
|
-
|
|
17857
|
-
|
|
17858
|
-
|
|
17859
|
-
|
|
17860
|
-
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
"data-interactive": onClick ? "" : undefined,
|
|
17864
|
-
onClick: onClick,
|
|
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, {
|
|
17865
17919
|
children: [jsx("span", {
|
|
17866
|
-
|
|
17867
|
-
|
|
17868
|
-
|
|
17869
|
-
|
|
17870
|
-
|
|
17871
|
-
|
|
17872
|
-
|
|
17873
|
-
|
|
17874
|
-
|
|
17875
|
-
|
|
17876
|
-
|
|
17877
|
-
|
|
17878
|
-
|
|
17879
|
-
|
|
17880
|
-
|
|
17881
|
-
|
|
17882
|
-
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",
|
|
17883
|
-
stroke: "currentColor",
|
|
17884
|
-
fill: "none",
|
|
17885
|
-
"stroke-width": "2",
|
|
17886
|
-
"stroke-linecap": "round",
|
|
17887
|
-
"stroke-linejoin": "round"
|
|
17888
|
-
})
|
|
17889
|
-
});
|
|
17890
|
-
};
|
|
17891
|
-
const LinkAnchorSvg = () => {
|
|
17892
|
-
return jsx("svg", {
|
|
17893
|
-
viewBox: "0 0 24 24",
|
|
17894
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
17895
|
-
children: jsxs("g", {
|
|
17896
|
-
children: [jsx("path", {
|
|
17897
|
-
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",
|
|
17898
|
-
fill: "currentColor"
|
|
17899
|
-
}), jsx("path", {
|
|
17900
|
-
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",
|
|
17901
|
-
fill: "currentColor"
|
|
17902
|
-
})]
|
|
17903
|
-
})
|
|
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) => {
|
|
@@ -27425,63 +27495,73 @@ installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
|
27425
27495
|
@layer navi {
|
|
27426
27496
|
}
|
|
27427
27497
|
.navi_badge_count {
|
|
27428
|
-
--x-
|
|
27429
|
-
--x-
|
|
27430
|
-
--x-number-font-size: var(--font-size);
|
|
27498
|
+
--x-background: var(--background);
|
|
27499
|
+
--x-background-color: var(--background-color);
|
|
27431
27500
|
position: relative;
|
|
27432
27501
|
display: inline-block;
|
|
27433
|
-
|
|
27434
27502
|
color: var(--color, var(--x-color-contrasting));
|
|
27435
27503
|
font-size: var(--font-size);
|
|
27436
27504
|
vertical-align: middle;
|
|
27437
|
-
|
|
27438
|
-
|
|
27439
|
-
|
|
27440
|
-
|
|
27441
|
-
|
|
27442
|
-
|
|
27443
|
-
|
|
27444
|
-
|
|
27445
|
-
|
|
27446
|
-
|
|
27447
|
-
|
|
27448
|
-
|
|
27449
|
-
|
|
27450
|
-
|
|
27451
|
-
|
|
27452
|
-
|
|
27453
|
-
|
|
27454
|
-
|
|
27455
|
-
|
|
27456
|
-
|
|
27457
|
-
|
|
27458
|
-
|
|
27459
|
-
|
|
27460
|
-
|
|
27461
|
-
|
|
27462
|
-
|
|
27463
|
-
|
|
27464
|
-
|
|
27465
|
-
|
|
27466
|
-
|
|
27467
|
-
|
|
27468
|
-
|
|
27469
|
-
|
|
27470
|
-
|
|
27471
|
-
|
|
27472
|
-
|
|
27473
|
-
|
|
27474
|
-
|
|
27475
|
-
|
|
27476
|
-
|
|
27477
|
-
|
|
27478
|
-
|
|
27479
|
-
|
|
27480
|
-
|
|
27481
|
-
|
|
27482
|
-
|
|
27483
|
-
|
|
27484
|
-
|
|
27505
|
+
|
|
27506
|
+
.navi_count_badge_overflow {
|
|
27507
|
+
position: relative;
|
|
27508
|
+
top: -0.1em;
|
|
27509
|
+
}
|
|
27510
|
+
|
|
27511
|
+
/* Ellipse */
|
|
27512
|
+
&[data-ellipse] {
|
|
27513
|
+
padding-right: 0.4em;
|
|
27514
|
+
padding-left: 0.4em;
|
|
27515
|
+
background: var(--x-background);
|
|
27516
|
+
background-color: var(--x-background-color, var(--x-background));
|
|
27517
|
+
border-radius: 1em;
|
|
27518
|
+
&[data-loading] {
|
|
27519
|
+
--x-background: transparent;
|
|
27520
|
+
}
|
|
27521
|
+
}
|
|
27522
|
+
|
|
27523
|
+
/* Circle */
|
|
27524
|
+
&[data-circle] {
|
|
27525
|
+
--x-size: 1.5em;
|
|
27526
|
+
--x-border-radius: var(--border-radius);
|
|
27527
|
+
--x-number-font-size: var(--font-size);
|
|
27528
|
+
|
|
27529
|
+
width: var(--x-size);
|
|
27530
|
+
height: var(--x-size);
|
|
27531
|
+
border-radius: var(--x-border-radius);
|
|
27532
|
+
&[data-single-char] {
|
|
27533
|
+
--x-border-radius: 100%;
|
|
27534
|
+
--x-number-font-size: unset;
|
|
27535
|
+
}
|
|
27536
|
+
&[data-two-chars] {
|
|
27537
|
+
--x-border-radius: 100%;
|
|
27538
|
+
--x-number-font-size: 0.8em;
|
|
27539
|
+
}
|
|
27540
|
+
&[data-three-chars] {
|
|
27541
|
+
--x-border-radius: 100%;
|
|
27542
|
+
--x-number-font-size: 0.6em;
|
|
27543
|
+
}
|
|
27544
|
+
|
|
27545
|
+
.navi_badge_count_frame {
|
|
27546
|
+
position: absolute;
|
|
27547
|
+
top: 50%;
|
|
27548
|
+
left: 0;
|
|
27549
|
+
width: 100%;
|
|
27550
|
+
height: 100%;
|
|
27551
|
+
background: var(--x-background);
|
|
27552
|
+
background-color: var(--x-background-color, var(--x-background));
|
|
27553
|
+
border-radius: inherit;
|
|
27554
|
+
transform: translateY(-50%);
|
|
27555
|
+
}
|
|
27556
|
+
|
|
27557
|
+
.navi_badge_count_text {
|
|
27558
|
+
position: absolute;
|
|
27559
|
+
top: 50%;
|
|
27560
|
+
left: 50%;
|
|
27561
|
+
font-size: var(--x-number-font-size, inherit);
|
|
27562
|
+
transform: translate(-50%, -50%);
|
|
27563
|
+
}
|
|
27564
|
+
}
|
|
27485
27565
|
}
|
|
27486
27566
|
`;
|
|
27487
27567
|
const BadgeStyleCSSVars = {
|
|
@@ -27502,11 +27582,11 @@ const BadgeCountOverflow = () => jsx("span", {
|
|
|
27502
27582
|
const MAX_CHAR_AS_CIRCLE = 3;
|
|
27503
27583
|
const BadgeCount = ({
|
|
27504
27584
|
children,
|
|
27505
|
-
max = 99,
|
|
27506
27585
|
maxElement = jsx(BadgeCountOverflow, {}),
|
|
27507
27586
|
// When you use max="none" (or max > 99) it might be a good idea to force ellipse
|
|
27508
27587
|
// so that visually the interface do not suddently switch from circle to ellipse depending on the count
|
|
27509
27588
|
ellipse,
|
|
27589
|
+
max = ellipse ? Infinity : 99,
|
|
27510
27590
|
...props
|
|
27511
27591
|
}) => {
|
|
27512
27592
|
const defaultRef = useRef();
|
|
@@ -27556,10 +27636,11 @@ const BadgeCountCircle = ({
|
|
|
27556
27636
|
ref,
|
|
27557
27637
|
charCount,
|
|
27558
27638
|
hasOverflow,
|
|
27639
|
+
loading,
|
|
27559
27640
|
children,
|
|
27560
27641
|
...props
|
|
27561
27642
|
}) => {
|
|
27562
|
-
return
|
|
27643
|
+
return jsx(Text, {
|
|
27563
27644
|
ref: ref,
|
|
27564
27645
|
className: "navi_badge_count",
|
|
27565
27646
|
"data-circle": "",
|
|
@@ -27571,42 +27652,50 @@ const BadgeCountCircle = ({
|
|
|
27571
27652
|
...props,
|
|
27572
27653
|
styleCSSVars: BadgeStyleCSSVars,
|
|
27573
27654
|
spacing: "pre",
|
|
27574
|
-
children:
|
|
27575
|
-
|
|
27576
|
-
|
|
27577
|
-
|
|
27578
|
-
|
|
27579
|
-
|
|
27580
|
-
|
|
27581
|
-
|
|
27582
|
-
|
|
27583
|
-
|
|
27584
|
-
|
|
27585
|
-
|
|
27655
|
+
children: loading ? jsx(LoadingDots, {}) : jsxs(Fragment, {
|
|
27656
|
+
children: [jsx("span", {
|
|
27657
|
+
style: "user-select: none",
|
|
27658
|
+
children: "\u200B"
|
|
27659
|
+
}), jsx("span", {
|
|
27660
|
+
className: "navi_badge_count_frame"
|
|
27661
|
+
}), jsx("span", {
|
|
27662
|
+
className: "navi_badge_count_text",
|
|
27663
|
+
children: children
|
|
27664
|
+
}), jsx("span", {
|
|
27665
|
+
style: "user-select: none",
|
|
27666
|
+
children: "\u200B"
|
|
27667
|
+
})]
|
|
27668
|
+
})
|
|
27586
27669
|
});
|
|
27587
27670
|
};
|
|
27588
27671
|
const BadgeCountEllipse = ({
|
|
27589
27672
|
ref,
|
|
27673
|
+
loading,
|
|
27590
27674
|
children,
|
|
27591
27675
|
hasOverflow,
|
|
27592
27676
|
...props
|
|
27593
27677
|
}) => {
|
|
27594
|
-
return
|
|
27678
|
+
return jsx(Text, {
|
|
27595
27679
|
ref: ref,
|
|
27596
27680
|
className: "navi_badge_count",
|
|
27597
27681
|
bold: true,
|
|
27598
27682
|
"data-ellipse": "",
|
|
27599
27683
|
"data-value-overflow": hasOverflow ? "" : undefined,
|
|
27684
|
+
"data-loading": loading ? "" : undefined,
|
|
27600
27685
|
...props,
|
|
27601
27686
|
styleCSSVars: BadgeStyleCSSVars,
|
|
27602
27687
|
spacing: "pre",
|
|
27603
|
-
children:
|
|
27604
|
-
|
|
27605
|
-
|
|
27606
|
-
|
|
27607
|
-
|
|
27608
|
-
|
|
27609
|
-
|
|
27688
|
+
children: loading ? jsx(Icon, {
|
|
27689
|
+
children: jsx(LoadingDots, {})
|
|
27690
|
+
}) : jsxs(Fragment, {
|
|
27691
|
+
children: [jsx("span", {
|
|
27692
|
+
style: "user-select: none",
|
|
27693
|
+
children: "\u200B"
|
|
27694
|
+
}), children, jsx("span", {
|
|
27695
|
+
style: "user-select: none",
|
|
27696
|
+
children: "\u200B"
|
|
27697
|
+
})]
|
|
27698
|
+
})
|
|
27610
27699
|
});
|
|
27611
27700
|
};
|
|
27612
27701
|
|