mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-08 13:00:13 +02:00
optimize various base components
This commit is contained in:
@@ -3,7 +3,7 @@ import {
|
||||
ActionIcon as MantineActionIcon,
|
||||
ActionIconProps as MantineActionIconProps,
|
||||
} from '@mantine/core';
|
||||
import { forwardRef } from 'react';
|
||||
import { forwardRef, useMemo } from 'react';
|
||||
|
||||
import styles from './action-icon.module.css';
|
||||
|
||||
@@ -41,11 +41,16 @@ const _ActionIcon = forwardRef<HTMLButtonElement, ActionIconProps>(
|
||||
if (onClick) onClick(e);
|
||||
};
|
||||
|
||||
const actionIconProps: ActionIconProps = {
|
||||
classNames: {
|
||||
const memoizedClassNames = useMemo(
|
||||
() => ({
|
||||
root: styles.root,
|
||||
...classNames,
|
||||
},
|
||||
}),
|
||||
[classNames],
|
||||
);
|
||||
|
||||
const actionIconProps: ActionIconProps = {
|
||||
classNames: memoizedClassNames,
|
||||
size,
|
||||
variant,
|
||||
...props,
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
Badge as MantineBadge,
|
||||
BadgeProps as MantineBadgeProps,
|
||||
} from '@mantine/core';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import styles from './badge.module.css';
|
||||
|
||||
@@ -12,17 +13,20 @@ export interface BadgeProps
|
||||
extends ElementProps<'div', keyof MantineBadgeProps>,
|
||||
MantineBadgeProps {}
|
||||
|
||||
const _Badge = ({ children, classNames, variant = 'default', ...props }: BadgeProps) => {
|
||||
const BaseBadge = ({ children, classNames, variant = 'default', ...props }: BadgeProps) => {
|
||||
const memoizedClassNames = useMemo(
|
||||
() => ({
|
||||
root: styles.root,
|
||||
...classNames,
|
||||
}),
|
||||
[classNames],
|
||||
);
|
||||
|
||||
return (
|
||||
<MantineBadge
|
||||
classNames={{ root: styles.root, ...classNames }}
|
||||
radius="md"
|
||||
variant={variant}
|
||||
{...props}
|
||||
>
|
||||
<MantineBadge classNames={memoizedClassNames} radius="md" variant={variant} {...props}>
|
||||
{children}
|
||||
</MantineBadge>
|
||||
);
|
||||
};
|
||||
|
||||
export const Badge = createPolymorphicComponent<'button', BadgeProps>(_Badge);
|
||||
export const Badge = createPolymorphicComponent<'button', BadgeProps>(BaseBadge);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { ElementProps, Box as MantineBox, BoxProps as MantineBoxProps } from '@mantine/core';
|
||||
import { memo } from 'react';
|
||||
|
||||
export interface BoxProps extends ElementProps<'div', keyof MantineBoxProps>, MantineBoxProps {}
|
||||
|
||||
export const Box = ({ children, ...props }: BoxProps) => {
|
||||
export const Box = memo(({ children, ...props }: BoxProps) => {
|
||||
return <MantineBox {...props}>{children}</MantineBox>;
|
||||
};
|
||||
});
|
||||
|
||||
Box.displayName = 'Box';
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { ButtonVariant, ButtonProps as MantineButtonProps } from '@mantine/
|
||||
|
||||
import { ElementProps, Button as MantineButton } from '@mantine/core';
|
||||
import clsx from 'clsx';
|
||||
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import styles from './button.module.css';
|
||||
|
||||
@@ -41,21 +41,26 @@ export const _Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
}: ButtonProps,
|
||||
ref,
|
||||
) => {
|
||||
const memoizedClassNames = useMemo(
|
||||
() => ({
|
||||
inner: styles.inner,
|
||||
label: clsx(styles.label, {
|
||||
[styles.uppercase]: uppercase,
|
||||
}),
|
||||
loader: styles.loader,
|
||||
root: styles.root,
|
||||
section: styles.section,
|
||||
...classNames,
|
||||
}),
|
||||
[classNames, uppercase],
|
||||
);
|
||||
|
||||
if (tooltip) {
|
||||
return (
|
||||
<Tooltip withinPortal {...tooltip}>
|
||||
<MantineButton
|
||||
autoContrast
|
||||
classNames={{
|
||||
inner: styles.inner,
|
||||
label: clsx(styles.label, {
|
||||
[styles.uppercase]: uppercase,
|
||||
}),
|
||||
loader: styles.loader,
|
||||
root: styles.root,
|
||||
section: styles.section,
|
||||
...classNames,
|
||||
}}
|
||||
classNames={memoizedClassNames}
|
||||
loading={loading}
|
||||
ref={ref}
|
||||
size={size}
|
||||
@@ -71,16 +76,7 @@ export const _Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
|
||||
return (
|
||||
<MantineButton
|
||||
classNames={{
|
||||
inner: styles.inner,
|
||||
label: clsx(styles.label, {
|
||||
[styles.uppercase]: uppercase,
|
||||
}),
|
||||
loader: styles.loader,
|
||||
root: styles.root,
|
||||
section: styles.section,
|
||||
...classNames,
|
||||
}}
|
||||
classNames={memoizedClassNames}
|
||||
loading={loading}
|
||||
ref={ref}
|
||||
size={size}
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import { Center as MantineCenter, CenterProps as MantineCenterProps } from '@mantine/core';
|
||||
import { forwardRef, MouseEvent } from 'react';
|
||||
import { forwardRef, memo, MouseEvent, useMemo } from 'react';
|
||||
|
||||
export interface CenterProps extends MantineCenterProps {
|
||||
onClick?: (e: MouseEvent<HTMLDivElement>) => void;
|
||||
}
|
||||
|
||||
export const Center = forwardRef<HTMLDivElement, CenterProps>(
|
||||
const _Center = forwardRef<HTMLDivElement, CenterProps>(
|
||||
({ children, classNames, onClick, style, ...props }, ref) => {
|
||||
const memoizedClassNames = useMemo(() => ({ ...classNames }), [classNames]);
|
||||
const memoizedStyle = useMemo(() => ({ ...style }), [style]);
|
||||
|
||||
return (
|
||||
<MantineCenter
|
||||
classNames={{ ...classNames }}
|
||||
classNames={memoizedClassNames}
|
||||
onClick={onClick}
|
||||
ref={ref}
|
||||
style={{ ...style }}
|
||||
style={memoizedStyle}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
@@ -20,3 +23,7 @@ export const Center = forwardRef<HTMLDivElement, CenterProps>(
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
_Center.displayName = 'Center';
|
||||
|
||||
export const Center = memo(_Center);
|
||||
|
||||
@@ -1,19 +1,33 @@
|
||||
import { Divider as MantineDivider, DividerProps as MantineDividerProps } from '@mantine/core';
|
||||
import { forwardRef } from 'react';
|
||||
import { forwardRef, memo, useMemo } from 'react';
|
||||
|
||||
import styles from './divider.module.css';
|
||||
|
||||
export interface DividerProps extends MantineDividerProps {}
|
||||
|
||||
export const Divider = forwardRef<HTMLDivElement, DividerProps>(
|
||||
const _Divider = forwardRef<HTMLDivElement, DividerProps>(
|
||||
({ classNames, style, ...props }, ref) => {
|
||||
const memoizedClassNames = useMemo(
|
||||
() => ({
|
||||
root: styles.root,
|
||||
...classNames,
|
||||
}),
|
||||
[classNames],
|
||||
);
|
||||
|
||||
const memoizedStyle = useMemo(() => ({ ...style }), [style]);
|
||||
|
||||
return (
|
||||
<MantineDivider
|
||||
classNames={{ root: styles.root, ...classNames }}
|
||||
classNames={memoizedClassNames}
|
||||
ref={ref}
|
||||
style={{ ...style }}
|
||||
style={memoizedStyle}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
_Divider.displayName = 'Divider';
|
||||
|
||||
export const Divider = memo(_Divider);
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
import { Flex as MantineFlex, FlexProps as MantineFlexProps } from '@mantine/core';
|
||||
import { forwardRef } from 'react';
|
||||
import { forwardRef, memo, useMemo } from 'react';
|
||||
|
||||
export interface FlexProps extends MantineFlexProps {}
|
||||
|
||||
export const Flex = forwardRef<HTMLDivElement, FlexProps>(({ children, ...props }, ref) => {
|
||||
return (
|
||||
<MantineFlex
|
||||
classNames={{ ...props.classNames }}
|
||||
ref={ref}
|
||||
style={{ ...props.style }}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</MantineFlex>
|
||||
);
|
||||
});
|
||||
const _Flex = forwardRef<HTMLDivElement, FlexProps>(
|
||||
({ children, classNames, style, ...props }, ref) => {
|
||||
const memoizedClassNames = useMemo(() => ({ ...classNames }), [classNames]);
|
||||
const memoizedStyle = useMemo(() => ({ ...style }), [style]);
|
||||
|
||||
return (
|
||||
<MantineFlex classNames={memoizedClassNames} ref={ref} style={memoizedStyle} {...props}>
|
||||
{children}
|
||||
</MantineFlex>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
_Flex.displayName = 'Flex';
|
||||
|
||||
export const Flex = memo(_Flex);
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import { Grid as MantineGrid, GridProps as MantineGridProps } from '@mantine/core';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
export interface GridProps extends MantineGridProps {}
|
||||
|
||||
export const Grid = ({ classNames, style, ...props }: GridProps) => {
|
||||
return <MantineGrid classNames={{ ...classNames }} style={{ ...style }} {...props} />;
|
||||
const BaseGrid = ({ classNames, style, ...props }: GridProps) => {
|
||||
const memoizedClassNames = useMemo(() => ({ ...classNames }), [classNames]);
|
||||
const memoizedStyle = useMemo(() => ({ ...style }), [style]);
|
||||
|
||||
return <MantineGrid classNames={memoizedClassNames} style={memoizedStyle} {...props} />;
|
||||
};
|
||||
|
||||
Grid.Col = MantineGrid.Col;
|
||||
BaseGrid.displayName = 'Grid';
|
||||
|
||||
export const Grid = memo(BaseGrid);
|
||||
|
||||
(Grid as typeof Grid & { Col: typeof MantineGrid.Col }).Col = MantineGrid.Col;
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
import { Group as MantineGroup, GroupProps as MantineGroupProps } from '@mantine/core';
|
||||
import { forwardRef } from 'react';
|
||||
import { forwardRef, memo, useMemo } from 'react';
|
||||
|
||||
export interface GroupProps extends MantineGroupProps {}
|
||||
|
||||
export const Group = forwardRef<HTMLDivElement, GroupProps>(({ children, ...props }, ref) => {
|
||||
return (
|
||||
<MantineGroup
|
||||
classNames={{ ...props.classNames }}
|
||||
ref={ref}
|
||||
style={{ ...props.style }}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</MantineGroup>
|
||||
);
|
||||
});
|
||||
const _Group = forwardRef<HTMLDivElement, GroupProps>(
|
||||
({ children, classNames, style, ...props }, ref) => {
|
||||
const memoizedClassNames = useMemo(() => ({ ...classNames }), [classNames]);
|
||||
const memoizedStyle = useMemo(() => ({ ...style }), [style]);
|
||||
|
||||
return (
|
||||
<MantineGroup
|
||||
classNames={memoizedClassNames}
|
||||
ref={ref}
|
||||
style={memoizedStyle}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</MantineGroup>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
_Group.displayName = 'Group';
|
||||
|
||||
export const Group = memo(_Group);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import clsx from 'clsx';
|
||||
import { motion } from 'motion/react';
|
||||
import { type ComponentType, forwardRef } from 'react';
|
||||
import { type ComponentType, forwardRef, memo, useMemo } from 'react';
|
||||
import { IconBaseProps } from 'react-icons';
|
||||
import { FaLastfmSquare } from 'react-icons/fa';
|
||||
import {
|
||||
@@ -278,19 +278,23 @@ type IconColor =
|
||||
| 'success'
|
||||
| 'warn';
|
||||
|
||||
export const Icon = forwardRef<HTMLDivElement, IconProps>((props, ref) => {
|
||||
const _Icon = forwardRef<HTMLDivElement, IconProps>((props, ref) => {
|
||||
const { animate, className, color, fill, icon, size = 'md' } = props;
|
||||
|
||||
const IconComponent: ComponentType<any> = AppIcon[icon];
|
||||
|
||||
const classNames = clsx(className, {
|
||||
[styles.fill]: true,
|
||||
[styles.pulse]: animate === 'pulse',
|
||||
[styles.spin]: animate === 'spin',
|
||||
[styles[`color-${color || fill}`]]: color || fill,
|
||||
[styles[`fill-${fill}`]]: fill,
|
||||
[styles[`size-${size}`]]: true,
|
||||
});
|
||||
const classNames = useMemo(
|
||||
() =>
|
||||
clsx(className, {
|
||||
[styles.fill]: true,
|
||||
[styles.pulse]: animate === 'pulse',
|
||||
[styles.spin]: animate === 'spin',
|
||||
[styles[`color-${color || fill}`]]: color || fill,
|
||||
[styles[`fill-${fill}`]]: fill,
|
||||
[styles[`size-${size}`]]: true,
|
||||
}),
|
||||
[animate, className, color, fill, size],
|
||||
);
|
||||
|
||||
return (
|
||||
<IconComponent
|
||||
@@ -302,6 +306,10 @@ export const Icon = forwardRef<HTMLDivElement, IconProps>((props, ref) => {
|
||||
);
|
||||
});
|
||||
|
||||
_Icon.displayName = 'Icon';
|
||||
|
||||
export const Icon = memo(_Icon);
|
||||
|
||||
Icon.displayName = 'Icon';
|
||||
|
||||
export const MotionIcon: ComponentType = motion.create(Icon);
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
MultiSelect as MantineMultiSelect,
|
||||
MultiSelectProps as MantineMultiSelectProps,
|
||||
} from '@mantine/core';
|
||||
import { CSSProperties } from 'react';
|
||||
import { CSSProperties, useMemo } from 'react';
|
||||
|
||||
import styles from './multi-select.module.css';
|
||||
|
||||
@@ -11,6 +11,23 @@ export interface MultiSelectProps extends MantineMultiSelectProps {
|
||||
width?: CSSProperties['width'];
|
||||
}
|
||||
|
||||
const defaultClassNames = {
|
||||
dropdown: styles.dropdown,
|
||||
input: styles.input,
|
||||
label: styles.label,
|
||||
option: styles.option,
|
||||
pill: styles.pill,
|
||||
pillsList: styles.pillsList,
|
||||
root: styles.root,
|
||||
};
|
||||
|
||||
const defaultClearButtonProps = {
|
||||
classNames: {
|
||||
root: styles.clearButton,
|
||||
},
|
||||
variant: 'transparent' as const,
|
||||
};
|
||||
|
||||
export const MultiSelect = ({
|
||||
classNames,
|
||||
maxWidth,
|
||||
@@ -18,25 +35,21 @@ export const MultiSelect = ({
|
||||
width,
|
||||
...props
|
||||
}: MultiSelectProps) => {
|
||||
const mergedClassNames = useMemo(
|
||||
() => (classNames ? { ...defaultClassNames, ...classNames } : defaultClassNames),
|
||||
[classNames],
|
||||
);
|
||||
|
||||
const style = useMemo(
|
||||
() => (maxWidth || width ? { maxWidth, width } : undefined),
|
||||
[maxWidth, width],
|
||||
);
|
||||
|
||||
return (
|
||||
<MantineMultiSelect
|
||||
classNames={{
|
||||
dropdown: styles.dropdown,
|
||||
input: styles.input,
|
||||
label: styles.label,
|
||||
option: styles.option,
|
||||
pill: styles.pill,
|
||||
pillsList: styles.pillsList,
|
||||
root: styles.root,
|
||||
...classNames,
|
||||
}}
|
||||
clearButtonProps={{
|
||||
classNames: {
|
||||
root: styles.clearButton,
|
||||
},
|
||||
variant: 'transparent',
|
||||
}}
|
||||
style={{ maxWidth, width }}
|
||||
classNames={mergedClassNames}
|
||||
clearButtonProps={defaultClearButtonProps}
|
||||
style={style}
|
||||
variant={variant}
|
||||
withCheckIcon={false}
|
||||
{...props}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { memo, ReactNode, useMemo } from 'react';
|
||||
|
||||
import styles from './option.module.css';
|
||||
|
||||
@@ -10,13 +10,22 @@ interface OptionProps extends GroupProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const Option = ({ children, ...props }: OptionProps) => {
|
||||
const defaultClassNames = { root: styles.root };
|
||||
|
||||
export const Option = memo(({ children, classNames, ...props }: OptionProps) => {
|
||||
const mergedClassNames = useMemo(
|
||||
() => (classNames ? { ...defaultClassNames, ...classNames } : defaultClassNames),
|
||||
[classNames],
|
||||
);
|
||||
|
||||
return (
|
||||
<Group classNames={{ root: styles.root }} grow {...props}>
|
||||
<Group classNames={mergedClassNames} grow {...props}>
|
||||
{children}
|
||||
</Group>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
Option.displayName = 'Option';
|
||||
|
||||
interface LabelProps {
|
||||
children: ReactNode;
|
||||
@@ -34,5 +43,5 @@ const Control = ({ children }: ControlProps) => {
|
||||
return <Flex justify="flex-end">{children}</Flex>;
|
||||
};
|
||||
|
||||
Option.Label = Label;
|
||||
Option.Control = Control;
|
||||
(Option as typeof Option & { Label: typeof Label }).Label = Label;
|
||||
(Option as typeof Option & { Control: typeof Control }).Control = Control;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { PaperProps as MantinePaperProps } from '@mantine/core';
|
||||
|
||||
import { Paper as MantinePaper } from '@mantine/core';
|
||||
import { ReactNode } from 'react';
|
||||
import { memo, ReactNode, useMemo } from 'react';
|
||||
|
||||
import styles from './paper.module.css';
|
||||
|
||||
@@ -9,19 +9,24 @@ export interface PaperProps extends MantinePaperProps {
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const Paper = ({ children, classNames, style, ...props }: PaperProps) => {
|
||||
const BasePaper = ({ children, classNames, style, ...props }: PaperProps) => {
|
||||
const memoizedClassNames = useMemo(
|
||||
() => ({
|
||||
root: styles.root,
|
||||
...classNames,
|
||||
}),
|
||||
[classNames],
|
||||
);
|
||||
|
||||
const memoizedStyle = useMemo(() => ({ ...style }), [style]);
|
||||
|
||||
return (
|
||||
<MantinePaper
|
||||
classNames={{
|
||||
root: styles.root,
|
||||
...classNames,
|
||||
}}
|
||||
style={{
|
||||
...style,
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
<MantinePaper classNames={memoizedClassNames} style={memoizedStyle} {...props}>
|
||||
{children}
|
||||
</MantinePaper>
|
||||
);
|
||||
};
|
||||
|
||||
BasePaper.displayName = 'Paper';
|
||||
|
||||
export const Paper = memo(BasePaper);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Center } from '@mantine/core';
|
||||
import { memo } from 'react';
|
||||
import { IconBaseProps } from 'react-icons';
|
||||
import { CgSpinnerTwo } from 'react-icons/cg';
|
||||
|
||||
@@ -12,7 +13,7 @@ interface SpinnerProps extends IconBaseProps {
|
||||
|
||||
export const SpinnerIcon = CgSpinnerTwo;
|
||||
|
||||
export const Spinner = ({ ...props }: SpinnerProps) => {
|
||||
const _Spinner = ({ ...props }: SpinnerProps) => {
|
||||
if (props.container) {
|
||||
return (
|
||||
<Center className={styles.container}>
|
||||
@@ -23,3 +24,7 @@ export const Spinner = ({ ...props }: SpinnerProps) => {
|
||||
|
||||
return <SpinnerIcon className={styles.icon} color={props.color} size={props.size} />;
|
||||
};
|
||||
|
||||
_Spinner.displayName = 'Spinner';
|
||||
|
||||
export const Spinner = memo(_Spinner);
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
import { Stack as MantineStack, StackProps as MantineStackProps } from '@mantine/core';
|
||||
import { forwardRef } from 'react';
|
||||
import { forwardRef, memo, useMemo } from 'react';
|
||||
|
||||
export interface StackProps extends MantineStackProps {}
|
||||
|
||||
export const Stack = forwardRef<HTMLDivElement, StackProps>(({ children, ...props }, ref) => {
|
||||
return (
|
||||
<MantineStack
|
||||
classNames={{ ...props.classNames }}
|
||||
ref={ref}
|
||||
style={{ ...props.style }}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</MantineStack>
|
||||
);
|
||||
});
|
||||
const _Stack = forwardRef<HTMLDivElement, StackProps>(
|
||||
({ children, classNames, style, ...props }, ref) => {
|
||||
const memoizedClassNames = useMemo(() => ({ ...classNames }), [classNames]);
|
||||
const memoizedStyle = useMemo(() => ({ ...style }), [style]);
|
||||
|
||||
return (
|
||||
<MantineStack
|
||||
classNames={memoizedClassNames}
|
||||
ref={ref}
|
||||
style={memoizedStyle}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</MantineStack>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
_Stack.displayName = 'Stack';
|
||||
|
||||
export const Stack = memo(_Stack);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Text as MantineText, TextProps as MantineTextProps } from '@mantine/core';
|
||||
import clsx from 'clsx';
|
||||
import { ComponentPropsWithoutRef, ReactNode } from 'react';
|
||||
import { ComponentPropsWithoutRef, ReactNode, useMemo } from 'react';
|
||||
|
||||
import styles from './text.module.css';
|
||||
|
||||
@@ -21,7 +21,7 @@ type Font = 'Epilogue' | 'Gotham' | 'Inter' | 'Poppins';
|
||||
|
||||
type MantineTextDivProps = ComponentPropsWithoutRef<'div'> & MantineTextProps;
|
||||
|
||||
export const _Text = ({
|
||||
export const BaseText = ({
|
||||
children,
|
||||
font,
|
||||
isLink,
|
||||
@@ -31,28 +31,31 @@ export const _Text = ({
|
||||
weight,
|
||||
...rest
|
||||
}: TextProps) => {
|
||||
const classNames = useMemo(
|
||||
() => ({
|
||||
root: clsx(styles.root, {
|
||||
[styles.link]: isLink,
|
||||
[styles.muted]: isMuted,
|
||||
[styles.noSelect]: isNoSelect,
|
||||
[styles.overflowHidden]: overflow === 'hidden',
|
||||
}),
|
||||
}),
|
||||
[isLink, isMuted, isNoSelect, overflow],
|
||||
);
|
||||
|
||||
const style = useMemo(
|
||||
() =>
|
||||
({
|
||||
'--font-family': font,
|
||||
}) as React.CSSProperties,
|
||||
[font],
|
||||
);
|
||||
|
||||
return (
|
||||
<MantineText
|
||||
classNames={{
|
||||
root: clsx(styles.root, {
|
||||
[styles.link]: isLink,
|
||||
[styles.muted]: isMuted,
|
||||
[styles.noSelect]: isNoSelect,
|
||||
[styles.overflowHidden]: overflow === 'hidden',
|
||||
}),
|
||||
}}
|
||||
component="div"
|
||||
fw={weight}
|
||||
style={
|
||||
{
|
||||
'--font-family': font,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
{...rest}
|
||||
>
|
||||
<MantineText classNames={classNames} component="div" fw={weight} style={style} {...rest}>
|
||||
{children}
|
||||
</MantineText>
|
||||
);
|
||||
};
|
||||
|
||||
export const Text = createPolymorphicComponent<'div', TextProps>(_Text);
|
||||
export const Text = createPolymorphicComponent<'div', TextProps>(BaseText);
|
||||
|
||||
@@ -1,38 +1,61 @@
|
||||
import { Tooltip as MantineTooltip, TooltipProps as MantineTooltipProps } from '@mantine/core';
|
||||
import clsx from 'clsx';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
import styles from './tooltip.module.css';
|
||||
|
||||
export interface TooltipProps extends MantineTooltipProps {}
|
||||
|
||||
export const Tooltip = ({
|
||||
children,
|
||||
classNames,
|
||||
openDelay = 500,
|
||||
transitionProps = {
|
||||
duration: 250,
|
||||
transition: 'fade',
|
||||
},
|
||||
withinPortal = true,
|
||||
...props
|
||||
}: TooltipProps) => {
|
||||
return (
|
||||
<MantineTooltip
|
||||
arrowSize={10}
|
||||
classNames={{
|
||||
const DEFAULT_TRANSITION_PROPS = {
|
||||
duration: 250,
|
||||
transition: 'fade',
|
||||
} as const;
|
||||
|
||||
const TooltipComponent = memo(
|
||||
({
|
||||
children,
|
||||
classNames,
|
||||
openDelay = 500,
|
||||
transitionProps = DEFAULT_TRANSITION_PROPS,
|
||||
withinPortal = true,
|
||||
...props
|
||||
}: TooltipProps) => {
|
||||
const memoizedClassNames = useMemo(
|
||||
() => ({
|
||||
...classNames,
|
||||
tooltip: clsx(styles.tooltip, classNames?.['tooltip']),
|
||||
}}
|
||||
multiline
|
||||
openDelay={openDelay}
|
||||
transitionProps={transitionProps}
|
||||
withArrow
|
||||
withinPortal={withinPortal}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</MantineTooltip>
|
||||
);
|
||||
}),
|
||||
[classNames],
|
||||
);
|
||||
|
||||
const memoizedTransitionProps = useMemo(
|
||||
() => transitionProps ?? DEFAULT_TRANSITION_PROPS,
|
||||
[transitionProps],
|
||||
);
|
||||
|
||||
return (
|
||||
<MantineTooltip
|
||||
arrowSize={10}
|
||||
classNames={memoizedClassNames}
|
||||
multiline
|
||||
openDelay={openDelay}
|
||||
transitionProps={memoizedTransitionProps}
|
||||
withArrow
|
||||
withinPortal={withinPortal}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</MantineTooltip>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
TooltipComponent.displayName = 'Tooltip';
|
||||
|
||||
export const Tooltip = TooltipComponent as typeof TooltipComponent & {
|
||||
Group: typeof MantineTooltip.Group;
|
||||
};
|
||||
|
||||
Tooltip.Group = MantineTooltip.Group;
|
||||
|
||||
Tooltip.Group = MantineTooltip.Group;
|
||||
|
||||
Reference in New Issue
Block a user