@hh.ru/magritte-ui-nav-bar 1.0.1

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.
Files changed (79) hide show
  1. package/NavBar-CrD8CEWb.js +118 -0
  2. package/NavBar-CrD8CEWb.js.map +1 -0
  3. package/index.css +289 -0
  4. package/index.d.ts +9 -0
  5. package/index.js +35 -0
  6. package/index.js.map +1 -0
  7. package/index.mock.d.ts +17 -0
  8. package/index.mock.js +47 -0
  9. package/index.mock.js.map +1 -0
  10. package/internal/KeyedSubscriptions.d.ts +41 -0
  11. package/internal/KeyedSubscriptions.js +79 -0
  12. package/internal/KeyedSubscriptions.js.map +1 -0
  13. package/internal/MetricsProvider.d.ts +77 -0
  14. package/internal/MetricsProvider.js +275 -0
  15. package/internal/MetricsProvider.js.map +1 -0
  16. package/internal/MorphStore.d.ts +10 -0
  17. package/internal/MorphStore.js +36 -0
  18. package/internal/MorphStore.js.map +1 -0
  19. package/internal/PaneStore.d.ts +60 -0
  20. package/internal/PaneStore.js +102 -0
  21. package/internal/PaneStore.js.map +1 -0
  22. package/internal/ProgressiveBlur.d.ts +7 -0
  23. package/internal/ProgressiveBlur.js +43 -0
  24. package/internal/ProgressiveBlur.js.map +1 -0
  25. package/internal/useAnimationRanges.d.ts +38 -0
  26. package/internal/useAnimationRanges.js +52 -0
  27. package/internal/useAnimationRanges.js.map +1 -0
  28. package/internal/useBindScrollToAnimationProgress.d.ts +9 -0
  29. package/internal/useBindScrollToAnimationProgress.js +82 -0
  30. package/internal/useBindScrollToAnimationProgress.js.map +1 -0
  31. package/internal/useDivider.d.ts +4 -0
  32. package/internal/useDivider.js +38 -0
  33. package/internal/useDivider.js.map +1 -0
  34. package/internal/useNavBarMetrics.d.ts +9 -0
  35. package/internal/useNavBarMetrics.js +34 -0
  36. package/internal/useNavBarMetrics.js.map +1 -0
  37. package/internal/useResetFocus.d.ts +3 -0
  38. package/internal/useResetFocus.js +31 -0
  39. package/internal/useResetFocus.js.map +1 -0
  40. package/internal/useScrollAdapter.d.ts +15 -0
  41. package/internal/useScrollAdapter.js +116 -0
  42. package/internal/useScrollAdapter.js.map +1 -0
  43. package/internal/useSnapScroll.d.ts +6 -0
  44. package/internal/useSnapScroll.js +148 -0
  45. package/internal/useSnapScroll.js.map +1 -0
  46. package/internal/useSyncMotionValue.d.ts +2 -0
  47. package/internal/useSyncMotionValue.js +9 -0
  48. package/internal/useSyncMotionValue.js.map +1 -0
  49. package/internal/utils.d.ts +207 -0
  50. package/internal/utils.js +359 -0
  51. package/internal/utils.js.map +1 -0
  52. package/package.json +38 -0
  53. package/public/Actions.d.ts +26 -0
  54. package/public/Actions.js +47 -0
  55. package/public/Actions.js.map +1 -0
  56. package/public/EnvironmentFingerprintNode.d.ts +7 -0
  57. package/public/EnvironmentFingerprintNode.js +70 -0
  58. package/public/EnvironmentFingerprintNode.js.map +1 -0
  59. package/public/LayoutMorph.d.ts +32 -0
  60. package/public/LayoutMorph.js +132 -0
  61. package/public/LayoutMorph.js.map +1 -0
  62. package/public/LayoutStage.d.ts +7 -0
  63. package/public/LayoutStage.js +87 -0
  64. package/public/LayoutStage.js.map +1 -0
  65. package/public/Morph.d.ts +28 -0
  66. package/public/Morph.js +66 -0
  67. package/public/Morph.js.map +1 -0
  68. package/public/NavBar.d.ts +57 -0
  69. package/public/NavBar.js +21 -0
  70. package/public/NavBar.js.map +1 -0
  71. package/public/Pane.d.ts +22 -0
  72. package/public/Pane.js +79 -0
  73. package/public/Pane.js.map +1 -0
  74. package/public/Stage.d.ts +10 -0
  75. package/public/Stage.js +43 -0
  76. package/public/Stage.js.map +1 -0
  77. package/public/TitleContainer.d.ts +24 -0
  78. package/public/TitleContainer.js +34 -0
  79. package/public/TitleContainer.js.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvironmentFingerprintNode.js","sources":["../../src/public/EnvironmentFingerprintNode.tsx"],"sourcesContent":["import {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useLayoutEffect,\n useRef,\n type RefCallback,\n type HTMLAttributes,\n type PropsWithChildren,\n type FC,\n type MutableRefObject,\n} from 'react';\n\nimport { useMeasureFingerprint } from '@hh.ru/magritte-ui-nav-bar/internal/MetricsProvider';\nimport { isDOMRectsEqual, scheduleMicro, useActualRef, useInitOnce } from '@hh.ru/magritte-ui-nav-bar/internal/utils';\n\ntype FingerprintContextValue = { registerCallback: (cb: VoidFunction) => VoidFunction; notify: VoidFunction };\nconst FingerprintContext = createContext<FingerprintContextValue | null>(null);\n\nexport type EnvironmentFingerprintNodeProps = PropsWithChildren<HTMLAttributes<HTMLDivElement>>;\nexport const EnvironmentFingerprintNode = forwardRef<HTMLDivElement, EnvironmentFingerprintNodeProps>(\n ({ children, ...rest }, ref) => {\n const ctx = useContext(FingerprintContext);\n if (!ctx) {\n throw new Error('EnvironmentFingerprintNode must be used inside EnvironmentFingerprintProvider');\n }\n const rootRef = useRef<HTMLDivElement | null>();\n const rootRefCallback = useCallback<RefCallback<HTMLDivElement>>(\n (element) => {\n rootRef.current = element;\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n !!ref && (typeof ref === 'function' ? ref(element) : (ref.current = element));\n },\n [ref]\n );\n const rectRef: MutableRefObject<DOMRectReadOnly | null> = useRef(null);\n\n useMeasureFingerprint(rootRef, (rect) => {\n if (!isDOMRectsEqual(rect, rectRef.current)) {\n rectRef.current = rect;\n ctx.notify();\n }\n });\n\n return (\n <div ref={rootRefCallback} {...rest}>\n {children}\n </div>\n );\n }\n);\n\nEnvironmentFingerprintNode.displayName = 'EnvironmentFingerprintNode';\n\nexport const EnvironmentFingerprintProvider: FC<PropsWithChildren> = ({ children }) => {\n const contextValue = useInitOnce(() => {\n const callbacks = new Set<VoidFunction>();\n // Ожидаем что изменения по фингерпринтам могут прилетать не чаще одного раза за тик\n // (потому что они генерятся только ResizeObserver). При этом элементов может измениться сразу несколько,\n // каждый коллбек нам нужно вызвать только один раз. Есть два варианта этого добиться:\n // - обернуть вызов коллбеков в schedule, но тогда они вызовутся не синхронно, а в следующей микротаске\n // - добавить флаг который предотвращает повторную нотификацию в тике и вызвать коллбеки синхронно\n // Синхронный вызов коллбеков позволяет эффективнее снимать метрики в одном цикле измерений,\n // поэтому выбран этот вариант - синхронизация через флаг.\n let notified = false;\n const resetNotified = scheduleMicro(() => (notified = false));\n return {\n registerCallback: (cb: VoidFunction) => {\n callbacks.add(cb);\n return () => callbacks.delete(cb);\n },\n notify: () => {\n if (notified) {\n return;\n }\n notified = true;\n resetNotified();\n callbacks.forEach((cb) => cb());\n },\n };\n });\n\n return <FingerprintContext.Provider value={contextValue}>{children}</FingerprintContext.Provider>;\n};\n\nEnvironmentFingerprintProvider.displayName = 'EnvironmentFingerprintProvider';\n\nexport const useEnvironmentFingerprint = (onChange: VoidFunction): void => {\n const ctx = useContext(FingerprintContext);\n const onChangeRef = useActualRef(onChange);\n const callback = useInitOnce(() => () => onChangeRef.current());\n\n if (!ctx) {\n throw new Error('useEnvironmentFingerprint must be used inside EnvironmentFingerprintProvider');\n }\n\n useLayoutEffect(() => ctx.registerCallback(callback), [ctx, callback]);\n};\n"],"names":["_jsx"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { type FC, type PropsWithChildren } from 'react';
2
+ import { type HTMLMotionProps } from 'motion/react';
3
+ import { type HorizontalAlign, type SizeAxis, type VerticalAlign } from '@hh.ru/magritte-ui-nav-bar/internal/utils';
4
+ export type LayoutMorphProps = PropsWithChildren<{
5
+ /**
6
+ * Задает стадию анимации на которой элемент будет виден.
7
+ * Если не задан, то элемент будет виден на протяжении всей анимации.
8
+ */
9
+ stage?: 'start' | 'end';
10
+ /**
11
+ * Позволяет анимировать элементы через морфинг, задав между ними связь с помощью указания одинакового `id`
12
+ * и разных `stage`
13
+ */
14
+ id?: string;
15
+ /**
16
+ * Задает ось на основе которой будет вычисляться коэффициент масштабирования применяемый в ходе анимации.
17
+ * В режиме `both` для каждой из осей применяется свой коэффициент что может привести к искажению пропорций в ходе
18
+ * анимации.
19
+ * В режиме `auto` применяется эвристика для выбора одного из трех остальных режимов для получения наилучшего
20
+ * результат и минимизации искажения пропорций.
21
+ */
22
+ sizeAxis?: SizeAxis;
23
+ /**
24
+ * Задает горизонтальное выравнивание анимируемых элементов в ходе анимации.
25
+ */
26
+ horizontalPositionAlign?: HorizontalAlign;
27
+ /**
28
+ * Задает вертикальное выравнивание анимируемых элементов в ходе анимации.
29
+ */
30
+ verticalPositionAlign?: VerticalAlign;
31
+ } & HTMLMotionProps<'div'>>;
32
+ export declare const LayoutMorph: FC<LayoutMorphProps>;
@@ -0,0 +1,132 @@
1
+ import './../index.css';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { createContext, useId, useRef, useContext, useLayoutEffect } from 'react';
4
+ import classNames from 'classnames';
5
+ import { useMotionValue, motion } from 'motion/react';
6
+ import { useMeasureManual } from '../internal/MetricsProvider.js';
7
+ import { useMorphStore } from '../internal/MorphStore.js';
8
+ import { usePaneStore } from '../internal/PaneStore.js';
9
+ import { useActualRef, useStoreSyncedTransform, lerp, calcMorphParams } from '../internal/utils.js';
10
+ import { AnimationStageContext } from './LayoutStage.js';
11
+ import { s as styles } from '../NavBar-CrD8CEWb.js';
12
+ import '../internal/KeyedSubscriptions.js';
13
+ import 'motion';
14
+ import '@hh.ru/magritte-common-use-when-font-loaded';
15
+ import './EnvironmentFingerprintNode.js';
16
+ import '@hh.ru/magritte-ui-divider';
17
+ import '@hh.ru/magritte-ui-layer';
18
+ import '../internal/ProgressiveBlur.js';
19
+ import '../internal/useAnimationRanges.js';
20
+ import '../internal/useBindScrollToAnimationProgress.js';
21
+ import '../internal/useDivider.js';
22
+ import '../internal/useNavBarMetrics.js';
23
+ import '../internal/useResetFocus.js';
24
+ import '../internal/useScrollAdapter.js';
25
+ import '@hh.ru/magritte-internal-custom-scroll';
26
+ import '../internal/useSnapScroll.js';
27
+ import '../internal/useSyncMotionValue.js';
28
+
29
+ const startKey = (id) => `${id}-start`;
30
+ const endKey = (id) => `${id}-end`;
31
+ const LayoutMorphContext = createContext('#container');
32
+ const useLayoutMorphContext = () => useContext(LayoutMorphContext);
33
+ const calcParams = (setup, sizeAxis, horizontalPositionAlign, verticalPositionAlign) => {
34
+ const start = DOMRect.fromRect(setup.start);
35
+ start.x -= setup.containerStart.x;
36
+ start.y -= setup.containerStart.y;
37
+ const end = DOMRect.fromRect(setup.end);
38
+ end.x -= setup.containerEnd.x;
39
+ end.y -= setup.containerEnd.y;
40
+ return calcMorphParams(start, end, sizeAxis, horizontalPositionAlign, verticalPositionAlign);
41
+ };
42
+ const LayoutMorph = ({ children, stage, id: manualId, sizeAxis = 'auto', verticalPositionAlign = 'center', horizontalPositionAlign = 'center', ...rest }) => {
43
+ const id = useId();
44
+ const rootRef = useRef(null);
45
+ const animationStageRef = useContext(AnimationStageContext);
46
+ const morphStore = useMorphStore();
47
+ const paneStore = usePaneStore();
48
+ const width = useMotionValue('auto');
49
+ const height = useMotionValue('auto');
50
+ const x = useMotionValue(0);
51
+ const y = useMotionValue(0);
52
+ const scaleX = useMotionValue(1);
53
+ const scaleY = useMotionValue(1);
54
+ const opacity = useMotionValue(stage !== 'end' ? 1 : 0);
55
+ const pointerEvents = useMotionValue('auto');
56
+ const childRef = useRef(null);
57
+ const containerId = useLayoutMorphContext();
58
+ useLayoutEffect(() => {
59
+ if (!rootRef.current || !rootRef.current.firstChild) {
60
+ return;
61
+ }
62
+ if (rootRef.current.children.length > 1) {
63
+ throw new Error('LayoutMorph expects exactly one child HTML element. Please wrap multiple children in a container.');
64
+ }
65
+ childRef.current = rootRef.current.firstChild;
66
+ }, []);
67
+ const isManual = !!manualId && !!stage;
68
+ const actualIdRef = useActualRef(isManual ? manualId : id);
69
+ useStoreSyncedTransform(paneStore.get('motionValue'), morphStore, [startKey(id), endKey(id), startKey(containerId), endKey(containerId)], () => {
70
+ const basicRect = new DOMRectReadOnly();
71
+ const sk = stage === 'end' ? endKey : startKey;
72
+ const ek = stage === 'end' ? startKey : endKey;
73
+ const setup = {
74
+ start: morphStore.get(sk(actualIdRef.current)) ?? basicRect,
75
+ end: morphStore.get(ek(actualIdRef.current)) ?? basicRect,
76
+ containerStart: morphStore.get(sk(containerId)) ?? basicRect,
77
+ containerEnd: morphStore.get(ek(containerId)) ?? basicRect,
78
+ };
79
+ const params = calcParams(setup, isManual ? sizeAxis : 'both', isManual ? horizontalPositionAlign : 'left', isManual ? verticalPositionAlign : 'top');
80
+ const startX = setup.start.x - setup.containerStart.x;
81
+ const startY = setup.start.y - setup.containerStart.y;
82
+ if (isManual) {
83
+ width.set(setup.start.width);
84
+ height.set(setup.start.height);
85
+ return (progress) => {
86
+ const p = stage === 'end' ? 1 - progress : progress;
87
+ x.set(lerp(startX, startX + params.deltaX, p));
88
+ y.set(lerp(startY, startY + params.deltaY, p));
89
+ scaleX.set(lerp(1, params.scaleX, p));
90
+ scaleY.set(lerp(1, params.scaleY, p));
91
+ pointerEvents.set(p === 0 || (p === 1 && !stage) ? 'auto' : 'none');
92
+ stage && opacity.set(1 - p);
93
+ };
94
+ }
95
+ scaleX.set(1);
96
+ scaleY.set(1);
97
+ return (progress) => {
98
+ const p = stage === 'end' ? 1 - progress : progress;
99
+ x.set(lerp(startX, startX + params.deltaX, p));
100
+ y.set(lerp(startY, startY + params.deltaY, p));
101
+ width.set(lerp(setup.start.width, setup.start.width * params.scaleX, p));
102
+ height.set(lerp(setup.start.height, setup.start.height * params.scaleY, p));
103
+ pointerEvents.set(p === 0 || (p === 1 && !stage) ? 'auto' : 'none');
104
+ stage && opacity.set(1 - p);
105
+ };
106
+ }, (interpolator, progress) => interpolator(progress));
107
+ useMeasureManual(childRef, (rect) => {
108
+ if (animationStageRef.current === 'start') {
109
+ (stage === 'start' || !stage) && morphStore.set(startKey(actualIdRef.current), rect);
110
+ // если элемент виден только в начальной или конечной точке анимации, то его позиция и размер
111
+ // не меняются в процессе анимации, только прозрачность
112
+ stage === 'start' && morphStore.set(endKey(actualIdRef.current), rect);
113
+ }
114
+ else if (animationStageRef.current === 'end') {
115
+ (stage === 'end' || !stage) && morphStore.set(endKey(actualIdRef.current), rect);
116
+ if ((!isManual || morphStore.get(startKey(actualIdRef.current)) === null) && stage === 'end') {
117
+ morphStore.set(startKey(actualIdRef.current), rect);
118
+ }
119
+ }
120
+ });
121
+ return (jsx(motion.div, { ...rest, ref: rootRef, className: classNames(styles.layoutMorph, {
122
+ [styles.layoutMorphStart]: stage === 'start',
123
+ [styles.layoutMorphEnd]: stage === 'end',
124
+ [styles.morphItemTop]: verticalPositionAlign === 'top' && isManual,
125
+ [styles.morphItemBottom]: verticalPositionAlign === 'bottom' && isManual,
126
+ [styles.morphItemLeft]: horizontalPositionAlign === 'left' && isManual,
127
+ [styles.morphItemRight]: horizontalPositionAlign === 'right' && isManual,
128
+ }), style: { width, height, x, y, scaleX, scaleY, opacity, pointerEvents }, children: jsx(LayoutMorphContext.Provider, { value: id, children: children }) }));
129
+ };
130
+
131
+ export { LayoutMorph };
132
+ //# sourceMappingURL=LayoutMorph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayoutMorph.js","sources":["../../src/public/LayoutMorph.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useId,\n useLayoutEffect,\n useRef,\n type FC,\n type MutableRefObject,\n type PropsWithChildren,\n} from 'react';\nimport classNames from 'classnames';\nimport { type HTMLMotionProps, motion, useMotionValue } from 'motion/react';\n\nimport { useMeasureManual } from '@hh.ru/magritte-ui-nav-bar/internal/MetricsProvider';\nimport { useMorphStore } from '@hh.ru/magritte-ui-nav-bar/internal/MorphStore';\nimport { usePaneStore } from '@hh.ru/magritte-ui-nav-bar/internal/PaneStore';\nimport {\n lerp,\n useActualRef,\n useStoreSyncedTransform,\n calcMorphParams,\n type MorphSetup,\n type HorizontalAlign,\n type SizeAxis,\n type VerticalAlign,\n} from '@hh.ru/magritte-ui-nav-bar/internal/utils';\nimport { AnimationStageContext } from '@hh.ru/magritte-ui-nav-bar/public/LayoutStage';\n\nimport styles from './nav-bar.less';\n\nconst startKey = (id: string) => `${id}-start`;\nconst endKey = (id: string) => `${id}-end`;\n\nconst LayoutMorphContext = createContext<string>('#container');\nconst useLayoutMorphContext = () => useContext(LayoutMorphContext);\n\nconst calcParams = (\n setup: MorphSetup,\n sizeAxis: SizeAxis,\n horizontalPositionAlign: HorizontalAlign,\n verticalPositionAlign: VerticalAlign\n) => {\n const start = DOMRect.fromRect(setup.start);\n start.x -= setup.containerStart.x;\n start.y -= setup.containerStart.y;\n\n const end = DOMRect.fromRect(setup.end);\n end.x -= setup.containerEnd.x;\n end.y -= setup.containerEnd.y;\n\n return calcMorphParams(start, end, sizeAxis, horizontalPositionAlign, verticalPositionAlign);\n};\n\nexport type LayoutMorphProps = PropsWithChildren<\n {\n /**\n * Задает стадию анимации на которой элемент будет виден.\n * Если не задан, то элемент будет виден на протяжении всей анимации.\n */\n stage?: 'start' | 'end';\n /**\n * Позволяет анимировать элементы через морфинг, задав между ними связь с помощью указания одинакового `id`\n * и разных `stage`\n */\n id?: string;\n /**\n * Задает ось на основе которой будет вычисляться коэффициент масштабирования применяемый в ходе анимации.\n * В режиме `both` для каждой из осей применяется свой коэффициент что может привести к искажению пропорций в ходе\n * анимации.\n * В режиме `auto` применяется эвристика для выбора одного из трех остальных режимов для получения наилучшего\n * результат и минимизации искажения пропорций.\n */\n sizeAxis?: SizeAxis;\n /**\n * Задает горизонтальное выравнивание анимируемых элементов в ходе анимации.\n */\n horizontalPositionAlign?: HorizontalAlign;\n /**\n * Задает вертикальное выравнивание анимируемых элементов в ходе анимации.\n */\n verticalPositionAlign?: VerticalAlign;\n } & HTMLMotionProps<'div'>\n>;\n\nexport const LayoutMorph: FC<LayoutMorphProps> = ({\n children,\n stage,\n id: manualId,\n sizeAxis = 'auto',\n verticalPositionAlign = 'center',\n horizontalPositionAlign = 'center',\n ...rest\n}) => {\n const id = useId();\n const rootRef = useRef<HTMLDivElement>(null);\n const animationStageRef = useContext(AnimationStageContext);\n const morphStore = useMorphStore();\n const paneStore = usePaneStore();\n\n const width = useMotionValue<'auto' | number>('auto');\n const height = useMotionValue<'auto' | number>('auto');\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n const scaleX = useMotionValue(1);\n const scaleY = useMotionValue(1);\n const opacity = useMotionValue(stage !== 'end' ? 1 : 0);\n const pointerEvents = useMotionValue<'auto' | 'none'>('auto');\n\n const childRef: MutableRefObject<HTMLElement | null> = useRef(null);\n\n const containerId = useLayoutMorphContext();\n\n useLayoutEffect(() => {\n if (!rootRef.current || !rootRef.current.firstChild) {\n return;\n }\n if (rootRef.current.children.length > 1) {\n throw new Error(\n 'LayoutMorph expects exactly one child HTML element. Please wrap multiple children in a container.'\n );\n }\n childRef.current = rootRef.current.firstChild as HTMLElement;\n }, []);\n\n const isManual = !!manualId && !!stage;\n\n const actualIdRef = useActualRef(isManual ? manualId : id);\n\n useStoreSyncedTransform(\n paneStore.get('motionValue'),\n morphStore,\n [startKey(id), endKey(id), startKey(containerId), endKey(containerId)],\n () => {\n const basicRect = new DOMRectReadOnly();\n const sk = stage === 'end' ? endKey : startKey;\n const ek = stage === 'end' ? startKey : endKey;\n const setup = {\n start: morphStore.get(sk(actualIdRef.current)) ?? basicRect,\n end: morphStore.get(ek(actualIdRef.current)) ?? basicRect,\n containerStart: morphStore.get(sk(containerId)) ?? basicRect,\n containerEnd: morphStore.get(ek(containerId)) ?? basicRect,\n };\n\n const params = calcParams(\n setup,\n isManual ? sizeAxis : 'both',\n isManual ? horizontalPositionAlign : 'left',\n isManual ? verticalPositionAlign : 'top'\n );\n const startX = setup.start.x - setup.containerStart.x;\n const startY = setup.start.y - setup.containerStart.y;\n\n if (isManual) {\n width.set(setup.start.width);\n height.set(setup.start.height);\n return (progress: number) => {\n const p = stage === 'end' ? 1 - progress : progress;\n x.set(lerp(startX, startX + params.deltaX, p));\n y.set(lerp(startY, startY + params.deltaY, p));\n scaleX.set(lerp(1, params.scaleX, p));\n scaleY.set(lerp(1, params.scaleY, p));\n pointerEvents.set(p === 0 || (p === 1 && !stage) ? 'auto' : 'none');\n stage && opacity.set(1 - p);\n };\n }\n\n scaleX.set(1);\n scaleY.set(1);\n return (progress: number) => {\n const p = stage === 'end' ? 1 - progress : progress;\n x.set(lerp(startX, startX + params.deltaX, p));\n y.set(lerp(startY, startY + params.deltaY, p));\n width.set(lerp(setup.start.width, setup.start.width * params.scaleX, p));\n height.set(lerp(setup.start.height, setup.start.height * params.scaleY, p));\n pointerEvents.set(p === 0 || (p === 1 && !stage) ? 'auto' : 'none');\n stage && opacity.set(1 - p);\n };\n },\n (interpolator, progress) => interpolator(progress)\n );\n\n useMeasureManual(childRef, (rect) => {\n if (animationStageRef.current === 'start') {\n (stage === 'start' || !stage) && morphStore.set(startKey(actualIdRef.current), rect);\n // если элемент виден только в начальной или конечной точке анимации, то его позиция и размер\n // не меняются в процессе анимации, только прозрачность\n stage === 'start' && morphStore.set(endKey(actualIdRef.current), rect);\n } else if (animationStageRef.current === 'end') {\n (stage === 'end' || !stage) && morphStore.set(endKey(actualIdRef.current), rect);\n if ((!isManual || morphStore.get(startKey(actualIdRef.current)) === null) && stage === 'end') {\n morphStore.set(startKey(actualIdRef.current), rect);\n }\n }\n });\n\n return (\n <motion.div\n {...rest}\n ref={rootRef}\n className={classNames(styles.layoutMorph, {\n [styles.layoutMorphStart]: stage === 'start',\n [styles.layoutMorphEnd]: stage === 'end',\n [styles.morphItemTop]: verticalPositionAlign === 'top' && isManual,\n [styles.morphItemBottom]: verticalPositionAlign === 'bottom' && isManual,\n [styles.morphItemLeft]: horizontalPositionAlign === 'left' && isManual,\n [styles.morphItemRight]: horizontalPositionAlign === 'right' && isManual,\n })}\n style={{ width, height, x, y, scaleX, scaleY, opacity, pointerEvents }}\n >\n <LayoutMorphContext.Provider value={id}>{children}</LayoutMorphContext.Provider>\n </motion.div>\n );\n};\n"],"names":["_jsx"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type FC, type MutableRefObject, type PropsWithChildren } from 'react';
2
+ import { HTMLMotionProps } from 'motion/react';
3
+ export declare const CONTAINER_START_KEY = "#container-start";
4
+ export declare const CONTAINER_END_KEY = "#container-end";
5
+ export type AnimationStage = 'start' | 'end' | 'progress';
6
+ export declare const AnimationStageContext: import("react").Context<MutableRefObject<AnimationStage | null>>;
7
+ export declare const LayoutStage: FC<PropsWithChildren<HTMLMotionProps<'div'>>>;
@@ -0,0 +1,87 @@
1
+ import './../index.css';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { createContext, createRef, useRef, useContext } from 'react';
4
+ import classNames from 'classnames';
5
+ import { useMotionValue, motion } from 'motion/react';
6
+ import { useWhenFontLoaded } from '@hh.ru/magritte-common-use-when-font-loaded';
7
+ import { MetricsProvider, useRemeasureAllManual, useMeasureManual } from '../internal/MetricsProvider.js';
8
+ import { MorphStoreProvider, useMorphStore } from '../internal/MorphStore.js';
9
+ import { usePaneStore } from '../internal/PaneStore.js';
10
+ import { useInitOnce } from '../internal/utils.js';
11
+ import { EnvironmentFingerprintNode, useEnvironmentFingerprint } from './EnvironmentFingerprintNode.js';
12
+ import { s as styles } from '../NavBar-CrD8CEWb.js';
13
+ import '../internal/KeyedSubscriptions.js';
14
+ import 'motion';
15
+ import '@hh.ru/magritte-ui-divider';
16
+ import '@hh.ru/magritte-ui-layer';
17
+ import '../internal/ProgressiveBlur.js';
18
+ import '../internal/useAnimationRanges.js';
19
+ import '../internal/useBindScrollToAnimationProgress.js';
20
+ import '../internal/useDivider.js';
21
+ import '../internal/useNavBarMetrics.js';
22
+ import '../internal/useResetFocus.js';
23
+ import '../internal/useScrollAdapter.js';
24
+ import '@hh.ru/magritte-internal-custom-scroll';
25
+ import '../internal/useSnapScroll.js';
26
+ import '../internal/useSyncMotionValue.js';
27
+
28
+ const CONTAINER_START_KEY = '#container-start';
29
+ const CONTAINER_END_KEY = '#container-end';
30
+ const AnimationStageContext = createContext(createRef());
31
+ const stageClasses = {
32
+ start: 'nav-bar-layout-animation-stage-start',
33
+ end: 'nav-bar-layout-animation-stage-end',
34
+ progress: styles.animationStageProgress,
35
+ };
36
+ const CombinedStageAnimationMeasurementManager = ({ children, ...rest }) => {
37
+ const wrapperRef = useRef(null);
38
+ const animationStageRef = useContext(AnimationStageContext);
39
+ const morphStore = useMorphStore();
40
+ const currentClassRef = useRef(stageClasses.start);
41
+ const paneStore = usePaneStore();
42
+ const forceMeasure = useRemeasureAllManual();
43
+ const setStage = useInitOnce(() => (stage) => {
44
+ if (!wrapperRef.current) {
45
+ return;
46
+ }
47
+ for (const animClasses of Object.entries(stageClasses)) {
48
+ wrapperRef.current.classList.toggle(animClasses[1], stage === animClasses[0]);
49
+ }
50
+ currentClassRef.current = stageClasses[stage];
51
+ animationStageRef.current = stage;
52
+ });
53
+ const measureSubtree = useInitOnce(() => () => {
54
+ setStage('start');
55
+ forceMeasure();
56
+ setStage('end');
57
+ forceMeasure();
58
+ setStage('progress');
59
+ });
60
+ const height = useMotionValue('auto');
61
+ useMeasureManual(wrapperRef, (rect) => {
62
+ if (animationStageRef.current === 'start') {
63
+ height.set(rect.height);
64
+ // height из MotionValue применится к DOM асинхронно, поэтому применяем высоту синхронно
65
+ // чтобы не триггерить ResizeObserver когда сбросим у элементов position в absolute
66
+ if (wrapperRef.current) {
67
+ wrapperRef.current.style.height = `${rect.height}px`;
68
+ }
69
+ paneStore.set({ top: rect.top, startHeight: rect.height });
70
+ morphStore.set(CONTAINER_START_KEY, rect);
71
+ }
72
+ else {
73
+ paneStore.set({ endHeight: rect.height });
74
+ morphStore.set(CONTAINER_END_KEY, rect);
75
+ }
76
+ });
77
+ useEnvironmentFingerprint(measureSubtree);
78
+ useWhenFontLoaded(() => height.get() !== 'auto' && measureSubtree());
79
+ return (jsx(motion.div, { ref: wrapperRef, ...rest, className: classNames(styles.layoutAnimationContainer, currentClassRef.current), style: { height }, children: children }));
80
+ };
81
+ const LayoutStage = ({ children, ...rest }) => {
82
+ const stageRef = useRef('start');
83
+ return (jsx(EnvironmentFingerprintNode, { style: { pointerEvents: 'auto' }, children: jsx(MorphStoreProvider, { children: jsx(AnimationStageContext.Provider, { value: stageRef, children: jsx(MetricsProvider, { children: jsx(CombinedStageAnimationMeasurementManager, { ...rest, children: children }) }) }) }) }));
84
+ };
85
+
86
+ export { AnimationStageContext, CONTAINER_END_KEY, CONTAINER_START_KEY, LayoutStage };
87
+ //# sourceMappingURL=LayoutStage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayoutStage.js","sources":["../../src/public/LayoutStage.tsx"],"sourcesContent":["import {\n createContext,\n createRef,\n useContext,\n useRef,\n type FC,\n type MutableRefObject,\n type PropsWithChildren,\n} from 'react';\nimport classNames from 'classnames';\nimport { HTMLMotionProps, motion, useMotionValue } from 'motion/react';\n\nimport { useWhenFontLoaded } from '@hh.ru/magritte-common-use-when-font-loaded';\nimport {\n MetricsProvider,\n useMeasureManual,\n useRemeasureAllManual,\n} from '@hh.ru/magritte-ui-nav-bar/internal/MetricsProvider';\nimport { MorphStoreProvider, useMorphStore } from '@hh.ru/magritte-ui-nav-bar/internal/MorphStore';\nimport { usePaneStore } from '@hh.ru/magritte-ui-nav-bar/internal/PaneStore';\nimport { useInitOnce } from '@hh.ru/magritte-ui-nav-bar/internal/utils';\nimport {\n EnvironmentFingerprintNode,\n useEnvironmentFingerprint,\n} from '@hh.ru/magritte-ui-nav-bar/public/EnvironmentFingerprintNode';\n\nimport styles from './nav-bar.less';\n\nexport const CONTAINER_START_KEY = '#container-start';\nexport const CONTAINER_END_KEY = '#container-end';\n\nexport type AnimationStage = 'start' | 'end' | 'progress';\n\nexport const AnimationStageContext = createContext<MutableRefObject<AnimationStage | null>>(createRef());\n\nconst stageClasses = {\n start: 'nav-bar-layout-animation-stage-start',\n end: 'nav-bar-layout-animation-stage-end',\n progress: styles.animationStageProgress,\n} as const;\n\nconst CombinedStageAnimationMeasurementManager: FC<PropsWithChildren<HTMLMotionProps<'div'>>> = ({\n children,\n ...rest\n}) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const animationStageRef = useContext(AnimationStageContext);\n const morphStore = useMorphStore();\n const currentClassRef = useRef<string>(stageClasses.start);\n const paneStore = usePaneStore();\n const forceMeasure = useRemeasureAllManual();\n const setStage = useInitOnce(() => (stage: AnimationStage) => {\n if (!wrapperRef.current) {\n return;\n }\n\n for (const animClasses of Object.entries(stageClasses)) {\n wrapperRef.current.classList.toggle(animClasses[1], stage === animClasses[0]);\n }\n currentClassRef.current = stageClasses[stage];\n animationStageRef.current = stage;\n });\n const measureSubtree = useInitOnce(() => () => {\n setStage('start');\n forceMeasure();\n setStage('end');\n forceMeasure();\n setStage('progress');\n });\n\n const height = useMotionValue<number | 'auto'>('auto');\n\n useMeasureManual(wrapperRef, (rect) => {\n if (animationStageRef.current === 'start') {\n height.set(rect.height);\n // height из MotionValue применится к DOM асинхронно, поэтому применяем высоту синхронно\n // чтобы не триггерить ResizeObserver когда сбросим у элементов position в absolute\n if (wrapperRef.current) {\n wrapperRef.current.style.height = `${rect.height}px`;\n }\n paneStore.set({ top: rect.top, startHeight: rect.height });\n morphStore.set(CONTAINER_START_KEY, rect);\n } else {\n paneStore.set({ endHeight: rect.height });\n morphStore.set(CONTAINER_END_KEY, rect);\n }\n });\n\n useEnvironmentFingerprint(measureSubtree);\n useWhenFontLoaded(() => height.get() !== 'auto' && measureSubtree());\n\n return (\n <motion.div\n ref={wrapperRef}\n {...rest}\n className={classNames(styles.layoutAnimationContainer, currentClassRef.current)}\n style={{ height }}\n >\n {children}\n </motion.div>\n );\n};\n\nexport const LayoutStage: FC<PropsWithChildren<HTMLMotionProps<'div'>>> = ({ children, ...rest }) => {\n const stageRef = useRef<AnimationStage | null>('start');\n\n return (\n <EnvironmentFingerprintNode style={{ pointerEvents: 'auto' }}>\n <MorphStoreProvider>\n <AnimationStageContext.Provider value={stageRef}>\n <MetricsProvider>\n <CombinedStageAnimationMeasurementManager {...rest}>\n {children}\n </CombinedStageAnimationMeasurementManager>\n </MetricsProvider>\n </AnimationStageContext.Provider>\n </MorphStoreProvider>\n </EnvironmentFingerprintNode>\n );\n};\n"],"names":["_jsx"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type PropsWithChildren, type FC, type CSSProperties } from 'react';
2
+ import { HTMLMotionProps } from 'motion/react';
3
+ import { type HorizontalAlign, type SizeAxis, type VerticalAlign } from '@hh.ru/magritte-ui-nav-bar/internal/utils';
4
+ export interface MorphProps extends HTMLMotionProps<'div'> {
5
+ /**
6
+ * Задает соответствие между элементами для морфинга между начальным и конечным <Stage />
7
+ */
8
+ id: string;
9
+ style?: CSSProperties;
10
+ className?: string;
11
+ /**
12
+ * Задает ось на основе которой будет вычисляться коэффициент масштабирования применяемый в ходе анимации.
13
+ * В режиме `both` для каждой из осей применяется свой коэффициент что может привести к искажению пропорций в ходе
14
+ * анимации.
15
+ * В режиме `auto` применяется эвристика для выбора одного из трех остальных режимов для получения наилучшего
16
+ * результат и минимизации искажения пропорций.
17
+ */
18
+ sizeAxis?: SizeAxis;
19
+ /**
20
+ * Задает горизонтальное выравнивание анимируемых элементов в ходе анимации.
21
+ */
22
+ horizontalPositionAlign?: HorizontalAlign;
23
+ /**
24
+ * Задает вертикальное выравнивание анимируемых элементов в ходе анимации.
25
+ */
26
+ verticalPositionAlign?: VerticalAlign;
27
+ }
28
+ export declare const Morph: FC<PropsWithChildren<MorphProps>>;
@@ -0,0 +1,66 @@
1
+ import './../index.css';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { useRef, useLayoutEffect } from 'react';
4
+ import classNames from 'classnames';
5
+ import { useMotionValue, motion } from 'motion/react';
6
+ import { useMeasureAuto } from '../internal/MetricsProvider.js';
7
+ import { useMorphStore } from '../internal/MorphStore.js';
8
+ import { usePaneStore } from '../internal/PaneStore.js';
9
+ import { useStoreSyncedTransform, calcMorphParams, lerp } from '../internal/utils.js';
10
+ import { useEnvironmentFingerprint } from './EnvironmentFingerprintNode.js';
11
+ import { useAnimationStage } from './Stage.js';
12
+ import { s as styles } from '../NavBar-CrD8CEWb.js';
13
+ import '../internal/KeyedSubscriptions.js';
14
+ import 'motion';
15
+ import '@hh.ru/magritte-ui-divider';
16
+ import '@hh.ru/magritte-ui-layer';
17
+ import '../internal/ProgressiveBlur.js';
18
+ import '../internal/useAnimationRanges.js';
19
+ import '../internal/useBindScrollToAnimationProgress.js';
20
+ import '../internal/useDivider.js';
21
+ import '../internal/useNavBarMetrics.js';
22
+ import '../internal/useResetFocus.js';
23
+ import '../internal/useScrollAdapter.js';
24
+ import '@hh.ru/magritte-internal-custom-scroll';
25
+ import '../internal/useSnapScroll.js';
26
+ import '../internal/useSyncMotionValue.js';
27
+
28
+ const Morph = ({ children, id, className, style, sizeAxis = 'auto', horizontalPositionAlign = 'center', verticalPositionAlign = 'center', ...rest }) => {
29
+ const paneStore = usePaneStore();
30
+ const morphStore = useMorphStore();
31
+ const animationStage = useAnimationStage();
32
+ const rootRef = useRef(null);
33
+ const x = useMotionValue(0);
34
+ const y = useMotionValue(0);
35
+ const scaleX = useMotionValue(1);
36
+ const scaleY = useMotionValue(1);
37
+ const startId = `start-${id}`;
38
+ const endId = `end-${id}`;
39
+ useStoreSyncedTransform(paneStore.get('motionValue'), morphStore, [startId, endId], () => {
40
+ const start = morphStore.get(animationStage === 'end' ? endId : startId);
41
+ const end = morphStore.get(animationStage === 'end' ? startId : endId);
42
+ const { deltaX, deltaY, scaleX: xScale, scaleY: yScale, } = calcMorphParams(start, end, sizeAxis, horizontalPositionAlign, verticalPositionAlign);
43
+ return (progress) => {
44
+ const p = animationStage === 'end' ? 1 - progress : progress;
45
+ x.set(lerp(0, deltaX, p));
46
+ y.set(lerp(0, deltaY, p));
47
+ scaleX.set(lerp(1, xScale, p));
48
+ scaleY.set(lerp(1, yScale, p));
49
+ };
50
+ }, (interpolator, progress) => interpolator(progress));
51
+ const forceInvalidate = useMeasureAuto(rootRef, (rect) => morphStore.set(`${animationStage}-${id}`, rect), [
52
+ id,
53
+ animationStage,
54
+ ]);
55
+ useEnvironmentFingerprint(forceInvalidate);
56
+ useLayoutEffect(() => () => morphStore.set(`${animationStage}-${id}`, null), [morphStore, animationStage, id]);
57
+ return (jsx(motion.div, { ref: rootRef, ...rest, className: classNames(styles.morphItem, className, {
58
+ [styles.morphItemTop]: verticalPositionAlign === 'top',
59
+ [styles.morphItemBottom]: verticalPositionAlign === 'bottom',
60
+ [styles.morphItemLeft]: horizontalPositionAlign === 'left',
61
+ [styles.morphItemRight]: horizontalPositionAlign === 'right',
62
+ }), style: { ...(style ?? {}), x, y, scaleX, scaleY }, children: children }));
63
+ };
64
+
65
+ export { Morph };
66
+ //# sourceMappingURL=Morph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Morph.js","sources":["../../src/public/Morph.tsx"],"sourcesContent":["import { type PropsWithChildren, type FC, useLayoutEffect, useRef, type CSSProperties } from 'react';\nimport classNames from 'classnames';\nimport { useMotionValue, motion, HTMLMotionProps } from 'motion/react';\n\nimport { useMeasureAuto } from '@hh.ru/magritte-ui-nav-bar/internal/MetricsProvider';\nimport { useMorphStore } from '@hh.ru/magritte-ui-nav-bar/internal/MorphStore';\nimport { usePaneStore } from '@hh.ru/magritte-ui-nav-bar/internal/PaneStore';\nimport {\n lerp,\n useStoreSyncedTransform,\n calcMorphParams,\n type HorizontalAlign,\n type SizeAxis,\n type VerticalAlign,\n} from '@hh.ru/magritte-ui-nav-bar/internal/utils';\nimport { useEnvironmentFingerprint } from '@hh.ru/magritte-ui-nav-bar/public/EnvironmentFingerprintNode';\nimport { useAnimationStage } from '@hh.ru/magritte-ui-nav-bar/public/Stage';\n\nimport styles from './nav-bar.less';\n\nexport interface MorphProps extends HTMLMotionProps<'div'> {\n /**\n * Задает соответствие между элементами для морфинга между начальным и конечным <Stage />\n */\n id: string;\n style?: CSSProperties;\n className?: string;\n /**\n * Задает ось на основе которой будет вычисляться коэффициент масштабирования применяемый в ходе анимации.\n * В режиме `both` для каждой из осей применяется свой коэффициент что может привести к искажению пропорций в ходе\n * анимации.\n * В режиме `auto` применяется эвристика для выбора одного из трех остальных режимов для получения наилучшего\n * результат и минимизации искажения пропорций.\n */\n sizeAxis?: SizeAxis;\n /**\n * Задает горизонтальное выравнивание анимируемых элементов в ходе анимации.\n */\n horizontalPositionAlign?: HorizontalAlign;\n /**\n * Задает вертикальное выравнивание анимируемых элементов в ходе анимации.\n */\n verticalPositionAlign?: VerticalAlign;\n}\n\nexport const Morph: FC<PropsWithChildren<MorphProps>> = ({\n children,\n id,\n className,\n style,\n sizeAxis = 'auto',\n horizontalPositionAlign = 'center',\n verticalPositionAlign = 'center',\n ...rest\n}) => {\n const paneStore = usePaneStore();\n const morphStore = useMorphStore();\n const animationStage = useAnimationStage();\n const rootRef = useRef<HTMLDivElement>(null);\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n const scaleX = useMotionValue(1);\n const scaleY = useMotionValue(1);\n\n const startId = `start-${id}`;\n const endId = `end-${id}`;\n\n useStoreSyncedTransform(\n paneStore.get('motionValue'),\n morphStore,\n [startId, endId],\n () => {\n const start = morphStore.get(animationStage === 'end' ? endId : startId);\n const end = morphStore.get(animationStage === 'end' ? startId : endId);\n const {\n deltaX,\n deltaY,\n scaleX: xScale,\n scaleY: yScale,\n } = calcMorphParams(start, end, sizeAxis, horizontalPositionAlign, verticalPositionAlign);\n\n return (progress: number) => {\n const p = animationStage === 'end' ? 1 - progress : progress;\n x.set(lerp(0, deltaX, p));\n y.set(lerp(0, deltaY, p));\n\n scaleX.set(lerp(1, xScale, p));\n scaleY.set(lerp(1, yScale, p));\n };\n },\n (interpolator, progress) => interpolator(progress)\n );\n\n const forceInvalidate = useMeasureAuto(rootRef, (rect) => morphStore.set(`${animationStage}-${id}`, rect), [\n id,\n animationStage,\n ]);\n\n useEnvironmentFingerprint(forceInvalidate);\n\n useLayoutEffect(() => () => morphStore.set(`${animationStage}-${id}`, null), [morphStore, animationStage, id]);\n\n return (\n <motion.div\n ref={rootRef}\n {...rest}\n className={classNames(styles.morphItem, className, {\n [styles.morphItemTop]: verticalPositionAlign === 'top',\n [styles.morphItemBottom]: verticalPositionAlign === 'bottom',\n [styles.morphItemLeft]: horizontalPositionAlign === 'left',\n [styles.morphItemRight]: horizontalPositionAlign === 'right',\n })}\n style={{ ...(style ?? {}), x, y, scaleX, scaleY }}\n >\n {children}\n </motion.div>\n );\n};\n"],"names":["_jsx"],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { type RefObject, type FC } from 'react';
2
+ import { MotionValue } from 'motion/react';
3
+ import { type ShowDivider } from '@hh.ru/magritte-ui-divider';
4
+ import { PaneStore } from '@hh.ru/magritte-ui-nav-bar/internal/PaneStore';
5
+ import { type PaneElement } from '@hh.ru/magritte-ui-nav-bar/public/Pane';
6
+ type PaneStoreContextValue = ((store: PaneStore) => VoidFunction) | null;
7
+ export declare const useNavBarContext: () => PaneStoreContextValue;
8
+ export interface NavBarProps {
9
+ /**
10
+ * В качестве потомков могут передаваться только компоненты <Pane />
11
+ */
12
+ children: PaneElement | PaneElement[];
13
+ /**
14
+ * Управляет режимом прозрачности:
15
+ * -- Прозрачность отключена (`false`)
16
+ * -- Прозрачный всегда (`true`)
17
+ * -- Прозрачный в начале анимации (`start`)
18
+ * -- Прозрачный в конце анимации (`end`)
19
+ */
20
+ transparent?: 'start' | 'end' | boolean;
21
+ /**
22
+ * Управляет позицией триггера начала анимации
23
+ */
24
+ startTriggerPosition?: 'start' | 'full-area' | RefObject<HTMLElement>;
25
+ /**
26
+ * Управляет позицией триггера конца анимации. Если не передан вычисляется автоматически на основе изменения
27
+ * высоты навбара в процессе анимации и позиции триггера начала анмиации.
28
+ */
29
+ endTriggerPosition?: RefObject<HTMLElement>;
30
+ /**
31
+ * Включает progressive blur. Эффект может не работать в некоторых вариантах верстки.
32
+ */
33
+ progressiveBlur?: boolean;
34
+ /**
35
+ * Включает режим когда NavBar не занимает место в лейауте и контент располагается под ним.
36
+ */
37
+ overlay?: boolean;
38
+ /**
39
+ * Управляет режимом автодоскролла. По умолчанию включен.
40
+ */
41
+ snapScroll?: boolean;
42
+ /**
43
+ * Управляет режимом отображения дивайдера:
44
+ * - `false` дивайдер отключен
45
+ * - `always` дивайдер отображается постоянно
46
+ * - `with-scroll` дивайдер отображается только когда контент подскроллен под NavBar
47
+ */
48
+ showDivider?: ShowDivider;
49
+ /**
50
+ * Принимает MotionValue значение которого будет обновляться синхронно с анимацией всего NavBar.
51
+ * Прогресс анимации представляется в виде числа 0..1
52
+ * Предназначен для синхронизации внешних анимаций с анимациями NavBar.
53
+ */
54
+ animationProgress?: MotionValue<number>;
55
+ }
56
+ export declare const NavBar: FC<NavBarProps>;
57
+ export {};
@@ -0,0 +1,21 @@
1
+ import './../index.css';
2
+ import 'react/jsx-runtime';
3
+ import 'react';
4
+ import 'classnames';
5
+ import 'motion/react';
6
+ import '@hh.ru/magritte-ui-divider';
7
+ import '@hh.ru/magritte-ui-layer';
8
+ import '../internal/MetricsProvider.js';
9
+ import '../internal/ProgressiveBlur.js';
10
+ import '../internal/useAnimationRanges.js';
11
+ import '../internal/useBindScrollToAnimationProgress.js';
12
+ import '../internal/useDivider.js';
13
+ import '../internal/useNavBarMetrics.js';
14
+ import '../internal/useResetFocus.js';
15
+ import '../internal/useScrollAdapter.js';
16
+ import '../internal/useSnapScroll.js';
17
+ import '../internal/useSyncMotionValue.js';
18
+ import '../internal/utils.js';
19
+ export { N as NavBar, u as useNavBarContext } from '../NavBar-CrD8CEWb.js';
20
+ import '@hh.ru/magritte-internal-custom-scroll';
21
+ //# sourceMappingURL=NavBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NavBar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,22 @@
1
+ import { type FC, type JSXElementConstructor, type PropsWithChildren, type ReactElement } from 'react';
2
+ import { type MotionValue } from 'motion/react';
3
+ export type InternalPaneProps = PropsWithChildren<{
4
+ foldable?: boolean;
5
+ nextPane?: ReactElement<InternalPaneProps, JSXElementConstructor<InternalPaneProps>> | null;
6
+ animationProgress?: MotionValue<number>;
7
+ }>;
8
+ export type ExternalPaneProps = PropsWithChildren<{
9
+ /**
10
+ * Включает режим когда панель "схлопывается" под стоящую над ней панель.
11
+ */
12
+ foldable?: boolean;
13
+ /**
14
+ * Принимает MotionValue значение которого будет обновляться синхронно с анимацией панели.
15
+ * Прогресс анимации представляется в виде числа 0..1
16
+ * Предназначен для синхронизации внешних анимаций с анимацией панели.
17
+ */
18
+ animationProgress?: MotionValue<number>;
19
+ }>;
20
+ export type PaneElement = ReactElement<ExternalPaneProps, JSXElementConstructor<ExternalPaneProps>>;
21
+ export declare const Pane: FC<InternalPaneProps>;
22
+ export declare const ExternalPane: FC<PropsWithChildren<ExternalPaneProps>>;