npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cloud-ru/ds-portal-context

v1.0.1

Published

React Context, который задаёт DOM-узел для портальных компонентов (Tooltip, Popover, Dropdown, Modal, Drawer).

Downloads

5,021

Readme

PortalContext

@cloud-ru/ds-portal-context — React Context, который задаёт DOM-узел для портальных компонентов (Tooltip, Popover, Dropdown, Modal, Drawer).

@cloud-ru/ds-portal-context — служебный пакет: задаёт через React Context корневой DOM-узел, в который компоненты дизайн-системы рендерят порталы (Tooltip, Popover, Dropdown, Modal, Drawer и др.). По умолчанию портал монтируется в document.body; контекст нужен, когда DS работает внутри shadow DOM, iframe или встроенного приложения с собственным rooted DOM.

Когда использовать

  • DS встраивается в micro-frontend / shadow DOM — document.body недоступен или принадлежит host-приложению.
  • Необходимо поднимать stacking-контекст всех порталов в один контейнер (например, ради scoped CSS).
  • E2E или Storybook-тесты — портал нужно монтировать в фиксированный узел iframe.

В обычном SPA-приложении провайдер не требуется — компоненты по умолчанию используют document.body.

Установка

pnpm add @cloud-ru/ds-portal-context
import { PortalContextProvider } from '@cloud-ru/ds-portal-context'

Примеры использования

Кастомный root через PortalContext

Портал монтируется в указанный ref, а не в document.body.

import { PortalContextProvider, usePortalContext } from '@cloud-ru/ds-portal-context';
import { useMemo, useState } from 'react';
import { createPortal } from 'react-dom';

function PortalChild() {
  const root = usePortalContext();

  if (!root.current) return null;

  return createPortal(<span>Я отрендерен в кастомном root-узле через PortalContext</span>, root.current);
}

export function CustomRoot() {
  const [node, setNode] = useState<HTMLDivElement | null>(null);
  const root = useMemo(() => ({ current: node }), [node]);

  return (
    <div style={{ display: 'flex', gap: 12, flexDirection: 'column' }}>
      <PortalContextProvider root={root}>
        <span>Хост-компонент</span>
        <PortalChild />
      </PortalContextProvider>
      <div ref={setNode} data-test-id='portal-root' />
    </div>
  );
}

Каскад тем: разные корни порталов

Два блока со своей темой и своим корнем порталов. Тултип и поповер из тёмного блока рендерятся в тёмной теме, из светлого — в светлой, потому что каждый монтируется в DOM-узел своего блока.

import { Button } from '@cloud-ru/ds-button';
import { Popover } from '@cloud-ru/ds-popover';
import { PortalContextProvider } from '@cloud-ru/ds-portal-context';
import { COLOR_SCHEME, ColorScheme, useThemeClassnames } from '@cloud-ru/ds-theme';
import { Tooltip } from '@cloud-ru/ds-tooltip';
import { useRef } from 'react';

import styles from './CascadingThemes.module.scss';

// Тематический блок: useThemeClassnames форсит colorScheme и эмитит полный набор sn-* на свой div.
// Этот же div — корень порталов блока (PortalContextProvider root={paneRef}), поэтому тултип и
// поповер монтируются ВНУТРЬ него и наследуют тему блока через CSS-каскад токенов.
function ThemedPane({ scheme, title }: { scheme: ColorScheme; title: string }) {
  const themeClassName = useThemeClassnames({ colorScheme: scheme });
  const paneRef = useRef<HTMLDivElement>(null);

  return (
    <div ref={paneRef} className={`${styles.pane} ${themeClassName}`}>
      <PortalContextProvider root={paneRef}>
        <p className={styles.paneTitle}>{title}</p>
        <Tooltip tip='Тултип рендерится в теме своего блока' placement='top'>
          <Button label='Навести — тултип' appearance='primary' view='filled' />
        </Tooltip>
        <Popover content='Поповер — тоже в теме блока' placement='bottom' trigger='click'>
          <Button label='Кликнуть — поповер' appearance='neutral' view='outline' />
        </Popover>
      </PortalContextProvider>
    </div>
  );
}

export function CascadingThemes() {
  return (
    <div className={styles.grid}>
      <ThemedPane scheme={COLOR_SCHEME.Dark} title='Тёмный блок' />
      <ThemedPane scheme={COLOR_SCHEME.Light} title='Светлый блок' />
    </div>
  );
}

Props

PortalContextProviderProps

| Prop | Type | Default | Description | |------|------|---------|-------------| | children | string \| number \| boolean \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| null \| undefined | — | | | root | T | — | |

Смотри также

  • Tooltip, Popover, Dropdown, Modal, Drawer — потребители контекста.