@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
@@ -14,7 +14,10 @@ import {
14
14
  import {forwardRef, ReactNode, RefObject, useLayoutEffect, useRef} from "react";
15
15
  import {border, fontWeight, space, textStyles, themeVars} from "../design-system";
16
16
  import {ellipsis} from "../styles-utils";
17
+ import {mobileRootSelector} from "../mobile-styles";
17
18
  import {TooltipIfOverflown} from "../tooltip-if-overflown";
19
+ import {useCallbackRef} from "@fibery/react/src/use-callback-ref";
20
+ import {useResizeObserver} from "@fibery/react/src/use-resize-observer";
18
21
 
19
22
  const tabNavIndicatorWidth = 100;
20
23
 
@@ -33,6 +36,10 @@ const tabNavItem = css`
33
36
  list-style: none;
34
37
  `;
35
38
 
39
+ const tabNavItemWide = css`
40
+ flex: 1 0 0;
41
+ `;
42
+
36
43
  const tabButton = css`
37
44
  all: unset;
38
45
  display: flex;
@@ -52,23 +59,40 @@ const tabButton = css`
52
59
  font-weight: ${fontWeight.medium};
53
60
  line-height: 16px;
54
61
 
55
- &:hover,
56
- &:focus-visible {
57
- background-color: ${themeVars.colorBgTabHover};
58
- color: ${themeVars.textColor};
62
+ @media (any-hover: hover) {
63
+ &:hover {
64
+ background-color: ${themeVars.colorBgTabHover};
65
+ color: ${themeVars.textColor};
66
+ }
59
67
  }
60
68
 
61
69
  &:focus-visible {
70
+ color: ${themeVars.textColor};
71
+ background-color: ${themeVars.colorBgTabHover};
62
72
  outline: 2px solid ${themeVars.colorBorderNeutralFocusRing};
63
73
  }
64
74
 
65
75
  &[data-active] {
66
76
  color: ${themeVars.textColor};
67
77
  }
78
+
79
+ .${tabNavItemWide} & {
80
+ justify-content: center;
81
+ text-align: center;
82
+ }
83
+
84
+ ${mobileRootSelector} & {
85
+ padding: ${space.s4}px ${space.s8}px ${space.s8}px ${space.s4}px;
86
+ font-size: ${textStyles.regular.fontSize}px;
87
+ }
68
88
  `;
69
89
 
70
90
  const tabNavButtonText = css`
71
91
  padding: 0 ${space.s4}px;
92
+
93
+ ${mobileRootSelector} & {
94
+ padding: 0 ${space.s6}px;
95
+ }
72
96
  `;
73
97
 
74
98
  const tabNavIndicatorTrack = css`
@@ -124,43 +148,34 @@ export const TabNavList = forwardRef<HTMLUListElement, NavigationMenuListProps>(
124
148
  }
125
149
  );
126
150
 
127
- const useTabNavIndicator = (
128
- {
129
- active,
130
- itemRef,
131
- }: {
132
- active?: boolean;
133
- itemRef: RefObject<HTMLElement>;
134
- },
135
- deps: Array<unknown> = []
136
- ) => {
151
+ const useTabNavIndicator = ({active, itemRef}: {active?: boolean; itemRef: RefObject<HTMLElement>}) => {
137
152
  const indicatorRef = useTabNavIndicatorCtx();
138
153
 
139
- useLayoutEffect(() => {
154
+ const updateIndicator = useCallbackRef(() => {
140
155
  if (active && itemRef.current && indicatorRef.current) {
141
156
  indicatorRef.current.style.transform = `translateX(${itemRef.current.offsetLeft}px) scaleX(${
142
157
  itemRef.current.offsetWidth / tabNavIndicatorWidth
143
158
  })`;
144
159
  indicatorRef.current.classList.add(tabNavIndicatorMounted);
145
160
  }
146
- }, [
147
- active,
148
- indicatorRef,
149
- itemRef,
150
- // eslint-disable-next-line react-hooks/exhaustive-deps
151
- ...deps,
152
- ]);
161
+ });
162
+
163
+ useLayoutEffect(() => {
164
+ updateIndicator();
165
+ }, [updateIndicator, active, indicatorRef, itemRef]);
166
+
167
+ useResizeObserver(itemRef, () => updateIndicator());
153
168
  };
154
169
 
155
- export const TabNavItem = forwardRef<HTMLLIElement, NavigationMenuItemProps & {active?: boolean}>(
156
- ({className, children, active, ...props}, forwardedRef) => {
170
+ export const TabNavItem = forwardRef<HTMLLIElement, NavigationMenuItemProps & {active?: boolean; wide?: boolean}>(
171
+ ({className, children, active, wide, ...props}, forwardedRef) => {
157
172
  const itemRef = useRef(null);
158
173
  const ref = useComposedRefs(itemRef, forwardedRef);
159
174
 
160
- useTabNavIndicator({active, itemRef}, [children]);
175
+ useTabNavIndicator({active, itemRef});
161
176
 
162
177
  return (
163
- <NavigationMenuItem ref={ref} className={cx(tabNavItem, className)} {...props}>
178
+ <NavigationMenuItem ref={ref} className={cx(tabNavItem, wide && tabNavItemWide, className)} {...props}>
164
179
  {children}
165
180
  </NavigationMenuItem>
166
181
  );
@@ -172,9 +187,13 @@ export const TabNavLink = forwardRef<
172
187
  Omit<NavigationMenuLinkProps, "asChild"> & {
173
188
  before?: ReactNode;
174
189
  after?: ReactNode;
190
+ wide?: boolean;
175
191
  itemClassName?: string;
176
192
  }
177
- >(function TabNavLink({children, className, itemClassName, active, before, after, href, ...linkProps}, forwardedRef) {
193
+ >(function TabNavLink(
194
+ {children, className, itemClassName, active, wide, before, after, href, ...linkProps},
195
+ forwardedRef
196
+ ) {
178
197
  const renderAsButton = typeof href === "undefined";
179
198
 
180
199
  const Component = renderAsButton ? "button" : "a";
@@ -185,7 +204,7 @@ export const TabNavLink = forwardRef<
185
204
  return (
186
205
  <TooltipIfOverflown title={children}>
187
206
  {({setNode}) => (
188
- <TabNavItem className={itemClassName} active={active}>
207
+ <TabNavItem className={itemClassName} active={active} wide={wide}>
189
208
  <NavigationMenuLink
190
209
  ref={forwardedRef}
191
210
  className={cx(tabButton, className)}
@@ -1,6 +1,7 @@
1
1
  import invariant from "invariant";
2
2
  import {themeStyles} from "./theme-styles";
3
- import {createContext, ReactNode, useContext, useEffect, useState} from "react";
3
+ import {layoutStyles} from "./layout-styles";
4
+ import {createContext, ReactNode, useContext, useEffect, useLayoutEffect, useState} from "react";
4
5
  import {colors, getThemeColors, ThemeColors} from "./design-system";
5
6
  import {
6
7
  subscribeOnThemeMenuPreferenceChange,
@@ -86,6 +87,13 @@ export function RootThemeProvider({
86
87
  unsubscribeMenuPreference();
87
88
  };
88
89
  }, []);
90
+ useLayoutEffect(() => {
91
+ const documentElement = document.documentElement;
92
+ documentElement.classList.add(layoutStyles);
93
+ return () => {
94
+ documentElement.classList.remove(layoutStyles);
95
+ };
96
+ }, []);
89
97
  useEffect(() => {
90
98
  const darkThemeClassName = "dark-theme";
91
99
  const lightThemeAndDarkMenuClassName = "light-theme-and-dark-menu";
@@ -5,6 +5,12 @@ import {ElementRef, forwardRef} from "react";
5
5
  import {IconButton} from "../button/icon-button";
6
6
  import {border, space, textStyles, themeVars, transition} from "../design-system";
7
7
  import CloseIcon from "../icons/react/Close";
8
+ import {
9
+ safeAreaInsetBottomVar,
10
+ safeAreaInsetLeftVar,
11
+ safeAreaInsetRightVar,
12
+ safeAreaInsetTopVar,
13
+ } from "../mobile-styles";
8
14
 
9
15
  const viewportCss = css`
10
16
  position: fixed;
@@ -17,7 +23,8 @@ const viewportCss = css`
17
23
  gap: ${space.s16}px;
18
24
  margin: 0;
19
25
  z-index: 1010; // inherited from old toast implementation
20
- padding: 0;
26
+ padding: var(${safeAreaInsetTopVar}) var(${safeAreaInsetRightVar}) var(${safeAreaInsetBottomVar})
27
+ var(${safeAreaInsetLeftVar});
21
28
  list-style: none;
22
29
 
23
30
  transition: bottom ${transition}; // bottom may change dynamically
@@ -0,0 +1,23 @@
1
+ import {ComponentRef, forwardRef} from "react";
2
+ import {ToggleButton, ToggleButtonProps} from "./toggle-button";
3
+ import {css, cx} from "@linaria/core";
4
+
5
+ const roundToggleButtonCss = css`
6
+ &:is(&) {
7
+ border-radius: 100%;
8
+ width: 28px;
9
+ height: 28px;
10
+ padding: 0;
11
+ justify-content: center;
12
+ }
13
+ `;
14
+
15
+ export const RoundToggleButton = forwardRef<ComponentRef<typeof ToggleButton>, Omit<ToggleButtonProps, "iconStart">>(
16
+ function RoundToggleButton({children, className, ...props}, ref) {
17
+ return (
18
+ <ToggleButton ref={ref} className={cx(roundToggleButtonCss, className)} {...props}>
19
+ {children}
20
+ </ToggleButton>
21
+ );
22
+ }
23
+ );
@@ -0,0 +1,34 @@
1
+ import {css, cx} from "@linaria/core";
2
+ import {
3
+ ToggleGroup,
4
+ ToggleGroupItem,
5
+ ToggleGroupItemProps,
6
+ ToggleGroupMultipleProps,
7
+ ToggleGroupSingleProps,
8
+ } from "@radix-ui/react-toggle-group";
9
+ import {ComponentRef, forwardRef} from "react";
10
+ import {ToggleButton, ToggleButtonProps} from "./toggle-button";
11
+ import {space} from "../design-system";
12
+
13
+ export const toggleButtonGroupCss = css`
14
+ display: flex;
15
+ flex-direction: row;
16
+ `;
17
+
18
+ export const ToggleButtonGroup = forwardRef<
19
+ ComponentRef<typeof ToggleGroup>,
20
+ (ToggleGroupSingleProps | ToggleGroupMultipleProps) & {gap?: number}
21
+ >(function ToggleButtonGroup({className, gap = space.s4, ...props}, ref) {
22
+ return <ToggleGroup ref={ref} style={{gap}} className={cx(toggleButtonGroupCss, className)} {...props} />;
23
+ });
24
+
25
+ export const ToggleButtonGroupItem = forwardRef<
26
+ ComponentRef<typeof ToggleGroupItem>,
27
+ ToggleGroupItemProps & ToggleButtonProps
28
+ >(function ToggleButtonGroupItem({className, children, asChild, ...props}, ref) {
29
+ return (
30
+ <ToggleGroupItem ref={ref} className={className} {...props} asChild>
31
+ {asChild ? children : <ToggleButton>{children}</ToggleButton>}
32
+ </ToggleGroupItem>
33
+ );
34
+ });
@@ -0,0 +1,164 @@
1
+ import {css, cx} from "@linaria/core";
2
+ import {Toggle, ToggleProps} from "@radix-ui/react-toggle";
3
+ import {forwardRef} from "react";
4
+ import {border, space, textStyles, themeVars} from "../design-system";
5
+ import {iconColorVar, iconSizeVar} from "../icons/Icon";
6
+
7
+ export const toggleButtonCss = css`
8
+ button:where(&) {
9
+ all: unset;
10
+ }
11
+
12
+ padding-inline: ${space.s6}px;
13
+ box-sizing: border-box;
14
+ display: flex;
15
+ align-items: center;
16
+ min-height: 24px;
17
+ font-size: ${textStyles.small.fontSize}px;
18
+ border-radius: ${border.radius8}px;
19
+
20
+ transition-property: border, background-color, color, opacity, box-shadow;
21
+ transition-duration: 0.15s;
22
+
23
+ color: ${themeVars.textColor};
24
+ ${iconColorVar}: ${themeVars.colorIconButtonGhostNeutral};
25
+
26
+ ${iconSizeVar}: 16px;
27
+
28
+ border: 1.5px solid ${themeVars.colorBorderReactionsHover};
29
+ background-color: ${themeVars.colorBgReactionsDefault};
30
+
31
+ &[aria-readonly="true"] {
32
+ background-color: ${themeVars.colorBgReactionsHover};
33
+ border-color: ${themeVars.colorBgReactionsHover};
34
+ }
35
+
36
+ cursor: pointer;
37
+ line-height: 16px;
38
+ user-select: none;
39
+
40
+ &[data-size="medium"] {
41
+ min-height: 28px;
42
+ }
43
+
44
+ &[data-size="large"] {
45
+ min-height: 32px;
46
+ padding-inline: 7px;
47
+ }
48
+
49
+ &:not(:disabled, [aria-readonly="true"]) {
50
+ &:hover {
51
+ background-color: ${themeVars.colorBgReactionsHover};
52
+ border-color: ${themeVars.colorBorderReactionsHover};
53
+ }
54
+
55
+ &:is(:active, [aria-expanded="true"]) {
56
+ background-color: ${themeVars.colorBgReactionsHover};
57
+ border-color: ${themeVars.colorBorderReactionsHover};
58
+ }
59
+ }
60
+
61
+ &:disabled,
62
+ &[aria-readonly="true"] {
63
+ cursor: default;
64
+ }
65
+
66
+ &:focus {
67
+ outline: none;
68
+ }
69
+
70
+ &:focus-visible {
71
+ background-color: ${themeVars.colorBgReactionsHover};
72
+ outline: 2px solid ${themeVars.colorBorderReactionsHover};
73
+ }
74
+
75
+ &:is([aria-pressed="true"], [aria-checked="true"]) {
76
+ color: ${themeVars.colorTextReactionsSelected};
77
+ ${iconColorVar}: ${themeVars.colorIconButtonGhostAccent};
78
+ background-color: ${themeVars.colorBgReactionsSelectedDefault};
79
+ border-color: ${themeVars.colorBorderReactionsSelectedDefault};
80
+
81
+ &[aria-readonly="true"] {
82
+ background-color: ${themeVars.colorBgReactionsSelectedDefault};
83
+ border-color: ${themeVars.colorBgReactionsSelectedDefault};
84
+ }
85
+
86
+ &:not(:disabled, [aria-readonly="true"]) {
87
+ &:hover {
88
+ background-color: ${themeVars.colorBgReactionsSelectedHover};
89
+ border-color: ${themeVars.colorBorderReactionsSelectedHover};
90
+ }
91
+
92
+ &:active {
93
+ background-color: ${themeVars.colorBgReactionsSelectedDefault};
94
+ border-color: ${themeVars.colorBorderReactionsSelectedHover};
95
+ }
96
+ }
97
+ }
98
+ `;
99
+
100
+ export const toggleButtonCssWithIconStart = css`
101
+ padding-left: ${space.s4}px;
102
+ `;
103
+
104
+ export const toggleButtonContent = css`
105
+ display: flex;
106
+ align-items: center;
107
+ gap: ${space.s4}px;
108
+ height: 100%;
109
+
110
+ transition-property: opacity;
111
+ transition-duration: 0.15s;
112
+
113
+ .${toggleButtonCss}:is(:active, [aria-expanded="true"]) > & {
114
+ opacity: 0.8;
115
+ }
116
+
117
+ .${toggleButtonCss}:disabled > & {
118
+ opacity: 0.6;
119
+ }
120
+
121
+ overflow: hidden;
122
+ `;
123
+
124
+ export type ToggleButtonVariant = "outline";
125
+ export type ToggleButtonSize = "small" | "medium" | "large";
126
+
127
+ export type ToggleButtonProps = {
128
+ iconStart?: React.ReactNode;
129
+ variant?: ToggleButtonVariant;
130
+ size?: ToggleButtonSize;
131
+ readOnly?: boolean;
132
+ } & Omit<ToggleProps, "asChild">;
133
+
134
+ export const ToggleButton = forwardRef<HTMLButtonElement, ToggleButtonProps>(
135
+ (
136
+ {
137
+ className,
138
+ iconStart,
139
+ size = "small",
140
+ variant = "outline",
141
+ children,
142
+ "aria-readonly": ariaReadonly,
143
+ readOnly = ariaReadonly,
144
+ ...props
145
+ },
146
+ ref
147
+ ): JSX.Element => {
148
+ return (
149
+ <Toggle
150
+ ref={ref}
151
+ className={cx(toggleButtonCss, iconStart && toggleButtonCssWithIconStart, className)}
152
+ data-variant={variant}
153
+ data-size={size}
154
+ aria-readonly={readOnly}
155
+ {...props}
156
+ >
157
+ <div className={toggleButtonContent}>
158
+ {iconStart}
159
+ {children}
160
+ </div>
161
+ </Toggle>
162
+ );
163
+ }
164
+ );
package/src/toggle.tsx CHANGED
@@ -2,7 +2,7 @@ import {css, cx} from "@linaria/core";
2
2
  import {styled} from "@linaria/react";
3
3
  import chroma from "chroma-js";
4
4
  import {ComponentProps, FC, ReactNode} from "react";
5
- import {layout, space, textStyles, transition} from "./design-system";
5
+ import {space, textStyles, transition} from "./design-system";
6
6
  import _ from "lodash";
7
7
  import SpinnerIcon from "./icons/react/Spinner";
8
8
 
@@ -26,7 +26,8 @@ const Input = styled.input<{outlineColor: string}>`
26
26
  }
27
27
 
28
28
  &:focus-visible {
29
- box-shadow: ${({outlineColor}) => `inset 0 0 0 1px ${outlineColor}`};
29
+ outline: ${({outlineColor}) => `2px solid ${outlineColor}`};
30
+ outline-offset: 1px;
30
31
  }
31
32
  `;
32
33
 
@@ -34,7 +35,6 @@ const Label = styled.div<{labelPosition: "last" | "first"; disabled?: boolean}>`
34
35
  margin-left: ${({labelPosition}) => (labelPosition === "last" ? `${space.s8}px` : 0)};
35
36
  margin-right: ${({labelPosition}) => (labelPosition === "first" ? `${space.s8}px` : 0)};
36
37
  opacity: ${({disabled}) => (disabled ? 0.5 : 1)};
37
- line-height: ${layout.checkboxSize}px;
38
38
  width: 100%;
39
39
  min-width: 0;
40
40
  `;
@@ -4,9 +4,7 @@ import {Tooltip, TooltipProps} from "./tooltip";
4
4
 
5
5
  type SetNode = (element: HTMLElement | null) => void;
6
6
 
7
- export const TooltipIfOverflown: React.FC<
8
- Omit<TooltipProps, "children"> & {children: (args: {setNode: SetNode}) => JSX.Element | null}
9
- > = ({children, ...tooltipProps}) => {
7
+ export const useTruncated = () => {
10
8
  const [truncated, setTruncated] = useState(false);
11
9
  const [node, setNode] = useState<HTMLElement | null>(null);
12
10
 
@@ -18,6 +16,14 @@ export const TooltipIfOverflown: React.FC<
18
16
  : target.scrollWidth > target.clientWidth;
19
17
  setTruncated(truncated);
20
18
  });
19
+
20
+ return {setNode, truncated};
21
+ };
22
+
23
+ export const TooltipIfOverflown: React.FC<
24
+ Omit<TooltipProps, "children"> & {children: (args: {setNode: SetNode}) => JSX.Element | null}
25
+ > = ({children, ...tooltipProps}) => {
26
+ const {truncated, setNode} = useTruncated();
21
27
  return (
22
28
  <Tooltip {...tooltipProps} disabled={!truncated}>
23
29
  {children({setNode})}
package/src/tooltip.tsx CHANGED
@@ -24,10 +24,10 @@ const descriptionStyle = css`
24
24
  `;
25
25
 
26
26
  export const tooltipStyle = css`
27
- font-size: 13px;
27
+ font-size: 12px;
28
28
  color: ${themeVars.whiteColor};
29
29
  z-index: 100000;
30
- min-height: 30px;
30
+ min-height: 28px;
31
31
  max-width: 300px;
32
32
  background-color: ${themeVars.tooltipBgColor};
33
33
  padding: ${space.s6}px ${space.s8}px;
@@ -51,5 +51,13 @@ export const OptionUnit = (props: UnitPrimitiveProps) => {
51
51
  };
52
52
 
53
53
  export const HistoryUnit = (props: UnitPrimitiveProps & {size: CardSize}) => {
54
- return <UnitPrimitive big={props.size === ":card-size/cell"} bgColor={themeVars.unitBg} border={false} {...props} />;
54
+ return (
55
+ <UnitPrimitive
56
+ big={props.size === ":card-size/cell"}
57
+ bgColor={themeVars.unitBg}
58
+ border={false}
59
+ tooltip={false}
60
+ {...props}
61
+ />
62
+ );
55
63
  };
@@ -2,6 +2,7 @@ import {css} from "@linaria/core";
2
2
  import {LoadingSausage, LoadingSausageProps} from "../loading-sausage";
3
3
 
4
4
  export const unitTextHeight = 8;
5
+
5
6
  export const LoadingUnitValue = (props: LoadingSausageProps) => (
6
7
  <div
7
8
  className={css`
@@ -1,9 +1,9 @@
1
1
  import {LoadingUnitValue} from "./loading-unit-value";
2
2
 
3
- interface MaybeUnitValueProps {
3
+ type Props = {
4
4
  value?: string;
5
- }
5
+ };
6
6
 
7
- export const MaybeUnitValue: React.FC<MaybeUnitValueProps> = ({value}) => {
7
+ export const MaybeUnitValue: React.FC<Props> = ({value}) => {
8
8
  return value === undefined ? <LoadingUnitValue minWidth={18} maxWidth={18} /> : <>{value}</>;
9
9
  };