rewrite website

This commit is contained in:
2025-10-13 17:22:49 +02:00
parent a6d910f56a
commit 32f28e5324
263 changed files with 17904 additions and 14451 deletions

View File

@@ -0,0 +1,49 @@
<script lang="ts">
interface Props {
available: Record<number, string>;
value: number;
readonly?: boolean;
}
// inputs
let { available, value = $bindable(), readonly }: Props = $props();
// callbacks
function onOptionSelect(e: Event) {
const selected = Number((e.target as HTMLSelectElement).value);
value |= selected;
(e.target as HTMLSelectElement).value = '-';
}
function onBadgeRemove(flag: number) {
value &= ~flag;
}
</script>
<div class="flex flex-col gap-4">
{#if !readonly}
<select class="select select-xs w-min" onchange={onOptionSelect}>
<option selected hidden>-</option>
{#each Object.entries(available) as [flag, badge] (flag)}
<option value={flag} hidden={(value & Number(flag)) !== 0}>{badge}</option>
{/each}
</select>
{/if}
<div class="flex flow flex-wrap gap-2">
{#key value}
{#each Object.entries(available) as [flag, badge] (flag)}
{#if (value & Number(flag)) !== 0}
<div class="badge badge-outline gap-1">
{#if !readonly}
<button class="cursor-pointer" type="button" onclick={() => onBadgeRemove(Number(flag))}>✕</button>
{/if}
<span>{badge}</span>
</div>
{/if}
{/each}
{/key}
</div>
</div>

View File

@@ -0,0 +1,51 @@
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
id?: string;
checked?: boolean | null;
required?: boolean;
validation?: {
hint: string;
};
disabled?: boolean;
label?: Snippet | string;
notice?: Snippet;
}
let { id, checked = $bindable(), required, validation, disabled, label, notice }: Props = $props();
</script>
<fieldset class="fieldset">
<div class="flex items-center">
<input
{id}
name={id}
bind:checked
type="checkbox"
class="checkbox"
class:validator={required || validation}
required={required ? true : null}
disabled={disabled ? true : null}
/>
<span class="ml-1">
{#if typeof label === 'string'}
<span>{label}</span>
{:else if label}
{@render label()}
{/if}
{#if required}
<span class="text-red-700">*</span>
{/if}
</span>
</div>
<p class="fieldset-label">
{#if notice}
{@render notice()}
{/if}
</p>
{#if validation}
<p class="validator-hint mt-0">{validation.hint}</p>
{/if}
</fieldset>

View File

@@ -0,0 +1,75 @@
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
id?: string;
type?: 'color' | 'date' | 'datetime-local' | 'number' | 'tel' | 'text' | 'email';
value?: string | null;
label?: string;
required?: boolean;
validation?: {
min?: string;
max?: string;
pattern?: string;
hint: string;
};
hidden?: boolean;
readonly?: boolean;
disabled?: boolean;
size?: 'sm';
dynamicWidth?: boolean;
notice?: Snippet;
}
let {
id,
type,
value = $bindable(),
label,
required,
validation,
hidden,
readonly,
disabled,
size,
dynamicWidth,
notice
}: Props = $props();
</script>
<fieldset class="fieldset" {hidden}>
<legend class="fieldset-legend">
<span>
{label}
{#if required}
<span class="text-red-700">*</span>
{/if}
</span>
</legend>
<input
{id}
name={id}
bind:value
class="input"
class:input-sm={size === 'sm'}
class:validator={required || validation}
class:w-full={dynamicWidth}
type={type || 'text'}
min={validation?.min}
max={validation?.max}
required={required ? true : null}
pattern={validation?.pattern}
readonly={readonly ? true : null}
disabled={disabled ? true : null}
/>
<p class="fieldset-label">
{#if notice}
{@render notice()}
{/if}
</p>
{#if validation}
<p class="validator-hint mt-0">{validation.hint}</p>
{/if}
</fieldset>

View File

@@ -0,0 +1,70 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import Icon from '@iconify/svelte';
interface Props {
id?: string;
value?: string | null;
label?: string;
required?: boolean;
validation?: {
pattern?: string;
hint: string;
};
disabled?: boolean;
notice?: Snippet;
}
let { id, value = $bindable(), label, required, validation, disabled, notice }: Props = $props();
let visible = $state(false);
</script>
<fieldset class="fieldset">
<legend class="fieldset-legend">
<span>
{label}
{#if required}
<span class="text-red-700">*</span>
{/if}
</span>
</legend>
<div class="relative flex items-center">
<input
{id}
bind:value
class="input pr-9"
class:validator={required || validation}
type={visible ? 'text' : 'password'}
required={required ? true : null}
pattern={validation?.pattern}
disabled={disabled ? true : null}
data-input-visible="false"
/>
<button
type="button"
class="absolute right-2 cursor-pointer z-10"
class:hidden={!visible}
onclick={() => (visible = !visible)}
>
<Icon icon="heroicons:eye-16-solid" width={22} />
</button>
<button
type="button"
class="absolute right-2 cursor-pointer z-10"
class:hidden={visible}
onclick={() => (visible = !visible)}
>
<Icon icon="heroicons:eye-slash-16-solid" width={22} />
</button>
</div>
<p class="fieldset-label">
{#if notice}
{@render notice()}
{/if}
</p>
{#if validation}
<p class="validator-hint mt-0">{validation.hint}</p>
{/if}
</fieldset>

View File

@@ -0,0 +1,73 @@
<script lang="ts">
import type { Snippet } from 'svelte';
// types
interface Props {
id?: string;
value?: string | null;
values: { [value: string]: string };
defaultValue?: string;
label?: string;
required?: boolean;
validation?: {
hint: string;
};
disabled?: boolean;
size?: 'sm';
dynamicWidth?: boolean;
notice?: Snippet;
}
// inputs
let {
id,
value = $bindable(),
values,
defaultValue,
label,
required,
validation,
disabled,
size,
dynamicWidth,
notice
}: Props = $props();
</script>
<fieldset class="fieldset">
<legend class="fieldset-legend">
<span>
{label}
{#if required}
<span class="text-red-700">*</span>
{/if}
</span>
</legend>
<select
{id}
bind:value
class="select"
class:select-sm={size === 'sm'}
class:w-full={dynamicWidth}
class:validator={required || validation}
required={required ? true : null}
disabled={disabled ? true : null}
>
{#if defaultValue != null}
<option disabled selected>{defaultValue}</option>
{/if}
{#each Object.entries(values) as [v, label] (v)}
<option value={v} selected={v === value}>{label}</option>
{/each}
</select>
<p class="fieldset-label">
{#if notice}
{@render notice()}
{/if}
</p>
{#if validation}
<p class="validator-hint mt-0">{validation.hint}</p>
{/if}
</fieldset>

View File

@@ -0,0 +1,36 @@
<script lang="ts">
interface Props {
id?: string;
value?: string | null;
label?: string;
required?: boolean;
readonly?: boolean;
size?: 'sm';
dynamicWidth?: boolean;
rows?: number;
}
let { id, value = $bindable(), label, required, readonly, size, dynamicWidth, rows }: Props = $props();
</script>
<fieldset class="fieldset">
<legend class="fieldset-legend">
{label}
{#if required}
<span class="text-red-700">*</span>
{/if}
</legend>
<textarea
{id}
class="textarea"
class:textarea-sm={size === 'sm'}
class:w-full={dynamicWidth}
class:validator={required}
bind:value
{required}
{rows}
{readonly}
></textarea>
</fieldset>