Skip to content

Commit

Permalink
Merge pull request #14 from fortanix/feature/form
Browse files Browse the repository at this point in the history
Checkbox improvements
  • Loading branch information
nighto authored Nov 8, 2024
2 parents 20c57df + 2b8b9ac commit efa1fc0
Show file tree
Hide file tree
Showing 13 changed files with 520 additions and 198 deletions.
59 changes: 40 additions & 19 deletions src/components/forms/controls/Checkbox/Checkbox.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,61 @@

@use '../../../../styling/defs.scss' as bk;

@mixin svg-checkbox {
background-image: url('data:image/svg+xml;utf8,<svg width="14" height="10" viewBox="0 0 14 10" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5 10L0 5.19231L1.4 3.84615L5 7.30769L12.6 0L14 1.34615L5 10Z" fill="white"/></svg>');
}

@mixin svg-dash {
background-image: url('data:image/svg+xml;utf8,<svg width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.97165 9.94239L2.97165 8.00003L2.97266 8.00103L14.9717 7.99997L14.9719 9.94239L2.97165 9.94239Z" fill="white"/></svg>');
}

@layer baklava.components {
.bk-checkbox {
@include bk.component-base(bk-checkbox);

--bk-checkbox-background-color: transparent;
--bk-checkbox-border-color: #{bk.$theme-checkbox-border-default};


cursor: pointer;

appearance: none;
width: 18px;
aspect-ratio: 1;
border-radius: 3px;
background: var(--bk-checkbox-background-color);

background: transparent;
background-position: top; /* Transition background-image from top */
border: 1px solid var(--bk-checkbox-border-color);

border: 1px solid bk.$theme-checkbox-border-default;

&:checked, &:indeterminate {
background-color: bk.$theme-checkbox-background-default;
background-position: center;
background-repeat: no-repeat;
border: none;
}
&:checked {
--bk-checkbox-background-color: #{bk.$theme-checkbox-background-default};
--bk-checkbox-border-color: var(--bk-checkbox-background-color);
background:
center url('data:image/svg+xml;utf8,<svg width="14" height="10" viewBox="0 0 14 10" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5 10L0 5.19231L1.4 3.84615L5 7.30769L12.6 0L14 1.34615L5 10Z" fill="white"/></svg>') no-repeat,
var(--bk-checkbox-background-color);
@include svg-checkbox;
}
&:indeterminate {
@include svg-dash;
}
&:disabled {
--bk-checkbox-border-color: #{bk.$theme-checkbox-border-disabled};
--bk-checkbox-background-color: transparent;

border-color: bk.$theme-checkbox-border-disabled;
background-color: transparent;
cursor: not-allowed;

&:checked, &:indeterminate {
background-color: bk.$theme-checkbox-background-non-active;
}
&:checked {
--bk-checkbox-background-color: bk.$theme-checkbox-background-non-active;
@include svg-checkbox;
}
&:indeterminate {
@include svg-dash;
}
}
&:focus-visible, &.pseudo-focused {
outline: 2px solid bk.$theme-checkbox-border-focus !important;
outline-offset: 0 !important;
}

@media (prefers-reduced-motion: no-preference) {
transition: none 100ms ease-out;
transition-property: background-color, background-position, border-color;
Expand Down
92 changes: 82 additions & 10 deletions src/components/forms/controls/Checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import * as React from 'react';

import { Checkbox } from './Checkbox.tsx';

import cl from './Checkbox.module.scss';


type CheckboxArgs = React.ComponentProps<typeof Checkbox>;
type Story = StoryObj<CheckboxArgs>;
Expand All @@ -20,28 +22,98 @@ export default {
tags: ['autodocs'],
argTypes: {
},
args: {
defaultChecked: true,
},
args: {},
decorators: [
Story => <form onSubmit={event => { event.preventDefault(); }}><Story/></form>,
],
render: (args) => <Checkbox {...args}/>,
} satisfies Meta<CheckboxArgs>;


export const Checked: Story = {};

export const Unchecked: Story = {
args: { defaultChecked: false },
args: {},
};

export const DisabledChecked: Story = {
name: 'Disabled (checked)',
args: { disabled: true, defaultChecked: true },
export const Checked: Story = {
args: { defaultChecked: true },
};

export const Indeterminate: Story = {
args: {
defaultChecked: false,
indeterminate: true,
},
};

export const DisabledUnchecked: Story = {
name: 'Disabled (unchecked)',
args: { disabled: true, defaultChecked: false },
args: { disabled: true },
};

export const DisabledChecked: Story = {
name: 'Disabled (checked)',
args: {
defaultChecked: true,
disabled: true,
},
};

export const DisabledIndeterminate: Story = {
name: 'Disabled (indeterminate)',
args: {
defaultChecked: false,
disabled: true,
indeterminate: true,
},
};

export const FocusedUnchecked: Story = {
name: 'Focused (unchecked)',
args: {
className: cl['pseudo-focused'],
},
};

export const FocusedChecked: Story = {
name: 'Focused (checked)',
args: {
className: cl['pseudo-focused'],
defaultChecked: true,
},
};

export const FocusedIndeterminate: Story = {
name: 'Focused (indeterminate)',
args: {
className: cl['pseudo-focused'],
defaultChecked: false,
indeterminate: true,
},
};

export const FocusedDisabledUnchecked: Story = {
name: 'Focused & Disabled (unchecked)',
args: {
className: cl['pseudo-focused'],
disabled: true,
},
};

export const FocusedDisabledChecked: Story = {
name: 'Focused & Disabled (checked)',
args: {
className: cl['pseudo-focused'],
defaultChecked: true,
disabled: true,
},
};

export const FocusedDisabledIndeterminate: Story = {
name: 'Focused & Disabled (indeterminate)',
args: {
className: cl['pseudo-focused'],
defaultChecked: false,
disabled: true,
indeterminate: true,
},
};
18 changes: 17 additions & 1 deletion src/components/forms/controls/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,35 @@ export { cl as CheckboxClassNames };
export type CheckboxProps = ComponentProps<'input'> & {
/** Whether this component should be unstyled. */
unstyled?: undefined | boolean,

/** Whether the checkbox is in indeterminate state (minus sign) */
indeterminate?: undefined | boolean,
};
/**
* Checkbox control.
* A simple Checkbox control, just the &lt;input type="checkbox"&gt; and nothing else..
*/
export const Checkbox = (props: CheckboxProps) => {
const {
unstyled = false,
indeterminate = false,
...propsRest
} = props;

const checkboxRef = React.useRef<React.ComponentRef<'input'>>(null);

React.useEffect(() => {
if (checkboxRef?.current) {
if (indeterminate) {
checkboxRef.current.checked = false;
}
checkboxRef.current.indeterminate = indeterminate;
}
}, [indeterminate]);

return (
<input
type="checkbox"
ref={checkboxRef}
{...propsRest}
className={cx(
'bk',
Expand Down
54 changes: 0 additions & 54 deletions src/components/forms/controls/CheckboxGroup/Checkbox.module.scss

This file was deleted.

46 changes: 0 additions & 46 deletions src/components/forms/controls/CheckboxGroup/Checkbox.stories.tsx

This file was deleted.

20 changes: 0 additions & 20 deletions src/components/forms/controls/CheckboxGroup/Checkbox.tsx

This file was deleted.

Loading

0 comments on commit efa1fc0

Please sign in to comment.