hazo_ui 4.3.0 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGE_LOG.md +16 -0
  2. package/README.md +89 -0
  3. package/package.json +3 -2
package/CHANGE_LOG.md CHANGED
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## v4.3.0 (2026-06-19)
9
+
10
+ ### New
11
+ - `NotificationCountBadge` — compact unread-count pill/badge. Renders a circular badge
12
+ for counts 1–`max` (default 9) and a pill-shaped `"N+"` label for overflow. Returns
13
+ null when `count <= 0`; no DOM footprint when there is nothing to show.
14
+ - `NotificationItem` — single notification row with an unread-dot indicator, message
15
+ content slot, pre-formatted timestamp, optional domain `actions` slot, and an optional
16
+ "mark read" button (rendered only when `!isRead && onMarkRead` is provided). Row
17
+ highlights on hover when an `onClick` handler is attached.
18
+ - `NotificationPanel` — scrollable notification list shell (max-height 480 px) that
19
+ wraps `NotificationItem` rows. Handles three display states: loading skeleton (3
20
+ animated rows), empty state slot, and populated list. Renders an optional "Mark all
21
+ as read" footer button via `onMarkAllRead`. All user-facing labels are props with no
22
+ English defaults so consumers can pass i18n strings directly.
23
+
8
24
  ## v4.2.0 (2026-06-14)
9
25
 
10
26
  ### New
package/README.md CHANGED
@@ -206,6 +206,8 @@ The following components support both global config and prop-level color overrid
206
206
 
207
207
  - **[HazoUiImageCropper / HazoUiImageCropperDialog](#hazouiimagecropper--hazouiimagecropperdialog)** (v4.2.0) - Round profile-photo cropper with pan/zoom built on `react-easy-crop`. Outputs a 512×512 WebP Blob. The standalone `HazoUiImageCropper` exposes a `getCroppedBlob()` imperative handle; `HazoUiImageCropperDialog` wraps it in a dialog with a managed object-URL lifecycle and loading state.
208
208
 
209
+ - **[Notification Components](#notification-components-v430)** (v4.3.0) - Three composable primitives for building notification UIs: `NotificationCountBadge` (unread-count pill), `NotificationItem` (single row with dot indicator, timestamp, actions, and mark-read), and `NotificationPanel` (scrollable shell with loading skeleton, empty state, and "Mark all as read" footer). All label strings are props — no English defaults — so i18n works without wrappers.
210
+
209
211
  - **[HazoUiTable](#hazouitable--column-config-driven-data-table-v2140)** - A column-config-driven data table built on a shadcn `Table` primitive family. Sortable headers, debounced search, multi-column filter / sort dialogs, pagination, row click (mouse + keyboard), loading / empty / no-results states, and a card-per-row mobile fallback. Optional server-side `onLoad`.
210
212
 
211
213
  - **[Drawer](#drawer)** - A `vaul`-backed bottom sheet primitive for mobile UIs. Pair with `useMediaQuery` to swap between `Dialog` and `Drawer` based on viewport width.
@@ -3703,6 +3705,93 @@ If `onCardSave` is not provided, the pencil is hidden entirely
3703
3705
 
3704
3706
  ---
3705
3707
 
3708
+ ## Notification Components (v4.3.0)
3709
+
3710
+ Three composable primitives for building in-app notification UIs. Import from `hazo_ui`:
3711
+
3712
+ ```ts
3713
+ import {
3714
+ NotificationCountBadge,
3715
+ NotificationItem,
3716
+ NotificationPanel,
3717
+ } from "hazo_ui";
3718
+ ```
3719
+
3720
+ ### NotificationCountBadge
3721
+
3722
+ Compact circular/pill badge showing an unread count. Returns `null` when `count <= 0` so
3723
+ you can unconditionally render it without extra guards.
3724
+
3725
+ ```tsx
3726
+ <NotificationCountBadge count={3} /> {/* circular "3" */}
3727
+ <NotificationCountBadge count={42} max={9} /> {/* pill "9+" */}
3728
+ ```
3729
+
3730
+ | Prop | Type | Default | Description |
3731
+ |---|---|---|---|
3732
+ | `count` | `number` | — | Raw unread count |
3733
+ | `max` | `number` | `9` | Shows `"N+"` when `count > max` |
3734
+ | `className` | `string` | — | Additional Tailwind classes |
3735
+
3736
+ ### NotificationItem
3737
+
3738
+ Single notification row. Renders an unread-dot indicator, message children, a timestamp,
3739
+ optional action buttons, and an optional "mark read" link.
3740
+
3741
+ ```tsx
3742
+ <NotificationItem
3743
+ isRead={false}
3744
+ timestamp="2 hours ago"
3745
+ onMarkRead={() => markRead(id)}
3746
+ markReadLabel="Mark read"
3747
+ onClick={() => openThread(id)}
3748
+ >
3749
+ <strong>Alice</strong> commented on your document.
3750
+ </NotificationItem>
3751
+ ```
3752
+
3753
+ | Prop | Type | Description |
3754
+ |---|---|---|
3755
+ | `isRead` | `boolean` | Suppresses dot indicator and blue background when true |
3756
+ | `timestamp` | `string` | Pre-formatted relative timestamp (e.g. `"2 hours ago"`) |
3757
+ | `children` | `ReactNode` | Notification message content |
3758
+ | `actions` | `ReactNode` | Optional domain buttons rendered below the message |
3759
+ | `onClick` | `() => void` | Makes the row clickable with hover state |
3760
+ | `onContextMenu` | `MouseEventHandler` | Right-click handler |
3761
+ | `onMarkRead` | `() => void` | When provided AND `!isRead`, shows the "mark read" button |
3762
+ | `markReadLabel` | `string` | i18n label for the mark-read button |
3763
+
3764
+ ### NotificationPanel
3765
+
3766
+ Scrollable shell (max-height 480 px) wrapping `NotificationItem` rows. Manages three
3767
+ display states automatically: loading skeleton, empty state, and populated list.
3768
+
3769
+ ```tsx
3770
+ <NotificationPanel
3771
+ loading={isLoading}
3772
+ emptyState={<p className="text-muted-foreground text-sm">No notifications</p>}
3773
+ onMarkAllRead={markAllRead}
3774
+ markAllReadLabel="Mark all as read"
3775
+ >
3776
+ {notifications.map((n) => (
3777
+ <NotificationItem key={n.id} isRead={n.is_read} timestamp={n.time_ago} markReadLabel="Mark read">
3778
+ {n.message}
3779
+ </NotificationItem>
3780
+ ))}
3781
+ </NotificationPanel>
3782
+ ```
3783
+
3784
+ | Prop | Type | Description |
3785
+ |---|---|---|
3786
+ | `children` | `ReactNode` | `NotificationItem` rows |
3787
+ | `loading` | `boolean` | Shows 3 animated skeleton rows when true |
3788
+ | `emptyState` | `ReactNode` | Rendered when not loading and no children |
3789
+ | `onMarkAllRead` | `() => void` | When provided, renders the "Mark all as read" footer button |
3790
+ | `markAllReadLabel` | `string` | i18n label for the mark-all-read button |
3791
+ | `className` | `string` | Additional Tailwind classes for the outer container |
3792
+
3793
+ ---
3794
+
3706
3795
  ## HazoUiTable — Column-config-driven Data Table (v2.14.0+, v2.15 additions)
3707
3796
 
3708
3797
  A higher-level data table that composes the shadcn `Table` primitive
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hazo_ui",
3
- "version": "4.3.0",
3
+ "version": "4.3.1",
4
4
  "description": "Set of UI components for common interaction elements in a SaaS app",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,8 @@
20
20
  },
21
21
  "./test-harness": {
22
22
  "types": "./dist/test-harness/index.d.ts",
23
- "import": "./dist/test-harness/index.js"
23
+ "import": "./dist/test-harness/index.js",
24
+ "require": "./dist/test-harness/index.cjs"
24
25
  },
25
26
  "./utils": {
26
27
  "types": "./dist/index.utils.d.ts",