Skip to content

Commit

Permalink
[Checkbox] Component and Hook
Browse files Browse the repository at this point in the history
  • Loading branch information
atomiks committed Mar 7, 2024
1 parent 608fdbb commit 54d6b03
Show file tree
Hide file tree
Showing 26 changed files with 1,872 additions and 4 deletions.
102 changes: 102 additions & 0 deletions docs/data/base/components/checkbox/UnstyledCheckboxIndeterminate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import * as React from 'react';
import { styled } from '@mui/system';
import { Checkbox as BaseCheckbox } from '@mui/base/Checkbox';
import HorizontalRule from '@mui/icons-material/HorizontalRule';

export default function UnstyledCheckboxIndeterminate() {
return (
<div style={{ display: 'flex', gap: 15 }}>
<Checkbox aria-label="Indeterminate checkbox" indeterminate>
<Indicator>
<HorizontalRuleIcon />
</Indicator>
</Checkbox>
<Checkbox aria-label="Indeterminate disabled checkbox" indeterminate disabled>
<Indicator>
<HorizontalRuleIcon />
</Indicator>
</Checkbox>
</div>
);
}

const blue = {
50: '#e3f2fd',
100: '#bbdefb',
200: '#90caf9',
300: '#64b5f6',
400: '#42a5f5',
500: '#2196f3',
600: '#1e88e5',
700: '#1976d2',
800: '#1565c0',
900: '#0d47a1',
};

const grey = {
50: '#F3F6F9',
100: '#E5EAF2',
200: '#DAE2ED',
300: '#C7D0DD',
400: '#B0B8C4',
500: '#9DA8B7',
600: '#6B7A90',
700: '#434D5B',
800: '#303740',
900: '#1C2025',
};

const Checkbox = styled(BaseCheckbox)(
({ theme }) => `
width: 32px;
height: 32px;
padding: 0;
border-radius: 4px;
border: 2px solid ${blue[500]};
background: none;
transition-property: background, border-color;
transition-duration: 0.15s;
outline: none;
&:not([data-disabled]):hover {
border-color: ${blue[700]};
}
&[data-disabled] {
opacity: 0.4;
cursor: not-allowed;
}
&:focus-visible {
outline: 2px solid ${theme.palette.mode === 'dark' ? blue[800] : blue[400]};
outline-offset: 2px;
}
&[data-state="checked"], &[data-state="mixed"] {
border-color: transparent;
background: ${blue[600]};
&:not([data-disabled]):hover {
background: ${blue[700]};
}
}
`,
);

const HorizontalRuleIcon = styled(HorizontalRule)`
height: 100%;
color: ${grey[100]};
`;

const Indicator = styled(BaseCheckbox.Indicator)(
({ theme }) => `
color: ${theme.palette.mode === 'dark' ? grey[100] : grey[100]};
height: 100%;
display: inline-block;
visibility: hidden;
&[data-state="checked"], &[data-state="mixed"] {
visibility: visible;
}
`,
);
102 changes: 102 additions & 0 deletions docs/data/base/components/checkbox/UnstyledCheckboxIndeterminate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import * as React from 'react';
import { styled } from '@mui/system';
import { Checkbox as BaseCheckbox } from '@mui/base/Checkbox';
import HorizontalRule from '@mui/icons-material/HorizontalRule';

export default function UnstyledCheckboxIndeterminate() {
return (
<div style={{ display: 'flex', gap: 15 }}>
<Checkbox aria-label="Indeterminate checkbox" indeterminate>
<Indicator>
<HorizontalRuleIcon />
</Indicator>
</Checkbox>
<Checkbox aria-label="Indeterminate checkbox" indeterminate disabled>
<Indicator>
<HorizontalRuleIcon />
</Indicator>
</Checkbox>
</div>
);
}

const blue = {
50: '#e3f2fd',
100: '#bbdefb',
200: '#90caf9',
300: '#64b5f6',
400: '#42a5f5',
500: '#2196f3',
600: '#1e88e5',
700: '#1976d2',
800: '#1565c0',
900: '#0d47a1',
};

const grey = {
50: '#F3F6F9',
100: '#E5EAF2',
200: '#DAE2ED',
300: '#C7D0DD',
400: '#B0B8C4',
500: '#9DA8B7',
600: '#6B7A90',
700: '#434D5B',
800: '#303740',
900: '#1C2025',
};

const Checkbox = styled(BaseCheckbox)(
({ theme }) => `
width: 32px;
height: 32px;
padding: 0;
border-radius: 4px;
border: 2px solid ${blue[500]};
background: none;
transition-property: background, border-color;
transition-duration: 0.15s;
outline: none;
&:not([data-disabled]):hover {
border-color: ${blue[700]};
}
&[data-disabled] {
opacity: 0.4;
cursor: not-allowed;
}
&:focus-visible {
outline: 2px solid ${theme.palette.mode === 'dark' ? blue[800] : blue[400]};
outline-offset: 2px;
}
&[data-state="checked"], &[data-state="mixed"] {
border-color: transparent;
background: ${blue[600]};
&:not([data-disabled]):hover {
background: ${blue[700]};
}
}
`,
);

const HorizontalRuleIcon = styled(HorizontalRule)`
height: 100%;
color: ${grey[100]};
`;

const Indicator = styled(BaseCheckbox.Indicator)(
({ theme }) => `
color: ${theme.palette.mode === 'dark' ? grey[100] : grey[100]};
height: 100%;
display: inline-block;
visibility: hidden;
&[data-state="checked"], &[data-state="mixed"] {
visibility: visible;
}
`,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import * as React from 'react';
import { Checkbox } from '@mui/base/Checkbox';
import { useTheme } from '@mui/system';
import Check from '@mui/icons-material/Check';

export default function UnstyledCheckboxIntroduction() {
return (
<div style={{ display: 'flex', gap: 15 }}>
<Checkbox
className="Checkbox"
aria-label="Basic checkbox, on by default"
defaultChecked
>
<Checkbox.Indicator className="Checkbox-indicator">
<Check className="Checkbox-icon" />
</Checkbox.Indicator>
</Checkbox>
<Checkbox className="Checkbox" aria-label="Basic checkbox, off by default">
<Checkbox.Indicator className="Checkbox-indicator">
<Check className="Checkbox-icon" />
</Checkbox.Indicator>
</Checkbox>
<Checkbox
className="Checkbox"
aria-label="Disabled checkbox, on by default"
defaultChecked
disabled
>
<Checkbox.Indicator className="Checkbox-indicator">
<Check className="Checkbox-icon" />
</Checkbox.Indicator>
</Checkbox>
<Checkbox
className="Checkbox"
aria-label="Disabled checkbox, off by default"
disabled
>
<Checkbox.Indicator className="Checkbox-indicator">
<Check className="Checkbox-icon" />
</Checkbox.Indicator>
</Checkbox>
<Styles />
</div>
);
}

const grey = {
50: '#F3F6F9',
100: '#E5EAF2',
200: '#DAE2ED',
300: '#C7D0DD',
400: '#B0B8C4',
500: '#9DA8B7',
600: '#6B7A90',
700: '#434D5B',
800: '#303740',
900: '#1C2025',
};

function useIsDarkMode() {
const theme = useTheme();
return theme.palette.mode === 'dark';
}

function Styles() {
// Replace this with your app logic for determining dark modes
const isDarkMode = useIsDarkMode();

return (
<style>
{`
.Checkbox {
all: unset;
box-sizing: border-box;
text-align: center;
width: 32px;
height: 32px;
padding: 0;
border-radius: 4px;
border: 2px solid ${grey[600]};
background: none;
transition-property: background, border-color;
transition-duration: 0.15s;
}
.Checkbox[data-disabled] {
opacity: 0.4;
cursor: not-allowed;
}
.Checkbox:hover:not([data-disabled]) {
border-color: ${isDarkMode ? grey[600] : grey[700]};
}
.Checkbox:focus-visible {
outline: 2px solid ${isDarkMode ? grey[600] : grey[500]};
outline-offset: 2px;
}
.Checkbox[data-state="checked"] {
border-color: ${grey[800]};
background: ${grey[800]};
}
.Checkbox[data-state="checked"]:not([data-disabled]):hover {
background: ${grey[900]};
border-color: transparent;
}
.Checkbox-indicator {
height: 100%;
display: inline-block;
visibility: hidden;
color: ${isDarkMode ? grey[900] : grey[100]};
}
.Checkbox-indicator[data-state="checked"] {
visibility: visible;
}
.Checkbox-icon {
height: 100%;
}
@media (prefers-color-scheme: dark) {
.Checkbox {
border-color: ${grey[500]};
}
.Checkbox[data-state="checked"] {
border-color: ${grey[300]};
background: ${grey[300]};
}
.Checkbox:hover:not([data-disabled]) {
border-color: ${grey[100]};
}
.Checkbox[data-state="checked"]:not([data-disabled]):hover {
background: ${grey[100]};
border-color: transparent;
}
.Checkbox-indicator {
color: ${grey[900]};
}
}
`}
</style>
);
}
Loading

0 comments on commit 54d6b03

Please sign in to comment.