- JavaScript 83.9%
- TypeScript 15.6%
- HTML 0.2%
- CSS 0.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
The clear button listed `absolute` before `touchHitArea`, whose leading `relative` won the tailwind-merge conflict. The X became an in-flow flex item instead of an overlay: on hover it sat about half a field height low and a slot to the right of the calendar/clock icon, and that reserved slot pushed the icon inward whenever a value was set. Put `touchHitArea` first, as Sidebar already does for the same reason. Affects DatePicker, DateRangePicker and TimePicker. |
||
| .forgejo | ||
| .github/workflows | ||
| .storybook | ||
| dist | ||
| docs | ||
| nix | ||
| scripts | ||
| src | ||
| storybook-static | ||
| tests | ||
| .envrc | ||
| .gitignore | ||
| CLAUDE.md | ||
| flake.lock | ||
| flake.nix | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.ts | ||
| postcss.config.mjs | ||
| README.md | ||
| tsconfig.json | ||
| tsup.config.ts | ||
| version.txt | ||
| vitest.config.ts | ||
tibui
A React UI component library built with TypeScript, Tailwind CSS, and Radix UI.
Installation
From the public mirror
Consumers install from the public mirror, not from this repo:
# Install a specific release, select any tag here
npm install https://code.grail.tiberius.com/public/tibui/archive/v2.9.0.tar.gz
The mirror exists so that nix pipelines can fetch tibui with no credentials. Installing from the private repo would require injecting a private npm key into the build, which is impure and anti-nix. See Releasing for how the mirror is kept up to date.
Local Development
- Clone and run the dev server:
git clone git@code.grail.tiberius.com:grail/tibui.git
cd tibui
npm install
npm run dev
- In your consuming project's
package.json, reference the local path:
{
"dependencies": {
"tibui": "file:/path/to/tibui"
}
}
Then run npm install in your project. Changes to tibui will be picked up automatically.
Usage
Import Components
import { Button, Tabs, Toggle, TextField, DataTable } from 'tibui'
Import Styles
In your CSS or main entry file:
@import 'tibui/theme.css';
Or in JavaScript/TypeScript:
import 'tibui/theme.css'
Development
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run dev
# Type check
npm run typecheck
Testing
npm test # unit: theme contrast pairs, theme structure, no hardcoded colours
npm run test:visual # Playwright + axe: every component under every theme, plus screenshots
npm run test:visual:update # accept reviewed screenshot changes
npm run test:visual starts Storybook on port 6007 (or reuses a running one; set STORYBOOK_URL to point at another instance), renders the Themes/Gallery stories and the Mock App under each theme, fails on any axe color-contrast violation, and compares against the baselines in tests/visual/__screenshots__. Every axe finding is also appended to test-results/theme-contrast.ndjson. Chromium for Playwright is installed with npx playwright install chromium.
Storybook
This library uses Storybook for component development and documentation.
Running Storybook
Start the Storybook development server:
npm run storybook
This will start Storybook at http://localhost:6006 where you can browse and interact with all components.
Building Storybook
Build a static version of Storybook for deployment:
npm run build-storybook
This outputs a static site to the storybook-static directory, which can be deployed to any static hosting service.
Releasing
A release is two steps. Tagging alone does not publish anything — the tag is not visible to consumers until the public mirror has been synchronized.
| Repo | Purpose | |
|---|---|---|
| Source (private) | git@code.grail.tiberius.com:grail/tibui.git |
Where you develop and tag. This is origin. |
| Public mirror | https://code.grail.tiberius.com/public/tibui | What consumers and nix pipelines install from. |
The private repo cannot be consumed by nix pipelines: cloning it requires credentials, which would mean injecting a private npm key into the build. That is impure and anti-nix, so release tags are mirrored to a public repo that needs no credentials to fetch.
Step 1 — Cut the release
npm run release
The script (scripts/release.mjs) will:
- Abort if the working tree is dirty, or if you are not on
main git pull origin main- Prompt you to choose a version bump (patch, minor, major)
- Create branch
release/vX.Y.Zand runnpm run build - Update the version in
package.json - Commit
package.jsonanddist/aschore: bump version to vX.Y.Z - Push the branch and print the link to open the PR
- After the PR is squash-merged, tag the merged commit
vX.Y.Zonmainand push the tag
Note that dist/ is listed in .gitignore but is deliberately committed on every release
via git add -f dist/. Consumers install straight from git and do not run a build step, so
a release without dist/ is broken.
On completion the script reminds you that the release is not yet published, and prints the mirror sync URL along with a command to verify the tag.
Step 2 — Synchronize the public mirror
Open the mirror settings and trigger a sync:
https://code.grail.tiberius.com/public/tibui/settings
Do this after every release. Until it completes, npm install ...#vX.Y.Z and any nix
pipeline pinned to the new tag will fail to resolve, because the tag only exists on the
private repo.
Verify the tag landed:
git ls-remote --tags https://code.grail.tiberius.com/public/tibui.git | grep vX.Y.Z
Manual release
If you need to release without the script, mirror what it does — in particular, do not skip
the build or the forced dist/ add:
# 1. Clean tree on main, up to date
git checkout main
git pull origin main
git status --porcelain # must be empty
# 2. Build, then bump the "version" field in package.json by hand
npm run build
# 3. Commit the bump together with the build output
git add package.json
git add -f dist/
git commit -m "chore: bump version to v1.0.0"
# 4. Push for a PR; after it is squash-merged, tag the merged commit on main
git push -u origin HEAD:release/v1.0.0
git fetch origin && git tag v1.0.0 origin/main
git push origin v1.0.0
Then complete Step 2.
Tag management
# List all tags
git tag
# Delete a local tag
git tag -d v1.0.0
# Delete a remote tag
git push origin --delete v1.0.0
# Create annotated tag with message
git tag -a v1.0.0 -m "Release v1.0.0"
If you delete or move a tag on the private repo, re-sync the mirror so it does not keep serving the old tag.