Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@

{#snippet trigger({ props }: { props: Record<string, unknown> })}
<Button disabled={readonly} bind:ref={triggerRef} variant="outline" {...props} role="combobox" aria-expanded={open}
class="w-full h-auto px-2 justify-between disabled:opacity-100 disabled:border-transparent">
class="w-full h-auto min-h-10 px-2 justify-between disabled:opacity-100 disabled:border-transparent">
{@render displayBadges()}
{#if !readonly}
<Icon icon="i-mdi-chevron-down" class="mr-2 size-5 shrink-0 opacity-50" />
Expand Down
25 changes: 17 additions & 8 deletions frontend/viewer/src/lib/components/field-editors/select.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,29 @@
value?: Value;
options: ReadonlyArray<Value>;
readonly?: boolean;
clearable?: boolean;
idSelector: ConditionalKeys<Value, Primitive> | ((value: Value) => Primitive);
labelSelector: ConditionalKeys<Value, string> | ((value: Value) => string);
placeholder?: string;
filterPlaceholder?: string;
emptyResultsPlaceholder?: string;
drawerTitle?: string;
onchange?: (value: Value) => void;
onchange?: (value: Value | undefined) => void;
class?: string;
} = $props();

const {
options,
readonly = false,
clearable = false,
idSelector,
labelSelector,
placeholder,
filterPlaceholder,
emptyResultsPlaceholder,
drawerTitle,
onchange,
class: className
class: className,
} = $derived(constProps);

function getId(value: Value): Primitive {
Expand All @@ -66,7 +68,7 @@
open = false;
}

function selectValue(newValue: Value) {
function selectValue(newValue: Value | undefined) {
value = newValue;
onchange?.(newValue);
open = false;
Expand All @@ -88,8 +90,9 @@
</script>

{#snippet trigger({ props }: { props: Record<string, unknown> })}
<Button disabled={readonly} bind:ref={triggerRef} variant="outline" {...props} role="combobox" aria-expanded={open}
class={cn('w-full h-auto px-2 justify-between disabled:opacity-100 disabled:border-transparent', className)}>
<div class="relative">
<Button disabled={readonly} bind:ref={triggerRef} variant="outline" {...props} role="combobox" aria-expanded={open}
class={cn('w-full h-auto min-h-10 px-2 justify-between disabled:opacity-100 disabled:border-transparent', className)}>
{#if value}
<span>
{getLabel(value)}
Expand All @@ -100,11 +103,17 @@
<!-- ensures that baseline alignment works for consumers of this component -->
&nbsp;
</span>
{/if}
{/if}
</Button>
{#if !readonly}
<Icon icon="i-mdi-chevron-down" class="mr-2 size-5 shrink-0 opacity-50" />
<div class="absolute right-0 z-10 top-1/2 -translate-y-1/2 flex items-center gap-0.5 pointer-events-none">
{#if clearable}
<XButton onclick={() => selectValue(undefined)} aria-label={$t`clear`} class={cn('pointer-events-auto', value || 'invisible')} />
{/if}
<Icon icon="i-mdi-chevron-down" class="mr-2 size-5 shrink-0 opacity-50" />
</div>
{/if}
</Button>
</div>
{/snippet}

{#snippet command()}
Expand Down
44 changes: 30 additions & 14 deletions frontend/viewer/src/lib/components/ui/select/select-trigger.svelte
Original file line number Diff line number Diff line change
@@ -1,30 +1,46 @@
<script lang="ts">
import {cn} from '$lib/utils.js';
import {Select as SelectPrimitive, type WithoutChild} from 'bits-ui';
import {mergeProps, Select as SelectPrimitive, type WithoutChild} from 'bits-ui';
import {Icon} from '../icon';
import type {IconClass} from '$lib/icon-class';
import XButton from '../button/x-button.svelte';
import type {ComponentProps} from 'svelte';

let {
ref = $bindable(null),
class: className,
downIcon = 'i-mdi-chevron-down',
children,
onClear,
style: styleProps,
...restProps
}: WithoutChild<SelectPrimitive.TriggerProps> & {
downIcon?: IconClass | null;
onClear?: ComponentProps<typeof XButton>['onclick'];
} = $props();

// turn style into a normal html format
const style = $derived(mergeProps({style: styleProps}).style);
</script>

<SelectPrimitive.Trigger
bind:ref
class={cn(
'border-input bg-background ring-offset-background data-[placeholder]:text-muted-foreground focus:ring-ring flex h-10 w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
className,
)}
{...restProps}
>
{@render children?.()}
{#if downIcon}
<Icon icon={downIcon} class="size-4 opacity-50" />
{/if}
</SelectPrimitive.Trigger>
<div class={cn('relative group', className)} {style}>
<SelectPrimitive.Trigger
bind:ref
class={cn(
'border-input bg-background ring-offset-background data-[placeholder]:text-muted-foreground focus:ring-ring flex h-10 w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
// matches the Button 'outline' variant
'hover:bg-accent hover:text-accent-foreground',
)}
{...restProps}
>
{@render children?.()}
</SelectPrimitive.Trigger>
<div class="absolute right-0 top-1/2 -translate-y-1/2 flex items-center gap-0.5 pointer-events-none">
{#if onClear && !restProps.disabled}
<XButton class="pointer-events-auto group-has-[[data-placeholder]]:hidden" onclick={onClear} />
{/if}
{#if downIcon}
<Icon icon={downIcon} class="mr-2 size-5 shrink-0 opacity-50" />
{/if}
</div>
</div>
4 changes: 2 additions & 2 deletions frontend/viewer/src/lib/components/ui/switch/switch.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
bind:checked
class={cn(
'focus-visible:ring-ring focus-visible:ring-offset-background data-[state=checked]:bg-primary data-[state=unchecked]:bg-input peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className,
!!label || className,
)}
{...restProps}
>
Expand All @@ -35,7 +35,7 @@
{/snippet}

{#if label}
<Label class="cursor-pointer flex items-center gap-2">
<Label class={cn('cursor-pointer flex items-center gap-4 max-md:w-full max-md:h-10', className)}>
{@render control()}
<span>{label}</span>
</Label>
Expand Down
56 changes: 36 additions & 20 deletions frontend/viewer/src/locales/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ msgstr "Add Word"
msgid "an entry"
msgstr "an entry"

#: src/project/browse/filter/SemanticDomainSelect.svelte
msgid "Any semantic domain"
msgstr "Any semantic domain"

#: src/project/browse/filter/WsSelect.svelte
msgid "Any Ws"
msgstr "Any Ws"
Expand Down Expand Up @@ -205,14 +209,15 @@ msgstr "Choose theme"
msgid "Citation form"
msgstr "Citation form"

#: src/project/browse/SearchFilter.svelte
#: src/project/browse/filter/FieldSelect.svelte
msgid "Citation Form"
msgstr "Citation Form"

#: src/home/HomeView.svelte
msgid "Classic FieldWorks Projects"
msgstr "Classic FieldWorks Projects"

#: src/lib/components/field-editors/select.svelte
#: src/lib/components/field-editors/select.svelte
#: src/lib/components/field-editors/multi-select.svelte
msgid "clear"
Expand Down Expand Up @@ -342,7 +347,7 @@ msgstr "Dictionary Preview"
msgid "Discard"
msgstr "Discard"

#: src/project/browse/SearchFilter.svelte
#: src/project/browse/filter/FieldSelect.svelte
#: src/lib/entry-editor/object-editors/EntryEditorPrimitive.svelte
msgid "Display as"
msgstr "Display as"
Expand Down Expand Up @@ -398,6 +403,10 @@ msgstr "Editor"
msgid "Ends with"
msgstr "Ends with"

#: src/project/browse/filter/MissingSelect.svelte
msgid "Entries missing..."
msgstr "Entries missing..."

#: src/project/browse/EntryMenu.svelte
#: src/lib/entry-editor/EntryOrSensePicker.svelte
#: src/lib/entry-editor/EditEntryDialog.svelte
Expand Down Expand Up @@ -464,7 +473,7 @@ msgstr "Failed to synchronize"
msgid "Feedback & Support"
msgstr "Feedback & Support"

#: src/project/browse/SearchFilter.svelte
#: src/project/browse/filter/FieldSelect.svelte
msgid "Field"
msgstr "Field"

Expand Down Expand Up @@ -526,8 +535,8 @@ msgid "Filter entries"
msgstr "Filter entries"

#: src/project/browse/SearchFilter.svelte
msgid "Filter for"
msgstr "Filter for"
msgid "Filter for..."
msgstr "Filter for..."

#: src/project/browse/SearchFilter.svelte
msgid "Filter words"
Expand Down Expand Up @@ -558,7 +567,7 @@ msgstr "For any other inquiries, feel free to send us an email."
msgid "Get support"
msgstr "Get support"

#: src/project/browse/SearchFilter.svelte
#: src/project/browse/filter/FieldSelect.svelte
#: src/lib/entry-editor/object-editors/SenseEditorPrimitive.svelte
msgid "Gloss"
msgstr "Gloss"
Expand Down Expand Up @@ -604,6 +613,14 @@ msgstr "Import"
msgid "in {0}"
msgstr "in {0}"

#: src/project/browse/SearchFilter.svelte
msgid "Include subdomains"
msgstr "Include subdomains"

#: src/project/browse/SearchFilter.svelte
msgid "Incomplete entries"
msgstr "Incomplete entries"

#: src/project/tasks/DoneView.svelte
msgid "Keep going"
msgstr "Keep going"
Expand Down Expand Up @@ -633,7 +650,7 @@ msgstr "Lexbox logo"
msgid "Lexeme form"
msgstr "Lexeme form"

#: src/project/browse/SearchFilter.svelte
#: src/project/browse/filter/FieldSelect.svelte
msgid "Lexeme Form"
msgstr "Lexeme Form"

Expand Down Expand Up @@ -711,26 +728,17 @@ msgstr "Missing Definition {0}"
msgid "Missing Example sentence {0}"
msgstr "Missing Example sentence {0}"

#: src/project/browse/SearchFilter.svelte
msgid "Missing Examples"
msgstr "Missing Examples"

#: src/project/tasks/tasks-service.ts
msgid "Missing Gloss {0}"
msgstr "Missing Gloss {0}"

#: src/project/tasks/tasks-service.ts
#: src/project/browse/SearchFilter.svelte
msgid "Missing Part of Speech"
msgstr "Missing Part of Speech"

#: src/project/browse/SearchFilter.svelte
msgid "Missing Semantic Domains"
msgstr "Missing Semantic Domains"

#: src/project/browse/SearchFilter.svelte
msgid "Missing Senses"
msgstr "Missing Senses"
#: src/project/browse/filter/MissingSelect.svelte
msgid "Missing: {0}"
msgstr "Missing: {0}"

#: src/lib/entry-editor/ItemListItem.svelte
msgid "Move"
Expand Down Expand Up @@ -992,6 +1000,10 @@ msgstr "Select a new task to work on"
msgid "Select file"
msgstr "Select file"

#: src/project/browse/SearchFilter.svelte
msgid "Semantic domain"
msgstr "Semantic domain"

#: src/lib/entry-editor/object-editors/SenseEditorPrimitive.svelte
msgid "Semantic domains"
msgstr "Semantic domains"
Expand Down Expand Up @@ -1051,6 +1063,10 @@ msgstr "Size:"
msgid "Skip"
msgstr "Skip"

#: src/project/browse/SearchFilter.svelte
msgid "Specific field"
msgstr "Specific field"

#: src/project/browse/filter/OpFilter.svelte
msgid "Starts with"
msgstr "Starts with"
Expand Down Expand Up @@ -1260,8 +1276,8 @@ msgstr "Where are my projects?"
msgid "Why is that?"
msgstr "Why is that?"

#: src/project/browse/SearchFilter.svelte
#: src/project/browse/EntryMenu.svelte
#: src/project/browse/filter/FieldSelect.svelte
#: src/lib/entry-editor/EntryOrSensePicker.svelte
#: src/lib/entry-editor/EditEntryDialog.svelte
#: src/lib/entry-editor/object-editors/EntryEditorPrimitive.svelte
Expand Down
Loading
Loading