Skip to content

Commit 6f1e623

Browse files
authored
2 Dictionary Preview style fixes (#2294)
* Adjust margins/paddings so that the focus-ring on the first/top text field is not clipped when the dictionary preview is hidden or pinned (or shown, but that already worked) * The dictionary preview radio-button list did not have our standard sizing. That's largely, because I made the radio-button-item "label aware" at one point, but not in a way that was easy for all consumers to use (i.e. as a strong prop). Instead of making the component more different than the base shadcn component, I introduced a sibling component that take the label as the default snippet. Now all radio-buttons lists should share same layout code/css.
1 parent a243697 commit 6f1e623

8 files changed

Lines changed: 55 additions & 48 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import Item from './radio-group-item.svelte';
2+
import Option from './radio-group-option.svelte';
23
import Root from './radio-group.svelte';
34

45
export {
56
Item,
7+
Option,
68
//
79
Root as RadioGroup,
810
Item as RadioGroupItem,
11+
Option as RadioGroupOption,
912
Root,
1013
};
Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,29 @@
11
<script lang="ts">
22
import {RadioGroup as RadioGroupPrimitive} from 'bits-ui';
33
import {Icon} from '../icon';
4-
import Label from '../label/label.svelte';
54
import {cn, type WithoutChildrenOrChild} from '$lib/utils.js';
65
7-
type Props = {
8-
label?: string;
9-
} & WithoutChildrenOrChild<RadioGroupPrimitive.ItemProps>;
10-
11-
let {ref = $bindable(null), class: className, label, ...restProps}: Props = $props();
6+
let {
7+
ref = $bindable(null),
8+
class: className,
9+
...restProps
10+
}: WithoutChildrenOrChild<RadioGroupPrimitive.ItemProps> = $props();
1211
</script>
1312

14-
{#snippet control()}
15-
<RadioGroupPrimitive.Item
16-
bind:ref
17-
data-slot="radio-group-item"
18-
class={cn(
19-
'border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
20-
className,
21-
)}
22-
{...restProps}
23-
>
24-
{#snippet children({checked})}
25-
<div data-slot="radio-group-indicator" class="relative flex items-center justify-center">
26-
{#if checked}
27-
<Icon icon="i-mdi-circle" class="size-2.5 fill-current text-current" />
28-
{/if}
29-
</div>
30-
{/snippet}
31-
</RadioGroupPrimitive.Item>
32-
{/snippet}
33-
34-
{#if label}
35-
<Label class={cn('flex items-center gap-4 md:gap-2 max-md:py-3', restProps.disabled || 'cursor-pointer')}>
36-
{@render control()}
37-
<span class="min-w-0 flex-1 text-sm truncate">{label}</span>
38-
</Label>
39-
{:else}
40-
{@render control()}
41-
{/if}
13+
<RadioGroupPrimitive.Item
14+
bind:ref
15+
data-slot="radio-group-item"
16+
class={cn(
17+
'border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
18+
className,
19+
)}
20+
{...restProps}
21+
>
22+
{#snippet children({checked})}
23+
<div data-slot="radio-group-indicator" class="relative flex items-center justify-center">
24+
{#if checked}
25+
<Icon icon="i-mdi-circle" class="size-2.5 fill-current text-current" />
26+
{/if}
27+
</div>
28+
{/snippet}
29+
</RadioGroupPrimitive.Item>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script lang="ts">
2+
import {type RadioGroup as RadioGroupPrimitive} from 'bits-ui';
3+
import Label from '../label/label.svelte';
4+
import Item from './radio-group-item.svelte';
5+
import {cn, type WithoutChildrenOrChild} from '$lib/utils.js';
6+
import {type Snippet} from 'svelte';
7+
8+
type Props = WithoutChildrenOrChild<RadioGroupPrimitive.ItemProps> & {
9+
children?: Snippet;
10+
};
11+
12+
let {ref = $bindable(null), class: className, children, ...restProps}: Props = $props();
13+
</script>
14+
15+
<Label class={cn('flex items-center gap-4 md:gap-2 max-md:py-3', restProps.disabled || 'cursor-pointer', className)}>
16+
<Item bind:ref {...restProps} />
17+
{@render children?.()}
18+
</Label>

frontend/viewer/src/lib/views/custom/CustomViewForm.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@
9292
<div class="flex flex-col gap-2">
9393
<div class="text-sm font-medium">{$t`Based on`}</div>
9494
<RadioGroup.Root bind:value={value.base}>
95-
<RadioGroup.Item value={ViewBase.FwLite} label={FW_LITE_VIEW.name} />
96-
<RadioGroup.Item value={ViewBase.FieldWorks} label={FW_CLASSIC_VIEW.name} />
95+
<RadioGroup.Option value={ViewBase.FwLite}>{FW_LITE_VIEW.name}</RadioGroup.Option>
96+
<RadioGroup.Option value={ViewBase.FieldWorks}>{FW_CLASSIC_VIEW.name}</RadioGroup.Option>
9797
</RadioGroup.Root>
9898
</div>
9999

frontend/viewer/src/lib/views/custom/CustomViewWritingSystems.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@
6363
{/if}
6464
</div>
6565
<RadioGroup.Root value={isAllMode ? 'all' : 'custom'} onValueChange={handleModeChange}>
66-
<RadioGroup.Item value="all" label={$t`All`} />
67-
<RadioGroup.Item value="custom" label={$t`Custom`} />
66+
<RadioGroup.Option value="all">{$t`All`}</RadioGroup.Option>
67+
<RadioGroup.Option value="custom">{$t`Custom`}</RadioGroup.Option>
6868
</RadioGroup.Root>
6969

7070
<Checkbox.Group class="md:mt-4 ms-2">

frontend/viewer/src/project/browse/EditorViewOptions.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
<Button {...props} size="icon" variant="ghost" icon="i-mdi-layers" />
2222
{/snippet}
2323
<div class="space-y-2 md:space-y-4">
24+
<h3 class="font-normal max-md:mb-1">{$t`Dictionary Preview`}</h3>
2425
<RadioGroup.Root bind:value={dictionaryPreview}>
25-
<h3 class="font-normal max-md:mb-1">{$t`Dictionary Preview`}</h3>
26-
<RadioGroup.Item value="show" label={$t`Show`} />
27-
<RadioGroup.Item value="hide" label={$t`Hide`}/>
28-
<RadioGroup.Item value="sticky" label={$t`Pinned`}/>
26+
<RadioGroup.Option value="show">{$t`Show`}</RadioGroup.Option>
27+
<RadioGroup.Option value="hide">{$t`Hide`}</RadioGroup.Option>
28+
<RadioGroup.Option value="sticky">{$t`Pinned`}</RadioGroup.Option>
2929
</RadioGroup.Root>
3030
<ViewPicker onClose={() => open = false} />
3131
<DevContent>

frontend/viewer/src/project/browse/EntryView.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
</script>
114114

115115
{#snippet preview(entry: IEntry)}
116-
<div class="md:pb-4">
116+
<div class="md:pb-3">
117117
<DictionaryEntry {entry} showLinks class={cn('rounded bg-muted/80 dark:bg-muted/50 p-4')}>
118118
{#snippet actions()}
119119
<Toggle bind:pressed={() => sticky, (value) => void dictionaryPreviewStorage.set(value ? 'sticky' : 'show')}
@@ -168,7 +168,7 @@
168168
{@render preview(entry)}
169169
</div>
170170
{/if}
171-
<div class="max-md:p-2 md:pb-2 md:px-2">
171+
<div class="max-md:p-2 md:pt-1 md:pb-2 md:px-2">
172172
{#key entry.id}
173173
<EntryEditor
174174
bind:this={editor}

frontend/viewer/src/project/browse/ViewPicker.svelte

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import ManageCustomViewsButton from '$lib/views/custom/ManageCustomViewsButton.svelte';
88
import Markdown from 'svelte-exmarkdown';
99
import {t} from 'svelte-i18n-lingui';
10-
import {Label} from '$lib/components/ui/label';
1110
import {isCustomView} from '$lib/views/view-data';
1211
import {ViewBase} from '$lib/dotnet-types';
1312
@@ -50,15 +49,14 @@
5049

5150
<RadioGroup.Root bind:value={getCurrentView, setCurrentView}>
5251
{#each viewService.views as view (view.id)}
53-
<Label class="flex items-center gap-4 md:gap-2 max-md:py-3 cursor-pointer">
54-
<RadioGroup.Item value={view.id} />
52+
<RadioGroup.Option value={view.id}>
5553
<span>
5654
{view.name}
5755
{#if isCustomView(view)}
5856
<span class="text-muted-foreground">({view.base === ViewBase.FieldWorks ? 'Classic' : 'Lite'})</span>
5957
{/if}
6058
</span>
61-
</Label>
59+
</RadioGroup.Option>
6260
{/each}
6361
</RadioGroup.Root>
6462

0 commit comments

Comments
 (0)