import React from 'react';
import { useToasts } from './useToasts';
export function Toaster() {
const { toasts, dismiss } = useToasts();
import { RefObject, useEffect, useRef } from "react";
type Handler = (event: MouseEvent | TouchEvent) => void;
export function useClickOutside<T extends HTMLElement>(
ref: RefObject<T>,
import { useEffect, useState } from 'react';
interface FetchState<T> {
data: T | null;
error: Error | null;
loading: boolean;
import { useEffect, useState } from "react";
export function useDebouncedValue<T>(value: T, delay = 300): T {
const [debounced, setDebounced] = useState<T>(value);
useEffect(() => {
<!DOCTYPE html>
<html>
<head>
<title><%= content_for(:title) || "App" %></title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<!DOCTYPE html>
<html>
<head>
<title><%= content_for(:title) || "App" %></title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["input", "frame"]
static values = { url: String, delay: { type: Number, default: 300 }, min: { type: Number, default: 2 } }
<div class="bookmarks">
<h1>Saved Bookmarks</h1>
<table>
<tbody id="bookmarks">
<%= render partial: "bookmark", collection: @bookmarks %>
let installed = false;
function notify(message, level = "error") {
document.dispatchEvent(
new CustomEvent("flash:show", { detail: { message, level } })
);
import { useEffect, useState } from 'react';
export function useLocalStorage<T>(
key: string,
initialValue: T
): [T, (value: T) => void] {
import { useCallback, useMemo, useState } from 'react';
function compare(a, b) {
if (typeof a === 'number' && typeof b === 'number') return a - b;
return String(a ?? '').localeCompare(String(b ?? ''));
}
<%# locals: item %>
<button
type="button"
class="toggle-btn"
data-controller="toggle"
data-action="click->toggle#toggle"