@navinc/base-react-components
Version:
Nav's Pattern Library
120 lines (112 loc) • 5.57 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { styled, useTheme } from 'styled-components';
import { Icon } from './icon.js';
const getChannelFill = (checked, color, theme, disabled) => {
if (disabled)
return theme.onSurfaceDim;
if (color && checked)
return color;
return checked ? theme.primary : theme.outlineVariant;
};
const getIndicatorColor = (theme, checked, disabled) => {
if (disabled)
return theme.surfaceDim;
return checked ? theme.onPrimary : theme.surfaceContainer;
};
const getStrokeColor = (color, theme, disabled) => {
if (disabled)
return theme.onSurfaceDim;
if (color)
return color;
return theme.primary;
};
const ToggleChannel = styled.label.withConfig({ displayName: "brc-sc-ToggleChannel", componentId: "brc-sc-u6k98x" }) `
position: relative;
display: inline-block;
border-radius: 100px;
line-height: 1;
height: 24px;
width: 40px;
text-align: justify;
background: ${({ checked, color, theme, disabled }) => getChannelFill(checked, color, theme, disabled)};
&:focus-within {
outline: 0;
/* Adding transparency to the color value. See https://gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 for values */
box-shadow: 0 0 0 2px ${({ theme, color }) => `${color || theme.primary}4D`};
}
> svg {
position: absolute;
top: 50%;
width: 30%;
fill: ${({ checked, color, theme, disabled }) => getChannelFill(checked, color, theme, disabled)};
left: ${({ checked }) => (checked ? 'calc(100% - 12px)' : '12px')};
transform: translate(-50%, -50%);
transition: left 0.2s ease-in-out;
z-index: 1;
visibility: ${({ checked }) => (checked ? 'visible' : 'hidden')};
}
`;
const ToggleIndicator = styled.input.attrs(() => ({ type: 'checkbox' })).withConfig({ displayName: "brc-sc-ToggleIndicator", componentId: "brc-sc-jgumja" }) `
position: absolute;
box-sizing: border-box;
border: 2px solid ${({ checked, color, theme, disabled }) => getChannelFill(checked, color, theme, disabled)};
border-radius: 50%;
background: ${({ theme, checked, disabled }) => getIndicatorColor(theme, checked, disabled)};
height: 24px;
width: 24px;
transition: transform 0.2s ease-in-out;
transform: translateX(${({ checked }) => (checked ? '16px' : '0')});
appearance: none;
margin: 0;
font-size: inherit;
z-index: 0; /* make sure the checkbox is below the icon */
&:focus {
outline: 0;
box-shadow: none;
}
`;
const StyledToggleContainer = styled.div.withConfig({ displayName: "brc-sc-StyledToggleContainer", componentId: "brc-sc-uilbt2" }) `
display: flex;
align-items: center;
flex-direction: ${({ $labelPosition }) => ($labelPosition === 'left' ? 'row-reverse' : 'row')};
justify-content: flex-start;
width: fit-content;
margin: ${({ $togglePosition }) => ($togglePosition === 'right' ? 'auto 0 auto auto' : 'auto auto auto 0')};
`;
const StyledLabelCopyContainer = styled.span.withConfig({ displayName: "brc-sc-StyledLabelCopyContainer", componentId: "brc-sc-mdy3c5" }) `
padding: ${({ $labelPosition }) => ($labelPosition === 'left' ? '0 12px 0 0' : '0 0 0 12px')};
`;
const UnstyledToggle = (_a) => {
var { checked, disabled, color, icon, labelPosition, label, togglePosition } = _a, props = __rest(_a, ["checked", "disabled", "color", "icon", "labelPosition", "label", "togglePosition"]);
const theme = useTheme();
return (_jsxs(StyledToggleContainer, { "$labelPosition": labelPosition, "$togglePosition": togglePosition, children: [
// eslint-disable-next-line styled-components-a11y/label-has-associated-control -- this doesn't like the fact there are two components in here
_jsxs(ToggleChannel, { "data-testid": "toggle-channel", checked, disabled, color, children: [_jsx(Icon, { name: icon !== null && icon !== void 0 ? icon : 'actions/done', stroke: getStrokeColor(color, theme, disabled) }), _jsx(ToggleIndicator, Object.assign({ checked, disabled, color }, props))] }), label && (_jsx(StyledLabelCopyContainer, { className: "body2", "$labelPosition": labelPosition, children: label }))] }));
};
/**
* @deprecated use the wayfinder toggle from @navinc/base-react-components/wayfinder instead
# Toggle
Displays a toggle switch using an html checkbox.
### Props
Optional
- **checked** (boolean): The checked state of the toggle.
- **disabled** (boolean): Prevent modifying current checked state of toggle.
- **color** (string): Custom color of toggle background when in the 'enabled' state. Defaults to theme color if not provided.
- **icon** (Icon): Icon name to display in the toggle.
- **labelPosition** ('left' | 'right'): Put the text on the left or right of the toggle button.
- **togglePosition** ('left' | 'right'): Put the toggle on the left or right of containing div.
- **label** (string): Text to display on the left or right of the toggle.
**/
export const Toggle = styled(UnstyledToggle).withConfig({ displayName: "brc-sc-Toggle", componentId: "brc-sc-13t4wvc" }) ``;
//# sourceMappingURL=toggle.js.map