learn and share notes on atproto (wip) 馃 malfestio.stormlightlabs.org/
readability solid axum atproto srs
at main 70 lines 2.3 kB view raw
1import { useDensity } from "$lib/density-context"; 2import type { DensityMode } from "$lib/design-tokens"; 3import { splitProps } from "solid-js"; 4import type { Component, JSX } from "solid-js"; 5 6type ButtonVariant = "primary" | "secondary" | "danger" | "ghost"; 7type ButtonSize = "sm" | "md" | "lg"; 8type ButtonProps = { variant?: ButtonVariant; size?: ButtonSize; density?: DensityMode }; 9 10export const Button: Component<JSX.ButtonHTMLAttributes<HTMLButtonElement> & ButtonProps> = (props) => { 11 const [local, others] = splitProps(props, ["variant", "size", "density", "class", "children"]); 12 const globalDensity = useDensity(); 13 const density = () => local.density || globalDensity; 14 const base = () => local.size || "md"; 15 16 const variantClass = () => { 17 switch (local.variant) { 18 case "secondary": 19 return "bg-gray-800 text-white hover:bg-gray-700"; 20 case "danger": 21 return "bg-red-600 text-white hover:bg-red-500"; 22 case "ghost": 23 return "bg-transparent text-gray-300 hover:bg-gray-800 hover:text-white"; 24 case "primary": 25 default: 26 return "bg-blue-600 text-white hover:bg-blue-500"; 27 } 28 }; 29 30 const sizeClass = () => { 31 const densityMode = density(); 32 const baseSize = base(); 33 if (baseSize === "sm") { 34 return densityMode === "compact" 35 ? "px-2 py-1 text-xs" 36 : densityMode === "spacious" 37 ? "px-4 py-2 text-sm" 38 : "px-3 py-1.5 text-sm"; 39 } 40 41 if (baseSize === "lg") { 42 return densityMode === "compact" 43 ? "px-5 py-2 text-base" 44 : densityMode === "spacious" 45 ? "px-8 py-4 text-xl" 46 : "px-6 py-3 text-lg"; 47 } 48 49 return densityMode === "compact" 50 ? "px-3 py-1.5 text-sm" 51 : densityMode === "spacious" 52 ? "px-6 py-3 text-base" 53 : "px-4 py-2"; 54 }; 55 56 return ( 57 <button 58 class={` 59 inline-flex items-center justify-center rounded-sm transition-standard font-medium 60 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-gray-900 61 disabled:opacity-50 disabled:cursor-not-allowed 62 ${variantClass()} 63 ${sizeClass()} 64 ${local.class || ""} 65 `} 66 {...others}> 67 {local.children} 68 </button> 69 ); 70};