npm.io
2.1.441 • Published 3d ago

@djangocfg/ui-core

Licence
MIT
Version
2.1.441
Deps
50
Size
1.1 MB
Vulns
0
Weekly
1.2K

@djangocfg/ui-core

@djangocfg/ui-core

Framework-agnostic React UI library: 70+ shadcn/Radix components on Tailwind v4, semantic theme tokens, palette hooks for Canvas/SVG, plus a router-adapter system that lets the same <Link> / <Sidebar> / <SSRPagination> work under Next.js, Vite, Electron, Wails, or plain React.

Part of DjangoCFG. Live demo.

Install

pnpm add @djangocfg/ui-core

Works in any React host. Next.js apps import components from here directly and add the Next router adapter from @djangocfg/ui-core/adapters/nextjs (see Router adapters below); Next-specific server utilities (sitemap, health, OG images, config) live in the separate @djangocfg/nextjs package.

Import styles once at the app root — use the golden path, which pins everything to the right cascade layers so import order can't break layout utilities:

/* FIRST style import in your app entry CSS */
@import "@djangocfg/ui-core/styles/full";   /* Tailwind v4 + tokens + base + utilities, layer-safe */

The plain @djangocfg/ui-core/styles entry does NOT import Tailwind and emits its CSS unlayered — if you use it you own the layer ordering (import tailwindcss first). See src/styles/README.md § App setup for why. Prefer …/styles/full.

Quick start

import { UiProviders, Button, Card } from '@djangocfg/ui-core';

<UiProviders>
  <Card><Button>Hello</Button></Card>
</UiProviders>

<UiProviders> mounts Tooltip / Dialog / Toast in the right order and a top-level error Boundary (a crash shows a recoverable fallback, not a white screen). Mount it once at the root — library components (and everything in @djangocfg/ui-tools) trust it to be there and never nest their own (a second TooltipProvider is the canonical "Tooltip must be used within TooltipProvider" trap). Pass onError to forward crashes to your logger, errorFallback for a custom (e.g. i18n) crash screen, or errorBoundary={false} to opt out.

Catalogue

Group Examples
components/data/ Avatar · Badge · Card · Table · BalancedText · Skeleton
components/forms/ Button · Input · Textarea · Select · Switch · Checkbox · Slider · Form
components/feedback/ Alert · Toast · Banner · Progress · Spinner
components/overlay/ Dialog · Drawer · Popover · Tooltip · HoverCard · Sheet · ContextMenu · DropdownMenu
components/navigation/ Sidebar · Tabs · Breadcrumb · Pagination · NavigationMenu · Command
components/layout/ Container · Grid · Stack · Separator · ScrollArea · Sticky
components/select/ Combobox · MultiSelect
components/effects/ Glass · Marquee · Backdrop
components/specialized/ Accordion · Collapsible · Toggle · Calendar · DatePicker
components/boundary/ ErrorBoundary

Imports stay flat — group folders are organisational.

Hooks (/hooks)

Topic Hooks
dom/ useSize · useResizeObserver · useMeasure · useMutationObserver · useIntersection
device/ useIsMobile · useIsTouch · useMediaQuery · useOnline · useViewportSize · useOrientation
state/ useLocalStorage · useSessionStorage · useToggle · useCounter · useDebouncedValue
events/ useEventListener · useClickOutside · useKeyPress · useFocusWithin
theme/ useTheme · useResolvedTheme · useThemePreset
feedback/ useToast · useDialog · useClipboard · useConfirm
hotkey/ useHotkey (single key + chord)
audio/ useBeep · useSpeak (Web Speech)
tabs/ useCrossTab (BroadcastChannel coordination)
media/ useMediaPermissions · useUserMedia · useDevices
time/ useNow · useInterval · useTimeout
router/ useLink · useRouter (router-adapter consumer)

Lib utilities (/lib)

  • cn(...)clsx + tailwind-merge shortcut
  • getIntensity(value, thresholds) — quantise values into discrete bins (heatmaps, gauges)
  • createLogger() — leveled console logger
  • dialog-service — imperative confirm() / alert() / prompt() returning promises
  • persist — typed localStorage / sessionStorage hooks
  • pretext (subpath @djangocfg/ui-core/lib/pretext) — DOM-free text measurement via @chenglou/pretext; powers <BalancedText> and is the primitive for non-CSS line balancing

Router adapters

The router-aware components (Sidebar, Link, SSRPagination) read the active router via RouterAdapterProvider. Ship the adapter that matches your host:

Adapter Source
Next.js App Router @djangocfg/ui-core/adapters/nextjs
Plain <a> fallback default (no adapter)

Theming (/styles)

Tailwind v4 with semantic tokens, not raw color scales:

<Card className="bg-card border-border text-foreground" />
<Button className="bg-primary text-primary-foreground" />
<Alert className="bg-warning-background text-warning-foreground border-warning-border" />

Tokens live in :root / .dark as fully-wrapped CSS colors; @theme inline exposes them as --color-X references, so opacity modifiers (bg-card/40, border-foreground/20) resolve via color-mix for every semantic token.

@custom-variant dark (&:where(.dark, .dark *)) binds the dark: variant to the .dark class on <html> (not prefers-color-scheme) — every theme-switcher in this monorepo toggles that class.

Tailwind's text-* size utilities are bridged to the preset-overridable --font-size-* scale, so overriding those vars (globally via buildThemeStyleSheet({ vars }) or scoped on a selector) re-sizes all text-* at once — no per-component edits. See src/styles/README.md § Typography tokens.

Programmatic theme colors for Canvas / SVG / Mermaid:

import { useThemeColor, alpha, useStylePresets } from '@djangocfg/ui-core/styles/palette';

const primary = useThemeColor('primary');           // #00d9ff (hex, not oklch)
const dim = alpha(primary, 0.15);                   // 'rgba(0, 217, 255, 0.15)'
const { success, warning, danger } = useStylePresets();

Always hex-strings — color-mix(...) / oklch(...) syntax is rejected by Canvas2D fillStyle.

Live playground covers all tokens, presets, and dark-mode pairs.

Maintenance rule

After any change to components or hooks — update this README and bump the package patch version. Consumers pin to npm versions; surface drift in this file is the canonical changelog.

Requirements

  • React 18 or 19
  • Tailwind CSS v4 (host imports @djangocfg/ui-core/styles)

License

MIT — djangocfg.

Keywords