UNPKG

@pmndrs/uikit-horizon

Version:

Horizon kit for @pmndrs/uikit based on the Reality Labs Design System (RLDS)

78 lines (77 loc) 3.54 kB
import { Container, } from '@pmndrs/uikit'; import { computed, signal } from '@preact/signals-core'; import { theme } from '../theme.js'; const _dropdownSizes = { lg: { paddingX: 20, paddingY: 12, fontSize: 14, lineHeight: '20px', }, sm: { paddingX: 16, paddingY: 8, fontSize: 12, lineHeight: '16px', }, }; const dropdownSizes = _dropdownSizes; export class Dropdown extends Container { uncontrolledSignal = signal(undefined); currentSignal = computed(() => this.properties.value.value ?? this.uncontrolledSignal.value ?? this.properties.value.defaultValue); uncontrolledOpenSignal = signal(undefined); currentOpenSignal = computed(() => this.properties.value.open ?? this.uncontrolledOpenSignal.value ?? this.properties.value.defaultOpen ?? false); constructor(inputProperties, initialClasses, config) { super(inputProperties, initialClasses, { ...config, defaultOverrides: { positionType: 'relative', cursor: 'pointer', borderRadius: 1000, fontSize: computed(() => dropdownSizes[this.properties.value.size ?? 'lg'].fontSize), lineHeight: computed(() => dropdownSizes[this.properties.value.size ?? 'lg'].lineHeight), paddingX: computed(() => dropdownSizes[this.properties.value.size ?? 'lg'].paddingX), paddingY: computed(() => dropdownSizes[this.properties.value.size ?? 'lg'].paddingY), fontWeight: 500, backgroundColor: theme.component.selectionDropdown.background.fill.default, color: theme.component.selectionDropdown.label.default, hover: { backgroundColor: theme.component.selectionDropdown.background.fill.hovered, color: theme.component.selectionDropdown.label.hovered, }, active: { backgroundColor: theme.component.selectionDropdown.background.fill.pressed, color: theme.component.selectionDropdown.label.pressed, }, important: { backgroundColor: computed(() => this.currentSignal.value == null ? this.currentOpenSignal.value ? theme.component.selectionDropdown.background.fill.hovered.value : undefined : theme.component.selectionDropdown.background.fill.selected.value), color: computed(() => this.currentSignal.value == null ? this.currentOpenSignal.value ? theme.component.selectionDropdown.label.hovered.value : undefined : theme.component.selectionDropdown.label.selected.value), }, flexDirection: 'row', alignItems: 'center', gap: 8, ...config?.defaultOverrides, }, }); this.addEventListener('click', (e) => { e.stopPropagation?.(); const newOpen = !this.currentOpenSignal.value; this.uncontrolledOpenSignal.value = newOpen; this.properties.peek().onOpenChange?.(newOpen); }); } } export * from './button.js'; export * from './icon.js'; export * from './avatar.js'; export * from './list.js'; export * from './list-item.js'; export * from './text-value.js';