git.iko.soy/rowtype-yoga/purescript-yoga-heroui3
on main help sign in
.github/workflows/deploy-stories.ymlnew file+54
since splitsnapshots
unifiedsplit
@@ -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 @@
1node_modules/
1node_modules/
2output/
2output/
3+output-es/
3.spago/
4.spago/
5+dist/
bun.lock+4−2
@@ -6,7 +6,7 @@
6 "dependencies": {
6 "dependencies": {
7 "@heroui/react": "^3.1.0",
7 "@heroui/react": "^3.1.0",
8 "@heroui/styles": "^3.1.0",
8 "@heroui/styles": "^3.1.0",
9− "yoga-stories": "0.1.5",
9+ "yoga-stories": "0.1.13",
10 },
10 },
11 "devDependencies": {
11 "devDependencies": {
12 "@tailwindcss/vite": "^4.1.18",
12 "@tailwindcss/vite": "^4.1.18",
@@ -120,6 +120,8 @@
120
120
121 "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="],
121 "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="],
122
122
123+ "@fontsource/jetbrains-mono": ["@fontsource/jetbrains-mono@5.2.8", "", {}, "sha512-6w8/SG4kqvIMu7xd7wt6x3idn1Qux3p9N62s6G3rfldOUYHpWcc2FKrqf+Vo44jRvqWj2oAtTHrZXEP23oSKwQ=="],
124+
123 "@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=="],
125 "@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=="],
124
126
125 "@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ=="],
127 "@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ=="],
@@ -538,7 +540,7 @@
538
540
539 "xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="],
541 "xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="],
540
542
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=="],
542
544
543 "@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=="],
545 "@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=="],
544
546
package.json+1−1
@@ -5,7 +5,7 @@
5 "dependencies": {
5 "dependencies": {
6 "@heroui/react": "^3.1.0",
6 "@heroui/react": "^3.1.0",
7 "@heroui/styles": "^3.1.0",
7 "@heroui/styles": "^3.1.0",
8− "yoga-stories": "0.1.5"
8+ "yoga-stories": "0.1.13"
9 },
9 },
10 "peerDependencies": {
10 "peerDependencies": {
11 "react": ">=19",
11 "react": ">=19",
spago.lock+7−3
@@ -76,6 +76,10 @@
76 "react-testing-library": {
76 "react-testing-library": {
77 "git": "https://github.com/i-am-the-slime/purescript-react-testing-library.git",
77 "git": "https://github.com/i-am-the-slime/purescript-react-testing-library.git",
78 "ref": "fd679db77337485058907ba5c6cbac3b478de342"
78 "ref": "fd679db77337485058907ba5c6cbac3b478de342"
79+ },
80+ "yoga-stories": {
81+ "git": "https://github.com/rowtype-yoga/purescript-yoga-stories.git",
82+ "ref": "v0.1.13"
79 }
83 }
80 }
84 }
81 },
85 },
@@ -1532,9 +1536,9 @@
1532 ]
1536 ]
1533 },
1537 },
1534 "yoga-stories": {
1538 "yoga-stories": {
1535− "type": "registry",
1539+ "type": "git",
1536− "version": "0.1.0",
1540+ "url": "https://github.com/rowtype-yoga/purescript-yoga-stories.git",
1537− "integrity": "sha256-8T+wUThPhXYH2MgSoe1/JjEmUnABk2A012wHliNLLcE=",
1541+ "rev": "8352da39a4d48dbb57416e1239692401b89a12fe",
1538 "dependencies": [
1542 "dependencies": [
1539 "aff",
1543 "aff",
1540 "arrays",
1544 "arrays",
spago.yaml+5
@@ -3,6 +3,11 @@ workspace:
3 react-testing-library:
3 react-testing-library:
4 git: https://github.com/i-am-the-slime/purescript-react-testing-library.git
4 git: https://github.com/i-am-the-slime/purescript-react-testing-library.git
5 ref: fd679db77337485058907ba5c6cbac3b478de342
5 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
6
11
7package:
12package:
8 name: yoga-heroui3
13 name: yoga-heroui3
src/HeroUI/Autocomplete.purs+30−2
@@ -6,7 +6,8 @@ import Effect (Effect)
6import Effect.Uncurried (EffectFn1)
6import Effect.Uncurried (EffectFn1)
7import React.Basic (JSX)
7import React.Basic (JSX)
8import Yoga.React.DOM.Internal (class IsJSX)
8import Yoga.React.DOM.Internal (class IsJSX)
9−import Data.Function.Uncurried (runFn4)
9+import Data.Function.Uncurried (Fn2, mkFn2, runFn4)
10+import Data.String (Pattern(..), contains, toLower)
10import HeroUI.Types (FieldVariant, fieldVariantToString)
11import HeroUI.Types (FieldVariant, fieldVariantToString)
11import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
12import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
12import HeroUI.Raw as Raw
13import HeroUI.Raw as Raw
@@ -51,10 +52,13 @@ autocompleteTrigger
51 -> JSX
52 -> JSX
52autocompleteTrigger props kids = runFn4 createElementTransformImpl {} Raw.autocompleteTrigger props kids
53autocompleteTrigger props kids = runFn4 createElementTransformImpl {} Raw.autocompleteTrigger props kids
53
54
55+-- | Shows the selected option's text, or `placeholder` when nothing is selected.
56+type AutocompleteValueProps r = (placeholder :: String, className :: String | r)
57+
54autocompleteValue
58autocompleteValue
55 :: forall givenProps nonDataProps kids
59 :: forall givenProps nonDataProps kids
56 . IsJSX kids
60 . IsJSX kids
57− => CoerceHeroProps { | givenProps } { | nonDataProps } { | SectionProps () }
61+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | AutocompleteValueProps () }
58 => { | givenProps }
62 => { | givenProps }
59 -> kids
63 -> kids
60 -> JSX
64 -> JSX
@@ -78,6 +82,30 @@ autocompletePopover
78 -> JSX
82 -> JSX
79autocompletePopover props kids = runFn4 createElementTransformImpl {} Raw.autocompletePopover props kids
83autocompletePopover props kids = runFn4 createElementTransformImpl {} Raw.autocompletePopover props kids
80
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+
81autocompleteClearButton
109autocompleteClearButton
82 :: forall givenProps nonDataProps kids
110 :: forall givenProps nonDataProps kids
83 . IsJSX kids
111 . IsJSX kids
src/HeroUI/Raw.js+2
@@ -87,6 +87,7 @@ import {
87 AutocompleteIndicator,
87 AutocompleteIndicator,
88 AutocompletePopover,
88 AutocompletePopover,
89 AutocompleteClearButton,
89 AutocompleteClearButton,
90+ AutocompleteFilter,
90 DateFieldRoot,
91 DateFieldRoot,
91 TimeFieldRoot,
92 TimeFieldRoot,
92 DatePickerRoot,
93 DatePickerRoot,
@@ -338,6 +339,7 @@ export const autocompleteValue = AutocompleteValue;
338export const autocompleteIndicator = AutocompleteIndicator;
339export const autocompleteIndicator = AutocompleteIndicator;
339export const autocompletePopover = AutocompletePopover;
340export const autocompletePopover = AutocompletePopover;
340export const autocompleteClearButton = AutocompleteClearButton;
341export const autocompleteClearButton = AutocompleteClearButton;
342+export const autocompleteFilter = AutocompleteFilter;
341
343
342// DateField / TimeField
344// DateField / TimeField
343export const dateField = DateFieldRoot;
345export const dateField = DateFieldRoot;
src/HeroUI/Raw.purs+1
@@ -137,6 +137,7 @@ foreign import autocompleteValue :: forall r. ReactComponent { | r }
137foreign import autocompleteIndicator :: forall r. ReactComponent { | r }
137foreign import autocompleteIndicator :: forall r. ReactComponent { | r }
138foreign import autocompletePopover :: forall r. ReactComponent { | r }
138foreign import autocompletePopover :: forall r. ReactComponent { | r }
139foreign import autocompleteClearButton :: forall r. ReactComponent { | r }
139foreign import autocompleteClearButton :: forall r. ReactComponent { | r }
140+foreign import autocompleteFilter :: forall r. ReactComponent { | r }
140
141
141-- DateField / TimeField
142-- DateField / TimeField
142foreign import dateField :: forall r. ReactComponent { | r }
143foreign import dateField :: forall r. ReactComponent { | r }
src/HeroUI/Toast.purs+11−8
@@ -9,6 +9,7 @@ import Yoga.React.DOM.Internal (class IsJSX)
9import Data.Function.Uncurried (runFn4)
9import Data.Function.Uncurried (runFn4)
10import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
10import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
11import HeroUI.Raw as Raw
11import HeroUI.Raw as Raw
12+import Unsafe.Coerce (unsafeCoerce)
12
13
13-- Render the provider once near the root of the app; fire toasts imperatively.
14-- Render the provider once near the root of the app; fire toasts imperatively.
14type ToastProviderProps r =
15type ToastProviderProps r =
@@ -64,17 +65,19 @@ foreign import closeAllToastsImpl :: Effect Unit
64foreign import pauseAllToastsImpl :: Effect Unit
65foreign import pauseAllToastsImpl :: Effect Unit
65foreign import resumeAllToastsImpl :: Effect Unit
66foreign import resumeAllToastsImpl :: Effect Unit
66
67
68+-- | The message accepts anything renderable (`IsJSX`): a plain `String`, a
69+-- | `JSX` element, or an `Array JSX`.
67−toastSuccess :: JSX -> Effect String
70+toastSuccess :: forall msg. IsJSX msg => msg -> Effect String
68−toastSuccess = runEffectFn1 toastSuccessImpl
71+toastSuccess msg = runEffectFn1 toastSuccessImpl (unsafeCoerce msg)
69
72
70−toastDanger :: JSX -> Effect String
73+toastDanger :: forall msg. IsJSX msg => msg -> Effect String
71−toastDanger = runEffectFn1 toastDangerImpl
74+toastDanger msg = runEffectFn1 toastDangerImpl (unsafeCoerce msg)
72
75
73−toastInfo :: JSX -> Effect String
76+toastInfo :: forall msg. IsJSX msg => msg -> Effect String
74−toastInfo = runEffectFn1 toastInfoImpl
77+toastInfo msg = runEffectFn1 toastInfoImpl (unsafeCoerce msg)
75
78
76−toastWarning :: JSX -> Effect String
79+toastWarning :: forall msg. IsJSX msg => msg -> Effect String
77−toastWarning = runEffectFn1 toastWarningImpl
80+toastWarning msg = runEffectFn1 toastWarningImpl (unsafeCoerce msg)
78
81
79closeToast :: String -> Effect Unit
82closeToast :: String -> Effect Unit
80closeToast = runEffectFn1 closeToastImpl
83closeToast = runEffectFn1 closeToastImpl
test/HeroUI/Accordion/Stories.purs+2−3
@@ -6,14 +6,13 @@ import React.Basic (JSX)
6import HeroUI.Accordion as Accordion
6import HeroUI.Accordion as Accordion
7import Yoga.React (component)
7import Yoga.React (component)
8import Yoga.React.DOM.HTML (div)
8import Yoga.React.DOM.HTML (div)
9−import Yoga.React.DOM.Internal (text)
10import YogaStories.Story (story)
9import YogaStories.Story (story)
11
10
12item :: String -> String -> String -> JSX
11item :: String -> String -> String -> JSX
13item key heading body =
12item key heading body =
14 Accordion.accordionItem { id: key }
13 Accordion.accordionItem { id: key }
15− [ Accordion.accordionHeading {} [ Accordion.accordionTrigger {} (text heading) ]
14+ [ Accordion.accordionHeading {} [ Accordion.accordionTrigger {} heading ]
16− , Accordion.accordionPanel {} [ Accordion.accordionBody {} (text body) ]
15+ , Accordion.accordionPanel {} [ Accordion.accordionBody {} body ]
17 ]
16 ]
18
17
19mkAccordion :: {} -> JSX
18mkAccordion :: {} -> JSX
test/HeroUI/Alert/Stories.purs+2−3
@@ -8,7 +8,6 @@ import HeroUI.Alert as Alert
8import HeroUI.Types as T
8import HeroUI.Types as T
9import Yoga.React (component)
9import Yoga.React (component)
10import Yoga.React.DOM.HTML (div)
10import Yoga.React.DOM.HTML (div)
11−import Yoga.React.DOM.Internal (text)
12import YogaStories.Controls (enum)
11import YogaStories.Controls (enum)
13import YogaStories.Story (story)
12import YogaStories.Story (story)
14
13
@@ -30,8 +29,8 @@ mkAlert = component "AlertStory" \props -> React.do
30 [ Alert.alert { status: toStatus props.status }
29 [ Alert.alert { status: toStatus props.status }
31 [ Alert.alertIndicator {} ([] :: Array JSX)
30 [ Alert.alertIndicator {} ([] :: Array JSX)
32 , Alert.alertContent {}
31 , Alert.alertContent {}
33− [ Alert.alertTitle {} (text props.title)
32+ [ Alert.alertTitle {} props.title
34− , Alert.alertDescription {} (text props.body)
33+ , Alert.alertDescription {} props.body
35 ]
34 ]
36 ]
35 ]
37 ]
36 ]
test/HeroUI/Autocomplete/Stories.purs+13−7
@@ -4,25 +4,31 @@ import Prelude hiding (div)
4
4
5import React.Basic (JSX)
5import React.Basic (JSX)
6import HeroUI.Autocomplete as Autocomplete
6import HeroUI.Autocomplete as Autocomplete
7+import HeroUI.Input as Input
7import HeroUI.ListBox as ListBox
8import HeroUI.ListBox as ListBox
8import Yoga.React (component)
9import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
10import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
11import YogaStories.Story (story)
12
12
13mkAutocomplete :: { placeholder :: String } -> JSX
13mkAutocomplete :: { placeholder :: String } -> JSX
14mkAutocomplete = component "AutocompleteStory" \props -> React.do
14mkAutocomplete = component "AutocompleteStory" \props -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-64" }
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-64" }
16− [ Autocomplete.autocomplete { placeholder: props.placeholder, defaultSelectedKey: "apple", "aria-label": "Fruit" }
16+ [ Autocomplete.autocomplete { placeholder: props.placeholder, "aria-label": "Fruit" }
17 [ Autocomplete.autocompleteTrigger {}
17 [ Autocomplete.autocompleteTrigger {}
18− [ Autocomplete.autocompleteValue {} ([] :: Array JSX)
18+ [ Autocomplete.autocompleteValue { placeholder: props.placeholder } ([] :: Array JSX)
19 , Autocomplete.autocompleteIndicator {} ([] :: Array JSX)
19 , Autocomplete.autocompleteIndicator {} ([] :: Array JSX)
20 ]
20 ]
21 , Autocomplete.autocompletePopover {}
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) ]
22− [ ListBox.listBox {}
25+ , ListBox.listBox {}
23− [ ListBox.listBoxItem { id: "apple" } (text "Apple")
26+ [ ListBox.listBoxItem { id: "apple", textValue: "Apple" } "Apple"
24− , ListBox.listBoxItem { id: "banana" } (text "Banana")
27+ , ListBox.listBoxItem { id: "banana", textValue: "Banana" } "Banana"
25− , ListBox.listBoxItem { id: "cherry" } (text "Cherry")
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+ ]
26 ]
32 ]
27 ]
33 ]
28 ]
34 ]
test/HeroUI/Avatar/Stories.purs+1−2
@@ -7,14 +7,13 @@ import HeroUI.Avatar as Avatar
7import HeroUI.Types as T
7import HeroUI.Types as T
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkAvatar :: { initials :: String } -> JSX
12mkAvatar :: { initials :: String } -> JSX
14mkAvatar = component "AvatarStory" \props -> React.do
13mkAvatar = component "AvatarStory" \props -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
16 [ Avatar.avatar { color: T.Accent, size: T.Md, variant: Avatar.Soft }
15 [ Avatar.avatar { color: T.Accent, size: T.Md, variant: Avatar.Soft }
17− [ Avatar.avatarFallback { color: T.Accent } (text props.initials) ]
16+ [ Avatar.avatarFallback { color: T.Accent } props.initials ]
18 ]
17 ]
19
18
20basic :: JSX
19basic :: JSX
test/HeroUI/Badge/Stories.purs+2−3
@@ -8,15 +8,14 @@ import HeroUI.Badge as Badge
8import HeroUI.Types as T
8import HeroUI.Types as T
9import Yoga.React (component)
9import Yoga.React (component)
10import Yoga.React.DOM.HTML (div)
10import Yoga.React.DOM.HTML (div)
11−import Yoga.React.DOM.Internal (text)
12import YogaStories.Story (story)
11import YogaStories.Story (story)
13
12
14mkBadge :: { count :: String } -> JSX
13mkBadge :: { count :: String } -> JSX
15mkBadge = component "BadgeStory" \props -> React.do
14mkBadge = component "BadgeStory" \props -> React.do
16 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
17 [ Badge.badge { color: T.Danger, variant: Badge.Primary, placement: Badge.TopRight, size: T.Md }
16 [ Badge.badge { color: T.Danger, variant: Badge.Primary, placement: Badge.TopRight, size: T.Md }
18− [ Badge.badgeLabel {} (text props.count)
17+ [ Badge.badgeLabel {} props.count
19− , Badge.badgeAnchor {} [ Avatar.avatar { color: T.Accent } [ Avatar.avatarFallback {} (text "ME") ] ]
18+ , Badge.badgeAnchor {} [ Avatar.avatar { color: T.Accent } [ Avatar.avatarFallback {} "ME" ] ]
20 ]
19 ]
21 ]
20 ]
22
21
test/HeroUI/Breadcrumbs/Stories.purs+3−4
@@ -6,16 +6,15 @@ import React.Basic (JSX)
6import HeroUI.Breadcrumbs as Breadcrumbs
6import HeroUI.Breadcrumbs as Breadcrumbs
7import Yoga.React (component)
7import Yoga.React (component)
8import Yoga.React.DOM.HTML (div)
8import Yoga.React.DOM.HTML (div)
9−import Yoga.React.DOM.Internal (text)
10import YogaStories.Story (story)
9import YogaStories.Story (story)
11
10
12mkBreadcrumbs :: {} -> JSX
11mkBreadcrumbs :: {} -> JSX
13mkBreadcrumbs = component "BreadcrumbsStory" \(_ :: {}) -> React.do
12mkBreadcrumbs = component "BreadcrumbsStory" \(_ :: {}) -> React.do
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
13 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15 [ Breadcrumbs.breadcrumbs {}
14 [ Breadcrumbs.breadcrumbs {}
16− [ Breadcrumbs.breadcrumbsItem { href: "#" } (text "Home")
15+ [ Breadcrumbs.breadcrumbsItem { href: "#" } "Home"
17− , Breadcrumbs.breadcrumbsItem { href: "#" } (text "Library")
16+ , Breadcrumbs.breadcrumbsItem { href: "#" } "Library"
18− , Breadcrumbs.breadcrumbsItem {} (text "Current")
17+ , Breadcrumbs.breadcrumbsItem {} "Current"
19 ]
18 ]
20 ]
19 ]
21
20
test/HeroUI/Button/Stories.purs+1−2
@@ -8,7 +8,6 @@ import HeroUI.Button as Btn
8import HeroUI.Types as T
8import HeroUI.Types as T
9import Yoga.React (component)
9import Yoga.React (component)
10import Yoga.React.DOM.HTML (div)
10import Yoga.React.DOM.HTML (div)
11−import Yoga.React.DOM.Internal (text)
12import YogaStories.Controls (enum)
11import YogaStories.Controls (enum)
13import YogaStories.Story (story)
12import YogaStories.Story (story)
14
13
@@ -45,7 +44,7 @@ mkButton = component "ButtonStory" \props -> React.do
45 , size: toSize props.size
44 , size: toSize props.size
46 , isDisabled: props.isDisabled
45 , isDisabled: props.isDisabled
47 }
46 }
48− (text props.label)
47+ props.label
49 ]
48 ]
50
49
51primary :: JSX
50primary :: JSX
test/HeroUI/Card/Stories.purs+3−4
@@ -7,7 +7,6 @@ import React.Basic (JSX)
7import HeroUI.Card as Card
7import HeroUI.Card as Card
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Controls (enum)
10import YogaStories.Controls (enum)
12import YogaStories.Story (story)
11import YogaStories.Story (story)
13
12
@@ -26,9 +25,9 @@ mkCard :: { title :: String, body :: String, variant :: Variant } -> JSX
26mkCard = component "CardStory" \props -> React.do
25mkCard = component "CardStory" \props -> React.do
27 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
26 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
28 [ Card.card { variant: toVariant props.variant, className: "max-w-sm" }
27 [ Card.card { variant: toVariant props.variant, className: "max-w-sm" }
29− [ Card.cardHeader {} [ Card.cardTitle {} (text props.title) ]
28+ [ Card.cardHeader {} [ Card.cardTitle {} props.title ]
30− , Card.cardContent {} (text props.body)
29+ , Card.cardContent {} props.body
31− , Card.cardFooter {} (text "Footer")
30+ , Card.cardFooter {} "Footer"
32 ]
31 ]
33 ]
32 ]
34
33
test/HeroUI/Checkbox/Stories.purs+1−2
@@ -7,13 +7,12 @@ import HeroUI.Checkbox as Checkbox
7import HeroUI.Types as T
7import HeroUI.Types as T
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkCheckbox :: { label :: String, defaultSelected :: Boolean } -> JSX
12mkCheckbox :: { label :: String, defaultSelected :: Boolean } -> JSX
14mkCheckbox = component "CheckboxStory" \props -> React.do
13mkCheckbox = component "CheckboxStory" \props -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16− [ Checkbox.checkbox { defaultSelected: props.defaultSelected, variant: T.Primary } (text props.label) ]
15+ [ Checkbox.checkbox { defaultSelected: props.defaultSelected, variant: T.Primary } props.label ]
17
16
18basic :: JSX
17basic :: JSX
19basic = story "basic" mkCheckbox { label: "Accept terms", defaultSelected: false }
18basic = story "basic" mkCheckbox { label: "Accept terms", defaultSelected: false }
test/HeroUI/Chip/Stories.purs+1−2
@@ -8,7 +8,6 @@ import HeroUI.Chip as Chip
8import HeroUI.Types as T
8import HeroUI.Types as T
9import Yoga.React (component)
9import Yoga.React (component)
10import Yoga.React.DOM.HTML (div)
10import Yoga.React.DOM.HTML (div)
11−import Yoga.React.DOM.Internal (text)
12import YogaStories.Controls (enum)
11import YogaStories.Controls (enum)
13import YogaStories.Story (story)
12import YogaStories.Story (story)
14
13
@@ -26,7 +25,7 @@ toVariant = case _ of
26mkChip :: { label :: String, variant :: Variant } -> JSX
25mkChip :: { label :: String, variant :: Variant } -> JSX
27mkChip = component "ChipStory" \props -> React.do
26mkChip = component "ChipStory" \props -> React.do
28 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
27 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
29− [ Chip.chip { color: T.Accent, size: T.Md, variant: toVariant props.variant } (text props.label) ]
28+ [ Chip.chip { color: T.Accent, size: T.Md, variant: toVariant props.variant } props.label ]
30
29
31basic :: JSX
30basic :: JSX
32basic = story "basic" mkChip { label: "new", variant: enum Soft }
31basic = story "basic" mkChip { label: "new", variant: enum Soft }
test/HeroUI/DatePicker/Stories.purs+1−2
@@ -6,14 +6,13 @@ import React.Basic (JSX)
6import HeroUI.DatePicker as DatePicker
6import HeroUI.DatePicker as DatePicker
7import Yoga.React (component)
7import Yoga.React (component)
8import Yoga.React.DOM.HTML (div)
8import Yoga.React.DOM.HTML (div)
9−import Yoga.React.DOM.Internal (text)
10import YogaStories.Story (story)
9import YogaStories.Story (story)
11
10
12mkDatePicker :: {} -> JSX
11mkDatePicker :: {} -> JSX
13mkDatePicker = component "DatePickerStory" \(_ :: {}) -> React.do
12mkDatePicker = component "DatePickerStory" \(_ :: {}) -> React.do
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-72" }
13 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-72" }
15 [ DatePicker.datePicker {}
14 [ DatePicker.datePicker {}
16− [ DatePicker.datePickerTrigger {} (text "Pick a date")
15+ [ DatePicker.datePickerTrigger {} "Pick a date"
17 , DatePicker.datePickerPopover {} ([] :: Array JSX)
16 , DatePicker.datePickerPopover {} ([] :: Array JSX)
18 ]
17 ]
19 ]
18 ]
test/HeroUI/Drawer/Stories.purs+4−5
@@ -7,20 +7,19 @@ import HeroUI.Button as Btn
7import HeroUI.Drawer as Drawer
7import HeroUI.Drawer as Drawer
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkDrawer :: { title :: String } -> JSX
12mkDrawer :: { title :: String } -> JSX
14mkDrawer = component "DrawerStory" \props -> React.do
13mkDrawer = component "DrawerStory" \props -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16 [ Drawer.drawer {}
15 [ Drawer.drawer {}
17− [ Btn.button { variant: Btn.Primary } (text "Open drawer")
16+ [ Btn.button { variant: Btn.Primary } "Open drawer"
18 , Drawer.drawerBackdrop { variant: Drawer.Blur }
17 , Drawer.drawerBackdrop { variant: Drawer.Blur }
19 [ Drawer.drawerContent { placement: Drawer.Right }
18 [ Drawer.drawerContent { placement: Drawer.Right }
20 [ Drawer.drawerDialog {}
19 [ Drawer.drawerDialog {}
21− [ Drawer.drawerHeader {} [ Drawer.drawerHeading {} (text props.title) ]
20+ [ Drawer.drawerHeader {} [ Drawer.drawerHeading {} props.title ]
22− , Drawer.drawerBody {} (text "Drawer body content.")
21+ , Drawer.drawerBody {} "Drawer body content."
23− , Drawer.drawerFooter {} [ Drawer.drawerCloseTrigger {} (text "Close") ]
22+ , Drawer.drawerFooter {} [ Drawer.drawerCloseTrigger {} "Close" ]
24 ]
23 ]
25 ]
24 ]
26 ]
25 ]
test/HeroUI/Dropdown/Stories.purs+4−5
@@ -8,19 +8,18 @@ import HeroUI.Dropdown as Dropdown
8import HeroUI.Types as T
8import HeroUI.Types as T
9import Yoga.React (component)
9import Yoga.React (component)
10import Yoga.React.DOM.HTML (div)
10import Yoga.React.DOM.HTML (div)
11−import Yoga.React.DOM.Internal (text)
12import YogaStories.Story (story)
11import YogaStories.Story (story)
13
12
14mkDropdown :: {} -> JSX
13mkDropdown :: {} -> JSX
15mkDropdown = component "DropdownStory" \(_ :: {}) -> React.do
14mkDropdown = component "DropdownStory" \(_ :: {}) -> React.do
16 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
17 [ Dropdown.dropdown {}
16 [ Dropdown.dropdown {}
18− [ Dropdown.dropdownTrigger {} [ Btn.button { variant: Btn.Primary } (text "Actions") ]
17+ [ Dropdown.dropdownTrigger {} [ Btn.button { variant: Btn.Primary } "Actions" ]
19 , Dropdown.dropdownPopover {}
18 , Dropdown.dropdownPopover {}
20 [ Dropdown.dropdownMenu { selectionMode: T.SelectionNone }
19 [ Dropdown.dropdownMenu { selectionMode: T.SelectionNone }
21− [ Dropdown.dropdownItem { id: "new" } (text "New file")
20+ [ Dropdown.dropdownItem { id: "new" } "New file"
22− , Dropdown.dropdownItem { id: "copy" } (text "Copy link")
21+ , Dropdown.dropdownItem { id: "copy" } "Copy link"
23− , Dropdown.dropdownItem { id: "delete" } (text "Delete")
22+ , Dropdown.dropdownItem { id: "delete" } "Delete"
24 ]
23 ]
25 ]
24 ]
26 ]
25 ]
test/HeroUI/Form/Stories.purs+1−2
@@ -8,7 +8,6 @@ import HeroUI.Form as Form
8import HeroUI.Input as Input
8import HeroUI.Input as Input
9import Yoga.React (component)
9import Yoga.React (component)
10import Yoga.React.DOM.HTML (div)
10import Yoga.React.DOM.HTML (div)
11−import Yoga.React.DOM.Internal (text)
12import YogaStories.Story (story)
11import YogaStories.Story (story)
13
12
14mkForm :: {} -> JSX
13mkForm :: {} -> JSX
@@ -17,7 +16,7 @@ mkForm = component "FormStory" \(_ :: {}) -> React.do
17 [ Form.form { validationBehavior: Form.Native, className: "flex flex-col gap-3" }
16 [ Form.form { validationBehavior: Form.Native, className: "flex flex-col gap-3" }
18 [ Input.textField { name: "email" }
17 [ Input.textField { name: "email" }
19 [ Input.input { placeholder: "you@example.com", type: Input.InputTypeEmail } ([] :: Array JSX) ]
18 [ Input.input { placeholder: "you@example.com", type: Input.InputTypeEmail } ([] :: Array JSX) ]
20− , Btn.button { type: Btn.ButtonTypeSubmit, variant: Btn.Primary } (text "Submit")
19+ , Btn.button { type: Btn.ButtonTypeSubmit, variant: Btn.Primary } "Submit"
21 ]
20 ]
22 ]
21 ]
23
22
test/HeroUI/Kbd/Stories.purs+1−2
@@ -6,7 +6,6 @@ import React.Basic (JSX)
6import HeroUI.Kbd as Kbd
6import HeroUI.Kbd as Kbd
7import Yoga.React (component)
7import Yoga.React (component)
8import Yoga.React.DOM.HTML (div)
8import Yoga.React.DOM.HTML (div)
9−import Yoga.React.DOM.Internal (text)
10import YogaStories.Story (story)
9import YogaStories.Story (story)
11
10
12mkKbd :: { label :: String } -> JSX
11mkKbd :: { label :: String } -> JSX
@@ -14,7 +13,7 @@ mkKbd = component "KbdStory" \props -> React.do
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-2" }
13 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-2" }
15 [ Kbd.kbd { variant: Kbd.Default }
14 [ Kbd.kbd { variant: Kbd.Default }
16 [ Kbd.kbdAbbr { keyValue: Kbd.Command } ([] :: Array JSX)
15 [ Kbd.kbdAbbr { keyValue: Kbd.Command } ([] :: Array JSX)
17− , Kbd.kbdContent {} (text props.label)
16+ , Kbd.kbdContent {} props.label
18 ]
17 ]
19 ]
18 ]
20
19
test/HeroUI/Link/Stories.purs+1−2
@@ -6,13 +6,12 @@ import React.Basic (JSX)
6import HeroUI.Link as Link
6import HeroUI.Link as Link
7import Yoga.React (component)
7import Yoga.React (component)
8import Yoga.React.DOM.HTML (div)
8import Yoga.React.DOM.HTML (div)
9−import Yoga.React.DOM.Internal (text)
10import YogaStories.Story (story)
9import YogaStories.Story (story)
11
10
12mkLink :: { label :: String, href :: String } -> JSX
11mkLink :: { label :: String, href :: String } -> JSX
13mkLink = component "LinkStory" \props -> React.do
12mkLink = component "LinkStory" \props -> React.do
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
13 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg flex items-center gap-4" }
15− [ Link.link { href: props.href, target: "_blank" } (text props.label) ]
14+ [ Link.link { href: props.href, target: "_blank" } props.label ]
16
15
17basic :: JSX
16basic :: JSX
18basic = story "basic" mkLink { label: "Visit HeroUI", href: "https://heroui.com" }
17basic = story "basic" mkLink { label: "Visit HeroUI", href: "https://heroui.com" }
test/HeroUI/ListBox/Stories.purs+3−4
@@ -7,16 +7,15 @@ import HeroUI.ListBox as ListBox
7import HeroUI.Types as T
7import HeroUI.Types as T
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkListBox :: {} -> JSX
12mkListBox :: {} -> JSX
14mkListBox = component "ListBoxStory" \(_ :: {}) -> React.do
13mkListBox = component "ListBoxStory" \(_ :: {}) -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-56" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-56" }
16 [ ListBox.listBox { selectionMode: T.Multiple, defaultSelectedKeys: [ "a" ] }
15 [ ListBox.listBox { selectionMode: T.Multiple, defaultSelectedKeys: [ "a" ] }
17− [ ListBox.listBoxItem { id: "a" } (text "Apple")
16+ [ ListBox.listBoxItem { id: "a" } "Apple"
18− , ListBox.listBoxItem { id: "b" } (text "Banana")
17+ , ListBox.listBoxItem { id: "b" } "Banana"
19− , ListBox.listBoxItem { id: "c" } (text "Cherry")
18+ , ListBox.listBoxItem { id: "c" } "Cherry"
20 ]
19 ]
21 ]
20 ]
22
21
test/HeroUI/Menu/Stories.purs+3−4
@@ -7,16 +7,15 @@ import HeroUI.Menu as Menu
7import HeroUI.Types as T
7import HeroUI.Types as T
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkMenu :: {} -> JSX
12mkMenu :: {} -> JSX
14mkMenu = component "MenuStory" \(_ :: {}) -> React.do
13mkMenu = component "MenuStory" \(_ :: {}) -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-56" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-56" }
16 [ Menu.menu { selectionMode: T.Single, defaultSelectedKeys: [ "profile" ] }
15 [ Menu.menu { selectionMode: T.Single, defaultSelectedKeys: [ "profile" ] }
17− [ Menu.menuItem { id: "profile" } (text "Profile")
16+ [ Menu.menuItem { id: "profile" } "Profile"
18− , Menu.menuItem { id: "settings" } (text "Settings")
17+ , Menu.menuItem { id: "settings" } "Settings"
19− , Menu.menuItem { id: "logout" } (text "Log out")
18+ , Menu.menuItem { id: "logout" } "Log out"
20 ]
19 ]
21 ]
20 ]
22
21
test/HeroUI/Modal/Stories.purs+4−5
@@ -7,20 +7,19 @@ import HeroUI.Button as Btn
7import HeroUI.Modal as Modal
7import HeroUI.Modal as Modal
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkModal :: { title :: String } -> JSX
12mkModal :: { title :: String } -> JSX
14mkModal = component "ModalStory" \props -> React.do
13mkModal = component "ModalStory" \props -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16 [ Modal.modal {}
15 [ Modal.modal {}
17− [ Btn.button { variant: Btn.Primary } (text "Open modal")
16+ [ Btn.button { variant: Btn.Primary } "Open modal"
18 , Modal.modalBackdrop { variant: Modal.Blur }
17 , Modal.modalBackdrop { variant: Modal.Blur }
19 [ Modal.modalContainer { placement: Modal.PlacementCenter, size: Modal.Md }
18 [ Modal.modalContainer { placement: Modal.PlacementCenter, size: Modal.Md }
20 [ Modal.modalDialog {}
19 [ Modal.modalDialog {}
21− [ Modal.modalHeader {} [ Modal.modalHeading {} (text props.title) ]
20+ [ Modal.modalHeader {} [ Modal.modalHeading {} props.title ]
22− , Modal.modalBody {} (text "Modal body content.")
21+ , Modal.modalBody {} "Modal body content."
23− , Modal.modalFooter {} [ Modal.modalCloseTrigger {} (text "Close") ]
22+ , Modal.modalFooter {} [ Modal.modalCloseTrigger {} "Close" ]
24 ]
23 ]
25 ]
24 ]
26 ]
25 ]
test/HeroUI/NumberField/Stories.purs+2−3
@@ -6,7 +6,6 @@ import React.Basic (JSX)
6import HeroUI.NumberField as NumberField
6import HeroUI.NumberField as NumberField
7import Yoga.React (component)
7import Yoga.React (component)
8import Yoga.React.DOM.HTML (div)
8import Yoga.React.DOM.HTML (div)
9−import Yoga.React.DOM.Internal (text)
10import YogaStories.Story (story)
9import YogaStories.Story (story)
11
10
12mkNumberField :: { defaultValue :: Number } -> JSX
11mkNumberField :: { defaultValue :: Number } -> JSX
@@ -14,9 +13,9 @@ mkNumberField = component "NumberFieldStory" \props -> React.do
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-60" }
13 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-60" }
15 [ NumberField.numberField { defaultValue: props.defaultValue, minValue: 0.0, maxValue: 100.0, step: 1.0 }
14 [ NumberField.numberField { defaultValue: props.defaultValue, minValue: 0.0, maxValue: 100.0, step: 1.0 }
16 [ NumberField.numberFieldGroup {}
15 [ NumberField.numberFieldGroup {}
17− [ NumberField.numberFieldDecrementButton {} (text "−")
16+ [ NumberField.numberFieldDecrementButton {} "−"
18 , NumberField.numberFieldInput {} ([] :: Array JSX)
17 , NumberField.numberFieldInput {} ([] :: Array JSX)
19− , NumberField.numberFieldIncrementButton {} (text "+")
18+ , NumberField.numberFieldIncrementButton {} "+"
20 ]
19 ]
21 ]
20 ]
22 ]
21 ]
test/HeroUI/Pagination/Stories.purs+5−6
@@ -7,7 +7,6 @@ import HeroUI.Pagination as Pagination
7import HeroUI.Types as T
7import HeroUI.Types as T
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkPagination :: {} -> JSX
12mkPagination :: {} -> JSX
@@ -15,11 +14,11 @@ mkPagination = component "PaginationStory" \(_ :: {}) -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16 [ Pagination.pagination { size: T.Md }
15 [ Pagination.pagination { size: T.Md }
17 [ Pagination.paginationContent {}
16 [ Pagination.paginationContent {}
18− [ Pagination.paginationPrevious {} (text "‹")
17+ [ Pagination.paginationPrevious {} "‹"
19− , Pagination.paginationItem { isActive: true } (text "1")
18+ , Pagination.paginationItem { isActive: true } "1"
20− , Pagination.paginationItem { isActive: false } (text "2")
19+ , Pagination.paginationItem { isActive: false } "2"
21− , Pagination.paginationItem { isActive: false } (text "3")
20+ , Pagination.paginationItem { isActive: false } "3"
22− , Pagination.paginationNext {} (text "›")
21+ , Pagination.paginationNext {} "›"
23 ]
22 ]
24 ]
23 ]
25 ]
24 ]
test/HeroUI/Popover/Stories.purs+2−2
@@ -14,9 +14,9 @@ mkPopover :: {} -> JSX
14mkPopover = component "PopoverStory" \(_ :: {}) -> React.do
14mkPopover = component "PopoverStory" \(_ :: {}) -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16 [ Popover.popover {}
16 [ Popover.popover {}
17− [ Popover.popoverTrigger {} [ Btn.button { variant: Btn.Primary } (text "Open popover") ]
17+ [ Popover.popoverTrigger {} [ Btn.button { variant: Btn.Primary } "Open popover" ]
18 , Popover.popoverContent { placement: "bottom", showArrow: true }
18 , Popover.popoverContent { placement: "bottom", showArrow: true }
19− [ Popover.popoverHeading {} (text "Heading")
19+ [ Popover.popoverHeading {} "Heading"
20 , text "Popover content."
20 , text "Popover content."
21 ]
21 ]
22 ]
22 ]
test/HeroUI/Radio/Stories.purs+3−4
@@ -7,16 +7,15 @@ import HeroUI.Radio as Radio
7import HeroUI.Types as T
7import HeroUI.Types as T
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkRadio :: { defaultValue :: String } -> JSX
12mkRadio :: { defaultValue :: String } -> JSX
14mkRadio = component "RadioStory" \props -> React.do
13mkRadio = component "RadioStory" \props -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16 [ Radio.radioGroup { defaultValue: props.defaultValue, orientation: T.Vertical, variant: T.Primary }
15 [ Radio.radioGroup { defaultValue: props.defaultValue, orientation: T.Vertical, variant: T.Primary }
17− [ Radio.radio { value: "a" } (text "Option A")
16+ [ Radio.radio { value: "a" } "Option A"
18− , Radio.radio { value: "b" } (text "Option B")
17+ , Radio.radio { value: "b" } "Option B"
19− , Radio.radio { value: "c" } (text "Option C")
18+ , Radio.radio { value: "c" } "Option C"
20 ]
19 ]
21 ]
20 ]
22
21
test/HeroUI/Select/Stories.purs+3−4
@@ -7,7 +7,6 @@ import HeroUI.ListBox as ListBox
7import HeroUI.Select as Select
7import HeroUI.Select as Select
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkSelect :: { placeholder :: String } -> JSX
12mkSelect :: { placeholder :: String } -> JSX
@@ -17,9 +16,9 @@ mkSelect = component "SelectStory" \props -> React.do
17 [ Select.selectTrigger {} [ Select.selectValue { placeholder: props.placeholder } ([] :: Array JSX) ]
16 [ Select.selectTrigger {} [ Select.selectValue { placeholder: props.placeholder } ([] :: Array JSX) ]
18 , Select.selectPopover {}
17 , Select.selectPopover {}
19 [ ListBox.listBox {}
18 [ ListBox.listBox {}
20− [ ListBox.listBoxItem { id: "apple" } (text "Apple")
19+ [ ListBox.listBoxItem { id: "apple" } "Apple"
21− , ListBox.listBoxItem { id: "banana" } (text "Banana")
20+ , ListBox.listBoxItem { id: "banana" } "Banana"
22− , ListBox.listBoxItem { id: "cherry" } (text "Cherry")
21+ , ListBox.listBoxItem { id: "cherry" } "Cherry"
23 ]
22 ]
24 ]
23 ]
25 ]
24 ]
test/HeroUI/Switch/Stories.purs+1−2
@@ -7,13 +7,12 @@ import HeroUI.Switch as Switch
7import HeroUI.Types as T
7import HeroUI.Types as T
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkSwitch :: { label :: String, defaultSelected :: Boolean } -> JSX
12mkSwitch :: { label :: String, defaultSelected :: Boolean } -> JSX
14mkSwitch = component "SwitchStory" \props -> React.do
13mkSwitch = component "SwitchStory" \props -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16− [ Switch.switch_ { defaultSelected: props.defaultSelected, size: T.Md } (text props.label) ]
15+ [ Switch.switch_ { defaultSelected: props.defaultSelected, size: T.Md } props.label ]
17
16
18basic :: JSX
17basic :: JSX
19basic = story "basic" mkSwitch { label: "Wi-Fi", defaultSelected: true }
18basic = story "basic" mkSwitch { label: "Wi-Fi", defaultSelected: true }
test/HeroUI/Table/Stories.purs+4−5
@@ -7,14 +7,13 @@ import HeroUI.Table as Table
7import HeroUI.Types as T
7import HeroUI.Types as T
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13row :: String -> String -> String -> JSX
12row :: String -> String -> String -> JSX
14row key name role =
13row key name role =
15 Table.tableRow { id: key }
14 Table.tableRow { id: key }
16− [ Table.tableCell {} (text name)
15+ [ Table.tableCell {} name
17− , Table.tableCell {} (text role)
16+ , Table.tableCell {} role
18 ]
17 ]
19
18
20mkTable :: {} -> JSX
19mkTable :: {} -> JSX
@@ -23,8 +22,8 @@ mkTable = component "TableStory" \(_ :: {}) -> React.do
23 [ Table.table {}
22 [ Table.table {}
24 [ Table.tableContent { selectionMode: T.Multiple, "aria-label": "People" }
23 [ Table.tableContent { selectionMode: T.Multiple, "aria-label": "People" }
25 [ Table.tableHeader {}
24 [ Table.tableHeader {}
26− [ Table.tableColumn { id: "name", isRowHeader: true } (text "Name")
25+ [ Table.tableColumn { id: "name", isRowHeader: true } "Name"
27− , Table.tableColumn { id: "role" } (text "Role")
26+ , Table.tableColumn { id: "role" } "Role"
28 ]
27 ]
29 , Table.tableBody {}
28 , Table.tableBody {}
30 [ row "1" "Alice" "Admin"
29 [ row "1" "Alice" "Admin"
test/HeroUI/Tabs/Stories.purs+4−5
@@ -7,7 +7,6 @@ import React.Basic (JSX)
7import HeroUI.Tabs as Tabs
7import HeroUI.Tabs as Tabs
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Controls (enum)
10import YogaStories.Controls (enum)
12import YogaStories.Story (story)
11import YogaStories.Story (story)
13
12
@@ -25,11 +24,11 @@ mkTabs = component "TabsStory" \props -> React.do
25 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-96" }
24 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg w-96" }
26 [ Tabs.tabs { variant: toVariant props.variant, defaultSelectedKey: "photos" }
25 [ Tabs.tabs { variant: toVariant props.variant, defaultSelectedKey: "photos" }
27 [ Tabs.tabList {}
26 [ Tabs.tabList {}
28− [ Tabs.tab { id: "photos" } (text "Photos")
27+ [ Tabs.tab { id: "photos" } "Photos"
29− , Tabs.tab { id: "music" } (text "Music")
28+ , Tabs.tab { id: "music" } "Music"
30 ]
29 ]
31− , Tabs.tabPanel { id: "photos" } (text "Photos panel")
30+ , Tabs.tabPanel { id: "photos" } "Photos panel"
32− , Tabs.tabPanel { id: "music" } (text "Music panel")
31+ , Tabs.tabPanel { id: "music" } "Music panel"
33 ]
32 ]
34 ]
33 ]
35
34
test/HeroUI/Toast/Stories.purs+2−3
@@ -8,15 +8,14 @@ import HeroUI.Button as Btn
8import HeroUI.Toast as Toast
8import HeroUI.Toast as Toast
9import Yoga.React (component)
9import Yoga.React (component)
10import Yoga.React.DOM.HTML (div)
10import Yoga.React.DOM.HTML (div)
11−import Yoga.React.DOM.Internal (text)
12import YogaStories.Story (story)
11import YogaStories.Story (story)
13
12
14mkToast :: { message :: String } -> JSX
13mkToast :: { message :: String } -> JSX
15mkToast = component "ToastStory" \props -> React.do
14mkToast = component "ToastStory" \props -> React.do
16 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
17 [ Toast.toastProvider { placement: "bottom-right" } ([] :: Array JSX)
16 [ Toast.toastProvider { placement: "bottom-right" } ([] :: Array JSX)
18− , Btn.button { variant: Btn.Primary, onPress: handler_ (void (Toast.toastSuccess (text props.message))) }
17+ , Btn.button { variant: Btn.Primary, onPress: handler_ (void (Toast.toastSuccess props.message)) }
19− (text "Show toast")
18+ "Show toast"
20 ]
19 ]
21
20
22basic :: JSX
21basic :: JSX
test/HeroUI/Tooltip/Stories.purs+2−3
@@ -7,15 +7,14 @@ import HeroUI.Button as Btn
7import HeroUI.Tooltip as Tooltip
7import HeroUI.Tooltip as Tooltip
8import Yoga.React (component)
8import Yoga.React (component)
9import Yoga.React.DOM.HTML (div)
9import Yoga.React.DOM.HTML (div)
10−import Yoga.React.DOM.Internal (text)
11import YogaStories.Story (story)
10import YogaStories.Story (story)
12
11
13mkTooltip :: { tip :: String } -> JSX
12mkTooltip :: { tip :: String } -> JSX
14mkTooltip = component "TooltipStory" \props -> React.do
13mkTooltip = component "TooltipStory" \props -> React.do
15 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
14 pure $ div { className: "dark bg-background text-foreground p-6 rounded-lg" }
16 [ Tooltip.tooltip {}
15 [ Tooltip.tooltip {}
17− [ Tooltip.tooltipTrigger {} [ Btn.button { variant: Btn.Primary } (text "Hover me") ]
16+ [ Tooltip.tooltipTrigger {} [ Btn.button { variant: Btn.Primary } "Hover me" ]
18− , Tooltip.tooltipContent { placement: "top", showArrow: true } (text props.tip)
17+ , Tooltip.tooltipContent { placement: "top", showArrow: true } props.tip
19 ]
18 ]
20 ]
19 ]
21
20
yoga-stories-head.js+5
@@ -1 +1,6 @@
1import "./heroui-styles.css"
1import "./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")