@@ -0,0 +1,143 @@
1+module HeroUI.Hooks
2+ ( UseDisclosure
3+ , UseDisclosureProps
4+ , UseDisclosureReturn
5+ , useDisclosure
6+ , UseModal
7+ , useModal
8+ , UseDraggable
9+ , useDraggable
10+ , UseDrawer
11+ , useDrawer
12+ , UsePopover
13+ , usePopover
14+ , UseDropdown
15+ , useDropdown
16+ , UseSelect
17+ , useSelect
18+ , UseAutocomplete
19+ , useAutocomplete
20+ , UseTabs
21+ , useTabs
22+ , UseAccordion
23+ , useAccordion
24+ , UseAccordionItem
25+ , useAccordionItem
26+ , UseCheckbox
27+ , useCheckbox
28+ , UseCheckboxGroup
29+ , useCheckboxGroup
30+ ) where
31+
32+import Prelude
33+
34+import Effect (Effect)
35+import Effect.Uncurried (EffectFn1, runEffectFn1)
36+import Foreign (Foreign)
37+import Prim.Row as Row
38+import React.Basic.Hooks (Hook)
39+import React.Basic.Hooks.Internal (unsafeHook)
40+import Unsafe.Coerce (unsafeCoerce)
41+
42+-- | Props accepted by `useDisclosure`. All optional; HeroUI inspects only
43+-- | the fields you actually pass.
44+type UseDisclosureProps =
45+ ( isOpen :: Boolean
46+ , defaultOpen :: Boolean
47+ , onClose :: Effect Unit
48+ , onOpen :: Effect Unit
49+ , onChange :: EffectFn1 Boolean Unit
50+ , id :: String
51+ )
52+
53+-- | Return shape of `useDisclosure`. `getButtonProps`/`getDisclosureProps`
54+-- | are passed through as `Foreign` because they take and return ARIA props
55+-- | records that vary per use site.
56+type UseDisclosureReturn =
57+ ( isOpen :: Boolean
58+ , onOpen :: Effect Unit
59+ , onClose :: Effect Unit
60+ , onOpenChange :: Effect Unit
61+ , isControlled :: Boolean
62+ , getButtonProps :: Foreign -> Foreign
63+ , getDisclosureProps :: Foreign -> Foreign
64+ )
65+
66+foreign import data UseDisclosure :: Type -> Type
67+foreign import data UseModal :: Type -> Type
68+foreign import data UseDraggable :: Type -> Type
69+foreign import data UseDrawer :: Type -> Type
70+foreign import data UsePopover :: Type -> Type
71+foreign import data UseDropdown :: Type -> Type
72+foreign import data UseSelect :: Type -> Type
73+foreign import data UseAutocomplete :: Type -> Type
74+foreign import data UseTabs :: Type -> Type
75+foreign import data UseAccordion :: Type -> Type
76+foreign import data UseAccordionItem :: Type -> Type
77+foreign import data UseCheckbox :: Type -> Type
78+foreign import data UseCheckboxGroup :: Type -> Type
79+
80+foreign import useDisclosureImpl :: EffectFn1 (Record UseDisclosureProps) (Record UseDisclosureReturn)
81+foreign import useModalImpl :: EffectFn1 Foreign Foreign
82+foreign import useDraggableImpl :: EffectFn1 Foreign Foreign
83+foreign import useDrawerImpl :: EffectFn1 Foreign Foreign
84+foreign import usePopoverImpl :: EffectFn1 Foreign Foreign
85+foreign import useDropdownImpl :: EffectFn1 Foreign Foreign
86+foreign import useSelectImpl :: EffectFn1 Foreign Foreign
87+foreign import useAutocompleteImpl :: EffectFn1 Foreign Foreign
88+foreign import useTabsImpl :: EffectFn1 Foreign Foreign
89+foreign import useAccordionImpl :: EffectFn1 Foreign Foreign
90+foreign import useAccordionItemImpl :: EffectFn1 Foreign Foreign
91+foreign import useCheckboxImpl :: EffectFn1 Foreign Foreign
92+foreign import useCheckboxGroupImpl :: EffectFn1 Foreign Foreign
93+
94+-- | https://heroui.com/docs/hooks/use-disclosure
95+useDisclosure
96+ :: forall props missing
97+ . Row.Union props missing UseDisclosureProps
98+ => Record props
99+ -> Hook UseDisclosure (Record UseDisclosureReturn)
100+useDisclosure props = unsafeHook (runEffectFn1 useDisclosureImpl (widen props))
101+ where
102+ widen :: Record props -> Record UseDisclosureProps
103+ widen = unsafeCoerce
104+
105+-- HeroUI's lower-level hooks (`useModal`, `useDropdown`, ...) return rich
106+-- objects shaped by internal slot machinery; their fields shift across
107+-- heroui versions. Surface them as `Foreign` and let consumers narrow.
108+
109+useModal :: Foreign -> Hook UseModal Foreign
110+useModal props = unsafeHook (runEffectFn1 useModalImpl props)
111+
112+useDraggable :: Foreign -> Hook UseDraggable Foreign
113+useDraggable props = unsafeHook (runEffectFn1 useDraggableImpl props)
114+
115+useDrawer :: Foreign -> Hook UseDrawer Foreign
116+useDrawer props = unsafeHook (runEffectFn1 useDrawerImpl props)
117+
118+usePopover :: Foreign -> Hook UsePopover Foreign
119+usePopover props = unsafeHook (runEffectFn1 usePopoverImpl props)
120+
121+useDropdown :: Foreign -> Hook UseDropdown Foreign
122+useDropdown props = unsafeHook (runEffectFn1 useDropdownImpl props)
123+
124+useSelect :: Foreign -> Hook UseSelect Foreign
125+useSelect props = unsafeHook (runEffectFn1 useSelectImpl props)
126+
127+useAutocomplete :: Foreign -> Hook UseAutocomplete Foreign
128+useAutocomplete props = unsafeHook (runEffectFn1 useAutocompleteImpl props)
129+
130+useTabs :: Foreign -> Hook UseTabs Foreign
131+useTabs props = unsafeHook (runEffectFn1 useTabsImpl props)
132+
133+useAccordion :: Foreign -> Hook UseAccordion Foreign
134+useAccordion props = unsafeHook (runEffectFn1 useAccordionImpl props)
135+
136+useAccordionItem :: Foreign -> Hook UseAccordionItem Foreign
137+useAccordionItem props = unsafeHook (runEffectFn1 useAccordionItemImpl props)
138+
139+useCheckbox :: Foreign -> Hook UseCheckbox Foreign
140+useCheckbox props = unsafeHook (runEffectFn1 useCheckboxImpl props)
141+
142+useCheckboxGroup :: Foreign -> Hook UseCheckboxGroup Foreign
143+useCheckboxGroup props = unsafeHook (runEffectFn1 useCheckboxGroupImpl props)