style: format files with prettier and fix eslint issues

This commit is contained in:
HorizonCode committed 2026-10-31 21:27:28 +01:00
1 parent 7648d1fd4c
commit a2b03d3014
42 files changed
+639 -666

No files matched your search

@@ -10,7 +10,6 @@
import {
DEFAULT_DISCORD_PRESENCE_CONFIG,
DISCORD_PRESENCE_PRESETS,
discordPresenceCustomConfig,
interpolatePresenceString,
loadDiscordPresenceConfig,
pushIdlePresenceFromConfig,
@@ -25,14 +24,11 @@
Check,
Clock,
Code2,
Copy,
ExternalLink,
Eye,
Gamepad2,
Globe,
Home,
Image as ImageIcon,
Info,
Link,
LoaderCircle,
Maximize2,
@@ -41,10 +37,8 @@
Play,
Plus,
RotateCcw,
Save,
Sparkles,
Type,
User,
X,
} from '@lucide/svelte';
import { invoke } from '@tauri-apps/api/core';
@@ -101,8 +95,10 @@
// Preset selector
let selectedPresetName = $state<string>('EZPPFarm Default');
const SIM_MODES = ['osu!', 'taiko', 'catch', 'mania'] as const;
// Simulation parameters for preview
let simMode = $state<'osu!' | 'taiko' | 'catch' | 'mania'>('osu!');
let simMode = $state<(typeof SIM_MODES)[number]>('osu!');
let simAction = $state<string>('Playing...');
let simBeatmapIndex = $state<number>(0);
let simRank = $state<number>(1337);
@@ -206,7 +202,11 @@
if (standalone) {
try {
unlistenSync = await listen<any>('sync-theme-editor-global-data', (event) => {
unlistenSync = await listen<{
user?: Parameters<typeof currentUser.set>[0];
info?: Parameters<typeof currentUserInfo.set>[0];
launcherVersion?: string;
}>('sync-theme-editor-global-data', (event) => {
if (event.payload?.user) currentUser.set(event.payload.user);
if (event.payload?.info) currentUserInfo.set(event.payload.info);
if (event.payload?.launcherVersion) launcherVersion.set(event.payload.launcherVersion);
@@ -844,7 +844,7 @@
Details (First Line)
</Label>
<span class="text-[10px] text-muted-foreground"
>[{'{'}mode{'}'}] {'{'}action{'}'}</span
>[{'{'}mode}] {'{'}action}</span
>
</div>
<Input
@@ -852,7 +852,7 @@
bind:value={workingConfig.playingDetails}
onfocus={() => handleInputFocus('playingDetails')}
onblur={handleInputBlur}
placeholder="[{'{'}mode{'}'}] {'{'}action{'}'}"
placeholder="[{'{'}mode}] {'{'}action}"
class="h-8 bg-black/40 text-xs border-theme-800 focus:border-primary"
/>
</div>
@@ -862,14 +862,14 @@
<Label class="text-[11px] font-medium text-theme-200" for="playing-state">
State (Second Line)
</Label>
<span class="text-[10px] text-muted-foreground">{'{'}beatmap{'}'}</span>
<span class="text-[10px] text-muted-foreground">{'{'}beatmap}</span>
</div>
<Input
id="playing-state"
bind:value={workingConfig.playingState}
onfocus={() => handleInputFocus('playingState')}
onblur={handleInputBlur}
placeholder="{'{'}beatmap{'}'}"
placeholder="{'{'}beatmap}"
class="h-8 bg-black/40 text-xs border-theme-800 focus:border-primary"
/>
</div>
@@ -907,14 +907,14 @@
>
Cover Art Hover Tooltip
</Label>
<span class="text-[10px] text-muted-foreground">{'{'}beatmap{'}'}</span>
<span class="text-[10px] text-muted-foreground">{'{'}beatmap}</span>
</div>
<Input
id="playing-large-text"
bind:value={workingConfig.playingLargeImageText}
onfocus={() => handleInputFocus('playingLargeImageText')}
onblur={handleInputBlur}
placeholder="{'{'}beatmap{'}'}"
placeholder="{'{'}beatmap}"
class="h-8 bg-black/40 text-xs border-theme-800 focus:border-primary"
/>
</div>
@@ -945,7 +945,7 @@
Small Badge Hover Tooltip
</Label>
<span class="text-[10px] text-muted-foreground"
>{'{'}username{'}'} (#{'{'}rank{'}'})</span
>{'{'}username} (#{'{'}rank})</span
>
</div>
<Input
@@ -953,7 +953,7 @@
bind:value={workingConfig.playingSmallImageText}
onfocus={() => handleInputFocus('playingSmallImageText')}
onblur={handleInputBlur}
placeholder="{'{'}username{'}'} (#{'{'}rank{'}'})"
placeholder="{'{'}username} (#{'{'}rank})"
class="h-8 bg-black/40 text-xs border-theme-800 focus:border-primary"
/>
</div>
@@ -1031,7 +1031,7 @@
<ThemeSection
title="Button 1 (Playing In-Game)"
icon={Link}
description="Primary action button shown while playing osu! (supports {'{'}beatmapUrl{'}'})"
description="Primary action button shown while playing osu! (supports {'{'}beatmapUrl})"
>
<div class="space-y-3">
<div
@@ -1067,7 +1067,7 @@
bind:value={workingConfig.playingButton1.url}
onfocus={() => handleInputFocus('playingButton1Url')}
onblur={handleInputBlur}
placeholder="{'{'}beatmapUrl{'}'}"
placeholder="{'{'}beatmapUrl}"
class="h-8 bg-black/40 text-xs border-theme-800 focus:border-primary"
/>
</div>
@@ -1128,7 +1128,7 @@
bordered={false}
>
<div class="space-y-2">
{#each DISCORD_PRESENCE_PRESETS as preset}
{#each DISCORD_PRESENCE_PRESETS as preset (preset.name)}
<div
class="flex flex-col gap-1.5 rounded-xl border border-theme-800/80 bg-theme-900/40 p-3 transition-colors hover:border-theme-700 {selectedPresetName ===
preset.name
@@ -1170,7 +1170,7 @@
description="Click any variable to copy or evaluate in the active field"
>
<div class="space-y-1.5">
{#each PLACEHOLDERS as p}
{#each PLACEHOLDERS as p (p.token)}
<div
class="flex items-center justify-between rounded-lg border border-theme-800/40 bg-black/30 px-2.5 py-1.5 text-[11px]"
>
@@ -1215,7 +1215,7 @@
</span>
</div>
<div class="flex flex-wrap gap-1">
{#each PLACEHOLDERS as p}
{#each PLACEHOLDERS as p (p.token)}
<button
type="button"
class="group flex items-center gap-1 rounded border border-theme-800 bg-theme-900/90 px-1.5 py-0.5 text-[10px] text-theme-200 transition-all hover:border-primary/60 hover:bg-primary/20 hover:text-white active:scale-95"
@@ -1354,14 +1354,14 @@
<div class="flex items-center gap-2">
<span class="text-muted-foreground">Mode:</span>
<div class="flex gap-0.5">
{#each ['osu!', 'taiko', 'catch', 'mania'] as mode}
{#each SIM_MODES as mode (mode)}
<button
type="button"
class="rounded px-2 py-0.5 text-[10px] font-semibold transition-colors {simMode ===
mode
? 'bg-primary text-primary-foreground'
: 'bg-black/40 text-theme-300 hover:text-white'}"
onclick={() => (simMode = mode as any)}
onclick={() => (simMode = mode)}
>
{mode}
</button>
@@ -1372,7 +1372,7 @@
<div class="flex items-center gap-2">
<span class="text-muted-foreground">Action:</span>
<div class="flex gap-0.5">
{#each ['Playing...', 'Editing...', 'AFK...'] as act}
{#each ['Playing...', 'Editing...', 'AFK...'] as act (act)}
<button
type="button"
class="rounded px-2 py-0.5 text-[10px] transition-colors {simAction === act
@@ -1392,7 +1392,7 @@
bind:value={simBeatmapIndex}
class="rounded border border-theme-800 bg-black/60 px-2 py-0.5 text-[10px] text-theme-200"
>
{#each SAMPLE_BEATMAPS as b, idx}
{#each SAMPLE_BEATMAPS as b, idx (`${b.artist}-${b.title}-${idx}`)}
<option value={idx}>{b.artist} - {b.title}</option>
{/each}
</select>
@@ -18,8 +18,6 @@
import { getThemeDataSampleValue, resolveThemeDataValue, themeGlobalData } from '$lib/themeData';
import type { ThemeFontChoice } from '$lib/themeFonts';
import { DEFAULT_THEME_ICON_SET, type ThemeIconSet } from '$lib/themeIcons';
import { openURL } from '$lib/utils';
import { sileo } from 'sileo';
import {
THEME_DATA_FIELDS,
THEME_PARTICLE_PRESETS,
@@ -32,6 +30,7 @@
type ThemeV2WidgetKind,
type ThemeV2WidgetVariant,
} from '$lib/themeV2';
import { openURL } from '$lib/utils';
import {
CircleUser,
Clock,
@@ -51,6 +50,7 @@
Timer,
Type,
} from '@lucide/svelte';
import { sileo } from 'sileo';
let {
element = $bindable(),
@@ -1643,7 +1643,8 @@
Test Button Action
</Button>
<p class="text-[9px] leading-relaxed text-muted-foreground">
In editor mode, canvas clicks select layers for dragging. Test actions using this button, or Shift+click on canvas.
In editor mode, canvas clicks select layers for dragging. Test actions using this button,
or Shift+click on canvas.
</p>
</div>
<div class="grid grid-cols-2 gap-2">
@@ -2502,7 +2503,8 @@
{:else if element.widget === 'telemetry'}
Pill bar showing beatmap counts, skin counts, ping, and osu! build.
{:else if element.widget === 'header'}
Launcher title and dynamic greeting. Full shows title and subtitle, Compact shows an inline pill greeting, and Minimal displays title only.
Launcher title and dynamic greeting. Full shows title and subtitle, Compact shows an
inline pill greeting, and Minimal displays title only.
{:else}
Launcher title and dynamic greeting.
{/if}
@@ -9,7 +9,7 @@
} from '$lib/themeIconCatalog';
import { DEFAULT_THEME_ICON_SET, type ThemeIconSet } from '$lib/themeIcons';
import ThemeIcon from './ThemeIcon.svelte';
import { Check, ChevronDown, ChevronsUpDown, LayoutGrid, List, Search, X } from '@lucide/svelte';
import { Check, ChevronsUpDown, LayoutGrid, List, Search, X } from '@lucide/svelte';
let {
value = $bindable(undefined),
@@ -4,11 +4,7 @@
import Input from '$lib/components/ui/input/input.svelte';
import Label from '$lib/components/ui/label/label.svelte';
import * as Select from '$lib/components/ui/select';
import type {
ThemeV2TextDecoration,
ThemeV2TextStyle,
ThemeV2TextTransform,
} from '$lib/themeV2';
import type { ThemeV2TextDecoration, ThemeV2TextStyle, ThemeV2TextTransform } from '$lib/themeV2';
import { Bold, Italic, RotateCcw, Strikethrough, Underline } from '@lucide/svelte';
let {
@@ -44,17 +44,7 @@
} from '$lib/themeV2';
import { currentUser } from '$lib/userAuthentication';
import { countryCodeToEmoji, formatRelativeTime, openURL } from '$lib/utils';
import {
Boxes,
ChevronRight,
Clock,
Medal,
Move,
RotateCw,
TrendingDown,
TrendingUp,
Trophy,
} from '@lucide/svelte';
import { Boxes, ChevronRight, Clock, Move, RotateCw, Trophy } from '@lucide/svelte';
import { onDestroy } from 'svelte';
import { SvelteSet } from 'svelte/reactivity';
import { TextMorph } from 'torph/svelte';
@@ -1,76 +1,76 @@
<script lang="ts">
import type { ComponentProps } from "svelte";
import type Calendar from "./calendar.svelte";
import CalendarMonthSelect from "./calendar-month-select.svelte";
import CalendarYearSelect from "./calendar-year-select.svelte";
import { DateFormatter, getLocalTimeZone, type DateValue } from "@internationalized/date";
import CalendarMonthSelect from './calendar-month-select.svelte';
import CalendarYearSelect from './calendar-year-select.svelte';
import type Calendar from './calendar.svelte';
import { DateFormatter, getLocalTimeZone, type DateValue } from '@internationalized/date';
import type { ComponentProps } from 'svelte';
let {
captionLayout,
months,
monthFormat,
years,
yearFormat,
month,
locale,
placeholder = $bindable(),
monthIndex = 0,
}: {
captionLayout: ComponentProps<typeof Calendar>["captionLayout"];
months: ComponentProps<typeof CalendarMonthSelect>["months"];
monthFormat: ComponentProps<typeof CalendarMonthSelect>["monthFormat"];
years: ComponentProps<typeof CalendarYearSelect>["years"];
yearFormat: ComponentProps<typeof CalendarYearSelect>["yearFormat"];
month: DateValue;
placeholder: DateValue | undefined;
locale: string;
monthIndex: number;
} = $props();
let {
captionLayout,
months,
monthFormat,
years,
yearFormat,
month,
locale,
placeholder = $bindable(),
monthIndex = 0,
}: {
captionLayout: ComponentProps<typeof Calendar>['captionLayout'];
months: ComponentProps<typeof CalendarMonthSelect>['months'];
monthFormat: ComponentProps<typeof CalendarMonthSelect>['monthFormat'];
years: ComponentProps<typeof CalendarYearSelect>['years'];
yearFormat: ComponentProps<typeof CalendarYearSelect>['yearFormat'];
month: DateValue;
placeholder: DateValue | undefined;
locale: string;
monthIndex: number;
} = $props();
function formatYear(date: DateValue) {
const dateObj = date.toDate(getLocalTimeZone());
if (typeof yearFormat === "function") return yearFormat(dateObj.getFullYear());
return new DateFormatter(locale, { year: yearFormat }).format(dateObj);
}
function formatYear(date: DateValue) {
const dateObj = date.toDate(getLocalTimeZone());
if (typeof yearFormat === 'function') return yearFormat(dateObj.getFullYear());
return new DateFormatter(locale, { year: yearFormat }).format(dateObj);
}
function formatMonth(date: DateValue) {
const dateObj = date.toDate(getLocalTimeZone());
if (typeof monthFormat === "function") return monthFormat(dateObj.getMonth() + 1);
return new DateFormatter(locale, { month: monthFormat }).format(dateObj);
}
function formatMonth(date: DateValue) {
const dateObj = date.toDate(getLocalTimeZone());
if (typeof monthFormat === 'function') return monthFormat(dateObj.getMonth() + 1);
return new DateFormatter(locale, { month: monthFormat }).format(dateObj);
}
</script>
{#snippet MonthSelect()}
<CalendarMonthSelect
{months}
{monthFormat}
value={month.month}
onchange={(e) => {
if (!placeholder) return;
const v = Number.parseInt(e.currentTarget.value);
const newPlaceholder = placeholder.set({ month: v });
placeholder = newPlaceholder.subtract({ months: monthIndex });
}}
/>
<CalendarMonthSelect
{months}
{monthFormat}
value={month.month}
onchange={(e) => {
if (!placeholder) return;
const v = Number.parseInt(e.currentTarget.value);
const newPlaceholder = placeholder.set({ month: v });
placeholder = newPlaceholder.subtract({ months: monthIndex });
}}
/>
{/snippet}
{#snippet YearSelect()}
<CalendarYearSelect {years} {yearFormat} value={month.year} />
<CalendarYearSelect {years} {yearFormat} value={month.year} />
{/snippet}
{#if captionLayout === "dropdown"}
{@render MonthSelect()}
{@render YearSelect()}
{:else if captionLayout === "dropdown-months"}
{@render MonthSelect()}
{#if placeholder}
{formatYear(placeholder)}
{/if}
{:else if captionLayout === "dropdown-years"}
{#if placeholder}
{formatMonth(placeholder)}
{/if}
{@render YearSelect()}
{#if captionLayout === 'dropdown'}
{@render MonthSelect()}
{@render YearSelect()}
{:else if captionLayout === 'dropdown-months'}
{@render MonthSelect()}
{#if placeholder}
{formatYear(placeholder)}
{/if}
{:else if captionLayout === 'dropdown-years'}
{#if placeholder}
{formatMonth(placeholder)}
{/if}
{@render YearSelect()}
{:else}
{formatMonth(month)} {formatYear(month)}
{formatMonth(month)} {formatYear(month)}
{/if}
@@ -1,19 +1,19 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
import { cn } from '$lib/utils.js';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.CellProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.CellProps = $props();
</script>
<CalendarPrimitive.Cell
bind:ref
class={cn(
"relative size-(--cell-size) p-0 text-center text-sm focus-within:z-20 [&:first-child[data-selected]_[data-bits-day]]:rounded-s-md [&:last-child[data-selected]_[data-bits-day]]:rounded-e-md",
className
)}
{...restProps}
bind:ref
class={cn(
'relative size-(--cell-size) p-0 text-center text-sm focus-within:z-20 [&:first-child[data-selected]_[data-bits-day]]:rounded-s-md [&:last-child[data-selected]_[data-bits-day]]:rounded-e-md',
className
)}
{...restProps}
/>
@@ -1,35 +1,35 @@
<script lang="ts">
import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js";
import { Calendar as CalendarPrimitive } from "bits-ui";
import { buttonVariants } from '$lib/components/ui/button/index.js';
import { cn } from '$lib/utils.js';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.DayProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.DayProps = $props();
</script>
<CalendarPrimitive.Day
bind:ref
class={cn(
buttonVariants({ variant: "ghost" }),
"flex size-(--cell-size) flex-col items-center justify-center gap-1 p-0 leading-none font-normal whitespace-nowrap select-none",
"[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground [&[data-today][data-disabled]]:text-muted-foreground",
"data-[selected]:bg-primary dark:data-[selected]:hover:bg-accent/50 data-[selected]:text-primary-foreground",
// Outside months
"[&[data-outside-month]:not([data-selected])]:text-muted-foreground [&[data-outside-month]:not([data-selected])]:hover:text-accent-foreground",
// Disabled
"data-[disabled]:text-muted-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
// Unavailable
"data-[unavailable]:text-muted-foreground data-[unavailable]:line-through",
// hover
"dark:hover:text-accent-foreground",
// focus
"focus:border-ring focus:ring-ring/50 focus:relative",
// inner spans
"[&>span]:text-xs [&>span]:opacity-70",
className
)}
{...restProps}
bind:ref
class={cn(
buttonVariants({ variant: 'ghost' }),
'flex size-(--cell-size) flex-col items-center justify-center gap-1 p-0 leading-none font-normal whitespace-nowrap select-none',
'[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground [&[data-today][data-disabled]]:text-muted-foreground',
'data-[selected]:bg-primary dark:data-[selected]:hover:bg-accent/50 data-[selected]:text-primary-foreground',
// Outside months
'[&[data-outside-month]:not([data-selected])]:text-muted-foreground [&[data-outside-month]:not([data-selected])]:hover:text-accent-foreground',
// Disabled
'data-[disabled]:text-muted-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
// Unavailable
'data-[unavailable]:text-muted-foreground data-[unavailable]:line-through',
// hover
'dark:hover:text-accent-foreground',
// focus
'focus:border-ring focus:ring-ring/50 focus:relative',
// inner spans
'[&>span]:text-xs [&>span]:opacity-70',
className
)}
{...restProps}
/>
@@ -1,12 +1,12 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
import { cn } from '$lib/utils.js';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.GridBodyProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.GridBodyProps = $props();
</script>
<CalendarPrimitive.GridBody bind:ref class={cn(className)} {...restProps} />
@@ -1,12 +1,12 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
import { cn } from '$lib/utils.js';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.GridHeadProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.GridHeadProps = $props();
</script>
<CalendarPrimitive.GridHead bind:ref class={cn(className)} {...restProps} />
@@ -1,12 +1,12 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
import { cn } from '$lib/utils.js';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.GridRowProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.GridRowProps = $props();
</script>
<CalendarPrimitive.GridRow bind:ref class={cn("flex", className)} {...restProps} />
<CalendarPrimitive.GridRow bind:ref class={cn('flex', className)} {...restProps} />
@@ -1,16 +1,16 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
import { cn } from '$lib/utils.js';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.GridProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.GridProps = $props();
</script>
<CalendarPrimitive.Grid
bind:ref
class={cn("mt-4 flex w-full border-collapse flex-col gap-1", className)}
{...restProps}
bind:ref
class={cn('mt-4 flex w-full border-collapse flex-col gap-1', className)}
{...restProps}
/>
@@ -1,19 +1,19 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
import { cn } from '$lib/utils.js';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.HeadCellProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.HeadCellProps = $props();
</script>
<CalendarPrimitive.HeadCell
bind:ref
class={cn(
"text-muted-foreground w-(--cell-size) rounded-md text-[0.8rem] font-normal",
className
)}
{...restProps}
bind:ref
class={cn(
'text-muted-foreground w-(--cell-size) rounded-md text-[0.8rem] font-normal',
className
)}
{...restProps}
/>
@@ -1,19 +1,19 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
import { cn } from '$lib/utils.js';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.HeaderProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.HeaderProps = $props();
</script>
<CalendarPrimitive.Header
bind:ref
class={cn(
"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
className
)}
{...restProps}
bind:ref
class={cn(
'flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium',
className
)}
{...restProps}
/>
@@ -1,16 +1,16 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
import { cn } from '$lib/utils.js';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.HeadingProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: CalendarPrimitive.HeadingProps = $props();
</script>
<CalendarPrimitive.Heading
bind:ref
class={cn("px-(--cell-size) text-sm font-medium", className)}
{...restProps}
bind:ref
class={cn('px-(--cell-size) text-sm font-medium', className)}
{...restProps}
/>
@@ -1,48 +1,48 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
import ChevronDownIcon from "@lucide/svelte/icons/chevron-down";
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
value,
onchange,
...restProps
}: WithoutChildrenOrChild<CalendarPrimitive.MonthSelectProps> = $props();
let {
ref = $bindable(null),
class: className,
value,
onchange,
...restProps
}: WithoutChildrenOrChild<CalendarPrimitive.MonthSelectProps> = $props();
</script>
<span
class={cn(
"has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]",
className
)}
class={cn(
'has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]',
className
)}
>
<CalendarPrimitive.MonthSelect
bind:ref
class="dark:bg-popover dark:text-popover-foreground absolute inset-0 opacity-0"
{...restProps}
>
{#snippet child({ props, monthItems, selectedMonthItem })}
<select {...props} {value} {onchange}>
{#each monthItems as monthItem (monthItem.value)}
<option
value={monthItem.value}
selected={value !== undefined
? monthItem.value === value
: monthItem.value === selectedMonthItem.value}
>
{monthItem.label}
</option>
{/each}
</select>
<span
class="[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md ps-2 pe-1 text-sm font-medium select-none [&>svg]:size-3.5"
aria-hidden="true"
>
{monthItems.find((item) => item.value === value)?.label || selectedMonthItem.label}
<ChevronDownIcon class="size-4" />
</span>
{/snippet}
</CalendarPrimitive.MonthSelect>
<CalendarPrimitive.MonthSelect
bind:ref
class="dark:bg-popover dark:text-popover-foreground absolute inset-0 opacity-0"
{...restProps}
>
{#snippet child({ props, monthItems, selectedMonthItem })}
<select {...props} {value} {onchange}>
{#each monthItems as monthItem (monthItem.value)}
<option
value={monthItem.value}
selected={value !== undefined
? monthItem.value === value
: monthItem.value === selectedMonthItem.value}
>
{monthItem.label}
</option>
{/each}
</select>
<span
class="[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md ps-2 pe-1 text-sm font-medium select-none [&>svg]:size-3.5"
aria-hidden="true"
>
{monthItems.find((item) => item.value === value)?.label || selectedMonthItem.label}
<ChevronDownIcon class="size-4" />
</span>
{/snippet}
</CalendarPrimitive.MonthSelect>
</span>
@@ -1,15 +1,15 @@
<script lang="ts">
import { type WithElementRef, cn } from "$lib/utils.js";
import type { HTMLAttributes } from "svelte/elements";
import { type WithElementRef, cn } from '$lib/utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
</script>
<div {...restProps} bind:this={ref} class={cn("flex flex-col", className)}>
{@render children?.()}
<div {...restProps} bind:this={ref} class={cn('flex flex-col', className)}>
{@render children?.()}
</div>
@@ -1,19 +1,19 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn, type WithElementRef } from "$lib/utils.js";
import { cn, type WithElementRef } from '$lib/utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
class={cn("relative flex flex-col gap-4 md:flex-row", className)}
{...restProps}
bind:this={ref}
class={cn('relative flex flex-col gap-4 md:flex-row', className)}
{...restProps}
>
{@render children?.()}
{@render children?.()}
</div>
@@ -1,19 +1,19 @@
<script lang="ts">
import { cn, type WithElementRef } from "$lib/utils.js";
import type { HTMLAttributes } from "svelte/elements";
import { cn, type WithElementRef } from '$lib/utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
</script>
<nav
{...restProps}
bind:this={ref}
class={cn("absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1", className)}
{...restProps}
bind:this={ref}
class={cn('absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1', className)}
>
{@render children?.()}
{@render children?.()}
</nav>
@@ -1,31 +1,31 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import ChevronRightIcon from "@lucide/svelte/icons/chevron-right";
import { buttonVariants, type ButtonVariant } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js";
import { buttonVariants, type ButtonVariant } from '$lib/components/ui/button/index.js';
import { cn } from '$lib/utils.js';
import ChevronRightIcon from '@lucide/svelte/icons/chevron-right';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
children,
variant = "ghost",
...restProps
}: CalendarPrimitive.NextButtonProps & {
variant?: ButtonVariant;
} = $props();
let {
ref = $bindable(null),
class: className,
children,
variant = 'ghost',
...restProps
}: CalendarPrimitive.NextButtonProps & {
variant?: ButtonVariant;
} = $props();
</script>
{#snippet Fallback()}
<ChevronRightIcon class="size-4" />
<ChevronRightIcon class="size-4" />
{/snippet}
<CalendarPrimitive.NextButton
bind:ref
class={cn(
buttonVariants({ variant }),
"size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180",
className
)}
children={children || Fallback}
{...restProps}
bind:ref
class={cn(
buttonVariants({ variant }),
'size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180',
className
)}
children={children || Fallback}
{...restProps}
/>
@@ -1,31 +1,31 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import ChevronLeftIcon from "@lucide/svelte/icons/chevron-left";
import { buttonVariants, type ButtonVariant } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js";
import { buttonVariants, type ButtonVariant } from '$lib/components/ui/button/index.js';
import { cn } from '$lib/utils.js';
import ChevronLeftIcon from '@lucide/svelte/icons/chevron-left';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
children,
variant = "ghost",
...restProps
}: CalendarPrimitive.PrevButtonProps & {
variant?: ButtonVariant;
} = $props();
let {
ref = $bindable(null),
class: className,
children,
variant = 'ghost',
...restProps
}: CalendarPrimitive.PrevButtonProps & {
variant?: ButtonVariant;
} = $props();
</script>
{#snippet Fallback()}
<ChevronLeftIcon class="size-4" />
<ChevronLeftIcon class="size-4" />
{/snippet}
<CalendarPrimitive.PrevButton
bind:ref
class={cn(
buttonVariants({ variant }),
"size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180",
className
)}
children={children || Fallback}
{...restProps}
bind:ref
class={cn(
buttonVariants({ variant }),
'size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180',
className
)}
children={children || Fallback}
{...restProps}
/>
@@ -1,47 +1,47 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
import ChevronDownIcon from "@lucide/svelte/icons/chevron-down";
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
import { Calendar as CalendarPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
value,
...restProps
}: WithoutChildrenOrChild<CalendarPrimitive.YearSelectProps> = $props();
let {
ref = $bindable(null),
class: className,
value,
...restProps
}: WithoutChildrenOrChild<CalendarPrimitive.YearSelectProps> = $props();
</script>
<span
class={cn(
"has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]",
className
)}
class={cn(
'has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]',
className
)}
>
<CalendarPrimitive.YearSelect
bind:ref
class="dark:bg-popover dark:text-popover-foreground absolute inset-0 opacity-0"
{...restProps}
>
{#snippet child({ props, yearItems, selectedYearItem })}
<select {...props} {value}>
{#each yearItems as yearItem (yearItem.value)}
<option
value={yearItem.value}
selected={value !== undefined
? yearItem.value === value
: yearItem.value === selectedYearItem.value}
>
{yearItem.label}
</option>
{/each}
</select>
<span
class="[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md ps-2 pe-1 text-sm font-medium select-none [&>svg]:size-3.5"
aria-hidden="true"
>
{yearItems.find((item) => item.value === value)?.label || selectedYearItem.label}
<ChevronDownIcon class="size-4" />
</span>
{/snippet}
</CalendarPrimitive.YearSelect>
<CalendarPrimitive.YearSelect
bind:ref
class="dark:bg-popover dark:text-popover-foreground absolute inset-0 opacity-0"
{...restProps}
>
{#snippet child({ props, yearItems, selectedYearItem })}
<select {...props} {value}>
{#each yearItems as yearItem (yearItem.value)}
<option
value={yearItem.value}
selected={value !== undefined
? yearItem.value === value
: yearItem.value === selectedYearItem.value}
>
{yearItem.label}
</option>
{/each}
</select>
<span
class="[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md ps-2 pe-1 text-sm font-medium select-none [&>svg]:size-3.5"
aria-hidden="true"
>
{yearItems.find((item) => item.value === value)?.label || selectedYearItem.label}
<ChevronDownIcon class="size-4" />
</span>
{/snippet}
</CalendarPrimitive.YearSelect>
</span>
+103 -103
View File
@@ -1,42 +1,42 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import * as Calendar from "./index.js";
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
import type { ButtonVariant } from "../button/button.svelte";
import { isEqualMonth, type DateValue } from "@internationalized/date";
import type { Snippet } from "svelte";
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
import type { ButtonVariant } from '../button/button.svelte';
import * as Calendar from './index.js';
import { isEqualMonth, type DateValue } from '@internationalized/date';
import { Calendar as CalendarPrimitive } from 'bits-ui';
import type { Snippet } from 'svelte';
let {
ref = $bindable(null),
value = $bindable(),
placeholder = $bindable(),
class: className,
weekdayFormat = "short",
buttonVariant = "ghost",
captionLayout = "label",
locale = "en-US",
months: monthsProp,
years,
monthFormat: monthFormatProp,
yearFormat = "numeric",
day,
disableDaysOutsideMonth = false,
...restProps
}: WithoutChildrenOrChild<CalendarPrimitive.RootProps> & {
buttonVariant?: ButtonVariant;
captionLayout?: "dropdown" | "dropdown-months" | "dropdown-years" | "label";
months?: CalendarPrimitive.MonthSelectProps["months"];
years?: CalendarPrimitive.YearSelectProps["years"];
monthFormat?: CalendarPrimitive.MonthSelectProps["monthFormat"];
yearFormat?: CalendarPrimitive.YearSelectProps["yearFormat"];
day?: Snippet<[{ day: DateValue; outsideMonth: boolean }]>;
} = $props();
let {
ref = $bindable(null),
value = $bindable(),
placeholder = $bindable(),
class: className,
weekdayFormat = 'short',
buttonVariant = 'ghost',
captionLayout = 'label',
locale = 'en-US',
months: monthsProp,
years,
monthFormat: monthFormatProp,
yearFormat = 'numeric',
day,
disableDaysOutsideMonth = false,
...restProps
}: WithoutChildrenOrChild<CalendarPrimitive.RootProps> & {
buttonVariant?: ButtonVariant;
captionLayout?: 'dropdown' | 'dropdown-months' | 'dropdown-years' | 'label';
months?: CalendarPrimitive.MonthSelectProps['months'];
years?: CalendarPrimitive.YearSelectProps['years'];
monthFormat?: CalendarPrimitive.MonthSelectProps['monthFormat'];
yearFormat?: CalendarPrimitive.YearSelectProps['yearFormat'];
day?: Snippet<[{ day: DateValue; outsideMonth: boolean }]>;
} = $props();
const monthFormat = $derived.by(() => {
if (monthFormatProp) return monthFormatProp;
if (captionLayout.startsWith("dropdown")) return "short";
return "long";
});
const monthFormat = $derived.by(() => {
if (monthFormatProp) return monthFormatProp;
if (captionLayout.startsWith('dropdown')) return 'short';
return 'long';
});
</script>
<!--
@@ -44,72 +44,72 @@ Discriminated Unions + Destructing (required for bindable) do not
get along, so we shut typescript up by casting `value` to `never`.
-->
<CalendarPrimitive.Root
bind:value={value as never}
bind:ref
bind:placeholder
{weekdayFormat}
{disableDaysOutsideMonth}
class={cn(
"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
className
)}
{locale}
{monthFormat}
{yearFormat}
{...restProps}
bind:value={value as never}
bind:ref
bind:placeholder
{weekdayFormat}
{disableDaysOutsideMonth}
class={cn(
'bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent',
className
)}
{locale}
{monthFormat}
{yearFormat}
{...restProps}
>
{#snippet children({ months, weekdays })}
<Calendar.Months>
<Calendar.Nav>
<Calendar.PrevButton variant={buttonVariant} />
<Calendar.NextButton variant={buttonVariant} />
</Calendar.Nav>
{#each months as month, monthIndex (month)}
<Calendar.Month>
<Calendar.Header>
<Calendar.Caption
{captionLayout}
months={monthsProp}
{monthFormat}
{years}
{yearFormat}
month={month.value}
bind:placeholder
{locale}
{monthIndex}
/>
</Calendar.Header>
<Calendar.Grid>
<Calendar.GridHead>
<Calendar.GridRow class="select-none">
{#each weekdays as weekday (weekday)}
<Calendar.HeadCell>
{weekday.slice(0, 2)}
</Calendar.HeadCell>
{/each}
</Calendar.GridRow>
</Calendar.GridHead>
<Calendar.GridBody>
{#each month.weeks as weekDates (weekDates)}
<Calendar.GridRow class="mt-2 w-full">
{#each weekDates as date (date)}
<Calendar.Cell {date} month={month.value}>
{#if day}
{@render day({
day: date,
outsideMonth: !isEqualMonth(date, month.value),
})}
{:else}
<Calendar.Day />
{/if}
</Calendar.Cell>
{/each}
</Calendar.GridRow>
{/each}
</Calendar.GridBody>
</Calendar.Grid>
</Calendar.Month>
{/each}
</Calendar.Months>
{/snippet}
{#snippet children({ months, weekdays })}
<Calendar.Months>
<Calendar.Nav>
<Calendar.PrevButton variant={buttonVariant} />
<Calendar.NextButton variant={buttonVariant} />
</Calendar.Nav>
{#each months as month, monthIndex (month)}
<Calendar.Month>
<Calendar.Header>
<Calendar.Caption
{captionLayout}
months={monthsProp}
{monthFormat}
{years}
{yearFormat}
month={month.value}
bind:placeholder
{locale}
{monthIndex}
/>
</Calendar.Header>
<Calendar.Grid>
<Calendar.GridHead>
<Calendar.GridRow class="select-none">
{#each weekdays as weekday (weekday)}
<Calendar.HeadCell>
{weekday.slice(0, 2)}
</Calendar.HeadCell>
{/each}
</Calendar.GridRow>
</Calendar.GridHead>
<Calendar.GridBody>
{#each month.weeks as weekDates (weekDates)}
<Calendar.GridRow class="mt-2 w-full">
{#each weekDates as date (date)}
<Calendar.Cell {date} month={month.value}>
{#if day}
{@render day({
day: date,
outsideMonth: !isEqualMonth(date, month.value),
})}
{:else}
<Calendar.Day />
{/if}
</Calendar.Cell>
{/each}
</Calendar.GridRow>
{/each}
</Calendar.GridBody>
</Calendar.Grid>
</Calendar.Month>
{/each}
</Calendar.Months>
{/snippet}
</CalendarPrimitive.Root>
+37 -37
View File
@@ -1,40 +1,40 @@
import Root from "./calendar.svelte";
import Cell from "./calendar-cell.svelte";
import Day from "./calendar-day.svelte";
import Grid from "./calendar-grid.svelte";
import Header from "./calendar-header.svelte";
import Months from "./calendar-months.svelte";
import GridRow from "./calendar-grid-row.svelte";
import Heading from "./calendar-heading.svelte";
import GridBody from "./calendar-grid-body.svelte";
import GridHead from "./calendar-grid-head.svelte";
import HeadCell from "./calendar-head-cell.svelte";
import NextButton from "./calendar-next-button.svelte";
import PrevButton from "./calendar-prev-button.svelte";
import MonthSelect from "./calendar-month-select.svelte";
import YearSelect from "./calendar-year-select.svelte";
import Month from "./calendar-month.svelte";
import Nav from "./calendar-nav.svelte";
import Caption from "./calendar-caption.svelte";
import Caption from './calendar-caption.svelte';
import Cell from './calendar-cell.svelte';
import Day from './calendar-day.svelte';
import GridBody from './calendar-grid-body.svelte';
import GridHead from './calendar-grid-head.svelte';
import GridRow from './calendar-grid-row.svelte';
import Grid from './calendar-grid.svelte';
import HeadCell from './calendar-head-cell.svelte';
import Header from './calendar-header.svelte';
import Heading from './calendar-heading.svelte';
import MonthSelect from './calendar-month-select.svelte';
import Month from './calendar-month.svelte';
import Months from './calendar-months.svelte';
import Nav from './calendar-nav.svelte';
import NextButton from './calendar-next-button.svelte';
import PrevButton from './calendar-prev-button.svelte';
import YearSelect from './calendar-year-select.svelte';
import Root from './calendar.svelte';
export {
Day,
Cell,
Grid,
Header,
Months,
GridRow,
Heading,
GridBody,
GridHead,
HeadCell,
NextButton,
PrevButton,
Nav,
Month,
YearSelect,
MonthSelect,
Caption,
//
Root as Calendar,
Day,
Cell,
Grid,
Header,
Months,
GridRow,
Heading,
GridBody,
GridHead,
HeadCell,
NextButton,
PrevButton,
Nav,
Month,
YearSelect,
MonthSelect,
Caption,
//
Root as Calendar,
};
@@ -73,7 +73,7 @@
return;
}
let next = '';
let next: string;
if (withTime) {
const d = new Date(
calendarValue.year,
+16 -16
View File
@@ -1,19 +1,19 @@
import Root from "./popover.svelte";
import Close from "./popover-close.svelte";
import Content from "./popover-content.svelte";
import Trigger from "./popover-trigger.svelte";
import Portal from "./popover-portal.svelte";
import Close from './popover-close.svelte';
import Content from './popover-content.svelte';
import Portal from './popover-portal.svelte';
import Trigger from './popover-trigger.svelte';
import Root from './popover.svelte';
export {
Root,
Content,
Trigger,
Close,
Portal,
//
Root as Popover,
Content as PopoverContent,
Trigger as PopoverTrigger,
Close as PopoverClose,
Portal as PopoverPortal,
Root,
Content,
Trigger,
Close,
Portal,
//
Root as Popover,
Content as PopoverContent,
Trigger as PopoverTrigger,
Close as PopoverClose,
Portal as PopoverPortal,
};
@@ -1,7 +1,7 @@
<script lang="ts">
import { Popover as PopoverPrimitive } from "bits-ui";
import { Popover as PopoverPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: PopoverPrimitive.CloseProps = $props();
let { ref = $bindable(null), ...restProps }: PopoverPrimitive.CloseProps = $props();
</script>
<PopoverPrimitive.Close bind:ref data-slot="popover-close" {...restProps} />
@@ -1,31 +1,31 @@
<script lang="ts">
import { Popover as PopoverPrimitive } from "bits-ui";
import PopoverPortal from "./popover-portal.svelte";
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
import type { ComponentProps } from "svelte";
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
import PopoverPortal from './popover-portal.svelte';
import { Popover as PopoverPrimitive } from 'bits-ui';
import type { ComponentProps } from 'svelte';
let {
ref = $bindable(null),
class: className,
sideOffset = 4,
align = "center",
portalProps,
...restProps
}: PopoverPrimitive.ContentProps & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof PopoverPortal>>;
} = $props();
let {
ref = $bindable(null),
class: className,
sideOffset = 4,
align = 'center',
portalProps,
...restProps
}: PopoverPrimitive.ContentProps & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof PopoverPortal>>;
} = $props();
</script>
<PopoverPortal {...portalProps}>
<PopoverPrimitive.Content
bind:ref
data-slot="popover-content"
{sideOffset}
{align}
class={cn(
"bg-popover text-popover-foreground 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--bits-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
className
)}
{...restProps}
/>
<PopoverPrimitive.Content
bind:ref
data-slot="popover-content"
{sideOffset}
{align}
class={cn(
'bg-popover text-popover-foreground 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--bits-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden',
className
)}
{...restProps}
/>
</PopoverPortal>
@@ -1,7 +1,7 @@
<script lang="ts">
import { Popover as PopoverPrimitive } from "bits-ui";
import { Popover as PopoverPrimitive } from 'bits-ui';
let { ...restProps }: PopoverPrimitive.PortalProps = $props();
let { ...restProps }: PopoverPrimitive.PortalProps = $props();
</script>
<PopoverPrimitive.Portal {...restProps} />
@@ -1,17 +1,17 @@
<script lang="ts">
import { cn } from "$lib/utils.js";
import { Popover as PopoverPrimitive } from "bits-ui";
import { cn } from '$lib/utils.js';
import { Popover as PopoverPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: PopoverPrimitive.TriggerProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: PopoverPrimitive.TriggerProps = $props();
</script>
<PopoverPrimitive.Trigger
bind:ref
data-slot="popover-trigger"
class={cn("", className)}
{...restProps}
bind:ref
data-slot="popover-trigger"
class={cn('', className)}
{...restProps}
/>
+2 -2
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import { Popover as PopoverPrimitive } from "bits-ui";
import { Popover as PopoverPrimitive } from 'bits-ui';
let { open = $bindable(false), ...restProps }: PopoverPrimitive.RootProps = $props();
let { open = $bindable(false), ...restProps }: PopoverPrimitive.RootProps = $props();
</script>
<PopoverPrimitive.Root bind:open {...restProps} />
+19 -19
View File
@@ -1,22 +1,22 @@
import Root from "./tooltip.svelte";
import Content from "./tooltip-content.svelte";
import Trigger from "./tooltip-trigger.svelte";
import Provider from "./tooltip-provider.svelte";
import Portal from "./tooltip-portal.svelte";
import Arrow from "./tooltip-arrow.svelte";
import Arrow from './tooltip-arrow.svelte';
import Content from './tooltip-content.svelte';
import Portal from './tooltip-portal.svelte';
import Provider from './tooltip-provider.svelte';
import Trigger from './tooltip-trigger.svelte';
import Root from './tooltip.svelte';
export {
Root,
Content,
Trigger,
Provider,
Portal,
Arrow,
//
Root as Tooltip,
Content as TooltipContent,
Trigger as TooltipTrigger,
Provider as TooltipProvider,
Portal as TooltipPortal,
Arrow as TooltipArrow,
Root,
Content,
Trigger,
Provider,
Portal,
Arrow,
//
Root as Tooltip,
Content as TooltipContent,
Trigger as TooltipTrigger,
Provider as TooltipProvider,
Portal as TooltipPortal,
Arrow as TooltipArrow,
};
@@ -1,29 +1,29 @@
<script lang="ts">
import { Tooltip as TooltipPrimitive } from "bits-ui";
import TooltipPortal from "./tooltip-portal.svelte";
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
import type { ComponentProps } from "svelte";
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
import TooltipPortal from './tooltip-portal.svelte';
import { Tooltip as TooltipPrimitive } from 'bits-ui';
import type { ComponentProps } from 'svelte';
let {
ref = $bindable(null),
class: className,
sideOffset = 6,
portalProps,
...restProps
}: TooltipPrimitive.ContentProps & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof TooltipPortal>>;
} = $props();
let {
ref = $bindable(null),
class: className,
sideOffset = 6,
portalProps,
...restProps
}: TooltipPrimitive.ContentProps & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof TooltipPortal>>;
} = $props();
</script>
<TooltipPortal {...portalProps}>
<TooltipPrimitive.Content
bind:ref
data-slot="tooltip-content"
{sideOffset}
class={cn(
"bg-popover text-popover-foreground 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md border border-border px-3 py-1.5 text-xs shadow-md",
className
)}
{...restProps}
/>
<TooltipPrimitive.Content
bind:ref
data-slot="tooltip-content"
{sideOffset}
class={cn(
'bg-popover text-popover-foreground 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md border border-border px-3 py-1.5 text-xs shadow-md',
className
)}
{...restProps}
/>
</TooltipPortal>
@@ -1,7 +1,7 @@
<script lang="ts">
import { Tooltip as TooltipPrimitive } from "bits-ui";
import { Tooltip as TooltipPrimitive } from 'bits-ui';
let { ...restProps }: TooltipPrimitive.PortalProps = $props();
let { ...restProps }: TooltipPrimitive.PortalProps = $props();
</script>
<TooltipPrimitive.Portal {...restProps} />
@@ -1,13 +1,7 @@
<script lang="ts">
import { Tooltip as TooltipPrimitive } from "bits-ui";
import { Tooltip as TooltipPrimitive } from 'bits-ui';
let {
delayDuration = 100,
...restProps
}: TooltipPrimitive.ProviderProps = $props();
let { delayDuration = 100, ...restProps }: TooltipPrimitive.ProviderProps = $props();
</script>
<TooltipPrimitive.Provider
{delayDuration}
{...restProps}
/>
<TooltipPrimitive.Provider {delayDuration} {...restProps} />
@@ -1,17 +1,17 @@
<script lang="ts">
import { cn } from "$lib/utils.js";
import { Tooltip as TooltipPrimitive } from "bits-ui";
import { cn } from '$lib/utils.js';
import { Tooltip as TooltipPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: TooltipPrimitive.TriggerProps = $props();
let {
ref = $bindable(null),
class: className,
...restProps
}: TooltipPrimitive.TriggerProps = $props();
</script>
<TooltipPrimitive.Trigger
bind:ref
data-slot="tooltip-trigger"
class={cn("", className)}
{...restProps}
bind:ref
data-slot="tooltip-trigger"
class={cn('', className)}
{...restProps}
/>
+2 -2
View File
@@ -1,7 +1,7 @@
<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();
let { open = $bindable(false), ...restProps }: TooltipPrimitive.RootProps = $props();
</script>
<TooltipPrimitive.Root bind:open {...restProps} />
+1 -1
View File
@@ -177,7 +177,7 @@ export const resolveThemeDataValue = (
const { global, theme, screen, mode = 'osu', now = new Date() } = context;
const stats = global.user.stats[mode];
let value = '';
let value: string;
switch (field) {
case 'user.name':
value = global.user.name;
+1 -6
View File
@@ -1,10 +1,5 @@
import { THEME_ICON_BODIES, type ThemeIconBody } from './themeIconData';
import {
DEFAULT_THEME_ICON_SET,
THEME_ICON_NAMES,
type ThemeIconName,
type ThemeIconSet,
} from './themeIcons';
import { DEFAULT_THEME_ICON_SET, THEME_ICON_NAMES, type ThemeIconSet } from './themeIcons';
import lucideCollection from '@iconify-json/lucide/icons.json';
import phCollection from '@iconify-json/ph/icons.json';
import tablerCollection from '@iconify-json/tabler/icons.json';
-2
View File
@@ -78,8 +78,6 @@ export const THEME_ICON_NAMES = [
export type ThemeIconName = (typeof THEME_ICON_NAMES)[number] | (string & {});
const ICON_NAME_SET = new Set<string>(THEME_ICON_NAMES);
export const isThemeIconName = (value: unknown): value is ThemeIconName =>
typeof value === 'string' && value.trim().length > 0 && value.length <= 120;
+11 -5
View File
@@ -5,7 +5,6 @@ import {
themeGlobalData,
} from './themeData';
import { getThemeIconBody } from './themeIconCatalog';
import { THEME_ICON_BODIES } from './themeIconData';
import {
themeArcGeometry,
themeClockDate,
@@ -1215,7 +1214,7 @@ const drawFooter = (context: PreviewContext, chrome?: ThemeV2Chrome) => {
ctx.restore();
};
const getWidgetPlayerData = (context: PreviewContext) => {
const getWidgetPlayerData = (_context: PreviewContext) => {
const globalData = get(themeGlobalData);
const name = globalData?.user?.name || getThemeDataSampleValue('user.name') || 'Player';
const rank = globalData?.user?.stats?.osu?.rank
@@ -1318,8 +1317,7 @@ const drawWidgetElement = async (context: PreviewContext, element: ThemeV2Widget
} else if (element.widget === 'header') {
const { name } = getWidgetPlayerData(context);
const hour = new Date().getHours();
const timeGreeting =
hour < 12 ? 'Good morning' : hour < 18 ? 'Good afternoon' : 'Good evening';
const timeGreeting = hour < 12 ? 'Good morning' : hour < 18 ? 'Good afternoon' : 'Good evening';
const greeting = `${timeGreeting}, ${name}!`;
ctx.save();
@@ -1822,7 +1820,15 @@ const drawWidgetElement = async (context: PreviewContext, element: ThemeV2Widget
const badgeW = 24;
const badgeH = 20;
const badgeX = element.x + element.width - badgeW - 10;
fillRoundedRect(ctx, badgeX, centerY - badgeH / 2, badgeW, badgeH, 4, 'rgba(251, 191, 36, 0.2)');
fillRoundedRect(
ctx,
badgeX,
centerY - badgeH / 2,
badgeW,
badgeH,
4,
'rgba(251, 191, 36, 0.2)'
);
strokeRoundedRect(
ctx,
badgeX,
+2 -10
View File
@@ -156,7 +156,6 @@
Clock,
ExternalLink,
Medal,
Sparkles,
TrendingDown,
TrendingUp,
Trophy,
@@ -650,7 +649,6 @@
userEvents.length === 0 ? 0 : Math.min(recentActivityIndex, userEvents.length - 1)
);
const activeEvent = $derived(userEvents[safeEventIndex]);
const latestEvent = $derived(activeEvent ?? userEvents[0]);
const timeGreeting = $derived.by(() => {
const hour = new Date().getHours();
@@ -2607,7 +2605,7 @@
<!-- Mini Feed of Recent Plays (clickable chips) -->
{#if userEvents.length > 1}
<div class="flex items-center gap-1.5 pt-0.5 overflow-x-auto no-scrollbar">
{#each userEvents.slice(0, 4) as event, idx}
{#each userEvents.slice(0, 4) as event, idx (`${event.time}-${idx}`)}
{@const eventGrade = gradeBadgeStyle(event.grade)}
<button
type="button"
@@ -3226,13 +3224,7 @@
variant="outline"
size="sm"
class="h-8 gap-1.5 px-3 text-xs shrink-0"
onclick={async () => {
try {
await invoke('open_presence_editor');
} catch {
presenceEditorOpen = true;
}
}}
onclick={openDiscordPresenceEditor}
>
<ThemeIcon name="palette" set={iconSet} class="size-3.5" />
Customize Activity