@celestia-island/hikari 0.55.149 → 0.55.151
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/animation/registerAnimations.ts +0 -1
- package/src/components/HkConnectionStatus.shell.test.tsx +34 -0
- package/src/components/HkConnectionStatus.tsx +31 -10
- package/src/components/HkKanban.tsx +10 -0
- package/src/components/HkScrollContainer.dock.test.tsx +89 -0
- package/src/components/HkScrollContainer.scss +50 -0
- package/src/components/HkScrollContainer.tsx +47 -0
- package/src/components/HkThemeDecor.test.tsx +11 -22
- package/src/components/HkThemeDecor.tsx +1 -1
- package/src/components/StatusTrayDecor.mount.test.ts +35 -0
- package/src/components/{HkStatusTray.size.test.ts → StatusTrayDecor.size.test.ts} +7 -3
- package/src/components/{HkStatusTray.test.tsx → StatusTrayDecor.test.tsx} +3 -2
- package/src/components/themeDecorLayout.contract.test.ts +6 -6
- package/src/composables/engineHealthTypes.ts +50 -0
- package/src/i18n/usageSurface.test.ts +0 -1
- package/src/index.ts +2 -102
- package/src/theme/standardDecor.test.ts +14 -13
- package/src/theme/standardDecor.ts +7 -3
- package/src/theme/themeDecorSurface.test.ts +5 -3
- package/src/utils/format.ts +0 -11
- package/src/components/HkAttachmentModal.scss +0 -49
- package/src/components/HkAttachmentModal.tsx +0 -318
- package/src/components/HkChatTypes.ts +0 -65
- package/src/components/HkContextRing.scss +0 -136
- package/src/components/HkContextRing.test.tsx +0 -309
- package/src/components/HkContextRing.tsx +0 -276
- package/src/components/HkModelCatalog.test.ts +0 -81
- package/src/components/HkModelCatalog.ts +0 -330
- package/src/components/HkModelTag.scss +0 -171
- package/src/components/HkModelTag.test.tsx +0 -155
- package/src/components/HkModelTag.tsx +0 -219
- package/src/components/HkRichInput.scss +0 -178
- package/src/components/HkRichInput.tsx +0 -335
- package/src/components/HkStatusTray.scss +0 -36
- package/src/components/HkStatusTray.tsx +0 -187
- package/src/components/HkTokenUsageBadge.scss +0 -50
- package/src/components/HkTokenUsageBadge.test.tsx +0 -59
- package/src/components/HkTokenUsageBadge.tsx +0 -54
- package/src/components/HkTokenUsagePanel.scss +0 -100
- package/src/components/HkTokenUsagePanel.tsx +0 -140
- package/src/components/HkToolBlock.scss +0 -327
- package/src/components/HkToolBlock.tsx +0 -394
- package/src/components/HkToolBlock.windowScroll.contract.test.ts +0 -93
- package/src/components/HkVoiceInputPopup.scss +0 -82
- package/src/components/HkVoiceInputPopup.tsx +0 -97
- package/src/composables/useAttachments.ts +0 -154
- package/src/composables/useConnectionProbe.test.ts +0 -179
- package/src/composables/useConnectionProbe.ts +0 -201
- package/src/composables/useEngineHealth.test.ts +0 -128
- package/src/composables/useEngineHealth.ts +0 -93
- package/src/composables/useSendShortcut.ts +0 -35
- package/src/i18n/contextKeys.test.ts +0 -52
- package/src/i18n/locales/ar/chat.json +0 -49
- package/src/i18n/locales/de/chat.json +0 -49
- package/src/i18n/locales/en/chat.json +0 -49
- package/src/i18n/locales/es/chat.json +0 -49
- package/src/i18n/locales/fr/chat.json +0 -49
- package/src/i18n/locales/ja/chat.json +0 -49
- package/src/i18n/locales/ko/chat.json +0 -49
- package/src/i18n/locales/pt/chat.json +0 -49
- package/src/i18n/locales/ru/chat.json +0 -49
- package/src/i18n/locales/zh-Hans/chat.json +0 -49
- package/src/i18n/locales/zh-Hant/chat.json +0 -49
package/src/index.ts
CHANGED
|
@@ -124,30 +124,7 @@ export { default as HWaterfall } from "./components/HkWaterfall";
|
|
|
124
124
|
export { default as HBlankCanvas } from "./components/HkBlankCanvas";
|
|
125
125
|
export type { BlankCanvasSize } from "./components/HkBlankCanvas";
|
|
126
126
|
export { default as HKanban } from "./components/HkKanban";
|
|
127
|
-
export type {
|
|
128
|
-
KanbanAxis,
|
|
129
|
-
KanbanCardSlotProps,
|
|
130
|
-
KanbanHeaderSlotProps,
|
|
131
|
-
KanbanMove,
|
|
132
|
-
} from "./components/HkKanban";
|
|
133
127
|
export { default as HNodeCanvas, NODE_CANVAS_DEFAULTS } from "./components/HkNodeCanvas";
|
|
134
|
-
export type {
|
|
135
|
-
NodeCanvasCamera,
|
|
136
|
-
NodeCanvasBounds,
|
|
137
|
-
NodeCanvasSlotProps,
|
|
138
|
-
MinimapPlacement,
|
|
139
|
-
NodeCanvasEdge,
|
|
140
|
-
EdgeRouting,
|
|
141
|
-
EdgeSide,
|
|
142
|
-
EdgeSubpath,
|
|
143
|
-
EdgePointerEvent,
|
|
144
|
-
} from "./components/HkNodeCanvas";
|
|
145
|
-
export type {
|
|
146
|
-
WaterfallBucket,
|
|
147
|
-
WaterfallCardSlotProps,
|
|
148
|
-
WaterfallHeaderSlotProps,
|
|
149
|
-
WaterfallRailSlotProps,
|
|
150
|
-
} from "./components/HkWaterfall";
|
|
151
128
|
export { default as HDateTimePicker } from "./components/HkDateTimePicker";
|
|
152
129
|
export { default as HDatePicker } from "./components/HkDatePicker";
|
|
153
130
|
export { default as HTimeline } from "./components/HkTimeline";
|
|
@@ -251,7 +228,6 @@ export { type TrendPen, type TrendPoint, type AlarmThresholds } from "./componen
|
|
|
251
228
|
|
|
252
229
|
// ── Theme decor (theme-provided decorative widgets, host-placed) ──────────
|
|
253
230
|
export { default as HkThemeDecor, type HkThemeDecorSize } from "./components/HkThemeDecor";
|
|
254
|
-
export { default as HkStatusTray, type HkStatusTraySize } from "./components/HkStatusTray";
|
|
255
231
|
|
|
256
232
|
// Theme system
|
|
257
233
|
export {
|
|
@@ -446,10 +422,6 @@ export { useApproachEnd } from "./composables/useApproachEnd";
|
|
|
446
422
|
export type { ApproachEndOptions, ApproachEndHandle } from "./composables/useApproachEnd";
|
|
447
423
|
export { useDeferredTransition } from "./composables/useDeferredTransition";
|
|
448
424
|
export { useSurfaceTransition } from "./composables/useSurfaceTransition";
|
|
449
|
-
export type {
|
|
450
|
-
SurfaceTransition,
|
|
451
|
-
SurfaceTransitionHooks,
|
|
452
|
-
} from "./composables/useSurfaceTransition";
|
|
453
425
|
export { useSizeMorph } from "./composables/useSizeMorph";
|
|
454
426
|
export type { SizeMorph } from "./composables/useSizeMorph";
|
|
455
427
|
export { useImage } from "./composables/useImage";
|
|
@@ -471,11 +443,6 @@ export {
|
|
|
471
443
|
nearestLaidAncestor,
|
|
472
444
|
placePoint,
|
|
473
445
|
} from "./composables/layoutGeometry";
|
|
474
|
-
export type {
|
|
475
|
-
FrameMetrics,
|
|
476
|
-
LayoutOffset,
|
|
477
|
-
LayoutRect,
|
|
478
|
-
} from "./composables/layoutGeometry";
|
|
479
446
|
export { useMeasuredHighlight } from "./composables/useMeasuredHighlight";
|
|
480
447
|
export type { UseMeasuredHighlightOptions, MeasuredHighlight } from "./composables/useMeasuredHighlight";
|
|
481
448
|
export {
|
|
@@ -532,10 +499,6 @@ export {
|
|
|
532
499
|
export { usePageTitle, useRouteTitle } from "./composables/usePageTitle";
|
|
533
500
|
export { provideActionBar, useActionBar } from "./composables/useActionBar";
|
|
534
501
|
export type { ActionBarRenderer } from "./composables/useActionBar";
|
|
535
|
-
export { setProbeEndpoint, useConnectionProbe } from "./composables/useConnectionProbe";
|
|
536
|
-
export type { ProbeResult } from "./composables/useConnectionProbe";
|
|
537
|
-
export { useEngineHealth } from "./composables/useEngineHealth";
|
|
538
|
-
export type { EngineHealth, EngineNetworkInfo } from "./composables/useEngineHealth";
|
|
539
502
|
export { leadingZeroBits, sha256, solvePow, solvePowSync, verifyPow } from "./utils/pow";
|
|
540
503
|
export type { PowChallenge, PowSolution } from "./utils/pow";
|
|
541
504
|
export { HkLocalePicker as HLocalePicker } from "./components/HkLocalePicker";
|
|
@@ -570,13 +533,6 @@ export {
|
|
|
570
533
|
} from "./components/HkSettingsDialog";
|
|
571
534
|
|
|
572
535
|
export { HkCookieConsent as HCookieConsent } from "./components/HkCookieConsent";
|
|
573
|
-
export {
|
|
574
|
-
HkAttachmentModal as HAttachmentModal,
|
|
575
|
-
previewKindFor,
|
|
576
|
-
type HAttachmentDetail,
|
|
577
|
-
type HAttachmentItem,
|
|
578
|
-
type HAttachmentPreviewType,
|
|
579
|
-
} from "./components/HkAttachmentModal";
|
|
580
536
|
export { HkStatusBar as HStatusBar } from "./components/HkStatusBar";
|
|
581
537
|
export { useConnectionInfo } from "./components/HkConnectionInfo";
|
|
582
538
|
export type { ConnectionStateInput, HkConnectionInfo } from "./components/HkConnectionInfo";
|
|
@@ -587,67 +543,22 @@ export {
|
|
|
587
543
|
type HkBackendStatus,
|
|
588
544
|
type HkConnectionProbeSource,
|
|
589
545
|
} from "./components/HkConnectionStatus";
|
|
546
|
+
export { HK_ENGINE_HEALTH } from "./components/HkConnectionStatus";
|
|
547
|
+
export type { ProbeResult, EngineHealth, EngineNetworkInfo } from "./composables/engineHealthTypes";
|
|
590
548
|
|
|
591
549
|
// ── Chat kit (upstreamed from shittim-chest's plana-legacy layer) ──────────
|
|
592
|
-
export { HkRichInput as HRichInput } from "./components/HkRichInput";
|
|
593
|
-
export { HkVoiceInputPopup as HVoiceInputPopup } from "./components/HkVoiceInputPopup";
|
|
594
|
-
export {
|
|
595
|
-
HkToolBlock as HToolBlock,
|
|
596
|
-
parseToolCallText,
|
|
597
|
-
extractExecCode,
|
|
598
|
-
buildHighlightedLines,
|
|
599
|
-
type HParsedToolCall,
|
|
600
|
-
type HToolBlockVariant,
|
|
601
|
-
type HHighlightedLine,
|
|
602
|
-
} from "./components/HkToolBlock";
|
|
603
550
|
export {
|
|
604
551
|
HkJsonTree as HJsonTree,
|
|
605
552
|
buildJsonTree,
|
|
606
553
|
type HJsonNode,
|
|
607
554
|
} from "./components/HkJsonTree";
|
|
608
|
-
export { HkTokenUsageBadge as HTokenUsageBadge } from "./components/HkTokenUsageBadge";
|
|
609
|
-
export { HkTokenUsagePanel as HTokenUsagePanel } from "./components/HkTokenUsagePanel";
|
|
610
|
-
export { HkModelTag as HModelTag } from "./components/HkModelTag";
|
|
611
|
-
export { HkContextRing as HContextRing, HkContextRing, type HkContextSegment } from "./components/HkContextRing";
|
|
612
|
-
export {
|
|
613
|
-
getModelMeta,
|
|
614
|
-
registerModelCatalog,
|
|
615
|
-
splitModelId,
|
|
616
|
-
type HModelPricing,
|
|
617
|
-
type HModelMeta,
|
|
618
|
-
type HModelCatalog,
|
|
619
|
-
} from "./components/HkModelCatalog";
|
|
620
|
-
export type {
|
|
621
|
-
HChatRole,
|
|
622
|
-
HToolCall,
|
|
623
|
-
HToolCallStatus,
|
|
624
|
-
HVoicePopupMode,
|
|
625
|
-
HVoiceState,
|
|
626
|
-
HModelUsageEntry,
|
|
627
|
-
HModelCosts,
|
|
628
|
-
} from "./components/HkChatTypes";
|
|
629
555
|
// Canonical Hk* names for the directly-exported types above (2026-09-24
|
|
630
556
|
// unification follow-up, second batch — caught by the third-scan reverse
|
|
631
557
|
// validation). These types are defined with their H* names at the source.
|
|
632
|
-
export type {
|
|
633
|
-
HChatRole as HkChatRole,
|
|
634
|
-
HToolCall as HkToolCall,
|
|
635
|
-
HToolCallStatus as HkToolCallStatus,
|
|
636
|
-
HVoicePopupMode as HkVoicePopupMode,
|
|
637
|
-
HVoiceState as HkVoiceState,
|
|
638
|
-
HModelUsageEntry as HkModelUsageEntry,
|
|
639
|
-
HModelCosts as HkModelCosts,
|
|
640
|
-
} from "./components/HkChatTypes";
|
|
641
|
-
export { useSendShortcut } from "./composables/useSendShortcut";
|
|
642
|
-
export type { SendShortcutMode } from "./composables/useSendShortcut";
|
|
643
|
-
export { useAttachments } from "./composables/useAttachments";
|
|
644
|
-
export type { HkUploadedFile } from "./composables/useAttachments";
|
|
645
558
|
|
|
646
559
|
export {
|
|
647
|
-
formatTokenCount,
|
|
648
560
|
formatNumber,
|
|
649
561
|
formatBytes,
|
|
650
|
-
formatPriceUsd,
|
|
651
562
|
formatRelativeTime,
|
|
652
563
|
formatDateTime,
|
|
653
564
|
formatDate,
|
|
@@ -861,27 +772,16 @@ export { HkSettingsGroup as HkSettingsGroup } from "./components/HkSettingsDialo
|
|
|
861
772
|
export { HkSettingsSub as HkSettingsSub } from "./components/HkSettingsDialog";
|
|
862
773
|
export { HkSettingsHint as HkSettingsHint } from "./components/HkSettingsDialog";
|
|
863
774
|
export { HkCookieConsent as HkCookieConsent } from "./components/HkCookieConsent";
|
|
864
|
-
export { HkAttachmentModal as HkAttachmentModal } from "./components/HkAttachmentModal";
|
|
865
775
|
export { HkStatusBar as HkStatusBar, hkMergeVersionDisplay, hkParseIdentity } from "./components/HkStatusBar";
|
|
866
776
|
export type { HkVersionIdentity } from "./components/HkStatusBar";
|
|
867
777
|
export { HkCountdownDigit as HkCountdownDigit } from "./components/HkCountdownDigit";
|
|
868
778
|
export { HkConnectionStatus as HkConnectionStatus } from "./components/HkConnectionStatus";
|
|
869
|
-
export { HkRichInput as HkRichInput } from "./components/HkRichInput";
|
|
870
|
-
export { HkVoiceInputPopup as HkVoiceInputPopup } from "./components/HkVoiceInputPopup";
|
|
871
|
-
export { HkToolBlock as HkToolBlock } from "./components/HkToolBlock";
|
|
872
779
|
export { HkJsonTree as HkJsonTree } from "./components/HkJsonTree";
|
|
873
|
-
export { HkTokenUsageBadge as HkTokenUsageBadge } from "./components/HkTokenUsageBadge";
|
|
874
|
-
export { HkTokenUsagePanel as HkTokenUsagePanel } from "./components/HkTokenUsagePanel";
|
|
875
|
-
export { HkModelTag as HkModelTag } from "./components/HkModelTag";
|
|
876
780
|
|
|
877
781
|
// Canonical Hk* names for directly-exported types (2026-09-24
|
|
878
782
|
// unification follow-up). These types were defined with their H*
|
|
879
783
|
// names at the source and exported directly — not aliased from an Hk*
|
|
880
784
|
// identifier — so the canonical Hk* form is an alias export here.
|
|
881
|
-
export { type HAttachmentItem as HkAttachmentItem } from "./components/HkAttachmentModal";
|
|
882
|
-
export { type HAttachmentDetail as HkAttachmentDetail } from "./components/HkAttachmentModal";
|
|
883
|
-
export { type HModelMeta as HkModelMeta } from "./components/HkModelCatalog";
|
|
884
|
-
export { type HModelPricing as HkModelPricing } from "./components/HkModelCatalog";
|
|
885
785
|
export { type HAboutCredit as HkAboutCredit } from "./components/HkAboutModal";
|
|
886
786
|
export { type HAboutLink as HkAboutLink } from "./components/HkAboutModal";
|
|
887
787
|
export { type HAboutLinkFace as HkAboutLinkFace } from "./components/HkAboutModal";
|
|
@@ -5,7 +5,6 @@ import HkDivider from "../components/HkDivider";
|
|
|
5
5
|
import HkEmptyState from "../components/HkEmptyState";
|
|
6
6
|
import HkSkeleton from "../components/HkSkeleton";
|
|
7
7
|
import HkSplash from "../components/HkSplash";
|
|
8
|
-
import HkStatusTray from "../components/HkStatusTray";
|
|
9
8
|
import { registerStandardThemeDecor, STANDARD_THEME_DECOR_SLOTS } from "./standardDecor";
|
|
10
9
|
import {
|
|
11
10
|
getThemeDecor,
|
|
@@ -24,7 +23,7 @@ import {
|
|
|
24
23
|
*/
|
|
25
24
|
|
|
26
25
|
describe("registerStandardThemeDecor", () => {
|
|
27
|
-
it("registers nothing at import, then fills the
|
|
26
|
+
it("registers nothing at import, then fills the four in-tree standard slots", async () => {
|
|
28
27
|
// A fresh module graph, so this proves the registration happens in the
|
|
29
28
|
// call and not in an earlier case of this file. The component is
|
|
30
29
|
// imported from the SAME fresh graph: module identity is per graph, so
|
|
@@ -32,7 +31,8 @@ describe("registerStandardThemeDecor", () => {
|
|
|
32
31
|
vi.resetModules();
|
|
33
32
|
const themeDecor = await import("./themeDecor");
|
|
34
33
|
const standardDecor = await import("./standardDecor");
|
|
35
|
-
|
|
34
|
+
// The tray moved to @celestia-island/default-theme; the builtin
|
|
35
|
+
// floor for status.tray is now EMPTY (pinned below).
|
|
36
36
|
|
|
37
37
|
// Importing this module is not a side effect (same contract as
|
|
38
38
|
// standardGroups): only the call populates the registry.
|
|
@@ -43,15 +43,14 @@ describe("registerStandardThemeDecor", () => {
|
|
|
43
43
|
expect([...themeDecor.themeDecorSlots()].sort()).toEqual(
|
|
44
44
|
[...STANDARD_THEME_DECOR_SLOTS].sort(),
|
|
45
45
|
);
|
|
46
|
-
expect(themeDecor.getThemeDecor("status.tray", "any-theme")
|
|
46
|
+
expect(themeDecor.getThemeDecor("status.tray", "any-theme")).toBeUndefined();
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
it("resolves every built-in for any theme id (floor level, and the declared list matches)", () => {
|
|
50
50
|
registerStandardThemeDecor();
|
|
51
51
|
|
|
52
52
|
const expected: [string, unknown][] = [
|
|
53
|
-
|
|
54
|
-
["placeholder.screen", HkSplash],
|
|
53
|
+
["placeholder.screen", HkSplash],
|
|
55
54
|
["placeholder.section", HkSkeleton],
|
|
56
55
|
["empty", HkEmptyState],
|
|
57
56
|
["divider", HkDivider],
|
|
@@ -93,28 +92,30 @@ describe("registerStandardThemeDecor", () => {
|
|
|
93
92
|
|
|
94
93
|
// A theme's own implementation wins over the built-in …
|
|
95
94
|
const themed = defineComponent({ name: "ThemedTray", setup: () => () => h("i") });
|
|
96
|
-
registerThemeDecor({ themeId: "endfield", slot: "
|
|
95
|
+
registerThemeDecor({ themeId: "endfield", slot: "placeholder.screen", component: themed });
|
|
97
96
|
registerStandardThemeDecor();
|
|
98
|
-
expect(getThemeDecor("
|
|
99
|
-
|
|
97
|
+
expect(getThemeDecor("placeholder.screen", "endfield")?.component).toBe(themed);
|
|
98
|
+
// A slot with no theme registration keeps the builtin floor.
|
|
99
|
+
expect(getThemeDecor("placeholder.screen", "other")?.component).toBe(HkSplash);
|
|
100
100
|
|
|
101
101
|
// … and so does a host-wide `"*"` registration.
|
|
102
102
|
const hostWide = defineComponent({ name: "HostTray", setup: () => () => h("i") });
|
|
103
|
-
registerThemeDecor({ themeId: "*", slot: "
|
|
103
|
+
registerThemeDecor({ themeId: "*", slot: "empty", component: hostWide });
|
|
104
104
|
registerStandardThemeDecor();
|
|
105
|
-
expect(getThemeDecor("
|
|
105
|
+
expect(getThemeDecor("empty", "other")?.component).toBe(hostWide);
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
it("lands in the registry via initTheme() (and not before)", async () => {
|
|
109
109
|
vi.resetModules();
|
|
110
110
|
const themeDecor = await import("./themeDecor");
|
|
111
|
-
|
|
111
|
+
// The tray moved to @celestia-island/default-theme; the builtin
|
|
112
|
+
// floor for status.tray is now EMPTY (pinned below).
|
|
112
113
|
const useTheme = await import("./useTheme");
|
|
113
114
|
expect(themeDecor.getThemeDecor("status.tray", "default")).toBeUndefined();
|
|
114
115
|
|
|
115
116
|
useTheme.initTheme();
|
|
116
117
|
|
|
117
|
-
expect(themeDecor.getThemeDecor("status.tray", "default")
|
|
118
|
+
expect(themeDecor.getThemeDecor("status.tray", "default")).toBeUndefined();
|
|
118
119
|
// initTheme starts the solar theme clock; stop it so this file leaves no
|
|
119
120
|
// timer behind.
|
|
120
121
|
useTheme.stopThemeClock();
|
|
@@ -2,7 +2,6 @@ import HkDivider from "../components/HkDivider";
|
|
|
2
2
|
import HkEmptyState from "../components/HkEmptyState";
|
|
3
3
|
import HkSkeleton from "../components/HkSkeleton";
|
|
4
4
|
import HkSplash from "../components/HkSplash";
|
|
5
|
-
import HkStatusTray from "../components/HkStatusTray";
|
|
6
5
|
import { registerThemeDecorBuiltin, type ThemeDecorSlot } from "./themeDecor";
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -15,6 +14,13 @@ import { registerThemeDecorBuiltin, type ThemeDecorSlot } from "./themeDecor";
|
|
|
15
14
|
* consumer that never calls `initTheme()` (tests, SSR, a host with its own
|
|
16
15
|
* theme engine) gets an untouched registry.
|
|
17
16
|
*
|
|
17
|
+
* The status.tray slot is deliberately UNREGISTERED here since the
|
|
18
|
+
* chat-kit demotion wave: hikari's former brand tray moved to the
|
|
19
|
+
* @celestia-island/default-theme package (the reference precompiled
|
|
20
|
+
* theme), which registers it on the "*" wildcard — the same override
|
|
21
|
+
* path any custom theme takes. A host that mounts nothing gets an
|
|
22
|
+
* empty tray slot (the documented "no backdrop" pattern).
|
|
23
|
+
*
|
|
18
24
|
* These land on the BUILT-IN floor of the decor registry, below both an
|
|
19
25
|
* exact theme id and the `"*"` wildcard: a theme (or a host) that registers
|
|
20
26
|
* its own implementation for a slot replaces hikari's default without
|
|
@@ -36,7 +42,6 @@ import { registerThemeDecorBuiltin, type ThemeDecorSlot } from "./themeDecor";
|
|
|
36
42
|
* gap is a decision on record, not an oversight.
|
|
37
43
|
*/
|
|
38
44
|
export const STANDARD_THEME_DECOR_SLOTS: readonly ThemeDecorSlot[] = [
|
|
39
|
-
"status.tray",
|
|
40
45
|
"placeholder.screen",
|
|
41
46
|
"placeholder.section",
|
|
42
47
|
"empty",
|
|
@@ -56,7 +61,6 @@ let registered = false;
|
|
|
56
61
|
export function registerStandardThemeDecor(): void {
|
|
57
62
|
if (registered) return;
|
|
58
63
|
registered = true;
|
|
59
|
-
registerThemeDecorBuiltin({ slot: "status.tray", component: HkStatusTray });
|
|
60
64
|
registerThemeDecorBuiltin({ slot: "placeholder.screen", component: HkSplash });
|
|
61
65
|
registerThemeDecorBuiltin({ slot: "placeholder.section", component: HkSkeleton });
|
|
62
66
|
registerThemeDecorBuiltin({ slot: "empty", component: HkEmptyState });
|
|
@@ -56,11 +56,13 @@ describe("theme decor public surface", () => {
|
|
|
56
56
|
expect(typeof themeBarrel.getThemeDecor).toBe("function");
|
|
57
57
|
expect(typeof themeBarrel.registerStandardThemeDecor).toBe("function");
|
|
58
58
|
expect(themeBarrel.themeDecorVersion.value).toBeTypeOf("number");
|
|
59
|
-
|
|
59
|
+
// status.tray moved to @celestia-island/default-theme (the
|
|
60
|
+
// demotion wave) — the builtin floor no longer carries it.
|
|
61
|
+
expect(themeBarrel.STANDARD_THEME_DECOR_SLOTS).not.toContain("status.tray");
|
|
60
62
|
|
|
61
63
|
// The components ride the root barrel, where every other component lives.
|
|
62
64
|
expect((barrel.HkThemeDecor as { name?: string }).name).toBe("HkThemeDecor");
|
|
63
|
-
expect((barrel.
|
|
65
|
+
expect((barrel.HkSplash as { name?: string }).name).toBe("HkSplash");
|
|
64
66
|
});
|
|
65
67
|
|
|
66
68
|
it("registers nothing just because the surface was imported", () => {
|
|
@@ -77,6 +79,6 @@ describe("theme decor public surface", () => {
|
|
|
77
79
|
|
|
78
80
|
// …and the extractor does detect a component import where one exists.
|
|
79
81
|
const seamImports = importSpecifiers("standardDecor.ts");
|
|
80
|
-
expect(seamImports.filter((s) => s.includes("components/")).length).toBeGreaterThanOrEqual(
|
|
82
|
+
expect(seamImports.filter((s) => s.includes("components/")).length).toBeGreaterThanOrEqual(4);
|
|
81
83
|
});
|
|
82
84
|
});
|
package/src/utils/format.ts
CHANGED
|
@@ -15,11 +15,6 @@
|
|
|
15
15
|
import { activeLocale } from "../i18n/context";
|
|
16
16
|
|
|
17
17
|
/** "1234" -> "1.2k", "2500000" -> "2.5M". */
|
|
18
|
-
export function formatTokenCount(n: number): string {
|
|
19
|
-
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
|
|
20
|
-
if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`;
|
|
21
|
-
return String(n);
|
|
22
|
-
}
|
|
23
18
|
|
|
24
19
|
/** "1234" -> "1.2k". */
|
|
25
20
|
export function formatNumber(n: number): string {
|
|
@@ -37,12 +32,6 @@ export function formatBytes(bytes: number): string {
|
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
/** USD amount -> "$0.10" / "$1.5" / "$120". Negative/NaN clamp to 0. */
|
|
40
|
-
export function formatPriceUsd(n: number, currency = "$"): string {
|
|
41
|
-
if (!Number.isFinite(n) || n < 0) n = 0;
|
|
42
|
-
if (n >= 100) return `${currency}${Math.round(n)}`;
|
|
43
|
-
if (n >= 1) return `${currency}${n.toFixed(1)}`;
|
|
44
|
-
return `${currency}${n.toFixed(2)}`;
|
|
45
|
-
}
|
|
46
35
|
|
|
47
36
|
/** Timestamp -> "Just now" / "5m ago" / "3h ago" / "2d ago" / "2w ago" /
|
|
48
37
|
* locale date. */
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
.s-attachment-modal {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: column;
|
|
4
|
-
gap: var(--space-12, 0.75rem);
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.s-attachment-modal-text {
|
|
8
|
-
max-height: 48vh;
|
|
9
|
-
padding: var(--space-12, 0.75rem);
|
|
10
|
-
border: 1px solid var(--border-faint, rgb(var(--color-border) / 10%));
|
|
11
|
-
border-radius: var(--radius-md, 8px);
|
|
12
|
-
background: rgb(var(--color-surface) / 0.5);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.s-attachment-modal-text-empty {
|
|
16
|
-
margin: 0;
|
|
17
|
-
font-size: var(--text-xs, 0.75rem);
|
|
18
|
-
color: rgb(var(--color-muted));
|
|
19
|
-
font-style: italic;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.s-attachment-modal-text-error {
|
|
23
|
-
margin: var(--space-8, 0.5rem) 0 0;
|
|
24
|
-
font-size: var(--text-xs, 0.75rem);
|
|
25
|
-
color: rgb(var(--color-error));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.s-attachment-modal-file {
|
|
29
|
-
display: flex;
|
|
30
|
-
flex-direction: column;
|
|
31
|
-
align-items: center;
|
|
32
|
-
gap: var(--space-8, 0.5rem);
|
|
33
|
-
padding: var(--space-24, 1.5rem);
|
|
34
|
-
color: rgb(var(--color-muted));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.s-attachment-modal-file-name {
|
|
38
|
-
margin: 0;
|
|
39
|
-
font-size: var(--text-sm, 0.8125rem);
|
|
40
|
-
max-width: 100%;
|
|
41
|
-
overflow: hidden;
|
|
42
|
-
text-overflow: ellipsis;
|
|
43
|
-
white-space: nowrap;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.s-attachment-modal-meta {
|
|
47
|
-
display: flex;
|
|
48
|
-
gap: var(--space-8, 0.5rem);
|
|
49
|
-
}
|