Skip to content

Commit 0594dc7

Browse files
kubeclaude
andcommitted
Add vertical orientation and icon-only mode to SegmentGroup
- Add `orientation` prop ("horizontal" | "vertical") with appropriate layout styles for each direction - Add `hideLabel` option to SegmentOption for icon-only segments - Show tooltips on all items with tooltips, not just disabled ones - Hide ItemControl element that added unwanted spacing - Fix content gap: use 1.5 (6px) instead of 4 (16px) between icon/label - Replace overflow:hidden with whitespace:nowrap to prevent content clipping - Add stories: WithIconsOnly, VerticalIconOnly, VerticalIconOnlyMedium, VerticalWithLabels Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ae168f5 commit 0594dc7

47 files changed

Lines changed: 4801 additions & 1392 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

libs/@hashintel/petrinaut/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@hashintel/ds-helpers": "workspace:^",
4444
"@hashintel/refractive": "workspace:^",
4545
"@monaco-editor/react": "4.8.0-rc.3",
46+
"@tanstack/react-form": "1.29.0",
4647
"@xyflow/react": "12.10.1",
4748
"d3-scale": "4.0.2",
4849
"elkjs": "0.11.0",
@@ -52,6 +53,7 @@
5253
"react-icons": "5.5.0",
5354
"react-resizable-panels": "4.6.5",
5455
"typescript": "5.9.3",
56+
"uplot": "1.6.32",
5557
"uuid": "13.0.0",
5658
"vscode-languageserver-types": "3.17.5",
5759
"web-worker": "1.4.1",

libs/@hashintel/petrinaut/panda.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ export default defineConfig({
6464
from: { opacity: "1", transform: "scale(1)" },
6565
to: { opacity: "0", transform: "scale(0.96)" },
6666
},
67+
"drawer-in": {
68+
from: { opacity: "0", transform: "translateX(100px)" },
69+
to: { opacity: "1", transform: "translateX(0)" },
70+
},
71+
"drawer-out": {
72+
from: { opacity: "1", transform: "translateX(0)" },
73+
to: { opacity: "0", transform: "translateX(100px)" },
74+
},
6775
},
6876
},
6977
},

libs/@hashintel/petrinaut/src/components/dialog.tsx

Lines changed: 22 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,16 @@ import type { ComponentProps, ReactNode } from "react";
55
import { TbX } from "react-icons/tb";
66

77
import { usePortalContainerRef } from "../state/portal-container-context";
8+
import {
9+
Body,
10+
Card as PanelCard,
11+
closeButtonStyle,
12+
Footer,
13+
Header as PanelHeader,
14+
outerStyle,
15+
} from "./panel-primitives";
816

9-
// -- Styles ------------------------------------------------------------------
17+
// -- Dialog-specific styles ---------------------------------------------------
1018

1119
const backdropStyle = css({
1220
position: "fixed",
@@ -37,21 +45,10 @@ const positionerStyle = css({
3745
zIndex: "sticky",
3846
});
3947

40-
/** Outer gray container — matches Figma "size=sm, glass=false" frame. */
41-
const outerStyle = css({
42-
backgroundColor: "neutral.s10",
43-
borderRadius: "2xl",
44-
padding: "1",
45-
display: "flex",
46-
flexDirection: "column",
47-
gap: "1",
48+
const dialogOuterStyle = css({
4849
maxWidth: "[400px]",
4950
width: "[90vw]",
5051
maxHeight: "[85vh]",
51-
overflow: "clip",
52-
userSelect: "none",
53-
boxShadow:
54-
"[0px 0px 1px 0px rgba(0,0,0,0.02), 0px 1px 1px -0.5px rgba(0,0,0,0.04), 0px 6px 6px -3px rgba(0,0,0,0.04), 0px 12px 12px -6px rgba(0,0,0,0.03), 0px 24px 24px -12px rgba(0,0,0,0.02)]",
5552
"&[data-state=open]": {
5653
animation: "dialogContentIn 150ms ease-out",
5754
},
@@ -60,94 +57,8 @@ const outerStyle = css({
6057
},
6158
});
6259

63-
/** Inner white card that holds header + body. */
64-
const cardStyle = css({
65-
position: "relative",
66-
backgroundColor: "neutral.s00",
67-
borderRadius: "xl",
68-
boxShadow:
69-
"[0px 0px 0px 1px rgba(0,0,0,0.08), 0px 12px 32px 0px rgba(0,0,0,0.02)]",
70-
overflow: "clip",
71-
display: "flex",
72-
flexDirection: "column",
73-
width: "full",
74-
zIndex: "[2]",
75-
flex: "[1 1 auto]",
76-
minHeight: "[0]",
77-
});
78-
79-
const closeButtonStyle = css({
80-
position: "absolute",
81-
top: "2",
82-
right: "2",
83-
display: "flex",
84-
alignItems: "center",
85-
justifyContent: "center",
86-
width: "[30px]",
87-
height: "[30px]",
88-
fontSize: "base",
89-
color: "neutral.s100",
90-
backgroundColor: "[transparent]",
91-
border: "none",
92-
borderRadius: "lg",
93-
cursor: "pointer",
94-
zIndex: "[3]",
95-
_hover: {
96-
backgroundColor: "neutral.bg.min.hover",
97-
},
98-
});
99-
100-
const headerStyle = css({
101-
display: "flex",
102-
flexDirection: "column",
103-
gap: "1",
104-
paddingX: "5",
105-
paddingTop: "4",
106-
paddingBottom: "4",
107-
paddingRight: "[46px]",
108-
borderBottom: "[1px solid {colors.neutral.a10}]",
109-
flexShrink: "[0]",
110-
});
111-
112-
const titleStyle = css({
113-
fontSize: "lg",
114-
fontWeight: "semibold",
115-
lineHeight: "[20px]",
116-
color: "neutral.fg.heading",
117-
margin: "[0]",
118-
});
119-
120-
const descriptionStyle = css({
121-
fontSize: "sm",
122-
fontWeight: "medium",
123-
lineHeight: "[1.25]",
124-
color: "neutral.s90",
125-
margin: "[0]",
126-
});
127-
128-
const bodyStyle = css({
129-
padding: "5",
130-
overflowY: "auto",
131-
flex: "[1]",
132-
});
133-
134-
const footerStyle = css({
135-
display: "flex",
136-
alignItems: "center",
137-
justifyContent: "flex-end",
138-
gap: "2",
139-
paddingX: "4",
140-
paddingY: "3",
141-
flexShrink: "[0]",
142-
zIndex: "[1]",
143-
});
144-
14560
// -- Subcomponents -----------------------------------------------------------
14661

147-
/**
148-
* Dialog content portalled into the shared .petrinaut-root container.
149-
* Renders the outer gray frame that wraps both the Card and Footer.
150-
*/
15162
const Content = ({
15263
children,
15364
className,
@@ -161,70 +72,35 @@ const Content = ({
16172
<Portal container={portalContainerRef}>
16273
<ArkDialog.Backdrop className={backdropStyle} />
16374
<ArkDialog.Positioner className={positionerStyle}>
164-
<ArkDialog.Content className={cx(outerStyle, className)}>
75+
<ArkDialog.Content
76+
className={cx(outerStyle, dialogOuterStyle, className)}
77+
>
16578
{children}
16679
</ArkDialog.Content>
16780
</ArkDialog.Positioner>
16881
</Portal>
16982
);
17083
};
17184

172-
/**
173-
* Inner white card that holds Header + Body.
174-
* Includes an absolute-positioned close button in the top-right corner.
175-
*/
17685
const Card = ({ children }: { children: ReactNode }) => (
177-
<div className={cardStyle}>
86+
<PanelCard
87+
closeButton={
88+
<ArkDialog.CloseTrigger className={closeButtonStyle} aria-label="Close">
89+
<TbX />
90+
</ArkDialog.CloseTrigger>
91+
}
92+
>
17893
{children}
179-
<ArkDialog.CloseTrigger className={closeButtonStyle} aria-label="Close">
180-
<TbX />
181-
</ArkDialog.CloseTrigger>
182-
</div>
94+
</PanelCard>
18395
);
18496

185-
/**
186-
* Dialog header with title and optional description.
187-
* Sits inside Card, has a subtle bottom border.
188-
*/
18997
const Header = ({
19098
children,
19199
description,
192100
}: {
193101
children: ReactNode;
194102
description?: ReactNode;
195-
}) => (
196-
<div className={headerStyle}>
197-
<ArkDialog.Title className={titleStyle}>{children}</ArkDialog.Title>
198-
{description != null && (
199-
<ArkDialog.Description className={descriptionStyle}>
200-
{description}
201-
</ArkDialog.Description>
202-
)}
203-
</div>
204-
);
205-
206-
/**
207-
* Scrollable body area inside the Card.
208-
*/
209-
const Body = ({
210-
children,
211-
className,
212-
}: {
213-
children: ReactNode;
214-
className?: string;
215-
}) => <div className={cx(bodyStyle, className)}>{children}</div>;
216-
217-
/**
218-
* Footer area for action buttons. Sits outside the Card,
219-
* in the outer gray frame.
220-
*/
221-
const Footer = ({
222-
children,
223-
className,
224-
}: {
225-
children: ReactNode;
226-
className?: string;
227-
}) => <div className={cx(footerStyle, className)}>{children}</div>;
103+
}) => <PanelHeader description={description}>{children}</PanelHeader>;
228104

229105
// -- Compound export ---------------------------------------------------------
230106

0 commit comments

Comments
 (0)