@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,9 @@
1
+ /**
2
+ * Части диалога. Каждая помечает свой корневой элемент атрибутом
3
+ * `data-dialog-part`, чтобы контейнер мог найти её в DOM, не зная её устройства.
4
+ * Например, `Sheet` делает `header` зоной перетаскивания, а `main` растягивает
5
+ * на свободную высоту.
6
+ */
7
+ export type DialogPart = "header" | "main" | "footer";
8
+ /** CSS-селектор части диалога: `[data-dialog-part="header"]` и т.п. */
9
+ export declare const getDialogPartSelector: (part: DialogPart) => string;
@@ -0,0 +1,4 @@
1
+ const a = (t) => `[data-dialog-part="${t}"]`;
2
+ export {
3
+ a as getDialogPartSelector
4
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Контекст диалога. Его задаёт контейнер (`Modal`, `Sheet`), а части берут
3
+ * отсюда `onClose` для кнопки закрытия и `showBorders` для своих границ.
4
+ */
5
+ export interface DialogContextValue {
6
+ /** Callback закрытия диалога */
7
+ onClose: () => void;
8
+ /** Показывать ли границы под Header и над Footer */
9
+ showBorders: boolean;
10
+ }
11
+ export declare const DialogContext: import('react').Context<DialogContextValue>;
12
+ export declare const useDialogContext: () => DialogContextValue;
@@ -1,10 +1,10 @@
1
1
  import { createContext as o, useContext as t } from "react";
2
2
  const e = o({
3
- isOpen: !1,
4
3
  onClose: () => {
5
- }
6
- }), s = () => t(e);
4
+ },
5
+ showBorders: !0
6
+ }), r = () => t(e);
7
7
  export {
8
- e as ModalContext,
9
- s as useModalContext
8
+ e as DialogContext,
9
+ r as useDialogContext
10
10
  };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Части диалога для составных компонентов: `Modal.Header`, `Sheet.Header`
3
+ * и т.д. Обе обёртки получают один и тот же набор, поэтому
4
+ * `Modal.Header === Sheet.Header`.
5
+ */
6
+ export declare const dialogParts: {
7
+ Header: import('react').ForwardRefExoticComponent<import('./DialogHeader').DialogHeaderProps & import('react').RefAttributes<HTMLDivElement>>;
8
+ Main: import('react').ForwardRefExoticComponent<import('./DialogMain').DialogMainProps & import('react').RefAttributes<import('./DialogMain').DialogMainRef>>;
9
+ Footer: import('react').ForwardRefExoticComponent<Omit<import('./DialogFooter').DialogFooterProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
10
+ };
11
+ export type DialogParts = typeof dialogParts;
@@ -0,0 +1,11 @@
1
+ import { DialogFooter as o } from "./DialogFooter/DialogFooter.js";
2
+ import { DialogMain as r } from "./DialogMain/DialogMain.js";
3
+ import { DialogHeader as a } from "./DialogHeader/DialogHeader.js";
4
+ const m = {
5
+ Header: a,
6
+ Main: r,
7
+ Footer: o
8
+ };
9
+ export {
10
+ m as dialogParts
11
+ };
@@ -0,0 +1,44 @@
1
+ import { PropsWithChildren } from 'react';
2
+ /**
3
+ * Общие пропсы диалогов. `ModalProps` и `SheetProps` расширяют их своими.
4
+ */
5
+ export interface DialogProps extends PropsWithChildren {
6
+ /** Показывать ли диалог */
7
+ isOpen: boolean;
8
+ /** Callback закрытия диалога */
9
+ onClose: () => void;
10
+ /**
11
+ * Цвет фона: любой CSS-цвет или токен,
12
+ * например `theme.color.fill.bg_secondary`
13
+ * @default theme.color.fill.bg_primary */
14
+ backgroundColor?: string;
15
+ /**
16
+ * Закрывать ли при клике на backdrop
17
+ * @default true */
18
+ closeOnBackdropClick?: boolean;
19
+ /**
20
+ * Закрывать ли при нажатии ESC
21
+ * @default true */
22
+ closeOnEsc?: boolean;
23
+ /**
24
+ * Отключать прокрутку body, пока диалог открыт
25
+ * @default true */
26
+ disableBodyScroll?: boolean;
27
+ /**
28
+ * Показывать ли кнопку закрытия c абсолютным позиционированием внутри
29
+ * диалога (когда не нужен Header)
30
+ * @default undefined */
31
+ showAbsoluteCloseButton?: boolean;
32
+ /**
33
+ * Показывать ли границы под Header и над Footer.
34
+ * По умолчанию у `Modal` включены, у `Sheet` выключены */
35
+ showBorders?: boolean;
36
+ /**
37
+ * Кастомный класс для overlay (backdrop)
38
+ * @default undefined */
39
+ overlayClassName?: string;
40
+ /**
41
+ * Кастомный класс для абсолютной кнопки закрытия (когда `showAbsoluteCloseButton`)
42
+ * @default undefined */
43
+ absoluteCloseButtonClassName?: string;
44
+ }
@@ -0,0 +1,10 @@
1
+ export interface DialogCloseButtonProps {
2
+ /**
3
+ * В правом верхнем углу диалога поверх содержимого — когда нет Header
4
+ * @default false */
5
+ absolute?: boolean;
6
+ /** Класс для `IconButton` */
7
+ className?: string;
8
+ }
9
+ /** Кнопка закрытия диалога: вызывает `onClose` из `DialogContext` */
10
+ export declare function DialogCloseButton({ absolute, className, }: DialogCloseButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,34 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import l from "../../../../assets/svg/modal/close.svg.js";
3
+ import { useDialogContext as s } from "../Dialog.context.js";
4
+ import { IconButton as m } from "../../../controls/IconButton/IconButton.js";
5
+ import { Box as p } from "../../Box/Box.js";
6
+ import { theme as r } from "../../../../utils/theme/index.js";
7
+ function C({
8
+ absolute: n = !1,
9
+ className: i
10
+ }) {
11
+ const { onClose: e } = s(), t = /* @__PURE__ */ o(
12
+ m,
13
+ {
14
+ onClick: e,
15
+ color: "neutral",
16
+ className: i,
17
+ size: "xs",
18
+ children: /* @__PURE__ */ o(l, {})
19
+ }
20
+ );
21
+ return n ? /* @__PURE__ */ o(
22
+ p,
23
+ {
24
+ position: "absolute",
25
+ top: r.spacing.lg,
26
+ right: r.spacing.lg,
27
+ zIndex: 1,
28
+ children: t
29
+ }
30
+ ) : t;
31
+ }
32
+ export {
33
+ C as DialogCloseButton
34
+ };
@@ -0,0 +1,2 @@
1
+ export type { DialogCloseButtonProps } from './DialogCloseButton';
2
+ export { DialogCloseButton } from './DialogCloseButton';
@@ -1,11 +1,11 @@
1
1
  import { BoxProps } from '../../Box';
2
2
  /**
3
- * Пропсы компонента `ModalFooter`.
3
+ * Пропсы компонента `DialogFooter`.
4
4
  *
5
5
  * Наследует все пропсы `Box` (см. {@link BoxProps}); ниже переопределены
6
6
  * футер-специфичные пропсы с их значениями по умолчанию.
7
7
  */
8
- export interface ModalFooterProps extends BoxProps {
8
+ export interface DialogFooterProps extends BoxProps {
9
9
  /**
10
10
  * Дочерние элементы футера (обычно кнопки действий).
11
11
  * @default undefined */
@@ -32,42 +32,33 @@ export interface ModalFooterProps extends BoxProps {
32
32
  className?: string;
33
33
  }
34
34
  /**
35
- * Компонент футера модального окна.
35
+ * Компонент футера диалога. Общий для `Modal` и `Sheet`: доступен как
36
+ * `Modal.Footer` и `Sheet.Footer`.
36
37
  *
37
- * `ModalFooter` представляет собой нижнюю часть модального окна, предназначенную
38
+ * `DialogFooter` представляет собой нижнюю часть диалога, предназначенную
38
39
  * для размещения кнопок действий и другого контента управления. Компонент является
39
40
  * оберткой над `Box` с предустановленными стилями и настройками.
40
41
  *
41
42
  * @example
42
43
  * ```tsx
43
44
  * // Базовое использование с кнопками
44
- * <ModalFooter>
45
+ * <Modal.Footer>
45
46
  * <Button variant="secondary">Отмена</Button>
46
47
  * <Button variant="primary">Сохранить</Button>
47
- * </ModalFooter>
48
+ * </Modal.Footer>
48
49
  *
49
50
  * // С настройкой отступов
50
- * <ModalFooter gap="var(--spacing-md)" p="var(--spacing-xl)">
51
+ * <Modal.Footer gap="var(--spacing-md)" p="var(--spacing-xl)">
51
52
  * <Button variant="ghost">Назад</Button>
52
53
  * <Button variant="primary">Далее</Button>
53
- * </ModalFooter>
54
+ * </Modal.Footer>
54
55
  *
55
56
  * // Вертикальное расположение
56
- * <ModalFooter row={false}>
57
+ * <Modal.Footer row={false}>
57
58
  * <Button variant="primary" fullWidth>Основное действие</Button>
58
59
  * <Button variant="secondary" fullWidth>Дополнительное действие</Button>
59
- * </ModalFooter>
60
+ * </Modal.Footer>
60
61
  * ```
61
62
  */
62
- declare const ModalFooter: import('react').ForwardRefExoticComponent<Omit<ModalFooterProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
63
- /**
64
- * Экспорт компонента ModalFooter.
65
- *
66
- * Компонент автоматически применяет следующие стили:
67
- * - Верхняя граница для визуального разделения с основным контентом
68
- * - Flexbox layout с горизонтальным расположением по умолчанию
69
- * - Стандартные отступы и промежутки между элементами
70
- *
71
- * Поддерживает все пропсы компонента Box для максимальной гибкости настройки.
72
- */
73
- export { ModalFooter };
63
+ declare const DialogFooter: import('react').ForwardRefExoticComponent<Omit<DialogFooterProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
64
+ export { DialogFooter };
@@ -0,0 +1,48 @@
1
+ import { jsx as y } from "react/jsx-runtime";
2
+ import { cx as D, css as s } from "@emotion/css";
3
+ import { forwardRef as w } from "react";
4
+ import { bp as B } from "../../../../styles/utils/breakpoints.js";
5
+ import { useDialogContext as C } from "../Dialog.context.js";
6
+ import { Box as F } from "../../Box/Box.js";
7
+ import { theme as o } from "../../../../utils/theme/index.js";
8
+ const N = s({
9
+ borderTop: `1px solid ${o.color.border.neutral_alpha_basic}`
10
+ }), P = s({
11
+ [B.sm()]: { padding: o.spacing.lg }
12
+ }), S = w(
13
+ ({
14
+ children: a,
15
+ row: e = !0,
16
+ flex: i = !0,
17
+ gap: p = o.spacing.lg,
18
+ p: r,
19
+ className: m,
20
+ ...t
21
+ }, l) => {
22
+ const { showBorders: d } = C(), { px: n, py: c, pt: g, pr: f, pb: x, pl: b } = t, u = [r, n, c, g, f, x, b].some(
23
+ (h) => h !== void 0
24
+ );
25
+ return /* @__PURE__ */ y(
26
+ F,
27
+ {
28
+ "data-dialog-part": "footer",
29
+ flex: i,
30
+ row: e,
31
+ gap: p,
32
+ p: r ?? o.spacing["2xl"],
33
+ className: D(
34
+ d && N,
35
+ !u && P,
36
+ m
37
+ ),
38
+ ref: l,
39
+ ...t,
40
+ children: a
41
+ }
42
+ );
43
+ }
44
+ );
45
+ S.displayName = "DialogFooter";
46
+ export {
47
+ S as DialogFooter
48
+ };
@@ -0,0 +1,2 @@
1
+ export type { DialogFooterProps } from './DialogFooter';
2
+ export { DialogFooter } from './DialogFooter';
@@ -1,7 +1,7 @@
1
1
  import { BoxProps } from '../../Box';
2
- export interface ModalHeaderProps extends Pick<BoxProps, "p" | "px" | "py" | "pt" | "pb" | "row" | "justifyContent" | "w"> {
2
+ export interface DialogHeaderProps extends Pick<BoxProps, "p" | "px" | "py" | "pt" | "pb" | "row" | "justifyContent" | "w"> {
3
3
  /**
4
- * Основной заголовок, отображаемый в шапке модального окна.
4
+ * Основной заголовок, отображаемый в шапке диалога.
5
5
  * Стилизуется как title-3 с полужирным начертанием.
6
6
  *
7
7
  * @default undefined */
@@ -14,8 +14,8 @@ export interface ModalHeaderProps extends Pick<BoxProps, "p" | "px" | "py" | "pt
14
14
  * @default undefined */
15
15
  subtitle?: string;
16
16
  /**
17
- * Флаг отображения кнопки закрытия модального окна в правой части шапки.
18
- * При нажатии вызывает колбэк onClose из ModalContext.
17
+ * Флаг отображения кнопки закрытия диалога в правой части шапки.
18
+ * При нажатии вызывает колбэк onClose из DialogContext.
19
19
  *
20
20
  * @default false */
21
21
  showCloseButton?: boolean;
@@ -28,5 +28,9 @@ export interface ModalHeaderProps extends Pick<BoxProps, "p" | "px" | "py" | "pt
28
28
  /** Класс для `IconButton` кнопки закрытия. */
29
29
  closeButtonClassName?: string;
30
30
  }
31
- declare const ModalHeader: import('react').ForwardRefExoticComponent<ModalHeaderProps & import('react').RefAttributes<HTMLDivElement>>;
32
- export { ModalHeader };
31
+ /**
32
+ * Шапка диалога. Общая для `Modal` и `Sheet`: доступна как `Modal.Header`
33
+ * и `Sheet.Header`.
34
+ */
35
+ declare const DialogHeader: import('react').ForwardRefExoticComponent<DialogHeaderProps & import('react').RefAttributes<HTMLDivElement>>;
36
+ export { DialogHeader };
@@ -0,0 +1,97 @@
1
+ import { jsxs as s, jsx as r } from "react/jsx-runtime";
2
+ import { cx as W, css as a } from "@emotion/css";
3
+ import { forwardRef as w } from "react";
4
+ import { bp as i } from "../../../../styles/utils/breakpoints.js";
5
+ import { useDialogContext as C } from "../Dialog.context.js";
6
+ import { Text as m } from "../../Text/Text.js";
7
+ import { DialogCloseButton as j } from "../DialogCloseButton/DialogCloseButton.js";
8
+ import { Box as l } from "../../Box/Box.js";
9
+ import { theme as o } from "../../../../utils/theme/index.js";
10
+ const e = {
11
+ root: a({
12
+ [i.sm()]: { columnGap: o.spacing.md }
13
+ }),
14
+ paddingTop: a({
15
+ [i.sm()]: { paddingTop: o.spacing.xl }
16
+ }),
17
+ paddingX: a({
18
+ [i.sm()]: {
19
+ paddingLeft: o.spacing.lg,
20
+ paddingRight: o.spacing.lg
21
+ }
22
+ })
23
+ }, H = w(
24
+ ({
25
+ title: p,
26
+ subtitle: n,
27
+ w: c = "full",
28
+ p: g,
29
+ py: f,
30
+ px: t,
31
+ pt: d,
32
+ pb: h = o.spacing.lg,
33
+ row: b = !0,
34
+ justifyContent: x = "space-between",
35
+ showCloseButton: u = !1,
36
+ className: N,
37
+ titleClassName: y,
38
+ subtitleClassName: v,
39
+ closeButtonClassName: B
40
+ }, D) => {
41
+ const { showBorders: T } = C();
42
+ return /* @__PURE__ */ s(
43
+ l,
44
+ {
45
+ "data-dialog-part": "header",
46
+ w: c,
47
+ p: g,
48
+ py: f,
49
+ px: t ?? o.spacing["2xl"],
50
+ pt: d ?? o.spacing["2xl"],
51
+ pb: h,
52
+ row: b,
53
+ justifyContent: x,
54
+ ref: D,
55
+ borderColor: o.color.border.neutral_alpha_basic,
56
+ borderWidth: 0,
57
+ borderBottomWidth: T ? 1 : 0,
58
+ borderStyle: "solid",
59
+ className: W(
60
+ e.root,
61
+ d === void 0 && e.paddingTop,
62
+ t === void 0 && e.paddingX,
63
+ N
64
+ ),
65
+ children: [
66
+ /* @__PURE__ */ s(l, { gap: o.spacing.sm, children: [
67
+ /* @__PURE__ */ r(
68
+ m,
69
+ {
70
+ variant: "title-3",
71
+ colorName: "primary",
72
+ fontWeight: "semibold",
73
+ className: y,
74
+ children: p
75
+ }
76
+ ),
77
+ /* @__PURE__ */ r(
78
+ m,
79
+ {
80
+ variant: "body-1",
81
+ colorName: "tertiary",
82
+ fontWeight: "medium",
83
+ className: v,
84
+ children: n
85
+ }
86
+ )
87
+ ] }),
88
+ u && /* @__PURE__ */ r(j, { className: B })
89
+ ]
90
+ }
91
+ );
92
+ }
93
+ );
94
+ H.displayName = "DialogHeader";
95
+ export {
96
+ H as DialogHeader
97
+ };
@@ -0,0 +1,2 @@
1
+ export type { DialogHeaderProps } from './DialogHeader';
2
+ export { DialogHeader } from './DialogHeader';
@@ -1,6 +1,6 @@
1
1
  import { ScrollToOptions } from '@tanstack/react-virtual';
2
2
  import { PropsWithChildren } from 'react';
3
- interface ModalMainRef {
3
+ interface DialogMainRef {
4
4
  /** Скролл к началу списка */
5
5
  scrollToTop: () => void;
6
6
  /** Скролл к концу списка */
@@ -19,12 +19,12 @@ interface ModalMainRef {
19
19
  getTotalSize: () => number;
20
20
  }
21
21
  /**
22
- * Пропсы компонента ModalMain
22
+ * Пропсы компонента DialogMain
23
23
  *
24
- * @interface ModalMainProps
24
+ * @interface DialogMainProps
25
25
  * @extends {PropsWithChildren}
26
26
  */
27
- export interface ModalMainProps extends PropsWithChildren {
27
+ export interface DialogMainProps extends PropsWithChildren {
28
28
  /**
29
29
  * Направление расположения элементов
30
30
  * Если true, flex-direction будет row, иначе column
@@ -55,7 +55,8 @@ export interface ModalMainProps extends PropsWithChildren {
55
55
  maxHeight?: React.CSSProperties["maxHeight"];
56
56
  }
57
57
  /**
58
- * Основной контейнер для содержимого модального окна с поддержкой виртуализации.
58
+ * Основной контейнер для содержимого диалога с поддержкой виртуализации.
59
+ * Общий для `Modal` и `Sheet`: доступен как `Modal.Main` и `Sheet.Main`.
59
60
  *
60
61
  * Компонент автоматически включает виртуализацию для списков более 50 элементов,
61
62
  * что значительно улучшает производительность при работе с большими объемами данных.
@@ -63,35 +64,35 @@ export interface ModalMainProps extends PropsWithChildren {
63
64
  *
64
65
  * @example
65
66
  * // Простое использование
66
- * <ModalMain>
67
+ * <Modal.Main>
67
68
  * <div>Элемент 1</div>
68
69
  * <div>Элемент 2</div>
69
- * </ModalMain>
70
+ * </Modal.Main>
70
71
  *
71
72
  * @example
72
73
  * // С виртуализацией и управлением скроллом
73
- * const modalRef = useRef<ModalMainRef>(null);
74
+ * const mainRef = useRef<ComponentRef<typeof Modal.Main>>(null);
74
75
  *
75
76
  * const handleScrollToTop = () => {
76
- * modalRef.current?.scrollToTop();
77
+ * mainRef.current?.scrollToTop();
77
78
  * };
78
79
  *
79
- * <ModalMain
80
- * ref={modalRef}
80
+ * <Modal.Main
81
+ * ref={mainRef}
81
82
  * virtualize
82
83
  * estimatedItemHeight={120}
83
84
  * maxHeight={600}
84
85
  * >
85
86
  * {items.map(item => <Item key={item.id} data={item} />)}
86
- * </ModalMain>
87
+ * </Modal.Main>
87
88
  *
88
89
  * @example
89
90
  * // Горизонтальное расположение
90
- * <ModalMain row>
91
+ * <Modal.Main row>
91
92
  * <Column>Левая колонка</Column>
92
93
  * <Column>Правая колонка</Column>
93
- * </ModalMain>
94
+ * </Modal.Main>
94
95
  */
95
- declare const ModalMain: import('react').ForwardRefExoticComponent<ModalMainProps & import('react').RefAttributes<ModalMainRef>>;
96
- export { ModalMain };
97
- export type { ModalMainRef };
96
+ declare const DialogMain: import('react').ForwardRefExoticComponent<DialogMainProps & import('react').RefAttributes<DialogMainRef>>;
97
+ export { DialogMain };
98
+ export type { DialogMainRef };
@@ -1,26 +1,26 @@
1
1
  import { jsx as r } from "react/jsx-runtime";
2
- import { cx as p } from "@emotion/css";
2
+ import { cx as g } from "@emotion/css";
3
3
  import { useVirtualizer as T } from "@tanstack/react-virtual";
4
- import { forwardRef as O, useRef as y, useMemo as h, Children as z, useImperativeHandle as S } from "react";
5
- import { styles as u } from "./styles.js";
6
- import { Box as s } from "../../Box/Box.js";
4
+ import { forwardRef as b, useRef as O, useMemo as p, Children as y, useImperativeHandle as z } from "react";
5
+ import { styles as s } from "./styles.js";
6
+ import { Box as a } from "../../Box/Box.js";
7
7
  import { theme as i } from "../../../../utils/theme/index.js";
8
- const b = O(
8
+ const S = b(
9
9
  ({
10
- children: n,
10
+ children: m,
11
11
  className: f,
12
12
  row: c = !1,
13
- estimatedItemHeight: g = 100,
14
- virtualize: m = !1,
15
- maxHeight: d = 448
13
+ estimatedItemHeight: u = 100,
14
+ virtualize: d = !1,
15
+ maxHeight: h = 448
16
16
  }, x) => {
17
- const a = y(null), t = h(() => z.toArray(n), [n]), e = T({
17
+ const n = O(null), t = p(() => y.toArray(m), [m]), e = T({
18
18
  count: t.length,
19
- getScrollElement: () => a.current,
20
- estimateSize: () => g,
19
+ getScrollElement: () => n.current,
20
+ estimateSize: () => u,
21
21
  measureElement: (o) => o.getBoundingClientRect().height
22
22
  });
23
- return S(
23
+ return z(
24
24
  x,
25
25
  () => ({
26
26
  scrollToTop: () => e.scrollToOffset(0, { behavior: "smooth" }),
@@ -38,25 +38,26 @@ const b = O(
38
38
  behavior: "smooth"
39
39
  });
40
40
  },
41
- getElement: () => a.current,
41
+ getElement: () => n.current,
42
42
  getScrollOffset: () => e.scrollOffset || 0,
43
43
  getTotalSize: () => e.getTotalSize()
44
44
  }),
45
45
  [e]
46
- ), h(
47
- () => m || t.length > 50,
48
- [m, t]
46
+ ), p(
47
+ () => d || t.length > 50,
48
+ [d, t]
49
49
  ) && t.length > 0 ? /* @__PURE__ */ r(
50
- s,
50
+ a,
51
51
  {
52
- ref: a,
52
+ "data-dialog-part": "main",
53
+ ref: n,
53
54
  row: c,
54
- maxHeight: d,
55
- className: p(u.main, f),
55
+ maxHeight: h,
56
+ className: g(s.main, s.mobileVirtualPadding, f),
56
57
  w: "full",
57
58
  p: i.spacing["2xl"],
58
- children: /* @__PURE__ */ r(s, { relative: !0, h: e.getTotalSize(), children: e.getVirtualItems().map((o) => /* @__PURE__ */ r(
59
- s,
59
+ children: /* @__PURE__ */ r(a, { relative: !0, h: e.getTotalSize(), children: e.getVirtualItems().map((o) => /* @__PURE__ */ r(
60
+ a,
60
61
  {
61
62
  "data-index": o.index,
62
63
  ref: e.measureElement,
@@ -73,20 +74,29 @@ const b = O(
73
74
  )) })
74
75
  }
75
76
  ) : /* @__PURE__ */ r(
76
- s,
77
+ a,
77
78
  {
78
- ref: a,
79
- className: p(u.main, f),
79
+ "data-dialog-part": "main",
80
+ ref: n,
81
+ className: g(s.main, s.mobilePadding, f),
80
82
  w: "full",
81
83
  row: c,
82
84
  pl: i.spacing["2xl"],
83
85
  pr: i.spacing.xs,
84
- children: /* @__PURE__ */ r(s, { py: i.spacing["2xl"], pr: i.spacing.xl, children: n })
86
+ children: /* @__PURE__ */ r(
87
+ a,
88
+ {
89
+ py: i.spacing["2xl"],
90
+ pr: i.spacing.xl,
91
+ className: s.mobileContentPadding,
92
+ children: m
93
+ }
94
+ )
85
95
  }
86
96
  );
87
97
  }
88
98
  );
89
- b.displayName = "ModalMain";
99
+ S.displayName = "DialogMain";
90
100
  export {
91
- b as ModalMain
101
+ S as DialogMain
92
102
  };
@@ -0,0 +1,2 @@
1
+ export type { DialogMainProps, DialogMainRef } from './DialogMain';
2
+ export { DialogMain } from './DialogMain';
@@ -0,0 +1,6 @@
1
+ export declare const styles: {
2
+ mobilePadding: string;
3
+ mobileContentPadding: string;
4
+ mobileVirtualPadding: string;
5
+ main: string;
6
+ };
@@ -1,6 +1,22 @@
1
1
  import { css as o } from "@emotion/css";
2
+ import { bp as a } from "../../../../styles/utils/breakpoints.js";
2
3
  import { theme as r } from "../../../../utils/theme/index.js";
3
4
  const c = {
5
+ // На узких экранах — отступы как у Sheet. Справа часть отступа отдана
6
+ // под полосу прокрутки: внешние 4px + внутренние 12px
7
+ mobilePadding: o({
8
+ [a.sm()]: { paddingLeft: r.spacing.lg }
9
+ }),
10
+ mobileContentPadding: o({
11
+ [a.sm()]: {
12
+ paddingTop: r.spacing.md,
13
+ paddingRight: r.spacing.md,
14
+ paddingBottom: r.spacing.md
15
+ }
16
+ }),
17
+ mobileVirtualPadding: o({
18
+ [a.sm()]: { padding: `${r.spacing.md} ${r.spacing.lg}` }
19
+ }),
4
20
  main: o({
5
21
  flex: 0,
6
22
  overflowY: "auto",
@@ -0,0 +1,3 @@
1
+ export { useBackdropClose } from './useBackdropClose';
2
+ export { useBodyScrollLock } from './useBodyScrollLock';
3
+ export { useCloseOnEsc } from './useCloseOnEsc';