@amiable-dev/docusaurus-plugin-stentorosaur 0.20.0 → 0.21.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.
@@ -3,6 +3,89 @@
3
3
  padding: 2rem 0;
4
4
  }
5
5
 
6
+ /* Minimal layout styles (ADR-004) */
7
+ .statusBoard {
8
+ max-width: 1200px;
9
+ margin: 0 auto;
10
+ padding: 2rem 1rem;
11
+ }
12
+
13
+ .header {
14
+ margin-bottom: 2rem;
15
+ }
16
+
17
+ .header h1 {
18
+ margin: 0 0 0.5rem;
19
+ font-size: 2.5rem;
20
+ }
21
+
22
+ .description {
23
+ color: var(--ifm-color-emphasis-700);
24
+ font-size: 1.125rem;
25
+ margin: 0.5rem 0 1.5rem;
26
+ }
27
+
28
+ .overallStatus {
29
+ padding: 1rem 1.5rem;
30
+ border-radius: 8px;
31
+ background: var(--ifm-color-emphasis-100);
32
+ display: inline-flex;
33
+ align-items: center;
34
+ gap: 0.75rem;
35
+ font-weight: 600;
36
+ }
37
+
38
+ .statusGood {
39
+ display: flex;
40
+ align-items: center;
41
+ gap: 0.75rem;
42
+ color: #10b981;
43
+ }
44
+
45
+ .statusIssue {
46
+ display: flex;
47
+ align-items: center;
48
+ gap: 0.75rem;
49
+ color: #f59e0b;
50
+ }
51
+
52
+ .statusDot {
53
+ width: 12px;
54
+ height: 12px;
55
+ border-radius: 50%;
56
+ background-color: currentColor;
57
+ animation: pulse 2s ease-in-out infinite;
58
+ }
59
+
60
+ @keyframes pulse {
61
+ 0%, 100% {
62
+ opacity: 1;
63
+ }
64
+ 50% {
65
+ opacity: 0.5;
66
+ }
67
+ }
68
+
69
+ .systemCards {
70
+ display: flex;
71
+ flex-direction: column;
72
+ gap: 1rem;
73
+ margin-top: 2rem;
74
+ }
75
+
76
+ .emptyState {
77
+ text-align: center;
78
+ padding: 3rem 1rem;
79
+ color: var(--ifm-color-emphasis-600);
80
+ background: var(--ifm-color-emphasis-100);
81
+ border-radius: 8px;
82
+ }
83
+
84
+ .emptyState p {
85
+ margin: 0;
86
+ font-size: 1.125rem;
87
+ }
88
+
6
89
  .chartsSection {
7
90
  max-width: 1400px;
8
91
  margin: 3rem auto;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Copyright (c) Your Organization
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ /**
8
+ * ADR-004: SystemCard Compound Component
9
+ *
10
+ * Collapsible system status card with compound component pattern.
11
+ * Includes Header, UptimeBar, Details, Metrics, and Charts sub-components.
12
+ *
13
+ * @see docs/adrs/ADR-004-simplified-status-card-ux.md
14
+ */
15
+ import React, { type ReactNode } from 'react';
16
+ import { type UptimeBarProps } from '../UptimeBar';
17
+ /**
18
+ * Status types
19
+ */
20
+ export type SystemStatus = 'up' | 'degraded' | 'down' | 'maintenance';
21
+ /**
22
+ * Props for SystemCard component
23
+ */
24
+ export interface SystemCardProps {
25
+ /** System identifier */
26
+ name: string;
27
+ /** Display name (optional) */
28
+ displayName?: string;
29
+ /** Current status */
30
+ status: SystemStatus;
31
+ /** Enable expand on click (default: true) */
32
+ expandable?: boolean;
33
+ /** Initial expanded state */
34
+ defaultExpanded?: boolean;
35
+ /** Controlled expanded state */
36
+ expanded?: boolean;
37
+ /** Callback when expanded/collapsed */
38
+ onExpandChange?: (expanded: boolean) => void;
39
+ /** Semantic heading level (default: 3) */
40
+ headingLevel?: 2 | 3 | 4;
41
+ /** Accessibility label for expand button */
42
+ expandButtonLabel?: string;
43
+ /** Compound component children */
44
+ children?: ReactNode;
45
+ /** Optional additional className */
46
+ className?: string;
47
+ }
48
+ /**
49
+ * SystemCard Component
50
+ *
51
+ * Main container for system status with expand/collapse functionality.
52
+ */
53
+ export declare function SystemCard({ name, displayName, status, expandable, defaultExpanded, expanded: controlledExpanded, onExpandChange, headingLevel, expandButtonLabel, children, className, }: SystemCardProps): React.ReactElement;
54
+ export declare namespace SystemCard {
55
+ var Header: typeof SystemCardHeader;
56
+ var UptimeBar: typeof SystemCardUptimeBar;
57
+ var Details: typeof SystemCardDetails;
58
+ var Metrics: typeof SystemCardMetrics;
59
+ var Charts: typeof SystemCardCharts;
60
+ }
61
+ /**
62
+ * SystemCard.Header - Custom header content
63
+ */
64
+ export interface SystemCardHeaderProps {
65
+ children?: ReactNode;
66
+ }
67
+ export declare function SystemCardHeader({ children, }: SystemCardHeaderProps): React.ReactElement;
68
+ /**
69
+ * SystemCard.UptimeBar - Embedded UptimeBar
70
+ */
71
+ export declare function SystemCardUptimeBar(props: Omit<UptimeBarProps, 'serviceName'> & {
72
+ serviceName?: string;
73
+ }): React.ReactElement;
74
+ /**
75
+ * SystemCard.Details - Expandable content container
76
+ */
77
+ export interface SystemCardDetailsProps {
78
+ children?: ReactNode;
79
+ }
80
+ export declare function SystemCardDetails({ children, }: SystemCardDetailsProps): React.ReactElement;
81
+ /**
82
+ * SystemCard.Metrics - Response time and last checked
83
+ */
84
+ export interface SystemCardMetricsProps {
85
+ responseTime?: number;
86
+ lastChecked?: string;
87
+ }
88
+ export declare function SystemCardMetrics({ responseTime, lastChecked, }: SystemCardMetricsProps): React.ReactElement;
89
+ /**
90
+ * SystemCard.Charts - Chart container (placeholder)
91
+ */
92
+ export interface SystemCardChartsProps {
93
+ serviceName?: string;
94
+ children?: ReactNode;
95
+ }
96
+ export declare function SystemCardCharts({ children, }: SystemCardChartsProps): React.ReactElement;
97
+ export default SystemCard;
98
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/theme/SystemCard/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAKZ,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC;AA0BtE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,0CAA0C;IAC1C,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,WAAW,EACX,MAAM,EACN,UAAiB,EACjB,eAAuB,EACvB,QAAQ,EAAE,kBAAkB,EAC5B,cAAc,EACd,YAAgB,EAChB,iBAAiB,EACjB,QAAQ,EACR,SAAS,GACV,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CA2FtC;yBAvGe,UAAU;;;;;;;AAyG1B;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,GACT,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAE5C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACpE,KAAK,CAAC,YAAY,CAOpB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,GACT,EAAE,sBAAsB,GAAG,KAAK,CAAC,YAAY,CAW7C;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,WAAW,GACZ,EAAE,sBAAsB,GAAG,KAAK,CAAC,YAAY,CAsB7C;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,GACT,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAE5C;AAUD,eAAe,UAAU,CAAC"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SystemCard = SystemCard;
7
+ exports.SystemCardHeader = SystemCardHeader;
8
+ exports.SystemCardUptimeBar = SystemCardUptimeBar;
9
+ exports.SystemCardDetails = SystemCardDetails;
10
+ exports.SystemCardMetrics = SystemCardMetrics;
11
+ exports.SystemCardCharts = SystemCardCharts;
12
+ const jsx_runtime_1 = require("react/jsx-runtime");
13
+ /**
14
+ * Copyright (c) Your Organization
15
+ *
16
+ * This source code is licensed under the MIT license found in the
17
+ * LICENSE file in the root directory of this source tree.
18
+ */
19
+ /**
20
+ * ADR-004: SystemCard Compound Component
21
+ *
22
+ * Collapsible system status card with compound component pattern.
23
+ * Includes Header, UptimeBar, Details, Metrics, and Charts sub-components.
24
+ *
25
+ * @see docs/adrs/ADR-004-simplified-status-card-ux.md
26
+ */
27
+ const react_1 = require("react");
28
+ const StatusBadge_1 = require("../StatusBadge");
29
+ const UptimeBar_1 = require("../UptimeBar");
30
+ const styles_module_css_1 = __importDefault(require("./styles.module.css"));
31
+ const SystemCardContext = (0, react_1.createContext)(undefined);
32
+ function useSystemCardContext() {
33
+ const context = (0, react_1.useContext)(SystemCardContext);
34
+ if (!context) {
35
+ throw new Error('SystemCard compound components must be used within a SystemCard');
36
+ }
37
+ return context;
38
+ }
39
+ /**
40
+ * Status class mapping
41
+ */
42
+ const STATUS_CLASS_MAP = {
43
+ up: styles_module_css_1.default.statusUp,
44
+ degraded: styles_module_css_1.default.statusDegraded,
45
+ down: styles_module_css_1.default.statusDown,
46
+ maintenance: styles_module_css_1.default.statusMaintenance,
47
+ };
48
+ /**
49
+ * SystemCard Component
50
+ *
51
+ * Main container for system status with expand/collapse functionality.
52
+ */
53
+ function SystemCard({ name, displayName, status, expandable = true, defaultExpanded = false, expanded: controlledExpanded, onExpandChange, headingLevel = 3, expandButtonLabel, children, className, }) {
54
+ // Uncontrolled state
55
+ const [internalExpanded, setInternalExpanded] = (0, react_1.useState)(defaultExpanded);
56
+ // Use controlled or uncontrolled state
57
+ const isControlled = controlledExpanded !== undefined;
58
+ const expanded = isControlled ? controlledExpanded : internalExpanded;
59
+ const handleToggle = (0, react_1.useCallback)(() => {
60
+ if (!expandable)
61
+ return;
62
+ const newExpanded = !expanded;
63
+ if (!isControlled) {
64
+ setInternalExpanded(newExpanded);
65
+ }
66
+ onExpandChange?.(newExpanded);
67
+ }, [expandable, expanded, isControlled, onExpandChange]);
68
+ const handleKeyDown = (0, react_1.useCallback)((event) => {
69
+ if (!expandable)
70
+ return;
71
+ if (event.key === 'Enter' || event.key === ' ') {
72
+ event.preventDefault();
73
+ handleToggle();
74
+ }
75
+ else if (event.key === 'Escape' && expanded) {
76
+ event.preventDefault();
77
+ if (!isControlled) {
78
+ setInternalExpanded(false);
79
+ }
80
+ onExpandChange?.(false);
81
+ }
82
+ }, [expandable, expanded, isControlled, onExpandChange, handleToggle]);
83
+ const Heading = `h${headingLevel}`;
84
+ const label = displayName || name;
85
+ // Context value for compound components
86
+ const contextValue = {
87
+ name,
88
+ status,
89
+ expanded,
90
+ expandable,
91
+ };
92
+ const statusClass = STATUS_CLASS_MAP[status];
93
+ return ((0, jsx_runtime_1.jsx)(SystemCardContext.Provider, { value: contextValue, children: (0, jsx_runtime_1.jsxs)("article", { className: `${styles_module_css_1.default.systemCard} ${statusClass} ${expanded ? styles_module_css_1.default.expanded : ''} ${className || ''}`, role: "article", "aria-expanded": expanded, tabIndex: expandable ? 0 : undefined, onClick: handleToggle, onKeyDown: handleKeyDown, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.cardHeader, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.cardTitleRow, children: [(0, jsx_runtime_1.jsx)(Heading, { className: styles_module_css_1.default.cardTitle, children: label }), (0, jsx_runtime_1.jsx)(StatusBadge_1.StatusBadge, { status: status, size: "sm" })] }), expandable && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: styles_module_css_1.default.expandButton, "aria-label": expandButtonLabel || `Toggle ${label} details`, "aria-expanded": expanded, onClick: (e) => {
94
+ e.stopPropagation();
95
+ handleToggle();
96
+ }, children: (0, jsx_runtime_1.jsx)("span", { className: `${styles_module_css_1.default.expandIcon} ${expanded ? styles_module_css_1.default.expandIconOpen : ''}`, children: "\u25BC" }) }))] }), children] }) }));
97
+ }
98
+ function SystemCardHeader({ children, }) {
99
+ return (0, jsx_runtime_1.jsx)("div", { className: styles_module_css_1.default.customHeader, children: children });
100
+ }
101
+ /**
102
+ * SystemCard.UptimeBar - Embedded UptimeBar
103
+ */
104
+ function SystemCardUptimeBar(props) {
105
+ const { name } = useSystemCardContext();
106
+ return ((0, jsx_runtime_1.jsx)("div", { className: styles_module_css_1.default.uptimeBarWrapper, children: (0, jsx_runtime_1.jsx)(UptimeBar_1.UptimeBar, { ...props, serviceName: props.serviceName || name }) }));
107
+ }
108
+ function SystemCardDetails({ children, }) {
109
+ const { expanded } = useSystemCardContext();
110
+ return ((0, jsx_runtime_1.jsx)("div", { className: `${styles_module_css_1.default.cardDetails} ${expanded ? styles_module_css_1.default.detailsVisible : ''}`, "aria-hidden": !expanded, children: children }));
111
+ }
112
+ function SystemCardMetrics({ responseTime, lastChecked, }) {
113
+ return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.metricsGrid, children: [responseTime !== undefined && ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.metricItem, children: [(0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.metricLabel, children: "Response Time" }), (0, jsx_runtime_1.jsxs)("span", { className: styles_module_css_1.default.metricValue, children: [responseTime, "ms"] })] })), lastChecked !== undefined && ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.metricItem, children: [(0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.metricLabel, children: "Last Checked" }), (0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.metricValue, children: lastChecked })] })), responseTime === undefined && lastChecked === undefined && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_css_1.default.metricItem, children: (0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.metricValue, children: "N/A" }) }))] }));
114
+ }
115
+ function SystemCardCharts({ children, }) {
116
+ return (0, jsx_runtime_1.jsx)("div", { className: styles_module_css_1.default.chartsContainer, children: children });
117
+ }
118
+ // Attach compound components to SystemCard
119
+ SystemCard.Header = SystemCardHeader;
120
+ SystemCard.UptimeBar = SystemCardUptimeBar;
121
+ SystemCard.Details = SystemCardDetails;
122
+ SystemCard.Metrics = SystemCardMetrics;
123
+ SystemCard.Charts = SystemCardCharts;
124
+ // Default export
125
+ exports.default = SystemCard;
@@ -0,0 +1,208 @@
1
+ /**
2
+ * ADR-004: SystemCard Styles
3
+ *
4
+ * Collapsible system status card with expand/collapse animation.
5
+ */
6
+
7
+ /* CSS Variables */
8
+ :root {
9
+ --card-border-radius: 8px;
10
+ --card-padding: 1rem;
11
+ --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
12
+ --card-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.15);
13
+ }
14
+
15
+ /* Main card container */
16
+ .systemCard {
17
+ background: var(--ifm-card-background-color, #fff);
18
+ border: 1px solid var(--ifm-color-emphasis-200);
19
+ border-radius: var(--card-border-radius);
20
+ padding: var(--card-padding);
21
+ box-shadow: var(--card-shadow);
22
+ cursor: pointer;
23
+ transition: box-shadow 0.2s ease, border-color 0.2s ease;
24
+ outline: none;
25
+ }
26
+
27
+ .systemCard:hover {
28
+ box-shadow: var(--card-shadow-hover);
29
+ }
30
+
31
+ .systemCard:focus-visible {
32
+ outline: 2px solid var(--ifm-color-primary);
33
+ outline-offset: 2px;
34
+ }
35
+
36
+ /* Expanded state */
37
+ .expanded {
38
+ border-color: var(--ifm-color-primary-light);
39
+ }
40
+
41
+ /* Status indicator border */
42
+ .statusUp {
43
+ border-left: 4px solid var(--status-operational, #22c55e);
44
+ }
45
+
46
+ .statusDegraded {
47
+ border-left: 4px solid var(--status-degraded, #eab308);
48
+ }
49
+
50
+ .statusDown {
51
+ border-left: 4px solid var(--status-outage, #ef4444);
52
+ }
53
+
54
+ .statusMaintenance {
55
+ border-left: 4px solid var(--status-maintenance, #3b82f6);
56
+ }
57
+
58
+ /* Card header */
59
+ .cardHeader {
60
+ display: flex;
61
+ align-items: center;
62
+ justify-content: space-between;
63
+ gap: 1rem;
64
+ }
65
+
66
+ .cardTitleRow {
67
+ display: flex;
68
+ align-items: center;
69
+ gap: 0.75rem;
70
+ flex: 1;
71
+ }
72
+
73
+ .cardTitle {
74
+ margin: 0;
75
+ font-size: 1rem;
76
+ font-weight: 600;
77
+ color: var(--ifm-color-content);
78
+ }
79
+
80
+ /* Expand button */
81
+ .expandButton {
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: center;
85
+ width: 32px;
86
+ height: 32px;
87
+ background: transparent;
88
+ border: 1px solid var(--ifm-color-emphasis-300);
89
+ border-radius: 4px;
90
+ cursor: pointer;
91
+ transition: background-color 0.15s ease;
92
+ }
93
+
94
+ .expandButton:hover {
95
+ background: var(--ifm-color-emphasis-100);
96
+ }
97
+
98
+ .expandIcon {
99
+ font-size: 0.75rem;
100
+ color: var(--ifm-color-content-secondary);
101
+ transition: transform 0.2s ease;
102
+ }
103
+
104
+ .expandIconOpen {
105
+ transform: rotate(180deg);
106
+ }
107
+
108
+ /* Custom header slot */
109
+ .customHeader {
110
+ margin-top: 0.5rem;
111
+ }
112
+
113
+ /* UptimeBar wrapper */
114
+ .uptimeBarWrapper {
115
+ margin-top: 0.75rem;
116
+ }
117
+
118
+ /* Card details (expandable content) */
119
+ .cardDetails {
120
+ max-height: 0;
121
+ overflow: hidden;
122
+ opacity: 0;
123
+ transition: max-height 0.3s ease, opacity 0.2s ease, margin-top 0.3s ease;
124
+ margin-top: 0;
125
+ }
126
+
127
+ .detailsVisible {
128
+ max-height: 500px;
129
+ opacity: 1;
130
+ margin-top: 1rem;
131
+ padding-top: 1rem;
132
+ border-top: 1px solid var(--ifm-color-emphasis-200);
133
+ }
134
+
135
+ /* Metrics grid */
136
+ .metricsGrid {
137
+ display: grid;
138
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
139
+ gap: 1rem;
140
+ }
141
+
142
+ .metricItem {
143
+ display: flex;
144
+ flex-direction: column;
145
+ gap: 0.25rem;
146
+ }
147
+
148
+ .metricLabel {
149
+ font-size: 0.75rem;
150
+ color: var(--ifm-color-content-secondary);
151
+ text-transform: uppercase;
152
+ letter-spacing: 0.05em;
153
+ }
154
+
155
+ .metricValue {
156
+ font-size: 1rem;
157
+ font-weight: 600;
158
+ color: var(--ifm-color-content);
159
+ }
160
+
161
+ /* Charts container */
162
+ .chartsContainer {
163
+ margin-top: 1rem;
164
+ }
165
+
166
+ /* Dark mode */
167
+ [data-theme='dark'] .systemCard {
168
+ background: var(--ifm-card-background-color, #1a1a1a);
169
+ border-color: var(--ifm-color-emphasis-300);
170
+ }
171
+
172
+ [data-theme='dark'] .systemCard:hover {
173
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
174
+ }
175
+
176
+ /* Reduced motion */
177
+ @media (prefers-reduced-motion: reduce) {
178
+ .systemCard,
179
+ .expandIcon,
180
+ .cardDetails {
181
+ transition: none;
182
+ }
183
+
184
+ .cardDetails {
185
+ max-height: none;
186
+ }
187
+
188
+ .cardDetails:not(.detailsVisible) {
189
+ display: none;
190
+ }
191
+ }
192
+
193
+ /* Mobile responsiveness */
194
+ @media (max-width: 600px) {
195
+ .systemCard {
196
+ padding: 0.75rem;
197
+ }
198
+
199
+ .cardTitleRow {
200
+ flex-direction: column;
201
+ align-items: flex-start;
202
+ gap: 0.5rem;
203
+ }
204
+
205
+ .metricsGrid {
206
+ grid-template-columns: 1fr;
207
+ }
208
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Copyright (c) Your Organization
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ /**
8
+ * ADR-004: SystemCardGroup Component
9
+ *
10
+ * Container for grouping multiple SystemCards with collapsible behavior.
11
+ * Shows aggregate status (worst-of) for the group.
12
+ *
13
+ * @see docs/adrs/ADR-004-simplified-status-card-ux.md
14
+ */
15
+ import React, { type ReactNode } from 'react';
16
+ /**
17
+ * Status types (matching SystemCard)
18
+ */
19
+ export type GroupStatus = 'up' | 'degraded' | 'down' | 'maintenance';
20
+ /**
21
+ * Props for SystemCardGroup component
22
+ */
23
+ export interface SystemCardGroupProps {
24
+ /** Group identifier */
25
+ name: string;
26
+ /** Display name */
27
+ displayName: string;
28
+ /** Initially collapsed (default: false) */
29
+ defaultCollapsed?: boolean;
30
+ /** Group status override (derived from children if not provided) */
31
+ status?: GroupStatus;
32
+ /** Semantic heading level (default: 2) */
33
+ headingLevel?: 2 | 3 | 4;
34
+ /** Children (SystemCard components) */
35
+ children: ReactNode;
36
+ /** Optional additional className */
37
+ className?: string;
38
+ }
39
+ /**
40
+ * SystemCardGroup Component
41
+ *
42
+ * Groups multiple SystemCards together with a collapsible header.
43
+ * Displays aggregate status based on worst child status.
44
+ */
45
+ export declare function SystemCardGroup({ name, displayName, defaultCollapsed, status: explicitStatus, headingLevel, children, className, }: SystemCardGroupProps): React.ReactElement;
46
+ export default SystemCardGroup;
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/theme/SystemCardGroup/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAGf;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC;AAYrE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,uCAAuC;IACvC,QAAQ,EAAE,SAAS,CAAC;IACpB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyDD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,WAAW,EACX,gBAAwB,EACxB,MAAM,EAAE,cAAc,EACtB,YAAgB,EAChB,QAAQ,EACR,SAAS,GACV,EAAE,oBAAoB,GAAG,KAAK,CAAC,YAAY,CA0E3C;AAGD,eAAe,eAAe,CAAC"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SystemCardGroup = SystemCardGroup;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ /**
9
+ * Copyright (c) Your Organization
10
+ *
11
+ * This source code is licensed under the MIT license found in the
12
+ * LICENSE file in the root directory of this source tree.
13
+ */
14
+ /**
15
+ * ADR-004: SystemCardGroup Component
16
+ *
17
+ * Container for grouping multiple SystemCards with collapsible behavior.
18
+ * Shows aggregate status (worst-of) for the group.
19
+ *
20
+ * @see docs/adrs/ADR-004-simplified-status-card-ux.md
21
+ */
22
+ const react_1 = require("react");
23
+ const styles_module_css_1 = __importDefault(require("./styles.module.css"));
24
+ /**
25
+ * Status priority for aggregation (higher = worse)
26
+ */
27
+ const STATUS_PRIORITY = {
28
+ up: 0,
29
+ maintenance: 1,
30
+ degraded: 2,
31
+ down: 3,
32
+ };
33
+ /**
34
+ * Status labels for group header
35
+ */
36
+ const GROUP_STATUS_LABELS = {
37
+ up: 'All Operational',
38
+ degraded: 'Partial Issues',
39
+ down: 'Service Outage',
40
+ maintenance: 'Maintenance',
41
+ };
42
+ /**
43
+ * Status class mapping
44
+ */
45
+ const GROUP_STATUS_CLASS_MAP = {
46
+ up: styles_module_css_1.default.groupStatusUp,
47
+ degraded: styles_module_css_1.default.groupStatusDegraded,
48
+ down: styles_module_css_1.default.groupStatusDown,
49
+ maintenance: styles_module_css_1.default.groupStatusMaintenance,
50
+ };
51
+ /**
52
+ * Extract status from SystemCard children
53
+ */
54
+ function getWorstStatus(children) {
55
+ let worstStatus = 'up';
56
+ let worstPriority = STATUS_PRIORITY.up;
57
+ react_1.Children.forEach(children, (child) => {
58
+ if ((0, react_1.isValidElement)(child) && child.props.status) {
59
+ const childStatus = child.props.status;
60
+ const priority = STATUS_PRIORITY[childStatus] ?? 0;
61
+ if (priority > worstPriority) {
62
+ worstPriority = priority;
63
+ worstStatus = childStatus;
64
+ }
65
+ }
66
+ });
67
+ return worstStatus;
68
+ }
69
+ /**
70
+ * Count valid children
71
+ */
72
+ function countChildren(children) {
73
+ let count = 0;
74
+ react_1.Children.forEach(children, (child) => {
75
+ if ((0, react_1.isValidElement)(child)) {
76
+ count++;
77
+ }
78
+ });
79
+ return count;
80
+ }
81
+ /**
82
+ * SystemCardGroup Component
83
+ *
84
+ * Groups multiple SystemCards together with a collapsible header.
85
+ * Displays aggregate status based on worst child status.
86
+ */
87
+ function SystemCardGroup({ name, displayName, defaultCollapsed = false, status: explicitStatus, headingLevel = 2, children, className, }) {
88
+ const [collapsed, setCollapsed] = (0, react_1.useState)(defaultCollapsed);
89
+ // Derive status from children or use explicit override
90
+ const aggregatedStatus = (0, react_1.useMemo)(() => {
91
+ if (explicitStatus)
92
+ return explicitStatus;
93
+ return getWorstStatus(children);
94
+ }, [explicitStatus, children]);
95
+ // Count children
96
+ const childCount = (0, react_1.useMemo)(() => countChildren(children), [children]);
97
+ const handleToggle = (0, react_1.useCallback)(() => {
98
+ setCollapsed((prev) => !prev);
99
+ }, []);
100
+ const handleKeyDown = (0, react_1.useCallback)((event) => {
101
+ if (event.key === 'Enter' || event.key === ' ') {
102
+ event.preventDefault();
103
+ handleToggle();
104
+ }
105
+ }, [handleToggle]);
106
+ const Heading = `h${headingLevel}`;
107
+ const statusLabel = GROUP_STATUS_LABELS[aggregatedStatus];
108
+ const statusClass = GROUP_STATUS_CLASS_MAP[aggregatedStatus];
109
+ const serviceWord = childCount === 1 ? 'service' : 'services';
110
+ return ((0, jsx_runtime_1.jsxs)("section", { className: `${styles_module_css_1.default.systemCardGroup} ${collapsed ? styles_module_css_1.default.collapsed : ''} ${statusClass} ${className || ''}`, "data-group": name, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.groupHeader, children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: styles_module_css_1.default.toggleButton, onClick: handleToggle, onKeyDown: handleKeyDown, "aria-expanded": !collapsed, "aria-label": `Toggle ${displayName} group`, children: (0, jsx_runtime_1.jsx)("span", { className: `${styles_module_css_1.default.expandIcon} ${!collapsed ? styles_module_css_1.default.expandIconOpen : ''}`, children: "\u25BC" }) }), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.groupInfo, children: [(0, jsx_runtime_1.jsx)(Heading, { className: styles_module_css_1.default.groupTitle, children: displayName }), (0, jsx_runtime_1.jsxs)("span", { className: styles_module_css_1.default.groupMeta, children: [(0, jsx_runtime_1.jsxs)("span", { className: styles_module_css_1.default.serviceCount, children: [childCount, " ", serviceWord] }), (0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.statusDot }), (0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.statusLabel, children: statusLabel })] })] })] }), (0, jsx_runtime_1.jsx)("div", { className: `${styles_module_css_1.default.groupContent} ${collapsed ? styles_module_css_1.default.contentHidden : ''}`, "aria-hidden": collapsed, children: children })] }));
111
+ }
112
+ // Default export
113
+ exports.default = SystemCardGroup;