@fibery/ui-kit 1.36.2 → 1.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/package.json +8 -5
  3. package/src/action-badge.tsx +5 -4
  4. package/src/actions-menu/actions-menu-confirmation.tsx +1 -12
  5. package/src/actions-menu/actions-menu-item.tsx +19 -7
  6. package/src/actions-menu/actions-menu-props.tsx +4 -0
  7. package/src/actions-menu/actions-menu-sub-command-menu.tsx +7 -4
  8. package/src/actions-menu/actions-menu-sub-menu.tsx +9 -3
  9. package/src/actions-menu/actions-menu.tsx +24 -8
  10. package/src/actions-panel.tsx +12 -2
  11. package/src/antd/ant-modal.tsx +17 -2
  12. package/src/antd/input.tsx +4 -3
  13. package/src/app-icon-with-fallback.tsx +5 -8
  14. package/src/app-icon-wrapper.tsx +4 -4
  15. package/src/appIcons.json +20 -0
  16. package/src/axis-header.tsx +136 -76
  17. package/src/badge.tsx +14 -7
  18. package/src/beta-badge.tsx +12 -8
  19. package/src/box.tsx +1 -1
  20. package/src/breadcrumb.tsx +78 -0
  21. package/src/button/actions-button-compact.tsx +5 -2
  22. package/src/button/base-button.tsx +7 -4
  23. package/src/button/button-group.tsx +1 -1
  24. package/src/button/button.tsx +120 -2
  25. package/src/button/icon-button.tsx +13 -2
  26. package/src/button/select-button.tsx +27 -8
  27. package/src/card-container.tsx +36 -69
  28. package/src/card-hidden-link.tsx +52 -0
  29. package/src/collapsible-section.tsx +13 -3
  30. package/src/color-picker/index.js +65 -60
  31. package/src/color-picker/swatch.tsx +29 -14
  32. package/src/command-menu/index.tsx +5 -5
  33. package/src/context-menu/index.tsx +10 -1
  34. package/src/count-badge.tsx +57 -0
  35. package/src/date-picker/date-range-input.tsx +1 -1
  36. package/src/date-picker/date-range-picker.tsx +6 -3
  37. package/src/date-picker/fake-date-input.tsx +1 -1
  38. package/src/date-picker/relative-date-picker.tsx +7 -3
  39. package/src/date-picker/single-date-input.tsx +1 -1
  40. package/src/date-picker/single-date-picker.tsx +8 -5
  41. package/src/date-picker/styles.ts +32 -26
  42. package/src/date-picker/types.ts +3 -1
  43. package/src/date-picker/utils.ts +9 -2
  44. package/src/day-select/day-select.tsx +21 -75
  45. package/src/day-select/iso-week-day-select.tsx +1 -1
  46. package/src/day-select/mount-day-select.tsx +2 -2
  47. package/src/day-select/week-day-select.tsx +1 -5
  48. package/src/design-system.ts +91 -51
  49. package/src/dropdown-menu/index.tsx +8 -1
  50. package/src/emoji-picker/app-icon-picker.tsx +6 -4
  51. package/src/emoji-picker/emoji-picker-content-with-color.tsx +3 -9
  52. package/src/emoji-picker/emoji-picker-preview-footer.tsx +1 -1
  53. package/src/emoji-picker/emoji-picker.tsx +3 -0
  54. package/src/emoji-picker/emoji.tsx +2 -1
  55. package/src/emoji-picker/icon-emoji-picker.tsx +83 -68
  56. package/src/emoji-picker/primitives/footer.tsx +0 -1
  57. package/src/emoji-picker/primitives/header.tsx +1 -0
  58. package/src/emoji-picker/primitives/search.tsx +12 -13
  59. package/src/emoji-picker/primitives/skin-tone.tsx +1 -0
  60. package/src/emoji-picker/use-responsive-emoji-size.ts +11 -0
  61. package/src/emoji-picker/utils/emoji-set.ts +2 -1
  62. package/src/empty-state/empty-state.tsx +6 -0
  63. package/src/error-alert/error-alert.tsx +19 -7
  64. package/src/field-app-icon.tsx +29 -0
  65. package/src/field-container.tsx +4 -2
  66. package/src/field-icon.tsx +29 -0
  67. package/src/field-type-icon.tsx +82 -0
  68. package/src/file-item.tsx +164 -47
  69. package/src/guide-link.tsx +4 -3
  70. package/src/hint.tsx +10 -1
  71. package/src/html-styles.ts +23 -13
  72. package/src/icons/ast/ActivityFilled.ts +8 -0
  73. package/src/icons/ast/AiAssistantFilled.ts +8 -0
  74. package/src/icons/ast/AiFiberyBuild.ts +8 -0
  75. package/src/icons/ast/Anthropic.ts +1 -1
  76. package/src/icons/ast/Apple.ts +8 -0
  77. package/src/icons/ast/ArrowBottom.ts +1 -1
  78. package/src/icons/ast/ArrowForward.ts +1 -1
  79. package/src/icons/ast/ArrowLeft.ts +1 -1
  80. package/src/icons/ast/ArrowRight.ts +1 -1
  81. package/src/icons/ast/ArrowTop.ts +1 -1
  82. package/src/icons/ast/CollapseAllHorizontal.ts +8 -0
  83. package/src/icons/ast/Crosshair.ts +8 -0
  84. package/src/icons/ast/DateRange.ts +1 -1
  85. package/src/icons/ast/Document.ts +8 -0
  86. package/src/icons/ast/EntityCreate.ts +8 -0
  87. package/src/icons/ast/EntityCreateFilled.ts +8 -0
  88. package/src/icons/ast/ExpandAll.ts +8 -0
  89. package/src/icons/ast/ExpandAllHorizontal.ts +8 -0
  90. package/src/icons/ast/FiberyDesktopApp.ts +8 -0
  91. package/src/icons/ast/FileDownload.ts +8 -0
  92. package/src/icons/ast/GlobeUnpublish.ts +8 -0
  93. package/src/icons/ast/GraduationCapFilled.ts +8 -0
  94. package/src/icons/ast/Home.ts +1 -1
  95. package/src/icons/ast/HomeFilled.ts +8 -0
  96. package/src/icons/ast/ImportFilled.ts +8 -0
  97. package/src/icons/ast/IntegrationsFilled.ts +8 -0
  98. package/src/icons/ast/KeyboardHideDown.ts +8 -0
  99. package/src/icons/ast/LayoutMultiple.ts +8 -0
  100. package/src/icons/ast/LocationEdit.ts +8 -0
  101. package/src/icons/ast/MessagePlus.ts +8 -0
  102. package/src/icons/ast/OpenAi.ts +1 -1
  103. package/src/icons/ast/RicheditorHistoryRedo.ts +1 -1
  104. package/src/icons/ast/RicheditorHistoryUndo.ts +1 -1
  105. package/src/icons/ast/RicheditorMarkHighlight.ts +8 -0
  106. package/src/icons/ast/RicheditorMarkStrike.ts +1 -1
  107. package/src/icons/ast/RicheditorMarkUnderline.ts +1 -1
  108. package/src/icons/ast/SearchFilled.ts +8 -0
  109. package/src/icons/ast/SettingsFilled.ts +8 -0
  110. package/src/icons/ast/SlideMenuFilled.ts +8 -0
  111. package/src/icons/ast/SpaceApp.ts +8 -0
  112. package/src/icons/ast/SpaceGenerate.ts +8 -0
  113. package/src/icons/ast/SpaceScratch.ts +8 -0
  114. package/src/icons/ast/SpaceTemplate.ts +8 -0
  115. package/src/icons/ast/TableLayout.ts +8 -0
  116. package/src/icons/ast/TemplatesFilled.ts +8 -0
  117. package/src/icons/ast/ThumbsDown.ts +8 -0
  118. package/src/icons/ast/ThumbsUp.ts +8 -0
  119. package/src/icons/ast/TypeDate.ts +1 -1
  120. package/src/icons/ast/ViewDashboard.ts +8 -0
  121. package/src/icons/ast/WarningTriangleFilled.ts +8 -0
  122. package/src/icons/ast/Windows.ts +8 -0
  123. package/src/icons/ast/index.tsx +37 -0
  124. package/src/icons/react/ActivityFilled.tsx +13 -0
  125. package/src/icons/react/AiAssistantFilled.tsx +13 -0
  126. package/src/icons/react/AiFiberyBuild.tsx +13 -0
  127. package/src/icons/react/Apple.tsx +13 -0
  128. package/src/icons/react/CollapseAllHorizontal.tsx +13 -0
  129. package/src/icons/react/Crosshair.tsx +13 -0
  130. package/src/icons/react/Document.tsx +13 -0
  131. package/src/icons/react/EntityCreate.tsx +13 -0
  132. package/src/icons/react/EntityCreateFilled.tsx +13 -0
  133. package/src/icons/react/ExpandAll.tsx +13 -0
  134. package/src/icons/react/ExpandAllHorizontal.tsx +13 -0
  135. package/src/icons/react/FiberyDesktopApp.tsx +13 -0
  136. package/src/icons/react/FileDownload.tsx +13 -0
  137. package/src/icons/react/GlobeUnpublish.tsx +13 -0
  138. package/src/icons/react/GraduationCapFilled.tsx +13 -0
  139. package/src/icons/react/HomeFilled.tsx +13 -0
  140. package/src/icons/react/ImportFilled.tsx +13 -0
  141. package/src/icons/react/IntegrationsFilled.tsx +13 -0
  142. package/src/icons/react/KeyboardHideDown.tsx +13 -0
  143. package/src/icons/react/LayoutMultiple.tsx +13 -0
  144. package/src/icons/react/LocationEdit.tsx +13 -0
  145. package/src/icons/react/MessagePlus.tsx +13 -0
  146. package/src/icons/react/RicheditorMarkHighlight.tsx +13 -0
  147. package/src/icons/react/SearchFilled.tsx +13 -0
  148. package/src/icons/react/SettingsFilled.tsx +13 -0
  149. package/src/icons/react/SlideMenuFilled.tsx +13 -0
  150. package/src/icons/react/SpaceApp.tsx +13 -0
  151. package/src/icons/react/SpaceGenerate.tsx +13 -0
  152. package/src/icons/react/SpaceScratch.tsx +13 -0
  153. package/src/icons/react/SpaceTemplate.tsx +13 -0
  154. package/src/icons/react/TableLayout.tsx +13 -0
  155. package/src/icons/react/TemplatesFilled.tsx +13 -0
  156. package/src/icons/react/ThumbsDown.tsx +13 -0
  157. package/src/icons/react/ThumbsUp.tsx +13 -0
  158. package/src/icons/react/ViewDashboard.tsx +13 -0
  159. package/src/icons/react/WarningTriangleFilled.tsx +13 -0
  160. package/src/icons/react/Windows.tsx +13 -0
  161. package/src/icons/react/index.tsx +37 -0
  162. package/src/icons/svg/activity-filled.svg +4 -0
  163. package/src/icons/svg/ai-assistant-filled.svg +3 -0
  164. package/src/icons/svg/ai-fibery-build.svg +24 -0
  165. package/src/icons/svg/anthropic.svg +2 -14
  166. package/src/icons/svg/apple.svg +4 -0
  167. package/src/icons/svg/arrow-bottom.svg +1 -1
  168. package/src/icons/svg/arrow-forward.svg +1 -1
  169. package/src/icons/svg/arrow-left.svg +1 -1
  170. package/src/icons/svg/arrow-right.svg +1 -1
  171. package/src/icons/svg/arrow-top.svg +1 -1
  172. package/src/icons/svg/collapse-all-horizontal.svg +3 -0
  173. package/src/icons/svg/crosshair.svg +4 -0
  174. package/src/icons/svg/date-range.svg +3 -3
  175. package/src/icons/svg/document.svg +4 -0
  176. package/src/icons/svg/entity-create-filled.svg +4 -0
  177. package/src/icons/svg/entity-create.svg +3 -0
  178. package/src/icons/svg/expand-all-horizontal.svg +3 -0
  179. package/src/icons/svg/expand-all.svg +3 -0
  180. package/src/icons/svg/fibery-desktop-app.svg +101 -0
  181. package/src/icons/svg/file-download.svg +4 -0
  182. package/src/icons/svg/globe-unpublish.svg +4 -0
  183. package/src/icons/svg/go-to.svg +1 -3
  184. package/src/icons/svg/graduation-cap-filled.svg +4 -0
  185. package/src/icons/svg/home-filled.svg +3 -0
  186. package/src/icons/svg/home.svg +4 -2
  187. package/src/icons/svg/import-filled.svg +4 -0
  188. package/src/icons/svg/integrations-filled.svg +4 -0
  189. package/src/icons/svg/keyboard-hide-down.svg +1 -0
  190. package/src/icons/svg/layout-multiple.svg +3 -0
  191. package/src/icons/svg/location-edit.svg +13 -0
  192. package/src/icons/svg/message-plus.svg +4 -0
  193. package/src/icons/svg/open-ai.svg +2 -7
  194. package/src/icons/svg/open-as-page.svg +2 -3
  195. package/src/icons/svg/richeditor/history/redo.svg +3 -2
  196. package/src/icons/svg/richeditor/history/undo.svg +3 -2
  197. package/src/icons/svg/richeditor/mark/code.svg +4 -5
  198. package/src/icons/svg/richeditor/mark/em.svg +3 -2
  199. package/src/icons/svg/richeditor/mark/highlight.svg +3 -0
  200. package/src/icons/svg/richeditor/mark/strike.svg +3 -2
  201. package/src/icons/svg/richeditor/mark/strong.svg +3 -2
  202. package/src/icons/svg/richeditor/mark/underline.svg +4 -2
  203. package/src/icons/svg/search-filled.svg +3 -0
  204. package/src/icons/svg/settings-filled.svg +3 -0
  205. package/src/icons/svg/slide-menu-filled.svg +1 -0
  206. package/src/icons/svg/space-app.svg +3 -0
  207. package/src/icons/svg/space-generate.svg +3 -0
  208. package/src/icons/svg/space-scratch.svg +3 -0
  209. package/src/icons/svg/space-template.svg +3 -0
  210. package/src/icons/svg/table-layout.svg +3 -0
  211. package/src/icons/svg/templates-filled.svg +6 -0
  212. package/src/icons/svg/thumbs-down.svg +3 -0
  213. package/src/icons/svg/thumbs-up.svg +3 -0
  214. package/src/icons/svg/type/date.svg +3 -2
  215. package/src/icons/svg/view-dashboard.svg +5 -0
  216. package/src/icons/svg/warning-triangle-filled.svg +3 -0
  217. package/src/icons/svg/windows.svg +15 -0
  218. package/src/images-gallery/images-gallery.tsx +254 -0
  219. package/src/images-gallery/zoom.tsx +112 -0
  220. package/src/integration-compact-info-button.tsx +3 -1
  221. package/src/is-in-popup.ts +1 -1
  222. package/src/layout-styles.ts +43 -0
  223. package/src/lists/actions-menu-row-surface.tsx +3 -1
  224. package/src/lists/list-row-surface.tsx +9 -2
  225. package/src/loaders.tsx +6 -6
  226. package/src/logo.tsx +16 -9
  227. package/src/mobile-keyboard-aware-popup.tsx +87 -0
  228. package/src/mobile-styles.ts +10 -0
  229. package/src/modal-menu/contexts/modal-menu-context.tsx +22 -0
  230. package/src/modal-menu/contexts/modal-submenu-context.tsx +16 -0
  231. package/src/modal-menu/index.tsx +14 -0
  232. package/src/modal-menu/modal-menu-content.tsx +68 -0
  233. package/src/modal-menu/modal-menu-group.tsx +10 -0
  234. package/src/modal-menu/modal-menu-item.tsx +37 -0
  235. package/src/modal-menu/modal-menu-label.tsx +24 -0
  236. package/src/modal-menu/modal-menu-root.tsx +57 -0
  237. package/src/modal-menu/modal-menu-separator.tsx +14 -0
  238. package/src/modal-menu/modal-menu-trigger.tsx +37 -0
  239. package/src/modal-menu/modal-submenu-content.tsx +49 -0
  240. package/src/modal-menu/modal-submenu-trigger.tsx +34 -0
  241. package/src/modal-menu/modal-submenu.tsx +17 -0
  242. package/src/new-badge.tsx +4 -7
  243. package/src/number-input/text-area-auto-sized.tsx +47 -0
  244. package/src/number-input/text-input-auto-sized.tsx +49 -0
  245. package/src/online-users.tsx +3 -3
  246. package/src/palette.ts +50 -50
  247. package/src/popover/index.tsx +687 -0
  248. package/src/popover/mobile-popup-context.tsx +29 -0
  249. package/src/{popup → popover}/modifiers.tsx +0 -7
  250. package/src/{popup → popover}/popup-modifiers-context.ts +3 -3
  251. package/src/reactions/reaction-button.tsx +30 -45
  252. package/src/reactions/reaction-picker.tsx +39 -45
  253. package/src/rich-text-embed-error.tsx +2 -2
  254. package/src/select/{custom-select-partials → components}/menu.tsx +13 -7
  255. package/src/select/{custom-select-partials → components}/no-option-message.tsx +0 -1
  256. package/src/select/constants.ts +1 -0
  257. package/src/select/index.tsx +143 -148
  258. package/src/select/select-in-popover.tsx +119 -138
  259. package/src/select/styles.ts +60 -24
  260. package/src/shortcut-badge.tsx +1 -0
  261. package/src/tab-nav/tab-nav.tsx +47 -28
  262. package/src/theme-provider.tsx +9 -1
  263. package/src/toast/primitives.tsx +8 -1
  264. package/src/toggle-button/round-toggle-button.tsx +23 -0
  265. package/src/toggle-button/toggle-button-group.tsx +34 -0
  266. package/src/toggle-button/toggle-button.tsx +164 -0
  267. package/src/toggle.tsx +3 -3
  268. package/src/tooltip-if-overflown.tsx +9 -3
  269. package/src/tooltip.tsx +2 -2
  270. package/src/unit/index.tsx +9 -1
  271. package/src/unit/loading-unit-value.tsx +1 -0
  272. package/src/unit/maybe-unit-value.tsx +3 -3
  273. package/src/unit/primitive.tsx +58 -42
  274. package/src/unit/styles.ts +10 -14
  275. package/src/unit/types.ts +4 -2
  276. package/src/unit/unit-button-group.tsx +6 -11
  277. package/src/unit/unit-content.tsx +13 -5
  278. package/src/unit/unit-with-title.tsx +6 -1
  279. package/src/unit/unit-with-tooltip.tsx +24 -9
  280. package/src/use-is-phone.tsx +37 -0
  281. package/src/use-is-support-hover.ts +1 -1
  282. package/src/use-on-screen-keyboard-data.tsx +66 -0
  283. package/src/workflow-progress-icon.tsx +17 -23
  284. package/src/number-input/text-area-with-autosize.tsx +0 -91
  285. package/src/number-input/text-inline-input-with-autosize.tsx +0 -60
  286. package/src/popup/index.tsx +0 -382
  287. package/src/use-is-phone.ts +0 -5
  288. /package/src/{popup → popover}/popup-stack-context.tsx +0 -0
  289. /package/src/{popup → popover}/reference.ts +0 -0
  290. /package/src/{popup → popover}/styles.ts +0 -0
  291. /package/src/{popup → popover}/use-click-outside.ts +0 -0
  292. /package/src/select/{custom-select-partials → components}/clear-indicator.tsx +0 -0
  293. /package/src/select/{custom-select-partials → components}/drop-down-indicator.tsx +0 -0
  294. /package/src/select/{custom-select-partials → components}/group-heading.tsx +0 -0
  295. /package/src/select/{custom-select-partials → components}/menu-list-virtualized.tsx +0 -0
  296. /package/src/select/{custom-select-partials → components}/option.tsx +0 -0
@@ -1,10 +1,11 @@
1
1
  import {useControllableState} from "@fibery/react/src/use-controllable-state";
2
2
  import {css, cx} from "@linaria/core";
3
3
  import React, {
4
- ComponentProps,
5
4
  ComponentType,
5
+ ForwardedRef,
6
6
  forwardRef,
7
7
  ReactNode,
8
+ RefObject,
8
9
  useCallback,
9
10
  useEffect,
10
11
  useImperativeHandle,
@@ -14,10 +15,9 @@ import React, {
14
15
  } from "react";
15
16
  import {inputOverrides} from "../antd/styles";
16
17
  import {border, space, textStyles} from "../design-system";
17
- import {Popup} from "../popup";
18
- import {$TSFixMe} from "../tsfixme";
18
+ import {Popover} from "../popover";
19
19
  import {useIsPhone} from "../use-is-phone";
20
- import {Menu} from "./custom-select-partials/menu";
20
+ import {MenuTransparent} from "./components/menu";
21
21
  import {
22
22
  ActionMeta,
23
23
  combineStyles,
@@ -30,6 +30,11 @@ import {
30
30
  StylesConfig,
31
31
  } from "./index";
32
32
  import {SelectControlSettingsProvider} from "./select-control-settings-context";
33
+ import {ButtonColor, ButtonVariant} from "../button/base-button";
34
+ import {makeSelectInPopoverStyles} from "./styles";
35
+ import {SelectInstance} from "react-select";
36
+ import {SELECT_IN_POPOVER_VALUE_MAX_HEIGHT} from "./constants";
37
+ import {Wrap} from "@fibery/react/src/wrap";
33
38
 
34
39
  const offset = [0, space.s4] as [number, number];
35
40
  const popupHeightVH = 45;
@@ -60,7 +65,8 @@ const mobileClassName = css`
60
65
  padding-right: ${space.s12}px;
61
66
  `;
62
67
 
63
- const valueClassName = css`
68
+ const triggerCss = css`
69
+ min-width: 0;
64
70
  border-radius: ${border.radius6}px;
65
71
 
66
72
  &:focus {
@@ -85,113 +91,81 @@ const titleClassName = css`
85
91
  padding-inline: ${space.s12}px;
86
92
  `;
87
93
 
88
- export const valueMaxHeight = 116;
89
-
90
- export const selectInPopupStyles = {
91
- container: (props: $TSFixMe) => ({
92
- ...props,
93
- minWidth: 180,
94
- width: "100%",
95
- paddingTop: space.s6,
96
- paddingInline: space.s6,
97
- }),
98
- option: (props: $TSFixMe) => ({
99
- ...props,
100
- padding: 0,
101
- borderRadius: border.radius4,
102
- paddingLeft: 0,
103
- paddingRight: 0,
104
- }),
105
- control: (props: $TSFixMe) => ({
106
- ...props,
107
- maxHeight: valueMaxHeight,
108
- overflow: "auto",
109
- margin: space.s2,
110
- marginBottom: space.s4,
111
- width: `calc(100% - ${space.s2 * 2}px)`,
112
- borderRadius: border.radius4,
113
- }),
114
- menu: (props: $TSFixMe) => ({
115
- ...props,
116
- minWidth: 100,
117
- position: "static",
118
- marginBlock: 0,
119
- boxShadow: "none !important",
120
- borderRadius: border.radius4,
121
- }),
122
- };
123
-
124
94
  export type TriggerProps = {
125
95
  innerRef: React.Ref<HTMLDivElement>;
126
96
  children: ReactNode;
127
97
  onClick?: React.MouseEventHandler;
128
98
  iconStart?: ReactNode;
129
99
  pending?: boolean;
100
+ pressed?: boolean;
101
+ menuOpened?: boolean;
130
102
  onKeyDown?: React.KeyboardEventHandler;
131
103
  disabled?: boolean;
104
+ size?: "small" | "medium" | "large";
105
+ fullWidth?: boolean;
106
+ style?: React.CSSProperties;
107
+ className?: string;
108
+ variant?: ButtonVariant;
109
+ color?: ButtonColor;
110
+ valueSelected: boolean;
132
111
  };
133
112
 
134
- const Trigger = ({innerRef, children, onClick, onKeyDown}: TriggerProps) => {
113
+ const TriggerDefault = ({innerRef, children, onClick, onKeyDown}: TriggerProps) => {
135
114
  return (
136
- <div ref={innerRef} onClick={onClick} onKeyDown={onKeyDown} tabIndex={0} className={valueClassName}>
115
+ <div ref={innerRef} onClick={onClick} onKeyDown={onKeyDown} tabIndex={0} className={triggerCss}>
137
116
  {children}
138
117
  </div>
139
118
  );
140
119
  };
141
120
 
142
- type Components = {
143
- Trigger: ComponentType<TriggerProps>;
144
- Menu: ComponentType<ComponentProps<typeof Menu>>;
121
+ export type SelectComponents<T, U extends boolean, V extends GroupBase<T>> = SelectProps<T, U, V>["components"] & {
122
+ Trigger?: ComponentType<TriggerProps>;
145
123
  };
146
124
 
147
- export type ComponentsConfig = Partial<Components>;
148
-
149
- const defaultComponents = {Trigger, Menu};
150
-
151
- type Ref = {
125
+ export type SelectInPopoverRef<T, U extends boolean, V extends GroupBase<T>> = {
152
126
  valueRef: HTMLDivElement | null;
153
- selectRef: $TSFixMe | null;
127
+ selectRef: RefObject<SelectInstance<T, U, V>>;
154
128
  };
155
129
 
156
- type Props<Option, IsMulti extends boolean, Group extends GroupBase<Option>> = {
157
- value?: PropsValue<Option>;
130
+ type Props<T, U extends boolean, V extends GroupBase<T>> = {
131
+ value?: PropsValue<T>;
158
132
  menuIsOpen?: boolean;
159
133
  autoFocus?: boolean;
160
134
  virtualized?: boolean;
161
135
  defaultMenuIsOpen?: boolean;
162
136
  placeholder?: string;
163
137
  noOptionsMessage?: () => string | JSX.Element | null;
164
- options: OptionsOrGroups<Option, Group>;
165
- filterOption?: SelectProps<Option>["filterOption"];
138
+ options: OptionsOrGroups<T, V>;
139
+ filterOption?: SelectProps<T, U, V>["filterOption"];
166
140
  inputValue?: string;
167
141
  disabled?: boolean;
168
- isCollectionMode?: IsMulti;
142
+ isCollectionMode?: U;
169
143
  isClearable?: boolean;
170
144
  renderValue?: () => ReactNode;
171
145
  title?: string;
172
146
  maxMenuHeight?: number;
173
- hideOnChange?: boolean | ((newValue: OnChangeValue<Option, IsMulti>, actionMeta: ActionMeta<Option>) => boolean);
147
+ hideOnChange?: boolean | ((newValue: OnChangeValue<T, U>, actionMeta: ActionMeta<T>) => boolean);
174
148
  renderInPortal?: boolean;
175
149
  popupStyles?: string;
176
- selectStyles?: StylesConfig<Option, IsMulti, Group>;
177
- formatGroupLabel?: (group: Group) => ReactNode;
178
- formatOptionLabel?: (option: Option, {context}: {context: "menu" | "value"}) => ReactNode;
179
- components?: ComponentsConfig;
150
+ selectStyles?: StylesConfig<T, U, V>;
151
+ formatGroupLabel?: (group: V) => ReactNode;
152
+ formatOptionLabel?: (option: T, {context}: {context: "menu" | "value"}) => ReactNode;
153
+ components?: SelectComponents<T, U, V>;
180
154
  onInputChange?: (s: string, actionType: {action: string}) => void;
181
155
  onFocus?: () => void;
182
- onChange: (newValue: OnChangeValue<Option, IsMulti>, actionMeta: ActionMeta<Option>) => void;
156
+ onChange: (newValue: OnChangeValue<T, U>, actionMeta: ActionMeta<T>) => void;
183
157
  onMenuOpen?: () => void;
184
158
  onMenuClose?: () => void | boolean;
185
159
  getPopupContainer?: () => HTMLElement;
186
160
  onSelectKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
187
161
  forbidValuesClearInCollnMode?: boolean;
188
162
  otherSelectProps?: Record<string, unknown>;
189
- isOptionDisabled?: (option: Option) => boolean;
163
+ isOptionDisabled?: (option: T) => boolean;
190
164
  };
191
165
 
192
- function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends GroupBase<Option>>(
193
- props: Omit<Props<Option, IsMulti, Group>, "maxMenuHeight">,
194
- forwardedRef: React.ForwardedRef<Ref>
166
+ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
167
+ props: Omit<Props<T, U, V>, "maxMenuHeight">,
168
+ forwardedRef: ForwardedRef<SelectInPopoverRef<T, U, V>>
195
169
  ) {
196
170
  const {
197
171
  value,
@@ -227,7 +201,6 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
227
201
  forbidValuesClearInCollnMode,
228
202
  isOptionDisabled,
229
203
  } = props;
230
- const [triggerElement, setTriggerElement] = useState<HTMLDivElement | null>(null);
231
204
  const [visible, setVisible] = useControllableState({
232
205
  value: menuIsOpen,
233
206
  defaultValue: false,
@@ -236,20 +209,14 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
236
209
  },
237
210
  });
238
211
  const blurTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
239
- const selectRef = useRef<{focus: () => void}>(null);
240
- const ref = useRef<HTMLDivElement | null>(null);
241
-
242
- useImperativeHandle(
243
- forwardedRef,
244
- () =>
245
- ({
246
- valueRef: ref.current,
247
- selectRef: selectRef.current,
248
- } as {valueRef: HTMLDivElement; selectRef: $TSFixMe | null})
249
- );
250
- useEffect(() => {
251
- setTriggerElement(ref.current);
252
- }, []);
212
+ const selectRef = useRef<SelectInstance<T, U, V>>(null);
213
+ const [triggerElement, setTriggerElement] = useState<HTMLDivElement | null>(null);
214
+
215
+ useImperativeHandle(forwardedRef, () => ({
216
+ valueRef: triggerElement,
217
+ selectRef,
218
+ }));
219
+
253
220
  useEffect(() => {
254
221
  if (blurTimeoutRef.current) {
255
222
  clearTimeout(blurTimeoutRef.current);
@@ -301,7 +268,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
301
268
  }, [disabled, onMenuOpen, setVisible]);
302
269
 
303
270
  const styles = useMemo(() => {
304
- return combineStyles<Option, IsMulti, Group>([selectInPopupStyles, selectStyles]);
271
+ return combineStyles<T, U, V>([makeSelectInPopoverStyles(), selectStyles]);
305
272
  }, [selectStyles]);
306
273
 
307
274
  const onTriggerClick: React.MouseEventHandler = useCallback(
@@ -326,29 +293,77 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
326
293
  },
327
294
  [onShow, visible]
328
295
  );
296
+
297
+ const onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = useCallback(
298
+ (event) => {
299
+ if ((event.key === "Escape" || event.key === "Tab") && visible) {
300
+ onHide();
301
+ event.preventDefault();
302
+ event.stopPropagation();
303
+ }
304
+ onSelectKeyDown?.(event);
305
+ },
306
+ [onHide, onSelectKeyDown, visible]
307
+ );
308
+
309
+ const isPhone = useIsPhone();
310
+
311
+ const onBlur: React.FocusEventHandler<HTMLDivElement> = useCallback(() => {
312
+ if (isPhone) {
313
+ return;
314
+ }
315
+ blurTimeoutRef.current = setTimeout(() => {
316
+ onHide(false);
317
+ }, 250);
318
+ }, [isPhone, onHide]);
319
+
320
+ const handleChange = useCallback(
321
+ (newValue: OnChangeValue<T, U>, actionMeta: ActionMeta<T>) => {
322
+ if (typeof hideOnChange === "function") {
323
+ if (hideOnChange(newValue, actionMeta)) {
324
+ onHide();
325
+ }
326
+ } else if (hideOnChange) {
327
+ onHide();
328
+ }
329
+ onChange(newValue, actionMeta);
330
+ },
331
+ [hideOnChange, onChange, onHide]
332
+ );
333
+
329
334
  const paddingPopup = popupPaddingTop + popupPaddingBottom;
330
335
  const paddingMenu = 6 + 6 + 6;
331
- const isPhone = useIsPhone();
336
+
332
337
  const maxMenuHeight = isPhone
333
- ? document.body.clientHeight - 45 - valueMaxHeight
338
+ ? document.body.clientHeight - 45 - SELECT_IN_POPOVER_VALUE_MAX_HEIGHT
334
339
  : Math.max((document.body.clientHeight / 100) * popupHeightVH, popupMinHeightPx) -
335
- valueMaxHeight -
340
+ SELECT_IN_POPOVER_VALUE_MAX_HEIGHT -
336
341
  paddingPopup -
337
342
  paddingMenu;
338
- const mergedComponents = {...defaultComponents, ...components};
343
+
344
+ const Trigger = components.Trigger || TriggerDefault;
345
+ const selectComponents = {
346
+ Menu: MenuTransparent,
347
+ DropdownIndicator: null,
348
+ IndicatorSeparator: null,
349
+ ...components,
350
+ };
339
351
 
340
352
  return (
341
- <>
342
- <mergedComponents.Trigger
343
- innerRef={ref}
353
+ <Popover.Root open={visible} onOpen={() => onShow()} onClose={() => onHide()}>
354
+ <Trigger
355
+ innerRef={setTriggerElement}
356
+ menuOpened={visible}
357
+ disabled={disabled}
358
+ valueSelected={Boolean(value)}
344
359
  onClick={onTriggerClick}
345
360
  onKeyDown={onTriggerKeyDown}
346
- disabled={disabled}
347
361
  >
348
362
  {renderValue ? renderValue() : null}
349
- </mergedComponents.Trigger>
350
- {Boolean(triggerElement) && (
351
- <Popup
363
+ </Trigger>
364
+ <Popover.Trigger reference={triggerElement} />
365
+ <Wrap with={Popover.Portal} if={renderInPortal} getPopupContainer={getPopupContainer}>
366
+ <Popover.Content
352
367
  supportMobile
353
368
  title={title}
354
369
  offset={offset}
@@ -356,55 +371,25 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
356
371
  popupClassName={cx(popupClassName, popupStyles)}
357
372
  mobilePopupContentClassName={mobileClassName}
358
373
  placement="bottom-start"
359
- renderInPortal={renderInPortal}
360
- open={visible}
361
- onOpen={() => onShow()}
362
- onClose={() => onHide()}
363
- trigger={<></>}
364
- triggerDomElement={triggerElement}
365
- getPopupContainer={getPopupContainer}
366
374
  >
367
375
  {title && !isPhone && <div className={titleClassName}>{title}</div>}
368
376
  {/*Usually we set popupContainerElement for react-select via context (SelectControlSettingsProvider). But here we render react-select in popover.*/}
369
377
  {/*Render target in controlled by Popover here. So we just override SelectControlContext here and set popupContainerElement to undefined. */}
370
378
  {/*So in dom react-select will be a child of popover. */}
371
379
  <SelectControlSettingsProvider getPopupContainerElement={undefined}>
372
- <ReactSelect
380
+ <ReactSelect<T, U, V>
373
381
  ref={selectRef}
374
382
  styles={styles}
375
383
  isSearchable={true}
376
- onKeyDown={(event) => {
377
- if ((event.key === "Escape" || event.key === "Tab") && visible) {
378
- onHide();
379
- event.preventDefault();
380
- event.stopPropagation();
381
- }
382
- onSelectKeyDown?.(event);
383
- }}
384
+ onKeyDown={onKeyDown}
384
385
  autoFocus={autoFocus}
385
- onBlur={() => {
386
- if (isPhone) {
387
- return;
388
- }
389
- blurTimeoutRef.current = setTimeout(() => {
390
- onHide(false);
391
- }, 250);
392
- }}
386
+ onBlur={onBlur}
393
387
  value={value}
394
388
  defaultMenuIsOpen={defaultMenuIsOpen}
395
389
  controlShouldRenderValue
396
390
  closeMenuOnScroll={false}
397
391
  closeMenuOnSelect={false}
398
- onChange={(newValue, actionMeta) => {
399
- if (typeof hideOnChange === "function") {
400
- if (hideOnChange(newValue, actionMeta)) {
401
- onHide();
402
- }
403
- } else if (hideOnChange) {
404
- onHide();
405
- }
406
- onChange(newValue, actionMeta);
407
- }}
392
+ onChange={handleChange}
408
393
  placeholder={placeholder}
409
394
  onInputChange={onInputChange}
410
395
  noOptionsMessage={noOptionsMessage}
@@ -421,23 +406,19 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
421
406
  formatGroupLabel={formatGroupLabel}
422
407
  formatOptionLabel={formatOptionLabel}
423
408
  {...otherSelectProps}
424
- components={{
425
- DropdownIndicator: null,
426
- IndicatorSeparator: null,
427
- Menu: mergedComponents.Menu as $TSFixMe,
428
- }}
409
+ components={selectComponents}
429
410
  forbidValuesClearInCollnMode={forbidValuesClearInCollnMode}
430
411
  isOptionDisabled={isOptionDisabled}
431
412
  />
432
413
  </SelectControlSettingsProvider>
433
- </Popup>
434
- )}
435
- </>
414
+ </Popover.Content>
415
+ </Wrap>
416
+ </Popover.Root>
436
417
  );
437
418
  }
438
419
 
439
- type SelectInPopoverType = <Option, IsMulti extends boolean, Group extends GroupBase<Option>>(
440
- props: Omit<Props<Option, IsMulti, Group>, "maxMenuHeight"> & {ref?: React.ForwardedRef<Ref>}
420
+ type SelectInPopoverType = <T, U extends boolean, V extends GroupBase<T>>(
421
+ props: Omit<Props<T, U, V>, "maxMenuHeight"> & {ref?: ForwardedRef<SelectInPopoverRef<T, U, V>>}
441
422
  ) => ReturnType<typeof SelectInPopoverInner>;
442
423
 
443
424
  // Explicit type assertion to specify that component accepts generic props because forwardRef breaks it
@@ -1,20 +1,21 @@
1
1
  import {css} from "@linaria/core";
2
- import type {ControlProps, CSSObjectWithLabel, StylesConfig} from "react-select";
2
+ import type {CSSObjectWithLabel, GroupBase, StylesConfig} from "react-select";
3
3
  import {inputOverrides} from "../antd/styles";
4
- import {layout, space, themeVars} from "../design-system";
5
- import {groupHeadingNulledStyles} from "./custom-select-partials/group-heading";
6
- import {MenuListNulledStyles, MenuNulledStyles} from "./custom-select-partials/menu";
7
- import {OptionNulledStyles, OptionNulledVitualizedStyles} from "./custom-select-partials/option";
4
+ import {border, layout, space, themeVars} from "../design-system";
5
+ import {groupHeadingNulledStyles} from "./components/group-heading";
6
+ import {MenuListNulledStyles, MenuNulledStyles} from "./components/menu";
7
+ import {OptionNulledStyles, OptionNulledVitualizedStyles} from "./components/option";
8
+ import {SELECT_IN_POPOVER_VALUE_MAX_HEIGHT} from "./constants";
8
9
 
9
10
  export const expanderExpandedStyle = css`
10
11
  transform: rotate(180deg);
11
12
  `;
12
13
 
13
- function createControlStyle({
14
+ function makeControlStyle<T, U extends boolean, V extends GroupBase<T>>({
14
15
  isSingleLine,
15
16
  }: {
16
17
  isSingleLine: boolean;
17
- }): (base: CSSObjectWithLabel, props: ControlProps) => CSSObjectWithLabel {
18
+ }): StylesConfig<T, U, V> {
18
19
  const childDivStyle: CSSObjectWithLabel = {
19
20
  padding: 0,
20
21
  overflow: "visible",
@@ -24,8 +25,8 @@ function createControlStyle({
24
25
  childDivStyle.flexWrap = "nowrap";
25
26
  }
26
27
 
27
- return (provided, state) =>
28
- ({
28
+ return {
29
+ control: (provided, state) => ({
29
30
  display: "flex",
30
31
  flexWrap: isSingleLine ? "nowrap" : "wrap",
31
32
  justifyContent: "space-between",
@@ -38,27 +39,30 @@ function createControlStyle({
38
39
  paddingLeft: space.s10,
39
40
  paddingRight: space.s12,
40
41
  "& > div": childDivStyle,
41
- } as unknown as CSSObjectWithLabel);
42
+ }),
43
+ };
42
44
  }
43
45
 
44
- export const virtualizedStyles: StylesConfig = {
46
+ export const makeVirtualizedStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
45
47
  option: () => ({...OptionNulledVitualizedStyles, ...OptionNulledStyles}),
46
48
  groupHeading: (provided) => ({
47
49
  ...provided,
48
50
  ...groupHeadingNulledStyles,
49
51
  height: layout.menuItemHeight,
50
52
  }),
51
- };
53
+ });
52
54
 
53
- export const nonVirtualizedStyles: StylesConfig = {
55
+ export const makeNonVirtualizedStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
54
56
  menuList: (provided) => ({
55
57
  ...provided,
56
58
  paddingTop: 6,
57
59
  paddingBottom: 6,
58
60
  }),
59
- };
61
+ });
60
62
 
61
- export const zIndexStyles = (zIndex: number): StylesConfig => ({
63
+ export const makeZIndexStyles = <T, U extends boolean, V extends GroupBase<T>>(
64
+ zIndex: number
65
+ ): StylesConfig<T, U, V> => ({
62
66
  menuPortal: (provided) => ({
63
67
  ...provided,
64
68
  zIndex: zIndex,
@@ -69,13 +73,11 @@ export const zIndexStyles = (zIndex: number): StylesConfig => ({
69
73
  }),
70
74
  });
71
75
 
72
- export const componentsStyles: StylesConfig = {
76
+ export const makeComponentsStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
73
77
  option: () => OptionNulledStyles,
74
78
  noOptionsMessage: (provided) => ({
75
79
  ...provided,
76
- paddingLeft: "",
77
- paddingTop: "",
78
- paddingBottom: "",
80
+ padding: 0,
79
81
  }),
80
82
  placeholder: (provided) => ({
81
83
  ...provided,
@@ -112,7 +114,7 @@ export const componentsStyles: StylesConfig = {
112
114
  alignItems: "center",
113
115
  height: layout.inputHeight - 2,
114
116
  }),
115
- control: createControlStyle({isSingleLine: false}),
117
+ control: makeControlStyle<T, U, V>({isSingleLine: false}).control,
116
118
  group: (provided) => ({
117
119
  ...provided,
118
120
  padding: 0,
@@ -150,8 +152,42 @@ export const componentsStyles: StylesConfig = {
150
152
  color: themeVars.textColor,
151
153
  };
152
154
  },
153
- };
155
+ });
156
+
157
+ export const makeSingleLineStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
158
+ control: makeControlStyle<T, U, V>({isSingleLine: true}).control,
159
+ });
154
160
 
155
- export const singleLineComponentsStyle: StylesConfig = {
156
- control: createControlStyle({isSingleLine: true}),
157
- };
161
+ export const makeSelectInPopoverStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
162
+ container: (props) => ({
163
+ ...props,
164
+ minWidth: 180,
165
+ width: "100%",
166
+ paddingTop: space.s6,
167
+ paddingInline: space.s6,
168
+ }),
169
+ option: (props) => ({
170
+ ...props,
171
+ padding: 0,
172
+ borderRadius: border.radius4,
173
+ paddingLeft: 0,
174
+ paddingRight: 0,
175
+ }),
176
+ control: (props) => ({
177
+ ...props,
178
+ maxHeight: SELECT_IN_POPOVER_VALUE_MAX_HEIGHT,
179
+ overflow: "auto",
180
+ margin: space.s2,
181
+ marginBottom: space.s4,
182
+ width: `calc(100% - ${space.s2 * 2}px)`,
183
+ borderRadius: border.radius4,
184
+ }),
185
+ menu: (props) => ({
186
+ ...props,
187
+ minWidth: 100,
188
+ position: "static",
189
+ marginBlock: 0,
190
+ boxShadow: "none !important",
191
+ borderRadius: border.radius4,
192
+ }),
193
+ });
@@ -5,6 +5,7 @@ import {useIsSupportHardwareKeyboard} from "./use-is-support-hardware-keyboard";
5
5
  export const shortcutCss = css`
6
6
  ${{
7
7
  ...textStyles.small,
8
+ ...textStyles.numeric.tabularOn,
8
9
  borderRadius: border.radius4,
9
10
  border: themeVars.shortcutBorderColor,
10
11
  color: themeVars.shortcutTextColor,