@shmidko61/lc-ui-kit 0.17.1 → 0.18.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/README.md +6 -0
- package/dist/dropdown-menu/dropdown-menu.d.ts +4 -0
- package/dist/dropdown-menu/helpers/dropdown-menu.helpers.d.ts +4 -0
- package/dist/dropdown-menu/helpers/index.d.ts +1 -0
- package/dist/dropdown-menu/index.d.ts +2 -0
- package/dist/dropdown-menu/types/dropdown-menu.types.d.ts +66 -0
- package/dist/dropdown-menu/types/index.d.ts +1 -0
- package/dist/dropdown-menu/types/internal/dropdown-menu-internal.types.d.ts +17 -0
- package/dist/dropdown-menu/types/internal/index.d.ts +1 -0
- package/dist/dropdown-menu-D14xkawH.js +199 -0
- package/dist/dropdown-menu-hivkBAku.cjs +1 -0
- package/dist/dropdown-menu.cjs +1 -0
- package/dist/dropdown-menu.js +5 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +95 -93
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -266,3 +266,9 @@ export function Question() {
|
|
|
266
266
|
```
|
|
267
267
|
|
|
268
268
|
Storybook: **UI Kit / Accordion / ContentInner**.
|
|
269
|
+
|
|
270
|
+
## DropdownMenu
|
|
271
|
+
|
|
272
|
+
Меню действий с клавиатурой, поиском, portal, автоматическим позиционированием,
|
|
273
|
+
прокруткой, controlled/uncontrolled состоянием и настройкой обёрток через BoxProps.
|
|
274
|
+
Импорт: `@shmidko61/lc-ui-kit/dropdown-menu`. [API и примеры](src/dropdown-menu/README.md).
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Находит соседний tab-stop относительно триггера, исключая закрываемую portal-панель.
|
|
2
|
+
* Положительные tabindex идут первыми, скрытые и disabled-элементы пропускаются.
|
|
3
|
+
*/
|
|
4
|
+
export declare function getDropdownTabTarget(trigger: HTMLButtonElement, panel: HTMLElement | null, backwards: boolean): HTMLElement | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getDropdownTabTarget } from './dropdown-menu.helpers';
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { BoxProps } from '../../box/index';
|
|
3
|
+
/** Настройки обёртки без замены семантического элемента и содержимого. style имеет итоговый приоритет. */
|
|
4
|
+
export type DropdownMenuBoxProps = Omit<BoxProps, 'as' | 'children'>;
|
|
5
|
+
/** Пункт меню действий; id уникален, textValue используется для поиска с клавиатуры. */
|
|
6
|
+
export interface DropdownMenuItem {
|
|
7
|
+
/** Уникальный ключ действия. */
|
|
8
|
+
id: string;
|
|
9
|
+
/** Видимая подпись или произвольное содержимое. */
|
|
10
|
+
label: ReactNode;
|
|
11
|
+
/** Текст для поиска; обязателен для сложной JSX-подписи. */
|
|
12
|
+
textValue?: string;
|
|
13
|
+
/** Дополнительное описание действия. */
|
|
14
|
+
description?: ReactNode;
|
|
15
|
+
/** Начальный слот: например, иконка. */
|
|
16
|
+
leading?: ReactNode;
|
|
17
|
+
/** Конечный слот: например, сочетание клавиш. */
|
|
18
|
+
trailing?: ReactNode;
|
|
19
|
+
/** Недоступный пункт пропускается при навигации. */
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
/** Деструктивное действие окрашивается в красный. */
|
|
22
|
+
destructive?: boolean;
|
|
23
|
+
/** Индивидуальное оформление пункта, включая md/lg/xl; style приоритетнее. */
|
|
24
|
+
boxProps?: DropdownMenuBoxProps;
|
|
25
|
+
}
|
|
26
|
+
/** Props меню действий. Для выбора значения формы используйте Select. */
|
|
27
|
+
export interface DropdownMenuProps {
|
|
28
|
+
/** Список действий; пустой список отображает emptyContent. */
|
|
29
|
+
items: Array<DropdownMenuItem>;
|
|
30
|
+
/** Содержимое стандартной кнопки. По умолчанию «Действия». */
|
|
31
|
+
trigger?: ReactNode;
|
|
32
|
+
/** Настройка кнопки через Box, включая md/lg/xl, className, style и HTML props. */
|
|
33
|
+
triggerProps?: Omit<BoxProps<'button'>, 'as' | 'children'>;
|
|
34
|
+
/** Внешняя обёртка триггера. */
|
|
35
|
+
rootProps?: DropdownMenuBoxProps;
|
|
36
|
+
/** Оформление позиционируемой панели. */
|
|
37
|
+
panelProps?: DropdownMenuBoxProps;
|
|
38
|
+
/** Оформление списка: padding, maxHeight, scrollbar и md/lg/xl. */
|
|
39
|
+
menuProps?: DropdownMenuBoxProps;
|
|
40
|
+
/** Общие настройки пунктов; индивидуальные boxProps имеют приоритет. */
|
|
41
|
+
itemProps?: DropdownMenuBoxProps;
|
|
42
|
+
/** Кастомизация содержимого пункта без изменения его доступной семантики. */
|
|
43
|
+
renderItem?: (item: DropdownMenuItem) => ReactNode;
|
|
44
|
+
/** Доступное название списка; по умолчанию «Действия». */
|
|
45
|
+
label?: string;
|
|
46
|
+
/** Содержимое при отсутствии действий. По умолчанию «Нет действий». */
|
|
47
|
+
emptyContent?: ReactNode;
|
|
48
|
+
/** Controlled-состояние панели. */
|
|
49
|
+
open?: boolean;
|
|
50
|
+
/** Начальное раскрытие uncontrolled-панели; по умолчанию false. */
|
|
51
|
+
defaultOpen?: boolean;
|
|
52
|
+
/** Изменение раскрытия. */
|
|
53
|
+
onOpenChange?: (open: boolean) => void;
|
|
54
|
+
/** Выбор доступного действия. */
|
|
55
|
+
onAction?: (id: string) => void;
|
|
56
|
+
/** Отключает триггер; по умолчанию false. */
|
|
57
|
+
disabled?: boolean;
|
|
58
|
+
/** Закрывать после действия; по умолчанию true. */
|
|
59
|
+
closeOnSelect?: boolean;
|
|
60
|
+
/** Положение с автоматическим переворотом у края экрана; по умолчанию bottom start. */
|
|
61
|
+
placement?: DropdownMenuPlacement;
|
|
62
|
+
/** Расстояние от триггера в px; по умолчанию 8. */
|
|
63
|
+
offset?: number;
|
|
64
|
+
}
|
|
65
|
+
/** Положение панели: физические left/right либо логические start/end с учётом направления текста. */
|
|
66
|
+
export type DropdownMenuPlacement = 'top' | 'bottom' | 'left' | 'right' | 'start' | 'end' | `${'top' | 'bottom'} ${'left' | 'right' | 'start' | 'end'}` | `${'left' | 'right' | 'start' | 'end'} ${'top' | 'bottom'}`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { DropdownMenuBoxProps, DropdownMenuItem, DropdownMenuPlacement, DropdownMenuProps, } from './dropdown-menu.types';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
import { TreeState, useMenuTriggerState } from 'react-stately';
|
|
3
|
+
import { DropdownMenuItem, DropdownMenuProps } from '..';
|
|
4
|
+
/** Внутренние props доступного пункта. */
|
|
5
|
+
export interface DropdownMenuEntryProps {
|
|
6
|
+
item: DropdownMenuItem;
|
|
7
|
+
state: TreeState<DropdownMenuItem>;
|
|
8
|
+
options: DropdownMenuProps;
|
|
9
|
+
close: () => void;
|
|
10
|
+
}
|
|
11
|
+
/** Внутренние props позиционируемой панели. */
|
|
12
|
+
export interface DropdownMenuPanelProps {
|
|
13
|
+
options: DropdownMenuProps;
|
|
14
|
+
triggerRef: RefObject<HTMLButtonElement | null>;
|
|
15
|
+
state: ReturnType<typeof useMenuTriggerState>;
|
|
16
|
+
triggerMenuProps: object;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { DropdownMenuEntryProps, DropdownMenuPanelProps, } from './dropdown-menu-internal.types';
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as b, jsx as l } from "react/jsx-runtime";
|
|
3
|
+
import { useRef as g, useId as P, useEffect as I, useLayoutEffect as O } from "react";
|
|
4
|
+
import { useMenuTrigger as w, useButton as D, mergeProps as m, usePopover as S, useMenu as v, Overlay as k, FocusScope as T, DismissButton as x, useMenuItem as C } from "react-aria";
|
|
5
|
+
import { useMenuTriggerState as M, useTreeState as F, Item as A } from "react-stately";
|
|
6
|
+
import { Box as a } from "./box.js";
|
|
7
|
+
import { Flex as E } from "./flex.js";
|
|
8
|
+
import { Typography as R } from "./typography.js";
|
|
9
|
+
function V(e, i, t) {
|
|
10
|
+
const o = Array.from(
|
|
11
|
+
e.ownerDocument.querySelectorAll(
|
|
12
|
+
'a[href],button,input,select,textarea,[tabindex],[contenteditable="true"]'
|
|
13
|
+
)
|
|
14
|
+
).filter(
|
|
15
|
+
(r) => r.tabIndex >= 0 && !r.matches(":disabled") && !r.closest("[inert]") && r.getClientRects().length > 0 && !0
|
|
16
|
+
).sort(
|
|
17
|
+
(r, s) => (r.tabIndex > 0 ? r.tabIndex : 1 / 0) - (s.tabIndex > 0 ? s.tabIndex : 1 / 0)
|
|
18
|
+
);
|
|
19
|
+
return o[o.indexOf(e) + (t ? -1 : 1)];
|
|
20
|
+
}
|
|
21
|
+
function q({ item: e, state: i, options: t, close: o }) {
|
|
22
|
+
const r = g(null), { menuItemProps: s, labelProps: c, descriptionProps: f, isFocused: u } = C(
|
|
23
|
+
{
|
|
24
|
+
key: e.id,
|
|
25
|
+
onAction: () => t.onAction?.(e.id),
|
|
26
|
+
onClose: o,
|
|
27
|
+
closeOnSelect: t.closeOnSelect ?? !0
|
|
28
|
+
},
|
|
29
|
+
i,
|
|
30
|
+
r
|
|
31
|
+
);
|
|
32
|
+
return /* @__PURE__ */ l(
|
|
33
|
+
a,
|
|
34
|
+
{
|
|
35
|
+
outlineStyle: "none",
|
|
36
|
+
focusVisible: {
|
|
37
|
+
outlineStyle: "solid",
|
|
38
|
+
outlineWidth: "2px",
|
|
39
|
+
outlineOffset: "-2px",
|
|
40
|
+
outlineColor: "--color-primary-accent"
|
|
41
|
+
},
|
|
42
|
+
p: { px: 16, py: 12 },
|
|
43
|
+
border: { radius: "8px" },
|
|
44
|
+
color: e.destructive ? "#dc2626" : "--color-text-primary",
|
|
45
|
+
bg: u ? "--color-background-subtle" : void 0,
|
|
46
|
+
...m(t.itemProps ?? {}, e.boxProps ?? {}, s),
|
|
47
|
+
ref: r,
|
|
48
|
+
style: { ...t.itemProps?.style, ...e.boxProps?.style },
|
|
49
|
+
children: t.renderItem ? /* @__PURE__ */ l(a, { ...c, children: t.renderItem(e) }) : /* @__PURE__ */ b(E, { align: "center", gap: 12, children: [
|
|
50
|
+
e.leading,
|
|
51
|
+
/* @__PURE__ */ b(a, { width: "100%", children: [
|
|
52
|
+
/* @__PURE__ */ l(a, { ...c, children: e.label }),
|
|
53
|
+
e.description && /* @__PURE__ */ l(R, { ...f, variant: "b3", color: "--color-text-secondary", children: e.description })
|
|
54
|
+
] }),
|
|
55
|
+
e.trailing
|
|
56
|
+
] })
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
function B({
|
|
61
|
+
options: e,
|
|
62
|
+
triggerRef: i,
|
|
63
|
+
state: t,
|
|
64
|
+
triggerMenuProps: o
|
|
65
|
+
}) {
|
|
66
|
+
const r = g(null), s = g(null), { popoverProps: c, underlayProps: f } = S(
|
|
67
|
+
{
|
|
68
|
+
popoverRef: r,
|
|
69
|
+
triggerRef: i,
|
|
70
|
+
placement: e.placement ?? "bottom start",
|
|
71
|
+
offset: e.offset ?? 8
|
|
72
|
+
},
|
|
73
|
+
t
|
|
74
|
+
), u = F({
|
|
75
|
+
items: e.items,
|
|
76
|
+
disabledKeys: e.items.filter((n) => n.disabled).map((n) => n.id),
|
|
77
|
+
selectionMode: "none",
|
|
78
|
+
children: (n) => /* @__PURE__ */ l(
|
|
79
|
+
A,
|
|
80
|
+
{
|
|
81
|
+
textValue: n.textValue ?? (typeof n.label == "string" ? n.label : n.id),
|
|
82
|
+
children: n.label
|
|
83
|
+
},
|
|
84
|
+
n.id
|
|
85
|
+
)
|
|
86
|
+
}), { menuProps: d } = v(
|
|
87
|
+
{
|
|
88
|
+
...o,
|
|
89
|
+
...e.label ? { "aria-labelledby": void 0 } : {},
|
|
90
|
+
onClose: t.close,
|
|
91
|
+
"aria-label": e.label ?? "Действия",
|
|
92
|
+
autoFocus: t.focusStrategy ?? "first"
|
|
93
|
+
},
|
|
94
|
+
u,
|
|
95
|
+
s
|
|
96
|
+
);
|
|
97
|
+
return /* @__PURE__ */ b(k, { children: [
|
|
98
|
+
/* @__PURE__ */ l(a, { ...f, position: { type: "fixed", top: 0, right: 0, bottom: 0, left: 0 } }),
|
|
99
|
+
/* @__PURE__ */ l(T, { restoreFocus: !0, children: /* @__PURE__ */ b(
|
|
100
|
+
a,
|
|
101
|
+
{
|
|
102
|
+
bg: "--color-background-default",
|
|
103
|
+
border: { radius: "12px" },
|
|
104
|
+
boxShadow: "0 8px 32px rgba(0,0,0,.12)",
|
|
105
|
+
...m(e.panelProps ?? {}, c),
|
|
106
|
+
ref: r,
|
|
107
|
+
style: { ...c.style, ...e.panelProps?.style },
|
|
108
|
+
children: [
|
|
109
|
+
/* @__PURE__ */ l(x, { onDismiss: t.close }),
|
|
110
|
+
/* @__PURE__ */ l(
|
|
111
|
+
a,
|
|
112
|
+
{
|
|
113
|
+
outlineStyle: "none",
|
|
114
|
+
p: 8,
|
|
115
|
+
minWidth: 220,
|
|
116
|
+
maxHeight: "min(320px, 60vh)",
|
|
117
|
+
overflowY: "auto",
|
|
118
|
+
...m(e.menuProps ?? {}, d),
|
|
119
|
+
ref: s,
|
|
120
|
+
children: e.items.length ? e.items.map((n) => /* @__PURE__ */ l(
|
|
121
|
+
q,
|
|
122
|
+
{
|
|
123
|
+
item: n,
|
|
124
|
+
state: u,
|
|
125
|
+
options: e,
|
|
126
|
+
close: t.close
|
|
127
|
+
},
|
|
128
|
+
n.id
|
|
129
|
+
)) : /* @__PURE__ */ l(a, { p: 16, children: e.emptyContent ?? "Нет действий" })
|
|
130
|
+
}
|
|
131
|
+
),
|
|
132
|
+
/* @__PURE__ */ l(x, { onDismiss: t.close })
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
) })
|
|
136
|
+
] });
|
|
137
|
+
}
|
|
138
|
+
function J(e) {
|
|
139
|
+
const i = g(null), t = P(), o = e.disabled ?? e.triggerProps?.disabled ?? !1, r = M({
|
|
140
|
+
isOpen: e.open,
|
|
141
|
+
defaultOpen: o ? !1 : e.defaultOpen,
|
|
142
|
+
onOpenChange: e.onOpenChange
|
|
143
|
+
}), s = g(!1);
|
|
144
|
+
I(() => {
|
|
145
|
+
!o || !r.isOpen ? s.current = !1 : s.current || (s.current = !0, r.close());
|
|
146
|
+
}, [o, r]);
|
|
147
|
+
const { menuTriggerProps: c, menuProps: f } = w(
|
|
148
|
+
{ type: "menu", isDisabled: o },
|
|
149
|
+
r,
|
|
150
|
+
i
|
|
151
|
+
), { buttonProps: u } = D(
|
|
152
|
+
{ ...m(c, e.triggerProps ?? {}), isDisabled: o },
|
|
153
|
+
i
|
|
154
|
+
);
|
|
155
|
+
return O(() => {
|
|
156
|
+
const d = i.current;
|
|
157
|
+
if (!d || !r.isOpen) return;
|
|
158
|
+
const n = d.ownerDocument, y = (p) => {
|
|
159
|
+
if (p.key !== "Tab" || !(p.target instanceof Element) || p.target.closest('[role="menu"]')?.id !== t)
|
|
160
|
+
return;
|
|
161
|
+
p.preventDefault(), p.stopPropagation();
|
|
162
|
+
const h = p.shiftKey;
|
|
163
|
+
r.close(), requestAnimationFrame(
|
|
164
|
+
() => requestAnimationFrame(() => {
|
|
165
|
+
(V(d, null, h) ?? d).focus();
|
|
166
|
+
})
|
|
167
|
+
);
|
|
168
|
+
};
|
|
169
|
+
return n.defaultView?.addEventListener("keydown", y, !0), () => n.defaultView?.removeEventListener("keydown", y, !0);
|
|
170
|
+
}, [r, t]), /* @__PURE__ */ b(a, { display: "inline-block", ...e.rootProps, children: [
|
|
171
|
+
/* @__PURE__ */ l(
|
|
172
|
+
a,
|
|
173
|
+
{
|
|
174
|
+
as: "button",
|
|
175
|
+
p: { px: 16, py: 10 },
|
|
176
|
+
bg: "--color-background-subtle",
|
|
177
|
+
border: { radius: "8px", style: "none" },
|
|
178
|
+
...e.triggerProps,
|
|
179
|
+
...u,
|
|
180
|
+
"aria-expanded": !o && r.isOpen,
|
|
181
|
+
"aria-controls": r.isOpen && !o ? t : void 0,
|
|
182
|
+
ref: i,
|
|
183
|
+
children: e.trigger ?? "Действия"
|
|
184
|
+
}
|
|
185
|
+
),
|
|
186
|
+
r.isOpen && !o && /* @__PURE__ */ l(
|
|
187
|
+
B,
|
|
188
|
+
{
|
|
189
|
+
options: e,
|
|
190
|
+
state: r,
|
|
191
|
+
triggerRef: i,
|
|
192
|
+
triggerMenuProps: { ...f, id: t }
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
] });
|
|
196
|
+
}
|
|
197
|
+
export {
|
|
198
|
+
J as D
|
|
199
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";"use strict";const s=require("react/jsx-runtime"),a=require("react"),l=require("react-aria"),g=require("react-stately"),c=require("./box.cjs"),h=require("./flex.cjs"),P=require("./typography.cjs");function j(e,i,t){const o=Array.from(e.ownerDocument.querySelectorAll('a[href],button,input,select,textarea,[tabindex],[contenteditable="true"]')).filter(r=>r.tabIndex>=0&&!r.matches(":disabled")&&!r.closest("[inert]")&&r.getClientRects().length>0&&!0).sort((r,u)=>(r.tabIndex>0?r.tabIndex:1/0)-(u.tabIndex>0?u.tabIndex:1/0));return o[o.indexOf(e)+(t?-1:1)]}function I({item:e,state:i,options:t,close:o}){const r=a.useRef(null),{menuItemProps:u,labelProps:d,descriptionProps:b,isFocused:p}=l.useMenuItem({key:e.id,onAction:()=>t.onAction?.(e.id),onClose:o,closeOnSelect:t.closeOnSelect??!0},i,r);return s.jsx(c.Box,{outlineStyle:"none",focusVisible:{outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"-2px",outlineColor:"--color-primary-accent"},p:{px:16,py:12},border:{radius:"8px"},color:e.destructive?"#dc2626":"--color-text-primary",bg:p?"--color-background-subtle":void 0,...l.mergeProps(t.itemProps??{},e.boxProps??{},u),ref:r,style:{...t.itemProps?.style,...e.boxProps?.style},children:t.renderItem?s.jsx(c.Box,{...d,children:t.renderItem(e)}):s.jsxs(h.Flex,{align:"center",gap:12,children:[e.leading,s.jsxs(c.Box,{width:"100%",children:[s.jsx(c.Box,{...d,children:e.label}),e.description&&s.jsx(P.Typography,{...b,variant:"b3",color:"--color-text-secondary",children:e.description})]}),e.trailing]})})}function O({options:e,triggerRef:i,state:t,triggerMenuProps:o}){const r=a.useRef(null),u=a.useRef(null),{popoverProps:d,underlayProps:b}=l.usePopover({popoverRef:r,triggerRef:i,placement:e.placement??"bottom start",offset:e.offset??8},t),p=g.useTreeState({items:e.items,disabledKeys:e.items.filter(n=>n.disabled).map(n=>n.id),selectionMode:"none",children:n=>s.jsx(g.Item,{textValue:n.textValue??(typeof n.label=="string"?n.label:n.id),children:n.label},n.id)}),{menuProps:x}=l.useMenu({...o,...e.label?{"aria-labelledby":void 0}:{},onClose:t.close,"aria-label":e.label??"Действия",autoFocus:t.focusStrategy??"first"},p,u);return s.jsxs(l.Overlay,{children:[s.jsx(c.Box,{...b,position:{type:"fixed",top:0,right:0,bottom:0,left:0}}),s.jsx(l.FocusScope,{restoreFocus:!0,children:s.jsxs(c.Box,{bg:"--color-background-default",border:{radius:"12px"},boxShadow:"0 8px 32px rgba(0,0,0,.12)",...l.mergeProps(e.panelProps??{},d),ref:r,style:{...d.style,...e.panelProps?.style},children:[s.jsx(l.DismissButton,{onDismiss:t.close}),s.jsx(c.Box,{outlineStyle:"none",p:8,minWidth:220,maxHeight:"min(320px, 60vh)",overflowY:"auto",...l.mergeProps(e.menuProps??{},x),ref:u,children:e.items.length?e.items.map(n=>s.jsx(I,{item:n,state:p,options:e,close:t.close},n.id)):s.jsx(c.Box,{p:16,children:e.emptyContent??"Нет действий"})}),s.jsx(l.DismissButton,{onDismiss:t.close})]})})]})}function w(e){const i=a.useRef(null),t=a.useId(),o=e.disabled??e.triggerProps?.disabled??!1,r=g.useMenuTriggerState({isOpen:e.open,defaultOpen:o?!1:e.defaultOpen,onOpenChange:e.onOpenChange}),u=a.useRef(!1);a.useEffect(()=>{!o||!r.isOpen?u.current=!1:u.current||(u.current=!0,r.close())},[o,r]);const{menuTriggerProps:d,menuProps:b}=l.useMenuTrigger({type:"menu",isDisabled:o},r,i),{buttonProps:p}=l.useButton({...l.mergeProps(d,e.triggerProps??{}),isDisabled:o},i);return a.useLayoutEffect(()=>{const x=i.current;if(!x||!r.isOpen)return;const n=x.ownerDocument,y=f=>{if(f.key!=="Tab"||!(f.target instanceof Element)||f.target.closest('[role="menu"]')?.id!==t)return;f.preventDefault(),f.stopPropagation();const m=f.shiftKey;r.close(),requestAnimationFrame(()=>requestAnimationFrame(()=>{(j(x,null,m)??x).focus()}))};return n.defaultView?.addEventListener("keydown",y,!0),()=>n.defaultView?.removeEventListener("keydown",y,!0)},[r,t]),s.jsxs(c.Box,{display:"inline-block",...e.rootProps,children:[s.jsx(c.Box,{as:"button",p:{px:16,py:10},bg:"--color-background-subtle",border:{radius:"8px",style:"none"},...e.triggerProps,...p,"aria-expanded":!o&&r.isOpen,"aria-controls":r.isOpen&&!o?t:void 0,ref:i,children:e.trigger??"Действия"}),r.isOpen&&!o&&s.jsx(O,{options:e,state:r,triggerRef:i,triggerMenuProps:{...b,id:t}})]})}exports.DropdownMenu=w;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./dropdown-menu-hivkBAku.cjs");exports.DropdownMenu=e.DropdownMenu;
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./accordion.cjs"),l=require("./alert-DTc0Usg-.cjs"),I=require("./box.cjs"),n=require("./button.cjs"),r=require("./ui-kit-provider-raEFsUm0.cjs"),u=require("./flex.cjs"),a=require("./grid.cjs"),o=require("./icons.cjs"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./accordion.cjs"),l=require("./alert-DTc0Usg-.cjs"),I=require("./box.cjs"),n=require("./button.cjs"),r=require("./ui-kit-provider-raEFsUm0.cjs"),u=require("./dropdown-menu-hivkBAku.cjs"),d=require("./flex.cjs"),a=require("./grid.cjs"),o=require("./icons.cjs"),p=require("./input.cjs"),T=require("./loader-ODTCTLKE.cjs"),b=require("./media-card.cjs"),g=require("./media-gallery.cjs"),t=require("./notification-provider-C2ypXy2W.cjs"),C=require("./pagination.cjs"),k=require("./picture.cjs"),M=require("./progress-bar-XIJDb_UM.cjs"),S=require("./select.cjs"),c=require("./responsive-style.config-B2m9jVlX.cjs"),h=require("./status-badge.cjs"),q=require("./switch.cjs"),e=require("./table-container-DqqqkChm.cjs"),y=require("./tabs-BNZDJRz_.cjs"),P=require("./toast-CH8VqvLC.cjs"),B=require("./tooltip-0RbTCYn_.cjs"),s=require("./typography.cjs");exports.Accordion=i.Accordion;exports.AccordionItem=i.AccordionItem;exports.AccordionRoot=i.AccordionRoot;exports.Alert=l.Alert;exports.Box=I.Box;exports.Button=n.Button;exports.buttonSizeBorderRadius=n.buttonSizeBorderRadius;exports.buttonSizeBoxProps=n.buttonSizeBoxProps;exports.buttonSizeClassNames=n.buttonSizeClassNames;exports.buttonVariantClassNames=n.buttonVariantClassNames;exports.buttonVariants=n.buttonVariants;exports.UiKitProvider=r.UiKitProvider;exports.uiKitColorTokens=r.uiKitColorTokens;exports.uiKitTypographyTokens=r.uiKitTypographyTokens;exports.useUiKitConfig=r.useUiKitConfig;exports.DropdownMenu=u.DropdownMenu;exports.Flex=d.Flex;exports.Grid=a.Grid;exports.GridItem=a.GridItem;exports.ArrowCornerIcon=o.ArrowCornerIcon;exports.ArrowIcon=o.ArrowIcon;exports.ArrowLongLeftIcon=o.ArrowLongLeftIcon;exports.ArrowheadRightIcon=o.ArrowheadRightIcon;exports.BlockIcon=o.BlockIcon;exports.BurgerIcon=o.BurgerIcon;exports.CheckIcon=o.CheckIcon;exports.CopyIcon=o.CopyIcon;exports.DoubleCheckIcon=o.DoubleCheckIcon;exports.DropDown=o.DropDown;exports.ExclamationMarkIcon=o.ExclamationMarkIcon;exports.EyeOpenIcon=o.EyeOpenIcon;exports.FileIcon=o.FileIcon;exports.GeminiStarIcon=o.GeminiStarIcon;exports.GeoIcon=o.GeoIcon;exports.InfoCircleIcon=o.InfoCircleIcon;exports.LockClosedIcon=o.LockClosedIcon;exports.LockOpenIcon=o.LockOpenIcon;exports.LogoutIcon=o.LogoutIcon;exports.MailIcon=o.MailIcon;exports.MediaMaxIcon=o.MediaMaxIcon;exports.MediaPictureIcon=o.MediaPictureIcon;exports.MediaTgIcon=o.MediaTgIcon;exports.MediaVkIcon=o.MediaVkIcon;exports.MediaWaIcon=o.MediaWaIcon;exports.NetUploadIcon=o.NetUploadIcon;exports.PaperclipIcon=o.PaperclipIcon;exports.PdfIcon=o.PdfIcon;exports.PhoneIcon=o.PhoneIcon;exports.PlusIcon=o.PlusIcon;exports.SaveIcon=o.SaveIcon;exports.SparkIcon=o.SparkIcon;exports.SparkleIcon=o.SparkleIcon;exports.TelephoneIcon=o.TelephoneIcon;exports.TimeClockIcon=o.TimeClockIcon;exports.TrashIcon=o.TrashIcon;exports.WarningTriangleIcon=o.WarningTriangleIcon;exports.XMarkIcon=o.XMarkIcon;exports.Input=p.Input;exports.Loader=T.Loader;exports.MediaCard=b.MediaCard;exports.MediaGallery=g.MediaGallery;exports.NotificationProvider=t.NotificationProvider;exports.useNotifications=t.useNotifications;exports.Pagination=C.Pagination;exports.Picture=k.Picture;exports.ProgressBar=M.ProgressBar;exports.Select=S.Select;exports.responsiveBreakpointMinWidth=c.responsiveBreakpointMinWidth;exports.responsiveBreakpoints=c.responsiveBreakpoints;exports.StatusBadge=h.StatusBadge;exports.Switch=q.Switch;exports.DataTable=e.DataTable;exports.Table=e.Table;exports.TableBody=e.TableBody;exports.TableCaption=e.TableCaption;exports.TableCell=e.TableCell;exports.TableContainer=e.TableContainer;exports.TableFooter=e.TableFooter;exports.TableHead=e.TableHead;exports.TableHeader=e.TableHeader;exports.TableRow=e.TableRow;exports.TableScrollArea=e.TableScrollArea;exports.TableStatus=e.TableStatus;exports.TableToolbar=e.TableToolbar;exports.Tabs=y.Tabs;exports.Toast=P.Toast;exports.Tooltip=B.Tooltip;exports.Typography=s.Typography;exports.typographyVariants=s.typographyVariants;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { Box } from './box/box';
|
|
|
5
5
|
export * from './button/button';
|
|
6
6
|
export * from './design-tokens/color.tokens';
|
|
7
7
|
export * from './design-tokens/typography.tokens';
|
|
8
|
+
export * from './dropdown-menu/index';
|
|
8
9
|
export type { FlexBreakpointProps, FlexProps, FlexResponsiveProps } from './flex/flex';
|
|
9
10
|
export { Flex } from './flex/flex';
|
|
10
11
|
export * from './grid/grid';
|
package/dist/index.js
CHANGED
|
@@ -3,113 +3,115 @@ import { A as i } from "./alert-CTIWpkmD.js";
|
|
|
3
3
|
import { Box as s } from "./box.js";
|
|
4
4
|
import { Button as l, buttonSizeBorderRadius as I, buttonSizeBoxProps as f, buttonSizeClassNames as m, buttonVariantClassNames as x, buttonVariants as T } from "./button.js";
|
|
5
5
|
import { U as b, u, a as k, b as g } from "./ui-kit-provider-C6Mk5g_7.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import { T as $o } from "./
|
|
23
|
-
import { T as rr } from "./
|
|
24
|
-
import { T as ar } from "./
|
|
25
|
-
import {
|
|
6
|
+
import { D as h } from "./dropdown-menu-D14xkawH.js";
|
|
7
|
+
import { Flex as P } from "./flex.js";
|
|
8
|
+
import { Grid as B, GridItem as y } from "./grid.js";
|
|
9
|
+
import { ArrowCornerIcon as w, ArrowIcon as D, ArrowLongLeftIcon as L, ArrowheadRightIcon as N, BlockIcon as v, BurgerIcon as G, CheckIcon as K, CopyIcon as R, DoubleCheckIcon as U, DropDown as V, ExclamationMarkIcon as z, EyeOpenIcon as F, FileIcon as W, GeminiStarIcon as E, GeoIcon as H, InfoCircleIcon as O, LockClosedIcon as j, LockOpenIcon as X, LogoutIcon as q, MailIcon as J, MediaMaxIcon as Q, MediaPictureIcon as Y, MediaTgIcon as Z, MediaVkIcon as _, MediaWaIcon as $, NetUploadIcon as oo, PaperclipIcon as ro, PdfIcon as eo, PhoneIcon as ao, PlusIcon as no, SaveIcon as to, SparkIcon as io, SparkleIcon as co, TelephoneIcon as so, TimeClockIcon as po, TrashIcon as lo, WarningTriangleIcon as Io, XMarkIcon as fo } from "./icons.js";
|
|
10
|
+
import { Input as xo } from "./input.js";
|
|
11
|
+
import { L as bo } from "./loader-Daam055i.js";
|
|
12
|
+
import { MediaCard as ko } from "./media-card.js";
|
|
13
|
+
import { MediaGallery as Co } from "./media-gallery.js";
|
|
14
|
+
import { N as Mo, u as Po } from "./notification-provider-WLUaZyMB.js";
|
|
15
|
+
import { Pagination as Bo } from "./pagination.js";
|
|
16
|
+
import { Picture as Ao } from "./picture.js";
|
|
17
|
+
import { P as Do } from "./progress-bar-D4CL9r42.js";
|
|
18
|
+
import { Select as No } from "./select.js";
|
|
19
|
+
import { r as Go, a as Ko } from "./responsive-style.config-DFuATrIM.js";
|
|
20
|
+
import { StatusBadge as Uo } from "./status-badge.js";
|
|
21
|
+
import { Switch as zo } from "./switch.js";
|
|
22
|
+
import { D as Wo, T as Eo, a as Ho, b as Oo, c as jo, d as Xo, e as qo, f as Jo, g as Qo, h as Yo, i as Zo, j as _o, k as $o } from "./table-container-BsE-uIE1.js";
|
|
23
|
+
import { T as rr } from "./tabs-DIPSJX1z.js";
|
|
24
|
+
import { T as ar } from "./toast-DpjugQ8H.js";
|
|
25
|
+
import { T as tr } from "./tooltip-CWnHAfbI.js";
|
|
26
|
+
import { Typography as cr, typographyVariants as sr } from "./typography.js";
|
|
26
27
|
export {
|
|
27
28
|
e as Accordion,
|
|
28
29
|
a as AccordionItem,
|
|
29
30
|
n as AccordionRoot,
|
|
30
31
|
i as Alert,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
w as ArrowCornerIcon,
|
|
33
|
+
D as ArrowIcon,
|
|
34
|
+
L as ArrowLongLeftIcon,
|
|
35
|
+
N as ArrowheadRightIcon,
|
|
36
|
+
v as BlockIcon,
|
|
36
37
|
s as Box,
|
|
37
|
-
|
|
38
|
+
G as BurgerIcon,
|
|
38
39
|
l as Button,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
xo as
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
ko as
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
Uo as
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
$o as
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
ar as
|
|
98
|
-
|
|
99
|
-
|
|
40
|
+
K as CheckIcon,
|
|
41
|
+
R as CopyIcon,
|
|
42
|
+
Wo as DataTable,
|
|
43
|
+
U as DoubleCheckIcon,
|
|
44
|
+
V as DropDown,
|
|
45
|
+
h as DropdownMenu,
|
|
46
|
+
z as ExclamationMarkIcon,
|
|
47
|
+
F as EyeOpenIcon,
|
|
48
|
+
W as FileIcon,
|
|
49
|
+
P as Flex,
|
|
50
|
+
E as GeminiStarIcon,
|
|
51
|
+
H as GeoIcon,
|
|
52
|
+
B as Grid,
|
|
53
|
+
y as GridItem,
|
|
54
|
+
O as InfoCircleIcon,
|
|
55
|
+
xo as Input,
|
|
56
|
+
bo as Loader,
|
|
57
|
+
j as LockClosedIcon,
|
|
58
|
+
X as LockOpenIcon,
|
|
59
|
+
q as LogoutIcon,
|
|
60
|
+
J as MailIcon,
|
|
61
|
+
ko as MediaCard,
|
|
62
|
+
Co as MediaGallery,
|
|
63
|
+
Q as MediaMaxIcon,
|
|
64
|
+
Y as MediaPictureIcon,
|
|
65
|
+
Z as MediaTgIcon,
|
|
66
|
+
_ as MediaVkIcon,
|
|
67
|
+
$ as MediaWaIcon,
|
|
68
|
+
oo as NetUploadIcon,
|
|
69
|
+
Mo as NotificationProvider,
|
|
70
|
+
Bo as Pagination,
|
|
71
|
+
ro as PaperclipIcon,
|
|
72
|
+
eo as PdfIcon,
|
|
73
|
+
ao as PhoneIcon,
|
|
74
|
+
Ao as Picture,
|
|
75
|
+
no as PlusIcon,
|
|
76
|
+
Do as ProgressBar,
|
|
77
|
+
to as SaveIcon,
|
|
78
|
+
No as Select,
|
|
79
|
+
io as SparkIcon,
|
|
80
|
+
co as SparkleIcon,
|
|
81
|
+
Uo as StatusBadge,
|
|
82
|
+
zo as Switch,
|
|
83
|
+
Eo as Table,
|
|
84
|
+
Ho as TableBody,
|
|
85
|
+
Oo as TableCaption,
|
|
86
|
+
jo as TableCell,
|
|
87
|
+
Xo as TableContainer,
|
|
88
|
+
qo as TableFooter,
|
|
89
|
+
Jo as TableHead,
|
|
90
|
+
Qo as TableHeader,
|
|
91
|
+
Yo as TableRow,
|
|
92
|
+
Zo as TableScrollArea,
|
|
93
|
+
_o as TableStatus,
|
|
94
|
+
$o as TableToolbar,
|
|
95
|
+
rr as Tabs,
|
|
96
|
+
so as TelephoneIcon,
|
|
97
|
+
po as TimeClockIcon,
|
|
98
|
+
ar as Toast,
|
|
99
|
+
tr as Tooltip,
|
|
100
|
+
lo as TrashIcon,
|
|
101
|
+
cr as Typography,
|
|
100
102
|
b as UiKitProvider,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
Io as WarningTriangleIcon,
|
|
104
|
+
fo as XMarkIcon,
|
|
103
105
|
I as buttonSizeBorderRadius,
|
|
104
106
|
f as buttonSizeBoxProps,
|
|
105
107
|
m as buttonSizeClassNames,
|
|
106
108
|
x as buttonVariantClassNames,
|
|
107
109
|
T as buttonVariants,
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
Go as responsiveBreakpointMinWidth,
|
|
111
|
+
Ko as responsiveBreakpoints,
|
|
112
|
+
sr as typographyVariants,
|
|
111
113
|
u as uiKitColorTokens,
|
|
112
114
|
k as uiKitTypographyTokens,
|
|
113
|
-
|
|
115
|
+
Po as useNotifications,
|
|
114
116
|
g as useUiKitConfig
|
|
115
117
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shmidko61/lc-ui-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -90,6 +90,9 @@
|
|
|
90
90
|
],
|
|
91
91
|
"tabs": [
|
|
92
92
|
"dist/tabs/index.d.ts"
|
|
93
|
+
],
|
|
94
|
+
"dropdown-menu": [
|
|
95
|
+
"dist/dropdown-menu/index.d.ts"
|
|
93
96
|
]
|
|
94
97
|
}
|
|
95
98
|
},
|
|
@@ -229,6 +232,11 @@
|
|
|
229
232
|
"types": "./dist/tabs/index.d.ts",
|
|
230
233
|
"import": "./dist/tabs.js",
|
|
231
234
|
"require": "./dist/tabs.cjs"
|
|
235
|
+
},
|
|
236
|
+
"./dropdown-menu": {
|
|
237
|
+
"types": "./dist/dropdown-menu/index.d.ts",
|
|
238
|
+
"import": "./dist/dropdown-menu.js",
|
|
239
|
+
"require": "./dist/dropdown-menu.cjs"
|
|
232
240
|
}
|
|
233
241
|
},
|
|
234
242
|
"sideEffects": [
|
|
@@ -236,7 +244,7 @@
|
|
|
236
244
|
],
|
|
237
245
|
"scripts": {
|
|
238
246
|
"prepublishOnly": "node -e \"throw new Error('Публикуйте проверенный tarball: corepack pnpm publish:ui-kit из apps')\"",
|
|
239
|
-
"verify:package": "pnpm typecheck && pnpm lint && pnpm format:check && pnpm build && pnpm typecheck:package && pnpm test:checks && pnpm test:package && pnpm test:hover && pnpm test:states && pnpm test:animation && pnpm test:progress-bar && pnpm test:tabs && pnpm test:scrollbar && pnpm test:accordion && pnpm pack:check && pnpm storybook:build",
|
|
247
|
+
"verify:package": "pnpm typecheck && pnpm lint && pnpm format:check && pnpm build && pnpm typecheck:package && pnpm test:checks && pnpm test:package && pnpm test:hover && pnpm test:states && pnpm test:animation && pnpm test:progress-bar && pnpm test:tabs && pnpm test:scrollbar && pnpm test:accordion && pnpm test:dropdown-menu && pnpm pack:check && pnpm storybook:build",
|
|
240
248
|
"build": "vite build && tailwindcss -i src/styles.css -o dist/styles.css --minify",
|
|
241
249
|
"lint": "eslint src .storybook vite.config.ts --max-warnings=0",
|
|
242
250
|
"lint:fix": "eslint src .storybook vite.config.ts --fix",
|
|
@@ -262,7 +270,9 @@
|
|
|
262
270
|
"test:scrollbar": "node scripts/check-scrollbar.mjs",
|
|
263
271
|
"test:scrollbar:browser": "node scripts/check-scrollbar-browser.mjs",
|
|
264
272
|
"test:accordion": "node scripts/check-accordion.mjs",
|
|
265
|
-
"test:accordion:browser": "node scripts/check-accordion-browser.mjs"
|
|
273
|
+
"test:accordion:browser": "node scripts/check-accordion-browser.mjs",
|
|
274
|
+
"test:dropdown-menu": "node scripts/check-dropdown-menu.mjs",
|
|
275
|
+
"test:dropdown-menu:browser": "node scripts/check-dropdown-menu-browser.mjs"
|
|
266
276
|
},
|
|
267
277
|
"dependencies": {
|
|
268
278
|
"class-variance-authority": "^0.7.1",
|