@amaui/ui-react
Version:
UI for React
204 lines (203 loc) • 7.71 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
const _excluded = ["size", "Component", "className", "style", "children"],
_excluded2 = ["tonal", "color", "version", "size", "render", "inputRef", "colorUnchecked", "valueDefault", "checkedDefault", "value", "checked", "onChange", "disabled", "Component", "className", "children"];
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
import React from 'react';
import { is } from '@amaui/utils';
import { classNames, style as styleMethod, useAmauiTheme } from '@amaui/style-react';
import IconButtonElement from '../IconButton';
import { iconSizeToFontSize, staticClassName } from '../utils';
const useStyle = styleMethod(theme => ({
root: {
position: 'relative',
'& *': {
boxSizing: 'border-box'
}
},
input: {
position: 'absolute',
inset: '0',
width: '100%',
height: '100%',
opacity: '0',
cursor: 'inherit',
zIndex: '1'
},
icon: {
zIndex: '1',
pointerEvents: 'none'
},
iconBox: {
border: '0.12em solid currentColor',
borderRadius: `calc(${theme.shape.radius.unit / 8} * 0.75em)`
},
iconBox_size_small: {
width: '0.75em',
height: '0.75em'
},
iconBox_size_regular: {
width: '1em',
height: '1em'
},
iconBox_size_large: {
width: '1.25em',
height: '1.25em'
},
iconDot: {
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
inset: '0',
width: '100%',
height: '100%',
background: 'currentColor',
borderRadius: `calc(${theme.shape.radius.unit / 8} * 0.75em)`,
zIndex: '3',
transform: 'scale(0)',
transition: theme.methods.transitions.make('transform', {
duration: 'xxs'
})
},
checked: {
transform: 'scale(0.5)'
},
disabled: {
cursor: 'default'
}
}), {
name: 'amaui-Radio'
});
const IconItem = props => {
const {
size,
Component = 'span',
className,
style,
children
} = props,
other = _objectWithoutProperties(props, _excluded);
const styles = {
root: {}
};
const fontSize = iconSizeToFontSize(size);
styles.root.fontSize = `calc(${fontSize} / 1.2)`;
return /*#__PURE__*/React.createElement(Component, {
className: className,
style: _objectSpread(_objectSpread({}, style), styles.root),
size: size
}, children && /*#__PURE__*/React.cloneElement(children, _objectSpread({}, other)));
};
const Radio = /*#__PURE__*/React.forwardRef((props_, ref) => {
const theme = useAmauiTheme();
const props = React.useMemo(() => _objectSpread(_objectSpread(_objectSpread({}, theme?.ui?.elements?.all?.props?.default), theme?.ui?.elements?.amauiRadio?.props?.default), props_), [props_]);
const IconButton = React.useMemo(() => theme?.elements?.IconButton || IconButtonElement, [theme]);
const {
tonal = true,
color = 'primary',
version = 'text',
size = 'regular',
render,
inputRef,
colorUnchecked = 'default',
valueDefault: valueDefault_,
checkedDefault: checkedDefault_,
value: value_,
checked: checked_,
onChange,
disabled,
Component = 'span',
className,
children
} = props,
other = _objectWithoutProperties(props, _excluded2);
const checkedDefault = valueDefault_ !== undefined ? valueDefault_ : checkedDefault_;
const checked = value_ !== undefined ? value_ : checked_;
const [value, setValue] = React.useState((checkedDefault !== undefined ? checkedDefault : checked) || false);
const refs = {
value: React.useRef(undefined),
input: React.useRef(undefined)
};
refs.value.current = value;
const {
classes
} = useStyle();
const styles = {
iconBox: {}
};
React.useEffect(() => {
if (checked !== undefined && checked !== refs.value.current) setValue(checked);
}, [checked]);
const onUpdate = event => {
if (!disabled) {
// Inner controlled checkbox
if (!props.hasOwnProperty('checked')) setValue(event.target.checked);
if (is('function', onChange)) onChange(event.target.checked, event);
}
};
const onKeyDown = event => {
switch (event.key) {
case 'Enter':
if (refs.input.current) refs.input.current.click();
break;
default:
break;
}
};
let palette;
if (!theme.palette.color[color]) palette = theme.methods.color(color);
if (tonal) {
// Text
// Outlined
if (['text', 'outlined', undefined].includes(version)) {
styles.iconBox.color = styles.iconBox.color = theme.methods.palette.color.value(color, 30, true, palette);
}
// Outlined
if (version === 'outlined') styles.iconBox.color = styles.iconBox.color = theme.methods.palette.color.value(color, 40, true, palette);
}
let colorValue = color;
if (!value) colorValue = colorUnchecked;
return /*#__PURE__*/React.createElement(IconButton, _extends({
ref: ref,
tabIndex: !disabled ? 0 : -1,
tonal: tonal,
color: colorValue,
version: version,
size: size,
onKeyDown: onKeyDown,
firstLevelChildren: /*#__PURE__*/React.createElement("input", {
ref: item => {
if (inputRef) inputRef.current = item;
refs.input.current = item;
},
tabIndex: -1,
type: "checkbox",
checked: value,
onChange: onUpdate,
className: classNames([staticClassName('Radio', theme) && ['amaui-Radio-input'], classes.input]),
disabled: disabled
}),
role: "radio",
"aria-checked": value,
"aria-disabled": disabled,
disabled: disabled,
Component: Component,
className: classNames([staticClassName('Radio', theme) && ['amaui-Radio-root', `amaui-Radio-version-${version}`, `amaui-Radio-size-${size}`, value && `amaui-Radio-checked`, disabled && `amaui-Radio-disabled`], className, classes.root, disabled && classes.disabled])
}, other), is('function', render) ? render(value, _objectSpread(_objectSpread(_objectSpread({}, props), other), {}, {
tonal,
color,
version
})) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(IconItem, {
Component: "div",
className: classNames([staticClassName('Radio', theme) && ['amaui-Radio-icon', 'amaui-Radio-icon-box'], classes.icon, classes.iconBox, classes[`iconBox_size_${size}`], classes[version], disabled && classes.disabled]),
style: styles.iconBox
}), /*#__PURE__*/React.createElement(IconItem, {
Component: "div",
className: classNames([staticClassName('Radio', theme) && ['amaui-Radio-icon', 'amaui-Radio-icon-dot', value && 'amaui-Radio-icon-dot-checked'], classes.icon, classes.iconDot, value && classes.checked])
})));
});
Radio.displayName = 'amaui-Radio';
export default Radio;