@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
@@ -0,0 +1,254 @@
1
+ import {ReactNode, useCallback, useEffect, useMemo, useReducer, useRef, useState} from "react";
2
+ import _ from "lodash";
3
+ import {createContext} from "@fibery/react/src/create-context";
4
+ import {useIsPhone} from "../use-is-phone";
5
+ import {safeAreaInsetBottomVar} from "../mobile-styles";
6
+ import {buttonGroup, ButtonGroup} from "../button/button-group";
7
+ import {IconButton} from "../button/icon-button";
8
+ import ArrowRight from "../icons/react/ArrowRight";
9
+ import ArrowLeft from "../icons/react/ArrowLeft";
10
+ import {css} from "@linaria/core";
11
+ import cx from "classnames";
12
+
13
+ type Registry = Map<string, {zoomed: boolean; setZoomed: (zoomed: boolean) => void}>;
14
+
15
+ const [ImagesGalleryRegistryProvider, useImagesGalleryRegistry] = createContext(
16
+ "ImagesGalleryRegistryContext",
17
+ new Map()
18
+ );
19
+
20
+ export {useImagesGalleryRegistry};
21
+
22
+ type Methods = {
23
+ setVisible: (visible: boolean) => void;
24
+ setActivated: (activated: boolean) => void;
25
+ update: () => void;
26
+ nextImage: () => void;
27
+ prevImage: () => void;
28
+ };
29
+ const [ImagesGalleryMethodsProvider, useImagesGalleryMethods] = createContext<Methods>("ImagesGalleryMethodsProvider", {
30
+ setVisible: _.noop,
31
+ setActivated: _.noop,
32
+ update: _.noop,
33
+ nextImage: _.noop,
34
+ prevImage: _.noop,
35
+ });
36
+ type State = {visible: boolean; activated: boolean; _inc: number};
37
+
38
+ const [ImagesGalleryStateProvider, useImagesGalleryState] = createContext<State>("ImagesGalleryStateContext", {
39
+ visible: false,
40
+ activated: false,
41
+ _inc: 0,
42
+ });
43
+
44
+ export {useImagesGalleryMethods, useImagesGalleryState};
45
+
46
+ type Actions = {type: "set-visible"; payload: boolean} | {type: "set-activated"; payload: boolean} | {type: "inc"};
47
+
48
+ function initialState(): State {
49
+ return {visible: false, activated: false, _inc: 0};
50
+ }
51
+
52
+ function imagesGalleryReducer(state: State, action: Actions) {
53
+ if (action.type === "set-visible") {
54
+ return {...state, visible: action.payload};
55
+ }
56
+ if (action.type === "set-activated") {
57
+ return {...state, activated: action.payload};
58
+ }
59
+ if (action.type === "inc") {
60
+ return {...state, _inc: state._inc + 1};
61
+ }
62
+ return state;
63
+ }
64
+
65
+ const controlsGroupStyle = css`
66
+ &.${buttonGroup} {
67
+ display: none;
68
+ }
69
+ `;
70
+
71
+ export function Controls() {
72
+ const imagesRegistry = useImagesGalleryRegistry();
73
+ const {visible} = useImagesGalleryState();
74
+ const isPhone = useIsPhone();
75
+ const {prevImage, nextImage, setVisible} = useImagesGalleryMethods();
76
+ // Determine if there is a zoomed image and its position in the registry
77
+ let activeNext = true;
78
+ let activePrev = true;
79
+ let i = 0;
80
+ for (const image of imagesRegistry.values()) {
81
+ if (image.zoomed) {
82
+ if (i === 0) {
83
+ activePrev = false;
84
+ }
85
+ if (i === imagesRegistry.size - 1) {
86
+ activeNext = false;
87
+ }
88
+ break;
89
+ }
90
+ i++;
91
+ }
92
+ const visibleState = visible || isPhone;
93
+ if (imagesRegistry.size > 1) {
94
+ const size = isPhone ? "xLarge" : "small";
95
+ return (
96
+ <div
97
+ className={css`
98
+ position: fixed;
99
+ bottom: max(var(${safeAreaInsetBottomVar}), 12px);
100
+ left: 0;
101
+ right: 0;
102
+ display: grid;
103
+ align-items: center;
104
+ justify-content: center;
105
+ &:hover .${controlsGroupStyle}.${buttonGroup} {
106
+ display: flex;
107
+ }
108
+ `}
109
+ >
110
+ <ButtonGroup
111
+ className={cx(
112
+ controlsGroupStyle,
113
+ visibleState &&
114
+ css`
115
+ &.${controlsGroupStyle}.${buttonGroup} {
116
+ display: flex;
117
+ }
118
+ `
119
+ )}
120
+ >
121
+ <IconButton
122
+ variant={"outline"}
123
+ size={size}
124
+ onClick={() => {
125
+ prevImage();
126
+ setVisible(true);
127
+ }}
128
+ disabled={!activePrev}
129
+ >
130
+ <ArrowLeft />
131
+ </IconButton>
132
+ <IconButton
133
+ variant={"outline"}
134
+ size={size}
135
+ onClick={() => {
136
+ nextImage();
137
+ setVisible(true);
138
+ }}
139
+ disabled={!activeNext}
140
+ >
141
+ <ArrowRight />
142
+ </IconButton>
143
+ </ButtonGroup>
144
+ </div>
145
+ );
146
+ }
147
+ return null;
148
+ }
149
+
150
+ export function ImagesGalleryProvider({children}: {children: ReactNode}) {
151
+ const [imagesRegistry] = useState<Registry>(() => new Map());
152
+ const timeoutRef = useRef<ReturnType<typeof setTimeout>>();
153
+ const [galleryState, dispatchState] = useReducer(imagesGalleryReducer, [], initialState);
154
+ const setVisible = useCallback((visible: boolean) => dispatchState({type: "set-visible", payload: visible}), []);
155
+ const setActivated = useCallback(
156
+ (activated: boolean) => dispatchState({type: "set-activated", payload: activated}),
157
+ []
158
+ );
159
+ const update = useCallback(() => dispatchState({type: "inc"}), []);
160
+ const {visible} = galleryState;
161
+ const timeout = 3000;
162
+ useEffect(() => {
163
+ if (visible) {
164
+ clearTimeout(timeoutRef.current);
165
+ timeoutRef.current = setTimeout(() => {
166
+ setVisible(false);
167
+ }, timeout);
168
+ }
169
+ return () => {
170
+ clearTimeout(timeoutRef.current);
171
+ };
172
+ }, [setVisible, visible]);
173
+ const nextImage = useCallback(() => {
174
+ let i = 0;
175
+ for (const image of imagesRegistry.values()) {
176
+ if (image.zoomed) {
177
+ if (i === imagesRegistry.size - 1) {
178
+ break;
179
+ }
180
+ image.setZoomed(false);
181
+ const nextImage = Array.from(imagesRegistry.values())[i + 1];
182
+ nextImage.setZoomed(true);
183
+ break;
184
+ }
185
+ i++;
186
+ }
187
+ clearTimeout(timeoutRef.current);
188
+ timeoutRef.current = setTimeout(() => {
189
+ setVisible(false);
190
+ }, timeout);
191
+ }, [imagesRegistry, setVisible]);
192
+
193
+ const prevImage = useCallback(() => {
194
+ let i = 0;
195
+ for (const image of imagesRegistry.values()) {
196
+ if (image.zoomed) {
197
+ if (i === 0) {
198
+ break;
199
+ }
200
+ image.setZoomed(false);
201
+ const prevImage = Array.from(imagesRegistry.values())[i - 1];
202
+ prevImage.setZoomed(true);
203
+ break;
204
+ }
205
+ i++;
206
+ }
207
+ clearTimeout(timeoutRef.current);
208
+ timeoutRef.current = setTimeout(() => {
209
+ setVisible(false);
210
+ }, timeout);
211
+ }, [imagesRegistry, setVisible]);
212
+
213
+ const methods = useMemo(
214
+ () => ({setVisible, setActivated, update, nextImage, prevImage}),
215
+ [setVisible, setActivated, update, nextImage, prevImage]
216
+ );
217
+
218
+ useEffect(() => {
219
+ const listener = (evt: KeyboardEvent) => {
220
+ const hasActive = Array.from(imagesRegistry.values()).some((image) => image.zoomed);
221
+ if (!hasActive) {
222
+ return;
223
+ }
224
+ if (evt.key === "Escape") {
225
+ for (const image of imagesRegistry.values()) {
226
+ if (image.zoomed) {
227
+ image.setZoomed(false);
228
+ break;
229
+ }
230
+ }
231
+ }
232
+ if (evt.key === "ArrowRight") {
233
+ nextImage();
234
+ }
235
+ if (evt.key === "ArrowLeft") {
236
+ prevImage();
237
+ }
238
+ };
239
+ document.addEventListener("keydown", listener, {capture: true});
240
+ return () => {
241
+ document.removeEventListener("keydown", listener, {capture: true});
242
+ };
243
+ }, [imagesRegistry, nextImage, prevImage]);
244
+
245
+ return (
246
+ <>
247
+ <ImagesGalleryRegistryProvider value={imagesRegistry}>
248
+ <ImagesGalleryMethodsProvider value={methods}>
249
+ <ImagesGalleryStateProvider value={galleryState}>{children}</ImagesGalleryStateProvider>
250
+ </ImagesGalleryMethodsProvider>
251
+ </ImagesGalleryRegistryProvider>
252
+ </>
253
+ );
254
+ }
@@ -0,0 +1,112 @@
1
+ import {css} from "@linaria/core";
2
+ import React, {ReactNode, useCallback} from "react";
3
+ import {Controlled} from "react-medium-image-zoom";
4
+ import "react-medium-image-zoom/dist/styles.css";
5
+ import {themeVars} from "../design-system";
6
+ import {IconButton} from "../button/icon-button";
7
+ import Close from "../icons/react/Close";
8
+ import {Controls, useImagesGalleryMethods} from "./images-gallery";
9
+ import {useIsPhone} from "../use-is-phone";
10
+
11
+ const dialogCss = css`
12
+ :global() {
13
+ [data-rmiz-modal-overlay="hidden"] {
14
+ background-color: transparent;
15
+ }
16
+ [data-rmiz-modal-overlay="visible"] {
17
+ background-color: ${themeVars.colorBgEditorImageZoomed};
18
+ }
19
+ [data-rmiz-content="found"] > img {
20
+ cursor: auto;
21
+ }
22
+ }
23
+ `;
24
+
25
+ type ModalState = "LOADED" | "LOADING" | "UNLOADED" | "UNLOADING";
26
+
27
+ const ZoomContent = ({
28
+ img,
29
+ modalState,
30
+ onUnzoom,
31
+ }: {
32
+ img: React.ReactElement | null;
33
+ modalState: ModalState;
34
+ onUnzoom: (e: Event) => void;
35
+ }) => {
36
+ const imagesGalleryMethods = useImagesGalleryMethods();
37
+ const isPhone = useIsPhone();
38
+
39
+ const button = modalState === "LOADED" && (
40
+ <IconButton
41
+ size={isPhone ? "xLarge" : "small"}
42
+ color="neutral"
43
+ variant="ghost"
44
+ className={css`
45
+ position: absolute;
46
+ inset: 20px 20px auto auto;
47
+ z-index: 1;
48
+ `}
49
+ onClick={onUnzoom as () => void}
50
+ >
51
+ <Close />
52
+ </IconButton>
53
+ );
54
+ return (
55
+ <>
56
+ <div
57
+ onMouseMove={() => {
58
+ imagesGalleryMethods.setVisible(true);
59
+ }}
60
+ className={css`
61
+ position: absolute;
62
+ inset: 0;
63
+ `}
64
+ >
65
+ {img}
66
+ {button}
67
+ </div>
68
+ <Controls />
69
+ </>
70
+ );
71
+ };
72
+
73
+ type Props = {
74
+ zoomed: boolean;
75
+ onZoomedChange: (value: boolean) => void;
76
+ children: ReactNode;
77
+ className?: string;
78
+ openOnClick?: boolean;
79
+ zoomImg?: {src: string; alt?: string};
80
+ };
81
+
82
+ export const Zoom = (props: Props) => {
83
+ const {zoomed, onZoomedChange, children, className, openOnClick, zoomImg} = props;
84
+ const imagesGalleryMethods = useImagesGalleryMethods();
85
+ const onClick = useCallback(() => {
86
+ if (zoomed) {
87
+ onZoomedChange(false);
88
+ } else if (openOnClick) {
89
+ onZoomedChange(true);
90
+ }
91
+ }, [zoomed, onZoomedChange, openOnClick]);
92
+
93
+ const onDoubleClick = useCallback(() => {
94
+ if (!zoomed) {
95
+ onZoomedChange(true);
96
+ }
97
+ }, [zoomed, onZoomedChange]);
98
+
99
+ return (
100
+ <div className={className} onClick={onClick} onDoubleClick={openOnClick ? undefined : onDoubleClick}>
101
+ <Controlled
102
+ zoomImg={zoomImg}
103
+ onZoomChange={imagesGalleryMethods.update}
104
+ classDialog={dialogCss}
105
+ isZoomed={zoomed}
106
+ ZoomContent={ZoomContent}
107
+ >
108
+ {children}
109
+ </Controlled>
110
+ </div>
111
+ );
112
+ };
@@ -34,7 +34,9 @@ export const IntegrationCompactInfoButton: React.FC<{
34
34
  if (error) {
35
35
  iconNode = <WarningIcon color={colors.errorButtonColor} iconSize={18} containerSize={24} />;
36
36
  } else if (loading) {
37
- iconNode = <Spinner color={colors.accentTextColor} backgroundColor={colors.mainBg} size={16} containerSize={24} />;
37
+ iconNode = (
38
+ <Spinner color={colors.accentTextColor} backgroundColor={colors.mainBg} iconSize={16} containerSize={24} />
39
+ );
38
40
  }
39
41
 
40
42
  const className = cx(buttonCss, loading && loadingCss);
@@ -1,4 +1,4 @@
1
- import {basicPopupClassName} from "./popup/styles";
1
+ import {basicPopupClassName} from "./popover/styles";
2
2
  import {$TSFixMe} from "./tsfixme";
3
3
 
4
4
  const selectors = [
@@ -0,0 +1,43 @@
1
+ import {css} from "@linaria/core";
2
+ import {
3
+ layout,
4
+ listRowSurfaceFontSizeVar,
5
+ sidebarMenuItemHeightVar,
6
+ sidebarMenuIconSizeVar,
7
+ textStyles,
8
+ menuItemHeightVar,
9
+ } from "./design-system";
10
+ import {
11
+ keyboardHeightVar,
12
+ keyboardInsetBottomVar,
13
+ mobileRootClassName,
14
+ safeAreaInsetLeftVar,
15
+ safeAreaInsetRightVar,
16
+ safeAreaInsetTopVar,
17
+ safeAreaInsetBottomVar,
18
+ } from "./mobile-styles";
19
+
20
+ export const layoutStyles = css`
21
+ :global() {
22
+ html:root {
23
+ ${safeAreaInsetLeftVar}: var(--app-safe-area-inset-left, env(safe-area-inset-left));
24
+ ${safeAreaInsetRightVar}: var(--app-safe-area-inset-right, env(safe-area-inset-right));
25
+ ${safeAreaInsetTopVar}: var(--app-safe-area-inset-top, env(safe-area-inset-top));
26
+ ${safeAreaInsetBottomVar}: var(--app-safe-area-inset-bottom, env(safe-area-inset-bottom));
27
+ ${keyboardInsetBottomVar}: var(--app-current-keyboard-height, 0px);
28
+ ${keyboardHeightVar}: 350px;
29
+
30
+ ${menuItemHeightVar}: ${layout.menuItemHeight}px;
31
+ ${sidebarMenuItemHeightVar}: ${layout.newMenuItemHeight}px;
32
+ ${sidebarMenuIconSizeVar}: ${layout.newMenuIconSize}px;
33
+ ${listRowSurfaceFontSizeVar}: ${textStyles.regular.fontSize}px;
34
+
35
+ &.${mobileRootClassName} {
36
+ ${menuItemHeightVar}: ${layout.mobileMenuItemHeight}px;
37
+ ${sidebarMenuItemHeightVar}: ${layout.mobileSidebarMenuItemHeight}px;
38
+ ${sidebarMenuIconSizeVar}: ${layout.mobileSidebarIconSize}px;
39
+ ${listRowSurfaceFontSizeVar}: ${textStyles.big.fontSize}px;
40
+ }
41
+ }
42
+ }
43
+ `;
@@ -7,6 +7,7 @@ import {useActionsMenuContext} from "../actions-menu";
7
7
  import {ActionsMenuItemProps} from "../actions-menu/actions-menu-item";
8
8
  import {useActiveDangerousRow, useSetActiveDangerousRow} from "../actions-menu/contexts/actions-menu-dangerous-rows";
9
9
  import {colors, layout, lineHeight, space, textStyles, themeVars} from "../design-system";
10
+ import {useIsSupportHover} from "../use-is-support-hover";
10
11
  import {
11
12
  ListRowContent,
12
13
  ListRowContentProps,
@@ -66,6 +67,7 @@ export const actionMenuItemSurface = css`
66
67
  export const ActionMenuItemSurface = forwardRef<HTMLDivElement, ActionMenuItemSurfaceProps>(
67
68
  ({testId, className, loading, selected, hovered, focused, title, disabled, children, dangerous, ...props}, ref) => {
68
69
  const id = useId();
70
+ const platformSupportsHover = useIsSupportHover();
69
71
  const activeDangerousRow = useActiveDangerousRow();
70
72
  const showWarning = activeDangerousRow === id;
71
73
  const onSelect = useCallbackRef(props.onSelect || _.noop);
@@ -100,7 +102,7 @@ export const ActionMenuItemSurface = forwardRef<HTMLDivElement, ActionMenuItemSu
100
102
  listRowSurfaceStylesBase,
101
103
  actionMenuItemSurface,
102
104
  className,
103
- hovered === undefined && NATURAL_HOVER_CLASS,
105
+ platformSupportsHover && hovered === undefined && NATURAL_HOVER_CLASS,
104
106
  focused === undefined && NATURAL_FOCUS_CLASS,
105
107
  focused && "focus",
106
108
  disabled && "done",
@@ -1,6 +1,8 @@
1
1
  import {css, cx} from "@linaria/core";
2
2
  import {ForwardedRef, forwardRef, HTMLAttributes, PropsWithChildren, ReactNode} from "react";
3
- import {border, space, textStyles, themeVars, transition} from "../design-system";
3
+ import {border, layoutVars, space, textStyles, themeVars, transition} from "../design-system";
4
+ import {useIsSupportHover} from "../use-is-support-hover";
5
+ import {mobileRootSelector} from "../mobile-styles";
4
6
 
5
7
  interface ListRowSurfaceBase extends HTMLAttributes<HTMLDivElement> {
6
8
  testId?: string;
@@ -28,6 +30,7 @@ export const listRowSurfaceStylesBase = css`
28
30
  padding: 0 ${space.s4}px;
29
31
  column-gap: ${space.s4}px;
30
32
  ${{...textStyles.regular}};
33
+ font-size: ${layoutVars.listRowSurfaceFontSize};
31
34
  color: ${themeVars.textColor};
32
35
  border-radius: ${border.radius6}px;
33
36
  transition: background-color ${transition};
@@ -151,6 +154,7 @@ export const listRowSurfaceStatesDark = css`
151
154
 
152
155
  export const ListRowSurface = forwardRef<HTMLDivElement, ListRowSurfaceProps>(
153
156
  ({selected, focused, darker, hovered, done, className, children, ...rest}, ref) => {
157
+ const platformSupportsHover = useIsSupportHover();
154
158
  return (
155
159
  <div
156
160
  {...rest}
@@ -158,7 +162,7 @@ export const ListRowSurface = forwardRef<HTMLDivElement, ListRowSurfaceProps>(
158
162
  listRowSurfaceStylesBase,
159
163
  darker ? listRowSurfaceStatesDark : listRowSurfaceStatesDefault,
160
164
  className,
161
- hovered === undefined && NATURAL_HOVER_CLASS,
165
+ platformSupportsHover && hovered === undefined && NATURAL_HOVER_CLASS,
162
166
  focused === undefined && NATURAL_FOCUS_CLASS,
163
167
  focused && "focus",
164
168
  hovered && "hover",
@@ -203,6 +207,9 @@ const ListRowContentSegment = css`
203
207
  min-width: 0; // allows ellipsis in flex contexts :)
204
208
  max-width: 100%;
205
209
  width: 100%;
210
+ ${mobileRootSelector} & {
211
+ ${textStyles.big}
212
+ }
206
213
  `;
207
214
  export const ListRowContent = forwardRef<HTMLDivElement, ListRowContentProps>(
208
215
  (
package/src/loaders.tsx CHANGED
@@ -105,7 +105,7 @@ const ContainerSpinner = styled.div<{containerSize: number}>`
105
105
  `;
106
106
 
107
107
  type Props = {
108
- size?: number;
108
+ iconSize?: number;
109
109
  containerSize?: number;
110
110
  width?: number;
111
111
  color?: string;
@@ -114,7 +114,7 @@ type Props = {
114
114
 
115
115
  export const Spinner = memo<Props>(
116
116
  ({
117
- size = 20,
117
+ iconSize = 20,
118
118
  containerSize = 15,
119
119
  width = 2,
120
120
  color = themeVars.iconColor,
@@ -122,14 +122,14 @@ export const Spinner = memo<Props>(
122
122
  }) => {
123
123
  const style = useMemo(() => {
124
124
  return {
125
- width: size,
126
- height: size,
127
- ...getShiftStyle({elementSize: size, containerSize}),
125
+ width: iconSize,
126
+ height: iconSize,
127
+ ...getShiftStyle({elementSize: iconSize, containerSize}),
128
128
  borderWidth: width,
129
129
  borderColor: backgroundColor,
130
130
  borderTopColor: color,
131
131
  };
132
- }, [backgroundColor, color, containerSize, size, width]);
132
+ }, [backgroundColor, color, containerSize, iconSize, width]);
133
133
 
134
134
  return (
135
135
  <ContainerSpinner containerSize={containerSize}>
package/src/logo.tsx CHANGED
@@ -10,40 +10,47 @@ export const Logo: FC<LogoProps> = ({size = 40}) => {
10
10
  return (
11
11
  <svg width={size} height={size} viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
12
12
  <path
13
- d="M4.03423 14.4218C3.21412 13.9208 2.98021 12.7899 3.50892 12.0007L9.78271 2.68903C10.3144 1.96674 11.3497 1.78689 12.0902 2.296C12.8324 2.80633 13.0464 3.84401 12.577 4.61037L6.30323 13.9221C5.81148 14.6516 4.79323 14.8855 4.03423 14.4218Z"
13
+ d="M3.5181 14.7077C2.61266 14.1545 2.35441 12.906 2.93813 12.0346L9.86469 1.75412C10.4517 0.956677 11.5947 0.758115 12.4123 1.3202C13.2317 1.88362 13.468 3.02927 12.9497 3.87537L6.02318 14.156C5.48027 14.9614 4.35607 15.2196 3.5181 14.7077Z"
14
14
  fill="#4FC5B3"
15
15
  />
16
16
  <path
17
- d="M12.5824 5.76052L14.4262 5.62076C15.0707 5.57197 15.7022 5.909 16.0235 6.47175C16.4824 7.27568 16.2062 8.3398 15.4042 8.80787L7.37161 13.4944L12.5824 5.76052Z"
17
+ d="M12.9561 5.1453L14.9917 4.99099C15.7033 4.93713 16.4005 5.30922 16.7552 5.93053C17.2619 6.8181 16.9569 7.99294 16.0715 8.50971L7.20312 13.6839L12.9561 5.1453Z"
18
18
  fill="#4FC5B3"
19
19
  />
20
20
  <path
21
- d="M7.9007 15.2941L7.54998 14.143L9.39081 13.069L10.9608 13.6928L11.1421 14.2861C11.4113 15.1703 10.9111 16.1473 10.0244 16.4244C9.13418 16.6992 8.17086 16.1782 7.9007 15.2941Z"
21
+ d="M7.78663 15.671L7.39941 14.4001L9.43178 13.2144L11.1651 13.9031L11.3653 14.5581C11.6625 15.5343 11.1102 16.6129 10.1313 16.9189C9.14845 17.2223 8.08489 16.6471 7.78663 15.671Z"
22
22
  fill="#4FC5B3"
23
23
  />
24
24
  <path
25
- d="M13.8573 10.463L10.1048 12.6524L13.1951 13.8803C14.1762 14.262 15.2829 13.6203 15.4739 12.6003C15.6223 11.8078 15.1831 10.9898 14.4313 10.6908L13.8573 10.463Z"
25
+ d="M14.3627 10.3369L10.2197 12.7541L13.6316 14.1098C14.7147 14.5312 15.9366 13.8227 16.1475 12.6966C16.3113 11.8216 15.8264 10.9185 14.9964 10.5884L14.3627 10.3369Z"
26
26
  fill="#4FC5B3"
27
27
  />
28
28
  <path
29
- d="M6.62886 6.21191L4.19346 9.82661C3.94456 9.84546 3.69329 9.87829 3.44344 9.87829C2.53771 9.87954 1.78415 9.13161 1.75116 8.23166C1.71817 7.33154 2.41483 6.52941 3.31826 6.46286L6.62886 6.21191Z"
29
+ d="M6.38255 5.64331L3.69375 9.63411C3.41895 9.65492 3.14154 9.69117 2.86569 9.69117C1.86572 9.69255 1.03376 8.8668 0.997336 7.87321C0.960913 6.87944 1.73006 5.99385 2.72749 5.92037L6.38255 5.64331Z"
30
30
  fill="#4FC5B3"
31
31
  />
32
32
  <path
33
- d="M7.47702 2.86321L8.28896 3.74803L7.052 5.58397L5.46788 5.70755L4.99456 5.19028C4.36761 4.50647 4.40795 3.40642 5.08509 2.77166C5.76095 2.13811 6.85128 2.1807 7.47702 2.86321Z"
33
+ d="M7.31897 1.94643L8.21539 2.92332L6.84973 4.95028L5.10078 5.08672L4.57821 4.51563C3.88603 3.76067 3.93057 2.54616 4.67816 1.84536C5.42435 1.14589 6.62812 1.19291 7.31897 1.94643Z"
34
34
  fill="#4FC5B3"
35
35
  />
36
36
  </svg>
37
37
  );
38
38
  };
39
39
 
40
- const logoPadding = (layout.newMenuIconSize - layout.logoSize) / 2;
41
-
42
40
  export const logoContainerStyle = css`
43
41
  ${{
44
- padding: logoPadding,
45
42
  width: layout.newMenuIconSize,
46
43
  height: layout.newMenuIconSize,
47
44
  lineHeight: 0,
48
45
  }}
49
46
  `;
47
+
48
+ export const mobileLogoSize = 28;
49
+
50
+ export const mobileLogoContainerStyle = css`
51
+ ${{
52
+ width: mobileLogoSize,
53
+ height: mobileLogoSize,
54
+ lineHeight: 0,
55
+ }}
56
+ `;
@@ -0,0 +1,87 @@
1
+ import {ReactNode, useEffect, useRef} from "react";
2
+ import {createPortal} from "react-dom";
3
+ import _ from "lodash";
4
+ import {css, cx} from "@linaria/core";
5
+ import {border, space, themeVars} from "./design-system";
6
+ import {keyboardInsetBottomVar, safeAreaInsetBottomVar} from "./mobile-styles";
7
+
8
+ export const mobileKeyboardAwarePopupZIndex = 1001;
9
+
10
+ export function MobileKeyboardAwarePopup({children, className}: {children: ReactNode; className?: string}) {
11
+ const ref = useRef<HTMLDivElement>(null);
12
+ useEffect(() => {
13
+ const viewport = window.visualViewport;
14
+ if (!viewport) {
15
+ return _.noop;
16
+ }
17
+
18
+ const manualKeyboardModeHandler = document.documentElement.classList.contains("fibery-manual-keyboard-mode");
19
+
20
+ let pendingUpdate = false;
21
+ const layoutViewport = document.getElementById("root") as HTMLDivElement;
22
+ const timeoutId = setTimeout(() => {
23
+ if (viewport.offsetTop >= 0 && ref.current) {
24
+ ref.current.style.transform = `translateY(${
25
+ manualKeyboardModeHandler
26
+ ? viewport.offsetTop
27
+ : viewport.height - layoutViewport.getBoundingClientRect().height + viewport.offsetTop
28
+ }px)`;
29
+ }
30
+ }, 0);
31
+
32
+ function viewportHandler() {
33
+ clearTimeout(timeoutId);
34
+ if (pendingUpdate) {
35
+ return;
36
+ }
37
+ pendingUpdate = true;
38
+
39
+ requestAnimationFrame(() => {
40
+ pendingUpdate = false;
41
+
42
+ if (viewport && viewport.offsetTop >= 0 && ref.current) {
43
+ ref.current.style.transform = `translateY(${
44
+ manualKeyboardModeHandler
45
+ ? viewport.offsetTop
46
+ : viewport.height - layoutViewport.getBoundingClientRect().height + viewport.offsetTop
47
+ }px)`;
48
+ }
49
+ });
50
+ }
51
+
52
+ viewport.addEventListener("scroll", viewportHandler);
53
+ viewport.addEventListener("resize", viewportHandler);
54
+ return () => {
55
+ clearTimeout(timeoutId);
56
+ viewport.removeEventListener("scroll", viewportHandler);
57
+ viewport.removeEventListener("resize", viewportHandler);
58
+ };
59
+ }, []);
60
+ return createPortal(
61
+ <div
62
+ ref={ref}
63
+ className={cx(
64
+ css`
65
+ box-shadow: ${themeVars.shadow200};
66
+ background-color: ${themeVars.actionMenuBg};
67
+ position: fixed;
68
+ bottom: max(max(var(${keyboardInsetBottomVar}), var(${safeAreaInsetBottomVar})), 8px);
69
+ left: 0;
70
+ right: 0;
71
+ z-index: ${mobileKeyboardAwarePopupZIndex};
72
+ transform: translateY(0px);
73
+ border-radius: ${border.radius16}px;
74
+ border: 1px solid ${themeVars.separatorColor};
75
+ margin: 0 ${space.s8}px;
76
+ .fibery-manual-keyboard-mode & {
77
+ margin-bottom: 8px;
78
+ }
79
+ `,
80
+ className
81
+ )}
82
+ >
83
+ {children}
84
+ </div>,
85
+ document.body
86
+ );
87
+ }