Files

87 lines
2.3 KiB
Plaintext

---
// Renders a <select id="select-{id}"> from explicit options and its TomSelect
// init script. For the selects.json/people-fed demo variant see
// @shared/components/demo/DataSelect.astro.
import CaptureScript from '../components/CaptureScript.astro';
import type { FormValidationState } from '@shared/lib/tokens';
export type SelectOption = { value: string; text: string; custom?: string | undefined; selected?: boolean };
export type SelectOptgroup = { label: string; options: SelectOption[] };
interface Props {
id: string;
class?: string | undefined;
state?: FormValidationState | undefined;
placeholder?: string | undefined;
multiple?: boolean | undefined;
options?: SelectOption[];
optgroups?: SelectOptgroup[];
}
const { id, class: className, state, placeholder, multiple, options = [], optgroups = [] } = Astro.props;
const selectClass = [
'form-select',
className,
state && `is-${state}`,
]
const selectId = `select-${id}`;
---
<select
class:list={selectClass}
data-placeholder={placeholder}
id={selectId}
multiple={multiple ? '' : undefined}
>
{
optgroups.map((group) => (
<optgroup label={group.label}>
{group.options.map((option) => (
<option value={option.value} selected={option.selected || undefined}>{option.text}</option>
))}
</optgroup>
))
}
{
options.map((option) => (
<option
value={option.value}
data-custom-properties={option.custom}
selected={option.selected || undefined}
>
{option.text}
</option>
))
}
</select>
<CaptureScript>
<!-- BEGIN SELECT -->
<script is:inline define:vars={{ selectId }}>
function initSelect() {
window.tabler_select ??= {};
const renderOption = (data, escape) => {
if (data.customProperties) {
return `<div class="dropdown-item"><span class="dropdown-item-indicator">${data.customProperties}</span>${escape(data.text)}</div>`;
}
return `<div>${escape(data.text)}</div>`;
};
window.TomSelect &&
(window.tabler_select[selectId] = new TomSelect(document.getElementById(selectId), {
copyClassesToDropdown: false,
dropdownParent: 'body',
render: {
item: renderOption,
option: renderOption,
},
}));
}
document.readyState !== 'loading' ? initSelect() : document.addEventListener('DOMContentLoaded', initSelect, { once: true });
</script>
<!-- END SELECT -->
</CaptureScript>