permalinkRadix UI accordion

Radix UI accordion

Radix UI accordion

Terminal
spago install radix-ui
npm install @radix-ui/react-accordion

permalinkStructure

AccordionStructure
module AccordionStructure where

import RadixUI.Accordion as Accordion
import React.Basic.DOM (text) as R
import React.Basic.DOM.Simplified.Generated (button)

accordion = Accordion.root {}
  [ Accordion.item {} (Accordion.header {} (button {} "Click to (un)collapse"))
    [ Accordion.content {} (R.text "This can be collapsed") ]
  ]

permalinkExample source

/src/Example/RadixUI/Accordion.purs
module Example.RadixUI.Accordion where

import Alethic.Prelude.View

import Beta.DOM (div, div_)
import Effect (Effect)
import Foreign.Object (singleton) as Object
import RadixUI.Accordion as Accordion
import React.Basic.Hooks as React
import React.Icons (icon)
import React.Icons.Rx (rxChevronDown)

mkAccordionDemo :: Effect (ReactComponent {})
mkAccordionDemo = React.reactComponent "AccordionDemo" \{} -> do
  pure $ Accordion.root
    { className: "bg-mauve6 w-[300px] rounded-md shadow-[0_2px_10px] shadow-black/5"
    , type: Accordion.Single
    , defaultValue: "item-1"
    , collapsible: true
    }
    [ accordionItem "item-1"
        [ accordionHeader "Is it accessible?"
        , accordionContent "Yes. It adheres to the WAI-ARIA design pattern."
        ]
    , accordionItem "item-2"
        [ accordionHeader "Is it unstyled?"
        , accordionContent "Yes. It's unstyled by default, giving you freedom over the look and feel."
        ]
    , accordionItem "item-3"
        [ accordionHeader "Can it be animated?"
        , accordionContent "Yes! You can animate the Accordion with CSS or JavaScript."
        ]
    ]

accordionItem :: String -> Array JSX -> JSX
accordionItem value children =
  Accordion.item
    { className: "focus-within:shadow-mauve12 mt-px overflow-hidden first:mt-0 first:rounded-t last:rounded-b focus-within:relative focus-within:z-10 focus-within:shadow-[0_0_0_2px]"
    , value
    }
    children

accordionHeader :: String -> JSX
accordionHeader text =
  Accordion.header { className: "flex" } $
    Accordion.trigger
      { className: "text-violet11 shadow-mauve6 hover:bg-mauve2 group flex h-[45px] flex-1 cursor-default items-center justify-between bg-white px-5 text-[15px] leading-none shadow-[0_1px_0] outline-none"
      }
      [ div {} text
      , chevronDown
      , div_ { "data-okay": "nokay", "aria-labelledby": "daba" }
      ]

chevronDown :: JSX
chevronDown = div { "aria-hidden": true } $ icon
  rxChevronDown
  { className: "text-violet10 ease-[cubic-bezier(0.87,_0,_0.13,_1)] transition-transform duration-300 group-data-[state=open]:rotate-180 w-[15px] h-[15px]"
  }

accordionContent :: String -> JSX
accordionContent children =
  Accordion.content
    { className: "text-mauve11 bg-mauve2 data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp overflow-hidden text-[15px]"
    }
    (div { className: "py-[15px] px-5" } children)