@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.
@@ -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
- export declare const ResetIcon: import("styled-components").StyledComponent<"span", import("styled-components").DefaultTheme, import("../../atoms/Icon").IIconProps, never>;
4
- export declare const Chevron: import("styled-components").StyledComponent<"span", import("styled-components").DefaultTheme, import("../../atoms/Icon").IIconProps & {
5
- isOpen?: boolean | undefined;
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 {};
@@ -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.25rem;
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: ${_ref => {
29808
+ background-color: ${_ref3 => {
29782
29809
  let {
29783
29810
  theme: {
29784
29811
  palette
29785
29812
  }
29786
- } = _ref;
29813
+ } = _ref3;
29787
29814
  return palette.primary;
29788
29815
  }};
29789
- color: ${_ref2 => {
29816
+ color: ${_ref4 => {
29790
29817
  let {
29791
29818
  theme: {
29792
29819
  palette
29793
29820
  }
29794
- } = _ref2;
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
- const ResetIcon = /*#__PURE__*/styled(Icon)`
29802
- width: 0.875rem;
29803
- height: 0.875rem;
29804
- cursor: pointer;
29805
- color: ${_ref3 => {
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
- } = _ref3;
29838
+ } = _ref5;
29811
29839
  return palette.textSecondary;
29812
29840
  }};
29813
29841
 
29814
29842
  &:after {
29815
- font-size: 0.875rem;
29843
+ font-size: 1.125rem;
29816
29844
  }
29845
+ `;
29846
+ /** Компактная управляющая кнопка в инпуте заданного размера (без фикс. ширины и паддингов IconButton). */
29817
29847
 
29818
- &:hover {
29819
- color: ${_ref4 => {
29820
- let {
29821
- theme: {
29822
- palette
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
- const Chevron = /*#__PURE__*/styled(Icon)`
29830
- width: 0.875rem;
29831
- height: 0.875rem;
29832
- cursor: pointer;
29833
- transform: ${_ref5 => {
29834
- let {
29835
- isOpen
29836
- } = _ref5;
29837
- return isOpen ? "rotate(180deg)" : "";
29838
- }};
29839
- transition: transform ${transition.press};
29840
- color: ${_ref6 => {
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: ${_ref8 => {
29920
+ max-height: ${_ref11 => {
29865
29921
  let {
29866
29922
  maxHeight
29867
- } = _ref8;
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: ${_ref9 => {
29959
+ background-color: ${_ref12 => {
29904
29960
  let {
29905
29961
  theme: {
29906
29962
  palette
29907
29963
  }
29908
- } = _ref9;
29964
+ } = _ref12;
29909
29965
  return palette.element;
29910
29966
  }};
29911
- color: ${_ref10 => {
29967
+ color: ${_ref13 => {
29912
29968
  let {
29913
29969
  theme: {
29914
29970
  palette
29915
29971
  }
29916
- } = _ref10;
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 handleReset = useCallback(event => {
30081
- event.stopPropagation();
30082
- onReset == null ? void 0 : onReset();
30083
- }, [onReset]);
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, multiSelect && count > 0 && React.createElement(CountBadge, null, formatCount(count)), count > 0 && onReset && React.createElement(ResetIcon, {
30138
- kind: "close",
30215
+ const iconAfter = React.createElement(FieldIcons, null, count > 0 && onReset && React.createElement(ClearControl, {
30216
+ kind: "error",
30139
30217
  onClick: handleReset
30140
- }), React.createElement(Chevron, {
30141
- kind: "input_dropdown",
30142
- isOpen: open,
30143
- onClick: toggleOpen
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("div", {
30233
+ anchor: React.createElement(AnchorWrap, {
30153
30234
  onClick: toggleOpen
30154
30235
  }, React.createElement(Input$1, {
30155
30236
  readOnly: true,