@neo-ui-kit/react 0.0.0-stage → 1.0.0
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/LICENSE +21 -0
- package/README.md +203 -2
- package/dist/artwork/icons.json.d.ts +2 -0
- package/dist/artwork/illustrations.json.d.ts +2 -0
- package/dist/chunks/chunk-347P6ZE4.js +104 -0
- package/dist/chunks/chunk-BJSFN52W.js +417 -0
- package/dist/chunks/chunk-FCOU3ODR.js +63 -0
- package/dist/chunks/chunk-JZ4GDTH5.js +87 -0
- package/dist/chunks/chunk-UGDRXR7P.js +3362 -0
- package/dist/chunks/chunk-VK6GHRLV.js +335 -0
- package/dist/chunks/chunk-YKCUOZ7V.js +777 -0
- package/dist/components/artwork/DatabaseArt/DatabaseArt.d.ts +6 -0
- package/dist/components/artwork/DatabaseArt/styles.css +58 -0
- package/dist/components/artwork/Landscape/Landscape.d.ts +7 -0
- package/dist/components/artwork/Landscape/styles.css +79 -0
- package/dist/components/artwork/NeonWaves/NeonWaves.d.ts +15 -0
- package/dist/components/artwork/NeonWaves/styles.css +48 -0
- package/dist/components/artwork/Planet/Planet.d.ts +4 -0
- package/dist/components/artwork/Planet/styles.css +52 -0
- package/dist/components/artwork/QuantumField/QuantumField.d.ts +42 -0
- package/dist/components/artwork/QuantumField/QuantumFieldExperience.d.ts +22 -0
- package/dist/components/artwork/QuantumField/UPSTREAM-LICENSE.txt +21 -0
- package/dist/components/artwork/QuantumField/audio.d.ts +15 -0
- package/dist/components/artwork/QuantumField/renderer.d.ts +24 -0
- package/dist/components/artwork/QuantumField/styles.css +77 -0
- package/dist/components/artwork/ServerArt/ServerArt.d.ts +8 -0
- package/dist/components/artwork/ServerArt/styles.css +43 -0
- package/dist/components/artwork/Spectrum/Spectrum.d.ts +7 -0
- package/dist/components/artwork/Spectrum/styles.css +35 -0
- package/dist/components/artwork/layers.d.ts +15 -0
- package/dist/components/artwork/useArtwork.d.ts +8 -0
- package/dist/components/controls/Autocomplete/Autocomplete.d.ts +2 -0
- package/dist/components/controls/Autocomplete/styles.css +1 -0
- package/dist/components/controls/Button/Button.d.ts +2 -0
- package/dist/components/controls/Button/styles.css +1 -0
- package/dist/components/controls/Checkbox/Checkbox.d.ts +2 -0
- package/dist/components/controls/Checkbox/styles.css +70 -0
- package/dist/components/controls/Chip/Chip.d.ts +21 -0
- package/dist/components/controls/Chip/styles.css +74 -0
- package/dist/components/controls/ChipField.d.ts +25 -0
- package/dist/components/controls/ColorPicker/ColorPicker.d.ts +16 -0
- package/dist/components/controls/ColorPicker/color.d.ts +9 -0
- package/dist/components/controls/ColorPicker/styles.css +103 -0
- package/dist/components/controls/DatePicker/DatePicker.d.ts +19 -0
- package/dist/components/controls/DatePicker/styles.css +69 -0
- package/dist/components/controls/FilePicker/FilePicker.d.ts +2 -0
- package/dist/components/controls/FilePicker/styles.css +149 -0
- package/dist/components/controls/IconButton/IconButton.d.ts +2 -0
- package/dist/components/controls/IconButton/styles.css +4 -0
- package/dist/components/controls/InputBase/InputBase.d.ts +21 -0
- package/dist/components/controls/InputBase/styles.css +379 -0
- package/dist/components/controls/Link/Link.d.ts +11 -0
- package/dist/components/controls/Link/styles.css +50 -0
- package/dist/components/controls/NumberField/NumberField.d.ts +2 -0
- package/dist/components/controls/NumberField/styles.css +1 -0
- package/dist/components/controls/PeoplePicker/PeoplePicker.d.ts +37 -0
- package/dist/components/controls/PeoplePicker/styles.css +7 -0
- package/dist/components/controls/SegmentedControl/SegmentedControl.d.ts +2 -0
- package/dist/components/controls/SegmentedControl/styles.css +9 -0
- package/dist/components/controls/Select/Select.d.ts +8 -0
- package/dist/components/controls/Select/styles.css +142 -0
- package/dist/components/controls/Slider/Slider.d.ts +3 -0
- package/dist/components/controls/Slider/styles.css +138 -0
- package/dist/components/controls/SplitButton/SplitButton.d.ts +2 -0
- package/dist/components/controls/SplitButton/styles.css +169 -0
- package/dist/components/controls/Switch/Switch.d.ts +2 -0
- package/dist/components/controls/Switch/styles.css +54 -0
- package/dist/components/controls/Tab/Tab.d.ts +2 -0
- package/dist/components/controls/Tab/styles.css +111 -0
- package/dist/components/controls/Tabs/Tabs.d.ts +2 -0
- package/dist/components/controls/Tabs/styles.css +239 -0
- package/dist/components/controls/TagInput/TagInput.d.ts +24 -0
- package/dist/components/controls/TagInput/styles.css +24 -0
- package/dist/components/controls/TextArea/TextArea.d.ts +2 -0
- package/dist/components/controls/TextArea/styles.css +15 -0
- package/dist/components/controls/TextField/TextField.d.ts +2 -0
- package/dist/components/controls/ThemePicker/ThemePicker.d.ts +24 -0
- package/dist/components/controls/ThemePicker/styles.css +128 -0
- package/dist/components/controls/ToggleButton/ToggleButton.d.ts +2 -0
- package/dist/components/controls/ToggleButton/styles.css +49 -0
- package/dist/components/controls/internal.d.ts +62 -0
- package/dist/components/controls/shared.css +694 -0
- package/dist/components/controls/shared.d.ts +204 -0
- package/dist/components/editor/PianoRoll/PianoRoll.d.ts +65 -0
- package/dist/components/editor/PianoRoll/styles.css +186 -0
- package/dist/components/editor/shared.css +1 -0
- package/dist/components/effects/AnimatedBorder/AnimatedBorder.d.ts +9 -0
- package/dist/components/effects/AnimatedBorder/styles.css +7 -0
- package/dist/components/effects/Beacon/Beacon.d.ts +9 -0
- package/dist/components/effects/Beacon/styles.css +38 -0
- package/dist/components/effects/Equalizer/Equalizer.d.ts +14 -0
- package/dist/components/effects/Equalizer/styles.css +38 -0
- package/dist/components/effects/GlowText/GlowText.d.ts +9 -0
- package/dist/components/effects/GlowText/styles.css +56 -0
- package/dist/components/effects/ImageShine/ImageShine.d.ts +13 -0
- package/dist/components/effects/ImageShine/styles.css +66 -0
- package/dist/components/effects/Marquee/Marquee.d.ts +9 -0
- package/dist/components/effects/Marquee/styles.css +46 -0
- package/dist/components/effects/MelodixText/MelodixText.d.ts +15 -0
- package/dist/components/effects/MelodixText/styles.css +28 -0
- package/dist/components/effects/Reveal/Reveal.d.ts +13 -0
- package/dist/components/effects/Reveal/styles.css +25 -0
- package/dist/components/effects/Shimmer/Shimmer.d.ts +10 -0
- package/dist/components/effects/Shimmer/styles.css +48 -0
- package/dist/components/effects/Sparkles/Sparkles.d.ts +9 -0
- package/dist/components/effects/Sparkles/styles.css +28 -0
- package/dist/components/effects/Spotlight/Spotlight.d.ts +11 -0
- package/dist/components/effects/Spotlight/styles.css +45 -0
- package/dist/components/effects/Tilt/Tilt.d.ts +11 -0
- package/dist/components/effects/Tilt/styles.css +67 -0
- package/dist/components/feedback/Badge/Badge.d.ts +3 -0
- package/dist/components/feedback/Badge/styles.css +91 -0
- package/dist/components/feedback/CollapsibleSection/CollapsibleSection.d.ts +2 -0
- package/dist/components/feedback/CollapsibleSection/styles.css +76 -0
- package/dist/components/feedback/DataTable/DataTable.d.ts +16 -0
- package/dist/components/feedback/DataTable/styles.css +522 -0
- package/dist/components/feedback/Dialog/Dialog.d.ts +2 -0
- package/dist/components/feedback/Dialog/styles.css +82 -0
- package/dist/components/feedback/EmptyState/EmptyState.d.ts +2 -0
- package/dist/components/feedback/EmptyState/styles.css +80 -0
- package/dist/components/feedback/KeyValueList/KeyValueList.d.ts +2 -0
- package/dist/components/feedback/KeyValueList/styles.css +51 -0
- package/dist/components/feedback/Menu/Menu.d.ts +2 -0
- package/dist/components/feedback/Menu/styles.css +123 -0
- package/dist/components/feedback/MenuItem/MenuItem.d.ts +2 -0
- package/dist/components/feedback/MenuItem/styles.css +71 -0
- package/dist/components/feedback/MessageBar/MessageBar.d.ts +2 -0
- package/dist/components/feedback/MessageBar/styles.css +116 -0
- package/dist/components/feedback/Popover/Popover.d.ts +2 -0
- package/dist/components/feedback/Popover/styles.css +44 -0
- package/dist/components/feedback/ProgressBar/ProgressBar.d.ts +2 -0
- package/dist/components/feedback/ProgressBar/styles.css +76 -0
- package/dist/components/feedback/SignalBars/SignalBars.d.ts +11 -0
- package/dist/components/feedback/SignalBars/styles.css +31 -0
- package/dist/components/feedback/StatusIndicator/StatusIndicator.d.ts +2 -0
- package/dist/components/feedback/StatusIndicator/styles.css +88 -0
- package/dist/components/feedback/Steps/Steps.d.ts +2 -0
- package/dist/components/feedback/Steps/styles.css +152 -0
- package/dist/components/feedback/Toast/Toast.d.ts +2 -0
- package/dist/components/feedback/Toast/styles.css +89 -0
- package/dist/components/feedback/Tooltip/Tooltip.d.ts +15 -0
- package/dist/components/feedback/Tooltip/styles.css +38 -0
- package/dist/components/feedback/shared.css +22 -0
- package/dist/components/feedback/shared.d.ts +231 -0
- package/dist/components/forms/Form/Form.d.ts +35 -0
- package/dist/components/forms/Form/styles.css +1 -0
- package/dist/components/forms/FormFields/FormFields.d.ts +20 -0
- package/dist/components/forms/FormFields/styles.css +72 -0
- package/dist/components/foundation/Loader/Loader.d.ts +30 -0
- package/dist/components/foundation/LoaderGenerator/LoaderGenerator.d.ts +38 -0
- package/dist/components/foundation/LoaderGenerator/styles.css +104 -0
- package/dist/components/foundation/ThemeEditor/ThemeEditor.d.ts +15 -0
- package/dist/components/foundation/ThemeEditor/styles.css +97 -0
- package/dist/components/foundation/ThemeEditor/themeConfig.d.ts +47 -0
- package/dist/components/foundation/ThemeProvider/ThemeProvider.d.ts +32 -0
- package/dist/components/foundation/ThemeProvider/styles.css +59 -0
- package/dist/components/foundation/Typography/Typography.d.ts +17 -0
- package/dist/components/foundation/Typography/styles.css +115 -0
- package/dist/components/layout/Avatar/Avatar.d.ts +2 -0
- package/dist/components/layout/Avatar/HostSeal.d.ts +5 -0
- package/dist/components/layout/Avatar/styles.css +166 -0
- package/dist/components/layout/BrandMark/BrandMark.d.ts +2 -0
- package/dist/components/layout/BrandMark/styles.css +39 -0
- package/dist/components/layout/ButtonGroup/ButtonGroup.d.ts +12 -0
- package/dist/components/layout/ButtonGroup/styles.css +36 -0
- package/dist/components/layout/Card/Card.d.ts +14 -0
- package/dist/components/layout/Card/styles.css +37 -0
- package/dist/components/layout/DialogActions/DialogActions.d.ts +12 -0
- package/dist/components/layout/DialogActions/styles.css +31 -0
- package/dist/components/layout/DialogBody/DialogBody.d.ts +12 -0
- package/dist/components/layout/DialogBody/styles.css +28 -0
- package/dist/components/layout/Divider/Divider.d.ts +2 -0
- package/dist/components/layout/Divider/styles.css +58 -0
- package/dist/components/layout/FloatingPanel/FloatingPanel.d.ts +15 -0
- package/dist/components/layout/FloatingPanel/styles.css +47 -0
- package/dist/components/layout/FloatingPanel/useFloatingPanel.d.ts +54 -0
- package/dist/components/layout/Grid/Grid.d.ts +24 -0
- package/dist/components/layout/Grid/styles.css +90 -0
- package/dist/components/layout/Header/Header.d.ts +2 -0
- package/dist/components/layout/Header/styles.css +42 -0
- package/dist/components/layout/Icon/Icon.d.ts +4 -0
- package/dist/components/layout/Icon/styles.css +62 -0
- package/dist/components/layout/Illustration/Illustration.d.ts +2 -0
- package/dist/components/layout/Illustration/styles.css +104 -0
- package/dist/components/layout/ScrollArea/ScrollArea.d.ts +2 -0
- package/dist/components/layout/ScrollArea/styles.css +61 -0
- package/dist/components/layout/Stack/Stack.d.ts +21 -0
- package/dist/components/layout/Stack/styles.css +53 -0
- package/dist/components/layout/StatTile/StatTile.d.ts +20 -0
- package/dist/components/layout/StatTile/styles.css +90 -0
- package/dist/components/layout/TabPanel/TabPanel.d.ts +2 -0
- package/dist/components/layout/TabPanel/styles.css +16 -0
- package/dist/components/layout/Text/Text.d.ts +2 -0
- package/dist/components/layout/Text/styles.css +29 -0
- package/dist/components/layout/Toolbar/Toolbar.d.ts +12 -0
- package/dist/components/layout/Toolbar/styles.css +7 -0
- package/dist/components/layout/shared.css +79 -0
- package/dist/components/layout/shared.d.ts +64 -0
- package/dist/components/media/AudioPlayer/AudioPlayer.d.ts +2 -0
- package/dist/components/media/AudioPlayer/styles.css +86 -0
- package/dist/components/media/KaraokeLyrics/KaraokeLyrics.d.ts +25 -0
- package/dist/components/media/KaraokeLyrics/styles.css +56 -0
- package/dist/components/media/LevelMeter/LevelMeter.d.ts +7 -0
- package/dist/components/media/LevelMeter/styles.css +30 -0
- package/dist/components/media/MediaCard/MediaCard.d.ts +24 -0
- package/dist/components/media/MediaCard/styles.css +108 -0
- package/dist/components/media/MelodyRoll/MelodyRoll.d.ts +48 -0
- package/dist/components/media/MelodyRoll/styles.css +196 -0
- package/dist/components/media/PianoKeyboard/PianoKeyboard.d.ts +24 -0
- package/dist/components/media/PianoKeyboard/styles.css +83 -0
- package/dist/components/media/RotaryKnob/RotaryKnob.d.ts +3 -0
- package/dist/components/media/RotaryKnob/styles.css +319 -0
- package/dist/components/media/Sparkline/Sparkline.d.ts +2 -0
- package/dist/components/media/Sparkline/styles.css +70 -0
- package/dist/components/media/WaveDecoration/WaveDecoration.d.ts +2 -0
- package/dist/components/media/WaveDecoration/styles.css +2 -0
- package/dist/components/media/Waveform/Waveform.d.ts +9 -0
- package/dist/components/media/Waveform/styles.css +375 -0
- package/dist/components/media/Waveform/useWaveformPeaks.d.ts +11 -0
- package/dist/components/media/shared.css +7 -0
- package/dist/components/media/shared.d.ts +80 -0
- package/dist/components/navigation/Router/Router.d.ts +32 -0
- package/dist/components/navigation/Router/styles.css +1 -0
- package/dist/components.css +102 -0
- package/dist/core/artwork.d.ts +17 -0
- package/dist/core/base.d.ts +65 -0
- package/dist/core/environment.d.ts +5 -0
- package/dist/core/i18n.d.ts +34 -0
- package/dist/core/messages.d.ts +1 -0
- package/dist/core/motion/hooks.d.ts +17 -0
- package/dist/core/motion-engine.d.ts +13 -0
- package/dist/core/noise.d.ts +20 -0
- package/dist/core/providers/context.d.ts +4 -0
- package/dist/core/responsive.d.ts +13 -0
- package/dist/core.d.ts +8 -0
- package/dist/core.js +56 -0
- package/dist/editor.d.ts +2 -0
- package/dist/editor.js +8 -0
- package/dist/fonts/melodix/Melodix-100.woff2 +0 -0
- package/dist/fonts/melodix/Melodix-200.woff2 +0 -0
- package/dist/fonts/melodix/Melodix-300.woff2 +0 -0
- package/dist/fonts/melodix/Melodix-400.woff2 +0 -0
- package/dist/fonts/melodix/Melodix-500.woff2 +0 -0
- package/dist/fonts/melodix/Melodix-600.woff2 +0 -0
- package/dist/fonts/melodix/Melodix-700.woff2 +0 -0
- package/dist/fonts/melodix/Melodix-800.woff2 +0 -0
- package/dist/fonts/melodix/Melodix-900.woff2 +0 -0
- package/dist/fonts/melodix/MelodixText-100.woff2 +0 -0
- package/dist/fonts/melodix/MelodixText-200.woff2 +0 -0
- package/dist/fonts/melodix/MelodixText-300.woff2 +0 -0
- package/dist/fonts/melodix/MelodixText-400.woff2 +0 -0
- package/dist/fonts/melodix/MelodixText-500.woff2 +0 -0
- package/dist/fonts/melodix/MelodixText-600.woff2 +0 -0
- package/dist/fonts/melodix/MelodixText-700.woff2 +0 -0
- package/dist/fonts/melodix/MelodixText-800.woff2 +0 -0
- package/dist/fonts/melodix/MelodixText-900.woff2 +0 -0
- package/dist/fonts/melodix/OFL-PlayfairDisplay.txt +93 -0
- package/dist/fonts/melodix.css +123 -0
- package/dist/forms.d.ts +4 -0
- package/dist/forms.js +17 -0
- package/dist/index.d.ts +163 -0
- package/dist/index.js +9683 -0
- package/dist/router.d.ts +2 -0
- package/dist/router.js +11 -0
- package/dist/styles.css +2 -0
- package/dist/theme/base.css +221 -0
- package/dist/theme/tokens.css +196 -0
- package/dist/theme/typography.d.ts +24 -0
- package/dist/tokens.css +1 -0
- package/package.json +83 -4
|
@@ -0,0 +1,777 @@
|
|
|
1
|
+
import {
|
|
2
|
+
canObserveIntersection,
|
|
3
|
+
createResizeObserver,
|
|
4
|
+
reducedMotionQuery,
|
|
5
|
+
useMotion
|
|
6
|
+
} from "./chunk-FCOU3ODR.js";
|
|
7
|
+
|
|
8
|
+
// src/core/motion-engine.js
|
|
9
|
+
var uid = 0;
|
|
10
|
+
var U = {
|
|
11
|
+
uid: (p = "ad") => `${p}-${++uid}`,
|
|
12
|
+
svg(tag, attrs = {}) {
|
|
13
|
+
const n = document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
14
|
+
for (const [k, v] of Object.entries(attrs)) n.setAttribute(k, String(v));
|
|
15
|
+
return n;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var seen = /* @__PURE__ */ new WeakMap();
|
|
19
|
+
var running = /* @__PURE__ */ new Set();
|
|
20
|
+
var measurements = /* @__PURE__ */ new Set();
|
|
21
|
+
var raf = null;
|
|
22
|
+
var timer = null;
|
|
23
|
+
var last = 0;
|
|
24
|
+
var weakDevice = typeof navigator !== "undefined" && ((navigator.hardwareConcurrency || 8) <= 4 || (navigator.deviceMemory || 8) <= 4);
|
|
25
|
+
var FRAME = 1e3 / (weakDevice ? 20 : 30);
|
|
26
|
+
U.setMotionFrameRate = (fps) => {
|
|
27
|
+
FRAME = 1e3 / Math.max(1, Math.min(120, fps));
|
|
28
|
+
};
|
|
29
|
+
var looping = /* @__PURE__ */ new Set();
|
|
30
|
+
var pendingAnimations = /* @__PURE__ */ new Set();
|
|
31
|
+
var pendingTargets = /* @__PURE__ */ new Set();
|
|
32
|
+
var active = [];
|
|
33
|
+
var lastScan = -Infinity;
|
|
34
|
+
var needsScan = false;
|
|
35
|
+
var tickers = /* @__PURE__ */ new Set();
|
|
36
|
+
U.subscribeTick = (listener) => {
|
|
37
|
+
tickers.add(listener);
|
|
38
|
+
schedule();
|
|
39
|
+
return () => {
|
|
40
|
+
tickers.delete(listener);
|
|
41
|
+
schedule();
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
var isLoop = (animation) => {
|
|
45
|
+
if (!animation.animationName || !animation.animationName.startsWith("ad-")) return false;
|
|
46
|
+
const timing = animation.effect && animation.effect.getTiming();
|
|
47
|
+
return !!timing && timing.iterations === Infinity;
|
|
48
|
+
};
|
|
49
|
+
function scan(now, animations = pendingAnimations) {
|
|
50
|
+
lastScan = now;
|
|
51
|
+
needsScan = false;
|
|
52
|
+
for (const target of pendingTargets)
|
|
53
|
+
for (const animation of target.getAnimations?.() || []) pendingAnimations.add(animation);
|
|
54
|
+
pendingTargets.clear();
|
|
55
|
+
for (const animation of animations)
|
|
56
|
+
if (!looping.has(animation) && animation.playState === "running" && isLoop(animation)) {
|
|
57
|
+
animation.__adStart = now - (animation.currentTime || 0);
|
|
58
|
+
animation.pause();
|
|
59
|
+
looping.add(animation);
|
|
60
|
+
}
|
|
61
|
+
pendingAnimations.clear();
|
|
62
|
+
active = [];
|
|
63
|
+
for (const animation of looping) {
|
|
64
|
+
const target = animation.effect && animation.effect.target;
|
|
65
|
+
if (!target || !target.isConnected || animation.playState === "idle" || !isLoop(animation)) {
|
|
66
|
+
looping.delete(animation);
|
|
67
|
+
if (target && target.isConnected && animation.playState === "paused") animation.play();
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const hidden = document.hidden || target.closest("[data-ad-offscreen], [data-ad-paused]");
|
|
71
|
+
if (hidden) {
|
|
72
|
+
animation.__adHeld = true;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (animation.__adHeld) {
|
|
76
|
+
animation.__adStart = now - (animation.currentTime || 0);
|
|
77
|
+
animation.__adHeld = false;
|
|
78
|
+
}
|
|
79
|
+
active.push(animation);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function tick(now) {
|
|
83
|
+
raf = null;
|
|
84
|
+
if (needsScan || now - lastScan > 400) scan(now);
|
|
85
|
+
const deadline = performance.now() + 8;
|
|
86
|
+
for (const item of measurements) {
|
|
87
|
+
if (!item.element.isConnected) {
|
|
88
|
+
measurements.delete(item);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (item.element._adInView === false) continue;
|
|
92
|
+
if (performance.now() >= deadline) break;
|
|
93
|
+
measurements.delete(item);
|
|
94
|
+
item.sync();
|
|
95
|
+
}
|
|
96
|
+
if (now - last >= FRAME - 6) {
|
|
97
|
+
for (const animation of active) animation.currentTime = now - animation.__adStart;
|
|
98
|
+
for (const scope of running) scope.tick(now);
|
|
99
|
+
for (const listener of tickers) listener(now);
|
|
100
|
+
last = now;
|
|
101
|
+
}
|
|
102
|
+
if (hasVisibleWork() && !document.hidden) {
|
|
103
|
+
timer = setTimeout(() => {
|
|
104
|
+
timer = null;
|
|
105
|
+
schedule();
|
|
106
|
+
}, Math.max(0, FRAME - (performance.now() - now) - 4));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function hasVisibleWork() {
|
|
110
|
+
if (needsScan || tickers.size || active.length) return true;
|
|
111
|
+
for (const item of measurements)
|
|
112
|
+
if (item.element.isConnected && item.element._adInView !== false) return true;
|
|
113
|
+
for (const scope of running)
|
|
114
|
+
if (scope.enabled) {
|
|
115
|
+
for (const node of scope.callbacks.keys())
|
|
116
|
+
if (node.isConnected && node._adInView !== false) return true;
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
function schedule() {
|
|
121
|
+
if (document.hidden || !hasVisibleWork()) {
|
|
122
|
+
if (raf !== null) cancelAnimationFrame(raf);
|
|
123
|
+
if (timer !== null) clearTimeout(timer);
|
|
124
|
+
raf = timer = null;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (raf === null && timer === null) raf = requestAnimationFrame(tick);
|
|
128
|
+
}
|
|
129
|
+
function refreshMotion() {
|
|
130
|
+
needsScan = true;
|
|
131
|
+
schedule();
|
|
132
|
+
}
|
|
133
|
+
var wake = () => {
|
|
134
|
+
for (const s of running) s.previous = null;
|
|
135
|
+
if (document.hidden) scan(performance.now());
|
|
136
|
+
refreshMotion();
|
|
137
|
+
};
|
|
138
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
139
|
+
document.addEventListener("visibilitychange", wake);
|
|
140
|
+
const onAnimation = (event) => {
|
|
141
|
+
if (!event.animationName.startsWith("ad-")) return;
|
|
142
|
+
pendingTargets.add(event.target);
|
|
143
|
+
needsScan = true;
|
|
144
|
+
schedule();
|
|
145
|
+
};
|
|
146
|
+
document.addEventListener("animationstart", onAnimation);
|
|
147
|
+
document.addEventListener("animationcancel", onAnimation);
|
|
148
|
+
scan(performance.now(), document.getAnimations?.() || []);
|
|
149
|
+
schedule();
|
|
150
|
+
}
|
|
151
|
+
var scopeCount = 0;
|
|
152
|
+
var preferenceMedia = null;
|
|
153
|
+
var preferenceScopes = /* @__PURE__ */ new Set();
|
|
154
|
+
var onPreference = (event) => {
|
|
155
|
+
for (const scope of preferenceScopes)
|
|
156
|
+
if (!scope.explicit) scope.set(!event.matches, false);
|
|
157
|
+
};
|
|
158
|
+
var visibilityObserver = null;
|
|
159
|
+
var visibilityScopes = /* @__PURE__ */ new Map();
|
|
160
|
+
var observeScope = (node, scope) => {
|
|
161
|
+
if (!canObserveIntersection()) return;
|
|
162
|
+
let scopes = visibilityScopes.get(node);
|
|
163
|
+
if (!scopes) {
|
|
164
|
+
scopes = /* @__PURE__ */ new Set();
|
|
165
|
+
visibilityScopes.set(node, scopes);
|
|
166
|
+
visibilityObserver ??= new IntersectionObserver(
|
|
167
|
+
(entries) => {
|
|
168
|
+
for (const entry of entries) {
|
|
169
|
+
entry.target._adInView = entry.isIntersecting;
|
|
170
|
+
for (const watcher of visibilityScopes.get(entry.target) || []) watcher.previous = null;
|
|
171
|
+
}
|
|
172
|
+
schedule();
|
|
173
|
+
},
|
|
174
|
+
{ rootMargin: "10%" }
|
|
175
|
+
);
|
|
176
|
+
visibilityObserver.observe(node);
|
|
177
|
+
}
|
|
178
|
+
scopes.add(scope);
|
|
179
|
+
};
|
|
180
|
+
var unobserveScope = (node, scope) => {
|
|
181
|
+
const scopes = visibilityScopes.get(node);
|
|
182
|
+
if (!scopes) return;
|
|
183
|
+
scopes.delete(scope);
|
|
184
|
+
if (scopes.size) return;
|
|
185
|
+
visibilityScopes.delete(node);
|
|
186
|
+
visibilityObserver.unobserve(node);
|
|
187
|
+
if (!visibilityScopes.size) {
|
|
188
|
+
visibilityObserver.disconnect();
|
|
189
|
+
visibilityObserver = null;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
U.createMotion = (root = document) => {
|
|
193
|
+
scopeCount++;
|
|
194
|
+
if (!preferenceMedia) {
|
|
195
|
+
preferenceMedia = reducedMotionQuery();
|
|
196
|
+
preferenceMedia.addEventListener("change", onPreference);
|
|
197
|
+
}
|
|
198
|
+
const scope = {
|
|
199
|
+
root,
|
|
200
|
+
enabled: !preferenceMedia.matches,
|
|
201
|
+
time: 0,
|
|
202
|
+
previous: null,
|
|
203
|
+
explicit: false,
|
|
204
|
+
callbacks: /* @__PURE__ */ new Map(),
|
|
205
|
+
tick(now) {
|
|
206
|
+
if (!this.enabled) {
|
|
207
|
+
this.previous = null;
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
let painted = false;
|
|
211
|
+
for (const [node, fn] of this.callbacks) {
|
|
212
|
+
if (!node.isConnected) {
|
|
213
|
+
this.callbacks.delete(node);
|
|
214
|
+
unobserveScope(node, this);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (node._adInView === true || node._adInView !== false && node.getClientRects().length) {
|
|
218
|
+
if (!painted) {
|
|
219
|
+
if (this.previous !== null)
|
|
220
|
+
this.time += Math.min((now - this.previous) / 1e3, 0.1);
|
|
221
|
+
this.previous = now;
|
|
222
|
+
painted = true;
|
|
223
|
+
}
|
|
224
|
+
fn(this.time);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (!painted) this.previous = null;
|
|
228
|
+
},
|
|
229
|
+
add(node, callback, immediate = true) {
|
|
230
|
+
this.callbacks.set(node, callback);
|
|
231
|
+
if (immediate) callback(this.time);
|
|
232
|
+
observeScope(node, this);
|
|
233
|
+
schedule();
|
|
234
|
+
return () => {
|
|
235
|
+
this.callbacks.delete(node);
|
|
236
|
+
unobserveScope(node, this);
|
|
237
|
+
schedule();
|
|
238
|
+
};
|
|
239
|
+
},
|
|
240
|
+
set(enabled, explicit = true) {
|
|
241
|
+
this.enabled = !!enabled;
|
|
242
|
+
this.explicit ||= explicit;
|
|
243
|
+
this.previous = null;
|
|
244
|
+
const target = root.dataset ? root : root.host || document.documentElement;
|
|
245
|
+
target.dataset.adMotion = enabled ? "on" : "off";
|
|
246
|
+
if (this.enabled) running.add(this);
|
|
247
|
+
else running.delete(this);
|
|
248
|
+
schedule();
|
|
249
|
+
return this.enabled;
|
|
250
|
+
},
|
|
251
|
+
dispose() {
|
|
252
|
+
if (this.disposed) return;
|
|
253
|
+
this.disposed = true;
|
|
254
|
+
--scopeCount;
|
|
255
|
+
running.delete(this);
|
|
256
|
+
for (const node of this.callbacks.keys()) unobserveScope(node, this);
|
|
257
|
+
this.callbacks.clear();
|
|
258
|
+
preferenceScopes.delete(this);
|
|
259
|
+
if (!preferenceScopes.size) {
|
|
260
|
+
preferenceMedia.removeEventListener("change", onPreference);
|
|
261
|
+
preferenceMedia = null;
|
|
262
|
+
}
|
|
263
|
+
schedule();
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
preferenceScopes.add(scope);
|
|
267
|
+
scope.set(scope.enabled, false);
|
|
268
|
+
return scope;
|
|
269
|
+
};
|
|
270
|
+
U.roundedPath = (w, h, corners) => {
|
|
271
|
+
const i = 0.65, R = w - i, B = h - i;
|
|
272
|
+
const factor = Math.min(
|
|
273
|
+
1,
|
|
274
|
+
w / (corners[0][0] + corners[1][0]),
|
|
275
|
+
w / (corners[2][0] + corners[3][0]),
|
|
276
|
+
h / (corners[0][1] + corners[3][1]),
|
|
277
|
+
h / (corners[1][1] + corners[2][1])
|
|
278
|
+
);
|
|
279
|
+
const [tl, tr, br, bl] = corners.map(([x2, y2]) => {
|
|
280
|
+
x2 = Math.max(0, x2 * factor - i);
|
|
281
|
+
y2 = Math.max(0, y2 * factor - i);
|
|
282
|
+
return x2 && y2 ? [x2, y2] : [0, 0];
|
|
283
|
+
});
|
|
284
|
+
const segments = [];
|
|
285
|
+
let d = `M${i + tl[0]} ${i}`, x = i + tl[0], y = i;
|
|
286
|
+
const line = (toX, toY) => {
|
|
287
|
+
const fromX = x, fromY = y, dx = toX - x, dy = toY - y;
|
|
288
|
+
const length2 = Math.hypot(dx, dy);
|
|
289
|
+
segments.push({ length: length2, point: (distance) => ({ x: fromX + dx * distance / length2, y: fromY + dy * distance / length2 }) });
|
|
290
|
+
d += `L${toX} ${toY}`;
|
|
291
|
+
x = toX;
|
|
292
|
+
y = toY;
|
|
293
|
+
};
|
|
294
|
+
const arc = (cx, cy, [rx, ry], angle, toX, toY) => {
|
|
295
|
+
if (!rx || !ry) return line(toX, toY);
|
|
296
|
+
const point = (t) => ({ x: cx + rx * Math.cos(angle + t * Math.PI / 2), y: cy + ry * Math.sin(angle + t * Math.PI / 2) });
|
|
297
|
+
const distances = [0];
|
|
298
|
+
if (rx !== ry) {
|
|
299
|
+
let previous = point(0);
|
|
300
|
+
for (let step = 1; step <= 32; step++) {
|
|
301
|
+
const next = point(step / 32);
|
|
302
|
+
distances.push(distances[step - 1] + Math.hypot(next.x - previous.x, next.y - previous.y));
|
|
303
|
+
previous = next;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
const length2 = rx === ry ? rx * Math.PI / 2 : distances[32];
|
|
307
|
+
segments.push({ length: length2, point(distance) {
|
|
308
|
+
if (rx === ry) return point(distance / length2);
|
|
309
|
+
let lo = 0, hi = 32;
|
|
310
|
+
while (hi - lo > 1) {
|
|
311
|
+
const middle = lo + hi >> 1;
|
|
312
|
+
if (distances[middle] < distance) lo = middle;
|
|
313
|
+
else hi = middle;
|
|
314
|
+
}
|
|
315
|
+
return point((lo + (distance - distances[lo]) / (distances[hi] - distances[lo])) / 32);
|
|
316
|
+
} });
|
|
317
|
+
d += `A${rx} ${ry} 0 0 1 ${toX} ${toY}`;
|
|
318
|
+
x = toX;
|
|
319
|
+
y = toY;
|
|
320
|
+
};
|
|
321
|
+
line(R - tr[0], i);
|
|
322
|
+
arc(R - tr[0], i + tr[1], tr, -Math.PI / 2, R, i + tr[1]);
|
|
323
|
+
line(R, B - br[1]);
|
|
324
|
+
arc(R - br[0], B - br[1], br, 0, R - br[0], B);
|
|
325
|
+
line(i + bl[0], B);
|
|
326
|
+
arc(i + bl[0], B - bl[1], bl, Math.PI / 2, i, B - bl[1]);
|
|
327
|
+
line(i, i + tl[1]);
|
|
328
|
+
arc(i + tl[0], i + tl[1], tl, Math.PI, i + tl[0], i);
|
|
329
|
+
d += "Z";
|
|
330
|
+
const length = segments.reduce((total, segment) => total + segment.length, 0);
|
|
331
|
+
return {
|
|
332
|
+
d,
|
|
333
|
+
point(fraction) {
|
|
334
|
+
let distance = fraction * length;
|
|
335
|
+
for (const segment of segments) {
|
|
336
|
+
if (segment.length && distance <= segment.length) return segment.point(distance);
|
|
337
|
+
distance -= segment.length;
|
|
338
|
+
}
|
|
339
|
+
return { x: i + tl[0], y: i };
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
};
|
|
343
|
+
var borders = /* @__PURE__ */ new WeakMap();
|
|
344
|
+
var AURA = [[25, 0.016], [22, 0.031], [19, 0.055], [16, 0.087], [13, 0.124], [10, 0.157], [7, 0.17], [4, 0.153]];
|
|
345
|
+
var borderSerial = 0;
|
|
346
|
+
var HALO = 16;
|
|
347
|
+
var CORE_STOPS = [
|
|
348
|
+
["var(--ad-neutral-200)", 0],
|
|
349
|
+
["var(--ad-neutral-200)", 4],
|
|
350
|
+
["var(--ad-secondary)", 16],
|
|
351
|
+
["rgb(from var(--ad-primary) r g b / 0.85)", 40],
|
|
352
|
+
["rgb(from var(--ad-primary) r g b / 0.32)", 72],
|
|
353
|
+
["rgb(from var(--ad-primary) r g b / 0)", 100]
|
|
354
|
+
];
|
|
355
|
+
var AURA_STOPS = [
|
|
356
|
+
["var(--ad-primary)", 0],
|
|
357
|
+
["rgb(from var(--ad-primary) r g b / 0.7)", 40],
|
|
358
|
+
["rgb(from var(--ad-primary) r g b / 0)", 100]
|
|
359
|
+
];
|
|
360
|
+
var radial = (stops) => `radial-gradient(circle closest-side, ${stops.map(([color, at]) => `${color} ${at}%`).join(", ")})`;
|
|
361
|
+
var ringMask = (w, h, d, strokes) => {
|
|
362
|
+
const paths = strokes.map(([width, opacity]) => `<path d='${d}' stroke-width='${width}' stroke-opacity='${opacity}'/>`).join("");
|
|
363
|
+
return `url("data:image/svg+xml,${encodeURIComponent(
|
|
364
|
+
`<svg xmlns='http://www.w3.org/2000/svg' viewBox='${-HALO} ${-HALO} ${w + 2 * HALO} ${h + 2 * HALO}'><g fill='none' stroke='#000' stroke-linecap='round' stroke-linejoin='round'>${paths}</g></svg>`
|
|
365
|
+
)}")`;
|
|
366
|
+
};
|
|
367
|
+
U.attachBorder = (element, { shell = false, round = false, scope, defer = false } = {}) => {
|
|
368
|
+
if (borders.has(element)) return borders.get(element);
|
|
369
|
+
defer &&= !!scope;
|
|
370
|
+
if (defer && canObserveIntersection()) element._adInView = false;
|
|
371
|
+
let radius = round ? 28 : shell ? 102 : 116;
|
|
372
|
+
const overlay = document.createElement("div");
|
|
373
|
+
overlay.className = "ad-border";
|
|
374
|
+
overlay.setAttribute("aria-hidden", "true");
|
|
375
|
+
overlay.setAttribute("data-ad-component", "AnimatedBorder");
|
|
376
|
+
const edge = U.svg("svg", { fill: "none", preserveAspectRatio: "none" });
|
|
377
|
+
const path = U.svg("path", {
|
|
378
|
+
stroke: shell ? "rgb(from var(--ad-secondary) r g b / 0.65)" : "rgb(from var(--ad-primary) r g b / 0.16)",
|
|
379
|
+
"stroke-width": shell ? 1.1 : 0.6
|
|
380
|
+
});
|
|
381
|
+
edge.append(path);
|
|
382
|
+
const ring = (className) => {
|
|
383
|
+
const node = document.createElement("div");
|
|
384
|
+
node.className = className;
|
|
385
|
+
return node;
|
|
386
|
+
};
|
|
387
|
+
const aura = ring("ad-border-aura"), core = ring("ad-border-core");
|
|
388
|
+
overlay.append(edge, aura, core);
|
|
389
|
+
const instancePhase = ++borderSerial * 0.38196601125 % 1;
|
|
390
|
+
const lights = Array.from({ length: 2 }, (_, k) => {
|
|
391
|
+
const spot = (parent, stops) => {
|
|
392
|
+
const node = ring("ad-border-light");
|
|
393
|
+
node.style.background = radial(stops);
|
|
394
|
+
parent.append(node);
|
|
395
|
+
return node;
|
|
396
|
+
};
|
|
397
|
+
return {
|
|
398
|
+
radius,
|
|
399
|
+
phase: (k * 0.48 + 0.535 + instancePhase) % 1,
|
|
400
|
+
speed: round ? k ? 25 : 36 : k ? 86 : 125,
|
|
401
|
+
spots: [spot(aura, AURA_STOPS), spot(core, CORE_STOPS)],
|
|
402
|
+
at: null
|
|
403
|
+
};
|
|
404
|
+
});
|
|
405
|
+
const previousInlinePosition = element.style.position;
|
|
406
|
+
element.append(overlay);
|
|
407
|
+
const item = {
|
|
408
|
+
element,
|
|
409
|
+
overlay,
|
|
410
|
+
path,
|
|
411
|
+
lights,
|
|
412
|
+
length: 0,
|
|
413
|
+
elapsed: 0,
|
|
414
|
+
previousTime: null,
|
|
415
|
+
patchedPosition: false,
|
|
416
|
+
previousInlinePosition
|
|
417
|
+
};
|
|
418
|
+
item.paint = (time) => {
|
|
419
|
+
if (!item.length) return;
|
|
420
|
+
if (item.previousTime !== null)
|
|
421
|
+
item.elapsed += Math.min(0.1, Math.max(0, time - item.previousTime));
|
|
422
|
+
item.previousTime = time;
|
|
423
|
+
for (const light of lights) {
|
|
424
|
+
const p = item.contour.point((light.phase * item.length + item.elapsed * light.speed) % item.length / item.length);
|
|
425
|
+
light.at = p;
|
|
426
|
+
const transform = `translate3d(${(p.x - radius + HALO).toFixed(2)}px, ${(p.y - radius + HALO).toFixed(2)}px, 0)`;
|
|
427
|
+
for (const spot of light.spots) spot.style.transform = transform;
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
item.sync = () => {
|
|
431
|
+
const computed = getComputedStyle(element);
|
|
432
|
+
const sides = ["Top", "Right", "Bottom", "Left"];
|
|
433
|
+
const borderWidths = sides.map((side) => parseFloat(computed[`border${side}Width`]) || 0);
|
|
434
|
+
const [w, h] = [["width", 3, 1, "offsetWidth"], ["height", 0, 2, "offsetHeight"]].map(([axis, start, end, fallback]) => {
|
|
435
|
+
const value = parseFloat(computed[axis]);
|
|
436
|
+
return Number.isFinite(value) ? value + (computed.boxSizing === "border-box" ? 0 : [start, end].reduce((sum, side) => sum + borderWidths[side] + (parseFloat(computed[`padding${sides[side]}`]) || 0), 0)) : element[fallback];
|
|
437
|
+
});
|
|
438
|
+
if (!w || !h) return;
|
|
439
|
+
if (computed.position === "static") {
|
|
440
|
+
item.patchedPosition = true;
|
|
441
|
+
element.style.position = "relative";
|
|
442
|
+
}
|
|
443
|
+
const corners = ["TopLeft", "TopRight", "BottomRight", "BottomLeft"].map((corner) => {
|
|
444
|
+
const values = (computed[`border${corner}Radius`] || computed.borderTopLeftRadius).split(/\s+/);
|
|
445
|
+
return [w, h].map((size, axis) => {
|
|
446
|
+
const value = values[axis] || values[0];
|
|
447
|
+
return (parseFloat(value) || 0) * (value.includes("%") ? size / 100 : 1);
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
const geometry = `${w},${h},${corners},${borderWidths}`;
|
|
451
|
+
if (item.geometry === geometry) return;
|
|
452
|
+
item.geometry = geometry;
|
|
453
|
+
overlay.style.inset = borderWidths.map((width) => `${-width}px`).join(" ");
|
|
454
|
+
overlay.style.width = `calc(100% + ${borderWidths[1] + borderWidths[3]}px)`;
|
|
455
|
+
overlay.style.height = `calc(100% + ${borderWidths[0] + borderWidths[2]}px)`;
|
|
456
|
+
item.contour = U.roundedPath(w, h, corners);
|
|
457
|
+
const { d } = item.contour;
|
|
458
|
+
edge.setAttribute("viewBox", `0 0 ${w} ${h}`);
|
|
459
|
+
path.setAttribute("d", d);
|
|
460
|
+
for (const [node, strokes] of [[aura, AURA], [core, [[shell ? 1.9 : 1.35, 1]]]]) {
|
|
461
|
+
const mask = ringMask(w, h, d, strokes);
|
|
462
|
+
node.style.maskImage = mask;
|
|
463
|
+
node.style.webkitMaskImage = mask;
|
|
464
|
+
}
|
|
465
|
+
item.length = path.getTotalLength();
|
|
466
|
+
radius = round ? 28 : Math.min(260, Math.max(42, item.length * 0.153));
|
|
467
|
+
for (const light of lights) {
|
|
468
|
+
light.radius = radius;
|
|
469
|
+
for (const spot of light.spots) {
|
|
470
|
+
spot.style.width = `${radius * 2}px`;
|
|
471
|
+
spot.style.height = `${radius * 2}px`;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
item.paint(scope?.time || 0);
|
|
475
|
+
};
|
|
476
|
+
const queueMeasurement = () => {
|
|
477
|
+
if (item.destroyed) return;
|
|
478
|
+
measurements.add(item);
|
|
479
|
+
schedule();
|
|
480
|
+
};
|
|
481
|
+
item.observer = createResizeObserver(defer ? queueMeasurement : item.sync);
|
|
482
|
+
item.observer.observe(element);
|
|
483
|
+
if (defer) queueMeasurement();
|
|
484
|
+
else item.sync();
|
|
485
|
+
const unsubscribe = scope?.add(element, item.paint, !defer);
|
|
486
|
+
item.destroy = () => {
|
|
487
|
+
item.destroyed = true;
|
|
488
|
+
measurements.delete(item);
|
|
489
|
+
unsubscribe?.();
|
|
490
|
+
item.observer.disconnect();
|
|
491
|
+
overlay.remove();
|
|
492
|
+
if (item.patchedPosition) element.style.position = item.previousInlinePosition;
|
|
493
|
+
borders.delete(element);
|
|
494
|
+
};
|
|
495
|
+
borders.set(element, item);
|
|
496
|
+
return item;
|
|
497
|
+
};
|
|
498
|
+
U.attachTabShape = (button) => {
|
|
499
|
+
if (seen.has(button)) return seen.get(button);
|
|
500
|
+
const id = U.uid("ad-tab-fill"), shape = U.svg("svg", {
|
|
501
|
+
class: "tab-shape ad-tab-shape",
|
|
502
|
+
"aria-hidden": "true",
|
|
503
|
+
fill: "none",
|
|
504
|
+
preserveAspectRatio: "none"
|
|
505
|
+
});
|
|
506
|
+
const defs = U.svg("defs"), grad = U.svg("linearGradient", { id, x1: 0, y1: 0, x2: 0, y2: 1 });
|
|
507
|
+
[
|
|
508
|
+
[0, "var(--ad-primary-700)", 0.77],
|
|
509
|
+
[0.38, "var(--ad-primary-900)", 0.86],
|
|
510
|
+
[0.76, "var(--ad-primary-900)", 0.94],
|
|
511
|
+
[1, "var(--ad-primary-600)", 0.94]
|
|
512
|
+
].forEach(
|
|
513
|
+
([offset, color, opacity]) => grad.append(
|
|
514
|
+
U.svg("stop", { offset, "stop-color": color, "stop-opacity": opacity })
|
|
515
|
+
)
|
|
516
|
+
);
|
|
517
|
+
defs.append(grad);
|
|
518
|
+
shape.append(defs);
|
|
519
|
+
const glow = U.svg("path", { class: "tab-shape__glow" }), edge = U.svg("path", { class: "tab-shape__edge", fill: `url(#${id})` }), floor = U.svg("path", { class: "tab-shape__floor" });
|
|
520
|
+
shape.append(glow, edge, floor);
|
|
521
|
+
const glints = U.svg("svg", {
|
|
522
|
+
class: "tab-shape ad-tab-shape ad-tab-shape-glint",
|
|
523
|
+
"aria-hidden": "true",
|
|
524
|
+
fill: "none",
|
|
525
|
+
preserveAspectRatio: "none"
|
|
526
|
+
});
|
|
527
|
+
const glint = ["wide", "near", "core"].map(
|
|
528
|
+
(part) => U.svg("path", { class: "tab-shape__glint", "data-part": part, pathLength: 100 })
|
|
529
|
+
);
|
|
530
|
+
glints.append(...glint);
|
|
531
|
+
button.prepend(shape, glints);
|
|
532
|
+
button.dataset.adShapeReady = "";
|
|
533
|
+
const position = () => {
|
|
534
|
+
const siblings = [...button.parentElement?.children || []].filter(
|
|
535
|
+
(node) => node instanceof HTMLElement && node.getAttribute("role") === "tab"
|
|
536
|
+
);
|
|
537
|
+
const index = siblings.indexOf(button);
|
|
538
|
+
return {
|
|
539
|
+
first: index === 0,
|
|
540
|
+
last: index === siblings.length - 1,
|
|
541
|
+
single: siblings.length === 1
|
|
542
|
+
};
|
|
543
|
+
};
|
|
544
|
+
const sync = () => {
|
|
545
|
+
const w = button.offsetWidth, h = button.offsetHeight;
|
|
546
|
+
if (!w || !h) return;
|
|
547
|
+
shape.setAttribute("viewBox", `0 0 ${w} ${h}`);
|
|
548
|
+
glints.setAttribute("viewBox", `0 0 ${w} ${h}`);
|
|
549
|
+
const { first, last: last2, single } = position();
|
|
550
|
+
const top = 1.5, bottom = h - 1.5, outer = 1.2;
|
|
551
|
+
const shoulder = Math.min(24, w * 0.11), corner = Math.min(34, w * 0.19), sideLift = Math.min(13, h * 0.28);
|
|
552
|
+
const notchWidth = Math.min(10, w * 0.05), notchDepth = Math.min(3.5, h * 0.08);
|
|
553
|
+
const radius = Math.min(10, h * 0.22, w * 0.05);
|
|
554
|
+
const leftOuter = single || first;
|
|
555
|
+
const rightOuter = single || last2;
|
|
556
|
+
let d = `M${w / 2 - notchWidth} ${bottom}`;
|
|
557
|
+
if (leftOuter) {
|
|
558
|
+
d += `H${outer + radius}Q${outer} ${bottom} ${outer} ${bottom - radius}V${top + radius}Q${outer} ${top} ${outer + radius} ${top}`;
|
|
559
|
+
} else {
|
|
560
|
+
d += `H${outer + 4.5}Q${outer + 1.5} ${bottom - 0.3} ${outer + 4.5} ${bottom - sideLift}L${shoulder} 13Q${shoulder + 4} ${top} ${corner} ${top}`;
|
|
561
|
+
}
|
|
562
|
+
d += `H${rightOuter ? w - (outer + radius) : w - corner}`;
|
|
563
|
+
if (rightOuter) {
|
|
564
|
+
d += `Q${w - outer} ${top} ${w - outer} ${top + radius}V${bottom - radius}Q${w - outer} ${bottom} ${w - (outer + radius)} ${bottom}`;
|
|
565
|
+
} else {
|
|
566
|
+
d += `Q${w - shoulder - 4} ${top} ${w - shoulder} 13L${w - (outer + 4.5)} ${bottom - sideLift}Q${w - (outer + 1.5)} ${bottom - 0.3} ${w - (outer + 4.5)} ${bottom}`;
|
|
567
|
+
}
|
|
568
|
+
d += `H${w / 2 + notchWidth}L${w / 2} ${bottom + notchDepth}L${w / 2 - notchWidth} ${bottom}Z`;
|
|
569
|
+
for (const path of [glow, edge, ...glint]) path.setAttribute("d", d);
|
|
570
|
+
const floorLeft = leftOuter ? outer + radius : outer + 5;
|
|
571
|
+
const floorRight = rightOuter ? w - (outer + radius) : w - (outer + 5);
|
|
572
|
+
floor.setAttribute(
|
|
573
|
+
"d",
|
|
574
|
+
`M${floorLeft} ${bottom}H${w / 2 - notchWidth - 1}L${w / 2} ${bottom + notchDepth}L${w / 2 + notchWidth + 1} ${bottom}H${floorRight}`
|
|
575
|
+
);
|
|
576
|
+
button.dataset.adTabEdge = single ? "single" : first ? "first" : last2 ? "last" : "middle";
|
|
577
|
+
};
|
|
578
|
+
const observer = createResizeObserver(sync);
|
|
579
|
+
observer.observe(button);
|
|
580
|
+
if (button.parentElement) observer.observe(button.parentElement);
|
|
581
|
+
sync();
|
|
582
|
+
const item = {
|
|
583
|
+
observer,
|
|
584
|
+
shape,
|
|
585
|
+
sync,
|
|
586
|
+
destroy() {
|
|
587
|
+
observer.disconnect();
|
|
588
|
+
shape.remove();
|
|
589
|
+
glints.remove();
|
|
590
|
+
button.removeAttribute("data-ad-shape-ready");
|
|
591
|
+
button.removeAttribute("data-ad-tab-edge");
|
|
592
|
+
seen.delete(button);
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
seen.set(button, item);
|
|
596
|
+
return item;
|
|
597
|
+
};
|
|
598
|
+
var createMotion = U.createMotion;
|
|
599
|
+
var attachBorder = U.attachBorder;
|
|
600
|
+
var attachTabShape = U.attachTabShape;
|
|
601
|
+
var setMotionFrameRate = U.setMotionFrameRate;
|
|
602
|
+
var subscribeTick = U.subscribeTick;
|
|
603
|
+
function getMotionStats() {
|
|
604
|
+
return {
|
|
605
|
+
scopes: scopeCount,
|
|
606
|
+
running: running.size,
|
|
607
|
+
scheduled: raf !== null || timer !== null,
|
|
608
|
+
callbacks: [...running].reduce((n, s) => n + s.callbacks.size, 0)
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// src/core/motion/hooks.ts
|
|
613
|
+
import { useEffect, useLayoutEffect, useRef } from "react";
|
|
614
|
+
function useDecoration(ref, paint) {
|
|
615
|
+
const enabled = useMotion();
|
|
616
|
+
const painter = useRef(paint);
|
|
617
|
+
painter.current = paint;
|
|
618
|
+
const scope = useRef(null);
|
|
619
|
+
useLayoutEffect(() => {
|
|
620
|
+
const node = ref.current;
|
|
621
|
+
if (!node) return;
|
|
622
|
+
const controller = createMotion(node);
|
|
623
|
+
scope.current = controller;
|
|
624
|
+
const unsubscribe = controller.add(
|
|
625
|
+
node,
|
|
626
|
+
(time) => painter.current(time)
|
|
627
|
+
);
|
|
628
|
+
return () => {
|
|
629
|
+
unsubscribe();
|
|
630
|
+
controller.dispose();
|
|
631
|
+
scope.current = null;
|
|
632
|
+
};
|
|
633
|
+
}, [ref]);
|
|
634
|
+
useLayoutEffect(() => {
|
|
635
|
+
scope.current?.set(enabled);
|
|
636
|
+
}, [enabled]);
|
|
637
|
+
}
|
|
638
|
+
function useBorder(ref, enabled = true, shell = false, round = false) {
|
|
639
|
+
const motion = useMotion();
|
|
640
|
+
const scope = useRef(null);
|
|
641
|
+
useLayoutEffect(() => {
|
|
642
|
+
const node = ref.current;
|
|
643
|
+
if (!node || !enabled) return;
|
|
644
|
+
const controller = createMotion(node);
|
|
645
|
+
scope.current = controller;
|
|
646
|
+
const border = attachBorder(node, { shell, round, scope: controller, defer: true });
|
|
647
|
+
return () => {
|
|
648
|
+
border.destroy();
|
|
649
|
+
controller.dispose();
|
|
650
|
+
scope.current = null;
|
|
651
|
+
};
|
|
652
|
+
}, [ref, enabled, shell, round]);
|
|
653
|
+
useLayoutEffect(() => {
|
|
654
|
+
scope.current?.set(motion);
|
|
655
|
+
}, [motion, enabled, shell, round]);
|
|
656
|
+
}
|
|
657
|
+
function useTick(callback, active2 = true) {
|
|
658
|
+
const latest = useRef(callback);
|
|
659
|
+
latest.current = callback;
|
|
660
|
+
useEffect(() => {
|
|
661
|
+
if (!active2) return;
|
|
662
|
+
return subscribeTick((now) => latest.current(now));
|
|
663
|
+
}, [active2]);
|
|
664
|
+
}
|
|
665
|
+
var offscreenObserver = null;
|
|
666
|
+
var offscreenCount = 0;
|
|
667
|
+
var watchOffscreen = (node) => {
|
|
668
|
+
if (typeof IntersectionObserver === "undefined") return () => void 0;
|
|
669
|
+
offscreenObserver ??= new IntersectionObserver(
|
|
670
|
+
(entries) => {
|
|
671
|
+
for (const entry of entries) entry.target.toggleAttribute("data-ad-offscreen", !entry.isIntersecting);
|
|
672
|
+
refreshMotion();
|
|
673
|
+
},
|
|
674
|
+
{ rootMargin: "12% 0px" }
|
|
675
|
+
);
|
|
676
|
+
offscreenObserver.observe(node);
|
|
677
|
+
offscreenCount++;
|
|
678
|
+
return () => {
|
|
679
|
+
offscreenObserver?.unobserve(node);
|
|
680
|
+
if (--offscreenCount === 0) {
|
|
681
|
+
offscreenObserver?.disconnect();
|
|
682
|
+
offscreenObserver = null;
|
|
683
|
+
}
|
|
684
|
+
node.removeAttribute("data-ad-offscreen");
|
|
685
|
+
refreshMotion();
|
|
686
|
+
};
|
|
687
|
+
};
|
|
688
|
+
function usePauseOffscreen(ref) {
|
|
689
|
+
useLayoutEffect(() => {
|
|
690
|
+
const node = ref.current;
|
|
691
|
+
if (!node) return;
|
|
692
|
+
return watchOffscreen(node);
|
|
693
|
+
}, [ref]);
|
|
694
|
+
}
|
|
695
|
+
function useTabShape(ref) {
|
|
696
|
+
useLayoutEffect(() => {
|
|
697
|
+
const node = ref.current;
|
|
698
|
+
if (!node) return;
|
|
699
|
+
const shape = attachTabShape(node);
|
|
700
|
+
return () => shape.destroy();
|
|
701
|
+
}, [ref]);
|
|
702
|
+
}
|
|
703
|
+
function useSmoothWheel(ref) {
|
|
704
|
+
const enabled = useMotion();
|
|
705
|
+
useEffect(() => {
|
|
706
|
+
const element = ref.current;
|
|
707
|
+
if (!element || !enabled || reducedMotionQuery().matches)
|
|
708
|
+
return;
|
|
709
|
+
let target = element.scrollTop;
|
|
710
|
+
let position = target;
|
|
711
|
+
let applied = target;
|
|
712
|
+
let frame = 0;
|
|
713
|
+
let last2 = 0;
|
|
714
|
+
const stop = () => {
|
|
715
|
+
cancelAnimationFrame(frame);
|
|
716
|
+
frame = 0;
|
|
717
|
+
last2 = 0;
|
|
718
|
+
};
|
|
719
|
+
const glide = (now) => {
|
|
720
|
+
const shift = element.scrollTop - applied;
|
|
721
|
+
if (Math.abs(shift) > 1.5) {
|
|
722
|
+
position += shift;
|
|
723
|
+
target += shift;
|
|
724
|
+
}
|
|
725
|
+
const elapsed = Math.min(64, now - (last2 || now - 16));
|
|
726
|
+
last2 = now;
|
|
727
|
+
target = Math.max(
|
|
728
|
+
0,
|
|
729
|
+
Math.min(element.scrollHeight - element.clientHeight, target)
|
|
730
|
+
);
|
|
731
|
+
position += (target - position) * (1 - Math.exp(-elapsed / 95));
|
|
732
|
+
if (Math.abs(target - position) < 0.25) position = target;
|
|
733
|
+
element.scrollTop = position;
|
|
734
|
+
applied = element.scrollTop;
|
|
735
|
+
if (position === target) return stop();
|
|
736
|
+
frame = requestAnimationFrame(glide);
|
|
737
|
+
};
|
|
738
|
+
const onWheel = (event) => {
|
|
739
|
+
if (event.defaultPrevented || event.ctrlKey || Math.abs(event.deltaX) > Math.abs(event.deltaY))
|
|
740
|
+
return;
|
|
741
|
+
const delta = event.deltaMode === 1 ? event.deltaY * 16 : event.deltaY;
|
|
742
|
+
if (event.deltaMode === 0 && Math.abs(delta) < 40) return;
|
|
743
|
+
for (let node = event.target; node && node !== element; node = node.parentElement) {
|
|
744
|
+
const canScroll = node.scrollHeight > node.clientHeight + 1 && /auto|scroll/.test(getComputedStyle(node).overflowY);
|
|
745
|
+
if (canScroll && (delta < 0 ? node.scrollTop > 0 : node.scrollTop + node.clientHeight < node.scrollHeight - 1))
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
if (element.scrollHeight <= element.clientHeight + 1 || !/auto|scroll/.test(getComputedStyle(element).overflowY))
|
|
749
|
+
return;
|
|
750
|
+
event.preventDefault();
|
|
751
|
+
if (!frame) target = position = applied = element.scrollTop;
|
|
752
|
+
target = Math.max(
|
|
753
|
+
0,
|
|
754
|
+
Math.min(element.scrollHeight - element.clientHeight, target + delta)
|
|
755
|
+
);
|
|
756
|
+
if (!frame) frame = requestAnimationFrame(glide);
|
|
757
|
+
};
|
|
758
|
+
element.addEventListener("wheel", onWheel, { passive: false });
|
|
759
|
+
return () => {
|
|
760
|
+
element.removeEventListener("wheel", onWheel);
|
|
761
|
+
stop();
|
|
762
|
+
};
|
|
763
|
+
}, [ref, enabled]);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
export {
|
|
767
|
+
refreshMotion,
|
|
768
|
+
setMotionFrameRate,
|
|
769
|
+
subscribeTick,
|
|
770
|
+
getMotionStats,
|
|
771
|
+
useDecoration,
|
|
772
|
+
useBorder,
|
|
773
|
+
useTick,
|
|
774
|
+
usePauseOffscreen,
|
|
775
|
+
useTabShape,
|
|
776
|
+
useSmoothWheel
|
|
777
|
+
};
|