Updating mechanics for OS protocols
Validate and deploy production / validate (push) Canceled after 0s
Validate and deploy production / deploy (push) Canceled after 0s
Validate and deploy staging / validate (push) Successful in 33s
Validate and deploy staging / deploy (push) Successful in 1m9s

This commit is contained in:
jb
2026-08-03 16:12:20 -04:00
parent 57068b61cd
commit 7ca6cb8458
27 changed files with 1272 additions and 280 deletions
+24 -15
View File
@@ -24,6 +24,8 @@
} = $props();
let query = $state('');
let open = $state(false);
const selected = $derived(items.find((item) => item.id === value));
const visible = $derived(items.filter((item) =>
!query.trim() || `${item.name} ${item.category ?? ''}`.toLocaleLowerCase().includes(query.trim().toLocaleLowerCase())
));
@@ -31,26 +33,33 @@
function choose(id: string) {
value = id;
onchange?.(id);
if (searchable) {
open = false;
query = '';
}
}
</script>
<fieldset class="builder-radio-grid" class:icon-only={iconOnly} style={`--builder-radio-columns:${Math.max(1, columns)}`}>
<legend>{label}</legend>
{#if searchable}
{#if searchable}<button type="button" class="builder-radio-toggle" aria-expanded={open} onclick={() => open = !open}><ItemIcon src={selected?.iconUrl} alt=""/><span><b>{selected?.name ?? 'SELECT OPTION'}</b><small>{selected?.category ?? 'NOT CONFIGURED'}</small></span><em>{open ? 'CLOSE' : 'CHANGE'}</em></button>{/if}
{#if searchable && open}
<input class="builder-radio-search" type="search" bind:value={query} placeholder="SEARCH AVAILABLE OPTIONS" aria-label={`Search ${label.toLocaleLowerCase()}`}/>
{/if}
<div>
{#each visible as item}
<label title={item.name}>
<input type="radio" {name} value={item.id} checked={value === item.id} {required} aria-label={item.name} onchange={() => choose(item.id)}/>
<span>
<ItemIcon src={item.iconUrl} alt=""/>
<b>{item.name}</b>
{#if item.category}<small>{item.category}</small>{/if}
</span>
</label>
{:else}
<p>NO MATCHING OPTIONS</p>
{/each}
</div>
{#if !searchable || open}
<div>
{#each visible as item}
<label title={item.name}>
<input type="radio" {name} value={item.id} checked={value === item.id} {required} aria-label={item.name} onchange={() => choose(item.id)}/>
<span>
<ItemIcon src={item.iconUrl} alt=""/>
<b>{item.name}</b>
{#if item.category}<small>{item.category}</small>{/if}
</span>
</label>
{:else}
<p>NO MATCHING OPTIONS</p>
{/each}
</div>
{/if}
</fieldset>