Skip to content

feat(vertical-stepper,card-stepper): new TEDI-Ready components #172 - #690

Open
airikej wants to merge 16 commits into
rcfrom
feat/172-verticalstepper-new-tedi-ready-component
Open

feat(vertical-stepper,card-stepper): new TEDI-Ready components #172#690
airikej wants to merge 16 commits into
rcfrom
feat/172-verticalstepper-new-tedi-ready-component

Conversation

@airikej

@airikej airikej commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

https://storybook.tedi.ee/react/feat/172-verticalstepper-new-tedi-ready-component/?path=/docs/tedi-ready-components-navigation-verticalstepper--docs

https://storybook.tedi.ee/react/feat/172-verticalstepper-new-tedi-ready-component/?path=/docs/tedi-ready-components-navigation-cardstepper--docs


Summary by CodeRabbit

  • New Features
    • Added accessible VerticalStepper navigation with expandable sub-steps.
    • Added compact CardStepper with progress, navigation, counters, and step-list dialog.
    • Added a reusable bottom-sheet presentation for mobile navigation content.
  • Documentation
    • Added component reference documentation and Storybook examples for both steppers.
  • Bug Fixes / Updates
    • Deprecated older VerticalStepper components in favor of the new API.
    • Preserved semantic card-button icon colors during hover and active states.
    • Updated the table of contents mobile view to use the bottom sheet.
  • Tests
    • Added comprehensive accessibility and behavior coverage for both steppers.

@airikej airikej linked an issue Jun 25, 2026 that may be closed by this pull request
21 tasks
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 86cb2d65-8afb-4210-ab09-4e71aaf9fa3e

📥 Commits

Reviewing files that changed from the base of the PR and between d369b6b and 3bdd4a3.

📒 Files selected for processing (3)
  • src/tedi/components/navigation/card-stepper/card-stepper.module.scss
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.module.scss
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.stories.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/tedi/components/navigation/card-stepper/card-stepper.module.scss
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.stories.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.module.scss

📝 Walkthrough

Walkthrough

Adds VerticalStepper and CardStepper with accessible navigation, expandable sub-items, modal step lists, styling, tests, Storybook stories, documentation, exports, localized labels, and deprecation markers for community steppers.

Changes

Stepper navigation migration

Layer / File(s) Summary
Migration markers, labels, and exports
src/community/components/vertical-stepper/..., src/tedi/providers/label-provider/labels-map.ts, src/tedi/index.ts, src/tedi/components/navigation/*/index.ts, src/tedi/components/buttons/card-button/card-button.module.scss
Community steppers are deprecated. Stepper labels and public exports are added. Storybook metadata is updated. Semantic card-button icon colors remain unchanged during hover and active states.
VerticalStepper implementation
src/tedi/components/navigation/vertical-stepper/*, src/tedi/components/navigation/vertical-stepper/vertical-stepper.spec.tsx, src/tedi/components/navigation/vertical-stepper/vertical-stepper.stories.tsx, skills/tedi-react/references/components.md
Adds numbered items, current-state ARIA semantics, interactive titles, expandable controlled or uncontrolled sub-items, compact styling, tests, stories, and reference documentation.
Sheet overlay and navigation integration
src/tedi/components/overlays/sheet/*, src/tedi/components/navigation/table-of-contents/...
Adds a bottom Sheet built on Modal. Migrates TableOfContentsCollapsible to use it with updated close handling and sizing styles.
CardStepper implementation
src/tedi/components/navigation/card-stepper/*, skills/tedi-react/references/components.md
Adds data-driven and compound APIs with active-step control, navigation, progress segments, status presentation, bottom slots, modal step lists, jump restrictions, tests, stories, styling, and documentation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant VerticalStepper
  participant VerticalStepperItem
  participant VerticalStepperSubItem
  participant User
  VerticalStepper->>VerticalStepperItem: clone with index and compact context
  User->>VerticalStepperItem: toggle expandable step
  VerticalStepperItem->>VerticalStepperSubItem: render nested sub-items
  User->>VerticalStepperSubItem: activate link or button
Loading
sequenceDiagram
  participant User
  participant CardStepper
  participant Sheet
  participant VerticalStepper
  User->>CardStepper: open step list
  CardStepper->>Sheet: open bottom sheet
  CardStepper->>VerticalStepper: render step rows
  User->>VerticalStepper: select navigable step
  VerticalStepper->>CardStepper: invoke step selection
  CardStepper->>Sheet: close sheet
Loading

Possibly related PRs

Suggested reviewers: mart-sessman, ly-tempel-bitweb

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the two new TEDI-Ready components introduced by the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/172-verticalstepper-new-tedi-ready-component

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.14815% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...omponents/navigation/card-stepper/card-stepper.tsx 96.46% 3 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/tedi/components/navigation/card-stepper/card-stepper.spec.tsx`:
- Around line 1-13: The modal mock in CardStepperSpec uses any for its props,
which violates the TypeScript guidance; replace the untyped Modal,
Modal.Content, Modal.Header, and Modal.Body props with explicit interfaces or
shared prop types. Update the jest.mock for modal in card-stepper.spec.tsx so
the mock components are properly typed while preserving the current
open/children behavior.

In `@src/tedi/components/navigation/card-stepper/card-stepper.stories.tsx`:
- Around line 26-31: The story meta in card-stepper.stories.tsx is missing the
required Storybook status metadata in meta.parameters. Update the default export
metadata alongside the existing design block to include status, and keep the
pattern consistent with the storybook metadata used in other stories. If needed,
verify the default story and other visual variants remain defined under the same
CardStepper story module.

In `@src/tedi/components/navigation/vertical-stepper/vertical-stepper-item.tsx`:
- Around line 49-50: VerticalStepperItem currently exposes an `as` prop but is
still a plain function component; refactor it to the repository’s polymorphic
`forwardRef` pattern. Update the `VerticalStepperItem` component in
`vertical-stepper-item.tsx` to use `React.forwardRef` with generic typing (`<C
extends React.ElementType>`), and thread the ref through the rendered element
while preserving the existing `as` behavior and props typing. Use the existing
`VerticalStepperItem` symbol and its polymorphic props definitions as the place
to apply the change.

In
`@src/tedi/components/navigation/vertical-stepper/vertical-stepper-sub-item.tsx`:
- Around line 42-53: The VerticalStepperSubItem component is using a fixed
element switch instead of the required polymorphic ref-forwarding pattern.
Refactor VerticalStepperSubItemProps and VerticalStepperSubItem to use a generic
`<C extends React.ElementType = 'div'>` with `forwardRef`, so the `as` prop
drives the rendered element type and the ref is forwarded correctly. Update the
current `Element` selection logic inside VerticalStepperSubItem to derive from
`as` dynamically and preserve existing interactive/non-interactive behavior
while passing the ref to the rendered element.

In `@src/tedi/components/navigation/vertical-stepper/vertical-stepper.spec.tsx`:
- Around line 40-43: The vertical stepper spec is using non-semantic DOM access
via querySelector for the current step assertion. Update the test in the
vertical stepper spec to use semantic RTL queries such as getByRole or
getByLabelText to locate the active step, and keep the assertions against the
returned element instead of querying the DOM directly. If you need to verify
there is only one current step, use a semantic query pattern consistent with the
existing VerticalStepper test setup rather than selector-based matching.

In
`@src/tedi/components/navigation/vertical-stepper/vertical-stepper.stories.tsx`:
- Around line 27-32: The story metadata in the vertical stepper stories
currently includes design details but is missing the required status entry in
meta.parameters. Update the default export in vertical-stepper.stories.tsx to
include status alongside the existing design metadata, and verify the story file
still follows the project convention with a Default story and any key visual
variants.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 70676b51-291f-4046-be6f-1c8db6246bb1

📥 Commits

Reviewing files that changed from the base of the PR and between 3855074 and 618d8b6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (22)
  • package.json
  • skills/tedi-react/references/components.md
  • src/community/components/vertical-stepper/step-item/step-item.tsx
  • src/community/components/vertical-stepper/sub-item/sub-item.tsx
  • src/community/components/vertical-stepper/vertical-stepper.stories.tsx
  • src/community/components/vertical-stepper/vertical-stepper.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper-step.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.module.scss
  • src/tedi/components/navigation/card-stepper/card-stepper.spec.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.stories.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.tsx
  • src/tedi/components/navigation/card-stepper/index.ts
  • src/tedi/components/navigation/vertical-stepper/index.ts
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper-context.ts
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper-item.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper-sub-item.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.module.scss
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.spec.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.stories.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.tsx
  • src/tedi/index.ts
  • src/tedi/providers/label-provider/labels-map.ts

Comment thread src/tedi/components/navigation/card-stepper/card-stepper.spec.tsx Outdated
Comment thread src/tedi/components/navigation/vertical-stepper/vertical-stepper-sub-item.tsx Outdated
Comment thread src/tedi/components/navigation/vertical-stepper/vertical-stepper.spec.tsx Outdated
justify-content: center;
width: 1.75rem;
height: 1.75rem;
font-size: var(--body-small-size);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

--body-small-size is not defined - pls check

border-radius: 50%;
}

.tedi-vertical-stepper__number {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

in Figma, font-weight is bold
font-weight: var(--body-bold-weight, 700);

state="completed"
href="#i1"
info={
<StatusBadge color="success" variant="filled">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

use bordered badge to match figma

),
};

export const Compact: Story = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Vertical alignment of the indicators look off, should be center-aligned

Image

@@ -0,0 +1,111 @@
.tedi-card-stepper {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

when looking at Figma design, there is no padding nor border at the bottom of the stepper


.tedi-card-stepper__counter {
flex-shrink: 0;
font-size: var(--body-extra-small-size);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

figma uses --body-small-regular

font-size: var(--body-small-regular-size, 14px);
font-weight: var(--body-small-regular-weight, 400);
line-height: var(--body-small-regular-line-height, 20px); /* 142.857% */

render: () => (
<VerticalSpacing size={1}>
<Row alignItems="center">
<Col xs={12} md={2} />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

md is still a breakpoint too small I believe:

Image

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/tedi/components/navigation/vertical-stepper/vertical-stepper.spec.tsx (1)

253-260: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Avoid reintroducing selector-based assertions here.

container.querySelector('.tedi-vertical-stepper__number') couples this test to CSS implementation details again. Please scope the check to the rendered list item and assert the absence of the number via Testing Library queries so the test survives classname/markup refactors.

Suggested change
-    const { container } = render(
+    render(
       <VerticalStepper compact>
         <VerticalStepper.Item title="Plain" />
       </VerticalStepper>
     );
-    expect(container.querySelector('.tedi-vertical-stepper__number')).not.toBeInTheDocument();
+    expect(within(screen.getByRole('listitem')).queryByText('1')).not.toBeInTheDocument();
     expect(screen.queryByRole('img')).not.toBeInTheDocument();

As per coding guidelines, "Use semantic queries in tests (getByRole, getByLabelText) instead of non-semantic queries"; as per path instructions, TEDI tests should "use semantic queries in tests (avoid getByTestId unless necessary)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tedi/components/navigation/vertical-stepper/vertical-stepper.spec.tsx`
around lines 253 - 260, The VerticalStepper compact-mode test is using a CSS
selector via container.querySelector for the step number, which reintroduces
implementation coupling. Update the assertion in the VerticalStepper.Item test
to scope within the rendered list item and use Testing Library semantic queries
to verify the number is absent, keeping only role-based checks like the existing
queryByRole('img') where appropriate.

Sources: Coding guidelines, Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/tedi/components/navigation/vertical-stepper/vertical-stepper.spec.tsx`:
- Around line 253-260: The VerticalStepper compact-mode test is using a CSS
selector via container.querySelector for the step number, which reintroduces
implementation coupling. Update the assertion in the VerticalStepper.Item test
to scope within the rendered list item and use Testing Library semantic queries
to verify the number is absent, keeping only role-based checks like the existing
queryByRole('img') where appropriate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c52be5af-5c1c-4356-914f-df3931df2066

📥 Commits

Reviewing files that changed from the base of the PR and between 618d8b6 and 70a4ce1.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (16)
  • package.json
  • skills/tedi-react/references/components.md
  • src/community/components/vertical-stepper/vertical-stepper.stories.tsx
  • src/tedi/components/buttons/card-button/card-button.module.scss
  • src/tedi/components/navigation/card-stepper/card-stepper-step.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.module.scss
  • src/tedi/components/navigation/card-stepper/card-stepper.spec.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.stories.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper-item.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper-sub-item.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.module.scss
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.spec.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.stories.tsx
  • src/tedi/index.ts
  • src/tedi/providers/label-provider/labels-map.ts
🚧 Files skipped from review as they are similar to previous changes (11)
  • src/tedi/index.ts
  • src/community/components/vertical-stepper/vertical-stepper.stories.tsx
  • src/tedi/providers/label-provider/labels-map.ts
  • package.json
  • src/tedi/components/navigation/card-stepper/card-stepper.module.scss
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.stories.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.spec.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.stories.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper-item.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper-sub-item.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.tsx

@airikej
airikej requested a review from mart-sessman July 1, 2026 06:15
* Per-instance label overrides. When omitted, each label comes from the
* `LabelProvider` (`stepper.previous`, `stepper.next`, `stepper.open-steps`,
* `stepper.steps`, `stepper.status`).
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add Figma link.

import { VerticalStepperSubItem, VerticalStepperSubItemProps } from './vertical-stepper-sub-item';

/**
* <a href="https://www.figma.com/design/jWiRIXhHRxwVdMSimKX2FF/TEDI-READY-2.54.75?node-id=4375-57530&m=dev" target="_blank">Figma ↗</a><br/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add Zeroheight link as well: https://www.tedi.ee/1ee8444b7/p/25a440-stepper-vertical.

<>
<div className={styles['tedi-vertical-stepper__toggle']}>
{interactiveTitle}
<Collapse

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Replace with CollapseButton?

<VerticalStepper.Item title="Kutse" state="completed" href="#k1" />
<VerticalStepper.Item
title="Tahteavaldus"
description="Ülevaatamine võib võtta kuni 30 tööpäeva"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In Figma, there's this grey little dot next to descriptions:

Image

/>
<VerticalStepper.Item title="Üldandmed" state="completed" href="#i2" />
<VerticalStepper.Item title="Terviseandmed" state="completed" href="#i3" />
<VerticalStepper.Item title="Vastus" current href="#i4" info={<Text color="tertiary">Täidab ametnik</Text>} />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Add modifiers="small" if we want to match Figma.

parameters: { pseudo: { hover: ['.vs-hover a', '.vs-hover button'] } },
render: () => (
<VerticalSpacing size={2}>
<StateMatrix states={ITEM_STATES} renderCell={(props) => itemCell(false, props)} />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe add a subheading for each row here so it would be easier to understand what is presented here (Default, Compact, Has subitems)?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also, could we find a bit better solution for the story on mobile?

Image

}

.tedi-vertical-stepper__item--default:has(.tedi-vertical-stepper__link:hover) .tedi-vertical-stepper__indicator {
border-color: var(--stepper-step-default-border-hover);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Completed and Has error states should have hover color on indicator as well:

background: var(--stepper-step-completed-bg-hover);
background: var(--stepper-step-danger-bg-hover);

{ label: 'Default', props: {} },
{ label: 'Selected', props: { current: true } },
{ label: 'Disabled', props: { state: 'disabled' }, noHover: true },
{ label: 'Informative', props: { state: 'informative' }, noHover: true },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In Figma, this "Informative" dot is filled:

Storybook:

Image

Figma:

Image

.tedi-card-stepper__trail {
display: flex;
grid-column: 3;
gap: var(--layout-grid-gutters-08);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this gap added here because otherwise the focus ring would be overflowing the step number?

minWidth: 0,
}}
>
<Text element="span" modifiers="bold">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In Figma, this title is not in bold.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/tedi/components/overlays/sheet/sheet.tsx`:
- Around line 71-72: Update SheetProps and the Sheet component’s accessibility
behavior so callers cannot omit both title and ariaLabel: require ariaLabel when
no title is provided, while preserving title-based labeling when a title exists.
Add or update accessibility checks covering the dialog/sheet role and accessible
name for both title and ariaLabel paths.
- Around line 9-13: Update SheetProps to add optional defaultOpen and make open
and onToggle optional, then update the Sheet component’s Modal usage to forward
defaultOpen while preserving controlled behavior when open/onToggle are
provided. Ensure Sheet supports both controlled and uncontrolled state modes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c3090959-12cc-4b43-bffb-deaebbd158cf

📥 Commits

Reviewing files that changed from the base of the PR and between d0504f0 and d369b6b.

📒 Files selected for processing (9)
  • src/tedi/components/navigation/card-stepper/card-stepper.spec.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.stories.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.tsx
  • src/tedi/components/navigation/table-of-contents/components/table-of-contents-collapsible/table-of-contents-collapsible.tsx
  • src/tedi/components/navigation/table-of-contents/table-of-contents.module.scss
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.module.scss
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.stories.tsx
  • src/tedi/components/overlays/sheet/sheet.module.scss
  • src/tedi/components/overlays/sheet/sheet.tsx
💤 Files with no reviewable changes (1)
  • src/tedi/components/navigation/table-of-contents/table-of-contents.module.scss
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.stories.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.tsx
  • src/tedi/components/navigation/card-stepper/card-stepper.spec.tsx
  • src/tedi/components/navigation/vertical-stepper/vertical-stepper.module.scss
  • src/tedi/components/navigation/card-stepper/card-stepper.stories.tsx

Comment on lines +9 to +13
export interface SheetProps {
/** Controlled open state. */
open: boolean;
/** Called when the sheet opens or closes. */
onToggle: (open: boolean) => void;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Support uncontrolled Sheet state.

Sheet requires open and onToggle, even though its underlying Modal supports uncontrolled state. Add optional defaultOpen, make open/onToggle optional, and forward defaultOpen to Modal.

Proposed change
 export interface SheetProps {
-  /** Controlled open state. */
-  open: boolean;
+  /** Initial open state for uncontrolled usage. */
+  defaultOpen?: boolean;
+  /** Controlled open state. */
+  open?: boolean;
   /** Called when the sheet opens or closes. */
-  onToggle: (open: boolean) => void;
+  onToggle?: (open: boolean) => void;
 export const Sheet = ({
+  defaultOpen,
   open,
   onToggle,
   ...
 }: SheetProps): JSX.Element => {
   ...
-    <Modal open={open} onToggle={onToggle}>
+    <Modal defaultOpen={defaultOpen} open={open} onToggle={onToggle}>

As per path instructions, “always support controlled + uncontrolled modes.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export interface SheetProps {
/** Controlled open state. */
open: boolean;
/** Called when the sheet opens or closes. */
onToggle: (open: boolean) => void;
export interface SheetProps {
/** Initial open state for uncontrolled usage. */
defaultOpen?: boolean;
/** Controlled open state. */
open?: boolean;
/** Called when the sheet opens or closes. */
onToggle?: (open: boolean) => void;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tedi/components/overlays/sheet/sheet.tsx` around lines 9 - 13, Update
SheetProps to add optional defaultOpen and make open and onToggle optional, then
update the Sheet component’s Modal usage to forward defaultOpen while preserving
controlled behavior when open/onToggle are provided. Ensure Sheet supports both
controlled and uncontrolled state modes.

Source: Path instructions

Comment on lines +71 to +72
aria-label={ariaLabel}
aria-labelledby={!header && title !== undefined && title !== null ? titleId : undefined}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Prevent unnamed dialogs.

SheetProps allows callers to omit both title and ariaLabel; this leaves both accessible-name attributes unset. Model valid prop combinations so a label is required when no title is rendered.

As per path instructions, include accessibility checks for “role/name behavior.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tedi/components/overlays/sheet/sheet.tsx` around lines 71 - 72, Update
SheetProps and the Sheet component’s accessibility behavior so callers cannot
omit both title and ariaLabel: require ariaLabel when no title is provided,
while preserving title-based labeling when a title exists. Add or update
accessibility checks covering the dialog/sheet role and accessible name for both
title and ariaLabel paths.

Source: Path instructions

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[VerticalStepper]: New TEDI-Ready component

3 participants