@fibery/ui-kit 1.36.1 → 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 +15 -0
- package/package.json +3 -3
- package/scripts/generate-icons.mjs +15 -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 +3 -3
- package/src/actions-menu/actions-menu-sub-command-menu.tsx +3 -0
- 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 +21 -0
- package/src/button/actions-button-compact.tsx +1 -1
- package/src/button/base-button.tsx +4 -3
- 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 +16 -11
- package/src/command-menu/nested-command-menu.tsx +8 -1
- package/src/context-menu/index.tsx +3 -3
- 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 +85 -50
- package/src/dropdown-menu/index.tsx +1 -1
- 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/format-date-from-now.ts +1 -1
- 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 +8 -0
- 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/Csv.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/FiberyMono.ts +1 -1
- 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 +8 -0
- 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/SpaceList.ts +8 -0
- package/src/icons/ast/SpaceScratch.ts +8 -0
- package/src/icons/ast/SpaceTemplate.ts +8 -0
- package/src/icons/ast/SuggestIntegration.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 +30 -0
- package/src/icons/react/AiFiberyBuild.tsx +13 -0
- package/src/icons/react/Anthropic.tsx +13 -0
- package/src/icons/react/Apple.tsx +13 -0
- package/src/icons/react/Crosshair.tsx +13 -0
- package/src/icons/react/Csv.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/OpenAi.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/SpaceList.tsx +13 -0
- package/src/icons/react/SpaceScratch.tsx +13 -0
- package/src/icons/react/SpaceTemplate.tsx +13 -0
- package/src/icons/react/SuggestIntegration.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 +30 -0
- package/src/icons/svg/ai-fibery-build.svg +24 -0
- package/src/icons/svg/anthropic.svg +3 -0
- 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/csv.svg +3 -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/fibery-mono.svg +6 -1
- 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 +3 -0
- 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-list.svg +4 -0
- package/src/icons/svg/space-scratch.svg +3 -0
- package/src/icons/svg/space-template.svg +3 -0
- package/src/icons/svg/suggest-integration.svg +4 -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/icons/types.ts +2 -2
- 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 +23 -48
- package/src/mobile-styles.ts +2 -0
- package/src/new-badge.tsx +5 -6
- 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 +103 -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/toast/utils/toastify-item-name.ts +1 -1
- package/src/tooltip-if-overflown.tsx +9 -3
- package/src/type-badge-box.tsx +4 -2
- package/src/type-badge.tsx +20 -12
- 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 +60 -41
- package/src/unit/styles.ts +12 -12
- package/src/unit/types.ts +5 -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,51 +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;
|
|
95
|
+
iconStart?: ReactNode;
|
|
96
|
+
pending?: boolean;
|
|
97
|
+
pressed?: boolean;
|
|
98
|
+
menuOpened?: boolean;
|
|
128
99
|
onKeyDown?: React.KeyboardEventHandler;
|
|
129
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;
|
|
130
108
|
};
|
|
131
109
|
|
|
132
|
-
const
|
|
110
|
+
const TriggerDefault = ({innerRef, children, onClick, onKeyDown}: TriggerProps) => {
|
|
133
111
|
return (
|
|
134
112
|
<div ref={innerRef} onClick={onClick} onKeyDown={onKeyDown} tabIndex={0} className={valueClassName}>
|
|
135
113
|
{children}
|
|
@@ -137,59 +115,54 @@ const Trigger = ({innerRef, children, onClick, onKeyDown}: TriggerProps) => {
|
|
|
137
115
|
);
|
|
138
116
|
};
|
|
139
117
|
|
|
140
|
-
type
|
|
141
|
-
Trigger
|
|
142
|
-
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>;
|
|
143
120
|
};
|
|
144
121
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const defaultComponents = {Trigger, Menu};
|
|
148
|
-
|
|
149
|
-
type Ref = {
|
|
122
|
+
type SelectInPopoverRef<T, U extends boolean, V extends GroupBase<T>> = {
|
|
150
123
|
valueRef: HTMLDivElement | null;
|
|
151
|
-
selectRef:
|
|
124
|
+
selectRef: SelectInstance<T, U, V> | null;
|
|
152
125
|
};
|
|
153
126
|
|
|
154
|
-
type Props<
|
|
155
|
-
value?: PropsValue<
|
|
127
|
+
type Props<T, U extends boolean, V extends GroupBase<T>> = {
|
|
128
|
+
value?: PropsValue<T>;
|
|
156
129
|
menuIsOpen?: boolean;
|
|
157
130
|
autoFocus?: boolean;
|
|
158
131
|
virtualized?: boolean;
|
|
159
132
|
defaultMenuIsOpen?: boolean;
|
|
160
133
|
placeholder?: string;
|
|
161
134
|
noOptionsMessage?: () => string | JSX.Element | null;
|
|
162
|
-
options: OptionsOrGroups<
|
|
163
|
-
filterOption?: SelectProps<
|
|
135
|
+
options: OptionsOrGroups<T, V>;
|
|
136
|
+
filterOption?: SelectProps<T, U, V>["filterOption"];
|
|
164
137
|
inputValue?: string;
|
|
165
138
|
disabled?: boolean;
|
|
166
|
-
isCollectionMode?:
|
|
139
|
+
isCollectionMode?: U;
|
|
167
140
|
isClearable?: boolean;
|
|
168
141
|
renderValue?: () => ReactNode;
|
|
169
142
|
title?: string;
|
|
170
143
|
maxMenuHeight?: number;
|
|
171
|
-
hideOnChange?: boolean | ((newValue: OnChangeValue<
|
|
144
|
+
hideOnChange?: boolean | ((newValue: OnChangeValue<T, U>, actionMeta: ActionMeta<T>) => boolean);
|
|
172
145
|
renderInPortal?: boolean;
|
|
173
146
|
popupStyles?: string;
|
|
174
|
-
selectStyles?: StylesConfig<
|
|
175
|
-
formatGroupLabel?: (group:
|
|
176
|
-
formatOptionLabel?: (option:
|
|
177
|
-
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>;
|
|
178
151
|
onInputChange?: (s: string, actionType: {action: string}) => void;
|
|
179
152
|
onFocus?: () => void;
|
|
180
|
-
onChange: (newValue: OnChangeValue<
|
|
153
|
+
onChange: (newValue: OnChangeValue<T, U>, actionMeta: ActionMeta<T>) => void;
|
|
181
154
|
onMenuOpen?: () => void;
|
|
182
155
|
onMenuClose?: () => void | boolean;
|
|
183
156
|
getPopupContainer?: () => HTMLElement;
|
|
184
157
|
onSelectKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
|
185
158
|
forbidValuesClearInCollnMode?: boolean;
|
|
186
159
|
otherSelectProps?: Record<string, unknown>;
|
|
187
|
-
isOptionDisabled?: (option:
|
|
160
|
+
isOptionDisabled?: (option: T) => boolean;
|
|
188
161
|
};
|
|
189
162
|
|
|
190
|
-
function SelectInPopoverInner<
|
|
191
|
-
props: Omit<Props<
|
|
192
|
-
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>>
|
|
193
166
|
) {
|
|
194
167
|
const {
|
|
195
168
|
value,
|
|
@@ -234,7 +207,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
234
207
|
},
|
|
235
208
|
});
|
|
236
209
|
const blurTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
|
|
237
|
-
const selectRef = useRef<
|
|
210
|
+
const selectRef = useRef<SelectInstance<T, U, V>>(null);
|
|
238
211
|
const ref = useRef<HTMLDivElement | null>(null);
|
|
239
212
|
|
|
240
213
|
useImperativeHandle(
|
|
@@ -243,11 +216,13 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
243
216
|
({
|
|
244
217
|
valueRef: ref.current,
|
|
245
218
|
selectRef: selectRef.current,
|
|
246
|
-
} as {valueRef: HTMLDivElement; selectRef:
|
|
219
|
+
} as {valueRef: HTMLDivElement; selectRef: SelectInstance<T, U, V> | null})
|
|
247
220
|
);
|
|
221
|
+
|
|
248
222
|
useEffect(() => {
|
|
249
223
|
setTriggerElement(ref.current);
|
|
250
224
|
}, []);
|
|
225
|
+
|
|
251
226
|
useEffect(() => {
|
|
252
227
|
if (blurTimeoutRef.current) {
|
|
253
228
|
clearTimeout(blurTimeoutRef.current);
|
|
@@ -299,7 +274,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
299
274
|
}, [disabled, onMenuOpen, setVisible]);
|
|
300
275
|
|
|
301
276
|
const styles = useMemo(() => {
|
|
302
|
-
return combineStyles<
|
|
277
|
+
return combineStyles<T, U, V>([makeSelectInPopoverStyles(), selectStyles]);
|
|
303
278
|
}, [selectStyles]);
|
|
304
279
|
|
|
305
280
|
const onTriggerClick: React.MouseEventHandler = useCallback(
|
|
@@ -324,27 +299,74 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
324
299
|
},
|
|
325
300
|
[onShow, visible]
|
|
326
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
|
+
|
|
327
340
|
const paddingPopup = popupPaddingTop + popupPaddingBottom;
|
|
328
341
|
const paddingMenu = 6 + 6 + 6;
|
|
329
|
-
|
|
342
|
+
|
|
330
343
|
const maxMenuHeight = isPhone
|
|
331
|
-
? document.body.clientHeight - 45 -
|
|
344
|
+
? document.body.clientHeight - 45 - SELECT_IN_POPOVER_VALUE_MAX_HEIGHT
|
|
332
345
|
: Math.max((document.body.clientHeight / 100) * popupHeightVH, popupMinHeightPx) -
|
|
333
|
-
|
|
346
|
+
SELECT_IN_POPOVER_VALUE_MAX_HEIGHT -
|
|
334
347
|
paddingPopup -
|
|
335
348
|
paddingMenu;
|
|
336
|
-
|
|
349
|
+
|
|
350
|
+
const Trigger = components.Trigger || TriggerDefault;
|
|
351
|
+
const selectComponents = {
|
|
352
|
+
Menu: MenuTransparent,
|
|
353
|
+
DropdownIndicator: null,
|
|
354
|
+
IndicatorSeparator: null,
|
|
355
|
+
...components,
|
|
356
|
+
};
|
|
337
357
|
|
|
338
358
|
return (
|
|
339
359
|
<>
|
|
340
|
-
<
|
|
360
|
+
<Trigger
|
|
341
361
|
innerRef={ref}
|
|
362
|
+
menuOpened={visible}
|
|
363
|
+
disabled={disabled}
|
|
364
|
+
valueSelected={Boolean(value)}
|
|
342
365
|
onClick={onTriggerClick}
|
|
343
366
|
onKeyDown={onTriggerKeyDown}
|
|
344
|
-
disabled={disabled}
|
|
345
367
|
>
|
|
346
368
|
{renderValue ? renderValue() : null}
|
|
347
|
-
</
|
|
369
|
+
</Trigger>
|
|
348
370
|
{Boolean(triggerElement) && (
|
|
349
371
|
<Popup
|
|
350
372
|
supportMobile
|
|
@@ -367,42 +389,19 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
367
389
|
{/*Render target in controlled by Popover here. So we just override SelectControlContext here and set popupContainerElement to undefined. */}
|
|
368
390
|
{/*So in dom react-select will be a child of popover. */}
|
|
369
391
|
<SelectControlSettingsProvider getPopupContainerElement={undefined}>
|
|
370
|
-
<ReactSelect
|
|
392
|
+
<ReactSelect<T, U, V>
|
|
371
393
|
ref={selectRef}
|
|
372
394
|
styles={styles}
|
|
373
395
|
isSearchable={true}
|
|
374
|
-
onKeyDown={
|
|
375
|
-
if ((event.key === "Escape" || event.key === "Tab") && visible) {
|
|
376
|
-
onHide();
|
|
377
|
-
event.preventDefault();
|
|
378
|
-
event.stopPropagation();
|
|
379
|
-
}
|
|
380
|
-
onSelectKeyDown?.(event);
|
|
381
|
-
}}
|
|
396
|
+
onKeyDown={onKeyDown}
|
|
382
397
|
autoFocus={autoFocus}
|
|
383
|
-
onBlur={
|
|
384
|
-
if (isPhone) {
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
blurTimeoutRef.current = setTimeout(() => {
|
|
388
|
-
onHide(false);
|
|
389
|
-
}, 250);
|
|
390
|
-
}}
|
|
398
|
+
onBlur={onBlur}
|
|
391
399
|
value={value}
|
|
392
400
|
defaultMenuIsOpen={defaultMenuIsOpen}
|
|
393
401
|
controlShouldRenderValue
|
|
394
402
|
closeMenuOnScroll={false}
|
|
395
403
|
closeMenuOnSelect={false}
|
|
396
|
-
onChange={
|
|
397
|
-
if (typeof hideOnChange === "function") {
|
|
398
|
-
if (hideOnChange(newValue, actionMeta)) {
|
|
399
|
-
onHide();
|
|
400
|
-
}
|
|
401
|
-
} else if (hideOnChange) {
|
|
402
|
-
onHide();
|
|
403
|
-
}
|
|
404
|
-
onChange(newValue, actionMeta);
|
|
405
|
-
}}
|
|
404
|
+
onChange={handleChange}
|
|
406
405
|
placeholder={placeholder}
|
|
407
406
|
onInputChange={onInputChange}
|
|
408
407
|
noOptionsMessage={noOptionsMessage}
|
|
@@ -419,11 +418,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
419
418
|
formatGroupLabel={formatGroupLabel}
|
|
420
419
|
formatOptionLabel={formatOptionLabel}
|
|
421
420
|
{...otherSelectProps}
|
|
422
|
-
components={
|
|
423
|
-
DropdownIndicator: null,
|
|
424
|
-
IndicatorSeparator: null,
|
|
425
|
-
Menu: mergedComponents.Menu as $TSFixMe,
|
|
426
|
-
}}
|
|
421
|
+
components={selectComponents}
|
|
427
422
|
forbidValuesClearInCollnMode={forbidValuesClearInCollnMode}
|
|
428
423
|
isOptionDisabled={isOptionDisabled}
|
|
429
424
|
/>
|
|
@@ -434,8 +429,8 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
434
429
|
);
|
|
435
430
|
}
|
|
436
431
|
|
|
437
|
-
type SelectInPopoverType = <
|
|
438
|
-
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>>}
|
|
439
434
|
) => ReturnType<typeof SelectInPopoverInner>;
|
|
440
435
|
|
|
441
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/type-badge-box.tsx
CHANGED
|
@@ -8,9 +8,10 @@ type Props = {
|
|
|
8
8
|
height: number;
|
|
9
9
|
typeObject: {title: string};
|
|
10
10
|
children: ReactNode;
|
|
11
|
+
className?: string;
|
|
11
12
|
};
|
|
12
13
|
|
|
13
|
-
export const TypeBadgeBox = ({width, height, typeObject, children}: Props) => {
|
|
14
|
+
export const TypeBadgeBox = ({width, height, typeObject, children, className}: Props) => {
|
|
14
15
|
const abbr = makeAbbreviation(typeObject.title);
|
|
15
16
|
|
|
16
17
|
return (
|
|
@@ -33,7 +34,8 @@ export const TypeBadgeBox = ({width, height, typeObject, children}: Props) => {
|
|
|
33
34
|
& > div {
|
|
34
35
|
mask-image: linear-gradient(90deg, #000 60%, rgba(0, 0, 0, 0.4));
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
+
`,
|
|
38
|
+
className
|
|
37
39
|
)}
|
|
38
40
|
>
|
|
39
41
|
{children}
|