SegmentedControl: add size prop (default/small)

This commit is contained in:
Justin Edmund 2025-12-01 09:54:06 -08:00
parent 7a57680ec1
commit 395a5c166f
3 changed files with 25 additions and 3 deletions

View file

@ -6,7 +6,7 @@
import { getContext } from 'svelte' import { getContext } from 'svelte'
import type { Snippet } from 'svelte' import type { Snippet } from 'svelte'
import styles from './segment.module.scss' import styles from './segment.module.scss'
import type { SegmentedControlVariant } from './SegmentedControl.svelte' import type { SegmentedControlVariant, SegmentedControlSize } from './SegmentedControl.svelte'
interface Props { interface Props {
value: string value: string
@ -17,8 +17,9 @@
let { value, class: className, disabled, children: content }: Props = $props() let { value, class: className, disabled, children: content }: Props = $props()
// Get variant from parent context // Get variant and size from parent context
const variant = getContext<SegmentedControlVariant>('segmented-control-variant') || 'default' const variant = getContext<SegmentedControlVariant>('segmented-control-variant') || 'default'
const size = getContext<SegmentedControlSize>('segmented-control-size') || 'default'
// Apply variant-specific classes // Apply variant-specific classes
const variantClasses = { const variantClasses = {
@ -27,10 +28,17 @@
background: styles.background background: styles.background
} }
// Apply size-specific classes
const sizeClasses = {
default: '',
small: styles.small
}
const segmentClass = $derived( const segmentClass = $derived(
[ [
styles.segment, styles.segment,
variantClasses[variant], variantClasses[variant],
sizeClasses[size],
className || '' className || ''
] ]
.filter(Boolean) .filter(Boolean)

View file

@ -9,11 +9,13 @@
import type { HTMLAttributes } from 'svelte/elements' import type { HTMLAttributes } from 'svelte/elements'
export type SegmentedControlVariant = 'default' | 'blended' | 'background' export type SegmentedControlVariant = 'default' | 'blended' | 'background'
export type SegmentedControlSize = 'default' | 'small'
interface Props extends HTMLAttributes<HTMLDivElement> { interface Props extends HTMLAttributes<HTMLDivElement> {
value?: string value?: string
onValueChange?: (value: string) => void onValueChange?: (value: string) => void
variant?: SegmentedControlVariant variant?: SegmentedControlVariant
size?: SegmentedControlSize
element?: 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light' | null element?: 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light' | null
grow?: boolean grow?: boolean
gap?: boolean gap?: boolean
@ -26,6 +28,7 @@
value = $bindable(), value = $bindable(),
onValueChange, onValueChange,
variant = 'default', variant = 'default',
size = 'default',
element = null, element = null,
grow = false, grow = false,
gap = false, gap = false,
@ -34,8 +37,9 @@
children children
}: Props = $props() }: Props = $props()
// Provide variant to child segments via context // Provide variant and size to child segments via context
setContext('segmented-control-variant', variant) setContext('segmented-control-variant', variant)
setContext('segmented-control-size', size)
// Track previous value to only fire callback on actual changes (not initialization) // Track previous value to only fire callback on actual changes (not initialization)
let previousValue = $state<string | undefined>(undefined) let previousValue = $state<string | undefined>(undefined)

View file

@ -29,6 +29,16 @@
} }
} }
// Small size variant
.small {
font-size: typography.$font-small;
min-width: 80px;
.label {
padding: spacing.$unit spacing.$unit-2x;
}
}
.label { .label {
border: 0.5px solid transparent; border: 0.5px solid transparent;
border-radius: layout.$full-corner; border-radius: layout.$full-corner;