Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(PreviewTip): add preview tip #2923

Merged
merged 68 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
1647c73
feat(PreviewTip): add preview tip
dreamwasp Aug 6, 2024
35af5f6
start on visuals
dreamwasp Aug 12, 2024
1392114
Merge branch 'main' into cass-gm-645
dreamwasp Aug 13, 2024
eb86a45
start breaking things into elements + type work
dreamwasp Aug 13, 2024
f5b6605
start working on pattern stuff
dreamwasp Aug 13, 2024
11d859d
Merge branch 'main' into cass-gm-645
dreamwasp Aug 13, 2024
c80f844
sort content props + shadow offset
dreamwasp Aug 13, 2024
aa1d538
Merge branch 'main' into cass-gm-645
dreamwasp Aug 14, 2024
9f14afa
wip
dreamwasp Aug 14, 2024
2db226a
Merge branch 'cass-gm-645' of ssh://github.com/Codecademy/gamut into …
dreamwasp Aug 14, 2024
2c61386
Merge branch 'main' into cass-gm-645
dreamwasp Aug 14, 2024
57d643a
more work on overline + avatar prop
dreamwasp Aug 14, 2024
f1cfb8f
shadow working and avatar props cleaned up
dreamwasp Aug 15, 2024
7a25246
need to adjust shadow width, but mostly good
dreamwasp Aug 15, 2024
9648591
temp width change
dreamwasp Aug 15, 2024
a8f1f09
start flexi
dreamwasp Aug 16, 2024
cabd249
start working on inline descriptions
dreamwasp Aug 16, 2024
29bb468
more storybook fixes + avatar sizing gucci :sparkles:
dreamwasp Aug 16, 2024
89228a5
Merge branch 'main' into cass-gm-645
dreamwasp Aug 20, 2024
99f64b7
fix tooltip alignment
dreamwasp Aug 20, 2024
2b0cb28
Merge branch 'cass-gm-645' of ssh://github.com/Codecademy/gamut into …
dreamwasp Aug 20, 2024
26ac884
more progress on PreviewTip, need to fix infotip floating sizing
dreamwasp Aug 20, 2024
8865e51
floating widths sorted
dreamwasp Aug 21, 2024
31febbc
spacing stuff fixed, start loading work
dreamwasp Aug 21, 2024
c955d3b
test loading prop
dreamwasp Aug 21, 2024
ee7892e
dine with loading state
dreamwasp Aug 21, 2024
d3098e7
fix this test, figure out other things tomorrow
dreamwasp Aug 21, 2024
254b5f5
Merge branch 'main' into cass-gm-645
dreamwasp Aug 22, 2024
144a815
Merge branch 'main' into cass-gm-645
dreamwasp Aug 26, 2024
62611a6
dedupe patterns
dreamwasp Aug 26, 2024
cf0969a
Merge branch 'main' into cass-gm-645
dreamwasp Aug 27, 2024
3d54f01
fix more :)
dreamwasp Aug 27, 2024
db53846
Merge branch 'cass-gm-645' of ssh://github.com/Codecademy/gamut into …
dreamwasp Aug 27, 2024
d3847e5
format fix
dreamwasp Aug 27, 2024
f8e97d3
fix circular deps
dreamwasp Aug 27, 2024
e5c25fc
shadow fixed, may need de-duping
dreamwasp Aug 28, 2024
86e380c
fix shadows
dreamwasp Aug 28, 2024
f6dd55f
add delay to inline styles
dreamwasp Aug 29, 2024
5836f43
add transition delays
dreamwasp Aug 30, 2024
0825fc7
start styling
dreamwasp Sep 3, 2024
9e0378d
real pkg
dreamwasp Sep 3, 2024
2ebc53f
real pkg
dreamwasp Sep 3, 2024
09ca971
Merge branch 'main' into cass-gm-645
dreamwasp Sep 4, 2024
d499e75
start working on better docs
dreamwasp Sep 4, 2024
5368676
Merge branch 'cass-gm-645' of ssh://github.com/Codecademy/gamut into …
dreamwasp Sep 4, 2024
2bd89b5
avatar hover styles
dreamwasp Sep 4, 2024
0bccc14
more docs + fix truncation
dreamwasp Sep 4, 2024
0821d35
floating widths sorted + responsive grid row gaps
dreamwasp Sep 5, 2024
eb6abfa
busy status for loading text
dreamwasp Sep 5, 2024
adb00a6
tests
dreamwasp Sep 9, 2024
0af64e1
more work on tests
dreamwasp Sep 10, 2024
6c4bc86
more work on tests
dreamwasp Sep 10, 2024
213a67c
format + change popover defaults back
dreamwasp Sep 10, 2024
d6ad23c
fix tests
dreamwasp Sep 11, 2024
6f5a7c5
lint + fix loading
dreamwasp Sep 11, 2024
e45d692
Merge branch 'main' into cass-gm-645
dreamwasp Sep 13, 2024
47bbb75
Merge branch 'main' into cass-gm-645
dreamwasp Sep 23, 2024
914286b
amy edit pt1
dreamwasp Sep 23, 2024
28fb8b2
fix other stuff
dreamwasp Sep 23, 2024
0685764
Merge branch 'main' into cass-gm-645
dreamwasp Sep 23, 2024
d8810dd
format stuff
dreamwasp Sep 23, 2024
af046b9
Merge branch 'cass-gm-645' of ssh://github.com/Codecademy/gamut into …
dreamwasp Sep 23, 2024
e9aa6fe
awkward overline text;
dreamwasp Sep 23, 2024
adaf964
fix exmaple
dreamwasp Sep 25, 2024
bb6348e
try on pr env
dreamwasp Sep 25, 2024
c130411
rm unused import
dreamwasp Sep 25, 2024
4e6dd73
fix aria-live region
dreamwasp Sep 26, 2024
30b741a
fix tests + spacing
dreamwasp Sep 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/gamut-styles/src/variables/timing.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
export const timingValues = {
fast: 150,
medium: 200,
base: 300,
slow: 350,
};

export const timing = {
fast: `${timingValues.fast}ms`,
medium: `${timingValues.medium}ms`,
base: `${timingValues.base}ms`,
slow: `${timingValues.slow}ms`,
};
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ exports[`Gamut Exported Keys 1`] = `
"Pagination",
"Popover",
"PopoverContainer",
"PreviewTip",
"ProgressBar",
"RadialProgress",
"Radio",
Expand Down
2 changes: 1 addition & 1 deletion packages/gamut/src/Button/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useId } from '@reach/auto-id';
import { ComponentProps, forwardRef } from 'react';

import { ButtonBaseElements } from '../ButtonBase/ButtonBase';
import { ToolTip, ToolTipProps } from '../Tip';
import { ToolTip, ToolTipProps } from '../Tip/ToolTip';
import { IconComponentType } from '../utils';
import {
createButtonComponent,
Expand Down
8 changes: 5 additions & 3 deletions packages/gamut/src/Button/__tests__/IconButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ describe('IconButton', () => {
it('renders a tip with repetition removed', async () => {
const { view } = renderView({});

view.getByRole('button', { name: label });
const button = view.getByRole('button', { name: label });

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: We need to update the rest of the testing suite to use the correct types (which are reliant on upgrading Node)
expect(button).toHaveAccessibleDescription(tipText);
expect(view.getByRole('tooltip', { hidden: true })).toHaveTextContent(
tipText
);
Expand Down Expand Up @@ -81,7 +84,6 @@ describe('IconButton', () => {
expect(view.queryByText('tooltip')).toBeNull();

userEvent.hover(cta);

view.getByText(tip);
await view.findByText(tip);
});
});
2 changes: 1 addition & 1 deletion packages/gamut/src/Form/elements/FormGroupLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { HTMLAttributes } from 'react';
import * as React from 'react';

import { FlexBox } from '../..';
import { InfoTip, InfoTipProps } from '../../Tip';
import { InfoTip, InfoTipProps } from '../../Tip/InfoTip';
import { Text } from '../../Typography/Text';
import { formBaseStyles, formFieldTextDisabledStyles } from '../styles';
import { BaseInputProps } from '../types';
Expand Down
2 changes: 1 addition & 1 deletion packages/gamut/src/Form/inputs/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { forwardRef, InputHTMLAttributes, ReactNode } from 'react';
import * as React from 'react';

import { FlexBox } from '../../Box';
import { InfoTip, InfoTipProps } from '../../Tip';
import { InfoTip, InfoTipProps } from '../../Tip/InfoTip';
import {
conditionalRadioInputStyles,
conditionalRadioLabelStyles,
Expand Down
2 changes: 1 addition & 1 deletion packages/gamut/src/GridForm/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { BoxProps } from '../Box';
import { TextAreaProps } from '../Form';
import { CheckboxPaddingProps } from '../Form/types';
import { ColumnProps } from '../Layout';
import { InfoTipProps } from '../Tip';
import { InfoTipProps } from '../Tip/InfoTip';
import { Text, TextProps } from '../Typography/Text';

export interface BaseFormInputProps {
Expand Down
10 changes: 1 addition & 9 deletions packages/gamut/src/Popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,7 @@ export const Popover: React.FC<PopoverProps> = ({
alignment={alignment}
outline={outline ? 'outline' : 'boxShadow'}
variant={variant}
widthRestricted={
variant === 'secondary'
? alignment === 'centered'
? 'centered'
: 'aligned'
: widthRestricted
? 'popover'
: 'default'
}
widthRestricted={widthRestricted}
>
{beak && (
<Beak
Expand Down
26 changes: 10 additions & 16 deletions packages/gamut/src/Popover/elements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@ import * as React from 'react';
import { WithChildrenProp } from '..';
import { BodyPortal } from '../BodyPortal';
import { Box } from '../Box';
import {
popoverToolTipBodyAlignments,
toolTipWidthRestrictions,
} from '../Tip/shared/styles';
import { popoverToolTipBodyAlignments } from '../Tip/shared/styles';
import {
beakSize,
beakVariants,
outlineVariants,
patternContainerBaseStyles,
patternVariantStyles,
popoverStates,
raisedDivVariants,
transformValues,
widthStates,
} from './styles';
import { PopoverProps } from './types';

Expand All @@ -27,18 +26,17 @@ export type PopoverVariants = StyleProps<typeof raisedDivVariants> & {
};

export const RaisedDiv = styled.div<
StyleProps<typeof raisedDivVariants> &
StyleProps<typeof outlineVariants> &
StyleProps<typeof raisedDivVariants> &
StyleProps<typeof popoverToolTipBodyAlignments> &
StyleProps<typeof toolTipWidthRestrictions> &
StyleProps<typeof outlineVariants>
StyleProps<typeof widthStates>
>(
popoverToolTipBodyAlignments,
toolTipWidthRestrictions,
outlineVariants,
raisedDivVariants
popoverToolTipBodyAlignments,
raisedDivVariants,
widthStates
);

// TO-DO -- prob should use variance compose, only needs left
export const Beak = styled(Box)<
StyleProps<typeof popoverStates> &
StyleProps<typeof outlineVariants> &
Expand All @@ -49,12 +47,8 @@ export const Beak = styled(Box)<
export const PatternContainer = styled.div(
variant({
base: {
width: '100%',
height: '100%',
borderRadius: 'sm',
overflow: 'hidden',
bg: 'background',
position: 'absolute',
...patternContainerBaseStyles,
},
variants: patternVariantStyles,
})
Expand Down
15 changes: 15 additions & 0 deletions packages/gamut/src/Popover/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ export const outlineVariants = variant({
},
});

export const widthStates = states({
widthRestricted: {
minWidth: '4rem',
maxWidth: '16rem',
},
});

const beakVariantsArray = [
'below-left',
'below-right',
Expand Down Expand Up @@ -88,6 +95,14 @@ export const beakSize = variant({
},
});

export const patternContainerBaseStyles = {
bg: 'transparent',
borderRadius: 'sm',
overflow: 'hidden',
position: 'absolute',
width: '100%',
} as const;

const patternVariantArray = [
'above-left',
'above-right',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const DeprecatedInlineToolTip: React.FC<DeprecatedToolTipPlacementCompone
as="div"
id={id}
role="tooltip"
isToolTip
>
<TipBody
alignment={alignment.includes('center') ? 'centered' : 'aligned'}
Expand Down
156 changes: 156 additions & 0 deletions packages/gamut/src/Tip/PreviewTip/elements.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { CheckerDense } from '@codecademy/gamut-patterns';
import { css, variant } from '@codecademy/gamut-styles';
import styled from '@emotion/styled';
import { useMemo } from 'react';

import { Anchor } from '../../Anchor';
import { Box, FlexBox, GridBox } from '../../Box';
import { ButtonSelectors } from '../../ButtonBase/ButtonBase';
import { Shimmer } from '../../Loading/Shimmer';
import { patternContainerBaseStyles } from '../../Popover/styles';
import { Text } from '../../Typography';
import { PreviewTipContent, TipPlacementComponentProps } from '../shared/types';
import {
avatarColumnTemplate,
avatarGridTemplate,
defaultGridTemplate,
getShadowAlignment,
} from './styles';

export const PreviewTipAnchor = styled(Anchor)(
variant({
defaultVariant: 'anchor',
prop: 'tipType',
variants: {
anchor: {
textDecorationStyle: 'dotted',
[ButtonSelectors.HOVER]: {
textDecoration: 'underline',
textDecorationStyle: 'solid',
},
},
avatar: {
borderRadius: 'sm',
[ButtonSelectors.HOVER]: {
bg: 'background-hover',
},
},
},
})
);

const PreviewTipBodyShimmer = ({
avatar,
truncateLines = 4,
}: Pick<PreviewTipContent, 'avatar' | 'truncateLines'>) => {
const lineHeight = 24;
const height = avatar ? lineHeight : (truncateLines as number) * lineHeight;
const width = avatar ? '5.5rem' : '100%';
return (
<>
<Shimmer height={lineHeight} width="4.5rem" />
<Shimmer height={height} width={width} />
</>
);
};

type PreviewTipContentsProps = Pick<TipPlacementComponentProps, 'info'> &
PreviewTipContent;

export const PreviewTipContents: React.FC<PreviewTipContentsProps> = ({
avatar,
loading,
info,
overline,
truncateLines = 4,
username,
}) => {
const gridTemplateAreas = useMemo(() => {
if (!avatar) return defaultGridTemplate;

let avatarGridTemplateString = '';

[info, overline, username].forEach((el) => {
if (el)
avatarGridTemplateString = avatarGridTemplateString.concat(
`\n`,
avatarGridTemplate
);
});

return avatarGridTemplateString;
}, [avatar, info, overline, username]);

const contents = useMemo(() => {
return loading ? (
<PreviewTipBodyShimmer avatar={avatar} truncateLines={truncateLines} />
) : (
<>
{overline && (
<Text textColor="text-secondary" fontFamily="accent" fontSize={14}>
{overline}
</Text>
)}
{username && (
<Text fontWeight="bold" fontSize={16}>
{username}
</Text>
)}
<Text
as="p"
fontSize={16}
truncate="ellipsis"
truncateLines={truncateLines ?? 4}
>
{info}
</Text>
</>
);
}, [loading, avatar, info, overline, truncateLines, username]);

return (
<GridBox
gridTemplateAreas={gridTemplateAreas}
gridTemplateColumns={avatar ? avatarColumnTemplate : '1fr'}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the 1fr here be using defaultGridTemplate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call, thank you!

rowGap={4}
>
{avatar && (
<FlexBox center aria-hidden gridArea="avatar" pr={12}>
<Box height={40} width={40}>
{avatar}
</Box>
</FlexBox>
)}
{contents}
</GridBox>
);
};

type PreviewTipShadowProps = Pick<
TipPlacementComponentProps,
'alignment' | 'zIndex'
>;

export const PreviewTipPattern = styled(Box)(
css({
height: 'calc(100% - 12px)',
...patternContainerBaseStyles,
})
);

export const PreviewTipShadow: React.FC<PreviewTipShadowProps> = ({
alignment,
zIndex,
}) => {
const shadowAlignment = getShadowAlignment(alignment);

return (
<PreviewTipPattern
aria-hidden
zIndex={zIndex ? zIndex - 2 : -1}
{...shadowAlignment}
>
<CheckerDense />
</PreviewTipPattern>
);
};
Loading
Loading