@lichta/svelte 2.1.0 → 2.2.0
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/README.md +7 -2
- package/dist/components/Calendar.svelte +31 -18
- package/dist/components/Calendar.svelte.d.ts +7 -1
- package/dist/components/DatePicker.svelte +20 -16
- package/dist/components/DatePicker.svelte.d.ts +5 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @lichta/svelte
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@lichta/svelte)
|
|
4
|
+
[](https://www.npmjs.com/package/@lichta/core)
|
|
5
5
|
|
|
6
6
|
🚀 **[Demo trực tiếp](https://lichta.zeneo.app/)**
|
|
7
7
|
|
|
@@ -63,8 +63,11 @@ Bạn cần cài `svelte` (peer dependency, `^5.0.0`) nếu dự án chưa có.
|
|
|
63
63
|
| `selectedDate` | `Date \| null` | `null` | Ngày được chọn (controlled) |
|
|
64
64
|
| `showLunar` | `boolean` | `true` | Hiện ngày âm lịch dưới ngày dương |
|
|
65
65
|
| `locale` | `'vi' \| 'en' \| 'ja' \| 'ko'` | `'vi'` | Ngôn ngữ nhãn thứ trong tuần |
|
|
66
|
+
| `firstDayOfWeek` | `0 \| 1` | `0` | Ngày bắt đầu tuần: `0` = Chủ Nhật, `1` = Thứ Hai |
|
|
67
|
+
| `showWeekNumber` | `boolean` | `false` | Hiện số tuần (ISO-8601) ở đầu mỗi hàng |
|
|
66
68
|
| `theme` | `'classic' \| 'glass'` | `'classic'` | Giao diện lịch |
|
|
67
69
|
| `onSelect` | `(date: Date, lunar: LunarDate) => void` | — | Callback khi chọn ngày |
|
|
70
|
+
| `onMonthChange` | `(month: number, year: number) => void` | — | Callback khi điều hướng tháng qua nút prev/next trong header |
|
|
68
71
|
| `dayCell` | `Snippet<[DayCellData]>` | — | Custom snippet cho mỗi ô ngày |
|
|
69
72
|
| `children` | `Snippet` | — | Nội dung footer tùy chỉnh |
|
|
70
73
|
|
|
@@ -95,8 +98,10 @@ Bạn cần cài `svelte` (peer dependency, `^5.0.0`) nếu dự án chưa có.
|
|
|
95
98
|
| ----------- | ----------------------------------------- | -------------- | ----------------------------------------------------------------------- |
|
|
96
99
|
| `value` | `Date \| null` | `null` | Ngày đang chọn (uncontrolled — component tự quản lý sau lần mount đầu) |
|
|
97
100
|
| `onSelect` | `(date: Date, lunar: LunarDate) => void` | — | Callback khi chọn ngày trong popover |
|
|
101
|
+
| `onMonthChange` | `(month: number, year: number) => void` | — | Callback khi điều hướng tháng qua nút prev/next trong popover |
|
|
98
102
|
| `placeholder` | `string` | `'Chọn ngày'` | Placeholder khi chưa chọn ngày |
|
|
99
103
|
| `locale` | `'vi' \| 'en' \| 'ja' \| 'ko'` | `'vi'` | Ngôn ngữ hiển thị trong popover |
|
|
104
|
+
| `firstDayOfWeek` | `0 \| 1` | `0` | Ngày bắt đầu tuần: `0` = Chủ Nhật, `1` = Thứ Hai |
|
|
100
105
|
| `theme` | `'classic' \| 'glass'` | `'classic'` | Giao diện input + popover |
|
|
101
106
|
| `showLunar` | `boolean` | `true` | Hiện ngày âm lịch trong popover |
|
|
102
107
|
| `format` | `(date: Date) => string` | `dd/MM/yyyy` | Hàm format ngày hiển thị trên input |
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { getYearDetails, getCalendarGrid, t } from '@lichta/core';
|
|
2
|
+
import { getYearDetails, getCalendarGrid, getWeekDayLabels, t } from '@lichta/core';
|
|
3
3
|
import type { LunarDate, CalendarDayCell } from '@lichta/core';
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
5
|
import { untrack } from 'svelte';
|
|
6
6
|
|
|
7
|
-
import type { Locale } from '@lichta/core';
|
|
7
|
+
import type { Locale, FirstDayOfWeek } from '@lichta/core';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Dữ liệu cho mỗi ô ngày trong lưới lịch
|
|
@@ -20,10 +20,16 @@
|
|
|
20
20
|
selectedDate?: Date | null;
|
|
21
21
|
/** Callback khi chọn ngày */
|
|
22
22
|
onSelect?: (date: Date, lunar: LunarDate) => void;
|
|
23
|
+
/** Callback khi user điều hướng tháng qua nút prev/next trong header */
|
|
24
|
+
onMonthChange?: (month: number, year: number) => void;
|
|
23
25
|
/** Hiển thị ngày âm lịch bên dưới ngày dương */
|
|
24
26
|
showLunar?: boolean;
|
|
25
27
|
/** Locale (vi | en | ja | ko) */
|
|
26
28
|
locale?: Locale;
|
|
29
|
+
/** Ngày bắt đầu tuần: 0 = Chủ Nhật (mặc định), 1 = Thứ Hai */
|
|
30
|
+
firstDayOfWeek?: FirstDayOfWeek;
|
|
31
|
+
/** Hiển thị số tuần (ISO-8601) ở đầu mỗi hàng */
|
|
32
|
+
showWeekNumber?: boolean;
|
|
27
33
|
/** Custom snippet cho mỗi ô ngày */
|
|
28
34
|
dayCell?: Snippet<[DayCellData]>;
|
|
29
35
|
children?: Snippet;
|
|
@@ -36,8 +42,11 @@
|
|
|
36
42
|
year = new Date().getFullYear(),
|
|
37
43
|
selectedDate = null,
|
|
38
44
|
onSelect,
|
|
45
|
+
onMonthChange,
|
|
39
46
|
showLunar = true,
|
|
40
47
|
locale = 'vi',
|
|
48
|
+
firstDayOfWeek = 0,
|
|
49
|
+
showWeekNumber = false,
|
|
41
50
|
dayCell,
|
|
42
51
|
children,
|
|
43
52
|
theme = 'classic'
|
|
@@ -60,7 +69,7 @@
|
|
|
60
69
|
});
|
|
61
70
|
|
|
62
71
|
// Tên thứ trong tuần
|
|
63
|
-
const weekDayLabels = $derived(
|
|
72
|
+
const weekDayLabels = $derived(getWeekDayLabels(locale, firstDayOfWeek));
|
|
64
73
|
|
|
65
74
|
// Tên tháng dương lịch cho phần header điều hướng
|
|
66
75
|
const monthNames = $derived(t(locale).solarMonthNames);
|
|
@@ -69,25 +78,23 @@
|
|
|
69
78
|
let yearInfo = $derived(getYearDetails(currentYear));
|
|
70
79
|
|
|
71
80
|
// Tính grid lịch 6x7 = 42 ô
|
|
72
|
-
let calendarGrid = $derived(getCalendarGrid(currentMonth, currentYear, selectedDate));
|
|
81
|
+
let calendarGrid = $derived(getCalendarGrid(currentMonth, currentYear, selectedDate, firstDayOfWeek));
|
|
73
82
|
|
|
74
83
|
// Navigation
|
|
75
84
|
function prevMonth() {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
85
|
+
const newMonth = currentMonth === 1 ? 12 : currentMonth - 1;
|
|
86
|
+
const newYear = currentMonth === 1 ? currentYear - 1 : currentYear;
|
|
87
|
+
currentMonth = newMonth;
|
|
88
|
+
currentYear = newYear;
|
|
89
|
+
onMonthChange?.(newMonth, newYear);
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
function nextMonth() {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
93
|
+
const newMonth = currentMonth === 12 ? 1 : currentMonth + 1;
|
|
94
|
+
const newYear = currentMonth === 12 ? currentYear + 1 : currentYear;
|
|
95
|
+
currentMonth = newMonth;
|
|
96
|
+
currentYear = newYear;
|
|
97
|
+
onMonthChange?.(newMonth, newYear);
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
function handleDayClick(cell: DayCellData) {
|
|
@@ -102,7 +109,7 @@
|
|
|
102
109
|
}
|
|
103
110
|
</script>
|
|
104
111
|
|
|
105
|
-
<div class={['lich-ta-calendar', `lichta-theme-${theme}
|
|
112
|
+
<div class={['lich-ta-calendar', `lichta-theme-${theme}`, showWeekNumber ? 'lich-ta-calendar--with-week-number' : ''].filter(Boolean).join(' ')}>
|
|
106
113
|
<!-- Header: Navigation + Tháng/Năm -->
|
|
107
114
|
<div class="lich-ta-calendar-header">
|
|
108
115
|
<button class="lich-ta-calendar-nav" onclick={prevMonth} aria-label="Tháng trước">◀</button>
|
|
@@ -120,6 +127,9 @@
|
|
|
120
127
|
|
|
121
128
|
<!-- Tên thứ -->
|
|
122
129
|
<div class="lich-ta-calendar-weekdays">
|
|
130
|
+
{#if showWeekNumber}
|
|
131
|
+
<div class="lich-ta-calendar-week-number" aria-hidden="true"></div>
|
|
132
|
+
{/if}
|
|
123
133
|
{#each weekDayLabels as label (label)}
|
|
124
134
|
<div class="lich-ta-calendar-weekday">{label}</div>
|
|
125
135
|
{/each}
|
|
@@ -127,7 +137,10 @@
|
|
|
127
137
|
|
|
128
138
|
<!-- Grid ngày -->
|
|
129
139
|
<div class="lich-ta-calendar-grid">
|
|
130
|
-
{#each calendarGrid as cell (cell.solar.getTime())}
|
|
140
|
+
{#each calendarGrid as cell, idx (cell.solar.getTime())}
|
|
141
|
+
{#if showWeekNumber && idx % 7 === 0}
|
|
142
|
+
<div class="lich-ta-calendar-week-number">{cell.weekNumber}</div>
|
|
143
|
+
{/if}
|
|
131
144
|
{#if dayCell}
|
|
132
145
|
{@render dayCell(cell)}
|
|
133
146
|
{:else}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LunarDate, CalendarDayCell } from '@lichta/core';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { Locale } from '@lichta/core';
|
|
3
|
+
import type { Locale, FirstDayOfWeek } from '@lichta/core';
|
|
4
4
|
/**
|
|
5
5
|
* Dữ liệu cho mỗi ô ngày trong lưới lịch
|
|
6
6
|
*/
|
|
@@ -14,10 +14,16 @@ interface Props {
|
|
|
14
14
|
selectedDate?: Date | null;
|
|
15
15
|
/** Callback khi chọn ngày */
|
|
16
16
|
onSelect?: (date: Date, lunar: LunarDate) => void;
|
|
17
|
+
/** Callback khi user điều hướng tháng qua nút prev/next trong header */
|
|
18
|
+
onMonthChange?: (month: number, year: number) => void;
|
|
17
19
|
/** Hiển thị ngày âm lịch bên dưới ngày dương */
|
|
18
20
|
showLunar?: boolean;
|
|
19
21
|
/** Locale (vi | en | ja | ko) */
|
|
20
22
|
locale?: Locale;
|
|
23
|
+
/** Ngày bắt đầu tuần: 0 = Chủ Nhật (mặc định), 1 = Thứ Hai */
|
|
24
|
+
firstDayOfWeek?: FirstDayOfWeek;
|
|
25
|
+
/** Hiển thị số tuần (ISO-8601) ở đầu mỗi hàng */
|
|
26
|
+
showWeekNumber?: boolean;
|
|
21
27
|
/** Custom snippet cho mỗi ô ngày */
|
|
22
28
|
dayCell?: Snippet<[DayCellData]>;
|
|
23
29
|
children?: Snippet;
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { getYearDetails, getCalendarGrid, t } from '@lichta/core';
|
|
3
|
-
import type { LunarDate, Locale, CalendarDayCell } from '@lichta/core';
|
|
2
|
+
import { getYearDetails, getCalendarGrid, getWeekDayLabels, t } from '@lichta/core';
|
|
3
|
+
import type { LunarDate, Locale, CalendarDayCell, FirstDayOfWeek } from '@lichta/core';
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
/** Ngày đang chọn (uncontrolled — component tự quản lý sau lần mount đầu) */
|
|
7
7
|
value?: Date | null;
|
|
8
8
|
/** Gọi khi người dùng chọn 1 ngày trong popover */
|
|
9
9
|
onSelect?: (date: Date, lunar: LunarDate) => void;
|
|
10
|
+
/** Callback khi user điều hướng tháng qua nút prev/next trong popover */
|
|
11
|
+
onMonthChange?: (month: number, year: number) => void;
|
|
10
12
|
placeholder?: string;
|
|
11
13
|
locale?: Locale;
|
|
14
|
+
/** Ngày bắt đầu tuần: 0 = Chủ Nhật (mặc định), 1 = Thứ Hai */
|
|
15
|
+
firstDayOfWeek?: FirstDayOfWeek;
|
|
12
16
|
theme?: 'classic' | 'glass';
|
|
13
17
|
showLunar?: boolean;
|
|
14
18
|
format?: (date: Date) => string;
|
|
@@ -24,8 +28,10 @@
|
|
|
24
28
|
let {
|
|
25
29
|
value = null,
|
|
26
30
|
onSelect,
|
|
31
|
+
onMonthChange,
|
|
27
32
|
placeholder = 'Chọn ngày',
|
|
28
33
|
locale = 'vi',
|
|
34
|
+
firstDayOfWeek = 0,
|
|
29
35
|
theme = 'classic',
|
|
30
36
|
showLunar = true,
|
|
31
37
|
format = defaultFormat,
|
|
@@ -53,10 +59,10 @@
|
|
|
53
59
|
}
|
|
54
60
|
});
|
|
55
61
|
|
|
56
|
-
const weekDayLabels = $derived(
|
|
62
|
+
const weekDayLabels = $derived(getWeekDayLabels(locale, firstDayOfWeek));
|
|
57
63
|
const monthNames = $derived(t(locale).solarMonthNames);
|
|
58
64
|
let yearInfo = $derived(getYearDetails(viewYear));
|
|
59
|
-
let grid = $derived(getCalendarGrid(viewMonth, viewYear, selected));
|
|
65
|
+
let grid = $derived(getCalendarGrid(viewMonth, viewYear, selected, firstDayOfWeek));
|
|
60
66
|
const displayValue = $derived(selected ? format(selected) : '');
|
|
61
67
|
|
|
62
68
|
function toggleOpen() {
|
|
@@ -64,21 +70,19 @@
|
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
function prevMonth() {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
+
const newMonth = viewMonth === 1 ? 12 : viewMonth - 1;
|
|
74
|
+
const newYear = viewMonth === 1 ? viewYear - 1 : viewYear;
|
|
75
|
+
viewMonth = newMonth;
|
|
76
|
+
viewYear = newYear;
|
|
77
|
+
onMonthChange?.(newMonth, newYear);
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
function nextMonth() {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
81
|
+
const newMonth = viewMonth === 12 ? 1 : viewMonth + 1;
|
|
82
|
+
const newYear = viewMonth === 12 ? viewYear + 1 : viewYear;
|
|
83
|
+
viewMonth = newMonth;
|
|
84
|
+
viewYear = newYear;
|
|
85
|
+
onMonthChange?.(newMonth, newYear);
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
function handleDaySelect(cell: CalendarDayCell) {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import type { LunarDate, Locale } from '@lichta/core';
|
|
1
|
+
import type { LunarDate, Locale, FirstDayOfWeek } from '@lichta/core';
|
|
2
2
|
interface Props {
|
|
3
3
|
/** Ngày đang chọn (uncontrolled — component tự quản lý sau lần mount đầu) */
|
|
4
4
|
value?: Date | null;
|
|
5
5
|
/** Gọi khi người dùng chọn 1 ngày trong popover */
|
|
6
6
|
onSelect?: (date: Date, lunar: LunarDate) => void;
|
|
7
|
+
/** Callback khi user điều hướng tháng qua nút prev/next trong popover */
|
|
8
|
+
onMonthChange?: (month: number, year: number) => void;
|
|
7
9
|
placeholder?: string;
|
|
8
10
|
locale?: Locale;
|
|
11
|
+
/** Ngày bắt đầu tuần: 0 = Chủ Nhật (mặc định), 1 = Thứ Hai */
|
|
12
|
+
firstDayOfWeek?: FirstDayOfWeek;
|
|
9
13
|
theme?: 'classic' | 'glass';
|
|
10
14
|
showLunar?: boolean;
|
|
11
15
|
format?: (date: Date) => string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { LichTa, jdFromDate, jdToDate, getYearDetails, getDayCanChi, getMonthCanChi, getHourCanChi, getAuspiciousHours, formatLunarDate, formatTraditional, getMonthName, getDayName, t, getZodiacAnimal } from '@lichta/core';
|
|
2
|
-
export type { LunarDate, SolarDate, Locale } from '@lichta/core';
|
|
1
|
+
export { LichTa, jdFromDate, jdToDate, getYearDetails, getDayCanChi, getMonthCanChi, getHourCanChi, getAuspiciousHours, formatLunarDate, formatTraditional, getMonthName, getDayName, getCalendarGrid, getISOWeekNumber, t, getZodiacAnimal } from '@lichta/core';
|
|
2
|
+
export type { LunarDate, SolarDate, Locale, CalendarDayCell, FirstDayOfWeek } from '@lichta/core';
|
|
3
3
|
export { default as Formatter } from './components/Formatter.svelte';
|
|
4
4
|
export { default as Calendar } from './components/Calendar.svelte';
|
|
5
5
|
export { default as DatePicker } from './components/DatePicker.svelte';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Lichta Svelte — Public API (Root Entry Point)
|
|
3
3
|
// ============================================================
|
|
4
4
|
// Re-export phần lõi từ @lichta/core
|
|
5
|
-
export { LichTa, jdFromDate, jdToDate, getYearDetails, getDayCanChi, getMonthCanChi, getHourCanChi, getAuspiciousHours, formatLunarDate, formatTraditional, getMonthName, getDayName, t, getZodiacAnimal } from '@lichta/core';
|
|
5
|
+
export { LichTa, jdFromDate, jdToDate, getYearDetails, getDayCanChi, getMonthCanChi, getHourCanChi, getAuspiciousHours, formatLunarDate, formatTraditional, getMonthName, getDayName, getCalendarGrid, getISOWeekNumber, t, getZodiacAnimal } from '@lichta/core';
|
|
6
6
|
// Xuất bản phần Svelte Component
|
|
7
7
|
export { default as Formatter } from './components/Formatter.svelte';
|
|
8
8
|
export { default as Calendar } from './components/Calendar.svelte';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lichta/svelte",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Svelte components for LichTa",
|
|
5
5
|
"author": "Zeforc Labs | Stridev",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"vite": "^8.0.16"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@lichta/core": "2.
|
|
55
|
+
"@lichta/core": "2.2.0"
|
|
56
56
|
},
|
|
57
57
|
"repository": {
|
|
58
58
|
"type": "git",
|