UNPKG

baseui

Version:

A React Component library implementing the Base design language

263 lines (257 loc) • 7.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Root = exports.Label = exports.Input = exports.CheckmarkContainer = exports.Checkmark = void 0; var _styles = require("../styles"); var _constants = require("./constants"); var _getSharedStyles = require("../utils/get-shared-styles"); /* Copyright (c) Uber Technologies, Inc. This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree. */ function getBorderColor(props) { const { $disabled, $checked, $error, $isIndeterminate, $theme, $isFocusVisible } = props; const { colors } = $theme; if ($disabled) { return colors.contentStateDisabled; } if ($checked || $isIndeterminate) { return 'transparent'; } if ($error) { return colors.tagRedContentSecondary; } if ($isFocusVisible) { return colors.borderSelected; } return colors.contentTertiary; } function getLabelPadding(props) { const { $labelPlacement = '', $theme } = props; const { sizing } = $theme; const { scale100 } = sizing; let paddingDirection; switch ($labelPlacement) { case _constants.LABEL_PLACEMENT.left: paddingDirection = 'Right'; break; default: case _constants.LABEL_PLACEMENT.right: paddingDirection = 'Left'; break; } if ($theme.direction === 'rtl' && paddingDirection === 'Left') { paddingDirection = 'Right'; } else if ($theme.direction === 'rtl' && paddingDirection === 'Right') { paddingDirection = 'Left'; } return { [`padding${paddingDirection}`]: scale100 }; } function getBackgroundColor(props) { const { $disabled, $checked, $isIndeterminate, $error, $isHovered, $isActive, $theme } = props; const { colors } = $theme; if ($disabled) { return $checked || $isIndeterminate ? colors.contentStateDisabled : 'transparent'; } if ($checked || $isIndeterminate) { return $error ? colors.tagRedContentSecondary : colors.contentPrimary; } if ($isHovered) { return $error ? colors.hoverNegativeAlpha : colors.hoverOverlayAlpha; } if ($isActive) { return $error ? colors.pressedNegativeAlpha : colors.pressedOverlayAlpha; } return 'transparent'; } function getLabelColor(props) { const { $disabled, $theme } = props; const { colors } = $theme; return $disabled ? colors.contentStateDisabled : colors.contentPrimary; } const Root = exports.Root = (0, _styles.styled)('label', props => { const { $disabled, $theme } = props; const { sizing } = $theme; return { flexDirection: 'row', display: 'inline-flex', verticalAlign: 'middle', alignItems: 'flex-start', cursor: $disabled ? 'not-allowed' : 'pointer', userSelect: 'none', '@media (pointer: coarse)': { // Increase target size for touch devices to meet the minimum touch target size of 48x48dp padding: sizing.scale300 } }; }); Root.displayName = "Root"; Root.displayName = 'Root'; // Styled checkmark container as the state layer, backplate container const CheckmarkContainer = exports.CheckmarkContainer = (0, _styles.styled)('span', props => { const { $theme } = props; const { sizing } = $theme; const { hoveredColor, pressedColor } = (0, _getSharedStyles.getOverlayColor)(props); return { display: 'flex', alignItems: 'center', justifyContent: 'center', boxSizing: 'border-box', minHeight: sizing.scale900, minWidth: sizing.scale900, borderRadius: sizing.scale300, paddingTop: sizing.scale300, paddingBottom: sizing.scale300, paddingLeft: sizing.scale300, paddingRight: sizing.scale300, '@media (hover: hover)': { ':hover': { backgroundColor: hoveredColor } }, ':active': { backgroundColor: pressedColor } }; }); // @ts-ignore CheckmarkContainer.displayName = "CheckmarkContainer"; const Checkmark = exports.Checkmark = (0, _styles.styled)('span', props => { const { $checked, $isIndeterminate, $theme, $isFocusVisible, $isFocused } = props; const { sizing, animation } = $theme; const tickColor = $theme.colors.contentInversePrimary; const indeterminate = encodeURIComponent(` <svg width="17" height="17" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M18 10.5H6v3h12v-3Z" fill="${tickColor}"/> </svg> `); const check = encodeURIComponent(` <svg width="17" height="17" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="m10 17.34-4.56-4.56 2.12-2.12L10 13.1l6.44-6.44 2.12 2.12L10 17.34Z" fill="${tickColor}"/> </svg> `); const borderRadius = sizing.scale100; const borderColor = getBorderColor(props); return { flex: '0 0 auto', transitionDuration: animation.timing200, transitionTimingFunction: animation.easeOutCurve, transitionProperty: 'background-image, border-color, background-color', width: '17px', height: '17px', boxSizing: 'border-box', borderLeftStyle: 'solid', borderRightStyle: 'solid', borderTopStyle: 'solid', borderBottomStyle: 'solid', borderLeftWidth: sizing.scale0, borderRightWidth: sizing.scale0, borderTopWidth: sizing.scale0, borderBottomWidth: sizing.scale0, borderLeftColor: borderColor, borderRightColor: borderColor, borderTopColor: borderColor, borderBottomColor: borderColor, borderTopLeftRadius: borderRadius, borderTopRightRadius: borderRadius, borderBottomRightRadius: borderRadius, borderBottomLeftRadius: borderRadius, // Apply focus outline style if the checkbox is focused and focus is visible(focused by Tab) ...($isFocusVisible && $isFocused ? (0, _getSharedStyles.getFocusOutlineStyle)($theme) : {}), display: 'inline-block', verticalAlign: 'middle', backgroundImage: $isIndeterminate ? `url('data:image/svg+xml,${indeterminate}');` : $checked ? `url('data:image/svg+xml,${check}');` : null, backgroundColor: getBackgroundColor(props), backgroundRepeat: 'no-repeat', backgroundPosition: 'center' }; }); Checkmark.displayName = "Checkmark"; Checkmark.displayName = 'Checkmark'; const Label = exports.Label = (0, _styles.styled)('div', props => { const { $theme } = props; const { typography, sizing } = $theme; return { verticalAlign: 'middle', paddingTop: sizing.scale200, // top padding to make checkbox aligned with first row of the label ...getLabelPadding(props), color: getLabelColor(props), ...typography.ParagraphSmall }; }); Label.displayName = "Label"; Label.displayName = 'Label'; // tricky style for focus event cause display: none doesn't work const Input = exports.Input = (0, _styles.styled)('input', { opacity: 0, width: 0, height: 0, overflow: 'hidden', margin: 0, padding: 0, position: 'absolute' }); Input.displayName = "Input"; Input.displayName = 'Input';