@koslibs/components 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/dist/components/Button/button.js +1 -0
- package/dist/components/Collapse/collapse.d.ts +91 -0
- package/dist/components/Collapse/collapse.js +103 -0
- package/dist/components/Collapse/index.d.ts +2 -0
- package/dist/components/Collapse/index.js +1 -0
- package/dist/components/Collapse/index.module.js +12 -0
- package/dist/components/Collapse/index_module.css +82 -0
- package/dist/components/Collapse/vars.css +6 -0
- package/dist/components/Modal/colors.module.js +5 -0
- package/dist/components/Modal/colors_module.css +10 -0
- package/dist/components/Modal/components/content/index.d.ts +15 -0
- package/dist/components/Modal/components/content/index.js +18 -0
- package/dist/components/Modal/components/content/index.module.js +5 -0
- package/dist/components/Modal/components/content/index_module.css +12 -0
- package/dist/components/Modal/components/controls/index.d.ts +56 -0
- package/dist/components/Modal/components/controls/index.js +23 -0
- package/dist/components/Modal/components/controls/index.module.js +19 -0
- package/dist/components/Modal/components/controls/index_module.css +52 -0
- package/dist/components/Modal/components/footer/index.d.ts +15 -0
- package/dist/components/Modal/components/footer/index.js +18 -0
- package/dist/components/Modal/components/footer/index.module.js +5 -0
- package/dist/components/Modal/components/footer/index_module.css +9 -0
- package/dist/components/Modal/components/header/index.d.ts +43 -0
- package/dist/components/Modal/components/header/index.js +53 -0
- package/dist/components/Modal/components/header/index.module.js +8 -0
- package/dist/components/Modal/components/header/index_module.css +31 -0
- package/dist/components/Modal/components/modal-surface/index.d.ts +4 -0
- package/dist/components/Modal/components/modal-surface/index.js +81 -0
- package/dist/components/Modal/context.d.ts +6 -0
- package/dist/components/Modal/context.js +3 -0
- package/dist/components/Modal/index.d.ts +10 -0
- package/dist/components/Modal/index.js +5 -0
- package/dist/components/Modal/index.module.js +15 -0
- package/dist/components/Modal/index_module.css +46 -0
- package/dist/components/Modal/modal.d.ts +10 -0
- package/dist/components/Modal/modal.js +13 -0
- package/dist/components/Modal/types.d.ts +41 -0
- package/dist/components/Modal/types.js +0 -0
- package/dist/components/Modal/utils/lock-scroll.d.ts +1 -0
- package/dist/components/Modal/utils/lock-scroll.js +31 -0
- package/dist/components/Modal/vars.css +9 -0
- package/dist/components/Popover/popover.js +9 -7
- package/dist/components/Popover/types.d.ts +3 -1
- package/dist/components/Portal/index.d.ts +2 -0
- package/dist/components/Portal/index.js +1 -0
- package/dist/components/Portal/portal.d.ts +2 -0
- package/dist/components/Portal/portal.js +19 -0
- package/dist/components/Portal/types.d.ts +18 -0
- package/dist/components/Portal/types.js +0 -0
- package/dist/components/Typography/shared.d.ts +9 -3
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# @koslibs/components
|
|
2
2
|
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#5](https://github.com/koslibs/components/pull/5) [`68d3460`](https://github.com/koslibs/components/commit/68d34608d599582acf4115d31f64fb0168213edb) Thanks [@holypower777](https://github.com/holypower777)! - Перенесён Modal из GullEye core-components с Header, Content, Footer и Controls.
|
|
8
|
+
Добавлены прямой импорт `@koslibs/components/Modal`, размеры 480/600/720/960/fullscreen,
|
|
9
|
+
управляемое закрытие, блокировка прокрутки и поддержка вложенных окон.
|
|
10
|
+
Docs содержат вкладки документации, Props, CSS-переменных и истории изменений,
|
|
11
|
+
а также примеры длинного контента и Popover внутри нативного dialog.
|
|
12
|
+
Блокировка прокрутки учитывает `scrollbar-gutter: stable`, чтобы контент страницы
|
|
13
|
+
не смещался из-за двойной компенсации места под скроллбар.
|
|
14
|
+
|
|
15
|
+
Modal синхронизирован с документацией Figma: типографика Header 20 px semibold /
|
|
16
|
+
14 px regular, крестик 18 px в области 48 × 32 px, Header без нижнего и Footer
|
|
17
|
+
без верхнего отступа. В строковых Controls две Button с block=true делят ширину
|
|
18
|
+
одной строки поровну с учётом gap; column растягивает кнопки по ширине вертикально.
|
|
19
|
+
|
|
20
|
+
Убран `Header.onClose`: крестик вызывает общий `Modal.onClose` через внутренний
|
|
21
|
+
React Context. Вложенный Header использует обработчик ближайшего Modal;
|
|
22
|
+
обработчик больше не нужно передавать отдельно в заголовок.
|
|
23
|
+
|
|
24
|
+
Header, Content, Footer и Controls наследуют `Modal.dataTestId` с суффиксами
|
|
25
|
+
`-header`, `-content`, `-footer`, `-controls`. Явный dataTestId части имеет приоритет;
|
|
26
|
+
вложенные окна используют только свой базовый идентификатор.
|
|
27
|
+
|
|
28
|
+
Добавлен отдельный Portal с `getPortalContainer`, `immediateMount`, ref на контейнер
|
|
29
|
+
и немедленным монтированием по умолчанию (`immediateMount=true`). Значение false
|
|
30
|
+
позволяет дождаться DOM-контейнера из ref. Modal и Popover используют
|
|
31
|
+
общий Portal; прямой импорт доступен через `@koslibs/components/Portal`.
|
|
32
|
+
|
|
33
|
+
## 1.3.0
|
|
34
|
+
|
|
35
|
+
### Minor Changes
|
|
36
|
+
|
|
37
|
+
- [#4](https://github.com/koslibs/components/pull/4) [`b37f3b0`](https://github.com/koslibs/components/commit/b37f3b008be8ffea80908557c13ea77d6d55c792) Thanks [@holypower777](https://github.com/holypower777)! - Перенесён Collapse из core-components GullEye с отдельным импортом
|
|
38
|
+
`@koslibs/components/Collapse`, внутренним и внешним управлением, сохранением
|
|
39
|
+
содержимого, анимацией и поддержкой reduced motion. Проп `colors` убран:
|
|
40
|
+
оформление кнопки настраивается через CSS-переменные. Добавлены документация
|
|
41
|
+
с тремя вкладками, Playground и история компонента. Стрелка подключается
|
|
42
|
+
отдельным импортом из `@koslibs/icons`.
|
|
43
|
+
|
|
44
|
+
Подписи `collapsedLabel` и `expandedLabel` не имеют дефолтных значений.
|
|
45
|
+
Добавлены `showRightChevron` (по умолчанию `true`) и `showLeftChevron`
|
|
46
|
+
(по умолчанию `false`): можно независимо показывать шевроны или скрыть оба.
|
|
47
|
+
Левый шеврон смотрит вправо в закрытом состоянии и вниз в раскрытом,
|
|
48
|
+
правый сохраняет поворот вниз → вверх.
|
|
49
|
+
|
|
50
|
+
Комментарии публичных пропсов приведены к единому многострочному формату JSDoc
|
|
51
|
+
с отдельной строкой для `@default`.
|
|
52
|
+
|
|
3
53
|
## 1.2.0
|
|
4
54
|
|
|
5
55
|
### Minor Changes
|
|
@@ -76,6 +76,7 @@ const Button = /*#__PURE__*/ forwardRef(({ view = 'primary', shape = 'rectangula
|
|
|
76
76
|
[colors_module.loading]: showLoader
|
|
77
77
|
}, className),
|
|
78
78
|
"data-test-id": dataTestId,
|
|
79
|
+
"data-block": block || void 0,
|
|
79
80
|
type: type,
|
|
80
81
|
disabled: disabled || showLoader,
|
|
81
82
|
"aria-busy": showLoader,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
export type CollapseProps = Omit<HTMLAttributes<HTMLDivElement>, 'onTransitionEnd'> & {
|
|
3
|
+
/**
|
|
4
|
+
* Состояние controlled-компонента.
|
|
5
|
+
*/
|
|
6
|
+
expanded?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Начальное состояние uncontrolled-компонента.
|
|
9
|
+
* @default false
|
|
10
|
+
*/
|
|
11
|
+
defaultExpanded?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Подпись кнопки, когда содержимое скрыто.
|
|
14
|
+
*/
|
|
15
|
+
collapsedLabel?: ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Подпись кнопки, когда содержимое раскрыто.
|
|
18
|
+
*/
|
|
19
|
+
expandedLabel?: ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* Показывать шеврон справа от подписи: вниз при закрытии, вверх при раскрытии.
|
|
22
|
+
* @default true
|
|
23
|
+
*/
|
|
24
|
+
showRightChevron?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Показывать шеврон слева от подписи: вправо при закрытии, вниз при раскрытии.
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
showLeftChevron?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Запрос изменения состояния. В controlled-режиме обновите expanded.
|
|
32
|
+
*/
|
|
33
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Завершение раскрытия/сворачивания; без анимации вызывается сразу.
|
|
36
|
+
*/
|
|
37
|
+
onTransitionEnd?: (expanded: boolean) => void;
|
|
38
|
+
/**
|
|
39
|
+
* Дополнительный класс внутреннего контейнера содержимого.
|
|
40
|
+
*/
|
|
41
|
+
expandedContentClassName?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Идентификатор корневого элемента для автоматизированных тестов.
|
|
44
|
+
*/
|
|
45
|
+
dataTestId?: string;
|
|
46
|
+
};
|
|
47
|
+
export declare const Collapse: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "onTransitionEnd"> & {
|
|
48
|
+
/**
|
|
49
|
+
* Состояние controlled-компонента.
|
|
50
|
+
*/
|
|
51
|
+
expanded?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Начальное состояние uncontrolled-компонента.
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
defaultExpanded?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Подпись кнопки, когда содержимое скрыто.
|
|
59
|
+
*/
|
|
60
|
+
collapsedLabel?: ReactNode;
|
|
61
|
+
/**
|
|
62
|
+
* Подпись кнопки, когда содержимое раскрыто.
|
|
63
|
+
*/
|
|
64
|
+
expandedLabel?: ReactNode;
|
|
65
|
+
/**
|
|
66
|
+
* Показывать шеврон справа от подписи: вниз при закрытии, вверх при раскрытии.
|
|
67
|
+
* @default true
|
|
68
|
+
*/
|
|
69
|
+
showRightChevron?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Показывать шеврон слева от подписи: вправо при закрытии, вниз при раскрытии.
|
|
72
|
+
* @default false
|
|
73
|
+
*/
|
|
74
|
+
showLeftChevron?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Запрос изменения состояния. В controlled-режиме обновите expanded.
|
|
77
|
+
*/
|
|
78
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
79
|
+
/**
|
|
80
|
+
* Завершение раскрытия/сворачивания; без анимации вызывается сразу.
|
|
81
|
+
*/
|
|
82
|
+
onTransitionEnd?: (expanded: boolean) => void;
|
|
83
|
+
/**
|
|
84
|
+
* Дополнительный класс внутреннего контейнера содержимого.
|
|
85
|
+
*/
|
|
86
|
+
expandedContentClassName?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Идентификатор корневого элемента для автоматизированных тестов.
|
|
89
|
+
*/
|
|
90
|
+
dataTestId?: string;
|
|
91
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ChevronDownIcon } from "@koslibs/icons/ChevronDownIcon";
|
|
3
|
+
import classnames from "classnames";
|
|
4
|
+
import { forwardRef, useId, useLayoutEffect, useRef, useState } from "react";
|
|
5
|
+
import index_module from "./index.module.js";
|
|
6
|
+
const Collapse = /*#__PURE__*/ forwardRef(({ expanded, defaultExpanded = false, collapsedLabel, expandedLabel, showRightChevron = true, showLeftChevron = false, onExpandedChange, onTransitionEnd, expandedContentClassName, dataTestId, className, children, ...restProps }, ref)=>{
|
|
7
|
+
const [expandedState, setExpandedState] = useState(defaultExpanded);
|
|
8
|
+
const isExpanded = expanded ?? expandedState;
|
|
9
|
+
const contentId = `collapse-${useId()}`;
|
|
10
|
+
const contentRef = useRef(null);
|
|
11
|
+
const innerRef = useRef(null);
|
|
12
|
+
const toggleRef = useRef(null);
|
|
13
|
+
const previousExpanded = useRef(isExpanded);
|
|
14
|
+
const pendingTransition = useRef(false);
|
|
15
|
+
const transitionCallback = useRef(onTransitionEnd);
|
|
16
|
+
const label = isExpanded ? expandedLabel || collapsedLabel : collapsedLabel || expandedLabel;
|
|
17
|
+
useLayoutEffect(()=>{
|
|
18
|
+
transitionCallback.current = onTransitionEnd;
|
|
19
|
+
}, [
|
|
20
|
+
onTransitionEnd
|
|
21
|
+
]);
|
|
22
|
+
useLayoutEffect(()=>{
|
|
23
|
+
const content = contentRef.current;
|
|
24
|
+
if (!content) return;
|
|
25
|
+
if (!isExpanded && content.contains(content.ownerDocument.activeElement)) toggleRef.current?.focus();
|
|
26
|
+
content.inert = !isExpanded;
|
|
27
|
+
if (previousExpanded.current === isExpanded) return;
|
|
28
|
+
previousExpanded.current = isExpanded;
|
|
29
|
+
pendingTransition.current = true;
|
|
30
|
+
const transitionDuration = content.ownerDocument.defaultView?.getComputedStyle(content).transitionDuration;
|
|
31
|
+
if (innerRef.current?.scrollHeight === 0 || 0 === parseFloat(transitionDuration ?? '0')) {
|
|
32
|
+
pendingTransition.current = false;
|
|
33
|
+
transitionCallback.current?.(isExpanded);
|
|
34
|
+
}
|
|
35
|
+
}, [
|
|
36
|
+
isExpanded
|
|
37
|
+
]);
|
|
38
|
+
const handleToggle = ()=>{
|
|
39
|
+
const nextExpanded = !isExpanded;
|
|
40
|
+
if (void 0 === expanded) setExpandedState(nextExpanded);
|
|
41
|
+
onExpandedChange?.(nextExpanded);
|
|
42
|
+
};
|
|
43
|
+
const handleTransitionEnd = (event)=>{
|
|
44
|
+
if (event.target === event.currentTarget && 'grid-template-rows' === event.propertyName && pendingTransition.current) {
|
|
45
|
+
pendingTransition.current = false;
|
|
46
|
+
transitionCallback.current?.(isExpanded);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
50
|
+
...restProps,
|
|
51
|
+
ref: ref,
|
|
52
|
+
className: classnames(index_module.component, className),
|
|
53
|
+
"data-test-id": dataTestId,
|
|
54
|
+
children: [
|
|
55
|
+
label && /*#__PURE__*/ jsxs("button", {
|
|
56
|
+
ref: toggleRef,
|
|
57
|
+
type: "button",
|
|
58
|
+
className: index_module.toggle,
|
|
59
|
+
"aria-expanded": isExpanded,
|
|
60
|
+
"aria-controls": contentId,
|
|
61
|
+
onClick: handleToggle,
|
|
62
|
+
"data-test-id": dataTestId ? `${dataTestId}-toggle` : void 0,
|
|
63
|
+
children: [
|
|
64
|
+
showLeftChevron && /*#__PURE__*/ jsx(ChevronDownIcon, {
|
|
65
|
+
className: classnames(index_module.icon, index_module.leftIcon, {
|
|
66
|
+
[index_module.rotated]: isExpanded
|
|
67
|
+
}),
|
|
68
|
+
"aria-hidden": "true"
|
|
69
|
+
}),
|
|
70
|
+
/*#__PURE__*/ jsx("span", {
|
|
71
|
+
children: label
|
|
72
|
+
}),
|
|
73
|
+
showRightChevron && /*#__PURE__*/ jsx(ChevronDownIcon, {
|
|
74
|
+
className: classnames(index_module.icon, {
|
|
75
|
+
[index_module.rotated]: isExpanded
|
|
76
|
+
}),
|
|
77
|
+
"aria-hidden": "true"
|
|
78
|
+
})
|
|
79
|
+
]
|
|
80
|
+
}),
|
|
81
|
+
/*#__PURE__*/ jsx("div", {
|
|
82
|
+
ref: contentRef,
|
|
83
|
+
id: contentId,
|
|
84
|
+
className: classnames(index_module.content, {
|
|
85
|
+
[index_module.expanded]: isExpanded
|
|
86
|
+
}),
|
|
87
|
+
"aria-hidden": !isExpanded,
|
|
88
|
+
"data-test-id": dataTestId ? `${dataTestId}-content` : void 0,
|
|
89
|
+
onTransitionEnd: handleTransitionEnd,
|
|
90
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
91
|
+
className: index_module.clip,
|
|
92
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
93
|
+
ref: innerRef,
|
|
94
|
+
className: expandedContentClassName,
|
|
95
|
+
children: children
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
]
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
Collapse.displayName = 'Collapse';
|
|
103
|
+
export { Collapse };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Collapse } from "./collapse.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "./index_module.css";
|
|
2
|
+
const index_module = {
|
|
3
|
+
component: "component-tPiInR",
|
|
4
|
+
content: "content-D8E_z9",
|
|
5
|
+
expanded: "expanded-rqGMOG",
|
|
6
|
+
clip: "clip-D3ydtQ",
|
|
7
|
+
toggle: "toggle-YA8uJB",
|
|
8
|
+
icon: "icon-wFeaQN",
|
|
9
|
+
rotated: "rotated-sRw5l2",
|
|
10
|
+
leftIcon: "leftIcon-PGZrVM"
|
|
11
|
+
};
|
|
12
|
+
export default index_module;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
@import "../../styles/theme.css";
|
|
2
|
+
@import "./vars.css";
|
|
3
|
+
|
|
4
|
+
.component-tPiInR {
|
|
5
|
+
min-width: 0;
|
|
6
|
+
font-family: var(--font-primary);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.content-D8E_z9 {
|
|
10
|
+
visibility: hidden;
|
|
11
|
+
grid-template-rows: 0fr;
|
|
12
|
+
transition: grid-template-rows .2s, visibility 0s linear .2s;
|
|
13
|
+
display: grid;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.expanded-rqGMOG {
|
|
17
|
+
visibility: visible;
|
|
18
|
+
grid-template-rows: 1fr;
|
|
19
|
+
transition-delay: 0s;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.clip-D3ydtQ {
|
|
23
|
+
min-height: 0;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.toggle-YA8uJB {
|
|
28
|
+
align-items: center;
|
|
29
|
+
gap: var(--size-4, 4px);
|
|
30
|
+
max-width: 100%;
|
|
31
|
+
padding: var(--size-8, 8px) 0;
|
|
32
|
+
color: var(--collapse-color);
|
|
33
|
+
font: inherit;
|
|
34
|
+
text-align: left;
|
|
35
|
+
overflow-wrap: anywhere;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
background: none;
|
|
38
|
+
border: 0;
|
|
39
|
+
margin: 0;
|
|
40
|
+
font-size: 13px;
|
|
41
|
+
line-height: 20px;
|
|
42
|
+
display: inline-flex;
|
|
43
|
+
|
|
44
|
+
&:hover {
|
|
45
|
+
color: var(--collapse-hover-color);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&:hover span {
|
|
49
|
+
text-underline-offset: 3px;
|
|
50
|
+
text-decoration: underline;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&:focus-visible {
|
|
54
|
+
outline: 2px solid var(--collapse-focus-color);
|
|
55
|
+
outline-offset: 2px;
|
|
56
|
+
border-radius: var(--border-radius-4, 4px);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.icon-wFeaQN {
|
|
61
|
+
flex-shrink: 0;
|
|
62
|
+
transition: transform .2s;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.rotated-sRw5l2 {
|
|
66
|
+
transform: rotate(180deg);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.leftIcon-PGZrVM {
|
|
70
|
+
transform: rotate(-90deg);
|
|
71
|
+
|
|
72
|
+
&.rotated-sRw5l2 {
|
|
73
|
+
transform: rotate(0);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@media (prefers-reduced-motion: reduce) {
|
|
78
|
+
.content-D8E_z9, .icon-wFeaQN {
|
|
79
|
+
transition: none;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type HTMLAttributes } from 'react';
|
|
2
|
+
export type ContentProps = HTMLAttributes<HTMLDivElement> & {
|
|
3
|
+
/**
|
|
4
|
+
* Базовый идентификатор для автоматизированных тестов с суффиксом -content.
|
|
5
|
+
* По умолчанию наследуется от ближайшего Modal; явно заданный имеет приоритет.
|
|
6
|
+
*/
|
|
7
|
+
dataTestId?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const Content: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & {
|
|
10
|
+
/**
|
|
11
|
+
* Базовый идентификатор для автоматизированных тестов с суффиксом -content.
|
|
12
|
+
* По умолчанию наследуется от ближайшего Modal; явно заданный имеет приоритет.
|
|
13
|
+
*/
|
|
14
|
+
dataTestId?: string;
|
|
15
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
import { forwardRef, useContext } from "react";
|
|
4
|
+
import { ModalContext } from "../../context.js";
|
|
5
|
+
import index_module from "./index.module.js";
|
|
6
|
+
const Content = /*#__PURE__*/ forwardRef(({ children, className, dataTestId, ...restProps }, ref)=>{
|
|
7
|
+
const { dataTestId: modalDataTestId } = useContext(ModalContext);
|
|
8
|
+
const testId = dataTestId ?? modalDataTestId;
|
|
9
|
+
return /*#__PURE__*/ jsx("div", {
|
|
10
|
+
...restProps,
|
|
11
|
+
ref: ref,
|
|
12
|
+
className: classnames(index_module.component, className),
|
|
13
|
+
"data-test-id": testId ? `${testId}-content` : void 0,
|
|
14
|
+
children: children
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
Content.displayName = 'ModalContent';
|
|
18
|
+
export { Content };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export type ControlsProps = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
/**
|
|
5
|
+
* Основное действие, отображается после дополнительного.
|
|
6
|
+
*/
|
|
7
|
+
primary?: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Дополнительное действие.
|
|
10
|
+
*/
|
|
11
|
+
secondary?: ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* Выравнивание действий.
|
|
14
|
+
* В строковых раскладках block-кнопки делят свободную ширину поровну.
|
|
15
|
+
* В column кнопки занимают всю ширину и располагаются друг под другом.
|
|
16
|
+
* @default 'end'
|
|
17
|
+
*/
|
|
18
|
+
layout?: 'start' | 'end' | 'center' | 'space-between' | 'column';
|
|
19
|
+
/**
|
|
20
|
+
* Расстояние между действиями.
|
|
21
|
+
* @default 12
|
|
22
|
+
*/
|
|
23
|
+
gap?: 8 | 12 | 16 | 24;
|
|
24
|
+
/**
|
|
25
|
+
* Базовый идентификатор для автоматизированных тестов с суффиксом -controls.
|
|
26
|
+
* По умолчанию наследуется от ближайшего Modal; явно заданный имеет приоритет.
|
|
27
|
+
*/
|
|
28
|
+
dataTestId?: string;
|
|
29
|
+
};
|
|
30
|
+
export declare const Controls: React.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & {
|
|
31
|
+
/**
|
|
32
|
+
* Основное действие, отображается после дополнительного.
|
|
33
|
+
*/
|
|
34
|
+
primary?: ReactNode;
|
|
35
|
+
/**
|
|
36
|
+
* Дополнительное действие.
|
|
37
|
+
*/
|
|
38
|
+
secondary?: ReactNode;
|
|
39
|
+
/**
|
|
40
|
+
* Выравнивание действий.
|
|
41
|
+
* В строковых раскладках block-кнопки делят свободную ширину поровну.
|
|
42
|
+
* В column кнопки занимают всю ширину и располагаются друг под другом.
|
|
43
|
+
* @default 'end'
|
|
44
|
+
*/
|
|
45
|
+
layout?: "start" | "end" | "center" | "space-between" | "column";
|
|
46
|
+
/**
|
|
47
|
+
* Расстояние между действиями.
|
|
48
|
+
* @default 12
|
|
49
|
+
*/
|
|
50
|
+
gap?: 8 | 12 | 16 | 24;
|
|
51
|
+
/**
|
|
52
|
+
* Базовый идентификатор для автоматизированных тестов с суффиксом -controls.
|
|
53
|
+
* По умолчанию наследуется от ближайшего Modal; явно заданный имеет приоритет.
|
|
54
|
+
*/
|
|
55
|
+
dataTestId?: string;
|
|
56
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
import react, { forwardRef, useContext } from "react";
|
|
4
|
+
import { ModalContext } from "../../context.js";
|
|
5
|
+
import index_module from "./index.module.js";
|
|
6
|
+
const Controls = /*#__PURE__*/ forwardRef(({ primary, secondary, layout = 'end', gap = 12, className, children, dataTestId, ...restProps }, ref)=>{
|
|
7
|
+
const { dataTestId: modalDataTestId } = useContext(ModalContext);
|
|
8
|
+
const testId = dataTestId ?? modalDataTestId;
|
|
9
|
+
return /*#__PURE__*/ jsx("div", {
|
|
10
|
+
...restProps,
|
|
11
|
+
ref: ref,
|
|
12
|
+
className: classnames(index_module.component, index_module[layout], index_module[`gap-${gap}`], className),
|
|
13
|
+
"data-test-id": testId ? `${testId}-controls` : void 0,
|
|
14
|
+
children: children ?? /*#__PURE__*/ jsxs(react.Fragment, {
|
|
15
|
+
children: [
|
|
16
|
+
secondary,
|
|
17
|
+
primary
|
|
18
|
+
]
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
Controls.displayName = 'ModalControls';
|
|
23
|
+
export { Controls };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import "./index_module.css";
|
|
2
|
+
const index_module = {
|
|
3
|
+
component: "component-IPNCFT",
|
|
4
|
+
column: "column-dBeQXP",
|
|
5
|
+
start: "start-ouHlcU",
|
|
6
|
+
end: "end-TYAvEX",
|
|
7
|
+
center: "center-I4ALjs",
|
|
8
|
+
"space-between": "space-between-OxpVhA",
|
|
9
|
+
spaceBetween: "space-between-OxpVhA",
|
|
10
|
+
"gap-8": "gap-8-xwhlts",
|
|
11
|
+
gap8: "gap-8-xwhlts",
|
|
12
|
+
"gap-12": "gap-12-IFyQQK",
|
|
13
|
+
gap12: "gap-12-IFyQQK",
|
|
14
|
+
"gap-16": "gap-16-iZpxeN",
|
|
15
|
+
gap16: "gap-16-iZpxeN",
|
|
16
|
+
"gap-24": "gap-24-eEhuId",
|
|
17
|
+
gap24: "gap-24-eEhuId"
|
|
18
|
+
};
|
|
19
|
+
export default index_module;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
.component-IPNCFT {
|
|
2
|
+
flex-wrap: wrap;
|
|
3
|
+
align-items: center;
|
|
4
|
+
width: 100%;
|
|
5
|
+
display: flex;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.component-IPNCFT:not(.column-dBeQXP) > button[data-block="true"] {
|
|
9
|
+
flex: 1 1 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.start-ouHlcU {
|
|
13
|
+
justify-content: flex-start;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.end-TYAvEX {
|
|
17
|
+
justify-content: flex-end;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.center-I4ALjs {
|
|
21
|
+
justify-content: center;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.space-between-OxpVhA {
|
|
25
|
+
justify-content: space-between;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.column-dBeQXP {
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
align-items: stretch;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.column-dBeQXP > button {
|
|
34
|
+
width: 100%;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.gap-8-xwhlts {
|
|
38
|
+
gap: var(--size-8, 8px);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.gap-12-IFyQQK {
|
|
42
|
+
gap: var(--size-12, 12px);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.gap-16-iZpxeN {
|
|
46
|
+
gap: var(--size-16, 16px);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.gap-24-eEhuId {
|
|
50
|
+
gap: var(--size-24, 24px);
|
|
51
|
+
}
|
|
52
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type HTMLAttributes } from 'react';
|
|
2
|
+
export type FooterProps = HTMLAttributes<HTMLDivElement> & {
|
|
3
|
+
/**
|
|
4
|
+
* Базовый идентификатор для автоматизированных тестов с суффиксом -footer.
|
|
5
|
+
* По умолчанию наследуется от ближайшего Modal; явно заданный имеет приоритет.
|
|
6
|
+
*/
|
|
7
|
+
dataTestId?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const Footer: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & {
|
|
10
|
+
/**
|
|
11
|
+
* Базовый идентификатор для автоматизированных тестов с суффиксом -footer.
|
|
12
|
+
* По умолчанию наследуется от ближайшего Modal; явно заданный имеет приоритет.
|
|
13
|
+
*/
|
|
14
|
+
dataTestId?: string;
|
|
15
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
import { forwardRef, useContext } from "react";
|
|
4
|
+
import { ModalContext } from "../../context.js";
|
|
5
|
+
import index_module from "./index.module.js";
|
|
6
|
+
const Footer = /*#__PURE__*/ forwardRef(({ children, className, dataTestId, ...restProps }, ref)=>{
|
|
7
|
+
const { dataTestId: modalDataTestId } = useContext(ModalContext);
|
|
8
|
+
const testId = dataTestId ?? modalDataTestId;
|
|
9
|
+
return /*#__PURE__*/ jsx("div", {
|
|
10
|
+
...restProps,
|
|
11
|
+
ref: ref,
|
|
12
|
+
className: classnames(index_module.component, className),
|
|
13
|
+
"data-test-id": testId ? `${testId}-footer` : void 0,
|
|
14
|
+
children: children
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
Footer.displayName = 'ModalFooter';
|
|
18
|
+
export { Footer };
|