personal web client for Bluesky
typescript solidjs bluesky atcute
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at trunk 98 lines 2.2 kB view raw
1import type { Component, JSX } from 'solid-js'; 2 3import { useFieldset } from './fieldset'; 4 5export interface IconButtonProps { 6 icon: Component; 7 title: string; 8 // href?: string; 9 disabled?: boolean; 10 onClick?: JSX.EventHandler<HTMLButtonElement, MouseEvent>; 11 12 variant?: 'ghost' | 'outline' | 'accent' | 'danger' | 'black'; 13 size?: 'md' | 'sm'; 14 class?: string; 15} 16 17const IconButton = (props: IconButtonProps) => { 18 const fieldset = useFieldset(); 19 const isDisabled = (): boolean => fieldset.disabled || !!props.disabled; 20 21 return ( 22 <button 23 type="button" 24 disabled={isDisabled()} 25 title={props.title} 26 onClick={props.onClick} 27 class={iconButtonClasses(isDisabled, props)} 28 > 29 {(() => { 30 const Icon = props.icon; 31 return <Icon />; 32 })()} 33 </button> 34 ); 35}; 36 37const iconButtonClasses = ( 38 isDisabled: () => boolean, 39 { variant = 'ghost', size = 'md', class: className }: IconButtonProps, 40) => { 41 var cn = `grid shrink-0 place-items-center`; 42 43 if (variant === 'ghost') { 44 cn += ` rounded-full text-contrast`; 45 46 if (!isDisabled()) { 47 cn += ` hover:bg-contrast-hinted/md active:bg-contrast-hinted/md-pressed`; 48 } else { 49 cn += ` opacity-50`; 50 } 51 } else if (variant === 'outline') { 52 cn += ` rounded border border-outline-lg text-contrast`; 53 54 if (!isDisabled()) { 55 cn += ` hover:bg-contrast-hinted/md active:bg-contrast-hinted/md-pressed`; 56 } else { 57 cn += ` opacity-50`; 58 } 59 } else if (variant === 'accent') { 60 cn += ` rounded-full text-accent`; 61 62 if (!isDisabled()) { 63 cn += ` hover:bg-accent/md active:bg-accent/md-pressed`; 64 } else { 65 cn += ` opacity-50`; 66 } 67 } else if (variant === 'black') { 68 cn += ` rounded-full bg-p-neutral-950/75 text-white`; 69 70 if (!isDisabled()) { 71 cn += ` hover:bg-p-neutral-800/75 active:bg-p-neutral-700/75`; 72 } else { 73 cn += ` opacity-50`; 74 } 75 } else if (variant === 'danger') { 76 cn += ` rounded-full text-error`; 77 78 if (!isDisabled()) { 79 cn += ` hover:bg-error/md active:bg-error/md-pressed`; 80 } else { 81 cn += ` opacity-50`; 82 } 83 } 84 85 if (size === 'md') { 86 cn += ` h-9 w-9 text-lg`; 87 } else if (size === 'sm') { 88 cn += ` h-8 w-8 text-lg`; 89 } 90 91 if (className) { 92 return `${cn} ${className}`; 93 } else { 94 return cn; 95 } 96}; 97 98export default IconButton;