Accordion.jsx
1 month ago
Card.jsx
1 month ago
CardSkeleton.jsx
1 month ago
FileUploaderField.jsx
1 month ago
SearchComboBox.jsx
1 month ago
Accordion.jsx
62 lines
| 1 | /** |
| 2 | * External Dependencies |
| 3 | */ |
| 4 | import { Plus, Minus } from 'lucide-react'; |
| 5 | import { useId, useState } from '@wordpress/element'; |
| 6 | |
| 7 | /** |
| 8 | * Internal Dependencies |
| 9 | */ |
| 10 | import { clsx } from '@admin/utils'; |
| 11 | |
| 12 | export function Accordion( { className, children } ) { |
| 13 | return ( |
| 14 | <div |
| 15 | className={ clsx( |
| 16 | 'bg-white rounded-md divide-y divide-border', |
| 17 | className |
| 18 | ) } |
| 19 | > |
| 20 | { children } |
| 21 | </div> |
| 22 | ); |
| 23 | } |
| 24 | |
| 25 | Accordion.Item = function Item( { title, content, defaultOpen = false } ) { |
| 26 | const id = useId(); |
| 27 | const [ open, setOpen ] = useState( defaultOpen ); |
| 28 | |
| 29 | return ( |
| 30 | <div className="relative transition-all duration-500"> |
| 31 | <input |
| 32 | type="checkbox" |
| 33 | className="absolute opacity-0 z-[-1]" |
| 34 | id={ id } |
| 35 | checked={ open } |
| 36 | onChange={ () => setOpen( ! open ) } |
| 37 | /> |
| 38 | <label |
| 39 | htmlFor={ id } |
| 40 | className="flex font-medium text-sm justify-between py-4 px-1 cursor-pointer" |
| 41 | > |
| 42 | { title } |
| 43 | { open ? ( |
| 44 | <Minus className="size-4" /> |
| 45 | ) : ( |
| 46 | <Plus className="size-4" /> |
| 47 | ) } |
| 48 | </label> |
| 49 | { open && ( |
| 50 | <div |
| 51 | className={ clsx( |
| 52 | 'px-1 max-h-0 overflow-hidden [&>:*]:p-0 [&>:*]:m-0 space-y-4', |
| 53 | open ? 'max-h-[600px] pb-4' : '' |
| 54 | ) } |
| 55 | > |
| 56 | { content } |
| 57 | </div> |
| 58 | ) } |
| 59 | </div> |
| 60 | ); |
| 61 | }; |
| 62 |