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

@semiont/react-ui

v0.5.26

Published

React components and hooks for Semiont

Readme

@semiont/react-ui

Tests codecov npm version npm downloads License Accessibility Tests WCAG 2.1 AA

Framework-agnostic React component library for building Semiont knowledge management applications.

Overview

@semiont/react-ui provides reusable React components, hooks, and utilities for creating Semiont applications. The library is designed to be completely framework-agnostic, working seamlessly with Next.js, Create React App, Vite, Remix, or any other React framework.

Key Features

  • Framework Independence - Zero dependencies on Next.js, next-auth, or next-intl
  • Component Composition - Components accept framework-specific implementations (Link, routing) as props
  • Provider Pattern - Consistent approach for session, translations, and routing
  • SDK Live Queries - Read data with useObservable() over the SDK's read-through cache; no bespoke fetching layer
  • Authentication Components - Sign-in, sign-up, and error display components
  • Navigation Components - Collapsible sidebar with drag & drop resource tabs
  • Modal Components - Global search and resource selection modals
  • Accessibility First - WCAG compliant with keyboard navigation, screen reader support
  • Comprehensive Testing - 1250+ tests with extensive coverage
  • Annotation System - Rich annotation and tagging capabilities
  • Built-in Translations - English and Spanish included, with dynamic loading for optimal bundle size
  • Flexible i18n - Three modes: default English, built-in locales, or custom translation system
  • Favicon Assets - Complete set of Semiont branded favicons for all platforms

Installation

npm install @semiont/react-ui @semiont/sdk @semiont/core

@semiont/sdk is the primary dependency — it provides the SemiontBrowser, SemiontClient, the read-through cache, and the state machinery that @semiont/react-ui renders. @semiont/core provides the shared API types.

Peer Dependencies

{
  "react": "^19.0.0",
  "react-dom": "^19.0.0"
}

CSS Setup

Import the styles in your app's main CSS file:

/* Your app's main CSS file (e.g., globals.css, app.css) */
@import '@semiont/react-ui/styles';

Requirements:

  • Your build system must support PostCSS with postcss-import plugin
  • This is standard in Next.js, Vite, and most modern build tools
  • The package exports source CSS files, which your build system will process

What this does:

  • Imports all component styles, design tokens, and CSS variables
  • Your build tool processes the @import statements and bundles the CSS
  • No additional configuration needed in most frameworks

Quick Start

1. Set Up Providers

import {
  SemiontProvider,
  TranslationProvider,
  ProtectedErrorBoundary,
  SessionExpiredModal,
  PermissionDeniedModal,
} from '@semiont/react-ui';

function App({ children }) {
  const translationManager = useTranslationManager(); // Your implementation

  return (
    <TranslationProvider translationManager={translationManager}>
      {/* SemiontProvider puts the SemiontBrowser singleton into context.
          useSemiont() hands it back; the active SemiontSession (and its
          SemiontClient) flow from there. */}
      <SemiontProvider>
        <ProtectedErrorBoundary>
          <SessionExpiredModal />
          <PermissionDeniedModal />
          {children}
        </ProtectedErrorBoundary>
      </SemiontProvider>
    </TranslationProvider>
  );
}

2. Use Components

import { ResourceViewer, useSemiont, useObservable } from '@semiont/react-ui';

function MyComponent() {
  const semiont = useObservable(useSemiont().activeSession$)?.client;
  // browse.resources() is an SDK live query backed by the read-through cache.
  const resources = useObservable(semiont?.browse.resources({ limit: 20 }));

  if (!resources) return <div>Loading...</div>;

  return <ResourceViewer resource={resources[0]} />;
}

3. Use Translations

import { useTranslations } from '@semiont/react-ui';

// Option 1: Default English (no provider needed)
function Toolbar() {
  const t = useTranslations('Toolbar');
  return <button>{t('save')}</button>;
}

// Option 2: Built-in locales
import { TranslationProvider } from '@semiont/react-ui';

function App() {
  return (
    <TranslationProvider locale="es">
      <Toolbar />
    </TranslationProvider>
  );
}

// Option 3: Custom translation system
const myTranslationManager = {
  t: (namespace, key, params) => myI18n.translate(`${namespace}.${key}`, params)
};

function App() {
  return (
    <TranslationProvider translationManager={myTranslationManager}>
      <Toolbar />
    </TranslationProvider>
  );
}

Favicon Assets

The package includes Semiont-branded favicons in multiple formats (SVG, PNG, ICO) and a React component for inline usage. See docs/FAVICON.md for complete usage instructions.

Architecture

The library follows strict architectural principles:

  • No Aliasing or Wrappers - Direct API access, no compatibility layers
  • Provider Pattern - Consistent dependency injection via React Context
  • Framework Agnostic - Apps provide framework-specific implementations
  • TypeScript First - Full type safety throughout

CSS Architecture

The styles are organized into a modular, maintainable structure:

  • Design Tokens - Centralized variables for consistent theming
  • Core UI Elements - Fundamental, reusable components (buttons, toggles, sliders, etc.)
  • W3C Motivations - Dedicated styles for Web Annotation standard motivations
  • Component/Panel Separation - Complex components vs. layout containers
  • Dark Theme Support - Comprehensive dark mode using [data-theme="dark"]

Key directories:

  • styles/core/ - Fundamental UI elements (buttons, toggles, progress bars, sliders, badges, tags, indicators)
  • styles/motivations/ - W3C Web Annotation motivation styles (reference, highlight, assessment, comment, tag)
  • styles/components/ - Complex, composed components
  • styles/panels/ - Panel layouts and containers
  • styles/features/ - Feature-specific styling

See docs/STYLES.md for detailed CSS documentation.

Core Concepts

Providers

Cross-cutting concerns use the Provider Pattern:

  • SemiontProvider - The single React provider for session state. Puts the module-scoped SemiontBrowser singleton into context; useSemiont() returns it. The browser owns the KB list, active KB, and validated session lifecycle — it's the single source of truth for "which KB and what's the session against it." The active SemiontSession (and its SemiontClient) flow from browser.activeSession$.
  • TranslationProvider - Internationalization
  • RoutingContext - Framework-agnostic navigation

See docs/SESSION.md for details.

Page state machines

@semiont/react-ui houses the framework-neutral state machinery for the Semiont web frontend's specific pages and shell. These are RxJS-based factories (no React inside; pure observables and async functions) but they're shaped around the web frontend's page taxonomy, so they belong with the components that render them rather than in @semiont/sdk:

  • ShellcreateShellStateUnit (toolbar panel state with 'knowledge-base' | 'common' | 'resource' taxonomy), createSessionStateUnit (session-scoped logout)
  • PagescreateComposePageStateUnit, createResourceViewerPageStateUnit, createResourceLoaderStateUnit
  • AdmincreateAdminUsersStateUnit, createAdminSecurityStateUnit, createExchangeStateUnit (backup/restore + import/export)
  • Auth + discovery + moderationcreateWelcomeStateUnit, createDiscoverStateUnit, createEntityTagsStateUnit

Adjacent to the state units: useKBDiscovery binds the sdk's launcher-KB discovery subscription (subscribeDiscovery) to React state — see SESSION.md.

Each lives in src/features/<feature>/state/ (or src/state/ for cross-feature ones) next to the components that consume it. The useStateUnit hook wires them into React lifecycles.

Use them via import { createComposePageStateUnit } from '@semiont/react-ui'. UI-shape-neutral state machines (flow VMs, worker adapters, search pipeline) continue to live in @semiont/sdk and are re-exported from here for convenience.

API Integration

Data fetching and caching are an SDK concern. The SDK exposes an RxJS read-through cache (stale-while-revalidate); react-ui consumes it as live queries via useObservable(). Reads come from client.browse.*(...) observables; writes go through the typed namespaces (client.mark.*, client.bind.*, etc.).

import { useSemiont, useObservable } from '@semiont/react-ui';

function Example() {
  const client = useObservable(useSemiont().activeSession$)?.client;

  // Read: live query over the read-through cache
  const resources = useObservable(client?.browse.resources({ limit: 10 }));

  // Write: typed namespace call (cache invalidation is handled by the SDK)
  const archive = (rUri) => client?.mark.archive(rUri);
}

See docs/API-INTEGRATION.md for details.

Testing

Comprehensive test utilities included:

import { renderWithProviders } from '@semiont/react-ui/test-utils';

it('should render component', () => {
  renderWithProviders(<MyComponent />);
  expect(screen.getByText('Hello')).toBeInTheDocument();
});

See docs/TESTING.md for details.

Documentation

Examples

Next.js Integration

// app/providers.tsx
'use client';

import { useLocale } from 'next-intl';
import { TranslationProvider, SemiontProvider } from '@semiont/react-ui';

export function useTranslationManager() {
  const locale = useLocale();
  const messages = require(`@/messages/${locale}.json`);

  return {
    t: (namespace, key) => messages[namespace]?.[key] || key
  };
}

export function Providers({ children }) {
  const translationManager = useTranslationManager();

  // SemiontProvider defaults to the canonical web setup (WebBrowserStorage +
  // an HTTP session factory). It reads the module-scoped SemiontBrowser
  // singleton via getBrowser() — no client construction here. Sign-in flows
  // adopt the OAuth session onto the browser; browser.activeSession$ then
  // carries the live SemiontClient.
  return (
    <TranslationProvider translationManager={translationManager}>
      <SemiontProvider>{children}</SemiontProvider>
    </TranslationProvider>
  );
}

Vite Integration

// src/App.tsx
import { useState } from 'react';
import { TranslationProvider } from '@semiont/react-ui';

function useTranslationManager() {
  const [locale] = useState('en');

  return {
    t: (namespace, key) => `${namespace}.${key}` // Your i18n library
  };
}

function App() {
  const translationManager = useTranslationManager();

  return (
    <TranslationProvider translationManager={translationManager}>
      {/* Your app */}
    </TranslationProvider>
  );
}

Development

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

# Type checking
npm run typecheck

Contributing

This library follows strict quality standards:

  • 100% TypeScript - All code must be properly typed
  • No any casts - Without explicit permission
  • No cruft - Delete dead code immediately, no "legacy" patterns
  • Direct fixes - If something is wrong, fix it directly (no aliases/wrappers)

See CONTRIBUTING.md in the repository root for full guidelines.

License

[License information to be added]

Related Packages

  • @semiont/sdk - SemiontBrowser, SemiontClient, the read-through cache, and the state machinery. Its Developer Guide covers end-to-end use, including embedding this package's ResourceViewer.
  • @semiont/core - Shared API types (components) generated from the OpenAPI spec
  • @semiont/http-transport - HTTP transport (HttpTransport, HttpContentTransport, APIError)
  • semiont-frontend - Reference Next.js implementation