Skip to content

feat(evo-react): add evo-details component#640

Open
HenriqueLimas wants to merge 2 commits intomainfrom
evo-details-react
Open

feat(evo-react): add evo-details component#640
HenriqueLimas wants to merge 2 commits intomainfrom
evo-details-react

Conversation

@HenriqueLimas
Copy link
Copy Markdown
Member

  • Fixes #

Description

Migrates ebay-details from @ebay/ebayui-core-react to @evo-web/react as a new compound component, and adds the missing leading attribute tag to evo-details in @evo-web/marko.

@evo-web/react — new evo-details component

Uses a compound sub-component API backed by React context instead of flat props or React.Children scanning (see ADR 0005):

<EvoDetails size="small" alignment="center" onToggle={handler}>
  <EvoDetailsSummary>
    <EvoDetailsLeading><EvoIconLightbulb16 /></EvoDetailsLeading>
    <EvoDetailsLabel>Show me the details!</EvoDetailsLabel>
  </EvoDetailsSummary>
  <EvoDetailsContent>Content</EvoDetailsContent>
</EvoDetails>

Exported components: EvoDetails, EvoDetailsSummary, EvoDetailsLeading, EvoDetailsLabel, EvoDetailsContent.

@evo-web/markoleading attribute tag on evo-details

Adds the leading attribute tag that was present in @ebay/ebayui-core (Marko 5) but was missed during the Marko 6 migration.

Notes

  • ADR 0005 documents the compound component composition pattern and why React.Children / React.cloneElement were ruled out.
  • evo-migrate-react and evo-app-migrate-react skills updated with migration guidance for this component.
  • The evo-react API intentionally diverges from evo-marko's <@summary> attribute tag pattern, which has no direct React equivalent.

Screenshots

Checklist

  • I verify the linked issue has been triaged ("Needs Triage" label removed)
  • I verify all changes are within scope of the linked issue
  • I added/updated/removed testing (Storybook in Skin) coverage as appropriate

Migrates ebay-details from @ebay/ebayui-core-react to @evo-web/react using
a compound sub-component API (EvoDetails, EvoDetailsSummary, EvoDetailsLeading,
EvoDetailsLabel, EvoDetailsContent) backed by React context, avoiding React.Children.

Also adds the missing `leading` attribute tag to evo-details in @evo-web/marko,
and adds ADR 0005 documenting the child component composition pattern.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 23, 2026 21:43
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 23, 2026

🦋 Changeset detected

Latest commit: aa694d7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@evo-web/marko Patch
@evo-web/react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new evo-details compound component to @evo-web/react (migrated from ebay-details) and updates @evo-web/marko’s evo-details tag to restore the missing leading attribute tag from the Marko 5 implementation.

Changes:

  • Add EvoDetails + sub-components (Summary, Leading, Label, Content) to @evo-web/react, including stories and SSR/browser tests.
  • Add leading attribute tag support to @evo-web/marko’s evo-details, plus story/test/example updates.
  • Add ADR 0005 documenting the compound component composition approach, and update migration skill docs + changesets.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/evo-react/src/index.ts Exports new evo-details components/types from the package entry point
packages/evo-react/src/evo-details/types.ts Defines evo-details public prop and type surface
packages/evo-react/src/evo-details/test/test.server.tsx Adds SSR snapshot coverage for evo-details
packages/evo-react/src/evo-details/test/test.browser.tsx Adds browser interaction coverage (toggle, classes, slots)
packages/evo-react/src/evo-details/test/snapshots/test.server.tsx.snap Stores SSR snapshot expectations
packages/evo-react/src/evo-details/index.ts Component folder barrel exports for evo-details
packages/evo-react/src/evo-details/details.tsx Implements EvoDetails wrapper + context provider + Skin import
packages/evo-react/src/evo-details/details.stories.tsx Adds Storybook docs/stories for evo-details
packages/evo-react/src/evo-details/details-summary.tsx Implements summary sub-component (classes + chevron icon)
packages/evo-react/src/evo-details/details-leading.tsx Implements leading slot sub-component
packages/evo-react/src/evo-details/details-label.tsx Implements label slot sub-component
packages/evo-react/src/evo-details/details-content.tsx Implements content wrapper sub-component with as support
packages/evo-react/src/evo-details/context.ts Adds context + hook used by sub-components
packages/evo-react/src/evo-details/README.md Adds minimal documentation pointing to Storybook
packages/evo-marko/src/tags/evo-details/test/test.server.ts Extends server snapshot coverage to include leading variant
packages/evo-marko/src/tags/evo-details/index.marko Adds leading attribute tag support and renders it in the summary
packages/evo-marko/src/tags/evo-details/examples/with-leading.marko Adds Marko example demonstrating <@leading> usage
packages/evo-marko/src/tags/evo-details/details.stories.ts Adds Storybook story + argTypes/docs for leading attribute tag
docs/adr/0005-evo-react-child-component-composition.md Documents compound component pattern decision for evo-react
.claude/skills/evo-migrate-react/SKILL.md Updates migration authoring guidance (context usage, icon/testing rules, etc.)
.claude/skills/evo-app-migrate-react/SKILL.md Adds app-level migration guidance from ebay-details to compound evo-details API
.changeset/add-evo-details-react.md Changeset for publishing the new evo-react component
.changeset/add-evo-details-leading.md Changeset for publishing the Marko leading attr tag addition

Comment thread packages/evo-react/src/evo-details/details.tsx
Comment thread packages/evo-react/src/index.ts Outdated
Comment on lines +49 to +52
<EvoDetailsSummary>
<EvoDetailsLeading>
<span>icon</span>
</EvoDetailsLeading>
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test uses a custom placeholder (<span>icon</span>) for the leading slot. The repo guidance explicitly says stories/tests should use an existing EvoIcon* component instead of placeholders (see .claude/skills/evo-migrate-react/SKILL.md around the “This applies to stories and tests as well” note). Using a real icon here will keep tests aligned with expected consumer usage and avoid drift in markup.

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +97
<EvoDetailsLeading>
<span data-testid="icon">icon</span>
</EvoDetailsLeading>
<EvoDetailsLabel>Details</EvoDetailsLabel>
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test uses a custom placeholder (<span data-testid="icon">icon</span>) for the leading slot. Per .claude/skills/evo-migrate-react/SKILL.md (stories/tests should use an existing EvoIcon* component rather than placeholder icons), please switch this to a real Evo icon component and attach the test id to that element if needed.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +19
function Details(props: Partial<ComponentProps<typeof EvoDetails>> = {}) {
return (
<EvoDetails {...props}>
<EvoDetailsSummary>
<EvoDetailsLabel>Show me the details!</EvoDetailsLabel>
</EvoDetailsSummary>
<EvoDetailsContent>Content</EvoDetailsContent>
</EvoDetails>
);
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These SSR snapshots render EvoDetails (which includes EvoIconChevronDown16) without an EvoIconProvider. On the server, EvoIcon logs a console.warn when rendered without the provider, so this test file will emit warnings during normal test runs. Consider wrapping the rendered tree in <EvoIconProvider> (or explicitly stubbing console.warn) to keep the test output clean and representative of recommended SSR usage.

Copilot uses AI. Check for mistakes.
Comment thread .changeset/add-evo-details-react.md
…ve Alignment from public API

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@LuLaValva LuLaValva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Just one change on the Marko side and some high-level thoughts on design decisions for React


No prop changes. Global renames (Step 2) are sufficient.

### `ebay-details`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list is going to get really long once everything's in here... maybe we should have a separate markdown file for each component?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah probably we should start moving around.

</EvoDetailsLeading>
<EvoDetailsLabel>How do I get started?</EvoDetailsLabel>
</EvoDetailsSummary>
<EvoDetailsContent>Content</EvoDetailsContent>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we planning on always having *Content tags? I'd hope that in many cases we can just keep the content inline

<EvoDetails size="small" onToggle={handler}>
  <EvoDetailsSummary>
    <EvoDetailsLeading>
      <EvoIconLightbulb16 />
    </EvoDetailsLeading>
    How do I get started?
  </EvoDetailsSummary>
  Content
</EvoDetails>

Copy link
Copy Markdown
Member Author

@HenriqueLimas HenriqueLimas Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not always, it will depend on the component and how skin organizes it. Having the component allow the developer to add other properties like class names to the container, but it will depend for each component might be different.

Comment on lines +2 to +3
<@summary>Details</@summary>
<@leading><evo-icon-lightbulb-16/></@leading>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we nest <@leading> inside <@summary> instead? It'll require a <const/{ leading, ...rest }=summary/> on the consuming side but I think that's worth it

Suggested change
<@summary>Details</@summary>
<@leading><evo-icon-lightbulb-16/></@leading>
<@summary>
<@leading><evo-icon-lightbulb-16/></@leading>
Details
</@summary>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be wrong no? It will render the icon inside the summary text? But it is a sibling

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the markup it is a child of <summary>, not a sibling...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I guess you're right but it does mess with my mental model a little bit. I've also never been a fan of @leading as a name, maybe that's part of it. How about leadingIcon?

Comment on lines +23 to +31
<EvoDetails size="small" onToggle={handler}>
<EvoDetailsSummary>
<EvoDetailsLeading>
<EvoIconLightbulb16 />
</EvoDetailsLeading>
<EvoDetailsLabel>How do I get started?</EvoDetailsLabel>
</EvoDetailsSummary>
<EvoDetailsContent>Content</EvoDetailsContent>
</EvoDetails>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on using an object instead of individual components, like Radix does? Might make more sense for grouping, but I'm not sure

<EvoDetails.Root size="small" onToggle={handler}>
  <EvoDetails.Summary>
    <EvoDetails.Leading>
      <EvoIconLightbulb16 />
    </EvoDetails.Leading>
    <EvoDetails.Label>How do I get started?</EvoDetails.Label>
  </EvoDetails.Summary>
  <EvoDetails.Content>Content</EvoDetails.Content>
</EvoDetails.Root>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have both at some point like base-ui has.

@@ -0,0 +1,13 @@
import { createContext, useContext } from "react";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it was up to me I'd probably put all of the component parts in one file, you know better than I do though

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having in a separate file prevents the risk of circular dependencies since we have multiple components.

Copy link
Copy Markdown
Member

@LuLaValva LuLaValva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving because evo-react is still in alpha, but some of the conversations here are maybe worth continuing as more components are migrated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants