rune-lab 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/money/index.d.ts +2 -0
- package/dist/core/money/index.d.ts.map +1 -0
- package/dist/core/money/index.js +2 -0
- package/dist/core/money/money.d.ts +37 -0
- package/dist/core/money/money.d.ts.map +1 -0
- package/dist/core/money/money.js +79 -0
- package/dist/index.d.ts +0 -6
- package/dist/index.js +1 -7
- package/dist/state/auth/index.d.ts +2 -0
- package/dist/state/auth/index.js +2 -0
- package/dist/state/auth/session.svelte.d.ts +40 -0
- package/dist/state/auth/session.svelte.js +57 -0
- package/dist/state/auth/types.d.ts +30 -0
- package/dist/state/auth/types.js +3 -0
- package/dist/state/cart.svelte.d.ts +64 -0
- package/dist/state/cart.svelte.js +122 -0
- package/dist/state/composables/useMoney.d.ts +15 -0
- package/dist/state/composables/useMoney.js +48 -0
- package/dist/state/composables/useRuneLab.d.ts +3 -1
- package/dist/state/composables/useRuneLab.js +11 -0
- package/dist/state/context.d.ts +2 -0
- package/dist/state/context.js +2 -0
- package/dist/state/createConfigStore.svelte.d.ts +8 -3
- package/dist/state/createConfigStore.svelte.js +10 -0
- package/dist/state/currency.svelte.d.ts +9 -1
- package/dist/state/currency.svelte.js +28 -7
- package/dist/state/index.d.ts +7 -4
- package/dist/state/index.js +6 -2
- package/dist/state/language.svelte.d.ts +1 -0
- package/dist/state/persistence/drivers.d.ts +3 -1
- package/dist/state/persistence/drivers.js +5 -1
- package/dist/state/theme.svelte.d.ts +9 -1
- package/dist/state/theme.svelte.js +34 -8
- package/dist/ui/components/Icon.svelte +5 -2
- package/dist/ui/components/RuneProvider.svelte +59 -4
- package/dist/ui/components/RuneProvider.svelte.d.ts +19 -0
- package/dist/ui/components/money/MoneyDisplay.svelte +59 -0
- package/dist/ui/components/money/MoneyDisplay.svelte.d.ts +13 -0
- package/dist/ui/components/money/MoneyInput.svelte +106 -0
- package/dist/ui/components/money/MoneyInput.svelte.d.ts +19 -0
- package/dist/ui/components/money/index.d.ts +2 -0
- package/dist/ui/components/money/index.js +3 -0
- package/dist/ui/components/user/UserAvatar.svelte +66 -0
- package/dist/ui/components/user/UserAvatar.svelte.d.ts +13 -0
- package/dist/ui/components/user/UserProfile.svelte +79 -0
- package/dist/ui/components/user/UserProfile.svelte.d.ts +17 -0
- package/dist/ui/components/user/index.d.ts +2 -0
- package/dist/ui/components/user/index.js +3 -0
- package/dist/ui/features/notifications/NotificationBell.svelte +89 -0
- package/dist/ui/features/notifications/NotificationBell.svelte.d.ts +11 -0
- package/dist/ui/features/notifications/index.d.ts +1 -0
- package/dist/ui/features/notifications/index.js +2 -0
- package/dist/ui/index.d.ts +6 -0
- package/dist/ui/index.js +10 -0
- package/dist/ui/layout/WorkspaceLayout.svelte +9 -0
- package/dist/ui/paraglide/messages/_index.d.ts +4 -0
- package/dist/ui/paraglide/messages/_index.js +4 -0
- package/dist/ui/paraglide/messages/brl3.d.ts +17 -0
- package/dist/ui/paraglide/messages/brl3.js +85 -0
- package/dist/ui/paraglide/messages/cad3.d.ts +17 -0
- package/dist/ui/paraglide/messages/cad3.js +85 -0
- package/dist/ui/paraglide/messages/gbp3.d.ts +17 -0
- package/dist/ui/paraglide/messages/gbp3.js +85 -0
- package/dist/ui/paraglide/messages/inr3.d.ts +17 -0
- package/dist/ui/paraglide/messages/inr3.js +85 -0
- package/dist/ui/primitives/DatePicker.svelte +257 -0
- package/dist/ui/primitives/DatePicker.svelte.d.ts +17 -0
- package/dist/ui/primitives/index.d.ts +1 -0
- package/dist/ui/primitives/index.js +3 -0
- package/package.json +28 -18
- package/dist/state/config.d.ts +0 -4
- package/dist/state/config.js +0 -8
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { getLocale, experimentalStaticLocale } from '../runtime.js';
|
|
3
|
+
|
|
4
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
5
|
+
|
|
6
|
+
/** @typedef {{}} Gbp3Inputs */
|
|
7
|
+
|
|
8
|
+
const es_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
9
|
+
return /** @type {LocalizedString} */ (`Libra esterlina`)
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const fr_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
13
|
+
return /** @type {LocalizedString} */ (`Livre sterling`)
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const it_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
17
|
+
return /** @type {LocalizedString} */ (`Sterlina britannica`)
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const pt_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
21
|
+
return /** @type {LocalizedString} */ (`Libra esterlina`)
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const en_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
25
|
+
return /** @type {LocalizedString} */ (`British Pound`)
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const de_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
29
|
+
return /** @type {LocalizedString} */ (`Britisches Pfund`)
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const ru_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
33
|
+
return /** @type {LocalizedString} */ (`Британский фунт`)
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const hi_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
37
|
+
return /** @type {LocalizedString} */ (`ब्रिटिश पाउंड`)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const ar_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
41
|
+
return /** @type {LocalizedString} */ (`جنيه إسترليني`)
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const zh_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
45
|
+
return /** @type {LocalizedString} */ (`英镑`)
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const ja_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
49
|
+
return /** @type {LocalizedString} */ (`英ポンド`)
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const ko_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
53
|
+
return /** @type {LocalizedString} */ (`영국 파운드`)
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const vi_gbp3 = /** @type {(inputs: Gbp3Inputs) => LocalizedString} */ () => {
|
|
57
|
+
return /** @type {LocalizedString} */ (`Bảng Anh`)
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* | output |
|
|
62
|
+
* | --- |
|
|
63
|
+
* | "British Pound" |
|
|
64
|
+
*
|
|
65
|
+
* @param {Gbp3Inputs} inputs
|
|
66
|
+
* @param {{ locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" }} options
|
|
67
|
+
* @returns {LocalizedString}
|
|
68
|
+
*/
|
|
69
|
+
const gbp3 = /** @type {((inputs?: Gbp3Inputs, options?: { locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Gbp3Inputs, { locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" }, {}>} */ ((inputs = {}, options = {}) => {
|
|
70
|
+
const locale = experimentalStaticLocale ?? options.locale ?? getLocale()
|
|
71
|
+
if (locale === "es") return es_gbp3(inputs)
|
|
72
|
+
if (locale === "fr") return fr_gbp3(inputs)
|
|
73
|
+
if (locale === "it") return it_gbp3(inputs)
|
|
74
|
+
if (locale === "pt") return pt_gbp3(inputs)
|
|
75
|
+
if (locale === "en") return en_gbp3(inputs)
|
|
76
|
+
if (locale === "de") return de_gbp3(inputs)
|
|
77
|
+
if (locale === "ru") return ru_gbp3(inputs)
|
|
78
|
+
if (locale === "hi") return hi_gbp3(inputs)
|
|
79
|
+
if (locale === "ar") return ar_gbp3(inputs)
|
|
80
|
+
if (locale === "zh") return zh_gbp3(inputs)
|
|
81
|
+
if (locale === "ja") return ja_gbp3(inputs)
|
|
82
|
+
if (locale === "ko") return ko_gbp3(inputs)
|
|
83
|
+
return vi_gbp3(inputs)
|
|
84
|
+
});
|
|
85
|
+
export { gbp3 as "GBP" }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export { inr3 as INR };
|
|
2
|
+
export type LocalizedString = import("../runtime.js").LocalizedString;
|
|
3
|
+
export type Inr3Inputs = {};
|
|
4
|
+
/**
|
|
5
|
+
* | output |
|
|
6
|
+
* | --- |
|
|
7
|
+
* | "Indian Rupee" |
|
|
8
|
+
*
|
|
9
|
+
* @param {Inr3Inputs} inputs
|
|
10
|
+
* @param {{ locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" }} options
|
|
11
|
+
* @returns {LocalizedString}
|
|
12
|
+
*/
|
|
13
|
+
declare const inr3: ((inputs?: Inr3Inputs, options?: {
|
|
14
|
+
locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi";
|
|
15
|
+
}) => LocalizedString) & import("../runtime.js").MessageMetadata<Inr3Inputs, {
|
|
16
|
+
locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi";
|
|
17
|
+
}, {}>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { getLocale, experimentalStaticLocale } from '../runtime.js';
|
|
3
|
+
|
|
4
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
5
|
+
|
|
6
|
+
/** @typedef {{}} Inr3Inputs */
|
|
7
|
+
|
|
8
|
+
const es_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
9
|
+
return /** @type {LocalizedString} */ (`Rupia india`)
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const fr_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
13
|
+
return /** @type {LocalizedString} */ (`Roupie indienne`)
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const it_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
17
|
+
return /** @type {LocalizedString} */ (`Rupia indiana`)
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const pt_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
21
|
+
return /** @type {LocalizedString} */ (`Rúpia indiana`)
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const en_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
25
|
+
return /** @type {LocalizedString} */ (`Indian Rupee`)
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const de_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
29
|
+
return /** @type {LocalizedString} */ (`Indische Rupie`)
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const ru_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
33
|
+
return /** @type {LocalizedString} */ (`Индийская рупия`)
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const hi_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
37
|
+
return /** @type {LocalizedString} */ (`भारतीय रुपया`)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const ar_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
41
|
+
return /** @type {LocalizedString} */ (`روبية هندية`)
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const zh_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
45
|
+
return /** @type {LocalizedString} */ (`印度卢比`)
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const ja_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
49
|
+
return /** @type {LocalizedString} */ (`インドルピー`)
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const ko_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
53
|
+
return /** @type {LocalizedString} */ (`인도 루피`)
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const vi_inr3 = /** @type {(inputs: Inr3Inputs) => LocalizedString} */ () => {
|
|
57
|
+
return /** @type {LocalizedString} */ (`Rupee Ấn Độ`)
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* | output |
|
|
62
|
+
* | --- |
|
|
63
|
+
* | "Indian Rupee" |
|
|
64
|
+
*
|
|
65
|
+
* @param {Inr3Inputs} inputs
|
|
66
|
+
* @param {{ locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" }} options
|
|
67
|
+
* @returns {LocalizedString}
|
|
68
|
+
*/
|
|
69
|
+
const inr3 = /** @type {((inputs?: Inr3Inputs, options?: { locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Inr3Inputs, { locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" }, {}>} */ ((inputs = {}, options = {}) => {
|
|
70
|
+
const locale = experimentalStaticLocale ?? options.locale ?? getLocale()
|
|
71
|
+
if (locale === "es") return es_inr3(inputs)
|
|
72
|
+
if (locale === "fr") return fr_inr3(inputs)
|
|
73
|
+
if (locale === "it") return it_inr3(inputs)
|
|
74
|
+
if (locale === "pt") return pt_inr3(inputs)
|
|
75
|
+
if (locale === "en") return en_inr3(inputs)
|
|
76
|
+
if (locale === "de") return de_inr3(inputs)
|
|
77
|
+
if (locale === "ru") return ru_inr3(inputs)
|
|
78
|
+
if (locale === "hi") return hi_inr3(inputs)
|
|
79
|
+
if (locale === "ar") return ar_inr3(inputs)
|
|
80
|
+
if (locale === "zh") return zh_inr3(inputs)
|
|
81
|
+
if (locale === "ja") return ja_inr3(inputs)
|
|
82
|
+
if (locale === "ko") return ko_inr3(inputs)
|
|
83
|
+
return vi_inr3(inputs)
|
|
84
|
+
});
|
|
85
|
+
export { inr3 as "INR" }
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
DatePicker — Locale-aware calendar grid primitive.
|
|
3
|
+
Reads LanguageStore from context for weekday/month names.
|
|
4
|
+
Zero domain knowledge.
|
|
5
|
+
-->
|
|
6
|
+
<script module lang="ts">
|
|
7
|
+
export interface DatePickerProps {
|
|
8
|
+
/** Currently selected date */
|
|
9
|
+
value?: Date | string;
|
|
10
|
+
/** Disabled dates (cannot be selected) */
|
|
11
|
+
disabledDates?: Date[];
|
|
12
|
+
/** Highlighted dates (visual emphasis) */
|
|
13
|
+
highlightedDates?: Date[];
|
|
14
|
+
/** Minimum selectable date */
|
|
15
|
+
minDate?: Date;
|
|
16
|
+
/** Maximum selectable date */
|
|
17
|
+
maxDate?: Date;
|
|
18
|
+
/** Fired when a date is selected */
|
|
19
|
+
onchange?: (date: Date) => void;
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
import { getLanguageStore } from "rune-lab/state";
|
|
25
|
+
import { untrack } from "svelte";
|
|
26
|
+
|
|
27
|
+
let {
|
|
28
|
+
value,
|
|
29
|
+
disabledDates = [],
|
|
30
|
+
highlightedDates = [],
|
|
31
|
+
minDate,
|
|
32
|
+
maxDate,
|
|
33
|
+
onchange,
|
|
34
|
+
}: DatePickerProps = $props();
|
|
35
|
+
|
|
36
|
+
const languageStore = getLanguageStore();
|
|
37
|
+
|
|
38
|
+
// Parse initial value
|
|
39
|
+
function parseDate(d?: Date | string): Date {
|
|
40
|
+
if (!d) return new Date();
|
|
41
|
+
return typeof d === "string" ? new Date(d) : d;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Capture the initial value once to avoid state_referenced_locally warnings
|
|
45
|
+
const initialDate = untrack(() => parseDate(value));
|
|
46
|
+
|
|
47
|
+
let selectedDate = $state(initialDate);
|
|
48
|
+
let viewYear = $state(initialDate.getFullYear());
|
|
49
|
+
let viewMonth = $state(initialDate.getMonth());
|
|
50
|
+
|
|
51
|
+
// Locale-aware formatting
|
|
52
|
+
const locale = $derived(String(languageStore.current) || "en");
|
|
53
|
+
|
|
54
|
+
const weekdayNames = $derived(
|
|
55
|
+
Array.from({ length: 7 }, (_, i) => {
|
|
56
|
+
const d = new Date(2024, 0, i + 1); // Mon=1 Jan 2024
|
|
57
|
+
return new Intl.DateTimeFormat(locale, { weekday: "short" }).format(
|
|
58
|
+
d,
|
|
59
|
+
);
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const monthName = $derived(
|
|
64
|
+
new Intl.DateTimeFormat(locale, { month: "long" }).format(
|
|
65
|
+
new Date(viewYear, viewMonth),
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// Calendar grid
|
|
70
|
+
const calendarDays = $derived.by(() => {
|
|
71
|
+
const firstDay = new Date(viewYear, viewMonth, 1);
|
|
72
|
+
const lastDay = new Date(viewYear, viewMonth + 1, 0);
|
|
73
|
+
const startOffset = (firstDay.getDay() + 6) % 7; // Monday-based
|
|
74
|
+
const totalDays = lastDay.getDate();
|
|
75
|
+
|
|
76
|
+
const days: (number | null)[] = [];
|
|
77
|
+
|
|
78
|
+
// Leading empty slots
|
|
79
|
+
for (let i = 0; i < startOffset; i++) days.push(null);
|
|
80
|
+
// Actual days
|
|
81
|
+
for (let d = 1; d <= totalDays; d++) days.push(d);
|
|
82
|
+
|
|
83
|
+
return days;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const today = new Date();
|
|
87
|
+
const todayStr = `${today.getFullYear()}-${today.getMonth()}-${today.getDate()}`;
|
|
88
|
+
|
|
89
|
+
function dateKey(year: number, month: number, day: number): string {
|
|
90
|
+
return `${year}-${month}-${day}`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const disabledSet = $derived(
|
|
94
|
+
new Set(
|
|
95
|
+
disabledDates.map((d) =>
|
|
96
|
+
dateKey(d.getFullYear(), d.getMonth(), d.getDate()),
|
|
97
|
+
),
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const highlightedSet = $derived(
|
|
102
|
+
new Set(
|
|
103
|
+
highlightedDates.map((d) =>
|
|
104
|
+
dateKey(d.getFullYear(), d.getMonth(), d.getDate()),
|
|
105
|
+
),
|
|
106
|
+
),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
function isDisabled(day: number): boolean {
|
|
110
|
+
const k = dateKey(viewYear, viewMonth, day);
|
|
111
|
+
if (disabledSet.has(k)) return true;
|
|
112
|
+
const d = new Date(viewYear, viewMonth, day);
|
|
113
|
+
if (minDate && d < minDate) return true;
|
|
114
|
+
if (maxDate && d > maxDate) return true;
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function isSelected(day: number): boolean {
|
|
119
|
+
return (
|
|
120
|
+
selectedDate.getFullYear() === viewYear &&
|
|
121
|
+
selectedDate.getMonth() === viewMonth &&
|
|
122
|
+
selectedDate.getDate() === day
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function isToday(day: number): boolean {
|
|
127
|
+
return dateKey(viewYear, viewMonth, day) === todayStr;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function isHighlighted(day: number): boolean {
|
|
131
|
+
return highlightedSet.has(dateKey(viewYear, viewMonth, day));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function selectDay(day: number) {
|
|
135
|
+
if (isDisabled(day)) return;
|
|
136
|
+
selectedDate = new Date(viewYear, viewMonth, day);
|
|
137
|
+
onchange?.(selectedDate);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function prevMonth() {
|
|
141
|
+
if (viewMonth === 0) {
|
|
142
|
+
viewMonth = 11;
|
|
143
|
+
viewYear--;
|
|
144
|
+
} else {
|
|
145
|
+
viewMonth--;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function nextMonth() {
|
|
150
|
+
if (viewMonth === 11) {
|
|
151
|
+
viewMonth = 0;
|
|
152
|
+
viewYear++;
|
|
153
|
+
} else {
|
|
154
|
+
viewMonth++;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function handleKeydown(e: KeyboardEvent) {
|
|
159
|
+
const day = selectedDate.getDate();
|
|
160
|
+
let newDate: Date | null = null;
|
|
161
|
+
|
|
162
|
+
switch (e.key) {
|
|
163
|
+
case "ArrowLeft":
|
|
164
|
+
newDate = new Date(viewYear, viewMonth, day - 1);
|
|
165
|
+
break;
|
|
166
|
+
case "ArrowRight":
|
|
167
|
+
newDate = new Date(viewYear, viewMonth, day + 1);
|
|
168
|
+
break;
|
|
169
|
+
case "ArrowUp":
|
|
170
|
+
newDate = new Date(viewYear, viewMonth, day - 7);
|
|
171
|
+
break;
|
|
172
|
+
case "ArrowDown":
|
|
173
|
+
newDate = new Date(viewYear, viewMonth, day + 7);
|
|
174
|
+
break;
|
|
175
|
+
case "Enter":
|
|
176
|
+
selectDay(day);
|
|
177
|
+
return;
|
|
178
|
+
case "Escape":
|
|
179
|
+
(e.currentTarget as HTMLElement)?.blur();
|
|
180
|
+
return;
|
|
181
|
+
default:
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (newDate) {
|
|
186
|
+
e.preventDefault();
|
|
187
|
+
selectedDate = newDate;
|
|
188
|
+
viewYear = newDate.getFullYear();
|
|
189
|
+
viewMonth = newDate.getMonth();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
</script>
|
|
193
|
+
|
|
194
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
195
|
+
<div
|
|
196
|
+
class="rl-datepicker inline-flex flex-col gap-2 p-4 rounded-box bg-base-200 border border-base-content/10 select-none"
|
|
197
|
+
tabindex="0"
|
|
198
|
+
role="grid"
|
|
199
|
+
aria-label="Date picker"
|
|
200
|
+
onkeydown={handleKeydown}
|
|
201
|
+
>
|
|
202
|
+
<!-- Header: Month/Year + Navigation -->
|
|
203
|
+
<div class="flex items-center justify-between">
|
|
204
|
+
<button
|
|
205
|
+
class="btn btn-ghost btn-sm btn-square"
|
|
206
|
+
onclick={prevMonth}
|
|
207
|
+
aria-label="Previous month"
|
|
208
|
+
>
|
|
209
|
+
‹
|
|
210
|
+
</button>
|
|
211
|
+
<span class="font-semibold text-sm capitalize">
|
|
212
|
+
{monthName}
|
|
213
|
+
{viewYear}
|
|
214
|
+
</span>
|
|
215
|
+
<button
|
|
216
|
+
class="btn btn-ghost btn-sm btn-square"
|
|
217
|
+
onclick={nextMonth}
|
|
218
|
+
aria-label="Next month"
|
|
219
|
+
>
|
|
220
|
+
›
|
|
221
|
+
</button>
|
|
222
|
+
</div>
|
|
223
|
+
|
|
224
|
+
<!-- Weekday Headers -->
|
|
225
|
+
<div class="grid grid-cols-7 gap-1 text-center">
|
|
226
|
+
{#each weekdayNames as wd}
|
|
227
|
+
<span class="text-xs text-base-content/50 font-medium">{wd}</span>
|
|
228
|
+
{/each}
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<!-- Day Grid -->
|
|
232
|
+
<div class="grid grid-cols-7 gap-1">
|
|
233
|
+
{#each calendarDays as day}
|
|
234
|
+
{#if day === null}
|
|
235
|
+
<div></div>
|
|
236
|
+
{:else}
|
|
237
|
+
<button
|
|
238
|
+
class="btn btn-sm btn-square text-xs transition-all duration-150"
|
|
239
|
+
class:btn-primary={isSelected(day)}
|
|
240
|
+
class:btn-ghost={!isSelected(day)}
|
|
241
|
+
class:ring-2={isToday(day) && !isSelected(day)}
|
|
242
|
+
class:ring-primary={isToday(day) && !isSelected(day)}
|
|
243
|
+
class:btn-disabled={isDisabled(day)}
|
|
244
|
+
class:opacity-30={isDisabled(day)}
|
|
245
|
+
class:bg-accent={isHighlighted(day) && !isSelected(day)}
|
|
246
|
+
class:bg-opacity-20={isHighlighted(day) && !isSelected(day)}
|
|
247
|
+
onclick={() => selectDay(day)}
|
|
248
|
+
disabled={isDisabled(day)}
|
|
249
|
+
aria-label={`${day} ${monthName} ${viewYear}`}
|
|
250
|
+
aria-pressed={isSelected(day)}
|
|
251
|
+
>
|
|
252
|
+
{day}
|
|
253
|
+
</button>
|
|
254
|
+
{/if}
|
|
255
|
+
{/each}
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface DatePickerProps {
|
|
2
|
+
/** Currently selected date */
|
|
3
|
+
value?: Date | string;
|
|
4
|
+
/** Disabled dates (cannot be selected) */
|
|
5
|
+
disabledDates?: Date[];
|
|
6
|
+
/** Highlighted dates (visual emphasis) */
|
|
7
|
+
highlightedDates?: Date[];
|
|
8
|
+
/** Minimum selectable date */
|
|
9
|
+
minDate?: Date;
|
|
10
|
+
/** Maximum selectable date */
|
|
11
|
+
maxDate?: Date;
|
|
12
|
+
/** Fired when a date is selected */
|
|
13
|
+
onchange?: (date: Date) => void;
|
|
14
|
+
}
|
|
15
|
+
declare const DatePicker: import("svelte").Component<DatePickerProps, {}, "">;
|
|
16
|
+
type DatePicker = ReturnType<typeof DatePicker>;
|
|
17
|
+
export default DatePicker;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as DatePicker } from "./DatePicker.svelte";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rune-lab",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Modern toolkit for Svelte 5 Runes applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
"build:index": "bun run scripts/build-index.js"
|
|
17
17
|
},
|
|
18
18
|
"workspaces": [
|
|
19
|
-
"src/sdk/*"
|
|
20
|
-
"src/explorer/*"
|
|
19
|
+
"src/sdk/*"
|
|
21
20
|
],
|
|
22
21
|
"files": [
|
|
23
22
|
"dist"
|
|
@@ -43,28 +42,39 @@
|
|
|
43
42
|
},
|
|
44
43
|
"./package.json": "./package.json"
|
|
45
44
|
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"svelte": "^5.53.7",
|
|
47
|
+
"tailwindcss": "^4.2.1",
|
|
48
|
+
"daisyui": "^5.5.19"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"better-auth": {
|
|
52
|
+
"optional": true
|
|
53
|
+
},
|
|
54
|
+
"dinero.js": {
|
|
55
|
+
"optional": true
|
|
56
|
+
}
|
|
57
|
+
},
|
|
46
58
|
"dependencies": {
|
|
47
|
-
"vite": "npm:vite@^7.3.1",
|
|
48
|
-
"typescript": "npm:typescript@^5.9.3",
|
|
49
|
-
"tailwindcss": "npm:tailwindcss@^4.2.1",
|
|
50
|
-
"@tailwindcss/vite": "npm:@tailwindcss/vite@^4.2.1",
|
|
51
|
-
"@tailwindcss/forms": "npm:@tailwindcss/forms@^0.5.11",
|
|
52
|
-
"@tailwindcss/typography": "npm:@tailwindcss/typography@^0.5.19",
|
|
53
|
-
"@inlang/paraglide-js": "npm:@inlang/paraglide-js@^2.13.1",
|
|
54
59
|
"hotkeys-js": "npm:hotkeys-js@^4.0.2",
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"svelte": "npm:svelte@^5.53.6",
|
|
58
|
-
"svelte-check": "npm:svelte-check@^4.4.4",
|
|
59
|
-
"@sveltejs/kit": "npm:@sveltejs/kit@^2.53.4",
|
|
60
|
-
"@sveltejs/adapter-static": "npm:@sveltejs/adapter-static@^3.0.10",
|
|
61
|
-
"@sveltejs/vite-plugin-svelte": "npm:@sveltejs/vite-plugin-svelte@^7.0.0"
|
|
60
|
+
"better-auth": "^1.5.2",
|
|
61
|
+
"dinero.js": "npm:dinero.js@^2.0.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
+
"@inlang/paraglide-js": "npm:@inlang/paraglide-js@^2.13.1",
|
|
65
|
+
"@sveltejs/adapter-static": "npm:@sveltejs/adapter-static@^3.0.10",
|
|
66
|
+
"@sveltejs/kit": "npm:@sveltejs/kit@^2.53.4",
|
|
67
|
+
"@sveltejs/vite-plugin-svelte": "npm:@sveltejs/vite-plugin-svelte@^7.0.0",
|
|
64
68
|
"@sveltejs/package": "^2.5.7",
|
|
69
|
+
"@tailwindcss/forms": "npm:@tailwindcss/forms@^0.5.11",
|
|
70
|
+
"@tailwindcss/typography": "npm:@tailwindcss/typography@^0.5.19",
|
|
71
|
+
"@tailwindcss/vite": "npm:@tailwindcss/vite@^4.2.1",
|
|
72
|
+
"svelte-check": "npm:svelte-check@^4.4.4",
|
|
73
|
+
"typescript": "npm:typescript@^5.9.3",
|
|
74
|
+
"vite": "npm:vite@^7.3.1",
|
|
65
75
|
"publint": "^0.3.18",
|
|
66
76
|
"@internal/core": "0.2.0",
|
|
67
77
|
"@internal/state": "0.2.0",
|
|
68
78
|
"@internal/ui": "0.2.0"
|
|
69
79
|
}
|
|
70
|
-
}
|
|
80
|
+
}
|
package/dist/state/config.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { AppStore, createAppStore, getAppStore } from "./state/app.svelte";
|
|
2
|
-
export { createLayoutStore, getLayoutStore, LayoutStore, } from "./state/layout.svelte";
|
|
3
|
-
export { type Command, CommandStore, createCommandStore, getCommandStore, } from "./state/commands.svelte";
|
|
4
|
-
export { createApiStore, createCurrencyStore, createLanguageStore, createShortcutStore, createThemeStore, createToastStore, getApiStore, getCurrencyStore, getLanguageStore, getShortcutStore, getThemeStore, getToastStore, } from "./state/index";
|
package/dist/state/config.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// src/lib/config.ts
|
|
2
|
-
// Unified facade over all app-level stores.
|
|
3
|
-
// Updated for SSR safety: Re-exports factories for context-aware stores.
|
|
4
|
-
export { AppStore, createAppStore, getAppStore } from "./state/app.svelte";
|
|
5
|
-
export { createLayoutStore, getLayoutStore, LayoutStore, } from "./state/layout.svelte";
|
|
6
|
-
export { CommandStore, createCommandStore, getCommandStore, } from "./state/commands.svelte";
|
|
7
|
-
// These stores are factories now
|
|
8
|
-
export { createApiStore, createCurrencyStore, createLanguageStore, createShortcutStore, createThemeStore, createToastStore, getApiStore, getCurrencyStore, getLanguageStore, getShortcutStore, getThemeStore, getToastStore, } from "./state/index";
|