@infomaximum/ui-kit 0.19.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/BaseSelect/BaseSelect.d.ts +1 -1
- package/dist/components/BaseSelect/BaseSelect.js +21 -12
- package/dist/components/BaseSelect/BaseSelect.tokens.d.ts +1 -0
- package/dist/components/BaseSelect/BaseSelect.tokens.js +1 -0
- package/dist/components/BaseSelect/BaseSelect.types.d.ts +5 -2
- package/dist/components/BaseSelect/components/SelectOptionList/SelectOptionList.d.ts +1 -1
- package/dist/components/BaseSelect/components/SelectOptionList/SelectOptionList.js +6 -6
- package/dist/components/BaseSelect/components/SelectOptionList/SelectOptionList.types.d.ts +1 -0
- package/dist/components/BaseSelect/hooks/useDefaultCurrentValue.js +2 -1
- package/dist/components/BaseTooltip/BaseTooltip.js +38 -56
- package/dist/components/BaseTooltip/BaseTooltip.types.d.ts +1 -1
- package/dist/components/BaseTooltip/BaseTooltip.utils.d.ts +1 -3
- package/dist/components/BaseTooltip/BaseTooltip.utils.js +2 -32
- package/dist/components/BaseTooltip/hooks/useCustomFloating.d.ts +2 -1
- package/dist/components/BaseTooltip/hooks/useCustomFloating.js +9 -7
- package/dist/components/BaseTooltip/hooks/useShowTooltipController.d.ts +1 -2
- package/dist/components/BaseTooltip/hooks/useShowTooltipController.js +42 -57
- package/dist/components/Checkbox/Checkbox.styles.d.ts +1 -0
- package/dist/components/Checkbox/Checkbox.styles.js +1 -0
- package/dist/components/Collapse/Collapse.js +1 -1
- package/dist/components/Dropdown/Dropdown.types.d.ts +1 -0
- package/dist/components/Dropdown/components/SubMenu/SubMenu.js +7 -3
- package/dist/components/InternalPicker/styles/DatePanel.styles.d.ts +596 -596
- package/dist/components/InternalPicker/styles/Popup.styles.d.ts +593 -593
- package/dist/components/NewDropdown/NewDropdown.d.ts +2 -0
- package/dist/components/NewDropdown/NewDropdown.js +180 -0
- package/dist/components/NewDropdown/NewDropdown.styles.d.ts +10 -0
- package/dist/components/NewDropdown/NewDropdown.styles.js +11 -0
- package/dist/components/NewDropdown/NewDropdown.tokens.d.ts +18 -0
- package/dist/components/NewDropdown/NewDropdown.tokens.js +14 -0
- package/dist/components/NewDropdown/NewDropdown.types.d.ts +132 -0
- package/dist/components/NewDropdown/NewDropdown.utils.d.ts +26 -0
- package/dist/components/NewDropdown/NewDropdown.utils.js +55 -0
- package/dist/components/NewDropdown/components/Divider/Divider.d.ts +2 -0
- package/dist/components/NewDropdown/components/Divider/Divider.js +21 -0
- package/dist/components/NewDropdown/components/Divider/Divider.styles.d.ts +10 -0
- package/dist/components/NewDropdown/components/Divider/Divider.styles.js +12 -0
- package/dist/components/NewDropdown/components/Divider/index.d.ts +1 -0
- package/dist/components/NewDropdown/components/GroupItem/GroupItem.d.ts +3 -0
- package/dist/components/NewDropdown/components/GroupItem/GroupItem.js +33 -0
- package/dist/components/NewDropdown/components/GroupItem/GroupItem.styles.d.ts +29 -0
- package/dist/components/NewDropdown/components/GroupItem/GroupItem.styles.js +31 -0
- package/dist/components/NewDropdown/components/GroupItem/GroupItem.types.d.ts +5 -0
- package/dist/components/NewDropdown/components/GroupItem/index.d.ts +1 -0
- package/dist/components/NewDropdown/components/Menu/Menu.d.ts +3 -0
- package/dist/components/NewDropdown/components/Menu/Menu.js +33 -0
- package/dist/components/NewDropdown/components/Menu/Menu.styles.d.ts +2 -0
- package/dist/components/NewDropdown/components/Menu/Menu.styles.js +8 -0
- package/dist/components/NewDropdown/components/Menu/Menu.types.d.ts +11 -0
- package/dist/components/NewDropdown/components/Menu/index.d.ts +1 -0
- package/dist/components/NewDropdown/components/MenuItem/MenuItem.d.ts +3 -0
- package/dist/components/NewDropdown/components/MenuItem/MenuItem.js +75 -0
- package/dist/components/NewDropdown/components/MenuItem/MenuItem.styles.d.ts +42 -0
- package/dist/components/NewDropdown/components/MenuItem/MenuItem.styles.js +67 -0
- package/dist/components/NewDropdown/components/MenuItem/MenuItem.types.d.ts +5 -0
- package/dist/components/NewDropdown/components/MenuItem/index.d.ts +1 -0
- package/dist/components/NewDropdown/components/SubMenuItem/SubMenuItem.d.ts +3 -0
- package/dist/components/NewDropdown/components/SubMenuItem/SubMenuItem.js +170 -0
- package/dist/components/NewDropdown/components/SubMenuItem/SubMenuItem.styles.d.ts +13 -0
- package/dist/components/NewDropdown/components/SubMenuItem/SubMenuItem.styles.js +15 -0
- package/dist/components/NewDropdown/components/SubMenuItem/SubMenuItem.types.d.ts +5 -0
- package/dist/components/NewDropdown/components/SubMenuItem/index.d.ts +1 -0
- package/dist/components/NewDropdown/contexts/NewDropdownContext.d.ts +9 -0
- package/dist/components/NewDropdown/contexts/NewDropdownContext.js +8 -0
- package/dist/components/NewDropdown/contexts/NewDropdownNavigationContext.d.ts +11 -0
- package/dist/components/NewDropdown/contexts/NewDropdownNavigationContext.js +8 -0
- package/dist/components/NewDropdown/hooks/useContextMenu/index.d.ts +2 -0
- package/dist/components/NewDropdown/hooks/useContextMenu/useContextMenu.d.ts +9 -0
- package/dist/components/NewDropdown/hooks/useContextMenu/useContextMenu.js +38 -0
- package/dist/components/NewDropdown/hooks/useContextMenu/useContextMenu.types.d.ts +7 -0
- package/dist/components/NewDropdown/hooks/useNewDropdownTokens/index.d.ts +1 -0
- package/dist/components/NewDropdown/hooks/useNewDropdownTokens/useNewDropdownTokens.d.ts +7 -0
- package/dist/components/NewDropdown/hooks/useNewDropdownTokens/useNewDropdownTokens.js +14 -0
- package/dist/components/NewDropdown/hooks/useNewDropdownTokens/useNewDropdownTokens.types.d.ts +6 -0
- package/dist/components/NewDropdown/index.d.ts +2 -0
- package/dist/components/Segmented/Segmented.js +1 -1
- package/dist/components/Select/Select.d.ts +9 -1
- package/dist/components/Select/Select.js +53 -28
- package/dist/components/Select/Select.types.d.ts +5 -1
- package/dist/components/Select/Select.utils.d.ts +10 -1
- package/dist/components/Select/Select.utils.js +110 -7
- package/dist/components/Select/components/SelectGroupOption/SelectGroupOption.d.ts +5 -0
- package/dist/components/Select/components/SelectGroupOption/SelectGroupOption.js +68 -0
- package/dist/components/Select/components/SelectGroupOption/SelectGroupOption.styles.d.ts +28 -0
- package/dist/components/Select/components/SelectGroupOption/SelectGroupOption.styles.js +34 -0
- package/dist/components/Select/components/SelectGroupOption/SelectGroupOption.types.d.ts +21 -0
- package/dist/components/Select/components/SelectGroupOption/SelectGroupOption.types.js +7 -0
- package/dist/components/Select/components/SelectOption/SelectOption.d.ts +3 -2
- package/dist/components/Select/components/SelectOption/SelectOption.js +25 -15
- package/dist/components/Select/components/SelectOption/SelectOption.styles.d.ts +16 -2
- package/dist/components/Select/components/SelectOption/SelectOption.styles.js +18 -2
- package/dist/components/Select/components/SelectOption/SelectOption.types.d.ts +5 -0
- package/dist/components/Select/contexts/DepthContext.d.ts +3 -0
- package/dist/components/Select/contexts/DepthContext.js +9 -0
- package/dist/components/Select/contexts/SelectRenderContext.d.ts +11 -0
- package/dist/components/Select/contexts/SelectRenderContext.js +7 -0
- package/dist/components/Select/forStories/dataForExamples.d.ts +65 -3
- package/dist/components/Select/hooks/useElementSizesController.d.ts +5 -0
- package/dist/components/Select/hooks/useElementSizesController.js +17 -0
- package/dist/components/Select/hooks/useKeyControl.d.ts +4 -4
- package/dist/components/Select/hooks/useKeyControl.js +15 -10
- package/dist/components/Slider/components/SliderHandleTooltip/SliderHandleTooltip.js +1 -1
- package/dist/components/Slider/components/SliderInternal/SliderInternal.js +1 -1
- package/dist/components/Table/features/tableRowSelection/hooks/useTableRowSelection/useTableRowSelection.js +1 -1
- package/dist/components/Table/hooks/useTableVisualParamsChange/utils.d.ts +1 -1
- package/dist/components/Tabs/Tabs.utils.d.ts +2 -2
- package/dist/components/Tabs/Tabs.utils.js +11 -24
- package/dist/components/Tabs/components/TabBar/TabBar.js +8 -7
- package/dist/components/Tabs/components/TabItem/TabItem.js +7 -5
- package/dist/components/Tabs/components/TabItem/TabItem.styles.d.ts +1 -1
- package/dist/components/Tabs/components/TabItem/TabItem.types.d.ts +1 -0
- package/dist/components/Tabs/hooks/useMoreTabsController.d.ts +2 -1
- package/dist/components/Tabs/hooks/useMoreTabsController.js +10 -6
- package/dist/components/TreeSelect/TreeSelect.js +8 -3
- package/dist/components/TreeSelect/components/TreeSelectOption/TreeSelectOption.types.d.ts +1 -0
- package/dist/components/TreeSelect/hooks/useKeyControl.d.ts +2 -2
- package/dist/components/TreeSelect/hooks/useKeyControl.js +9 -8
- package/dist/hooks/useInputModeDetector/index.d.ts +2 -0
- package/dist/hooks/useInputModeDetector/useInputModeDetector.d.ts +13 -0
- package/dist/hooks/useInputModeDetector/useInputModeDetector.js +50 -0
- package/dist/hooks/useInputModeDetector/useInputModeDetector.types.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/package.json +2 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { memo, useRef, useState, useMemo, useEffect, isValidElement, cloneElement } from "react";
|
|
3
|
+
import { useFloatingParentNodeId, FloatingTree, useFloatingNodeId, size, useFloating, offset, flip, shift, autoUpdate, useMergeRefs, useClick, useHover, safePolygon, useDismiss, useListNavigation, useInteractions, useFloatingTree, FloatingNode, FloatingList, FloatingPortal, FloatingFocusManager } from "@floating-ui/react";
|
|
4
|
+
import { useControlledState } from "../../hooks/useControlledState/useControlledState.js";
|
|
5
|
+
import { useEvent } from "../../hooks/useEvent/useEvent.js";
|
|
6
|
+
import { rootStyle } from "./NewDropdown.styles.js";
|
|
7
|
+
import { placementMap, getFirstEnabledIndex, defaultMenuConfig, defaultTrigger, defaultDropdownMinWidth, defaultDropdownMaxHeight } from "./NewDropdown.utils.js";
|
|
8
|
+
import { Menu } from "./components/Menu/Menu.js";
|
|
9
|
+
import { NewDropdownContext } from "./contexts/NewDropdownContext.js";
|
|
10
|
+
import { NewDropdownNavigationContext } from "./contexts/NewDropdownNavigationContext.js";
|
|
11
|
+
import { getNodeRef } from "rc-util/es/ref.js";
|
|
12
|
+
import { useNewDropdownTokens } from "./hooks/useNewDropdownTokens/useNewDropdownTokens.js";
|
|
13
|
+
import { useContextMenu } from "./hooks/useContextMenu/useContextMenu.js";
|
|
14
|
+
const NewDropdownInner = (props) => {
|
|
15
|
+
var _a;
|
|
16
|
+
const {
|
|
17
|
+
children: childrenProp,
|
|
18
|
+
menu,
|
|
19
|
+
placement = "bottomLeft",
|
|
20
|
+
styles,
|
|
21
|
+
trigger = defaultTrigger,
|
|
22
|
+
open: openProp,
|
|
23
|
+
onOpenChange: onOpenChangeProp,
|
|
24
|
+
disabled = false,
|
|
25
|
+
autoFocus = false,
|
|
26
|
+
dropdownWidth = null,
|
|
27
|
+
dropdownMinWidth = defaultDropdownMinWidth,
|
|
28
|
+
dropdownMaxHeight = defaultDropdownMaxHeight,
|
|
29
|
+
popupRender,
|
|
30
|
+
getPopupContainer,
|
|
31
|
+
"test-id": testId
|
|
32
|
+
} = props;
|
|
33
|
+
const {
|
|
34
|
+
theme,
|
|
35
|
+
tokens
|
|
36
|
+
} = useNewDropdownTokens();
|
|
37
|
+
const nodeId = useFloatingNodeId();
|
|
38
|
+
const elementsRef = useRef([]);
|
|
39
|
+
const [open, setOpen] = useControlledState(false, openProp);
|
|
40
|
+
const [activeIndex, setActiveIndex] = useState(null);
|
|
41
|
+
const [triggerEl, setTriggerEl] = useState(null);
|
|
42
|
+
const handleOpenChange = (next, _event, reason) => {
|
|
43
|
+
setOpen(next);
|
|
44
|
+
onOpenChangeProp == null ? void 0 : onOpenChangeProp(next, {
|
|
45
|
+
source: reason !== void 0 ? "trigger" : "menu"
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
const [referenceWidth, setReferenceWidth] = useState(null);
|
|
49
|
+
const sizeMiddleware = useMemo(() => size({
|
|
50
|
+
apply({
|
|
51
|
+
rects
|
|
52
|
+
}) {
|
|
53
|
+
if (dropdownWidth === "equal") {
|
|
54
|
+
setReferenceWidth(rects.reference.width);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}), [dropdownWidth]);
|
|
58
|
+
const {
|
|
59
|
+
refs,
|
|
60
|
+
floatingStyles,
|
|
61
|
+
context
|
|
62
|
+
} = useFloating({
|
|
63
|
+
nodeId,
|
|
64
|
+
open,
|
|
65
|
+
onOpenChange: handleOpenChange,
|
|
66
|
+
placement: placementMap[placement],
|
|
67
|
+
middleware: [offset(theme.x1), flip(), shift(), sizeMiddleware],
|
|
68
|
+
whileElementsMounted: autoUpdate
|
|
69
|
+
});
|
|
70
|
+
const childRef = getNodeRef(childrenProp);
|
|
71
|
+
const mergedRef = useMergeRefs([refs.setReference, childRef, setTriggerEl]);
|
|
72
|
+
const click = useClick(context, {
|
|
73
|
+
enabled: !disabled && trigger.includes("click")
|
|
74
|
+
});
|
|
75
|
+
const hover = useHover(context, {
|
|
76
|
+
enabled: !disabled && trigger.includes("hover"),
|
|
77
|
+
handleClose: safePolygon()
|
|
78
|
+
});
|
|
79
|
+
const isContextMenuOnly = trigger.includes("contextMenu") && !trigger.includes("click");
|
|
80
|
+
const dismiss = useDismiss(context, {
|
|
81
|
+
escapeKey: true,
|
|
82
|
+
outsidePress: true,
|
|
83
|
+
referencePress: isContextMenuOnly,
|
|
84
|
+
enabled: !disabled
|
|
85
|
+
});
|
|
86
|
+
const contextMenu = useContextMenu(context, {
|
|
87
|
+
enabled: !disabled && trigger.includes("contextMenu")
|
|
88
|
+
});
|
|
89
|
+
const listNavigation = useListNavigation(context, {
|
|
90
|
+
listRef: elementsRef,
|
|
91
|
+
activeIndex,
|
|
92
|
+
onNavigate: setActiveIndex,
|
|
93
|
+
enabled: !disabled
|
|
94
|
+
});
|
|
95
|
+
const {
|
|
96
|
+
getFloatingProps,
|
|
97
|
+
getReferenceProps,
|
|
98
|
+
getItemProps
|
|
99
|
+
} = useInteractions([click, hover, dismiss, contextMenu, listNavigation]);
|
|
100
|
+
const stableGetItemProps = useEvent(getItemProps);
|
|
101
|
+
const autoFocusIndex = useMemo(() => getFirstEnabledIndex(menu.items), [menu.items]);
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (!open) {
|
|
104
|
+
setActiveIndex(null);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (autoFocus) {
|
|
108
|
+
setActiveIndex(autoFocusIndex);
|
|
109
|
+
}
|
|
110
|
+
}, [autoFocus, open, autoFocusIndex]);
|
|
111
|
+
const tree = useFloatingTree();
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (!tree) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const handleTreeClick = (event) => {
|
|
117
|
+
context.onOpenChange(false, event);
|
|
118
|
+
};
|
|
119
|
+
tree.events.on("click", handleTreeClick);
|
|
120
|
+
return () => {
|
|
121
|
+
tree.events.off("click", handleTreeClick);
|
|
122
|
+
};
|
|
123
|
+
}, [tree, context]);
|
|
124
|
+
const referenceProps = getReferenceProps({
|
|
125
|
+
ref: mergedRef,
|
|
126
|
+
...childrenProp.props
|
|
127
|
+
});
|
|
128
|
+
const children = isValidElement(childrenProp) ? cloneElement(childrenProp, referenceProps) : childrenProp;
|
|
129
|
+
const contextValue = useMemo(() => ({
|
|
130
|
+
styles,
|
|
131
|
+
triggerSubMenuAction: menu.triggerSubMenuAction ?? defaultMenuConfig.triggerSubMenuAction,
|
|
132
|
+
subMenuOpenDelay: menu.subMenuOpenDelay ?? defaultMenuConfig.subMenuOpenDelay,
|
|
133
|
+
subMenuCloseDelay: menu.subMenuCloseDelay ?? defaultMenuConfig.subMenuCloseDelay,
|
|
134
|
+
onMenuClick: menu.onClick
|
|
135
|
+
}), [styles, menu.triggerSubMenuAction, menu.subMenuOpenDelay, menu.subMenuCloseDelay, menu.onClick]);
|
|
136
|
+
const navigationContextValue = useMemo(() => ({
|
|
137
|
+
activeIndex,
|
|
138
|
+
getItemProps: stableGetItemProps
|
|
139
|
+
}), [activeIndex, stableGetItemProps]);
|
|
140
|
+
const popupContainer = useMemo(() => {
|
|
141
|
+
if (!getPopupContainer || !triggerEl) {
|
|
142
|
+
return void 0;
|
|
143
|
+
}
|
|
144
|
+
return getPopupContainer(triggerEl);
|
|
145
|
+
}, [getPopupContainer, triggerEl]);
|
|
146
|
+
const canRenderPopup = open && (!getPopupContainer || popupContainer);
|
|
147
|
+
const popupStyle = useMemo(() => {
|
|
148
|
+
const width = dropdownWidth === "equal" ? referenceWidth : dropdownWidth;
|
|
149
|
+
return {
|
|
150
|
+
...floatingStyles,
|
|
151
|
+
...width !== null && {
|
|
152
|
+
width
|
|
153
|
+
},
|
|
154
|
+
...dropdownMinWidth !== null && {
|
|
155
|
+
minWidth: dropdownMinWidth
|
|
156
|
+
},
|
|
157
|
+
...dropdownMaxHeight !== null && {
|
|
158
|
+
maxHeight: dropdownMaxHeight,
|
|
159
|
+
overflowY: "auto",
|
|
160
|
+
overflowX: "hidden"
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}, [floatingStyles, dropdownWidth, dropdownMinWidth, dropdownMaxHeight, referenceWidth]);
|
|
164
|
+
const menuNode = /* @__PURE__ */ jsx(NewDropdownContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(NewDropdownNavigationContext.Provider, { value: navigationContextValue, children: /* @__PURE__ */ jsx(Menu, { items: menu.items, "test-id": menu["test-id"] }) }) });
|
|
165
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
166
|
+
children,
|
|
167
|
+
/* @__PURE__ */ jsx(FloatingNode, { id: nodeId, children: /* @__PURE__ */ jsx(FloatingList, { elementsRef, children: canRenderPopup && /* @__PURE__ */ jsx(FloatingPortal, { root: popupContainer, children: /* @__PURE__ */ jsx(FloatingFocusManager, { context, modal: false, initialFocus: autoFocus ? 0 : -1, children: /* @__PURE__ */ jsx("div", { ref: refs.setFloating, style: popupStyle, css: [rootStyle(theme), (_a = styles == null ? void 0 : styles.root) == null ? void 0 : _a.call(styles, tokens, theme), process.env.NODE_ENV === "production" ? "" : ";label:NewDropdownInner;", process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9idWlsZHMvZnJvbnRlbmQvbGlicy91aS1raXQvc3JjL2NvbXBvbmVudHMvTmV3RHJvcGRvd24vTmV3RHJvcGRvd24udHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQStQa0IiLCJmaWxlIjoiL2J1aWxkcy9mcm9udGVuZC9saWJzL3VpLWtpdC9zcmMvY29tcG9uZW50cy9OZXdEcm9wZG93bi9OZXdEcm9wZG93bi50c3giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBjbG9uZUVsZW1lbnQsXG4gIGlzVmFsaWRFbGVtZW50LFxuICBtZW1vLFxuICB1c2VFZmZlY3QsXG4gIHVzZU1lbW8sXG4gIHVzZVJlZixcbiAgdXNlU3RhdGUsXG4gIHR5cGUgQ1NTUHJvcGVydGllcyxcbiAgdHlwZSBGQyxcbn0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQge1xuICBhdXRvVXBkYXRlLFxuICBmbGlwLFxuICBGbG9hdGluZ0ZvY3VzTWFuYWdlcixcbiAgRmxvYXRpbmdMaXN0LFxuICBGbG9hdGluZ05vZGUsXG4gIEZsb2F0aW5nUG9ydGFsLFxuICBGbG9hdGluZ1RyZWUsXG4gIG9mZnNldCxcbiAgc2FmZVBvbHlnb24sXG4gIHNoaWZ0LFxuICBzaXplLFxuICB1c2VDbGljayxcbiAgdXNlRGlzbWlzcyxcbiAgdXNlRmxvYXRpbmcsXG4gIHVzZUZsb2F0aW5nTm9kZUlkLFxuICB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCxcbiAgdXNlRmxvYXRpbmdUcmVlLFxuICB1c2VIb3ZlcixcbiAgdXNlSW50ZXJhY3Rpb25zLFxuICB1c2VMaXN0TmF2aWdhdGlvbixcbiAgdXNlTWVyZ2VSZWZzLFxufSBmcm9tIFwiQGZsb2F0aW5nLXVpL3JlYWN0XCI7XG5pbXBvcnQgeyB1c2VDb250cm9sbGVkU3RhdGUgfSBmcm9tIFwiaG9va3MvdXNlQ29udHJvbGxlZFN0YXRlXCI7XG5pbXBvcnQgeyB1c2VFdmVudCB9IGZyb20gXCJob29rcy91c2VFdmVudFwiO1xuaW1wb3J0IHsgdXNlTmV3RHJvcGRvd25Ub2tlbnMgfSBmcm9tIFwiLi9ob29rcy91c2VOZXdEcm9wZG93blRva2Vuc1wiO1xuaW1wb3J0IHsgcm9vdFN0eWxlIH0gZnJvbSBcIi4vTmV3RHJvcGRvd24uc3R5bGVzXCI7XG5pbXBvcnQge1xuICBkZWZhdWx0RHJvcGRvd25NYXhIZWlnaHQsXG4gIGRlZmF1bHREcm9wZG93bk1pbldpZHRoLFxuICBkZWZhdWx0TWVudUNvbmZpZyxcbiAgZGVmYXVsdFRyaWdnZXIsXG4gIGdldEZpcnN0RW5hYmxlZEluZGV4LFxuICBwbGFjZW1lbnRNYXAsXG59IGZyb20gXCIuL05ld0Ryb3Bkb3duLnV0aWxzXCI7XG5pbXBvcnQgeyBNZW51IH0gZnJvbSBcIi4vY29tcG9uZW50cy9NZW51L01lbnVcIjtcbmltcG9ydCB7IHVzZUNvbnRleHRNZW51IH0gZnJvbSBcIi4vaG9va3MvdXNlQ29udGV4dE1lbnVcIjtcbmltcG9ydCB7IE5ld0Ryb3Bkb3duQ29udGV4dCwgdHlwZSBOZXdEcm9wZG93bkNvbnRleHRWYWx1ZSB9IGZyb20gXCIuL2NvbnRleHRzL05ld0Ryb3Bkb3duQ29udGV4dFwiO1xuaW1wb3J0IHtcbiAgTmV3RHJvcGRvd25OYXZpZ2F0aW9uQ29udGV4dCxcbiAgdHlwZSBOZXdEcm9wZG93bk5hdmlnYXRpb25Db250ZXh0VmFsdWUsXG59IGZyb20gXCIuL2NvbnRleHRzL05ld0Ryb3Bkb3duTmF2aWdhdGlvbkNvbnRleHRcIjtcbmltcG9ydCB0eXBlIHsgTmV3RHJvcGRvd25Qcm9wcyB9IGZyb20gXCIuL05ld0Ryb3Bkb3duLnR5cGVzXCI7XG5pbXBvcnQgeyBnZXROb2RlUmVmIH0gZnJvbSBcInJjLXV0aWwvZXMvcmVmLmpzXCI7XG5cbmNvbnN0IE5ld0Ryb3Bkb3duSW5uZXI6IEZDPE5ld0Ryb3Bkb3duUHJvcHM+ID0gKHByb3BzKSA9PiB7XG4gIGNvbnN0IHtcbiAgICBjaGlsZHJlbjogY2hpbGRyZW5Qcm9wLFxuICAgIG1lbnUsXG4gICAgcGxhY2VtZW50ID0gXCJib3R0b21MZWZ0XCIsXG4gICAgc3R5bGVzLFxuICAgIHRyaWdnZXIgPSBkZWZhdWx0VHJpZ2dlcixcbiAgICBvcGVuOiBvcGVuUHJvcCxcbiAgICBvbk9wZW5DaGFuZ2U6IG9uT3BlbkNoYW5nZVByb3AsXG4gICAgZGlzYWJsZWQgPSBmYWxzZSxcbiAgICBhdXRvRm9jdXMgPSBmYWxzZSxcbiAgICBkcm9wZG93bldpZHRoID0gbnVsbCxcbiAgICBkcm9wZG93bk1pbldpZHRoID0gZGVmYXVsdERyb3Bkb3duTWluV2lkdGgsXG4gICAgZHJvcGRvd25NYXhIZWlnaHQgPSBkZWZhdWx0RHJvcGRvd25NYXhIZWlnaHQsXG4gICAgcG9wdXBSZW5kZXIsXG4gICAgZ2V0UG9wdXBDb250YWluZXIsXG4gICAgXCJ0ZXN0LWlkXCI6IHRlc3RJZCxcbiAgfSA9IHByb3BzO1xuICBjb25zdCB7IHRoZW1lLCB0b2tlbnMgfSA9IHVzZU5ld0Ryb3Bkb3duVG9rZW5zKCk7XG4gIGNvbnN0IG5vZGVJZCA9IHVzZUZsb2F0aW5nTm9kZUlkKCk7XG4gIGNvbnN0IGVsZW1lbnRzUmVmID0gdXNlUmVmPEFycmF5PEhUTUxFbGVtZW50IHwgbnVsbD4+KFtdKTtcblxuICBjb25zdCBbb3Blbiwgc2V0T3Blbl0gPSB1c2VDb250cm9sbGVkU3RhdGUoZmFsc2UsIG9wZW5Qcm9wKTtcbiAgY29uc3QgW2FjdGl2ZUluZGV4LCBzZXRBY3RpdmVJbmRleF0gPSB1c2VTdGF0ZTxudW1iZXIgfCBudWxsPihudWxsKTtcbiAgY29uc3QgW3RyaWdnZXJFbCwgc2V0VHJpZ2dlckVsXSA9IHVzZVN0YXRlPEhUTUxFbGVtZW50IHwgbnVsbD4obnVsbCk7XG5cbiAgY29uc3QgaGFuZGxlT3BlbkNoYW5nZTogTm9uTnVsbGFibGU8UGFyYW1ldGVyczx0eXBlb2YgdXNlRmxvYXRpbmc+WzBdPltcIm9uT3BlbkNoYW5nZVwiXSA9IChcbiAgICBuZXh0LFxuICAgIF9ldmVudCxcbiAgICByZWFzb25cbiAgKSA9PiB7XG4gICAgc2V0T3BlbihuZXh0KTtcbiAgICBvbk9wZW5DaGFuZ2VQcm9wPy4obmV4dCwgeyBzb3VyY2U6IHJlYXNvbiAhPT0gdW5kZWZpbmVkID8gXCJ0cmlnZ2VyXCIgOiBcIm1lbnVcIiB9KTtcbiAgfTtcblxuICBjb25zdCBbcmVmZXJlbmNlV2lkdGgsIHNldFJlZmVyZW5jZVdpZHRoXSA9IHVzZVN0YXRlPG51bWJlciB8IG51bGw+KG51bGwpO1xuXG4gIGNvbnN0IHNpemVNaWRkbGV3YXJlID0gdXNlTWVtbyhcbiAgICAoKSA9PlxuICAgICAgc2l6ZSh7XG4gICAgICAgIGFwcGx5KHsgcmVjdHMgfSkge1xuICAgICAgICAgIGlmIChkcm9wZG93bldpZHRoID09PSBcImVxdWFsXCIpIHtcbiAgICAgICAgICAgIHNldFJlZmVyZW5jZVdpZHRoKHJlY3RzLnJlZmVyZW5jZS53aWR0aCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgW2Ryb3Bkb3duV2lkdGhdXG4gICk7XG5cbiAgY29uc3QgeyByZWZzLCBmbG9hdGluZ1N0eWxlcywgY29udGV4dCB9ID0gdXNlRmxvYXRpbmcoe1xuICAgIG5vZGVJZCxcbiAgICBvcGVuLFxuICAgIG9uT3BlbkNoYW5nZTogaGFuZGxlT3BlbkNoYW5nZSxcbiAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudE1hcFtwbGFjZW1lbnRdLFxuICAgIG1pZGRsZXdhcmU6IFtvZmZzZXQodGhlbWUueDEpLCBmbGlwKCksIHNoaWZ0KCksIHNpemVNaWRkbGV3YXJlXSxcbiAgICB3aGlsZUVsZW1lbnRzTW91bnRlZDogYXV0b1VwZGF0ZSxcbiAgfSk7XG4gIGNvbnN0IGNoaWxkUmVmID0gZ2V0Tm9kZVJlZihjaGlsZHJlblByb3ApO1xuICBjb25zdCBtZXJnZWRSZWYgPSB1c2VNZXJnZVJlZnMoW3JlZnMuc2V0UmVmZXJlbmNlLCBjaGlsZFJlZiwgc2V0VHJpZ2dlckVsXSk7XG5cbiAgY29uc3QgY2xpY2sgPSB1c2VDbGljayhjb250ZXh0LCB7IGVuYWJsZWQ6ICFkaXNhYmxlZCAmJiB0cmlnZ2VyLmluY2x1ZGVzKFwiY2xpY2tcIikgfSk7XG4gIGNvbnN0IGhvdmVyID0gdXNlSG92ZXIoY29udGV4dCwge1xuICAgIGVuYWJsZWQ6ICFkaXNhYmxlZCAmJiB0cmlnZ2VyLmluY2x1ZGVzKFwiaG92ZXJcIiksXG4gICAgaGFuZGxlQ2xvc2U6IHNhZmVQb2x5Z29uKCksXG4gIH0pO1xuICBjb25zdCBpc0NvbnRleHRNZW51T25seSA9IHRyaWdnZXIuaW5jbHVkZXMoXCJjb250ZXh0TWVudVwiKSAmJiAhdHJpZ2dlci5pbmNsdWRlcyhcImNsaWNrXCIpO1xuICBjb25zdCBkaXNtaXNzID0gdXNlRGlzbWlzcyhjb250ZXh0LCB7XG4gICAgZXNjYXBlS2V5OiB0cnVlLFxuICAgIG91dHNpZGVQcmVzczogdHJ1ZSxcbiAgICByZWZlcmVuY2VQcmVzczogaXNDb250ZXh0TWVudU9ubHksXG4gICAgZW5hYmxlZDogIWRpc2FibGVkLFxuICB9KTtcbiAgY29uc3QgY29udGV4dE1lbnUgPSB1c2VDb250ZXh0TWVudShjb250ZXh0LCB7XG4gICAgZW5hYmxlZDogIWRpc2FibGVkICYmIHRyaWdnZXIuaW5jbHVkZXMoXCJjb250ZXh0TWVudVwiKSxcbiAgfSk7XG4gIGNvbnN0IGxpc3ROYXZpZ2F0aW9uID0gdXNlTGlzdE5hdmlnYXRpb24oY29udGV4dCwge1xuICAgIGxpc3RSZWY6IGVsZW1lbnRzUmVmLFxuICAgIGFjdGl2ZUluZGV4LFxuICAgIG9uTmF2aWdhdGU6IHNldEFjdGl2ZUluZGV4LFxuICAgIGVuYWJsZWQ6ICFkaXNhYmxlZCxcbiAgfSk7XG4gIGNvbnN0IHsgZ2V0RmxvYXRpbmdQcm9wcywgZ2V0UmVmZXJlbmNlUHJvcHMsIGdldEl0ZW1Qcm9wcyB9ID0gdXNlSW50ZXJhY3Rpb25zKFtcbiAgICBjbGljayxcbiAgICBob3ZlcixcbiAgICBkaXNtaXNzLFxuICAgIGNvbnRleHRNZW51LFxuICAgIGxpc3ROYXZpZ2F0aW9uLFxuICBdKTtcbiAgLy8gZ2V0SXRlbVByb3BzINC+0YIgdXNlSW50ZXJhY3Rpb25zINC40LzQtdC10YIg0L3QvtCy0YPRjiDRgdGB0YvQu9C60YMg0LrQsNC20LTRi9C5INGA0LXQvdC00LXRgDsg0YHRgtCw0LHQuNC70LjQt9C40YDRg9C10LxcbiAgLy8g0YfQtdGA0LXQtyB1c2VFdmVudCwg0YfRgtC+0LHRiyBuYXZpZ2F0aW9uQ29udGV4dFZhbHVlINC90LUg0LjQvdCy0LDQu9C40LTQuNGA0L7QstCw0LvRgdGPINCx0LXQtyDRgdC80LXQvdGLIGFjdGl2ZUluZGV4LlxuICBjb25zdCBzdGFibGVHZXRJdGVtUHJvcHMgPSB1c2VFdmVudChnZXRJdGVtUHJvcHMpO1xuXG4gIGNvbnN0IGF1dG9Gb2N1c0luZGV4ID0gdXNlTWVtbygoKSA9PiBnZXRGaXJzdEVuYWJsZWRJbmRleChtZW51Lml0ZW1zKSwgW21lbnUuaXRlbXNdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghb3Blbikge1xuICAgICAgc2V0QWN0aXZlSW5kZXgobnVsbCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoYXV0b0ZvY3VzKSB7XG4gICAgICBzZXRBY3RpdmVJbmRleChhdXRvRm9jdXNJbmRleCk7XG4gICAgfVxuICB9LCBbYXV0b0ZvY3VzLCBvcGVuLCBhdXRvRm9jdXNJbmRleF0pO1xuXG4gIGNvbnN0IHRyZWUgPSB1c2VGbG9hdGluZ1RyZWUoKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghdHJlZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbmRsZVRyZWVDbGljayA9IChldmVudD86IEV2ZW50KSA9PiB7XG4gICAgICBjb250ZXh0Lm9uT3BlbkNoYW5nZShmYWxzZSwgZXZlbnQpO1xuICAgIH07XG5cbiAgICB0cmVlLmV2ZW50cy5vbihcImNsaWNrXCIsIGhhbmRsZVRyZWVDbGljayk7XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgdHJlZS5ldmVudHMub2ZmKFwiY2xpY2tcIiwgaGFuZGxlVHJlZUNsaWNrKTtcbiAgICB9O1xuICB9LCBbdHJlZSwgY29udGV4dF0pO1xuXG4gIGNvbnN0IHJlZmVyZW5jZVByb3BzID0gZ2V0UmVmZXJlbmNlUHJvcHMoe1xuICAgIHJlZjogbWVyZ2VkUmVmLFxuICAgIC4uLmNoaWxkcmVuUHJvcC5wcm9wcyxcbiAgfSk7XG5cbiAgY29uc3QgY2hpbGRyZW4gPSBpc1ZhbGlkRWxlbWVudChjaGlsZHJlblByb3ApXG4gICAgPyBjbG9uZUVsZW1lbnQoY2hpbGRyZW5Qcm9wLCByZWZlcmVuY2VQcm9wcylcbiAgICA6IGNoaWxkcmVuUHJvcDtcblxuICBjb25zdCBjb250ZXh0VmFsdWUgPSB1c2VNZW1vPE5ld0Ryb3Bkb3duQ29udGV4dFZhbHVlPihcbiAgICAoKSA9PiAoe1xuICAgICAgc3R5bGVzLFxuICAgICAgdHJpZ2dlclN1Yk1lbnVBY3Rpb246IG1lbnUudHJpZ2dlclN1Yk1lbnVBY3Rpb24gPz8gZGVmYXVsdE1lbnVDb25maWcudHJpZ2dlclN1Yk1lbnVBY3Rpb24sXG4gICAgICBzdWJNZW51T3BlbkRlbGF5OiBtZW51LnN1Yk1lbnVPcGVuRGVsYXkgPz8gZGVmYXVsdE1lbnVDb25maWcuc3ViTWVudU9wZW5EZWxheSxcbiAgICAgIHN1Yk1lbnVDbG9zZURlbGF5OiBtZW51LnN1Yk1lbnVDbG9zZURlbGF5ID8/IGRlZmF1bHRNZW51Q29uZmlnLnN1Yk1lbnVDbG9zZURlbGF5LFxuICAgICAgb25NZW51Q2xpY2s6IG1lbnUub25DbGljayxcbiAgICB9KSxcbiAgICBbc3R5bGVzLCBtZW51LnRyaWdnZXJTdWJNZW51QWN0aW9uLCBtZW51LnN1Yk1lbnVPcGVuRGVsYXksIG1lbnUuc3ViTWVudUNsb3NlRGVsYXksIG1lbnUub25DbGlja11cbiAgKTtcblxuICBjb25zdCBuYXZpZ2F0aW9uQ29udGV4dFZhbHVlID0gdXNlTWVtbzxOZXdEcm9wZG93bk5hdmlnYXRpb25Db250ZXh0VmFsdWU+KFxuICAgICgpID0+ICh7IGFjdGl2ZUluZGV4LCBnZXRJdGVtUHJvcHM6IHN0YWJsZUdldEl0ZW1Qcm9wcyB9KSxcbiAgICBbYWN0aXZlSW5kZXgsIHN0YWJsZUdldEl0ZW1Qcm9wc11cbiAgKTtcblxuICBjb25zdCBwb3B1cENvbnRhaW5lciA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmICghZ2V0UG9wdXBDb250YWluZXIgfHwgIXRyaWdnZXJFbCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0UG9wdXBDb250YWluZXIodHJpZ2dlckVsKTtcbiAgfSwgW2dldFBvcHVwQ29udGFpbmVyLCB0cmlnZ2VyRWxdKTtcblxuICAvLyDQldGB0LvQuCBnZXRQb3B1cENvbnRhaW5lciDQt9Cw0LTQsNC9LCDQttC00ZHQvCDQs9C+0YLQvtCy0L3QvtGB0YLQuCB0cmlnZ2VyRWwsINGH0YLQvtCx0Ysg0L/QvtGA0YLQsNC7XG4gIC8vINC90LUg0LzQvtGA0LPQsNC7IMKrYm9keSDihpIg0L3Rg9C20L3Ri9C5INC60L7QvdGC0LXQudC90LXRgMK7INC/0YDQuCDQv9C10YDQstC40YfQvdC+0LwgcmVuZGVyINGBIGNvbnRyb2xsZWQgb3Blbj10cnVlLlxuICBjb25zdCBjYW5SZW5kZXJQb3B1cCA9IG9wZW4gJiYgKCFnZXRQb3B1cENvbnRhaW5lciB8fCBwb3B1cENvbnRhaW5lcik7XG5cbiAgY29uc3QgcG9wdXBTdHlsZSA9IHVzZU1lbW88Q1NTUHJvcGVydGllcz4oKCkgPT4ge1xuICAgIGNvbnN0IHdpZHRoID0gZHJvcGRvd25XaWR0aCA9PT0gXCJlcXVhbFwiID8gcmVmZXJlbmNlV2lkdGggOiBkcm9wZG93bldpZHRoO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmZsb2F0aW5nU3R5bGVzLFxuICAgICAgLi4uKHdpZHRoICE9PSBudWxsICYmIHsgd2lkdGggfSksXG4gICAgICAuLi4oZHJvcGRvd25NaW5XaWR0aCAhPT0gbnVsbCAmJiB7IG1pbldpZHRoOiBkcm9wZG93bk1pbldpZHRoIH0pLFxuICAgICAgLi4uKGRyb3Bkb3duTWF4SGVpZ2h0ICE9PSBudWxsICYmIHtcbiAgICAgICAgbWF4SGVpZ2h0OiBkcm9wZG93bk1heEhlaWdodCxcbiAgICAgICAgb3ZlcmZsb3dZOiBcImF1dG9cIixcbiAgICAgICAgb3ZlcmZsb3dYOiBcImhpZGRlblwiLFxuICAgICAgfSksXG4gICAgfTtcbiAgfSwgW2Zsb2F0aW5nU3R5bGVzLCBkcm9wZG93bldpZHRoLCBkcm9wZG93bk1pbldpZHRoLCBkcm9wZG93bk1heEhlaWdodCwgcmVmZXJlbmNlV2lkdGhdKTtcblxuICBjb25zdCBtZW51Tm9kZSA9IChcbiAgICA8TmV3RHJvcGRvd25Db250ZXh0LlByb3ZpZGVyIHZhbHVlPXtjb250ZXh0VmFsdWV9PlxuICAgICAgPE5ld0Ryb3Bkb3duTmF2aWdhdGlvbkNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e25hdmlnYXRpb25Db250ZXh0VmFsdWV9PlxuICAgICAgICA8TWVudSBpdGVtcz17bWVudS5pdGVtc30gdGVzdC1pZD17bWVudVtcInRlc3QtaWRcIl19IC8+XG4gICAgICA8L05ld0Ryb3Bkb3duTmF2aWdhdGlvbkNvbnRleHQuUHJvdmlkZXI+XG4gICAgPC9OZXdEcm9wZG93bkNvbnRleHQuUHJvdmlkZXI+XG4gICk7XG5cbiAgcmV0dXJuIChcbiAgICA8PlxuICAgICAge2NoaWxkcmVufVxuICAgICAgPEZsb2F0aW5nTm9kZSBpZD17bm9kZUlkfT5cbiAgICAgICAgPEZsb2F0aW5nTGlzdCBlbGVtZW50c1JlZj17ZWxlbWVudHNSZWZ9PlxuICAgICAgICAgIHtjYW5SZW5kZXJQb3B1cCAmJiAoXG4gICAgICAgICAgICA8RmxvYXRpbmdQb3J0YWwgcm9vdD17cG9wdXBDb250YWluZXJ9PlxuICAgICAgICAgICAgICA8RmxvYXRpbmdGb2N1c01hbmFnZXJcbiAgICAgICAgICAgICAgICBjb250ZXh0PXtjb250ZXh0fVxuICAgICAgICAgICAgICAgIG1vZGFsPXtmYWxzZX1cbiAgICAgICAgICAgICAgICBpbml0aWFsRm9jdXM9e2F1dG9Gb2N1cyA/IDAgOiAtMX1cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIHJlZj17cmVmcy5zZXRGbG9hdGluZ31cbiAgICAgICAgICAgICAgICAgIHN0eWxlPXtwb3B1cFN0eWxlfVxuICAgICAgICAgICAgICAgICAgY3NzPXtbcm9vdFN0eWxlKHRoZW1lKSwgc3R5bGVzPy5yb290Py4odG9rZW5zLCB0aGVtZSldfVxuICAgICAgICAgICAgICAgICAgey4uLmdldEZsb2F0aW5nUHJvcHMoKX1cbiAgICAgICAgICAgICAgICAgIHRlc3QtaWQ9e3Rlc3RJZH1cbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICB7cG9wdXBSZW5kZXI/LihtZW51Tm9kZSkgPz8gbWVudU5vZGV9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvRmxvYXRpbmdGb2N1c01hbmFnZXI+XG4gICAgICAgICAgICA8L0Zsb2F0aW5nUG9ydGFsPlxuICAgICAgICAgICl9XG4gICAgICAgIDwvRmxvYXRpbmdMaXN0PlxuICAgICAgPC9GbG9hdGluZ05vZGU+XG4gICAgPC8+XG4gICk7XG59O1xuXG5jb25zdCBOZXdEcm9wZG93bkNvbXBvbmVudDogRkM8TmV3RHJvcGRvd25Qcm9wcz4gPSAocHJvcHMpID0+IHtcbiAgY29uc3QgcGFyZW50SWQgPSB1c2VGbG9hdGluZ1BhcmVudE5vZGVJZCgpO1xuXG4gIGlmIChwYXJlbnRJZCA9PT0gbnVsbCkge1xuICAgIHJldHVybiAoXG4gICAgICA8RmxvYXRpbmdUcmVlPlxuICAgICAgICA8TmV3RHJvcGRvd25Jbm5lciB7Li4ucHJvcHN9IC8+XG4gICAgICA8L0Zsb2F0aW5nVHJlZT5cbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIDxOZXdEcm9wZG93bklubmVyIHsuLi5wcm9wc30gLz47XG59O1xuXG5leHBvcnQgY29uc3QgTmV3RHJvcGRvd24gPSBtZW1vKE5ld0Ryb3Bkb3duQ29tcG9uZW50KTtcbiJdfQ== */"], ...getFloatingProps(), "test-id": testId, children: (popupRender == null ? void 0 : popupRender(menuNode)) ?? menuNode }) }) }) }) })
|
|
168
|
+
] });
|
|
169
|
+
};
|
|
170
|
+
const NewDropdownComponent = (props) => {
|
|
171
|
+
const parentId = useFloatingParentNodeId();
|
|
172
|
+
if (parentId === null) {
|
|
173
|
+
return /* @__PURE__ */ jsx(FloatingTree, { children: /* @__PURE__ */ jsx(NewDropdownInner, { ...props }) });
|
|
174
|
+
}
|
|
175
|
+
return /* @__PURE__ */ jsx(NewDropdownInner, { ...props });
|
|
176
|
+
};
|
|
177
|
+
const NewDropdown = memo(NewDropdownComponent);
|
|
178
|
+
export {
|
|
179
|
+
NewDropdown
|
|
180
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Interpolation } from '@emotion/react';
|
|
2
|
+
import { Theme } from 'themes';
|
|
3
|
+
/**
|
|
4
|
+
* Стили внешней обёртки popup-контейнера.
|
|
5
|
+
* Принимает только theme → именование без `get`-префикса.
|
|
6
|
+
*
|
|
7
|
+
* Свойства, зависящие от пропсов (`min-width`, `max-height`, `overflow`),
|
|
8
|
+
* задаются инлайном в `NewDropdown.tsx` — см. `popupStyle`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const rootStyle: (theme: Theme) => Interpolation;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Theme } from 'themes';
|
|
2
|
+
export declare const getNewDropdownTokens: (theme: Theme) => {
|
|
3
|
+
readonly dropdownItemText: "#262626";
|
|
4
|
+
readonly dropdownItemTextSelected: "#0CB3B3";
|
|
5
|
+
readonly dropdownItemTextDisabled: "#8C8C8C";
|
|
6
|
+
readonly dropdownItemTextExtra: "#8C8C8C";
|
|
7
|
+
readonly dropdownItemTextTitle: "#8C8C8C";
|
|
8
|
+
readonly dropdownItemBgHover: `rgba(${number}, ${number}, ${number}, 0.08)`;
|
|
9
|
+
readonly dropdownItemDivider: "#E5E5E5";
|
|
10
|
+
readonly dropdownItemPaddingVertical: 4;
|
|
11
|
+
readonly dropdownItemPaddingHorizontal: 8;
|
|
12
|
+
};
|
|
13
|
+
export type NewDropdownTokens = ReturnType<typeof getNewDropdownTokens>;
|
|
14
|
+
declare module "../ConfigProvider" {
|
|
15
|
+
interface Tokens {
|
|
16
|
+
NewDropdown?: Partial<NewDropdownTokens>;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const getNewDropdownTokens = (theme) => ({
|
|
2
|
+
dropdownItemText: theme.textPrimary,
|
|
3
|
+
dropdownItemTextSelected: theme.primaryBase,
|
|
4
|
+
dropdownItemTextDisabled: theme.textDisabled,
|
|
5
|
+
dropdownItemTextExtra: theme.textSecondary,
|
|
6
|
+
dropdownItemTextTitle: theme.textSecondary,
|
|
7
|
+
dropdownItemBgHover: theme.bgContainerHover,
|
|
8
|
+
dropdownItemDivider: theme.lineDivider,
|
|
9
|
+
dropdownItemPaddingVertical: theme.x1,
|
|
10
|
+
dropdownItemPaddingHorizontal: theme.x2
|
|
11
|
+
});
|
|
12
|
+
export {
|
|
13
|
+
getNewDropdownTokens
|
|
14
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Interpolation } from '@emotion/react';
|
|
2
|
+
import { CSSProperties, MouseEvent, ReactElement, ReactNode } from 'react';
|
|
3
|
+
import { Theme } from 'themes';
|
|
4
|
+
import { NewDropdownTokens } from './NewDropdown.tokens';
|
|
5
|
+
export type NewDropdownTriggerType = "click" | "hover" | "contextMenu";
|
|
6
|
+
export type NewDropdownPlacementType = "bottomLeft" | "bottom" | "bottomRight" | "topLeft" | "top" | "topRight";
|
|
7
|
+
export type NewDropdownSubMenuTrigger = Extract<NewDropdownTriggerType, "click" | "hover">;
|
|
8
|
+
interface NewDropdownItemBase {
|
|
9
|
+
key: string;
|
|
10
|
+
label: ReactNode;
|
|
11
|
+
type?: never;
|
|
12
|
+
icon?: ReactNode;
|
|
13
|
+
/** @default false */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
"test-id"?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface NewDropdownMenuItem extends NewDropdownItemBase {
|
|
18
|
+
extra?: ReactNode;
|
|
19
|
+
onClick?: NewDropdownItemClickHandler;
|
|
20
|
+
}
|
|
21
|
+
export interface NewDropdownSubMenuItem extends NewDropdownItemBase {
|
|
22
|
+
children: NewDropdownItem[];
|
|
23
|
+
onClick?: NewDropdownSubMenuClickHandler;
|
|
24
|
+
}
|
|
25
|
+
export interface NewDropdownGroupItem extends Partial<Pick<NewDropdownItemBase, "key" | "label" | "icon">> {
|
|
26
|
+
type: "group";
|
|
27
|
+
children: NewDropdownItem[];
|
|
28
|
+
}
|
|
29
|
+
export interface NewDropdownDividerItem extends Partial<Pick<NewDropdownItemBase, "key">> {
|
|
30
|
+
type: "divider";
|
|
31
|
+
}
|
|
32
|
+
export type NewDropdownItem = NewDropdownMenuItem | NewDropdownSubMenuItem | NewDropdownGroupItem | NewDropdownDividerItem;
|
|
33
|
+
export interface NewDropdownOpenChangeInfo {
|
|
34
|
+
source: "trigger" | "menu";
|
|
35
|
+
}
|
|
36
|
+
export interface NewDropdownMenuClickInfo {
|
|
37
|
+
item: NewDropdownItem;
|
|
38
|
+
key: string;
|
|
39
|
+
keyPath: string[];
|
|
40
|
+
domEvent: MouseEvent;
|
|
41
|
+
}
|
|
42
|
+
export type NewDropdownMenuClickHandler = (info: NewDropdownMenuClickInfo) => void;
|
|
43
|
+
export interface NewDropdownItemClickInfo {
|
|
44
|
+
key: string;
|
|
45
|
+
keyPath: string[];
|
|
46
|
+
domEvent: MouseEvent;
|
|
47
|
+
}
|
|
48
|
+
export type NewDropdownItemClickHandler = (info: NewDropdownItemClickInfo) => void;
|
|
49
|
+
export interface NewDropdownSubMenuClickInfo {
|
|
50
|
+
key: string;
|
|
51
|
+
domEvent: MouseEvent;
|
|
52
|
+
}
|
|
53
|
+
export type NewDropdownSubMenuClickHandler = (info: NewDropdownSubMenuClickInfo) => void;
|
|
54
|
+
export type GetStyle = (newDropdownTokens: NewDropdownTokens, theme: Theme) => Interpolation;
|
|
55
|
+
export interface NewDropdownStyles {
|
|
56
|
+
root?: GetStyle;
|
|
57
|
+
item?: GetStyle;
|
|
58
|
+
itemTitle?: GetStyle;
|
|
59
|
+
itemIcon?: GetStyle;
|
|
60
|
+
itemContent?: GetStyle;
|
|
61
|
+
itemExtra?: GetStyle;
|
|
62
|
+
divider?: GetStyle;
|
|
63
|
+
}
|
|
64
|
+
export interface NewDropdownMenuProps {
|
|
65
|
+
items: NewDropdownItem[];
|
|
66
|
+
onClick?: NewDropdownMenuClickHandler;
|
|
67
|
+
/**
|
|
68
|
+
* Задержка перед открытием подменю по hover, в секундах.
|
|
69
|
+
* @default 0
|
|
70
|
+
*/
|
|
71
|
+
subMenuOpenDelay?: number;
|
|
72
|
+
/**
|
|
73
|
+
* Задержка перед закрытием подменю по hover, в секундах.
|
|
74
|
+
* @default 0.1
|
|
75
|
+
*/
|
|
76
|
+
subMenuCloseDelay?: number;
|
|
77
|
+
/** @default "click" */
|
|
78
|
+
triggerSubMenuAction?: NewDropdownSubMenuTrigger;
|
|
79
|
+
"test-id"?: string;
|
|
80
|
+
}
|
|
81
|
+
export interface NewDropdownProps {
|
|
82
|
+
/**
|
|
83
|
+
* Триггер выпадающего меню. Должен быть ОДНИМ React-элементом —
|
|
84
|
+
* DOM-узлом или компонентом, который пробрасывает ref в DOM и
|
|
85
|
+
* расплющивает остальные props (...rest) на корневой элемент.
|
|
86
|
+
* Fragment и массивы не поддерживаются.
|
|
87
|
+
*/
|
|
88
|
+
children: ReactElement;
|
|
89
|
+
menu: NewDropdownMenuProps;
|
|
90
|
+
/** @default ["click"] */
|
|
91
|
+
trigger?: NewDropdownTriggerType[];
|
|
92
|
+
popupRender?: (originNode: ReactNode) => ReactNode;
|
|
93
|
+
open?: boolean;
|
|
94
|
+
onOpenChange?: (open: boolean, info: NewDropdownOpenChangeInfo) => void;
|
|
95
|
+
/** @default "bottomLeft" */
|
|
96
|
+
placement?: NewDropdownPlacementType;
|
|
97
|
+
/**
|
|
98
|
+
* Отключает все триггеры взаимодействия (useClick, useHover, useDismiss).
|
|
99
|
+
* При `disabled={true}` и `open={true}` (controlled) контролируемое состояние
|
|
100
|
+
* не перезаписывается принудительным закрытием.
|
|
101
|
+
* @default false
|
|
102
|
+
*/
|
|
103
|
+
disabled?: boolean;
|
|
104
|
+
/** @default false */
|
|
105
|
+
autoFocus?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Ширина выпадающего списка.
|
|
108
|
+
* - `"equal"` — равна ширине триггера (как у `<Select>`);
|
|
109
|
+
* - число — пиксели;
|
|
110
|
+
* - строка — произвольное CSS-значение (`fit-content`, `100%`, `12rem`, ...);
|
|
111
|
+
* - `null` — `width` вообще не применяется (popup растёт по контенту).
|
|
112
|
+
* @default null
|
|
113
|
+
*/
|
|
114
|
+
dropdownWidth?: number | "equal" | (string & {}) | null;
|
|
115
|
+
/**
|
|
116
|
+
* Минимальная ширина выпадающего списка. Число — пиксели, строка — произвольное CSS-значение.
|
|
117
|
+
* `null` — `min-width` не применяется.
|
|
118
|
+
* @default 120
|
|
119
|
+
*/
|
|
120
|
+
dropdownMinWidth?: CSSProperties["minWidth"] | null;
|
|
121
|
+
/**
|
|
122
|
+
* Максимальная высота выпадающего списка; при превышении появляется вертикальный скролл.
|
|
123
|
+
* Число — пиксели, строка — произвольное CSS-значение. `null` — `max-height`/скролл не применяются.
|
|
124
|
+
* @default 414
|
|
125
|
+
*/
|
|
126
|
+
dropdownMaxHeight?: CSSProperties["maxHeight"] | null;
|
|
127
|
+
/** @default () => document.body */
|
|
128
|
+
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
|
129
|
+
styles?: NewDropdownStyles;
|
|
130
|
+
"test-id"?: string;
|
|
131
|
+
}
|
|
132
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { NewDropdownDividerItem, NewDropdownGroupItem, NewDropdownItem, NewDropdownMenuItem, NewDropdownSubMenuItem, NewDropdownTriggerType } from './NewDropdown.types';
|
|
2
|
+
export declare const defaultTrigger: NewDropdownTriggerType[];
|
|
3
|
+
export declare const defaultDropdownMinWidth = 120;
|
|
4
|
+
export declare const defaultDropdownMaxHeight = 414;
|
|
5
|
+
export declare const defaultMenuConfig: {
|
|
6
|
+
readonly triggerSubMenuAction: "click";
|
|
7
|
+
readonly subMenuOpenDelay: 0;
|
|
8
|
+
readonly subMenuCloseDelay: 0.1;
|
|
9
|
+
};
|
|
10
|
+
export declare const placementMap: {
|
|
11
|
+
bottomLeft: "bottom-start";
|
|
12
|
+
bottom: "bottom";
|
|
13
|
+
bottomRight: "bottom-end";
|
|
14
|
+
topLeft: "top-start";
|
|
15
|
+
top: "top";
|
|
16
|
+
topRight: "top-end";
|
|
17
|
+
};
|
|
18
|
+
export declare function isFlatMenuItem(item: NewDropdownItem): item is NewDropdownMenuItem;
|
|
19
|
+
export declare function isDividerItem(item: NewDropdownItem): item is NewDropdownDividerItem;
|
|
20
|
+
export declare function isSubMenuItem(item: NewDropdownItem): item is NewDropdownSubMenuItem;
|
|
21
|
+
export declare function isGroupItem(item: NewDropdownItem): item is NewDropdownGroupItem;
|
|
22
|
+
/**
|
|
23
|
+
* Возвращает индекс первого не-disabled пункта в порядке FloatingList'а.
|
|
24
|
+
* Возвращает `null`, если интерактивных пунктов нет или все disabled.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getFirstEnabledIndex(items: NewDropdownItem[]): number | null;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const defaultTrigger = ["click"];
|
|
2
|
+
const defaultDropdownMinWidth = 120;
|
|
3
|
+
const defaultDropdownMaxHeight = 414;
|
|
4
|
+
const defaultMenuConfig = {
|
|
5
|
+
triggerSubMenuAction: "click",
|
|
6
|
+
subMenuOpenDelay: 0,
|
|
7
|
+
subMenuCloseDelay: 0.1
|
|
8
|
+
};
|
|
9
|
+
const placementMap = {
|
|
10
|
+
bottomLeft: "bottom-start",
|
|
11
|
+
bottom: "bottom",
|
|
12
|
+
bottomRight: "bottom-end",
|
|
13
|
+
topLeft: "top-start",
|
|
14
|
+
top: "top",
|
|
15
|
+
topRight: "top-end"
|
|
16
|
+
};
|
|
17
|
+
function isFlatMenuItem(item) {
|
|
18
|
+
return item.type === void 0 && !("children" in item);
|
|
19
|
+
}
|
|
20
|
+
function isDividerItem(item) {
|
|
21
|
+
return item.type === "divider";
|
|
22
|
+
}
|
|
23
|
+
function isSubMenuItem(item) {
|
|
24
|
+
return "children" in item && item.type !== "group";
|
|
25
|
+
}
|
|
26
|
+
function isGroupItem(item) {
|
|
27
|
+
return item.type === "group";
|
|
28
|
+
}
|
|
29
|
+
function flattenInteractiveItems(items) {
|
|
30
|
+
return items.flatMap((item) => {
|
|
31
|
+
if (isDividerItem(item)) {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
if (isGroupItem(item)) {
|
|
35
|
+
return flattenInteractiveItems(item.children);
|
|
36
|
+
}
|
|
37
|
+
return [item];
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function getFirstEnabledIndex(items) {
|
|
41
|
+
const index = flattenInteractiveItems(items).findIndex((item) => !item.disabled);
|
|
42
|
+
return index === -1 ? null : index;
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
defaultDropdownMaxHeight,
|
|
46
|
+
defaultDropdownMinWidth,
|
|
47
|
+
defaultMenuConfig,
|
|
48
|
+
defaultTrigger,
|
|
49
|
+
getFirstEnabledIndex,
|
|
50
|
+
isDividerItem,
|
|
51
|
+
isFlatMenuItem,
|
|
52
|
+
isGroupItem,
|
|
53
|
+
isSubMenuItem,
|
|
54
|
+
placementMap
|
|
55
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { useContext } from "react";
|
|
3
|
+
import { NewDropdownContext } from "../../contexts/NewDropdownContext.js";
|
|
4
|
+
import { getDividerStyle } from "./Divider.styles.js";
|
|
5
|
+
import { useNewDropdownTokens } from "../../hooks/useNewDropdownTokens/useNewDropdownTokens.js";
|
|
6
|
+
const Divider = () => {
|
|
7
|
+
var _a;
|
|
8
|
+
const {
|
|
9
|
+
styles
|
|
10
|
+
} = useContext(NewDropdownContext);
|
|
11
|
+
const {
|
|
12
|
+
theme,
|
|
13
|
+
tokens
|
|
14
|
+
} = useNewDropdownTokens();
|
|
15
|
+
return /* @__PURE__ */ jsx("li", { css: [getDividerStyle({
|
|
16
|
+
tokens
|
|
17
|
+
}), (_a = styles == null ? void 0 : styles.divider) == null ? void 0 : _a.call(styles, tokens, theme), process.env.NODE_ENV === "production" ? "" : ";label:Divider;", process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9idWlsZHMvZnJvbnRlbmQvbGlicy91aS1raXQvc3JjL2NvbXBvbmVudHMvTmV3RHJvcGRvd24vY29tcG9uZW50cy9EaXZpZGVyL0RpdmlkZXIudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNhIiwiZmlsZSI6Ii9idWlsZHMvZnJvbnRlbmQvbGlicy91aS1raXQvc3JjL2NvbXBvbmVudHMvTmV3RHJvcGRvd24vY29tcG9uZW50cy9EaXZpZGVyL0RpdmlkZXIudHN4Iiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdXNlQ29udGV4dCwgdHlwZSBGQyB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlTmV3RHJvcGRvd25Ub2tlbnMgfSBmcm9tIFwiLi4vLi4vaG9va3MvdXNlTmV3RHJvcGRvd25Ub2tlbnNcIjtcbmltcG9ydCB7IE5ld0Ryb3Bkb3duQ29udGV4dCB9IGZyb20gXCIuLi8uLi9jb250ZXh0cy9OZXdEcm9wZG93bkNvbnRleHRcIjtcbmltcG9ydCB7IGdldERpdmlkZXJTdHlsZSB9IGZyb20gXCIuL0RpdmlkZXIuc3R5bGVzXCI7XG5cbmV4cG9ydCBjb25zdCBEaXZpZGVyOiBGQyA9ICgpID0+IHtcbiAgY29uc3QgeyBzdHlsZXMgfSA9IHVzZUNvbnRleHQoTmV3RHJvcGRvd25Db250ZXh0KTtcbiAgY29uc3QgeyB0aGVtZSwgdG9rZW5zIH0gPSB1c2VOZXdEcm9wZG93blRva2VucygpO1xuXG4gIHJldHVybiA8bGkgY3NzPXtbZ2V0RGl2aWRlclN0eWxlKHsgdG9rZW5zIH0pLCBzdHlsZXM/LmRpdmlkZXI/Lih0b2tlbnMsIHRoZW1lKV19IC8+O1xufTtcbiJdfQ== */"] });
|
|
18
|
+
};
|
|
19
|
+
export {
|
|
20
|
+
Divider
|
|
21
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Interpolation } from '@emotion/react';
|
|
2
|
+
import { NewDropdownTokens } from '../../NewDropdown.tokens';
|
|
3
|
+
/**
|
|
4
|
+
* Стили строки-разделителя `<li>`.
|
|
5
|
+
* Горизонтальная линия на всю ширину: цвет `dropdownItemDivider`, вертикальные отступы — `dropdownItemPaddingVertical`.
|
|
6
|
+
* Не зависит от темы — все значения берутся из component-tokens.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getDividerStyle: ({ tokens }: {
|
|
9
|
+
tokens: NewDropdownTokens;
|
|
10
|
+
}) => Interpolation;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Divider } from './Divider';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsxs, jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { itemIconStyle } from "../MenuItem/MenuItem.styles.js";
|
|
3
|
+
import { Menu } from "../Menu/Menu.js";
|
|
4
|
+
import { groupItemStyle, getGroupHeaderStyle, groupHeaderLabelStyle } from "./GroupItem.styles.js";
|
|
5
|
+
import { useNewDropdownTokens } from "../../hooks/useNewDropdownTokens/useNewDropdownTokens.js";
|
|
6
|
+
const GroupItem = (props) => {
|
|
7
|
+
const {
|
|
8
|
+
item,
|
|
9
|
+
parentKeyPath
|
|
10
|
+
} = props;
|
|
11
|
+
const {
|
|
12
|
+
key,
|
|
13
|
+
label,
|
|
14
|
+
icon,
|
|
15
|
+
children
|
|
16
|
+
} = item;
|
|
17
|
+
const {
|
|
18
|
+
theme,
|
|
19
|
+
tokens
|
|
20
|
+
} = useNewDropdownTokens();
|
|
21
|
+
const hasHeader = Boolean(label || icon);
|
|
22
|
+
const childKeyPath = key ? parentKeyPath ? `${parentKeyPath}.${key}` : key : parentKeyPath;
|
|
23
|
+
return /* @__PURE__ */ jsxs("li", { role: "presentation", css: groupItemStyle(theme), children: [
|
|
24
|
+
hasHeader && /* @__PURE__ */ jsxs("div", { css: getGroupHeaderStyle(tokens)(theme), children: [
|
|
25
|
+
icon && /* @__PURE__ */ jsx("span", { css: itemIconStyle(theme), children: icon }),
|
|
26
|
+
label && /* @__PURE__ */ jsx("span", { css: groupHeaderLabelStyle(theme), children: label })
|
|
27
|
+
] }),
|
|
28
|
+
/* @__PURE__ */ jsx(Menu, { items: children, parentKeyPath: childKeyPath })
|
|
29
|
+
] });
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
GroupItem
|
|
33
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Interpolation } from '@emotion/react';
|
|
2
|
+
import { Theme } from 'themes';
|
|
3
|
+
import { NewDropdownTokens } from '../../NewDropdown.tokens';
|
|
4
|
+
/**
|
|
5
|
+
* Стили корневого `<li role="presentation">` для группы.
|
|
6
|
+
* Сбрасывает маркер списка — остальное наследуется из родительского `<ul>`.
|
|
7
|
+
*
|
|
8
|
+
* `& > ul` — дочерний `<ul>`, рендерится через `<Menu items={children}>`.
|
|
9
|
+
* Специфичность `[0,1,1]` (class + element) > menuListStyle `[0,1,0]` (class),
|
|
10
|
+
* поэтому longhand `paddingInlineStart: theme.x5` (20 px) перебивает shorthand `padding: 0`.
|
|
11
|
+
*
|
|
12
|
+
* inlineIndent = 20 означает, что children должны быть на 20 px ПРАВЕЕ заголовка группы.
|
|
13
|
+
* Заголовок группы имеет `paddingInline: 8 px` (dropdownItemPaddingHorizontal).
|
|
14
|
+
* Children `<li>` тоже имеет `paddingInline: 8 px` от MenuItem.
|
|
15
|
+
* Для дельты 20 px: ul.paddingInlineStart + li.paddingInline = header.paddingInline + 20
|
|
16
|
+
* ul.paddingInlineStart = 8 + 20 - 8 = 20 px = theme.x5.
|
|
17
|
+
*/
|
|
18
|
+
export declare const groupItemStyle: (theme: Theme) => Interpolation;
|
|
19
|
+
/**
|
|
20
|
+
* Стили заголовка группы (не интерактивный блок с label + icon).
|
|
21
|
+
* Цвет `dropdownItemTextTitle` (= `textSecondary`) применяется к тексту и иконке через наследование.
|
|
22
|
+
* Hover-состояние отсутствует (матрица Overview: group → hover: `—`).
|
|
23
|
+
*/
|
|
24
|
+
export declare const getGroupHeaderStyle: (tokens: NewDropdownTokens) => (theme: Theme) => Interpolation;
|
|
25
|
+
/**
|
|
26
|
+
* Стили текстового узла label в заголовке группы.
|
|
27
|
+
* Цвет наследуется из `getGroupHeaderStyle` (= `dropdownItemTextTitle`).
|
|
28
|
+
*/
|
|
29
|
+
export declare const groupHeaderLabelStyle: (theme: Theme) => Interpolation;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const groupItemStyle = (theme) => ({
|
|
2
|
+
listStyle: "none",
|
|
3
|
+
// inlineIndent = 20: children располагаются на 20 px правее заголовка группы (API Menu.inlineIndent = 20).
|
|
4
|
+
// ul.paddingInlineStart = 20 px = theme.x5.
|
|
5
|
+
"& > ul": {
|
|
6
|
+
paddingInlineStart: theme.x5
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
const getGroupHeaderStyle = (tokens) => (theme) => ({
|
|
10
|
+
display: "flex",
|
|
11
|
+
alignItems: "center",
|
|
12
|
+
paddingBlock: tokens.dropdownItemPaddingVertical,
|
|
13
|
+
paddingInline: tokens.dropdownItemPaddingHorizontal,
|
|
14
|
+
gap: theme.marginXS,
|
|
15
|
+
color: tokens.dropdownItemTextTitle,
|
|
16
|
+
cursor: "default",
|
|
17
|
+
userSelect: "none"
|
|
18
|
+
});
|
|
19
|
+
const groupHeaderLabelStyle = (theme) => ({
|
|
20
|
+
...theme.typography.body2,
|
|
21
|
+
overflow: "hidden",
|
|
22
|
+
textOverflow: "ellipsis",
|
|
23
|
+
whiteSpace: "nowrap",
|
|
24
|
+
// flex-reset: позволяет дочернему flex-элементу сжиматься ниже content-size при overflow: hidden
|
|
25
|
+
minWidth: 0
|
|
26
|
+
});
|
|
27
|
+
export {
|
|
28
|
+
getGroupHeaderStyle,
|
|
29
|
+
groupHeaderLabelStyle,
|
|
30
|
+
groupItemStyle
|
|
31
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GroupItem } from './GroupItem';
|