@pmndrs/uikit-horizon
Version:
Horizon kit for @pmndrs/uikit based on the Reality Labs Design System (RLDS)
97 lines (96 loc) • 3.75 kB
JavaScript
import { abortableEffect, Container, Text, } from '@pmndrs/uikit';
import { computed } from '@preact/signals-core';
import { theme } from '../theme.js';
const _badgeVariants = {
primary: {
backgroundColor: theme.component.badges.primary.background,
color: theme.component.badges.primary.label,
},
secondary: {
backgroundColor: theme.component.badges.secondary.background,
color: theme.component.badges.secondary.label,
},
positive: {
backgroundColor: theme.component.badges.positive.background,
color: theme.component.badges.positive.label,
},
negative: {
backgroundColor: theme.component.badges.background.background,
color: theme.component.badges.background.label,
},
};
const badgeVariants = _badgeVariants;
export class Badge extends Container {
label;
iconPlaceholder;
icon;
constructor(inputProperties, initialClasses, config) {
const width = computed(() => {
if (this.properties.value.icon != null) {
return undefined;
}
const length = this.properties.value.label?.length ?? 0;
if (length === 0) {
return 12;
}
if (length === 1) {
return 24;
}
return undefined;
});
super(inputProperties, initialClasses, {
...config,
defaultOverrides: {
borderRadius: computed(() => (this.properties.value.label?.length ?? 0) > 1 || this.properties.value.icon != null ? 8 : 1000),
color: computed(() => badgeVariants[this.properties.value.variant ?? 'primary'].color?.value),
backgroundColor: computed(() => badgeVariants[this.properties.value.variant ?? 'primary'].backgroundColor?.value),
paddingX: computed(() => (this.properties.value.label?.length ?? 0) > 1 || this.properties.value.icon != null ? 8 : undefined),
paddingY: computed(() => (this.properties.value.label?.length ?? 0) > 1 || this.properties.value.icon != null ? 4 : undefined),
width: width,
height: width,
fontSize: 12,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: 4,
lineHeight: '16px',
fontWeight: 700,
...config?.defaultOverrides,
},
});
this.iconPlaceholder = new Container(undefined, undefined, {
defaultOverrides: { display: computed(() => (this.properties.value.icon == null ? 'none' : 'flex')) },
});
super.add(this.iconPlaceholder);
this.label = new Text(undefined, undefined, {
defaultOverrides: {
text: this.properties.signal.label,
display: computed(() => ((this.properties.value.label?.length ?? 0) === 0 ? 'none' : 'flex')),
},
});
super.add(this.label);
abortableEffect(() => {
const Icon = this.properties.value.icon;
if (Icon == null) {
return;
}
const icon = new Icon(undefined, undefined, {
defaultOverrides: { width: 16, height: 16 },
});
this.iconPlaceholder.add(icon);
this.icon = icon;
return () => {
this.icon = undefined;
icon.dispose();
};
}, this.abortSignal);
}
dispose() {
this.icon?.dispose();
this.label.dispose();
super.dispose();
}
add() {
throw new Error(`the Badge component can not have any children`);
}
}