@treasuryspatial/viewer-ui-kit 0.1.42 → 0.1.56
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/AdminLayout.js +1 -1
- package/dist/AdminShell.d.ts +6 -1
- package/dist/AdminShell.d.ts.map +1 -1
- package/dist/AdminShell.js +45 -3
- package/dist/ChooserActionCard.d.ts +10 -0
- package/dist/ChooserActionCard.d.ts.map +1 -0
- package/dist/ChooserActionCard.js +39 -0
- package/dist/ComposerRightRail.d.ts +3 -1
- package/dist/ComposerRightRail.d.ts.map +1 -1
- package/dist/ComposerRightRail.js +11 -43
- package/dist/ConfiguratorShell.js +1 -1
- package/dist/LandingShell.d.ts +2 -1
- package/dist/LandingShell.d.ts.map +1 -1
- package/dist/LandingShell.js +133 -33
- package/dist/LoginShell.d.ts +2 -1
- package/dist/LoginShell.d.ts.map +1 -1
- package/dist/LoginShell.js +26 -3
- package/dist/ManifestTopBar.d.ts +7 -1
- package/dist/ManifestTopBar.d.ts.map +1 -1
- package/dist/ManifestTopBar.js +249 -38
- package/dist/MetricsPanel.d.ts +1 -1
- package/dist/MetricsPanel.d.ts.map +1 -1
- package/dist/MetricsPanel.js +19 -29
- package/dist/MetricsPanelContent.d.ts +38 -17
- package/dist/MetricsPanelContent.d.ts.map +1 -1
- package/dist/MetricsPanelContent.js +84 -90
- package/dist/ModeBar.d.ts +6 -2
- package/dist/ModeBar.d.ts.map +1 -1
- package/dist/ModeBar.js +49 -82
- package/dist/ModuleSelectorPanel.d.ts +2 -1
- package/dist/ModuleSelectorPanel.d.ts.map +1 -1
- package/dist/ModuleSelectorPanel.js +47 -49
- package/dist/PanelSkin.d.ts.map +1 -1
- package/dist/PanelSkin.js +1598 -312
- package/dist/PanelSystem.d.ts +45 -0
- package/dist/PanelSystem.d.ts.map +1 -0
- package/dist/PanelSystem.js +450 -0
- package/dist/PanelTabs.d.ts.map +1 -1
- package/dist/PanelTabs.js +8 -34
- package/dist/PanelToggleDock.d.ts +10 -0
- package/dist/PanelToggleDock.d.ts.map +1 -0
- package/dist/PanelToggleDock.js +40 -0
- package/dist/PromptPackChooserPanel.d.ts +12 -11
- package/dist/PromptPackChooserPanel.d.ts.map +1 -1
- package/dist/PromptPackChooserPanel.js +103 -63
- package/dist/SceneInspectorPanel.d.ts +42 -0
- package/dist/SceneInspectorPanel.d.ts.map +1 -0
- package/dist/SceneInspectorPanel.js +135 -0
- package/dist/ScienceDataPanelContent.d.ts +16 -0
- package/dist/ScienceDataPanelContent.d.ts.map +1 -0
- package/dist/ScienceDataPanelContent.js +31 -0
- package/dist/ScienceMetricsPanelContent.d.ts +53 -0
- package/dist/ScienceMetricsPanelContent.d.ts.map +1 -0
- package/dist/ScienceMetricsPanelContent.js +415 -0
- package/dist/SpatialHud.d.ts +18 -0
- package/dist/SpatialHud.d.ts.map +1 -0
- package/dist/SpatialHud.js +120 -0
- package/dist/StreetviewModeSurface.d.ts +40 -0
- package/dist/StreetviewModeSurface.d.ts.map +1 -0
- package/dist/StreetviewModeSurface.js +358 -0
- package/dist/SurfaceSwitcher.d.ts +11 -0
- package/dist/SurfaceSwitcher.d.ts.map +1 -0
- package/dist/SurfaceSwitcher.js +46 -0
- package/dist/TopBar.d.ts +2 -0
- package/dist/TopBar.d.ts.map +1 -1
- package/dist/TopBar.js +3 -1
- package/dist/UnknownModeSurface.d.ts +6 -0
- package/dist/UnknownModeSurface.d.ts.map +1 -0
- package/dist/UnknownModeSurface.js +41 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/landingTokens.d.ts +7 -0
- package/dist/landingTokens.d.ts.map +1 -0
- package/dist/landingTokens.js +6 -0
- package/dist/layout.d.ts +27 -27
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +33 -27
- package/dist/mapMetrics.d.ts +88 -0
- package/dist/mapMetrics.d.ts.map +1 -0
- package/dist/mapMetrics.js +1 -0
- package/dist/panelPrimitives.d.ts +11 -0
- package/dist/panelPrimitives.d.ts.map +1 -0
- package/dist/panelPrimitives.js +41 -0
- package/dist/topbarLogoPolicy.d.ts +14 -0
- package/dist/topbarLogoPolicy.d.ts.map +1 -0
- package/dist/topbarLogoPolicy.js +41 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -5
|
@@ -1,97 +1,91 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import styled from 'styled-components';
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
gap: 18px;
|
|
4
|
+
const Root = styled.div.attrs({ className: 'viewer-ui-panel-sections' }) ``;
|
|
5
|
+
const Section = styled.section.attrs({ className: 'panel-section' }) ``;
|
|
6
|
+
const SectionHeader = styled.div.attrs({ className: 'panel-section-header' }) ``;
|
|
7
|
+
const SectionHeaderCopy = styled.div `
|
|
8
|
+
min-width: 0;
|
|
10
9
|
`;
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
`;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
},
|
|
10
|
+
const SectionList = styled.div.attrs({ className: 'panel-section-list' }) ``;
|
|
11
|
+
const MetricRow = styled.div.attrs({ className: 'panel-section-row' }) ``;
|
|
12
|
+
const MetricMeta = styled.div.attrs({ className: 'panel-section-row-copy' }) ``;
|
|
13
|
+
const MetricLabel = styled.span.attrs({ className: 'panel-section-row-label' }) ``;
|
|
14
|
+
const MetricHelp = styled.span.attrs({ className: 'panel-section-row-help' }) ``;
|
|
15
|
+
const MetricValue = styled.span.attrs({ className: 'panel-section-row-value' }) ``;
|
|
16
|
+
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
17
|
+
const resolvePathValue = (root, path) => {
|
|
18
|
+
if (!root || !path.trim())
|
|
19
|
+
return null;
|
|
20
|
+
const parts = path.split('.').map((part) => part.trim()).filter(Boolean);
|
|
21
|
+
let current = root;
|
|
22
|
+
for (const part of parts) {
|
|
23
|
+
if (!isRecord(current))
|
|
24
|
+
return null;
|
|
25
|
+
current = current[part];
|
|
26
|
+
}
|
|
27
|
+
return current ?? null;
|
|
28
|
+
};
|
|
29
|
+
const formatMetricValue = (metric, value) => {
|
|
30
|
+
if (value === null || value === undefined || value === '') {
|
|
31
|
+
return metric.emptyLabel?.trim() || 'not emitted';
|
|
32
|
+
}
|
|
33
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
34
|
+
if (metric.prefix === '$') {
|
|
35
|
+
const digits = metric.digits ?? 0;
|
|
36
|
+
return new Intl.NumberFormat('en-US', {
|
|
37
|
+
style: 'currency',
|
|
38
|
+
currency: 'USD',
|
|
39
|
+
minimumFractionDigits: digits,
|
|
40
|
+
maximumFractionDigits: digits,
|
|
41
|
+
}).format(value);
|
|
42
|
+
}
|
|
43
|
+
if (metric.format === 'count') {
|
|
44
|
+
return `${metric.prefix ?? ''}${Math.round(value)}${metric.suffix ?? ''}`;
|
|
45
|
+
}
|
|
46
|
+
const digits = metric.digits ?? (Number.isInteger(value) ? 0 : 2);
|
|
47
|
+
return `${metric.prefix ?? ''}${value.toFixed(digits)}${metric.suffix ?? ''}`;
|
|
48
|
+
}
|
|
49
|
+
if (typeof value === 'boolean') {
|
|
50
|
+
return value ? `${metric.prefix ?? ''}yes${metric.suffix ?? ''}` : `${metric.prefix ?? ''}no${metric.suffix ?? ''}`;
|
|
51
|
+
}
|
|
52
|
+
return `${metric.prefix ?? ''}${String(value)}${metric.suffix ?? ''}`;
|
|
53
|
+
};
|
|
54
|
+
export default function MetricsPanelContent({ modeId, modeLabel, moduleLabel, moduleSummary, promptPackLabel, promptPackDescription, renderCount = 0, imageSetCount = 0, toolMetrics, feeds, }) {
|
|
55
|
+
const supportsDerivedMetrics = modeId === 'design' || modeId === 'map' || modeId === 'streetmix' || modeId === 'streetview';
|
|
56
|
+
const manifestGroups = Array.isArray(toolMetrics?.groups) ? toolMetrics.groups : [];
|
|
57
|
+
const hasManifestMetrics = manifestGroups.length > 0;
|
|
58
|
+
const runtimeFeed = isRecord(feeds?.runtime) ? feeds.runtime : null;
|
|
59
|
+
const mapFeed = isRecord(feeds?.map) ? feeds.map : null;
|
|
60
|
+
const mapMetrics = mapFeed ? feeds?.map : null;
|
|
61
|
+
const hasMapFeed = Boolean(mapFeed && Object.keys(mapFeed).length > 0);
|
|
62
|
+
const manifestUsesMapFeed = manifestGroups.some((group) => Array.isArray(group.metrics) ? group.metrics.some((metric) => metric.source.kind === 'map') : false);
|
|
63
|
+
const mapMetricsSourceLabel = hasMapFeed && mapMetrics?.source?.trim() ? mapMetrics.source.trim() : 'derived';
|
|
64
|
+
const eyebrowLabel = hasManifestMetrics
|
|
65
|
+
? 'manifest-driven feeds'
|
|
66
|
+
: modeId === 'map' && hasMapFeed
|
|
67
|
+
? 'runtime + map feed'
|
|
68
|
+
: 'runtime context only';
|
|
69
|
+
const runtimeRows = [
|
|
70
|
+
{ label: 'mode', value: modeLabel },
|
|
71
|
+
{ label: 'module', value: moduleLabel?.trim() || 'none' },
|
|
72
|
+
{ label: 'prompt system', value: promptPackLabel?.trim() || 'default' },
|
|
73
|
+
{ label: 'renders', value: `${renderCount}` },
|
|
74
|
+
{ label: 'image sets', value: `${imageSetCount}` },
|
|
74
75
|
{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
{ label: 'east', value: formatMeters(distanceToEast) },
|
|
82
|
-
{ label: 'west', value: formatMeters(distanceToWest) },
|
|
83
|
-
],
|
|
76
|
+
label: 'geometry status',
|
|
77
|
+
value: typeof runtimeFeed?.geometryStatus === 'string' && runtimeFeed.geometryStatus.trim()
|
|
78
|
+
? runtimeFeed.geometryStatus
|
|
79
|
+
: modeId === 'imagine'
|
|
80
|
+
? 'blank canvas'
|
|
81
|
+
: 'idle',
|
|
84
82
|
},
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
: null,
|
|
95
|
-
].filter(Boolean);
|
|
96
|
-
return (_jsxs(Root, { children: [_jsxs(Header, { children: [_jsx(Title, { children: "viewer metrics" }), _jsx(Eyebrow, { children: "live scene telemetry" })] }), _jsx("div", { children: sections.map((section) => (_jsxs(Section, { children: [_jsx(SectionTitle, { children: section.title }), section.metrics.map((metric) => (_jsxs(MetricRow, { children: [_jsx(MetricLabel, { children: metric.label }), _jsx(MetricValue, { children: metric.value })] }, metric.label)))] }, section.title))) })] }));
|
|
83
|
+
];
|
|
84
|
+
return (_jsxs(Root, { children: [_jsx(Section, { "data-panel-id": "metrics-overview", children: _jsx(SectionHeader, { children: _jsxs(SectionHeaderCopy, { children: [_jsx("h3", { children: toolMetrics?.title?.trim() || 'surface metrics' }), _jsx("p", { children: eyebrowLabel }), toolMetrics?.summary?.trim() ? _jsx("p", { children: toolMetrics.summary }) : null] }) }) }), _jsxs(Section, { "data-panel-id": "metrics-context", children: [_jsx(SectionHeader, { children: _jsxs(SectionHeaderCopy, { children: [_jsx("h3", { children: "surface context" }), moduleSummary?.trim() ? _jsx("p", { children: moduleSummary }) : null, promptPackDescription?.trim() ? _jsx("p", { children: promptPackDescription }) : null] }) }), _jsx(SectionList, { children: runtimeRows.map((metric) => (_jsxs(MetricRow, { children: [_jsx(MetricMeta, { children: _jsx(MetricLabel, { children: metric.label }) }), _jsx(MetricValue, { children: metric.value })] }, metric.label))) })] }), !hasManifestMetrics ? (_jsx(Section, { "data-panel-id": "metrics-contract-warning", children: _jsx(SectionHeader, { children: _jsxs(SectionHeaderCopy, { children: [_jsx("h3", { children: modeId === 'map' ? 'map metrics contract missing' : 'tool metrics not declared' }), _jsx("p", { children: modeId === 'map'
|
|
85
|
+
? 'This map tool is receiving live site metrics, but its manifest does not declare canonical groups against the shared map feed. Add manifest metrics instead of relying on frontend-only cards.'
|
|
86
|
+
: 'This tool manifest does not declare canonical metrics feeds. Composer is only showing shared runtime context and will not invent tool-specific metrics from frontend heuristics.' })] }) }) })) : null, modeId === 'map' && manifestUsesMapFeed && !hasMapFeed ? (_jsx(Section, { "data-panel-id": "metrics-map-feed-warning", children: _jsx(SectionHeader, { children: _jsxs(SectionHeaderCopy, { children: [_jsx("h3", { children: "map feed missing" }), _jsx("p", { children: "This panel has manifest-declared map metrics, but no canonical `feeds.map` payload was provided. This is a metrics wiring bug, not absent site data." })] }) }) })) : null, manifestGroups.map((group) => (_jsxs(Section, { "data-panel-id": `metrics-${group.id}`, children: [_jsx(SectionHeader, { children: _jsxs(SectionHeaderCopy, { children: [_jsx("h3", { children: group.label }), group.summary?.trim() ? _jsx("p", { children: group.summary }) : null] }) }), group.metrics.length > 0 ? (_jsx(SectionList, { children: group.metrics.map((metric) => {
|
|
87
|
+
const feedRoot = isRecord(feeds?.[metric.source.kind]) ? feeds?.[metric.source.kind] : null;
|
|
88
|
+
const value = resolvePathValue(feedRoot, metric.source.path);
|
|
89
|
+
return (_jsxs(MetricRow, { children: [_jsxs(MetricMeta, { children: [_jsx(MetricLabel, { children: metric.label }), metric.summary?.trim() ? _jsx(MetricHelp, { children: metric.summary }) : null] }), _jsx(MetricValue, { children: formatMetricValue(metric, value) })] }, metric.id));
|
|
90
|
+
}) })) : (_jsx("div", { className: "panel-section-empty", children: "This metrics group has no declared fields." }))] }, group.id))), _jsxs(Section, { "data-panel-id": "metrics-status", children: [_jsx(SectionHeader, { children: _jsx(SectionHeaderCopy, { children: _jsx("h3", { children: modeId === 'map' ? 'metrics' : supportsDerivedMetrics || hasManifestMetrics ? 'status' : 'metrics' }) }) }), _jsx(SectionList, { children: modeId === 'map' && hasMapFeed ? (_jsxs(MetricRow, { children: [_jsx(MetricMeta, { children: _jsx(MetricLabel, { children: "source" }) }), _jsx(MetricValue, { children: mapMetricsSourceLabel })] })) : (_jsxs(MetricRow, { children: [_jsx(MetricMeta, { children: _jsx(MetricLabel, { children: hasManifestMetrics ? 'source' : supportsDerivedMetrics ? 'availability' : 'state' }) }), _jsx(MetricValue, { children: hasManifestMetrics ? 'manifest + runtime' : supportsDerivedMetrics ? 'pending' : 'none' })] })) })] })] }));
|
|
97
91
|
}
|
package/dist/ModeBar.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare const MODE_BAR_HEIGHT_PX = 42;
|
|
2
|
+
export declare const MODE_BAR_WITH_UTILITIES_HEIGHT_PX = 42;
|
|
1
3
|
export type ModeTab = {
|
|
2
4
|
id: string;
|
|
3
5
|
label: string;
|
|
@@ -18,7 +20,9 @@ export type ModeBarProps = {
|
|
|
18
20
|
showPanelToggle?: boolean;
|
|
19
21
|
panelsCollapsed?: boolean;
|
|
20
22
|
onTogglePanels?: () => void;
|
|
23
|
+
inline?: boolean;
|
|
24
|
+
id?: string;
|
|
25
|
+
ariaLabel?: string;
|
|
21
26
|
};
|
|
22
|
-
export
|
|
23
|
-
export default function ModeBar({ active, topOffsetPx, tabs, tone, heightPx, lockedLabel, onSelect, hidden, className, showPanelToggle, panelsCollapsed, onTogglePanels, }: ModeBarProps): import("react/jsx-runtime").JSX.Element | null;
|
|
27
|
+
export default function ModeBar({ active, topOffsetPx, tabs, tone: _tone, heightPx, lockedLabel, onSelect, hidden, className, showPanelToggle, panelsCollapsed, onTogglePanels, inline, id, ariaLabel, }: ModeBarProps): import("react/jsx-runtime").JSX.Element | null;
|
|
24
28
|
//# sourceMappingURL=ModeBar.d.ts.map
|
package/dist/ModeBar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModeBar.d.ts","sourceRoot":"","sources":["../src/ModeBar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ModeBar.d.ts","sourceRoot":"","sources":["../src/ModeBar.tsx"],"names":[],"mappings":"AAWA,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,iCAAiC,KAAqB,CAAC;AAmDpE,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAC9B,MAAM,EACN,WAAW,EACX,IAAI,EACJ,IAAI,EAAE,KAAe,EACrB,QAAQ,EACR,WAA2B,EAC3B,QAAQ,EACR,MAAc,EACd,SAAS,EACT,eAAuB,EACvB,eAAuB,EACvB,cAAc,EACd,MAAc,EACd,EAAE,EACF,SAA2B,GAC5B,EAAE,YAAY,kDAmDd"}
|
package/dist/ModeBar.js
CHANGED
|
@@ -1,105 +1,72 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import styled from 'styled-components';
|
|
4
|
+
import { panelSystemFeatureToggleCss, panelSystemToggleBarCss, panelSystemVarsCss, } from './PanelSystem.js';
|
|
5
|
+
import PanelToggleDock from './PanelToggleDock.js';
|
|
6
|
+
export const MODE_BAR_HEIGHT_PX = 42;
|
|
7
|
+
export const MODE_BAR_WITH_UTILITIES_HEIGHT_PX = MODE_BAR_HEIGHT_PX;
|
|
4
8
|
const Root = styled.div `
|
|
5
|
-
|
|
9
|
+
${panelSystemVarsCss}
|
|
10
|
+
position: ${(props) => (props.$inline ? 'relative' : 'fixed')};
|
|
6
11
|
left: 0;
|
|
7
12
|
right: 0;
|
|
8
13
|
z-index: 70;
|
|
9
|
-
top: ${(props) => `${Math.max(0, props.$topOffsetPx)}px`};
|
|
14
|
+
top: ${(props) => (props.$inline ? 'auto' : `${Math.max(0, props.$topOffsetPx)}px`)};
|
|
15
|
+
width: ${(props) => (props.$inline ? '100vw' : 'auto')};
|
|
10
16
|
height: ${(props) => `${props.$heightPx}px`};
|
|
11
|
-
|
|
12
|
-
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
overflow: visible;
|
|
20
|
+
background: rgba(255, 255, 255, 0.95);
|
|
21
|
+
border-bottom: 1px solid var(--panel-system-border);
|
|
22
|
+
backdrop-filter: blur(12px);
|
|
23
|
+
font-family: var(--index-panel-font, var(--viewer-ui-font-body));
|
|
13
24
|
`;
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
left: 50%;
|
|
17
|
-
top: calc(100% + 8px);
|
|
18
|
-
transform: translateX(-50%);
|
|
19
|
-
z-index: 80;
|
|
25
|
+
const Content = styled.div `
|
|
26
|
+
flex: 0 0 ${() => `${MODE_BAR_HEIGHT_PX}px`};
|
|
20
27
|
display: flex;
|
|
21
28
|
align-items: center;
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
justify-content: center;
|
|
30
|
+
min-width: 0;
|
|
31
|
+
padding: 0 20px;
|
|
24
32
|
`;
|
|
25
33
|
const Tabs = styled.div `
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
34
|
+
${panelSystemToggleBarCss}
|
|
35
|
+
flex: 0 1 auto;
|
|
36
|
+
justify-content: center;
|
|
37
|
+
max-width: 100%;
|
|
38
|
+
min-width: 0;
|
|
29
39
|
`;
|
|
30
40
|
const TabLink = styled.a `
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
margin-left: ${(props) => (props.$index === 0 ? '0' : '-18px')};
|
|
34
|
-
border-left: ${(props) => (props.$index === 0 ? '1px solid var(--viewer-ui-color-panel-border)' : '0')};
|
|
35
|
-
border-right: 1px solid var(--viewer-ui-color-panel-border);
|
|
36
|
-
border-bottom: 1px solid var(--viewer-ui-color-panel-border);
|
|
37
|
-
border-radius: 0 0 18px 0;
|
|
38
|
-
box-shadow: inset 0 0 0 1px var(--viewer-ui-color-panel-border-subtle);
|
|
39
|
-
flex: 1 1 0;
|
|
40
|
-
min-width: 0;
|
|
41
|
-
display: inline-flex;
|
|
42
|
-
justify-content: center;
|
|
43
|
-
align-items: center;
|
|
44
|
-
text-decoration: none;
|
|
45
|
-
font-size: 13px;
|
|
46
|
-
font-weight: 600;
|
|
47
|
-
letter-spacing: 0.04em;
|
|
48
|
-
text-transform: lowercase;
|
|
49
|
-
transition: color 0.16s ease, background-color 0.16s ease, border-color 0.16s ease;
|
|
50
|
-
background: ${(props) => props.$active
|
|
51
|
-
? props.$tone === 'green'
|
|
52
|
-
? 'rgba(49, 143, 78, 0.12)'
|
|
53
|
-
: 'rgba(15, 23, 42, 0.08)'
|
|
54
|
-
: 'var(--viewer-ui-color-tab-bg, rgba(47, 74, 60, 0.08))'};
|
|
55
|
-
color: ${(props) => props.$active
|
|
56
|
-
? props.$tone === 'green'
|
|
57
|
-
? 'var(--viewer-ui-color-button-primary, #318f4e)'
|
|
58
|
-
: 'var(--viewer-ui-color-button-secondary, #0b1320)'
|
|
59
|
-
: 'var(--viewer-ui-color-text-muted, rgba(47, 74, 60, 0.75))'};
|
|
60
|
-
|
|
61
|
-
&:hover {
|
|
62
|
-
color: ${(props) => props.$active
|
|
63
|
-
? props.$tone === 'green'
|
|
64
|
-
? 'var(--viewer-ui-color-button-primary, #318f4e)'
|
|
65
|
-
: 'var(--viewer-ui-color-button-secondary, #0b1320)'
|
|
66
|
-
: 'var(--viewer-ui-color-text-strong, #0f172a)'};
|
|
67
|
-
}
|
|
41
|
+
${panelSystemFeatureToggleCss}
|
|
42
|
+
gap: 8px;
|
|
68
43
|
`;
|
|
69
44
|
const LockedLabel = styled.span `
|
|
70
|
-
margin-left: 8px;
|
|
71
|
-
font-size: 9px;
|
|
72
|
-
letter-spacing: 0.2em;
|
|
73
|
-
text-transform: uppercase;
|
|
74
|
-
color: var(--viewer-ui-color-text-muted, rgba(47, 74, 60, 0.75));
|
|
75
|
-
`;
|
|
76
|
-
const ToggleText = styled.button `
|
|
77
|
-
border: 0;
|
|
78
|
-
background: transparent;
|
|
79
45
|
font-size: 11px;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
color:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
white-space: nowrap;
|
|
86
|
-
|
|
87
|
-
&:hover {
|
|
88
|
-
color: var(--brand-text-primary);
|
|
89
|
-
}
|
|
46
|
+
letter-spacing: 0;
|
|
47
|
+
text-transform: none;
|
|
48
|
+
color: currentColor;
|
|
49
|
+
opacity: 0.72;
|
|
50
|
+
flex: 0 0 auto;
|
|
90
51
|
`;
|
|
91
|
-
export
|
|
92
|
-
export default function ModeBar({ active, topOffsetPx, tabs, tone = 'green', heightPx = MODE_BAR_HEIGHT_PX, lockedLabel = 'coming soon', onSelect, hidden = false, className, showPanelToggle = false, panelsCollapsed = false, onTogglePanels, }) {
|
|
52
|
+
export default function ModeBar({ active, topOffsetPx, tabs, tone: _tone = 'green', heightPx, lockedLabel = 'coming soon', onSelect, hidden = false, className, showPanelToggle = false, panelsCollapsed = false, onTogglePanels, inline = false, id, ariaLabel = 'Composer mode', }) {
|
|
93
53
|
if (hidden) {
|
|
94
54
|
return null;
|
|
95
55
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
56
|
+
const hasPanelUtility = Boolean(showPanelToggle && onTogglePanels);
|
|
57
|
+
const resolvedHeightPx = heightPx ?? MODE_BAR_HEIGHT_PX;
|
|
58
|
+
return (_jsxs(Root, { id: id, className: className, "$topOffsetPx": topOffsetPx, "$heightPx": resolvedHeightPx, "$inline": inline, children: [_jsx(Content, { children: _jsx(Tabs, { role: "radiogroup", "aria-label": ariaLabel, children: tabs.map((tab, index) => {
|
|
59
|
+
const isDisabled = tab.status === 'coming-soon' || tab.locked;
|
|
60
|
+
const statusLabel = isDisabled ? lockedLabel : null;
|
|
61
|
+
const isActive = tab.id === active;
|
|
62
|
+
return (_jsxs(TabLink, { role: "radio", "aria-checked": isActive, "aria-disabled": isDisabled ? 'true' : undefined, "data-active": isActive ? 'true' : 'false', "data-index": index, href: tab.href ?? '#', onClick: (event) => {
|
|
63
|
+
if (!tab.href || isDisabled) {
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
}
|
|
66
|
+
if (isDisabled) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
onSelect?.(tab.id);
|
|
70
|
+
}, children: [_jsx("span", { children: tab.label }), statusLabel ? _jsx(LockedLabel, { children: statusLabel }) : null] }, tab.id));
|
|
71
|
+
}) }) }), _jsx(PanelToggleDock, { placement: "absolute", topOffsetPx: resolvedHeightPx, collapsed: panelsCollapsed, hidden: !hasPanelUtility, onToggle: onTogglePanels })] }));
|
|
105
72
|
}
|
|
@@ -19,7 +19,8 @@ type ModuleSelectorPanelProps = {
|
|
|
19
19
|
uploadDescription?: string;
|
|
20
20
|
uploadSlot?: ReactNode;
|
|
21
21
|
uploadMeta?: ReactNode;
|
|
22
|
+
supplementarySlot?: ReactNode;
|
|
22
23
|
};
|
|
23
|
-
export default function ModuleSelectorPanel({ title, description, status, error, modules, activeModuleId, onSelectModule, emptyLabel, uploadTitle, uploadDescription, uploadSlot, uploadMeta, }: ModuleSelectorPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export default function ModuleSelectorPanel({ title, description: _description, status, error, modules, activeModuleId, onSelectModule, emptyLabel, uploadTitle, uploadDescription: _uploadDescription, uploadSlot, uploadMeta: _uploadMeta, supplementarySlot, }: ModuleSelectorPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
24
25
|
export {};
|
|
25
26
|
//# sourceMappingURL=ModuleSelectorPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModuleSelectorPanel.d.ts","sourceRoot":"","sources":["../src/ModuleSelectorPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ModuleSelectorPanel.d.ts","sourceRoot":"","sources":["../src/ModuleSelectorPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAUvC,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,KAAK,oBAAoB,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAE1D,KAAK,wBAAwB,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,iBAAiB,CAAC,EAAE,SAAS,CAAC;CAC/B,CAAC;AAoGF,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAC1C,KAA+B,EAC/B,WAAW,EAAE,YAAY,EACzB,MAAgB,EAChB,KAAK,EACL,OAAO,EACP,cAAc,EACd,cAAc,EACd,UAAoC,EACpC,WAAsB,EACtB,iBAAiB,EAAE,kBAAkB,EACrC,UAAU,EACV,UAAU,EAAE,WAAW,EACvB,iBAAiB,GAClB,EAAE,wBAAwB,2CAuC1B"}
|
|
@@ -1,61 +1,72 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import styled from 'styled-components';
|
|
4
|
+
import { panelSystemBodyTextCss, panelSystemSectionCss, panelSystemSectionHeadingCss, panelSystemValueCss, } from './PanelSystem.js';
|
|
4
5
|
const PanelRoot = styled.div `
|
|
5
6
|
display: flex;
|
|
6
7
|
flex-direction: column;
|
|
7
|
-
gap:
|
|
8
|
+
gap: 22px;
|
|
8
9
|
`;
|
|
9
10
|
const Section = styled.section `
|
|
10
|
-
|
|
11
|
-
padding-bottom: 18px;
|
|
11
|
+
${panelSystemSectionCss}
|
|
12
12
|
`;
|
|
13
13
|
const SectionHeader = styled.div `
|
|
14
14
|
display: flex;
|
|
15
15
|
flex-direction: column;
|
|
16
|
-
gap:
|
|
16
|
+
gap: 6px;
|
|
17
17
|
`;
|
|
18
18
|
const SectionTitle = styled.div `
|
|
19
|
-
|
|
20
|
-
font-size: 22px;
|
|
21
|
-
font-weight: 700;
|
|
22
|
-
text-transform: lowercase;
|
|
23
|
-
letter-spacing: 0.06em;
|
|
24
|
-
color: var(--viewer-ui-color-text-strong);
|
|
25
|
-
`;
|
|
26
|
-
const SectionDescription = styled.p `
|
|
27
|
-
font-size: 11px;
|
|
28
|
-
text-transform: lowercase;
|
|
29
|
-
letter-spacing: 0.04em;
|
|
30
|
-
color: var(--viewer-ui-color-text-muted);
|
|
19
|
+
${panelSystemSectionHeadingCss}
|
|
31
20
|
`;
|
|
32
21
|
const StatusBanner = styled.div `
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
${panelSystemBodyTextCss}
|
|
23
|
+
margin-top: 14px;
|
|
24
|
+
padding: 12px 0;
|
|
25
|
+
border-radius: 0;
|
|
35
26
|
border: 1px solid var(--viewer-ui-color-panel-border);
|
|
27
|
+
border-left: 0;
|
|
28
|
+
border-right: 0;
|
|
36
29
|
background: var(--viewer-ui-color-surface);
|
|
37
|
-
font-size: 11px;
|
|
38
|
-
text-transform: lowercase;
|
|
39
30
|
color: var(--viewer-ui-color-text-muted);
|
|
40
31
|
`;
|
|
41
32
|
const ModuleGrid = styled.div `
|
|
42
33
|
display: grid;
|
|
43
34
|
grid-template-columns: 1fr;
|
|
44
|
-
gap:
|
|
35
|
+
gap: 0;
|
|
36
|
+
margin-top: 14px;
|
|
37
|
+
max-height: clamp(320px, 48vh, 640px);
|
|
38
|
+
overflow-y: auto;
|
|
39
|
+
overscroll-behavior: contain;
|
|
40
|
+
scrollbar-gutter: stable;
|
|
41
|
+
padding-right: 0;
|
|
42
|
+
|
|
43
|
+
&::-webkit-scrollbar {
|
|
44
|
+
width: 10px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&::-webkit-scrollbar-track {
|
|
48
|
+
background: transparent;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&::-webkit-scrollbar-thumb {
|
|
52
|
+
border-radius: 999px;
|
|
53
|
+
border: 2px solid transparent;
|
|
54
|
+
background: color-mix(in srgb, var(--viewer-ui-color-panel-border) 78%, transparent);
|
|
55
|
+
background-clip: padding-box;
|
|
56
|
+
}
|
|
45
57
|
`;
|
|
46
58
|
const ModuleButton = styled.button `
|
|
47
|
-
border-radius:
|
|
48
|
-
border:
|
|
49
|
-
|
|
50
|
-
background:
|
|
51
|
-
color: ${(props) => props.$active ? 'var(--viewer-ui-color-
|
|
52
|
-
padding:
|
|
59
|
+
border-radius: 0;
|
|
60
|
+
border: 0;
|
|
61
|
+
border-bottom: 1px solid var(--viewer-ui-color-panel-border);
|
|
62
|
+
background: transparent;
|
|
63
|
+
color: ${(props) => props.$active ? 'var(--viewer-ui-color-button-primary)' : 'var(--viewer-ui-color-text-strong)'};
|
|
64
|
+
padding: 9px 0;
|
|
53
65
|
text-align: left;
|
|
54
66
|
cursor: pointer;
|
|
55
67
|
transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
|
|
56
68
|
|
|
57
69
|
&:hover {
|
|
58
|
-
border-color: var(--viewer-ui-color-button-primary);
|
|
59
70
|
color: var(--viewer-ui-color-text-strong);
|
|
60
71
|
}
|
|
61
72
|
|
|
@@ -65,32 +76,19 @@ const ModuleButton = styled.button `
|
|
|
65
76
|
}
|
|
66
77
|
`;
|
|
67
78
|
const ModuleTitle = styled.div `
|
|
68
|
-
|
|
69
|
-
font-size: 14px;
|
|
70
|
-
font-weight: 700;
|
|
71
|
-
letter-spacing: 0.04em;
|
|
72
|
-
text-transform: lowercase;
|
|
73
|
-
`;
|
|
74
|
-
const ModuleSummary = styled.div `
|
|
75
|
-
margin-top: 4px;
|
|
76
|
-
font-size: 11px;
|
|
77
|
-
color: var(--viewer-ui-color-text-muted);
|
|
78
|
-
text-transform: lowercase;
|
|
79
|
-
letter-spacing: 0.03em;
|
|
79
|
+
${panelSystemValueCss}
|
|
80
80
|
`;
|
|
81
|
-
const
|
|
81
|
+
const SupplementarySection = styled.section `
|
|
82
|
+
${panelSystemSectionCss}
|
|
82
83
|
display: flex;
|
|
83
84
|
flex-direction: column;
|
|
84
|
-
gap:
|
|
85
|
+
gap: 14px;
|
|
85
86
|
`;
|
|
86
|
-
const
|
|
87
|
+
const UploadSection = styled.section `
|
|
87
88
|
display: flex;
|
|
88
89
|
flex-direction: column;
|
|
89
|
-
gap:
|
|
90
|
-
font-size: 10px;
|
|
91
|
-
text-transform: lowercase;
|
|
92
|
-
color: var(--viewer-ui-color-text-muted);
|
|
90
|
+
gap: 10px;
|
|
93
91
|
`;
|
|
94
|
-
export default function ModuleSelectorPanel({ title = 'architectural modules', description, status = 'ready', error, modules, activeModuleId, onSelectModule, emptyLabel = 'No modules available.', uploadTitle = 'upload', uploadDescription, uploadSlot, uploadMeta, }) {
|
|
95
|
-
return (_jsxs(PanelRoot, { children: [_jsxs(Section, { children: [
|
|
92
|
+
export default function ModuleSelectorPanel({ title = 'architectural modules', description: _description, status = 'ready', error, modules, activeModuleId, onSelectModule, emptyLabel = 'No modules available.', uploadTitle = 'upload', uploadDescription: _uploadDescription, uploadSlot, uploadMeta: _uploadMeta, supplementarySlot, }) {
|
|
93
|
+
return (_jsxs(PanelRoot, { children: [_jsxs(Section, { children: [_jsx(SectionHeader, { children: _jsx(SectionTitle, { children: title }) }), status !== 'ready' ? (_jsx(StatusBanner, { children: error || (status === 'loading' ? 'Loading module registry…' : 'Module registry unavailable.') })) : modules.length === 0 ? (_jsx(StatusBanner, { children: emptyLabel })) : (_jsx(ModuleGrid, { children: modules.map((module) => (_jsx(ModuleButton, { type: "button", "$active": module.id === activeModuleId, onClick: () => onSelectModule?.(module.id), disabled: module.disabled, children: _jsx(ModuleTitle, { children: module.label }) }, module.id))) }))] }), supplementarySlot ? _jsx(SupplementarySection, { children: supplementarySlot }) : null, _jsxs(UploadSection, { children: [_jsx(SectionHeader, { children: _jsx(SectionTitle, { children: uploadTitle }) }), uploadSlot] })] }));
|
|
96
94
|
}
|
package/dist/PanelSkin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PanelSkin.d.ts","sourceRoot":"","sources":["../src/PanelSkin.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PanelSkin.d.ts","sourceRoot":"","sources":["../src/PanelSkin.tsx"],"names":[],"mappings":"AA4BA,eAAO,MAAM,SAAS,2FAm1DrB,CAAC"}
|