@celestia-island/hikari 0.55.302 → 0.55.304
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/HkAffixPicker.scss +16 -3
- package/src/components/HkDatePicker.scss +7 -2
- package/src/components/HkFileField.scss +3 -21
- package/src/components/HkFileField.tsx +9 -16
- package/src/components/HkFilterPanel.scss +22 -44
- package/src/components/HkFilterPanel.tsx +14 -10
- package/src/components/HkKeywordSearchModal.scss +3 -16
- package/src/components/HkKeywordSearchModal.tsx +20 -15
- package/src/components/HkModal.open-close-scale.test.ts +187 -50
- package/src/components/HkModal.scss +79 -42
- package/src/components/HkPasswordSurface.scss +9 -2
- package/src/components/HkSearchInput.scss +11 -4
- package/src/components/HkSelectionGrid.scss +3 -29
- package/src/components/HkSelectionGrid.tsx +7 -4
- package/src/components/HkTag.scss +4 -24
- package/src/components/HkTag.tsx +7 -4
- package/src/components/HkThemePanelContent.tsx +9 -5
- package/src/components/HkThemeToggle.scss +13 -23
- package/src/components/HkTokenInput.scss +19 -14
- package/src/components/HkTokenInput.tsx +7 -4
- package/src/components/HkUserPicker.scss +4 -17
- package/src/components/HkUserPicker.tsx +9 -4
- package/src/components/closeFamily.contract.test.tsx +44 -8
package/package.json
CHANGED
|
@@ -181,6 +181,13 @@
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
.hk-affix-tag-x {
|
|
184
|
+
/* Wave B2 hybrid decision: the × keeps its own onmousedown
|
|
185
|
+
prevent-default (tapping must not steal focus or start a selection) and
|
|
186
|
+
its 1.5rem field density, so it deliberately stays a BARE button — the
|
|
187
|
+
contract is pinned Rust-side
|
|
188
|
+
(`affix_tag_close_stays_a_bare_button_by_contract`). What standardizes
|
|
189
|
+
is the INK: it consumes the icon-button channel vars (current values as
|
|
190
|
+
first fallbacks = zero visual change). */
|
|
184
191
|
flex: none;
|
|
185
192
|
display: inline-flex;
|
|
186
193
|
align-items: center;
|
|
@@ -191,15 +198,21 @@
|
|
|
191
198
|
border: 0;
|
|
192
199
|
border-radius: var(--radius-full, 999px);
|
|
193
200
|
background: transparent;
|
|
194
|
-
color: rgb(var(--color-muted));
|
|
201
|
+
color: var(--hi-icon-button-icon-color, rgb(var(--color-muted)));
|
|
195
202
|
cursor: pointer;
|
|
196
203
|
appearance: none;
|
|
197
204
|
transition: color 0.12s ease, background 0.12s ease;
|
|
198
205
|
|
|
199
206
|
&:hover,
|
|
200
207
|
&:focus-visible {
|
|
201
|
-
color:
|
|
202
|
-
|
|
208
|
+
color: var(
|
|
209
|
+
--hi-icon-button-icon-color-active,
|
|
210
|
+
rgb(var(--color-error, 247 118 142))
|
|
211
|
+
);
|
|
212
|
+
background: var(
|
|
213
|
+
--hi-icon-button-bg-hover,
|
|
214
|
+
rgb(var(--color-error, 247 118 142) / 12%)
|
|
215
|
+
);
|
|
203
216
|
}
|
|
204
217
|
}
|
|
205
218
|
|
|
@@ -95,6 +95,11 @@
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
.hk-dp-clear {
|
|
98
|
+
/* Wave B1 hybrid decision (see HkSearchInput's twin): tabindex=-1 + own
|
|
99
|
+
keydown stop-propagation = stays a BARE button, pinned by
|
|
100
|
+
`date_clear_stays_a_bare_button_by_contract`. The reveal-on-hover
|
|
101
|
+
mechanism is the field's own contract and stays. What standardizes is
|
|
102
|
+
the INK via the icon-button channel vars (zero visual change). */
|
|
98
103
|
appearance: none;
|
|
99
104
|
display: inline-flex;
|
|
100
105
|
align-items: center;
|
|
@@ -104,7 +109,7 @@
|
|
|
104
109
|
border: 0;
|
|
105
110
|
background: transparent;
|
|
106
111
|
border-radius: var(--radius-sm, 4px);
|
|
107
|
-
color: var(--hi-color-muted);
|
|
112
|
+
color: var(--hi-icon-button-icon-color, var(--hi-color-muted));
|
|
108
113
|
cursor: pointer;
|
|
109
114
|
opacity: 0;
|
|
110
115
|
transition: opacity var(--duration-fast, 0.15s) ease, color var(--duration-fast, 0.15s) ease;
|
|
@@ -116,7 +121,7 @@
|
|
|
116
121
|
}
|
|
117
122
|
|
|
118
123
|
&:hover {
|
|
119
|
-
color: var(--hi-color-text-primary);
|
|
124
|
+
color: var(--hi-icon-button-icon-color-active, var(--hi-color-text-primary));
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
|
|
@@ -98,28 +98,10 @@
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
.hk-file-clear {
|
|
101
|
+
/* The clear affordance is the STANDARD icon button (wave B1): S24 exactly
|
|
102
|
+
replaces the old 1.5rem box; box, ink, hover and focus come from the
|
|
103
|
+
component. The seat keeps only its flex slot in the trigger row. */
|
|
101
104
|
flex-shrink: 0;
|
|
102
|
-
display: inline-flex;
|
|
103
|
-
align-items: center;
|
|
104
|
-
justify-content: center;
|
|
105
|
-
width: 1.5rem;
|
|
106
|
-
height: 1.5rem;
|
|
107
|
-
padding: 0;
|
|
108
|
-
background: transparent;
|
|
109
|
-
border: 0;
|
|
110
|
-
border-radius: var(--radius-xs, 2px);
|
|
111
|
-
color: rgb(var(--color-text) / 55%);
|
|
112
|
-
cursor: pointer;
|
|
113
|
-
|
|
114
|
-
&:hover {
|
|
115
|
-
background: rgb(var(--color-text) / 8%);
|
|
116
|
-
color: rgb(var(--color-text));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
&:focus-visible {
|
|
120
|
-
outline: 2px solid var(--hi-color-primary, #7aa2f7);
|
|
121
|
-
outline-offset: 1px;
|
|
122
|
-
}
|
|
123
105
|
}
|
|
124
106
|
|
|
125
107
|
/* The native input stays in the DOM for the trigger to click, but is
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { X } from "lucide-vue-next";
|
|
2
|
+
|
|
3
|
+
import HkIconButton from "./HkIconButton";
|
|
4
|
+
|
|
1
5
|
import { computed, defineComponent, ref, useId, watch } from "vue";
|
|
2
6
|
|
|
3
7
|
import { useI18n } from "../i18n/context";
|
|
@@ -170,26 +174,15 @@ export default defineComponent({
|
|
|
170
174
|
</span>
|
|
171
175
|
</button>
|
|
172
176
|
{files.length > 0 && !props.disabled && (
|
|
173
|
-
<
|
|
174
|
-
type="button"
|
|
177
|
+
<HkIconButton
|
|
175
178
|
class="hk-file-clear"
|
|
179
|
+
size={24}
|
|
180
|
+
variant="ghost"
|
|
176
181
|
aria-label={t("hikari::filePicker.fieldClear", "Clear selection")}
|
|
177
182
|
onClick={clear}
|
|
178
183
|
>
|
|
179
|
-
<
|
|
180
|
-
|
|
181
|
-
fill="none"
|
|
182
|
-
stroke="currentColor"
|
|
183
|
-
stroke-width="2"
|
|
184
|
-
stroke-linecap="round"
|
|
185
|
-
width="14"
|
|
186
|
-
height="14"
|
|
187
|
-
aria-hidden="true"
|
|
188
|
-
>
|
|
189
|
-
<line x1="18" y1="6" x2="6" y2="18" />
|
|
190
|
-
<line x1="6" y1="6" x2="18" y2="18" />
|
|
191
|
-
</svg>
|
|
192
|
-
</button>
|
|
184
|
+
{{ icon: () => <X aria-hidden="true" /> }}
|
|
185
|
+
</HkIconButton>
|
|
193
186
|
)}
|
|
194
187
|
{props.mode === "local" && (
|
|
195
188
|
<input
|
|
@@ -83,33 +83,23 @@
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
.hk-filter-panel-op {
|
|
86
|
+
/* Wave B2: the operator toggles are STANDARD icon buttons at the S28 rung
|
|
87
|
+
(the old 1.75rem box). The pressed operator's persistent primary tint
|
|
88
|
+
rides the seat's channel overrides, scoped to [aria-pressed="true"];
|
|
89
|
+
font-weight stays a seat concern (the component carries no text). */
|
|
86
90
|
flex: 0 0 auto;
|
|
87
91
|
scroll-snap-align: center;
|
|
88
|
-
min-width: 1.75rem;
|
|
89
|
-
height: 1.75rem;
|
|
90
|
-
padding: 0 var(--space-6, 0.375rem);
|
|
91
|
-
display: inline-flex;
|
|
92
|
-
align-items: center;
|
|
93
|
-
justify-content: center;
|
|
94
|
-
border: none;
|
|
95
|
-
border-radius: var(--radius-sm, 6px);
|
|
96
|
-
background: transparent;
|
|
97
|
-
color: rgb(var(--color-muted, var(--color-text-secondary)));
|
|
98
|
-
font-size: var(--text-sm, 0.875rem);
|
|
99
|
-
line-height: 1;
|
|
100
|
-
cursor: pointer;
|
|
101
|
-
transition: background 0.15s ease, color 0.15s ease;
|
|
102
|
-
}
|
|
103
92
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
93
|
+
&[aria-pressed="true"] {
|
|
94
|
+
--hi-icon-button-bg: rgb(var(--color-primary) / 18%);
|
|
95
|
+
--hi-icon-button-icon-color: rgb(var(--color-primary));
|
|
96
|
+
--hi-icon-button-icon-color-active: rgb(var(--color-primary));
|
|
97
|
+
/* Keep the primary tint THROUGH hover (the old file-order cascade
|
|
98
|
+
did): without this the pressed op falls back to the ghost gray-20
|
|
99
|
+
hover wash and reads un-pressed under the pointer. */
|
|
100
|
+
--hi-icon-button-bg-hover: rgb(var(--color-primary) / 18%);
|
|
101
|
+
font-weight: 700;
|
|
102
|
+
}
|
|
113
103
|
}
|
|
114
104
|
|
|
115
105
|
.hk-filter-panel-op:disabled {
|
|
@@ -133,28 +123,16 @@
|
|
|
133
123
|
}
|
|
134
124
|
|
|
135
125
|
.hk-filter-panel-remove {
|
|
126
|
+
/* Wave B2: the condition remove is the STANDARD icon button (S24 = the
|
|
127
|
+
old 1.5rem box). The error-tinted hover rides the channel vars — ink
|
|
128
|
+
hover-scoped (the token-input lesson: a rest-scoped ink var reads at
|
|
129
|
+
rest); the standard layer owns disabled presentation. */
|
|
136
130
|
flex: 0 0 auto;
|
|
137
|
-
|
|
138
|
-
height: 1.5rem;
|
|
139
|
-
display: inline-flex;
|
|
140
|
-
align-items: center;
|
|
141
|
-
justify-content: center;
|
|
142
|
-
border: none;
|
|
143
|
-
border-radius: var(--radius-sm, 6px);
|
|
144
|
-
background: transparent;
|
|
145
|
-
color: rgb(var(--color-muted, var(--color-text-secondary)));
|
|
146
|
-
cursor: pointer;
|
|
147
|
-
transition: background 0.15s ease, color 0.15s ease;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.hk-filter-panel-remove:hover {
|
|
151
|
-
background: rgb(var(--color-error) / 12%);
|
|
152
|
-
color: rgb(var(--color-error));
|
|
153
|
-
}
|
|
131
|
+
--hi-icon-button-bg-hover: rgb(var(--color-error) / 12%);
|
|
154
132
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
133
|
+
&:hover {
|
|
134
|
+
--hi-icon-button-icon-color: rgb(var(--color-error));
|
|
135
|
+
}
|
|
158
136
|
}
|
|
159
137
|
|
|
160
138
|
/* The growth verb: parked in the OPERATOR COLUMN (grid-column 2), so it
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import HkIconButton from "./HkIconButton";
|
|
2
|
+
|
|
1
3
|
import { computed, defineComponent, nextTick, ref, watch, type PropType } from "vue";
|
|
2
4
|
import { Plus, X } from "lucide-vue-next";
|
|
3
5
|
|
|
@@ -325,18 +327,19 @@ export default defineComponent({
|
|
|
325
327
|
{ops.map((op) => {
|
|
326
328
|
const glyph = glyphOpFor(kind, op);
|
|
327
329
|
return (
|
|
328
|
-
<
|
|
330
|
+
<HkIconButton
|
|
329
331
|
key={op}
|
|
330
|
-
type="button"
|
|
331
332
|
class="hk-filter-panel-op"
|
|
333
|
+
size={28}
|
|
334
|
+
variant="ghost"
|
|
332
335
|
aria-pressed={cond.op === op}
|
|
333
336
|
aria-label={t(OPERATOR_LABEL[glyph].key, OPERATOR_LABEL[glyph].fallback)}
|
|
334
|
-
title
|
|
337
|
+
{...{ title: t(OPERATOR_LABEL[glyph].key, OPERATOR_LABEL[glyph].fallback) }}
|
|
335
338
|
disabled={props.disabled || !field}
|
|
336
339
|
onClick={() => emitCondition(index, { op })}
|
|
337
340
|
>
|
|
338
|
-
<HkFilterOperatorIcon op={glyph} />
|
|
339
|
-
</
|
|
341
|
+
{{ icon: () => <HkFilterOperatorIcon op={glyph} /> }}
|
|
342
|
+
</HkIconButton>
|
|
340
343
|
);
|
|
341
344
|
})}
|
|
342
345
|
</div>
|
|
@@ -394,19 +397,20 @@ export default defineComponent({
|
|
|
394
397
|
* page refetches without it). Sibling conditions on
|
|
395
398
|
* the same field survive — index-targeted removal,
|
|
396
399
|
* never key-targeted. */}
|
|
397
|
-
<
|
|
398
|
-
type="button"
|
|
400
|
+
<HkIconButton
|
|
399
401
|
class="hk-filter-panel-remove"
|
|
402
|
+
size={24}
|
|
403
|
+
variant="ghost"
|
|
400
404
|
aria-label={t("hikari::filterPanel.removeCondition", "Remove condition")}
|
|
401
|
-
title
|
|
405
|
+
{...{ title: t("hikari::filterPanel.removeCondition", "Remove condition") }}
|
|
402
406
|
disabled={props.disabled}
|
|
403
407
|
onClick={() => {
|
|
404
408
|
const next = props.modelValue.filter((_, i) => i !== index);
|
|
405
409
|
emit("update:modelValue", next);
|
|
406
410
|
}}
|
|
407
411
|
>
|
|
408
|
-
<X
|
|
409
|
-
</
|
|
412
|
+
{{ icon: () => <X aria-hidden="true" /> }}
|
|
413
|
+
</HkIconButton>
|
|
410
414
|
</div>
|
|
411
415
|
</div>
|
|
412
416
|
);
|
|
@@ -41,23 +41,10 @@
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
.hk-kw-search-clear {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
color: var(--hi-color-text-secondary, #666666);
|
|
48
|
-
cursor: pointer;
|
|
49
|
-
display: inline-flex;
|
|
44
|
+
/* Wave B2/B3: the clear affordance is the STANDARD icon button — box,
|
|
45
|
+
ink, hover and focus come from the component; the seat keeps only the
|
|
46
|
+
field's inner padding slot. */
|
|
50
47
|
padding: var(--space-2, 0.125rem);
|
|
51
|
-
border-radius: var(--radius-sm, 0.25rem);
|
|
52
|
-
|
|
53
|
-
&:hover {
|
|
54
|
-
color: var(--hi-color-text-primary, #1e1e1e);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
&:focus-visible {
|
|
58
|
-
outline: 2px solid color-mix(in srgb, var(--hi-color-primary, #7aa2f7) 55%, transparent);
|
|
59
|
-
outline-offset: 2px;
|
|
60
|
-
}
|
|
61
48
|
}
|
|
62
49
|
|
|
63
50
|
/* ONE SCROLLBAR PER WINDOW (2026-09-08 audit): the results list is NOT a
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import HkIconButton from "./HkIconButton";
|
|
2
|
+
|
|
1
3
|
import { computed, defineComponent, onBeforeUnmount, ref, watch, type PropType } from "vue";
|
|
2
4
|
|
|
3
5
|
import { useI18n } from "../i18n/context";
|
|
@@ -241,9 +243,10 @@ export default defineComponent({
|
|
|
241
243
|
autofocus
|
|
242
244
|
/>
|
|
243
245
|
{query.value && (
|
|
244
|
-
<
|
|
246
|
+
<HkIconButton
|
|
245
247
|
class="hk-kw-search-clear"
|
|
246
|
-
|
|
248
|
+
size={24}
|
|
249
|
+
variant="ghost"
|
|
247
250
|
aria-label={t("hikari::keywordSearch.clear", "Clear")}
|
|
248
251
|
onClick={() => {
|
|
249
252
|
query.value = "";
|
|
@@ -251,19 +254,21 @@ export default defineComponent({
|
|
|
251
254
|
semanticResults.value = [];
|
|
252
255
|
}}
|
|
253
256
|
>
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
257
|
+
{{ icon: () => (
|
|
258
|
+
<svg
|
|
259
|
+
width="14"
|
|
260
|
+
height="14"
|
|
261
|
+
viewBox="0 0 24 24"
|
|
262
|
+
fill="none"
|
|
263
|
+
stroke="currentColor"
|
|
264
|
+
stroke-width="2"
|
|
265
|
+
stroke-linecap="round"
|
|
266
|
+
>
|
|
267
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
268
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
269
|
+
</svg>
|
|
270
|
+
) }}
|
|
271
|
+
</HkIconButton>
|
|
267
272
|
)}
|
|
268
273
|
</div>
|
|
269
274
|
|