@patreon/studio
Version:
Patreon Studio Design System
71 lines (69 loc) • 2.98 kB
JSX
/**
* @author @Patreon/fe-core
**/
'use client';
import React from 'react';
import styled from 'styled-components';
import { tokens } from '../../tokens';
import { mediaForBreakpoint } from '../../utilities/breakpoints';
import { cssForBodyText } from '../../utilities/type-bundles';
import { getDimensions } from '../Button/theme';
import { Spacer } from '../Spacer';
export const SegmentedControl = ({ segments, fluidWidth = false, onClick, selectedIndex, size = 'md', }) => {
const onSelected = (index, segment) => {
onClick(index);
if (segment.onSelect) {
segment.onSelect();
}
};
const createSegment = (segment, index) => {
const isSelected = selectedIndex === index;
const SegmentIcon = 'icon' in segment ? segment.icon : undefined;
const segmentLabel = 'label' in segment ? segment.label : undefined;
return (<SegmentButton isSelected={isSelected} fluidWidth={fluidWidth} onClick={() => onSelected(index, segment)} data-tag={`segment-${index}`} key={`segment-${index}`} aria-current={isSelected} aria-label={segment['aria-label']} size={size}>
{SegmentIcon && <SegmentIcon size="20px"/>}
{segmentLabel && <Spacer ml={SegmentIcon && tokens.global.space.x8}>{segmentLabel}</Spacer>}
</SegmentButton>);
};
return (<SegmentContainer size={size} fluidWidth={fluidWidth} segmentCount={segments.length} role="row">
{segments.map((segment, index) => createSegment(segment, index))}
</SegmentContainer>);
};
const SegmentContainer = styled.div `
display: ${({ fluidWidth }) => (fluidWidth ? 'grid' : 'inline-grid')};
grid-template-columns: repeat(${({ segmentCount }) => segmentCount}, 1fr);
box-sizing: border-box;
height: ${({ size }) => getDimensions({ size, isMobile: true })};
border-radius: ${tokens.global.radius.md};
background-color: ${tokens.global.primary.muted.default};
border: ${tokens.global.borderWidth.thin} solid transparent;
@media ${mediaForBreakpoint('sm')} {
height: ${({ size }) => getDimensions({ size, isMobile: false })};
}
`;
function getButtonPadding(size) {
switch (size) {
case 'sm':
return tokens.global.space.x12;
case 'lg':
return tokens.global.space.x24;
case 'md':
default:
return tokens.global.space.x16;
}
}
const SegmentButton = styled.button `
background-color: ${({ isSelected }) => (isSelected ? tokens.global.bg.base.default : 'transparent')};
flex-direction: row;
display: flex;
justify-content: center;
align-items: center;
transition: background-color 0.3s ease;
padding: ${tokens.global.space.x4} ${({ size }) => getButtonPadding(size)};
border: none;
border-radius: calc(${tokens.global.radius.md} - ${tokens.global.borderWidth.thin});
color: ${tokens.global.content.regular.default};
white-space: nowrap;
${cssForBodyText({ size: 'md', weight: 'bold' })};
`;
//# sourceMappingURL=index.jsx.map