@celestia-island/hikari 0.49.3 → 0.49.5
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/package.json
CHANGED
|
@@ -393,7 +393,7 @@ describe("HkDatePicker", () => {
|
|
|
393
393
|
await nextTick();
|
|
394
394
|
panel()?.querySelector<HTMLButtonElement>(".hk-dp-title-btn")?.click();
|
|
395
395
|
await settle();
|
|
396
|
-
|
|
396
|
+
await waitForTitle("2026");
|
|
397
397
|
const navs = () => panel()?.querySelectorAll<HTMLButtonElement>(".hk-dp-nav");
|
|
398
398
|
navs()?.[1].click();
|
|
399
399
|
await nextTick();
|
|
@@ -413,23 +413,36 @@ describe("HkDatePicker", () => {
|
|
|
413
413
|
const stage = panel()?.querySelector<HTMLElement>(".hk-dp-stage");
|
|
414
414
|
expect(stage).not.toBeNull();
|
|
415
415
|
expect(stage?.children.length).toBe(1); // the single days pane
|
|
416
|
+
const pickCount = () =>
|
|
417
|
+
stage?.querySelectorAll<HTMLButtonElement>(".hk-dp-cell[data-variant='pick']").length ?? 0;
|
|
418
|
+
// Destination state = the entering pane mounted AND the leaving pane
|
|
419
|
+
// gone; mid-transition both conditions half-hold.
|
|
420
|
+
const settledDrill = (days: boolean) => (): boolean =>
|
|
421
|
+
days
|
|
422
|
+
? stage?.children.length === 1 &&
|
|
423
|
+
stage?.querySelectorAll<HTMLButtonElement>(".hk-dp-cell:not([data-variant])").length === 42
|
|
424
|
+
: pickCount() === 12 && stage?.children.length === 1;
|
|
416
425
|
panel()?.querySelector<HTMLButtonElement>(".hk-dp-title-btn")?.click();
|
|
417
426
|
await settle();
|
|
427
|
+
await waitForView("the months grid settled to one pane", settledDrill(false));
|
|
418
428
|
expect(panel()?.querySelector<HTMLElement>(".hk-dp-stage")).toBe(stage);
|
|
419
429
|
expect(stage?.getAttribute("data-dir")).toBe("fwd");
|
|
420
430
|
expect(stage?.children.length).toBe(1); // one pane at a time after settle
|
|
421
|
-
expect(
|
|
431
|
+
expect(pickCount()).toBe(12);
|
|
422
432
|
panel()?.querySelector<HTMLButtonElement>(".hk-dp-title-btn")?.click();
|
|
423
433
|
await settle();
|
|
434
|
+
await waitForView("the years grid settled to one pane", settledDrill(false));
|
|
424
435
|
expect(stage?.getAttribute("data-dir")).toBe("fwd");
|
|
425
|
-
expect(
|
|
436
|
+
expect(pickCount()).toBe(12);
|
|
426
437
|
// back steps down the stack one level at a time: years → months → days.
|
|
427
438
|
panel()?.querySelector<HTMLButtonElement>(".hk-dp-back")?.click();
|
|
428
439
|
await settle();
|
|
440
|
+
await waitForView("the months grid again, one pane", settledDrill(false));
|
|
429
441
|
expect(stage?.getAttribute("data-dir")).toBe("back");
|
|
430
|
-
expect(
|
|
442
|
+
expect(pickCount()).toBe(12);
|
|
431
443
|
panel()?.querySelector<HTMLButtonElement>(".hk-dp-back")?.click();
|
|
432
444
|
await settle();
|
|
445
|
+
await waitForView("the days grid settled to one pane", settledDrill(true));
|
|
433
446
|
expect(stage?.getAttribute("data-dir")).toBe("back");
|
|
434
447
|
expect(stage?.querySelectorAll<HTMLButtonElement>(".hk-dp-cell:not([data-variant])").length).toBe(42);
|
|
435
448
|
});
|
|
@@ -83,6 +83,20 @@ async function waitForTitle(expected: string): Promise<void> {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
/** The pick cells of the drilled months view (exactly 12 once mounted). */
|
|
87
|
+
function pickCells(): HTMLButtonElement[] {
|
|
88
|
+
return Array.from(picker()?.querySelectorAll<HTMLButtonElement>(".hk-dtp-cell[data-variant='pick']") ?? []);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Generic state poll over the same drill race: wait until `probe` holds. */
|
|
92
|
+
async function waitForView(desc: string, probe: () => boolean): Promise<void> {
|
|
93
|
+
const deadline = Date.now() + 2000;
|
|
94
|
+
while (!probe()) {
|
|
95
|
+
if (Date.now() > deadline) throw new Error(`view never reached: ${desc}`);
|
|
96
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
86
100
|
function picker(): HTMLElement | null {
|
|
87
101
|
return document.querySelector<HTMLElement>(".hk-dtp");
|
|
88
102
|
}
|
|
@@ -178,6 +192,10 @@ describe("HkDateTimePicker", () => {
|
|
|
178
192
|
const monthBtn = picker()?.querySelectorAll<HTMLButtonElement>(".hk-dtp-title-btn")[0];
|
|
179
193
|
monthBtn?.click();
|
|
180
194
|
await settle();
|
|
195
|
+
// Destination state = the months pane mounted AND the leaving days
|
|
196
|
+
// pane gone — mid-transition both conditions half-hold.
|
|
197
|
+
await waitForView("the months grid settled to one pane", () =>
|
|
198
|
+
pickCells().length === 12 && picker()?.querySelectorAll(".hk-dtp-cell").length === 12);
|
|
181
199
|
const cells = Array.from(picker()?.querySelectorAll<HTMLElement>(".hk-dtp-cell") ?? [])
|
|
182
200
|
.map((c) => c.textContent ?? "");
|
|
183
201
|
const expected = Array.from({ length: 12 }, (_, i) =>
|
|
@@ -196,6 +214,7 @@ describe("HkDateTimePicker", () => {
|
|
|
196
214
|
const monthBtn = picker()?.querySelectorAll<HTMLButtonElement>(".hk-dtp-title-btn")[0];
|
|
197
215
|
monthBtn?.click();
|
|
198
216
|
await settle();
|
|
217
|
+
await waitForView("the months grid", () => pickCells().length === 12);
|
|
199
218
|
expect(stage?.getAttribute("data-dir")).toBe("fwd");
|
|
200
219
|
expect(picker()?.querySelector<HTMLElement>(".hk-dtp-stage")).toBe(stage);
|
|
201
220
|
expect(stage?.children.length).toBe(1); // one pane at a time after settle
|
|
@@ -205,8 +224,9 @@ describe("HkDateTimePicker", () => {
|
|
|
205
224
|
expect(picker()?.querySelectorAll(".hk-dtp-step").length).toBe(2);
|
|
206
225
|
picker()?.querySelector<HTMLButtonElement>(".hk-dtp-back")?.click();
|
|
207
226
|
await settle();
|
|
227
|
+
await waitForView("the days grid settled to one pane", () =>
|
|
228
|
+
dayCells().length === 42 && stage?.children.length === 1);
|
|
208
229
|
expect(stage?.getAttribute("data-dir")).toBe("back");
|
|
209
|
-
expect(dayCells().length).toBe(42);
|
|
210
230
|
});
|
|
211
231
|
|
|
212
232
|
it("shifts the year with the chevrons inside the month view", async () => {
|
|
@@ -229,7 +249,8 @@ describe("HkDateTimePicker", () => {
|
|
|
229
249
|
const monthBtn = picker()?.querySelectorAll<HTMLButtonElement>(".hk-dtp-title-btn")[0];
|
|
230
250
|
monthBtn?.click();
|
|
231
251
|
await settle();
|
|
232
|
-
|
|
252
|
+
await waitForView("the months grid", () => pickCells().length === 12);
|
|
253
|
+
expect(pickCells().length).toBe(12);
|
|
233
254
|
// The first step button is "Hour +"; bumping it changes only the time
|
|
234
255
|
// part of the model, which must not yank the view back to days.
|
|
235
256
|
const upBtn = picker()?.querySelector<HTMLButtonElement>(".hk-dtp-step-btn");
|
|
@@ -118,32 +118,43 @@
|
|
|
118
118
|
will-change: transform, opacity, clip-path;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
// Close: the whole frame fades and drifts down as ONE piece — the
|
|
122
|
+
// unveil's clip does NOT re-run on close. Re-clipping first made the
|
|
123
|
+
// bottom band (usually the footer) vanish at the very first frame of
|
|
124
|
+
// the close while the rest was still on screen, which read as broken
|
|
125
|
+
// (user report 2026-09-14).
|
|
121
126
|
.hk-modal-content-leave-active {
|
|
122
127
|
transition:
|
|
123
128
|
opacity var(--hk-modal-duration, 0.25s)
|
|
124
129
|
var(--hk-modal-ease-in, cubic-bezier(0.4, 0, 1, 1)),
|
|
125
130
|
transform var(--hk-modal-duration, 0.25s)
|
|
126
|
-
var(--hk-modal-ease-in, cubic-bezier(0.4, 0, 1, 1)),
|
|
127
|
-
clip-path var(--hk-modal-duration, 0.25s)
|
|
128
131
|
var(--hk-modal-ease-in, cubic-bezier(0.4, 0, 1, 1));
|
|
129
|
-
will-change: transform, opacity
|
|
132
|
+
will-change: transform, opacity;
|
|
130
133
|
}
|
|
131
134
|
|
|
132
|
-
.hk-modal-content-enter-from
|
|
133
|
-
.hk-modal-content-leave-to {
|
|
135
|
+
.hk-modal-content-enter-from {
|
|
134
136
|
opacity: 0;
|
|
135
137
|
transform: translate(-50%, -50%) translateY(5%);
|
|
136
138
|
clip-path: inset(0 0 10% 0 round 0 0 var(--hk-modal-radius, var(--radius-lg, 12px))
|
|
137
139
|
var(--hk-modal-radius, var(--radius-lg, 12px)));
|
|
138
140
|
}
|
|
139
141
|
|
|
140
|
-
.hk-modal-content-enter-to
|
|
141
|
-
.hk-modal-content-leave-from {
|
|
142
|
+
.hk-modal-content-enter-to {
|
|
142
143
|
opacity: 1;
|
|
143
144
|
transform: translate(-50%, -50%);
|
|
144
145
|
clip-path: inset(0 0 0 0 round 0 0 var(--hk-modal-radius, var(--radius-lg, 12px))
|
|
145
146
|
var(--hk-modal-radius, var(--radius-lg, 12px)));
|
|
146
147
|
}
|
|
148
|
+
|
|
149
|
+
.hk-modal-content-leave-from {
|
|
150
|
+
opacity: 1;
|
|
151
|
+
transform: translate(-50%, -50%);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.hk-modal-content-leave-to {
|
|
155
|
+
opacity: 0;
|
|
156
|
+
transform: translate(-50%, -50%) translateY(5%);
|
|
157
|
+
}
|
|
147
158
|
}
|
|
148
159
|
|
|
149
160
|
// ------
|