mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-19 18:02:13 +00:00
Accessible components refactored
This commit is contained in:
parent
238915c76e
commit
c108fe2b35
3 changed files with 35 additions and 54 deletions
|
|
@ -1,4 +1,5 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const { useFocusable } = require('stremio-navigation');
|
||||
|
||||
|
|
@ -46,4 +47,17 @@ const Button = React.forwardRef(({ children, ...props }, ref) => {
|
|||
|
||||
Button.displayName = 'Button';
|
||||
|
||||
Button.propTypes = {
|
||||
className: PropTypes.string,
|
||||
tabIndex: PropTypes.number,
|
||||
href: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
onKeyUp: PropTypes.func,
|
||||
onMouseDown: PropTypes.func,
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
])
|
||||
};
|
||||
|
||||
module.exports = Button;
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ const Icon = require('stremio-icons/dom');
|
|||
const Button = require('../Button');
|
||||
const styles = require('./styles');
|
||||
|
||||
const Checkbox = React.forwardRef(({ className, checked = false, disabled = false, onClick, children }, ref) => {
|
||||
const Checkbox = React.forwardRef(({ children, ...props }, ref) => {
|
||||
return (
|
||||
<Button ref={ref} className={classnames(className, styles['checkbox-container'], { 'checked': checked })} disabled={disabled} onClick={onClick}>
|
||||
<Icon className={styles['icon']} icon={checked ? 'ic_check' : 'ic_box_empty'} />
|
||||
<Button {...props} ref={ref} className={classnames(props.className, styles['checkbox-container'], { 'checked': props.checked })}>
|
||||
<Icon className={styles['icon']} icon={props.checked ? 'ic_check' : 'ic_box_empty'} />
|
||||
{React.isValidElement(children) ? children : null}
|
||||
</Button>
|
||||
);
|
||||
|
|
@ -19,8 +19,6 @@ Checkbox.displayName = 'Checkbox';
|
|||
Checkbox.propTypes = {
|
||||
className: PropTypes.string,
|
||||
checked: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
|
|
|
|||
|
|
@ -1,71 +1,40 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const { useFocusable } = require('stremio-navigation');
|
||||
|
||||
const ENTER_KEY_CODE = 13;
|
||||
const BUTTON_INPUT_TYPES = ['button', 'link'];
|
||||
const TEXT_INPUT_TYPES = ['text', 'email', 'password'];
|
||||
const TAG_NAMES_FOR_TYPE = Object.assign(Object.create(null), {
|
||||
button: 'div',
|
||||
link: 'a',
|
||||
text: 'input',
|
||||
email: 'input',
|
||||
password: 'input'
|
||||
});
|
||||
|
||||
const Input = React.forwardRef(({ type, tabIndex, children, ...props }, ref) => {
|
||||
const Input = React.forwardRef((props, ref) => {
|
||||
const focusable = useFocusable();
|
||||
const onKeyUp = React.useCallback((event) => {
|
||||
if (typeof props.onKeyUp === 'function') {
|
||||
props.onKeyUp(event);
|
||||
}
|
||||
|
||||
if (!event.nativeEvent.submitPrevented && event.keyCode === ENTER_KEY_CODE) {
|
||||
if (BUTTON_INPUT_TYPES.includes(type)) {
|
||||
event.currentTarget.click();
|
||||
} else if (TEXT_INPUT_TYPES.includes(type)) {
|
||||
if (typeof props.onSubmit === 'function') {
|
||||
props.onSubmit(event);
|
||||
}
|
||||
}
|
||||
if (event.keyCode === ENTER_KEY_CODE && !event.nativeEvent.submitPrevented && typeof props.onSubmit === 'function') {
|
||||
props.onSubmit(event);
|
||||
}
|
||||
}, [props.onKeyUp, props.onSubmit, type]);
|
||||
const onMouseDown = React.useCallback((event) => {
|
||||
if (typeof props.onMouseDown === 'function') {
|
||||
props.onMouseDown(event);
|
||||
}
|
||||
|
||||
if (!event.nativeEvent.blurPrevented && BUTTON_INPUT_TYPES.includes(type)) {
|
||||
event.preventDefault();
|
||||
if (document.activeElement instanceof HTMLElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}
|
||||
}, [props.onMouseDown, type]);
|
||||
const tagName = TAG_NAMES_FOR_TYPE[type];
|
||||
const elementProps = {
|
||||
...props,
|
||||
ref,
|
||||
type: tagName === 'input' ? type : null,
|
||||
tabIndex: (isNaN(tabIndex) || tabIndex === null) ? (focusable ? 0 : -1) : tabIndex,
|
||||
onKeyUp,
|
||||
onMouseDown
|
||||
};
|
||||
return React.createElement(tagName, elementProps, children);
|
||||
}, [props.onKeyUp, props.onSubmit]);
|
||||
return (
|
||||
<input
|
||||
{...props}
|
||||
ref={ref}
|
||||
className={classnames(props.className, { 'disabled': props.disabled })}
|
||||
tabIndex={(props.tabIndex === null || isNaN(props.tabIndex)) ? (focusable ? 0 : -1) : props.tabIndex}
|
||||
onKeyUp={onKeyUp}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
Input.displayName = 'Input';
|
||||
|
||||
Input.propTypes = {
|
||||
type: PropTypes.oneOf([
|
||||
...BUTTON_INPUT_TYPES,
|
||||
...TEXT_INPUT_TYPES
|
||||
]).isRequired,
|
||||
className: PropTypes.string,
|
||||
tabIndex: PropTypes.number,
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
])
|
||||
disabled: PropTypes.bool,
|
||||
onKeyUp: PropTypes.func,
|
||||
onSubmit: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = Input;
|
||||
|
|
|
|||
Loading…
Reference in a new issue