-
Notifications
You must be signed in to change notification settings - Fork 30
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(Disclosure): creating an Disclosure component #2859
Merged
Merged
Changes from 49 commits
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
4eac500
mini progress
LinKCoding e19534a
got something working
LinKCoding b2b6882
added spacing
LinKCoding 6021804
text aligns to left now
LinKCoding 718ee70
adding styledanchor
LinKCoding 4652803
styling in a decent place
LinKCoding d64b589
styling ok
LinKCoding b8d3140
ran prettier
LinKCoding be8cc2d
Merge branch 'main' into kl-gm-562
LinKCoding 93df6e5
starting on testing
LinKCoding abfc202
forgot to save file
LinKCoding 74a5e3d
refactored into smaller components
LinKCoding 9151c3a
some progress
LinKCoding 8b7a585
Merge branch 'main' into kl-gm-562
LinKCoding a943147
made some stuff optional
LinKCoding b5b16cb
added optionals and first working test
LinKCoding 6d90f39
changed name to disclosure
LinKCoding 647e686
started on more tests
LinKCoding 0b175f0
tests and story and animation
LinKCoding 649dfa6
unsaved change
LinKCoding e9052e4
changed button to use a switch/case
LinKCoding a80b45b
Merge branch 'main' into kl-gm-562
LinKCoding 0a4aafa
updated button logic
LinKCoding d28ff7c
commented out buttonProps
LinKCoding 1dd7a82
updated heading and icon sizing
LinKCoding be03bf3
prettified
LinKCoding d24f356
editted button padding and icon size
LinKCoding e8a6387
fixed snapshot
LinKCoding 846ad9d
updated story
LinKCoding 645d290
Merge branch 'main' into kl-gm-562
LinKCoding 1876467
prettified
LinKCoding 248c1bb
edited story
LinKCoding 083b580
addressed most of Cass's feedback
LinKCoding 1de1764
prettified
LinKCoding c40448c
addressed Stacey's figma feedback
LinKCoding d200774
fixed some lingering issues
LinKCoding 61198e2
changed onClick prop
LinKCoding 5157b09
made additional variants to provide optional styling
LinKCoding 2884d47
updated variant names and stories
LinKCoding 17813df
prettified
LinKCoding 9b70efe
fixed up example
LinKCoding 9ceeb2b
Merge branch 'main' into kl-gm-562
LinKCoding ebeee3e
fixed stories
LinKCoding 80b86a9
fixed up stories and variants
LinKCoding 2868910
prettified
LinKCoding e78df21
fixed state issue
LinKCoding 5cd8b09
fixed some types stuff
LinKCoding 015241f
Merge branch 'main' into kl-gm-562
LinKCoding c5b1d11
converted props to types
LinKCoding effa49b
fixed expanding/contracting issue
LinKCoding aac71c4
updated snapshot
LinKCoding 874c39a
fixed transition speed
LinKCoding dd7b717
Merge branch 'main' into kl-gm-562
LinKCoding c7b6110
Merge branch 'main' into kl-gm-562
LinKCoding File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { motion } from 'framer-motion'; | ||
|
||
import { WithChildrenProp } from '../utils'; | ||
|
||
export const ExpandInCollapseOut: React.FC<WithChildrenProp> = ({ | ||
children, | ||
}) => { | ||
return ( | ||
<motion.div | ||
initial="collapsed" | ||
exit="collapsed" | ||
animate="expanded" | ||
style={{ overflow: 'hidden' }} | ||
variants={{ | ||
expanded: { height: 'auto' }, | ||
collapsed: { height: 0 }, | ||
}} | ||
transition={{ duration: 0.2, ease: 'easeInOut' }} | ||
> | ||
{children} | ||
</motion.div> | ||
); | ||
}; | ||
LinKCoding marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import * as React from 'react'; | ||
|
||
import { Text } from '../../Typography'; | ||
import { DisclosureBodyWrapper } from '../elements'; | ||
import { getSpacing, renderButton } from '../helpers'; | ||
import { DisclosureBodyProps } from '../types'; | ||
|
||
export const DisclosureBody: React.FC<DisclosureBodyProps> = ({ | ||
body, | ||
buttonType = 'TextButton', | ||
buttonPlacement = 'right', | ||
ctaCallback, | ||
ctaText, | ||
hasPanelBg = false, | ||
href, | ||
spacing = 'normal', | ||
}) => { | ||
const buttonRequirements = ctaText && ctaCallback; | ||
|
||
const getLineHeight = spacing === 'compact' ? 'title' : 'base'; | ||
const { verticalSpacing, horizontalSpacing } = getSpacing(spacing); | ||
return ( | ||
<DisclosureBodyWrapper | ||
column | ||
hasPanelBg={hasPanelBg} | ||
mb={verticalSpacing} | ||
mt={4} | ||
mx={horizontalSpacing} | ||
> | ||
<Text width="100%" lineHeight={getLineHeight}> | ||
{body} | ||
</Text> | ||
{buttonRequirements && | ||
renderButton({ | ||
buttonPlacement, | ||
buttonType, | ||
ctaCallback, | ||
ctaText, | ||
href, | ||
})} | ||
</DisclosureBodyWrapper> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import { | ||
ArrowChevronDownIcon, | ||
MiniChevronDownIcon, | ||
} from '@codecademy/gamut-icons'; | ||
import * as React from 'react'; | ||
|
||
import { Rotation, Text } from '../..'; | ||
import { Box, FlexBox } from '../../Box'; | ||
import { DisclosureButtonWrapper } from '../elements'; | ||
import { getRotationSize, getSpacing, getTitleSize } from '../helpers'; | ||
import { DisclosureButtonProps } from '../types'; | ||
|
||
export const DisclosureButton: React.FC<DisclosureButtonProps> = ({ | ||
disabled = false, | ||
heading, | ||
headingLevel = 'h3', | ||
isExpanded, | ||
overline, | ||
setIsExpanded, | ||
spacing = 'normal', | ||
subheading, | ||
}) => { | ||
const handleClick = () => { | ||
if (setIsExpanded) { | ||
setIsExpanded((prev: boolean) => !prev); | ||
} | ||
}; | ||
|
||
const titleSize = getTitleSize(spacing); | ||
const subheadingSize = spacing === 'normal' ? 'p-base' : 'p-small'; | ||
const rotationSize = getRotationSize(spacing); | ||
const { verticalSpacing, horizontalSpacing } = getSpacing(spacing); | ||
|
||
return ( | ||
<FlexBox> | ||
<DisclosureButtonWrapper | ||
aria-label={isExpanded ? 'Collapse Content' : 'Expand Content'} | ||
aria-expanded={isExpanded} | ||
onClick={handleClick} | ||
width="100%" | ||
variant="interface" | ||
py={verticalSpacing} | ||
px={horizontalSpacing} | ||
disabled={disabled} | ||
height="100%" | ||
> | ||
{overline && ( | ||
<Text | ||
textAlign="start" | ||
width="100%" | ||
color="text-secondary" | ||
fontFamily="accent" | ||
variant="p-small" | ||
> | ||
{overline} | ||
</Text> | ||
)} | ||
<FlexBox | ||
flexDirection="row" | ||
justifyContent="space-between" | ||
columnGap={40} | ||
alignItems="center" | ||
> | ||
<Text | ||
textAlign="start" | ||
as={headingLevel} | ||
width="100%" | ||
p={0} | ||
variant={titleSize} | ||
fontWeight="title" | ||
> | ||
{heading} | ||
</Text> | ||
|
||
<Box p={8}> | ||
<Rotation | ||
rotated={isExpanded} | ||
height={rotationSize} | ||
width={rotationSize} | ||
> | ||
{spacing === 'normal' ? ( | ||
<ArrowChevronDownIcon aria-hidden size={rotationSize} /> | ||
) : ( | ||
<MiniChevronDownIcon aria-hidden size={rotationSize} /> | ||
)} | ||
</Rotation> | ||
</Box> | ||
</FlexBox> | ||
{subheading && ( | ||
<Text textAlign="start" width="100%" variant={subheadingSize}> | ||
{subheading} | ||
</Text> | ||
)} | ||
</DisclosureButtonWrapper> | ||
</FlexBox> | ||
); | ||
}; |
57 changes: 57 additions & 0 deletions
57
packages/gamut/src/Disclosure/__tests__/Disclosure.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { setupRtl } from '@codecademy/gamut-tests'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
import { Disclosure } from '..'; | ||
|
||
const ctaCallback = jest.fn(); | ||
|
||
const defaultProps = { | ||
header: 'hi there!', | ||
body: <div>This should render when expanded </div>, | ||
withBackground: false, | ||
}; | ||
|
||
const renderView = setupRtl(Disclosure, defaultProps); | ||
|
||
describe('Disclosure', () => { | ||
it('renders the DisclosureBody when DisclosureButton is clicked', () => { | ||
const { view } = renderView({ | ||
initiallyExpanded: false, | ||
}); | ||
|
||
const DisclosureButton = view.getByRole('button'); | ||
let DisclosureBodyText = view.queryByText( | ||
'This should render when expanded' | ||
); | ||
expect(DisclosureBodyText).toBeNull(); | ||
expect(DisclosureButton.getAttribute('aria-expanded')).toBe('false'); | ||
|
||
userEvent.click(DisclosureButton); | ||
|
||
DisclosureBodyText = view.getByText('This should render when expanded'); | ||
expect(DisclosureButton.getAttribute('aria-expanded')).toBe('true'); | ||
}); | ||
|
||
it('renders the body when `initiallyExpanded` is set to true', () => { | ||
const { view } = renderView({ | ||
initiallyExpanded: true, | ||
}); | ||
|
||
const DisclosureButton = view.getByRole('button'); | ||
view.getByText('This should render when expanded'); | ||
|
||
expect(DisclosureButton.getAttribute('aria-expanded')).toBe('true'); | ||
}); | ||
|
||
it("renders the DisclosureBody's button when supplied a `cta` and `ctaCallback` argument", () => { | ||
const { view } = renderView({ | ||
initiallyExpanded: true, | ||
ctaText: 'click here', | ||
ctaCallback, | ||
}); | ||
|
||
const CTAButton = view.getByText('click here'); | ||
userEvent.click(CTAButton); | ||
expect(ctaCallback).toBeCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { states, variant } from '@codecademy/gamut-styles'; | ||
import { StyleProps } from '@codecademy/variance'; | ||
import styled from '@emotion/styled'; | ||
|
||
import { Anchor } from '../Anchor'; | ||
import { FlexBox } from '../Box'; | ||
import { FillButton, StrokeButton, TextButton } from '../Button'; | ||
|
||
const disclosureWrapperVariants = variant({ | ||
defaultVariant: 'default', | ||
base: { | ||
width: '100%', | ||
maxHeight: 'fit-content', | ||
}, | ||
variants: { | ||
default: { | ||
bg: 'background', | ||
}, | ||
subtle: { | ||
bg: 'background-selected', | ||
}, | ||
transparent: { | ||
bg: 'background-current', | ||
}, | ||
}, | ||
}); | ||
|
||
const disclosureWrapperStates = states({ | ||
hasBorder: { | ||
border: 1, | ||
}, | ||
}); | ||
|
||
type DisclosureWrapperStateProps = StyleProps<typeof disclosureWrapperStates>; | ||
type DisclosureWrapperVariantProps = StyleProps< | ||
typeof disclosureWrapperVariants | ||
>; | ||
export type DisclosureWrapperStyles = DisclosureWrapperStateProps & | ||
DisclosureWrapperVariantProps; | ||
|
||
export const DisclosureWrapper = styled(FlexBox)<DisclosureWrapperStyles>( | ||
disclosureWrapperStates, | ||
disclosureWrapperVariants | ||
); | ||
|
||
export const DisclosureButtonWrapper = styled(Anchor)( | ||
variant({ | ||
prop: 'isWrapper', | ||
defaultVariant: 'default', | ||
variants: { | ||
default: { | ||
bg: 'inherit', | ||
'&:hover': { | ||
color: 'text', | ||
bg: 'background-hover', | ||
}, | ||
'&:focus': { | ||
color: 'text', | ||
bg: 'background-selected', | ||
}, | ||
'&:disabled': { | ||
color: 'text-disabled', | ||
bg: 'background-disabled', | ||
}, | ||
}, | ||
}, | ||
}) | ||
); | ||
|
||
const sharedVariants = { | ||
left: { | ||
alignSelf: 'flex-start', | ||
justifyContent: 'left', | ||
}, | ||
right: { | ||
alignSelf: 'flex-end', | ||
justifyContent: 'right', | ||
}, | ||
}; | ||
|
||
export const StyledTextButton = styled(TextButton)( | ||
variant({ | ||
prop: 'placement', | ||
variants: sharedVariants, | ||
}) | ||
); | ||
|
||
export const StyledStrokeButton = styled(StrokeButton)( | ||
variant({ | ||
prop: 'placement', | ||
variants: sharedVariants, | ||
}) | ||
); | ||
|
||
export const StyledFillButton = styled(FillButton)( | ||
variant({ | ||
prop: 'placement', | ||
variants: sharedVariants, | ||
}) | ||
); | ||
|
||
export type DisclosureBodyWrapperStyles = StyleProps< | ||
typeof disclosureBodyWrapperStates | ||
>; | ||
|
||
const disclosureBodyWrapperStates = states({ | ||
hasPanelBg: { | ||
bg: 'background-selected', | ||
p: 8, | ||
}, | ||
}); | ||
|
||
export const DisclosureBodyWrapper = styled( | ||
FlexBox | ||
)<DisclosureBodyWrapperStyles>(disclosureBodyWrapperStates); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love this!!! starting to think we need more gamut documentation on our animations (not in this PR but maybe another ticket for the backlog ✨ )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, you're right -- I'll cut a ticket!