Skip to content

Commit

Permalink
feat(mantine,website): create the EllipsisText component (#3933)
Browse files Browse the repository at this point in the history
* feat(mantine,website): create the EllipsisText component

* refactor(mantine): group EllipsisText tooltipProps
  • Loading branch information
gdostie authored Oct 23, 2024
1 parent 908abf6 commit 6f52299
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/components-props-analyzer/src/ComponentsList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ const components: Component[] = [
name: 'Alert',
packageName: '@coveord/plasma-mantine',
},
{
name: 'EllipsisText',
packageName: '@coveord/plasma-mantine',
propsType: 'EllipsisTextProps',
},
];

export default components;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.root {
white-space: nowrap;
}

.text {
flex-basis: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
79 changes: 79 additions & 0 deletions packages/mantine/src/components/ellipsis-text/EllipsisText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
Box,
type BoxProps,
type Factory,
polymorphicFactory,
type StylesApiProps,
Text,
type TextProps,
Tooltip,
type TooltipProps,
useProps,
useStyles,
} from '@mantine/core';
import {ReactNode, useRef, useState} from 'react';
import classes from './EllipsisText.module.css';

export type EllipsisTextStylesNames = 'root' | 'tooltip' | 'text';

export interface EllipsisTextProps
extends BoxProps,
Pick<TextProps, 'variant'>,
Omit<StylesApiProps<EllipsisTextFactory>, 'variant'> {
children: ReactNode;
tooltipProps: Omit<TooltipProps, 'label' | 'opened'>;
}

type EllipsisTextFactory = Factory<{
props: EllipsisTextProps;
defaultRef: HTMLDivElement;
defaultComponent: 'div';
stylesNames: EllipsisTextStylesNames;
}>;

const defaultProps: Partial<EllipsisTextProps> = {};

export const EllipsisText = polymorphicFactory<EllipsisTextFactory>((props, ref) => {
const {className, children, style, classNames, styles, unstyled, variant, tooltipProps, ...others} = useProps(
'EllipsisText',
defaultProps,
props,
);
const getStyles = useStyles<EllipsisTextFactory>({
name: 'EllipsisText',
classes,
props,
className,
style,
classNames,
styles,
unstyled,
});

const [showTooltip, setShowTooltip] = useState(false);
const textRef = useRef<HTMLDivElement>();

return (
<Box
ref={ref}
onMouseEnter={() => {
if (textRef.current && isOverflowing(textRef.current)) {
setShowTooltip(true);
}
}}
onMouseLeave={() => setShowTooltip(false)}
display="flex"
w="100%"
{...getStyles('root')}
{...others}
>
<Tooltip label={children} opened={showTooltip} {...tooltipProps} {...getStyles('tooltip')}>
<Text variant={variant} ref={textRef} {...getStyles('text')}>
{children}
</Text>
</Tooltip>
</Box>
);
});

const isOverflowing = (h: HTMLDivElement) => h.scrollWidth > h.clientWidth;
1 change: 1 addition & 0 deletions packages/mantine/src/components/ellipsis-text/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './EllipsisText';
1 change: 1 addition & 0 deletions packages/mantine/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './code-editor';
export * from './collection';
export * from './copyToClipboard';
export * from './date-range-picker';
export * from './ellipsis-text';
export * from './header';
export * from './inline-confirm';
export * from './menu';
Expand Down
3 changes: 3 additions & 0 deletions packages/mantine/src/styles/Tooltip.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.tooltip {
word-break: break-word;
}
2 changes: 2 additions & 0 deletions packages/mantine/src/theme/Theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import SkeletonClasses from '../styles/Skeleton.module.css';
import StepperClasses from '../styles/Stepper.module.css';
import TabsClasses from '../styles/Tabs.module.css';
import TextClasses from '../styles/Text.module.css';
import TooltipClasses from '../styles/Tooltip.module.css';
import {NotificationVars} from '../vars/Notification.vars';
import {TextVars} from '../vars/Text.vars';
import {PlasmaColors} from './PlasmaColors';
Expand Down Expand Up @@ -371,6 +372,7 @@ export const plasmaTheme: MantineThemeOverride = createTheme({
withArrow: true,
zIndex: 10000,
},
classNames: TooltipClasses,
}),
},
});
1 change: 1 addition & 0 deletions packages/website/src/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const Navigation = () => (
</NavLink>
<NavLink label="Layout" leftSection={<RichUiSize16Px height={16} />} defaultOpened>
<InternalNavLink to="/layout/BrowserPreview" label="Browser Preview" />
<InternalNavLink to="/layout/EllipsisText" label="Ellipsis text" />
<InternalNavLink to="/layout/Header" label="Header" />
<InternalNavLink to="/layout/Modal" label="Modal" />
<InternalNavLink to="/layout/Prompt" label="Prompt" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {EllipsisText} from '@coveord/plasma-mantine';

const Demo = () => (
<>
<EllipsisText maw={250}>
This is a very long text that is truncated with an ellipsis. The rest is shown on hover.
</EllipsisText>
<EllipsisText maw={250}>This short text is not truncated.</EllipsisText>
</>
);
export default Demo;
18 changes: 18 additions & 0 deletions packages/website/src/pages/layout/EllipsisText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {EllipsisTextMetadata} from '@coveord/plasma-components-props-analyzer';
import EllipsisTextDemo from '@examples/layout/EllipsisText/EllipsisText.demo?demo';

import {PageLayout} from '../../building-blocs/PageLayout';

const Page = () => (
<PageLayout
section="Layout"
title="EllipsisText"
sourcePath="/packages/mantine/src/components/ellipsis-text/EllipsisText.tsx"
description="Allows to display text that will automatically truncate and shows a tooltip on hover if it overflows the max width."
id="EllipsisText"
propsMetadata={EllipsisTextMetadata}
demo={<EllipsisTextDemo />}
/>
);

export default Page;

0 comments on commit 6f52299

Please sign in to comment.