initial commit
This commit is contained in:
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import classnames from 'classnames';
|
||||
import { withInstanceId } from '@wordpress/compose';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import RadioControlOption from './option';
|
||||
import './style.scss';
|
||||
|
||||
const RadioControl = ( {
|
||||
className,
|
||||
instanceId,
|
||||
id,
|
||||
selected,
|
||||
onChange,
|
||||
options = [],
|
||||
} ) => {
|
||||
const radioControlId = id || instanceId;
|
||||
|
||||
return (
|
||||
options.length && (
|
||||
<div
|
||||
className={ classnames(
|
||||
'wc-block-components-radio-control',
|
||||
className
|
||||
) }
|
||||
>
|
||||
{ options.map( ( option ) => (
|
||||
<RadioControlOption
|
||||
key={ `${ radioControlId }-${ option.value }` }
|
||||
name={ `radio-control-${ radioControlId }` }
|
||||
checked={ option.value === selected }
|
||||
option={ option }
|
||||
onChange={ ( value ) => {
|
||||
onChange( value );
|
||||
if ( typeof option.onChange === 'function' ) {
|
||||
option.onChange( value );
|
||||
}
|
||||
} }
|
||||
/>
|
||||
) ) }
|
||||
</div>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default withInstanceId( RadioControl );
|
||||
export { RadioControlOption };
|
||||
export { default as RadioControlOptionLayout } from './option-layout';
|
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { ReactElement } from 'react';
|
||||
import type { PackageRateOption } from '@woocommerce/type-defs/shipping';
|
||||
|
||||
const OptionLayout = ( {
|
||||
label,
|
||||
secondaryLabel,
|
||||
description,
|
||||
secondaryDescription,
|
||||
id,
|
||||
}: Partial< PackageRateOption > ): ReactElement => {
|
||||
return (
|
||||
<div className="wc-block-components-radio-control__option-layout">
|
||||
<div className="wc-block-components-radio-control__label-group">
|
||||
{ label && (
|
||||
<span
|
||||
id={ id && `${ id }__label` }
|
||||
className="wc-block-components-radio-control__label"
|
||||
>
|
||||
{ label }
|
||||
</span>
|
||||
) }
|
||||
{ secondaryLabel && (
|
||||
<span
|
||||
id={ id && `${ id }__secondary-label` }
|
||||
className="wc-block-components-radio-control__secondary-label"
|
||||
>
|
||||
{ secondaryLabel }
|
||||
</span>
|
||||
) }
|
||||
</div>
|
||||
<div className="wc-block-components-radio-control__description-group">
|
||||
{ description && (
|
||||
<span
|
||||
id={ id && `${ id }__description` }
|
||||
className="wc-block-components-radio-control__description"
|
||||
>
|
||||
{ description }
|
||||
</span>
|
||||
) }
|
||||
{ secondaryDescription && (
|
||||
<span
|
||||
id={ id && `${ id }__secondary-description` }
|
||||
className="wc-block-components-radio-control__secondary-description"
|
||||
>
|
||||
{ secondaryDescription }
|
||||
</span>
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OptionLayout;
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import classnames from 'classnames';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import OptionLayout from './option-layout';
|
||||
|
||||
const Option = ( { checked, name, onChange, option } ) => {
|
||||
const {
|
||||
value,
|
||||
label,
|
||||
description,
|
||||
secondaryLabel,
|
||||
secondaryDescription,
|
||||
} = option;
|
||||
const onChangeValue = ( event ) => onChange( event.target.value );
|
||||
|
||||
return (
|
||||
<label
|
||||
className={ classnames(
|
||||
'wc-block-components-radio-control__option',
|
||||
{
|
||||
'wc-block-components-radio-control__option-checked': checked,
|
||||
}
|
||||
) }
|
||||
htmlFor={ `${ name }-${ value }` }
|
||||
>
|
||||
<input
|
||||
id={ `${ name }-${ value }` }
|
||||
className="wc-block-components-radio-control__input"
|
||||
type="radio"
|
||||
name={ name }
|
||||
value={ value }
|
||||
onChange={ onChangeValue }
|
||||
checked={ checked }
|
||||
aria-describedby={ classnames( {
|
||||
[ `${ name }-${ value }__label` ]: label,
|
||||
[ `${ name }-${ value }__secondary-label` ]: secondaryLabel,
|
||||
[ `${ name }-${ value }__description` ]: description,
|
||||
[ `${ name }-${ value }__secondary-description` ]: secondaryDescription,
|
||||
} ) }
|
||||
/>
|
||||
<OptionLayout
|
||||
id={ `${ name }-${ value }` }
|
||||
label={ label }
|
||||
secondaryLabel={ secondaryLabel }
|
||||
description={ description }
|
||||
secondaryDescription={ secondaryDescription }
|
||||
/>
|
||||
</label>
|
||||
);
|
||||
};
|
||||
|
||||
export default Option;
|
@ -0,0 +1,115 @@
|
||||
.wc-block-components-radio-control__option {
|
||||
@include reset-typography();
|
||||
display: block;
|
||||
margin: em($gap) 0;
|
||||
padding: 0 0 0 em($gap-largest);
|
||||
position: relative;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-block-components-radio-control__option-layout {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wc-block-components-radio-control__option .wc-block-components-radio-control__option-layout {
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-block-components-radio-control__label-group,
|
||||
.wc-block-components-radio-control__description-group {
|
||||
display: table-row;
|
||||
|
||||
> span {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.wc-block-components-radio-control__secondary-label,
|
||||
.wc-block-components-radio-control__secondary-description {
|
||||
text-align: right;
|
||||
min-width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-block-components-radio-control__label,
|
||||
.wc-block-components-radio-control__secondary-label {
|
||||
// Currently, max() CSS function calls need to be wrapped with unquote.
|
||||
// See: https://github.com/sass/sass/issues/2378#issuecomment-367490840
|
||||
// These values should be the same as the control input height.
|
||||
line-height: unquote("max(1.5rem, 24px)");
|
||||
}
|
||||
|
||||
.wc-block-components-radio-control__description,
|
||||
.wc-block-components-radio-control__secondary-description {
|
||||
@include font-size(small);
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
// Extra class for specificity.
|
||||
.wc-block-components-radio-control {
|
||||
.wc-block-components-radio-control__input {
|
||||
appearance: none;
|
||||
background: #fff;
|
||||
border: 2px solid $input-border-gray;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
height: em(24px); // =1.5rem
|
||||
min-height: 24px;
|
||||
min-width: 24px;
|
||||
width: em(24px);
|
||||
// The code belows centers the input vertically.
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
|
||||
&:checked::before {
|
||||
background: #000;
|
||||
border-radius: 50%;
|
||||
content: "";
|
||||
display: block;
|
||||
height: em(12px);
|
||||
left: 50%;
|
||||
margin: 0;
|
||||
min-height: 12px;
|
||||
min-width: 12px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: em(12px);
|
||||
}
|
||||
|
||||
.has-dark-controls & {
|
||||
border-color: $controls-border-dark;
|
||||
background-color: $input-background-dark;
|
||||
|
||||
&:checked::before {
|
||||
background: $input-text-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.theme-twentytwentyone {
|
||||
.wc-block-components-radio-control .wc-block-components-radio-control__input {
|
||||
&:checked {
|
||||
border-width: 2px;
|
||||
|
||||
&::before {
|
||||
background-color: var(--form--color-text);
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user