@fibery/ui-kit 1.38.0 → 1.38.1
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 +11 -0
- package/config/jest/testFrameworkSetup.js +1 -1
- package/package.json +16 -15
- package/src/abbreviate-name.ts +42 -0
- package/src/actions-menu/actions-menu-item.tsx +14 -5
- package/src/actions-menu/actions-menu-props.tsx +1 -0
- package/src/actions-menu/actions-menu.tsx +4 -1
- package/src/actions-menu/context-actions-menu.tsx +22 -0
- package/src/animated-height-container.tsx +24 -5
- package/src/antd/ant-upload.tsx +1 -1
- package/src/antd/input.tsx +4 -0
- package/src/avatar.tsx +1 -27
- package/src/button/base-button.tsx +2 -0
- package/src/button/button.tsx +3 -2
- package/src/button/icon-button.tsx +3 -3
- package/src/card-container.tsx +3 -2
- package/src/checkbox.tsx +17 -0
- package/src/collapsible-section.tsx +3 -1
- package/src/date-picker/autocomplete.tsx +11 -5
- package/src/date-picker/date-range-input.tsx +5 -1
- package/src/date-picker/date-range-picker-popup-content.tsx +31 -13
- package/src/date-picker/single-date-input.tsx +5 -1
- package/src/date-picker/styles.ts +20 -0
- package/src/design-system.ts +24 -0
- package/src/dropdown-menu/index.tsx +11 -1
- package/src/emoji-picker/emoji-picker-preview-footer.tsx +4 -0
- package/src/emoji-picker/emoji.tsx +4 -3
- package/src/emoji-picker/primitives/emoji.tsx +49 -51
- package/src/emoji-picker/primitives/footer.tsx +6 -0
- package/src/emoji-picker/primitives/search.tsx +8 -0
- package/src/emoji-picker/primitives/skin-tone.tsx +12 -2
- package/src/fibermoji-placeholder.tsx +1 -27
- package/src/file-item-2.tsx +408 -0
- package/src/file-item.tsx +63 -12
- package/src/header-layout.tsx +11 -0
- package/src/html-styles.ts +13 -4
- package/src/icons/ast/Back.ts +1 -1
- package/src/icons/ast/ExtensionFiles.ts +1 -1
- package/src/icons/ast/FileUpload.ts +1 -1
- package/src/icons/ast/SwitchToMention.ts +8 -0
- package/src/icons/ast/SwitchToText.ts +8 -0
- package/src/icons/ast/SwitchToWidget.ts +8 -0
- package/src/icons/ast/ViewGallery.ts +8 -0
- package/src/icons/ast/index.tsx +4 -0
- package/src/icons/react/SwitchToMention.tsx +13 -0
- package/src/icons/react/SwitchToText.tsx +13 -0
- package/src/icons/react/SwitchToWidget.tsx +13 -0
- package/src/icons/react/ViewGallery.tsx +13 -0
- package/src/icons/react/index.tsx +4 -0
- package/src/icons/svg/back.svg +3 -1
- package/src/icons/svg/extension/files.svg +3 -1
- package/src/icons/svg/file-upload.svg +3 -6
- package/src/icons/svg/switch-to-mention.svg +3 -0
- package/src/icons/svg/switch-to-text.svg +4 -0
- package/src/icons/svg/switch-to-widget.svg +4 -0
- package/src/icons/svg/view-gallery.svg +4 -0
- package/src/images-gallery/images-gallery-fall-through-provider.tsx +11 -0
- package/src/images-gallery/images-gallery.tsx +13 -10
- package/src/images-gallery/zoom.tsx +13 -2
- package/src/images-gallery-2/images-gallery-2.tsx +442 -0
- package/src/images-gallery-2/slide-buttons.tsx +230 -0
- package/src/images-gallery-2/zoom.tsx +35 -0
- package/src/kbd.tsx +46 -0
- package/src/modal-menu/modal-menu-item.tsx +10 -2
- package/src/modal-menu/modal-menu-trigger.tsx +19 -2
- package/src/notification-dot.tsx +16 -7
- package/src/platform-symbols.ts +9 -0
- package/src/platform.ts +2 -0
- package/src/popover/index.tsx +31 -8
- package/src/popover/modifiers.tsx +26 -19
- package/src/reactions/reaction-button.tsx +323 -101
- package/src/reactions/reaction-picker.tsx +14 -1
- package/src/reactions/reactions.tsx +11 -1
- package/src/reactions/tootltip.tsx +55 -0
- package/src/rich-text-embed-error.tsx +2 -1
- package/src/select/components/group-heading.tsx +8 -0
- package/src/select/components/menu-list-virtualized.tsx +6 -2
- package/src/select/components/option.tsx +4 -0
- package/src/select/select-control-settings-context.tsx +11 -2
- package/src/select/select-in-popover.tsx +10 -7
- package/src/select/styles.ts +21 -1
- package/src/tab-nav/tab-nav.tsx +1 -1
- package/src/toggle.tsx +8 -0
- package/src/tooltip.tsx +27 -18
- package/src/type-badge.tsx +5 -2
- package/src/unit/unit-with-tooltip.tsx +1 -1
- package/src/use-is-phone.tsx +27 -6
- package/src/shortcut-badge.tsx +0 -29
package/src/kbd.tsx
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {css, cx} from "@linaria/core";
|
|
2
|
+
import {border, lineHeight, space, textStyles, themeVars} from "./design-system";
|
|
3
|
+
import {useIsSupportHardwareKeyboard} from "./use-is-support-hardware-keyboard";
|
|
4
|
+
|
|
5
|
+
export const kbdCss = css`
|
|
6
|
+
${{
|
|
7
|
+
...textStyles.small,
|
|
8
|
+
...textStyles.numeric.tabularOn,
|
|
9
|
+
}}
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
min-width: ${space.s18}px;
|
|
14
|
+
height: ${space.s18}px;
|
|
15
|
+
padding: ${space.s2}px;
|
|
16
|
+
border-radius: ${border.radius4}px;
|
|
17
|
+
border: ${themeVars.shortcutBorderColor};
|
|
18
|
+
color: ${themeVars.shortcutTextColor};
|
|
19
|
+
line-height: ${lineHeight.nowrap};
|
|
20
|
+
white-space: nowrap;
|
|
21
|
+
user-select: none;
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
export const Kbd = ({className, ...props}: React.ComponentProps<"kbd">): JSX.Element | null => {
|
|
25
|
+
const isSupportHardwareKeyboard = useIsSupportHardwareKeyboard();
|
|
26
|
+
if (!isSupportHardwareKeyboard) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return <kbd className={cx(kbdCss, className)} {...props} />;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const KbdGroup = ({className, ...props}: React.ComponentProps<"kbd">) => {
|
|
33
|
+
return (
|
|
34
|
+
<kbd
|
|
35
|
+
className={cx(
|
|
36
|
+
className,
|
|
37
|
+
css`
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
gap: ${space.s2}px;
|
|
41
|
+
`
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
@@ -4,11 +4,12 @@ import {space, textStyles} from "../design-system";
|
|
|
4
4
|
import {useModalMenu} from "./contexts/modal-menu-context";
|
|
5
5
|
|
|
6
6
|
interface ModalMenuItemProps extends Omit<ComponentProps<"div">, "onSelect"> {
|
|
7
|
+
disabled?: boolean;
|
|
7
8
|
onSelect?: (event: Event) => void;
|
|
8
9
|
children?: ReactNode;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
export const ModalMenuItem = ({children, onSelect, ...otherProps}: ModalMenuItemProps) => {
|
|
12
|
+
export const ModalMenuItem = ({children, disabled, onSelect, ...otherProps}: ModalMenuItemProps) => {
|
|
12
13
|
const {onOpenChange} = useModalMenu();
|
|
13
14
|
|
|
14
15
|
return (
|
|
@@ -20,10 +21,17 @@ export const ModalMenuItem = ({children, onSelect, ...otherProps}: ModalMenuItem
|
|
|
20
21
|
css`
|
|
21
22
|
${textStyles.big}
|
|
22
23
|
padding: ${space.s10}px ${space.s16}px ${space.s10}px ${space.s16}px;
|
|
23
|
-
|
|
24
|
+
`,
|
|
25
|
+
disabled &&
|
|
26
|
+
css`
|
|
27
|
+
opacity: 0.4;
|
|
28
|
+
`
|
|
24
29
|
)}
|
|
25
30
|
onClick={(event) => {
|
|
26
31
|
otherProps.onClick?.(event);
|
|
32
|
+
if (disabled) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
27
35
|
const selectionEvent = new CustomEvent("modal-menu-select", {bubbles: true, cancelable: true});
|
|
28
36
|
onSelect?.(selectionEvent);
|
|
29
37
|
if (!selectionEvent.defaultPrevented) {
|
|
@@ -4,11 +4,20 @@ import {useModalMenu} from "./contexts/modal-menu-context";
|
|
|
4
4
|
|
|
5
5
|
interface ModalMenuTriggerProps extends ComponentProps<"div"> {
|
|
6
6
|
asChild?: boolean;
|
|
7
|
+
triggerEvent?: "click" | "context-menu";
|
|
7
8
|
children: ReactHTMLElement<HTMLDivElement> | ReactNode;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export const ModalMenuTrigger = ({
|
|
11
|
+
export const ModalMenuTrigger = ({
|
|
12
|
+
asChild,
|
|
13
|
+
triggerEvent,
|
|
14
|
+
children,
|
|
15
|
+
onClick,
|
|
16
|
+
onContextMenu,
|
|
17
|
+
...otherProps
|
|
18
|
+
}: ModalMenuTriggerProps) => {
|
|
11
19
|
const {open, onOpenChange} = useModalMenu();
|
|
20
|
+
|
|
12
21
|
if (asChild) {
|
|
13
22
|
const className = (children as ReactHTMLElement<HTMLDivElement>)?.props?.className;
|
|
14
23
|
return cloneElement(children as ReactHTMLElement<HTMLDivElement>, {
|
|
@@ -16,7 +25,15 @@ export const ModalMenuTrigger = ({asChild, children, onClick, ...otherProps}: Mo
|
|
|
16
25
|
className: cx(className, otherProps.className),
|
|
17
26
|
onClick: (event) => {
|
|
18
27
|
onClick?.(event);
|
|
19
|
-
|
|
28
|
+
if (triggerEvent === "click") {
|
|
29
|
+
onOpenChange(!open);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
onContextMenu: (event) => {
|
|
33
|
+
onContextMenu?.(event);
|
|
34
|
+
if (triggerEvent === "context-menu") {
|
|
35
|
+
onOpenChange(!open);
|
|
36
|
+
}
|
|
20
37
|
},
|
|
21
38
|
});
|
|
22
39
|
}
|
package/src/notification-dot.tsx
CHANGED
|
@@ -10,14 +10,23 @@ const activityIndicatorStyle = css`
|
|
|
10
10
|
}}
|
|
11
11
|
`;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
type PropsType = {
|
|
14
|
+
big?: boolean;
|
|
15
|
+
color?: string;
|
|
16
|
+
style?: Record<string, string | number | null>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const NotificationDot = ({big = true, color = themeVars.active, style}: PropsType) => {
|
|
14
20
|
const size = big ? space.s6 : space.s4;
|
|
15
21
|
const marginTop = big ? -6 : -1;
|
|
16
22
|
const marginRight = big ? -1 : 0;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
const styleObject = {
|
|
24
|
+
backgroundColor: color,
|
|
25
|
+
width: size,
|
|
26
|
+
height: size,
|
|
27
|
+
marginTop,
|
|
28
|
+
marginRight,
|
|
29
|
+
...style,
|
|
30
|
+
};
|
|
31
|
+
return <div className={activityIndicatorStyle} style={styleObject} />;
|
|
23
32
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {isMac} from "./platform";
|
|
2
|
+
|
|
3
|
+
export const ctrlSymbol = isMac ? "⌘" : "Ctrl";
|
|
4
|
+
export const explicitCtrlSymbol = isMac ? "⌃" : "Ctrl";
|
|
5
|
+
export const winSymbol = isMac ? "⌘" : "Win";
|
|
6
|
+
export const shiftSymbol = isMac ? "⇧" : "⇧";
|
|
7
|
+
export const altSymbol = isMac ? "⌥" : "Alt";
|
|
8
|
+
export const deleteSymbol = isMac ? "⌫" : "Delete";
|
|
9
|
+
export const enterSymbol = isMac ? "↵" : "↵";
|
package/src/platform.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import {UAParser} from "ua-parser-js";
|
|
2
2
|
|
|
3
3
|
export const isMac = navigator.platform.startsWith("Mac");
|
|
4
|
+
export const isWindows = navigator.platform.startsWith("Win");
|
|
5
|
+
export const isLinux = navigator.platform.startsWith("Linux");
|
|
4
6
|
export const isMobile = new UAParser(navigator.userAgent).getDevice().type === "mobile";
|
package/src/popover/index.tsx
CHANGED
|
@@ -36,7 +36,7 @@ import {useTheme} from "../theme-provider";
|
|
|
36
36
|
import {$TSFixMe} from "../tsfixme";
|
|
37
37
|
import {useIsPhone} from "../use-is-phone";
|
|
38
38
|
import {usePopupModifiers} from "./popup-modifiers-context";
|
|
39
|
-
import {
|
|
39
|
+
import {applyMaxSize, makeMaxSizeModifier, observeWidth} from "./modifiers";
|
|
40
40
|
import {isElementReference, Reference} from "./reference";
|
|
41
41
|
import {basicPopupClassName, basicPopupContainerClassName, hidePopupWhenTriggerIsHiddenClassName} from "./styles";
|
|
42
42
|
import {MobilePopupProvider, useMobilePopup} from "./mobile-popup-context";
|
|
@@ -249,13 +249,13 @@ const Trigger = ({asChild = false, reference, children}: TriggerProps) => {
|
|
|
249
249
|
}
|
|
250
250
|
}, [reference, setTriggerElement]);
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
// Reference is passed
|
|
253
|
+
if (reference !== undefined) {
|
|
253
254
|
return null;
|
|
254
255
|
}
|
|
255
256
|
|
|
256
257
|
if (asChild && isValidElement(children)) {
|
|
257
258
|
return cloneElement(children, {
|
|
258
|
-
// @ts-expect-error: React.cloneElement typing does not include `ref`, but it's valid at runtime
|
|
259
259
|
ref: setTriggerElement,
|
|
260
260
|
"aria-expanded": open,
|
|
261
261
|
"aria-haspopup": true,
|
|
@@ -307,6 +307,8 @@ type ContentProps = {
|
|
|
307
307
|
|
|
308
308
|
export type ContentRef = {update: (() => Promise<unknown>) | null};
|
|
309
309
|
|
|
310
|
+
const padding = space.s8;
|
|
311
|
+
|
|
310
312
|
const Content = forwardRef<ContentRef, ContentProps>(function PopoverContentInner(
|
|
311
313
|
{
|
|
312
314
|
children,
|
|
@@ -341,23 +343,44 @@ const Content = forwardRef<ContentRef, ContentProps>(function PopoverContentInne
|
|
|
341
343
|
|
|
342
344
|
// We get infinite popup renders if this is not in a separate memo
|
|
343
345
|
const shrinkableModifiers = useMemo(() => {
|
|
344
|
-
return shrinkable
|
|
346
|
+
return shrinkable
|
|
347
|
+
? [
|
|
348
|
+
makeMaxSizeModifier({
|
|
349
|
+
padding,
|
|
350
|
+
...preventOverflowOptions,
|
|
351
|
+
}),
|
|
352
|
+
applyMaxSize,
|
|
353
|
+
]
|
|
354
|
+
: [];
|
|
345
355
|
}, [preventOverflowOptions, shrinkable]);
|
|
346
356
|
|
|
347
357
|
const modifiers = useMemo(() => {
|
|
348
358
|
return _.compact([
|
|
349
|
-
{
|
|
359
|
+
{
|
|
360
|
+
name: "flip",
|
|
361
|
+
options: {
|
|
362
|
+
padding,
|
|
363
|
+
...popupModifiers.flipOptions,
|
|
364
|
+
...flipOptions,
|
|
365
|
+
},
|
|
366
|
+
},
|
|
350
367
|
{
|
|
351
368
|
name: "preventOverflow",
|
|
352
369
|
options: {
|
|
353
370
|
tether: false,
|
|
354
|
-
padding
|
|
371
|
+
padding,
|
|
355
372
|
...popupModifiers.preventOverflowOptions,
|
|
356
373
|
...preventOverflowOptions,
|
|
357
374
|
},
|
|
358
375
|
},
|
|
359
|
-
{
|
|
360
|
-
|
|
376
|
+
{
|
|
377
|
+
name: "offset",
|
|
378
|
+
options: {offset},
|
|
379
|
+
},
|
|
380
|
+
!transform && {
|
|
381
|
+
name: "computeStyles",
|
|
382
|
+
options: {gpuAcceleration: false},
|
|
383
|
+
},
|
|
361
384
|
observeWidth,
|
|
362
385
|
...shrinkableModifiers,
|
|
363
386
|
...additionalModifiers,
|
|
@@ -1,30 +1,37 @@
|
|
|
1
1
|
import {Options as PreventOverflowOptions} from "@popperjs/core/lib/modifiers/preventOverflow";
|
|
2
|
-
import {
|
|
3
|
-
import {Modifier, ModifierArguments} from "@popperjs/core";
|
|
2
|
+
import {Modifier, ModifierArguments, Placement, Boundary, RootBoundary, Padding, Context} from "@popperjs/core";
|
|
4
3
|
import maxSize from "popper-max-size-modifier";
|
|
5
4
|
import {getResizeListener} from "@fibery/helpers/utils/resize-listener";
|
|
6
5
|
import {isElementReference} from "./reference";
|
|
7
6
|
import _ from "lodash";
|
|
8
7
|
|
|
9
|
-
type
|
|
8
|
+
type MaxSizeOptions = {
|
|
9
|
+
placement: Placement;
|
|
10
|
+
boundary: Boundary;
|
|
11
|
+
rootBoundary: RootBoundary;
|
|
12
|
+
elementContext: Context;
|
|
13
|
+
altBoundary: boolean;
|
|
14
|
+
padding: Padding;
|
|
15
|
+
};
|
|
10
16
|
|
|
11
|
-
export const
|
|
12
|
-
{
|
|
17
|
+
export const makeMaxSizeModifier = (options: Partial<PreventOverflowOptions>): Modifier<"maxSize", MaxSizeOptions> => {
|
|
18
|
+
return {
|
|
13
19
|
...maxSize,
|
|
14
|
-
options
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
20
|
+
options,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const applyMaxSize: Modifier<"applyMaxSize", Record<string, never>> = {
|
|
25
|
+
name: "applyMaxSize",
|
|
26
|
+
enabled: true,
|
|
27
|
+
phase: "beforeWrite",
|
|
28
|
+
requires: ["maxSize"],
|
|
29
|
+
fn({state}) {
|
|
30
|
+
const {width, height} = state.modifiersData.maxSize;
|
|
31
|
+
state.styles.popper.maxWidth = `${width}px`;
|
|
32
|
+
state.styles.popper.maxHeight = `${height}px`;
|
|
26
33
|
},
|
|
27
|
-
|
|
34
|
+
};
|
|
28
35
|
|
|
29
36
|
const observeWidthEffect: (arg0: ModifierArguments<Record<string, unknown>>) => void = ({state, instance}) => {
|
|
30
37
|
const {popper, reference} = state.elements;
|
|
@@ -54,7 +61,7 @@ const observeWidthEffect: (arg0: ModifierArguments<Record<string, unknown>>) =>
|
|
|
54
61
|
};
|
|
55
62
|
};
|
|
56
63
|
|
|
57
|
-
export const observeWidth:
|
|
64
|
+
export const observeWidth: Modifier<"observeWidth", Record<string, never>> = {
|
|
58
65
|
name: "observeWidth",
|
|
59
66
|
enabled: true,
|
|
60
67
|
phase: "main",
|