summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/ui/collapsible.tsx
blob: e0202f617901468db587e8b7553093eeedf125b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { Collapsible as KobalteCollapsible } from "@kobalte/core/collapsible"
import { splitProps } from "solid-js"
import type { ComponentProps, ParentProps } from "solid-js"
import { Icon, type IconProps } from "./icon"

export interface CollapsibleProps extends ComponentProps<typeof KobalteCollapsible> {}
export interface CollapsibleTriggerProps extends ComponentProps<typeof KobalteCollapsible.Trigger> {}
export interface CollapsibleContentProps extends ComponentProps<typeof KobalteCollapsible.Content> {}

function CollapsibleRoot(props: CollapsibleProps) {
  return <KobalteCollapsible forceMount {...props} />
}

function CollapsibleTrigger(props: CollapsibleTriggerProps) {
  const [local, others] = splitProps(props, ["class"])
  return (
    <KobalteCollapsible.Trigger
      classList={{
        "w-full group/collapsible cursor-pointer": true,
        [local.class ?? ""]: !!local.class,
      }}
      {...others}
    />
  )
}

function CollapsibleContent(props: ParentProps<CollapsibleContentProps>) {
  const [local, others] = splitProps(props, ["class", "children"])
  return (
    <KobalteCollapsible.Content
      classList={{
        "h-0 overflow-hidden transition-all duration-100 ease-out": true,
        "data-expanded:h-fit": true,
        [local.class]: !!local.class,
      }}
      {...others}
    >
      {local.children}
    </KobalteCollapsible.Content>
  )
}

function CollapsibleArrow(props: Partial<IconProps>) {
  const [local, others] = splitProps(props, ["class", "name"])
  return (
    <Icon
      name={local.name ?? "chevron-right"}
      classList={{
        "flex-none text-text-muted transition-transform duration-100": true,
        "group-data-[expanded]/collapsible:rotate-90": true,
        [local.class ?? ""]: !!local.class,
      }}
      {...others}
    />
  )
}

export const Collapsible = Object.assign(CollapsibleRoot, {
  Trigger: CollapsibleTrigger,
  Content: CollapsibleContent,
  Arrow: CollapsibleArrow,
})