@celestia-island/hikari 0.55.225 → 0.55.226
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/HkAboutBody.test.tsx +124 -0
- package/src/components/HkAboutModal.tsx +204 -109
- package/src/index.ts +2 -0
package/package.json
CHANGED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { createApp, defineComponent, h, nextTick } from "vue";
|
|
3
|
+
|
|
4
|
+
import { HkAboutBody } from "./HkAboutModal";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* HkAboutBody contract tests for the extraction wave (2026-10-29): the
|
|
8
|
+
* body is the modal's whole layout mountable OUTSIDE a modal — the desktop
|
|
9
|
+
* settings' About pane renders it directly, and a second hand-copied body
|
|
10
|
+
* is exactly how the credits links drifted. These tests pin the two
|
|
11
|
+
* body-level knobs the modal never needed:
|
|
12
|
+
* - `filingsAsChips` renders the legal filings as their own chip group
|
|
13
|
+
* (`data-slot="filings"`) and NO bare footer-links row
|
|
14
|
+
* - default (modal) behavior keeps the bare footer-links row and no filings
|
|
15
|
+
* group
|
|
16
|
+
* - the default slot appends host content after the copyright footer
|
|
17
|
+
* - without a backdrop factory no backdrop layer renders (a body host may
|
|
18
|
+
* not want the decorative canvas at all)
|
|
19
|
+
*
|
|
20
|
+
* (Repo test convention: raw createApp + document queries, no
|
|
21
|
+
* @vue/test-utils dependency.)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const mounts: Array<{ app: ReturnType<typeof createApp>; container: HTMLElement }> = [];
|
|
25
|
+
|
|
26
|
+
function mountBody(props: Record<string, unknown> = {}, slot?: () => unknown): void {
|
|
27
|
+
const container = document.createElement("div");
|
|
28
|
+
document.body.appendChild(container);
|
|
29
|
+
|
|
30
|
+
const Wrapper = defineComponent({
|
|
31
|
+
setup() {
|
|
32
|
+
return () =>
|
|
33
|
+
h(HkAboutBody, { appName: "Test App", version: "1.2.3", ...props }, slot ? { default: slot } : undefined);
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
const app = createApp(Wrapper);
|
|
37
|
+
app.mount(container);
|
|
38
|
+
mounts.push({ app, container });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function query<T extends Element>(selector: string): T {
|
|
42
|
+
const el = document.body.querySelector<T>(selector);
|
|
43
|
+
expect(el, `${selector} renders`).toBeTruthy();
|
|
44
|
+
return el!;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function flush() {
|
|
48
|
+
await nextTick();
|
|
49
|
+
await nextTick();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
afterEach(() => {
|
|
53
|
+
for (const { app, container } of mounts.splice(0)) {
|
|
54
|
+
app.unmount();
|
|
55
|
+
container.remove();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const FILINGS = [
|
|
60
|
+
{ label: "苏ICP备2025155733号-2", href: "https://beian.miit.gov.cn/", face: "chip" as const },
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
describe("HkAboutBody extraction", () => {
|
|
64
|
+
it("mounts the full body outside a modal", async () => {
|
|
65
|
+
mountBody({
|
|
66
|
+
tagline: "Chat with your AI agents",
|
|
67
|
+
credits: [
|
|
68
|
+
{ text: "来自 " },
|
|
69
|
+
{ name: "Celestia Island", href: "https://celestia.world", face: "accent" },
|
|
70
|
+
{ text: ",由 " },
|
|
71
|
+
{ name: "伊欧", href: "https://github.com/langyo", face: "accent" },
|
|
72
|
+
{ text: " 主创" },
|
|
73
|
+
],
|
|
74
|
+
componentVersions: [{ label: "WebUI 版本", value: "0.1.0 master:abc1234" }],
|
|
75
|
+
});
|
|
76
|
+
await flush();
|
|
77
|
+
|
|
78
|
+
expect(query(".s-about-modal")).toBeTruthy();
|
|
79
|
+
// No HModal shell around it: no dialog surface, no overlay.
|
|
80
|
+
expect(document.body.querySelector(".hk-modal")).toBeNull();
|
|
81
|
+
expect(query(".s-about-modal-name").textContent).toContain("Test App");
|
|
82
|
+
expect(document.body.querySelectorAll(".s-about-modal-credit-link")).toHaveLength(2);
|
|
83
|
+
expect(query(".s-about-modal-row-number").textContent).toContain("master:abc1234");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("filingsAsChips renders the filings group and no footer-links row", async () => {
|
|
87
|
+
mountBody({ footerLinks: FILINGS, filingsAsChips: true });
|
|
88
|
+
await flush();
|
|
89
|
+
|
|
90
|
+
const group = query('.s-about-modal-links[data-slot="filings"]');
|
|
91
|
+
const link = group.querySelector<HTMLAnchorElement>(".s-about-modal-link");
|
|
92
|
+
expect(link?.getAttribute("data-face")).toBe("chip");
|
|
93
|
+
expect(link?.getAttribute("href")).toBe("https://beian.miit.gov.cn/");
|
|
94
|
+
// The bare row is the modal face; chips mode must not render both.
|
|
95
|
+
expect(document.body.querySelector(".s-about-modal-footer-links")).toBeNull();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("default filings keep the bare footer-links row with no group", async () => {
|
|
99
|
+
mountBody({ footerLinks: [{ label: "ICP", href: "https://beian.miit.gov.cn/" }] });
|
|
100
|
+
await flush();
|
|
101
|
+
|
|
102
|
+
expect(query(".s-about-modal-footer-links")).toBeTruthy();
|
|
103
|
+
expect(document.body.querySelector('.s-about-modal-links[data-slot="filings"]')).toBeNull();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("appends default-slot content after the copyright footer", async () => {
|
|
107
|
+
mountBody({}, () => h("button", { class: "body-slot-row" }, "Check update"));
|
|
108
|
+
await flush();
|
|
109
|
+
|
|
110
|
+
const body = query(".s-about-modal-body");
|
|
111
|
+
const footer = body.querySelector(".s-about-modal-footer")!;
|
|
112
|
+
const button = body.querySelector(".body-slot-row")!;
|
|
113
|
+
expect(button).toBeTruthy();
|
|
114
|
+
// After the footer in document order: the slot rides at the body's end.
|
|
115
|
+
expect(footer.compareDocumentPosition(button) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("renders no backdrop layer when the host passes no factory", async () => {
|
|
119
|
+
mountBody();
|
|
120
|
+
await flush();
|
|
121
|
+
|
|
122
|
+
expect(document.body.querySelector(".s-about-modal-backdrop")).toBeNull();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
@@ -82,24 +82,27 @@ export interface HAboutComponentVersion {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
|
-
*
|
|
86
|
-
* (Upstreamed from shittim-chest's plana-legacy layer.)
|
|
85
|
+
* HkAboutBody — the About dialog's body, mountable OUTSIDE a modal.
|
|
87
86
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
87
|
+
* Extracted verbatim from HkAboutModal (2026-10-29): the desktop settings'
|
|
88
|
+
* About section renders this same body inside its own pane, so every
|
|
89
|
+
* surface shares one implementation of the identity hero, the credits
|
|
90
|
+
* sentence, the spec card and the link rows — the hand-copied second body
|
|
91
|
+
* is exactly how the credits links drifted (both names pointing at the
|
|
92
|
+
* organization's URL, the trailing role word lost).
|
|
93
|
+
*
|
|
94
|
+
* Two body-level knobs exist for hosts that are not a modal:
|
|
95
|
+
* - `filingsAsChips` renders the legal filings as a chip group
|
|
96
|
+
* (`data-slot="filings"`) instead of the bare footer-text row — the
|
|
97
|
+
* desktop surface's standing direction (2026-10-23: no bare text
|
|
98
|
+
* hyperlinks on that surface) while the modal keeps the plain row
|
|
99
|
+
* (2026-09-14).
|
|
100
|
+
* - the default slot appends host content after the copyright footer
|
|
101
|
+
* (the desktop's update-check row), still inside the body's flow.
|
|
98
102
|
*/
|
|
99
|
-
export const
|
|
100
|
-
name: "
|
|
103
|
+
export const HkAboutBody = defineComponent({
|
|
104
|
+
name: "HkAboutBody",
|
|
101
105
|
props: {
|
|
102
|
-
modelValue: { type: Boolean, default: false },
|
|
103
106
|
/** Application display name. */
|
|
104
107
|
appName: { type: String, required: true },
|
|
105
108
|
/** Application version (e.g. "0.1.4"). */
|
|
@@ -134,18 +137,17 @@ export const HkAboutModal = defineComponent({
|
|
|
134
137
|
links: { type: Array as PropType<HAboutLink[]>, default: () => [] },
|
|
135
138
|
/** Optional centered legal links above the copyright (ICP filings). */
|
|
136
139
|
footerLinks: { type: Array as PropType<HAboutLink[]>, default: () => [] },
|
|
140
|
+
/** Render the legal filings as a chip group instead of the bare
|
|
141
|
+
* footer-text row (the desktop surface's standing direction). */
|
|
142
|
+
filingsAsChips: { type: Boolean, default: false },
|
|
137
143
|
/**
|
|
138
144
|
* Optional decorative backdrop factory, rendered behind the content
|
|
139
|
-
* inside a clipped, pointer-inert layer. The
|
|
145
|
+
* inside a clipped, pointer-inert layer. The body owns only the layer —
|
|
140
146
|
* sizing, theming and the render loop belong to the returned subtree.
|
|
141
147
|
*/
|
|
142
148
|
backdrop: { type: Function as PropType<() => unknown>, default: undefined },
|
|
143
|
-
title: { type: String, default: undefined },
|
|
144
|
-
},
|
|
145
|
-
emits: {
|
|
146
|
-
"update:modelValue": (_v: boolean) => true,
|
|
147
149
|
},
|
|
148
|
-
setup(props, {
|
|
150
|
+
setup(props, { slots }) {
|
|
149
151
|
const { t } = useI18n();
|
|
150
152
|
|
|
151
153
|
// One link renderer for every link in the dialog: credits names,
|
|
@@ -233,102 +235,195 @@ export const HkAboutModal = defineComponent({
|
|
|
233
235
|
};
|
|
234
236
|
|
|
235
237
|
return () => (
|
|
236
|
-
<
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
<div class="s-about-modal">
|
|
243
|
-
|
|
244
|
-
<div class="s-about-modal-
|
|
245
|
-
{props.
|
|
238
|
+
<div class="s-about-modal">
|
|
239
|
+
{props.backdrop && (
|
|
240
|
+
<div class="s-about-modal-backdrop" aria-hidden="true">
|
|
241
|
+
{props.backdrop()}
|
|
242
|
+
</div>
|
|
243
|
+
)}
|
|
244
|
+
<div class="s-about-modal-body">
|
|
245
|
+
<header class="s-about-modal-header">
|
|
246
|
+
<div class="s-about-modal-logo-frame">
|
|
247
|
+
{props.logoSrc ? (
|
|
248
|
+
<img
|
|
249
|
+
class="s-about-modal-logo-img"
|
|
250
|
+
src={props.logoSrc}
|
|
251
|
+
alt=""
|
|
252
|
+
draggable={false}
|
|
253
|
+
/>
|
|
254
|
+
) : (
|
|
255
|
+
<div class="s-about-modal-logo">{props.appName.slice(0, 1).toUpperCase()}</div>
|
|
256
|
+
)}
|
|
246
257
|
</div>
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
258
|
+
<div class="s-about-modal-identity">
|
|
259
|
+
<h2 class="s-about-modal-name">{props.appName}</h2>
|
|
260
|
+
<p class="s-about-modal-subtitle">
|
|
261
|
+
<span class="s-about-modal-version">
|
|
262
|
+
{t("hikari::about.version", "Version")} {props.version}
|
|
263
|
+
</span>
|
|
264
|
+
{props.tagline && (
|
|
265
|
+
<>
|
|
266
|
+
<span class="s-about-modal-subtitle-sep" aria-hidden="true">
|
|
267
|
+
·
|
|
268
|
+
</span>
|
|
269
|
+
<span class="s-about-modal-tagline">{props.tagline}</span>
|
|
270
|
+
</>
|
|
260
271
|
)}
|
|
261
|
-
</
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
<p class="s-about-modal-subtitle">
|
|
265
|
-
<span class="s-about-modal-version">
|
|
266
|
-
{t("hikari::about.version", "Version")} {props.version}
|
|
267
|
-
</span>
|
|
268
|
-
{props.tagline && (
|
|
269
|
-
<>
|
|
270
|
-
<span class="s-about-modal-subtitle-sep" aria-hidden="true">
|
|
271
|
-
·
|
|
272
|
-
</span>
|
|
273
|
-
<span class="s-about-modal-tagline">{props.tagline}</span>
|
|
274
|
-
</>
|
|
275
|
-
)}
|
|
276
|
-
</p>
|
|
277
|
-
</div>
|
|
278
|
-
</header>
|
|
272
|
+
</p>
|
|
273
|
+
</div>
|
|
274
|
+
</header>
|
|
279
275
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
276
|
+
{(props.credits.length > 0 || props.description) && (
|
|
277
|
+
<div class="s-about-modal-credits">
|
|
278
|
+
{renderCredits()}
|
|
279
|
+
{props.description && (
|
|
280
|
+
<p class="s-about-modal-description">{props.description}</p>
|
|
281
|
+
)}
|
|
282
|
+
</div>
|
|
283
|
+
)}
|
|
288
284
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
285
|
+
{props.componentVersions.length > 0 && (
|
|
286
|
+
<div class="s-about-modal-rows">
|
|
287
|
+
{props.componentVersions.map((component) => (
|
|
288
|
+
<div class="s-about-modal-row" key={component.label}>
|
|
289
|
+
<span class="s-about-modal-row-label">{component.label}</span>
|
|
290
|
+
<span class="s-about-modal-row-value">
|
|
291
|
+
<span class="s-about-modal-row-number">{component.value}</span>
|
|
292
|
+
{component.meta && (
|
|
293
|
+
<span
|
|
294
|
+
class="s-about-modal-row-meta"
|
|
295
|
+
data-tone={component.metaTone ?? "neutral"}
|
|
296
|
+
>
|
|
297
|
+
{component.meta}
|
|
298
|
+
</span>
|
|
299
|
+
)}
|
|
300
|
+
</span>
|
|
301
|
+
</div>
|
|
302
|
+
))}
|
|
303
|
+
</div>
|
|
304
|
+
)}
|
|
309
305
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
306
|
+
{(props.licenses.length > 0 || props.links.length > 0) && (
|
|
307
|
+
<div class="s-about-modal-chips">
|
|
308
|
+
{renderLinks(props.licenses, "licenses")}
|
|
309
|
+
{renderLinks(props.links, "links")}
|
|
310
|
+
</div>
|
|
311
|
+
)}
|
|
316
312
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
313
|
+
{props.filingsAsChips
|
|
314
|
+
? // The desktop surface's filings: chips in their own group,
|
|
315
|
+
// in the body flow (2026-10-23 direction).
|
|
316
|
+
renderLinks(props.footerLinks, "filings")
|
|
317
|
+
: visibleLinks(props.footerLinks).length > 0 && (
|
|
318
|
+
<div class="s-about-modal-footer-links">
|
|
319
|
+
{visibleLinks(props.footerLinks).map((link, index) =>
|
|
320
|
+
renderLink(link, "s-about-modal-footer-link", `legal:${index}`),
|
|
321
|
+
)}
|
|
322
|
+
</div>
|
|
323
|
+
)}
|
|
324
324
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
325
|
+
<footer class="s-about-modal-footer">
|
|
326
|
+
<HBadge variant="muted">
|
|
327
|
+
© {new Date().getFullYear()} {props.copyright ?? props.appName}
|
|
328
|
+
</HBadge>
|
|
329
|
+
</footer>
|
|
330
|
+
|
|
331
|
+
{slots.default?.()}
|
|
331
332
|
</div>
|
|
333
|
+
</div>
|
|
334
|
+
);
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* HkAboutModal — version / about dialog.
|
|
340
|
+
* (Upstreamed from shittim-chest's plana-legacy layer.)
|
|
341
|
+
*
|
|
342
|
+
* A centered HModal wrapping {@link HkAboutBody} — the body carries the
|
|
343
|
+
* whole layout (identity hero, credits block, spec card, link rows) and is
|
|
344
|
+
* the piece other surfaces mount directly, so the modal and the settings
|
|
345
|
+
* pane cannot drift. Every link opens in a new tab and renders in the face
|
|
346
|
+
* its entry asks for: the ghost chip, or bare text (`plain` / tinted
|
|
347
|
+
* `accent`) for names / URLs / filings that should read as ordinary
|
|
348
|
+
* sentence text. Every branding prop is optional — the modal degrades to
|
|
349
|
+
* the plain identity card when none are given.
|
|
350
|
+
*/
|
|
351
|
+
export const HkAboutModal = defineComponent({
|
|
352
|
+
name: "HkAboutModal",
|
|
353
|
+
props: {
|
|
354
|
+
modelValue: { type: Boolean, default: false },
|
|
355
|
+
/** Application display name. */
|
|
356
|
+
appName: { type: String, required: true },
|
|
357
|
+
/** Application version (e.g. "0.1.4"). */
|
|
358
|
+
version: { type: String, required: true },
|
|
359
|
+
/** Optional logo image URL — replaces the first-letter tile. */
|
|
360
|
+
logoSrc: { type: String, default: undefined },
|
|
361
|
+
/** Optional one-liner shown beside the version (e.g. the app tagline). */
|
|
362
|
+
tagline: { type: String, default: undefined },
|
|
363
|
+
/** Optional centered small line under the credits (organization blurb). */
|
|
364
|
+
description: { type: String, default: undefined },
|
|
365
|
+
/**
|
|
366
|
+
* Credits sentence, assembled from text runs and linked names
|
|
367
|
+
* (e.g. 来自 <Celestia Island>,由 <伊欧> 主创). Each name renders in the
|
|
368
|
+
* face its entry asks for — `chip`, bare text with `plain`, or bare
|
|
369
|
+
* text tinted in the primary colour with `accent`.
|
|
370
|
+
*/
|
|
371
|
+
credits: { type: Array as PropType<HAboutCredit[]>, default: () => [] },
|
|
372
|
+
/** License links (e.g. SySL-1.0 / BUSL-1.1), rendered centered. */
|
|
373
|
+
licenses: { type: Array as PropType<HAboutLink[]>, default: () => [] },
|
|
374
|
+
/** Software-component version rows (WebUI / engines), label + value. */
|
|
375
|
+
componentVersions: {
|
|
376
|
+
type: Array as PropType<HAboutComponentVersion[]>,
|
|
377
|
+
default: () => [],
|
|
378
|
+
},
|
|
379
|
+
/** Optional copyright holder in the footer (defaults to the app name). */
|
|
380
|
+
copyright: { type: String, default: undefined },
|
|
381
|
+
/**
|
|
382
|
+
* Optional external links (e.g. the site domains, the project's GitHub
|
|
383
|
+
* home). An entry may carry an `icon` instead of a `label` — that is how
|
|
384
|
+
* the GitHub mark rides at the end of the domain row.
|
|
385
|
+
*/
|
|
386
|
+
links: { type: Array as PropType<HAboutLink[]>, default: () => [] },
|
|
387
|
+
/** Optional centered legal links above the copyright (ICP filings). */
|
|
388
|
+
footerLinks: { type: Array as PropType<HAboutLink[]>, default: () => [] },
|
|
389
|
+
/** Render the legal filings as a chip group (see {@link HkAboutBody}). */
|
|
390
|
+
filingsAsChips: { type: Boolean, default: false },
|
|
391
|
+
/**
|
|
392
|
+
* Optional decorative backdrop factory, rendered behind the content
|
|
393
|
+
* inside a clipped, pointer-inert layer. The modal owns only the layer —
|
|
394
|
+
* sizing, theming and the render loop belong to the returned subtree.
|
|
395
|
+
*/
|
|
396
|
+
backdrop: { type: Function as PropType<() => unknown>, default: undefined },
|
|
397
|
+
title: { type: String, default: undefined },
|
|
398
|
+
},
|
|
399
|
+
emits: {
|
|
400
|
+
"update:modelValue": (_v: boolean) => true,
|
|
401
|
+
},
|
|
402
|
+
setup(props, { emit }) {
|
|
403
|
+
const { t } = useI18n();
|
|
404
|
+
|
|
405
|
+
return () => (
|
|
406
|
+
<HModal
|
|
407
|
+
modelValue={props.modelValue}
|
|
408
|
+
onUpdate:modelValue={(v: boolean) => emit("update:modelValue", v)}
|
|
409
|
+
title={props.title ?? t("hikari::about.title", "About")}
|
|
410
|
+
width="30rem"
|
|
411
|
+
>
|
|
412
|
+
<HkAboutBody
|
|
413
|
+
appName={props.appName}
|
|
414
|
+
version={props.version}
|
|
415
|
+
logoSrc={props.logoSrc}
|
|
416
|
+
tagline={props.tagline}
|
|
417
|
+
description={props.description}
|
|
418
|
+
credits={props.credits}
|
|
419
|
+
licenses={props.licenses}
|
|
420
|
+
componentVersions={props.componentVersions}
|
|
421
|
+
copyright={props.copyright}
|
|
422
|
+
links={props.links}
|
|
423
|
+
footerLinks={props.footerLinks}
|
|
424
|
+
filingsAsChips={props.filingsAsChips}
|
|
425
|
+
backdrop={props.backdrop}
|
|
426
|
+
/>
|
|
332
427
|
</HModal>
|
|
333
428
|
);
|
|
334
429
|
},
|
package/src/index.ts
CHANGED
|
@@ -534,6 +534,7 @@ export { HkCaptchaModal as HCaptchaModal } from "./components/HkCaptchaModal";
|
|
|
534
534
|
export { HkProtocolModal as HProtocolModal } from "./components/HkProtocolModal";
|
|
535
535
|
export {
|
|
536
536
|
HkAboutModal as HAboutModal,
|
|
537
|
+
HkAboutBody as HAboutBody,
|
|
537
538
|
type HAboutComponentVersion,
|
|
538
539
|
type HAboutCredit,
|
|
539
540
|
type HAboutLink,
|
|
@@ -806,6 +807,7 @@ export { HkCaptchaWidget as HkCaptchaWidget } from "./components/HkCaptchaWidget
|
|
|
806
807
|
export { HkCaptchaModal as HkCaptchaModal } from "./components/HkCaptchaModal";
|
|
807
808
|
export { HkProtocolModal as HkProtocolModal } from "./components/HkProtocolModal";
|
|
808
809
|
export { HkAboutModal as HkAboutModal } from "./components/HkAboutModal";
|
|
810
|
+
export { HkAboutBody as HkAboutBody } from "./components/HkAboutModal";
|
|
809
811
|
export { HkLogWindow as HkLogWindow } from "./components/HkLogWindow";
|
|
810
812
|
export { HkSettingsBody as HkSettingsBody } from "./components/HkSettingsDialog";
|
|
811
813
|
export { HkSettingsDialog as HkSettingsDialog } from "./components/HkSettingsDialog";
|