import { Link, useLocation, useMatches } from 'react-router-dom'
interface BreadcrumbMatch {
pathname: string
handle?: {
crumb?: (data?: any) => string
<h1>Catalog</h1>
<%= turbo_frame_tag "products" do %>
<div class="product-grid" data-controller="frame">
<% @products.each do |product| %>
<%= render "products/card", product: product %>
<div class="settings-layout">
<nav class="settings-sidebar">
<h2>Settings</h2>
<ul>
<% settings_sections.each do |section| %>
<li class="<%= "active" if current_page?(section.path) %>">
export interface QueryCodec<T> {
parse: (raw: string | null) => T;
serialize: (value: T) => string | null;
}
export function stringParam(fallback = ""): QueryCodec<string> {
<!DOCTYPE html>
<html>
<head>
<title><%= content_for(:title) || "App" %></title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
let installed = false;
function notify(message, level = "error") {
document.dispatchEvent(
new CustomEvent("flash:show", { detail: { message, level } })
);
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
export const RouterContext = createContext(null);
export function RouterProvider({ children }) {
const [path, setPath] = useState(() => window.location.pathname);