Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Lukebailey/infra 387 explore and create a micro interaction #54

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
17cffa8
feat: add react-aria and react-stately
lukerohanbailey Jan 5, 2022
23e5e0d
feat: add simple react-aria checkbox
lukerohanbailey Jan 5, 2022
e254aa5
feat: add simple checkbox story
lukerohanbailey Jan 5, 2022
1ce89d5
feat: add disabled and enabled checkbox styles
lukerohanbailey Jan 5, 2022
5c819c1
feat: add state styling to checkbox
lukerohanbailey Jan 5, 2022
d86c95d
style: update All Checkbox component name to Checkbox States
lukerohanbailey Jan 5, 2022
59efa9f
fix: update autoFocus attribute element to match the order on figma
lukerohanbailey Jan 5, 2022
c66b5cd
chore: move stitches to devdependencies
lukerohanbailey Jan 6, 2022
ca95774
fix: add react-aria and react-stately to build-cjs
lukerohanbailey Jan 6, 2022
0a41a35
feat: add aria-label to checkbox
lukerohanbailey Jan 6, 2022
93013ed
chore: add onChange handler to checkbox
lukerohanbailey Jan 6, 2022
177e1c9
build: add gsap to project
lukerohanbailey Jan 7, 2022
4f84d58
feat: add basic gsap setup and microinteraction to checkbox
lukerohanbailey Jan 7, 2022
3c53864
build: add .vscode to .gitignore
lukerohanbailey Jan 7, 2022
dac2cfd
fix: remove GSAPTimeline type import
lukerohanbailey Jan 7, 2022
969c328
feat: add animatiable check icon
lukerohanbailey Jan 9, 2022
ab4d3dc
feat: animate checkbox check icon based on isSelected state
lukerohanbailey Jan 9, 2022
7bf7cdd
feat: improve checkbox animation timings
lukerohanbailey Jan 10, 2022
fc43aa6
Merge branch 'lukebailey/infra-387-explore-and-create-a-micro-interac…
lukerohanbailey Jan 11, 2022
9d2b028
fix: destructure checkbox types from ComponentPropsWithRef, CheckboxP…
lukerohanbailey Jan 11, 2022
6786ee4
fix: invalid styling
lukerohanbailey Jan 11, 2022
661b8d3
Merge branch 'lukebailey/infra-386-create-a-a11y-checkbox' into lukeb…
lukerohanbailey Jan 11, 2022
aa97e6c
fix: aria-label console warnings
lukerohanbailey Jan 11, 2022
8b505fa
feat: update checkbox animation timings
lukerohanbailey Jan 11, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ junit.xml
.idea

# logs
*.log
*.log
.vscode/
9 changes: 8 additions & 1 deletion bin/build-cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ const sharedConfig = {
platform: 'node',
sourcemap: true,
bundle: true,
external: ['react', 'react-dom', '@stitches/react'],
external: [
'react',
'react-dom',
'@stitches/react',
'react-aria',
'react-stately',
'gsap',
],
target: ['node12'],
inject: ['./bin/util/react-shim.js'],
};
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@commitlint/cli": "^14.1.0",
"@commitlint/config-conventional": "^14.1.0",
"@skypack/package-check": "^0.2.2",
"@stitches/react": "^1.2.5",
"@storybook/addon-actions": "^6.3.12",
"@storybook/addon-essentials": "^6.3.12",
"@storybook/addon-links": "^6.3.12",
Expand Down Expand Up @@ -85,6 +86,8 @@
"react": "^16.14.0 || ^17.0.0"
},
"dependencies": {
"@stitches/react": "^1.2.5"
"gsap": "^3.9.1",
"react-aria": "^3.12.0",
"react-stately": "^3.11.0"
}
}
30 changes: 30 additions & 0 deletions src/animationIcons/CheckIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { SVGProps } from 'react';
import { styled } from '../../stitches.config';

const Path = styled('path', {
'input:checked ~ div &': {
transition: 'stroke-dashoffset 1s cubic-bezier(0.16, 1, 0.3, 1)',
},
transition: 'stroke-dashoffset 0.2s cubic-bezier(0.11, 0, 0.5, 0)',
});

export const CheckIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
fill="none"
focusable="false"
height="1em"
role="img"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<Path
d="M0.709339 7.44716L5.70834 12.4462L15.3004 2.8541"
stroke="currentColor"
strokeDasharray="21 21"
strokeMiterlimit="10"
strokeWidth="2"
/>
</svg>
);
123 changes: 123 additions & 0 deletions src/components/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import type { CheckboxProps, ToggleProps } from '@react-types/checkbox';
import { gsap } from 'gsap';
import type { ChangeEvent, ComponentPropsWithRef } from 'react';
import { useEffect, useRef } from 'react';
import { useCheckbox } from 'react-aria';
import { useToggleState } from 'react-stately';
import { styled } from '../../stitches.config';
import { CheckIcon } from '../animationIcons/CheckIcon';

const Label = styled('label', {
'& input:checked:disabled + div': {
color: '$gray50',
},
display: 'block',
position: 'relative',
});

const Input = styled('input', {
'&:checked': {
backgroundColor: '$brandYellow',
borderColor: '$brandYellow',
},
'&:checked&:disabled': {
backgroundColor: '$yellow20',
borderColor: '$yellow20',
},
'&:disabled': {
borderColor: '$gray30',
},
'&:focus': {
outline: '2px solid $brandYellow',
outlineOffset: '2px',
},
'&:indeterminate': {
borderColor: '$brandYellow',
position: 'relative',
},
'&:indeterminate:after': {
backgroundColor: '$brandYellow',
content: '""',
height: '12px',
left: '50%',
position: 'absolute',
top: '50%',
transform: 'translate(-50%, -50%)',
width: '12px',
},
'&:invalid': {
borderColor: '$uiErrorRegular',
},
appearance: 'none',
backgroundColor: '$brandWhite',
borderColor: '$gray50',
borderRadius: '$4',
borderStyle: '$solid',
borderWidth: '$thin',
height: '24px',
margin: '0',
position: 'relative',
width: '24px',
});

const IconContainer = styled('div', {
left: '50%',
position: 'absolute',
top: '50%',
transform: 'translate(-50%, -50%)',
});

type CustomCheckboxProps = {
text?: string;
};

export const Checkbox = ({
validationState,
text,
defaultSelected,
isIndeterminate,
...restProps
}: CheckboxProps &
ComponentPropsWithRef<'input'> &
CustomCheckboxProps &
ToggleProps) => {
const ref = useRef<HTMLInputElement>(null);
const state = useToggleState({ defaultSelected, validationState });
const { inputProps } = useCheckbox(
{ isIndeterminate, ...restProps },
state,
ref
);
const checkedTl = useRef<GSAPTimeline>(gsap.timeline({ paused: true }));

useEffect(() => {
checkedTl.current
.to(ref.current, {
duration: 0.1,
ease: 'quad.easeIn',
scale: 0.9,
})
.to(ref.current, {
duration: 0.1,
ease: 'quad.easeOut',
scale: 1,
});
}, []);

const onChange = (event: ChangeEvent<HTMLInputElement>) => {
const checked = event.target.checked;
state.setSelected(checked);

checkedTl.current.play(0);
};

return (
<Label>
<Input {...inputProps} {...restProps} onChange={onChange} ref={ref} />
<IconContainer>
<CheckIcon strokeDashoffset={state.isSelected ? '' : '21'} />
</IconContainer>
{text}
</Label>
);
};
34 changes: 34 additions & 0 deletions src/components/stories/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { styled } from '../../../stitches.config';
import { Checkbox } from '../Checkbox';

const Wrapper = styled('div', {
display: 'flex',
flexFlow: 'row wrap',
gap: '$16',
width: '100%',
});

export const CheckboxStates = () => (
<Wrapper>
<Checkbox aria-label="Example checkbox: disabled" disabled />
<Checkbox aria-label="Example checkbox: unchecked" />
<Checkbox aria-label="Example checkbox: checked" defaultSelected />
<Checkbox
aria-label="Example checkbox: focused"
autoFocus
defaultSelected
/>
<Checkbox
aria-label="Example checkbox: unchecked"
defaultSelected
disabled
/>
<Checkbox aria-label="test" isIndeterminate />
<Checkbox aria-label="test" required validationState="invalid" />
</Wrapper>
);

export default {
component: CheckboxStates,
title: 'Checkbox',
};
9 changes: 9 additions & 0 deletions stitches.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,16 @@ export const {
} = createStitches({
media: {},
theme: {
borderStyles: {
solid: 'solid',
},
borderWidths: {
thin: '2px',
},
colors: colorPrimitives,
radii: {
4: '4px',
},
space: {
4: '4px',
8: '8px',
Expand Down