git.iko.soy/rowtype-yoga/purescript-yoga-heroui3
on main help sign in
83 files changed+4158−6
since splitsnapshots
unifiedsplit
.github/workflows/deploy-stories.yml+54 .gitignore+2 bun.lock+4−2 package.json+1−1 spago.lock+7−3 spago.yaml+5 src/HeroUI.purs+26 src/HeroUI/Alert.purs+40 src/HeroUI/Autocomplete.purs+116 src/HeroUI/Breadcrumbs.purs+31 src/HeroUI/Calendar.purs+115 src/HeroUI/Checkbox.purs+93 src/HeroUI/DateField.purs+75 src/HeroUI/DatePicker.purs+126 src/HeroUI/Drawer.purs+107 src/HeroUI/Dropdown.purs+107 src/HeroUI/Form.purs+39 src/HeroUI/Hooks.js+13 src/HeroUI/Hooks.purs+82 src/HeroUI/Input.purs+120 src/HeroUI/InputOTP.purs+66 src/HeroUI/ListBox.purs+63 src/HeroUI/Menu.purs+71 src/HeroUI/Modal.purs+142 src/HeroUI/NumberField.purs+76 src/HeroUI/Pagination.purs+73 src/HeroUI/Popover.purs+63 src/HeroUI/Progress.purs+68 src/HeroUI/Radio.purs+85 src/HeroUI/Raw.js+384 src/HeroUI/Raw.purs+221 src/HeroUI/Select.purs+78 src/HeroUI/Slider.purs+81 src/HeroUI/Switch.purs+71 src/HeroUI/Table.purs+93 src/HeroUI/Toast.js+10 src/HeroUI/Toast.purs+92 src/HeroUI/Tooltip.purs+56 src/HeroUI/Types.purs+24 test/HeroUI/Accordion/Stories.purs+28 test/HeroUI/Alert/Stories.purs+40 test/HeroUI/Autocomplete/Stories.purs+38 test/HeroUI/Avatar/Stories.purs+20 test/HeroUI/Badge/Stories.purs+23 test/HeroUI/Breadcrumbs/Stories.purs+22 test/HeroUI/Button/Stories.purs+64 test/HeroUI/Calendar/Stories.purs+17 test/HeroUI/Card/Stories.purs+36 test/HeroUI/Checkbox/Stories.purs+18 test/HeroUI/Chip/Stories.purs+31 test/HeroUI/DateField/Stories.purs+17 test/HeroUI/DatePicker/Stories.purs+21 test/HeroUI/Drawer/Stories.purs+30 test/HeroUI/Dropdown/Stories.purs+29 test/HeroUI/Form/Stories.purs+24 test/HeroUI/HeroUI3Spec.purs+108 test/HeroUI/Input/Stories.purs+31 test/HeroUI/InputOTP/Stories.purs+22 test/HeroUI/Kbd/Stories.purs+21 test/HeroUI/Link/Stories.purs+17 test/HeroUI/ListBox/Stories.purs+23 test/HeroUI/Menu/Stories.purs+23 test/HeroUI/Modal/Stories.purs+30 test/HeroUI/NumberField/Stories.purs+24 test/HeroUI/Pagination/Stories.purs+27 test/HeroUI/Popover/Stories.purs+26 test/HeroUI/Progress/Stories.purs+20 test/HeroUI/Radio/Stories.purs+23 test/HeroUI/ScrollShadow/Stories.purs+22 test/HeroUI/Select/Stories.purs+28 test/HeroUI/Separator/Stories.purs+22 test/HeroUI/Skeleton/Stories.purs+31 test/HeroUI/Slider/Stories.purs+24 test/HeroUI/Spinner/Stories.purs+31 test/HeroUI/Switch/Stories.purs+18 test/HeroUI/Table/Stories.purs+37 test/HeroUI/Tabs/Stories.purs+36 test/HeroUI/Toast/Stories.purs+22 test/HeroUI/Tooltip/Stories.purs+22 test/JsdomSetup.js+3 test/JsdomSetup.purs+9 test/Main.purs+15 yoga-stories-head.js+5
.github/workflows/deploy-stories.ymlnew file+54
@@ -0,0 +1,54 @@
1+name: Deploy Stories to GitHub Pages
2+
3+on:
4+ push:
5+ branches: [main]
6+ workflow_dispatch:
7+
8+permissions:
9+ contents: read
10+ pages: write
11+ id-token: write
12+
13+concurrency:
14+ group: pages
15+ cancel-in-progress: true
16+
17+jobs:
18+ build-and-deploy:
19+ runs-on: ubuntu-latest
20+ environment:
21+ name: github-pages
22+ url: ${{ steps.deployment.outputs.page_url }}
23+ steps:
24+ - uses: actions/checkout@v4
25+
26+ - uses: oven-sh/setup-bun@v2
27+ with:
28+ bun-version: latest
29+
30+ - uses: purescript-contrib/setup-purescript@main
31+ with:
32+ purescript: "0.15.15"
33+ spago: "0.93.42"
34+
35+ - run: npm install -g purs-backend-es@1.4.2
36+
37+ - name: Install JS dependencies
38+ run: |
39+ rm -f bun.lock
40+ npm install
41+ test -f node_modules/vite/dist/node/chunks/config.js || npm install vite@7.3.1
42+
43+ - run: spago build
44+
45+ - run: npx yoga-stories build
46+
47+ - uses: actions/configure-pages@v5
48+
49+ - uses: actions/upload-pages-artifact@v3
50+ with:
51+ path: dist
52+
53+ - uses: actions/deploy-pages@v4
54+ id: deployment
.gitignore+2
@@ -1,3 +1,5 @@
11node_modules/
22output/
3+output-es/
34.spago/
5+dist/
bun.lock+4−2
@@ -6,7 +6,7 @@
66 "dependencies": {
77 "@heroui/react": "^3.1.0",
88 "@heroui/styles": "^3.1.0",
9− "yoga-stories": "0.1.5",
9+ "yoga-stories": "0.1.13",
1010 },
1111 "devDependencies": {
1212 "@tailwindcss/vite": "^4.1.18",
@@ -120,6 +120,8 @@
120120
121121 "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="],
122122
123+ "@fontsource/jetbrains-mono": ["@fontsource/jetbrains-mono@5.2.8", "", {}, "sha512-6w8/SG4kqvIMu7xd7wt6x3idn1Qux3p9N62s6G3rfldOUYHpWcc2FKrqf+Vo44jRvqWj2oAtTHrZXEP23oSKwQ=="],
124+
123125 "@formatjs/ecma402-abstract": ["@formatjs/ecma402-abstract@2.3.6", "", { "dependencies": { "@formatjs/fast-memoize": "2.2.7", "@formatjs/intl-localematcher": "0.6.2", "decimal.js": "^10.4.3", "tslib": "^2.8.0" } }, "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw=="],
124126
125127 "@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ=="],
@@ -538,7 +540,7 @@
538540
539541 "xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="],
540542
541− "yoga-stories": ["yoga-stories@0.1.5", "", { "dependencies": { "@codemirror/language": "^6.12.1", "@codemirror/legacy-modes": "^6.5.2", "@uiw/codemirror-theme-tokyo-night": "^4.25.4", "@uiw/react-codemirror": "^4.25.4", "vite": "^7.3.1" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "bin": { "yoga-stories": "bin/cli.js" } }, "sha512-XeXNxbUVwcsmGRm3NZ/SBqSxmKl+vb06MI2fDUsB69dXKt2nVtOsd5qiLRQd73dOp1y9ub/LjuwAUsnNQdLHbA=="],
543+ "yoga-stories": ["yoga-stories@0.1.13", "", { "dependencies": { "@codemirror/language": "^6.12.1", "@codemirror/legacy-modes": "^6.5.2", "@fontsource/jetbrains-mono": "^5.2.8", "@uiw/codemirror-theme-tokyo-night": "^4.25.4", "@uiw/react-codemirror": "^4.25.4", "vite": "^7.3.1" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "bin": { "yoga-stories": "bin/cli.js" } }, "sha512-oa57HWyChSlvhloJhe1CMubw9nDWy44Jn6GYcWcruwtPzMTAEaoh2665wIptSKFdw5iErSfhWEUt03nHAZ+FrQ=="],
542544
543545 "@adobe/react-spectrum/@react-types/shared": ["@react-types/shared@3.35.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-iNWvuzEwANttpQpdlu8nPBtdHb0mcCMj1ZTH//iRB5E/14IAnyRlR25rxH7pNLyzHINsPGEKnWvpwDMCT6vziQ=="],
544546
package.json+1−1
@@ -5,7 +5,7 @@
55 "dependencies": {
66 "@heroui/react": "^3.1.0",
77 "@heroui/styles": "^3.1.0",
8− "yoga-stories": "0.1.5"
8+ "yoga-stories": "0.1.13"
99 },
1010 "peerDependencies": {
1111 "react": ">=19",
spago.lock+7−3
@@ -76,6 +76,10 @@
7676 "react-testing-library": {
7777 "git": "https://github.com/i-am-the-slime/purescript-react-testing-library.git",
7878 "ref": "fd679db77337485058907ba5c6cbac3b478de342"
79+ },
80+ "yoga-stories": {
81+ "git": "https://github.com/rowtype-yoga/purescript-yoga-stories.git",
82+ "ref": "v0.1.13"
7983 }
8084 }
8185 },
@@ -1532,9 +1536,9 @@
15321536 ]
15331537 },
15341538 "yoga-stories": {
1535− "type": "registry",
1536− "version": "0.1.0",
1537− "integrity": "sha256-8T+wUThPhXYH2MgSoe1/JjEmUnABk2A012wHliNLLcE=",
1539+ "type": "git",
1540+ "url": "https://github.com/rowtype-yoga/purescript-yoga-stories.git",
1541+ "rev": "8352da39a4d48dbb57416e1239692401b89a12fe",
15381542 "dependencies": [
15391543 "aff",
15401544 "arrays",
spago.yaml+5
@@ -3,6 +3,11 @@ workspace:
33 react-testing-library:
44 git: https://github.com/i-am-the-slime/purescript-react-testing-library.git
55 ref: fd679db77337485058907ba5c6cbac3b478de342
6+ # Pinned to the git ref because the registry package is still 0.1.0, which
7+ # predates the registry-aware story loader the 0.1.13 CLI build needs.
8+ yoga-stories:
9+ git: https://github.com/rowtype-yoga/purescript-yoga-stories.git
10+ ref: v0.1.13
611
712package:
813 name: yoga-heroui3
src/HeroUI.pursnew file+26
@@ -0,0 +1,26 @@
1+-- | HeroUI v3 bindings.
2+-- |
3+-- | v3 components are decomposed compound components, so each lives in its
4+-- | own module meant to be imported qualified, e.g.
5+-- |
6+-- | ```purescript
7+-- | import HeroUI.Button as Button
8+-- | import HeroUI.Card as Card
9+-- | ```
10+-- |
11+-- | This umbrella re-exports only the shared semantic types
12+-- | (`HeroUI.Types`); pull components in per-module as above.
13+module HeroUI (module HeroUI.Types) where
14+
15+import HeroUI.Types
16+ ( Color(..)
17+ , colorToString
18+ , Size(..)
19+ , sizeToString
20+ , FieldVariant(..)
21+ , fieldVariantToString
22+ , SelectionMode(..)
23+ , selectionModeToString
24+ , Orientation(..)
25+ , orientationToString
26+ )
src/HeroUI/Alert.pursnew file+40
@@ -0,0 +1,40 @@
1+module HeroUI.Alert where
2+
3+import Prelude
4+
5+import React.Basic (JSX)
6+import Yoga.React.DOM.Internal (class IsJSX)
7+import Data.Function.Uncurried (runFn4)
8+import HeroUI.Types (Color, colorToString)
9+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
10+import HeroUI.Raw as Raw
11+
12+-- | Alert's `status` shares the semantic colour palette (`HeroUI.Types.Color`).
13+type AlertProps r = (status :: Color, className :: String | r)
14+
15+alert
16+ :: forall givenProps nonDataProps kids
17+ . IsJSX kids
18+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | AlertProps () }
19+ => { | givenProps }
20+ -> kids
21+ -> JSX
22+alert props kids = runFn4 createElementTransformImpl { status: colorToString } Raw.alert props kids
23+
24+type SectionProps r = (className :: String | r)
25+
26+alertIndicator
27+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
28+alertIndicator props kids = runFn4 createElementTransformImpl {} Raw.alertIndicator props kids
29+
30+alertContent
31+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
32+alertContent props kids = runFn4 createElementTransformImpl {} Raw.alertContent props kids
33+
34+alertTitle
35+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
36+alertTitle props kids = runFn4 createElementTransformImpl {} Raw.alertTitle props kids
37+
38+alertDescription
39+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
40+alertDescription props kids = runFn4 createElementTransformImpl {} Raw.alertDescription props kids
src/HeroUI/Autocomplete.pursnew file+116
@@ -0,0 +1,116 @@
1+module HeroUI.Autocomplete where
2+
3+import Prelude
4+
5+import Effect (Effect)
6+import Effect.Uncurried (EffectFn1)
7+import React.Basic (JSX)
8+import Yoga.React.DOM.Internal (class IsJSX)
9+import Data.Function.Uncurried (Fn2, mkFn2, runFn4)
10+import Data.String (Pattern(..), contains, toLower)
11+import HeroUI.Types (FieldVariant, fieldVariantToString)
12+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
13+import HeroUI.Raw as Raw
14+
15+type AutocompleteProps r =
16+ ( selectedKey :: String
17+ , defaultSelectedKey :: String
18+ , onSelectionChange :: EffectFn1 String Unit
19+ , inputValue :: String
20+ , defaultInputValue :: String
21+ , onInputChange :: EffectFn1 String Unit
22+ , onClear :: Effect Unit
23+ , allowsCustomValue :: Boolean
24+ , placeholder :: String
25+ , name :: String
26+ , isDisabled :: Boolean
27+ , isRequired :: Boolean
28+ , isInvalid :: Boolean
29+ , fullWidth :: Boolean
30+ , variant :: FieldVariant
31+ , className :: String
32+ | r
33+ )
34+
35+autocomplete
36+ :: forall givenProps nonDataProps kids
37+ . IsJSX kids
38+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | AutocompleteProps () }
39+ => { | givenProps }
40+ -> kids
41+ -> JSX
42+autocomplete props kids = runFn4 createElementTransformImpl { variant: fieldVariantToString } Raw.autocomplete props kids
43+
44+type SectionProps r = (className :: String | r)
45+
46+autocompleteTrigger
47+ :: forall givenProps nonDataProps kids
48+ . IsJSX kids
49+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
50+ => { | givenProps }
51+ -> kids
52+ -> JSX
53+autocompleteTrigger props kids = runFn4 createElementTransformImpl {} Raw.autocompleteTrigger props kids
54+
55+-- | Shows the selected option's text, or `placeholder` when nothing is selected.
56+type AutocompleteValueProps r = (placeholder :: String, className :: String | r)
57+
58+autocompleteValue
59+ :: forall givenProps nonDataProps kids
60+ . IsJSX kids
61+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | AutocompleteValueProps () }
62+ => { | givenProps }
63+ -> kids
64+ -> JSX
65+autocompleteValue props kids = runFn4 createElementTransformImpl {} Raw.autocompleteValue props kids
66+
67+autocompleteIndicator
68+ :: forall givenProps nonDataProps kids
69+ . IsJSX kids
70+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
71+ => { | givenProps }
72+ -> kids
73+ -> JSX
74+autocompleteIndicator props kids = runFn4 createElementTransformImpl {} Raw.autocompleteIndicator props kids
75+
76+autocompletePopover
77+ :: forall givenProps nonDataProps kids
78+ . IsJSX kids
79+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
80+ => { | givenProps }
81+ -> kids
82+ -> JSX
83+autocompletePopover props kids = runFn4 createElementTransformImpl {} Raw.autocompletePopover props kids
84+
85+-- | Wraps the search `input` + the options collection inside the popover;
86+-- | this is what makes the autocomplete typeable. Pass `filter` to narrow the
87+-- | options as the user types (see `containsFilter` for the common case).
88+type AutocompleteFilterProps r =
89+ ( filter :: Fn2 String String Boolean
90+ , className :: String
91+ | r
92+ )
93+
94+autocompleteFilter
95+ :: forall givenProps nonDataProps kids
96+ . IsJSX kids
97+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | AutocompleteFilterProps () }
98+ => { | givenProps }
99+ -> kids
100+ -> JSX
101+autocompleteFilter props kids = runFn4 createElementTransformImpl {} Raw.autocompleteFilter props kids
102+
103+-- | Case-insensitive substring match — the usual `filter` for `autocompleteFilter`.
104+-- | react-aria calls it as `filter optionTextValue typedInput`; keep an option
105+-- | when what the user typed appears anywhere in its `textValue`.
106+containsFilter :: Fn2 String String Boolean
107+containsFilter = mkFn2 \optionText typed -> contains (Pattern (toLower typed)) (toLower optionText)
108+
109+autocompleteClearButton
110+ :: forall givenProps nonDataProps kids
111+ . IsJSX kids
112+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
113+ => { | givenProps }
114+ -> kids
115+ -> JSX
116+autocompleteClearButton props kids = runFn4 createElementTransformImpl {} Raw.autocompleteClearButton props kids
src/HeroUI/Breadcrumbs.pursnew file+31
@@ -0,0 +1,31 @@
1+module HeroUI.Breadcrumbs where
2+
3+import Prelude
4+
5+import React.Basic (JSX)
6+import Yoga.React.DOM.Internal (class IsJSX)
7+import Data.Function.Uncurried (runFn4)
8+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
9+import HeroUI.Raw as Raw
10+
11+type BreadcrumbsProps r = (separator :: JSX, className :: String | r)
12+
13+breadcrumbs
14+ :: forall givenProps nonDataProps kids
15+ . IsJSX kids
16+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | BreadcrumbsProps () }
17+ => { | givenProps }
18+ -> kids
19+ -> JSX
20+breadcrumbs props kids = runFn4 createElementTransformImpl {} Raw.breadcrumbs props kids
21+
22+type BreadcrumbsItemProps r = (href :: String, isDisabled :: Boolean, className :: String | r)
23+
24+breadcrumbsItem
25+ :: forall givenProps nonDataProps kids
26+ . IsJSX kids
27+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | BreadcrumbsItemProps () }
28+ => { | givenProps }
29+ -> kids
30+ -> JSX
31+breadcrumbsItem props kids = runFn4 createElementTransformImpl {} Raw.breadcrumbsItem props kids
src/HeroUI/Calendar.pursnew file+115
@@ -0,0 +1,115 @@
1+module HeroUI.Calendar where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import Foreign (Foreign)
7+import React.Basic (JSX)
8+import Yoga.React.DOM.Internal (class IsJSX)
9+import Data.Function.Uncurried (runFn4)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+-- | Date values are opaque `@internationalized/date` objects; pass as `Foreign`.
14+type CalendarProps r =
15+ ( value :: Foreign
16+ , defaultValue :: Foreign
17+ , onChange :: EffectFn1 Foreign Unit
18+ , minValue :: Foreign
19+ , maxValue :: Foreign
20+ , isDisabled :: Boolean
21+ , isReadOnly :: Boolean
22+ , className :: String
23+ | r
24+ )
25+
26+calendar
27+ :: forall givenProps nonDataProps kids
28+ . IsJSX kids
29+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | CalendarProps () }
30+ => { | givenProps }
31+ -> kids
32+ -> JSX
33+calendar props kids = runFn4 createElementTransformImpl {} Raw.calendar props kids
34+
35+type SectionProps r = (className :: String | r)
36+
37+calendarHeader
38+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
39+calendarHeader props kids = runFn4 createElementTransformImpl {} Raw.calendarHeader props kids
40+
41+calendarHeading
42+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
43+calendarHeading props kids = runFn4 createElementTransformImpl {} Raw.calendarHeading props kids
44+
45+calendarNavButton
46+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
47+calendarNavButton props kids = runFn4 createElementTransformImpl {} Raw.calendarNavButton props kids
48+
49+calendarGrid
50+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
51+calendarGrid props kids = runFn4 createElementTransformImpl {} Raw.calendarGrid props kids
52+
53+calendarGridHeader
54+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
55+calendarGridHeader props kids = runFn4 createElementTransformImpl {} Raw.calendarGridHeader props kids
56+
57+calendarGridBody
58+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
59+calendarGridBody props kids = runFn4 createElementTransformImpl {} Raw.calendarGridBody props kids
60+
61+calendarHeaderCell
62+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
63+calendarHeaderCell props kids = runFn4 createElementTransformImpl {} Raw.calendarHeaderCell props kids
64+
65+type CalendarCellProps r = (date :: Foreign, className :: String | r)
66+
67+calendarCell
68+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | CalendarCellProps () } => { | g } -> k -> JSX
69+calendarCell props kids = runFn4 createElementTransformImpl {} Raw.calendarCell props kids
70+
71+calendarCellIndicator
72+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
73+calendarCellIndicator props kids = runFn4 createElementTransformImpl {} Raw.calendarCellIndicator props kids
74+
75+-- RangeCalendar
76+type RangeCalendarProps r =
77+ ( value :: Foreign
78+ , defaultValue :: Foreign
79+ , onChange :: EffectFn1 Foreign Unit
80+ , minValue :: Foreign
81+ , maxValue :: Foreign
82+ , isDisabled :: Boolean
83+ , isReadOnly :: Boolean
84+ , className :: String
85+ | r
86+ )
87+
88+rangeCalendar
89+ :: forall givenProps nonDataProps kids
90+ . IsJSX kids
91+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | RangeCalendarProps () }
92+ => { | givenProps }
93+ -> kids
94+ -> JSX
95+rangeCalendar props kids = runFn4 createElementTransformImpl {} Raw.rangeCalendar props kids
96+
97+rangeCalendarHeader
98+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
99+rangeCalendarHeader props kids = runFn4 createElementTransformImpl {} Raw.rangeCalendarHeader props kids
100+
101+rangeCalendarHeading
102+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
103+rangeCalendarHeading props kids = runFn4 createElementTransformImpl {} Raw.rangeCalendarHeading props kids
104+
105+rangeCalendarNavButton
106+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
107+rangeCalendarNavButton props kids = runFn4 createElementTransformImpl {} Raw.rangeCalendarNavButton props kids
108+
109+rangeCalendarGrid
110+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
111+rangeCalendarGrid props kids = runFn4 createElementTransformImpl {} Raw.rangeCalendarGrid props kids
112+
113+rangeCalendarCell
114+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | CalendarCellProps () } => { | g } -> k -> JSX
115+rangeCalendarCell props kids = runFn4 createElementTransformImpl {} Raw.rangeCalendarCell props kids
src/HeroUI/Checkbox.pursnew file+93
@@ -0,0 +1,93 @@
1+module HeroUI.Checkbox where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Types (FieldVariant, Orientation, fieldVariantToString, orientationToString)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+type CheckboxProps r =
14+ ( value :: String
15+ , isSelected :: Boolean
16+ , defaultSelected :: Boolean
17+ , onChange :: EffectFn1 Boolean Unit
18+ , isIndeterminate :: Boolean
19+ , isDisabled :: Boolean
20+ , isReadOnly :: Boolean
21+ , isRequired :: Boolean
22+ , isInvalid :: Boolean
23+ , name :: String
24+ , variant :: FieldVariant
25+ , className :: String
26+ | r
27+ )
28+
29+checkbox
30+ :: forall givenProps nonDataProps kids
31+ . IsJSX kids
32+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | CheckboxProps () }
33+ => { | givenProps }
34+ -> kids
35+ -> JSX
36+checkbox props kids = runFn4 createElementTransformImpl { variant: fieldVariantToString } Raw.checkbox props kids
37+
38+type CheckboxGroupProps r =
39+ ( value :: Array String
40+ , defaultValue :: Array String
41+ , onChange :: EffectFn1 (Array String) Unit
42+ , isDisabled :: Boolean
43+ , isReadOnly :: Boolean
44+ , isRequired :: Boolean
45+ , isInvalid :: Boolean
46+ , name :: String
47+ , orientation :: Orientation
48+ , variant :: FieldVariant
49+ , className :: String
50+ | r
51+ )
52+
53+checkboxGroupTransforms
54+ :: { variant :: FieldVariant -> String, orientation :: Orientation -> String }
55+checkboxGroupTransforms = { variant: fieldVariantToString, orientation: orientationToString }
56+
57+checkboxGroup
58+ :: forall givenProps nonDataProps kids
59+ . IsJSX kids
60+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | CheckboxGroupProps () }
61+ => { | givenProps }
62+ -> kids
63+ -> JSX
64+checkboxGroup props kids = runFn4 createElementTransformImpl checkboxGroupTransforms Raw.checkboxGroup props kids
65+
66+type SectionProps r = (className :: String | r)
67+
68+checkboxControl
69+ :: forall givenProps nonDataProps kids
70+ . IsJSX kids
71+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
72+ => { | givenProps }
73+ -> kids
74+ -> JSX
75+checkboxControl props kids = runFn4 createElementTransformImpl {} Raw.checkboxControl props kids
76+
77+checkboxIndicator
78+ :: forall givenProps nonDataProps kids
79+ . IsJSX kids
80+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
81+ => { | givenProps }
82+ -> kids
83+ -> JSX
84+checkboxIndicator props kids = runFn4 createElementTransformImpl {} Raw.checkboxIndicator props kids
85+
86+checkboxContent
87+ :: forall givenProps nonDataProps kids
88+ . IsJSX kids
89+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
90+ => { | givenProps }
91+ -> kids
92+ -> JSX
93+checkboxContent props kids = runFn4 createElementTransformImpl {} Raw.checkboxContent props kids
src/HeroUI/DateField.pursnew file+75
@@ -0,0 +1,75 @@
1+module HeroUI.DateField where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import Foreign (Foreign)
7+import React.Basic (JSX)
8+import Yoga.React.DOM.Internal (class IsJSX)
9+import Data.Function.Uncurried (runFn4)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+data Granularity = Day | Hour | Minute | Second
14+
15+derive instance Eq Granularity
16+derive instance Ord Granularity
17+
18+granularityToString :: Granularity -> String
19+granularityToString = case _ of
20+ Day -> "day"
21+ Hour -> "hour"
22+ Minute -> "minute"
23+ Second -> "second"
24+
25+-- | Date values are `@internationalized/date` objects (`CalendarDate`, ...);
26+-- | they're opaque here, so construct/inspect them via FFI and pass as `Foreign`.
27+type DateFieldProps r =
28+ ( value :: Foreign
29+ , defaultValue :: Foreign
30+ , onChange :: EffectFn1 Foreign Unit
31+ , minValue :: Foreign
32+ , maxValue :: Foreign
33+ , granularity :: Granularity
34+ , isDisabled :: Boolean
35+ , isReadOnly :: Boolean
36+ , isRequired :: Boolean
37+ , isInvalid :: Boolean
38+ , fullWidth :: Boolean
39+ , className :: String
40+ | r
41+ )
42+
43+dateField
44+ :: forall givenProps nonDataProps kids
45+ . IsJSX kids
46+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DateFieldProps () }
47+ => { | givenProps }
48+ -> kids
49+ -> JSX
50+dateField props kids = runFn4 createElementTransformImpl { granularity: granularityToString } Raw.dateField props kids
51+
52+type TimeFieldProps r =
53+ ( value :: Foreign
54+ , defaultValue :: Foreign
55+ , onChange :: EffectFn1 Foreign Unit
56+ , minValue :: Foreign
57+ , maxValue :: Foreign
58+ , granularity :: Granularity
59+ , isDisabled :: Boolean
60+ , isReadOnly :: Boolean
61+ , isRequired :: Boolean
62+ , isInvalid :: Boolean
63+ , fullWidth :: Boolean
64+ , className :: String
65+ | r
66+ )
67+
68+timeField
69+ :: forall givenProps nonDataProps kids
70+ . IsJSX kids
71+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | TimeFieldProps () }
72+ => { | givenProps }
73+ -> kids
74+ -> JSX
75+timeField props kids = runFn4 createElementTransformImpl { granularity: granularityToString } Raw.timeField props kids
src/HeroUI/DatePicker.pursnew file+126
@@ -0,0 +1,126 @@
1+module HeroUI.DatePicker where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import Foreign (Foreign)
7+import React.Basic (JSX)
8+import Yoga.React.DOM.Internal (class IsJSX)
9+import Data.Function.Uncurried (runFn4)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+-- | Date values are opaque `@internationalized/date` objects; pass as `Foreign`.
14+type DatePickerProps r =
15+ ( value :: Foreign
16+ , defaultValue :: Foreign
17+ , onChange :: EffectFn1 Foreign Unit
18+ , minValue :: Foreign
19+ , maxValue :: Foreign
20+ , isOpen :: Boolean
21+ , isDisabled :: Boolean
22+ , isReadOnly :: Boolean
23+ , isRequired :: Boolean
24+ , isInvalid :: Boolean
25+ , className :: String
26+ | r
27+ )
28+
29+datePicker
30+ :: forall givenProps nonDataProps kids
31+ . IsJSX kids
32+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DatePickerProps () }
33+ => { | givenProps }
34+ -> kids
35+ -> JSX
36+datePicker props kids = runFn4 createElementTransformImpl {} Raw.datePicker props kids
37+
38+type SectionProps r = (className :: String | r)
39+
40+datePickerTrigger
41+ :: forall givenProps nonDataProps kids
42+ . IsJSX kids
43+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
44+ => { | givenProps }
45+ -> kids
46+ -> JSX
47+datePickerTrigger props kids = runFn4 createElementTransformImpl {} Raw.datePickerTrigger props kids
48+
49+datePickerTriggerIndicator
50+ :: forall givenProps nonDataProps kids
51+ . IsJSX kids
52+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
53+ => { | givenProps }
54+ -> kids
55+ -> JSX
56+datePickerTriggerIndicator props kids = runFn4 createElementTransformImpl {} Raw.datePickerTriggerIndicator props kids
57+
58+datePickerPopover
59+ :: forall givenProps nonDataProps kids
60+ . IsJSX kids
61+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
62+ => { | givenProps }
63+ -> kids
64+ -> JSX
65+datePickerPopover props kids = runFn4 createElementTransformImpl {} Raw.datePickerPopover props kids
66+
67+-- | Range pickers take a `{ start, end }` range object; pass as `Foreign`.
68+type DateRangePickerProps r =
69+ ( value :: Foreign
70+ , defaultValue :: Foreign
71+ , onChange :: EffectFn1 Foreign Unit
72+ , minValue :: Foreign
73+ , maxValue :: Foreign
74+ , isOpen :: Boolean
75+ , isDisabled :: Boolean
76+ , isReadOnly :: Boolean
77+ , isRequired :: Boolean
78+ , isInvalid :: Boolean
79+ , className :: String
80+ | r
81+ )
82+
83+dateRangePicker
84+ :: forall givenProps nonDataProps kids
85+ . IsJSX kids
86+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DateRangePickerProps () }
87+ => { | givenProps }
88+ -> kids
89+ -> JSX
90+dateRangePicker props kids = runFn4 createElementTransformImpl {} Raw.dateRangePicker props kids
91+
92+dateRangePickerTrigger
93+ :: forall givenProps nonDataProps kids
94+ . IsJSX kids
95+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
96+ => { | givenProps }
97+ -> kids
98+ -> JSX
99+dateRangePickerTrigger props kids = runFn4 createElementTransformImpl {} Raw.dateRangePickerTrigger props kids
100+
101+dateRangePickerTriggerIndicator
102+ :: forall givenProps nonDataProps kids
103+ . IsJSX kids
104+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
105+ => { | givenProps }
106+ -> kids
107+ -> JSX
108+dateRangePickerTriggerIndicator props kids = runFn4 createElementTransformImpl {} Raw.dateRangePickerTriggerIndicator props kids
109+
110+dateRangePickerRangeSeparator
111+ :: forall givenProps nonDataProps kids
112+ . IsJSX kids
113+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
114+ => { | givenProps }
115+ -> kids
116+ -> JSX
117+dateRangePickerRangeSeparator props kids = runFn4 createElementTransformImpl {} Raw.dateRangePickerRangeSeparator props kids
118+
119+dateRangePickerPopover
120+ :: forall givenProps nonDataProps kids
121+ . IsJSX kids
122+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
123+ => { | givenProps }
124+ -> kids
125+ -> JSX
126+dateRangePickerPopover props kids = runFn4 createElementTransformImpl {} Raw.dateRangePickerPopover props kids
src/HeroUI/Drawer.pursnew file+107
@@ -0,0 +1,107 @@
1+module HeroUI.Drawer where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
10+import HeroUI.Raw as Raw
11+
12+data Placement = Top | Bottom | Left | Right
13+
14+derive instance Eq Placement
15+derive instance Ord Placement
16+
17+placementToString :: Placement -> String
18+placementToString = case _ of
19+ Top -> "top"
20+ Bottom -> "bottom"
21+ Left -> "left"
22+ Right -> "right"
23+
24+data Backdrop = Blur | Opaque | Transparent
25+
26+derive instance Eq Backdrop
27+derive instance Ord Backdrop
28+
29+backdropToString :: Backdrop -> String
30+backdropToString = case _ of
31+ Blur -> "blur"
32+ Opaque -> "opaque"
33+ Transparent -> "transparent"
34+
35+type DrawerProps r =
36+ ( isOpen :: Boolean
37+ , defaultOpen :: Boolean
38+ , onOpenChange :: EffectFn1 Boolean Unit
39+ , isDismissable :: Boolean
40+ , className :: String
41+ | r
42+ )
43+
44+drawer
45+ :: forall givenProps nonDataProps kids
46+ . IsJSX kids
47+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DrawerProps () }
48+ => { | givenProps }
49+ -> kids
50+ -> JSX
51+drawer props kids = runFn4 createElementTransformImpl {} Raw.drawer props kids
52+
53+type DrawerBackdropProps r = (variant :: Backdrop, isDismissable :: Boolean, className :: String | r)
54+
55+drawerBackdrop
56+ :: forall givenProps nonDataProps kids
57+ . IsJSX kids
58+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DrawerBackdropProps () }
59+ => { | givenProps }
60+ -> kids
61+ -> JSX
62+drawerBackdrop props kids = runFn4 createElementTransformImpl { variant: backdropToString } Raw.drawerBackdrop props kids
63+
64+type DrawerContentProps r = (placement :: Placement, className :: String | r)
65+
66+drawerContent
67+ :: forall givenProps nonDataProps kids
68+ . IsJSX kids
69+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DrawerContentProps () }
70+ => { | givenProps }
71+ -> kids
72+ -> JSX
73+drawerContent props kids = runFn4 createElementTransformImpl { placement: placementToString } Raw.drawerContent props kids
74+
75+type SectionProps r = (className :: String | r)
76+
77+drawerTrigger
78+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
79+drawerTrigger props kids = runFn4 createElementTransformImpl {} Raw.drawerTrigger props kids
80+
81+drawerDialog
82+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
83+drawerDialog props kids = runFn4 createElementTransformImpl {} Raw.drawerDialog props kids
84+
85+drawerHeader
86+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
87+drawerHeader props kids = runFn4 createElementTransformImpl {} Raw.drawerHeader props kids
88+
89+drawerHeading
90+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
91+drawerHeading props kids = runFn4 createElementTransformImpl {} Raw.drawerHeading props kids
92+
93+drawerBody
94+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
95+drawerBody props kids = runFn4 createElementTransformImpl {} Raw.drawerBody props kids
96+
97+drawerFooter
98+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
99+drawerFooter props kids = runFn4 createElementTransformImpl {} Raw.drawerFooter props kids
100+
101+drawerHandle
102+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
103+drawerHandle props kids = runFn4 createElementTransformImpl {} Raw.drawerHandle props kids
104+
105+drawerCloseTrigger
106+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
107+drawerCloseTrigger props kids = runFn4 createElementTransformImpl {} Raw.drawerCloseTrigger props kids
src/HeroUI/Dropdown.pursnew file+107
@@ -0,0 +1,107 @@
1+module HeroUI.Dropdown where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import Foreign (Foreign)
7+import React.Basic (JSX)
8+import Yoga.React.DOM.Internal (class IsJSX)
9+import Data.Function.Uncurried (runFn4)
10+import HeroUI.Types (SelectionMode, selectionModeToString)
11+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
12+import HeroUI.Raw as Raw
13+
14+type DropdownProps r =
15+ ( isOpen :: Boolean
16+ , defaultOpen :: Boolean
17+ , onOpenChange :: EffectFn1 Boolean Unit
18+ , className :: String
19+ | r
20+ )
21+
22+dropdown
23+ :: forall givenProps nonDataProps kids
24+ . IsJSX kids
25+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DropdownProps () }
26+ => { | givenProps }
27+ -> kids
28+ -> JSX
29+dropdown props kids = runFn4 createElementTransformImpl {} Raw.dropdown props kids
30+
31+type DropdownMenuProps r =
32+ ( selectionMode :: SelectionMode
33+ , selectedKeys :: Array String
34+ , defaultSelectedKeys :: Array String
35+ , onSelectionChange :: EffectFn1 Foreign Unit
36+ , onAction :: EffectFn1 String Unit
37+ , disabledKeys :: Array String
38+ , className :: String
39+ | r
40+ )
41+
42+dropdownMenu
43+ :: forall givenProps nonDataProps kids
44+ . IsJSX kids
45+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DropdownMenuProps () }
46+ => { | givenProps }
47+ -> kids
48+ -> JSX
49+dropdownMenu props kids = runFn4 createElementTransformImpl { selectionMode: selectionModeToString } Raw.dropdownMenu props kids
50+
51+type DropdownItemProps r =
52+ ( id :: String
53+ , textValue :: String
54+ , isDisabled :: Boolean
55+ , href :: String
56+ , className :: String
57+ | r
58+ )
59+
60+dropdownItem
61+ :: forall givenProps nonDataProps kids
62+ . IsJSX kids
63+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DropdownItemProps () }
64+ => { | givenProps }
65+ -> kids
66+ -> JSX
67+dropdownItem props kids = runFn4 createElementTransformImpl {} Raw.dropdownItem props kids
68+
69+type DropdownSectionProps r = (id :: String, className :: String | r)
70+
71+dropdownSection
72+ :: forall givenProps nonDataProps kids
73+ . IsJSX kids
74+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DropdownSectionProps () }
75+ => { | givenProps }
76+ -> kids
77+ -> JSX
78+dropdownSection props kids = runFn4 createElementTransformImpl {} Raw.dropdownSection props kids
79+
80+type DropdownPopoverProps r = (placement :: String, className :: String | r)
81+
82+dropdownPopover
83+ :: forall givenProps nonDataProps kids
84+ . IsJSX kids
85+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | DropdownPopoverProps () }
86+ => { | givenProps }
87+ -> kids
88+ -> JSX
89+dropdownPopover props kids = runFn4 createElementTransformImpl {} Raw.dropdownPopover props kids
90+
91+type SectionProps r = (className :: String | r)
92+
93+dropdownTrigger
94+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
95+dropdownTrigger props kids = runFn4 createElementTransformImpl {} Raw.dropdownTrigger props kids
96+
97+dropdownItemIndicator
98+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
99+dropdownItemIndicator props kids = runFn4 createElementTransformImpl {} Raw.dropdownItemIndicator props kids
100+
101+dropdownSubmenuIndicator
102+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
103+dropdownSubmenuIndicator props kids = runFn4 createElementTransformImpl {} Raw.dropdownSubmenuIndicator props kids
104+
105+dropdownSubmenuTrigger
106+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
107+dropdownSubmenuTrigger props kids = runFn4 createElementTransformImpl {} Raw.dropdownSubmenuTrigger props kids
src/HeroUI/Form.pursnew file+39
@@ -0,0 +1,39 @@
1+module HeroUI.Form where
2+
3+import Prelude
4+
5+import React.Basic (JSX)
6+import React.Basic.Events (EventHandler)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
10+import HeroUI.Raw as Raw
11+
12+data ValidationBehavior = Native | Aria
13+
14+derive instance Eq ValidationBehavior
15+derive instance Ord ValidationBehavior
16+
17+validationBehaviorToString :: ValidationBehavior -> String
18+validationBehaviorToString = case _ of
19+ Native -> "native"
20+ Aria -> "aria"
21+
22+type FormProps r =
23+ ( action :: String
24+ , method :: String
25+ , validationBehavior :: ValidationBehavior
26+ , onSubmit :: EventHandler
27+ , onReset :: EventHandler
28+ , className :: String
29+ | r
30+ )
31+
32+form
33+ :: forall givenProps nonDataProps kids
34+ . IsJSX kids
35+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | FormProps () }
36+ => { | givenProps }
37+ -> kids
38+ -> JSX
39+form props kids = runFn4 createElementTransformImpl { validationBehavior: validationBehaviorToString } Raw.form props kids
src/HeroUI/Hooks.jsnew file+13
@@ -0,0 +1,13 @@
1+import {
2+ useOverlayState,
3+ useTheme,
4+ useMediaQuery,
5+ useIsHydrated,
6+ useIsMounted,
7+} from "@heroui/react";
8+
9+export const useOverlayStateImpl = (props) => useOverlayState(props);
10+export const useThemeImpl = () => useTheme();
11+export const useMediaQueryImpl = (query) => useMediaQuery(query);
12+export const useIsHydratedImpl = () => useIsHydrated();
13+export const useIsMountedImpl = () => useIsMounted();
src/HeroUI/Hooks.pursnew file+82
@@ -0,0 +1,82 @@
1+module HeroUI.Hooks
2+ ( UseOverlayState
3+ , UseOverlayStateProps
4+ , UseOverlayStateReturn
5+ , useOverlayState
6+ , UseTheme
7+ , UseThemeReturn
8+ , useTheme
9+ , UseMediaQuery
10+ , useMediaQuery
11+ , UseIsHydrated
12+ , useIsHydrated
13+ , UseIsMounted
14+ , useIsMounted
15+ ) where
16+
17+import Prelude
18+
19+import Data.Nullable (Nullable)
20+import Effect (Effect)
21+import Effect.Uncurried (EffectFn1, runEffectFn1)
22+import Prim.Row as Row
23+import React.Basic.Hooks (Hook)
24+import React.Basic.Hooks.Internal (unsafeHook)
25+import Unsafe.Coerce (unsafeCoerce)
26+
27+-- | Manages overlay open state (Modal, Drawer, Popover, ...). Replaces v2's
28+-- | `useDisclosure`. All props optional. https://heroui.com (useOverlayState)
29+type UseOverlayStateProps =
30+ ( isOpen :: Boolean
31+ , defaultOpen :: Boolean
32+ , onOpenChange :: EffectFn1 Boolean Unit
33+ )
34+
35+type UseOverlayStateReturn =
36+ ( isOpen :: Boolean
37+ , setOpen :: EffectFn1 Boolean Unit
38+ , open :: Effect Unit
39+ , close :: Effect Unit
40+ , toggle :: Effect Unit
41+ )
42+
43+foreign import data UseOverlayState :: Type -> Type
44+foreign import data UseTheme :: Type -> Type
45+foreign import data UseMediaQuery :: Type -> Type
46+foreign import data UseIsHydrated :: Type -> Type
47+foreign import data UseIsMounted :: Type -> Type
48+
49+foreign import useOverlayStateImpl :: EffectFn1 (Record UseOverlayStateProps) (Record UseOverlayStateReturn)
50+foreign import useThemeImpl :: Effect (Record UseThemeReturn)
51+foreign import useMediaQueryImpl :: EffectFn1 String Boolean
52+foreign import useIsHydratedImpl :: Effect Boolean
53+foreign import useIsMountedImpl :: Effect (Effect Boolean)
54+
55+useOverlayState
56+ :: forall props missing
57+ . Row.Union props missing UseOverlayStateProps
58+ => Record props
59+ -> Hook UseOverlayState (Record UseOverlayStateReturn)
60+useOverlayState props = unsafeHook (runEffectFn1 useOverlayStateImpl (widen props))
61+ where
62+ widen :: Record props -> Record UseOverlayStateProps
63+ widen = unsafeCoerce
64+
65+type UseThemeReturn =
66+ ( theme :: String
67+ , resolvedTheme :: Nullable String
68+ , setTheme :: EffectFn1 String Unit
69+ )
70+
71+useTheme :: Hook UseTheme (Record UseThemeReturn)
72+useTheme = unsafeHook useThemeImpl
73+
74+useMediaQuery :: String -> Hook UseMediaQuery Boolean
75+useMediaQuery query = unsafeHook (runEffectFn1 useMediaQueryImpl query)
76+
77+useIsHydrated :: Hook UseIsHydrated Boolean
78+useIsHydrated = unsafeHook useIsHydratedImpl
79+
80+-- | Returns a getter; call the inner `Effect Boolean` to read mounted state.
81+useIsMounted :: Hook UseIsMounted (Effect Boolean)
82+useIsMounted = unsafeHook useIsMountedImpl
src/HeroUI/Input.pursnew file+120
@@ -0,0 +1,120 @@
1+module HeroUI.Input where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Types (FieldVariant, fieldVariantToString)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+data InputType
14+ = InputTypeText
15+ | InputTypeEmail
16+ | InputTypePassword
17+ | InputTypeNumber
18+ | InputTypeTel
19+ | InputTypeUrl
20+ | InputTypeSearch
21+ | InputTypeDate
22+ | InputTypeTime
23+ | InputTypeDateTimeLocal
24+ | InputTypeMonth
25+ | InputTypeWeek
26+ | InputTypeColor
27+
28+derive instance Eq InputType
29+derive instance Ord InputType
30+
31+inputTypeToString :: InputType -> String
32+inputTypeToString = case _ of
33+ InputTypeText -> "text"
34+ InputTypeEmail -> "email"
35+ InputTypePassword -> "password"
36+ InputTypeNumber -> "number"
37+ InputTypeTel -> "tel"
38+ InputTypeUrl -> "url"
39+ InputTypeSearch -> "search"
40+ InputTypeDate -> "date"
41+ InputTypeTime -> "time"
42+ InputTypeDateTimeLocal -> "datetime-local"
43+ InputTypeMonth -> "month"
44+ InputTypeWeek -> "week"
45+ InputTypeColor -> "color"
46+
47+-- | `TextField` is the stateful field wrapper (holds value/onChange,
48+-- | validation). Compose `input` / a `Label` inside it.
49+type TextFieldProps r =
50+ ( value :: String
51+ , defaultValue :: String
52+ , onChange :: EffectFn1 String Unit
53+ , type :: InputType
54+ , name :: String
55+ , isDisabled :: Boolean
56+ , isReadOnly :: Boolean
57+ , isRequired :: Boolean
58+ , isInvalid :: Boolean
59+ , autoFocus :: Boolean
60+ , fullWidth :: Boolean
61+ , variant :: FieldVariant
62+ , className :: String
63+ | r
64+ )
65+
66+textFieldTransforms :: { type :: InputType -> String, variant :: FieldVariant -> String }
67+textFieldTransforms = { type: inputTypeToString, variant: fieldVariantToString }
68+
69+textField
70+ :: forall givenProps nonDataProps kids
71+ . IsJSX kids
72+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | TextFieldProps () }
73+ => { | givenProps }
74+ -> kids
75+ -> JSX
76+textField props kids = runFn4 createElementTransformImpl textFieldTransforms Raw.textField props kids
77+
78+-- | The bare styled input element. Use inside `textField` for managed state.
79+type InputProps r =
80+ ( placeholder :: String
81+ , type :: InputType
82+ , name :: String
83+ , autoComplete :: String
84+ , fullWidth :: Boolean
85+ , variant :: FieldVariant
86+ , className :: String
87+ | r
88+ )
89+
90+inputTransforms :: { type :: InputType -> String, variant :: FieldVariant -> String }
91+inputTransforms = { type: inputTypeToString, variant: fieldVariantToString }
92+
93+input
94+ :: forall givenProps nonDataProps kids
95+ . IsJSX kids
96+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | InputProps () }
97+ => { | givenProps }
98+ -> kids
99+ -> JSX
100+input props kids = runFn4 createElementTransformImpl inputTransforms Raw.input props kids
101+
102+type TextareaProps r =
103+ ( placeholder :: String
104+ , rows :: Int
105+ , name :: String
106+ , isDisabled :: Boolean
107+ , fullWidth :: Boolean
108+ , variant :: FieldVariant
109+ , className :: String
110+ | r
111+ )
112+
113+textarea
114+ :: forall givenProps nonDataProps kids
115+ . IsJSX kids
116+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | TextareaProps () }
117+ => { | givenProps }
118+ -> kids
119+ -> JSX
120+textarea props kids = runFn4 createElementTransformImpl { variant: fieldVariantToString } Raw.textarea props kids
src/HeroUI/InputOTP.pursnew file+66
@@ -0,0 +1,66 @@
1+module HeroUI.InputOTP where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Types (FieldVariant, fieldVariantToString)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+type InputOTPProps r =
14+ ( value :: String
15+ , defaultValue :: String
16+ , onChange :: EffectFn1 String Unit
17+ , maxLength :: Int
18+ , isDisabled :: Boolean
19+ , isInvalid :: Boolean
20+ , variant :: FieldVariant
21+ , inputClassName :: String
22+ , className :: String
23+ | r
24+ )
25+
26+inputOTP
27+ :: forall givenProps nonDataProps kids
28+ . IsJSX kids
29+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | InputOTPProps () }
30+ => { | givenProps }
31+ -> kids
32+ -> JSX
33+inputOTP props kids = runFn4 createElementTransformImpl { variant: fieldVariantToString } Raw.inputOTP props kids
34+
35+type InputOTPGroupProps r = (className :: String | r)
36+
37+inputOTPGroup
38+ :: forall givenProps nonDataProps kids
39+ . IsJSX kids
40+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | InputOTPGroupProps () }
41+ => { | givenProps }
42+ -> kids
43+ -> JSX
44+inputOTPGroup props kids = runFn4 createElementTransformImpl {} Raw.inputOTPGroup props kids
45+
46+type InputOTPSlotProps r = (index :: Int, className :: String | r)
47+
48+inputOTPSlot
49+ :: forall givenProps nonDataProps kids
50+ . IsJSX kids
51+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | InputOTPSlotProps () }
52+ => { | givenProps }
53+ -> kids
54+ -> JSX
55+inputOTPSlot props kids = runFn4 createElementTransformImpl {} Raw.inputOTPSlot props kids
56+
57+type InputOTPSeparatorProps r = (className :: String | r)
58+
59+inputOTPSeparator
60+ :: forall givenProps nonDataProps kids
61+ . IsJSX kids
62+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | InputOTPSeparatorProps () }
63+ => { | givenProps }
64+ -> kids
65+ -> JSX
66+inputOTPSeparator props kids = runFn4 createElementTransformImpl {} Raw.inputOTPSeparator props kids
src/HeroUI/ListBox.pursnew file+63
@@ -0,0 +1,63 @@
1+module HeroUI.ListBox where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import Foreign (Foreign)
7+import React.Basic (JSX)
8+import Yoga.React.DOM.Internal (class IsJSX)
9+import Data.Function.Uncurried (runFn4)
10+import HeroUI.Types (SelectionMode, selectionModeToString)
11+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
12+import HeroUI.Raw as Raw
13+
14+type ListBoxProps r =
15+ ( selectionMode :: SelectionMode
16+ , selectedKeys :: Array String
17+ , defaultSelectedKeys :: Array String
18+ , onSelectionChange :: EffectFn1 Foreign Unit
19+ , disabledKeys :: Array String
20+ , isDisabled :: Boolean
21+ , className :: String
22+ | r
23+ )
24+
25+listBox
26+ :: forall givenProps nonDataProps kids
27+ . IsJSX kids
28+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | ListBoxProps () }
29+ => { | givenProps }
30+ -> kids
31+ -> JSX
32+listBox props kids = runFn4 createElementTransformImpl { selectionMode: selectionModeToString } Raw.listBox props kids
33+
34+-- | Collection item. `id` identifies the item for selection state; supply
35+-- | `textValue` when the children aren't plain text (used for typeahead).
36+type ListBoxItemProps r =
37+ ( id :: String
38+ , textValue :: String
39+ , isDisabled :: Boolean
40+ , href :: String
41+ , className :: String
42+ | r
43+ )
44+
45+listBoxItem
46+ :: forall givenProps nonDataProps kids
47+ . IsJSX kids
48+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | ListBoxItemProps () }
49+ => { | givenProps }
50+ -> kids
51+ -> JSX
52+listBoxItem props kids = runFn4 createElementTransformImpl {} Raw.listBoxItem props kids
53+
54+type ListBoxSectionProps r = (id :: String, className :: String | r)
55+
56+listBoxSection
57+ :: forall givenProps nonDataProps kids
58+ . IsJSX kids
59+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | ListBoxSectionProps () }
60+ => { | givenProps }
61+ -> kids
62+ -> JSX
63+listBoxSection props kids = runFn4 createElementTransformImpl {} Raw.listBoxSection props kids
src/HeroUI/Menu.pursnew file+71
@@ -0,0 +1,71 @@
1+module HeroUI.Menu where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import Foreign (Foreign)
7+import React.Basic (JSX)
8+import Yoga.React.DOM.Internal (class IsJSX)
9+import Data.Function.Uncurried (runFn4)
10+import HeroUI.Types (SelectionMode, selectionModeToString)
11+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
12+import HeroUI.Raw as Raw
13+
14+type MenuProps r =
15+ ( selectionMode :: SelectionMode
16+ , selectedKeys :: Array String
17+ , defaultSelectedKeys :: Array String
18+ , onSelectionChange :: EffectFn1 Foreign Unit
19+ , onAction :: EffectFn1 String Unit
20+ , disabledKeys :: Array String
21+ , className :: String
22+ | r
23+ )
24+
25+menu
26+ :: forall givenProps nonDataProps kids
27+ . IsJSX kids
28+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | MenuProps () }
29+ => { | givenProps }
30+ -> kids
31+ -> JSX
32+menu props kids = runFn4 createElementTransformImpl { selectionMode: selectionModeToString } Raw.menu props kids
33+
34+type MenuItemProps r =
35+ ( id :: String
36+ , textValue :: String
37+ , isDisabled :: Boolean
38+ , href :: String
39+ , className :: String
40+ | r
41+ )
42+
43+menuItem
44+ :: forall givenProps nonDataProps kids
45+ . IsJSX kids
46+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | MenuItemProps () }
47+ => { | givenProps }
48+ -> kids
49+ -> JSX
50+menuItem props kids = runFn4 createElementTransformImpl {} Raw.menuItem props kids
51+
52+type MenuSectionProps r = (id :: String, className :: String | r)
53+
54+menuSection
55+ :: forall givenProps nonDataProps kids
56+ . IsJSX kids
57+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | MenuSectionProps () }
58+ => { | givenProps }
59+ -> kids
60+ -> JSX
61+menuSection props kids = runFn4 createElementTransformImpl {} Raw.menuSection props kids
62+
63+type SectionProps r = (className :: String | r)
64+
65+menuItemIndicator
66+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
67+menuItemIndicator props kids = runFn4 createElementTransformImpl {} Raw.menuItemIndicator props kids
68+
69+menuItemSubmenuIndicator
70+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
71+menuItemSubmenuIndicator props kids = runFn4 createElementTransformImpl {} Raw.menuItemSubmenuIndicator props kids
src/HeroUI/Modal.pursnew file+142
@@ -0,0 +1,142 @@
1+module HeroUI.Modal where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
10+import HeroUI.Raw as Raw
11+
12+data Size = Xs | Sm | Md | Lg | Full | Cover
13+
14+derive instance Eq Size
15+derive instance Ord Size
16+
17+sizeToString :: Size -> String
18+sizeToString = case _ of
19+ Xs -> "xs"
20+ Sm -> "sm"
21+ Md -> "md"
22+ Lg -> "lg"
23+ Full -> "full"
24+ Cover -> "cover"
25+
26+data Placement = PlacementAuto | PlacementTop | PlacementCenter | PlacementBottom
27+
28+derive instance Eq Placement
29+derive instance Ord Placement
30+
31+placementToString :: Placement -> String
32+placementToString = case _ of
33+ PlacementAuto -> "auto"
34+ PlacementTop -> "top"
35+ PlacementCenter -> "center"
36+ PlacementBottom -> "bottom"
37+
38+data Backdrop = Blur | Opaque | Transparent
39+
40+derive instance Eq Backdrop
41+derive instance Ord Backdrop
42+
43+backdropToString :: Backdrop -> String
44+backdropToString = case _ of
45+ Blur -> "blur"
46+ Opaque -> "opaque"
47+ Transparent -> "transparent"
48+
49+data Scroll = ScrollInside | ScrollOutside
50+
51+derive instance Eq Scroll
52+derive instance Ord Scroll
53+
54+scrollToString :: Scroll -> String
55+scrollToString = case _ of
56+ ScrollInside -> "inside"
57+ ScrollOutside -> "outside"
58+
59+-- | The root wires the open state (react-aria `DialogTrigger`).
60+type ModalProps r =
61+ ( isOpen :: Boolean
62+ , defaultOpen :: Boolean
63+ , onOpenChange :: EffectFn1 Boolean Unit
64+ , isDismissable :: Boolean
65+ , className :: String
66+ | r
67+ )
68+
69+modal
70+ :: forall givenProps nonDataProps kids
71+ . IsJSX kids
72+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | ModalProps () }
73+ => { | givenProps }
74+ -> kids
75+ -> JSX
76+modal props kids = runFn4 createElementTransformImpl {} Raw.modal props kids
77+
78+type ModalBackdropProps r = (variant :: Backdrop, isDismissable :: Boolean, className :: String | r)
79+
80+modalBackdrop
81+ :: forall givenProps nonDataProps kids
82+ . IsJSX kids
83+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | ModalBackdropProps () }
84+ => { | givenProps }
85+ -> kids
86+ -> JSX
87+modalBackdrop props kids = runFn4 createElementTransformImpl { variant: backdropToString } Raw.modalBackdrop props kids
88+
89+type ModalContainerProps r =
90+ ( placement :: Placement
91+ , scroll :: Scroll
92+ , size :: Size
93+ , className :: String
94+ | r
95+ )
96+
97+modalContainerTransforms
98+ :: { placement :: Placement -> String, scroll :: Scroll -> String, size :: Size -> String }
99+modalContainerTransforms = { placement: placementToString, scroll: scrollToString, size: sizeToString }
100+
101+modalContainer
102+ :: forall givenProps nonDataProps kids
103+ . IsJSX kids
104+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | ModalContainerProps () }
105+ => { | givenProps }
106+ -> kids
107+ -> JSX
108+modalContainer props kids = runFn4 createElementTransformImpl modalContainerTransforms Raw.modalContainer props kids
109+
110+type SectionProps r = (className :: String | r)
111+
112+modalTrigger
113+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
114+modalTrigger props kids = runFn4 createElementTransformImpl {} Raw.modalTrigger props kids
115+
116+modalDialog
117+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
118+modalDialog props kids = runFn4 createElementTransformImpl {} Raw.modalDialog props kids
119+
120+modalHeader
121+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
122+modalHeader props kids = runFn4 createElementTransformImpl {} Raw.modalHeader props kids
123+
124+modalIcon
125+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
126+modalIcon props kids = runFn4 createElementTransformImpl {} Raw.modalIcon props kids
127+
128+modalHeading
129+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
130+modalHeading props kids = runFn4 createElementTransformImpl {} Raw.modalHeading props kids
131+
132+modalBody
133+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
134+modalBody props kids = runFn4 createElementTransformImpl {} Raw.modalBody props kids
135+
136+modalFooter
137+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
138+modalFooter props kids = runFn4 createElementTransformImpl {} Raw.modalFooter props kids
139+
140+modalCloseTrigger
141+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
142+modalCloseTrigger props kids = runFn4 createElementTransformImpl {} Raw.modalCloseTrigger props kids
src/HeroUI/NumberField.pursnew file+76
@@ -0,0 +1,76 @@
1+module HeroUI.NumberField where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Types (FieldVariant, fieldVariantToString)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+type NumberFieldProps r =
14+ ( value :: Number
15+ , defaultValue :: Number
16+ , onChange :: EffectFn1 Number Unit
17+ , minValue :: Number
18+ , maxValue :: Number
19+ , step :: Number
20+ , name :: String
21+ , isDisabled :: Boolean
22+ , isReadOnly :: Boolean
23+ , isRequired :: Boolean
24+ , isInvalid :: Boolean
25+ , fullWidth :: Boolean
26+ , variant :: FieldVariant
27+ , className :: String
28+ | r
29+ )
30+
31+numberField
32+ :: forall givenProps nonDataProps kids
33+ . IsJSX kids
34+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | NumberFieldProps () }
35+ => { | givenProps }
36+ -> kids
37+ -> JSX
38+numberField props kids = runFn4 createElementTransformImpl { variant: fieldVariantToString } Raw.numberField props kids
39+
40+type SectionProps r = (className :: String | r)
41+
42+numberFieldGroup
43+ :: forall givenProps nonDataProps kids
44+ . IsJSX kids
45+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
46+ => { | givenProps }
47+ -> kids
48+ -> JSX
49+numberFieldGroup props kids = runFn4 createElementTransformImpl {} Raw.numberFieldGroup props kids
50+
51+numberFieldInput
52+ :: forall givenProps nonDataProps kids
53+ . IsJSX kids
54+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
55+ => { | givenProps }
56+ -> kids
57+ -> JSX
58+numberFieldInput props kids = runFn4 createElementTransformImpl {} Raw.numberFieldInput props kids
59+
60+numberFieldIncrementButton
61+ :: forall givenProps nonDataProps kids
62+ . IsJSX kids
63+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
64+ => { | givenProps }
65+ -> kids
66+ -> JSX
67+numberFieldIncrementButton props kids = runFn4 createElementTransformImpl {} Raw.numberFieldIncrementButton props kids
68+
69+numberFieldDecrementButton
70+ :: forall givenProps nonDataProps kids
71+ . IsJSX kids
72+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
73+ => { | givenProps }
74+ -> kids
75+ -> JSX
76+numberFieldDecrementButton props kids = runFn4 createElementTransformImpl {} Raw.numberFieldDecrementButton props kids
src/HeroUI/Pagination.pursnew file+73
@@ -0,0 +1,73 @@
1+module HeroUI.Pagination where
2+
3+import Prelude
4+
5+import React.Basic (JSX)
6+import Yoga.React.DOM.Internal (class IsJSX)
7+import Data.Function.Uncurried (runFn4)
8+import HeroUI.Types (Size, sizeToString)
9+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
10+import HeroUI.Raw as Raw
11+
12+type PaginationProps r = (size :: Size, className :: String | r)
13+
14+pagination
15+ :: forall givenProps nonDataProps kids
16+ . IsJSX kids
17+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | PaginationProps () }
18+ => { | givenProps }
19+ -> kids
20+ -> JSX
21+pagination props kids = runFn4 createElementTransformImpl { size: sizeToString } Raw.pagination props kids
22+
23+type PaginationItemProps r = (isActive :: Boolean, className :: String | r)
24+
25+paginationItem
26+ :: forall givenProps nonDataProps kids
27+ . IsJSX kids
28+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | PaginationItemProps () }
29+ => { | givenProps }
30+ -> kids
31+ -> JSX
32+paginationItem props kids = runFn4 createElementTransformImpl {} Raw.paginationItem props kids
33+
34+type PaginationLinkProps r = (href :: String, isActive :: Boolean, className :: String | r)
35+
36+paginationLink
37+ :: forall givenProps nonDataProps kids
38+ . IsJSX kids
39+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | PaginationLinkProps () }
40+ => { | givenProps }
41+ -> kids
42+ -> JSX
43+paginationLink props kids = runFn4 createElementTransformImpl {} Raw.paginationLink props kids
44+
45+type SectionProps r = (className :: String | r)
46+
47+paginationSummary
48+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
49+paginationSummary props kids = runFn4 createElementTransformImpl {} Raw.paginationSummary props kids
50+
51+paginationContent
52+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
53+paginationContent props kids = runFn4 createElementTransformImpl {} Raw.paginationContent props kids
54+
55+paginationPrevious
56+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
57+paginationPrevious props kids = runFn4 createElementTransformImpl {} Raw.paginationPrevious props kids
58+
59+paginationPreviousIcon
60+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
61+paginationPreviousIcon props kids = runFn4 createElementTransformImpl {} Raw.paginationPreviousIcon props kids
62+
63+paginationNext
64+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
65+paginationNext props kids = runFn4 createElementTransformImpl {} Raw.paginationNext props kids
66+
67+paginationNextIcon
68+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
69+paginationNextIcon props kids = runFn4 createElementTransformImpl {} Raw.paginationNextIcon props kids
70+
71+paginationEllipsis
72+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
73+paginationEllipsis props kids = runFn4 createElementTransformImpl {} Raw.paginationEllipsis props kids
src/HeroUI/Popover.pursnew file+63
@@ -0,0 +1,63 @@
1+module HeroUI.Popover where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
10+import HeroUI.Raw as Raw
11+
12+type PopoverProps r =
13+ ( isOpen :: Boolean
14+ , defaultOpen :: Boolean
15+ , onOpenChange :: EffectFn1 Boolean Unit
16+ | r
17+ )
18+
19+popover
20+ :: forall givenProps nonDataProps kids
21+ . IsJSX kids
22+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | PopoverProps () }
23+ => { | givenProps }
24+ -> kids
25+ -> JSX
26+popover props kids = runFn4 createElementTransformImpl {} Raw.popover props kids
27+
28+-- | `placement` follows react-aria's placement strings (e.g. "bottom",
29+-- | "top start"); kept as `String` since the union is large.
30+type PopoverContentProps r =
31+ ( placement :: String
32+ , offset :: Number
33+ , showArrow :: Boolean
34+ , className :: String
35+ | r
36+ )
37+
38+popoverContent
39+ :: forall givenProps nonDataProps kids
40+ . IsJSX kids
41+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | PopoverContentProps () }
42+ => { | givenProps }
43+ -> kids
44+ -> JSX
45+popoverContent props kids = runFn4 createElementTransformImpl {} Raw.popoverContent props kids
46+
47+type SectionProps r = (className :: String | r)
48+
49+popoverTrigger
50+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
51+popoverTrigger props kids = runFn4 createElementTransformImpl {} Raw.popoverTrigger props kids
52+
53+popoverDialog
54+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
55+popoverDialog props kids = runFn4 createElementTransformImpl {} Raw.popoverDialog props kids
56+
57+popoverHeading
58+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
59+popoverHeading props kids = runFn4 createElementTransformImpl {} Raw.popoverHeading props kids
60+
61+popoverArrow
62+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
63+popoverArrow props kids = runFn4 createElementTransformImpl {} Raw.popoverArrow props kids
src/HeroUI/Progress.pursnew file+68
@@ -0,0 +1,68 @@
1+module HeroUI.Progress where
2+
3+import Prelude
4+
5+import React.Basic (JSX)
6+import Yoga.React.DOM.Internal (class IsJSX)
7+import Data.Function.Uncurried (runFn4)
8+import HeroUI.Types (Color, Size, colorToString, sizeToString)
9+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
10+import HeroUI.Raw as Raw
11+
12+type ProgressProps r =
13+ ( value :: Number
14+ , minValue :: Number
15+ , maxValue :: Number
16+ , isIndeterminate :: Boolean
17+ , color :: Color
18+ , size :: Size
19+ , className :: String
20+ | r
21+ )
22+
23+progressTransforms :: { color :: Color -> String, size :: Size -> String }
24+progressTransforms = { color: colorToString, size: sizeToString }
25+
26+progressBar
27+ :: forall givenProps nonDataProps kids
28+ . IsJSX kids
29+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | ProgressProps () }
30+ => { | givenProps }
31+ -> kids
32+ -> JSX
33+progressBar props kids = runFn4 createElementTransformImpl progressTransforms Raw.progressBar props kids
34+
35+progressCircle
36+ :: forall givenProps nonDataProps kids
37+ . IsJSX kids
38+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | ProgressProps () }
39+ => { | givenProps }
40+ -> kids
41+ -> JSX
42+progressCircle props kids = runFn4 createElementTransformImpl progressTransforms Raw.progressCircle props kids
43+
44+type SectionProps r = (className :: String | r)
45+
46+progressBarOutput
47+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
48+progressBarOutput props kids = runFn4 createElementTransformImpl {} Raw.progressBarOutput props kids
49+
50+progressBarTrack
51+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
52+progressBarTrack props kids = runFn4 createElementTransformImpl {} Raw.progressBarTrack props kids
53+
54+progressBarFill
55+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
56+progressBarFill props kids = runFn4 createElementTransformImpl {} Raw.progressBarFill props kids
57+
58+progressCircleTrack
59+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
60+progressCircleTrack props kids = runFn4 createElementTransformImpl {} Raw.progressCircleTrack props kids
61+
62+progressCircleTrackCircle
63+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
64+progressCircleTrackCircle props kids = runFn4 createElementTransformImpl {} Raw.progressCircleTrackCircle props kids
65+
66+progressCircleFillCircle
67+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
68+progressCircleFillCircle props kids = runFn4 createElementTransformImpl {} Raw.progressCircleFillCircle props kids
src/HeroUI/Radio.pursnew file+85
@@ -0,0 +1,85 @@
1+module HeroUI.Radio where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Types (FieldVariant, Orientation, fieldVariantToString, orientationToString)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+type RadioProps r =
14+ ( value :: String
15+ , isDisabled :: Boolean
16+ , name :: String
17+ , className :: String
18+ | r
19+ )
20+
21+radio
22+ :: forall givenProps nonDataProps kids
23+ . IsJSX kids
24+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | RadioProps () }
25+ => { | givenProps }
26+ -> kids
27+ -> JSX
28+radio props kids = runFn4 createElementTransformImpl {} Raw.radio props kids
29+
30+type RadioGroupProps r =
31+ ( value :: String
32+ , defaultValue :: String
33+ , onChange :: EffectFn1 String Unit
34+ , isDisabled :: Boolean
35+ , isReadOnly :: Boolean
36+ , isRequired :: Boolean
37+ , isInvalid :: Boolean
38+ , name :: String
39+ , orientation :: Orientation
40+ , variant :: FieldVariant
41+ , className :: String
42+ | r
43+ )
44+
45+radioGroupTransforms
46+ :: { variant :: FieldVariant -> String, orientation :: Orientation -> String }
47+radioGroupTransforms = { variant: fieldVariantToString, orientation: orientationToString }
48+
49+radioGroup
50+ :: forall givenProps nonDataProps kids
51+ . IsJSX kids
52+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | RadioGroupProps () }
53+ => { | givenProps }
54+ -> kids
55+ -> JSX
56+radioGroup props kids = runFn4 createElementTransformImpl radioGroupTransforms Raw.radioGroup props kids
57+
58+type SectionProps r = (className :: String | r)
59+
60+radioControl
61+ :: forall givenProps nonDataProps kids
62+ . IsJSX kids
63+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
64+ => { | givenProps }
65+ -> kids
66+ -> JSX
67+radioControl props kids = runFn4 createElementTransformImpl {} Raw.radioControl props kids
68+
69+radioIndicator
70+ :: forall givenProps nonDataProps kids
71+ . IsJSX kids
72+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
73+ => { | givenProps }
74+ -> kids
75+ -> JSX
76+radioIndicator props kids = runFn4 createElementTransformImpl {} Raw.radioIndicator props kids
77+
78+radioContent
79+ :: forall givenProps nonDataProps kids
80+ . IsJSX kids
81+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
82+ => { | givenProps }
83+ -> kids
84+ -> JSX
85+radioContent props kids = runFn4 createElementTransformImpl {} Raw.radioContent props kids
src/HeroUI/Raw.js+384
@@ -39,6 +39,169 @@ import {
3939 TabIndicator,
4040 TabSeparator,
4141 TabPanel,
42+ TextFieldRoot,
43+ InputRoot,
44+ TextAreaRoot,
45+ NumberFieldRoot,
46+ NumberFieldGroup,
47+ NumberFieldInput,
48+ NumberFieldIncrementButton,
49+ NumberFieldDecrementButton,
50+ CheckboxRoot,
51+ CheckboxControl,
52+ CheckboxIndicator,
53+ CheckboxContent,
54+ CheckboxGroup,
55+ RadioRoot,
56+ RadioControl,
57+ RadioIndicator,
58+ RadioContent,
59+ RadioGroupRoot,
60+ SwitchRoot,
61+ SwitchControl,
62+ SwitchThumb,
63+ SwitchIcon,
64+ SwitchContent,
65+ SliderRoot,
66+ SliderOutput,
67+ SliderTrack,
68+ SliderFill,
69+ SliderThumb,
70+ SliderMarks,
71+ FormRoot,
72+ InputOTPRoot,
73+ InputOTPGroup,
74+ InputOTPSlot,
75+ InputOTPSeparator,
76+ ListBoxRoot,
77+ ListBoxItemRoot,
78+ ListBoxSectionRoot,
79+ SelectRoot,
80+ SelectTrigger,
81+ SelectValue,
82+ SelectIndicator,
83+ SelectPopover,
84+ AutocompleteRoot,
85+ AutocompleteTrigger,
86+ AutocompleteValue,
87+ AutocompleteIndicator,
88+ AutocompletePopover,
89+ AutocompleteClearButton,
90+ AutocompleteFilter,
91+ DateFieldRoot,
92+ TimeFieldRoot,
93+ DatePickerRoot,
94+ DatePickerTrigger,
95+ DatePickerTriggerIndicator,
96+ DatePickerPopover,
97+ DateRangePickerRoot,
98+ DateRangePickerTrigger,
99+ DateRangePickerTriggerIndicator,
100+ DateRangePickerRangeSeparator,
101+ DateRangePickerPopover,
102+ CalendarRoot,
103+ CalendarHeader,
104+ CalendarHeading,
105+ CalendarNavButton,
106+ CalendarGrid,
107+ CalendarGridHeader,
108+ CalendarGridBody,
109+ CalendarHeaderCell,
110+ CalendarCell,
111+ CalendarCellIndicator,
112+ RangeCalendarRoot,
113+ RangeCalendarHeader,
114+ RangeCalendarHeading,
115+ RangeCalendarNavButton,
116+ RangeCalendarGrid,
117+ RangeCalendarCell,
118+ ModalRoot,
119+ ModalTrigger,
120+ ModalBackdrop,
121+ ModalContainer,
122+ ModalDialog,
123+ ModalHeader,
124+ ModalIcon,
125+ ModalHeading,
126+ ModalBody,
127+ ModalFooter,
128+ ModalCloseTrigger,
129+ DrawerRoot,
130+ DrawerTrigger,
131+ DrawerBackdrop,
132+ DrawerContent,
133+ DrawerDialog,
134+ DrawerHeader,
135+ DrawerHeading,
136+ DrawerBody,
137+ DrawerFooter,
138+ DrawerHandle,
139+ DrawerCloseTrigger,
140+ PopoverRoot,
141+ PopoverTrigger,
142+ PopoverContent,
143+ PopoverDialog,
144+ PopoverHeading,
145+ PopoverArrow,
146+ TooltipRoot,
147+ TooltipTrigger,
148+ TooltipContent,
149+ TooltipArrow,
150+ DropdownRoot,
151+ DropdownTrigger,
152+ DropdownPopover,
153+ DropdownMenu,
154+ DropdownSection,
155+ DropdownItem,
156+ DropdownItemIndicator,
157+ DropdownSubmenuIndicator,
158+ DropdownSubmenuTrigger,
159+ MenuRoot,
160+ MenuItemRoot,
161+ MenuItemIndicator,
162+ MenuItemSubmenuIndicator,
163+ MenuSectionRoot,
164+ TableRoot,
165+ TableScrollContainer,
166+ TableContent,
167+ TableHeader,
168+ TableColumn,
169+ TableBody,
170+ TableRow,
171+ TableCell,
172+ TableFooter,
173+ PaginationRoot,
174+ PaginationSummary,
175+ PaginationContent,
176+ PaginationItem,
177+ PaginationLink,
178+ PaginationPrevious,
179+ PaginationPreviousIcon,
180+ PaginationNext,
181+ PaginationNextIcon,
182+ PaginationEllipsis,
183+ BreadcrumbsRoot,
184+ BreadcrumbsItem,
185+ ProgressBarRoot,
186+ ProgressBarOutput,
187+ ProgressBarTrack,
188+ ProgressBarFill,
189+ ProgressCircleRoot,
190+ ProgressCircleTrack,
191+ ProgressCircleTrackCircle,
192+ ProgressCircleFillCircle,
193+ AlertRoot,
194+ AlertIndicator,
195+ AlertContent,
196+ AlertTitle,
197+ AlertDescription,
198+ ToastProvider,
199+ ToastContent,
200+ ToastIndicator,
201+ ToastTitle,
202+ ToastDescription,
203+ ToastActionButton,
204+ ToastCloseButton,
42205} from "@heroui/react";
43206
44207// Button
@@ -106,3 +269,224 @@ export const tab = Tab;
106269export const tabIndicator = TabIndicator;
107270export const tabSeparator = TabSeparator;
108271export const tabPanel = TabPanel;
272+
273+// TextField / Input / Textarea
274+export const textField = TextFieldRoot;
275+export const input = InputRoot;
276+export const textarea = TextAreaRoot;
277+
278+// NumberField
279+export const numberField = NumberFieldRoot;
280+export const numberFieldGroup = NumberFieldGroup;
281+export const numberFieldInput = NumberFieldInput;
282+export const numberFieldIncrementButton = NumberFieldIncrementButton;
283+export const numberFieldDecrementButton = NumberFieldDecrementButton;
284+
285+// Checkbox
286+export const checkbox = CheckboxRoot;
287+export const checkboxControl = CheckboxControl;
288+export const checkboxIndicator = CheckboxIndicator;
289+export const checkboxContent = CheckboxContent;
290+export const checkboxGroup = CheckboxGroup;
291+
292+// Radio
293+export const radio = RadioRoot;
294+export const radioControl = RadioControl;
295+export const radioIndicator = RadioIndicator;
296+export const radioContent = RadioContent;
297+export const radioGroup = RadioGroupRoot;
298+
299+// Switch
300+export const switch_ = SwitchRoot;
301+export const switchControl = SwitchControl;
302+export const switchThumb = SwitchThumb;
303+export const switchIcon = SwitchIcon;
304+export const switchContent = SwitchContent;
305+
306+// Slider
307+export const slider = SliderRoot;
308+export const sliderOutput = SliderOutput;
309+export const sliderTrack = SliderTrack;
310+export const sliderFill = SliderFill;
311+export const sliderThumb = SliderThumb;
312+export const sliderMarks = SliderMarks;
313+
314+// Form
315+export const form = FormRoot;
316+
317+// InputOTP
318+export const inputOTP = InputOTPRoot;
319+export const inputOTPGroup = InputOTPGroup;
320+export const inputOTPSlot = InputOTPSlot;
321+export const inputOTPSeparator = InputOTPSeparator;
322+
323+// ListBox
324+export const listBox = ListBoxRoot;
325+export const listBoxItem = ListBoxItemRoot;
326+export const listBoxSection = ListBoxSectionRoot;
327+
328+// Select
329+export const select = SelectRoot;
330+export const selectTrigger = SelectTrigger;
331+export const selectValue = SelectValue;
332+export const selectIndicator = SelectIndicator;
333+export const selectPopover = SelectPopover;
334+
335+// Autocomplete
336+export const autocomplete = AutocompleteRoot;
337+export const autocompleteTrigger = AutocompleteTrigger;
338+export const autocompleteValue = AutocompleteValue;
339+export const autocompleteIndicator = AutocompleteIndicator;
340+export const autocompletePopover = AutocompletePopover;
341+export const autocompleteClearButton = AutocompleteClearButton;
342+export const autocompleteFilter = AutocompleteFilter;
343+
344+// DateField / TimeField
345+export const dateField = DateFieldRoot;
346+export const timeField = TimeFieldRoot;
347+
348+// DatePicker
349+export const datePicker = DatePickerRoot;
350+export const datePickerTrigger = DatePickerTrigger;
351+export const datePickerTriggerIndicator = DatePickerTriggerIndicator;
352+export const datePickerPopover = DatePickerPopover;
353+
354+// DateRangePicker
355+export const dateRangePicker = DateRangePickerRoot;
356+export const dateRangePickerTrigger = DateRangePickerTrigger;
357+export const dateRangePickerTriggerIndicator = DateRangePickerTriggerIndicator;
358+export const dateRangePickerRangeSeparator = DateRangePickerRangeSeparator;
359+export const dateRangePickerPopover = DateRangePickerPopover;
360+
361+// Calendar
362+export const calendar = CalendarRoot;
363+export const calendarHeader = CalendarHeader;
364+export const calendarHeading = CalendarHeading;
365+export const calendarNavButton = CalendarNavButton;
366+export const calendarGrid = CalendarGrid;
367+export const calendarGridHeader = CalendarGridHeader;
368+export const calendarGridBody = CalendarGridBody;
369+export const calendarHeaderCell = CalendarHeaderCell;
370+export const calendarCell = CalendarCell;
371+export const calendarCellIndicator = CalendarCellIndicator;
372+
373+// RangeCalendar
374+export const rangeCalendar = RangeCalendarRoot;
375+export const rangeCalendarHeader = RangeCalendarHeader;
376+export const rangeCalendarHeading = RangeCalendarHeading;
377+export const rangeCalendarNavButton = RangeCalendarNavButton;
378+export const rangeCalendarGrid = RangeCalendarGrid;
379+export const rangeCalendarCell = RangeCalendarCell;
380+
381+// Modal
382+export const modal = ModalRoot;
383+export const modalTrigger = ModalTrigger;
384+export const modalBackdrop = ModalBackdrop;
385+export const modalContainer = ModalContainer;
386+export const modalDialog = ModalDialog;
387+export const modalHeader = ModalHeader;
388+export const modalIcon = ModalIcon;
389+export const modalHeading = ModalHeading;
390+export const modalBody = ModalBody;
391+export const modalFooter = ModalFooter;
392+export const modalCloseTrigger = ModalCloseTrigger;
393+
394+// Drawer
395+export const drawer = DrawerRoot;
396+export const drawerTrigger = DrawerTrigger;
397+export const drawerBackdrop = DrawerBackdrop;
398+export const drawerContent = DrawerContent;
399+export const drawerDialog = DrawerDialog;
400+export const drawerHeader = DrawerHeader;
401+export const drawerHeading = DrawerHeading;
402+export const drawerBody = DrawerBody;
403+export const drawerFooter = DrawerFooter;
404+export const drawerHandle = DrawerHandle;
405+export const drawerCloseTrigger = DrawerCloseTrigger;
406+
407+// Popover
408+export const popover = PopoverRoot;
409+export const popoverTrigger = PopoverTrigger;
410+export const popoverContent = PopoverContent;
411+export const popoverDialog = PopoverDialog;
412+export const popoverHeading = PopoverHeading;
413+export const popoverArrow = PopoverArrow;
414+
415+// Tooltip
416+export const tooltip = TooltipRoot;
417+export const tooltipTrigger = TooltipTrigger;
418+export const tooltipContent = TooltipContent;
419+export const tooltipArrow = TooltipArrow;
420+
421+// Dropdown
422+export const dropdown = DropdownRoot;
423+export const dropdownTrigger = DropdownTrigger;
424+export const dropdownPopover = DropdownPopover;
425+export const dropdownMenu = DropdownMenu;
426+export const dropdownSection = DropdownSection;
427+export const dropdownItem = DropdownItem;
428+export const dropdownItemIndicator = DropdownItemIndicator;
429+export const dropdownSubmenuIndicator = DropdownSubmenuIndicator;
430+export const dropdownSubmenuTrigger = DropdownSubmenuTrigger;
431+
432+// Menu
433+export const menu = MenuRoot;
434+export const menuItem = MenuItemRoot;
435+export const menuItemIndicator = MenuItemIndicator;
436+export const menuItemSubmenuIndicator = MenuItemSubmenuIndicator;
437+export const menuSection = MenuSectionRoot;
438+
439+// Table
440+export const table = TableRoot;
441+export const tableScrollContainer = TableScrollContainer;
442+export const tableContent = TableContent;
443+export const tableHeader = TableHeader;
444+export const tableColumn = TableColumn;
445+export const tableBody = TableBody;
446+export const tableRow = TableRow;
447+export const tableCell = TableCell;
448+export const tableFooter = TableFooter;
449+
450+// Pagination
451+export const pagination = PaginationRoot;
452+export const paginationSummary = PaginationSummary;
453+export const paginationContent = PaginationContent;
454+export const paginationItem = PaginationItem;
455+export const paginationLink = PaginationLink;
456+export const paginationPrevious = PaginationPrevious;
457+export const paginationPreviousIcon = PaginationPreviousIcon;
458+export const paginationNext = PaginationNext;
459+export const paginationNextIcon = PaginationNextIcon;
460+export const paginationEllipsis = PaginationEllipsis;
461+
462+// Breadcrumbs
463+export const breadcrumbs = BreadcrumbsRoot;
464+export const breadcrumbsItem = BreadcrumbsItem;
465+
466+// ProgressBar
467+export const progressBar = ProgressBarRoot;
468+export const progressBarOutput = ProgressBarOutput;
469+export const progressBarTrack = ProgressBarTrack;
470+export const progressBarFill = ProgressBarFill;
471+
472+// ProgressCircle
473+export const progressCircle = ProgressCircleRoot;
474+export const progressCircleTrack = ProgressCircleTrack;
475+export const progressCircleTrackCircle = ProgressCircleTrackCircle;
476+export const progressCircleFillCircle = ProgressCircleFillCircle;
477+
478+// Alert
479+export const alert = AlertRoot;
480+export const alertIndicator = AlertIndicator;
481+export const alertContent = AlertContent;
482+export const alertTitle = AlertTitle;
483+export const alertDescription = AlertDescription;
484+
485+// Toast
486+export const toastProvider = ToastProvider;
487+export const toastContent = ToastContent;
488+export const toastIndicator = ToastIndicator;
489+export const toastTitle = ToastTitle;
490+export const toastDescription = ToastDescription;
491+export const toastActionButton = ToastActionButton;
492+export const toastCloseButton = ToastCloseButton;
src/HeroUI/Raw.purs+221
@@ -67,3 +67,224 @@ foreign import tab :: forall r. ReactComponent { | r }
6767foreign import tabIndicator :: forall r. ReactComponent { | r }
6868foreign import tabSeparator :: forall r. ReactComponent { | r }
6969foreign import tabPanel :: forall r. ReactComponent { | r }
70+
71+-- TextField / Input / Textarea
72+foreign import textField :: forall r. ReactComponent { | r }
73+foreign import input :: forall r. ReactComponent { | r }
74+foreign import textarea :: forall r. ReactComponent { | r }
75+
76+-- NumberField
77+foreign import numberField :: forall r. ReactComponent { | r }
78+foreign import numberFieldGroup :: forall r. ReactComponent { | r }
79+foreign import numberFieldInput :: forall r. ReactComponent { | r }
80+foreign import numberFieldIncrementButton :: forall r. ReactComponent { | r }
81+foreign import numberFieldDecrementButton :: forall r. ReactComponent { | r }
82+
83+-- Checkbox
84+foreign import checkbox :: forall r. ReactComponent { | r }
85+foreign import checkboxControl :: forall r. ReactComponent { | r }
86+foreign import checkboxIndicator :: forall r. ReactComponent { | r }
87+foreign import checkboxContent :: forall r. ReactComponent { | r }
88+foreign import checkboxGroup :: forall r. ReactComponent { | r }
89+
90+-- Radio
91+foreign import radio :: forall r. ReactComponent { | r }
92+foreign import radioControl :: forall r. ReactComponent { | r }
93+foreign import radioIndicator :: forall r. ReactComponent { | r }
94+foreign import radioContent :: forall r. ReactComponent { | r }
95+foreign import radioGroup :: forall r. ReactComponent { | r }
96+
97+-- Switch
98+foreign import switch_ :: forall r. ReactComponent { | r }
99+foreign import switchControl :: forall r. ReactComponent { | r }
100+foreign import switchThumb :: forall r. ReactComponent { | r }
101+foreign import switchIcon :: forall r. ReactComponent { | r }
102+foreign import switchContent :: forall r. ReactComponent { | r }
103+
104+-- Slider
105+foreign import slider :: forall r. ReactComponent { | r }
106+foreign import sliderOutput :: forall r. ReactComponent { | r }
107+foreign import sliderTrack :: forall r. ReactComponent { | r }
108+foreign import sliderFill :: forall r. ReactComponent { | r }
109+foreign import sliderThumb :: forall r. ReactComponent { | r }
110+foreign import sliderMarks :: forall r. ReactComponent { | r }
111+
112+-- Form
113+foreign import form :: forall r. ReactComponent { | r }
114+
115+-- InputOTP
116+foreign import inputOTP :: forall r. ReactComponent { | r }
117+foreign import inputOTPGroup :: forall r. ReactComponent { | r }
118+foreign import inputOTPSlot :: forall r. ReactComponent { | r }
119+foreign import inputOTPSeparator :: forall r. ReactComponent { | r }
120+
121+-- ListBox
122+foreign import listBox :: forall r. ReactComponent { | r }
123+foreign import listBoxItem :: forall r. ReactComponent { | r }
124+foreign import listBoxSection :: forall r. ReactComponent { | r }
125+
126+-- Select
127+foreign import select :: forall r. ReactComponent { | r }
128+foreign import selectTrigger :: forall r. ReactComponent { | r }
129+foreign import selectValue :: forall r. ReactComponent { | r }
130+foreign import selectIndicator :: forall r. ReactComponent { | r }
131+foreign import selectPopover :: forall r. ReactComponent { | r }
132+
133+-- Autocomplete
134+foreign import autocomplete :: forall r. ReactComponent { | r }
135+foreign import autocompleteTrigger :: forall r. ReactComponent { | r }
136+foreign import autocompleteValue :: forall r. ReactComponent { | r }
137+foreign import autocompleteIndicator :: forall r. ReactComponent { | r }
138+foreign import autocompletePopover :: forall r. ReactComponent { | r }
139+foreign import autocompleteClearButton :: forall r. ReactComponent { | r }
140+foreign import autocompleteFilter :: forall r. ReactComponent { | r }
141+
142+-- DateField / TimeField
143+foreign import dateField :: forall r. ReactComponent { | r }
144+foreign import timeField :: forall r. ReactComponent { | r }
145+
146+-- DatePicker
147+foreign import datePicker :: forall r. ReactComponent { | r }
148+foreign import datePickerTrigger :: forall r. ReactComponent { | r }
149+foreign import datePickerTriggerIndicator :: forall r. ReactComponent { | r }
150+foreign import datePickerPopover :: forall r. ReactComponent { | r }
151+
152+-- DateRangePicker
153+foreign import dateRangePicker :: forall r. ReactComponent { | r }
154+foreign import dateRangePickerTrigger :: forall r. ReactComponent { | r }
155+foreign import dateRangePickerTriggerIndicator :: forall r. ReactComponent { | r }
156+foreign import dateRangePickerRangeSeparator :: forall r. ReactComponent { | r }
157+foreign import dateRangePickerPopover :: forall r. ReactComponent { | r }
158+
159+-- Calendar
160+foreign import calendar :: forall r. ReactComponent { | r }
161+foreign import calendarHeader :: forall r. ReactComponent { | r }
162+foreign import calendarHeading :: forall r. ReactComponent { | r }
163+foreign import calendarNavButton :: forall r. ReactComponent { | r }
164+foreign import calendarGrid :: forall r. ReactComponent { | r }
165+foreign import calendarGridHeader :: forall r. ReactComponent { | r }
166+foreign import calendarGridBody :: forall r. ReactComponent { | r }
167+foreign import calendarHeaderCell :: forall r. ReactComponent { | r }
168+foreign import calendarCell :: forall r. ReactComponent { | r }
169+foreign import calendarCellIndicator :: forall r. ReactComponent { | r }
170+
171+-- RangeCalendar
172+foreign import rangeCalendar :: forall r. ReactComponent { | r }
173+foreign import rangeCalendarHeader :: forall r. ReactComponent { | r }
174+foreign import rangeCalendarHeading :: forall r. ReactComponent { | r }
175+foreign import rangeCalendarNavButton :: forall r. ReactComponent { | r }
176+foreign import rangeCalendarGrid :: forall r. ReactComponent { | r }
177+foreign import rangeCalendarCell :: forall r. ReactComponent { | r }
178+
179+-- Modal
180+foreign import modal :: forall r. ReactComponent { | r }
181+foreign import modalTrigger :: forall r. ReactComponent { | r }
182+foreign import modalBackdrop :: forall r. ReactComponent { | r }
183+foreign import modalContainer :: forall r. ReactComponent { | r }
184+foreign import modalDialog :: forall r. ReactComponent { | r }
185+foreign import modalHeader :: forall r. ReactComponent { | r }
186+foreign import modalIcon :: forall r. ReactComponent { | r }
187+foreign import modalHeading :: forall r. ReactComponent { | r }
188+foreign import modalBody :: forall r. ReactComponent { | r }
189+foreign import modalFooter :: forall r. ReactComponent { | r }
190+foreign import modalCloseTrigger :: forall r. ReactComponent { | r }
191+
192+-- Drawer
193+foreign import drawer :: forall r. ReactComponent { | r }
194+foreign import drawerTrigger :: forall r. ReactComponent { | r }
195+foreign import drawerBackdrop :: forall r. ReactComponent { | r }
196+foreign import drawerContent :: forall r. ReactComponent { | r }
197+foreign import drawerDialog :: forall r. ReactComponent { | r }
198+foreign import drawerHeader :: forall r. ReactComponent { | r }
199+foreign import drawerHeading :: forall r. ReactComponent { | r }
200+foreign import drawerBody :: forall r. ReactComponent { | r }
201+foreign import drawerFooter :: forall r. ReactComponent { | r }
202+foreign import drawerHandle :: forall r. ReactComponent { | r }
203+foreign import drawerCloseTrigger :: forall r. ReactComponent { | r }
204+
205+-- Popover
206+foreign import popover :: forall r. ReactComponent { | r }
207+foreign import popoverTrigger :: forall r. ReactComponent { | r }
208+foreign import popoverContent :: forall r. ReactComponent { | r }
209+foreign import popoverDialog :: forall r. ReactComponent { | r }
210+foreign import popoverHeading :: forall r. ReactComponent { | r }
211+foreign import popoverArrow :: forall r. ReactComponent { | r }
212+
213+-- Tooltip
214+foreign import tooltip :: forall r. ReactComponent { | r }
215+foreign import tooltipTrigger :: forall r. ReactComponent { | r }
216+foreign import tooltipContent :: forall r. ReactComponent { | r }
217+foreign import tooltipArrow :: forall r. ReactComponent { | r }
218+
219+-- Dropdown
220+foreign import dropdown :: forall r. ReactComponent { | r }
221+foreign import dropdownTrigger :: forall r. ReactComponent { | r }
222+foreign import dropdownPopover :: forall r. ReactComponent { | r }
223+foreign import dropdownMenu :: forall r. ReactComponent { | r }
224+foreign import dropdownSection :: forall r. ReactComponent { | r }
225+foreign import dropdownItem :: forall r. ReactComponent { | r }
226+foreign import dropdownItemIndicator :: forall r. ReactComponent { | r }
227+foreign import dropdownSubmenuIndicator :: forall r. ReactComponent { | r }
228+foreign import dropdownSubmenuTrigger :: forall r. ReactComponent { | r }
229+
230+-- Menu
231+foreign import menu :: forall r. ReactComponent { | r }
232+foreign import menuItem :: forall r. ReactComponent { | r }
233+foreign import menuItemIndicator :: forall r. ReactComponent { | r }
234+foreign import menuItemSubmenuIndicator :: forall r. ReactComponent { | r }
235+foreign import menuSection :: forall r. ReactComponent { | r }
236+
237+-- Table
238+foreign import table :: forall r. ReactComponent { | r }
239+foreign import tableScrollContainer :: forall r. ReactComponent { | r }
240+foreign import tableContent :: forall r. ReactComponent { | r }
241+foreign import tableHeader :: forall r. ReactComponent { | r }
242+foreign import tableColumn :: forall r. ReactComponent { | r }
243+foreign import tableBody :: forall r. ReactComponent { | r }
244+foreign import tableRow :: forall r. ReactComponent { | r }
245+foreign import tableCell :: forall r. ReactComponent { | r }
246+foreign import tableFooter :: forall r. ReactComponent { | r }
247+
248+-- Pagination
249+foreign import pagination :: forall r. ReactComponent { | r }
250+foreign import paginationSummary :: forall r. ReactComponent { | r }
251+foreign import paginationContent :: forall r. ReactComponent { | r }
252+foreign import paginationItem :: forall r. ReactComponent { | r }
253+foreign import paginationLink :: forall r. ReactComponent { | r }
254+foreign import paginationPrevious :: forall r. ReactComponent { | r }
255+foreign import paginationPreviousIcon :: forall r. ReactComponent { | r }
256+foreign import paginationNext :: forall r. ReactComponent { | r }
257+foreign import paginationNextIcon :: forall r. ReactComponent { | r }
258+foreign import paginationEllipsis :: forall r. ReactComponent { | r }
259+
260+-- Breadcrumbs
261+foreign import breadcrumbs :: forall r. ReactComponent { | r }
262+foreign import breadcrumbsItem :: forall r. ReactComponent { | r }
263+
264+-- ProgressBar
265+foreign import progressBar :: forall r. ReactComponent { | r }
266+foreign import progressBarOutput :: forall r. ReactComponent { | r }
267+foreign import progressBarTrack :: forall r. ReactComponent { | r }
268+foreign import progressBarFill :: forall r. ReactComponent { | r }
269+
270+-- ProgressCircle
271+foreign import progressCircle :: forall r. ReactComponent { | r }
272+foreign import progressCircleTrack :: forall r. ReactComponent { | r }
273+foreign import progressCircleTrackCircle :: forall r. ReactComponent { | r }
274+foreign import progressCircleFillCircle :: forall r. ReactComponent { | r }
275+
276+-- Alert
277+foreign import alert :: forall r. ReactComponent { | r }
278+foreign import alertIndicator :: forall r. ReactComponent { | r }
279+foreign import alertContent :: forall r. ReactComponent { | r }
280+foreign import alertTitle :: forall r. ReactComponent { | r }
281+foreign import alertDescription :: forall r. ReactComponent { | r }
282+
283+-- Toast
284+foreign import toastProvider :: forall r. ReactComponent { | r }
285+foreign import toastContent :: forall r. ReactComponent { | r }
286+foreign import toastIndicator :: forall r. ReactComponent { | r }
287+foreign import toastTitle :: forall r. ReactComponent { | r }
288+foreign import toastDescription :: forall r. ReactComponent { | r }
289+foreign import toastActionButton :: forall r. ReactComponent { | r }
290+foreign import toastCloseButton :: forall r. ReactComponent { | r }
src/HeroUI/Select.pursnew file+78
@@ -0,0 +1,78 @@
1+module HeroUI.Select where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Types (FieldVariant, fieldVariantToString)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+type SelectProps r =
14+ ( selectedKey :: String
15+ , defaultSelectedKey :: String
16+ , onSelectionChange :: EffectFn1 String Unit
17+ , placeholder :: String
18+ , name :: String
19+ , isDisabled :: Boolean
20+ , isRequired :: Boolean
21+ , isInvalid :: Boolean
22+ , isOpen :: Boolean
23+ , fullWidth :: Boolean
24+ , variant :: FieldVariant
25+ , className :: String
26+ | r
27+ )
28+
29+select
30+ :: forall givenProps nonDataProps kids
31+ . IsJSX kids
32+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SelectProps () }
33+ => { | givenProps }
34+ -> kids
35+ -> JSX
36+select props kids = runFn4 createElementTransformImpl { variant: fieldVariantToString } Raw.select props kids
37+
38+type SectionProps r = (className :: String | r)
39+
40+selectTrigger
41+ :: forall givenProps nonDataProps kids
42+ . IsJSX kids
43+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
44+ => { | givenProps }
45+ -> kids
46+ -> JSX
47+selectTrigger props kids = runFn4 createElementTransformImpl {} Raw.selectTrigger props kids
48+
49+type SelectValueProps r = (placeholder :: String, className :: String | r)
50+
51+selectValue
52+ :: forall givenProps nonDataProps kids
53+ . IsJSX kids
54+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SelectValueProps () }
55+ => { | givenProps }
56+ -> kids
57+ -> JSX
58+selectValue props kids = runFn4 createElementTransformImpl {} Raw.selectValue props kids
59+
60+selectIndicator
61+ :: forall givenProps nonDataProps kids
62+ . IsJSX kids
63+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
64+ => { | givenProps }
65+ -> kids
66+ -> JSX
67+selectIndicator props kids = runFn4 createElementTransformImpl {} Raw.selectIndicator props kids
68+
69+type SelectPopoverProps r = (placement :: String, className :: String | r)
70+
71+selectPopover
72+ :: forall givenProps nonDataProps kids
73+ . IsJSX kids
74+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SelectPopoverProps () }
75+ => { | givenProps }
76+ -> kids
77+ -> JSX
78+selectPopover props kids = runFn4 createElementTransformImpl {} Raw.selectPopover props kids
src/HeroUI/Slider.pursnew file+81
@@ -0,0 +1,81 @@
1+module HeroUI.Slider where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Types (Orientation, orientationToString)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+type SliderProps r =
14+ ( value :: Number
15+ , defaultValue :: Number
16+ , onChange :: EffectFn1 Number Unit
17+ , onChangeEnd :: EffectFn1 Number Unit
18+ , minValue :: Number
19+ , maxValue :: Number
20+ , step :: Number
21+ , orientation :: Orientation
22+ , isDisabled :: Boolean
23+ , className :: String
24+ | r
25+ )
26+
27+slider
28+ :: forall givenProps nonDataProps kids
29+ . IsJSX kids
30+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SliderProps () }
31+ => { | givenProps }
32+ -> kids
33+ -> JSX
34+slider props kids = runFn4 createElementTransformImpl { orientation: orientationToString } Raw.slider props kids
35+
36+type SectionProps r = (className :: String | r)
37+
38+sliderOutput
39+ :: forall givenProps nonDataProps kids
40+ . IsJSX kids
41+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
42+ => { | givenProps }
43+ -> kids
44+ -> JSX
45+sliderOutput props kids = runFn4 createElementTransformImpl {} Raw.sliderOutput props kids
46+
47+sliderTrack
48+ :: forall givenProps nonDataProps kids
49+ . IsJSX kids
50+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
51+ => { | givenProps }
52+ -> kids
53+ -> JSX
54+sliderTrack props kids = runFn4 createElementTransformImpl {} Raw.sliderTrack props kids
55+
56+sliderFill
57+ :: forall givenProps nonDataProps kids
58+ . IsJSX kids
59+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
60+ => { | givenProps }
61+ -> kids
62+ -> JSX
63+sliderFill props kids = runFn4 createElementTransformImpl {} Raw.sliderFill props kids
64+
65+sliderThumb
66+ :: forall givenProps nonDataProps kids
67+ . IsJSX kids
68+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
69+ => { | givenProps }
70+ -> kids
71+ -> JSX
72+sliderThumb props kids = runFn4 createElementTransformImpl {} Raw.sliderThumb props kids
73+
74+sliderMarks
75+ :: forall givenProps nonDataProps kids
76+ . IsJSX kids
77+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
78+ => { | givenProps }
79+ -> kids
80+ -> JSX
81+sliderMarks props kids = runFn4 createElementTransformImpl {} Raw.sliderMarks props kids
src/HeroUI/Switch.pursnew file+71
@@ -0,0 +1,71 @@
1+module HeroUI.Switch where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Types (Size, sizeToString)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+
13+type SwitchProps r =
14+ ( value :: String
15+ , isSelected :: Boolean
16+ , defaultSelected :: Boolean
17+ , onChange :: EffectFn1 Boolean Unit
18+ , isDisabled :: Boolean
19+ , isReadOnly :: Boolean
20+ , name :: String
21+ , size :: Size
22+ , className :: String
23+ | r
24+ )
25+
26+switch_
27+ :: forall givenProps nonDataProps kids
28+ . IsJSX kids
29+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SwitchProps () }
30+ => { | givenProps }
31+ -> kids
32+ -> JSX
33+switch_ props kids = runFn4 createElementTransformImpl { size: sizeToString } Raw.switch_ props kids
34+
35+type SectionProps r = (className :: String | r)
36+
37+switchControl
38+ :: forall givenProps nonDataProps kids
39+ . IsJSX kids
40+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
41+ => { | givenProps }
42+ -> kids
43+ -> JSX
44+switchControl props kids = runFn4 createElementTransformImpl {} Raw.switchControl props kids
45+
46+switchThumb
47+ :: forall givenProps nonDataProps kids
48+ . IsJSX kids
49+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
50+ => { | givenProps }
51+ -> kids
52+ -> JSX
53+switchThumb props kids = runFn4 createElementTransformImpl {} Raw.switchThumb props kids
54+
55+switchIcon
56+ :: forall givenProps nonDataProps kids
57+ . IsJSX kids
58+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
59+ => { | givenProps }
60+ -> kids
61+ -> JSX
62+switchIcon props kids = runFn4 createElementTransformImpl {} Raw.switchIcon props kids
63+
64+switchContent
65+ :: forall givenProps nonDataProps kids
66+ . IsJSX kids
67+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
68+ => { | givenProps }
69+ -> kids
70+ -> JSX
71+switchContent props kids = runFn4 createElementTransformImpl {} Raw.switchContent props kids
src/HeroUI/Table.pursnew file+93
@@ -0,0 +1,93 @@
1+module HeroUI.Table where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import Foreign (Foreign)
7+import React.Basic (JSX)
8+import Yoga.React.DOM.Internal (class IsJSX)
9+import Data.Function.Uncurried (runFn4)
10+import HeroUI.Types (SelectionMode, selectionModeToString)
11+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
12+import HeroUI.Raw as Raw
13+
14+type TableProps r = (variant :: String, className :: String | r)
15+
16+table
17+ :: forall givenProps nonDataProps kids
18+ . IsJSX kids
19+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | TableProps () }
20+ => { | givenProps }
21+ -> kids
22+ -> JSX
23+table props kids = runFn4 createElementTransformImpl {} Raw.table props kids
24+
25+-- | The react-aria table that owns selection/sort state.
26+type TableContentProps r =
27+ ( selectionMode :: SelectionMode
28+ , selectedKeys :: Array String
29+ , defaultSelectedKeys :: Array String
30+ , onSelectionChange :: EffectFn1 Foreign Unit
31+ , disabledKeys :: Array String
32+ , className :: String
33+ | r
34+ )
35+
36+tableContent
37+ :: forall givenProps nonDataProps kids
38+ . IsJSX kids
39+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | TableContentProps () }
40+ => { | givenProps }
41+ -> kids
42+ -> JSX
43+tableContent props kids = runFn4 createElementTransformImpl { selectionMode: selectionModeToString } Raw.tableContent props kids
44+
45+type TableColumnProps r =
46+ ( id :: String
47+ , isRowHeader :: Boolean
48+ , allowsSorting :: Boolean
49+ , className :: String
50+ | r
51+ )
52+
53+tableColumn
54+ :: forall givenProps nonDataProps kids
55+ . IsJSX kids
56+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | TableColumnProps () }
57+ => { | givenProps }
58+ -> kids
59+ -> JSX
60+tableColumn props kids = runFn4 createElementTransformImpl {} Raw.tableColumn props kids
61+
62+type TableRowProps r = (id :: String, className :: String | r)
63+
64+tableRow
65+ :: forall givenProps nonDataProps kids
66+ . IsJSX kids
67+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | TableRowProps () }
68+ => { | givenProps }
69+ -> kids
70+ -> JSX
71+tableRow props kids = runFn4 createElementTransformImpl {} Raw.tableRow props kids
72+
73+type SectionProps r = (className :: String | r)
74+
75+tableScrollContainer
76+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
77+tableScrollContainer props kids = runFn4 createElementTransformImpl {} Raw.tableScrollContainer props kids
78+
79+tableHeader
80+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
81+tableHeader props kids = runFn4 createElementTransformImpl {} Raw.tableHeader props kids
82+
83+tableBody
84+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
85+tableBody props kids = runFn4 createElementTransformImpl {} Raw.tableBody props kids
86+
87+tableCell
88+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
89+tableCell props kids = runFn4 createElementTransformImpl {} Raw.tableCell props kids
90+
91+tableFooter
92+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
93+tableFooter props kids = runFn4 createElementTransformImpl {} Raw.tableFooter props kids
src/HeroUI/Toast.jsnew file+10
@@ -0,0 +1,10 @@
1+import { toast } from "@heroui/react";
2+
3+export const toastSuccessImpl = (message) => toast.success(message);
4+export const toastDangerImpl = (message) => toast.danger(message);
5+export const toastInfoImpl = (message) => toast.info(message);
6+export const toastWarningImpl = (message) => toast.warning(message);
7+export const closeToastImpl = (key) => toast.close(key);
8+export const closeAllToastsImpl = () => toast.clear();
9+export const pauseAllToastsImpl = () => toast.pauseAll();
10+export const resumeAllToastsImpl = () => toast.resumeAll();
src/HeroUI/Toast.pursnew file+92
@@ -0,0 +1,92 @@
1+module HeroUI.Toast where
2+
3+import Prelude
4+
5+import Effect (Effect)
6+import Effect.Uncurried (EffectFn1, runEffectFn1)
7+import React.Basic (JSX)
8+import Yoga.React.DOM.Internal (class IsJSX)
9+import Data.Function.Uncurried (runFn4)
10+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11+import HeroUI.Raw as Raw
12+import Unsafe.Coerce (unsafeCoerce)
13+
14+-- Render the provider once near the root of the app; fire toasts imperatively.
15+type ToastProviderProps r =
16+ ( placement :: String
17+ , maxVisibleToasts :: Int
18+ , className :: String
19+ | r
20+ )
21+
22+toastProvider
23+ :: forall givenProps nonDataProps kids
24+ . IsJSX kids
25+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | ToastProviderProps () }
26+ => { | givenProps }
27+ -> kids
28+ -> JSX
29+toastProvider props kids = runFn4 createElementTransformImpl {} Raw.toastProvider props kids
30+
31+type SectionProps r = (className :: String | r)
32+
33+toastContent
34+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
35+toastContent props kids = runFn4 createElementTransformImpl {} Raw.toastContent props kids
36+
37+toastIndicator
38+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
39+toastIndicator props kids = runFn4 createElementTransformImpl {} Raw.toastIndicator props kids
40+
41+toastTitle
42+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
43+toastTitle props kids = runFn4 createElementTransformImpl {} Raw.toastTitle props kids
44+
45+toastDescription
46+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
47+toastDescription props kids = runFn4 createElementTransformImpl {} Raw.toastDescription props kids
48+
49+toastActionButton
50+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
51+toastActionButton props kids = runFn4 createElementTransformImpl {} Raw.toastActionButton props kids
52+
53+toastCloseButton
54+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
55+toastCloseButton props kids = runFn4 createElementTransformImpl {} Raw.toastCloseButton props kids
56+
57+-- | Imperative toast API. Each `toastX` fires a toast and returns its key,
58+-- | which you can later pass to `closeToast`.
59+foreign import toastSuccessImpl :: EffectFn1 JSX String
60+foreign import toastDangerImpl :: EffectFn1 JSX String
61+foreign import toastInfoImpl :: EffectFn1 JSX String
62+foreign import toastWarningImpl :: EffectFn1 JSX String
63+foreign import closeToastImpl :: EffectFn1 String Unit
64+foreign import closeAllToastsImpl :: Effect Unit
65+foreign import pauseAllToastsImpl :: Effect Unit
66+foreign import resumeAllToastsImpl :: Effect Unit
67+
68+-- | The message accepts anything renderable (`IsJSX`): a plain `String`, a
69+-- | `JSX` element, or an `Array JSX`.
70+toastSuccess :: forall msg. IsJSX msg => msg -> Effect String
71+toastSuccess msg = runEffectFn1 toastSuccessImpl (unsafeCoerce msg)
72+
73+toastDanger :: forall msg. IsJSX msg => msg -> Effect String
74+toastDanger msg = runEffectFn1 toastDangerImpl (unsafeCoerce msg)
75+
76+toastInfo :: forall msg. IsJSX msg => msg -> Effect String
77+toastInfo msg = runEffectFn1 toastInfoImpl (unsafeCoerce msg)
78+
79+toastWarning :: forall msg. IsJSX msg => msg -> Effect String
80+toastWarning msg = runEffectFn1 toastWarningImpl (unsafeCoerce msg)
81+
82+closeToast :: String -> Effect Unit
83+closeToast = runEffectFn1 closeToastImpl
84+
85+closeAllToasts :: Effect Unit
86+closeAllToasts = closeAllToastsImpl
87+
88+pauseAllToasts :: Effect Unit
89+pauseAllToasts = pauseAllToastsImpl
90+
91+resumeAllToasts :: Effect Unit
92+resumeAllToasts = resumeAllToastsImpl
src/HeroUI/Tooltip.pursnew file+56
@@ -0,0 +1,56 @@
1+module HeroUI.Tooltip where
2+
3+import Prelude
4+
5+import Effect.Uncurried (EffectFn1)
6+import React.Basic (JSX)
7+import Yoga.React.DOM.Internal (class IsJSX)
8+import Data.Function.Uncurried (runFn4)
9+import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
10+import HeroUI.Raw as Raw
11+
12+type TooltipProps r =
13+ ( isOpen :: Boolean
14+ , defaultOpen :: Boolean
15+ , onOpenChange :: EffectFn1 Boolean Unit
16+ , isDisabled :: Boolean
17+ , delay :: Number
18+ , closeDelay :: Number
19+ | r
20+ )
21+
22+tooltip
23+ :: forall givenProps nonDataProps kids
24+ . IsJSX kids
25+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | TooltipProps () }
26+ => { | givenProps }
27+ -> kids
28+ -> JSX
29+tooltip props kids = runFn4 createElementTransformImpl {} Raw.tooltip props kids
30+
31+type TooltipContentProps r =
32+ ( placement :: String
33+ , offset :: Number
34+ , showArrow :: Boolean
35+ , className :: String
36+ | r
37+ )
38+
39+tooltipContent
40+ :: forall givenProps nonDataProps kids
41+ . IsJSX kids
42+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | TooltipContentProps () }
43+ => { | givenProps }
44+ -> kids
45+ -> JSX
46+tooltipContent props kids = runFn4 createElementTransformImpl {} Raw.tooltipContent props kids
47+
48+type SectionProps r = (className :: String | r)
49+
50+tooltipTrigger
51+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
52+tooltipTrigger props kids = runFn4 createElementTransformImpl {} Raw.tooltipTrigger props kids
53+
54+tooltipArrow
55+ :: forall g n k. IsJSX k => CoerceHeroProps { | g } { | n } { | SectionProps () } => { | g } -> k -> JSX
56+tooltipArrow props kids = runFn4 createElementTransformImpl {} Raw.tooltipArrow props kids
src/HeroUI/Types.purs+24
@@ -31,6 +31,30 @@ sizeToString = case _ of
3131 Md -> "md"
3232 Lg -> "lg"
3333
34+-- | The `primary | secondary` field variant shared by HeroUI v3 form
35+-- | controls (Input, Textarea, NumberField, Select, Checkbox, ...).
36+data FieldVariant = Primary | Secondary
37+
38+derive instance Eq FieldVariant
39+derive instance Ord FieldVariant
40+
41+fieldVariantToString :: FieldVariant -> String
42+fieldVariantToString = case _ of
43+ Primary -> "primary"
44+ Secondary -> "secondary"
45+
46+-- | Selection mode for collection components (ListBox, Menu, Table, ...).
47+data SelectionMode = SelectionNone | Single | Multiple
48+
49+derive instance Eq SelectionMode
50+derive instance Ord SelectionMode
51+
52+selectionModeToString :: SelectionMode -> String
53+selectionModeToString = case _ of
54+ SelectionNone -> "none"
55+ Single -> "single"
56+ Multiple -> "multiple"
57+
3458data Orientation = Horizontal | Vertical
3559
3660derive instance Eq Orientation
test/HeroUI/Accordion/Stories.pursnew file+28
@@ -0,0 +1,28 @@
1+module HeroUI.Accordion.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Accordion as Accordion
7+import Yoga.React (component)
8+import Yoga.React.DOM.HTML (div)
9+import YogaStories.Story (story)
10+
11+item :: String -> String -> String -> JSX
12+item key heading body =
13+ Accordion.accordionItem { id: key }
14+ [ Accordion.accordionHeading {} [ Accordion.accordionTrigger {} heading ]
15+ , Accordion.accordionPanel {} [ Accordion.accordionBody {} body ]
16+ ]
17+
18+mkAccordion :: {} -> JSX
19+mkAccordion = component "AccordionStory" \(_ :: {}) -> React.do
20+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-80" }
21+ [ Accordion.accordion { variant: Accordion.Default, defaultExpandedKeys: [ "a" ] }
22+ [ item "a" "First" "First panel body."
23+ , item "b" "Second" "Second panel body."
24+ ]
25+ ]
26+
27+basic :: JSX
28+basic = story "basic" mkAccordion {}
test/HeroUI/Alert/Stories.pursnew file+40
@@ -0,0 +1,40 @@
1+module HeroUI.Alert.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Generic.Rep (class Generic)
6+import React.Basic (JSX)
7+import HeroUI.Alert as Alert
8+import HeroUI.Types as T
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import YogaStories.Controls (enum)
12+import YogaStories.Story (story)
13+
14+data Status = Default | Accent | Success | Warning | Danger
15+
16+derive instance Generic Status _
17+
18+toStatus :: Status -> T.Color
19+toStatus = case _ of
20+ Default -> T.Default
21+ Accent -> T.Accent
22+ Success -> T.Success
23+ Warning -> T.Warning
24+ Danger -> T.Danger
25+
26+mkAlert :: { title :: String, body :: String, status :: Status } -> JSX
27+mkAlert = component "AlertStory" \props -> React.do
28+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-96" }
29+ [ Alert.alert { status: toStatus props.status }
30+ [ Alert.alertIndicator {} ([] :: Array JSX)
31+ , Alert.alertContent {}
32+ [ Alert.alertTitle {} props.title
33+ , Alert.alertDescription {} props.body
34+ ]
35+ ]
36+ ]
37+
38+basic :: JSX
39+basic = story "basic" mkAlert
40+ { title: "Heads up", body: "Your changes were saved.", status: enum Success }
test/HeroUI/Autocomplete/Stories.pursnew file+38
@@ -0,0 +1,38 @@
1+module HeroUI.Autocomplete.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Autocomplete as Autocomplete
7+import HeroUI.Input as Input
8+import HeroUI.ListBox as ListBox
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import YogaStories.Story (story)
12+
13+mkAutocomplete :: { placeholder :: String } -> JSX
14+mkAutocomplete = component "AutocompleteStory" \props -> React.do
15+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-64" }
16+ [ Autocomplete.autocomplete { placeholder: props.placeholder, "aria-label": "Fruit" }
17+ [ Autocomplete.autocompleteTrigger {}
18+ [ Autocomplete.autocompleteValue { placeholder: props.placeholder } ([] :: Array JSX)
19+ , Autocomplete.autocompleteIndicator {} ([] :: Array JSX)
20+ ]
21+ , Autocomplete.autocompletePopover {}
22+ [ Autocomplete.autocompleteFilter { filter: Autocomplete.containsFilter }
23+ [ Input.textField { "aria-label": "Search fruit" }
24+ [ Input.input { placeholder: "Type to filter…" } ([] :: Array JSX) ]
25+ , ListBox.listBox {}
26+ [ ListBox.listBoxItem { id: "apple", textValue: "Apple" } "Apple"
27+ , ListBox.listBoxItem { id: "banana", textValue: "Banana" } "Banana"
28+ , ListBox.listBoxItem { id: "cherry", textValue: "Cherry" } "Cherry"
29+ , ListBox.listBoxItem { id: "date", textValue: "Date" } "Date"
30+ , ListBox.listBoxItem { id: "elderberry", textValue: "Elderberry" } "Elderberry"
31+ ]
32+ ]
33+ ]
34+ ]
35+ ]
36+
37+basic :: JSX
38+basic = story "basic" mkAutocomplete { placeholder: "Search fruit" }
test/HeroUI/Avatar/Stories.pursnew file+20
@@ -0,0 +1,20 @@
1+module HeroUI.Avatar.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Avatar as Avatar
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkAvatar :: { initials :: String } -> JSX
13+mkAvatar = component "AvatarStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
15+ [ Avatar.avatar { color: T.Accent, size: T.Md, variant: Avatar.Soft }
16+ [ Avatar.avatarFallback { color: T.Accent } props.initials ]
17+ ]
18+
19+basic :: JSX
20+basic = story "basic" mkAvatar { initials: "ME" }
test/HeroUI/Badge/Stories.pursnew file+23
@@ -0,0 +1,23 @@
1+module HeroUI.Badge.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Avatar as Avatar
7+import HeroUI.Badge as Badge
8+import HeroUI.Types as T
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import YogaStories.Story (story)
12+
13+mkBadge :: { count :: String } -> JSX
14+mkBadge = component "BadgeStory" \props -> React.do
15+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
16+ [ Badge.badge { color: T.Danger, variant: Badge.Primary, placement: Badge.TopRight, size: T.Md }
17+ [ Badge.badgeLabel {} props.count
18+ , Badge.badgeAnchor {} [ Avatar.avatar { color: T.Accent } [ Avatar.avatarFallback {} "ME" ] ]
19+ ]
20+ ]
21+
22+basic :: JSX
23+basic = story "basic" mkBadge { count: "5" }
test/HeroUI/Breadcrumbs/Stories.pursnew file+22
@@ -0,0 +1,22 @@
1+module HeroUI.Breadcrumbs.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Breadcrumbs as Breadcrumbs
7+import Yoga.React (component)
8+import Yoga.React.DOM.HTML (div)
9+import YogaStories.Story (story)
10+
11+mkBreadcrumbs :: {} -> JSX
12+mkBreadcrumbs = component "BreadcrumbsStory" \(_ :: {}) -> React.do
13+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
14+ [ Breadcrumbs.breadcrumbs {}
15+ [ Breadcrumbs.breadcrumbsItem { href: "#" } "Home"
16+ , Breadcrumbs.breadcrumbsItem { href: "#" } "Library"
17+ , Breadcrumbs.breadcrumbsItem {} "Current"
18+ ]
19+ ]
20+
21+basic :: JSX
22+basic = story "basic" mkBreadcrumbs {}
test/HeroUI/Button/Stories.pursnew file+64
@@ -0,0 +1,64 @@
1+module HeroUI.Button.Stories (primary, variants) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Generic.Rep (class Generic)
6+import React.Basic (JSX)
7+import HeroUI.Button as Btn
8+import HeroUI.Types as T
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import YogaStories.Controls (enum)
12+import YogaStories.Story (story)
13+
14+-- | v3 merges v2's `color` + `variant` into a single `variant`.
15+data Variant = Primary | Secondary | Tertiary | Ghost | Outline | Danger | DangerSoft
16+
17+derive instance Generic Variant _
18+
19+data Size = Small | Medium | Large
20+
21+derive instance Generic Size _
22+
23+toVariant :: Variant -> Btn.Variant
24+toVariant = case _ of
25+ Primary -> Btn.Primary
26+ Secondary -> Btn.Secondary
27+ Tertiary -> Btn.Tertiary
28+ Ghost -> Btn.Ghost
29+ Outline -> Btn.Outline
30+ Danger -> Btn.Danger
31+ DangerSoft -> Btn.DangerSoft
32+
33+toSize :: Size -> T.Size
34+toSize = case _ of
35+ Small -> T.Sm
36+ Medium -> T.Md
37+ Large -> T.Lg
38+
39+mkButton :: { label :: String, variant :: Variant, size :: Size, isDisabled :: Boolean } -> JSX
40+mkButton = component "ButtonStory" \props -> React.do
41+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
42+ [ Btn.button
43+ { variant: toVariant props.variant
44+ , size: toSize props.size
45+ , isDisabled: props.isDisabled
46+ }
47+ props.label
48+ ]
49+
50+primary :: JSX
51+primary = story "primary" mkButton
52+ { label: "Click me"
53+ , variant: enum Primary
54+ , size: enum Medium
55+ , isDisabled: false
56+ }
57+
58+variants :: JSX
59+variants = story "variants" mkButton
60+ { label: "Button"
61+ , variant: enum Outline
62+ , size: enum Large
63+ , isDisabled: false
64+ }
test/HeroUI/Calendar/Stories.pursnew file+17
@@ -0,0 +1,17 @@
1+module HeroUI.Calendar.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Calendar as Calendar
7+import Yoga.React (component)
8+import Yoga.React.DOM.HTML (div)
9+import YogaStories.Story (story)
10+
11+mkCalendar :: {} -> JSX
12+mkCalendar = component "CalendarStory" \(_ :: {}) -> React.do
13+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
14+ [ Calendar.calendar {} ([] :: Array JSX) ]
15+
16+basic :: JSX
17+basic = story "basic" mkCalendar {}
test/HeroUI/Card/Stories.pursnew file+36
@@ -0,0 +1,36 @@
1+module HeroUI.Card.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Generic.Rep (class Generic)
6+import React.Basic (JSX)
7+import HeroUI.Card as Card
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Controls (enum)
11+import YogaStories.Story (story)
12+
13+data Variant = Default | Secondary | Tertiary | Transparent
14+
15+derive instance Generic Variant _
16+
17+toVariant :: Variant -> Card.Variant
18+toVariant = case _ of
19+ Default -> Card.Default
20+ Secondary -> Card.Secondary
21+ Tertiary -> Card.Tertiary
22+ Transparent -> Card.Transparent
23+
24+mkCard :: { title :: String, body :: String, variant :: Variant } -> JSX
25+mkCard = component "CardStory" \props -> React.do
26+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
27+ [ Card.card { variant: toVariant props.variant, className: "max-w-sm" }
28+ [ Card.cardHeader {} [ Card.cardTitle {} props.title ]
29+ , Card.cardContent {} props.body
30+ , Card.cardFooter {} "Footer"
31+ ]
32+ ]
33+
34+basic :: JSX
35+basic = story "basic" mkCard
36+ { title: "Card title", body: "Some descriptive body text.", variant: enum Default }
test/HeroUI/Checkbox/Stories.pursnew file+18
@@ -0,0 +1,18 @@
1+module HeroUI.Checkbox.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Checkbox as Checkbox
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkCheckbox :: { label :: String, defaultSelected :: Boolean } -> JSX
13+mkCheckbox = component "CheckboxStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15+ [ Checkbox.checkbox { defaultSelected: props.defaultSelected, variant: T.Primary } props.label ]
16+
17+basic :: JSX
18+basic = story "basic" mkCheckbox { label: "Accept terms", defaultSelected: false }
test/HeroUI/Chip/Stories.pursnew file+31
@@ -0,0 +1,31 @@
1+module HeroUI.Chip.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Generic.Rep (class Generic)
6+import React.Basic (JSX)
7+import HeroUI.Chip as Chip
8+import HeroUI.Types as T
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import YogaStories.Controls (enum)
12+import YogaStories.Story (story)
13+
14+data Variant = Primary | Secondary | Tertiary | Soft
15+
16+derive instance Generic Variant _
17+
18+toVariant :: Variant -> Chip.Variant
19+toVariant = case _ of
20+ Primary -> Chip.Primary
21+ Secondary -> Chip.Secondary
22+ Tertiary -> Chip.Tertiary
23+ Soft -> Chip.Soft
24+
25+mkChip :: { label :: String, variant :: Variant } -> JSX
26+mkChip = component "ChipStory" \props -> React.do
27+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
28+ [ Chip.chip { color: T.Accent, size: T.Md, variant: toVariant props.variant } props.label ]
29+
30+basic :: JSX
31+basic = story "basic" mkChip { label: "new", variant: enum Soft }
test/HeroUI/DateField/Stories.pursnew file+17
@@ -0,0 +1,17 @@
1+module HeroUI.DateField.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.DateField as DateField
7+import Yoga.React (component)
8+import Yoga.React.DOM.HTML (div)
9+import YogaStories.Story (story)
10+
11+mkDateField :: {} -> JSX
12+mkDateField = component "DateFieldStory" \(_ :: {}) -> React.do
13+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-72" }
14+ [ DateField.dateField { granularity: DateField.Day } ([] :: Array JSX) ]
15+
16+basic :: JSX
17+basic = story "basic" mkDateField {}
test/HeroUI/DatePicker/Stories.pursnew file+21
@@ -0,0 +1,21 @@
1+module HeroUI.DatePicker.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.DatePicker as DatePicker
7+import Yoga.React (component)
8+import Yoga.React.DOM.HTML (div)
9+import YogaStories.Story (story)
10+
11+mkDatePicker :: {} -> JSX
12+mkDatePicker = component "DatePickerStory" \(_ :: {}) -> React.do
13+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-72" }
14+ [ DatePicker.datePicker {}
15+ [ DatePicker.datePickerTrigger {} "Pick a date"
16+ , DatePicker.datePickerPopover {} ([] :: Array JSX)
17+ ]
18+ ]
19+
20+basic :: JSX
21+basic = story "basic" mkDatePicker {}
test/HeroUI/Drawer/Stories.pursnew file+30
@@ -0,0 +1,30 @@
1+module HeroUI.Drawer.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Button as Btn
7+import HeroUI.Drawer as Drawer
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkDrawer :: { title :: String } -> JSX
13+mkDrawer = component "DrawerStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15+ [ Drawer.drawer {}
16+ [ Btn.button { variant: Btn.Primary } "Open drawer"
17+ , Drawer.drawerBackdrop { variant: Drawer.Blur }
18+ [ Drawer.drawerContent { placement: Drawer.Right }
19+ [ Drawer.drawerDialog {}
20+ [ Drawer.drawerHeader {} [ Drawer.drawerHeading {} props.title ]
21+ , Drawer.drawerBody {} "Drawer body content."
22+ , Drawer.drawerFooter {} [ Drawer.drawerCloseTrigger {} "Close" ]
23+ ]
24+ ]
25+ ]
26+ ]
27+ ]
28+
29+basic :: JSX
30+basic = story "basic" mkDrawer { title: "Settings" }
test/HeroUI/Dropdown/Stories.pursnew file+29
@@ -0,0 +1,29 @@
1+module HeroUI.Dropdown.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Button as Btn
7+import HeroUI.Dropdown as Dropdown
8+import HeroUI.Types as T
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import YogaStories.Story (story)
12+
13+mkDropdown :: {} -> JSX
14+mkDropdown = component "DropdownStory" \(_ :: {}) -> React.do
15+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16+ [ Dropdown.dropdown {}
17+ [ Dropdown.dropdownTrigger {} [ Btn.button { variant: Btn.Primary } "Actions" ]
18+ , Dropdown.dropdownPopover {}
19+ [ Dropdown.dropdownMenu { selectionMode: T.SelectionNone }
20+ [ Dropdown.dropdownItem { id: "new" } "New file"
21+ , Dropdown.dropdownItem { id: "copy" } "Copy link"
22+ , Dropdown.dropdownItem { id: "delete" } "Delete"
23+ ]
24+ ]
25+ ]
26+ ]
27+
28+basic :: JSX
29+basic = story "basic" mkDropdown {}
test/HeroUI/Form/Stories.pursnew file+24
@@ -0,0 +1,24 @@
1+module HeroUI.Form.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Button as Btn
7+import HeroUI.Form as Form
8+import HeroUI.Input as Input
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import YogaStories.Story (story)
12+
13+mkForm :: {} -> JSX
14+mkForm = component "FormStory" \(_ :: {}) -> React.do
15+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-72" }
16+ [ Form.form { validationBehavior: Form.Native, className: "flex flex-col gap-3" }
17+ [ Input.textField { name: "email" }
18+ [ Input.input { placeholder: "you@example.com", type: Input.InputTypeEmail } ([] :: Array JSX) ]
19+ , Btn.button { type: Btn.ButtonTypeSubmit, variant: Btn.Primary } "Submit"
20+ ]
21+ ]
22+
23+basic :: JSX
24+basic = story "basic" mkForm {}
test/HeroUI/HeroUI3Spec.pursnew file+108
@@ -0,0 +1,108 @@
1+module Test.HeroUI.HeroUI3Spec where
2+
3+import Prelude
4+
5+import Effect.Class (liftEffect)
6+import HeroUI.Button as Btn
7+import HeroUI.Card as Card
8+import HeroUI.Checkbox as Checkbox
9+import HeroUI.Chip as Chip
10+import HeroUI.Hooks as Hooks
11+import HeroUI.Input as Input
12+import HeroUI.Separator as Separator
13+import HeroUI.Spinner as Spinner
14+import HeroUI.Switch as Switch
15+import HeroUI.Toast as Toast
16+import HeroUI.Types as T
17+import React.Basic (JSX)
18+import React.Basic.Hooks as React
19+import React.TestingLibrary (cleanup, render)
20+import Test.Spec (Spec, after_, describe, it)
21+import Test.Spec.Assertions (shouldEqual)
22+import Test.Spec.Assertions.DOM (textContentShouldEqual)
23+import Yoga.React (component)
24+import Yoga.React.DOM.Internal (text)
25+
26+spec :: Spec Unit
27+spec = after_ cleanup $ describe "purescript-yoga-heroui3 (HeroUI v3)" do
28+ it "Button renders children and accepts a typed variant + type" do
29+ { findByText } <- render submitButton
30+ btn <- findByText "Submit"
31+ btn `textContentShouldEqual` "Submit"
32+
33+ it "Aria props compile and reach the DOM (no provider needed in v3)" do
34+ { findByLabelText } <- render ariaButton
35+ el <- findByLabelText "close dialog"
36+ el `textContentShouldEqual` "X"
37+
38+ it "Card renders as a compound component" do
39+ { findByText } <- render cardHost
40+ title <- findByText "Card title"
41+ title `textContentShouldEqual` "Card title"
42+
43+ it "Chip accepts color/size/variant from the shared + per-component types" do
44+ { findByText } <- render chipHost
45+ el <- findByText "new"
46+ el `textContentShouldEqual` "new"
47+
48+ it "Switch and Checkbox accept boolean state props" do
49+ _ <- render switchAndCheckbox
50+ pure unit
51+
52+ it "Spinner and Separator render" do
53+ _ <- render spinnerAndSeparator
54+ pure unit
55+
56+ it "useOverlayState exposes isOpen (replaces v2 useDisclosure)" do
57+ { findByText } <- render overlayHost
58+ initial <- findByText "closed"
59+ initial `textContentShouldEqual` "closed"
60+
61+ it "Toast imperative API (success/close/clear) is callable" do
62+ key <- liftEffect $ Toast.toastSuccess (text "saved")
63+ liftEffect $ Toast.closeToast key
64+ liftEffect Toast.closeAllToasts
65+
66+ it "InputType strings round-trip" do
67+ Input.inputTypeToString Input.InputTypeEmail `shouldEqual` "email"
68+ Input.inputTypeToString Input.InputTypeDateTimeLocal `shouldEqual` "datetime-local"
69+
70+submitButton :: JSX
71+submitButton =
72+ Btn.button { variant: Btn.Primary, type: Btn.ButtonTypeSubmit } (text "Submit")
73+
74+ariaButton :: JSX
75+ariaButton = Btn.button { "aria-label": "close dialog" } (text "X")
76+
77+cardHost :: JSX
78+cardHost =
79+ Card.card { variant: Card.Default }
80+ [ Card.cardHeader {} [ Card.cardTitle {} (text "Card title") ]
81+ , Card.cardContent {} (text "body")
82+ ]
83+
84+chipHost :: JSX
85+chipHost =
86+ Chip.chip { color: T.Accent, size: T.Sm, variant: Chip.Soft } (text "new")
87+
88+switchAndCheckbox :: JSX
89+switchAndCheckbox =
90+ Card.card {}
91+ [ Switch.switch_ { defaultSelected: true, size: T.Md } (text "on")
92+ , Checkbox.checkbox { defaultSelected: false, variant: T.Primary } (text "agree")
93+ ]
94+
95+spinnerAndSeparator :: JSX
96+spinnerAndSeparator =
97+ Card.card {}
98+ [ Spinner.spinner { color: Spinner.Accent, size: Spinner.Md } ([] :: Array JSX)
99+ , Separator.separator { orientation: T.Horizontal } ([] :: Array JSX)
100+ ]
101+
102+overlayHost :: JSX
103+overlayHost = overlayComponent {}
104+
105+overlayComponent :: {} -> JSX
106+overlayComponent = component "OverlayHost" \(_ :: {}) -> React.do
107+ state <- Hooks.useOverlayState {}
108+ pure $ text (if state.isOpen then "open" else "closed")
test/HeroUI/Input/Stories.pursnew file+31
@@ -0,0 +1,31 @@
1+module HeroUI.Input.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Generic.Rep (class Generic)
6+import React.Basic (JSX)
7+import HeroUI.Input as Input
8+import HeroUI.Types as T
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import YogaStories.Controls (enum)
12+import YogaStories.Story (story)
13+
14+data Variant = Primary | Secondary
15+
16+derive instance Generic Variant _
17+
18+toVariant :: Variant -> T.FieldVariant
19+toVariant = case _ of
20+ Primary -> T.Primary
21+ Secondary -> T.Secondary
22+
23+mkInput :: { placeholder :: String, variant :: Variant } -> JSX
24+mkInput = component "InputStory" \props -> React.do
25+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-72" }
26+ [ Input.textField { variant: toVariant props.variant }
27+ [ Input.input { placeholder: props.placeholder, type: Input.InputTypeText } ([] :: Array JSX) ]
28+ ]
29+
30+basic :: JSX
31+basic = story "basic" mkInput { placeholder: "Type here…", variant: enum Primary }
test/HeroUI/InputOTP/Stories.pursnew file+22
@@ -0,0 +1,22 @@
1+module HeroUI.InputOTP.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Array ((..))
6+import React.Basic (JSX)
7+import HeroUI.InputOTP as InputOTP
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkInputOTP :: { length :: Int } -> JSX
13+mkInputOTP = component "InputOTPStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15+ [ InputOTP.inputOTP { maxLength: props.length }
16+ [ InputOTP.inputOTPGroup {}
17+ (map (\i -> InputOTP.inputOTPSlot { index: i } ([] :: Array JSX)) (0 .. (props.length - 1)))
18+ ]
19+ ]
20+
21+basic :: JSX
22+basic = story "basic" mkInputOTP { length: 4 }
test/HeroUI/Kbd/Stories.pursnew file+21
@@ -0,0 +1,21 @@
1+module HeroUI.Kbd.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Kbd as Kbd
7+import Yoga.React (component)
8+import Yoga.React.DOM.HTML (div)
9+import YogaStories.Story (story)
10+
11+mkKbd :: { label :: String } -> JSX
12+mkKbd = component "KbdStory" \props -> React.do
13+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-2" }
14+ [ Kbd.kbd { variant: Kbd.Default }
15+ [ Kbd.kbdAbbr { keyValue: Kbd.Command } ([] :: Array JSX)
16+ , Kbd.kbdContent {} props.label
17+ ]
18+ ]
19+
20+basic :: JSX
21+basic = story "basic" mkKbd { label: "K" }
test/HeroUI/Link/Stories.pursnew file+17
@@ -0,0 +1,17 @@
1+module HeroUI.Link.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Link as Link
7+import Yoga.React (component)
8+import Yoga.React.DOM.HTML (div)
9+import YogaStories.Story (story)
10+
11+mkLink :: { label :: String, href :: String } -> JSX
12+mkLink = component "LinkStory" \props -> React.do
13+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
14+ [ Link.link { href: props.href, target: "_blank" } props.label ]
15+
16+basic :: JSX
17+basic = story "basic" mkLink { label: "Visit HeroUI", href: "https://heroui.com" }
test/HeroUI/ListBox/Stories.pursnew file+23
@@ -0,0 +1,23 @@
1+module HeroUI.ListBox.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.ListBox as ListBox
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkListBox :: {} -> JSX
13+mkListBox = component "ListBoxStory" \(_ :: {}) -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-56" }
15+ [ ListBox.listBox { selectionMode: T.Multiple, defaultSelectedKeys: [ "a" ] }
16+ [ ListBox.listBoxItem { id: "a" } "Apple"
17+ , ListBox.listBoxItem { id: "b" } "Banana"
18+ , ListBox.listBoxItem { id: "c" } "Cherry"
19+ ]
20+ ]
21+
22+basic :: JSX
23+basic = story "basic" mkListBox {}
test/HeroUI/Menu/Stories.pursnew file+23
@@ -0,0 +1,23 @@
1+module HeroUI.Menu.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Menu as Menu
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkMenu :: {} -> JSX
13+mkMenu = component "MenuStory" \(_ :: {}) -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-56" }
15+ [ Menu.menu { selectionMode: T.Single, defaultSelectedKeys: [ "profile" ] }
16+ [ Menu.menuItem { id: "profile" } "Profile"
17+ , Menu.menuItem { id: "settings" } "Settings"
18+ , Menu.menuItem { id: "logout" } "Log out"
19+ ]
20+ ]
21+
22+basic :: JSX
23+basic = story "basic" mkMenu {}
test/HeroUI/Modal/Stories.pursnew file+30
@@ -0,0 +1,30 @@
1+module HeroUI.Modal.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Button as Btn
7+import HeroUI.Modal as Modal
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkModal :: { title :: String } -> JSX
13+mkModal = component "ModalStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15+ [ Modal.modal {}
16+ [ Btn.button { variant: Btn.Primary } "Open modal"
17+ , Modal.modalBackdrop { variant: Modal.Blur }
18+ [ Modal.modalContainer { placement: Modal.PlacementCenter, size: Modal.Md }
19+ [ Modal.modalDialog {}
20+ [ Modal.modalHeader {} [ Modal.modalHeading {} props.title ]
21+ , Modal.modalBody {} "Modal body content."
22+ , Modal.modalFooter {} [ Modal.modalCloseTrigger {} "Close" ]
23+ ]
24+ ]
25+ ]
26+ ]
27+ ]
28+
29+basic :: JSX
30+basic = story "basic" mkModal { title: "Dialog" }
test/HeroUI/NumberField/Stories.pursnew file+24
@@ -0,0 +1,24 @@
1+module HeroUI.NumberField.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.NumberField as NumberField
7+import Yoga.React (component)
8+import Yoga.React.DOM.HTML (div)
9+import YogaStories.Story (story)
10+
11+mkNumberField :: { defaultValue :: Number } -> JSX
12+mkNumberField = component "NumberFieldStory" \props -> React.do
13+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-60" }
14+ [ NumberField.numberField { defaultValue: props.defaultValue, minValue: 0.0, maxValue: 100.0, step: 1.0 }
15+ [ NumberField.numberFieldGroup {}
16+ [ NumberField.numberFieldDecrementButton {} "−"
17+ , NumberField.numberFieldInput {} ([] :: Array JSX)
18+ , NumberField.numberFieldIncrementButton {} "+"
19+ ]
20+ ]
21+ ]
22+
23+basic :: JSX
24+basic = story "basic" mkNumberField { defaultValue: 5.0 }
test/HeroUI/Pagination/Stories.pursnew file+27
@@ -0,0 +1,27 @@
1+module HeroUI.Pagination.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Pagination as Pagination
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkPagination :: {} -> JSX
13+mkPagination = component "PaginationStory" \(_ :: {}) -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15+ [ Pagination.pagination { size: T.Md }
16+ [ Pagination.paginationContent {}
17+ [ Pagination.paginationPrevious {} "‹"
18+ , Pagination.paginationItem { isActive: true } "1"
19+ , Pagination.paginationItem { isActive: false } "2"
20+ , Pagination.paginationItem { isActive: false } "3"
21+ , Pagination.paginationNext {} "›"
22+ ]
23+ ]
24+ ]
25+
26+basic :: JSX
27+basic = story "basic" mkPagination {}
test/HeroUI/Popover/Stories.pursnew file+26
@@ -0,0 +1,26 @@
1+module HeroUI.Popover.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Button as Btn
7+import HeroUI.Popover as Popover
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import Yoga.React.DOM.Internal (text)
11+import YogaStories.Story (story)
12+
13+mkPopover :: {} -> JSX
14+mkPopover = component "PopoverStory" \(_ :: {}) -> React.do
15+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16+ [ Popover.popover {}
17+ [ Popover.popoverTrigger {} [ Btn.button { variant: Btn.Primary } "Open popover" ]
18+ , Popover.popoverContent { placement: "bottom", showArrow: true }
19+ [ Popover.popoverHeading {} "Heading"
20+ , text "Popover content."
21+ ]
22+ ]
23+ ]
24+
25+basic :: JSX
26+basic = story "basic" mkPopover {}
test/HeroUI/Progress/Stories.pursnew file+20
@@ -0,0 +1,20 @@
1+module HeroUI.Progress.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Progress as Progress
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkProgress :: { value :: Number } -> JSX
13+mkProgress = component "ProgressStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex flex-col gap-4 w-72" }
15+ [ Progress.progressBar { value: props.value, minValue: 0.0, maxValue: 100.0, color: T.Accent, size: T.Md } ([] :: Array JSX)
16+ , Progress.progressCircle { value: props.value, minValue: 0.0, maxValue: 100.0, color: T.Success, size: T.Lg } ([] :: Array JSX)
17+ ]
18+
19+basic :: JSX
20+basic = story "basic" mkProgress { value: 60.0 }
test/HeroUI/Radio/Stories.pursnew file+23
@@ -0,0 +1,23 @@
1+module HeroUI.Radio.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Radio as Radio
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkRadio :: { defaultValue :: String } -> JSX
13+mkRadio = component "RadioStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15+ [ Radio.radioGroup { defaultValue: props.defaultValue, orientation: T.Vertical, variant: T.Primary }
16+ [ Radio.radio { value: "a" } "Option A"
17+ , Radio.radio { value: "b" } "Option B"
18+ , Radio.radio { value: "c" } "Option C"
19+ ]
20+ ]
21+
22+basic :: JSX
23+basic = story "basic" mkRadio { defaultValue: "a" }
test/HeroUI/ScrollShadow/Stories.pursnew file+22
@@ -0,0 +1,22 @@
1+module HeroUI.ScrollShadow.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Array (replicate)
6+import React.Basic (JSX)
7+import HeroUI.ScrollShadow as ScrollShadow
8+import HeroUI.Types as T
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import Yoga.React.DOM.Internal (text)
12+import YogaStories.Story (story)
13+
14+mkScrollShadow :: {} -> JSX
15+mkScrollShadow = component "ScrollShadowStory" \(_ :: {}) -> React.do
16+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
17+ [ ScrollShadow.scrollShadow { orientation: T.Vertical, className: "h-40 w-64" }
18+ (replicate 20 (div { className: "py-1" } [ text "Scrollable line" ]))
19+ ]
20+
21+basic :: JSX
22+basic = story "basic" mkScrollShadow {}
test/HeroUI/Select/Stories.pursnew file+28
@@ -0,0 +1,28 @@
1+module HeroUI.Select.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.ListBox as ListBox
7+import HeroUI.Select as Select
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkSelect :: { placeholder :: String } -> JSX
13+mkSelect = component "SelectStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-64" }
15+ [ Select.select { placeholder: props.placeholder, defaultSelectedKey: "apple" }
16+ [ Select.selectTrigger {} [ Select.selectValue { placeholder: props.placeholder } ([] :: Array JSX) ]
17+ , Select.selectPopover {}
18+ [ ListBox.listBox {}
19+ [ ListBox.listBoxItem { id: "apple" } "Apple"
20+ , ListBox.listBoxItem { id: "banana" } "Banana"
21+ , ListBox.listBoxItem { id: "cherry" } "Cherry"
22+ ]
23+ ]
24+ ]
25+ ]
26+
27+basic :: JSX
28+basic = story "basic" mkSelect { placeholder: "Pick a fruit" }
test/HeroUI/Separator/Stories.pursnew file+22
@@ -0,0 +1,22 @@
1+module HeroUI.Separator.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Separator as Separator
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import Yoga.React.DOM.Internal (text)
11+import YogaStories.Story (story)
12+
13+mkSeparator :: {} -> JSX
14+mkSeparator = component "SeparatorStory" \(_ :: {}) -> React.do
15+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex flex-col gap-3 w-64" }
16+ [ text "Above"
17+ , Separator.separator { orientation: T.Horizontal, variant: Separator.Default } ([] :: Array JSX)
18+ , text "Below"
19+ ]
20+
21+basic :: JSX
22+basic = story "basic" mkSeparator {}
test/HeroUI/Skeleton/Stories.pursnew file+31
@@ -0,0 +1,31 @@
1+module HeroUI.Skeleton.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Generic.Rep (class Generic)
6+import React.Basic (JSX)
7+import HeroUI.Skeleton as Skeleton
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Controls (enum)
11+import YogaStories.Story (story)
12+
13+data Animation = None | Pulse | Shimmer
14+
15+derive instance Generic Animation _
16+
17+toAnimation :: Animation -> Skeleton.AnimationType
18+toAnimation = case _ of
19+ None -> Skeleton.None
20+ Pulse -> Skeleton.Pulse
21+ Shimmer -> Skeleton.Shimmer
22+
23+mkSkeleton :: { animation :: Animation } -> JSX
24+mkSkeleton = component "SkeletonStory" \props -> React.do
25+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex flex-col gap-3 w-64" }
26+ [ Skeleton.skeleton { animationType: toAnimation props.animation, className: "h-4 w-full rounded" } ([] :: Array JSX)
27+ , Skeleton.skeleton { animationType: toAnimation props.animation, className: "h-4 w-3/4 rounded" } ([] :: Array JSX)
28+ ]
29+
30+basic :: JSX
31+basic = story "basic" mkSkeleton { animation: enum Pulse }
test/HeroUI/Slider/Stories.pursnew file+24
@@ -0,0 +1,24 @@
1+module HeroUI.Slider.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Slider as Slider
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkSlider :: { defaultValue :: Number } -> JSX
13+mkSlider = component "SliderStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-72" }
15+ [ Slider.slider { defaultValue: props.defaultValue, minValue: 0.0, maxValue: 100.0, step: 1.0, orientation: T.Horizontal }
16+ [ Slider.sliderTrack {}
17+ [ Slider.sliderFill {} ([] :: Array JSX)
18+ , Slider.sliderThumb {} ([] :: Array JSX)
19+ ]
20+ ]
21+ ]
22+
23+basic :: JSX
24+basic = story "basic" mkSlider { defaultValue: 40.0 }
test/HeroUI/Spinner/Stories.pursnew file+31
@@ -0,0 +1,31 @@
1+module HeroUI.Spinner.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Generic.Rep (class Generic)
6+import React.Basic (JSX)
7+import HeroUI.Spinner as Spinner
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Controls (enum)
11+import YogaStories.Story (story)
12+
13+data Color = Accent | Current | Success | Warning | Danger
14+
15+derive instance Generic Color _
16+
17+toColor :: Color -> Spinner.Color
18+toColor = case _ of
19+ Accent -> Spinner.Accent
20+ Current -> Spinner.Current
21+ Success -> Spinner.Success
22+ Warning -> Spinner.Warning
23+ Danger -> Spinner.Danger
24+
25+mkSpinner :: { color :: Color } -> JSX
26+mkSpinner = component "SpinnerStory" \props -> React.do
27+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
28+ [ Spinner.spinner { color: toColor props.color, size: Spinner.Lg } ([] :: Array JSX) ]
29+
30+basic :: JSX
31+basic = story "basic" mkSpinner { color: enum Accent }
test/HeroUI/Switch/Stories.pursnew file+18
@@ -0,0 +1,18 @@
1+module HeroUI.Switch.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Switch as Switch
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkSwitch :: { label :: String, defaultSelected :: Boolean } -> JSX
13+mkSwitch = component "SwitchStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15+ [ Switch.switch_ { defaultSelected: props.defaultSelected, size: T.Md } props.label ]
16+
17+basic :: JSX
18+basic = story "basic" mkSwitch { label: "Wi-Fi", defaultSelected: true }
test/HeroUI/Table/Stories.pursnew file+37
@@ -0,0 +1,37 @@
1+module HeroUI.Table.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Table as Table
7+import HeroUI.Types as T
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+row :: String -> String -> String -> JSX
13+row key name role =
14+ Table.tableRow { id: key }
15+ [ Table.tableCell {} name
16+ , Table.tableCell {} role
17+ ]
18+
19+mkTable :: {} -> JSX
20+mkTable = component "TableStory" \(_ :: {}) -> React.do
21+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
22+ [ Table.table {}
23+ [ Table.tableContent { selectionMode: T.Multiple, "aria-label": "People" }
24+ [ Table.tableHeader {}
25+ [ Table.tableColumn { id: "name", isRowHeader: true } "Name"
26+ , Table.tableColumn { id: "role" } "Role"
27+ ]
28+ , Table.tableBody {}
29+ [ row "1" "Alice" "Admin"
30+ , row "2" "Bob" "User"
31+ ]
32+ ]
33+ ]
34+ ]
35+
36+basic :: JSX
37+basic = story "basic" mkTable {}
test/HeroUI/Tabs/Stories.pursnew file+36
@@ -0,0 +1,36 @@
1+module HeroUI.Tabs.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import Data.Generic.Rep (class Generic)
6+import React.Basic (JSX)
7+import HeroUI.Tabs as Tabs
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Controls (enum)
11+import YogaStories.Story (story)
12+
13+data Variant = Primary | Secondary
14+
15+derive instance Generic Variant _
16+
17+toVariant :: Variant -> Tabs.Variant
18+toVariant = case _ of
19+ Primary -> Tabs.Primary
20+ Secondary -> Tabs.Secondary
21+
22+mkTabs :: { variant :: Variant } -> JSX
23+mkTabs = component "TabsStory" \props -> React.do
24+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-96" }
25+ [ Tabs.tabs { variant: toVariant props.variant, defaultSelectedKey: "photos" }
26+ [ Tabs.tabList {}
27+ [ Tabs.tab { id: "photos" } "Photos"
28+ , Tabs.tab { id: "music" } "Music"
29+ ]
30+ , Tabs.tabPanel { id: "photos" } "Photos panel"
31+ , Tabs.tabPanel { id: "music" } "Music panel"
32+ ]
33+ ]
34+
35+basic :: JSX
36+basic = story "basic" mkTabs { variant: enum Primary }
test/HeroUI/Toast/Stories.pursnew file+22
@@ -0,0 +1,22 @@
1+module HeroUI.Toast.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import React.Basic.Events (handler_)
7+import HeroUI.Button as Btn
8+import HeroUI.Toast as Toast
9+import Yoga.React (component)
10+import Yoga.React.DOM.HTML (div)
11+import YogaStories.Story (story)
12+
13+mkToast :: { message :: String } -> JSX
14+mkToast = component "ToastStory" \props -> React.do
15+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16+ [ Toast.toastProvider { placement: "bottom-right" } ([] :: Array JSX)
17+ , Btn.button { variant: Btn.Primary, onPress: handler_ (void (Toast.toastSuccess props.message)) }
18+ "Show toast"
19+ ]
20+
21+basic :: JSX
22+basic = story "basic" mkToast { message: "Saved!" }
test/HeroUI/Tooltip/Stories.pursnew file+22
@@ -0,0 +1,22 @@
1+module HeroUI.Tooltip.Stories (basic) where
2+
3+import Prelude hiding (div)
4+
5+import React.Basic (JSX)
6+import HeroUI.Button as Btn
7+import HeroUI.Tooltip as Tooltip
8+import Yoga.React (component)
9+import Yoga.React.DOM.HTML (div)
10+import YogaStories.Story (story)
11+
12+mkTooltip :: { tip :: String } -> JSX
13+mkTooltip = component "TooltipStory" \props -> React.do
14+ pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15+ [ Tooltip.tooltip {}
16+ [ Tooltip.tooltipTrigger {} [ Btn.button { variant: Btn.Primary } "Hover me" ]
17+ , Tooltip.tooltipContent { placement: "top", showArrow: true } props.tip
18+ ]
19+ ]
20+
21+basic :: JSX
22+basic = story "basic" mkTooltip { tip: "Helpful hint" }
test/JsdomSetup.jsnew file+3
@@ -0,0 +1,3 @@
1+import "global-jsdom/register";
2+
3+export const registerJsdomImpl = () => {};
test/JsdomSetup.pursnew file+9
@@ -0,0 +1,9 @@
1+module Test.JsdomSetup where
2+
3+import Prelude
4+import Effect (Effect)
5+
6+foreign import registerJsdomImpl :: Effect Unit
7+
8+registerJsdom :: Effect Unit
9+registerJsdom = registerJsdomImpl
test/Main.pursnew file+15
@@ -0,0 +1,15 @@
1+module Test.Main where
2+
3+import Prelude
4+
5+import Effect (Effect)
6+import Effect.Aff (launchAff_)
7+import Test.HeroUI.HeroUI3Spec as HeroUI3Spec
8+import Test.JsdomSetup (registerJsdom)
9+import Test.Spec.Reporter (consoleReporter)
10+import Test.Spec.Runner (runSpec)
11+
12+main :: Effect Unit
13+main = do
14+ registerJsdom
15+ launchAff_ $ runSpec [ consoleReporter ] HeroUI3Spec.spec
yoga-stories-head.js+5
@@ -1 +1,6 @@
11import "./heroui-styles.css"
2+
3+// HeroUI v3 themes via a `dark` class on an ancestor. Overlays (popover,
4+// modal, dropdown) portal to <body>, outside any per-story wrapper, so set
5+// the class on the document root to keep portaled content on-theme.
6+document.documentElement.classList.add("dark")