@pmndrs/uikit-horizon
Version:
Horizon kit for @pmndrs/uikit based on the Reality Labs Design System (RLDS)
78 lines (77 loc) • 3.54 kB
JavaScript
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';