Compare commits

...

10 Commits

Author SHA1 Message Date
Ilia Mashkov
792b142c07 fix: delete unused types
Some checks failed
Lint / Lint Code (push) Failing after 7m18s
Test / Svelte Checks (push) Failing after 7m16s
2026-01-02 11:18:05 +03:00
Ilia Mashkov
e35c1cb6dd fix: edit typescript config to avoid import errors 2026-01-02 11:17:16 +03:00
Ilia Mashkov
a903554695 chore: adjust package version 2026-01-02 11:16:46 +03:00
Ilia Mashkov
6041ffd954 feat(api): create api instance 2026-01-02 11:15:20 +03:00
Ilia Mashkov
7bc0a690cb feat(CategoryFilter): create CategoryFilter component 2026-01-02 11:15:02 +03:00
Ilia Mashkov
e885560c45 feat(CheckboxFilter): create CheckboxFilter component 2026-01-02 11:14:15 +03:00
Ilia Mashkov
1ecbc9b9d7 feat(createFilterStore): create reusable function that creates store object for different filters 2026-01-02 11:13:22 +03:00
Ilia Mashkov
4a283213d4 feat(shadcn): add new shadcn components 2026-01-02 11:12:29 +03:00
Ilia Mashkov
fcc266f3a5 feat(font): move font models 2026-01-02 11:11:36 +03:00
Ilia Mashkov
879e8cd710 fix: format indentatation inside script tag 2026-01-02 11:11:04 +03:00
76 changed files with 965 additions and 142 deletions

Binary file not shown.

View File

@@ -22,6 +22,7 @@
"@playwright/test": "^1.57.0",
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@tailwindcss/vite": "^4.1.18",
"@tsconfig/svelte": "^5.0.6",
"bits-ui": "^2.14.4",
"clsx": "^2.1.1",
"dprint": "^0.50.2",
@@ -29,6 +30,7 @@
"oxlint": "^1.35.0",
"svelte": "^5.45.6",
"svelte-check": "^4.3.4",
"svelte-language-server": "^0.17.23",
"tailwind-merge": "^3.4.0",
"tailwind-variants": "^3.2.2",
"tailwindcss": "^4.1.18",

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import favicon from '$shared/assets/favicon.svg';
import favicon from '$shared/assets/favicon.svg';
import './app.css';
import Page from './routes/Page.svelte';
</script>
@@ -13,8 +13,8 @@ import Page from './routes/Page.svelte';
</div>
<style>
#app-root {
width: 100%;
height: 100vh;
}
#app-root {
width: 100%;
height: 100vh;
}
</style>

View File

@@ -1,5 +1,7 @@
import type { CollectionApiModel } from '../../../shared/types/collection';
export const FONTSHARE_API_URL = 'https://api.fontshare.com/v2' as const;
/**
* Model of Fontshare API response
* @see https://fontshare.com

View File

@@ -1,17 +1,37 @@
import type { FilterModel } from '$shared/store/createFilterStore';
/**
* Model of state for CategoryFilter
*/
export interface CategoryFilterStateModel {
/**
* Search query
*/
searchQuery?: string;
/**
* Categories
*/
categories: string[];
/**
* Selected categories
*/
selectedCategories: string[];
}
export type CategoryFilterModel = FilterModel;
export const FONT_CATEGORIES = [
{
id: 'serif',
name: 'Serif',
},
{
id: 'sans-serif',
name: 'Sans-serif',
},
{
id: 'display',
name: 'Display',
},
{
id: 'handwriting',
name: 'Handwriting',
},
{
id: 'monospace',
name: 'Monospace',
},
{
id: 'script',
name: 'Script',
},
{
id: 'slab',
name: 'Slab',
},
] as const;

View File

@@ -1,35 +1,16 @@
import { writable } from 'svelte/store';
import type { CategoryFilterStateModel } from '../model/state';
import { FONT_CATEGORIES } from '$entities/Font/model/font';
import { createFilterStore } from '$shared/store/createFilterStore';
import type { CategoryFilterModel } from '../model/state';
/**
* Initial state for CategoryFilter
*/
export const initialState: CategoryFilterStateModel = {
export const initialState: CategoryFilterModel = {
searchQuery: '',
categories: [],
selectedCategories: [],
categories: FONT_CATEGORIES,
};
const { subscribe, set, update } = writable<CategoryFilterStateModel>(initialState);
export const categoryFilterStore = {
subscribe,
set,
update,
/**
* Update the search query filter.
*
* @param searchQuery - Search text (undefined to clear)
*
* Learning Note:
* We use update() to modify the store based on current state.
* This is like a Redux reducer but without the boilerplate!
*/
setSearchQuery: (searchQuery: string | undefined) => {
update(state => ({
...state,
searchQuery: searchQuery || undefined,
}));
},
};
/**
* CategoryFilter store
*/
export const categoryFilterStore = createFilterStore(initialState);

View File

@@ -0,0 +1,20 @@
<script lang="ts">
import CheckboxFilter from '$shared/ui/CheckboxFilter/CheckboxFilter.svelte';
import { categoryFilterStore } from '../store/categoryFilterStore';
const { categories } = $derived($categoryFilterStore);
function didCategoryToggle(categoryId: string) {
if (categories?.find(category => category.id === categoryId)) {
categoryFilterStore.deselectCategory(categoryId);
} else {
categoryFilterStore.selectCategory(categoryId);
}
}
</script>
<CheckboxFilter
filterName="Font category"
categories={categories}
onCategoryToggle={didCategoryToggle}
/>

View File

@@ -1,9 +1,10 @@
<script>
import Button from '$shared/shadcn/ui/button/button.svelte';
import CategoryFilter from '$features/CategoryFilter/ui/CategoryFilter.svelte';
import Button from '$shared/shadcn/ui/button/button.svelte';
</script>
<h1>Welcome to Svelte + Vite</h1>
<p>
Visit <a href="https://svelte.dev/docs">svelte.dev/docs</a> to read the documentation
</p>
<Button>Click me!</Button>
<CategoryFilter />

61
src/shared/api/api.ts Normal file
View File

@@ -0,0 +1,61 @@
import type { ApiResponse } from '$shared/types/common';
export class ApiError extends Error {
constructor(
public status: number,
message: string,
public response?: Response,
) {
super(message);
this.name = 'ApiError';
}
}
async function request<T>(
url: string,
options?: RequestInit,
): Promise<ApiResponse<T>> {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
...options,
});
if (!response.ok) {
throw new ApiError(
response.status,
`Request failed: ${response.statusText}`,
response,
);
}
const data = await response.json() as T;
return {
data,
status: response.status,
};
}
export const api = {
get: <T>(url: string, options?: RequestInit) => request<T>(url, { ...options, method: 'GET' }),
post: <T>(url: string, body?: unknown, options?: RequestInit) =>
request<T>(url, {
...options,
method: 'POST',
body: JSON.stringify(body),
}),
put: <T>(url: string, body?: unknown, options?: RequestInit) =>
request<T>(url, {
...options,
method: 'PUT',
body: JSON.stringify(body),
}),
delete: <T>(url: string, options?: RequestInit) =>
request<T>(url, { ...options, method: 'DELETE' }),
};

View File

@@ -1,5 +1,5 @@
<script lang="ts" module>
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
import { tv, type VariantProps } from 'tailwind-variants';
@@ -45,7 +45,7 @@ export type ButtonProps =
</script>
<script lang="ts">
let {
let {
class: className,
variant = 'default',
size = 'default',

View File

@@ -0,0 +1,36 @@
<script lang="ts">
import { cn, type WithoutChildrenOrChild } from '$shared/shadcn/utils/shadcn-utils.js';
import CheckIcon from '@lucide/svelte/icons/check';
import MinusIcon from '@lucide/svelte/icons/minus';
import { Checkbox as CheckboxPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
checked = $bindable(false),
indeterminate = $bindable(false),
class: className,
...restProps
}: WithoutChildrenOrChild<CheckboxPrimitive.RootProps> = $props();
</script>
<CheckboxPrimitive.Root
bind:ref
data-slot="checkbox"
class={cn(
'border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-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 peer flex size-4 shrink-0 items-center justify-center rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
bind:checked
bind:indeterminate
{...restProps}
>
{#snippet children({ checked, indeterminate })}
<div data-slot="checkbox-indicator" class="text-current transition-none">
{#if checked}
<CheckIcon class="size-3.5" />
{:else if indeterminate}
<MinusIcon class="size-3.5" />
{/if}
</div>
{/snippet}
</CheckboxPrimitive.Root>

View File

@@ -0,0 +1,6 @@
import Root from './checkbox.svelte';
export {
Root,
//
Root as Checkbox,
};

View File

@@ -0,0 +1,7 @@
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: CollapsiblePrimitive.ContentProps = $props();
</script>
<CollapsiblePrimitive.Content bind:ref data-slot="collapsible-content" {...restProps} />

View File

@@ -0,0 +1,7 @@
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: CollapsiblePrimitive.TriggerProps = $props();
</script>
<CollapsiblePrimitive.Trigger bind:ref data-slot="collapsible-trigger" {...restProps} />

View File

@@ -0,0 +1,11 @@
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
let {
ref = $bindable(null),
open = $bindable(false),
...restProps
}: CollapsiblePrimitive.RootProps = $props();
</script>
<CollapsiblePrimitive.Root bind:ref bind:open data-slot="collapsible" {...restProps} />

View File

@@ -0,0 +1,13 @@
import Content from './collapsible-content.svelte';
import Trigger from './collapsible-trigger.svelte';
import Root from './collapsible.svelte';
export {
Content,
Content as CollapsibleContent,
Root,
//
Root as Collapsible,
Trigger,
Trigger as CollapsibleTrigger,
};

View File

@@ -0,0 +1,7 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: DialogPrimitive.CloseProps = $props();
</script>
<DialogPrimitive.Close bind:ref data-slot="dialog-close" {...restProps} />

View File

@@ -0,0 +1,45 @@
<script lang="ts">
import { cn, type WithoutChildrenOrChild } from '$shared/shadcn/utils/shadcn-utils.js';
import XIcon from '@lucide/svelte/icons/x';
import { Dialog as DialogPrimitive } from 'bits-ui';
import type { Snippet } from 'svelte';
import type { ComponentProps } from 'svelte';
import DialogPortal from './dialog-portal.svelte';
import * as Dialog from './index.js';
let {
ref = $bindable(null),
class: className,
portalProps,
children,
showCloseButton = true,
...restProps
}: WithoutChildrenOrChild<DialogPrimitive.ContentProps> & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof DialogPortal>>;
children: Snippet;
showCloseButton?: boolean;
} = $props();
</script>
<DialogPortal {...portalProps}>
<Dialog.Overlay />
<DialogPrimitive.Content
bind:ref
data-slot="dialog-content"
class={cn(
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
className,
)}
{...restProps}
>
{@render children?.()}
{#if showCloseButton}
<DialogPrimitive.Close
class="ring-offset-background focus:ring-ring absolute end-4 top-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
>
<XIcon />
<span class="sr-only">Close</span>
</DialogPrimitive.Close>
{/if}
</DialogPrimitive.Content>
</DialogPortal>

View File

@@ -0,0 +1,17 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as DialogPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: DialogPrimitive.DescriptionProps = $props();
</script>
<DialogPrimitive.Description
bind:ref
data-slot="dialog-description"
class={cn('text-muted-foreground text-sm', className)}
{...restProps}
/>

View File

@@ -0,0 +1,20 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="dialog-footer"
class={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -0,0 +1,20 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="dialog-header"
class={cn('flex flex-col gap-2 text-center sm:text-start', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -0,0 +1,20 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as DialogPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: DialogPrimitive.OverlayProps = $props();
</script>
<DialogPrimitive.Overlay
bind:ref
data-slot="dialog-overlay"
class={cn(
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
className,
)}
{...restProps}
/>

View File

@@ -0,0 +1,7 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
let { ...restProps }: DialogPrimitive.PortalProps = $props();
</script>
<DialogPrimitive.Portal {...restProps} />

View File

@@ -0,0 +1,17 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as DialogPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: DialogPrimitive.TitleProps = $props();
</script>
<DialogPrimitive.Title
bind:ref
data-slot="dialog-title"
class={cn('text-lg leading-none font-semibold', className)}
{...restProps}
/>

View File

@@ -0,0 +1,7 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: DialogPrimitive.TriggerProps = $props();
</script>
<DialogPrimitive.Trigger bind:ref data-slot="dialog-trigger" {...restProps} />

View File

@@ -0,0 +1,7 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
let { open = $bindable(false), ...restProps }: DialogPrimitive.RootProps = $props();
</script>
<DialogPrimitive.Root bind:open {...restProps} />

View File

@@ -0,0 +1,34 @@
import Close from './dialog-close.svelte';
import Content from './dialog-content.svelte';
import Description from './dialog-description.svelte';
import Footer from './dialog-footer.svelte';
import Header from './dialog-header.svelte';
import Overlay from './dialog-overlay.svelte';
import Portal from './dialog-portal.svelte';
import Title from './dialog-title.svelte';
import Trigger from './dialog-trigger.svelte';
import Root from './dialog.svelte';
export {
Close,
Close as DialogClose,
Content,
Content as DialogContent,
Description,
Description as DialogDescription,
Footer,
Footer as DialogFooter,
Header,
Header as DialogHeader,
Overlay,
Overlay as DialogOverlay,
Portal,
Portal as DialogPortal,
Root,
//
Root as Dialog,
Title,
Title as DialogTitle,
Trigger,
Trigger as DialogTrigger,
};

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLInputAttributes, HTMLInputTypeAttribute } from 'svelte/elements';
type InputType = Exclude<HTMLInputTypeAttribute, 'file'>;

View File

@@ -0,0 +1,7 @@
import Root from './label.svelte';
export {
Root,
//
Root as Label,
};

View File

@@ -0,0 +1,20 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Label as LabelPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: LabelPrimitive.RootProps = $props();
</script>
<LabelPrimitive.Root
bind:ref
data-slot="label"
class={cn(
'flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
className,
)}
{...restProps}
/>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Separator as SeparatorPrimitive } from 'bits-ui';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from 'bits-ui';
import { Dialog as SheetPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: SheetPrimitive.CloseProps = $props();
</script>

View File

@@ -1,5 +1,5 @@
<script lang="ts" module>
import { tv, type VariantProps } from 'tailwind-variants';
import { tv, type VariantProps } from 'tailwind-variants';
export const sheetVariants = tv({
base:
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
@@ -23,7 +23,7 @@ export type Side = VariantProps<typeof sheetVariants>['side'];
</script>
<script lang="ts">
import { cn, type WithoutChildrenOrChild } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithoutChildrenOrChild } from '$shared/shadcn/utils/shadcn-utils.js';
import XIcon from '@lucide/svelte/icons/x';
import { Dialog as SheetPrimitive } from 'bits-ui';
import type { Snippet } from 'svelte';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as SheetPrimitive } from 'bits-ui';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as SheetPrimitive } from 'bits-ui';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from 'bits-ui';
import { Dialog as SheetPrimitive } from 'bits-ui';
let { ...restProps }: SheetPrimitive.PortalProps = $props();
</script>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as SheetPrimitive } from 'bits-ui';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from 'bits-ui';
import { Dialog as SheetPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: SheetPrimitive.TriggerProps = $props();
</script>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from 'bits-ui';
import { Dialog as SheetPrimitive } from 'bits-ui';
let { open = $bindable(false), ...restProps }: SheetPrimitive.RootProps = $props();
</script>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLButtonAttributes } from 'svelte/elements';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Input } from '$shared/shadcn/input/index.js';
import { Input } from '$shared/shadcn/input/index.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import type { ComponentProps } from 'svelte';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLButtonAttributes } from 'svelte/elements';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts" module>
import { tv, type VariantProps } from 'tailwind-variants';
import { tv, type VariantProps } from 'tailwind-variants';
export const sidebarMenuButtonVariants = tv({
base:
@@ -29,7 +29,7 @@ export type SidebarMenuButtonSize = VariantProps<typeof sidebarMenuButtonVariant
</script>
<script lang="ts">
import * as Tooltip from '$shared/shadcn/tooltip/index.js';
import * as Tooltip from '$shared/shadcn/tooltip/index.js';
import {
cn,
type WithElementRef,

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Skeleton } from '$shared/shadcn/skeleton/index.js';
import { Skeleton } from '$shared/shadcn/skeleton/index.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLAnchorAttributes } from 'svelte/elements';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import * as Tooltip from '$shared/shadcn/tooltip/index.js';
import * as Tooltip from '$shared/shadcn/tooltip/index.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
import {

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
import { useSidebar } from './context.svelte.js';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Separator } from '$shared/shadcn/separator/index.js';
import { Separator } from '$shared/shadcn/separator/index.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import type { ComponentProps } from 'svelte';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Button } from '$shared/shadcn/button/index.js';
import { Button } from '$shared/shadcn/button/index.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import PanelLeftIcon from '@lucide/svelte/icons/panel-left';
import type { ComponentProps } from 'svelte';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import * as Sheet from '$shared/shadcn/sheet/index.js';
import * as Sheet from '$shared/shadcn/sheet/index.js';
import { cn, type WithElementRef } from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
import { SIDEBAR_WIDTH_MOBILE } from './constants.js';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import {
import {
cn,
type WithElementRef,
type WithoutChildren,

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import type { WithoutChildrenOrChild } from '$shared/shadcn/utils/shadcn-utils.js';
import { Tooltip as TooltipPrimitive } from 'bits-ui';
import type { ComponentProps } from 'svelte';

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Tooltip as TooltipPrimitive } from 'bits-ui';
import { Tooltip as TooltipPrimitive } from 'bits-ui';
let { ...restProps }: TooltipPrimitive.PortalProps = $props();
</script>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Tooltip as TooltipPrimitive } from 'bits-ui';
import { Tooltip as TooltipPrimitive } from 'bits-ui';
let { ...restProps }: TooltipPrimitive.ProviderProps = $props();
</script>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Tooltip as TooltipPrimitive } from 'bits-ui';
import { Tooltip as TooltipPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: TooltipPrimitive.TriggerProps = $props();
</script>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Tooltip as TooltipPrimitive } from 'bits-ui';
import { Tooltip as TooltipPrimitive } from 'bits-ui';
let { open = $bindable(false), ...restProps }: TooltipPrimitive.RootProps = $props();
</script>

View File

@@ -1,4 +1,4 @@
import { derived, Readable, Writable, writable } from 'svelte/store';
import { derived, type Readable, type Writable, writable } from 'svelte/store';
export interface Category {
/**
@@ -12,7 +12,7 @@ export interface Category {
/**
* Category selected state
*/
selected: boolean;
selected?: boolean;
}
export interface FilterModel {
@@ -35,6 +35,11 @@ export interface FilterStore<T extends FilterModel> extends Writable<T> {
* @returns Readable store with filter data
*/
getStore: () => Readable<T>;
/**
* Get all categories.
* @returns Readable store with categories
*/
getAllCategories: () => Readable<Category[]>;
/**
* Get the selected categories.
* @returns Readable store with selected categories
@@ -83,7 +88,7 @@ export interface FilterStore<T extends FilterModel> extends Writable<T> {
* @returns FilterStore<T>
*/
export function createFilterStore<T extends FilterModel>(
initialState: T,
initialState?: T,
): FilterStore<T> {
const { subscribe, set, update } = writable<T>(initialState);
@@ -103,6 +108,14 @@ export function createFilterStore<T extends FilterModel>(
subscribe,
};
},
/**
* Get the filtered categories.
*/
getAllCategories: () => {
return derived({ subscribe }, $store => {
return $store.categories;
});
},
/**
* Get the selected categories.
*/

View File

@@ -1,37 +1,4 @@
/**
* Model of response with error
*/
export interface ApiErrorResponse {
/**
* Error text
*/
error: string;
/**
* Status
*/
status: number;
/**
* Status text
*/
statusText: string;
}
/**
* Model of response with success
*/
export interface ApiSuccessResponse<T> {
/**
* Data
*/
export interface ApiResponse<T> {
data: T;
/**
* Status
*/
status: number;
/**
* Status text
*/
statusText: string;
}
export type ApiResponse<T> = ApiErrorResponse | ApiSuccessResponse<T>;

View File

@@ -0,0 +1,98 @@
<script lang="ts">
import { buttonVariants } from '$shared/shadcn/ui/button';
import { Checkbox } from '$shared/shadcn/ui/checkbox';
import * as Collapsible from '$shared/shadcn/ui/collapsible';
import { Label } from '$shared/shadcn/ui/label';
import type { Category } from '$shared/store/createFilterStore';
import ChevronsUpDownIcon from '@lucide/svelte/icons/chevrons-up-down';
import { onMount } from 'svelte';
import { flip } from 'svelte/animate';
import { blur } from 'svelte/transition';
interface CategoryFilterProps {
/**
* Displayed filter name
*/
filterName: string;
/**
* List of filter categories
*/
categories: Category[];
/**
* Callback for category toggle event
*/
onCategoryToggle: (id: string) => void;
}
const { filterName, categories, onCategoryToggle }: CategoryFilterProps = $props();
// Track collapsible state for animations
let isOpen = $state(true);
// Respect user's motion preferences for accessibility
let prefersReducedMotion = $state(false);
onMount(() => {
if (typeof window !== 'undefined') {
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
prefersReducedMotion = mediaQuery.matches;
// Listen for changes in motion preference
const handleChange = (e: MediaQueryListEvent) => {
prefersReducedMotion = e.matches;
};
mediaQuery.addEventListener('change', handleChange);
return () => {
mediaQuery.removeEventListener('change', handleChange);
};
}
});
// Reactive animation configurations
const blurConfig = $derived({
duration: prefersReducedMotion ? 0 : 250,
amount: 5,
opacity: 0.5,
});
const checkboxFlipConfig = $derived({
duration: prefersReducedMotion ? 0 : 300,
});
</script>
<Collapsible.Root bind:open={isOpen} class="space-y-2">
<div class="flex items-center justify-between space-x-4 px-4">
<Collapsible.Trigger
class={buttonVariants({ variant: 'ghost', size: 'sm', class: 'w-fit' })}
>
<h4 class="text-sm font-semibold">{filterName}</h4>
<ChevronsUpDownIcon class="h-4 w-4" />
</Collapsible.Trigger>
</div>
<Collapsible.Content>
{#if isOpen}
<div transition:blur|local={blurConfig} class="px-4 py-2">
<div class="flex flex-col gap-2">
{#each categories as category (category.id)}
<div class="flex items-center gap-3" animate:flip={checkboxFlipConfig}>
<Checkbox
id={category.id}
onCheckedChange={() => onCategoryToggle(category.id)}
class="cursor-pointer transition-transform active:scale-95"
/>
<Label
for={category.id}
class="cursor-pointer transition-colors hover:text-foreground/80"
>
{category.name}
</Label>
</div>
{/each}
</div>
</div>
{/if}
</Collapsible.Content>
</Collapsible.Root>

View File

@@ -1,9 +1,11 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ESNext",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"types": ["svelte"],
/* Strictness & Safety */
"strict": true,
@@ -15,6 +17,8 @@
"skipLibCheck": true,
"sourceMap": true,
"isolatedModules": true,
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
/* Path Aliases */
"baseUrl": ".",

368
yarn.lock
View File

@@ -5,6 +5,16 @@ __metadata:
version: 8
cacheKey: 10c0
"@ampproject/remapping@npm:^2.2.1":
version: 2.3.0
resolution: "@ampproject/remapping@npm:2.3.0"
dependencies:
"@jridgewell/gen-mapping": "npm:^0.3.5"
"@jridgewell/trace-mapping": "npm:^0.3.24"
checksum: 10c0/81d63cca5443e0f0c72ae18b544cc28c7c0ec2cea46e7cb888bb0e0f411a1191d0d6b7af798d54e30777d8d1488b2ec0732aac2be342d3d7d3ffd271c6f489ed
languageName: node
linkType: hard
"@dprint/darwin-arm64@npm:0.50.2":
version: 0.50.2
resolution: "@dprint/darwin-arm64@npm:0.50.2"
@@ -68,6 +78,31 @@ __metadata:
languageName: node
linkType: hard
"@emmetio/abbreviation@npm:^2.3.3":
version: 2.3.3
resolution: "@emmetio/abbreviation@npm:2.3.3"
dependencies:
"@emmetio/scanner": "npm:^1.0.4"
checksum: 10c0/835b460706d5920a6f9a569a44b7d98e88d5530e3983af3678b44fa38b4cbdf68b5df933476d72e340779b16e7e7962ffa63142db8d2f59b1175a11c30c14635
languageName: node
linkType: hard
"@emmetio/css-abbreviation@npm:^2.1.8":
version: 2.1.8
resolution: "@emmetio/css-abbreviation@npm:2.1.8"
dependencies:
"@emmetio/scanner": "npm:^1.0.4"
checksum: 10c0/b5b3b39e773185d848b634e48e1b520e6ebffd28bfd0ba34fbcf877ca77e0edb8c7bbf58230cb0621f80f579bd7fd0265f00ab5e09ac482a835897cbdb6182a6
languageName: node
linkType: hard
"@emmetio/scanner@npm:^1.0.4":
version: 1.0.4
resolution: "@emmetio/scanner@npm:1.0.4"
checksum: 10c0/ae6244e563caaff0f88d7afefc33fd6cfb7cc767ce914b54d35b46002637948cfc65951dba6d6941328afa54c721c225836fafce2de40fb7643660ba09fe7372
languageName: node
linkType: hard
"@emnapi/core@npm:^1.7.1":
version: 1.7.1
resolution: "@emnapi/core@npm:1.7.1"
@@ -372,7 +407,7 @@ __metadata:
languageName: node
linkType: hard
"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
"@jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
version: 0.3.31
resolution: "@jridgewell/trace-mapping@npm:0.3.31"
dependencies:
@@ -856,6 +891,13 @@ __metadata:
languageName: node
linkType: hard
"@tsconfig/svelte@npm:^5.0.6":
version: 5.0.6
resolution: "@tsconfig/svelte@npm:5.0.6"
checksum: 10c0/0b382dd946e516271a97ee72c513bc509a5fd8f2d7ba9b315cf4b8d85a1796f4e043fd8e2a01c90b652e528a7cfd243f65ef373c18299a90872f602c5f93683e
languageName: node
linkType: hard
"@tybys/wasm-util@npm:^0.10.1":
version: 0.10.1
resolution: "@tybys/wasm-util@npm:0.10.1"
@@ -865,13 +907,34 @@ __metadata:
languageName: node
linkType: hard
"@types/estree@npm:1.0.8, @types/estree@npm:^1.0.5, @types/estree@npm:^1.0.6":
"@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.1, @types/estree@npm:^1.0.5, @types/estree@npm:^1.0.6":
version: 1.0.8
resolution: "@types/estree@npm:1.0.8"
checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5
languageName: node
linkType: hard
"@vscode/emmet-helper@npm:2.8.4":
version: 2.8.4
resolution: "@vscode/emmet-helper@npm:2.8.4"
dependencies:
emmet: "npm:^2.3.0"
jsonc-parser: "npm:^2.3.0"
vscode-languageserver-textdocument: "npm:^1.0.1"
vscode-languageserver-types: "npm:^3.15.1"
vscode-nls: "npm:^5.0.0"
vscode-uri: "npm:^2.1.2"
checksum: 10c0/775d49361c587eec5727ceff49299307cd3ecfc704ce75084c6ed077b4056a980049e5da72900f851d4a21f99fc81b876a7bc5a8f31ec6609d32dd2fe587ca50
languageName: node
linkType: hard
"@vscode/l10n@npm:^0.0.18":
version: 0.0.18
resolution: "@vscode/l10n@npm:0.0.18"
checksum: 10c0/d1fc797001f7d508ab3fa91175f7a50ea98516c4e47830ff2be79163cde9279279514a167a3bad15b7ab7fc243e7808d8f32d3eb41f4a7d6721d9dfdbb38d89e
languageName: node
linkType: hard
"abbrev@npm:^4.0.0":
version: 4.0.0
resolution: "abbrev@npm:4.0.0"
@@ -879,7 +942,7 @@ __metadata:
languageName: node
linkType: hard
"acorn@npm:^8.12.1":
"acorn@npm:^8.10.0, acorn@npm:^8.12.1, acorn@npm:^8.9.0":
version: 8.15.0
resolution: "acorn@npm:8.15.0"
bin:
@@ -895,14 +958,14 @@ __metadata:
languageName: node
linkType: hard
"aria-query@npm:^5.3.1":
"aria-query@npm:^5.3.0, aria-query@npm:^5.3.1":
version: 5.3.2
resolution: "aria-query@npm:5.3.2"
checksum: 10c0/003c7e3e2cff5540bf7a7893775fc614de82b0c5dde8ae823d47b7a28a9d4da1f7ed85f340bdb93d5649caa927755f0e31ecc7ab63edfdfc00c8ef07e505e03e
languageName: node
linkType: hard
"axobject-query@npm:^4.1.0":
"axobject-query@npm:^4.0.0, axobject-query@npm:^4.1.0":
version: 4.1.0
resolution: "axobject-query@npm:4.1.0"
checksum: 10c0/c470e4f95008f232eadd755b018cb55f16c03ccf39c027b941cd8820ac6b68707ce5d7368a46756db4256fbc91bb4ead368f84f7fb034b2b7932f082f6dc0775
@@ -968,6 +1031,29 @@ __metadata:
languageName: node
linkType: hard
"code-red@npm:^1.0.3":
version: 1.0.4
resolution: "code-red@npm:1.0.4"
dependencies:
"@jridgewell/sourcemap-codec": "npm:^1.4.15"
"@types/estree": "npm:^1.0.1"
acorn: "npm:^8.10.0"
estree-walker: "npm:^3.0.3"
periscopic: "npm:^3.1.0"
checksum: 10c0/1309f062369ae520c422d7f45b93190faea2cbc7e3fe3375918f36bb394030d0936d940601426564c30abc71b8aa8e6d1505cccd67a8620183fb01c84bcb7304
languageName: node
linkType: hard
"css-tree@npm:^2.3.1":
version: 2.3.1
resolution: "css-tree@npm:2.3.1"
dependencies:
mdn-data: "npm:2.0.30"
source-map-js: "npm:^1.0.1"
checksum: 10c0/6f8c1a11d5e9b14bf02d10717fc0351b66ba12594166f65abfbd8eb8b5b490dd367f5c7721db241a3c792d935fc6751fbc09f7e1598d421477ad9fadc30f4f24
languageName: node
linkType: hard
"debug@npm:4, debug@npm:^4.3.4, debug@npm:^4.4.1":
version: 4.4.3
resolution: "debug@npm:4.4.3"
@@ -980,6 +1066,13 @@ __metadata:
languageName: node
linkType: hard
"dedent-js@npm:^1.0.1":
version: 1.0.1
resolution: "dedent-js@npm:1.0.1"
checksum: 10c0/a8cff2e02d5a1ce64615c5c53c9789e7ef1abb9ae7bf2322dc991fcbaf08d901ace1a679c1e021de15a85db7787b8ccfb02011e1f394afef0f698fc857a47009
languageName: node
linkType: hard
"deepmerge@npm:^4.3.1":
version: 4.3.1
resolution: "deepmerge@npm:4.3.1"
@@ -1046,6 +1139,16 @@ __metadata:
languageName: node
linkType: hard
"emmet@npm:^2.3.0":
version: 2.4.11
resolution: "emmet@npm:2.4.11"
dependencies:
"@emmetio/abbreviation": "npm:^2.3.3"
"@emmetio/css-abbreviation": "npm:^2.1.8"
checksum: 10c0/4099d9d0d5dee766603c4ea03e1b87296bd397a0e8c6d8d5d6dcfdaad3e4581df5d48939a00eb4437dc08c83e857e231222ee037cb34ad63b1f2cce4041c6fc2
languageName: node
linkType: hard
"encoding@npm:^0.1.13":
version: 0.1.13
resolution: "encoding@npm:0.1.13"
@@ -1184,6 +1287,22 @@ __metadata:
languageName: node
linkType: hard
"estree-walker@npm:^2.0.1":
version: 2.0.2
resolution: "estree-walker@npm:2.0.2"
checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af
languageName: node
linkType: hard
"estree-walker@npm:^3.0.0, estree-walker@npm:^3.0.3":
version: 3.0.3
resolution: "estree-walker@npm:3.0.3"
dependencies:
"@types/estree": "npm:^1.0.0"
checksum: 10c0/c12e3c2b2642d2bcae7d5aa495c60fa2f299160946535763969a1c83fc74518ffa9c2cd3a8b69ac56aea547df6a8aac25f729a342992ef0bbac5f1c73e78995d
languageName: node
linkType: hard
"exponential-backoff@npm:^3.1.1":
version: 3.1.3
resolution: "exponential-backoff@npm:3.1.3"
@@ -1261,6 +1380,13 @@ __metadata:
languageName: node
linkType: hard
"globrex@npm:^0.1.2":
version: 0.1.2
resolution: "globrex@npm:0.1.2"
checksum: 10c0/a54c029520cf58bda1d8884f72bd49b4cd74e977883268d931fd83bcbd1a9eb96d57c7dbd4ad80148fb9247467ebfb9b215630b2ed7563b2a8de02e1ff7f89d1
languageName: node
linkType: hard
"glyphdiff@workspace:.":
version: 0.0.0-use.local
resolution: "glyphdiff@workspace:."
@@ -1270,6 +1396,7 @@ __metadata:
"@playwright/test": "npm:^1.57.0"
"@sveltejs/vite-plugin-svelte": "npm:^6.2.1"
"@tailwindcss/vite": "npm:^4.1.18"
"@tsconfig/svelte": "npm:^5.0.6"
bits-ui: "npm:^2.14.4"
clsx: "npm:^2.1.1"
dprint: "npm:^0.50.2"
@@ -1277,6 +1404,7 @@ __metadata:
oxlint: "npm:^1.35.0"
svelte: "npm:^5.45.6"
svelte-check: "npm:^4.3.4"
svelte-language-server: "npm:^0.17.23"
tailwind-merge: "npm:^3.4.0"
tailwind-variants: "npm:^3.2.2"
tailwindcss: "npm:^4.1.18"
@@ -1350,7 +1478,7 @@ __metadata:
languageName: node
linkType: hard
"is-reference@npm:^3.0.3":
"is-reference@npm:^3.0.0, is-reference@npm:^3.0.1, is-reference@npm:^3.0.3":
version: 3.0.3
resolution: "is-reference@npm:3.0.3"
dependencies:
@@ -1375,6 +1503,13 @@ __metadata:
languageName: node
linkType: hard
"jsonc-parser@npm:^2.3.0":
version: 2.3.1
resolution: "jsonc-parser@npm:2.3.1"
checksum: 10c0/b5e823612f6518a4d35e65d3c642e87b994c52a71b6d83d306d59f9b57003a1f6c64659808f0f1c3448991c28916d56faca45222f31ddb1a32effecdef0f0485
languageName: node
linkType: hard
"lefthook-darwin-arm64@npm:2.0.13":
version: 2.0.13
resolution: "lefthook-darwin-arm64@npm:2.0.13"
@@ -1613,6 +1748,13 @@ __metadata:
languageName: node
linkType: hard
"lodash@npm:^4.17.21":
version: 4.17.21
resolution: "lodash@npm:4.17.21"
checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c
languageName: node
linkType: hard
"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1":
version: 11.2.4
resolution: "lru-cache@npm:11.2.4"
@@ -1629,7 +1771,7 @@ __metadata:
languageName: node
linkType: hard
"magic-string@npm:^0.30.11, magic-string@npm:^0.30.17, magic-string@npm:^0.30.21":
"magic-string@npm:^0.30.11, magic-string@npm:^0.30.17, magic-string@npm:^0.30.21, magic-string@npm:^0.30.4":
version: 0.30.21
resolution: "magic-string@npm:0.30.21"
dependencies:
@@ -1657,6 +1799,13 @@ __metadata:
languageName: node
linkType: hard
"mdn-data@npm:2.0.30":
version: 2.0.30
resolution: "mdn-data@npm:2.0.30"
checksum: 10c0/a2c472ea16cee3911ae742593715aa4c634eb3d4b9f1e6ada0902aa90df13dcbb7285d19435f3ff213ebaa3b2e0c0265c1eb0e3fb278fda7f8919f046a410cd9
languageName: node
linkType: hard
"minimatch@npm:^10.1.1":
version: 10.1.1
resolution: "minimatch@npm:10.1.1"
@@ -1861,6 +2010,17 @@ __metadata:
languageName: node
linkType: hard
"periscopic@npm:^3.1.0":
version: 3.1.0
resolution: "periscopic@npm:3.1.0"
dependencies:
"@types/estree": "npm:^1.0.0"
estree-walker: "npm:^3.0.0"
is-reference: "npm:^3.0.0"
checksum: 10c0/fb5ce7cd810c49254cdf1cd3892811e6dd1a1dfbdf5f10a0a33fb7141baac36443c4cad4f0e2b30abd4eac613f6ab845c2bc1b7ce66ae9694c7321e6ada5bd96
languageName: node
linkType: hard
"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1":
version: 1.1.1
resolution: "picocolors@npm:1.1.1"
@@ -1910,6 +2070,25 @@ __metadata:
languageName: node
linkType: hard
"prettier-plugin-svelte@npm:^3.4.0":
version: 3.4.1
resolution: "prettier-plugin-svelte@npm:3.4.1"
peerDependencies:
prettier: ^3.0.0
svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0
checksum: 10c0/ae19ea425458ae26b79eba303a9dd9ffacfb17bf233fa9879a108d4be63929459b226d693e972514afd2fd3c9fa8ee31f9a1bb4749d6dce9012f70f282704c5d
languageName: node
linkType: hard
"prettier@npm:~3.3.3":
version: 3.3.3
resolution: "prettier@npm:3.3.3"
bin:
prettier: bin/prettier.cjs
checksum: 10c0/b85828b08e7505716324e4245549b9205c0cacb25342a030ba8885aba2039a115dbcf75a0b7ca3b37bc9d101ee61fab8113fc69ca3359f2a226f1ecc07ad2e26
languageName: node
linkType: hard
"proc-log@npm:^6.0.0":
version: 6.1.0
resolution: "proc-log@npm:6.1.0"
@@ -2055,7 +2234,14 @@ __metadata:
languageName: node
linkType: hard
"semver@npm:^7.3.5":
"scule@npm:^1.3.0":
version: 1.3.0
resolution: "scule@npm:1.3.0"
checksum: 10c0/5d1736daa10622c420f2aa74e60d3c722e756bfb139fa784ae5c66669fdfe92932d30ed5072e4ce3107f9c3053e35ad73b2461cb18de45b867e1d4dea63f8823
languageName: node
linkType: hard
"semver@npm:^7.3.5, semver@npm:^7.3.8":
version: 7.7.3
resolution: "semver@npm:7.7.3"
bin:
@@ -2092,7 +2278,7 @@ __metadata:
languageName: node
linkType: hard
"source-map-js@npm:^1.2.1":
"source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.1":
version: 1.2.1
resolution: "source-map-js@npm:1.2.1"
checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf
@@ -2135,6 +2321,35 @@ __metadata:
languageName: node
linkType: hard
"svelte-language-server@npm:^0.17.23":
version: 0.17.23
resolution: "svelte-language-server@npm:0.17.23"
dependencies:
"@jridgewell/trace-mapping": "npm:^0.3.25"
"@vscode/emmet-helper": "npm:2.8.4"
chokidar: "npm:^4.0.1"
estree-walker: "npm:^2.0.1"
fdir: "npm:^6.2.0"
globrex: "npm:^0.1.2"
lodash: "npm:^4.17.21"
prettier: "npm:~3.3.3"
prettier-plugin-svelte: "npm:^3.4.0"
svelte: "npm:^4.2.19"
svelte2tsx: "npm:~0.7.46"
typescript: "npm:^5.9.2"
typescript-auto-import-cache: "npm:^0.3.6"
vscode-css-languageservice: "npm:~6.3.5"
vscode-html-languageservice: "npm:~5.4.0"
vscode-languageserver: "npm:9.0.1"
vscode-languageserver-protocol: "npm:3.17.5"
vscode-languageserver-types: "npm:3.17.5"
vscode-uri: "npm:~3.1.0"
bin:
svelteserver: bin/server.js
checksum: 10c0/229e17c7c1845da0ef5f05380c9bb6cec83633c168546c70ee186f5b24994d733b4f9001fb0a005afea2a49c7e67acd6a70fda3a6f0594c57b83d5ec128b75e8
languageName: node
linkType: hard
"svelte-toolbelt@npm:^0.10.6":
version: 0.10.6
resolution: "svelte-toolbelt@npm:0.10.6"
@@ -2148,6 +2363,41 @@ __metadata:
languageName: node
linkType: hard
"svelte2tsx@npm:~0.7.46":
version: 0.7.46
resolution: "svelte2tsx@npm:0.7.46"
dependencies:
dedent-js: "npm:^1.0.1"
scule: "npm:^1.3.0"
peerDependencies:
svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0
typescript: ^4.9.4 || ^5.0.0
checksum: 10c0/b3c860bd9bd5b2de2f692c7561b8c17203dfb68a31f4ff19290ec5e68a5001db7666ec05a2ea1491730c332ea64d55ec3eef81a9f7748fb5a79947a4282ca026
languageName: node
linkType: hard
"svelte@npm:^4.2.19":
version: 4.2.20
resolution: "svelte@npm:4.2.20"
dependencies:
"@ampproject/remapping": "npm:^2.2.1"
"@jridgewell/sourcemap-codec": "npm:^1.4.15"
"@jridgewell/trace-mapping": "npm:^0.3.18"
"@types/estree": "npm:^1.0.1"
acorn: "npm:^8.9.0"
aria-query: "npm:^5.3.0"
axobject-query: "npm:^4.0.0"
code-red: "npm:^1.0.3"
css-tree: "npm:^2.3.1"
estree-walker: "npm:^3.0.3"
is-reference: "npm:^3.0.1"
locate-character: "npm:^3.0.0"
magic-string: "npm:^0.30.4"
periscopic: "npm:^3.1.0"
checksum: 10c0/b51d5d01aa363f47c1631b6f4160754221bc8d234146d3ddeea6172928ad6554acc925c2fb39c31e5cab77ba6711f1c49f4c79e2e592eb4df4eb418b8793a0f9
languageName: node
linkType: hard
"svelte@npm:^5.45.6":
version: 5.46.1
resolution: "svelte@npm:5.46.1"
@@ -2249,7 +2499,16 @@ __metadata:
languageName: node
linkType: hard
"typescript@npm:^5.9.3":
"typescript-auto-import-cache@npm:^0.3.6":
version: 0.3.6
resolution: "typescript-auto-import-cache@npm:0.3.6"
dependencies:
semver: "npm:^7.3.8"
checksum: 10c0/aad48d6aa9985f9a056c5c89ab91b6781c5430c0b80652586c2a997f2cc394f3ed70ec18c0c818a8423991a1cfe7e64d010cc2fded9ea192067a3188476c2b51
languageName: node
linkType: hard
"typescript@npm:^5.9.2, typescript@npm:^5.9.3":
version: 5.9.3
resolution: "typescript@npm:5.9.3"
bin:
@@ -2259,7 +2518,7 @@ __metadata:
languageName: node
linkType: hard
"typescript@patch:typescript@npm%3A^5.9.3#optional!builtin<compat/typescript>":
"typescript@patch:typescript@npm%3A^5.9.2#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A^5.9.3#optional!builtin<compat/typescript>":
version: 5.9.3
resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"
bin:
@@ -2354,6 +2613,93 @@ __metadata:
languageName: node
linkType: hard
"vscode-css-languageservice@npm:~6.3.5":
version: 6.3.9
resolution: "vscode-css-languageservice@npm:6.3.9"
dependencies:
"@vscode/l10n": "npm:^0.0.18"
vscode-languageserver-textdocument: "npm:^1.0.12"
vscode-languageserver-types: "npm:3.17.5"
vscode-uri: "npm:^3.1.0"
checksum: 10c0/bd796771a735e5ca8489a0830cb6d1880fadaaeb5ca6058ea58f3266f038dc9c9ccb8df1a80b30443b2c4f10f2544ab86a483bd46cdd9ba43f04e298f150155c
languageName: node
linkType: hard
"vscode-html-languageservice@npm:~5.4.0":
version: 5.4.0
resolution: "vscode-html-languageservice@npm:5.4.0"
dependencies:
"@vscode/l10n": "npm:^0.0.18"
vscode-languageserver-textdocument: "npm:^1.0.12"
vscode-languageserver-types: "npm:^3.17.5"
vscode-uri: "npm:^3.1.0"
checksum: 10c0/a67fafa723b55fd389d58b7105fd747ef79b9dd0b926e4b2169ca17655951a57904a7e02c4d4bdae2b01deaf37064583cec9a1b97d21a9e33b25fa19d4297e9a
languageName: node
linkType: hard
"vscode-jsonrpc@npm:8.2.0":
version: 8.2.0
resolution: "vscode-jsonrpc@npm:8.2.0"
checksum: 10c0/0789c227057a844f5ead55c84679206227a639b9fb76e881185053abc4e9848aa487245966cc2393fcb342c4541241b015a1a2559fddd20ac1e68945c95344e6
languageName: node
linkType: hard
"vscode-languageserver-protocol@npm:3.17.5":
version: 3.17.5
resolution: "vscode-languageserver-protocol@npm:3.17.5"
dependencies:
vscode-jsonrpc: "npm:8.2.0"
vscode-languageserver-types: "npm:3.17.5"
checksum: 10c0/5f38fd80da9868d706eaa4a025f4aff9c3faad34646bcde1426f915cbd8d7e8b6c3755ce3fef6eebd256ba3145426af1085305f8a76e34276d2e95aaf339a90b
languageName: node
linkType: hard
"vscode-languageserver-textdocument@npm:^1.0.1, vscode-languageserver-textdocument@npm:^1.0.12":
version: 1.0.12
resolution: "vscode-languageserver-textdocument@npm:1.0.12"
checksum: 10c0/534349894b059602c4d97615a1147b6c4c031141c2093e59657f54e38570f5989c21b376836f13b9375419869242e9efb4066643208b21ab1e1dee111a0f00fb
languageName: node
linkType: hard
"vscode-languageserver-types@npm:3.17.5, vscode-languageserver-types@npm:^3.15.1, vscode-languageserver-types@npm:^3.17.5":
version: 3.17.5
resolution: "vscode-languageserver-types@npm:3.17.5"
checksum: 10c0/1e1260de79a2cc8de3e46f2e0182cdc94a7eddab487db5a3bd4ee716f67728e685852707d72c059721ce500447be9a46764a04f0611e94e4321ffa088eef36f8
languageName: node
linkType: hard
"vscode-languageserver@npm:9.0.1":
version: 9.0.1
resolution: "vscode-languageserver@npm:9.0.1"
dependencies:
vscode-languageserver-protocol: "npm:3.17.5"
bin:
installServerIntoExtension: bin/installServerIntoExtension
checksum: 10c0/8a0838d77c98a211c76e54bd3a6249fc877e4e1a73322673fb0e921168d8e91de4f170f1d4ff7e8b6289d0698207afc6aba6662d4c1cd8e4bd7cae96afd6b0c2
languageName: node
linkType: hard
"vscode-nls@npm:^5.0.0":
version: 5.2.0
resolution: "vscode-nls@npm:5.2.0"
checksum: 10c0/dc9e48f58ebbc807f435d351008813a2ea0c9432d51e778bcac9163c0642f929ddb518411ad654e775ce31e24d6acfa8fb7db8893c05b42c2019894e08b050f9
languageName: node
linkType: hard
"vscode-uri@npm:^2.1.2":
version: 2.1.2
resolution: "vscode-uri@npm:2.1.2"
checksum: 10c0/4ed01e79f8caee5518d7dce567280001a00c87ff75c29421ac3693c735834f17950e79f818981c591e58c6efe681e13928470037b6ae75c948bec9b398e4c8db
languageName: node
linkType: hard
"vscode-uri@npm:^3.1.0, vscode-uri@npm:~3.1.0":
version: 3.1.0
resolution: "vscode-uri@npm:3.1.0"
checksum: 10c0/5f6c9c10fd9b1664d71fab4e9fbbae6be93c7f75bb3a1d9d74399a88ab8649e99691223fd7cef4644376cac6e94fa2c086d802521b9a8e31c5af3e60f0f35624
languageName: node
linkType: hard
"which@npm:^6.0.0":
version: 6.0.0
resolution: "which@npm:6.0.0"