@celestia-island/hikari 0.55.12 → 0.55.13
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 +1 -1
- package/src/components/HkAdminHeader.tsx +4 -5
- package/src/components/HkButton.test.tsx +2 -2
- package/src/components/HkButton.tsx +45 -1
- package/src/components/HkInput.password.test.tsx +478 -64
- package/src/components/HkInput.tsx +6 -3
- package/src/components/HkPasswordSurface.scss +3 -2
- package/src/components/HkPasswordSurface.tsx +134 -18
- package/src/components/HkSelectionGrid.scss +13 -0
- package/src/components/HkSelectionGrid.test.tsx +49 -0
- package/src/components/HkSelectionGrid.tsx +25 -1
- package/src/components/revealKinematogram.test.ts +121 -0
- package/src/components/revealKinematogram.ts +293 -0
- package/src/runtime/animationBus.test.ts +18 -1
- package/src/runtime/animationBus.ts +9 -0
- package/src/styles/admin-tokens.scss +4 -22
package/package.json
CHANGED
|
@@ -187,6 +187,10 @@ export const HkAdminHeader = defineComponent({
|
|
|
187
187
|
aria-expanded={props.avatarAction === "menu" ? userMenuOpen.value : undefined}
|
|
188
188
|
onClick={onAvatarClick}
|
|
189
189
|
>
|
|
190
|
+
{/* Deliberately NO hover veil here: the trigger opens the user
|
|
191
|
+
* MENU (the avatar edit lives one row down as the Camera
|
|
192
|
+
* item), so a camera overlay would promise click-to-change
|
|
193
|
+
* and lie (user report 2026-09-16). */}
|
|
190
194
|
{props.avatarUrl && !avatarFailed.value ? (
|
|
191
195
|
<img
|
|
192
196
|
src={props.avatarUrl}
|
|
@@ -204,11 +208,6 @@ export const HkAdminHeader = defineComponent({
|
|
|
204
208
|
{props.username?.charAt(0).toUpperCase() || "?"}
|
|
205
209
|
</span>
|
|
206
210
|
)}
|
|
207
|
-
{props.avatarAction === "menu" && (
|
|
208
|
-
<div class="s-admin-header-avatar-veil">
|
|
209
|
-
<Camera size={10} class="s-admin-header-veil-icon" />
|
|
210
|
-
</div>
|
|
211
|
-
)}
|
|
212
211
|
</button>
|
|
213
212
|
{/* WHERE am I — the open view's title, not the nickname. The
|
|
214
213
|
1.5 line-height (in the class) keeps descenders (g, y, p)
|
|
@@ -104,7 +104,7 @@ describe("HkButton click guard", () => {
|
|
|
104
104
|
|
|
105
105
|
it("clears the loading state back to a clickable button (aria-busy drops off)", () => {
|
|
106
106
|
const busy = mount(h(HkButton, { loading: true }, () => "x"));
|
|
107
|
-
expect(busy.querySelector(".hk-
|
|
107
|
+
expect(busy.querySelector(".hk-btn-ring")).not.toBeNull();
|
|
108
108
|
const idle = mount(h(HkButton, () => "x"));
|
|
109
109
|
const btn = button(idle);
|
|
110
110
|
expect(idle.querySelector(".hk-spinner")).toBeNull();
|
|
@@ -123,7 +123,7 @@ describe("HkButton content slots", () => {
|
|
|
123
123
|
// Loading swaps the icon out for the spinner — never both.
|
|
124
124
|
const busy = mount(h(HkButton, { icon: "close", loading: true }, () => "x"));
|
|
125
125
|
expect(busy.querySelector(".hk-btn-icon")).toBeNull();
|
|
126
|
-
expect(busy.querySelector(".hk-
|
|
126
|
+
expect(busy.querySelector(".hk-btn-ring")).not.toBeNull();
|
|
127
127
|
});
|
|
128
128
|
|
|
129
129
|
it("renders the suffix icon slot", () => {
|
|
@@ -66,7 +66,51 @@ export default defineComponent({
|
|
|
66
66
|
aria-busy={props.loading || undefined}
|
|
67
67
|
onClick={(e) => emit("click", e)}
|
|
68
68
|
>
|
|
69
|
-
{props.loading ?
|
|
69
|
+
{props.loading ? (
|
|
70
|
+
/* Loading ring as inline SVG + SMIL: renders identically in
|
|
71
|
+
WebView2 hosts where CSS-border rings got lost to border-
|
|
72
|
+
color pipelines or where the animation context suspends CSS
|
|
73
|
+
animations in rAF-starved background windows (user report
|
|
74
|
+
2026-09-16: an empty gap where the login ring should be).
|
|
75
|
+
Stroke follows currentcolor; SMIL rotates independently of
|
|
76
|
+
the CSS animation suspension switch. */
|
|
77
|
+
<svg
|
|
78
|
+
class="hk-btn-ring"
|
|
79
|
+
viewBox="0 0 16 16"
|
|
80
|
+
width="14"
|
|
81
|
+
height="14"
|
|
82
|
+
aria-hidden="true"
|
|
83
|
+
>
|
|
84
|
+
<circle
|
|
85
|
+
cx="8"
|
|
86
|
+
cy="8"
|
|
87
|
+
r="6.5"
|
|
88
|
+
fill="none"
|
|
89
|
+
stroke="currentColor"
|
|
90
|
+
stroke-opacity="0.3"
|
|
91
|
+
stroke-width="1.8"
|
|
92
|
+
/>
|
|
93
|
+
<circle
|
|
94
|
+
cx="8"
|
|
95
|
+
cy="8"
|
|
96
|
+
r="6.5"
|
|
97
|
+
fill="none"
|
|
98
|
+
stroke="currentColor"
|
|
99
|
+
stroke-width="1.8"
|
|
100
|
+
stroke-linecap="round"
|
|
101
|
+
stroke-dasharray="30 11"
|
|
102
|
+
>
|
|
103
|
+
<animateTransform
|
|
104
|
+
attributeName="transform"
|
|
105
|
+
type="rotate"
|
|
106
|
+
from="0 8 8"
|
|
107
|
+
to="360 8 8"
|
|
108
|
+
dur="0.7s"
|
|
109
|
+
repeatCount="indefinite"
|
|
110
|
+
/>
|
|
111
|
+
</circle>
|
|
112
|
+
</svg>
|
|
113
|
+
) : null}
|
|
70
114
|
{!props.loading && props.icon ? (
|
|
71
115
|
<span class="hk-btn-icon">
|
|
72
116
|
<HIcon name={props.icon} size={16} />
|