Skip to content

feat(fds): replace the left navigation with the design-system Navbar (#17539) - #17514

Merged
Sandy Ghs (sandyghs) merged 11 commits into
design-system/currentfrom
fds-navbar
Aug 10, 2026
Merged

feat(fds): replace the left navigation with the design-system Navbar (#17539)#17514
Sandy Ghs (sandyghs) merged 11 commits into
design-system/currentfrom
fds-navbar

Conversation

@sandyghs

@sandyghs Sandy Ghs (sandyghs) commented Aug 4, 2026

Copy link
Copy Markdown

What changed, in plain terms

The left navigation is now the design system's Navbar, not a hand-built MUI
Drawer. Same entries, same permissions, same destinations — but the rows are
real links, so Ctrl-click and "open in a new tab" work everywhere, and the rail
is painted by the design system instead of by ~870 lines of product CSS.

Four things a user can notice:

  • The collapsed rail is 48px wide instead of 55px. That is the design
    system's real rail width; the seven floating toolbars that align themselves
    against it read the constant, so they shift 7px with it.
  • Custom platform themes keep working exactly as before: a theme_background
    still paints the rail, a theme_primary still colours the selected row, and
    a draft still turns the accent orange.
  • Standard installations now get the design system's own rail gradient rather
    than a reimplementation of it.
  • The "Made by Filigran" signature keeps its two states: the wordmark when the
    rail is expanded, the emblem alone when it is collapsed — cropped from the
    same asset, so there is no second file to keep in sync with the brand.

Proposed changes

  • Replace the left navigation (LeftBar.jsx and its ~870 lines of styling)
    with NavBar.tsx, built on the design system's Navbar, NavbarItem,
    NavbarSubmenu and ProductSwitcher, keeping the menu structure, the three
    permission mechanisms, the feature flags and the submenu_show_icons user
    preference.
  • Install the private design system in the containerised build: BuildKit build
    secrets for the three Dockerfiles, explicit per-run injection for the
    workflows that install outside an image.
  • Re-anchor the end-to-end left-bar page object on what the component actually
    emits, and keep the rail's width contract for the eight files that read it.

Related issues

Pinned library version

486cec92c3abf006997ac269d34ff0fcc23f178f — head of main. Verified
installable from a clean external project and from inside a container
before being pinned.

Bumped from 56f7e59823cae7d815a451206e3cb4cb1d31022d to pick up library
PR #84, which gives button-rendered rail rows the pointer cursor. Before it,
every button-rendered row of this rail resolved to cursor: default — 14
expanded, 1 collapsed — while link rows got the hand cursor for free from the
user-agent sheet. That was a regression against the MUI navigation being
replaced, and no structural diff can see it. After the bump: 13/14 and 1/1.

The one row left out is the ProductSwitcher trigger, which is a sibling
component rather than a NavbarItem. Filed as observation 12 and deliberately
not compensated here — a host rule would hide the gap from every other
consumer.

Re-checked at the new pin, and recorded in fds-migration/IMPLEMENTATION-LOG.md:

  • No compensation could be retired. Navbar.tsx and NavbarSubmenu.tsx are
    byte-identical between the two pins; NavbarProps still exposes no accent
    prop and NavbarSubmenuProps still exposes a single open/onOpenChange
    pair.
  • Nothing this rail depends on moved. Set-diffing the compiled
    dist/index.css between the pins: 641 → 689 class selectors, 414 → 420
    custom properties, zero removals on either — so the accent guard that
    reads the installed stylesheet still holds.
  • One intentional visual change, inside the product dropdown: library
    PR Integrate with multiple MISP Instances #81 moved ProductSwitcher's panel onto Menu, so row padding-right goes
    8px → 16px, panel min-width 192px → 200px with a new cap and bounded height,
    divider margin 2px → 4px, group header band 24px → 32px, and disabled rows
    are painted with the disabled tokens instead of opacity-60. Row height
    (36px) and label size (14px) are unchanged — checked in the running platform.
  • Package size grew, it did not shrink: 3 384 759 → 3 637 106 bytes
    (+252 347, +7.5%), 60% of it source maps and typings for the new Header and
    Menu primitives. There was no documentation to drop: the package has
    shipped files: ["dist"] since the initial monorepo scaffold, an ancestor of
    both pins.

The point of this pull request

Beyond the navigation itself, this is the first time OpenCTI's continuous
integration installs the private design system. OpenCTI installs inside
containers
— three Dockerfiles and four workflows — and a credential placed
on the host does not cross the container boundary. So:

  • the three Dockerfiles receive the token as a BuildKit build secret, used
    only for the duration of the yarn install layer and never written to an
    image layer (verified: no match in image history, in any gitconfig, or
    anywhere on the filesystem of the built image);
  • the workflows that install outside an image inject it explicitly per
    container run, with tracing disabled around the credential;
  • git is installed where it was missing (node:22-alpine ships without it),
    including in the shared builder stage, because that image is exported as an
    artifact and reused by the rolling build.

Compensations

Eight, each carrying a comment explaining why, an entry in
fds-migration/LIBRARY-FEEDBACK.md, and a testable removal condition.

# What Why Removal condition
1 Brand tokens overridden inline on <nav> (entries 1, 6) NavbarItem paints its selected state from a fixed brand token, and the derived tint token is frozen against :root; OpenCTI's theme_primary is administrator-configurable and drafts switch the accent Navbar gains an accent prop — pass the same value, delete the block; the token-name guard test passes unchanged
2 Submenu icons composed product-side (entry 2) asChild — required for real links — makes the library's icon/showIcon inert, so submenu_show_icons had to be re-implemented A slotted child keeps the library's icon handling — pass icon/showIcon again
3 Row body re-implemented, collapsed label kept sr-only (entry 7) asChild replaces the library's own row content, including the hidden label the collapsed rail is navigated by asChild composes the row body instead of replacing it
4 open/onOpenChange bound only while expanded (entry 10) Collapsed, the same prop pair drives the hover flyout; controlling it made every flyout after the first unusable and wrote hover into the persisted menu state The flyout gets its own state — bind unconditionally, hover three collapsed rows in turn, each opens and selectedMenu is unchanged
5 Sticky, definite-height geometry inline (entry 11) The library's <nav> is laid out in flow and sized with a percentage height, which does not resolve against OpenCTI's shell: the rail was 776px tall in an 800px viewport and scrolled away with the page The <nav> takes the height it is given — delete the navStyle geometry block, the rail still measures the full viewport and stays put while an inner container scrolls
6 Host rule .app-navbar { flex: 0 0 auto } (entry 8) The rail does not defend its own width in a flex host The <nav> carries shrink-0 itself — delete the rule, the rail still measures 48/180px
7 Host rule raising portalled surfaces above the app bar (entry 5) Flyouts and tooltips are portalled to document.body below OpenCTI's app bar The library layers its portals above the host's own surfaces
8 useFdsThemeScope writes the theme classes on the document root The library portals flyouts and tooltips to document.body; a subtree class leaves them unthemed. The hook's guard against targeting the root was amended, not bypassed Never — this is the arbitrated mechanism

Conditional, not a compensation: the legacy gradient is restored inline
only when an administrator configured a custom theme_background. Standard
installations get the real design-system rendering — the point of this pilot —
and custom-theme deployments lose nothing. The branch is commented as a
deliberate choice, not a workaround, and both cases were checked in the running
platform.

Library observations filed

Twelve entries in fds-migration/LIBRARY-FEEDBACK.md, each with its removal
test. Three were added after hands-on passes on the running platform:

  • 10 — accordion state and hover flyout state share one controlled prop.
    Collapsed, open/onOpenChange drive the hover flyout; the 150ms delayed
    close of the row being left resolves against the same state snapshot as the
    next row's open, so the last one wins.
  • 11 — the rail is laid out in flow and sized by percentage. Both pilots had
    to write the same sticky, definite-height block in their host. Filed as an
    observation rather than a defect: it is arguably the host's responsibility,
    but two consumers out of two hit it.
  • 12 — the pointer-cursor fix stopped at NavbarItem. Library PR INTERNAL_SERVER_ERROR - "Int cannot represent non-integer value:" #84 fixed
    both of that component's render paths, which is 13 of this rail's 14
    button-rendered rows. The ProductSwitcher trigger declares no cursor of its
    own and still resolves to default. The ask is to generalise PR INTERNAL_SERVER_ERROR - "Int cannot represent non-integer value:" #84's own
    reasoning to every button the library renders.

Nothing in the library was modified by this pull request.

Validation

Run locally on this exact commit: type-check clean, lint clean, 1337 unit
tests passing
. Two failures are pre-existing and reproduced identically
with this branch stashed:

  • src/utils/Time.test.ts — timezone-dependent assertion, fails outside UTC.
  • src/buildConfig.test.ts — requires dist/index.html, i.e. a prior build.

41 unit tests cover the new code and the amended theme hook, including the
behaviours most at risk of a silent regression: a submenu parent navigates
only while the rail is collapsed (as before); the selected-row accent is
still driven by the library token this code overrides — that guard reads the
installed stylesheet, because a rename upstream would otherwise lose the accent
with nothing turning red; and the rail's sticky, full-height geometry.

Continuous integration is green on this commit: 17/17 jobs of OpenCTI CI
— frontend quality, backend, the three end-to-end groups, the client-python
matrix, the license check and the three container image builds, which is the
central proof here — plus PR conventions checks and PR add labels.
PR check linked issue is skipped by design on this base branch
(pr-check-linked-issue.yml only arms for master and lts/*). One red was
dated and re-run: pycti test - python 3.12 failed once on a runner port
collision (failed to bind host port … address already in use), unrelated to a
front-end change, green on re-run.

Note for reviewers: codeql-analysis.yml and cd-check-images-on-pr.yml
restrict their trigger to master/lts, so they do not run here — a
pre-existing structural gap of this base branch, already recorded on the
OpenAEV side. Independent review is the only safety net for what they cover.

How to test this PR

  • Run the platform, then check both rail states: entries, permissions and
    destinations identical to master; Ctrl-click and middle-click open a new
    tab from any row; collapsed, hover moves from one submenu to the next and
    each flyout opens.
  • Set a custom theme (theme_background + theme_primary in Settings →
    Customization): the rail keeps the configured background and the selected row
    the configured accent. Then switch back to a standard theme: the rail is
    painted by the design system.
  • Toggle "Show submenu icons" in user preferences, in both rail states.
  • yarn test src/private/components/nav src/utils/hooks/useFdsThemeScope.test.tsx
    — 41/41 passing.

Not fixed here (mono-subject), dated in fds-migration/IMPLEMENTATION-LOG.md

  • Two components read the collapsed-rail flag without subscribing to the toggle
    channel, so their offset goes stale. Pre-dates this change.
  • yarn i18n-checker is declared in package.json but the script file does not
    exist and no job runs it.
  • bannerHeight is built as the unitless string '0' when no banner is
    displayed, which makes any calc() containing it invalid — including the app
    shell's own marginTop. This rail derives its offsets from the numeric form
    instead; the shell's declaration is left alone.

Checklist

  • I consider the submitted work as finished
  • I tested the code for its functionality
  • I wrote test cases for the relevant use cases (coverage and e2e)
  • I added/updated the relevant documentation (either on GitHub or on Notion)
  • Where necessary, I refactored code to improve the overall quality

Replaces LeftBar.jsx, LeftBarItem.tsx and LeftBarHeader.tsx with the
Navbar, NavbarItem, NavbarSubmenu and ProductSwitcher components from
@filigran/design-system, pinned at the head of the library's main.

The menu tree, which was an untyped inline JSX tree mixing three
permission mechanisms with rendering, becomes a typed structure built by
useNavMenu, with a pure filterNavGroups that is unit-tested on its own.
Navigation rows are now real anchors, so Ctrl-click and "open in a new
tab" work on every entry.

The rail widths, the collapsed-state storage key and its notification
channel move to navBarConstants. Seven floating toolbars and the
end-to-end page object are retargeted onto it; the collapsed width goes
from 55px to 48px, the design-system rail's real width.

Installing a private library inside a container needs the credential to
cross the container boundary, so the three Dockerfiles take it as a
BuildKit build secret and the workflows that install outside an image
inject it explicitly. No token is written to any image layer.

The design-system theme class is now written on the document root: the
library portals its flyouts and tooltips to document.body, so a
subtree-scoped class would leave them unthemed. Custom themes keep their
background and their accent colour; both compensations are documented in
fds-migration/LIBRARY-FEEDBACK.md with a testable removal condition.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Filigran-Automation Filigran Automation (Filigran-Automation) changed the title Replace the left navigation with the design-system Navbar refactor(frontend): replace the left navigation with the design-system Navbar Aug 4, 2026
@Filigran-Automation Filigran Automation (Filigran-Automation) added the filigran team Item from the Filigran team. label Aug 4, 2026
@Filigran-Automation

Copy link
Copy Markdown
Member

🤖 [AI-generated]

Hey Sandy Ghs (@sandyghs)! 👋 Thanks so much for opening PR #17514 — this is an impressively thorough writeup of a big change, really appreciate the detail on the compensations, validation and pinned library version! 🙏

I just had a quick look and there's one thing that could help reviewers and the release process a little. I haven't changed anything in your description — just a gentle suggestion:

Area What could help Suggestion
Linked issue The description doesn't reference a tracked GitHub issue (e.g. "Closes #1234" / "Related to #1234") Since CONTRIBUTING.md asks that every Pull Request be linked to an issue, it'd be great to add a reference to the issue this work addresses (or open one if it doesn't exist yet)

💡 If helpful, the CONTRIBUTING.md walks through what to include.

No rush at all — thanks again for this contribution, the navigation migration looks like solid work! 🚀

…flow

The main continuous-integration workflow builds the platform image with
the same composite action as the delivery workflows, so it needs the same
credential. It was the one caller left unwired, and a composite action
cannot read the secrets context itself.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@sandyghs Sandy Ghs (sandyghs) changed the title refactor(frontend): replace the left navigation with the design-system Navbar feat(frontend): replace the left navigation with the design-system Navbar (#00000) Aug 4, 2026
@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 37.26415% with 133 lines in your changes missing coverage. Please review.
✅ Project coverage is 34.15%. Comparing base (b3d5974) to head (62669ad).

Files with missing lines Patch % Lines
...ti-front/src/private/components/nav/useNavMenu.tsx 13.33% 78 Missing ⚠️
...pencti-front/src/private/components/nav/NavBar.tsx 39.08% 53 Missing ⚠️
.../opencti-front/src/components/AppThemeProvider.tsx 0.00% 1 Missing ⚠️
...encti-platform/opencti-front/src/private/Index.tsx 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                    Coverage Diff                    @@
##           design-system/current   #17514      +/-   ##
=========================================================
+ Coverage                  34.07%   34.15%   +0.07%     
=========================================================
  Files                       3379     3380       +1     
  Lines                     137610   137528      -82     
  Branches                   37229    37180      -49     
=========================================================
+ Hits                       46895    46966      +71     
+ Misses                     90715    90562     -153     
Flag Coverage Δ
opencti-client-python 48.37% <ø> (ø)
opencti-front 11.10% <37.26%> (+0.10%) ⬆️
opencti-graphql 69.12% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sandy Ghs (sandyghs) and others added 5 commits August 5, 2026 00:46
Running the product surfaced three defects that no type-check, lint or unit
test could see, because none of them computes layout:

- the rail shrank from 48px to 22px: the MUI Drawer it replaces carried
  `flex: 0 0 auto`, the library's <nav> carries only its width utility, and
  the private layout is a flex row that overflows;
- top-level labels overflowed the collapsed rail: `asChild` replaces the
  library's row body, including the `sr-only` switch it applies to the label
  while collapsed. Reproduced verbatim so the accessible name survives;
- the selected-row tint ignored a custom `theme_primary`: it comes from a
  token the stylesheet DERIVES from the brand colour on `:root`, where the
  substitution happens, so the override on the <nav> never reached it. Both
  derived tokens are now re-derived alongside the base one.

The accent guard is reworked accordingly: it now extracts every custom
property the installed library resolves for `aria-current` rows and asserts
the rail overrides each one. The previous substring form passed while the
tint was visibly wrong.

Also names the logo link after the platform title: it pointed at /dashboard
under the name "Home", colliding with the "Home" row and making an exact
accessible-name lookup ambiguous for screen readers and for the e2e model.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Both survived the page-object re-anchoring because neither goes through it:

- a report spec clicked `getByTestId('ChevronRightIcon')`, the MUI icon inside
  the old rail's expand button, to expand the rail. It now calls the page
  object's `open()`, like every other rail interaction in the suite;
- the widget page object located perspective cards page-wide by label. The
  library's submenu is an accordion, which keeps a closed panel mounted as a
  hidden region labelled by its parent, so `getByLabel('Entities')` matched the
  navigation as well as the card. Both lookups are now scoped to the dialog the
  cards actually live in.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
count() does not auto-wait, so probing the parent row's role right after a
dialog closes read a page still marked aria-hidden, answered zero, and fell
into the collapsed branch on an expanded rail, where it waited 200 seconds
for a link that cannot exist.

Wait for either role to be visible first, then discriminate on the role: the
parent is a button when the rail is expanded and an anchor when it is
collapsed, and both carry aria-expanded. In the collapsed flyout the library's
Radix menu re-roles the submenu anchors to menuitem, so look them up there.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The replaced rail exposed its logo as a link named "logo", from the image's
alt text, and two settings specs read the logo source through that name. The
library names the logo link after its destination, which is /dashboard, so it
came out as "Home" and collided with the Home row; naming it after the
platform title fixed the collision but broke the two specs.

Name it "logo", which is both unambiguous inside the navigation and identical
to what the product exposed before. The platform title is no longer read.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Three findings from a hands-on pass on the running platform, each solved
where it belongs.

The rail was neither full height nor fixed: the library lays its <nav> out
in flow and sizes it with a percentage height, which does not resolve
against OpenCTI's shell. It now sticks to the viewport below the banners
with a definite height, the same geometry the OpenAEV pilot uses. The
offsets are derived from the numeric banner height: the string form is '0'
without a unit, which makes any calc() containing it invalid, and an
invalid declaration is dropped in silence.

The "Made by Filigran" signature is rewritten as its own component, ported
from the OpenAEV pilot: inline geometry, since the product has no Tailwind
build, and the wordmark cropped to the Filigran emblem alone when the rail
is collapsed, from the same asset.

Collapsed, the hover flyout is left uncontrolled. The library drives it
from the same props as the expanded accordion, so binding them to the
persisted menu state made every flyout after the first unusable and
rewrote that state on hover.

Four unit tests cover the geometry, the uncontrolled collapsed flyout and
the signature in both rail states. Library entries 10 and 11 filed, with
their removal tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@sandyghs Sandy Ghs (sandyghs) changed the title feat(frontend): replace the left navigation with the design-system Navbar (#00000) feat(fds): replace the left navigation with the design-system Navbar (#17539) Aug 5, 2026
Sandy Ghs (sandyghs) and others added 3 commits August 5, 2026 17:02
ci-docker-build.yml builds the whole platform Dockerfile, so it reaches
builder-front and its RUN --mount=type=secret,id=fds_git_token, but it
passed no secrets: to docker/build-push-action. An unprovided BuildKit
secret is no file at all, so the step dies on "can't open
/run/secrets/fds_git_token: No such file or directory" — which reads
like an absent repository secret. Its three callers never run on a pull
request, one of them on push to design-system/current, so no check here
could have caught it.

A test now does the enumeration instead of a human: every
docker/build-push-action step whose Dockerfile requires the secret, and
which does not stop at an earlier target:, must declare it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
filterNavGroups removed a parent once every one of its submenu rows had
been filtered out. The rail this replaces did the opposite: LeftBarItem's
"No Subitems" branch rendered such a parent as a plain navigable row.

Two reachable cases. canSeeData is granted by INGESTION alone, which
grants none of the eight Data sub-items, so an ingestion operator lost
/dashboard/data entirely. Hiding the Dashboard entity type empties the
Dashboards submenu the same way. NavBar.renderItem already renders an
empty subItems as a leaf, so the fix is to stop dropping the row.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The library's main has moved four commits on: sub-menu primitives for Menu
with ProductSwitcher adopting them, a docs correction, the pointer-cursor fix
on rail rows, and a new Header component.

The cursor fix is the one this rail needed. Every button-rendered row resolved
to `cursor: default` -- 14 of them expanded, 1 collapsed -- because a browser
gives `<a href>` the hand cursor for free and gives `<button>` nothing, and
the library restated neither. Measured in the running platform, the bump takes
that to 13/14 and 1/1. This is a regression against the MUI navigation being
replaced, which had the hand cursor on every row; it was reported by the
OpenAEV pilot, not by this one, and it survived a full structural parity pass
here because no structural diff can see a UA default.

The remaining row is the ProductSwitcher trigger, a sibling component and so
not a NavbarItem. It is filed as entry 12 in LIBRARY-FEEDBACK.md and
deliberately not compensated product-side: a host rule would hide the gap from
every other consumer.

No compensation could be retired. Navbar.tsx and NavbarSubmenu.tsx are
byte-identical between the two pins, `NavbarProps` still has no accent prop,
and `NavbarSubmenuProps` still has a single open/onOpenChange pair.

Nothing this rail depends on moved: set-diffing the compiled dist/index.css
between the pins gives 641 -> 689 class selectors and 414 -> 420 custom
properties with zero removals, so the accent guard that reads the installed
stylesheet still holds. One intentional visual change lands inside the product
dropdown, where ProductSwitcher now uses Menu's own metrics.

The install grows 3 384 759 -> 3 637 106 bytes. No reduction was available
from dropping the documentation: the package has shipped `files: ["dist"]`
since the initial scaffold, an ancestor of both pins.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@sandyghs

Copy link
Copy Markdown
Author

Update: I've bumped the design system pin on this PR, following feedback the OpenAEV team gave on the equivalent migration on their side. Since both products consume the same library, their review benefits this PR directly.

What the feedback found. Rows in the rail that render as buttons — the collapse toggle and the submenu triggers — didn't show the pointer cursor on hover, while rows rendering as links did. The browser gives links that cursor for free and gives buttons nothing, and the library ships no global reset, so nothing caught it. The old navigation, built on MUI, had it everywhere. Small, but a real iso-functionality regression: measured at 0 of 14 button rows before the bump, 13 of 14 after.

It was fixed in the library rather than patched here, so both products get it from the same place.

Also in this bump, since the pin moved forward: the ProductSwitcher now renders through the library's shared Menu. That changes its dropdown slightly — right padding 8→16px, minimum width 192→200px, separator 2→4px, group header 24→32px — with row height and label size unchanged. Nothing else moves: a set-diff of the compiled stylesheet between the two pins shows 641→689 class selectors and 414→420 custom properties, with zero removals on either side.

@natalie-natsu Natalie (natalie-natsu) left a comment

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.

Lots of changes. It's nice to have tests. It will require another review on the components because for me most parts were ok, it is a lot of noise with these comments.

However, I can't approve anything before getting clear with the "FDS_GIT_TOKEN". How does it works with OpenAEV? I don't understand how we aren't soft locking projects with that. A. Jard (@aHenryJard) have you seen this part?

Comment on lines +56 to +57
secrets: |
fds_git_token=${{ inputs.fds_git_token }}

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.

What happens if you don't have the FDS_GIT_TOKEN? If a contributor wants to fork the project could he build it?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

You're right to flag it — it's a real constraint today: the library is a private git dependency, so a fork can't build the front (in CI or locally). Two things frame it: no external contributor is affected yet, because fork PRs target master while this work lives on design-system/current; and the token was always an interim consumption mode. The structural fix is already planned — publishing the library to npm (workstream s5-release-machinery), which removes both the token and the private clone.

Review feedback on #17514 was that the explanatory comments around the
workarounds are noisy enough to obstruct a component review. Each of the
eight workaround sites now carries a single marker naming its removal
condition and pointing at its numbered entry:

  // FDS-WORKAROUND #N: <summary> — remove when <condition> — see fds-migration/LIBRARY-FEEDBACK.md #N

The rationale is not dropped, it moves to the matching entry in
fds-migration/LIBRARY-FEEDBACK.md, which becomes the single source of
truth: full why, the code shape, and the testable removal condition. That
also ends the duplication, where the same reasoning lived in two places
and only one of them was checked by anything.

Entry 5 (portalled surfaces) gains the removal test it never had, plus
the Radix inline-z-index and MUI zIndex.modal rationale. Entries 1, 2, 6,
7, 8, 10 and 11 gain the code shapes, measured figures and the OpenAEV
reference implementation path that were only in the source before.

The MUI icon-sizing rule and the conditional custom-theme background are
deliberately left with their inline rationale: neither is a workaround,
and marking them removable would misrepresent them.

Comment-only. Verified mechanically by stripping all comments from both
files before and after: the remaining code is byte-identical, so there is
no behaviour change.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@sandyghs

Copy link
Copy Markdown
Author

Lots of changes. It's nice to have tests. It will require another review on the components because for me most parts were ok, it is a lot of noise with these comments.

Fair point, and you were right to raise it. I've done a cleanup pass: each workaround is now a single line pointing at its numbered entry in fds-migration/LIBRARY-FEEDBACK.md, where the full context and the removal condition now live. These markers are temporary by design — each one gets deleted along with its workaround once the library ships the corresponding fix, and some of those fixes already landed this week. Nothing essential was lost, just the noise.

@natalie-natsu Natalie (natalie-natsu) left a comment

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.

I accept only to unlock the PR, because this is the same action than a local merge commit. In this current state, we can't approve any request other than POC.

@sandyghs
Sandy Ghs (sandyghs) merged commit 44d7493 into design-system/current Aug 10, 2026
46 checks passed
@sandyghs
Sandy Ghs (sandyghs) deleted the fds-navbar branch August 10, 2026 21:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

filigran team Item from the Filigran team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants