-
{group.name}
+
+ {group.name}
+
{group.tags.join(', ')}
diff --git a/src/lib/client/ui/form/Autocomplete.svelte b/src/lib/client/ui/form/Autocomplete.svelte
index 4117aaa..4719858 100644
--- a/src/lib/client/ui/form/Autocomplete.svelte
+++ b/src/lib/client/ui/form/Autocomplete.svelte
@@ -141,7 +141,9 @@
on:blur={handleBlur}
on:keydown={handleKeydown}
{placeholder}
- class="min-w-[120px] flex-1 border-0 bg-transparent text-sm text-neutral-900 outline-none placeholder:text-neutral-400 focus:ring-0 dark:text-neutral-100 dark:placeholder:text-neutral-500 {mono ? 'font-mono' : ''}"
+ class="min-w-[120px] flex-1 border-0 bg-transparent text-sm text-neutral-900 outline-none placeholder:text-neutral-400 focus:ring-0 dark:text-neutral-100 dark:placeholder:text-neutral-500 {mono
+ ? 'font-mono'
+ : ''}"
/>
{/if}
@@ -156,7 +158,9 @@
type="button"
on:mousedown|preventDefault={() => selectOption(option)}
on:mouseenter={() => (highlightedIndex = index)}
- class="w-full px-3 py-2 text-left text-sm transition-colors {mono ? 'font-mono' : ''} {highlightedIndex === index
+ class="w-full px-3 py-2 text-left text-sm transition-colors {mono
+ ? 'font-mono'
+ : ''} {highlightedIndex === index
? 'bg-accent-100 text-accent-900 dark:bg-accent-900/30 dark:text-accent-100'
: 'text-neutral-900 hover:bg-neutral-100 dark:text-neutral-100 dark:hover:bg-neutral-700'}"
>
diff --git a/src/lib/client/ui/form/FormInput.svelte b/src/lib/client/ui/form/FormInput.svelte
index 9cd256d..02336d7 100644
--- a/src/lib/client/ui/form/FormInput.svelte
+++ b/src/lib/client/ui/form/FormInput.svelte
@@ -4,6 +4,8 @@
export let placeholder: string = '';
export let value: string = '';
export let textarea: boolean = false;
+ export let type: 'text' | 'number' | 'email' | 'password' | 'url' = 'text';
+ export let required: boolean = false;
@@ -26,9 +28,10 @@
>
{:else}
{/if}
diff --git a/src/lib/client/ui/form/IconCheckbox.svelte b/src/lib/client/ui/form/IconCheckbox.svelte
index dde175c..d7f6c8c 100644
--- a/src/lib/client/ui/form/IconCheckbox.svelte
+++ b/src/lib/client/ui/form/IconCheckbox.svelte
@@ -6,6 +6,7 @@
export let color: string = 'accent'; // accent, blue, green, red, or hex color like #FFC230
export let shape: 'square' | 'circle' | 'rounded' = 'rounded';
export let disabled: boolean = false;
+ export let onclick: ((e: MouseEvent) => void) | undefined = undefined;
// Shape classes
const shapeClasses: Record
= {
@@ -25,12 +26,12 @@
role="checkbox"
aria-checked={checked}
{disabled}
- on:click
+ {onclick}
class="flex h-5 w-5 items-center justify-center border-2 transition-all {shapeClass} {disabled
? 'cursor-not-allowed opacity-50'
: 'cursor-pointer focus:outline-none'} {checked
? 'hover:brightness-110'
- : 'bg-neutral-50 hover:bg-neutral-100 hover:border-neutral-400 dark:bg-neutral-800 dark:hover:bg-neutral-700 dark:hover:border-neutral-500'}"
+ : 'bg-neutral-50 hover:border-neutral-400 hover:bg-neutral-100 dark:bg-neutral-800 dark:hover:border-neutral-500 dark:hover:bg-neutral-700'}"
style="background-color: {checked ? color : ''}; border-color: {checked
? color
: 'rgb(229, 231, 235)'};"
@@ -45,10 +46,10 @@
role="checkbox"
aria-checked={checked}
{disabled}
- on:click
+ {onclick}
class="flex h-5 w-5 items-center justify-center border-2 transition-all {shapeClass} {checked
- ? 'bg-accent-600 border-accent-600 dark:bg-accent-500 dark:border-accent-500 hover:brightness-110'
- : 'bg-neutral-50 border-neutral-300 hover:bg-neutral-100 hover:border-neutral-400 dark:bg-neutral-800 dark:border-neutral-700 dark:hover:bg-neutral-700 dark:hover:border-neutral-500'} {disabled
+ ? 'border-accent-600 bg-accent-600 hover:brightness-110 dark:border-accent-500 dark:bg-accent-500'
+ : 'border-neutral-300 bg-neutral-50 hover:border-neutral-400 hover:bg-neutral-100 dark:border-neutral-700 dark:bg-neutral-800 dark:hover:border-neutral-500 dark:hover:bg-neutral-700'} {disabled
? 'cursor-not-allowed opacity-50'
: 'cursor-pointer focus:outline-none'}"
>
@@ -62,10 +63,10 @@
role="checkbox"
aria-checked={checked}
{disabled}
- on:click
+ {onclick}
class="flex h-5 w-5 items-center justify-center border-2 transition-all {shapeClass} {checked
- ? 'bg-green-600 border-green-600 dark:bg-green-500 dark:border-green-500 hover:brightness-110'
- : 'bg-neutral-50 border-neutral-300 hover:bg-neutral-100 hover:border-neutral-400 dark:bg-neutral-800 dark:border-neutral-700 dark:hover:bg-neutral-700 dark:hover:border-neutral-500'} {disabled
+ ? 'border-green-600 bg-green-600 hover:brightness-110 dark:border-green-500 dark:bg-green-500'
+ : 'border-neutral-300 bg-neutral-50 hover:border-neutral-400 hover:bg-neutral-100 dark:border-neutral-700 dark:bg-neutral-800 dark:hover:border-neutral-500 dark:hover:bg-neutral-700'} {disabled
? 'cursor-not-allowed opacity-50'
: 'cursor-pointer focus:outline-none'}"
>
@@ -79,10 +80,10 @@
role="checkbox"
aria-checked={checked}
{disabled}
- on:click
+ {onclick}
class="flex h-5 w-5 items-center justify-center border-2 transition-all {shapeClass} {checked
- ? 'bg-red-600 border-red-600 dark:bg-red-500 dark:border-red-500 hover:brightness-110'
- : 'bg-neutral-50 border-neutral-300 hover:bg-neutral-100 hover:border-neutral-400 dark:bg-neutral-800 dark:border-neutral-700 dark:hover:bg-neutral-700 dark:hover:border-neutral-500'} {disabled
+ ? 'border-red-600 bg-red-600 hover:brightness-110 dark:border-red-500 dark:bg-red-500'
+ : 'border-neutral-300 bg-neutral-50 hover:border-neutral-400 hover:bg-neutral-100 dark:border-neutral-700 dark:bg-neutral-800 dark:hover:border-neutral-500 dark:hover:bg-neutral-700'} {disabled
? 'cursor-not-allowed opacity-50'
: 'cursor-pointer focus:outline-none'}"
>
@@ -96,10 +97,10 @@
role="checkbox"
aria-checked={checked}
{disabled}
- on:click
+ {onclick}
class="flex h-5 w-5 items-center justify-center border-2 transition-all {shapeClass} {checked
- ? 'bg-blue-600 border-blue-600 dark:bg-blue-500 dark:border-blue-500 hover:brightness-110'
- : 'bg-neutral-50 border-neutral-300 hover:bg-neutral-100 hover:border-neutral-400 dark:bg-neutral-800 dark:border-neutral-700 dark:hover:bg-neutral-700 dark:hover:border-neutral-500'} {disabled
+ ? 'border-blue-600 bg-blue-600 hover:brightness-110 dark:border-blue-500 dark:bg-blue-500'
+ : 'border-neutral-300 bg-neutral-50 hover:border-neutral-400 hover:bg-neutral-100 dark:border-neutral-700 dark:bg-neutral-800 dark:hover:border-neutral-500 dark:hover:bg-neutral-700'} {disabled
? 'cursor-not-allowed opacity-50'
: 'cursor-pointer focus:outline-none'}"
>
@@ -114,10 +115,10 @@
role="checkbox"
aria-checked={checked}
{disabled}
- on:click
+ {onclick}
class="flex h-5 w-5 items-center justify-center border-2 transition-all {shapeClass} {checked
- ? 'bg-accent-600 border-accent-600 dark:bg-accent-500 dark:border-accent-500 hover:brightness-110'
- : 'bg-neutral-50 border-neutral-300 hover:bg-neutral-100 hover:border-neutral-400 dark:bg-neutral-800 dark:border-neutral-700 dark:hover:bg-neutral-700 dark:hover:border-neutral-500'} {disabled
+ ? 'border-accent-600 bg-accent-600 hover:brightness-110 dark:border-accent-500 dark:bg-accent-500'
+ : 'border-neutral-300 bg-neutral-50 hover:border-neutral-400 hover:bg-neutral-100 dark:border-neutral-700 dark:bg-neutral-800 dark:hover:border-neutral-500 dark:hover:bg-neutral-700'} {disabled
? 'cursor-not-allowed opacity-50'
: 'cursor-pointer focus:outline-none'}"
>
diff --git a/src/lib/client/ui/form/Input.svelte b/src/lib/client/ui/form/Input.svelte
index e6c73b9..a3eb1e5 100644
--- a/src/lib/client/ui/form/Input.svelte
+++ b/src/lib/client/ui/form/Input.svelte
@@ -11,5 +11,7 @@
bind:value
{placeholder}
{disabled}
- class="{width} rounded-lg border border-neutral-300 bg-white px-2.5 py-1.5 text-sm text-neutral-900 placeholder:text-neutral-400 focus:outline-none dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-100 dark:placeholder:text-neutral-500 {disabled ? 'cursor-not-allowed opacity-50' : ''}"
+ class="{width} rounded-lg border border-neutral-300 bg-white px-2.5 py-1.5 text-sm text-neutral-900 placeholder:text-neutral-400 focus:outline-none dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-100 dark:placeholder:text-neutral-500 {disabled
+ ? 'cursor-not-allowed opacity-50'
+ : ''}"
/>
diff --git a/src/lib/client/ui/form/KeyValueList.svelte b/src/lib/client/ui/form/KeyValueList.svelte
index b8ff637..2b0013b 100644
--- a/src/lib/client/ui/form/KeyValueList.svelte
+++ b/src/lib/client/ui/form/KeyValueList.svelte
@@ -10,7 +10,8 @@
export let keyPlaceholder: string = 'Enter key';
export let valuePlaceholder: string = 'Enter value';
export let onchange: ((value: Record) => void) | undefined = undefined;
- export let lockedFirst: { key: string; value?: string; minMajor?: number } | undefined = undefined;
+ export let lockedFirst: { key: string; value?: string; minMajor?: number } | undefined =
+ undefined;
export let onLockedDeleteAttempt: (() => void) | undefined = undefined;
export let onLockedEditAttempt: (() => void) | undefined = undefined;
export let onLockedVersionMinBlocked: (() => void) | undefined = undefined;
@@ -88,8 +89,15 @@
// Sync when value changes externally (but preserve entries with empty keys being edited)
$: {
const externalEntries = Object.entries(value);
- const currentFilledKeys = entries.filter((e) => e.key.trim()).map((e) => e.key).sort().join(',');
- const externalKeys = externalEntries.map(([k]) => k).sort().join(',');
+ const currentFilledKeys = entries
+ .filter((e) => e.key.trim())
+ .map((e) => e.key)
+ .sort()
+ .join(',');
+ const externalKeys = externalEntries
+ .map(([k]) => k)
+ .sort()
+ .join(',');
if (currentFilledKeys !== externalKeys) {
const emptyKeyEntries = entries.filter((e) => !e.key.trim());
@@ -108,9 +116,9 @@
{#if label}
-
+
{/if}
{#if description}
@@ -122,7 +130,9 @@
{#if entries.length > 0}
-
+
{keyLabel}
{valueLabel}
@@ -153,7 +163,9 @@
updateValue(index, updateVersionPart(entry.value, 0, v))}
onMinBlocked={isLocked ? onLockedVersionMinBlocked : undefined}
@@ -191,7 +203,7 @@
{/if}