-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from fortanix/feature/radio
Radio Button
- Loading branch information
Showing
9 changed files
with
515 additions
and
0 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* Copyright (c) Fortanix, Inc. | ||
|* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of | ||
|* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
@use '../../../../styling/defs.scss' as bk; | ||
|
||
@layer baklava.components { | ||
.bk-radio { | ||
@include bk.component-base(bk-radio); | ||
|
||
cursor: pointer; | ||
|
||
appearance: none; | ||
width: 18px; | ||
aspect-ratio: 1; | ||
|
||
border-radius: bk.$border-radius-circle; | ||
background: transparent; | ||
border: 1px solid bk.$theme-radio-default; | ||
|
||
// doing the inner cicle on checked / disabled+checked options without SVG. | ||
background-clip: content-box; | ||
padding: 3px; // distance between background filling and the center of border | ||
// since the border is 2px when checked, it's center is 1px, thus for a distance of 2px we need to have 1 + 2 = 3px. | ||
|
||
&:checked { | ||
background-color: bk.$theme-radio-selected; | ||
border: 2px solid bk.$theme-radio-selected; | ||
} | ||
&:disabled { | ||
border: 1px solid bk.$theme-radio-disabled; | ||
background-color: transparent; | ||
|
||
&:checked { | ||
border: 2px solid bk.$theme-radio-non-active; | ||
background-color: bk.$theme-radio-non-active; | ||
} | ||
} | ||
&:focus-visible, &.pseudo-focused { | ||
// those have !important to override CSS rules on layer accessibility | ||
outline: 2px solid bk.$theme-radio-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; | ||
} | ||
} | ||
} |
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,76 @@ | ||
/* Copyright (c) Fortanix, Inc. | ||
|* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of | ||
|* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import * as React from 'react'; | ||
|
||
import { Radio } from './Radio.tsx'; | ||
|
||
import cl from './Radio.module.scss'; | ||
|
||
|
||
type RadioArgs = React.ComponentProps<typeof Radio>; | ||
type Story = StoryObj<RadioArgs>; | ||
|
||
export default { | ||
component: Radio, | ||
parameters: { | ||
layout: 'centered', | ||
}, | ||
tags: ['autodocs'], | ||
argTypes: { | ||
}, | ||
args: {}, | ||
decorators: [ | ||
Story => <form onSubmit={event => { event.preventDefault(); }}><Story/></form>, | ||
], | ||
render: (args) => <Radio {...args}/>, | ||
} satisfies Meta<RadioArgs>; | ||
|
||
|
||
export const Checked: Story = { | ||
args: { defaultChecked: true }, | ||
}; | ||
|
||
export const Unchecked: Story = { | ||
args: {}, | ||
}; | ||
|
||
export const DisabledSelected: Story = { | ||
name: 'Disabled (selected)', | ||
args: { | ||
defaultChecked: true, | ||
disabled: true, | ||
}, | ||
}; | ||
|
||
export const DisabledUnselected: Story = { | ||
name: 'Disabled (unselected)', | ||
args: { disabled: true }, | ||
}; | ||
|
||
export const FocusedSelected: Story = { | ||
name: 'Focused (selected)', | ||
args: { | ||
className: cl['pseudo-focused'], | ||
defaultChecked: true, | ||
}, | ||
}; | ||
|
||
export const FocusedUnselected: Story = { | ||
name: 'Focused (unselected)', | ||
args: { | ||
className: cl['pseudo-focused'], | ||
}, | ||
}; | ||
|
||
export const FocusedDisabledSelected: Story = { | ||
name: 'Focused & Disabled (selected)', | ||
args: { | ||
className: cl['pseudo-focused'], | ||
defaultChecked: true, | ||
disabled: true, | ||
}, | ||
}; |
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,37 @@ | ||
/* Copyright (c) Fortanix, Inc. | ||
|* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of | ||
|* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
import { classNames as cx, type ComponentProps } from '../../../../util/componentUtil.ts'; | ||
import * as React from 'react'; | ||
|
||
import cl from './Radio.module.scss'; | ||
|
||
|
||
export { cl as RadioClassNames }; | ||
|
||
export type RadioProps = ComponentProps<'input'> & { | ||
/** Whether this component should be unstyled. */ | ||
unstyled?: undefined | boolean, | ||
}; | ||
/** | ||
* A simple Radio control, just the <input type="radio"> and nothing else.. | ||
*/ | ||
export const Radio = (props: RadioProps) => { | ||
const { | ||
unstyled = false, | ||
...propsRest | ||
} = props; | ||
|
||
return ( | ||
<input | ||
type="radio" | ||
{...propsRest} | ||
className={cx( | ||
'bk', | ||
{ [cl['bk-radio']]: !unstyled }, | ||
propsRest.className, | ||
)} | ||
/> | ||
); | ||
}; |
46 changes: 46 additions & 0 deletions
46
src/components/forms/fields/RadioField/RadioField.module.scss
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,46 @@ | ||
/* Copyright (c) Fortanix, Inc. | ||
|* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of | ||
|* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
@use '../../../../styling/defs.scss' as bk; | ||
|
||
@layer baklava.components { | ||
.bk-radio-field { | ||
@include bk.component-base(bk-radio-field); | ||
|
||
.bk-radio-field__title { | ||
color: bk.$theme-text-label-default; | ||
font-weight: bk.$font-weight-semibold; | ||
margin-bottom: bk.$spacing-1; | ||
|
||
.bk-radio-field__title__icon { | ||
font-size: 18px; | ||
margin-left: bk.$spacing-1; | ||
} | ||
|
||
.bk-radio-field__title__optional { | ||
font-size: bk.$font-size-xs; | ||
font-weight: bk.$font-weight-regular; | ||
margin-left: bk.$spacing-1; | ||
} | ||
} | ||
|
||
.bk-radio-field__label { | ||
display: flex; | ||
align-items: flex-start; | ||
} | ||
|
||
.bk-radio-field__label__content { | ||
color: bk.$theme-text-label-default; | ||
cursor: pointer; | ||
position: relative; | ||
padding-left: bk.$spacing-2; | ||
top: -2px; | ||
} | ||
|
||
.bk-radio-field__sublabel { | ||
font-size: bk.$font-size-xs; | ||
padding-left: 26px; | ||
} | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
src/components/forms/fields/RadioField/RadioField.stories.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,74 @@ | ||
/* Copyright (c) Fortanix, Inc. | ||
|* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of | ||
|* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import * as React from 'react'; | ||
|
||
import { RadioField } from './RadioField.tsx'; | ||
|
||
|
||
type RadioFieldArgs = React.ComponentProps<typeof RadioField>; | ||
type Story = StoryObj<RadioFieldArgs>; | ||
|
||
export default { | ||
component: RadioField, | ||
parameters: { | ||
layout: 'centered', | ||
}, | ||
tags: ['autodocs'], | ||
argTypes: { | ||
}, | ||
args: {}, | ||
decorators: [ | ||
Story => <form onSubmit={event => { event.preventDefault(); }}><Story/></form>, | ||
], | ||
render: (args) => <RadioField {...args}/>, | ||
} satisfies Meta<RadioFieldArgs>; | ||
|
||
|
||
export const RadioFieldWithLabel: Story = { | ||
args: { | ||
label: 'Label', | ||
}, | ||
}; | ||
|
||
export const RadioFieldWithLabelAndTitle: Story = { | ||
args: { | ||
title: 'Title', | ||
label: 'Label', | ||
}, | ||
}; | ||
|
||
export const RadioFieldWithLabelWithTitleWithTooltip: Story = { | ||
args: { | ||
title: 'Title', | ||
label: 'Label', | ||
titleTooltip: 'This is a tooltip', | ||
} | ||
}; | ||
|
||
export const RadioFieldWithLabelWithTitleWithOptional: Story = { | ||
args: { | ||
title: 'Title', | ||
label: 'Label', | ||
optional: true, | ||
}, | ||
}; | ||
|
||
export const RadioFieldWithLabelWithTitleWithTooltipWithOptional: Story = { | ||
args: { | ||
title: 'Title', | ||
label: 'Label', | ||
titleTooltip: 'This is a tooltip', | ||
optional: true, | ||
}, | ||
}; | ||
|
||
export const RadioFieldWithLabelAndSublabel: Story = { | ||
args: { | ||
label: 'Label', | ||
sublabel: 'Supporting copy', | ||
}, | ||
}; |
Oops, something went wrong.