@papernote/ui 1.7.1 → 1.7.2

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.
package/dist/index.js CHANGED
@@ -7279,8 +7279,93 @@ function Hide({ children, above, below, only, className = '' }) {
7279
7279
  return (jsxRuntime.jsx("div", { className: `${visibilityClasses} ${className}`, children: children }));
7280
7280
  }
7281
7281
 
7282
+ /**
7283
+ * Hook to detect breadcrumb navigation and trigger callbacks.
7284
+ * Use this in host components to reset state when a breadcrumb is clicked.
7285
+ *
7286
+ * @param onReset - Callback fired when breadcrumb navigation is detected
7287
+ *
7288
+ * @example
7289
+ * function ProductsPage() {
7290
+ * const [viewMode, setViewMode] = useState<'list' | 'detail'>('list');
7291
+ *
7292
+ * // Automatically reset to list view when breadcrumb is clicked
7293
+ * useBreadcrumbReset(() => setViewMode('list'));
7294
+ *
7295
+ * // ... rest of component
7296
+ * }
7297
+ */
7298
+ function useBreadcrumbReset(onReset) {
7299
+ const location = reactRouterDom.useLocation();
7300
+ const lastResetRef = React.useRef(null);
7301
+ React.useEffect(() => {
7302
+ const state = location.state;
7303
+ if (state?.breadcrumbReset && state.breadcrumbReset !== lastResetRef.current) {
7304
+ lastResetRef.current = state.breadcrumbReset;
7305
+ onReset();
7306
+ }
7307
+ }, [location.state, onReset]);
7308
+ }
7309
+ /**
7310
+ * Breadcrumbs navigation component.
7311
+ *
7312
+ * When a breadcrumb with href is clicked:
7313
+ * - If navigating to a different route: standard navigation occurs
7314
+ * - If navigating to the same route: navigation state is updated with a unique key,
7315
+ * which can be used by host apps to detect "reset" navigation via useLocation().state
7316
+ *
7317
+ * @example
7318
+ * // Basic usage
7319
+ * <Breadcrumbs items={[
7320
+ * { label: 'Home', href: '/' },
7321
+ * { label: 'Products', href: '/products' },
7322
+ * { label: 'Widget' } // Current page (no href)
7323
+ * ]} />
7324
+ *
7325
+ * @example
7326
+ * // Host app detecting breadcrumb navigation for state reset
7327
+ * function ProductsPage() {
7328
+ * const location = useLocation();
7329
+ * const [viewMode, setViewMode] = useState<'list' | 'detail'>('list');
7330
+ *
7331
+ * // Reset to list view when breadcrumb navigation occurs
7332
+ * useEffect(() => {
7333
+ * if (location.state?.breadcrumbReset) {
7334
+ * setViewMode('list');
7335
+ * }
7336
+ * }, [location.state?.breadcrumbReset]);
7337
+ *
7338
+ * // ... rest of component
7339
+ * }
7340
+ */
7282
7341
  function Breadcrumbs({ items, showHome = true }) {
7283
- return (jsxRuntime.jsxs("nav", { "aria-label": "Breadcrumb", className: "flex items-center space-x-2 text-sm", children: [showHome && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactRouterDom.Link, { to: "/", className: "text-ink-500 hover:text-ink-900 transition-colors", "aria-label": "Home", children: jsxRuntime.jsx(lucideReact.Home, { className: "h-4 w-4" }) }), items.length > 0 && jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-ink-400" })] })), items.map((item, index) => {
7342
+ const navigate = reactRouterDom.useNavigate();
7343
+ const location = reactRouterDom.useLocation();
7344
+ /**
7345
+ * Handle breadcrumb click with same-route detection.
7346
+ * When clicking a breadcrumb that points to the current route,
7347
+ * we navigate with state to trigger a reset in the host component.
7348
+ */
7349
+ const handleBreadcrumbClick = (e, href, onClick) => {
7350
+ // Always call onClick if provided (for custom actions)
7351
+ onClick?.();
7352
+ // Check if we're navigating to the same base path
7353
+ const targetPath = href.split('?')[0].split('#')[0];
7354
+ const currentPath = location.pathname;
7355
+ if (targetPath === currentPath) {
7356
+ // Same route - prevent default Link behavior and use navigate with state
7357
+ e.preventDefault();
7358
+ navigate(href, {
7359
+ state: {
7360
+ breadcrumbReset: Date.now(),
7361
+ from: 'breadcrumb'
7362
+ },
7363
+ replace: true
7364
+ });
7365
+ }
7366
+ // Different route - let the Link handle it normally
7367
+ };
7368
+ return (jsxRuntime.jsxs("nav", { "aria-label": "Breadcrumb", className: "flex items-center space-x-2 text-sm", children: [showHome && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactRouterDom.Link, { to: "/", className: "text-ink-500 hover:text-ink-900 transition-colors", "aria-label": "Home", onClick: (e) => handleBreadcrumbClick(e, '/'), children: jsxRuntime.jsx(lucideReact.Home, { className: "h-4 w-4" }) }), items.length > 0 && jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-ink-400" })] })), items.map((item, index) => {
7284
7369
  const isLast = index === items.length - 1;
7285
7370
  const isActive = isLast;
7286
7371
  const content = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon && jsxRuntime.jsx("span", { className: "flex-shrink-0", children: item.icon }), jsxRuntime.jsx("span", { children: item.label })] }));
@@ -7289,9 +7374,9 @@ function Breadcrumbs({ items, showHome = true }) {
7289
7374
  if (isActive) {
7290
7375
  return (jsxRuntime.jsx("span", { className: "flex items-center gap-2 px-2 py-1 rounded-md bg-accent-50 text-accent-900 font-semibold transition-colors", "aria-current": "page", children: content }));
7291
7376
  }
7292
- // Has href - render as Link, also call onClick if provided
7377
+ // Has href - render as Link with same-route detection
7293
7378
  if (item.href) {
7294
- return (jsxRuntime.jsx(reactRouterDom.Link, { to: item.href, onClick: item.onClick, className: "flex items-center gap-2 text-ink-500 hover:text-ink-900 hover:underline transition-colors", children: content }));
7379
+ return (jsxRuntime.jsx(reactRouterDom.Link, { to: item.href, onClick: (e) => handleBreadcrumbClick(e, item.href, item.onClick), className: "flex items-center gap-2 text-ink-500 hover:text-ink-900 hover:underline transition-colors", children: content }));
7295
7380
  }
7296
7381
  // Only onClick (no href) - render as button
7297
7382
  if (item.onClick) {
@@ -56998,6 +57083,7 @@ exports.saveColumnOrder = saveColumnOrder;
56998
57083
  exports.saveColumnWidths = saveColumnWidths;
56999
57084
  exports.searchFormulas = searchFormulas;
57000
57085
  exports.statusManager = statusManager;
57086
+ exports.useBreadcrumbReset = useBreadcrumbReset;
57001
57087
  exports.useBreakpoint = useBreakpoint;
57002
57088
  exports.useBreakpointValue = useBreakpointValue;
57003
57089
  exports.useColumnReorder = useColumnReorder;