diff --git a/package.json b/package.json index f46958f7..3a1f3d7a 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "@dicebear/core": "^9.4.3", "@dicebear/initials": "^9.4.2", "@floating-ui/dom": "^1.8.0", + "@lucide/svelte": "^1.37.0", "@sveltejs/kit": "^2.70.3", - "@xylightdev/svelte-hero-icons": "^2.2.10", "lemmy-js-client": "0.19.11-donation-dialog.1", "linkify-it": "^6.1.0", "marked": "^16.4.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 47924936..0adfc5f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,12 +20,12 @@ importers: '@floating-ui/dom': specifier: ^1.8.0 version: 1.8.0 + '@lucide/svelte': + specifier: ^1.37.0 + version: 1.37.0(svelte@5.56.10(@typescript-eslint/types@8.68.0)) '@sveltejs/kit': specifier: ^2.70.3 version: 2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.10(@typescript-eslint/types@8.68.0))(vite@8.2.2(@types/node@25.9.5)(esbuild@0.27.2)(jiti@2.7.0)))(svelte@5.56.10(@typescript-eslint/types@8.68.0))(typescript@5.9.3)(vite@8.2.2(@types/node@25.9.5)(esbuild@0.27.2)(jiti@2.7.0)) - '@xylightdev/svelte-hero-icons': - specifier: ^2.2.10 - version: 2.2.10(svelte@5.56.10(@typescript-eslint/types@8.68.0)) lemmy-js-client: specifier: 0.19.11-donation-dialog.1 version: 0.19.11-donation-dialog.1 @@ -399,6 +399,11 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@lucide/svelte@1.37.0': + resolution: {integrity: sha512-AxaiSxeuErlt4fNmmN28oaL5R7yVoQLsfSeiAONxCEK+l0/SrLAjRktQ0DkTQpomv1oRzOA3hohWY0ZHTZCMmw==} + peerDependencies: + svelte: ^5 + '@napi-rs/lzma-linux-x64-gnu@1.5.1': resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} engines: {node: ^22.20 || ^24.12 || >=25} @@ -969,11 +974,6 @@ packages: '@vitest/utils@4.1.11': resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==} - '@xylightdev/svelte-hero-icons@2.2.10': - resolution: {integrity: sha512-dQ+U4sBiQrcp1GwNTJTDMrORZMxI9RJPioF+nsqtvzmyjYIUpMaPV9BgggN4JIdc6H+5swpw4aiiizl8JHrO+w==} - peerDependencies: - svelte: ^5.0.0 - abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} deprecated: Use your platform's native atob() and btoa() methods instead @@ -2360,6 +2360,10 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@lucide/svelte@1.37.0(svelte@5.56.10(@typescript-eslint/types@8.68.0))': + dependencies: + svelte: 5.56.10(@typescript-eslint/types@8.68.0) + '@napi-rs/lzma-linux-x64-gnu@1.5.1': optional: true @@ -2829,10 +2833,6 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.1 - '@xylightdev/svelte-hero-icons@2.2.10(svelte@5.56.10(@typescript-eslint/types@8.68.0))': - dependencies: - svelte: 5.56.10(@typescript-eslint/types@8.68.0) - abab@2.0.6: optional: true diff --git a/src/app.d.ts b/src/app.d.ts index 2fddeb0a..7a693e66 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -129,14 +129,6 @@ declare const __VERSION__: string declare module 'markdown-it-sub' declare module 'markdown-it-sup' -declare module '@xylightdev/svelte-hero-icons' { - interface IconProps { - 'aria-label'?: string - 'aria-hidden'?: boolean - title?: string - } -} - declare module '*.svg?raw' { const content: string export default content diff --git a/src/lib/feature/comment/Comment.svelte b/src/lib/feature/comment/Comment.svelte index 3d806bb4..46ebe800 100644 --- a/src/lib/feature/comment/Comment.svelte +++ b/src/lib/feature/comment/Comment.svelte @@ -15,13 +15,7 @@ import { publishedToDate } from '$lib/ui/util/date' import { Button, Modal, toast } from '$lib/ui/kit' import RelativeDate from '$lib/ui/util/RelativeDate.svelte' - import { - Icon, - Microphone, - Minus, - Plus, - Trash, - } from '@xylightdev/svelte-hero-icons' + import { Icon, Mic, Minus, Plus, Trash2 } from '$lib/ui/kit/icon' import { expoOut } from 'svelte/easing' import type { ClassValue } from 'svelte/elements' import { slide } from 'svelte/transition' @@ -189,7 +183,7 @@ 'transition-all duration-500 ease-out my-auto h-full w-8 grid place-items-center', ]} > - + {@render metaSuffix?.()} @@ -211,12 +205,7 @@ {#if creatorIsOp} - + {/if} {/if} {#if node.comment.isDeleted} (replying = !replying)} disabled={disabled || !profile.current?.jwt} - icon={ChatBubbleOvalLeft} + icon={MessageSquare} > {$t('comment.reply')} @@ -126,7 +126,7 @@ rounding="pill" size="square-md" class="text-slate-600 dark:text-zinc-400" - icon={EllipsisHorizontal} + icon={Ellipsis} > {/snippet} {$t('post.actions.more.share')} @@ -159,7 +159,7 @@ onedit?.(comment)} - icon={PencilSquare} + icon={SquarePen} > {$t('post.actions.more.edit')} @@ -169,7 +169,7 @@ disabled={comment.isDeleted} color="danger-subtle" onclick={confirmDelete} - icon={Trash} + icon={Trash2} > {$t('post.actions.more.delete')} diff --git a/src/lib/feature/comment/CommentForm.svelte b/src/lib/feature/comment/CommentForm.svelte index 8613df2a..bec17ad5 100644 --- a/src/lib/feature/comment/CommentForm.svelte +++ b/src/lib/feature/comment/CommentForm.svelte @@ -9,7 +9,7 @@ import MarkdownEditor from '$lib/feature/markdown/MarkdownEditor.svelte' import { placeholders } from '$lib/app/util/placeholders' import { Button, toast } from '$lib/ui/kit' - import { Icon, XMark } from '@xylightdev/svelte-hero-icons' + import { Icon, X } from '$lib/ui/kit/icon' import type { ClassValue, HTMLTextareaAttributes } from 'svelte/elements' interface Props extends Omit { @@ -128,12 +128,7 @@ class="w-8 h-8" rounding="xl" > - + @@ -111,7 +110,7 @@ bind:value={settings.defaultSort.comments} onchange={onupdate} > - + @@ -122,7 +121,7 @@ class="h-8.5 w-8.5" rounding="xl" onclick={onupdate} - icon={ArrowPath} + icon={RefreshCw} > {/snippet} @@ -161,7 +160,7 @@ bind:value={settings.defaultSort.comments} onchange={onupdate} > - + @@ -172,7 +171,7 @@ class="h-8.5 w-8.5" rounding="xl" onclick={onupdate} - icon={ArrowPath} + icon={RefreshCw} > {/if} @@ -180,7 +179,7 @@ {#snippet allCommentsPlaceholder()} {#snippet action()} - {/snippet} @@ -199,7 +198,7 @@ href={postLink(post)} class="mt-2 -mb-2 -mx-2.5 w-max" > - + {$t('routes.post.thread.allComments')}
{$t('comment.thread')} @@ -167,7 +164,7 @@ shadow="none" loaderWidth={16} onclick={() => fetchChildren(nodes[index])} - icon={ArrowDownCircle} + icon={CircleArrowDown} > {$t('comment.more')} diff --git a/src/lib/feature/community/CommunityCard.svelte b/src/lib/feature/community/CommunityCard.svelte index ab25f012..f8f26cd1 100644 --- a/src/lib/feature/community/CommunityCard.svelte +++ b/src/lib/feature/community/CommunityCard.svelte @@ -16,12 +16,7 @@ Spinner, toast, } from '$lib/ui/kit' - import { - Cog6Tooth, - EllipsisHorizontal, - Fire, - } from '@xylightdev/svelte-hero-icons' - + import { Ellipsis, Flame, Settings } from '$lib/ui/kit/icon' /** * Purge a community by DID. * Not yet available in the Coves API. @@ -111,7 +106,7 @@ {#if isHydratedCommunity(community) && profile.isMod(community)} {/if} @@ -121,7 +116,7 @@ {/snippet} {$t('admin.purge')} diff --git a/src/lib/feature/community/CommunityForm.svelte b/src/lib/feature/community/CommunityForm.svelte index 9f11e82b..a74c6a62 100644 --- a/src/lib/feature/community/CommunityForm.svelte +++ b/src/lib/feature/community/CommunityForm.svelte @@ -9,8 +9,7 @@ import MarkdownEditor from '$lib/feature/markdown/MarkdownEditor.svelte' import { Header } from '$lib/ui/layout' import { Button, Option, Select, TextInput, toast } from '$lib/ui/kit' - import { GlobeAlt, LockClosed, MapPin } from '@xylightdev/svelte-hero-icons' - + import { Globe, Lock, MapPin } from '$lib/ui/kit/icon' interface Props { formtitle?: import('svelte').Snippet } @@ -89,9 +88,9 @@ /> {/if} {#if profile.current?.jwt && profile.isAdmin} {#snippet target(attachment)} - {/snippet} {$t('admin.purge')} diff --git a/src/lib/feature/community/CommunityItem.svelte b/src/lib/feature/community/CommunityItem.svelte index 761e95b3..96b0fee1 100644 --- a/src/lib/feature/community/CommunityItem.svelte +++ b/src/lib/feature/community/CommunityItem.svelte @@ -4,7 +4,7 @@ import CommonItem from '$lib/ui/layout/CommonItem.svelte' import { Button, modal } from '$lib/ui/kit' import type { Snippet } from 'svelte' - import { Icon, InformationCircle } from '@xylightdev/svelte-hero-icons' + import { Icon, Info } from '$lib/ui/kit/icon' import CommunityCard from './CommunityCard.svelte' import SubscribeButton from './SubscribeButton.svelte' import { @@ -57,7 +57,7 @@ aria-label={$t('common.info')} size="square-md" > - + {:else} diff --git a/src/lib/feature/community/CommunityItemBig.svelte b/src/lib/feature/community/CommunityItemBig.svelte index d06c86f4..f22dfcc4 100644 --- a/src/lib/feature/community/CommunityItemBig.svelte +++ b/src/lib/feature/community/CommunityItemBig.svelte @@ -8,7 +8,7 @@ import Blobs from '$lib/ui/generic/Blobs.svelte' import { Button, modal } from '$lib/ui/kit' import type { Snippet } from 'svelte' - import { Icon, InformationCircle } from '@xylightdev/svelte-hero-icons' + import { Icon, Info } from '$lib/ui/kit/icon' import CommunityCard from './CommunityCard.svelte' import SubscribeButton from './SubscribeButton.svelte' import { @@ -100,7 +100,7 @@ aria-label={$t('common.info')} size="square-md" > - +
diff --git a/src/lib/feature/community/SubscribeButton.svelte b/src/lib/feature/community/SubscribeButton.svelte index 342d936b..5f3f8cde 100644 --- a/src/lib/feature/community/SubscribeButton.svelte +++ b/src/lib/feature/community/SubscribeButton.svelte @@ -4,7 +4,7 @@ import { errorMessage } from '$lib/app/util/error' import { t } from '$lib/app/state/i18n' import { Button, toast } from '$lib/ui/kit' - import { Check, Plus } from '@xylightdev/svelte-hero-icons' + import { Check, Plus } from '$lib/ui/kit/icon' import { isSubscribed, isSubscriptionPending, diff --git a/src/lib/feature/filter/SortMenu.svelte b/src/lib/feature/filter/SortMenu.svelte index f53a5a4b..6419ae9e 100644 --- a/src/lib/feature/filter/SortMenu.svelte +++ b/src/lib/feature/filter/SortMenu.svelte @@ -14,16 +14,15 @@ import MenuButton from '$lib/ui/kit/popover/MenuButton.svelte' import { Button, toast } from '$lib/ui/kit' import { + Icon, + type IconSource, Check, ChevronDown, Clock, - Fire, - Icon, + Flame, Star, Trophy, - type IconSource, - } from '@xylightdev/svelte-hero-icons' - + } from '$lib/ui/kit/icon' interface Props { sort: CovesSortType timeframe?: CovesTimeframe @@ -42,7 +41,7 @@ CovesSortType, { icon: IconSource; labelKey: string } > = { - hot: { icon: Fire, labelKey: 'filter.sort.hot' }, + hot: { icon: Flame, labelKey: 'filter.sort.hot' }, top: { icon: Trophy, labelKey: 'filter.sort.top.label' }, new: { icon: Star, labelKey: 'filter.sort.new' }, } @@ -124,23 +123,22 @@ {/snippet} - selectSort('hot')}> + selectSort('hot')}> {$t('filter.sort.hot')} {#snippet suffix()} {#if sort === 'hot'} {/if} @@ -154,7 +152,6 @@ {/if} @@ -174,7 +171,6 @@ {/if} @@ -190,7 +186,6 @@ {/if} diff --git a/src/lib/feature/filter/ViewSelect.svelte b/src/lib/feature/filter/ViewSelect.svelte index e9dae16f..f4931a2f 100644 --- a/src/lib/feature/filter/ViewSelect.svelte +++ b/src/lib/feature/filter/ViewSelect.svelte @@ -4,32 +4,45 @@ import { Option, Select } from '$lib/ui/kit' import { type SelectProps } from '$lib/ui/kit/forms/select/Select.svelte' import { - Bars3, Icon, - RectangleGroup, - ViewColumns, - } from '@xylightdev/svelte-hero-icons' - + CloudDrizzle, + Columns3, + Rows4, + type IconSource, + } from '$lib/ui/kit/icon' interface Props extends SelectProps { showLabel?: boolean } let { showLabel = true, ...rest }: Props = $props() + + // Resolved in an effect (browser-only) rather than inline: `settings.view` + // comes from localStorage, so the server always renders the default view. + // An SSR'd icon for the wrong view would get patched — not replaced — during + // hydration, leaving a chimera of both icons' SVG nodes in the DOM. + let viewIcon: IconSource | undefined = $state(undefined) + $effect(() => { + viewIcon = settings.view == 'cozy' ? CloudDrizzle : Rows4 + }) - {#snippet customLabel()} {#if showLabel} - + {$t('filter.view.label')} {/if} {/snippet} - - diff --git a/src/lib/feature/instance/CovesSidebar.svelte b/src/lib/feature/instance/CovesSidebar.svelte index 5c75fae2..f00d3f48 100644 --- a/src/lib/feature/instance/CovesSidebar.svelte +++ b/src/lib/feature/instance/CovesSidebar.svelte @@ -6,7 +6,7 @@ import SidebarButton from '$lib/ui/sidebar/SidebarButton.svelte' import { Spinner } from '$lib/ui/kit' import { onMount } from 'svelte' - import { BuildingOffice, GlobeAlt } from '@xylightdev/svelte-hero-icons' + import { Building, Compass } from '$lib/ui/kit/icon' import type { ClassValue } from 'svelte/elements' import { siteStats } from './siteStats.svelte' @@ -43,13 +43,9 @@ - + {#if siteStats.data || siteStats.loading} diff --git a/src/lib/feature/markdown/MarkdownEditor.svelte b/src/lib/feature/markdown/MarkdownEditor.svelte index 84e63c29..2d899329 100644 --- a/src/lib/feature/markdown/MarkdownEditor.svelte +++ b/src/lib/feature/markdown/MarkdownEditor.svelte @@ -5,17 +5,17 @@ import type { TextAreaProps } from '$lib/ui/kit/forms/TextArea.svelte' import { tick } from 'svelte' import { - Bold, - CodeBracket, - ExclamationTriangle, - H1, Icon, + Bold, + Code, + Heading1, + Image, Italic, Link, - ListBullet, - Photo, + List, Strikethrough, - } from '@xylightdev/svelte-hero-icons' + TriangleAlert, + } from '$lib/ui/kit/icon' import type { ClassValue } from 'svelte/elements' import { t } from '$lib/app/state/i18n' import Markdown from './Markdown.svelte' @@ -187,7 +187,7 @@ class="w-8 h-8" rounding="lg" > - + {/if} diff --git a/src/lib/feature/markdown/renderers/MdCode.svelte b/src/lib/feature/markdown/renderers/MdCode.svelte index 7088a883..990a424d 100644 --- a/src/lib/feature/markdown/renderers/MdCode.svelte +++ b/src/lib/feature/markdown/renderers/MdCode.svelte @@ -1,8 +1,7 @@ @@ -41,20 +41,20 @@ href={profile.current.type === 'authenticated' ? `/profile/${encodeURIComponent(profile.current.handle)}` : '/login'} - icon={UserCircle} + icon={CircleUser} > {$t('profile.profile')} {:else} - + {$t('account.login')} {/if} - + {$t('account.accounts')} {$t('nav.menu.app')} - + {$t('nav.menu.settings')} - + {$t('nav.menu.theme')} {#snippet key(label: string)} @@ -94,7 +94,7 @@ {/snippet} (chords.commands = !chords.commands)} - icon={CommandLine} + icon={Terminal} > {$t('nav.commands.prompt')}
@@ -103,7 +103,7 @@
{#if settings.debugInfo} - Debug + Debug {/if}
  • @@ -130,7 +130,7 @@ title={$t('nav.menu.instance')} size="square-md" > - +
  • diff --git a/src/lib/feature/shell/navbar/commands/CommandItem.svelte b/src/lib/feature/shell/navbar/commands/CommandItem.svelte index 2ec11d2c..76301a6c 100644 --- a/src/lib/feature/shell/navbar/commands/CommandItem.svelte +++ b/src/lib/feature/shell/navbar/commands/CommandItem.svelte @@ -3,11 +3,7 @@ import Avatar from '$lib/ui/generic/Avatar.svelte' import { Button } from '$lib/ui/kit' import type { Snippet } from 'svelte' - import { - ArrowUturnDown, - Icon, - QuestionMarkCircle, - } from '@xylightdev/svelte-hero-icons' + import { Icon, CircleHelp, CornerDownRight } from '$lib/ui/kit/icon' import type { HTMLButtonAttributes } from 'svelte/elements' import type { Action } from './actions.svelte' @@ -35,8 +31,7 @@ {:else} @@ -55,6 +50,6 @@ {/if} {#if action.subActions} - + {/if} diff --git a/src/lib/feature/shell/navbar/commands/Commands.svelte b/src/lib/feature/shell/navbar/commands/Commands.svelte index d2d43a9c..66012a12 100644 --- a/src/lib/feature/shell/navbar/commands/Commands.svelte +++ b/src/lib/feature/shell/navbar/commands/Commands.svelte @@ -11,7 +11,7 @@ import EndPlaceholder from '$lib/ui/layout/EndPlaceholder.svelte' import { TextInput } from '$lib/ui/kit' import { onMount } from 'svelte' - import { Home, Icon } from '@xylightdev/svelte-hero-icons' + import { Icon, House } from '$lib/ui/kit/icon' import { type Action, type Group, @@ -242,7 +242,7 @@ class="text-[13px] font-medium text-slate-600 dark:text-zinc-400" onclick={goBack} > - + {#each breadcrumbs as crumb} / diff --git a/src/lib/feature/shell/navbar/commands/actions.svelte.ts b/src/lib/feature/shell/navbar/commands/actions.svelte.ts index b2b7a2e3..f1a57462 100644 --- a/src/lib/feature/shell/navbar/commands/actions.svelte.ts +++ b/src/lib/feature/shell/navbar/commands/actions.svelte.ts @@ -10,30 +10,29 @@ import { TIMEFRAME_OPTIONS } from '$lib/api/coves/sort' import { theme, type ThemeData } from '$lib/app/state/theme/theme.svelte' import type { ResumableItem } from '$lib/feature/legacy/item.svelte' import { - ArrowRightOnRectangle, - ChartBar, + type IconSource, + ChartColumn, + CircleUser, Clock, - Cog6Tooth, - ComputerDesktop, - Fire, - GlobeAlt, - GlobeAmericas, - Home, + Columns3, + Earth, + Flame, + Compass, + House, + LogIn, + Monitor, Moon, Newspaper, - PaintBrush, - PencilSquare, + Paintbrush, + Settings, Sparkles, + SquarePen, Star, Sun, - Swatch, + SwatchBook, Trophy, - UserCircle, - UserGroup, - ViewColumns, - type IconSource, -} from '@xylightdev/svelte-hero-icons' - + Users, +} from '$lib/ui/kit/icon' export interface Group { name: string actions: Action[] @@ -62,7 +61,7 @@ export function getGroups( name: t.get('nav.commands.recents'), actions: resumables.map((r) => ({ name: r.name, - icon: r.avatar ?? PencilSquare, + icon: r.avatar ?? SquarePen, href: r.url, })), }, @@ -73,11 +72,11 @@ export function getGroups( { name: t.get('nav.commands.main'), actions: [ - { href: '/', name: t.get('nav.home'), icon: Home, shortcut: 'h' }, + { href: '/', name: t.get('nav.home'), icon: House, shortcut: 'h' }, { href: '/communities', name: t.get('nav.communities'), - icon: GlobeAlt, + icon: Compass, }, ], }, @@ -86,11 +85,11 @@ export function getGroups( actions: [ { name: t.get('filter.feed.label'), - icon: GlobeAmericas, + icon: Earth, subActions: [ { name: t.get('filter.feed.discover'), - icon: GlobeAmericas, + icon: Earth, href: '/?type=discover', }, { @@ -102,11 +101,11 @@ export function getGroups( }, { name: t.get('filter.sort.label'), - icon: ChartBar, + icon: ChartColumn, subActions: [ { name: t.get('filter.sort.hot'), - icon: Fire, + icon: Flame, href: '/?sort=hot', }, { @@ -135,29 +134,29 @@ export function getGroups( { href: `/profile/${encodeURIComponent(profile.handle)}`, name: t.get('profile.profile'), - icon: UserCircle, + icon: CircleUser, }, { href: '/accounts', name: t.get('account.accounts'), - icon: UserGroup, + icon: Users, }, { href: '/login', name: t.get('account.login'), - icon: ArrowRightOnRectangle, + icon: LogIn, }, ] : [ { href: '/login', name: t.get('account.login'), - icon: ArrowRightOnRectangle, + icon: LogIn, }, { href: '/accounts', name: t.get('account.accounts'), - icon: UserGroup, + icon: Users, }, ], }, @@ -165,7 +164,7 @@ export function getGroups( name: t.get('account.accounts'), actions: profiles.map((p) => ({ name: p.handle ?? t.get('account.guest'), - icon: p.avatar ?? UserCircle, + icon: p.avatar ?? CircleUser, detail: p.instance, handle: async () => { if (profile.id != p.id) { @@ -184,38 +183,38 @@ export function getGroups( { href: '/settings', name: t.get('nav.menu.settings'), - icon: Cog6Tooth, + icon: Settings, }, { name: t.get('nav.commands.setView'), - icon: ViewColumns, + icon: Columns3, subActions: [ { name: t.get('nav.commands.setViewTo', { default: t.get('filter.view.compact'), }), - icon: ViewColumns, + icon: Columns3, handle: () => (settings.view = 'compact'), }, { name: t.get('nav.commands.setViewTo', { default: t.get('filter.view.cozy'), }), - icon: ViewColumns, + icon: Columns3, handle: () => (settings.view = 'cozy'), }, ], }, { name: t.get('nav.commands.setColor'), - icon: PaintBrush, + icon: Paintbrush, subActions: [ { name: t.get('nav.commands.setColorTo', { default: t.get('nav.menu.colorscheme.system'), }), handle: () => (theme.colorScheme = 'system'), - icon: ComputerDesktop, + icon: Monitor, }, { name: t.get('nav.commands.setColorTo', { @@ -235,10 +234,10 @@ export function getGroups( }, { name: t.get('nav.commands.setTheme'), - icon: Swatch, + icon: SwatchBook, subActions: td.themes.map((th) => ({ name: t.get('nav.commands.setThemeTo', { default: th.name }), - icon: Swatch, + icon: SwatchBook, handle: () => (theme.data.currentTheme = th.id), })), }, @@ -250,7 +249,7 @@ export function getGroups( { href: '/create/post', name: t.get('form.post.create'), - icon: PencilSquare, + icon: SquarePen, }, ], }, diff --git a/src/lib/feature/user/PictrsImage.svelte b/src/lib/feature/user/PictrsImage.svelte index d3552ee1..94ee103f 100644 --- a/src/lib/feature/user/PictrsImage.svelte +++ b/src/lib/feature/user/PictrsImage.svelte @@ -7,7 +7,7 @@ import { publishedToDate } from '$lib/ui/util/date' import { action, Button, modal, toast } from '$lib/ui/kit' import RelativeDate from '$lib/ui/util/RelativeDate.svelte' - import { ArrowDownTray, Trash } from '@xylightdev/svelte-hero-icons' + import { Download, Trash2 } from '$lib/ui/kit/icon' import UserLink from './UserLink.svelte' /** @@ -77,7 +77,7 @@ )}/pictrs/image/{image.pictrs_alias}" size="square-md" class="ml-auto" - icon={ArrowDownTray} + icon={Download} /> @@ -76,20 +70,19 @@
    {#if !p.jwt} - + {/if} {#if selected} {/if}
    {/each} - + {$t('account.accounts')} diff --git a/src/lib/feature/user/UserAutocomplete.svelte b/src/lib/feature/user/UserAutocomplete.svelte index 9abc266a..7968077c 100644 --- a/src/lib/feature/user/UserAutocomplete.svelte +++ b/src/lib/feature/user/UserAutocomplete.svelte @@ -5,7 +5,7 @@ import Avatar from '$lib/ui/generic/Avatar.svelte' import { log } from '$lib/app/util/log' import { MenuButton, Search } from '$lib/ui/kit' - import { Icon, XCircle } from '@xylightdev/svelte-hero-icons' + import { Icon, CircleX } from '$lib/ui/kit/icon' import { fly } from 'svelte/transition' interface Props { @@ -56,7 +56,7 @@
    {#if showWhenEmpty} onselect?.(undefined)}> - +
    None
    diff --git a/src/lib/feature/user/UserLink.svelte b/src/lib/feature/user/UserLink.svelte index 58f5236d..174fef18 100644 --- a/src/lib/feature/user/UserLink.svelte +++ b/src/lib/feature/user/UserLink.svelte @@ -4,11 +4,7 @@ import { userLink } from '$lib/app/util/links' import Avatar from '$lib/ui/generic/Avatar.svelte' import Logo from '$lib/ui/generic/Logo.svelte' - import { - Icon, - type IconSource, - Language, - } from '@xylightdev/svelte-hero-icons' + import { Icon, type IconSource, Languages } from '$lib/ui/kit/icon' import { userLabel } from './helpers' function parseBadge(): Record { @@ -46,7 +42,7 @@ return { classes: 'bg-linear-to-r bg-clip-text text-transparent from-sky-500 to-blue-700 dark:from-blue-300 dark:to-indigo-500', - icon: Language, + icon: Languages, iconClass: 'text-blue-500 dark:text-blue-400', } } @@ -116,7 +112,6 @@ {:else} diff --git a/src/lib/ui/form/ImageAttachForm.svelte b/src/lib/ui/form/ImageAttachForm.svelte index 9f56fe76..a8a94a33 100644 --- a/src/lib/ui/form/ImageAttachForm.svelte +++ b/src/lib/ui/form/ImageAttachForm.svelte @@ -5,7 +5,7 @@ import { t } from '$lib/app/state/i18n' import { uploadImage } from '$lib/api/upload' import { Button, toast } from '$lib/ui/kit' - import { DocumentPlus, Icon } from '@xylightdev/svelte-hero-icons' + import { Icon, FilePlus } from '$lib/ui/kit/icon' import { expoOut } from 'svelte/easing' import { slide } from 'svelte/transition' import ProgressBar from '../info/ProgressBar.svelte' @@ -103,7 +103,7 @@ class="flex flex-col justify-center w-full items-center gap-2 text-slate-600 dark:text-zinc-400" > - + {$t('form.post.selectFile')}
    {/if} diff --git a/src/lib/ui/form/ImageInputUpload.svelte b/src/lib/ui/form/ImageInputUpload.svelte index 29a8bbd9..5d32b401 100644 --- a/src/lib/ui/form/ImageInputUpload.svelte +++ b/src/lib/ui/form/ImageInputUpload.svelte @@ -1,7 +1,7 @@ {#snippet selectTarget(attachment: Attachment)} @@ -74,13 +85,28 @@ class={['space-y-1 relative max-w-full w-max min-w-0', baseClass]} > @@ -139,22 +171,23 @@ option.isLabel && 'text-xs mt-2', ]} > - {#if option.value == value} + {#if option.icon} - {:else if option.icon} + {/if} + {option.label} + {#if option.value == value} {/if} - {option.label}
    {/if} {/each} diff --git a/src/lib/ui/kit/forms/select/context.ts b/src/lib/ui/kit/forms/select/context.ts index fbdc26d9..7a1ce237 100644 --- a/src/lib/ui/kit/forms/select/context.ts +++ b/src/lib/ui/kit/forms/select/context.ts @@ -1,5 +1,4 @@ -import type { IconSource } from '@xylightdev/svelte-hero-icons' - +import type { IconSource } from '$lib/ui/kit/icon' export interface SelectOption { value: string label: string diff --git a/src/lib/ui/kit/icon/Icon.svelte b/src/lib/ui/kit/icon/Icon.svelte new file mode 100644 index 00000000..0d49a5e7 --- /dev/null +++ b/src/lib/ui/kit/icon/Icon.svelte @@ -0,0 +1,15 @@ + + + diff --git a/src/lib/ui/kit/icon/index.ts b/src/lib/ui/kit/icon/index.ts new file mode 100644 index 00000000..d37f334d --- /dev/null +++ b/src/lib/ui/kit/icon/index.ts @@ -0,0 +1,118 @@ +/** + * The Kelp icon vocabulary: every icon the app uses, re-exported from + * Lucide's per-icon paths so Vite only ever transforms the icons we ship. + * + * Names match Lucide's own (https://lucide.dev) — the set the mobile app is + * standardising on — so a glyph name means the same thing across Coves + * clients. Add icons here as they're needed. + */ +export { default as Icon } from './Icon.svelte' +export type { LucideIcon as IconSource } from '@lucide/svelte' + +export { default as Archive } from '@lucide/svelte/icons/archive' +export { default as ArrowDownWideNarrow } from '@lucide/svelte/icons/arrow-down-wide-narrow' +export { default as ArrowLeft } from '@lucide/svelte/icons/arrow-left' +export { default as ArrowRight } from '@lucide/svelte/icons/arrow-right' +export { default as ArrowRightLeft } from '@lucide/svelte/icons/arrow-right-left' +export { default as ArrowUpDown } from '@lucide/svelte/icons/arrow-up-down' +export { default as Ban } from '@lucide/svelte/icons/ban' +export { default as Bold } from '@lucide/svelte/icons/bold' +export { default as Bookmark } from '@lucide/svelte/icons/bookmark' +export { default as BookmarkX } from '@lucide/svelte/icons/bookmark-x' +export { default as Bug } from '@lucide/svelte/icons/bug' +export { default as Building } from '@lucide/svelte/icons/building' +export { default as Calendar } from '@lucide/svelte/icons/calendar' +export { default as ChartColumn } from '@lucide/svelte/icons/chart-column' +export { default as Check } from '@lucide/svelte/icons/check' +export { default as ChevronDown } from '@lucide/svelte/icons/chevron-down' +export { default as ChevronLeft } from '@lucide/svelte/icons/chevron-left' +export { default as ChevronRight } from '@lucide/svelte/icons/chevron-right' +export { default as ChevronUp } from '@lucide/svelte/icons/chevron-up' +export { default as ChevronsDown } from '@lucide/svelte/icons/chevrons-down' +export { default as ChevronsUp } from '@lucide/svelte/icons/chevrons-up' +export { default as ChevronsUpDown } from '@lucide/svelte/icons/chevrons-up-down' +export { default as CircleAlert } from '@lucide/svelte/icons/circle-alert' +export { default as CircleArrowDown } from '@lucide/svelte/icons/circle-arrow-down' +export { default as CircleArrowRight } from '@lucide/svelte/icons/circle-arrow-right' +export { default as CircleCheck } from '@lucide/svelte/icons/circle-check' +export { default as CircleHelp } from '@lucide/svelte/icons/circle-help' +export { default as CirclePlus } from '@lucide/svelte/icons/circle-plus' +export { default as CircleUser } from '@lucide/svelte/icons/circle-user' +export { default as CircleX } from '@lucide/svelte/icons/circle-x' +export { default as Clock } from '@lucide/svelte/icons/clock' +export { default as CloudDrizzle } from '@lucide/svelte/icons/cloud-drizzle' +export { default as Code } from '@lucide/svelte/icons/code' +export { default as Columns3 } from '@lucide/svelte/icons/columns-3' +export { default as Compass } from '@lucide/svelte/icons/compass' +export { default as Copy } from '@lucide/svelte/icons/copy' +export { default as CornerDownRight } from '@lucide/svelte/icons/corner-down-right' +export { default as Dock } from '@lucide/svelte/icons/dock' +export { default as Download } from '@lucide/svelte/icons/download' +export { default as Earth } from '@lucide/svelte/icons/earth' +export { default as Ellipsis } from '@lucide/svelte/icons/ellipsis' +export { default as Equal } from '@lucide/svelte/icons/equal' +export { default as ExternalLink } from '@lucide/svelte/icons/external-link' +export { default as FilePlus } from '@lucide/svelte/icons/file-plus' +export { default as FileText } from '@lucide/svelte/icons/file-text' +export { default as Flag } from '@lucide/svelte/icons/flag' +export { default as Flame } from '@lucide/svelte/icons/flame' +export { default as Forward } from '@lucide/svelte/icons/forward' +export { default as Globe } from '@lucide/svelte/icons/globe' +export { default as Heading1 } from '@lucide/svelte/icons/heading-1' +export { default as House } from '@lucide/svelte/icons/house' +export { default as IdCard } from '@lucide/svelte/icons/id-card' +export { default as Image } from '@lucide/svelte/icons/image' +export { default as Info } from '@lucide/svelte/icons/info' +export { default as Italic } from '@lucide/svelte/icons/italic' +export { default as Languages } from '@lucide/svelte/icons/languages' +export { default as LayoutList } from '@lucide/svelte/icons/layout-list' +export { default as Link } from '@lucide/svelte/icons/link' +export { default as List } from '@lucide/svelte/icons/list' +export { default as Lock } from '@lucide/svelte/icons/lock' +export { default as LogIn } from '@lucide/svelte/icons/log-in' +export { default as Mail } from '@lucide/svelte/icons/mail' +export { default as MapPin } from '@lucide/svelte/icons/map-pin' +export { default as Maximize2 } from '@lucide/svelte/icons/maximize-2' +export { default as Megaphone } from '@lucide/svelte/icons/megaphone' +export { default as Menu } from '@lucide/svelte/icons/menu' +export { default as MessageSquare } from '@lucide/svelte/icons/message-square' +export { default as MessageSquareMore } from '@lucide/svelte/icons/message-square-more' +export { default as MessageSquareText } from '@lucide/svelte/icons/message-square-text' +export { default as Mic } from '@lucide/svelte/icons/mic' +export { default as Minus } from '@lucide/svelte/icons/minus' +export { default as Monitor } from '@lucide/svelte/icons/monitor' +export { default as Moon } from '@lucide/svelte/icons/moon' +export { default as MousePointerClick } from '@lucide/svelte/icons/mouse-pointer-click' +export { default as Newspaper } from '@lucide/svelte/icons/newspaper' +export { default as Paintbrush } from '@lucide/svelte/icons/paintbrush' +export { default as Pencil } from '@lucide/svelte/icons/pencil' +export { default as Play } from '@lucide/svelte/icons/play' +export { default as Plus } from '@lucide/svelte/icons/plus' +export { default as Puzzle } from '@lucide/svelte/icons/puzzle' +export { default as QrCode } from '@lucide/svelte/icons/qr-code' +export { default as RefreshCw } from '@lucide/svelte/icons/refresh-cw' +export { default as Rows4 } from '@lucide/svelte/icons/rows-4' +export { default as Search } from '@lucide/svelte/icons/search' +export { default as Send } from '@lucide/svelte/icons/send' +export { default as Server } from '@lucide/svelte/icons/server' +export { default as Settings } from '@lucide/svelte/icons/settings' +export { default as SlidersHorizontal } from '@lucide/svelte/icons/sliders-horizontal' +export { default as Smartphone } from '@lucide/svelte/icons/smartphone' +export { default as Sparkles } from '@lucide/svelte/icons/sparkles' +export { default as SquarePen } from '@lucide/svelte/icons/square-pen' +export { default as Star } from '@lucide/svelte/icons/star' +export { default as Strikethrough } from '@lucide/svelte/icons/strikethrough' +export { default as Sun } from '@lucide/svelte/icons/sun' +export { default as SwatchBook } from '@lucide/svelte/icons/swatch-book' +export { default as Table } from '@lucide/svelte/icons/table' +export { default as Tablet } from '@lucide/svelte/icons/tablet' +export { default as Tag } from '@lucide/svelte/icons/tag' +export { default as Terminal } from '@lucide/svelte/icons/terminal' +export { default as Trash2 } from '@lucide/svelte/icons/trash-2' +export { default as TriangleAlert } from '@lucide/svelte/icons/triangle-alert' +export { default as Trophy } from '@lucide/svelte/icons/trophy' +export { default as Undo2 } from '@lucide/svelte/icons/undo-2' +export { default as Upload } from '@lucide/svelte/icons/upload' +export { default as Users } from '@lucide/svelte/icons/users' +export { default as Video } from '@lucide/svelte/icons/video' +export { default as X } from '@lucide/svelte/icons/x' diff --git a/src/lib/ui/kit/materials/Material.svelte b/src/lib/ui/kit/materials/Material.svelte index ee86f2a5..483aa467 100644 --- a/src/lib/ui/kit/materials/Material.svelte +++ b/src/lib/ui/kit/materials/Material.svelte @@ -1,5 +1,5 @@ @@ -12,7 +12,7 @@ class="w-max hover:underline text-slate-600 dark:text-zinc-400" onclick={() => history?.back()} > - + {$t('account.accounts')} diff --git a/src/routes/c/[handle=handle]/post/[rkey]/+page.svelte b/src/routes/c/[handle=handle]/post/[rkey]/+page.svelte index c8f2b619..6fd2e3d0 100644 --- a/src/routes/c/[handle=handle]/post/[rkey]/+page.svelte +++ b/src/routes/c/[handle=handle]/post/[rkey]/+page.svelte @@ -11,11 +11,7 @@ import { postTextFallback } from '$lib/feature/post/helpers' import Placeholder from '$lib/ui/info/Placeholder.svelte' import { Material, Spinner, toast } from '$lib/ui/kit' - import { - ChatBubbleOvalLeft, - Icon, - NoSymbol, - } from '@xylightdev/svelte-hero-icons' + import { Icon, Ban, MessageSquare } from '$lib/ui/kit/icon' import { tick } from 'svelte' import type { PageData } from './$types' @@ -185,7 +181,7 @@

    - + Comments {#if post.stats?.commentCount} @@ -226,7 +222,7 @@ {:else if data.data.value?.unavailable} {$t('comment.permalink.allComments')} @@ -93,7 +93,7 @@ href={commentLink(post, focused.parentUri)} rounding="pill" color="secondary" - icon={ArrowUturnUp} + icon={Undo2} > {$t('comment.permalink.context')} diff --git a/src/routes/c/[handle=handle]/settings/team/+page.svelte b/src/routes/c/[handle=handle]/settings/team/+page.svelte index 69219f29..7126c187 100644 --- a/src/routes/c/[handle=handle]/settings/team/+page.svelte +++ b/src/routes/c/[handle=handle]/settings/team/+page.svelte @@ -8,7 +8,7 @@ import Avatar from '$lib/ui/generic/Avatar.svelte' import { CommonList, Header } from '$lib/ui/layout' import { action, Button, modal, toast } from '$lib/ui/kit' - import { Icon, Plus, Trash } from '@xylightdev/svelte-hero-icons' + import { Icon, Plus, Trash2 } from '$lib/ui/kit/icon' import type { PageData } from '../$types' interface Props { @@ -122,7 +122,7 @@ }) }} > - + {/snippet} diff --git a/src/routes/explore/+layout.svelte b/src/routes/explore/+layout.svelte index b824c9e9..2cacdaa2 100644 --- a/src/routes/explore/+layout.svelte +++ b/src/routes/explore/+layout.svelte @@ -6,14 +6,13 @@ import { Option, Select } from '$lib/ui/kit' import { untrack } from 'svelte' import { - ChartBar, - Fire, Icon, - Language, + ChartColumn, + Flame, + Languages, Star, - UserGroup, - } from '@xylightdev/svelte-hero-icons' - + Users, + } from '$lib/ui/kit/icon' let { data, children } = $props() // Navigating within /explore re-runs load() but reuses this layout, so a @@ -74,16 +73,16 @@ > {#snippet customLabel()} - + {$t('filter.sort.label')} {/snippet} - - + + - + diff --git a/src/routes/explore/communities/+page.svelte b/src/routes/explore/communities/+page.svelte index 97dc1e38..58e6587c 100644 --- a/src/routes/explore/communities/+page.svelte +++ b/src/routes/explore/communities/+page.svelte @@ -8,7 +8,7 @@ import { CommonList } from '$lib/ui/layout' import EndPlaceholder from '$lib/ui/layout/EndPlaceholder.svelte' import { Material } from '$lib/ui/kit' - import { QuestionMarkCircle } from '@xylightdev/svelte-hero-icons' + import { CircleHelp } from '$lib/ui/kit/icon' import { expoOut } from 'svelte/easing' import { fly } from 'svelte/transition' @@ -40,7 +40,7 @@
      {#if data.communities.length == 0} diff --git a/src/routes/profile/(local_user)/blocks/communities/+page.svelte b/src/routes/profile/(local_user)/blocks/communities/+page.svelte index f97b1d03..2d618065 100644 --- a/src/routes/profile/(local_user)/blocks/communities/+page.svelte +++ b/src/routes/profile/(local_user)/blocks/communities/+page.svelte @@ -6,8 +6,7 @@ import ItemList from '$lib/ui/generic/ItemList.svelte' import Placeholder from '$lib/ui/info/Placeholder.svelte' import { Button } from '$lib/ui/kit' - import { ArrowUturnUp, Check, Trash } from '@xylightdev/svelte-hero-icons' - + import { Check, Trash2, Undo2 } from '$lib/ui/kit/icon' let { data } = $props() async function unblock(id: number) { @@ -41,13 +40,13 @@ size="square-md" href={block.url} color="primary" - icon={ArrowUturnUp} + icon={Undo2} /> diff --git a/src/routes/profile/[handle=actor]/+page.svelte b/src/routes/profile/[handle=actor]/+page.svelte index 22cfdb8a..8d5c65d0 100644 --- a/src/routes/profile/[handle=actor]/+page.svelte +++ b/src/routes/profile/[handle=actor]/+page.svelte @@ -11,11 +11,11 @@ import { Option, Select } from '$lib/ui/kit' import { formatRelativeDate } from '$lib/ui/util/RelativeDate.svelte' import { - AdjustmentsHorizontal, - ChatBubbleOvalLeft, Icon, - PencilSquare, - } from '@xylightdev/svelte-hero-icons' + MessageSquare, + SlidersHorizontal, + SquarePen, + } from '$lib/ui/kit/icon' import { type PageData } from './$types' import UserActions from './UserActions.svelte' @@ -100,7 +100,7 @@ > {#snippet customLabel()} - + {$t('filter.type')} {/snippet} @@ -123,7 +123,7 @@ {:else if filterType === 'posts'} @@ -140,7 +140,7 @@
      - + {#if comment.author} {:else} @@ -165,7 +165,7 @@
    {:else if filterType === 'comments'} @@ -174,14 +174,14 @@ {#if filterType === 'all' && posts.length === 0 && comments.length === 0} {/if} {:else} diff --git a/src/routes/profile/[handle=actor]/UserActions.svelte b/src/routes/profile/[handle=actor]/UserActions.svelte index 9c7c999a..80aa5fe1 100644 --- a/src/routes/profile/[handle=actor]/UserActions.svelte +++ b/src/routes/profile/[handle=actor]/UserActions.svelte @@ -8,13 +8,7 @@ import { t } from '$lib/app/state/i18n' import { Button, Menu, MenuButton, toast } from '$lib/ui/kit' import { untrack } from 'svelte' - import { - EllipsisHorizontal, - Envelope, - Icon, - NoSymbol, - } from '@xylightdev/svelte-hero-icons' - + import { Icon, Ban, Ellipsis, Mail } from '$lib/ui/kit/icon' interface Props { profile: ProfileViewDetailed } @@ -114,7 +108,7 @@ diff --git a/src/routes/settings/other/+page.svelte b/src/routes/settings/other/+page.svelte index 3481538b..97866718 100644 --- a/src/routes/settings/other/+page.svelte +++ b/src/routes/settings/other/+page.svelte @@ -2,19 +2,19 @@ import { t } from '$lib/app/state/i18n' import { settings } from '$lib/app/state/settings.svelte' import { CommonList } from '$lib/ui/layout' - import { Bars3, BugAnt } from '@xylightdev/svelte-hero-icons' + import { Bug, Menu } from '$lib/ui/kit/icon' import ToggleSetting from '../ToggleSetting.svelte' - + {$t('settings.import')} diff --git a/src/routes/theme/ThemePreset.svelte b/src/routes/theme/ThemePreset.svelte index 4aee812e..69cdd182 100644 --- a/src/routes/theme/ThemePreset.svelte +++ b/src/routes/theme/ThemePreset.svelte @@ -5,8 +5,7 @@ theme as themeData, } from '$lib/app/state/theme/theme.svelte' import { action, Button, Material, modal, TextInput } from '$lib/ui/kit' - import { CheckCircle, Icon, Trash } from '@xylightdev/svelte-hero-icons' - + import { Icon, CircleCheck, Trash2 } from '$lib/ui/kit/icon' interface Props { theme: Theme } @@ -42,9 +41,8 @@ {#if theme.id == themeData.data.currentTheme} {/if} @@ -106,7 +104,7 @@ title: $t('routes.theme.preset.delete.title'), }) }} - icon={Trash} + icon={Trash2} > {/if}