@fibery/ui-kit 1.37.0 → 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.
- package/CHANGELOG.md +14 -0
- package/package.json +8 -5
- package/src/actions-menu/actions-menu-item.tsx +18 -6
- package/src/actions-menu/actions-menu-props.tsx +4 -0
- package/src/actions-menu/actions-menu-sub-command-menu.tsx +7 -4
- package/src/actions-menu/actions-menu-sub-menu.tsx +9 -3
- package/src/actions-menu/actions-menu.tsx +24 -8
- package/src/actions-panel.tsx +12 -2
- package/src/axis-header.tsx +136 -76
- package/src/box.tsx +1 -1
- package/src/breadcrumb.tsx +78 -0
- package/src/button/actions-button-compact.tsx +4 -1
- package/src/button/base-button.tsx +5 -3
- package/src/button/button-group.tsx +1 -1
- package/src/button/button.tsx +31 -0
- package/src/button/icon-button.tsx +9 -0
- package/src/button/select-button.tsx +4 -0
- package/src/card-container.tsx +7 -4
- package/src/color-picker/swatch.tsx +1 -0
- package/src/command-menu/index.tsx +3 -3
- package/src/context-menu/index.tsx +10 -1
- package/src/date-picker/date-range-picker.tsx +6 -3
- package/src/date-picker/relative-date-picker.tsx +6 -2
- package/src/date-picker/single-date-picker.tsx +8 -5
- package/src/date-picker/styles.ts +32 -26
- package/src/date-picker/types.ts +3 -1
- package/src/day-select/day-select.tsx +21 -75
- package/src/day-select/iso-week-day-select.tsx +1 -1
- package/src/day-select/mount-day-select.tsx +2 -2
- package/src/day-select/week-day-select.tsx +1 -5
- package/src/design-system.ts +21 -12
- package/src/dropdown-menu/index.tsx +8 -1
- package/src/emoji-picker/app-icon-picker.tsx +6 -4
- package/src/emoji-picker/emoji-picker-preview-footer.tsx +1 -1
- package/src/emoji-picker/emoji-picker.tsx +3 -0
- package/src/emoji-picker/emoji.tsx +2 -1
- package/src/emoji-picker/icon-emoji-picker.tsx +10 -1
- package/src/emoji-picker/primitives/footer.tsx +0 -1
- package/src/emoji-picker/primitives/skin-tone.tsx +1 -0
- package/src/emoji-picker/use-responsive-emoji-size.ts +11 -0
- package/src/emoji-picker/utils/emoji-set.ts +2 -1
- package/src/empty-state/empty-state.tsx +6 -0
- package/src/field-icon.tsx +4 -1
- package/src/file-item.tsx +164 -47
- package/src/html-styles.ts +8 -0
- package/src/icons/ast/ActivityFilled.ts +8 -0
- package/src/icons/ast/AiAssistantFilled.ts +8 -0
- package/src/icons/ast/CollapseAllHorizontal.ts +8 -0
- package/src/icons/ast/DateRange.ts +1 -1
- package/src/icons/ast/EntityCreateFilled.ts +8 -0
- package/src/icons/ast/ExpandAllHorizontal.ts +8 -0
- package/src/icons/ast/GlobeUnpublish.ts +8 -0
- package/src/icons/ast/HomeFilled.ts +8 -0
- package/src/icons/ast/KeyboardHideDown.ts +8 -0
- package/src/icons/ast/LayoutMultiple.ts +8 -0
- package/src/icons/ast/RicheditorHistoryRedo.ts +1 -1
- package/src/icons/ast/RicheditorHistoryUndo.ts +1 -1
- package/src/icons/ast/SearchFilled.ts +8 -0
- package/src/icons/ast/SettingsFilled.ts +8 -0
- package/src/icons/ast/SlideMenuFilled.ts +8 -0
- package/src/icons/ast/TypeDate.ts +1 -1
- package/src/icons/ast/index.tsx +12 -0
- package/src/icons/react/ActivityFilled.tsx +13 -0
- package/src/icons/react/AiAssistantFilled.tsx +13 -0
- package/src/icons/react/CollapseAllHorizontal.tsx +13 -0
- package/src/icons/react/EntityCreateFilled.tsx +13 -0
- package/src/icons/react/ExpandAllHorizontal.tsx +13 -0
- package/src/icons/react/GlobeUnpublish.tsx +13 -0
- package/src/icons/react/HomeFilled.tsx +13 -0
- package/src/icons/react/KeyboardHideDown.tsx +13 -0
- package/src/icons/react/LayoutMultiple.tsx +13 -0
- package/src/icons/react/SearchFilled.tsx +13 -0
- package/src/icons/react/SettingsFilled.tsx +13 -0
- package/src/icons/react/SlideMenuFilled.tsx +13 -0
- package/src/icons/react/index.tsx +12 -0
- package/src/icons/svg/activity-filled.svg +4 -0
- package/src/icons/svg/ai-assistant-filled.svg +3 -0
- package/src/icons/svg/collapse-all-horizontal.svg +3 -0
- package/src/icons/svg/date-range.svg +3 -3
- package/src/icons/svg/entity-create-filled.svg +4 -0
- package/src/icons/svg/expand-all-horizontal.svg +3 -0
- package/src/icons/svg/globe-unpublish.svg +4 -0
- package/src/icons/svg/home-filled.svg +3 -0
- package/src/icons/svg/keyboard-hide-down.svg +1 -0
- package/src/icons/svg/layout-multiple.svg +3 -0
- package/src/icons/svg/richeditor/history/redo.svg +3 -2
- package/src/icons/svg/richeditor/history/undo.svg +3 -2
- package/src/icons/svg/search-filled.svg +3 -0
- package/src/icons/svg/settings-filled.svg +3 -0
- package/src/icons/svg/slide-menu-filled.svg +1 -0
- package/src/icons/svg/type/date.svg +3 -2
- package/src/images-gallery/images-gallery.tsx +254 -0
- package/src/images-gallery/zoom.tsx +112 -0
- package/src/is-in-popup.ts +1 -1
- package/src/layout-styles.ts +21 -1
- package/src/lists/actions-menu-row-surface.tsx +3 -1
- package/src/lists/list-row-surface.tsx +7 -1
- package/src/mobile-keyboard-aware-popup.tsx +87 -0
- package/src/mobile-styles.ts +8 -0
- package/src/modal-menu/contexts/modal-menu-context.tsx +22 -0
- package/src/modal-menu/contexts/modal-submenu-context.tsx +16 -0
- package/src/modal-menu/index.tsx +14 -0
- package/src/modal-menu/modal-menu-content.tsx +68 -0
- package/src/modal-menu/modal-menu-group.tsx +10 -0
- package/src/modal-menu/modal-menu-item.tsx +37 -0
- package/src/modal-menu/modal-menu-label.tsx +24 -0
- package/src/modal-menu/modal-menu-root.tsx +57 -0
- package/src/modal-menu/modal-menu-separator.tsx +14 -0
- package/src/modal-menu/modal-menu-trigger.tsx +37 -0
- package/src/modal-menu/modal-submenu-content.tsx +49 -0
- package/src/modal-menu/modal-submenu-trigger.tsx +34 -0
- package/src/modal-menu/modal-submenu.tsx +17 -0
- package/src/online-users.tsx +3 -3
- package/src/palette.ts +1 -1
- package/src/popover/index.tsx +687 -0
- package/src/popover/mobile-popup-context.tsx +29 -0
- package/src/{popup → popover}/modifiers.tsx +0 -7
- package/src/{popup → popover}/popup-modifiers-context.ts +3 -3
- package/src/reactions/reaction-button.tsx +30 -45
- package/src/reactions/reaction-picker.tsx +39 -45
- package/src/select/index.tsx +8 -4
- package/src/select/select-in-popover.tsx +21 -33
- package/src/tab-nav/tab-nav.tsx +35 -9
- package/src/toast/primitives.tsx +8 -1
- package/src/toggle-button/round-toggle-button.tsx +23 -0
- package/src/toggle-button/toggle-button-group.tsx +34 -0
- package/src/toggle-button/toggle-button.tsx +164 -0
- package/src/toggle.tsx +3 -3
- package/src/tooltip.tsx +2 -2
- package/src/unit/styles.ts +2 -2
- package/src/use-is-phone.tsx +28 -3
- package/src/use-is-support-hover.ts +1 -1
- package/src/use-on-screen-keyboard-data.tsx +66 -0
- package/src/workflow-progress-icon.tsx +16 -22
- package/src/popup/index.tsx +0 -383
- /package/src/{popup → popover}/popup-stack-context.tsx +0 -0
- /package/src/{popup → popover}/reference.ts +0 -0
- /package/src/{popup → popover}/styles.ts +0 -0
- /package/src/{popup → popover}/use-click-outside.ts +0 -0
|
@@ -26,13 +26,6 @@ export const getMaxSize = (overflowOptions: Partial<PreventOverflowOptions>): Po
|
|
|
26
26
|
},
|
|
27
27
|
];
|
|
28
28
|
|
|
29
|
-
export const disableGpuAcceleration = {
|
|
30
|
-
name: "computeStyles",
|
|
31
|
-
options: {
|
|
32
|
-
gpuAcceleration: false,
|
|
33
|
-
},
|
|
34
|
-
} as unknown as PopupModifier;
|
|
35
|
-
|
|
36
29
|
const observeWidthEffect: (arg0: ModifierArguments<Record<string, unknown>>) => void = ({state, instance}) => {
|
|
37
30
|
const {popper, reference} = state.elements;
|
|
38
31
|
|
|
@@ -2,11 +2,11 @@ import {createContext} from "@fibery/react/src/create-context";
|
|
|
2
2
|
import {getPopupContainerElement} from "../utils-dom";
|
|
3
3
|
import {$TSFixMe} from "../tsfixme";
|
|
4
4
|
import {Modifier} from "react-popper";
|
|
5
|
-
import {
|
|
5
|
+
import {PopoverOldProps} from "./index";
|
|
6
6
|
|
|
7
7
|
export const [PopupModifiersProvider, usePopupModifiers] = createContext<{
|
|
8
8
|
getPopupContainer: () => HTMLElement;
|
|
9
9
|
additionalModifiers?: Array<Partial<Modifier<$TSFixMe, $TSFixMe>>>;
|
|
10
|
-
preventOverflowOptions?:
|
|
11
|
-
flipOptions?:
|
|
10
|
+
preventOverflowOptions?: PopoverOldProps["preventOverflowOptions"];
|
|
11
|
+
flipOptions?: PopoverOldProps["flipOptions"];
|
|
12
12
|
}>("PopupModifiersProvider", {getPopupContainer: getPopupContainerElement});
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import {css, cx} from "@linaria/core";
|
|
2
|
-
import {createPortal} from "react-dom";
|
|
3
|
-
import {useLongPress} from "../use-long-press";
|
|
4
2
|
import {Fragment, ReactNode, useState} from "react";
|
|
3
|
+
import {createPortal} from "react-dom";
|
|
4
|
+
import {border, lineHeight, space, themeVars} from "../design-system";
|
|
5
5
|
import {Emoji} from "../emoji-picker/emoji";
|
|
6
|
-
import {
|
|
6
|
+
import {ToggleButton} from "../toggle-button/toggle-button";
|
|
7
7
|
import {Tooltip} from "../tooltip";
|
|
8
8
|
import {useIsPhone} from "../use-is-phone";
|
|
9
|
+
import {safeAreaInsetBottomVar} from "../mobile-styles";
|
|
10
|
+
import {useLongPress} from "../use-long-press";
|
|
9
11
|
import {getWordDivider} from "./get-word-divider";
|
|
10
12
|
|
|
11
13
|
export type Reaction = {
|
|
@@ -22,6 +24,7 @@ type Props = {
|
|
|
22
24
|
onSelect: (reactionKey: string) => unknown;
|
|
23
25
|
};
|
|
24
26
|
|
|
27
|
+
// @deprecated. remove it
|
|
25
28
|
export const reactionButtonCss = css`
|
|
26
29
|
all: unset;
|
|
27
30
|
padding-inline: ${space.s6}px;
|
|
@@ -50,27 +53,8 @@ export const reactionButtonCss = css`
|
|
|
50
53
|
}
|
|
51
54
|
`;
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
&:not([aria-disabled="true"]) {
|
|
56
|
-
background-color: ${themeVars.colorBgReactionsSelectedDefault};
|
|
57
|
-
border-color: ${themeVars.colorBorderReactionsSelectedDefault};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
&:not([aria-disabled="true"]):hover {
|
|
61
|
-
background-color: ${themeVars.colorBgReactionsSelectedHover};
|
|
62
|
-
border-color: ${themeVars.colorBorderReactionsSelectedHover};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
`;
|
|
66
|
-
|
|
67
|
-
const countCss = css`
|
|
68
|
-
${textStyles.small};
|
|
69
|
-
line-height: ${lineHeight.nowrap};
|
|
70
|
-
padding: ${space.s2}px ${space.s2}px ${space.s2}px ${space.s4}px;
|
|
71
|
-
.${selectedReactionButtonCss}:not(:disabled) & {
|
|
72
|
-
color: ${themeVars.colorTextReactionsSelected};
|
|
73
|
-
}
|
|
56
|
+
const reactionButtonCssV2 = css`
|
|
57
|
+
min-width: ${space.s24 + space.s12}px;
|
|
74
58
|
`;
|
|
75
59
|
|
|
76
60
|
const overlayClassName = css`
|
|
@@ -99,6 +83,7 @@ function MobileOverlay({content, onClose}: {content: ReactNode; onClose: () => v
|
|
|
99
83
|
className={css`
|
|
100
84
|
flex-shrink: 0;
|
|
101
85
|
background-color: ${themeVars.tooltipBgColor};
|
|
86
|
+
padding-bottom: var(${safeAreaInsetBottomVar});
|
|
102
87
|
`}
|
|
103
88
|
>
|
|
104
89
|
{content}
|
|
@@ -131,30 +116,30 @@ export const ReactionButton = ({reaction, disabled, onSelect}: Props): JSX.Eleme
|
|
|
131
116
|
isPreventDefault: true,
|
|
132
117
|
delay: 300,
|
|
133
118
|
});
|
|
119
|
+
|
|
134
120
|
const button = (
|
|
135
|
-
<
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
121
|
+
<ToggleButton
|
|
122
|
+
className={reactionButtonCssV2}
|
|
123
|
+
disabled={disabled}
|
|
124
|
+
iconStart={
|
|
125
|
+
<div
|
|
126
|
+
className={css`
|
|
127
|
+
font-size: 16px;
|
|
128
|
+
height: 16px;
|
|
129
|
+
width: 16px;
|
|
130
|
+
`}
|
|
131
|
+
{...longPressEvent}
|
|
132
|
+
>
|
|
133
|
+
<Emoji emoji={reaction.key} />
|
|
134
|
+
</div>
|
|
135
|
+
}
|
|
136
|
+
onPressedChange={() => onSelect(reaction.key)}
|
|
137
|
+
pressed={reaction.selected}
|
|
145
138
|
>
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
font-size: 18px;
|
|
149
|
-
height: 18px;
|
|
150
|
-
width: 18px;
|
|
151
|
-
`}
|
|
152
|
-
>
|
|
153
|
-
<Emoji emoji={reaction.key} />
|
|
154
|
-
</div>
|
|
155
|
-
<span className={countCss}>{reaction.count}</span>
|
|
156
|
-
</button>
|
|
139
|
+
{reaction.count}
|
|
140
|
+
</ToggleButton>
|
|
157
141
|
);
|
|
142
|
+
|
|
158
143
|
if (reaction?.userNames?.length) {
|
|
159
144
|
// noinspection CssInvalidPropertyValue
|
|
160
145
|
const title = (
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import {EmojiItem} from "@fibery/emoji-data";
|
|
2
|
-
import {measureScrollbar} from "@fibery/helpers/utils/measure-scrollbar";
|
|
3
2
|
import {useControllableState} from "@fibery/react/src/use-controllable-state";
|
|
4
3
|
import {css} from "@linaria/core";
|
|
5
4
|
import {CSSProperties, type FC, useCallback, useState} from "react";
|
|
6
5
|
import {IconButton} from "../button/icon-button";
|
|
7
6
|
import {layout, space, themeVars} from "../design-system";
|
|
8
7
|
import {type EmojiPickerProps} from "../emoji-picker/emoji-picker";
|
|
8
|
+
import {useResponsiveEmojiSize} from "../emoji-picker/use-responsive-emoji-size";
|
|
9
9
|
import AddReactions from "../icons/react/AddReactions";
|
|
10
|
-
import {
|
|
10
|
+
import {Popover} from "../popover";
|
|
11
|
+
import {ToggleButton} from "../toggle-button/toggle-button";
|
|
11
12
|
import {Tooltip} from "../tooltip";
|
|
12
|
-
import {useIsPhone} from "../use-is-phone";
|
|
13
|
-
import {reactionButtonCss} from "./reaction-button";
|
|
14
13
|
|
|
15
14
|
type Props = {
|
|
16
15
|
mode: "default" | "in-row";
|
|
@@ -52,7 +51,7 @@ const pickerOffset: [number, number] = [0, space.s4];
|
|
|
52
51
|
export const ReactionPicker = ({mode, onSelect, open, onOpenChange, EmojiPicker}: Props): JSX.Element => {
|
|
53
52
|
const [isOpen = false, setOpen] = useControllableState({value: open, onChange: onOpenChange});
|
|
54
53
|
const [triggerDomElement, setTriggerDomElement] = useState<HTMLButtonElement | null>(null);
|
|
55
|
-
const
|
|
54
|
+
const emojiSize = useResponsiveEmojiSize();
|
|
56
55
|
const onEmojiSelect = useCallback(
|
|
57
56
|
(emojiData: EmojiItem) => {
|
|
58
57
|
onSelect(emojiData.colons);
|
|
@@ -65,62 +64,57 @@ export const ReactionPicker = ({mode, onSelect, open, onOpenChange, EmojiPicker}
|
|
|
65
64
|
<div>
|
|
66
65
|
<Tooltip side="bottom" title="Add reaction">
|
|
67
66
|
{mode === "in-row" ? (
|
|
68
|
-
<
|
|
67
|
+
<ToggleButton
|
|
69
68
|
ref={setTriggerDomElement}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
onClick={() => setOpen(!isOpen)}
|
|
70
|
+
aria-expanded={isOpen}
|
|
71
|
+
aria-pressed={undefined}
|
|
72
|
+
style={{
|
|
73
|
+
// TODO: add IconToggleButton? or a separate prop?
|
|
74
|
+
width: "24px",
|
|
75
|
+
justifyContent: "center",
|
|
76
|
+
paddingInline: 0,
|
|
73
77
|
}}
|
|
74
|
-
className={reactionButtonCss}
|
|
75
78
|
>
|
|
76
|
-
<AddReactions
|
|
77
|
-
</
|
|
79
|
+
<AddReactions />
|
|
80
|
+
</ToggleButton>
|
|
78
81
|
) : (
|
|
79
82
|
<IconButton
|
|
80
83
|
ref={setTriggerDomElement}
|
|
84
|
+
aria-expanded={isOpen}
|
|
81
85
|
onClick={() => {
|
|
82
86
|
setOpen(!isOpen);
|
|
83
87
|
}}
|
|
84
88
|
size="small"
|
|
89
|
+
supportMobile
|
|
85
90
|
>
|
|
86
91
|
<AddReactions />
|
|
87
92
|
</IconButton>
|
|
88
93
|
)}
|
|
89
94
|
</Tooltip>
|
|
90
|
-
{
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
placement="auto"
|
|
103
|
-
offset={pickerOffset}
|
|
104
|
-
popupContainerClassName={popupContainerCss}
|
|
105
|
-
popupClassName={popupCss}
|
|
106
|
-
open={isOpen}
|
|
107
|
-
triggerDomElement={triggerDomElement}
|
|
108
|
-
trigger={<></>}
|
|
109
|
-
renderInPortal
|
|
110
|
-
onOpen={() => setOpen(true)}
|
|
111
|
-
onClose={() => setOpen(false)}
|
|
112
|
-
>
|
|
113
|
-
<EmojiPicker
|
|
114
|
-
emojiSize={
|
|
115
|
-
isPhone
|
|
116
|
-
? Math.min(Math.floor((document.body.clientWidth - 24 - measureScrollbar() - 9 * 12) / 9), 40)
|
|
117
|
-
: 20
|
|
95
|
+
<Popover.Root open={isOpen} onOpen={() => setOpen(true)} onClose={() => setOpen(false)}>
|
|
96
|
+
<Popover.Trigger reference={triggerDomElement}></Popover.Trigger>
|
|
97
|
+
<Popover.Portal>
|
|
98
|
+
<Popover.Content
|
|
99
|
+
supportMobile
|
|
100
|
+
mobilePopupStyle={
|
|
101
|
+
{
|
|
102
|
+
"--fibery-emoji-container-width": "100%",
|
|
103
|
+
"--fibery-emoji-grid-height": "auto",
|
|
104
|
+
"--fibery-emoji-content-max-height": "auto",
|
|
105
|
+
zIndex: zIndex,
|
|
106
|
+
} as CSSProperties
|
|
118
107
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
108
|
+
title={"Add reaction"}
|
|
109
|
+
placement="auto"
|
|
110
|
+
offset={pickerOffset}
|
|
111
|
+
popupContainerClassName={popupContainerCss}
|
|
112
|
+
popupClassName={popupCss}
|
|
113
|
+
>
|
|
114
|
+
<EmojiPicker emojiSize={emojiSize} showSkinTones onSelect={onEmojiSelect} />
|
|
115
|
+
</Popover.Content>
|
|
116
|
+
</Popover.Portal>
|
|
117
|
+
</Popover.Root>
|
|
124
118
|
</div>
|
|
125
119
|
);
|
|
126
120
|
};
|
package/src/select/index.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import BaseSelect, {
|
|
|
7
7
|
createFilter,
|
|
8
8
|
MenuListProps,
|
|
9
9
|
MenuProps,
|
|
10
|
+
ControlProps,
|
|
10
11
|
mergeStyles,
|
|
11
12
|
MultiValue,
|
|
12
13
|
MultiValueProps,
|
|
@@ -44,6 +45,7 @@ export type {
|
|
|
44
45
|
GroupBase,
|
|
45
46
|
MenuListProps,
|
|
46
47
|
MenuProps,
|
|
48
|
+
ControlProps,
|
|
47
49
|
MultiValue,
|
|
48
50
|
MultiValueProps,
|
|
49
51
|
OnChangeValue,
|
|
@@ -53,6 +55,8 @@ export type {
|
|
|
53
55
|
SingleValue,
|
|
54
56
|
SingleValueProps,
|
|
55
57
|
StylesConfig,
|
|
58
|
+
SelectInstance,
|
|
59
|
+
BaseSelectProps,
|
|
56
60
|
};
|
|
57
61
|
|
|
58
62
|
export {reactSelectComponents as components, MenuListVirtualized, createFilter};
|
|
@@ -207,8 +211,8 @@ export const Select = forwardRef(function Select<
|
|
|
207
211
|
[onKeyDown, menuOpenState]
|
|
208
212
|
);
|
|
209
213
|
|
|
210
|
-
const
|
|
211
|
-
const
|
|
214
|
+
const selectRef = useRef<SelectInstance<T, U, V> | null>(null);
|
|
215
|
+
const composedRef = useComposedRefs(forwardedRef, selectRef);
|
|
212
216
|
|
|
213
217
|
const selectComponents = useSelectComponents({
|
|
214
218
|
components,
|
|
@@ -221,9 +225,9 @@ export const Select = forwardRef(function Select<
|
|
|
221
225
|
const combinedStyles = useSelectStyles({virtualized, zIndex, styles});
|
|
222
226
|
|
|
223
227
|
return (
|
|
224
|
-
<ReactSelectRefContext.Provider value={
|
|
228
|
+
<ReactSelectRefContext.Provider value={selectRef as RefObject<SelectInstance>}>
|
|
225
229
|
<BaseSelect<T, U, V>
|
|
226
|
-
ref={
|
|
230
|
+
ref={composedRef}
|
|
227
231
|
// There are places, where it is useful to override menuPortalTarget globally for all selects.
|
|
228
232
|
// When you are already in some popup. e.g. user input in buttons, relation filter popover.
|
|
229
233
|
menuPortalTarget={getPopupContainerElement ? getPopupContainerElement() : menuPortalTarget}
|
|
@@ -5,6 +5,7 @@ import React, {
|
|
|
5
5
|
ForwardedRef,
|
|
6
6
|
forwardRef,
|
|
7
7
|
ReactNode,
|
|
8
|
+
RefObject,
|
|
8
9
|
useCallback,
|
|
9
10
|
useEffect,
|
|
10
11
|
useImperativeHandle,
|
|
@@ -14,7 +15,7 @@ import React, {
|
|
|
14
15
|
} from "react";
|
|
15
16
|
import {inputOverrides} from "../antd/styles";
|
|
16
17
|
import {border, space, textStyles} from "../design-system";
|
|
17
|
-
import {
|
|
18
|
+
import {Popover} from "../popover";
|
|
18
19
|
import {useIsPhone} from "../use-is-phone";
|
|
19
20
|
import {MenuTransparent} from "./components/menu";
|
|
20
21
|
import {
|
|
@@ -33,6 +34,7 @@ import {ButtonColor, ButtonVariant} from "../button/base-button";
|
|
|
33
34
|
import {makeSelectInPopoverStyles} from "./styles";
|
|
34
35
|
import {SelectInstance} from "react-select";
|
|
35
36
|
import {SELECT_IN_POPOVER_VALUE_MAX_HEIGHT} from "./constants";
|
|
37
|
+
import {Wrap} from "@fibery/react/src/wrap";
|
|
36
38
|
|
|
37
39
|
const offset = [0, space.s4] as [number, number];
|
|
38
40
|
const popupHeightVH = 45;
|
|
@@ -63,7 +65,8 @@ const mobileClassName = css`
|
|
|
63
65
|
padding-right: ${space.s12}px;
|
|
64
66
|
`;
|
|
65
67
|
|
|
66
|
-
const
|
|
68
|
+
const triggerCss = css`
|
|
69
|
+
min-width: 0;
|
|
67
70
|
border-radius: ${border.radius6}px;
|
|
68
71
|
|
|
69
72
|
&:focus {
|
|
@@ -109,7 +112,7 @@ export type TriggerProps = {
|
|
|
109
112
|
|
|
110
113
|
const TriggerDefault = ({innerRef, children, onClick, onKeyDown}: TriggerProps) => {
|
|
111
114
|
return (
|
|
112
|
-
<div ref={innerRef} onClick={onClick} onKeyDown={onKeyDown} tabIndex={0} className={
|
|
115
|
+
<div ref={innerRef} onClick={onClick} onKeyDown={onKeyDown} tabIndex={0} className={triggerCss}>
|
|
113
116
|
{children}
|
|
114
117
|
</div>
|
|
115
118
|
);
|
|
@@ -119,9 +122,9 @@ export type SelectComponents<T, U extends boolean, V extends GroupBase<T>> = Sel
|
|
|
119
122
|
Trigger?: ComponentType<TriggerProps>;
|
|
120
123
|
};
|
|
121
124
|
|
|
122
|
-
type SelectInPopoverRef<T, U extends boolean, V extends GroupBase<T>> = {
|
|
125
|
+
export type SelectInPopoverRef<T, U extends boolean, V extends GroupBase<T>> = {
|
|
123
126
|
valueRef: HTMLDivElement | null;
|
|
124
|
-
selectRef: SelectInstance<T, U, V
|
|
127
|
+
selectRef: RefObject<SelectInstance<T, U, V>>;
|
|
125
128
|
};
|
|
126
129
|
|
|
127
130
|
type Props<T, U extends boolean, V extends GroupBase<T>> = {
|
|
@@ -198,7 +201,6 @@ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
|
|
|
198
201
|
forbidValuesClearInCollnMode,
|
|
199
202
|
isOptionDisabled,
|
|
200
203
|
} = props;
|
|
201
|
-
const [triggerElement, setTriggerElement] = useState<HTMLDivElement | null>(null);
|
|
202
204
|
const [visible, setVisible] = useControllableState({
|
|
203
205
|
value: menuIsOpen,
|
|
204
206
|
defaultValue: false,
|
|
@@ -208,20 +210,12 @@ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
|
|
|
208
210
|
});
|
|
209
211
|
const blurTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
|
|
210
212
|
const selectRef = useRef<SelectInstance<T, U, V>>(null);
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
useImperativeHandle(
|
|
214
|
-
forwardedRef,
|
|
215
|
-
() =>
|
|
216
|
-
({
|
|
217
|
-
valueRef: ref.current,
|
|
218
|
-
selectRef: selectRef.current,
|
|
219
|
-
} as {valueRef: HTMLDivElement; selectRef: SelectInstance<T, U, V> | null})
|
|
220
|
-
);
|
|
213
|
+
const [triggerElement, setTriggerElement] = useState<HTMLDivElement | null>(null);
|
|
221
214
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
215
|
+
useImperativeHandle(forwardedRef, () => ({
|
|
216
|
+
valueRef: triggerElement,
|
|
217
|
+
selectRef,
|
|
218
|
+
}));
|
|
225
219
|
|
|
226
220
|
useEffect(() => {
|
|
227
221
|
if (blurTimeoutRef.current) {
|
|
@@ -356,9 +350,9 @@ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
|
|
|
356
350
|
};
|
|
357
351
|
|
|
358
352
|
return (
|
|
359
|
-
|
|
353
|
+
<Popover.Root open={visible} onOpen={() => onShow()} onClose={() => onHide()}>
|
|
360
354
|
<Trigger
|
|
361
|
-
innerRef={
|
|
355
|
+
innerRef={setTriggerElement}
|
|
362
356
|
menuOpened={visible}
|
|
363
357
|
disabled={disabled}
|
|
364
358
|
valueSelected={Boolean(value)}
|
|
@@ -367,8 +361,9 @@ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
|
|
|
367
361
|
>
|
|
368
362
|
{renderValue ? renderValue() : null}
|
|
369
363
|
</Trigger>
|
|
370
|
-
{
|
|
371
|
-
|
|
364
|
+
<Popover.Trigger reference={triggerElement} />
|
|
365
|
+
<Wrap with={Popover.Portal} if={renderInPortal} getPopupContainer={getPopupContainer}>
|
|
366
|
+
<Popover.Content
|
|
372
367
|
supportMobile
|
|
373
368
|
title={title}
|
|
374
369
|
offset={offset}
|
|
@@ -376,13 +371,6 @@ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
|
|
|
376
371
|
popupClassName={cx(popupClassName, popupStyles)}
|
|
377
372
|
mobilePopupContentClassName={mobileClassName}
|
|
378
373
|
placement="bottom-start"
|
|
379
|
-
renderInPortal={renderInPortal}
|
|
380
|
-
open={visible}
|
|
381
|
-
onOpen={() => onShow()}
|
|
382
|
-
onClose={() => onHide()}
|
|
383
|
-
trigger={<></>}
|
|
384
|
-
triggerDomElement={triggerElement}
|
|
385
|
-
getPopupContainer={getPopupContainer}
|
|
386
374
|
>
|
|
387
375
|
{title && !isPhone && <div className={titleClassName}>{title}</div>}
|
|
388
376
|
{/*Usually we set popupContainerElement for react-select via context (SelectControlSettingsProvider). But here we render react-select in popover.*/}
|
|
@@ -423,9 +411,9 @@ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
|
|
|
423
411
|
isOptionDisabled={isOptionDisabled}
|
|
424
412
|
/>
|
|
425
413
|
</SelectControlSettingsProvider>
|
|
426
|
-
</
|
|
427
|
-
|
|
428
|
-
|
|
414
|
+
</Popover.Content>
|
|
415
|
+
</Wrap>
|
|
416
|
+
</Popover.Root>
|
|
429
417
|
);
|
|
430
418
|
}
|
|
431
419
|
|
package/src/tab-nav/tab-nav.tsx
CHANGED
|
@@ -14,6 +14,7 @@ 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";
|
|
18
19
|
import {useCallbackRef} from "@fibery/react/src/use-callback-ref";
|
|
19
20
|
import {useResizeObserver} from "@fibery/react/src/use-resize-observer";
|
|
@@ -35,6 +36,10 @@ const tabNavItem = css`
|
|
|
35
36
|
list-style: none;
|
|
36
37
|
`;
|
|
37
38
|
|
|
39
|
+
const tabNavItemWide = css`
|
|
40
|
+
flex: 1 0 0;
|
|
41
|
+
`;
|
|
42
|
+
|
|
38
43
|
const tabButton = css`
|
|
39
44
|
all: unset;
|
|
40
45
|
display: flex;
|
|
@@ -54,23 +59,40 @@ const tabButton = css`
|
|
|
54
59
|
font-weight: ${fontWeight.medium};
|
|
55
60
|
line-height: 16px;
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
@media (any-hover: hover) {
|
|
63
|
+
&:hover {
|
|
64
|
+
background-color: ${themeVars.colorBgTabHover};
|
|
65
|
+
color: ${themeVars.textColor};
|
|
66
|
+
}
|
|
61
67
|
}
|
|
62
68
|
|
|
63
69
|
&:focus-visible {
|
|
70
|
+
color: ${themeVars.textColor};
|
|
71
|
+
background-color: ${themeVars.colorBgTabHover};
|
|
64
72
|
outline: 2px solid ${themeVars.colorBorderNeutralFocusRing};
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
&[data-active] {
|
|
68
76
|
color: ${themeVars.textColor};
|
|
69
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
|
+
}
|
|
70
88
|
`;
|
|
71
89
|
|
|
72
90
|
const tabNavButtonText = css`
|
|
73
91
|
padding: 0 ${space.s4}px;
|
|
92
|
+
|
|
93
|
+
${mobileRootSelector} & {
|
|
94
|
+
padding: 0 ${space.s6}px;
|
|
95
|
+
}
|
|
74
96
|
`;
|
|
75
97
|
|
|
76
98
|
const tabNavIndicatorTrack = css`
|
|
@@ -145,15 +167,15 @@ const useTabNavIndicator = ({active, itemRef}: {active?: boolean; itemRef: RefOb
|
|
|
145
167
|
useResizeObserver(itemRef, () => updateIndicator());
|
|
146
168
|
};
|
|
147
169
|
|
|
148
|
-
export const TabNavItem = forwardRef<HTMLLIElement, NavigationMenuItemProps & {active?: boolean}>(
|
|
149
|
-
({className, children, active, ...props}, forwardedRef) => {
|
|
170
|
+
export const TabNavItem = forwardRef<HTMLLIElement, NavigationMenuItemProps & {active?: boolean; wide?: boolean}>(
|
|
171
|
+
({className, children, active, wide, ...props}, forwardedRef) => {
|
|
150
172
|
const itemRef = useRef(null);
|
|
151
173
|
const ref = useComposedRefs(itemRef, forwardedRef);
|
|
152
174
|
|
|
153
175
|
useTabNavIndicator({active, itemRef});
|
|
154
176
|
|
|
155
177
|
return (
|
|
156
|
-
<NavigationMenuItem ref={ref} className={cx(tabNavItem, className)} {...props}>
|
|
178
|
+
<NavigationMenuItem ref={ref} className={cx(tabNavItem, wide && tabNavItemWide, className)} {...props}>
|
|
157
179
|
{children}
|
|
158
180
|
</NavigationMenuItem>
|
|
159
181
|
);
|
|
@@ -165,9 +187,13 @@ export const TabNavLink = forwardRef<
|
|
|
165
187
|
Omit<NavigationMenuLinkProps, "asChild"> & {
|
|
166
188
|
before?: ReactNode;
|
|
167
189
|
after?: ReactNode;
|
|
190
|
+
wide?: boolean;
|
|
168
191
|
itemClassName?: string;
|
|
169
192
|
}
|
|
170
|
-
>(function TabNavLink(
|
|
193
|
+
>(function TabNavLink(
|
|
194
|
+
{children, className, itemClassName, active, wide, before, after, href, ...linkProps},
|
|
195
|
+
forwardedRef
|
|
196
|
+
) {
|
|
171
197
|
const renderAsButton = typeof href === "undefined";
|
|
172
198
|
|
|
173
199
|
const Component = renderAsButton ? "button" : "a";
|
|
@@ -178,7 +204,7 @@ export const TabNavLink = forwardRef<
|
|
|
178
204
|
return (
|
|
179
205
|
<TooltipIfOverflown title={children}>
|
|
180
206
|
{({setNode}) => (
|
|
181
|
-
<TabNavItem className={itemClassName} active={active}>
|
|
207
|
+
<TabNavItem className={itemClassName} active={active} wide={wide}>
|
|
182
208
|
<NavigationMenuLink
|
|
183
209
|
ref={forwardedRef}
|
|
184
210
|
className={cx(tabButton, className)}
|
package/src/toast/primitives.tsx
CHANGED
|
@@ -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:
|
|
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
|
+
});
|