harebear-ui 0.8.0 → 0.8.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.
|
@@ -4,6 +4,7 @@ import { Badge } from "../ui/badge.js";
|
|
|
4
4
|
import { Button } from "../ui/button.js";
|
|
5
5
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible.js";
|
|
6
6
|
import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from "../ui/sidebar.js";
|
|
7
|
+
import { useToastClearance } from "../../lib/toast-clearance.js";
|
|
7
8
|
import { cn } from "../../lib/utils.js";
|
|
8
9
|
import * as React from "react";
|
|
9
10
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -18,6 +19,8 @@ const TAB_LIMIT = 5;
|
|
|
18
19
|
*/
|
|
19
20
|
function AppNav({ brand, places, group, footer, action, label = "Main", linkComponent = "a", collapsible, storageKey, defaultOpen, width = "15.75rem", className, children }) {
|
|
20
21
|
const tabs = places.filter((p) => p.tab !== false).slice(0, TAB_LIMIT);
|
|
22
|
+
useToastClearance("--hb-toast-nav", "calc(4.5rem + env(safe-area-inset-bottom))", tabs.length > 0);
|
|
23
|
+
useToastClearance("--hb-toast-fab", "4.5rem", Boolean(action));
|
|
21
24
|
return /* @__PURE__ */ jsxs(SidebarLayout, {
|
|
22
25
|
brand,
|
|
23
26
|
collapsible,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { AskBox } from "./ask-box.js";
|
|
3
3
|
import { AssistantAvatar, ChatMessage, ChatThread, TypingIndicator } from "./chat.js";
|
|
4
4
|
import { Button } from "../ui/button.js";
|
|
5
|
+
import { useToastClearance } from "../../lib/toast-clearance.js";
|
|
5
6
|
import { cn } from "../../lib/utils.js";
|
|
6
7
|
import * as React from "react";
|
|
7
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -136,6 +137,7 @@ function AssistantDock({ title = "Assistant", icon = /* @__PURE__ */ jsx(Sparkle
|
|
|
136
137
|
panelRef.current?.querySelector("textarea")?.focus();
|
|
137
138
|
send(text);
|
|
138
139
|
};
|
|
140
|
+
useToastClearance("--hb-toast-launcher", "3.5rem", !open && launcher);
|
|
139
141
|
if (!open) {
|
|
140
142
|
if (!launcher) return null;
|
|
141
143
|
return /* @__PURE__ */ jsxs("button", {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
// src/lib/toast-clearance.ts
|
|
4
|
+
const counts = /* @__PURE__ */ new Map();
|
|
5
|
+
function useToastClearance(name, value, enabled = true) {
|
|
6
|
+
React.useEffect(() => {
|
|
7
|
+
if (!enabled || typeof document === "undefined") return;
|
|
8
|
+
const root = document.documentElement;
|
|
9
|
+
counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
10
|
+
root.style.setProperty(name, value);
|
|
11
|
+
return () => {
|
|
12
|
+
const left = (counts.get(name) ?? 1) - 1;
|
|
13
|
+
counts.set(name, left);
|
|
14
|
+
if (left === 0) root.style.removeProperty(name);
|
|
15
|
+
};
|
|
16
|
+
}, [
|
|
17
|
+
name,
|
|
18
|
+
value,
|
|
19
|
+
enabled
|
|
20
|
+
]);
|
|
21
|
+
}
|
|
22
|
+
export { useToastClearance };
|
package/dist/styles.css
CHANGED
|
@@ -285,3 +285,26 @@
|
|
|
285
285
|
background-color: color-mix(in oklab, var(--muted-foreground) 60%, transparent);
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
|
+
|
|
289
|
+
/* Toasts clear floating controls. AppNav (tab bar, action button) and AssistantDock (launcher) set --hb-toast-* on
|
|
290
|
+
<html> while mounted (src/lib/toast-clearance.ts); this adds them to Sonner's bottom offset. Unlayered and
|
|
291
|
+
!important because Sonner injects its own unlayered rule at runtime. Breakpoints: AppNav's tab bar shows under
|
|
292
|
+
768px; Sonner switches to full-width mobile toasts under 600px. */
|
|
293
|
+
[data-sonner-toaster][data-y-position="bottom"] {
|
|
294
|
+
bottom: calc(var(--offset-bottom) + var(--hb-toast-launcher, 0px)) !important;
|
|
295
|
+
}
|
|
296
|
+
@media (max-width: 767px) {
|
|
297
|
+
[data-sonner-toaster][data-y-position="bottom"] {
|
|
298
|
+
bottom: calc(
|
|
299
|
+
var(--offset-bottom) + var(--hb-toast-nav, 0px) + var(--hb-toast-fab, 0px) + var(--hb-toast-launcher, 0px)
|
|
300
|
+
) !important;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
@media (max-width: 600px) {
|
|
304
|
+
[data-sonner-toaster][data-y-position="bottom"] {
|
|
305
|
+
bottom: calc(
|
|
306
|
+
var(--mobile-offset-bottom) + var(--hb-toast-nav, 0px) + var(--hb-toast-fab, 0px) +
|
|
307
|
+
var(--hb-toast-launcher, 0px)
|
|
308
|
+
) !important;
|
|
309
|
+
}
|
|
310
|
+
}
|
package/docs/COMPONENTS.md
CHANGED
|
@@ -278,7 +278,7 @@ Muted tile that lifts on hover, for service launchers. Props: `title`, `subtitle
|
|
|
278
278
|
One nav config, two renderings: on desktop a `SidebarLayout` sidebar (brand, action button, places, one collapsible group, footer; active place is a raised card; collapses to the icon rail), under 768px a bottom tab bar (first 5 places, 56px targets, `aria-current="page"`) plus a round floating action button. Use it instead of `AppShell` for consumer apps that need phone navigation.
|
|
279
279
|
|
|
280
280
|
Props: `places: AppNavPlace[]` (`label`, `icon?`, `href?` or `onSelect?`, `active?`, `count?`, `tab?: false` to keep out of the tab bar), `group?: AppNavGroup` (`label`, `items`, `defaultOpen?`, `onAdd?`, `addLabel?`), `action?: { label; icon; onSelect }`, `brand?`, `footer?` (usually `UserMenu`), `label?` (nav name, default "Main"), `linkComponent?`, `collapsible?`, `storageKey?`, `defaultOpen?`, `width?`, `children`.
|
|
281
|
-
On phones the group and footer live in the sidebar sheet: put a `SidebarTrigger` in the page header if users need them there. Render `AssistantDock` inside `children` so it clears the tab bar, and
|
|
281
|
+
On phones the group and footer live in the sidebar sheet: put a `SidebarTrigger` in the page header if users need them there. Render `AssistantDock` inside `children` so it clears the tab bar. Toasts stack above the tab bar, the action button and the dock launcher on their own; no `Toaster` offset needed.
|
|
282
282
|
|
|
283
283
|
### `FocusLayout`
|
|
284
284
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harebear-ui",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Opinionated, pre-themed shadcn/ui component library for React 19 + Tailwind CSS v4. Admin, data, and AI chat building blocks, ready for agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Harrison Milbradt",
|