UNPKG

lucid-ui

Version:

A UI component library from AppNexus.

76 lines (75 loc) 2.86 kB
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;