@celestia-island/hikari 0.4.4

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.
Files changed (187) hide show
  1. package/README.md +54 -0
  2. package/package.json +63 -0
  3. package/src/DemoApp.vue +400 -0
  4. package/src/components/HkActionBar.tsx +15 -0
  5. package/src/components/HkAlert.scss +121 -0
  6. package/src/components/HkAlert.tsx +85 -0
  7. package/src/components/HkAvatar.tsx +29 -0
  8. package/src/components/HkBadge.scss +117 -0
  9. package/src/components/HkBadge.tsx +50 -0
  10. package/src/components/HkBreadcrumb.tsx +39 -0
  11. package/src/components/HkButton.scss +128 -0
  12. package/src/components/HkButton.tsx +74 -0
  13. package/src/components/HkCard.scss +49 -0
  14. package/src/components/HkCard.tsx +38 -0
  15. package/src/components/HkCheckbox.scss +102 -0
  16. package/src/components/HkCheckbox.tsx +85 -0
  17. package/src/components/HkCollapse.tsx +48 -0
  18. package/src/components/HkColorPicker.scss +148 -0
  19. package/src/components/HkColorPicker.tsx +204 -0
  20. package/src/components/HkConfirmDialog.scss +12 -0
  21. package/src/components/HkConfirmDialog.tsx +75 -0
  22. package/src/components/HkDateTimePicker.scss +361 -0
  23. package/src/components/HkDateTimePicker.tsx +424 -0
  24. package/src/components/HkDivider.scss +85 -0
  25. package/src/components/HkDivider.tsx +51 -0
  26. package/src/components/HkDraggableGrid.scss +132 -0
  27. package/src/components/HkDraggableGrid.tsx +291 -0
  28. package/src/components/HkDraggableList.scss +110 -0
  29. package/src/components/HkDraggableList.tsx +238 -0
  30. package/src/components/HkDrawer.scss +175 -0
  31. package/src/components/HkDrawer.tsx +171 -0
  32. package/src/components/HkEmptyState.scss +42 -0
  33. package/src/components/HkEmptyState.tsx +41 -0
  34. package/src/components/HkErrorBoundary.scss +64 -0
  35. package/src/components/HkErrorBoundary.tsx +82 -0
  36. package/src/components/HkGaugeRing.scss +4 -0
  37. package/src/components/HkGaugeRing.tsx +130 -0
  38. package/src/components/HkHoverRevealAction.scss +66 -0
  39. package/src/components/HkHoverRevealAction.tsx +77 -0
  40. package/src/components/HkIcon.tsx +43 -0
  41. package/src/components/HkIconButton.tsx +42 -0
  42. package/src/components/HkImageViewer.scss +33 -0
  43. package/src/components/HkImageViewer.tsx +250 -0
  44. package/src/components/HkInput.scss +172 -0
  45. package/src/components/HkInput.tsx +175 -0
  46. package/src/components/HkKbd.tsx +26 -0
  47. package/src/components/HkKeywordSearchModal.scss +148 -0
  48. package/src/components/HkKeywordSearchModal.tsx +308 -0
  49. package/src/components/HkListTransition.scss +131 -0
  50. package/src/components/HkListTransition.tsx +29 -0
  51. package/src/components/HkLocalePickerPopup.tsx +42 -0
  52. package/src/components/HkLogo.scss +36 -0
  53. package/src/components/HkLogo.tsx +93 -0
  54. package/src/components/HkMarkdownRenderer.scss +141 -0
  55. package/src/components/HkMarkdownRenderer.tsx +123 -0
  56. package/src/components/HkMediaControlBar.scss +65 -0
  57. package/src/components/HkMediaControlBar.tsx +115 -0
  58. package/src/components/HkMediaPlayer.scss +29 -0
  59. package/src/components/HkMediaPlayer.tsx +210 -0
  60. package/src/components/HkMediaSlider.scss +54 -0
  61. package/src/components/HkMediaSlider.tsx +81 -0
  62. package/src/components/HkMediaVisualizer.scss +7 -0
  63. package/src/components/HkMediaVisualizer.tsx +119 -0
  64. package/src/components/HkMinimap.scss +76 -0
  65. package/src/components/HkMinimap.tsx +255 -0
  66. package/src/components/HkModal.scss +318 -0
  67. package/src/components/HkModal.tsx +481 -0
  68. package/src/components/HkModalBreadcrumb.scss +55 -0
  69. package/src/components/HkModalBreadcrumb.tsx +113 -0
  70. package/src/components/HkMorphingTabs.scss +141 -0
  71. package/src/components/HkMorphingTabs.tsx +113 -0
  72. package/src/components/HkNavItem.scss +81 -0
  73. package/src/components/HkNavItem.tsx +157 -0
  74. package/src/components/HkNumberInput.scss +154 -0
  75. package/src/components/HkNumberInput.tsx +161 -0
  76. package/src/components/HkPasswordInput.scss +289 -0
  77. package/src/components/HkPasswordInput.tsx +533 -0
  78. package/src/components/HkPhaseTransition.scss +25 -0
  79. package/src/components/HkPhaseTransition.tsx +40 -0
  80. package/src/components/HkPopover.scss +82 -0
  81. package/src/components/HkPopover.tsx +410 -0
  82. package/src/components/HkPopupSelect.scss +136 -0
  83. package/src/components/HkPopupSelect.tsx +199 -0
  84. package/src/components/HkProgressBar.scss +106 -0
  85. package/src/components/HkProgressBar.tsx +61 -0
  86. package/src/components/HkProgressDialog.tsx +67 -0
  87. package/src/components/HkProgressRing.scss +56 -0
  88. package/src/components/HkProgressRing.tsx +82 -0
  89. package/src/components/HkRadio.scss +119 -0
  90. package/src/components/HkRadio.tsx +75 -0
  91. package/src/components/HkRollingNumber.scss +37 -0
  92. package/src/components/HkRollingNumber.tsx +97 -0
  93. package/src/components/HkScrollContainer.scss +101 -0
  94. package/src/components/HkScrollContainer.tsx +362 -0
  95. package/src/components/HkSearchInput.scss +132 -0
  96. package/src/components/HkSearchInput.tsx +117 -0
  97. package/src/components/HkSelect.scss +143 -0
  98. package/src/components/HkSelect.tsx +230 -0
  99. package/src/components/HkSelectionGrid.scss +177 -0
  100. package/src/components/HkSelectionGrid.tsx +99 -0
  101. package/src/components/HkSelectionWaterfall.scss +93 -0
  102. package/src/components/HkSelectionWaterfall.tsx +90 -0
  103. package/src/components/HkSidebar.scss +81 -0
  104. package/src/components/HkSidebar.tsx +45 -0
  105. package/src/components/HkSkeleton.scss +44 -0
  106. package/src/components/HkSkeleton.tsx +30 -0
  107. package/src/components/HkSkeletonList.tsx +35 -0
  108. package/src/components/HkSpinner.scss +67 -0
  109. package/src/components/HkSpinner.tsx +41 -0
  110. package/src/components/HkSplash.scss +60 -0
  111. package/src/components/HkSplash.tsx +40 -0
  112. package/src/components/HkSwitch.scss +157 -0
  113. package/src/components/HkSwitch.tsx +72 -0
  114. package/src/components/HkTable.scss +198 -0
  115. package/src/components/HkTable.tsx +246 -0
  116. package/src/components/HkTabs.scss +109 -0
  117. package/src/components/HkTabs.tsx +111 -0
  118. package/src/components/HkTag.scss +88 -0
  119. package/src/components/HkTag.tsx +44 -0
  120. package/src/components/HkTextarea.scss +72 -0
  121. package/src/components/HkTextarea.tsx +104 -0
  122. package/src/components/HkTimeline.scss +139 -0
  123. package/src/components/HkTimeline.tsx +95 -0
  124. package/src/components/HkToast.scss +168 -0
  125. package/src/components/HkToast.tsx +175 -0
  126. package/src/components/HkTooltip.scss +47 -0
  127. package/src/components/HkTooltip.tsx +108 -0
  128. package/src/components/HkTree.scss +188 -0
  129. package/src/components/HkTree.tsx +217 -0
  130. package/src/components/HkTrendChart.tsx +180 -0
  131. package/src/components/HkWindowedItem.scss +17 -0
  132. package/src/components/HkWindowedItem.tsx +107 -0
  133. package/src/components/HkZoomToolbar.scss +35 -0
  134. package/src/components/HkZoomToolbar.tsx +69 -0
  135. package/src/composables/useBreakpoint.ts +41 -0
  136. package/src/composables/useClipboard.ts +37 -0
  137. package/src/composables/useConfirm.ts +35 -0
  138. package/src/composables/useProgressDialog.ts +52 -0
  139. package/src/composables/useReportedTransition.ts +69 -0
  140. package/src/composables/useScrollWindow.ts +21 -0
  141. package/src/composables/useToast.ts +2 -0
  142. package/src/demo.scss +24 -0
  143. package/src/demo.ts +22 -0
  144. package/src/env.d.ts +6 -0
  145. package/src/i18n/context.ts +89 -0
  146. package/src/i18n/locales/ar/components.json +43 -0
  147. package/src/i18n/locales/ar/components.toml +40 -0
  148. package/src/i18n/locales/de/components.json +43 -0
  149. package/src/i18n/locales/de/components.toml +40 -0
  150. package/src/i18n/locales/en/components.json +43 -0
  151. package/src/i18n/locales/en/components.toml +40 -0
  152. package/src/i18n/locales/es/components.json +43 -0
  153. package/src/i18n/locales/es/components.toml +40 -0
  154. package/src/i18n/locales/fr/components.json +43 -0
  155. package/src/i18n/locales/fr/components.toml +40 -0
  156. package/src/i18n/locales/ja/components.json +43 -0
  157. package/src/i18n/locales/ja/components.toml +40 -0
  158. package/src/i18n/locales/ko/components.json +43 -0
  159. package/src/i18n/locales/ko/components.toml +40 -0
  160. package/src/i18n/locales/pt/components.json +43 -0
  161. package/src/i18n/locales/pt/components.toml +40 -0
  162. package/src/i18n/locales/ru/components.json +43 -0
  163. package/src/i18n/locales/ru/components.toml +40 -0
  164. package/src/i18n/locales/zh-Hans/components.json +43 -0
  165. package/src/i18n/locales/zh-Hans/components.toml +40 -0
  166. package/src/i18n/locales/zh-Hant/components.json +43 -0
  167. package/src/i18n/locales/zh-Hant/components.toml +40 -0
  168. package/src/index.ts +137 -0
  169. package/src/render.ts +18 -0
  170. package/src/runtime/animationBus.ts +278 -0
  171. package/src/runtime/cronBus.ts +25 -0
  172. package/src/runtime/index.ts +12 -0
  173. package/src/runtime/useAsyncData.ts +30 -0
  174. package/src/runtime/useBreakpoint.ts +62 -0
  175. package/src/runtime/useClipboard.ts +37 -0
  176. package/src/runtime/useConfirm.ts +35 -0
  177. package/src/runtime/useOverlay.ts +82 -0
  178. package/src/runtime/usePopupManager.ts +89 -0
  179. package/src/runtime/useToast.ts +140 -0
  180. package/src/styles/index.scss +10 -0
  181. package/src/theme/index.ts +5 -0
  182. package/src/theme/presets.ts +307 -0
  183. package/src/theme/theme.scss +17 -0
  184. package/src/theme/useBackgroundLuminance.ts +145 -0
  185. package/src/theme/useSolarTime.ts +101 -0
  186. package/src/theme/useTheme.ts +141 -0
  187. package/src/tokens.scss +26 -0
@@ -0,0 +1,172 @@
1
+ @use "../tokens";
2
+
3
+ .hk-input-wrapper {
4
+ display: block;
5
+ width: 100%;
6
+ }
7
+
8
+ .hk-input-label {
9
+ display: block;
10
+ font-size: var(--text-base);
11
+ font-weight: 500;
12
+ margin-bottom: var(--space-6);
13
+ color: rgb(var(--color-text));
14
+ }
15
+
16
+ .hk-input-required {
17
+ margin-left: var(--space-2);
18
+ color: rgb(var(--color-error));
19
+ }
20
+
21
+ .hk-input-box {
22
+ position: relative;
23
+ display: flex;
24
+ align-items: center;
25
+ gap: var(--space-6);
26
+ padding: var(--space-8) var(--space-12);
27
+ min-height: 2.5rem;
28
+ background: rgb(var(--color-surface) / var(--opacity-half));
29
+ backdrop-filter: blur(var(--blur-sm));
30
+ border: 1px solid var(--border-input);
31
+ border-radius: var(--radius-sm);
32
+ overflow: hidden;
33
+ transition: background-color, border-color, color, box-shadow, opacity, transform, filter var(--duration-normal) var(--ease-standard);
34
+ color: rgb(var(--color-text));
35
+
36
+ &:hover:not(.hk-input-box-disabled) {
37
+ border-color: var(--c-primary-strong);
38
+ }
39
+ }
40
+
41
+ .hk-input-box:focus-within {
42
+ border-color: rgb(var(--color-focused-border));
43
+ box-shadow: var(--shadow-focus);
44
+ background: rgb(var(--color-surface));
45
+ }
46
+
47
+ .hk-input-box-error {
48
+ border-color: var(--c-error-strong);
49
+ }
50
+
51
+ .hk-input-box-error:focus-within {
52
+ border-color: rgb(var(--color-error));
53
+ box-shadow: var(--shadow-focus-error);
54
+ }
55
+
56
+ .hk-input-box-disabled {
57
+ opacity: 0.5;
58
+ cursor: not-allowed;
59
+ }
60
+
61
+ .hk-input-box[data-autogrow] {
62
+ display: flex;
63
+ flex-direction: column;
64
+ align-items: stretch;
65
+ }
66
+
67
+ .hk-input-element {
68
+ position: absolute;
69
+ inset: 0;
70
+ width: 100%;
71
+ height: 100%;
72
+ background: transparent;
73
+ border: none;
74
+ outline: none;
75
+ font-family: inherit;
76
+ font-size: var(--text-base);
77
+ line-height: 1.5;
78
+ color: rgb(var(--color-text));
79
+ text-align: center;
80
+ padding: var(--space-8) var(--space-12);
81
+ }
82
+
83
+ .hk-input-element.hk-input-textarea {
84
+ position: relative;
85
+ inset: unset;
86
+ width: 100%;
87
+ height: auto;
88
+ flex: 1;
89
+ min-width: 0;
90
+ text-align: start;
91
+ padding: var(--space-8) var(--space-12);
92
+ }
93
+
94
+ .hk-input-textarea {
95
+ resize: vertical;
96
+ min-height: 2.5rem;
97
+ }
98
+
99
+ .hk-input-box[data-autogrow] {
100
+ display: flex;
101
+ flex-direction: column;
102
+ align-items: stretch;
103
+ }
104
+
105
+ .hk-input-autogrow {
106
+ flex: 1;
107
+ min-height: 0;
108
+ }
109
+
110
+ .hk-input-textarea[data-autogrow] {
111
+ position: relative;
112
+ inset: unset;
113
+ width: 100%;
114
+ flex: 0 0 auto;
115
+ resize: none;
116
+ overflow: hidden;
117
+ min-height: 2.5rem;
118
+ text-align: start;
119
+ }
120
+
121
+ .hk-input-affix {
122
+ display: flex;
123
+ align-items: center;
124
+ color: color-mix(in srgb, rgb(var(--color-muted)) 70%, rgb(var(--color-background)));
125
+ flex-shrink: 0;
126
+ position: relative;
127
+ z-index: 1;
128
+ }
129
+
130
+ .hk-input-error-msg {
131
+ margin-top: var(--space-4);
132
+ font-size: var(--text-xs);
133
+ color: rgb(var(--color-error));
134
+ }
135
+
136
+ .hk-input-hint {
137
+ margin-top: var(--space-4);
138
+ font-size: var(--text-xs);
139
+ color: color-mix(in srgb, rgb(var(--color-muted)) 70%, rgb(var(--color-background)));
140
+ }
141
+
142
+ /* Autofill overrides */
143
+ .hk-input-box input,
144
+ .hk-input-box textarea {
145
+ transition: color calc(infinity * 1s) step-end, background-color calc(infinity * 1s) step-end;
146
+ }
147
+
148
+ .hk-input-box input:-webkit-autofill,
149
+ .hk-input-box input:-webkit-autofill:hover,
150
+ .hk-input-box input:-webkit-autofill:focus,
151
+ .hk-input-box input:-webkit-autofill:active,
152
+ .hk-input-box textarea:-webkit-autofill,
153
+ .hk-input-box textarea:-webkit-autofill:hover,
154
+ .hk-input-box textarea:-webkit-autofill:focus {
155
+ -webkit-text-fill-color: rgb(var(--color-text)) !important;
156
+ -webkit-box-shadow: 0 0 0 1000px rgb(var(--color-surface)) inset !important;
157
+ caret-color: rgb(var(--color-text));
158
+ }
159
+
160
+ .hk-input-box input:-webkit-autofill::first-line,
161
+ .hk-input-box textarea:-webkit-autofill::first-line {
162
+ font-size: inherit !important;
163
+ font-family: inherit !important;
164
+ color: rgb(var(--color-text));
165
+ }
166
+
167
+ .hk-input-box input:-internal-autofill-previewed,
168
+ .hk-input-box input:-internal-autofill-selected {
169
+ -webkit-text-fill-color: rgb(var(--color-text)) !important;
170
+ -webkit-box-shadow: 0 0 0 1000px rgb(var(--color-surface)) inset !important;
171
+ caret-color: rgb(var(--color-text));
172
+ }
@@ -0,0 +1,175 @@
1
+ import { computed, defineComponent, nextTick, onBeforeUnmount, onMounted, ref, useAttrs, watch } from "vue";
2
+ import "./HkInput.scss";
3
+
4
+ export default defineComponent({
5
+ name: "HkInput",
6
+ inheritAttrs: false,
7
+ props: {
8
+ modelValue: { type: String, default: "" },
9
+ type: { type: String, default: "text" },
10
+ placeholder: { type: String, default: "" },
11
+ label: { type: String, default: undefined },
12
+ error: { type: String, default: undefined },
13
+ hint: { type: String, default: undefined },
14
+ disabled: { type: Boolean, default: false },
15
+ readonly: { type: Boolean, default: false },
16
+ required: { type: Boolean, default: false },
17
+ name: { type: String, default: undefined },
18
+ autocomplete: { type: String, default: "off" },
19
+ rows: { type: Number, default: 3 },
20
+ autoGrow: { type: Boolean, default: false },
21
+ size: { type: String as () => "sm" | "md" | "lg", default: "md" },
22
+ },
23
+ emits: {
24
+ "update:modelValue": (_value: string) => true,
25
+ focus: (_e: FocusEvent) => true,
26
+ blur: (_e: FocusEvent) => true,
27
+ keydown: (_e: KeyboardEvent) => true,
28
+ },
29
+ setup(props, { emit, slots }) {
30
+ const attrs = useAttrs();
31
+ const inputRef = ref<HTMLElement>();
32
+
33
+ const filteredAttrs = computed(() => {
34
+ const { class: _, style: __, ...rest } = attrs as Record<string, unknown>;
35
+ return rest;
36
+ });
37
+
38
+ function onInput(e: Event) {
39
+ const target = e.target as HTMLInputElement | HTMLTextAreaElement;
40
+ emit("update:modelValue", target.value);
41
+ }
42
+
43
+ const isTextarea = computed(() => props.type === "textarea");
44
+ const isAutoGrow = computed(() => props.autoGrow && props.type === "textarea");
45
+
46
+ let lastWidth = -1;
47
+ let ro: ResizeObserver | null = null;
48
+
49
+ function resize() {
50
+ if (!props.autoGrow || props.type !== "textarea") return;
51
+ const ta = inputRef.value as HTMLTextAreaElement | null;
52
+ if (!ta) return;
53
+ ta.style.height = "auto";
54
+ ta.style.height = `${ta.scrollHeight}px`;
55
+ }
56
+
57
+ watch(
58
+ () => props.modelValue,
59
+ () => {
60
+ if (props.autoGrow) nextTick(resize);
61
+ },
62
+ );
63
+
64
+ onMounted(() => {
65
+ if (!isAutoGrow.value) return;
66
+ const ta = inputRef.value as HTMLTextAreaElement | null;
67
+ if (!ta) return;
68
+ ro = new ResizeObserver(() => {
69
+ const el = inputRef.value as HTMLTextAreaElement | null;
70
+ if (!el) return;
71
+ const w = el.clientWidth;
72
+ if (w === lastWidth) return;
73
+ lastWidth = w;
74
+ resize();
75
+ });
76
+ ro.observe(ta);
77
+ nextTick(resize);
78
+ });
79
+
80
+ onBeforeUnmount(() => ro?.disconnect());
81
+
82
+ const boxClass = computed(() => [
83
+ "hk-input-box",
84
+ `hk-input-box-${props.size}`,
85
+ props.error ? "hk-input-box-error" : "",
86
+ props.disabled ? "hk-input-box-disabled" : "",
87
+ ]);
88
+
89
+ const isText = !isTextarea.value;
90
+
91
+ return () => (
92
+ <div class="hk-input-wrapper">
93
+ {props.label && (
94
+ <label class="hk-input-label">
95
+ {props.label}
96
+ {props.required && <span class="hk-input-required">*</span>}
97
+ </label>
98
+ )}
99
+ <div
100
+ class={boxClass.value}
101
+ data-autogrow={isAutoGrow.value || undefined}
102
+ >
103
+ {slots.prefix && (
104
+ <span class="hk-input-affix hk-input-prefix">
105
+ {slots.prefix()}
106
+ </span>
107
+ )}
108
+ {slots.prefixIcon && !slots.prefix && (
109
+ <span class="hk-input-affix hk-input-prefix">
110
+ {slots.prefixIcon()}
111
+ </span>
112
+ )}
113
+ {isText ? (
114
+ <input
115
+ ref={inputRef}
116
+ type={props.type}
117
+ value={props.modelValue}
118
+ placeholder={props.placeholder}
119
+ disabled={props.disabled}
120
+ readonly={props.readonly}
121
+ name={props.name}
122
+ autocomplete={props.autocomplete}
123
+ data-1p-ignore
124
+ data-lpignore="true"
125
+ class="hk-input-element"
126
+ {...filteredAttrs.value}
127
+ onInput={onInput}
128
+ onFocus={(e) => emit("focus", e)}
129
+ onBlur={(e) => emit("blur", e)}
130
+ onKeydown={(e) => emit("keydown", e)}
131
+ />
132
+ ) : (
133
+ <textarea
134
+ ref={inputRef}
135
+ value={props.modelValue}
136
+ placeholder={props.placeholder}
137
+ disabled={props.disabled}
138
+ readonly={props.readonly}
139
+ rows={props.rows}
140
+ name={props.name}
141
+ autocomplete={props.autocomplete}
142
+ data-1p-ignore
143
+ data-lpignore="true"
144
+ class={[
145
+ "hk-input-element",
146
+ "hk-input-textarea",
147
+ isAutoGrow.value ? "hk-input-textarea-autogrow" : "",
148
+ ]}
149
+ {...filteredAttrs.value}
150
+ onInput={onInput}
151
+ onFocus={(e) => emit("focus", e)}
152
+ onBlur={(e) => emit("blur", e)}
153
+ onKeydown={(e) => emit("keydown", e)}
154
+ />
155
+ )}
156
+ {slots.suffix && (
157
+ <span class="hk-input-affix hk-input-suffix">
158
+ {slots.suffix()}
159
+ </span>
160
+ )}
161
+ {slots.suffixIcon && !slots.suffix && (
162
+ <span class="hk-input-affix hk-input-suffix">
163
+ {slots.suffixIcon()}
164
+ </span>
165
+ )}
166
+ </div>
167
+ {props.error ? (
168
+ <p class="hk-input-error-msg">{props.error}</p>
169
+ ) : props.hint ? (
170
+ <p class="hk-input-hint">{props.hint}</p>
171
+ ) : null}
172
+ </div>
173
+ );
174
+ },
175
+ });
@@ -0,0 +1,26 @@
1
+ import { computed, defineComponent, type PropType } from "vue";
2
+
3
+ export default defineComponent({
4
+ name: "HkKbd",
5
+ props: {
6
+ keys: { type: String, required: true },
7
+ size: { type: String as PropType<"sm" | "md">, default: "md" },
8
+ },
9
+ setup(props) {
10
+ const chunks = computed(() => props.keys.split("+").map((k) => k.trim()));
11
+
12
+ return () => (
13
+ <kbd
14
+ class={["hk-kbd", `hk-kbd-${props.size}`]}
15
+ aria-hidden="true"
16
+ >
17
+ {chunks.value.map((key, i) => (
18
+ <span key={i}>
19
+ {i > 0 && <span class="hk-kbd-sep">+</span>}
20
+ <span class="hk-kbd-key">{key}</span>
21
+ </span>
22
+ ))}
23
+ </kbd>
24
+ );
25
+ },
26
+ });
@@ -0,0 +1,148 @@
1
+ .hk-kw-search {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--hi-space-10, 1.25rem);
5
+ padding: var(--hi-space-4, 0.25rem) 0;
6
+ }
7
+
8
+ .hk-kw-search-box {
9
+ display: flex;
10
+ align-items: center;
11
+ gap: var(--hi-space-8, 0.5rem);
12
+ padding: var(--hi-space-8, 0.5rem) var(--hi-space-10, 0.75rem);
13
+ background: var(--hi-color-surface, rgba(255, 255, 255, 0.95));
14
+ border: 1px solid var(--hk-kw-border, rgba(0, 0, 0, 0.08));
15
+ border-radius: var(--hi-radius-lg, 0.75rem);
16
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
17
+
18
+ &:focus-within {
19
+ border-color: var(--hi-color-primary, #58a6ff);
20
+ box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.12);
21
+ }
22
+ }
23
+
24
+ .hk-kw-search-icon {
25
+ color: var(--hi-color-text-secondary, #666);
26
+ flex-shrink: 0;
27
+ }
28
+
29
+ .hk-kw-search-input {
30
+ flex: 1;
31
+ min-width: 0;
32
+ appearance: none;
33
+ background: transparent;
34
+ border: 0;
35
+ outline: none;
36
+ color: var(--hi-color-text-primary, #333);
37
+ font-size: 0.875rem;
38
+ }
39
+
40
+ .hk-kw-search-clear {
41
+ appearance: none;
42
+ background: transparent;
43
+ border: 0;
44
+ color: var(--hi-color-text-secondary, #666);
45
+ cursor: pointer;
46
+ display: inline-flex;
47
+ padding: var(--hi-space-2, 0.125rem);
48
+ border-radius: var(--hi-radius-sm, 0.25rem);
49
+
50
+ &:hover {
51
+ color: var(--hi-color-text-primary, #333);
52
+ }
53
+ }
54
+
55
+ .hk-kw-search-results {
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: var(--hi-space-4, 0.25rem);
59
+ max-height: min(22rem, 50vh);
60
+ overflow-y: auto;
61
+ overflow-x: hidden;
62
+ padding: 0 var(--hi-space-2, 0.125rem);
63
+ }
64
+
65
+ .hk-kw-search-result {
66
+ appearance: none;
67
+ text-align: left;
68
+ background: transparent;
69
+ border: 1px solid transparent;
70
+ border-radius: var(--hi-radius-sm, 0.25rem);
71
+ padding: var(--hi-space-8, 0.5rem) var(--hi-space-10, 0.75rem);
72
+ cursor: pointer;
73
+ width: 100%;
74
+ color: var(--hi-color-text-primary, #333);
75
+ transition: background 0.15s ease, border-color 0.15s ease;
76
+
77
+ &:hover {
78
+ background: var(--hi-color-surface, rgba(255, 255, 255, 0.95));
79
+ border-color: rgba(0, 0, 0, 0.06);
80
+ }
81
+ }
82
+
83
+ .hk-kw-search-empty {
84
+ padding: var(--hi-space-24, 3rem) var(--hi-space-8, 0.5rem);
85
+ text-align: center;
86
+ font-size: 0.875rem;
87
+ color: var(--hi-color-text-secondary, #666);
88
+ }
89
+
90
+ .hk-kw-search-result-semantic {
91
+ display: block;
92
+ }
93
+
94
+ .hk-kw-search-semantic {
95
+ display: flex;
96
+ flex-direction: column;
97
+ gap: var(--hi-space-4, 0.25rem);
98
+ min-width: 0;
99
+ }
100
+
101
+ .hk-kw-search-semantic-head {
102
+ display: flex;
103
+ align-items: baseline;
104
+ justify-content: space-between;
105
+ gap: var(--hi-space-8, 0.5rem);
106
+ }
107
+
108
+ .hk-kw-search-semantic-title {
109
+ font-size: 0.875rem;
110
+ font-weight: 600;
111
+ color: var(--hi-color-text-primary, #333);
112
+ overflow: hidden;
113
+ text-overflow: ellipsis;
114
+ white-space: nowrap;
115
+ }
116
+
117
+ .hk-kw-search-semantic-score {
118
+ flex-shrink: 0;
119
+ font-size: var(--hi-text-xs, 0.75rem);
120
+ font-variant-numeric: tabular-nums;
121
+ color: var(--hi-color-primary, #58a6ff);
122
+ background: rgba(88, 166, 255, 0.12);
123
+ padding: 0 var(--hi-space-6, 0.375rem);
124
+ border-radius: var(--hi-radius-sm, 0.25rem);
125
+ line-height: 1.5;
126
+ }
127
+
128
+ .hk-kw-search-semantic-snippet {
129
+ font-size: var(--hi-text-xs, 0.75rem);
130
+ color: var(--hi-color-text-secondary, #666);
131
+ line-height: 1.5;
132
+ display: -webkit-box;
133
+ -webkit-line-clamp: 2;
134
+ line-clamp: 2;
135
+ -webkit-box-orient: vertical;
136
+ overflow: hidden;
137
+ }
138
+
139
+ .hk-kw-search-semantic-source {
140
+ align-self: flex-start;
141
+ font-size: var(--hi-text-xs, 0.75rem);
142
+ text-transform: uppercase;
143
+ letter-spacing: 0.04em;
144
+ color: var(--hi-color-text-secondary, #666);
145
+ background: rgba(0, 0, 0, 0.04);
146
+ padding: 0 var(--hi-space-6, 0.375rem);
147
+ border-radius: var(--hi-radius-sm, 0.25rem);
148
+ }