@countermeasure-platform/web-components 1.3.4-dev.35.1 → 1.3.5-dev.36.1
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/dist/react/layout/core-app-chrome.d.ts +14 -0
- package/dist/react/layout/core-app-chrome.d.ts.map +1 -0
- package/dist/react/layout/core-app-chrome.js +46 -0
- package/dist/react/layout/core-app-chrome.js.map +1 -0
- package/dist/react/layout/index.d.ts +1 -0
- package/dist/react/layout/index.d.ts.map +1 -1
- package/dist/react/layout/index.js +3 -2
- package/dist/react.js +97 -96
- package/package.json +6 -1
- package/src/react/layout/core-app-chrome.test.tsx +124 -0
- package/src/react/layout/core-app-chrome.tsx +110 -0
- package/src/react/layout/index.ts +7 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CoreAppChromeMount, CoreAppChromeMountOptions, CoreAppSidebarPresetOptions, CoreAppTopbarPresetOptions } from '../../layout/core-app-chrome';
|
|
2
|
+
export interface CoreAppChromeProps extends Omit<CoreAppChromeMountOptions, 'sidebarContainer' | 'topbarContainer' | 'topbar'> {
|
|
3
|
+
className?: string;
|
|
4
|
+
sidebarClassName?: string;
|
|
5
|
+
topbarClassName?: string;
|
|
6
|
+
topbar?: Omit<CoreAppTopbarPresetOptions, 'container'> | false;
|
|
7
|
+
}
|
|
8
|
+
export type { CoreAppChromeMount, CoreAppSidebarPresetOptions, CoreAppTopbarPresetOptions };
|
|
9
|
+
declare function CoreAppChrome({ className, sidebarClassName, topbarClassName, basePath, pathname, scope, sidebarUser, sidebarFooterActions, topbarUser, topbarActions, sidebar, topbar, preserveTopbarActions, topbarActionSelector, clearContainers, }: CoreAppChromeProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
declare namespace CoreAppChrome {
|
|
11
|
+
var displayName: string;
|
|
12
|
+
}
|
|
13
|
+
export { CoreAppChrome };
|
|
14
|
+
//# sourceMappingURL=core-app-chrome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-app-chrome.d.ts","sourceRoot":"","sources":["../../../src/react/layout/core-app-chrome.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAChC,MAAM,8BAA8B,CAAA;AAGrC,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAC9C,yBAAyB,EACzB,kBAAkB,GAAG,iBAAiB,GAAG,QAAQ,CAClD;IACC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,MAAM,CAAC,EAAE,IAAI,CAAC,0BAA0B,EAAE,WAAW,CAAC,GAAG,KAAK,CAAA;CAC/D;AAED,YAAY,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,0BAA0B,EAAE,CAAA;AAE3F,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,WAAW,EACX,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,OAAO,EACP,MAAW,EACX,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,EAAE,kBAAkB,2CAkEpB;kBAlFQ,aAAa;;;AAsFtB,OAAO,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { mountCoreAppChrome as e } from "../../layout/core-app-chrome.js";
|
|
2
|
+
import { t } from "../../utils-BC9GT6Pr.js";
|
|
3
|
+
import * as n from "react";
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
//#region src/react/layout/core-app-chrome.tsx
|
|
6
|
+
function a({ className: a, sidebarClassName: o, topbarClassName: s, basePath: c, pathname: l, scope: u, sidebarUser: d, sidebarFooterActions: f, topbarUser: p, topbarActions: m, sidebar: h, topbar: g = {}, preserveTopbarActions: _, topbarActionSelector: v, clearContainers: y }) {
|
|
7
|
+
let b = n.useRef(null), x = n.useRef(null), S = n.useRef(null);
|
|
8
|
+
return n.useEffect(() => {
|
|
9
|
+
let t = b.current, n = g === !1 ? void 0 : x.current;
|
|
10
|
+
if (t === null || g !== !1 && n === null) return;
|
|
11
|
+
let r = { sidebarContainer: t };
|
|
12
|
+
return c !== void 0 && (r.basePath = c), l !== void 0 && (r.pathname = l), u !== void 0 && (r.scope = u), d !== void 0 && (r.sidebarUser = d), f !== void 0 && (r.sidebarFooterActions = f), p !== void 0 && (r.topbarUser = p), m !== void 0 && (r.topbarActions = m), h !== void 0 && (r.sidebar = h), _ !== void 0 && (r.preserveTopbarActions = _), v !== void 0 && (r.topbarActionSelector = v), y !== void 0 && (r.clearContainers = y), g !== !1 && n != null && (r.topbarContainer = n, r.topbar = g), S.current = e(r), () => {
|
|
13
|
+
S.current?.destroy(), S.current = null;
|
|
14
|
+
};
|
|
15
|
+
}, [
|
|
16
|
+
c,
|
|
17
|
+
l,
|
|
18
|
+
u,
|
|
19
|
+
d,
|
|
20
|
+
f,
|
|
21
|
+
p,
|
|
22
|
+
m,
|
|
23
|
+
h,
|
|
24
|
+
g,
|
|
25
|
+
_,
|
|
26
|
+
v,
|
|
27
|
+
y
|
|
28
|
+
]), /* @__PURE__ */ i("div", {
|
|
29
|
+
"data-slot": "core-app-chrome",
|
|
30
|
+
className: t(a),
|
|
31
|
+
children: [/* @__PURE__ */ r("div", {
|
|
32
|
+
ref: b,
|
|
33
|
+
"data-slot": "core-app-sidebar",
|
|
34
|
+
className: t(o)
|
|
35
|
+
}), g === !1 ? null : /* @__PURE__ */ r("div", {
|
|
36
|
+
ref: x,
|
|
37
|
+
"data-slot": "core-app-topbar",
|
|
38
|
+
className: t(s)
|
|
39
|
+
})]
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
a.displayName = "CoreAppChrome";
|
|
43
|
+
//#endregion
|
|
44
|
+
export { a as CoreAppChrome };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=core-app-chrome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-app-chrome.js","names":[],"sources":["../../../src/react/layout/core-app-chrome.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {\n mountCoreAppChrome,\n type CoreAppChromeMount,\n type CoreAppChromeMountOptions,\n type CoreAppSidebarPresetOptions,\n type CoreAppTopbarPresetOptions,\n} from '../../layout/core-app-chrome'\nimport { cn } from '../primitives/utils'\n\nexport interface CoreAppChromeProps extends Omit<\n CoreAppChromeMountOptions,\n 'sidebarContainer' | 'topbarContainer' | 'topbar'\n> {\n className?: string\n sidebarClassName?: string\n topbarClassName?: string\n topbar?: Omit<CoreAppTopbarPresetOptions, 'container'> | false\n}\n\nexport type { CoreAppChromeMount, CoreAppSidebarPresetOptions, CoreAppTopbarPresetOptions }\n\nfunction CoreAppChrome({\n className,\n sidebarClassName,\n topbarClassName,\n basePath,\n pathname,\n scope,\n sidebarUser,\n sidebarFooterActions,\n topbarUser,\n topbarActions,\n sidebar,\n topbar = {},\n preserveTopbarActions,\n topbarActionSelector,\n clearContainers,\n}: CoreAppChromeProps) {\n const sidebarContainerRef = React.useRef<HTMLDivElement>(null)\n const topbarContainerRef = React.useRef<HTMLDivElement>(null)\n const mountRef = React.useRef<CoreAppChromeMount | null>(null)\n\n React.useEffect(() => {\n const sidebarContainer = sidebarContainerRef.current\n const topbarContainer = topbar === false ? undefined : topbarContainerRef.current\n\n if (sidebarContainer === null || (topbar !== false && topbarContainer === null)) {\n return\n }\n\n const mountOptions: CoreAppChromeMountOptions = { sidebarContainer }\n\n if (basePath !== undefined) mountOptions.basePath = basePath\n if (pathname !== undefined) mountOptions.pathname = pathname\n if (scope !== undefined) mountOptions.scope = scope\n if (sidebarUser !== undefined) mountOptions.sidebarUser = sidebarUser\n if (sidebarFooterActions !== undefined) mountOptions.sidebarFooterActions = sidebarFooterActions\n if (topbarUser !== undefined) mountOptions.topbarUser = topbarUser\n if (topbarActions !== undefined) mountOptions.topbarActions = topbarActions\n if (sidebar !== undefined) mountOptions.sidebar = sidebar\n if (preserveTopbarActions !== undefined)\n mountOptions.preserveTopbarActions = preserveTopbarActions\n if (topbarActionSelector !== undefined) mountOptions.topbarActionSelector = topbarActionSelector\n if (clearContainers !== undefined) mountOptions.clearContainers = clearContainers\n\n if (topbar !== false && topbarContainer !== undefined && topbarContainer !== null) {\n mountOptions.topbarContainer = topbarContainer\n mountOptions.topbar = topbar\n }\n\n mountRef.current = mountCoreAppChrome(mountOptions)\n\n return () => {\n mountRef.current?.destroy()\n mountRef.current = null\n }\n }, [\n basePath,\n pathname,\n scope,\n sidebarUser,\n sidebarFooterActions,\n topbarUser,\n topbarActions,\n sidebar,\n topbar,\n preserveTopbarActions,\n topbarActionSelector,\n clearContainers,\n ])\n\n return (\n <div data-slot=\"core-app-chrome\" className={cn(className)}>\n <div\n ref={sidebarContainerRef}\n data-slot=\"core-app-sidebar\"\n className={cn(sidebarClassName)}\n />\n {topbar === false ? null : (\n <div ref={topbarContainerRef} data-slot=\"core-app-topbar\" className={cn(topbarClassName)} />\n )}\n </div>\n )\n}\n\nCoreAppChrome.displayName = 'CoreAppChrome'\n\nexport { CoreAppChrome }\n"],"mappings":";;;;;AAuBA,SAAS,EAAc,EACrB,cACA,qBACA,oBACA,aACA,aACA,UACA,gBACA,yBACA,eACA,kBACA,YACA,YAAS,CAAC,GACV,0BACA,yBACA,sBACqB;CACrB,IAAM,IAAsB,EAAM,OAAuB,IAAI,GACvD,IAAqB,EAAM,OAAuB,IAAI,GACtD,IAAW,EAAM,OAAkC,IAAI;CAmD7D,OAjDA,EAAM,gBAAgB;EACpB,IAAM,IAAmB,EAAoB,SACvC,IAAkB,MAAW,KAAQ,KAAA,IAAY,EAAmB;EAE1E,IAAI,MAAqB,QAAS,MAAW,MAAS,MAAoB,MACxE;EAGF,IAAM,IAA0C,EAAE,oBAAiB;EAsBnE,OApBI,MAAa,KAAA,MAAW,EAAa,WAAW,IAChD,MAAa,KAAA,MAAW,EAAa,WAAW,IAChD,MAAU,KAAA,MAAW,EAAa,QAAQ,IAC1C,MAAgB,KAAA,MAAW,EAAa,cAAc,IACtD,MAAyB,KAAA,MAAW,EAAa,uBAAuB,IACxE,MAAe,KAAA,MAAW,EAAa,aAAa,IACpD,MAAkB,KAAA,MAAW,EAAa,gBAAgB,IAC1D,MAAY,KAAA,MAAW,EAAa,UAAU,IAC9C,MAA0B,KAAA,MAC5B,EAAa,wBAAwB,IACnC,MAAyB,KAAA,MAAW,EAAa,uBAAuB,IACxE,MAAoB,KAAA,MAAW,EAAa,kBAAkB,IAE9D,MAAW,MAAS,KAAqD,SAC3E,EAAa,kBAAkB,GAC/B,EAAa,SAAS,IAGxB,EAAS,UAAU,EAAmB,CAAY,SAErC;GAEX,AADA,EAAS,SAAS,QAAQ,GAC1B,EAAS,UAAU;EACrB;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAGC,kBAAC,OAAD;EAAK,aAAU;EAAkB,WAAW,EAAG,CAAS;YAAxD,CACE,kBAAC,OAAD;GACE,KAAK;GACL,aAAU;GACV,WAAW,EAAG,CAAgB;EAC/B,CAAA,GACA,MAAW,KAAQ,OAClB,kBAAC,OAAD;GAAK,KAAK;GAAoB,aAAU;GAAkB,WAAW,EAAG,CAAe;EAAI,CAAA,CAE1F;;AAET;AAEA,EAAc,cAAc"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { AppShell, type AppShellProps } from './app-shell';
|
|
2
2
|
export { BrowserLayout, type BrowserLayoutProps } from './browser-layout';
|
|
3
|
+
export { CoreAppChrome, type CoreAppChromeMount, type CoreAppChromeProps, type CoreAppSidebarPresetOptions, type CoreAppTopbarPresetOptions, } from './core-app-chrome';
|
|
3
4
|
export { DetailHeader, type DetailHeaderProps } from './detail-header';
|
|
4
5
|
export { PageHeader, type PageHeaderProps } from './page-header';
|
|
5
6
|
export { SubNav, type SubNavItem, type SubNavProps } from './sub-nav';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AACrE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,GAChC,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AACrE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppShell as e } from "./app-shell.js";
|
|
2
2
|
import { i as t, n, r, t as i } from "../../layout-64M2la9A.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { CoreAppChrome as a } from "./core-app-chrome.js";
|
|
4
|
+
import { PageHeader as o } from "./page-header.js";
|
|
5
|
+
export { e as AppShell, t as BrowserLayout, a as CoreAppChrome, r as DetailHeader, i as PageFrame, o as PageHeader, n as SubNav };
|
package/dist/react.js
CHANGED
|
@@ -20,99 +20,100 @@ import "./react/hooks/index.js";
|
|
|
20
20
|
import { BrandLockup as Ne, ConnectorLogo as Pe, CounterMeasureBrandLockup as Fe, CounterMeasureLogo as Ie, CounterMeasureWordmark as Le, CountermeasureBrandLockup as Re, CountermeasureLogo as ze, CountermeasureWordmark as Be, Diamond as Ve, Wordmark as He } from "./react/brand.js";
|
|
21
21
|
import { AppShell as Ue } from "./react/layout/app-shell.js";
|
|
22
22
|
import { i as We, n as Ge, r as Ke, t as qe } from "./layout-64M2la9A.js";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import { t as Bt } from "./
|
|
34
|
-
import {
|
|
35
|
-
import { i as
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import { n as
|
|
49
|
-
import { t as Fn } from "./
|
|
50
|
-
import { t as In } from "./
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
-
import {
|
|
57
|
-
import {
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
61
|
-
import {
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
64
|
-
import {
|
|
65
|
-
import {
|
|
66
|
-
import {
|
|
67
|
-
import {
|
|
68
|
-
import {
|
|
69
|
-
import {
|
|
70
|
-
import {
|
|
71
|
-
import {
|
|
72
|
-
import {
|
|
73
|
-
import {
|
|
74
|
-
import {
|
|
75
|
-
import {
|
|
76
|
-
import {
|
|
77
|
-
import {
|
|
78
|
-
import {
|
|
79
|
-
import {
|
|
80
|
-
import {
|
|
81
|
-
import {
|
|
82
|
-
import {
|
|
83
|
-
import {
|
|
84
|
-
import {
|
|
85
|
-
import {
|
|
86
|
-
import {
|
|
87
|
-
import {
|
|
88
|
-
import {
|
|
89
|
-
import {
|
|
90
|
-
import {
|
|
91
|
-
import {
|
|
92
|
-
import {
|
|
93
|
-
import {
|
|
94
|
-
import {
|
|
95
|
-
import {
|
|
96
|
-
import {
|
|
97
|
-
import {
|
|
98
|
-
import {
|
|
99
|
-
import {
|
|
100
|
-
import {
|
|
101
|
-
import {
|
|
102
|
-
import {
|
|
103
|
-
import {
|
|
104
|
-
import {
|
|
105
|
-
import {
|
|
106
|
-
import {
|
|
107
|
-
import {
|
|
108
|
-
import {
|
|
109
|
-
import {
|
|
110
|
-
import {
|
|
111
|
-
import {
|
|
112
|
-
import {
|
|
113
|
-
import {
|
|
114
|
-
import {
|
|
115
|
-
import {
|
|
116
|
-
import {
|
|
117
|
-
import {
|
|
118
|
-
|
|
23
|
+
import { CoreAppChrome as Je } from "./react/layout/core-app-chrome.js";
|
|
24
|
+
import { PageHeader as Ye } from "./react/layout/page-header.js";
|
|
25
|
+
import { Badge as Xe, badgeVariants as Ze, severityBadge as Qe, statusBadge as $e } from "./react/primitives/badge.js";
|
|
26
|
+
import { Dialog as et, DialogClose as tt, DialogContent as nt, DialogDescription as rt, DialogFooter as it, DialogHeader as at, DialogOverlay as ot, DialogPortal as st, DialogTitle as ct, DialogTrigger as lt } from "./react/primitives/dialog.js";
|
|
27
|
+
import { a as ut, c as dt, d as ft, i as pt, l as mt, n as ht, o as gt, r as _t, s as vt, t as yt, u as bt } from "./alert-dialog-BGze9wyy.js";
|
|
28
|
+
import { Sheet as xt, SheetClose as St, SheetContent as Ct, SheetDescription as wt, SheetFooter as Tt, SheetHeader as Et, SheetOverlay as Dt, SheetPortal as Ot, SheetTitle as kt, SheetTrigger as At } from "./react/primitives/sheet.js";
|
|
29
|
+
import { a as jt, i as Mt, n as Nt, o as Pt, r as Ft, t as It } from "./dropdown-menu-B_FFd_Mm.js";
|
|
30
|
+
import { Input as Lt } from "./react/primitives/input.js";
|
|
31
|
+
import { Textarea as Rt } from "./react/primitives/textarea.js";
|
|
32
|
+
import { Checkbox as zt } from "./react/primitives/checkbox.js";
|
|
33
|
+
import { t as Bt } from "./label-BY4iF5od.js";
|
|
34
|
+
import { t as Vt } from "./switch-Cn_U9KJN.js";
|
|
35
|
+
import { a as Ht, c as Ut, i as Wt, l as Gt, n as Kt, o as qt, r as Jt, s as Yt, t as Xt, u as Zt } from "./select-C1sq2inY.js";
|
|
36
|
+
import { i as Qt, n as $t, r as en, t as tn } from "./tabs-5EFeoEID.js";
|
|
37
|
+
import { Skeleton as nn } from "./react/primitives/skeleton.js";
|
|
38
|
+
import { Collapsible as rn, CollapsibleContent as an, CollapsibleTrigger as on } from "./react/primitives/collapsible.js";
|
|
39
|
+
import { a as sn, i as cn, n as ln, r as un, t as dn } from "./tooltip-jbccdZ73.js";
|
|
40
|
+
import { SlidePanel as fn } from "./react/primitives/slide-panel.js";
|
|
41
|
+
import { HeatmapLegend as pn } from "./react/primitives/heatmap-legend.js";
|
|
42
|
+
import { HeatmapToolbar as mn } from "./react/primitives/heatmap-toolbar.js";
|
|
43
|
+
import { AnimatedCounter as hn, AnimatedPercentage as gn, AnimatedScore as _n } from "./react/primitives/animated-counter.js";
|
|
44
|
+
import { RippleContainer as vn, useRipple as yn } from "./react/primitives/ripple.js";
|
|
45
|
+
import { Field as bn } from "./react/primitives/field.js";
|
|
46
|
+
import { a as xn, c as Sn, i as Cn, l as wn, n as Tn, o as En, r as Dn, s as On, t as kn, u as An } from "./primitives-Cya96raJ.js";
|
|
47
|
+
import { Kbd as jn } from "./react/primitives/kbd.js";
|
|
48
|
+
import { n as Mn, t as Nn } from "./radio-group-DN8T45dA.js";
|
|
49
|
+
import { n as Pn, t as Fn } from "./scroll-area-C6KoFGKu.js";
|
|
50
|
+
import { t as In } from "./separator-Ti4x5X1W.js";
|
|
51
|
+
import { t as Ln } from "./slider-DCYaTI8V.js";
|
|
52
|
+
import { Spinner as Rn } from "./react/primitives/spinner.js";
|
|
53
|
+
import { i as zn, n as Bn, r as Vn, t as Hn } from "./toggle-BqCEqHr6.js";
|
|
54
|
+
import { Alert as Un, AlertDescription as Wn, AlertTitle as Gn, alertVariants as Kn } from "./react/primitives/alert.js";
|
|
55
|
+
import { AspectRatio as qn } from "./react/primitives/aspect-ratio.js";
|
|
56
|
+
import { Avatar as Jn, AvatarFallback as Yn, AvatarGroup as Xn, AvatarImage as Zn, avatarVariants as Qn } from "./react/primitives/avatar.js";
|
|
57
|
+
import { CodeBlock as $n } from "./react/primitives/code-block.js";
|
|
58
|
+
import { CodeViewer as er } from "./react/primitives/code-viewer.js";
|
|
59
|
+
import { EmptyState as tr } from "./react/primitives/empty-state.js";
|
|
60
|
+
import { HoverCard as nr, HoverCardContent as rr, HoverCardTrigger as ir } from "./react/primitives/hover-card.js";
|
|
61
|
+
import { MarkdownViewer as ar } from "./react/primitives/markdown-viewer.js";
|
|
62
|
+
import { NotificationCenter as or, NotificationCenterItem as sr } from "./react/primitives/notification-center.js";
|
|
63
|
+
import { Popover as cr, PopoverAnchor as lr, PopoverClose as ur, PopoverContent as dr, PopoverTrigger as fr } from "./react/primitives/popover.js";
|
|
64
|
+
import { SeverityIndicator as pr, severityVariants as mr } from "./react/primitives/severity-indicator.js";
|
|
65
|
+
import { StatCard as hr, trendVariants as gr } from "./react/primitives/stat-card.js";
|
|
66
|
+
import { StatusDot as _r } from "./react/primitives/status-dot.js";
|
|
67
|
+
import { Blockquote as vr, H1 as yr, H2 as br, H3 as xr, H4 as Sr, InlineCode as Cr, Large as wr, Lead as Tr, Muted as Er, P as Dr, Small as Or } from "./react/primitives/typography.js";
|
|
68
|
+
import { UptimeBar as kr } from "./react/primitives/uptime-bar.js";
|
|
69
|
+
import { ContextMenu as Ar, ContextMenuContent as jr, ContextMenuItem as Mr, ContextMenuLabel as Nr, ContextMenuSeparator as Pr, ContextMenuShortcut as Fr, ContextMenuTrigger as Ir } from "./react/primitives/context-menu.js";
|
|
70
|
+
import { CopyButton as Lr, copyButtonVariants as Rr } from "./react/primitives/copy-button.js";
|
|
71
|
+
import { DataTable as zr } from "./react/primitives/data-table.js";
|
|
72
|
+
import { Modal as Br, ModalBody as Vr, ModalClose as Hr, ModalContent as Ur, ModalDescription as Wr, ModalFooter as Gr, ModalHeader as Kr, ModalOverlay as qr, ModalTitle as Jr, ModalTrigger as Yr } from "./react/primitives/modal.js";
|
|
73
|
+
import { CommandPalette as Xr, Search as Zr } from "./react/primitives/search.js";
|
|
74
|
+
import { SplitPane as Qr } from "./react/primitives/split-pane.js";
|
|
75
|
+
import { StatusBar as $r, StatusBarItem as ei, StatusBarSection as ti, StatusBarSeparator as ni } from "./react/primitives/status-bar.js";
|
|
76
|
+
import { TreeItem as ri, TreeView as ii } from "./react/primitives/tree-view.js";
|
|
77
|
+
import { Breadcrumb as ai, BreadcrumbEllipsis as oi, BreadcrumbItem as si, BreadcrumbLink as ci, BreadcrumbList as li, BreadcrumbPage as ui, BreadcrumbSeparator as di } from "./react/primitives/breadcrumb.js";
|
|
78
|
+
import { Drawer as fi, DrawerClose as pi, DrawerContent as mi, DrawerDescription as hi, DrawerFooter as gi, DrawerHeader as _i, DrawerOverlay as vi, DrawerPortal as yi, DrawerTitle as bi, DrawerTrigger as xi } from "./react/primitives/drawer.js";
|
|
79
|
+
import { a as Si, c as Ci, i as wi, l as Ti, n as Ei, o as Di, r as Oi, s as ki, t as Ai } from "./navigation-menu-BO6a4SOI.js";
|
|
80
|
+
import { Stepper as ji, StepperItem as Mi } from "./react/primitives/stepper.js";
|
|
81
|
+
import { Calendar as Ni } from "./react/primitives/calendar.js";
|
|
82
|
+
import { ColorPicker as Pi } from "./react/primitives/color-picker.js";
|
|
83
|
+
import { CronEditor as Fi, cronToHuman as Ii, formatCron as Li, getNextRuns as Ri, isValidCron as zi, parseCron as Bi } from "./react/primitives/cron-editor.js";
|
|
84
|
+
import { DatePicker as Vi, DateRangePicker as Hi, DateTimePicker as Ui } from "./react/primitives/date-picker.js";
|
|
85
|
+
import { DirectionContext as Wi, DirectionProvider as Gi, useDirection as Ki } from "./react/primitives/direction.js";
|
|
86
|
+
import { TagInput as qi } from "./react/primitives/tag-input.js";
|
|
87
|
+
import { AreaChart as Ji } from "./react/primitives/chart-area.js";
|
|
88
|
+
import { BarChart as Yi } from "./react/primitives/chart-bar.js";
|
|
89
|
+
import { CandlestickChart as Xi } from "./react/primitives/chart-candlestick.js";
|
|
90
|
+
import { FunnelChart as Zi } from "./react/primitives/chart-funnel.js";
|
|
91
|
+
import { GaugeChart as Qi } from "./react/primitives/chart-gauge.js";
|
|
92
|
+
import { HeatmapChart as $i } from "./react/primitives/chart-heatmap.js";
|
|
93
|
+
import { LineChart as ea } from "./react/primitives/chart-line.js";
|
|
94
|
+
import { PieChart as ta } from "./react/primitives/chart-pie.js";
|
|
95
|
+
import { RadarChart as na } from "./react/primitives/chart-radar.js";
|
|
96
|
+
import { SankeyChart as ra } from "./react/primitives/chart-sankey.js";
|
|
97
|
+
import { ScatterChart as ia } from "./react/primitives/chart-scatter.js";
|
|
98
|
+
import { SparklineChart as aa } from "./react/primitives/chart-sparkline.js";
|
|
99
|
+
import { TreemapChart as oa } from "./react/primitives/chart-treemap.js";
|
|
100
|
+
import { WaterfallChart as sa } from "./react/primitives/chart-waterfall.js";
|
|
101
|
+
import { ErrorBoundary as ca } from "./react/primitives/error-boundary.js";
|
|
102
|
+
import { FileTree as la } from "./react/primitives/file-tree.js";
|
|
103
|
+
import { FlowDiagram as ua } from "./react/primitives/flow-diagram.js";
|
|
104
|
+
import { JsonPathBrowser as da } from "./react/primitives/json-path-browser.js";
|
|
105
|
+
import { KanbanBoard as fa, KanbanCard as pa, KanbanColumn as ma } from "./react/primitives/kanban.js";
|
|
106
|
+
import { Map as ha } from "./react/primitives/map.js";
|
|
107
|
+
import { MermaidDiagram as ga } from "./react/primitives/mermaid-diagram.js";
|
|
108
|
+
import { NetworkGraph as _a } from "./react/primitives/network-graph.js";
|
|
109
|
+
import { RuleEditor as va } from "./react/primitives/rule-editor.js";
|
|
110
|
+
import { Terminal as ya } from "./react/primitives/terminal.js";
|
|
111
|
+
import { Timeline as ba, TimelineItem as xa } from "./react/primitives/timeline.js";
|
|
112
|
+
import { AttackPath as Sa, AttackPathStep as Ca, stepVariants as wa } from "./react/primitives/attack-path.js";
|
|
113
|
+
import { CvssBadge as Ta, cvssBadgeVariants as Ea } from "./react/primitives/cvss-badge.js";
|
|
114
|
+
import { DetectionStatusBadge as Da, DetectionStatusList as Oa, DetectionStatusRow as ka, severityBadgeVariants as Aa, statusDotVariants as ja, statusLabelVariants as Ma } from "./react/primitives/detection-status.js";
|
|
115
|
+
import { MitreMatrix as Na, techniqueVariants as Pa } from "./react/primitives/mitre-matrix.js";
|
|
116
|
+
import { VulnerabilityCard as Fa, severityBadgeVariants as Ia, statusBadgeVariants as La } from "./react/primitives/vulnerability-card.js";
|
|
117
|
+
import { FlowNodeCard as Ra, MetricTile as za, StatCard as Ba, UptimeBar as Va } from "./react/threat-visuals.js";
|
|
118
|
+
import { ThemeStudio as Ha } from "./react/theme-studio.js";
|
|
119
|
+
export { Un as Alert, Wn as AlertDescription, yt as AlertDialog, ht as AlertDialogAction, _t as AlertDialogCancel, pt as AlertDialogContent, ut as AlertDialogDescription, gt as AlertDialogFooter, vt as AlertDialogHeader, dt as AlertDialogOverlay, mt as AlertDialogPortal, bt as AlertDialogTitle, ft as AlertDialogTrigger, Gn as AlertTitle, hn as AnimatedCounter, z as AnimatedEdge, gn as AnimatedPercentage, _n as AnimatedScore, Ue as AppShell, Ji as AreaChart, qn as AspectRatio, J as AtomicRedTeamLogo, Sa as AttackPath, Ca as AttackPathStep, Jn as Avatar, Yn as AvatarFallback, Xn as AvatarGroup, Zn as AvatarImage, Xe as Badge, Yi as BarChart, vr as Blockquote, Ne as BrandLockup, ai as Breadcrumb, oi as BreadcrumbEllipsis, si as BreadcrumbItem, ci as BreadcrumbLink, li as BreadcrumbList, ui as BreadcrumbPage, di as BreadcrumbSeparator, We as BrowserLayout, Ce as Button, Ni as Calendar, Xi as CandlestickChart, le as Card, ue as CardBody, de as CardHeader, fe as CardTitle, a as Carousel, n as CarouselContent, i as CarouselItem, t as CarouselNext, e as CarouselPrevious, Tn as ChartFrame, Cn as ChatDrawer, Dn as ChatInput, zt as Checkbox, F as ChronicleLogo, pe as CircularProgress, $n as CodeBlock, er as CodeViewer, rn as Collapsible, an as CollapsibleContent, on as CollapsibleTrigger, Pi as ColorPicker, Xr as CommandPalette, Pe as ConnectorLogo, M as ConnectorNode, Ar as ContextMenu, jr as ContextMenuContent, Mr as ContextMenuItem, Nr as ContextMenuLabel, Pr as ContextMenuSeparator, Fr as ContextMenuShortcut, Ir as ContextMenuTrigger, Lr as CopyButton, Je as CoreAppChrome, Fe as CounterMeasureBrandLockup, Ie as CounterMeasureLogo, Le as CounterMeasureWordmark, Re as CountermeasureBrandLockup, ze as CountermeasureLogo, Be as CountermeasureWordmark, Fi as CronEditor, I as CrowdStrikeLogo, Ta as CvssBadge, xn as DashboardMetricCard, wn as DataField, zr as DataTable, Vi as DatePicker, Hi as DateRangePicker, Ui as DateTimePicker, W as DefaultConnectorLogo, Ke as DetailHeader, Da as DetectionStatusBadge, Oa as DetectionStatusList, ka as DetectionStatusRow, et as Dialog, tt as DialogClose, nt as DialogContent, rt as DialogDescription, it as DialogFooter, at as DialogHeader, ot as DialogOverlay, st as DialogPortal, ct as DialogTitle, lt as DialogTrigger, Ve as Diamond, Wi as DirectionContext, Gi as DirectionProvider, fi as Drawer, pi as DrawerClose, mi as DrawerContent, hi as DrawerDescription, gi as DrawerFooter, _i as DrawerHeader, vi as DrawerOverlay, yi as DrawerPortal, bi as DrawerTitle, xi as DrawerTrigger, It as DropdownMenu, Nt as DropdownMenuContent, Ft as DropdownMenuItem, Mt as DropdownMenuLabel, jt as DropdownMenuSeparator, Pt as DropdownMenuTrigger, V as ElasticLogo, tr as EmptyState, ca as ErrorBoundary, bn as Field, la as FileTree, ua as FlowDiagram, Ra as FlowNodeCard, Zi as FunnelChart, Qi as GaugeChart, yr as H1, br as H2, xr as H3, Sr as H4, $i as HeatmapChart, pn as HeatmapLegend, mn as HeatmapToolbar, nr as HoverCard, rr as HoverCardContent, ir as HoverCardTrigger, Cr as InlineCode, Lt as Input, da as JsonPathBrowser, fa as KanbanBoard, pa as KanbanCard, ma as KanbanColumn, jn as Kbd, Bt as Label, wr as Large, Tr as Lead, U as LibraryNode, ea as LineChart, ha as Map, ar as MarkdownViewer, D as Menubar, S as MenubarCheckboxItem, T as MenubarContent, y as MenubarGroup, p as MenubarItem, C as MenubarLabel, E as MenubarMenu, m as MenubarPortal, b as MenubarRadioGroup, O as MenubarRadioItem, h as MenubarSeparator, g as MenubarShortcut, w as MenubarSub, x as MenubarSubContent, v as MenubarSubTrigger, _ as MenubarTrigger, ga as MermaidDiagram, An as MetadataGrid, za as MetricTile, R as MitreLogo, Na as MitreMatrix, Br as Modal, Vr as ModalBody, Hr as ModalClose, Ur as ModalContent, Wr as ModalDescription, Gr as ModalFooter, Kr as ModalHeader, qr as ModalOverlay, Jr as ModalTitle, Yr as ModalTrigger, Er as Muted, Ai as NavigationMenu, Ei as NavigationMenuContent, Oi as NavigationMenuIndicator, wi as NavigationMenuItem, Si as NavigationMenuLink, Di as NavigationMenuList, ki as NavigationMenuTrigger, Ci as NavigationMenuViewport, _a as NetworkGraph, or as NotificationCenter, sr as NotificationCenterItem, L as OpenCTILogo, Dr as P, qe as PageFrame, Ye as PageHeader, f as Pagination, c as PaginationContent, u as PaginationEllipsis, s as PaginationItem, o as PaginationLink, l as PaginationNext, d as PaginationPrevious, ta as PieChart, K as PlatformNode, cr as Popover, lr as PopoverAnchor, ur as PopoverClose, dr as PopoverContent, fr as PopoverTrigger, me as Progress, kn as QueryBoundary, na as RadarChart, Nn as RadioGroup, Mn as RadioGroupItem, vn as RippleContainer, va as RuleEditor, ra as SankeyChart, ia as ScatterChart, On as ScoreRing, Fn as ScrollArea, Pn as ScrollBar, Zr as Search, Sn as SectionPanel, Xt as Select, Kt as SelectContent, Jt as SelectGroup, Wt as SelectItem, Ht as SelectLabel, qt as SelectScrollDownButton, Yt as SelectScrollUpButton, Ut as SelectSeparator, Gt as SelectTrigger, Zt as SelectValue, j as SentinelLogo, In as Separator, pr as SeverityIndicator, xt as Sheet, St as SheetClose, Ct as SheetContent, wt as SheetDescription, Tt as SheetFooter, Et as SheetHeader, Dt as SheetOverlay, Ot as SheetPortal, kt as SheetTitle, At as SheetTrigger, Y as SigmaLogo, nn as Skeleton, fn as SlidePanel, Ln as Slider, Or as Small, Z as SnortLogo, P as SourceNode, aa as SparklineChart, Rn as Spinner, Qr as SplitPane, N as SplunkLogo, hr as StatCard, $r as StatusBar, ei as StatusBarItem, ti as StatusBarSection, ni as StatusBarSeparator, _r as StatusDot, ji as Stepper, Mi as StepperItem, Ge as SubNav, Vt as Switch, q as TOPOLOGY_STYLES, he as Table, ge as TableBody, _e as TableCaption, ve as TableCell, ye as TableFooter, be as TableHead, xe as TableHeader, Se as TableRow, tn as Tabs, $t as TabsContent, en as TabsList, Qt as TabsTrigger, qi as TagInput, X as TaniumLogo, B as TenantNode, ya as Terminal, Rt as Textarea, ce as ThemeIcon, Ha as ThemeStudioReact, oe as ThemeToggleButton, Ba as ThreatStatCard, Va as ThreatUptimeBar, ba as Timeline, xa as TimelineItem, ae as Toast, te as ToastAction, re as ToastClose, ee as ToastDescription, Q as ToastProvider, ne as ToastTitle, Hn as Toggle, Bn as ToggleGroup, Vn as ToggleGroupItem, dn as Tooltip, ln as TooltipArrow, un as TooltipContent, cn as TooltipProvider, sn as TooltipTrigger, ri as TreeItem, ii as TreeView, oa as TreemapChart, kr as UptimeBar, Fa as VulnerabilityCard, sa as WaterfallChart, He as Wordmark, A as YaraLogo, Kn as alertVariants, Qn as avatarVariants, Ze as badgeVariants, H as buildGlobalPipeline, G as buildPipelineForTenant, we as buttonVariants, Rr as copyButtonVariants, Ii as cronToHuman, Ea as cvssBadgeVariants, Li as formatCron, k as getConnectorLogo, Ri as getNextRuns, zi as isValidCron, En as metricIconVariants, Ti as navigationMenuTriggerStyle, Bi as parseCron, Qe as severityBadge, Aa as severityBadgeVariants, mr as severityVariants, $e as statusBadge, ja as statusDotVariants, Ma as statusLabelVariants, wa as stepVariants, Pa as techniqueVariants, ie as toastVariants, zn as toggleVariants, gr as trendVariants, Te as useApi, Ae as useAuth, r as useCarousel, Me as useConsent, Ki as useDirection, De as useKeybindings, je as usePasskey, yn as useRipple, Oe as useRouter, Ee as useSSE, ke as useStorage, se as useThemeState, $ as useToast, Ia as vulnSeverityBadgeVariants, La as vulnStatusBadgeVariants };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@countermeasure-platform/web-components",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.5-dev.36.1",
|
|
4
4
|
"description": "Shared web components for CounterMeasure applications - consolidates common frontend functionality across projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -1520,6 +1520,11 @@
|
|
|
1520
1520
|
"import": "./dist/react/layout/app-shell.js",
|
|
1521
1521
|
"types": "./dist/react/layout/app-shell.d.ts"
|
|
1522
1522
|
},
|
|
1523
|
+
"./react/layout/core-app-chrome": {
|
|
1524
|
+
"source": "./src/react/layout/core-app-chrome.tsx",
|
|
1525
|
+
"import": "./dist/react/layout/core-app-chrome.js",
|
|
1526
|
+
"types": "./dist/react/layout/core-app-chrome.d.ts"
|
|
1527
|
+
},
|
|
1523
1528
|
"./react/layout/page-header": {
|
|
1524
1529
|
"source": "./src/react/layout/page-header.tsx",
|
|
1525
1530
|
"import": "./dist/react/layout/page-header.js",
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { render } from '@testing-library/react'
|
|
2
|
+
import { describe, expect, it, beforeEach } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { CoreAppChrome } from './core-app-chrome'
|
|
5
|
+
|
|
6
|
+
describe('CoreAppChrome React wrapper', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
localStorage.clear()
|
|
9
|
+
window.history.replaceState({}, '', '/app')
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('mounts the vanilla native core chrome inside React host elements', () => {
|
|
13
|
+
const { container } = render(
|
|
14
|
+
<CoreAppChrome
|
|
15
|
+
basePath="/app"
|
|
16
|
+
pathname="/app/jobs"
|
|
17
|
+
scope={{
|
|
18
|
+
label: 'Tenant',
|
|
19
|
+
value: 'all',
|
|
20
|
+
options: [{ id: 'all', label: 'All Tenants' }],
|
|
21
|
+
}}
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
const sidebar = container.querySelector<HTMLElement>('.sidebar')
|
|
26
|
+
const topbar = container.querySelector<HTMLElement>('.cmm-topbar')
|
|
27
|
+
const active = container.querySelector<HTMLElement>('[data-item-id="jobs"]')
|
|
28
|
+
|
|
29
|
+
expect(container.querySelector('[data-slot="core-app-chrome"]')).toBeTruthy()
|
|
30
|
+
expect(sidebar?.classList.contains('sidebar--product')).toBe(true)
|
|
31
|
+
expect(sidebar?.getAttribute('data-sidebar')).toBe('cm')
|
|
32
|
+
expect(active?.classList.contains('sidebar__item--active')).toBe(true)
|
|
33
|
+
expect(topbar?.querySelector('.cmm-topbar__product')?.textContent).toBe('CounterMeasure Core')
|
|
34
|
+
expect(topbar?.querySelector('.cmm-topbar__current')?.textContent).toBe('Jobs')
|
|
35
|
+
expect(container.querySelector('.sidebar__scope-current')?.textContent).toBe('All Tenants')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('remounts through the vanilla API when route props change', () => {
|
|
39
|
+
const { container, rerender } = render(<CoreAppChrome basePath="/app" pathname="/app/jobs" />)
|
|
40
|
+
|
|
41
|
+
expect(container.querySelector('.cmm-topbar__current')?.textContent).toBe('Jobs')
|
|
42
|
+
expect(
|
|
43
|
+
container.querySelector('[data-item-id="jobs"]')?.classList.contains('sidebar__item--active')
|
|
44
|
+
).toBe(true)
|
|
45
|
+
|
|
46
|
+
rerender(<CoreAppChrome basePath="/app" pathname="/app/runners" />)
|
|
47
|
+
|
|
48
|
+
expect(container.querySelector('.cmm-topbar__current')?.textContent).toBe('Runners')
|
|
49
|
+
expect(
|
|
50
|
+
container
|
|
51
|
+
.querySelector('[data-item-id="runners"]')
|
|
52
|
+
?.classList.contains('sidebar__item--active')
|
|
53
|
+
).toBe(true)
|
|
54
|
+
expect(container.querySelectorAll('.sidebar')).toHaveLength(1)
|
|
55
|
+
expect(container.querySelectorAll('.cmm-topbar')).toHaveLength(1)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('supports sidebar-only mounts and host class names', () => {
|
|
59
|
+
const { container } = render(
|
|
60
|
+
<CoreAppChrome
|
|
61
|
+
className="chrome-host"
|
|
62
|
+
sidebarClassName="sidebar-host"
|
|
63
|
+
topbar={false}
|
|
64
|
+
basePath="/app"
|
|
65
|
+
pathname="/app"
|
|
66
|
+
/>
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
expect(
|
|
70
|
+
container.querySelector('[data-slot="core-app-chrome"]')?.classList.contains('chrome-host')
|
|
71
|
+
).toBe(true)
|
|
72
|
+
expect(
|
|
73
|
+
container.querySelector('[data-slot="core-app-sidebar"]')?.classList.contains('sidebar-host')
|
|
74
|
+
).toBe(true)
|
|
75
|
+
expect(container.querySelector('.sidebar')).toBeTruthy()
|
|
76
|
+
expect(container.querySelector('.cmm-topbar')).toBeNull()
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('passes custom vanilla mount options through without duplicating behavior in React', () => {
|
|
80
|
+
const customAction = {
|
|
81
|
+
id: 'custom',
|
|
82
|
+
label: 'Custom Action',
|
|
83
|
+
attributes: { 'data-custom-action': true },
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const { container } = render(
|
|
87
|
+
<CoreAppChrome
|
|
88
|
+
basePath="/app"
|
|
89
|
+
pathname="/app/custom"
|
|
90
|
+
preserveTopbarActions={false}
|
|
91
|
+
topbarActionSelector="[data-preserve-me]"
|
|
92
|
+
clearContainers={false}
|
|
93
|
+
sidebar={{
|
|
94
|
+
sections: [
|
|
95
|
+
{
|
|
96
|
+
id: 'custom',
|
|
97
|
+
items: [{ id: 'custom-item', label: 'Custom Item', href: '/app/custom' }],
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
activeItemId: 'custom-item',
|
|
101
|
+
collapsible: false,
|
|
102
|
+
mobileBackdrop: false,
|
|
103
|
+
}}
|
|
104
|
+
topbar={{
|
|
105
|
+
product: 'Core React',
|
|
106
|
+
current: 'Custom Current',
|
|
107
|
+
actions: [customAction],
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
expect(container.querySelector('[data-item-id="custom-item"]')?.textContent).toContain(
|
|
113
|
+
'Custom Item'
|
|
114
|
+
)
|
|
115
|
+
expect(
|
|
116
|
+
container
|
|
117
|
+
.querySelector('[data-item-id="custom-item"]')
|
|
118
|
+
?.classList.contains('sidebar__item--active')
|
|
119
|
+
).toBe(true)
|
|
120
|
+
expect(container.querySelector('.cmm-topbar__product')?.textContent).toBe('Core React')
|
|
121
|
+
expect(container.querySelector('.cmm-topbar__current')?.textContent).toBe('Custom Current')
|
|
122
|
+
expect(container.querySelector('[data-custom-action]')).toBeTruthy()
|
|
123
|
+
})
|
|
124
|
+
})
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
mountCoreAppChrome,
|
|
5
|
+
type CoreAppChromeMount,
|
|
6
|
+
type CoreAppChromeMountOptions,
|
|
7
|
+
type CoreAppSidebarPresetOptions,
|
|
8
|
+
type CoreAppTopbarPresetOptions,
|
|
9
|
+
} from '../../layout/core-app-chrome'
|
|
10
|
+
import { cn } from '../primitives/utils'
|
|
11
|
+
|
|
12
|
+
export interface CoreAppChromeProps extends Omit<
|
|
13
|
+
CoreAppChromeMountOptions,
|
|
14
|
+
'sidebarContainer' | 'topbarContainer' | 'topbar'
|
|
15
|
+
> {
|
|
16
|
+
className?: string
|
|
17
|
+
sidebarClassName?: string
|
|
18
|
+
topbarClassName?: string
|
|
19
|
+
topbar?: Omit<CoreAppTopbarPresetOptions, 'container'> | false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type { CoreAppChromeMount, CoreAppSidebarPresetOptions, CoreAppTopbarPresetOptions }
|
|
23
|
+
|
|
24
|
+
function CoreAppChrome({
|
|
25
|
+
className,
|
|
26
|
+
sidebarClassName,
|
|
27
|
+
topbarClassName,
|
|
28
|
+
basePath,
|
|
29
|
+
pathname,
|
|
30
|
+
scope,
|
|
31
|
+
sidebarUser,
|
|
32
|
+
sidebarFooterActions,
|
|
33
|
+
topbarUser,
|
|
34
|
+
topbarActions,
|
|
35
|
+
sidebar,
|
|
36
|
+
topbar = {},
|
|
37
|
+
preserveTopbarActions,
|
|
38
|
+
topbarActionSelector,
|
|
39
|
+
clearContainers,
|
|
40
|
+
}: CoreAppChromeProps) {
|
|
41
|
+
const sidebarContainerRef = React.useRef<HTMLDivElement>(null)
|
|
42
|
+
const topbarContainerRef = React.useRef<HTMLDivElement>(null)
|
|
43
|
+
const mountRef = React.useRef<CoreAppChromeMount | null>(null)
|
|
44
|
+
|
|
45
|
+
React.useEffect(() => {
|
|
46
|
+
const sidebarContainer = sidebarContainerRef.current
|
|
47
|
+
const topbarContainer = topbar === false ? undefined : topbarContainerRef.current
|
|
48
|
+
|
|
49
|
+
if (sidebarContainer === null || (topbar !== false && topbarContainer === null)) {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const mountOptions: CoreAppChromeMountOptions = { sidebarContainer }
|
|
54
|
+
|
|
55
|
+
if (basePath !== undefined) mountOptions.basePath = basePath
|
|
56
|
+
if (pathname !== undefined) mountOptions.pathname = pathname
|
|
57
|
+
if (scope !== undefined) mountOptions.scope = scope
|
|
58
|
+
if (sidebarUser !== undefined) mountOptions.sidebarUser = sidebarUser
|
|
59
|
+
if (sidebarFooterActions !== undefined) mountOptions.sidebarFooterActions = sidebarFooterActions
|
|
60
|
+
if (topbarUser !== undefined) mountOptions.topbarUser = topbarUser
|
|
61
|
+
if (topbarActions !== undefined) mountOptions.topbarActions = topbarActions
|
|
62
|
+
if (sidebar !== undefined) mountOptions.sidebar = sidebar
|
|
63
|
+
if (preserveTopbarActions !== undefined)
|
|
64
|
+
mountOptions.preserveTopbarActions = preserveTopbarActions
|
|
65
|
+
if (topbarActionSelector !== undefined) mountOptions.topbarActionSelector = topbarActionSelector
|
|
66
|
+
if (clearContainers !== undefined) mountOptions.clearContainers = clearContainers
|
|
67
|
+
|
|
68
|
+
if (topbar !== false && topbarContainer !== undefined && topbarContainer !== null) {
|
|
69
|
+
mountOptions.topbarContainer = topbarContainer
|
|
70
|
+
mountOptions.topbar = topbar
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
mountRef.current = mountCoreAppChrome(mountOptions)
|
|
74
|
+
|
|
75
|
+
return () => {
|
|
76
|
+
mountRef.current?.destroy()
|
|
77
|
+
mountRef.current = null
|
|
78
|
+
}
|
|
79
|
+
}, [
|
|
80
|
+
basePath,
|
|
81
|
+
pathname,
|
|
82
|
+
scope,
|
|
83
|
+
sidebarUser,
|
|
84
|
+
sidebarFooterActions,
|
|
85
|
+
topbarUser,
|
|
86
|
+
topbarActions,
|
|
87
|
+
sidebar,
|
|
88
|
+
topbar,
|
|
89
|
+
preserveTopbarActions,
|
|
90
|
+
topbarActionSelector,
|
|
91
|
+
clearContainers,
|
|
92
|
+
])
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div data-slot="core-app-chrome" className={cn(className)}>
|
|
96
|
+
<div
|
|
97
|
+
ref={sidebarContainerRef}
|
|
98
|
+
data-slot="core-app-sidebar"
|
|
99
|
+
className={cn(sidebarClassName)}
|
|
100
|
+
/>
|
|
101
|
+
{topbar === false ? null : (
|
|
102
|
+
<div ref={topbarContainerRef} data-slot="core-app-topbar" className={cn(topbarClassName)} />
|
|
103
|
+
)}
|
|
104
|
+
</div>
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
CoreAppChrome.displayName = 'CoreAppChrome'
|
|
109
|
+
|
|
110
|
+
export { CoreAppChrome }
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
export { AppShell, type AppShellProps } from './app-shell'
|
|
2
2
|
export { BrowserLayout, type BrowserLayoutProps } from './browser-layout'
|
|
3
|
+
export {
|
|
4
|
+
CoreAppChrome,
|
|
5
|
+
type CoreAppChromeMount,
|
|
6
|
+
type CoreAppChromeProps,
|
|
7
|
+
type CoreAppSidebarPresetOptions,
|
|
8
|
+
type CoreAppTopbarPresetOptions,
|
|
9
|
+
} from './core-app-chrome'
|
|
3
10
|
export { DetailHeader, type DetailHeaderProps } from './detail-header'
|
|
4
11
|
export { PageHeader, type PageHeaderProps } from './page-header'
|
|
5
12
|
export { SubNav, type SubNavItem, type SubNavProps } from './sub-nav'
|