@dss-kit/ui-kit 1.0.2 → 1.0.3

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 (71) hide show
  1. package/dist/components/builders/Dialog/Dialog.const.d.ts +9 -0
  2. package/dist/components/builders/Dialog/Dialog.const.js +4 -0
  3. package/dist/components/builders/Dialog/Dialog.context.d.ts +12 -0
  4. package/dist/components/builders/{Modal/context.js → Dialog/Dialog.context.js} +5 -5
  5. package/dist/components/builders/Dialog/Dialog.parts.d.ts +11 -0
  6. package/dist/components/builders/Dialog/Dialog.parts.js +11 -0
  7. package/dist/components/builders/Dialog/Dialog.types.d.ts +44 -0
  8. package/dist/components/builders/Dialog/DialogCloseButton/DialogCloseButton.d.ts +10 -0
  9. package/dist/components/builders/Dialog/DialogCloseButton/DialogCloseButton.js +34 -0
  10. package/dist/components/builders/Dialog/DialogCloseButton/index.d.ts +2 -0
  11. package/dist/components/builders/{Modal/ModalFooter/ModalFooter.d.ts → Dialog/DialogFooter/DialogFooter.d.ts} +13 -22
  12. package/dist/components/builders/Dialog/DialogFooter/DialogFooter.js +48 -0
  13. package/dist/components/builders/Dialog/DialogFooter/index.d.ts +2 -0
  14. package/dist/components/builders/{Modal/ModalHeader/ModalHeader.d.ts → Dialog/DialogHeader/DialogHeader.d.ts} +10 -6
  15. package/dist/components/builders/Dialog/DialogHeader/DialogHeader.js +97 -0
  16. package/dist/components/builders/Dialog/DialogHeader/index.d.ts +2 -0
  17. package/dist/components/builders/{Modal/ModalMain/ModalMain.d.ts → Dialog/DialogMain/DialogMain.d.ts} +18 -17
  18. package/dist/components/builders/{Modal/ModalMain/ModalMain.js → Dialog/DialogMain/DialogMain.js} +39 -29
  19. package/dist/components/builders/Dialog/DialogMain/index.d.ts +2 -0
  20. package/dist/components/builders/Dialog/DialogMain/styles.d.ts +6 -0
  21. package/dist/components/builders/{Modal/ModalMain → Dialog/DialogMain}/styles.js +16 -0
  22. package/dist/components/builders/Dialog/hooks/index.d.ts +3 -0
  23. package/dist/components/builders/Dialog/hooks/useBackdropClose.d.ts +10 -0
  24. package/dist/components/builders/Dialog/hooks/useBackdropClose.js +15 -0
  25. package/dist/components/builders/Dialog/hooks/useBodyScrollLock.d.ts +6 -0
  26. package/dist/components/builders/Dialog/hooks/useBodyScrollLock.js +13 -0
  27. package/dist/components/builders/Dialog/hooks/useCloseOnEsc.d.ts +6 -0
  28. package/dist/components/builders/Dialog/hooks/useCloseOnEsc.js +21 -0
  29. package/dist/components/builders/Dialog/index.d.ts +10 -0
  30. package/dist/components/builders/Modal/Modal.d.ts +8 -28
  31. package/dist/components/builders/Modal/Modal.js +50 -78
  32. package/dist/components/builders/Modal/index.d.ts +6 -11
  33. package/dist/components/builders/Modal/index.js +7 -9
  34. package/dist/components/builders/Modal/styles.js +6 -7
  35. package/dist/components/builders/Sheet/Sheet.const.d.ts +50 -0
  36. package/dist/components/builders/Sheet/Sheet.const.js +38 -0
  37. package/dist/components/builders/Sheet/Sheet.d.ts +12 -0
  38. package/dist/components/builders/Sheet/Sheet.js +55 -0
  39. package/dist/components/builders/Sheet/Sheet.types.d.ts +82 -0
  40. package/dist/components/builders/Sheet/Sheet.utils.d.ts +34 -0
  41. package/dist/components/builders/Sheet/Sheet.utils.js +50 -0
  42. package/dist/components/builders/Sheet/SheetLayer.d.ts +22 -0
  43. package/dist/components/builders/Sheet/SheetLayer.js +115 -0
  44. package/dist/components/builders/Sheet/hooks/index.d.ts +2 -0
  45. package/dist/components/builders/Sheet/hooks/useSheetGesture.d.ts +24 -0
  46. package/dist/components/builders/Sheet/hooks/useSheetGesture.js +67 -0
  47. package/dist/components/builders/Sheet/hooks/useSheetMotion.d.ts +31 -0
  48. package/dist/components/builders/Sheet/hooks/useSheetMotion.js +74 -0
  49. package/dist/components/builders/Sheet/hooks/useSheetPointer.d.ts +31 -0
  50. package/dist/components/builders/Sheet/hooks/useSheetPointer.js +81 -0
  51. package/dist/components/builders/Sheet/index.d.ts +15 -0
  52. package/dist/components/builders/Sheet/index.js +9 -0
  53. package/dist/components/builders/Sheet/styles.d.ts +17 -0
  54. package/dist/components/builders/Sheet/styles.js +135 -0
  55. package/dist/components/builders/Table/TablePagination/TablePagination.js +1 -1
  56. package/dist/components/builders/Text/Text.d.ts +1 -1
  57. package/dist/components/builders/index.d.ts +1 -0
  58. package/dist/components/controls/Checkbox/Checkbox.js +6 -6
  59. package/dist/components/controls/Select/Select.js +6 -6
  60. package/dist/index.js +93 -91
  61. package/dist/ui-kit.cjs +8 -8
  62. package/dist/utils/hooks/useLatestRef.d.ts +6 -0
  63. package/dist/utils/hooks/useLatestRef.js +10 -0
  64. package/package.json +1 -1
  65. package/dist/components/builders/Modal/ModalFooter/ModalFooter.js +0 -35
  66. package/dist/components/builders/Modal/ModalFooter/index.d.ts +0 -2
  67. package/dist/components/builders/Modal/ModalHeader/ModalHeader.js +0 -86
  68. package/dist/components/builders/Modal/ModalHeader/index.d.ts +0 -2
  69. package/dist/components/builders/Modal/ModalMain/index.d.ts +0 -2
  70. package/dist/components/builders/Modal/ModalMain/styles.d.ts +0 -3
  71. package/dist/components/builders/Modal/context.d.ts +0 -8
@@ -0,0 +1,34 @@
1
+ /** Положение указателя вдоль оси в момент события */
2
+ export interface PointerSample {
3
+ /** `event.timeStamp`, мс */
4
+ time: number;
5
+ /** Координата вдоль оси, px */
6
+ position: number;
7
+ }
8
+ export declare const clamp: (value: number, min: number, max: number) => number;
9
+ /** Оставляет точки из диапазона (0, 1], сортирует по возрастанию и убирает дубли */
10
+ export declare function normalizeSnapPoints(snapPoints?: readonly number[]): number[];
11
+ /** Ближайшая к `value` точка фиксации */
12
+ export declare function getClosestSnapPoint(snapPoints: readonly number[], value: number): number;
13
+ /**
14
+ * Соседняя точка в направлении свайпа: `1` — следующая бо́льшая,
15
+ * `-1` — следующая меньшая. Если дальше точек нет — крайняя.
16
+ */
17
+ export declare function getNextSnapPoint(snapPoints: readonly number[], value: number, direction: 1 | -1): number;
18
+ /**
19
+ * «Резинка» при перетягивании за границу: смещение растёт всё медленнее
20
+ * и никогда не превышает `limit`.
21
+ */
22
+ export declare function rubberband(distance: number, limit?: number): number;
23
+ /**
24
+ * Скорость (px/s) по движениям указателя за последние
25
+ * `SHEET_VELOCITY_WINDOW` мс. Если указатель перед отпусканием стоял,
26
+ * скорость нулевая.
27
+ */
28
+ export declare function getVelocity(samples: readonly PointerSample[]): number;
29
+ /**
30
+ * Можно ли начать перетаскивание с этого элемента: он внутри панели,
31
+ * в зоне перетаскивания (drag handle или Sheet.Header) и не на интерактивном
32
+ * элементе вроде кнопки или поля ввода.
33
+ */
34
+ export declare function isDragZoneTarget(target: EventTarget | null, panel: HTMLElement): boolean;
@@ -0,0 +1,50 @@
1
+ import { SHEET_NO_DRAG_SELECTOR as o, SHEET_DRAG_ZONE_SELECTOR as f, SHEET_VELOCITY_WINDOW as c, SHEET_OVERDRAG_LIMIT as u } from "./Sheet.const.js";
2
+ const E = (t, n, e) => Math.min(Math.max(t, n), e);
3
+ function g(t) {
4
+ if (!t?.length) return [];
5
+ const n = t.filter(
6
+ (e) => Number.isFinite(e) && e > 0 && e <= 1
7
+ );
8
+ return Array.from(new Set(n)).sort((e, i) => e - i);
9
+ }
10
+ function h(t, n) {
11
+ return t.length ? t.reduce(
12
+ (e, i) => Math.abs(i - n) < Math.abs(e - n) ? i : e
13
+ ) : n;
14
+ }
15
+ function S(t, n, e) {
16
+ if (e === 1)
17
+ return t.find((r) => r > n + 1e-3) ?? t[t.length - 1];
18
+ for (let r = t.length - 1; r >= 0; r--)
19
+ if (t[r] < n - 1e-3) return t[r];
20
+ return t[0];
21
+ }
22
+ function _(t, n = u) {
23
+ return n * (1 - 1 / (t * 0.55 / n + 1));
24
+ }
25
+ function T(t) {
26
+ if (!t.length) return 0;
27
+ const n = t[t.length - 1];
28
+ let e = n;
29
+ for (let r = t.length - 1; r >= 0 && !(n.time - t[r].time > c); r--)
30
+ e = t[r];
31
+ const i = n.time - e.time;
32
+ return i > 0 ? (n.position - e.position) / i * 1e3 : 0;
33
+ }
34
+ function d(t, n) {
35
+ if (!t || typeof t.closest != "function" || !n.contains(t))
36
+ return !1;
37
+ const e = t, i = e.closest(o);
38
+ if (i && n.contains(i)) return !1;
39
+ const r = e.closest(f);
40
+ return r !== null && n.contains(r);
41
+ }
42
+ export {
43
+ E as clamp,
44
+ h as getClosestSnapPoint,
45
+ S as getNextSnapPoint,
46
+ T as getVelocity,
47
+ d as isDragZoneTarget,
48
+ g as normalizeSnapPoints,
49
+ _ as rubberband
50
+ };
@@ -0,0 +1,22 @@
1
+ import { SheetProps, SheetSizing } from './Sheet.types';
2
+ export type SheetLayerProps = Omit<SheetProps, "sizeMode" | "snapPoints" | "closeOnEsc" | "disableBodyScroll" | "showBorders"> & Required<Pick<SheetProps, "position" | "backgroundColor" | "closeThreshold" | "closeOnDrag" | "closeOnBackdropClick">> & {
3
+ /** Итоговый режим размера */
4
+ sizing: SheetSizing;
5
+ /** Нормализованные точки фиксации; пусто, если режим не `snap` */
6
+ snapPoints: number[];
7
+ /** Анимация закрытия завершилась: Sheet можно размонтировать */
8
+ onExited: () => void;
9
+ };
10
+ /**
11
+ * Подложка и панель Sheet. Монтируется на время показа (включая анимацию
12
+ * закрытия), поэтому состояние жестов и точек фиксации сбрасывается при
13
+ * каждом открытии.
14
+ */
15
+ export declare const SheetLayer: import('react').ForwardRefExoticComponent<Omit<SheetProps, "showBorders" | "closeOnEsc" | "disableBodyScroll" | "snapPoints" | "sizeMode"> & Required<Pick<SheetProps, "position" | "backgroundColor" | "closeOnBackdropClick" | "closeOnDrag" | "closeThreshold">> & {
16
+ /** Итоговый режим размера */
17
+ sizing: SheetSizing;
18
+ /** Нормализованные точки фиксации; пусто, если режим не `snap` */
19
+ snapPoints: number[];
20
+ /** Анимация закрытия завершилась: Sheet можно размонтировать */
21
+ onExited: () => void;
22
+ } & import('react').RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,115 @@
1
+ import { jsx as o, jsxs as y } from "react/jsx-runtime";
2
+ import { css as A, cx as t } from "@emotion/css";
3
+ import { useMergeRefs as F } from "@floating-ui/react";
4
+ import { motion as v } from "framer-motion";
5
+ import { forwardRef as G, useRef as L, useState as q, useMemo as J } from "react";
6
+ import { SHEET_POSITION_CONFIG as K, SHEET_SNAP_POINT_VAR as Q } from "./Sheet.const.js";
7
+ import { getClosestSnapPoint as U } from "./Sheet.utils.js";
8
+ import { styles as e, positionStyles as W } from "./styles.js";
9
+ import { useSheetMotion as X } from "./hooks/useSheetMotion.js";
10
+ import { useSheetGesture as Y } from "./hooks/useSheetGesture.js";
11
+ import { useBackdropClose as Z } from "../Dialog/hooks/useBackdropClose.js";
12
+ import { DialogCloseButton as $ } from "../Dialog/DialogCloseButton/DialogCloseButton.js";
13
+ const ee = G(
14
+ ({
15
+ isOpen: n,
16
+ onClose: m,
17
+ onExited: P,
18
+ position: c,
19
+ backgroundColor: d,
20
+ sizing: k,
21
+ snapPoints: r,
22
+ defaultSnapPoint: C,
23
+ onSnapPointChange: M,
24
+ closeThreshold: R,
25
+ closeOnDrag: g,
26
+ closeOnBackdropClick: x,
27
+ showAbsoluteCloseButton: _,
28
+ overlayClassName: b,
29
+ sheetClassName: w,
30
+ handleClassName: B,
31
+ absoluteCloseButtonClassName: D,
32
+ children: E
33
+ }, H) => {
34
+ const { axis: p, direction: i } = K[c], a = W[c], u = L(null), I = F([u, H]), [T, O] = q(
35
+ C ?? r[0] ?? 1
36
+ ), f = U(r, T), s = X({
37
+ isOpen: n,
38
+ onExited: P,
39
+ direction: i,
40
+ snapPoint: f
41
+ }), { onPointerDown: V } = Y({
42
+ axis: p,
43
+ direction: i,
44
+ panelRef: u,
45
+ isOpen: n,
46
+ snapPoints: r,
47
+ closeOnDrag: g,
48
+ closeThreshold: R,
49
+ motion: s,
50
+ onClose: m,
51
+ onSnapPointSettle: (l) => {
52
+ l !== f && (O(l), M?.(l));
53
+ }
54
+ }), S = Z(x, m), j = J(
55
+ () => A({ backgroundColor: d }),
56
+ [d]
57
+ ), h = i === 1, z = {
58
+ [p]: s.translate,
59
+ [Q]: s.snapSize
60
+ }, N = /* @__PURE__ */ o(
61
+ "div",
62
+ {
63
+ "data-sheet-handle": "",
64
+ "aria-hidden": !0,
65
+ className: t(e.handle, a.handle, B),
66
+ children: /* @__PURE__ */ o("div", { className: t(e.handleBar, a.handleBar) })
67
+ }
68
+ );
69
+ return /* @__PURE__ */ y("div", { className: t(e.root, !n && e.rootClosing), children: [
70
+ /* @__PURE__ */ o(
71
+ v.div,
72
+ {
73
+ "aria-hidden": !0,
74
+ className: t(e.backdrop, b),
75
+ style: { opacity: s.backdropOpacity },
76
+ onMouseDown: S.onMouseDown,
77
+ onClick: S.onClick
78
+ }
79
+ ),
80
+ /* @__PURE__ */ y(
81
+ v.div,
82
+ {
83
+ ref: I,
84
+ role: "dialog",
85
+ "aria-modal": "true",
86
+ className: t(
87
+ e.panel,
88
+ a.panel,
89
+ a.sizing[k],
90
+ j,
91
+ w
92
+ ),
93
+ style: z,
94
+ onPointerDown: V,
95
+ children: [
96
+ h && N,
97
+ /* @__PURE__ */ o("div", { className: e.content, children: E }),
98
+ !h && N,
99
+ _ && /* @__PURE__ */ o(
100
+ $,
101
+ {
102
+ absolute: !0,
103
+ className: D
104
+ }
105
+ )
106
+ ]
107
+ }
108
+ )
109
+ ] });
110
+ }
111
+ );
112
+ ee.displayName = "SheetLayer";
113
+ export {
114
+ ee as SheetLayer
115
+ };
@@ -0,0 +1,2 @@
1
+ export { useSheetGesture } from './useSheetGesture';
2
+ export { useSheetMotion } from './useSheetMotion';
@@ -0,0 +1,24 @@
1
+ import { RefObject } from 'react';
2
+ import { SheetPositionConfig } from '../Sheet.types';
3
+ import { SheetMotion } from './useSheetMotion';
4
+ interface UseSheetGestureOptions extends SheetPositionConfig {
5
+ panelRef: RefObject<HTMLElement>;
6
+ isOpen: boolean;
7
+ /** Нормализованные точки фиксации; пусто, если их нет */
8
+ snapPoints: number[];
9
+ closeOnDrag: boolean;
10
+ closeThreshold: number;
11
+ motion: SheetMotion;
12
+ onClose: () => void;
13
+ /** Sheet доведён до точки фиксации после жеста */
14
+ onSnapPointSettle: (snapPoint: number) => void;
15
+ }
16
+ /**
17
+ * Перетаскивание Sheet: переводит смещение указателя в положение и размер
18
+ * панели, а при отпускании решает — закрыть Sheet, вернуть его на место или
19
+ * довести до точки фиксации. Возвращает обработчик для панели Sheet.
20
+ */
21
+ export declare function useSheetGesture({ axis, direction, panelRef, isOpen, snapPoints, closeOnDrag, closeThreshold, motion, onClose, onSnapPointSettle, }: UseSheetGestureOptions): {
22
+ onPointerDown: (event: import('react').PointerEvent<HTMLElement>) => void;
23
+ };
24
+ export {};
@@ -0,0 +1,67 @@
1
+ import { useRef as z, useEffect as y } from "react";
2
+ import { SHEET_AXIS_KEYS as F, SHEET_FLICK_VELOCITY as H, SHEET_FLICK_MIN_DISTANCE as K } from "../Sheet.const.js";
3
+ import { getNextSnapPoint as L, getClosestSnapPoint as N, clamp as A, rubberband as T } from "../Sheet.utils.js";
4
+ import { useSheetPointer as R } from "./useSheetPointer.js";
5
+ function J({
6
+ axis: h,
7
+ direction: S,
8
+ panelRef: E,
9
+ isOpen: d,
10
+ snapPoints: o,
11
+ closeOnDrag: V,
12
+ closeThreshold: _,
13
+ motion: I,
14
+ onClose: p,
15
+ onSnapPointSettle: v
16
+ }) {
17
+ const { offset: c, snapSize: b, animateTo: C, snapTo: D, releaseToClose: x } = I, l = o.length > 0, u = z(null);
18
+ return y(() => {
19
+ d || (u.current = null);
20
+ }, [d]), R({
21
+ axis: h,
22
+ panelRef: E,
23
+ onDragStart: () => {
24
+ const a = E.current;
25
+ if (!a || !d) return;
26
+ c.stop(), b.stop();
27
+ const t = a.getBoundingClientRect()[F[h].size], i = l ? t / b.get() : t, r = t * (1 - c.get());
28
+ u.current = {
29
+ plane: i,
30
+ minVisible: l ? o[0] * i : t,
31
+ maxVisible: l ? o[o.length - 1] * i : t,
32
+ startVisible: r,
33
+ visible: r
34
+ };
35
+ },
36
+ onDragMove: (a) => {
37
+ const t = u.current;
38
+ if (!t) return;
39
+ const { plane: i, minVisible: r, maxVisible: n } = t;
40
+ let e = t.startVisible - S * a;
41
+ e > n ? e = n + T(e - n) : e < r && !V && (e = r - T(r - e)), e = Math.max(e, 0), t.visible = e;
42
+ const s = A(e, r, n);
43
+ l && b.set(s / i), c.set(s > 0 ? (s - e) / s : 0);
44
+ },
45
+ onDragEnd: (a, t) => {
46
+ const i = u.current;
47
+ if (u.current = null, !i || !d) return;
48
+ const { plane: r, minVisible: n, maxVisible: e, visible: s } = i, f = -S * t, M = Math.abs(f) > H && Math.abs(a) > K;
49
+ if (s < n) {
50
+ const g = -f / n, m = (n - s) / n;
51
+ if (V && (M ? f < 0 : m > _)) {
52
+ x(g), p();
53
+ return;
54
+ }
55
+ C(c, 0, { velocity: g }), l && (D(o[0]), v(o[0]));
56
+ return;
57
+ }
58
+ if (C(c, 0), l) {
59
+ const g = Math.min(s, e) / r, m = M ? L(o, g, f > 0 ? 1 : -1) : N(o, g);
60
+ D(m, f / r), v(m);
61
+ }
62
+ }
63
+ });
64
+ }
65
+ export {
66
+ J as useSheetGesture
67
+ };
@@ -0,0 +1,31 @@
1
+ import { MotionValue } from 'framer-motion';
2
+ interface UseSheetMotionOptions {
3
+ isOpen: boolean;
4
+ /** Анимация закрытия завершилась: Sheet можно размонтировать */
5
+ onExited: () => void;
6
+ /** Направление закрытия вдоль оси */
7
+ direction: 1 | -1;
8
+ /** Активная точка фиксации; без snap-points не используется */
9
+ snapPoint: number;
10
+ }
11
+ interface AnimateOptions {
12
+ /** Начальная скорость; без неё продолжается текущее движение значения */
13
+ velocity?: number;
14
+ onComplete?: () => void;
15
+ }
16
+ /**
17
+ * Анимации Sheet: выезд и уезд, доводка до точки фиксации, затемнение
18
+ * подложки. Положение и размер хранятся в motion values, поэтому жест
19
+ * меняет их напрямую, без ререндеров.
20
+ */
21
+ export declare function useSheetMotion({ isOpen, onExited, direction, snapPoint, }: UseSheetMotionOptions): {
22
+ offset: MotionValue<number>;
23
+ snapSize: MotionValue<number>;
24
+ translate: MotionValue<string>;
25
+ backdropOpacity: MotionValue<number>;
26
+ animateTo: (value: MotionValue<number>, target: number, { velocity, onComplete }?: AnimateOptions) => void;
27
+ snapTo: (target: number, velocity?: number) => void;
28
+ releaseToClose: (velocity: number) => void;
29
+ };
30
+ export type SheetMotion = ReturnType<typeof useSheetMotion>;
31
+ export {};
@@ -0,0 +1,74 @@
1
+ import { useReducedMotion as y, useMotionValue as F, useTransform as M, animate as C } from "framer-motion";
2
+ import { useRef as m, useCallback as l, useEffect as p } from "react";
3
+ import { useLatestRef as V } from "../../../../utils/hooks/useLatestRef.js";
4
+ import { SHEET_SPRING as S } from "../Sheet.const.js";
5
+ import { clamp as q } from "../Sheet.utils.js";
6
+ function N({
7
+ isOpen: u,
8
+ onExited: A,
9
+ direction: b,
10
+ snapPoint: o
11
+ }) {
12
+ const d = y(), t = F(1), n = F(o), h = M(
13
+ t,
14
+ (e) => `${e * b * 100}%`
15
+ ), k = M(
16
+ t,
17
+ (e) => q(1 - e, 0, 1)
18
+ ), R = m(o), s = m(void 0), a = m(0), c = V({ isOpen: u, onExited: A }), r = l(
19
+ (e, i, { velocity: T, onComplete: E } = {}) => {
20
+ if (d) {
21
+ e.stop(), e.set(i), E?.();
22
+ return;
23
+ }
24
+ const x = T === void 0 ? S : { ...S, velocity: T };
25
+ C(e, i, { ...x, onComplete: E });
26
+ },
27
+ [d]
28
+ ), f = l(
29
+ (e, i) => {
30
+ R.current = e, r(n, e, { velocity: i });
31
+ },
32
+ [r, n]
33
+ );
34
+ p(() => {
35
+ const e = s.current;
36
+ if (s.current = void 0, u) {
37
+ r(t, 0, { velocity: e });
38
+ return;
39
+ }
40
+ r(t, 1, {
41
+ velocity: e,
42
+ onComplete: () => {
43
+ c.current.isOpen || c.current.onExited();
44
+ }
45
+ });
46
+ }, [u, r, t, c]), p(() => {
47
+ R.current !== o && f(o);
48
+ }, [o, f]), p(
49
+ () => () => {
50
+ cancelAnimationFrame(a.current), t.stop(), n.stop();
51
+ },
52
+ [t, n]
53
+ );
54
+ const v = l(
55
+ (e) => {
56
+ s.current = e, cancelAnimationFrame(a.current), a.current = requestAnimationFrame(() => {
57
+ s.current = void 0, c.current.isOpen && r(t, 0);
58
+ });
59
+ },
60
+ [r, t, c]
61
+ );
62
+ return {
63
+ offset: t,
64
+ snapSize: n,
65
+ translate: h,
66
+ backdropOpacity: k,
67
+ animateTo: r,
68
+ snapTo: f,
69
+ releaseToClose: v
70
+ };
71
+ }
72
+ export {
73
+ N as useSheetMotion
74
+ };
@@ -0,0 +1,31 @@
1
+ import { PointerEvent as ReactPointerEvent, RefObject } from 'react';
2
+ import { SheetAxis } from '../Sheet.types';
3
+ export interface SheetPointerHandlers {
4
+ /** Нажатие стало перетаскиванием: указатель сдвинулся вдоль оси */
5
+ onDragStart: () => void;
6
+ /** Смещение указателя вдоль оси от точки нажатия, px */
7
+ onDragMove: (offset: number) => void;
8
+ /** Отпускание: итоговое смещение (px) и скорость (px/s) вдоль оси */
9
+ onDragEnd: (offset: number, velocity: number) => void;
10
+ }
11
+ interface UseSheetPointerOptions extends SheetPointerHandlers {
12
+ /** Ось перетаскивания */
13
+ axis: SheetAxis;
14
+ /** Панель Sheet: перетаскивание начинается только внутри неё */
15
+ panelRef: RefObject<HTMLElement>;
16
+ }
17
+ /**
18
+ * Отслеживает жест указателя в зонах перетаскивания (drag handle,
19
+ * Sheet.Header): смещение и скорость вдоль оси. Построено на Pointer Events,
20
+ * поэтому мышь, касание и перо обрабатываются одинаково. Возвращает
21
+ * обработчик для панели Sheet.
22
+ *
23
+ * Свой трекинг вместо `drag`/`onPan` из framer-motion: обработчики `onPan*`
24
+ * вызываются асинхронно (после отрисовки кадра), а здесь нужно решить по
25
+ * нажатию, начинать ли жест, и менять не только `transform`, но и высоту
26
+ * (snap-points).
27
+ */
28
+ export declare function useSheetPointer({ axis, panelRef, ...handlers }: UseSheetPointerOptions): {
29
+ onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void;
30
+ };
31
+ export {};
@@ -0,0 +1,81 @@
1
+ import { useRef as y, useEffect as L, useCallback as H } from "react";
2
+ import { useLatestRef as O } from "../../../../utils/hooks/useLatestRef.js";
3
+ import { SHEET_AXIS_KEYS as C, SHEET_DRAG_START_THRESHOLD as P, SHEET_VELOCITY_WINDOW as R } from "../Sheet.const.js";
4
+ import { isDragZoneTarget as E, getVelocity as A } from "../Sheet.utils.js";
5
+ function k({
6
+ axis: h,
7
+ panelRef: s,
8
+ ...T
9
+ }) {
10
+ const a = O(T), c = y(null);
11
+ L(() => () => c.current?.(), []);
12
+ const b = H(
13
+ (r) => {
14
+ const i = s.current;
15
+ if (!i || !r.isPrimary || r.button !== 0 || !E(r.target, i))
16
+ return;
17
+ c.current?.();
18
+ const { client: e, crossClient: w } = C[h], { pointerId: p, pointerType: M } = r, _ = r.target, m = r[e], I = r[w];
19
+ let o = [
20
+ { time: r.timeStamp, position: m }
21
+ ], d = !1, l = 0;
22
+ function g() {
23
+ window.removeEventListener("pointermove", D), window.removeEventListener("pointerup", u), window.removeEventListener("pointercancel", u), c.current = null;
24
+ }
25
+ function S(t, n) {
26
+ g(), d && a.current.onDragEnd(t, n);
27
+ }
28
+ function D(t) {
29
+ if (t.pointerId !== p) return;
30
+ if (M === "mouse" && t.buttons === 0) {
31
+ S(l, 0);
32
+ return;
33
+ }
34
+ const n = t[e] - m;
35
+ if (!d) {
36
+ const f = t[w] - I;
37
+ if (Math.max(Math.abs(n), Math.abs(f)) < P)
38
+ return;
39
+ if (Math.abs(f) > Math.abs(n)) {
40
+ g();
41
+ return;
42
+ }
43
+ d = !0;
44
+ try {
45
+ _.setPointerCapture(p);
46
+ } catch {
47
+ }
48
+ a.current.onDragStart();
49
+ }
50
+ l = n, o = o.filter(
51
+ (f) => t.timeStamp - f.time <= R
52
+ ), o.push({
53
+ time: t.timeStamp,
54
+ position: t[e]
55
+ }), a.current.onDragMove(n);
56
+ }
57
+ function u(t) {
58
+ if (t.pointerId === p) {
59
+ if (t.type === "pointercancel") {
60
+ S(l, 0);
61
+ return;
62
+ }
63
+ o.push({ time: t.timeStamp, position: t[e] }), S(t[e] - m, A(o));
64
+ }
65
+ }
66
+ window.addEventListener("pointermove", D), window.addEventListener("pointerup", u), window.addEventListener("pointercancel", u), c.current = g;
67
+ },
68
+ [h, s, a]
69
+ );
70
+ return L(() => {
71
+ const r = s.current;
72
+ if (!r) return;
73
+ const i = (e) => {
74
+ E(e.target, r) && e.preventDefault();
75
+ };
76
+ return r.addEventListener("dragstart", i), () => r.removeEventListener("dragstart", i);
77
+ }, [s]), { onPointerDown: b };
78
+ }
79
+ export {
80
+ k as useSheetPointer
81
+ };
@@ -0,0 +1,15 @@
1
+ import { ReactNode, RefAttributes } from 'react';
2
+ import { DialogParts } from '../Dialog';
3
+ import { SheetProps } from './Sheet.types';
4
+ /**
5
+ * Тип составного компонента `Sheet` — по аналогии с `Modal`: без служебных
6
+ * полей `ForwardRefExoticComponent` в автодополнении `<Sheet.`.
7
+ *
8
+ * `Header` / `Main` / `Footer` — те же компоненты, что `Modal.Header` /
9
+ * `Modal.Main` / `Modal.Footer` (общие части диалогов, см. `../Dialog`).
10
+ */
11
+ type SheetComponent = ((props: SheetProps & RefAttributes<HTMLDivElement>) => ReactNode) & DialogParts;
12
+ declare const SheetWithSubComponents: SheetComponent;
13
+ export { SheetWithSubComponents as Sheet };
14
+ export type { DialogFooterProps as SheetFooterProps, DialogHeaderProps as SheetHeaderProps, DialogMainProps as SheetMainProps, } from '../Dialog';
15
+ export type { SheetPosition, SheetProps, SheetSizeMode } from './Sheet.types';
@@ -0,0 +1,9 @@
1
+ import { Sheet as t } from "./Sheet.js";
2
+ import { dialogParts as e } from "../Dialog/Dialog.parts.js";
3
+ const s = Object.assign(
4
+ t,
5
+ e
6
+ );
7
+ export {
8
+ s as Sheet
9
+ };
@@ -0,0 +1,17 @@
1
+ import { SheetPosition, SheetSizing } from './Sheet.types';
2
+ /** Стили, зависящие от позиции: прижатие к краю, скругления, ручка, размеры */
3
+ export declare const positionStyles: Record<SheetPosition, {
4
+ panel: string;
5
+ handle: string;
6
+ handleBar: string;
7
+ sizing: Record<SheetSizing, string>;
8
+ }>;
9
+ export declare const styles: {
10
+ root: string;
11
+ rootClosing: string;
12
+ backdrop: string;
13
+ panel: string;
14
+ content: string;
15
+ handle: string;
16
+ handleBar: string;
17
+ };