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

@u-b/tides-react

v0.1.0

Published

React tide widget for @u-b/tides-core with the ubtide theming contract

Downloads

28

Readme

@u-b/tides-react

React tide widget for @u-b/tides-core. ESM-only, ships 'use client' components with a fully namespaced (.ubtide) theming contract.

pnpm add @u-b/tides-react

@u-b/tides-core comes along as a dependency. react / react-dom (18.2+ or 19) are peer dependencies you already have.

Usage

Two lines — import the stylesheet once, drop the widget in:

import { TideWidget } from '@u-b/tides-react'
import '@u-b/tides-react/styles.css'

export default function Page() {
  return <TideWidget />
}

Consumer contract

The widget renders its own content only. You own the page chrome:

  • Import the stylesheetimport '@u-b/tides-react/styles.css' exactly once in your app. Without it the widget is unstyled.
  • Supply the page shell — the widget no longer paints a page background, min-height, or padding. Give the page its own min-h-screen, padding, and background/text colors.
  • Constrain the width yourself — every widget section is width: 100% (fluid). Wrap it in your own max-width container if you want a column.
  • Known stylesheet globals — besides the .ubtide-scoped rules, styles.css carries Tailwind v4's declaration-only layers: :root theme variables (--spacing, --text-*, --color-*, …) and --tw-* @property fallbacks. They restyle nothing by themselves, but if your page also uses Tailwind v4 with customized theme values, load your own stylesheet after this one so yours wins.
<main className="min-h-screen bg-white text-black p-4">
  <div className="mx-auto max-w-md">
    <TideWidget />
  </div>
</main>

SSR / RSC

The components carry the 'use client' directive and render fine from a Server Component tree (Next.js App Router, etc.). For deterministic server output pass now / initialDate; without them the clock resolves in a mount effect and the server-rendered skeleton hydrates cleanly.

Theming

Everything renders inside a .ubtide wrapper, and every themable value is a --ubtide-* CSS custom property on it. There are three ways to theme, in increasing specificity.

1. Defaults

Ship nothing and you get the brutalist monochrome default (see table below).

2. CSS cascade

Override tokens anywhere in your own CSS — they inherit down from .ubtide:

.ubtide {
  --ubtide-accent: #0aa;
  --ubtide-card-border-width: 2px; /* see note below */
}

3. theme prop

Pass a partial theme object (camelCase keys map 1:1 to the kebab tokens):

<TideWidget theme={{ accent: '#0aa', cardBg: '#fff', cardBorderWidth: '2px' }} />

Regional class hooks

Each section carries a stable class you can target without touching internals: ubtide-current, ubtide-calendar, ubtide-curve, ubtide-events.

.ubtide-events { font-size: 0.9rem; }

Card border note

--ubtide-card-border-width defaults to 0px. The historical pre-split --card-border compound token produced an invalid declaration and never rendered, so 0px preserves the established look. For the intended brutalist card border:

.ubtide { --ubtide-card-border-width: 2px; }

Token table

| Token | Colors / controls | Default | | --- | --- | --- | | --ubtide-bg | Widget background | transparent | | --ubtide-card-bg | Card surfaces (curve panel, calendar cells) | #fff | | --ubtide-card-border-width | Card border thickness (0px historical, 2px brutalist) | 0px | | --ubtide-card-border-color | Card border color | #111 | | --ubtide-border-strong | Strong dividers / structural borders | #111 | | --ubtide-header-bg | Header strip background | #f0f0f0 | | --ubtide-header-text | Header text | #111 | | --ubtide-text | Primary text | #111 | | --ubtide-text-muted | Secondary / muted text | #555 | | --ubtide-accent | Accent color | #111 | | --ubtide-current-bg | Current-level panel background | #111 | | --ubtide-current-text | Current-level text | #fff | | --ubtide-current-muted | Current-level muted text | #aaa | | --ubtide-high-bg | High-tide badge background | #111 | | --ubtide-high-text | High-tide badge text | #fff | | --ubtide-low-bg | Low-tide badge background | #fff | | --ubtide-low-text | Low-tide badge text | #111 | | --ubtide-low-border | Low-tide badge border | #111 | | --ubtide-selected-bg | Selected calendar day background | #111 | | --ubtide-selected-text | Selected calendar day text | #fff | | --ubtide-today-border | Today cell border | #111 | | --ubtide-curve-stroke | Tide curve line | #111 | | --ubtide-curve-dot | Curve extreme dots (high) | #111 | | --ubtide-curve-dot-low | Curve extreme dots (low fill) | #fff | | --ubtide-bar-bg | Level bar track | #e5e5e5 | | --ubtide-bar-fill | Level bar fill | #111 | | --ubtide-sun-moon-bg | Sun/moon almanac panel background | #f5f5f5 | | --ubtide-sun-color | Sun glyph color | #d97706 | | --ubtide-font-family | Widget font family | 'SF Mono', Consolas, monospace | | --ubtide-border-radius | Corner radius | 0 | | --ubtide-shadow | Box shadow | none |

Composing individual components

TideWidget is the batteries-included layout. You can also compose the pieces yourself and drive them from the headless @u-b/tides-core station:

import { CurrentLevel, Calendar, TideCurve, TideEvents } from '@u-b/tides-react'
import { stHelier } from '@u-b/tides-core/stations/st-helier'

Exported components: TideWidget, Calendar, CurrentLevel, TideCurve, TideEvents, plus the TideTheme type. Each component ships its own *Props type.

License

MIT