Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/lib/holocene/checkbox.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@
: checked
? ('checkmark' as const)
: null;

$: errorId = `${id}-error`;
$: showError = !valid && !!error;
</script>

<div
Expand Down Expand Up @@ -114,6 +117,8 @@
data-track-name="checkbox"
data-track-intent="toggle"
data-track-text={label}
aria-invalid={showError ? 'true' : undefined}
aria-describedby={showError ? errorId : undefined}
bind:checked
{disabled}
{required}
Expand Down Expand Up @@ -175,7 +180,7 @@
</span>
</slot>
</Label>
{#if !valid && error}
<span class="text-xs text-danger">{error}</span>
{#if showError}
<span id={errorId} role="alert" class="text-xs text-danger">{error}</span>
{/if}
</div>
9 changes: 7 additions & 2 deletions src/lib/holocene/combobox/combobox.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@
});
}

const errorId = $derived(`${id}-error`);
const showError = $derived(!!error && !valid);

const handleInputClick: MouseEventHandler<HTMLInputElement> = (event) => {
event.stopPropagation();
if (!$open) openList();
Expand Down Expand Up @@ -556,6 +559,8 @@
aria-controls="{id}-listbox"
aria-expanded={$open}
aria-required={required}
aria-invalid={showError ? 'true' : undefined}
aria-describedby={showError ? errorId : undefined}
aria-autocomplete="list"
onfocus={handleFocus}
onblur={handleBlur}
Expand Down Expand Up @@ -680,8 +685,8 @@
{/if}
</Menu>

{#if error && !valid}
<span class="error">{error}</span>
{#if showError}
<span id={errorId} role="alert" class="error">{error}</span>
{/if}
</MenuContainer>

Expand Down
5 changes: 5 additions & 0 deletions src/lib/holocene/input/chip-input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
let displayValue = $state('');

const invalid = $derived(chips.some((chip) => !validator(chip)));
const errorId = $derived(`${id}-error`);

const handleKeydown = (e: KeyboardEvent) => {
e.stopPropagation();
Expand Down Expand Up @@ -144,6 +145,8 @@
{id}
{name}
{required}
aria-invalid={invalid ? 'true' : undefined}
aria-describedby={invalid && hintText ? errorId : undefined}
multiple
data-testid={id}
bind:value={displayValue}
Expand All @@ -159,9 +162,11 @@
{#if (invalid && hintText) || (maxLength && !disabled)}
<div class="flex justify-between gap-2">
<div
id={errorId}
class="error-msg"
class:min-width={maxLength}
aria-live={invalid ? 'assertive' : 'off'}
role={invalid ? 'alert' : null}
>
{#if invalid && hintText}
<p>{hintText}</p>
Expand Down
7 changes: 6 additions & 1 deletion src/lib/holocene/input/input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@

const isDisabled = $derived(disabled || copyable);
const testId = $derived(dataTestId || id);
const errorId = $derived(`${id}-error`);
const showError = $derived(error || !valid);

function callFocus(input: HTMLInputElement) {
if (autoFocus && input) input.focus();
Expand Down Expand Up @@ -134,6 +136,8 @@
{name}
{spellcheck}
{required}
aria-invalid={showError ? 'true' : undefined}
aria-describedby={showError && hintText ? errorId : undefined}
{autocomplete}
bind:value
onclick={(e) => {
Expand Down Expand Up @@ -191,10 +195,11 @@
class:hidden={!hintText && (!maxLength || isDisabled || hideCount)}
>
<span
id={errorId}
class="hint-text inline-block"
class:invalid={!valid}
class:error
role={error ? 'alert' : null}
role={showError ? 'alert' : null}
>
{hintText}
</span>
Expand Down
8 changes: 7 additions & 1 deletion src/lib/holocene/input/number-input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
$: {
validate(value);
}

$: errorId = `${id}-error`;
</script>

<div class={merge('flex flex-col gap-1', $$props.class)}>
Expand Down Expand Up @@ -66,6 +68,8 @@
{name}
{step}
{required}
aria-invalid={!valid ? 'true' : undefined}
aria-describedby={!valid && hintText ? errorId : undefined}
{autocomplete}
spellcheck="false"
bind:value
Expand All @@ -86,7 +90,9 @@
</div>
</div>
{#if !valid && hintText}
<span class="mt-1 text-xs text-danger">{hintText}</span>
<span id={errorId} role="alert" class="mt-1 text-xs text-danger"
>{hintText}</span
>
{/if}

<style lang="postcss">
Expand Down
9 changes: 7 additions & 2 deletions src/lib/holocene/select/select.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@
// After all the Options are mounted use context to read the label assocaited with the value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Argument of type 'T | undefined' is not assignable to parameter of type 'T'.

$labelCtx = getLabelFromOptions(value);
});

const errorId = $derived(`${id}-error`);
const showError = $derived(!!error && !valid);
</script>

<MenuContainer class="w-full" {open}>
Expand Down Expand Up @@ -155,6 +158,8 @@
class:disabled
{required}
aria-required={required}
aria-invalid={showError ? 'true' : undefined}
aria-describedby={showError ? errorId : undefined}
{...rest}
/>
{#snippet trailing()}
Expand All @@ -173,8 +178,8 @@
</Menu>
{/if}

{#if error && !valid}
<span class="text-xs text-danger">{error}</span>
{#if showError}
<span id={errorId} role="alert" class="text-xs text-danger">{error}</span>
{/if}
</MenuContainer>

Expand Down
6 changes: 6 additions & 0 deletions src/lib/holocene/textarea.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

let className = 'text-primary';
export { className as class };

$: errorId = `${id}-error`;
</script>

<div class={merge('group flex flex-col gap-1', className)}>
Expand All @@ -64,6 +66,8 @@
{rows}
{spellcheck}
{required}
aria-invalid={!isValid ? 'true' : undefined}
aria-describedby={!isValid && error ? errorId : undefined}
on:input
on:change
on:focus
Expand All @@ -76,9 +80,11 @@
</div>
<div class="flex justify-between gap-2">
<div
id={errorId}
class="error-msg"
class:min-width={maxLength}
aria-live={isValid ? 'off' : 'assertive'}
role={!isValid ? 'alert' : null}
>
{#if !isValid}
{#if error}
Expand Down
Loading