@fibery/ui-kit 1.36.2 → 1.37.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 +6 -0
- package/package.json +1 -1
- package/src/action-badge.tsx +5 -4
- package/src/actions-menu/actions-menu-confirmation.tsx +1 -12
- package/src/actions-menu/actions-menu-item.tsx +1 -1
- package/src/antd/ant-modal.tsx +17 -2
- package/src/antd/input.tsx +4 -3
- package/src/app-icon-with-fallback.tsx +5 -8
- package/src/app-icon-wrapper.tsx +4 -4
- package/src/appIcons.json +20 -0
- package/src/badge.tsx +14 -7
- package/src/beta-badge.tsx +12 -8
- package/src/button/actions-button-compact.tsx +1 -1
- package/src/button/base-button.tsx +2 -1
- package/src/button/button.tsx +89 -2
- package/src/button/icon-button.tsx +4 -2
- package/src/button/select-button.tsx +23 -8
- package/src/card-container.tsx +29 -65
- package/src/card-hidden-link.tsx +52 -0
- package/src/collapsible-section.tsx +13 -3
- package/src/color-picker/index.js +65 -60
- package/src/color-picker/swatch.tsx +28 -14
- package/src/command-menu/index.tsx +2 -2
- package/src/count-badge.tsx +57 -0
- package/src/date-picker/date-range-input.tsx +1 -1
- package/src/date-picker/fake-date-input.tsx +1 -1
- package/src/date-picker/relative-date-picker.tsx +1 -1
- package/src/date-picker/single-date-input.tsx +1 -1
- package/src/date-picker/utils.ts +9 -2
- package/src/design-system.ts +72 -41
- package/src/emoji-picker/emoji-picker-content-with-color.tsx +3 -9
- package/src/emoji-picker/icon-emoji-picker.tsx +75 -69
- package/src/emoji-picker/primitives/header.tsx +1 -0
- package/src/emoji-picker/primitives/search.tsx +12 -13
- package/src/error-alert/error-alert.tsx +19 -7
- package/src/field-app-icon.tsx +29 -0
- package/src/field-container.tsx +4 -2
- package/src/field-icon.tsx +26 -0
- package/src/field-type-icon.tsx +82 -0
- package/src/guide-link.tsx +4 -3
- package/src/hint.tsx +10 -1
- package/src/html-styles.ts +15 -13
- package/src/icons/ast/AiFiberyBuild.ts +8 -0
- package/src/icons/ast/Anthropic.ts +1 -1
- package/src/icons/ast/Apple.ts +8 -0
- package/src/icons/ast/ArrowBottom.ts +1 -1
- package/src/icons/ast/ArrowForward.ts +1 -1
- package/src/icons/ast/ArrowLeft.ts +1 -1
- package/src/icons/ast/ArrowRight.ts +1 -1
- package/src/icons/ast/ArrowTop.ts +1 -1
- package/src/icons/ast/Crosshair.ts +8 -0
- package/src/icons/ast/Document.ts +8 -0
- package/src/icons/ast/EntityCreate.ts +8 -0
- package/src/icons/ast/ExpandAll.ts +8 -0
- package/src/icons/ast/FiberyDesktopApp.ts +8 -0
- package/src/icons/ast/FileDownload.ts +8 -0
- package/src/icons/ast/GraduationCapFilled.ts +8 -0
- package/src/icons/ast/Home.ts +1 -1
- package/src/icons/ast/ImportFilled.ts +8 -0
- package/src/icons/ast/IntegrationsFilled.ts +8 -0
- package/src/icons/ast/LocationEdit.ts +8 -0
- package/src/icons/ast/MessagePlus.ts +8 -0
- package/src/icons/ast/OpenAi.ts +1 -1
- package/src/icons/ast/RicheditorMarkHighlight.ts +8 -0
- package/src/icons/ast/RicheditorMarkStrike.ts +1 -1
- package/src/icons/ast/RicheditorMarkUnderline.ts +1 -1
- package/src/icons/ast/SpaceApp.ts +8 -0
- package/src/icons/ast/SpaceGenerate.ts +8 -0
- package/src/icons/ast/SpaceScratch.ts +8 -0
- package/src/icons/ast/SpaceTemplate.ts +8 -0
- package/src/icons/ast/TableLayout.ts +8 -0
- package/src/icons/ast/TemplatesFilled.ts +8 -0
- package/src/icons/ast/ThumbsDown.ts +8 -0
- package/src/icons/ast/ThumbsUp.ts +8 -0
- package/src/icons/ast/ViewDashboard.ts +8 -0
- package/src/icons/ast/WarningTriangleFilled.ts +8 -0
- package/src/icons/ast/Windows.ts +8 -0
- package/src/icons/ast/index.tsx +25 -0
- package/src/icons/react/AiFiberyBuild.tsx +13 -0
- package/src/icons/react/Apple.tsx +13 -0
- package/src/icons/react/Crosshair.tsx +13 -0
- package/src/icons/react/Document.tsx +13 -0
- package/src/icons/react/EntityCreate.tsx +13 -0
- package/src/icons/react/ExpandAll.tsx +13 -0
- package/src/icons/react/FiberyDesktopApp.tsx +13 -0
- package/src/icons/react/FileDownload.tsx +13 -0
- package/src/icons/react/GraduationCapFilled.tsx +13 -0
- package/src/icons/react/ImportFilled.tsx +13 -0
- package/src/icons/react/IntegrationsFilled.tsx +13 -0
- package/src/icons/react/LocationEdit.tsx +13 -0
- package/src/icons/react/MessagePlus.tsx +13 -0
- package/src/icons/react/RicheditorMarkHighlight.tsx +13 -0
- package/src/icons/react/SpaceApp.tsx +13 -0
- package/src/icons/react/SpaceGenerate.tsx +13 -0
- package/src/icons/react/SpaceScratch.tsx +13 -0
- package/src/icons/react/SpaceTemplate.tsx +13 -0
- package/src/icons/react/TableLayout.tsx +13 -0
- package/src/icons/react/TemplatesFilled.tsx +13 -0
- package/src/icons/react/ThumbsDown.tsx +13 -0
- package/src/icons/react/ThumbsUp.tsx +13 -0
- package/src/icons/react/ViewDashboard.tsx +13 -0
- package/src/icons/react/WarningTriangleFilled.tsx +13 -0
- package/src/icons/react/Windows.tsx +13 -0
- package/src/icons/react/index.tsx +25 -0
- package/src/icons/svg/ai-fibery-build.svg +24 -0
- package/src/icons/svg/anthropic.svg +2 -14
- package/src/icons/svg/apple.svg +4 -0
- package/src/icons/svg/arrow-bottom.svg +1 -1
- package/src/icons/svg/arrow-forward.svg +1 -1
- package/src/icons/svg/arrow-left.svg +1 -1
- package/src/icons/svg/arrow-right.svg +1 -1
- package/src/icons/svg/arrow-top.svg +1 -1
- package/src/icons/svg/crosshair.svg +4 -0
- package/src/icons/svg/document.svg +4 -0
- package/src/icons/svg/entity-create.svg +3 -0
- package/src/icons/svg/expand-all.svg +3 -0
- package/src/icons/svg/fibery-desktop-app.svg +101 -0
- package/src/icons/svg/file-download.svg +4 -0
- package/src/icons/svg/go-to.svg +1 -3
- package/src/icons/svg/graduation-cap-filled.svg +4 -0
- package/src/icons/svg/home.svg +4 -2
- package/src/icons/svg/import-filled.svg +4 -0
- package/src/icons/svg/integrations-filled.svg +4 -0
- package/src/icons/svg/location-edit.svg +13 -0
- package/src/icons/svg/message-plus.svg +4 -0
- package/src/icons/svg/open-ai.svg +2 -7
- package/src/icons/svg/open-as-page.svg +2 -3
- package/src/icons/svg/richeditor/mark/code.svg +4 -5
- package/src/icons/svg/richeditor/mark/em.svg +3 -2
- package/src/icons/svg/richeditor/mark/highlight.svg +3 -0
- package/src/icons/svg/richeditor/mark/strike.svg +3 -2
- package/src/icons/svg/richeditor/mark/strong.svg +3 -2
- package/src/icons/svg/richeditor/mark/underline.svg +4 -2
- package/src/icons/svg/space-app.svg +3 -0
- package/src/icons/svg/space-generate.svg +3 -0
- package/src/icons/svg/space-scratch.svg +3 -0
- package/src/icons/svg/space-template.svg +3 -0
- package/src/icons/svg/table-layout.svg +3 -0
- package/src/icons/svg/templates-filled.svg +6 -0
- package/src/icons/svg/thumbs-down.svg +3 -0
- package/src/icons/svg/thumbs-up.svg +3 -0
- package/src/icons/svg/view-dashboard.svg +5 -0
- package/src/icons/svg/warning-triangle-filled.svg +3 -0
- package/src/icons/svg/windows.svg +15 -0
- package/src/integration-compact-info-button.tsx +3 -1
- package/src/layout-styles.ts +23 -0
- package/src/lists/list-row-surface.tsx +2 -1
- package/src/loaders.tsx +6 -6
- package/src/logo.tsx +16 -9
- package/src/mobile-styles.ts +2 -0
- package/src/new-badge.tsx +4 -7
- package/src/number-input/text-area-auto-sized.tsx +47 -0
- package/src/number-input/text-input-auto-sized.tsx +49 -0
- package/src/palette.ts +50 -50
- package/src/popup/index.tsx +1 -0
- package/src/rich-text-embed-error.tsx +2 -2
- package/src/select/{custom-select-partials → components}/menu.tsx +13 -7
- package/src/select/{custom-select-partials → components}/no-option-message.tsx +0 -1
- package/src/select/constants.ts +1 -0
- package/src/select/index.tsx +136 -145
- package/src/select/select-in-popover.tsx +101 -108
- package/src/select/styles.ts +60 -24
- package/src/shortcut-badge.tsx +1 -0
- package/src/tab-nav/tab-nav.tsx +12 -19
- package/src/theme-provider.tsx +9 -1
- package/src/tooltip-if-overflown.tsx +9 -3
- package/src/unit/index.tsx +9 -1
- package/src/unit/loading-unit-value.tsx +1 -0
- package/src/unit/maybe-unit-value.tsx +3 -3
- package/src/unit/primitive.tsx +58 -42
- package/src/unit/styles.ts +8 -12
- package/src/unit/types.ts +4 -2
- package/src/unit/unit-button-group.tsx +6 -11
- package/src/unit/unit-content.tsx +13 -5
- package/src/unit/unit-with-title.tsx +6 -1
- package/src/unit/unit-with-tooltip.tsx +24 -9
- package/src/use-is-phone.tsx +12 -0
- package/src/workflow-progress-icon.tsx +1 -1
- package/src/number-input/text-area-with-autosize.tsx +0 -91
- package/src/number-input/text-inline-input-with-autosize.tsx +0 -60
- package/src/use-is-phone.ts +0 -5
- /package/src/select/{custom-select-partials → components}/clear-indicator.tsx +0 -0
- /package/src/select/{custom-select-partials → components}/drop-down-indicator.tsx +0 -0
- /package/src/select/{custom-select-partials → components}/group-heading.tsx +0 -0
- /package/src/select/{custom-select-partials → components}/menu-list-virtualized.tsx +0 -0
- /package/src/select/{custom-select-partials → components}/option.tsx +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {useControllableState} from "@fibery/react/src/use-controllable-state";
|
|
2
2
|
import {css, cx} from "@linaria/core";
|
|
3
3
|
import React, {
|
|
4
|
-
ComponentProps,
|
|
5
4
|
ComponentType,
|
|
5
|
+
ForwardedRef,
|
|
6
6
|
forwardRef,
|
|
7
7
|
ReactNode,
|
|
8
8
|
useCallback,
|
|
@@ -15,9 +15,8 @@ import React, {
|
|
|
15
15
|
import {inputOverrides} from "../antd/styles";
|
|
16
16
|
import {border, space, textStyles} from "../design-system";
|
|
17
17
|
import {Popup} from "../popup";
|
|
18
|
-
import {$TSFixMe} from "../tsfixme";
|
|
19
18
|
import {useIsPhone} from "../use-is-phone";
|
|
20
|
-
import {
|
|
19
|
+
import {MenuTransparent} from "./components/menu";
|
|
21
20
|
import {
|
|
22
21
|
ActionMeta,
|
|
23
22
|
combineStyles,
|
|
@@ -30,6 +29,10 @@ import {
|
|
|
30
29
|
StylesConfig,
|
|
31
30
|
} from "./index";
|
|
32
31
|
import {SelectControlSettingsProvider} from "./select-control-settings-context";
|
|
32
|
+
import {ButtonColor, ButtonVariant} from "../button/base-button";
|
|
33
|
+
import {makeSelectInPopoverStyles} from "./styles";
|
|
34
|
+
import {SelectInstance} from "react-select";
|
|
35
|
+
import {SELECT_IN_POPOVER_VALUE_MAX_HEIGHT} from "./constants";
|
|
33
36
|
|
|
34
37
|
const offset = [0, space.s4] as [number, number];
|
|
35
38
|
const popupHeightVH = 45;
|
|
@@ -85,53 +88,26 @@ const titleClassName = css`
|
|
|
85
88
|
padding-inline: ${space.s12}px;
|
|
86
89
|
`;
|
|
87
90
|
|
|
88
|
-
export const valueMaxHeight = 116;
|
|
89
|
-
|
|
90
|
-
export const selectInPopupStyles = {
|
|
91
|
-
container: (props: $TSFixMe) => ({
|
|
92
|
-
...props,
|
|
93
|
-
minWidth: 180,
|
|
94
|
-
width: "100%",
|
|
95
|
-
paddingTop: space.s6,
|
|
96
|
-
paddingInline: space.s6,
|
|
97
|
-
}),
|
|
98
|
-
option: (props: $TSFixMe) => ({
|
|
99
|
-
...props,
|
|
100
|
-
padding: 0,
|
|
101
|
-
borderRadius: border.radius4,
|
|
102
|
-
paddingLeft: 0,
|
|
103
|
-
paddingRight: 0,
|
|
104
|
-
}),
|
|
105
|
-
control: (props: $TSFixMe) => ({
|
|
106
|
-
...props,
|
|
107
|
-
maxHeight: valueMaxHeight,
|
|
108
|
-
overflow: "auto",
|
|
109
|
-
margin: space.s2,
|
|
110
|
-
marginBottom: space.s4,
|
|
111
|
-
width: `calc(100% - ${space.s2 * 2}px)`,
|
|
112
|
-
borderRadius: border.radius4,
|
|
113
|
-
}),
|
|
114
|
-
menu: (props: $TSFixMe) => ({
|
|
115
|
-
...props,
|
|
116
|
-
minWidth: 100,
|
|
117
|
-
position: "static",
|
|
118
|
-
marginBlock: 0,
|
|
119
|
-
boxShadow: "none !important",
|
|
120
|
-
borderRadius: border.radius4,
|
|
121
|
-
}),
|
|
122
|
-
};
|
|
123
|
-
|
|
124
91
|
export type TriggerProps = {
|
|
125
92
|
innerRef: React.Ref<HTMLDivElement>;
|
|
126
93
|
children: ReactNode;
|
|
127
94
|
onClick?: React.MouseEventHandler;
|
|
128
95
|
iconStart?: ReactNode;
|
|
129
96
|
pending?: boolean;
|
|
97
|
+
pressed?: boolean;
|
|
98
|
+
menuOpened?: boolean;
|
|
130
99
|
onKeyDown?: React.KeyboardEventHandler;
|
|
131
100
|
disabled?: boolean;
|
|
101
|
+
size?: "small" | "medium" | "large";
|
|
102
|
+
fullWidth?: boolean;
|
|
103
|
+
style?: React.CSSProperties;
|
|
104
|
+
className?: string;
|
|
105
|
+
variant?: ButtonVariant;
|
|
106
|
+
color?: ButtonColor;
|
|
107
|
+
valueSelected: boolean;
|
|
132
108
|
};
|
|
133
109
|
|
|
134
|
-
const
|
|
110
|
+
const TriggerDefault = ({innerRef, children, onClick, onKeyDown}: TriggerProps) => {
|
|
135
111
|
return (
|
|
136
112
|
<div ref={innerRef} onClick={onClick} onKeyDown={onKeyDown} tabIndex={0} className={valueClassName}>
|
|
137
113
|
{children}
|
|
@@ -139,59 +115,54 @@ const Trigger = ({innerRef, children, onClick, onKeyDown}: TriggerProps) => {
|
|
|
139
115
|
);
|
|
140
116
|
};
|
|
141
117
|
|
|
142
|
-
type
|
|
143
|
-
Trigger
|
|
144
|
-
Menu: ComponentType<ComponentProps<typeof Menu>>;
|
|
118
|
+
export type SelectComponents<T, U extends boolean, V extends GroupBase<T>> = SelectProps<T, U, V>["components"] & {
|
|
119
|
+
Trigger?: ComponentType<TriggerProps>;
|
|
145
120
|
};
|
|
146
121
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const defaultComponents = {Trigger, Menu};
|
|
150
|
-
|
|
151
|
-
type Ref = {
|
|
122
|
+
type SelectInPopoverRef<T, U extends boolean, V extends GroupBase<T>> = {
|
|
152
123
|
valueRef: HTMLDivElement | null;
|
|
153
|
-
selectRef:
|
|
124
|
+
selectRef: SelectInstance<T, U, V> | null;
|
|
154
125
|
};
|
|
155
126
|
|
|
156
|
-
type Props<
|
|
157
|
-
value?: PropsValue<
|
|
127
|
+
type Props<T, U extends boolean, V extends GroupBase<T>> = {
|
|
128
|
+
value?: PropsValue<T>;
|
|
158
129
|
menuIsOpen?: boolean;
|
|
159
130
|
autoFocus?: boolean;
|
|
160
131
|
virtualized?: boolean;
|
|
161
132
|
defaultMenuIsOpen?: boolean;
|
|
162
133
|
placeholder?: string;
|
|
163
134
|
noOptionsMessage?: () => string | JSX.Element | null;
|
|
164
|
-
options: OptionsOrGroups<
|
|
165
|
-
filterOption?: SelectProps<
|
|
135
|
+
options: OptionsOrGroups<T, V>;
|
|
136
|
+
filterOption?: SelectProps<T, U, V>["filterOption"];
|
|
166
137
|
inputValue?: string;
|
|
167
138
|
disabled?: boolean;
|
|
168
|
-
isCollectionMode?:
|
|
139
|
+
isCollectionMode?: U;
|
|
169
140
|
isClearable?: boolean;
|
|
170
141
|
renderValue?: () => ReactNode;
|
|
171
142
|
title?: string;
|
|
172
143
|
maxMenuHeight?: number;
|
|
173
|
-
hideOnChange?: boolean | ((newValue: OnChangeValue<
|
|
144
|
+
hideOnChange?: boolean | ((newValue: OnChangeValue<T, U>, actionMeta: ActionMeta<T>) => boolean);
|
|
174
145
|
renderInPortal?: boolean;
|
|
175
146
|
popupStyles?: string;
|
|
176
|
-
selectStyles?: StylesConfig<
|
|
177
|
-
formatGroupLabel?: (group:
|
|
178
|
-
formatOptionLabel?: (option:
|
|
179
|
-
components?:
|
|
147
|
+
selectStyles?: StylesConfig<T, U, V>;
|
|
148
|
+
formatGroupLabel?: (group: V) => ReactNode;
|
|
149
|
+
formatOptionLabel?: (option: T, {context}: {context: "menu" | "value"}) => ReactNode;
|
|
150
|
+
components?: SelectComponents<T, U, V>;
|
|
180
151
|
onInputChange?: (s: string, actionType: {action: string}) => void;
|
|
181
152
|
onFocus?: () => void;
|
|
182
|
-
onChange: (newValue: OnChangeValue<
|
|
153
|
+
onChange: (newValue: OnChangeValue<T, U>, actionMeta: ActionMeta<T>) => void;
|
|
183
154
|
onMenuOpen?: () => void;
|
|
184
155
|
onMenuClose?: () => void | boolean;
|
|
185
156
|
getPopupContainer?: () => HTMLElement;
|
|
186
157
|
onSelectKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
|
187
158
|
forbidValuesClearInCollnMode?: boolean;
|
|
188
159
|
otherSelectProps?: Record<string, unknown>;
|
|
189
|
-
isOptionDisabled?: (option:
|
|
160
|
+
isOptionDisabled?: (option: T) => boolean;
|
|
190
161
|
};
|
|
191
162
|
|
|
192
|
-
function SelectInPopoverInner<
|
|
193
|
-
props: Omit<Props<
|
|
194
|
-
forwardedRef:
|
|
163
|
+
function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
|
|
164
|
+
props: Omit<Props<T, U, V>, "maxMenuHeight">,
|
|
165
|
+
forwardedRef: ForwardedRef<SelectInPopoverRef<T, U, V>>
|
|
195
166
|
) {
|
|
196
167
|
const {
|
|
197
168
|
value,
|
|
@@ -236,7 +207,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
236
207
|
},
|
|
237
208
|
});
|
|
238
209
|
const blurTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
|
|
239
|
-
const selectRef = useRef<
|
|
210
|
+
const selectRef = useRef<SelectInstance<T, U, V>>(null);
|
|
240
211
|
const ref = useRef<HTMLDivElement | null>(null);
|
|
241
212
|
|
|
242
213
|
useImperativeHandle(
|
|
@@ -245,11 +216,13 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
245
216
|
({
|
|
246
217
|
valueRef: ref.current,
|
|
247
218
|
selectRef: selectRef.current,
|
|
248
|
-
} as {valueRef: HTMLDivElement; selectRef:
|
|
219
|
+
} as {valueRef: HTMLDivElement; selectRef: SelectInstance<T, U, V> | null})
|
|
249
220
|
);
|
|
221
|
+
|
|
250
222
|
useEffect(() => {
|
|
251
223
|
setTriggerElement(ref.current);
|
|
252
224
|
}, []);
|
|
225
|
+
|
|
253
226
|
useEffect(() => {
|
|
254
227
|
if (blurTimeoutRef.current) {
|
|
255
228
|
clearTimeout(blurTimeoutRef.current);
|
|
@@ -301,7 +274,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
301
274
|
}, [disabled, onMenuOpen, setVisible]);
|
|
302
275
|
|
|
303
276
|
const styles = useMemo(() => {
|
|
304
|
-
return combineStyles<
|
|
277
|
+
return combineStyles<T, U, V>([makeSelectInPopoverStyles(), selectStyles]);
|
|
305
278
|
}, [selectStyles]);
|
|
306
279
|
|
|
307
280
|
const onTriggerClick: React.MouseEventHandler = useCallback(
|
|
@@ -326,27 +299,74 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
326
299
|
},
|
|
327
300
|
[onShow, visible]
|
|
328
301
|
);
|
|
302
|
+
|
|
303
|
+
const onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = useCallback(
|
|
304
|
+
(event) => {
|
|
305
|
+
if ((event.key === "Escape" || event.key === "Tab") && visible) {
|
|
306
|
+
onHide();
|
|
307
|
+
event.preventDefault();
|
|
308
|
+
event.stopPropagation();
|
|
309
|
+
}
|
|
310
|
+
onSelectKeyDown?.(event);
|
|
311
|
+
},
|
|
312
|
+
[onHide, onSelectKeyDown, visible]
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
const isPhone = useIsPhone();
|
|
316
|
+
|
|
317
|
+
const onBlur: React.FocusEventHandler<HTMLDivElement> = useCallback(() => {
|
|
318
|
+
if (isPhone) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
blurTimeoutRef.current = setTimeout(() => {
|
|
322
|
+
onHide(false);
|
|
323
|
+
}, 250);
|
|
324
|
+
}, [isPhone, onHide]);
|
|
325
|
+
|
|
326
|
+
const handleChange = useCallback(
|
|
327
|
+
(newValue: OnChangeValue<T, U>, actionMeta: ActionMeta<T>) => {
|
|
328
|
+
if (typeof hideOnChange === "function") {
|
|
329
|
+
if (hideOnChange(newValue, actionMeta)) {
|
|
330
|
+
onHide();
|
|
331
|
+
}
|
|
332
|
+
} else if (hideOnChange) {
|
|
333
|
+
onHide();
|
|
334
|
+
}
|
|
335
|
+
onChange(newValue, actionMeta);
|
|
336
|
+
},
|
|
337
|
+
[hideOnChange, onChange, onHide]
|
|
338
|
+
);
|
|
339
|
+
|
|
329
340
|
const paddingPopup = popupPaddingTop + popupPaddingBottom;
|
|
330
341
|
const paddingMenu = 6 + 6 + 6;
|
|
331
|
-
|
|
342
|
+
|
|
332
343
|
const maxMenuHeight = isPhone
|
|
333
|
-
? document.body.clientHeight - 45 -
|
|
344
|
+
? document.body.clientHeight - 45 - SELECT_IN_POPOVER_VALUE_MAX_HEIGHT
|
|
334
345
|
: Math.max((document.body.clientHeight / 100) * popupHeightVH, popupMinHeightPx) -
|
|
335
|
-
|
|
346
|
+
SELECT_IN_POPOVER_VALUE_MAX_HEIGHT -
|
|
336
347
|
paddingPopup -
|
|
337
348
|
paddingMenu;
|
|
338
|
-
|
|
349
|
+
|
|
350
|
+
const Trigger = components.Trigger || TriggerDefault;
|
|
351
|
+
const selectComponents = {
|
|
352
|
+
Menu: MenuTransparent,
|
|
353
|
+
DropdownIndicator: null,
|
|
354
|
+
IndicatorSeparator: null,
|
|
355
|
+
...components,
|
|
356
|
+
};
|
|
339
357
|
|
|
340
358
|
return (
|
|
341
359
|
<>
|
|
342
|
-
<
|
|
360
|
+
<Trigger
|
|
343
361
|
innerRef={ref}
|
|
362
|
+
menuOpened={visible}
|
|
363
|
+
disabled={disabled}
|
|
364
|
+
valueSelected={Boolean(value)}
|
|
344
365
|
onClick={onTriggerClick}
|
|
345
366
|
onKeyDown={onTriggerKeyDown}
|
|
346
|
-
disabled={disabled}
|
|
347
367
|
>
|
|
348
368
|
{renderValue ? renderValue() : null}
|
|
349
|
-
</
|
|
369
|
+
</Trigger>
|
|
350
370
|
{Boolean(triggerElement) && (
|
|
351
371
|
<Popup
|
|
352
372
|
supportMobile
|
|
@@ -369,42 +389,19 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
369
389
|
{/*Render target in controlled by Popover here. So we just override SelectControlContext here and set popupContainerElement to undefined. */}
|
|
370
390
|
{/*So in dom react-select will be a child of popover. */}
|
|
371
391
|
<SelectControlSettingsProvider getPopupContainerElement={undefined}>
|
|
372
|
-
<ReactSelect
|
|
392
|
+
<ReactSelect<T, U, V>
|
|
373
393
|
ref={selectRef}
|
|
374
394
|
styles={styles}
|
|
375
395
|
isSearchable={true}
|
|
376
|
-
onKeyDown={
|
|
377
|
-
if ((event.key === "Escape" || event.key === "Tab") && visible) {
|
|
378
|
-
onHide();
|
|
379
|
-
event.preventDefault();
|
|
380
|
-
event.stopPropagation();
|
|
381
|
-
}
|
|
382
|
-
onSelectKeyDown?.(event);
|
|
383
|
-
}}
|
|
396
|
+
onKeyDown={onKeyDown}
|
|
384
397
|
autoFocus={autoFocus}
|
|
385
|
-
onBlur={
|
|
386
|
-
if (isPhone) {
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
blurTimeoutRef.current = setTimeout(() => {
|
|
390
|
-
onHide(false);
|
|
391
|
-
}, 250);
|
|
392
|
-
}}
|
|
398
|
+
onBlur={onBlur}
|
|
393
399
|
value={value}
|
|
394
400
|
defaultMenuIsOpen={defaultMenuIsOpen}
|
|
395
401
|
controlShouldRenderValue
|
|
396
402
|
closeMenuOnScroll={false}
|
|
397
403
|
closeMenuOnSelect={false}
|
|
398
|
-
onChange={
|
|
399
|
-
if (typeof hideOnChange === "function") {
|
|
400
|
-
if (hideOnChange(newValue, actionMeta)) {
|
|
401
|
-
onHide();
|
|
402
|
-
}
|
|
403
|
-
} else if (hideOnChange) {
|
|
404
|
-
onHide();
|
|
405
|
-
}
|
|
406
|
-
onChange(newValue, actionMeta);
|
|
407
|
-
}}
|
|
404
|
+
onChange={handleChange}
|
|
408
405
|
placeholder={placeholder}
|
|
409
406
|
onInputChange={onInputChange}
|
|
410
407
|
noOptionsMessage={noOptionsMessage}
|
|
@@ -421,11 +418,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
421
418
|
formatGroupLabel={formatGroupLabel}
|
|
422
419
|
formatOptionLabel={formatOptionLabel}
|
|
423
420
|
{...otherSelectProps}
|
|
424
|
-
components={
|
|
425
|
-
DropdownIndicator: null,
|
|
426
|
-
IndicatorSeparator: null,
|
|
427
|
-
Menu: mergedComponents.Menu as $TSFixMe,
|
|
428
|
-
}}
|
|
421
|
+
components={selectComponents}
|
|
429
422
|
forbidValuesClearInCollnMode={forbidValuesClearInCollnMode}
|
|
430
423
|
isOptionDisabled={isOptionDisabled}
|
|
431
424
|
/>
|
|
@@ -436,8 +429,8 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
436
429
|
);
|
|
437
430
|
}
|
|
438
431
|
|
|
439
|
-
type SelectInPopoverType = <
|
|
440
|
-
props: Omit<Props<
|
|
432
|
+
type SelectInPopoverType = <T, U extends boolean, V extends GroupBase<T>>(
|
|
433
|
+
props: Omit<Props<T, U, V>, "maxMenuHeight"> & {ref?: ForwardedRef<SelectInPopoverRef<T, U, V>>}
|
|
441
434
|
) => ReturnType<typeof SelectInPopoverInner>;
|
|
442
435
|
|
|
443
436
|
// Explicit type assertion to specify that component accepts generic props because forwardRef breaks it
|
package/src/select/styles.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import {css} from "@linaria/core";
|
|
2
|
-
import type {
|
|
2
|
+
import type {CSSObjectWithLabel, GroupBase, StylesConfig} from "react-select";
|
|
3
3
|
import {inputOverrides} from "../antd/styles";
|
|
4
|
-
import {layout, space, themeVars} from "../design-system";
|
|
5
|
-
import {groupHeadingNulledStyles} from "./
|
|
6
|
-
import {MenuListNulledStyles, MenuNulledStyles} from "./
|
|
7
|
-
import {OptionNulledStyles, OptionNulledVitualizedStyles} from "./
|
|
4
|
+
import {border, layout, space, themeVars} from "../design-system";
|
|
5
|
+
import {groupHeadingNulledStyles} from "./components/group-heading";
|
|
6
|
+
import {MenuListNulledStyles, MenuNulledStyles} from "./components/menu";
|
|
7
|
+
import {OptionNulledStyles, OptionNulledVitualizedStyles} from "./components/option";
|
|
8
|
+
import {SELECT_IN_POPOVER_VALUE_MAX_HEIGHT} from "./constants";
|
|
8
9
|
|
|
9
10
|
export const expanderExpandedStyle = css`
|
|
10
11
|
transform: rotate(180deg);
|
|
11
12
|
`;
|
|
12
13
|
|
|
13
|
-
function
|
|
14
|
+
function makeControlStyle<T, U extends boolean, V extends GroupBase<T>>({
|
|
14
15
|
isSingleLine,
|
|
15
16
|
}: {
|
|
16
17
|
isSingleLine: boolean;
|
|
17
|
-
}):
|
|
18
|
+
}): StylesConfig<T, U, V> {
|
|
18
19
|
const childDivStyle: CSSObjectWithLabel = {
|
|
19
20
|
padding: 0,
|
|
20
21
|
overflow: "visible",
|
|
@@ -24,8 +25,8 @@ function createControlStyle({
|
|
|
24
25
|
childDivStyle.flexWrap = "nowrap";
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
return
|
|
28
|
-
({
|
|
28
|
+
return {
|
|
29
|
+
control: (provided, state) => ({
|
|
29
30
|
display: "flex",
|
|
30
31
|
flexWrap: isSingleLine ? "nowrap" : "wrap",
|
|
31
32
|
justifyContent: "space-between",
|
|
@@ -38,27 +39,30 @@ function createControlStyle({
|
|
|
38
39
|
paddingLeft: space.s10,
|
|
39
40
|
paddingRight: space.s12,
|
|
40
41
|
"& > div": childDivStyle,
|
|
41
|
-
}
|
|
42
|
+
}),
|
|
43
|
+
};
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
export const
|
|
46
|
+
export const makeVirtualizedStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
|
|
45
47
|
option: () => ({...OptionNulledVitualizedStyles, ...OptionNulledStyles}),
|
|
46
48
|
groupHeading: (provided) => ({
|
|
47
49
|
...provided,
|
|
48
50
|
...groupHeadingNulledStyles,
|
|
49
51
|
height: layout.menuItemHeight,
|
|
50
52
|
}),
|
|
51
|
-
};
|
|
53
|
+
});
|
|
52
54
|
|
|
53
|
-
export const
|
|
55
|
+
export const makeNonVirtualizedStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
|
|
54
56
|
menuList: (provided) => ({
|
|
55
57
|
...provided,
|
|
56
58
|
paddingTop: 6,
|
|
57
59
|
paddingBottom: 6,
|
|
58
60
|
}),
|
|
59
|
-
};
|
|
61
|
+
});
|
|
60
62
|
|
|
61
|
-
export const
|
|
63
|
+
export const makeZIndexStyles = <T, U extends boolean, V extends GroupBase<T>>(
|
|
64
|
+
zIndex: number
|
|
65
|
+
): StylesConfig<T, U, V> => ({
|
|
62
66
|
menuPortal: (provided) => ({
|
|
63
67
|
...provided,
|
|
64
68
|
zIndex: zIndex,
|
|
@@ -69,13 +73,11 @@ export const zIndexStyles = (zIndex: number): StylesConfig => ({
|
|
|
69
73
|
}),
|
|
70
74
|
});
|
|
71
75
|
|
|
72
|
-
export const
|
|
76
|
+
export const makeComponentsStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
|
|
73
77
|
option: () => OptionNulledStyles,
|
|
74
78
|
noOptionsMessage: (provided) => ({
|
|
75
79
|
...provided,
|
|
76
|
-
|
|
77
|
-
paddingTop: "",
|
|
78
|
-
paddingBottom: "",
|
|
80
|
+
padding: 0,
|
|
79
81
|
}),
|
|
80
82
|
placeholder: (provided) => ({
|
|
81
83
|
...provided,
|
|
@@ -112,7 +114,7 @@ export const componentsStyles: StylesConfig = {
|
|
|
112
114
|
alignItems: "center",
|
|
113
115
|
height: layout.inputHeight - 2,
|
|
114
116
|
}),
|
|
115
|
-
control:
|
|
117
|
+
control: makeControlStyle<T, U, V>({isSingleLine: false}).control,
|
|
116
118
|
group: (provided) => ({
|
|
117
119
|
...provided,
|
|
118
120
|
padding: 0,
|
|
@@ -150,8 +152,42 @@ export const componentsStyles: StylesConfig = {
|
|
|
150
152
|
color: themeVars.textColor,
|
|
151
153
|
};
|
|
152
154
|
},
|
|
153
|
-
};
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
export const makeSingleLineStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
|
|
158
|
+
control: makeControlStyle<T, U, V>({isSingleLine: true}).control,
|
|
159
|
+
});
|
|
154
160
|
|
|
155
|
-
export const
|
|
156
|
-
|
|
157
|
-
|
|
161
|
+
export const makeSelectInPopoverStyles = <T, U extends boolean, V extends GroupBase<T>>(): StylesConfig<T, U, V> => ({
|
|
162
|
+
container: (props) => ({
|
|
163
|
+
...props,
|
|
164
|
+
minWidth: 180,
|
|
165
|
+
width: "100%",
|
|
166
|
+
paddingTop: space.s6,
|
|
167
|
+
paddingInline: space.s6,
|
|
168
|
+
}),
|
|
169
|
+
option: (props) => ({
|
|
170
|
+
...props,
|
|
171
|
+
padding: 0,
|
|
172
|
+
borderRadius: border.radius4,
|
|
173
|
+
paddingLeft: 0,
|
|
174
|
+
paddingRight: 0,
|
|
175
|
+
}),
|
|
176
|
+
control: (props) => ({
|
|
177
|
+
...props,
|
|
178
|
+
maxHeight: SELECT_IN_POPOVER_VALUE_MAX_HEIGHT,
|
|
179
|
+
overflow: "auto",
|
|
180
|
+
margin: space.s2,
|
|
181
|
+
marginBottom: space.s4,
|
|
182
|
+
width: `calc(100% - ${space.s2 * 2}px)`,
|
|
183
|
+
borderRadius: border.radius4,
|
|
184
|
+
}),
|
|
185
|
+
menu: (props) => ({
|
|
186
|
+
...props,
|
|
187
|
+
minWidth: 100,
|
|
188
|
+
position: "static",
|
|
189
|
+
marginBlock: 0,
|
|
190
|
+
boxShadow: "none !important",
|
|
191
|
+
borderRadius: border.radius4,
|
|
192
|
+
}),
|
|
193
|
+
});
|
package/src/shortcut-badge.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import {useIsSupportHardwareKeyboard} from "./use-is-support-hardware-keyboard";
|
|
|
5
5
|
export const shortcutCss = css`
|
|
6
6
|
${{
|
|
7
7
|
...textStyles.small,
|
|
8
|
+
...textStyles.numeric.tabularOn,
|
|
8
9
|
borderRadius: border.radius4,
|
|
9
10
|
border: themeVars.shortcutBorderColor,
|
|
10
11
|
color: themeVars.shortcutTextColor,
|
package/src/tab-nav/tab-nav.tsx
CHANGED
|
@@ -15,6 +15,8 @@ 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
17
|
import {TooltipIfOverflown} from "../tooltip-if-overflown";
|
|
18
|
+
import {useCallbackRef} from "@fibery/react/src/use-callback-ref";
|
|
19
|
+
import {useResizeObserver} from "@fibery/react/src/use-resize-observer";
|
|
18
20
|
|
|
19
21
|
const tabNavIndicatorWidth = 100;
|
|
20
22
|
|
|
@@ -124,32 +126,23 @@ export const TabNavList = forwardRef<HTMLUListElement, NavigationMenuListProps>(
|
|
|
124
126
|
}
|
|
125
127
|
);
|
|
126
128
|
|
|
127
|
-
const useTabNavIndicator = (
|
|
128
|
-
{
|
|
129
|
-
active,
|
|
130
|
-
itemRef,
|
|
131
|
-
}: {
|
|
132
|
-
active?: boolean;
|
|
133
|
-
itemRef: RefObject<HTMLElement>;
|
|
134
|
-
},
|
|
135
|
-
deps: Array<unknown> = []
|
|
136
|
-
) => {
|
|
129
|
+
const useTabNavIndicator = ({active, itemRef}: {active?: boolean; itemRef: RefObject<HTMLElement>}) => {
|
|
137
130
|
const indicatorRef = useTabNavIndicatorCtx();
|
|
138
131
|
|
|
139
|
-
|
|
132
|
+
const updateIndicator = useCallbackRef(() => {
|
|
140
133
|
if (active && itemRef.current && indicatorRef.current) {
|
|
141
134
|
indicatorRef.current.style.transform = `translateX(${itemRef.current.offsetLeft}px) scaleX(${
|
|
142
135
|
itemRef.current.offsetWidth / tabNavIndicatorWidth
|
|
143
136
|
})`;
|
|
144
137
|
indicatorRef.current.classList.add(tabNavIndicatorMounted);
|
|
145
138
|
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
useLayoutEffect(() => {
|
|
142
|
+
updateIndicator();
|
|
143
|
+
}, [updateIndicator, active, indicatorRef, itemRef]);
|
|
144
|
+
|
|
145
|
+
useResizeObserver(itemRef, () => updateIndicator());
|
|
153
146
|
};
|
|
154
147
|
|
|
155
148
|
export const TabNavItem = forwardRef<HTMLLIElement, NavigationMenuItemProps & {active?: boolean}>(
|
|
@@ -157,7 +150,7 @@ export const TabNavItem = forwardRef<HTMLLIElement, NavigationMenuItemProps & {a
|
|
|
157
150
|
const itemRef = useRef(null);
|
|
158
151
|
const ref = useComposedRefs(itemRef, forwardedRef);
|
|
159
152
|
|
|
160
|
-
useTabNavIndicator({active, itemRef}
|
|
153
|
+
useTabNavIndicator({active, itemRef});
|
|
161
154
|
|
|
162
155
|
return (
|
|
163
156
|
<NavigationMenuItem ref={ref} className={cx(tabNavItem, className)} {...props}>
|
package/src/theme-provider.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import invariant from "invariant";
|
|
2
2
|
import {themeStyles} from "./theme-styles";
|
|
3
|
-
import {
|
|
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";
|
|
@@ -4,9 +4,7 @@ import {Tooltip, TooltipProps} from "./tooltip";
|
|
|
4
4
|
|
|
5
5
|
type SetNode = (element: HTMLElement | null) => void;
|
|
6
6
|
|
|
7
|
-
export const
|
|
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/unit/index.tsx
CHANGED
|
@@ -51,5 +51,13 @@ export const OptionUnit = (props: UnitPrimitiveProps) => {
|
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
export const HistoryUnit = (props: UnitPrimitiveProps & {size: CardSize}) => {
|
|
54
|
-
return
|
|
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
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {LoadingUnitValue} from "./loading-unit-value";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
type Props = {
|
|
4
4
|
value?: string;
|
|
5
|
-
}
|
|
5
|
+
};
|
|
6
6
|
|
|
7
|
-
export const MaybeUnitValue: React.FC<
|
|
7
|
+
export const MaybeUnitValue: React.FC<Props> = ({value}) => {
|
|
8
8
|
return value === undefined ? <LoadingUnitValue minWidth={18} maxWidth={18} /> : <>{value}</>;
|
|
9
9
|
};
|