lucid-ui
Version:
A UI component library from AppNexus.
76 lines (75 loc) • 2.86 kB
JavaScript
import _ from 'lodash';
import React from 'react';
import PropTypes from 'react-peek/prop-types';
import { CSSTransition } from 'react-transition-group';
import { lucidClassNames } from '../../util/style-helpers';
import { getFirst, omitProps } from '../../util/component-types';
import Switch from '../Switch/Switch';
import { useState } from 'react';
import { useEffect } from 'react';
const cx = lucidClassNames.bind('&-SwitchLabeled');
const { any, node, object, string } = PropTypes;
const defaultProps = {
isDisabled: false,
isSelected: false,
onSelect: _.noop,
};
const defaultState = {
_labelKey: 0,
};
const SwitchLabeled = (props) => {
const { className, isDisabled, isSelected, onSelect, style, ...passThroughs } = props;
const [state, setState] = useState(defaultState);
const currentLabel = _.get(getFirst(props, SwitchLabeled.Label), 'props.children', null);
useEffect(() => {
setState({ _labelKey: state._labelKey + 1 });
}, [currentLabel]);
const labelChildProps = _.get(getFirst(props, SwitchLabeled.Label), 'props');
const isShown = !!labelChildProps;
return (React.createElement("label", { className: cx('&', {
'&-is-disabled': isDisabled,
'&-is-selected': isSelected,
}, className), style: style },
React.createElement(Switch, Object.assign({ className: className, isDisabled: isDisabled, isSelected: isSelected, onSelect: onSelect }, omitProps(passThroughs, undefined, _.keys(SwitchLabeled.propTypes), false))),
labelChildProps && (React.createElement(CSSTransition, { in: isShown, classNames: cx('&-text'), timeout: 100, style: { position: 'relative' }, className: cx('&-text'), unmountOnExit: true },
React.createElement("span", { key: state._labelKey }, labelChildProps.children || labelChildProps)))));
};
SwitchLabeled.defaultProps = defaultProps;
SwitchLabeled.displayName = 'SwitchLabeled';
SwitchLabeled.peek = {
description: `
This is a composite of the \`Switch\` component and the native
\`label\` element.
`,
categories: ['controls', 'toggles'],
madeFrom: ['Switch'],
};
const Label = () => { return null; };
Label.displayName = 'SwitchLabeled.Label';
Label.peek = {
description: `
Label to be shown alongside the switch.
`,
};
Label.propName = 'Label';
Label.propTypes = {
children: node `
Used to identify the purpose of this switch to the user -- can be any
renderable content.
`,
};
SwitchLabeled.Label = Label;
SwitchLabeled.propTypes = {
...Switch.propTypes,
className: string `
Appended to the component-specific class names set on the root element.
`,
style: object `
Passed through to the root element.
`,
Label: any `
Child element whose children are used to identify the purpose of this
switch to the user.
`,
};
export default SwitchLabeled;