Compare commits

..

1 Commits

Author SHA1 Message Date
Raunak Bhagat
9cad897794 fix: address PR review comments
- Add ContentXl to layouts/README.md description
- Fix misleading routing comment in components.tsx
- Update shared.ts consumer comment to include ContentXl
- Remove unused inputRef from ContentXl and ContentLg
2026-03-01 12:40:41 -08:00
7 changed files with 57 additions and 44 deletions

View File

@@ -5,7 +5,7 @@ import type { SizeVariant } from "@opal/shared";
import SvgEdit from "@opal/icons/edit";
import type { IconFunctionComponent } from "@opal/types";
import { cn } from "@opal/utils";
import { useRef, useState } from "react";
import { useState } from "react";
// ---------------------------------------------------------------------------
// Types
@@ -89,7 +89,6 @@ function ContentLg({
}: ContentLgProps) {
const [editing, setEditing] = useState(false);
const [editValue, setEditValue] = useState(title);
const inputRef = useRef<HTMLInputElement>(null);
const config = CONTENT_LG_PRESETS[sizePreset];
@@ -131,7 +130,6 @@ function ContentLg({
{editValue || "\u00A0"}
</span>
<input
ref={inputRef}
className={cn(
"opal-content-lg-input",
config.titleFont,

View File

@@ -5,7 +5,7 @@ import type { SizeVariant } from "@opal/shared";
import SvgEdit from "@opal/icons/edit";
import type { IconFunctionComponent } from "@opal/types";
import { cn } from "@opal/utils";
import { useRef, useState } from "react";
import { useState } from "react";
// ---------------------------------------------------------------------------
// Types
@@ -109,7 +109,6 @@ function ContentXl({
}: ContentXlProps) {
const [editing, setEditing] = useState(false);
const [editValue, setEditValue] = useState(title);
const inputRef = useRef<HTMLInputElement>(null);
const config = CONTENT_XL_PRESETS[sizePreset];
@@ -189,7 +188,6 @@ function ContentXl({
{editValue || "\u00A0"}
</span>
<input
ref={inputRef}
className={cn(
"opal-content-xl-input",
config.titleFont,

View File

@@ -148,7 +148,8 @@ function Content(props: ContentProps) {
}
}
// ContentMd: main-content/main-ui/secondary with section variant
// ContentMd: main-content/main-ui/secondary with section/heading variant
// (variant defaults to "heading" when omitted on MdContentProps, so both arms are needed)
else if (variant === "section" || variant === "heading") {
layout = (
<ContentMd

View File

@@ -8,7 +8,7 @@ Layout primitives for composing icon + title + description rows. These component
| Component | Description | Docs |
|---|---|---|
| [`Content`](./Content/README.md) | Icon + title + description row. Routes to an internal layout (`ContentLg`, `ContentMd`, or `ContentSm`) based on `sizePreset` and `variant`. | [Content README](./Content/README.md) |
| [`Content`](./Content/README.md) | Icon + title + description row. Routes to an internal layout (`ContentXl`, `ContentLg`, `ContentMd`, or `ContentSm`) based on `sizePreset` and `variant`. | [Content README](./Content/README.md) |
| [`ContentAction`](./ContentAction/README.md) | Wraps `Content` in a flex-row with an optional `rightChildren` slot for action buttons. Adds padding alignment via the shared `SizeVariant` scale. | [ContentAction README](./ContentAction/README.md) |
## Quick Start

View File

@@ -16,7 +16,7 @@
// - Interactive.Container (height + min-width + padding)
// - Button (icon sizing)
// - ContentAction (padding only)
// - Content (ContentLg / ContentMd) (edit-button size)
// - Content (ContentXl / ContentLg / ContentMd) (edit-button size)
// ---------------------------------------------------------------------------
/**

View File

@@ -3,9 +3,9 @@
import React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { cn } from "@/lib/utils";
import type { IconFunctionComponent } from "@opal/types";
import type { IconProps } from "@opal/types";
import Text from "@/refresh-components/texts/Text";
import { Button } from "@opal/components";
import { Content } from "@opal/layouts";
import { SvgX } from "@opal/icons";
import { WithoutStyles } from "@/types";
import { Section, SectionProps } from "@/layouts/general-layouts";
@@ -407,7 +407,7 @@ ModalContent.displayName = DialogPrimitive.Content.displayName;
* ```
*/
interface ModalHeaderProps extends WithoutStyles<SectionProps> {
icon?: IconFunctionComponent;
icon?: React.FunctionComponent<IconProps>;
title: string;
description?: string;
onClose?: () => void;
@@ -416,6 +416,8 @@ const ModalHeader = React.forwardRef<HTMLDivElement, ModalHeaderProps>(
({ icon: Icon, title, description, onClose, children, ...props }, ref) => {
const { closeButtonRef, setHasDescription } = useModalContext();
// useLayoutEffect ensures aria-describedby is set before paint,
// so screen readers announce the description when the dialog opens
React.useLayoutEffect(() => {
setHasDescription(!!description);
}, [description, setHasDescription]);
@@ -438,38 +440,52 @@ const ModalHeader = React.forwardRef<HTMLDivElement, ModalHeaderProps>(
return (
<Section ref={ref} padding={1} alignItems="start" height="fit" {...props}>
<Section
flexDirection="row"
justifyContent="between"
alignItems="start"
gap={0}
padding={0}
>
<div className="relative w-full">
{/* Close button is absolutely positioned because:
1. Figma mocks place it overlapping the top-right of the content area
2. Using ContentAction with rightChildren causes the description
to wrap to the second line early due to the button reserving space */}
<div className="absolute top-0 right-0">{closeButton}</div>
<DialogPrimitive.Title asChild>
<div>
<Content
icon={Icon}
title={title}
description={description}
sizePreset="section"
variant="heading"
/>
{description && (
<DialogPrimitive.Description className="hidden">
{description}
</DialogPrimitive.Description>
)}
</div>
</DialogPrimitive.Title>
</div>
</Section>
<Section gap={0.5}>
{Icon && (
<Section
gap={0}
padding={0}
flexDirection="row"
justifyContent="between"
>
{/*
The `h-[1.5rem]` and `w-[1.5rem]` were added as backups here.
However, prop-resolution technically resolves to choosing classNames over size props, so technically the `size={24}` is the backup.
We specify both to be safe.
# Note
1.5rem === 24px
*/}
<Icon
className="stroke-text-04 h-[1.5rem] w-[1.5rem]"
size={24}
/>
{closeButton}
</Section>
)}
<Section
alignItems="start"
gap={0}
padding={0}
flexDirection="row"
justifyContent="between"
>
<Section alignItems="start" padding={0} gap={0}>
<DialogPrimitive.Title asChild>
<Text headingH3>{title}</Text>
</DialogPrimitive.Title>
{description && (
<DialogPrimitive.Description asChild>
<Text secondaryBody text03>
{description}
</Text>
</DialogPrimitive.Description>
)}
</Section>
{!Icon && closeButton}
</Section>
</Section>
{children}
</Section>
);

View File

@@ -248,7 +248,7 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
bottomSlot={<AgentChatInput agent={agent} onSubmit={handleStartChat} />}
>
<Modal.Header
icon={(props) => <AgentAvatar agent={agent} {...props} size={28} />}
icon={(props) => <AgentAvatar agent={agent} {...props} size={24} />}
title={agent.name}
onClose={() => agentViewerModal.toggle(false)}
/>