baseui
Version:
A React Component library implementing the Base design language
263 lines (257 loc) ⢠7.07 kB
JavaScript
"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';