@evergis/uilib-gl 1.0.116 → 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,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  /**
2
3
  * Обёртка инпута-якоря: даёт полю собственный фон (сам `Input` прозрачен — `background: transparent`
3
4
  * в `inputMixin`), а `inline-flex` + `align-self` не дают обёртке растягиваться во flex-контейнере,
@@ -6,10 +7,12 @@
6
7
  export declare const AnchorWrap: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, {}, never>;
7
8
  export declare const FieldIcons: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, import("../../atoms/Grid").FlexProps, never>;
8
9
  export declare const CountBadge: import("styled-components").StyledComponent<"span", import("styled-components").DefaultTheme, {}, never>;
9
- export declare const ResetIcon: import("styled-components").StyledComponent<"span", import("styled-components").DefaultTheme, import("../../atoms/Icon").IIconProps, never>;
10
- export declare const Chevron: import("styled-components").StyledComponent<"span", import("styled-components").DefaultTheme, import("../../atoms/Icon").IIconProps & {
11
- isOpen?: boolean | undefined;
12
- }, 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>;
13
16
  export declare const Content: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, {
14
17
  width?: string | undefined;
15
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 {};
@@ -29793,7 +29793,7 @@ const FieldIcons = /*#__PURE__*/styled(Flex)`
29793
29793
  right: 0.5rem;
29794
29794
  transform: translateY(-50%);
29795
29795
  align-items: center;
29796
- gap: 0.25rem;
29796
+ gap: 0.5rem;
29797
29797
  width: max-content;
29798
29798
  white-space: nowrap;
29799
29799
  `;
@@ -29825,10 +29825,11 @@ const CountBadge = styled.span`
29825
29825
  font-weight: 600;
29826
29826
  line-height: 1;
29827
29827
  `;
29828
- const ResetIcon = /*#__PURE__*/styled(Icon)`
29829
- width: 0.875rem;
29830
- height: 0.875rem;
29831
- cursor: pointer;
29828
+ /** Иконка свёрнутого состояния без выбора (справа в инпуте). */
29829
+
29830
+ const TreeIcon = /*#__PURE__*/styled(Icon)`
29831
+ width: 1.125rem;
29832
+ height: 1.125rem;
29832
29833
  color: ${_ref5 => {
29833
29834
  let {
29834
29835
  theme: {
@@ -29839,83 +29840,87 @@ const ResetIcon = /*#__PURE__*/styled(Icon)`
29839
29840
  }};
29840
29841
 
29841
29842
  &:after {
29842
- font-size: 0.875rem;
29843
+ font-size: 1.125rem;
29843
29844
  }
29845
+ `;
29846
+ /** Компактная управляющая кнопка в инпуте заданного размера (без фикс. ширины и паддингов IconButton). */
29844
29847
 
29845
- &:hover {
29846
- color: ${_ref6 => {
29847
- let {
29848
- theme: {
29849
- 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};
29850
29860
  }
29851
- } = _ref6;
29852
- return palette.textPrimary;
29853
- }};
29854
29861
  }
29855
29862
  `;
29856
- const Chevron = /*#__PURE__*/styled(Icon)`
29857
- width: 0.875rem;
29858
- height: 0.875rem;
29859
- cursor: pointer;
29860
- transform: ${_ref7 => {
29861
- let {
29862
- isOpen
29863
- } = _ref7;
29864
- return isOpen ? "rotate(180deg)" : "";
29865
- }};
29866
- transition: transform ${transition.press};
29867
- color: ${_ref8 => {
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 => {
29868
29876
  let {
29869
29877
  theme: {
29870
29878
  palette
29871
29879
  }
29872
- } = _ref8;
29880
+ } = _ref6;
29873
29881
  return palette.textSecondary;
29874
29882
  }};
29875
-
29876
- &:after {
29877
- font-size: 0.875rem;
29878
29883
  }
29879
29884
  `;
29880
29885
  const Content = styled.div`
29881
- width: ${_ref9 => {
29886
+ width: ${_ref7 => {
29882
29887
  let {
29883
29888
  width
29884
- } = _ref9;
29889
+ } = _ref7;
29885
29890
  return width || "auto";
29886
29891
  }};
29887
29892
  padding: 0.5rem;
29888
29893
  box-sizing: border-box;
29889
- background-color: ${_ref10 => {
29894
+ background-color: ${_ref8 => {
29890
29895
  let {
29891
29896
  theme: {
29892
29897
  palette
29893
29898
  }
29894
- } = _ref10;
29899
+ } = _ref8;
29895
29900
  return palette.background;
29896
29901
  }};
29897
- border-radius: ${_ref11 => {
29902
+ border-radius: ${_ref9 => {
29898
29903
  let {
29899
29904
  theme: {
29900
29905
  borderRadius
29901
29906
  }
29902
- } = _ref11;
29907
+ } = _ref9;
29903
29908
  return borderRadius.medium;
29904
29909
  }};
29905
- box-shadow: ${_ref12 => {
29910
+ box-shadow: ${_ref10 => {
29906
29911
  let {
29907
29912
  theme: {
29908
29913
  shadows
29909
29914
  }
29910
- } = _ref12;
29915
+ } = _ref10;
29911
29916
  return shadows.raised;
29912
29917
  }};
29913
29918
  `;
29914
29919
  const TreeScroll = styled.div`
29915
- max-height: ${_ref13 => {
29920
+ max-height: ${_ref11 => {
29916
29921
  let {
29917
29922
  maxHeight
29918
- } = _ref13;
29923
+ } = _ref11;
29919
29924
  return maxHeight || "15rem";
29920
29925
  }};
29921
29926
  overflow-y: auto;
@@ -29951,20 +29956,20 @@ const ItemBadge = styled.span`
29951
29956
  margin-left: 0.25rem;
29952
29957
  padding: 0;
29953
29958
  border-radius: 0.5rem;
29954
- background-color: ${_ref14 => {
29959
+ background-color: ${_ref12 => {
29955
29960
  let {
29956
29961
  theme: {
29957
29962
  palette
29958
29963
  }
29959
- } = _ref14;
29964
+ } = _ref12;
29960
29965
  return palette.element;
29961
29966
  }};
29962
- color: ${_ref15 => {
29967
+ color: ${_ref13 => {
29963
29968
  let {
29964
29969
  theme: {
29965
29970
  palette
29966
29971
  }
29967
- } = _ref15;
29972
+ } = _ref13;
29968
29973
  return palette.textSecondary;
29969
29974
  }};
29970
29975
  font-size: 0.625rem;
@@ -30051,6 +30056,24 @@ const TreeDropdownItemComponent = _ref => {
30051
30056
 
30052
30057
  const TreeDropdownItem = /*#__PURE__*/memo(TreeDropdownItemComponent);
30053
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
+
30054
30077
  const useTreeDropdownOpen = (onOpen, onClose) => {
30055
30078
  const [open, setOpen] = useState(false);
30056
30079
  const openDropdown = useCallback(() => {
@@ -30119,6 +30142,7 @@ const useTreeDropdown = _ref => {
30119
30142
  onClose,
30120
30143
  onToggleSelect,
30121
30144
  onReset,
30145
+ onSave,
30122
30146
  onSearchChange
30123
30147
  } = _ref;
30124
30148
  const {
@@ -30128,10 +30152,10 @@ const useTreeDropdown = _ref => {
30128
30152
  toggleOpen
30129
30153
  } = useTreeDropdownOpen(onOpen, onClose);
30130
30154
  const contextValue = useTreeDropdownSelection(selectedIds, onToggleSelect, closeDropdown, multiSelect);
30131
- const handleReset = useCallback(event => {
30132
- event.stopPropagation();
30133
- onReset == null ? void 0 : onReset();
30134
- }, [onReset]);
30155
+ const {
30156
+ handleReset,
30157
+ handleSave
30158
+ } = useTreeDropdownActions(closeDropdown, onReset, onSave);
30135
30159
  const count = selectedCount ?? selectedIds.size;
30136
30160
  const displayValue = useMemo(() => open ? searchValue : multiSelect ? "" : selectedLabel ?? "", [open, searchValue, multiSelect, selectedLabel]);
30137
30161
  const onInputChange = useCallback(event => {
@@ -30144,6 +30168,7 @@ const useTreeDropdown = _ref => {
30144
30168
  closeDropdown,
30145
30169
  toggleOpen,
30146
30170
  handleReset,
30171
+ handleSave,
30147
30172
  contextValue,
30148
30173
  count,
30149
30174
  displayValue,
@@ -30173,25 +30198,30 @@ const TreeDropdownComponent = props => {
30173
30198
  expanded,
30174
30199
  setExpanded,
30175
30200
  onLoadChildren,
30176
- onReset
30201
+ onReset,
30202
+ dirty
30177
30203
  } = props;
30178
30204
  const {
30179
30205
  open,
30180
30206
  closeDropdown,
30181
30207
  toggleOpen,
30182
30208
  handleReset,
30209
+ handleSave,
30183
30210
  contextValue,
30184
30211
  count,
30185
30212
  displayValue,
30186
30213
  onInputChange
30187
30214
  } = useTreeDropdown(props);
30188
- const iconAfter = React.createElement(FieldIcons, null, multiSelect && count > 0 && React.createElement(CountBadge, null, formatCount(count)), count > 0 && onReset && React.createElement(ResetIcon, {
30189
- kind: "close",
30215
+ const iconAfter = React.createElement(FieldIcons, null, count > 0 && onReset && React.createElement(ClearControl, {
30216
+ kind: "error",
30190
30217
  onClick: handleReset
30191
- }), React.createElement(Chevron, {
30192
- kind: "input_dropdown",
30193
- isOpen: open,
30194
- 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"
30195
30225
  }));
30196
30226
  return React.createElement(Popover, {
30197
30227
  open: open,