Skip to content

Commit 35743b0

Browse files
committed
coral csa cto
1 parent f9943be commit 35743b0

File tree

18 files changed

+1700
-0
lines changed

18 files changed

+1700
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# coral.config
2+
3+
**Coral Config** defines the application’s structural baseline — component scaffolding, prebuilt modules, import bundling, and system-wide utilities.
4+
5+
> This folder is not intended for feature development.
6+
7+
---
8+
9+
## What Lives Here
10+
11+
- `components/` – Stateless layout primitives like `Header`, `PanelLeft`, `PanelRight`, `Content`, etc. These are styled and functional, but intentionally generic.
12+
- `modules/` – Composite UI blocks that encapsulate common layouts and logic (e.g., a full-width `ChatPanel`, or a `PanelLeft` with navigation baked in). These are production-ready and reusable
13+
- `imports/` – Centralized icon and asset imports to streamline DX and reduce boilerplate.
14+
- `eventbus.ts` – Shared event system for cross-component communication.
15+
- `PanelRegistry.ts` – Central config for registering and referencing dynamic panel zones.
16+
17+
---
18+
19+
## When Should You Modify This?
20+
21+
Only when you're:
22+
- Creating or updating shared UI primitives
23+
- Building new reusable modules
24+
- Extending foundational architecture
25+
26+
Avoid editing directly unless your change impacts system-level behavior. When in doubt, route it through the Coral steward or log it in the dev sync.
27+
28+
---
29+
30+
## Design Philosophy
31+
32+
Coral isolates **infrastructure from implementation** — keeping base components clean and predictable, while enabling rapid development through composable modules.
33+
34+
This layer isn’t for experiments. It’s for the architecture that lets experiments happen without breaking production.
35+
36+
---
37+
38+
🐙
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import React, { useState, ReactNode, ReactElement } from "react";
2+
import PanelToolbar from "../Panels/PanelLeftToolbar.js"; // Import to identify toolbar
3+
4+
interface ContentProps {
5+
children?: ReactNode;
6+
}
7+
8+
const Content: React.FC<ContentProps> = ({ children }) => {
9+
const childrenArray = React.Children.toArray(children) as ReactElement[];
10+
const toolbar = childrenArray.find(
11+
(child) => React.isValidElement(child) && child.type === PanelToolbar
12+
);
13+
const content = childrenArray.filter(
14+
(child) => !(React.isValidElement(child) && child.type === PanelToolbar)
15+
);
16+
17+
return (
18+
<div
19+
className="content"
20+
style={{
21+
display: "flex",
22+
flex: "1",
23+
flexDirection: "column",
24+
height: "100%",
25+
boxSizing: "border-box",
26+
position: "relative",
27+
minWidth: '320px',
28+
29+
}}
30+
>
31+
{toolbar && <div style={{ flexShrink: 0 }}>{toolbar}</div>}
32+
33+
<div
34+
className="panelContent"
35+
style={{
36+
display: "flex",
37+
flexDirection: "column",
38+
flex: 1,
39+
width:'100%',
40+
41+
42+
overflow: "hidden", // prevent double scrollbars
43+
minHeight: 0, // allow child to shrink properly
44+
}}
45+
>
46+
{content}
47+
</div>
48+
</div>
49+
);
50+
};
51+
52+
export default Content;
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import React, { ReactNode } from "react";
2+
import { Body1Strong } from "@fluentui/react-components";
3+
4+
interface ContentToolbarProps {
5+
panelIcon?: ReactNode;
6+
panelTitle?: string | null;
7+
children?: ReactNode;
8+
}
9+
10+
const ContentToolbar: React.FC<ContentToolbarProps> = ({
11+
panelIcon,
12+
panelTitle,
13+
children,
14+
}) => {
15+
return (
16+
<div
17+
className="panelToolbar"
18+
style={{
19+
display: "flex",
20+
alignItems: "center",
21+
gap: "8px",
22+
padding: "16px",
23+
boxSizing: "border-box",
24+
height: "56px",
25+
}}
26+
>
27+
{(panelIcon || panelTitle) && (
28+
<div
29+
className="panelTitle"
30+
style={{
31+
display: "flex",
32+
alignItems: "center",
33+
gap: "6px",
34+
flex: "1 1 auto",
35+
overflow: "hidden", // Ensure title section is contained
36+
}}
37+
>
38+
{panelIcon && (
39+
<div
40+
style={{
41+
flexShrink: 0, // Prevent the icon from shrinking
42+
display: "flex",
43+
alignItems: "center",
44+
}}
45+
>
46+
{panelIcon}
47+
</div>
48+
)}
49+
{panelTitle && (
50+
<Body1Strong
51+
style={{
52+
whiteSpace: "nowrap",
53+
overflow: "hidden",
54+
textOverflow: "ellipsis",
55+
}}
56+
>
57+
{panelTitle}
58+
</Body1Strong>
59+
)}
60+
</div>
61+
)}
62+
<div
63+
className="panelTools"
64+
style={{
65+
display: "flex",
66+
alignItems: "center",
67+
gap: "0",
68+
}}
69+
>
70+
{children}
71+
</div>
72+
</div>
73+
);
74+
};
75+
76+
export default ContentToolbar;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React from "react";
2+
import { Avatar, Subtitle2 } from "@fluentui/react-components";
3+
import MsftColor from "../../imports/MsftColor.tsx"; // Default icon component
4+
5+
/**
6+
* @component
7+
* @name Header
8+
* @description A header component for displaying a logo, title, and optional subtitle.
9+
*
10+
* @prop {React.ReactNode} [logo] - Custom logo (defaults to Microsoft icon).
11+
* @prop {string} [title="Microsoft"] - Main title text.
12+
* @prop {string} [subtitle] - Optional subtitle displayed next to the title.
13+
* @prop {React.ReactNode} [children] - Optional header toolbar (e.g., buttons, menus).
14+
*/
15+
type HeaderProps = {
16+
logo?: React.ReactNode;
17+
title?: string;
18+
subtitle?: string;
19+
children?: React.ReactNode;
20+
};
21+
22+
const Header: React.FC<HeaderProps> = ({ logo, title = "Microsoft", subtitle, children }) => {
23+
return (
24+
<header
25+
style={{
26+
display: "flex",
27+
justifyContent: "space-between",
28+
alignItems: "center",
29+
width: "100%",
30+
backgroundColor: "var(--colorNeutralBackgroundAlpha)",
31+
borderBottom: "1px solid var(--colorNeutralStroke2)",
32+
padding: "16px",
33+
height: "64px",
34+
boxSizing: "border-box",
35+
gap: "12px",
36+
}}
37+
data-figma-component="Header"
38+
>
39+
<div
40+
style={{
41+
display: "flex",
42+
justifyContent: "space-between",
43+
alignItems: "center",
44+
gap: "8px",
45+
}}
46+
>
47+
{/* Render custom logo or default MsftColor logo */}
48+
<Avatar shape="square" color={null} icon={logo || <MsftColor />} />
49+
50+
{/* Render title and optional subtitle */}
51+
<Subtitle2 style={{ whiteSpace: "nowrap", marginTop: "-2px" }}>
52+
{title}
53+
{subtitle && (
54+
<span style={{ fontWeight: "400" }}> | {subtitle}</span>
55+
)}
56+
</Subtitle2>
57+
</div>
58+
59+
{/* HEADER TOOLBAR (rendered only if passed as a child) */}
60+
{children}
61+
</header>
62+
);
63+
};
64+
65+
export default Header;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React, { useState } from "react";
2+
import { Toolbar, ToolbarDivider, Avatar } from "@fluentui/react-components";
3+
import eventBus from "../eventbus";
4+
import PanelRightToggles from "./PanelRightToggles"; // Import PanelRightToggles
5+
6+
7+
interface HeaderToolsProps {
8+
children?: React.ReactNode;
9+
}
10+
11+
const HeaderTools: React.FC<HeaderToolsProps> = ({ children }) => {
12+
13+
14+
return (
15+
<Toolbar
16+
style={{
17+
display: "flex",
18+
flex: "0",
19+
alignItems: "center",
20+
flexDirection: "row-reverse",
21+
padding: "4px 0",
22+
}}
23+
>
24+
{children}
25+
</Toolbar>
26+
);
27+
};
28+
29+
export default HeaderTools;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import React, { useState, useEffect, ReactElement } from "react";
2+
import { Toolbar, ToggleButton, ToggleButtonProps } from "@fluentui/react-components";
3+
import eventBus from "../eventbus.js";
4+
5+
type PanelRightTogglesProps = {
6+
children: React.ReactNode;
7+
};
8+
9+
const PanelRightToggles: React.FC<PanelRightTogglesProps> = ({ children }) => {
10+
const [activePanel, setActivePanel] = useState<"first" | "second" | "third" | "fourth" | null>(null);
11+
12+
const panelTypes = ["first", "second", "third", "fourth"] as const;
13+
14+
useEffect(() => {
15+
const handlePanelToggle = (panel: "first" | "second" | "third" | "fourth" | null) => {
16+
setActivePanel(panel);
17+
};
18+
19+
const handlePanelInit = ({ panelType, isActive }: { panelType: string; isActive: boolean }) => {
20+
if (isActive) setActivePanel(panelType as any);
21+
};
22+
23+
eventBus.on("setActivePanel", handlePanelToggle);
24+
eventBus.on("panelInitState", handlePanelInit);
25+
26+
return () => {
27+
eventBus.off("setActivePanel", handlePanelToggle);
28+
eventBus.off("panelInitState", handlePanelInit);
29+
};
30+
}, []);
31+
32+
const togglePanel = (panel: "first" | "second" | "third" | "fourth" | null) => {
33+
eventBus.emit("setActivePanel", activePanel === panel ? null : panel);
34+
};
35+
36+
const isToggleButton = (child: React.ReactNode): child is ReactElement<ToggleButtonProps> => {
37+
return React.isValidElement(child) && child.type === ToggleButton;
38+
};
39+
40+
return (
41+
<Toolbar style={{ padding: "4px 0", display: "flex", flexDirection: "row-reverse" }}>
42+
{React.Children.map(children, (child, index) => {
43+
const panelType = panelTypes[index];
44+
if (isToggleButton(child) && panelType) {
45+
return React.cloneElement(child, {
46+
onClick: () => togglePanel(panelType),
47+
checked: activePanel === panelType,
48+
});
49+
}
50+
return child;
51+
})}
52+
</Toolbar>
53+
);
54+
};
55+
56+
export default PanelRightToggles;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// coral.config/components/Layout/CoralShellColumn.tsx
2+
// Structural wrapper for top-level app layout (vertical orientation)
3+
4+
import React from "react";
5+
6+
const CoralShellColumn: React.FC<{ children: React.ReactNode }> = ({ children }) => {
7+
return (
8+
<div
9+
style={{
10+
display: "flex",
11+
flexDirection: "column",
12+
height: "100vh",
13+
overflow: "hidden",
14+
backgroundColor: "var(--colorNeutralBackground3)",
15+
}}
16+
>
17+
{children}
18+
</div>
19+
);
20+
};
21+
22+
export default CoralShellColumn;
23+
24+
25+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// coral.config/components/Layout/CoralShellRow.tsx
2+
// Structural wrapper for main workspace layout (horizontal split)
3+
4+
import React from "react";
5+
6+
const CoralShellRow: React.FC<{ children: React.ReactNode }> = ({ children }) => {
7+
return (
8+
<div
9+
style={{
10+
display: "flex",
11+
flex: 1,
12+
overflow: "hidden",
13+
}}
14+
>
15+
{children}
16+
</div>
17+
);
18+
};
19+
20+
export default CoralShellRow;

0 commit comments

Comments
 (0)