Skip to content
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

[PBNTR-373] (Enable Kits Instead of Text for Radio label) #3612

Merged
merged 18 commits into from
Sep 6, 2024
Merged
4 changes: 2 additions & 2 deletions playbook/app/pb_kits/playbook/pb_radio/_radio.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
display: inline-flex;
cursor: pointer;

.pb_radio_button {
.pb_radio_button{
width: 22px;
min-width: 22px;
height: 22px;
Expand All @@ -18,7 +18,7 @@
margin-right: $space_xs;
transition: background $transition_default ease, box-shadow $transition_default ease, border-color $transition_default ease;
}

@media (hover:hover) {
&:hover .pb_radio_button {
background-color: $bg_light;
Expand Down
150 changes: 100 additions & 50 deletions playbook/app/pb_kits/playbook/pb_radio/_radio.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
/*eslint-disable react/no-multi-comp, flowtype/space-before-type-colon */

import React, { forwardRef } from 'react'
import React, { forwardRef, isValidElement, useRef } from 'react'
import Body from '../pb_body/_body'
import Flex from '../pb_flex/_flex'
import classnames from 'classnames'
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
import { globalProps, GlobalProps } from '../utilities/globalProps'

type RadioProps = {
aria?: {[key: string]: string},
aria?: { [key: string]: string },
alignment?: string,
checked?: boolean,
children?: React.ReactChild[] | React.ReactChild,
className?: string,
dark?: boolean,
data?: {[key: string]: string},
data?: { [key: string]: string },
disabled?: boolean,
error?: boolean,
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
htmlOptions?: { [key: string]: string | number | boolean | (() => void) },
id?: string,
label: string,
name?: string,
value?: string,
text?: string,
onChange: (event: React.FormEvent<HTMLInputElement> | null)=>void,
onChange: (event: React.FormEvent<HTMLInputElement> | null) => void,
} & GlobalProps

const Radio = ({
Expand All @@ -31,9 +30,9 @@ const Radio = ({
children,
className,
dark = false,
data = {},
disabled = false,
error = false,
data = {},
htmlOptions = {},
id,
label,
Expand All @@ -42,52 +41,103 @@ const Radio = ({
value = 'radio_text',
onChange = () => { void 0 },
...props
}: RadioProps, ref: any) => {
const ariaProps = buildAriaProps(aria)
const dataProps = buildDataProps(data)
const htmlProps = buildHtmlProps(htmlOptions)
}: RadioProps ) => {
const radioRef = useRef(null);

const ariaProps = buildAriaProps(aria);
const dataProps = buildDataProps(data);
const htmlProps = buildHtmlProps(htmlOptions);
const classes = classnames(
buildCss('pb_radio_kit', alignment ),
dark ? 'dark': null, error ? 'error': null,
buildCss('pb_radio_kit', alignment),
dark ? 'dark' : null,
error ? 'error' : null,
globalProps(props),
className)
className
);

const classesCustom = classnames(
dark ? 'dark' : null,
error ? 'error' : null,
globalProps(props),
className
);

const isCustomChild = children && isValidElement(children) && children.type !== 'input';

const displayRadio = (props: RadioProps & any) => {
if (children)
return (children)
else
return (
<input
disabled={disabled}
id={id}
name={name}
onChange={onChange}
ref={ref}
text={text}
type="radio"
value={value}
{...props}
/>
)}
if (isValidElement(children) && children.type === 'input') {
return React.cloneElement(children, { ...props, ref: radioRef });
} else if (isCustomChild || !children) {
return (
<input
disabled={disabled}
id={id}
name={name}
onChange={onChange}
ref={radioRef}
text={text}
type="radio"
value={value}
{...props}
/>
);
}
};

const handleContainerClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent> | undefined) => {
if (event) {
const target = event.target as HTMLElement;
if (
target.id === 'children-wrapper' ||
target.closest('#children-wrapper')
nickamantia marked this conversation as resolved.
Show resolved Hide resolved
) {
radioRef.current?.click();
}
}
};

return (
<label
{...ariaProps}
{...dataProps}
{...htmlProps}
className={classes}
htmlFor={id}
>
<>{displayRadio(props)}</>
<span className="pb_radio_button" />
<Body
dark={dark}
status={error ? 'negative' : null}
text={label}
variant={null}
/>
</label>
)
}
isCustomChild ? (
<Flex
{...ariaProps}
{...dataProps}
{...htmlProps}
align='center'
className={classesCustom}
cursor='pointer'
htmlFor={id}
htmlOptions={{
onClick: ((event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
handleContainerClick(event);
}) as unknown as () => void
}}
id="radio-container"
>
<label className={buildCss('pb_radio_kit', alignment)}>
<>{displayRadio(props)}</>
<span className="pb_radio_button" />
</label>
<div id="children-wrapper"> {children} </div>
</Flex>
) : (
<label
{...ariaProps}
{...dataProps}
{...htmlProps}
className={classes}
htmlFor={id}
>
<>{displayRadio(props)}</>
<span className="pb_radio_button" />
<Body
dark={dark}
status={error ? 'negative' : null}
text={label}
variant={null}
/>
</label>
)
);
};

export default forwardRef(Radio)
export default forwardRef(Radio);
43 changes: 43 additions & 0 deletions playbook/app/pb_kits/playbook/pb_radio/docs/_radio_children.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import Radio from '../_radio'
import Dropdown from '../../pb_dropdown/_dropdown'
import Title from '../../pb_title/_title'

const RadioChildren = (props) => {


const options = [
{ label: 'Orange', value: '#FFA500' },
{ label: 'Red', value: '#FF0000' },
{ label: 'Green', value: '#00FF00' },
{ label: 'Blue', value: '#0000FF' },
]

return (
<div>
<Radio
label="Power"
name="Group2"
tabIndex={0}
value="Power"
{...props}
>
<Dropdown
minWidth="xs"
options={options}
/>
</Radio>
<br />
<Radio
defaultChecked={false}
label="Google"
name="Group2"
value="Google"
{...props}
>
<Title text="Custom Typography" />
</Radio>
nickamantia marked this conversation as resolved.
Show resolved Hide resolved
</div>
)
}
export default RadioChildren
1 change: 1 addition & 0 deletions playbook/app/pb_kits/playbook/pb_radio/docs/example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ examples:
- radio_error: With Error
- radio_alignment: Alignment
- radio_disabled: Disabled
- radio_children: Children

swift:
- radio_default_swift: Default
Expand Down
1 change: 1 addition & 0 deletions playbook/app/pb_kits/playbook/pb_radio/docs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { default as RadioCustom } from './_radio_custom.jsx'
export { default as RadioError } from './_radio_error.jsx'
export { default as RadioAlignment } from './_radio_alignment.jsx'
export { default as RadioDisabled } from './_radio_disabled.jsx'
export { default as RadioChildren } from './_radio_children.jsx'
Loading