UNPKG

@innovaccer/design-system

Version:

React components library project for Innovaccer Design System

59 lines (57 loc) 3.29 kB
/** * Scope roots for MDS's own portaled overlays, always added to the scoped bundle's * `@scope` prelude by `build-scoped.mjs`. * * Every overlay listed here is portaled to `document.body` by `ReactDOM.createPortal`, * escaping the consumer's `[data-mds-root]` container. Inside `@scope`, a rule like * `.Backdrop` is implicitly `:scope .Backdrop` and so matches descendants only, so these * elements have to be scope roots in their own right — and there is no MDS-owned ancestor * to hang that on. Their own rules then match via the root-anchored selector variants the * build adds (`.Backdrop, :scope.Backdrop`). * * Each selector targets markup the components *already* render. That is what keeps the * scoped stylesheet a CSS-only feature: nothing in `core/` changes, so the CSS can be * updated independently of the library version and works with releases already shipped. * * Each is also qualified so it cannot collide with a host app's own class names: * * - `body >` — every one of these lands as a direct child of `<body>`, so a colliding * host class would have to be at body level too. * - `:has([data-layer])``data-layer` is an MDS-only attribute, present on all five * portal roots. `.Overlay-wrapper` is a generic enough name that a host app could * plausibly reuse it, so the class alone is not sufficient. The `:has()` matches a * descendant rather than a child because Modal wraps its container in `OutsideClick` * when `backdropClose` is set. * - `data-test='DesignSystem-*'` — already namespaced, so `body >` is enough. * * This file is the single source of truth, shared with * `core/utils/__tests__/scopedPortalRoots.test.tsx`, which renders each overlay and * asserts these selectors still match — so the coupling to component markup cannot rot * silently. */ const PORTAL_ROOT_SELECTORS = [ /** Modal, Sidesheet and FullscreenModal all portal into this shared container. */ 'body > .Overlay-wrapper:has([data-layer])', /** Popover and everything built on it: Tooltip, Dropdown, Menu, DateRangePicker, … */ "body > [data-test='DesignSystem-Popover']", /** * `PopperWrapper` now renders through `@floating-ui/react`'s `FloatingPortal`, which * inserts its own `<div data-floating-ui-portal>` directly under `body` and nests the * `data-test='DesignSystem-Popover'` element one level inside *that* — so the selector * above no longer matches a direct child of `body` for any Popover-built component * (Tooltip, Dropdown, Menu, Select, DateRangePicker, AvatarGroup, …). This selector * targets the actual direct child instead. `data-floating-ui-portal` is set * unconditionally by the library itself, so it doesn't depend on a component's * (now overridable via a `dataTest` prop) `data-test` value. */ 'body > [data-floating-ui-portal]', /** Backdrop, including the one Modal/Sidesheet render. */ "body > [data-test='DesignSystem-Backdrop']", /** * Listbox drag ghost. No `data-test` exists on it, so `body >` is the only qualifier * available; the BEM class name is at least MDS-specific. Worth tightening with a * `data-test` the next time component changes ship. */ 'body > .Listbox-item--draggable', ]; module.exports = { PORTAL_ROOT_SELECTORS };