@evergis/uilib-gl 1.0.115 → 1.0.117
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/organisms/TreeDropdown/styled.d.ts +13 -4
- package/dist/organisms/TreeDropdown/types.d.ts +4 -0
- package/dist/organisms/TreeDropdown/useTreeDropdown.d.ts +4 -1
- package/dist/organisms/TreeDropdown/useTreeDropdownActions.d.ts +9 -0
- package/dist/uilib-gl.esm.js +134 -53
- package/dist/uilib-gl.esm.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
/**
|
|
3
|
+
* Обёртка инпута-якоря: даёт полю собственный фон (сам `Input` прозрачен — `background: transparent`
|
|
4
|
+
* в `inputMixin`), а `inline-flex` + `align-self` не дают обёртке растягиваться во flex-контейнере,
|
|
5
|
+
* иначе Popover (`anchorOrigin="bottom-left"`) уводит меню к низу растянутого якоря.
|
|
6
|
+
*/
|
|
7
|
+
export declare const AnchorWrap: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, {}, never>;
|
|
1
8
|
export declare const FieldIcons: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, import("../../atoms/Grid").FlexProps, never>;
|
|
2
9
|
export declare const CountBadge: import("styled-components").StyledComponent<"span", import("styled-components").DefaultTheme, {}, never>;
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
5
|
-
|
|
6
|
-
}, never>;
|
|
10
|
+
/** Иконка свёрнутого состояния без выбора (справа в инпуте). */
|
|
11
|
+
export declare const TreeIcon: import("styled-components").StyledComponent<"span", import("styled-components").DefaultTheme, import("../../atoms/Icon").IIconProps, never>;
|
|
12
|
+
/** Кнопка «применить» (success). */
|
|
13
|
+
export declare const SuccessControl: import("styled-components").StyledComponent<import("react").FC<import("../../molecules/IconButton").IIconButtonProps>, import("styled-components").DefaultTheme, {}, never>;
|
|
14
|
+
/** Кнопка «очистить» (error) — цвет как на макете (приглушённый серый). */
|
|
15
|
+
export declare const ClearControl: import("styled-components").StyledComponent<import("react").FC<import("../../molecules/IconButton").IIconButtonProps>, import("styled-components").DefaultTheme, {}, never>;
|
|
7
16
|
export declare const Content: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, {
|
|
8
17
|
width?: string | undefined;
|
|
9
18
|
}, never>;
|
|
@@ -21,6 +21,10 @@ export interface ITreeDropdownProps {
|
|
|
21
21
|
onClose?: VoidFunction;
|
|
22
22
|
onToggleSelect: (item: TreeItemProps) => void;
|
|
23
23
|
onReset?: VoidFunction;
|
|
24
|
+
/** Выбор изменён с момента последнего сохранения — активирует кнопку «применить» (success, primary). */
|
|
25
|
+
dirty?: boolean;
|
|
26
|
+
/** Применить текущий выбор (сохранить фильтр) — клик по кнопке success. */
|
|
27
|
+
onSave?: VoidFunction;
|
|
24
28
|
}
|
|
25
29
|
export interface ITreeDropdownContextValue {
|
|
26
30
|
selectedIds: Set<TreeId>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ChangeEvent } from "react";
|
|
2
2
|
import { ITreeDropdownProps } from "./types";
|
|
3
|
-
export declare const useTreeDropdown: ({ multiSelect, selectedIds, selectedCount, selectedLabel, searchValue, onOpen, onClose, onToggleSelect, onReset, onSearchChange, }: ITreeDropdownProps) => {
|
|
3
|
+
export declare const useTreeDropdown: ({ multiSelect, selectedIds, selectedCount, selectedLabel, searchValue, onOpen, onClose, onToggleSelect, onReset, onSave, onSearchChange, }: ITreeDropdownProps) => {
|
|
4
4
|
open: boolean;
|
|
5
5
|
openDropdown: () => void;
|
|
6
6
|
closeDropdown: () => void;
|
|
@@ -8,6 +8,9 @@ export declare const useTreeDropdown: ({ multiSelect, selectedIds, selectedCount
|
|
|
8
8
|
handleReset: (event: {
|
|
9
9
|
stopPropagation: VoidFunction;
|
|
10
10
|
}) => void;
|
|
11
|
+
handleSave: (event: {
|
|
12
|
+
stopPropagation: VoidFunction;
|
|
13
|
+
}) => void;
|
|
11
14
|
contextValue: import("./types").ITreeDropdownContextValue;
|
|
12
15
|
count: number;
|
|
13
16
|
displayValue: string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare type StopEvent = {
|
|
2
|
+
stopPropagation: VoidFunction;
|
|
3
|
+
};
|
|
4
|
+
/** Обработчики управляющих кнопок инпута: очистка (error) и применение выбора (success). */
|
|
5
|
+
export declare const useTreeDropdownActions: (closeDropdown: VoidFunction, onReset?: VoidFunction | undefined, onSave?: VoidFunction | undefined) => {
|
|
6
|
+
handleReset: (event: StopEvent) => void;
|
|
7
|
+
handleSave: (event: StopEvent) => void;
|
|
8
|
+
};
|
|
9
|
+
export {};
|
package/dist/uilib-gl.esm.js
CHANGED
|
@@ -29760,13 +29760,40 @@ const TreeComponent = _ref => {
|
|
|
29760
29760
|
|
|
29761
29761
|
const Tree = /*#__PURE__*/memo(TreeComponent);
|
|
29762
29762
|
|
|
29763
|
+
/**
|
|
29764
|
+
* Обёртка инпута-якоря: даёт полю собственный фон (сам `Input` прозрачен — `background: transparent`
|
|
29765
|
+
* в `inputMixin`), а `inline-flex` + `align-self` не дают обёртке растягиваться во flex-контейнере,
|
|
29766
|
+
* иначе Popover (`anchorOrigin="bottom-left"`) уводит меню к низу растянутого якоря.
|
|
29767
|
+
*/
|
|
29768
|
+
|
|
29769
|
+
const AnchorWrap = styled.div`
|
|
29770
|
+
display: inline-flex;
|
|
29771
|
+
align-self: flex-start;
|
|
29772
|
+
width: max-content;
|
|
29773
|
+
background-color: ${_ref => {
|
|
29774
|
+
let {
|
|
29775
|
+
theme: {
|
|
29776
|
+
palette
|
|
29777
|
+
}
|
|
29778
|
+
} = _ref;
|
|
29779
|
+
return palette.background;
|
|
29780
|
+
}};
|
|
29781
|
+
border-radius: ${_ref2 => {
|
|
29782
|
+
let {
|
|
29783
|
+
theme: {
|
|
29784
|
+
borderRadius
|
|
29785
|
+
}
|
|
29786
|
+
} = _ref2;
|
|
29787
|
+
return borderRadius.medium;
|
|
29788
|
+
}};
|
|
29789
|
+
`;
|
|
29763
29790
|
const FieldIcons = /*#__PURE__*/styled(Flex)`
|
|
29764
29791
|
position: absolute;
|
|
29765
29792
|
top: 50%;
|
|
29766
29793
|
right: 0.5rem;
|
|
29767
29794
|
transform: translateY(-50%);
|
|
29768
29795
|
align-items: center;
|
|
29769
|
-
gap: 0.
|
|
29796
|
+
gap: 0.5rem;
|
|
29770
29797
|
width: max-content;
|
|
29771
29798
|
white-space: nowrap;
|
|
29772
29799
|
`;
|
|
@@ -29778,66 +29805,74 @@ const CountBadge = styled.span`
|
|
|
29778
29805
|
height: 1rem;
|
|
29779
29806
|
padding: 0;
|
|
29780
29807
|
border-radius: 0.5rem;
|
|
29781
|
-
background-color: ${
|
|
29808
|
+
background-color: ${_ref3 => {
|
|
29782
29809
|
let {
|
|
29783
29810
|
theme: {
|
|
29784
29811
|
palette
|
|
29785
29812
|
}
|
|
29786
|
-
} =
|
|
29813
|
+
} = _ref3;
|
|
29787
29814
|
return palette.primary;
|
|
29788
29815
|
}};
|
|
29789
|
-
color: ${
|
|
29816
|
+
color: ${_ref4 => {
|
|
29790
29817
|
let {
|
|
29791
29818
|
theme: {
|
|
29792
29819
|
palette
|
|
29793
29820
|
}
|
|
29794
|
-
} =
|
|
29821
|
+
} = _ref4;
|
|
29795
29822
|
return palette.background;
|
|
29796
29823
|
}};
|
|
29797
29824
|
font-size: 0.625rem;
|
|
29798
29825
|
font-weight: 600;
|
|
29799
29826
|
line-height: 1;
|
|
29800
29827
|
`;
|
|
29801
|
-
|
|
29802
|
-
|
|
29803
|
-
|
|
29804
|
-
|
|
29805
|
-
|
|
29828
|
+
/** Иконка свёрнутого состояния без выбора (справа в инпуте). */
|
|
29829
|
+
|
|
29830
|
+
const TreeIcon = /*#__PURE__*/styled(Icon)`
|
|
29831
|
+
width: 1.125rem;
|
|
29832
|
+
height: 1.125rem;
|
|
29833
|
+
color: ${_ref5 => {
|
|
29806
29834
|
let {
|
|
29807
29835
|
theme: {
|
|
29808
29836
|
palette
|
|
29809
29837
|
}
|
|
29810
|
-
} =
|
|
29838
|
+
} = _ref5;
|
|
29811
29839
|
return palette.textSecondary;
|
|
29812
29840
|
}};
|
|
29813
29841
|
|
|
29814
29842
|
&:after {
|
|
29815
|
-
font-size:
|
|
29843
|
+
font-size: 1.125rem;
|
|
29816
29844
|
}
|
|
29845
|
+
`;
|
|
29846
|
+
/** Компактная управляющая кнопка в инпуте заданного размера (без фикс. ширины и паддингов IconButton). */
|
|
29817
29847
|
|
|
29818
|
-
|
|
29819
|
-
|
|
29820
|
-
|
|
29821
|
-
|
|
29822
|
-
|
|
29848
|
+
const controlButton = size => css`
|
|
29849
|
+
width: auto;
|
|
29850
|
+
height: ${size};
|
|
29851
|
+
min-width: 0;
|
|
29852
|
+
padding: 0;
|
|
29853
|
+
|
|
29854
|
+
${Icon} {
|
|
29855
|
+
width: ${size};
|
|
29856
|
+
height: ${size};
|
|
29857
|
+
|
|
29858
|
+
&:after {
|
|
29859
|
+
font-size: ${size};
|
|
29823
29860
|
}
|
|
29824
|
-
} = _ref4;
|
|
29825
|
-
return palette.textPrimary;
|
|
29826
|
-
}};
|
|
29827
29861
|
}
|
|
29828
29862
|
`;
|
|
29829
|
-
|
|
29830
|
-
|
|
29831
|
-
|
|
29832
|
-
|
|
29833
|
-
|
|
29834
|
-
|
|
29835
|
-
|
|
29836
|
-
|
|
29837
|
-
|
|
29838
|
-
}
|
|
29839
|
-
|
|
29840
|
-
|
|
29863
|
+
/** Кнопка «применить» (success). */
|
|
29864
|
+
|
|
29865
|
+
|
|
29866
|
+
const SuccessControl = /*#__PURE__*/styled(IconButton)`
|
|
29867
|
+
${/*#__PURE__*/controlButton("1rem")};
|
|
29868
|
+
`;
|
|
29869
|
+
/** Кнопка «очистить» (error) — цвет как на макете (приглушённый серый). */
|
|
29870
|
+
|
|
29871
|
+
const ClearControl = /*#__PURE__*/styled(IconButton)`
|
|
29872
|
+
${/*#__PURE__*/controlButton("0.75rem")};
|
|
29873
|
+
|
|
29874
|
+
${Icon} {
|
|
29875
|
+
color: ${_ref6 => {
|
|
29841
29876
|
let {
|
|
29842
29877
|
theme: {
|
|
29843
29878
|
palette
|
|
@@ -29845,9 +29880,6 @@ const Chevron = /*#__PURE__*/styled(Icon)`
|
|
|
29845
29880
|
} = _ref6;
|
|
29846
29881
|
return palette.textSecondary;
|
|
29847
29882
|
}};
|
|
29848
|
-
|
|
29849
|
-
&:after {
|
|
29850
|
-
font-size: 0.875rem;
|
|
29851
29883
|
}
|
|
29852
29884
|
`;
|
|
29853
29885
|
const Content = styled.div`
|
|
@@ -29859,12 +29891,36 @@ const Content = styled.div`
|
|
|
29859
29891
|
}};
|
|
29860
29892
|
padding: 0.5rem;
|
|
29861
29893
|
box-sizing: border-box;
|
|
29894
|
+
background-color: ${_ref8 => {
|
|
29895
|
+
let {
|
|
29896
|
+
theme: {
|
|
29897
|
+
palette
|
|
29898
|
+
}
|
|
29899
|
+
} = _ref8;
|
|
29900
|
+
return palette.background;
|
|
29901
|
+
}};
|
|
29902
|
+
border-radius: ${_ref9 => {
|
|
29903
|
+
let {
|
|
29904
|
+
theme: {
|
|
29905
|
+
borderRadius
|
|
29906
|
+
}
|
|
29907
|
+
} = _ref9;
|
|
29908
|
+
return borderRadius.medium;
|
|
29909
|
+
}};
|
|
29910
|
+
box-shadow: ${_ref10 => {
|
|
29911
|
+
let {
|
|
29912
|
+
theme: {
|
|
29913
|
+
shadows
|
|
29914
|
+
}
|
|
29915
|
+
} = _ref10;
|
|
29916
|
+
return shadows.raised;
|
|
29917
|
+
}};
|
|
29862
29918
|
`;
|
|
29863
29919
|
const TreeScroll = styled.div`
|
|
29864
|
-
max-height: ${
|
|
29920
|
+
max-height: ${_ref11 => {
|
|
29865
29921
|
let {
|
|
29866
29922
|
maxHeight
|
|
29867
|
-
} =
|
|
29923
|
+
} = _ref11;
|
|
29868
29924
|
return maxHeight || "15rem";
|
|
29869
29925
|
}};
|
|
29870
29926
|
overflow-y: auto;
|
|
@@ -29900,20 +29956,20 @@ const ItemBadge = styled.span`
|
|
|
29900
29956
|
margin-left: 0.25rem;
|
|
29901
29957
|
padding: 0;
|
|
29902
29958
|
border-radius: 0.5rem;
|
|
29903
|
-
background-color: ${
|
|
29959
|
+
background-color: ${_ref12 => {
|
|
29904
29960
|
let {
|
|
29905
29961
|
theme: {
|
|
29906
29962
|
palette
|
|
29907
29963
|
}
|
|
29908
|
-
} =
|
|
29964
|
+
} = _ref12;
|
|
29909
29965
|
return palette.element;
|
|
29910
29966
|
}};
|
|
29911
|
-
color: ${
|
|
29967
|
+
color: ${_ref13 => {
|
|
29912
29968
|
let {
|
|
29913
29969
|
theme: {
|
|
29914
29970
|
palette
|
|
29915
29971
|
}
|
|
29916
|
-
} =
|
|
29972
|
+
} = _ref13;
|
|
29917
29973
|
return palette.textSecondary;
|
|
29918
29974
|
}};
|
|
29919
29975
|
font-size: 0.625rem;
|
|
@@ -30000,6 +30056,24 @@ const TreeDropdownItemComponent = _ref => {
|
|
|
30000
30056
|
|
|
30001
30057
|
const TreeDropdownItem = /*#__PURE__*/memo(TreeDropdownItemComponent);
|
|
30002
30058
|
|
|
30059
|
+
/** Обработчики управляющих кнопок инпута: очистка (error) и применение выбора (success). */
|
|
30060
|
+
|
|
30061
|
+
const useTreeDropdownActions = (closeDropdown, onReset, onSave) => {
|
|
30062
|
+
const handleReset = useCallback(event => {
|
|
30063
|
+
event.stopPropagation();
|
|
30064
|
+
onReset == null ? void 0 : onReset();
|
|
30065
|
+
}, [onReset]);
|
|
30066
|
+
const handleSave = useCallback(event => {
|
|
30067
|
+
event.stopPropagation();
|
|
30068
|
+
onSave == null ? void 0 : onSave();
|
|
30069
|
+
closeDropdown();
|
|
30070
|
+
}, [onSave, closeDropdown]);
|
|
30071
|
+
return {
|
|
30072
|
+
handleReset,
|
|
30073
|
+
handleSave
|
|
30074
|
+
};
|
|
30075
|
+
};
|
|
30076
|
+
|
|
30003
30077
|
const useTreeDropdownOpen = (onOpen, onClose) => {
|
|
30004
30078
|
const [open, setOpen] = useState(false);
|
|
30005
30079
|
const openDropdown = useCallback(() => {
|
|
@@ -30068,6 +30142,7 @@ const useTreeDropdown = _ref => {
|
|
|
30068
30142
|
onClose,
|
|
30069
30143
|
onToggleSelect,
|
|
30070
30144
|
onReset,
|
|
30145
|
+
onSave,
|
|
30071
30146
|
onSearchChange
|
|
30072
30147
|
} = _ref;
|
|
30073
30148
|
const {
|
|
@@ -30077,10 +30152,10 @@ const useTreeDropdown = _ref => {
|
|
|
30077
30152
|
toggleOpen
|
|
30078
30153
|
} = useTreeDropdownOpen(onOpen, onClose);
|
|
30079
30154
|
const contextValue = useTreeDropdownSelection(selectedIds, onToggleSelect, closeDropdown, multiSelect);
|
|
30080
|
-
const
|
|
30081
|
-
|
|
30082
|
-
|
|
30083
|
-
},
|
|
30155
|
+
const {
|
|
30156
|
+
handleReset,
|
|
30157
|
+
handleSave
|
|
30158
|
+
} = useTreeDropdownActions(closeDropdown, onReset, onSave);
|
|
30084
30159
|
const count = selectedCount ?? selectedIds.size;
|
|
30085
30160
|
const displayValue = useMemo(() => open ? searchValue : multiSelect ? "" : selectedLabel ?? "", [open, searchValue, multiSelect, selectedLabel]);
|
|
30086
30161
|
const onInputChange = useCallback(event => {
|
|
@@ -30093,6 +30168,7 @@ const useTreeDropdown = _ref => {
|
|
|
30093
30168
|
closeDropdown,
|
|
30094
30169
|
toggleOpen,
|
|
30095
30170
|
handleReset,
|
|
30171
|
+
handleSave,
|
|
30096
30172
|
contextValue,
|
|
30097
30173
|
count,
|
|
30098
30174
|
displayValue,
|
|
@@ -30122,25 +30198,30 @@ const TreeDropdownComponent = props => {
|
|
|
30122
30198
|
expanded,
|
|
30123
30199
|
setExpanded,
|
|
30124
30200
|
onLoadChildren,
|
|
30125
|
-
onReset
|
|
30201
|
+
onReset,
|
|
30202
|
+
dirty
|
|
30126
30203
|
} = props;
|
|
30127
30204
|
const {
|
|
30128
30205
|
open,
|
|
30129
30206
|
closeDropdown,
|
|
30130
30207
|
toggleOpen,
|
|
30131
30208
|
handleReset,
|
|
30209
|
+
handleSave,
|
|
30132
30210
|
contextValue,
|
|
30133
30211
|
count,
|
|
30134
30212
|
displayValue,
|
|
30135
30213
|
onInputChange
|
|
30136
30214
|
} = useTreeDropdown(props);
|
|
30137
|
-
const iconAfter = React.createElement(FieldIcons, null,
|
|
30138
|
-
kind: "
|
|
30215
|
+
const iconAfter = React.createElement(FieldIcons, null, count > 0 && onReset && React.createElement(ClearControl, {
|
|
30216
|
+
kind: "error",
|
|
30139
30217
|
onClick: handleReset
|
|
30140
|
-
}), React.createElement(
|
|
30141
|
-
kind: "
|
|
30142
|
-
|
|
30143
|
-
|
|
30218
|
+
}), multiSelect && count > 0 && React.createElement(CountBadge, null, formatCount(count)), open && React.createElement(SuccessControl, {
|
|
30219
|
+
kind: "success",
|
|
30220
|
+
primary: dirty,
|
|
30221
|
+
disabled: !dirty,
|
|
30222
|
+
onClick: handleSave
|
|
30223
|
+
}), !open && count === 0 && React.createElement(TreeIcon, {
|
|
30224
|
+
kind: "tree_vertical"
|
|
30144
30225
|
}));
|
|
30145
30226
|
return React.createElement(Popover, {
|
|
30146
30227
|
open: open,
|
|
@@ -30149,7 +30230,7 @@ const TreeDropdownComponent = props => {
|
|
|
30149
30230
|
targetOrigin: "top-left",
|
|
30150
30231
|
animateX: false,
|
|
30151
30232
|
zIndex: zIndex,
|
|
30152
|
-
anchor: React.createElement(
|
|
30233
|
+
anchor: React.createElement(AnchorWrap, {
|
|
30153
30234
|
onClick: toggleOpen
|
|
30154
30235
|
}, React.createElement(Input$1, {
|
|
30155
30236
|
readOnly: true,
|