@lichta/vue 2.0.1 → 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 CHANGED
@@ -1,6 +1,9 @@
1
1
  # @lichta/vue
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@lichta/vue.svg)](https://www.npmjs.com/package/@lichta/vue)
3
+ [![@lichta/vue](https://img.shields.io/npm/v/@lichta/vue.svg?label=%40lichta%2Fvue)](https://www.npmjs.com/package/@lichta/vue)
4
+ [![@lichta/core](https://img.shields.io/npm/v/@lichta/core.svg?label=%40lichta%2Fcore)](https://www.npmjs.com/package/@lichta/core)
5
+
6
+ 🚀 **[Demo trực tiếp](https://lichta.zeneo.app/)**
4
7
 
5
8
  Component `Calendar` (lịch tháng có ngày âm lịch) cho Vue 3, đóng gói trên [`@lichta/core`](https://www.npmjs.com/package/@lichta/core).
6
9
 
@@ -41,6 +44,8 @@ function onSelect(date: Date, lunar: LunarDate) {
41
44
  | `year` | `number` | Năm hiện tại | Năm hiển thị ban đầu |
42
45
  | `showLunar` | `boolean` | `true` | Hiện ngày âm lịch dưới ngày dương |
43
46
  | `locale` | `'vi' \| 'en' \| 'ja' \| 'ko'` | `'vi'` | Ngôn ngữ nhãn thứ trong tuần |
47
+ | `firstDayOfWeek` | `0 \| 1` | `0` | Ngày bắt đầu tuần: `0` = Chủ Nhật, `1` = Thứ Hai |
48
+ | `showWeekNumber` | `boolean` | `false` | Hiện số tuần (ISO-8601) ở đầu mỗi hàng |
44
49
  | `theme` | `'classic' \| 'glass'` | `'classic'` | Giao diện lịch |
45
50
 
46
51
  ## Events
@@ -48,8 +53,53 @@ function onSelect(date: Date, lunar: LunarDate) {
48
53
  | Event | Payload | Mô tả |
49
54
  |---|---|---|
50
55
  | `select` | `(date: Date, lunar: LunarDate)` | Bắn ra khi người dùng chọn 1 ngày |
56
+ | `month-change` | `(month: number, year: number)` | Bắn ra khi điều hướng tháng qua nút prev/next trong header |
57
+
58
+ > Khác với `@lichta/react`/`@lichta/svelte` (dùng prop `onSelect`), Vue theo đúng convention của framework nên dùng `emit`/`@select` (và `@month-change`) thay vì prop callback. Component cũng chưa hỗ trợ custom render cho từng ô ngày (có ở React/Svelte qua `renderDay`/`dayCell`). `month`/`year` là controlled prop — component tự đồng bộ lại khi cha đổi giá trị; kết hợp với `@month-change` để đồng bộ 2 chiều với 1 nguồn điều hướng khác (ví dụ FullCalendar).
59
+
60
+ ## DatePicker
61
+
62
+ Component `DatePicker` (input + popover chọn ngày, dựng trên `Calendar` ở trên).
51
63
 
52
- > Khác với `@lichta/react`/`@lichta/svelte` (dùng prop `onSelect`), Vue theo đúng convention của framework nên dùng `emit`/`@select` thay vì prop callback. Component cũng chưa hỗ trợ custom render cho từng ô ngày (có ở React/Svelte qua `renderDay`/`dayCell`) hay điều khiển `month`/`year` như controlled prop — thay đổi prop sau khi mount chưa tự động cập nhật lại lịch đang hiển thị.
64
+ ```vue
65
+ <script setup>
66
+ import { DatePicker } from '@lichta/vue';
67
+ import '@lichta/core/styles/calendar-base.css';
68
+ import '@lichta/core/styles/calendar-glass.css'; // theme "glass" (tùy chọn)
69
+ import '@lichta/core/styles/datepicker-base.css';
70
+ import '@lichta/core/styles/datepicker-glass.css'; // theme "glass" (tùy chọn)
71
+
72
+ function onSelect(date, lunar) {
73
+ console.log(date, lunar);
74
+ }
75
+ </script>
76
+
77
+ <template>
78
+ <DatePicker theme="glass" locale="vi" @select="onSelect" />
79
+ </template>
80
+ ```
81
+
82
+ > ⚠️ Cần import cả CSS của `Calendar` (dùng trong popover) lẫn `DatePicker` (input + popover chrome) — thiếu 1 trong 2 sẽ hiển thị thiếu style.
83
+
84
+ ### Props / Events
85
+
86
+ | Prop | Kiểu | Mặc định | Mô tả |
87
+ |---|---|---|---|
88
+ | `value` | `Date \| null` | `null` | Ngày đang chọn (uncontrolled — component tự quản lý sau lần mount đầu) |
89
+ | `placeholder` | `string` | `'Chọn ngày'` | Placeholder khi chưa chọn ngày |
90
+ | `locale` | `'vi' \| 'en' \| 'ja' \| 'ko'` | `'vi'` | Ngôn ngữ hiển thị trong popover |
91
+ | `firstDayOfWeek` | `0 \| 1` | `0` | Ngày bắt đầu tuần: `0` = Chủ Nhật, `1` = Thứ Hai |
92
+ | `theme` | `'classic' \| 'glass'` | `'classic'` | Giao diện input + popover |
93
+ | `showLunar` | `boolean` | `true` | Hiện ngày âm lịch trong popover |
94
+ | `format` | `(date: Date) => string` | `dd/MM/yyyy` | Hàm format ngày hiển thị trên input |
95
+ | `disabled` | `boolean` | `false` | Vô hiệu hoá input |
96
+
97
+ | Event | Payload | Mô tả |
98
+ |---|---|---|
99
+ | `select` | `(date: Date, lunar: LunarDate)` | Bắn khi chọn ngày trong popover |
100
+ | `month-change` | `(month: number, year: number)` | Bắn khi điều hướng tháng qua nút prev/next trong popover |
101
+
102
+ Popover tự đóng khi: chọn xong 1 ngày, click ra ngoài, hoặc nhấn phím `Escape`.
53
103
 
54
104
  ## Theming
55
105
 
@@ -66,6 +116,8 @@ function onSelect(date: Date, lunar: LunarDate) {
66
116
  }
67
117
  ```
68
118
 
119
+ `DatePicker` dùng chung biến CSS `--lichta-*` ở trên — không cần custom class riêng.
120
+
69
121
  ## License
70
122
 
71
123
  [MIT](./LICENSE)
@@ -1,31 +1,36 @@
1
- import { type LunarDate, type Locale } from '@lichta/core';
1
+ import { type LunarDate, type Locale, type CalendarDayCell, type FirstDayOfWeek } from '@lichta/core';
2
2
  interface Props {
3
3
  month?: number;
4
4
  year?: number;
5
+ /** Ngày được chọn (controlled). Bỏ qua thì Calendar tự quản lý selection nội bộ (uncontrolled). */
6
+ selectedDate?: Date | null;
5
7
  showLunar?: boolean;
6
8
  locale?: Locale;
9
+ /** Ngày bắt đầu tuần: 0 = Chủ Nhật (mặc định), 1 = Thứ Hai */
10
+ firstDayOfWeek?: FirstDayOfWeek;
11
+ /** Hiển thị số tuần (ISO-8601) ở đầu mỗi hàng */
12
+ showWeekNumber?: boolean;
7
13
  theme?: 'classic' | 'glass';
8
14
  }
9
- export interface DayCellData {
10
- solar: Date;
11
- lunar: LunarDate;
12
- isToday: boolean;
13
- isSelected: boolean;
14
- isCurrentMonth: boolean;
15
- }
15
+ export type DayCellData = CalendarDayCell;
16
16
  declare var __VLS_1: {};
17
17
  type __VLS_Slots = {} & {
18
18
  default?: (props: typeof __VLS_1) => any;
19
19
  };
20
20
  declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
21
21
  select: (date: Date, lunar: LunarDate) => any;
22
+ "month-change": (month: number, year: number) => any;
22
23
  }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
23
24
  onSelect?: ((date: Date, lunar: LunarDate) => any) | undefined;
25
+ "onMonth-change"?: ((month: number, year: number) => any) | undefined;
24
26
  }>, {
25
27
  month: number;
26
28
  year: number;
29
+ selectedDate: Date | null;
27
30
  showLunar: boolean;
28
31
  locale: Locale;
32
+ firstDayOfWeek: FirstDayOfWeek;
33
+ showWeekNumber: boolean;
29
34
  theme: "classic" | "glass";
30
35
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
36
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
@@ -0,0 +1,30 @@
1
+ import { type LunarDate, type Locale, type FirstDayOfWeek } from '@lichta/core';
2
+ interface Props {
3
+ /** Ngày đang chọn (uncontrolled — component tự quản lý sau lần mount đầu) */
4
+ value?: Date | null;
5
+ placeholder?: string;
6
+ locale?: Locale;
7
+ /** Ngày bắt đầu tuần: 0 = Chủ Nhật (mặc định), 1 = Thứ Hai */
8
+ firstDayOfWeek?: FirstDayOfWeek;
9
+ theme?: 'classic' | 'glass';
10
+ showLunar?: boolean;
11
+ format?: (date: Date) => string;
12
+ disabled?: boolean;
13
+ }
14
+ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
15
+ select: (date: Date, lunar: LunarDate) => any;
16
+ "month-change": (month: number, year: number) => any;
17
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
18
+ onSelect?: ((date: Date, lunar: LunarDate) => any) | undefined;
19
+ "onMonth-change"?: ((month: number, year: number) => any) | undefined;
20
+ }>, {
21
+ showLunar: boolean;
22
+ locale: Locale;
23
+ firstDayOfWeek: FirstDayOfWeek;
24
+ theme: "classic" | "glass";
25
+ value: Date | null;
26
+ placeholder: string;
27
+ format: (date: Date) => string;
28
+ disabled: boolean;
29
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
+ export default _default;
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export { default as Calendar } from './Calendar.vue';
2
+ export { default as DatePicker } from './DatePicker.vue';
@@ -1,139 +1,241 @@
1
- import { defineComponent as q, ref as $, computed as L, openBlock as i, createElementBlock as d, normalizeClass as b, createElementVNode as l, toDisplayString as o, Fragment as T, renderList as N, createTextVNode as Y, createCommentVNode as x, renderSlot as A } from "vue";
2
- import { getYearDetails as H, LichTa as w } from "@lichta/core";
3
- const J = { class: "lich-ta-calendar-header" }, P = { class: "lich-ta-calendar-title" }, Q = { class: "lich-ta-calendar-month-year" }, R = { class: "lich-ta-calendar-canchi" }, U = { class: "lich-ta-calendar-weekdays" }, X = { class: "lich-ta-calendar-grid" }, Z = ["tabindex", "onClick", "onKeydown"], ee = { class: "solar-day" }, ae = {
1
+ import { defineComponent as T, ref as _, computed as k, watch as B, openBlock as l, createElementBlock as s, normalizeClass as N, createElementVNode as t, toDisplayString as n, createCommentVNode as w, Fragment as p, renderList as x, createTextVNode as W, renderSlot as I, onMounted as z, onBeforeUnmount as A } from "vue";
2
+ import { getYearDetails as F, getWeekDayLabels as K, t as V, getCalendarGrid as P } from "@lichta/core";
3
+ const U = { class: "lich-ta-calendar-header" }, j = { class: "lich-ta-calendar-title" }, q = { class: "lich-ta-calendar-month-year" }, H = { class: "lich-ta-calendar-canchi" }, J = { class: "lich-ta-calendar-weekdays" }, Q = {
4
+ key: 0,
5
+ class: "lich-ta-calendar-week-number",
6
+ "aria-hidden": "true"
7
+ }, R = { class: "lich-ta-calendar-grid" }, X = {
8
+ key: 0,
9
+ class: "lich-ta-calendar-week-number"
10
+ }, Z = ["tabindex", "onClick", "onKeydown"], ee = { class: "solar-day" }, ae = {
4
11
  key: 0,
5
12
  class: "lunar-day"
6
13
  }, te = {
7
14
  key: 0,
8
15
  class: "lich-ta-calendar-footer"
9
- }, le = /* @__PURE__ */ q({
16
+ }, pe = /* @__PURE__ */ T({
10
17
  __name: "Calendar",
11
18
  props: {
12
19
  month: { default: (/* @__PURE__ */ new Date()).getMonth() + 1 },
13
20
  year: { default: (/* @__PURE__ */ new Date()).getFullYear() },
21
+ selectedDate: { default: void 0 },
14
22
  showLunar: { type: Boolean, default: !0 },
15
23
  locale: { default: "vi" },
24
+ firstDayOfWeek: { default: 0 },
25
+ showWeekNumber: { type: Boolean, default: !1 },
16
26
  theme: { default: "classic" }
17
27
  },
18
- emits: ["select"],
19
- setup(F, { emit: B }) {
20
- const v = F, e = $(v.month), s = $(v.year), h = $(null), C = L(() => H(s.value)), E = B, K = [
21
- "Tháng 1",
22
- "Tháng 2",
23
- "Tháng 3",
24
- "Tháng 4",
25
- "Tháng 5",
26
- "Tháng 6",
27
- "Tháng 7",
28
- "Tháng 8",
29
- "Tháng 9",
30
- "Tháng 10",
31
- "Tháng 11",
32
- "Tháng 12"
33
- ], V = ["CN", "T2", "T3", "T4", "T5", "T6", "T7"], I = L(() => {
34
- const t = [], y = new Date(s.value, e.value - 1, 1), a = new Date(s.value, e.value, 0), D = y.getDay(), g = a.getDate(), p = /* @__PURE__ */ new Date(), _ = `${p.getFullYear()}-${p.getMonth() + 1}-${p.getDate()}`;
35
- let f = "";
36
- h.value && (f = `${h.value.getFullYear()}-${h.value.getMonth() + 1}-${h.value.getDate()}`);
37
- const W = new Date(s.value, e.value - 1, 0).getDate();
38
- for (let n = D - 1; n >= 0; n--) {
39
- const r = W - n, c = e.value - 1 < 1 ? 12 : e.value - 1, u = e.value - 1 < 1 ? s.value - 1 : s.value, k = new Date(u, c - 1, r), m = w.toLunar(r, c, u), S = `${u}-${c}-${r}`;
40
- t.push({
41
- solar: k,
42
- lunar: m,
43
- isToday: S === _,
44
- isSelected: S === f,
45
- isCurrentMonth: !1
46
- });
47
- }
48
- for (let n = 1; n <= g; n++) {
49
- const r = new Date(s.value, e.value - 1, n), c = w.toLunar(n, e.value, s.value), u = `${s.value}-${e.value}-${n}`;
50
- t.push({
51
- solar: r,
52
- lunar: c,
53
- isToday: u === _,
54
- isSelected: u === f,
55
- isCurrentMonth: !0
56
- });
57
- }
58
- const j = 42 - t.length;
59
- for (let n = 1; n <= j; n++) {
60
- const r = e.value + 1 > 12 ? 1 : e.value + 1, c = e.value + 1 > 12 ? s.value + 1 : s.value, u = new Date(c, r - 1, n), k = w.toLunar(n, r, c), m = `${c}-${r}-${n}`;
61
- t.push({
62
- solar: u,
63
- lunar: k,
64
- isToday: m === _,
65
- isSelected: m === f,
66
- isCurrentMonth: !1
67
- });
68
- }
69
- return t;
28
+ emits: ["select", "month-change"],
29
+ setup(v, { emit: g }) {
30
+ const e = v, i = _(e.month), c = _(e.year), m = _(null), b = k(
31
+ () => e.selectedDate !== void 0 ? e.selectedDate : m.value
32
+ );
33
+ B(() => e.month, (a) => {
34
+ i.value = a;
35
+ }), B(() => e.year, (a) => {
36
+ c.value = a;
70
37
  });
71
- function z() {
72
- e.value === 1 ? (e.value = 12, s.value -= 1) : e.value -= 1;
38
+ const D = k(() => F(c.value)), d = g, h = k(() => K(e.locale, e.firstDayOfWeek)), M = k(() => V(e.locale).solarMonthNames), Y = k(
39
+ () => P(i.value, c.value, b.value, e.firstDayOfWeek)
40
+ );
41
+ function E() {
42
+ const a = i.value === 1 ? 12 : i.value - 1, f = i.value === 1 ? c.value - 1 : c.value;
43
+ i.value = a, c.value = f, d("month-change", a, f);
73
44
  }
74
- function G() {
75
- e.value === 12 ? (e.value = 1, s.value += 1) : e.value += 1;
45
+ function S() {
46
+ const a = i.value === 12 ? 1 : i.value + 1, f = i.value === 12 ? c.value + 1 : c.value;
47
+ i.value = a, c.value = f, d("month-change", a, f);
76
48
  }
77
- function M(t) {
78
- h.value = t.solar, E("select", t.solar, t.lunar);
49
+ function L(a) {
50
+ e.selectedDate === void 0 && (m.value = a.solar), d("select", a.solar, a.lunar);
79
51
  }
80
- function O(t, y) {
81
- (t.key === "Enter" || t.key === " ") && (t.preventDefault(), M(y));
52
+ function O(a, f) {
53
+ (a.key === "Enter" || a.key === " ") && (a.preventDefault(), L(f));
82
54
  }
83
- return (t, y) => (i(), d("div", {
84
- class: b(["lich-ta-calendar", `lichta-theme-${v.theme}`])
55
+ return (a, f) => (l(), s("div", {
56
+ class: N(["lich-ta-calendar", `lichta-theme-${e.theme}`, { "lich-ta-calendar--with-week-number": e.showWeekNumber }])
85
57
  }, [
86
- l("div", J, [
87
- l("button", {
58
+ t("div", U, [
59
+ t("button", {
88
60
  class: "lich-ta-calendar-nav",
89
61
  "aria-label": "Tháng trước",
90
- onClick: z
62
+ onClick: E
91
63
  }, "◀"),
92
- l("div", P, [
93
- l("span", Q, o(K[e.value - 1]) + ", " + o(s.value), 1),
94
- l("span", R, o(C.value.can) + " " + o(C.value.chi), 1)
64
+ t("div", j, [
65
+ t("span", q, n(M.value[i.value - 1]) + ", " + n(c.value), 1),
66
+ t("span", H, n(D.value.can) + " " + n(D.value.chi), 1)
95
67
  ]),
96
- l("button", {
68
+ t("button", {
97
69
  class: "lich-ta-calendar-nav",
98
70
  "aria-label": "Tháng sau",
99
- onClick: G
71
+ onClick: S
100
72
  }, "▶")
101
73
  ]),
102
- l("div", U, [
103
- (i(), d(T, null, N(V, (a) => l("div", {
104
- key: a,
74
+ t("div", J, [
75
+ e.showWeekNumber ? (l(), s("div", Q)) : w("", !0),
76
+ (l(!0), s(p, null, x(h.value, (o) => (l(), s("div", {
77
+ key: o,
105
78
  class: "lich-ta-calendar-weekday"
106
- }, o(a), 1)), 64))
79
+ }, n(o), 1))), 128))
107
80
  ]),
108
- l("div", X, [
109
- (i(!0), d(T, null, N(I.value, (a, D) => (i(), d("button", {
110
- key: D,
111
- class: b(["lich-ta-calendar-day", {
112
- "is-today": a.isToday,
113
- "is-selected": a.isSelected,
114
- "is-other-month": !a.isCurrentMonth,
115
- "is-first-lunar": a.lunar.day === 1
116
- }]),
117
- tabindex: a.isCurrentMonth ? 0 : -1,
118
- onClick: (g) => M(a),
119
- onKeydown: (g) => O(g, a)
120
- }, [
121
- l("span", ee, o(a.solar.getDate()), 1),
122
- v.showLunar ? (i(), d("span", ae, [
123
- a.lunar.day === 1 ? (i(), d(T, { key: 0 }, [
124
- Y(o(a.lunar.day) + "/" + o(a.lunar.month) + o(a.lunar.isLeap ? "*" : ""), 1)
125
- ], 64)) : (i(), d(T, { key: 1 }, [
126
- Y(o(a.lunar.day), 1)
127
- ], 64))
128
- ])) : x("", !0)
129
- ], 42, Z))), 128))
81
+ t("div", R, [
82
+ (l(!0), s(p, null, x(Y.value, (o, $) => (l(), s(p, { key: $ }, [
83
+ e.showWeekNumber && $ % 7 === 0 ? (l(), s("div", X, n(o.weekNumber), 1)) : w("", !0),
84
+ t("button", {
85
+ class: N(["lich-ta-calendar-day", {
86
+ "is-today": o.isToday,
87
+ "is-selected": o.isSelected,
88
+ "is-other-month": !o.isCurrentMonth,
89
+ "is-first-lunar": o.lunar.day === 1
90
+ }]),
91
+ tabindex: o.isCurrentMonth ? 0 : -1,
92
+ onClick: (C) => L(o),
93
+ onKeydown: (C) => O(C, o)
94
+ }, [
95
+ t("span", ee, n(o.solar.getDate()), 1),
96
+ e.showLunar ? (l(), s("span", ae, [
97
+ o.lunar.day === 1 ? (l(), s(p, { key: 0 }, [
98
+ W(n(o.lunar.day) + "/" + n(o.lunar.month) + n(o.lunar.isLeap ? "*" : ""), 1)
99
+ ], 64)) : (l(), s(p, { key: 1 }, [
100
+ W(n(o.lunar.day), 1)
101
+ ], 64))
102
+ ])) : w("", !0)
103
+ ], 42, Z)
104
+ ], 64))), 128))
130
105
  ]),
131
- t.$slots.default ? (i(), d("div", te, [
132
- A(t.$slots, "default")
133
- ])) : x("", !0)
106
+ a.$slots.default ? (l(), s("div", te, [
107
+ I(a.$slots, "default")
108
+ ])) : w("", !0)
109
+ ], 2));
110
+ }
111
+ }), ne = ["disabled", "placeholder", "value", "aria-expanded"], le = {
112
+ key: 0,
113
+ class: "lich-ta-datepicker-popover",
114
+ role: "dialog"
115
+ }, se = { class: "lich-ta-datepicker-calendar" }, oe = { class: "lich-ta-datepicker-calendar-header" }, ce = { class: "lich-ta-datepicker-calendar-title" }, re = { class: "lich-ta-datepicker-calendar-month-year" }, ie = { class: "lich-ta-datepicker-calendar-canchi" }, de = { class: "lich-ta-datepicker-calendar-weekdays" }, ue = { class: "lich-ta-datepicker-calendar-grid" }, he = ["tabindex", "onClick"], ve = { class: "solar-day" }, ye = {
116
+ key: 0,
117
+ class: "lunar-day"
118
+ }, _e = /* @__PURE__ */ T({
119
+ __name: "DatePicker",
120
+ props: {
121
+ value: { default: null },
122
+ placeholder: { default: "Chọn ngày" },
123
+ locale: { default: "vi" },
124
+ firstDayOfWeek: { default: 0 },
125
+ theme: { default: "classic" },
126
+ showLunar: { type: Boolean, default: !0 },
127
+ format: { type: Function, default: (v) => {
128
+ const g = String(v.getDate()).padStart(2, "0"), e = String(v.getMonth() + 1).padStart(2, "0");
129
+ return `${g}/${e}/${v.getFullYear()}`;
130
+ } },
131
+ disabled: { type: Boolean, default: !1 }
132
+ },
133
+ emits: ["select", "month-change"],
134
+ setup(v, { emit: g }) {
135
+ const e = v, i = g, c = _(e.value), m = _(!1), b = _(null), D = c.value ?? /* @__PURE__ */ new Date(), d = _(D.getMonth() + 1), h = _(D.getFullYear());
136
+ B(
137
+ () => e.value,
138
+ (r) => {
139
+ const y = r ?? null;
140
+ c.value = y, y && (d.value = y.getMonth() + 1, h.value = y.getFullYear());
141
+ }
142
+ );
143
+ const M = k(() => F(h.value)), Y = k(() => K(e.locale, e.firstDayOfWeek)), E = k(() => V(e.locale).solarMonthNames), S = k(() => P(d.value, h.value, c.value, e.firstDayOfWeek)), L = k(() => c.value ? e.format(c.value) : "");
144
+ function O() {
145
+ e.disabled || (m.value = !m.value);
146
+ }
147
+ function a() {
148
+ const r = d.value === 1 ? 12 : d.value - 1, y = d.value === 1 ? h.value - 1 : h.value;
149
+ d.value = r, h.value = y, i("month-change", r, y);
150
+ }
151
+ function f() {
152
+ const r = d.value === 12 ? 1 : d.value + 1, y = d.value === 12 ? h.value + 1 : h.value;
153
+ d.value = r, h.value = y, i("month-change", r, y);
154
+ }
155
+ function o(r) {
156
+ c.value = r.solar, m.value = !1, i("select", r.solar, r.lunar);
157
+ }
158
+ function $(r) {
159
+ b.value && !b.value.contains(r.target) && (m.value = !1);
160
+ }
161
+ function C(r) {
162
+ r.key === "Escape" && (m.value = !1);
163
+ }
164
+ return z(() => {
165
+ document.addEventListener("mousedown", $), document.addEventListener("keydown", C);
166
+ }), A(() => {
167
+ document.removeEventListener("mousedown", $), document.removeEventListener("keydown", C);
168
+ }), (r, y) => (l(), s("div", {
169
+ ref_key: "rootEl",
170
+ ref: b,
171
+ class: N(["lich-ta-datepicker", `lichta-theme-${v.theme}`])
172
+ }, [
173
+ t("input", {
174
+ type: "text",
175
+ class: "lich-ta-datepicker-input",
176
+ readonly: "",
177
+ disabled: v.disabled,
178
+ placeholder: v.placeholder,
179
+ value: L.value,
180
+ "aria-haspopup": "dialog",
181
+ "aria-expanded": m.value,
182
+ onClick: O
183
+ }, null, 8, ne),
184
+ m.value ? (l(), s("div", le, [
185
+ t("div", se, [
186
+ t("div", oe, [
187
+ t("button", {
188
+ type: "button",
189
+ class: "lich-ta-datepicker-calendar-nav",
190
+ "aria-label": "Tháng trước",
191
+ onClick: a
192
+ }, " ◀ "),
193
+ t("div", ce, [
194
+ t("span", re, n(E.value[d.value - 1]) + ", " + n(h.value), 1),
195
+ t("span", ie, n(M.value.can) + " " + n(M.value.chi), 1)
196
+ ]),
197
+ t("button", {
198
+ type: "button",
199
+ class: "lich-ta-datepicker-calendar-nav",
200
+ "aria-label": "Tháng sau",
201
+ onClick: f
202
+ }, " ▶ ")
203
+ ]),
204
+ t("div", de, [
205
+ (l(!0), s(p, null, x(Y.value, (u) => (l(), s("div", {
206
+ key: u,
207
+ class: "lich-ta-datepicker-calendar-weekday"
208
+ }, n(u), 1))), 128))
209
+ ]),
210
+ t("div", ue, [
211
+ (l(!0), s(p, null, x(S.value, (u, G) => (l(), s("button", {
212
+ key: G,
213
+ type: "button",
214
+ class: N(["lich-ta-datepicker-calendar-day", {
215
+ "is-today": u.isToday,
216
+ "is-selected": u.isSelected,
217
+ "is-other-month": !u.isCurrentMonth,
218
+ "is-first-lunar": u.lunar.day === 1
219
+ }]),
220
+ tabindex: u.isCurrentMonth ? 0 : -1,
221
+ onClick: (me) => o(u)
222
+ }, [
223
+ t("span", ve, n(u.solar.getDate()), 1),
224
+ v.showLunar ? (l(), s("span", ye, [
225
+ u.lunar.day === 1 ? (l(), s(p, { key: 0 }, [
226
+ W(n(u.lunar.day) + "/" + n(u.lunar.month) + n(u.lunar.isLeap ? "*" : ""), 1)
227
+ ], 64)) : (l(), s(p, { key: 1 }, [
228
+ W(n(u.lunar.day), 1)
229
+ ], 64))
230
+ ])) : w("", !0)
231
+ ], 10, he))), 128))
232
+ ])
233
+ ])
234
+ ])) : w("", !0)
134
235
  ], 2));
135
236
  }
136
237
  });
137
238
  export {
138
- le as Calendar
239
+ pe as Calendar,
240
+ _e as DatePicker
139
241
  };
@@ -1 +1 @@
1
- (function(c,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("@lichta/core")):typeof define=="function"&&define.amd?define(["exports","vue","@lichta/core"],e):(c=typeof globalThis<"u"?globalThis:c||self,e(c.LichTaVue={},c.Vue,c.LichTaCore))})(this,(function(c,e,h){"use strict";const E={class:"lich-ta-calendar-header"},$={class:"lich-ta-calendar-title"},w={class:"lich-ta-calendar-month-year"},B={class:"lich-ta-calendar-canchi"},N={class:"lich-ta-calendar-weekdays"},V={class:"lich-ta-calendar-grid"},L=["tabindex","onClick","onKeydown"],M={class:"solar-day"},b={key:0,class:"lunar-day"},F={key:0,class:"lich-ta-calendar-footer"},x=e.defineComponent({__name:"Calendar",props:{month:{default:new Date().getMonth()+1},year:{default:new Date().getFullYear()},showLunar:{type:Boolean,default:!0},locale:{default:"vi"},theme:{default:"classic"}},emits:["select"],setup(Y,{emit:K}){const u=Y,t=e.ref(u.month),l=e.ref(u.year),d=e.ref(null),_=e.computed(()=>h.getYearDetails(l.value)),j=K,q=["Tháng 1","Tháng 2","Tháng 3","Tháng 4","Tháng 5","Tháng 6","Tháng 7","Tháng 8","Tháng 9","Tháng 10","Tháng 11","Tháng 12"],v=["CN","T2","T3","T4","T5","T6","T7"],z=e.computed(()=>{const n=[],y=new Date(l.value,t.value-1,1),a=new Date(l.value,t.value,0),f=y.getDay(),m=a.getDate(),D=new Date,T=`${D.getFullYear()}-${D.getMonth()+1}-${D.getDate()}`;let g="";d.value&&(g=`${d.value.getFullYear()}-${d.value.getMonth()+1}-${d.value.getDate()}`);const P=new Date(l.value,t.value-1,0).getDate();for(let o=f-1;o>=0;o--){const s=P-o,r=t.value-1<1?12:t.value-1,i=t.value-1<1?l.value-1:l.value,k=new Date(i,r-1,s),p=h.LichTa.toLunar(s,r,i),C=`${i}-${r}-${s}`;n.push({solar:k,lunar:p,isToday:C===T,isSelected:C===g,isCurrentMonth:!1})}for(let o=1;o<=m;o++){const s=new Date(l.value,t.value-1,o),r=h.LichTa.toLunar(o,t.value,l.value),i=`${l.value}-${t.value}-${o}`;n.push({solar:s,lunar:r,isToday:i===T,isSelected:i===g,isCurrentMonth:!0})}const W=42-n.length;for(let o=1;o<=W;o++){const s=t.value+1>12?1:t.value+1,r=t.value+1>12?l.value+1:l.value,i=new Date(r,s-1,o),k=h.LichTa.toLunar(o,s,r),p=`${r}-${s}-${o}`;n.push({solar:i,lunar:k,isToday:p===T,isSelected:p===g,isCurrentMonth:!1})}return n});function I(){t.value===1?(t.value=12,l.value-=1):t.value-=1}function O(){t.value===12?(t.value=1,l.value+=1):t.value+=1}function S(n){d.value=n.solar,j("select",n.solar,n.lunar)}function G(n,y){(n.key==="Enter"||n.key===" ")&&(n.preventDefault(),S(y))}return(n,y)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["lich-ta-calendar",`lichta-theme-${u.theme}`])},[e.createElementVNode("div",E,[e.createElementVNode("button",{class:"lich-ta-calendar-nav","aria-label":"Tháng trước",onClick:I},"◀"),e.createElementVNode("div",$,[e.createElementVNode("span",w,e.toDisplayString(q[t.value-1])+", "+e.toDisplayString(l.value),1),e.createElementVNode("span",B,e.toDisplayString(_.value.can)+" "+e.toDisplayString(_.value.chi),1)]),e.createElementVNode("button",{class:"lich-ta-calendar-nav","aria-label":"Tháng sau",onClick:O},"▶")]),e.createElementVNode("div",N,[(e.openBlock(),e.createElementBlock(e.Fragment,null,e.renderList(v,a=>e.createElementVNode("div",{key:a,class:"lich-ta-calendar-weekday"},e.toDisplayString(a),1)),64))]),e.createElementVNode("div",V,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(z.value,(a,f)=>(e.openBlock(),e.createElementBlock("button",{key:f,class:e.normalizeClass(["lich-ta-calendar-day",{"is-today":a.isToday,"is-selected":a.isSelected,"is-other-month":!a.isCurrentMonth,"is-first-lunar":a.lunar.day===1}]),tabindex:a.isCurrentMonth?0:-1,onClick:m=>S(a),onKeydown:m=>G(m,a)},[e.createElementVNode("span",M,e.toDisplayString(a.solar.getDate()),1),u.showLunar?(e.openBlock(),e.createElementBlock("span",b,[a.lunar.day===1?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(e.toDisplayString(a.lunar.day)+"/"+e.toDisplayString(a.lunar.month)+e.toDisplayString(a.lunar.isLeap?"*":""),1)],64)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createTextVNode(e.toDisplayString(a.lunar.day),1)],64))])):e.createCommentVNode("",!0)],42,L))),128))]),n.$slots.default?(e.openBlock(),e.createElementBlock("div",F,[e.renderSlot(n.$slots,"default")])):e.createCommentVNode("",!0)],2))}});c.Calendar=x,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(k,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("@lichta/core")):typeof define=="function"&&define.amd?define(["exports","vue","@lichta/core"],e):(k=typeof globalThis<"u"?globalThis:k||self,e(k.LichTaVue={},k.Vue,k.LichTaCore))})(this,(function(k,e,y){"use strict";const C={class:"lich-ta-calendar-header"},S={class:"lich-ta-calendar-title"},M={class:"lich-ta-calendar-month-year"},$={class:"lich-ta-calendar-canchi"},L={class:"lich-ta-calendar-weekdays"},T={key:0,class:"lich-ta-calendar-week-number","aria-hidden":"true"},x={class:"lich-ta-calendar-grid"},F={key:0,class:"lich-ta-calendar-week-number"},W=["tabindex","onClick","onKeydown"],Y={class:"solar-day"},O={key:0,class:"lunar-day"},z={key:0,class:"lich-ta-calendar-footer"},K=e.defineComponent({__name:"Calendar",props:{month:{default:new Date().getMonth()+1},year:{default:new Date().getFullYear()},selectedDate:{default:void 0},showLunar:{type:Boolean,default:!0},locale:{default:"vi"},firstDayOfWeek:{default:0},showWeekNumber:{type:Boolean,default:!1},theme:{default:"classic"}},emits:["select","month-change"],setup(d,{emit:u}){const t=d,c=e.ref(t.month),l=e.ref(t.year),m=e.ref(null),f=e.computed(()=>t.selectedDate!==void 0?t.selectedDate:m.value);e.watch(()=>t.month,a=>{c.value=a}),e.watch(()=>t.year,a=>{l.value=a});const g=e.computed(()=>y.getYearDetails(l.value)),r=u,i=e.computed(()=>y.getWeekDayLabels(t.locale,t.firstDayOfWeek)),E=e.computed(()=>y.t(t.locale).solarMonthNames),w=e.computed(()=>y.getCalendarGrid(c.value,l.value,f.value,t.firstDayOfWeek));function N(){const a=c.value===1?12:c.value-1,p=c.value===1?l.value-1:l.value;c.value=a,l.value=p,r("month-change",a,p)}function V(){const a=c.value===12?1:c.value+1,p=c.value===12?l.value+1:l.value;c.value=a,l.value=p,r("month-change",a,p)}function B(a){t.selectedDate===void 0&&(m.value=a.solar),r("select",a.solar,a.lunar)}function b(a,p){(a.key==="Enter"||a.key===" ")&&(a.preventDefault(),B(p))}return(a,p)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["lich-ta-calendar",`lichta-theme-${t.theme}`,{"lich-ta-calendar--with-week-number":t.showWeekNumber}])},[e.createElementVNode("div",C,[e.createElementVNode("button",{class:"lich-ta-calendar-nav","aria-label":"Tháng trước",onClick:N},""),e.createElementVNode("div",S,[e.createElementVNode("span",M,e.toDisplayString(E.value[c.value-1])+", "+e.toDisplayString(l.value),1),e.createElementVNode("span",$,e.toDisplayString(g.value.can)+" "+e.toDisplayString(g.value.chi),1)]),e.createElementVNode("button",{class:"lich-ta-calendar-nav","aria-label":"Tháng sau",onClick:V},"")]),e.createElementVNode("div",L,[t.showWeekNumber?(e.openBlock(),e.createElementBlock("div",T)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(i.value,n=>(e.openBlock(),e.createElementBlock("div",{key:n,class:"lich-ta-calendar-weekday"},e.toDisplayString(n),1))),128))]),e.createElementVNode("div",x,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(w.value,(n,D)=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:D},[t.showWeekNumber&&D%7===0?(e.openBlock(),e.createElementBlock("div",F,e.toDisplayString(n.weekNumber),1)):e.createCommentVNode("",!0),e.createElementVNode("button",{class:e.normalizeClass(["lich-ta-calendar-day",{"is-today":n.isToday,"is-selected":n.isSelected,"is-other-month":!n.isCurrentMonth,"is-first-lunar":n.lunar.day===1}]),tabindex:n.isCurrentMonth?0:-1,onClick:_=>B(n),onKeydown:_=>b(_,n)},[e.createElementVNode("span",Y,e.toDisplayString(n.solar.getDate()),1),t.showLunar?(e.openBlock(),e.createElementBlock("span",O,[n.lunar.day===1?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(e.toDisplayString(n.lunar.day)+"/"+e.toDisplayString(n.lunar.month)+e.toDisplayString(n.lunar.isLeap?"*":""),1)],64)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createTextVNode(e.toDisplayString(n.lunar.day),1)],64))])):e.createCommentVNode("",!0)],42,W)],64))),128))]),a.$slots.default?(e.openBlock(),e.createElementBlock("div",z,[e.renderSlot(a.$slots,"default")])):e.createCommentVNode("",!0)],2))}}),P=["disabled","placeholder","value","aria-expanded"],G={key:0,class:"lich-ta-datepicker-popover",role:"dialog"},j={class:"lich-ta-datepicker-calendar"},q={class:"lich-ta-datepicker-calendar-header"},I={class:"lich-ta-datepicker-calendar-title"},A={class:"lich-ta-datepicker-calendar-month-year"},U={class:"lich-ta-datepicker-calendar-canchi"},H={class:"lich-ta-datepicker-calendar-weekdays"},J={class:"lich-ta-datepicker-calendar-grid"},Q=["tabindex","onClick"],R={class:"solar-day"},X={key:0,class:"lunar-day"},Z=e.defineComponent({__name:"DatePicker",props:{value:{default:null},placeholder:{default:"Chọn ngày"},locale:{default:"vi"},firstDayOfWeek:{default:0},theme:{default:"classic"},showLunar:{type:Boolean,default:!0},format:{type:Function,default:d=>{const u=String(d.getDate()).padStart(2,"0"),t=String(d.getMonth()+1).padStart(2,"0");return`${u}/${t}/${d.getFullYear()}`}},disabled:{type:Boolean,default:!1}},emits:["select","month-change"],setup(d,{emit:u}){const t=d,c=u,l=e.ref(t.value),m=e.ref(!1),f=e.ref(null),g=l.value??new Date,r=e.ref(g.getMonth()+1),i=e.ref(g.getFullYear());e.watch(()=>t.value,o=>{const h=o??null;l.value=h,h&&(r.value=h.getMonth()+1,i.value=h.getFullYear())});const E=e.computed(()=>y.getYearDetails(i.value)),w=e.computed(()=>y.getWeekDayLabels(t.locale,t.firstDayOfWeek)),N=e.computed(()=>y.t(t.locale).solarMonthNames),V=e.computed(()=>y.getCalendarGrid(r.value,i.value,l.value,t.firstDayOfWeek)),B=e.computed(()=>l.value?t.format(l.value):"");function b(){t.disabled||(m.value=!m.value)}function a(){const o=r.value===1?12:r.value-1,h=r.value===1?i.value-1:i.value;r.value=o,i.value=h,c("month-change",o,h)}function p(){const o=r.value===12?1:r.value+1,h=r.value===12?i.value+1:i.value;r.value=o,i.value=h,c("month-change",o,h)}function n(o){l.value=o.solar,m.value=!1,c("select",o.solar,o.lunar)}function D(o){f.value&&!f.value.contains(o.target)&&(m.value=!1)}function _(o){o.key==="Escape"&&(m.value=!1)}return e.onMounted(()=>{document.addEventListener("mousedown",D),document.addEventListener("keydown",_)}),e.onBeforeUnmount(()=>{document.removeEventListener("mousedown",D),document.removeEventListener("keydown",_)}),(o,h)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"rootEl",ref:f,class:e.normalizeClass(["lich-ta-datepicker",`lichta-theme-${d.theme}`])},[e.createElementVNode("input",{type:"text",class:"lich-ta-datepicker-input",readonly:"",disabled:d.disabled,placeholder:d.placeholder,value:B.value,"aria-haspopup":"dialog","aria-expanded":m.value,onClick:b},null,8,P),m.value?(e.openBlock(),e.createElementBlock("div",G,[e.createElementVNode("div",j,[e.createElementVNode("div",q,[e.createElementVNode("button",{type:"button",class:"lich-ta-datepicker-calendar-nav","aria-label":"Tháng trước",onClick:a}," "),e.createElementVNode("div",I,[e.createElementVNode("span",A,e.toDisplayString(N.value[r.value-1])+", "+e.toDisplayString(i.value),1),e.createElementVNode("span",U,e.toDisplayString(E.value.can)+" "+e.toDisplayString(E.value.chi),1)]),e.createElementVNode("button",{type:"button",class:"lich-ta-datepicker-calendar-nav","aria-label":"Tháng sau",onClick:p}," ")]),e.createElementVNode("div",H,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(w.value,s=>(e.openBlock(),e.createElementBlock("div",{key:s,class:"lich-ta-datepicker-calendar-weekday"},e.toDisplayString(s),1))),128))]),e.createElementVNode("div",J,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(V.value,(s,v)=>(e.openBlock(),e.createElementBlock("button",{key:v,type:"button",class:e.normalizeClass(["lich-ta-datepicker-calendar-day",{"is-today":s.isToday,"is-selected":s.isSelected,"is-other-month":!s.isCurrentMonth,"is-first-lunar":s.lunar.day===1}]),tabindex:s.isCurrentMonth?0:-1,onClick:ee=>n(s)},[e.createElementVNode("span",R,e.toDisplayString(s.solar.getDate()),1),d.showLunar?(e.openBlock(),e.createElementBlock("span",X,[s.lunar.day===1?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(e.toDisplayString(s.lunar.day)+"/"+e.toDisplayString(s.lunar.month)+e.toDisplayString(s.lunar.isLeap?"*":""),1)],64)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createTextVNode(e.toDisplayString(s.lunar.day),1)],64))])):e.createCommentVNode("",!0)],10,Q))),128))])])])):e.createCommentVNode("",!0)],2))}});k.Calendar=K,k.DatePicker=Z,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lichta/vue",
3
- "version": "2.0.1",
3
+ "version": "2.2.0",
4
4
  "description": "Vue components for LichTa",
5
5
  "author": "Zeforc Labs | Stridev",
6
6
  "license": "MIT",
@@ -20,7 +20,7 @@
20
20
  "LICENSE"
21
21
  ],
22
22
  "dependencies": {
23
- "@lichta/core": "2.0.1"
23
+ "@lichta/core": "2.2.0"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "vue": "^3.0.0"