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

@kollegioai/ui

v1.3.6

Published

Kollegio shared React components — framework-agnostic (plain CSS + tokens)

Readme

@kollegioai/ui

Kollegio's shared React component library — framework-agnostic (plain CSS + design tokens, no Chakra/Tailwind/emotion dependency). Published to npmjs.com.

Companion to @kollegioai/tokens (colors + typography). This package is the component layer.


Setup (all apps)

Load the token variables and component styles once, at the app entry:

import '@kollegioai/tokens/vars.css'; // --kollegio-* design-token variables
import '@kollegioai/ui/styles.css';   // component CSS (wrapped in @layer kollegio-ui)

All component CSS lives in @layer kollegio-ui, so any unlayered app CSS (emotion, Tailwind utilities, inline styles) automatically wins over the variant presets — no specificity fights.

Peer dependency: react >= 18. Nothing else.


Two consumption modes

1. Direct (non-Chakra apps — e.g. landing-v2)

Use the components as-is. Bespoke styling via className or the CSS-variable hooks on style (these also apply inside hover/active states):

import { Button } from '@kollegioai/ui/Button';

<Button variant="primary" buttonSize="lg" onClick={...}>Save</Button>

// override paint via --kui-* hooks
<Button
  variant="outline"
  style={{ '--kui-btn-radius': '999px', '--kui-btn-hover-bg': 'var(--kollegio-backgroundPrimarySubtle)' }}
>
  Pill
</Button>

Button hooks: --kui-btn-bg, -color, -border-color, -hover-bg, -hover-color, -hover-border-color, -active-bg, -radius, -h, -min-h, -px, -py, -fs, -gap, -disabled-opacity. Tooltip hooks: --kui-tooltip-bg, -color, -fs, -radius, -px, -py, -max-w, -z.

2. Chakra bridge (Chakra v3 apps — client/client-src, counsellor)

Wrap the universal component with Chakra's chakra() factory at one adapter seam. Call sites then keep the full Chakra style-prop API (w="150px", bg="backgroundPrimary", _hover={{…}}, responsive values), resolved against the app's own theme:

// src/shared/components/KollegioButton.tsx (adapter seam — once per app)
import { chakra, type HTMLChakraProps } from '@chakra-ui/react';
import { Button as UniversalButton } from '@kollegioai/ui/Button';

const KollegioButton = chakra(UniversalButton, {}, {
  // non-style props the factory must pass through to the component
  forwardProps: ['variant', 'buttonSize', 'fullWidth', 'isLoading', 'loadingText',
                 'spinnerPlacement', 'leftIcon', 'rightIcon', 'enableTouchEndClickFix'],
});

Because the package CSS is layered, the emotion styles generated by the bridge always override the variant presets.

Caveat: as= / asChild on a bridged component replaces the universal Button itself (losing its logic and classes) — don't use them; handle navigation in onClick instead.

New shared components automatically get both modes — author them universally here, and each Chakra app's seam file decides whether to bridge.


Components

Subpath exports keep bundles lean (sideEffects: false):

| Import | Description | |---|---| | @kollegioai/ui/Button | Brand button. Variants: primary, primaryStrong, accent, outline, secondary, tertiary, light, ghost, oauth, logOut. Sizes via buttonSize (sm/md/lg). Also: fullWidth, isLoading/loadingText/spinnerPlacement, leftIcon/rightIcon, enableTouchEndClickFix. | | @kollegioai/ui/Spinner | Loading spinner (size sm/md/lg, optional label). Inherits currentColor. | | @kollegioai/ui/Input | Text input. inputSize (sm/md/lg), invalid, fullWidth, leftElement/rightElement adornments. className + chakra-bridge style props target the bordered group. | | @kollegioai/ui/Textarea | Multiline input. invalid, fullWidth, rows; shares the --kui-input-* paint vars with Input. | | @kollegioai/ui/Field | Form-field layout: label row (+ required, labelExtra) + control + error/helperText. Pair with Input/Textarea (pass matching id/htmlFor and invalid={!!error}). | | @kollegioai/ui/Tooltip | Radix-based tooltip (plain-text/ReactNode label), tap-to-open on touch devices. offset accepts a number or { mainAxis, crossAxis }. | | @kollegioai/ui/TooltipMarkdown | Tooltip whose label renders markdown (pulls in react-markdown — only pay for it if you import this entry). | | @kollegioai/ui/EllipsisMenu | Three-dot overflow menu (EllipsisMenu + EllipsisMenuOption). | | @kollegioai/ui | Barrel of all of the above (except TooltipMarkdown). |

Variant/size presets are data in src/recipes/button.ts; scripts/gen-button-css.mjs generates styles/button.css from it at build time.


Storybook

pnpm --filter @kollegioai/ui storybook

Renders every component/variant against the token CSS variables — no provider needed.


Test changes in a consumer app (without publishing)

When you change a component here and want to see it in client/client-src (or counsellor) before publishing, don't bump+publish a throwaway version. Use one of the methods below.

Why not npm link / file:? Those symlink the package, and Vite then resolves react from packages/ui/node_modules (its dev copy of React 18) instead of the app's React. Two React instances → Invalid hook call crash. The tarball method below avoids this because the tarball ships no node_modulesreact, react-dom, @radix-ui/*, and @kollegioai/tokens are all external, so they resolve to the consumer app's own copies, exactly as a real install would. (If you must symlink for a faster loop, see the note at the end.)

Method 1 — packed tarball (recommended, true-to-published)

This produces the exact artifact npm would publish.

# 1) Build + pack the package → kollegioai-ui-<version>.tgz
cd "landing-v2/packages/ui"
pnpm build
pnpm pack

# 2) Install that tarball into the consumer (absolute path is safest)
cd "../../../client/client-src"
npm install "../../landing-v2/packages/ui/kollegioai-ui-$(node -p "require('../../landing-v2/packages/ui/package.json').version").tgz"

# 3) Run the app and verify
npm run dev

package.json in client-src will now point at the local tarball ("@kollegioai/ui": "file:..."). Don't commit that change.

Method 2 — tarball watch loop (faster iteration)

For repeated edits, keep a rebuild loop running and re-pack/re-install after each change. In one terminal:

cd "landing-v2/packages/ui" && pnpm dev    # tsup --watch: rebuilds dist/ on every save

Then, after a batch of edits, refresh the consumer (the tarball reflects whatever dist/ currently holds):

cd "landing-v2/packages/ui" && pnpm pack
cd "../../../client/client-src" && npm install "../../landing-v2/packages/ui/"*.tgz && npm run dev

Revert to the published version

Once you've published (or to undo local linking), reinstall from the registry and discard the package.json/lockfile edits:

cd "client/client-src"
npm install @kollegioai/ui@latest        # or @^<version>
git checkout package.json package-lock.json   # drop the file: pointer
rm -f "../../landing-v2/packages/ui/"*.tgz     # clean up tarballs

Faster symlink loop (advanced). If the re-pack loop is too slow, you can npm install "../../landing-v2/packages/ui" (symlinked) together with pnpm dev, but you must first stop Vite from double-loading React: add react and react-dom to resolve.dedupe in client-src/vite.config.ts. Without that you'll get Invalid hook call. Revert the vite.config.ts edit afterward.


Build, version & publish

The registry rejects re-publishing an existing version, so every publish starts with a version bump.

1. Bump the version in package.json (semver — patch for fixes, minor for new components, major for breaking prop changes).

// packages/ui/package.json
"version": "1.3.3",

Option A — CI auto-publish (recommended)

Just merge the version bump to main. .github/workflows/publish-ui.yml builds and runs pnpm --filter @kollegioai/ui publish --no-git-checks automatically on any change under packages/ui/** (story-only changes are excluded). It authenticates with the NPM_TOKEN repo secret — no local token needed. This is how releases normally go out.

Option B — Manual local publish (pnpm release)

Use when you can't wait for CI. After bumping the version, one command does everything:

cd "landing-v2/packages/ui"
pnpm release

release runs scripts/publish.sh, which:

  1. Loads NPM_TOKEN from packages/ui/.env (gitignored — never committed, never echoed).
  2. Builds (pnpm build).
  3. Writes a temporary .npmrc containing only the literal ${NPM_TOKEN} placeholder (npm expands it from the env var at publish time — the secret never touches disk).
  4. Runs pnpm publish --no-git-checks --access public (pnpm rewrites workspace:^ deps to real versions automatically).
  5. Removes the temp .npmrc on exit via a trap — guaranteed even if the publish fails.

Setup (one-time): create packages/ui/.env with:

NPM_TOKEN=npm_yourAutomationTokenHere

The NPM_TOKEN must be an Automation token (or a granular token with "bypass two-factor authentication" enabled). The account enforces 2FA for publishing, so a plain publish/login token fails with E403 … bypass 2fa. Both .env and .npmrc are already covered by the repo .gitignore.

Verify & consume

npm view @kollegioai/ui version            # confirm the new version is live

# repoint consumers (landing apps auto-update via workspace:^)
cd "/Users/mac/Documents/Kollegio AI/client/client-src" && npm install @kollegioai/ui@^<new-version>
cd "/Users/mac/Documents/Kollegio AI/counsellor"        && npm install @kollegioai/ui@^<new-version>

For local testing before publishing, skip the registry entirely: pnpm pack and install the resulting tarball in a consumer.