Skip to content

Commit 3561600

Browse files
authored
Shadcn low-hanging fruit follow-up (#1693)
* Move I dont see my project, outside of item-list * Make entry-menu drawer close when item is selected * Style FLEx logo via iconVariants * Apply cursor-pointer to component/complex-form list items * Enable tabbing to sort toggle badge * Remove duplicate tab-able child * Use same icon in project-dropdown list and trigger * Don't show "No dictionaries found" while loading * Extend icon component to support <img> * Scroll to top of entry when different entry selected * Always autofocus the first field when selecting an entry on desktop * Debounce entry list querying * fixup! Always autofocus the first field when selecting an entry on desktop * Autofocus first field of added sense or example, on desktop * Enforce alt on img icons * Remove forgotten test bool * Tidy up watch * Refactor highlighting and autofocus * Don't show focus ring on entry filter when sidebar or filter toggle are focused
1 parent 50979d5 commit 3561600

30 files changed

Lines changed: 190 additions & 102 deletions

frontend/pnpm-lock.yaml

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/viewer/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
"svelte-preprocess": "catalog:",
9898
"svelte-routing": "^2.12.0",
9999
"svelte-ux": "^0.76.0",
100+
"tabbable": "^6.2.0",
100101
"type-fest": "^4.18.2"
101102
}
102103
}

frontend/viewer/src/home/HomeView.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import {Button} from '$lib/components/ui/button';
3030
import {mode} from 'mode-watcher';
3131
import * as ResponsiveMenu from '$lib/components/responsive-menu';
32+
import {Icon} from '$lib/components/ui/icon';
3233
3334
const projectsService = useProjectsService();
3435
const importFwdataService = useImportFwdataService();
@@ -104,7 +105,7 @@
104105

105106
<AppBar title={$t`Dictionaries`} class="bg-primary/15 min-h-12 shadow-md justify-between" menuIcon={null}>
106107
<div slot="title" class="text-lg flex gap-2 items-center">
107-
<img src={mode.current === 'dark' ? logoLight : logoDark} alt={$t`Lexbox logo`} class="h-6 shrink-0" />
108+
<Icon src={mode.current === 'dark' ? logoLight : logoDark} alt={$t`Lexbox logo`} />
108109
<h3>{$t`Dictionaries`}</h3>
109110
</div>
110111
<div slot="actions" class="flex">
@@ -222,7 +223,7 @@
222223
<ButtonListItem href={`/fwdata/${project.code}`}>
223224
<ListItem classes={{root: 'dark:bg-muted/50 bg-muted/80 hover:bg-muted/30 hover:dark:bg-muted' }}>
224225
<ProjectTitle slot="title" {project}/>
225-
<img slot="avatar" src={flexLogo} alt={$t`FieldWorks logo`} class="h-6 shrink-0" />
226+
<Icon slot="avatar" src={flexLogo} alt={$t`FieldWorks logo`} />
226227
<div slot="actions" class="shrink-0">
227228
<DevContent invisible>
228229
<UxButton

frontend/viewer/src/home/Server.svelte

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@
123123
</ButtonListItem>
124124
{/if}
125125
{/each}
126-
<div class="text-center py-2">
127-
<Button variant="link" target="_blank" href="{server?.authority}/wheresMyProject">
128-
{$t`I don't see my project`}
129-
<Icon icon="i-mdi-open-in-new" class="size-4" />
130-
</Button>
131-
</div>
126+
</div>
127+
<div class="text-center pt-2">
128+
<Button variant="link" target="_blank" href="{server?.authority}/wheresMyProject">
129+
{$t`I don't see my project`}
130+
<Icon icon="i-mdi-open-in-new" class="size-4" />
131+
</Button>
132132
</div>
133133
{/if}
134134
</div>

frontend/viewer/src/lib/OpenInFieldWorksButton.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import {t} from 'svelte-i18n-lingui';
99
import {mergeProps} from 'bits-ui';
1010
import {cn} from './utils';
11+
import {Icon} from './components/ui/icon';
1112
1213
type Props = {
1314
entry: IEntry
@@ -52,6 +53,6 @@
5253

5354
<!--button must be a link otherwise it won't follow the redirect to a protocol handler-->
5455
<button class={cn(buttonVariants({ variant: 'ghost'}), className)} {...mergedProps}>
55-
<img src={flexLogo} alt={$t`FieldWorks logo`} class="h-6 max-w-fit"/>
56+
<Icon src={flexLogo} alt={$t`FieldWorks logo`} />
5657
{$t`Open in FieldWorks`}
5758
</button>

frontend/viewer/src/lib/components/editor/editor-root.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
77
type EditorRootProps = WithElementRef<HTMLAttributes<HTMLDivElement>>;
88
9-
const {
9+
let {
1010
class: className,
1111
children,
1212
ref = $bindable(null),
1313
...restProps
1414
}: EditorRootProps = $props();
1515
</script>
1616

17-
<div class={cn('@container/editor', className)} {...restProps}>
17+
<div class={cn('@container/editor', className)} {...restProps} bind:this={ref}>
1818
{@render children?.()}
1919
</div>

frontend/viewer/src/lib/components/editor/editor-sub-grid.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import type {WithElementRef} from 'bits-ui';
44
import type {HTMLAttributes} from 'svelte/elements';
55
6-
type EditorSubGridProps = WithElementRef<HTMLAttributes<HTMLDivElement>>;
6+
export type EditorSubGridProps = WithElementRef<HTMLAttributes<HTMLDivElement>>;
77
88
const {
99
class: className,

frontend/viewer/src/lib/components/reorderer/reorderer-item-list.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
<DropdownMenu.Group {...mergedProps}>
4444
{#each displayItems as item, i}
4545
{@const reorderName = getDisplayName(item) || ''}
46-
<DropdownMenu.Item class="grid grid-cols-subgrid col-span-full justify-items-start items-center cursor-pointer"
46+
<DropdownMenu.Item class="grid grid-cols-subgrid col-span-full justify-items-start items-center"
4747
onmouseover={() => displayIndex = i}
4848
onfocus={() => displayIndex = i}
4949
onSelect={() => {

frontend/viewer/src/lib/components/responsive-menu/responsive-menu-item.svelte

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,20 @@
44
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
55
import * as ContextMenu from '$lib/components/ui/context-menu';
66
import { IsMobile } from '$lib/hooks/is-mobile.svelte';
7-
import Button, {buttonVariants} from '$lib/components/ui/button/button.svelte';
7+
import {buttonVariants} from '$lib/components/ui/button/button.svelte';
88
import type {Snippet} from 'svelte';
99
import {useResponsiveMenuItemList} from './responsive-menu.svelte';
10-
import type {ButtonProps} from 'node_modules/bits-ui/dist/bits/toolbar/exports';
11-
import {mergeProps, type ContextMenuItemProps} from 'bits-ui';
10+
import type {ContextMenuItemProps} from 'bits-ui';
11+
import type {DrawerCloseProps} from 'vaul-svelte';
1212
import {cn} from '$lib/utils';
13+
import {DrawerClose} from '../ui/drawer';
1314
1415
type Props = {
1516
children?: Snippet;
1617
icon?: IconClass;
1718
onSelect?: () => void;
1819
href?: string;
19-
} & ContextMenuItemProps & ButtonProps;
20+
} & Omit<ContextMenuItemProps & DrawerCloseProps, 'onclick'>;
2021
2122
let {
2223
icon,
@@ -28,14 +29,6 @@
2829
}: Props = $props();
2930
3031
const state = useResponsiveMenuItemList();
31-
32-
const buttonProps = $derived({
33-
variant: 'ghost',
34-
class: cn(buttonVariants({ variant: 'ghost', class: 'w-full justify-start gap-2' }), className),
35-
onclick: onSelect,
36-
} as const);
37-
38-
const mergedProps = $derived(mergeProps(buttonProps, rest));
3932
</script>
4033

4134
{#snippet content()}
@@ -52,21 +45,21 @@
5245
{/snippet}
5346

5447
{#if state.contextMenu}
55-
<ContextMenu.Item class={cn('cursor-pointer gap-2 w-full', className)} onclick={onSelect} bind:ref
48+
<ContextMenu.Item class={cn('gap-2 w-full', className)} {onSelect} bind:ref
5649
child={rest.href ? anchorChild : undefined} {...rest}>
5750
{@render content()}
5851
</ContextMenu.Item>
5952
{:else if !IsMobile.value}
60-
<DropdownMenu.Item class={cn('cursor-pointer gap-2 w-full', className)} {onSelect} bind:ref
53+
<DropdownMenu.Item class={cn('gap-2 w-full', className)} {onSelect} bind:ref
6154
child={rest.href ? anchorChild : undefined} {...rest}>
6255
{@render content()}
6356
</DropdownMenu.Item>
64-
{:else if rest.child}
65-
{@render rest.child({ props: mergedProps})}
6657
{:else}
67-
<Button
68-
{...buttonProps}
58+
<DrawerClose
59+
class={cn(buttonVariants({ variant: 'ghost', class: 'w-full justify-start gap-2' }), className)}
60+
onclick={onSelect}
61+
{...rest}
6962
bind:ref>
7063
{@render content()}
71-
</Button>
64+
</DrawerClose>
7265
{/if}

frontend/viewer/src/lib/components/ui/button/index.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ import Root, {
88
import XButton from './x-button.svelte';
99

1010
export {
11-
//
12-
Root as Button,
11+
Root,
1312
XButton,
14-
buttonVariants, Root, type ButtonProps,
13+
type ButtonProps,
1514
type ButtonSize,
16-
type ButtonVariant, type ButtonProps as Props
15+
type ButtonVariant,
16+
buttonVariants,
17+
//
18+
Root as Button,
19+
type ButtonProps as Props
1720
};

0 commit comments

Comments
 (0)