Skip to content

feat(svelte-ds-app-launchpad): upstream Link & Breadcrumbs components#438

Open
goulinkh wants to merge 9 commits intomainfrom
feat/upstream-link-and-breadcrumbs
Open

feat(svelte-ds-app-launchpad): upstream Link & Breadcrumbs components#438
goulinkh wants to merge 9 commits intomainfrom
feat/upstream-link-and-breadcrumbs

Conversation

@goulinkh
Copy link
Contributor

Fixes LP-3722

PR readiness check

  • PR should have one of the following labels:
    • Feature 🎁, Breaking Change 💣, Bug 🐛, Documentation 📝, Maintenance 🔨.
  • PR title follows the Conventional Commits format.
  • All packages define the required scripts in package.json:
    • All packages: check, check:fix, and test.
    • Packages with build steps: build to build the package for development or distribution, build:all to build all artifacts. See CONTRIBUTING.md for details.

Screenshots

Breadcrumbs

image

Upstream the Link component from launchpad-ui with semantic tokens
and separated CSS. Also fix component tokens in styles/index.css.
Upstream the Breadcrumbs component from launchpad-ui with semantic
tokens, separated CSS, and sub-components (CollapsedItems,
ExpandedItems, Item). WebKit focus tests marked as todo due to
macOS TabsToLinks preference.
Copy link
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 upstreams the Link and Breadcrumbs components to the ds-app-launchpad package. These components were generated using @canonical/summon:component-svelte v0.1.0 and follow established patterns in the codebase. The Link component is a styled anchor element with an optional soft variant that inherits the parent's color. The Breadcrumbs component is a navigation component with intelligent collapsing behavior when space is limited, featuring progressive enhancement for non-JavaScript environments.

Changes:

  • Added Link component with support for soft styling and comprehensive test coverage
  • Added Breadcrumbs component with smart collapsing mechanism and accessibility features
  • Updated CSS variables from --dimension-* to --lp-dimension-* prefix for consistency

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 5 comments.

File Description
packages/svelte/ds-app-launchpad/src/lib/styles/index.css Updated CSS variable names to use --lp- prefix for consistency
packages/svelte/ds-app-launchpad/src/lib/components/index.ts Added exports for Link and Breadcrumbs components
packages/svelte/ds-app-launchpad/src/lib/components/Link/* New Link component with types, styles, tests, and stories
packages/svelte/ds-app-launchpad/src/lib/components/Breadcrumbs/* New Breadcrumbs component with collapsing logic, sub-components, comprehensive tests

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
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

Copilot reviewed 29 out of 29 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Choose a reason for hiding this comment

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

You have two nested common folders, I am unsure this is intentional

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes since Item is only consumed by parent level CollaspedItems and ExpandedItems it is by definition a common component for these two components and it should be placed inside a nested common folder.

Copy link
Contributor

@advl advl left a comment

Choose a reason for hiding this comment

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

I left a couple comments passing by - I would also recuse myself from a full review here as I'm not a svelte specialist.

I would nevertheless recommend strongly to split the PR into two (or do this for future ones) - as smaller PRs are easier - and faster to review.

This is likely something to document in the issues template as well.

@goulinkh
Copy link
Contributor Author

I would nevertheless recommend strongly to split the PR into two (or do this for future ones) - as smaller PRs are easier - and faster to review.
This is likely something to document in the issues template as well.

@advl I agree with you 100% but I would say this PR fits into a medium sized PR rather than big.

1200 lines added is not a lot to review in one PR. But if we check by number of files changed, 30 files is a lot. However 30 files for 5 total components (3 sub components) and all of them are fully connected since each component requires at least 4 files it adds up (index, styles, stories, ssr test, client test, svelte file).

@advl
Copy link
Contributor

advl commented Feb 26, 2026

@goulinkh Yes ! however I would add small size beats medium size - there are companies where this advice is applied as a principle and really help smoothen the dev process - I'd be keen to discuss this more. In all cases it would be great to set the expectations on this together for the monorepo

Copy link
Member

@jmuzina jmuzina left a comment

Choose a reason for hiding this comment

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

Reviewed the rest of it - looking good. Just leaving some non-blocking comments. Thanks!

collapseClickOpened = !collapseClickOpened;
}}
>
<ol role="none" data-testid="collapsed-segments">
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't need to hard code data-testid inside the core implementation of the component

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure what a good alternative would be here, though, as this is a roleless element, which does not provide a way to pass arbitrary props (can't pass testid from the test), and selecting it is heavily relied on for auto-collapsing tests.

Comment on lines +17 to +23
const maxNumCollapsed = $derived(
minNumExpanded === "all"
? 0
: Math.max(0, segments.length - Math.max(0, minNumExpanded)),
);
let containerWidth = $state<number>();
let segmentWidths = $state<number[]>([]);
Copy link
Member

Choose a reason for hiding this comment

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

This auto-collapsing/expanding behavior is really really impressive and intuitive..... first implementation of this new requirement for Breadcrumbs. Great work LP folks!!

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you!

collapseClickOpened = !collapseClickOpened;
}}
>
<ol role="none" data-testid="collapsed-segments">
Copy link
Member

Choose a reason for hiding this comment

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

Just curious, why role="none"? Likely worth a comment at least

Copy link
Contributor

Choose a reason for hiding this comment

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

This lets us expose all the segments (both collapsed and shown) as one flat, coherent list to assistive technologies.

image

I'll add a comment about this :)

Comment on lines +6 to +9
type LinkSegment = Omit<LinkProps, "children" | "href"> & {
label: string;
href: string;
};
Copy link
Member

Choose a reason for hiding this comment

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

Why Omit href if you're going to add it back in the type here? Is there some type incompatibility?

Copy link
Contributor

Choose a reason for hiding this comment

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

To make sure it is required for the LinkSegment as this is eventually used to differentiate between the members of the Segment discriminated union (in the Item component).

steciuk and others added 3 commits February 27, 2026 08:30
macOS WebKit only tabs to form controls by default; Option+Tab is
needed to include links. Extract shared tabToNextFocusable helper
into src/lib/test-utils.ts so other components can reuse it.
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.

5 participants