@colisweb/rescript-toolkit 2.67.0 → 2.67.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +3 -2
- package/.yarn/cache/boolbase-npm-1.0.0-965fe9af6d-3e25c80ef6.zip +0 -0
- package/.yarn/cache/camelcase-npm-3.0.0-0c65af0c7f-ae4fe1c17c.zip +0 -0
- package/.yarn/cache/comma-separated-tokens-npm-1.0.8-00dbbf3418-0adcb07174.zip +0 -0
- package/.yarn/cache/css-selector-parser-npm-1.4.1-b8c642c4c5-31948754e5.zip +0 -0
- package/.yarn/cache/fault-npm-2.0.1-c462630f58-c9b30f47d9.zip +0 -0
- package/.yarn/cache/format-npm-0.2.2-679f3acc64-646a60e133.zip +0 -0
- package/.yarn/cache/github-slugger-npm-2.0.0-3afba76e6c-250375cde2.zip +0 -0
- package/.yarn/cache/hast-util-has-property-npm-1.0.4-a09b607810-23025cee66.zip +0 -0
- package/.yarn/cache/hast-util-has-property-npm-2.0.1-aa6919669c-cc909b7e29.zip +0 -0
- package/.yarn/cache/hast-util-heading-rank-npm-2.1.1-0d71da5801-a49233e9ac.zip +0 -0
- package/.yarn/cache/hast-util-is-element-npm-1.1.0-be10e62fa7-30fad3f65e.zip +0 -0
- package/.yarn/cache/hast-util-is-element-npm-2.1.3-3051d610ff-9d988f6839.zip +0 -0
- package/.yarn/cache/hast-util-select-npm-1.0.1-115974f390-9cdb20850f.zip +0 -0
- package/.yarn/cache/hast-util-to-string-npm-2.0.0-c6108aa2b8-0c087f8dee.zip +0 -0
- package/.yarn/cache/hast-util-to-text-npm-3.1.2-922eb1f623-d17cf3344c.zip +0 -0
- package/.yarn/cache/hast-util-whitespace-npm-1.0.4-43bb1ff3d0-b7f4a1942b.zip +0 -0
- package/.yarn/cache/{husky-npm-8.0.2-46c70b41ed-e101656fcb.zip → husky-npm-8.0.3-b0b59c5127-837bc7e441.zip} +0 -0
- package/.yarn/cache/lowlight-npm-2.8.0-c65abb6cac-c45a91e715.zip +0 -0
- package/.yarn/cache/not-npm-0.1.0-a1712708cd-8043bb53bc.zip +0 -0
- package/.yarn/cache/nth-check-npm-1.0.2-3f6d0d22eb-59e115fdd7.zip +0 -0
- package/.yarn/cache/property-information-npm-3.2.0-ae434c241d-ed2614520d.zip +0 -0
- package/.yarn/cache/rehype-add-classes-npm-1.0.0-ddf6b4e74d-25c0e2dbf5.zip +0 -0
- package/.yarn/cache/rehype-autolink-headings-npm-6.1.1-fe8058cc11-60782fb2e5.zip +0 -0
- package/.yarn/cache/rehype-highlight-npm-6.0.0-5179257139-5a70e7ad45.zip +0 -0
- package/.yarn/cache/rehype-slug-npm-5.1.0-ae08840ba8-2a7c17fd74.zip +0 -0
- package/.yarn/cache/space-separated-tokens-npm-1.1.5-2352c83473-8ef68f1cfa.zip +0 -0
- package/.yarn/cache/unist-util-find-after-npm-4.0.0-11b3b7fb4f-8381ef0bad.zip +0 -0
- package/.yarn/cache/zwitch-npm-1.0.5-5911cef6ce-28a1bebaca.zip +0 -0
- package/.yarn/install-state.gz +0 -0
- package/package.json +8 -5
- package/playground/{App.res → PlaygroundApp.res} +14 -7
- package/playground/PlaygroundComponents.res +109 -0
- package/playground/PlaygroundLocales.res +1 -0
- package/playground/PlaygroundRouter.res +23 -0
- package/playground/{CodeBlock.res → Playground_CodeBlock.res} +12 -16
- package/playground/{stories/IntroductionColors.stories.mdx → design/DesignSystem_Colors.mdx} +0 -0
- package/playground/{stories/IntroductionFonts.stories.mdx → design/DesignSystem_Fonts.mdx} +0 -0
- package/playground/{stories/IntroductionMediaQueries.stories.mdx → design/DesignSystem_MediaQueries.mdx} +0 -0
- package/playground/design/Playground_DesignSystem.res +12 -0
- package/playground/{stories/TailwindConfigBreakpoints.js → design/TailwindConfigBreakpoints.jsx} +1 -1
- package/playground/{stories/TailwindConfigColorsPreview.js → design/TailwindConfigColorsPreview.jsx} +1 -1
- package/playground/{stories/TailwindConfigFontsPreview.js → design/TailwindConfigFontsPreview.jsx} +1 -1
- package/playground/docs/ApiDecoding.mdx +70 -0
- package/playground/docs/Form.mdx +109 -0
- package/playground/docs/Identifiers.mdx +38 -0
- package/playground/{Doc.res → docs/Playground_Docs.res} +8 -8
- package/playground/docs/Primitives.mdx +53 -0
- package/playground/docs/Request.mdx +281 -0
- package/playground/docs/Router.mdx +43 -0
- package/playground/docs/Setup.mdx +58 -0
- package/playground/docs/Unleash.mdx +53 -0
- package/playground/main.jsx +1 -1
- package/src/intl/Toolkit__Intl.res +5 -9
- package/src/intl/Toolkit__Intl.resi +1 -0
- package/src/logger/Toolkit__BrowserLogger.res +15 -15
- package/src/tailwind/tailwind.config.cjs +3 -5
- package/vite.config.js +43 -1
- package/.yarn/cache/cosmiconfig-npm-7.0.0-b9d0d7d156-6801feaa02.zip +0 -0
- package/.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip +0 -0
- package/.yarn/cache/klona-npm-2.0.4-6bc4e7cd86-abc6690882.zip +0 -0
- package/.yarn/cache/postcss-loader-npm-4.2.0-f01fec2503-c45ec1ca1b.zip +0 -0
- package/.yarn/cache/semver-npm-7.3.4-4c3baf0ead-96451bfd7c.zip +0 -0
- package/playground/Playground_Component.res +0 -33
- package/playground/Playground_ComponentDetails.res +0 -25
- package/playground/Playground_ComponentsList.res +0 -43
package/.gitlab-ci.yml
CHANGED
|
@@ -47,7 +47,7 @@ publish rescript-toolkit:
|
|
|
47
47
|
# -----------------------------------------------
|
|
48
48
|
pages:
|
|
49
49
|
image: node:16-bullseye
|
|
50
|
-
extends: .rules-only-for-
|
|
50
|
+
extends: .rules-only-for-master
|
|
51
51
|
tags:
|
|
52
52
|
- aws
|
|
53
53
|
stage: deploy
|
|
@@ -55,9 +55,10 @@ pages:
|
|
|
55
55
|
- export NPM_TOKEN=${NPM_TOKEN:-undefined}
|
|
56
56
|
- yarn
|
|
57
57
|
- yarn build
|
|
58
|
+
- cp -a dist/. public/
|
|
58
59
|
artifacts:
|
|
59
60
|
paths:
|
|
60
|
-
-
|
|
61
|
+
- public
|
|
61
62
|
cache:
|
|
62
63
|
key: "yarn-$CI_COMMIT_REF_SLUG"
|
|
63
64
|
paths:
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/.yarn/install-state.gz
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colisweb/rescript-toolkit",
|
|
3
|
-
"version": "2.67.
|
|
3
|
+
"version": "2.67.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"clean": "rescript clean",
|
|
@@ -59,8 +59,7 @@
|
|
|
59
59
|
"lenses-ppx": "6.1.10",
|
|
60
60
|
"list-selectors": "2.0.1",
|
|
61
61
|
"lodash": "4.17.21",
|
|
62
|
-
"postcss": "8.4.
|
|
63
|
-
"postcss-loader": "4.2.0",
|
|
62
|
+
"postcss": "8.4.21",
|
|
64
63
|
"postcss-preset-env": "7.8.3",
|
|
65
64
|
"prismjs": "1.29.0",
|
|
66
65
|
"react": "18.2.0",
|
|
@@ -95,12 +94,16 @@
|
|
|
95
94
|
"@vitejs/plugin-react": "^3.0.0",
|
|
96
95
|
"babel-loader": "8.2.5",
|
|
97
96
|
"highlight.js": "11.7.0",
|
|
98
|
-
"husky": "8.0.
|
|
97
|
+
"husky": "8.0.3",
|
|
99
98
|
"is-ci": "3.0.1",
|
|
100
99
|
"raw-loader": "4.0.2",
|
|
101
100
|
"react-is": "18.2.0",
|
|
101
|
+
"rehype-add-classes": "^1.0.0",
|
|
102
|
+
"rehype-autolink-headings": "^6.1.1",
|
|
103
|
+
"rehype-highlight": "^6.0.0",
|
|
104
|
+
"rehype-slug": "^5.1.0",
|
|
102
105
|
"sass": "1.56.1",
|
|
103
|
-
"vite": "
|
|
106
|
+
"vite": "4.0.4"
|
|
104
107
|
},
|
|
105
108
|
"packageManager": "yarn@3.3.1"
|
|
106
109
|
}
|
|
@@ -72,18 +72,25 @@ let make = () => {
|
|
|
72
72
|
<PlaygroundRouter.Breadcrumb />
|
|
73
73
|
<div className="p-4">
|
|
74
74
|
{switch currentRoute {
|
|
75
|
-
| Home => <
|
|
75
|
+
| Home => <Playground_Docs.Setup />
|
|
76
76
|
| Docs(doc) =>
|
|
77
77
|
switch doc {
|
|
78
|
-
| Identifiers => <
|
|
79
|
-
| ApiDecoding => <
|
|
80
|
-
| Form => <
|
|
81
|
-
| Requests => <
|
|
78
|
+
| Identifiers => <Playground_Docs.Identifiers />
|
|
79
|
+
| ApiDecoding => <Playground_Docs.ApiDecoding />
|
|
80
|
+
| Form => <Playground_Docs.Form />
|
|
81
|
+
| Requests => <Playground_Docs.Requests />
|
|
82
82
|
}
|
|
83
|
+
| DesignSystem(_route) => React.null
|
|
84
|
+
// switch route {
|
|
85
|
+
// | Fonts => <Playground_DesignSystem.Fonts />
|
|
86
|
+
// | Colors => <Playground_DesignSystem.Colors />
|
|
87
|
+
// | MediaQueries => <Playground_DesignSystem.MediaQueries />
|
|
88
|
+
// }
|
|
89
|
+
|
|
83
90
|
| Components(component) =>
|
|
84
91
|
switch component {
|
|
85
|
-
| List => <
|
|
86
|
-
| Details(component) => <
|
|
92
|
+
| List => <PlaygroundComponents.List />
|
|
93
|
+
| Details(component) => <PlaygroundComponents.Details component />
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
| NotFound => "NotFound"->React.string
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
module type Config = {
|
|
2
|
+
let resi: string
|
|
3
|
+
let codeExample: string
|
|
4
|
+
@react.component
|
|
5
|
+
let make: unit => React.element
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
let components: array<(string, module(Config))> = [
|
|
9
|
+
("card", module(Playground_Card)),
|
|
10
|
+
("switch", module(Playground_Switch)),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
module List = {
|
|
14
|
+
module ComponentLink = {
|
|
15
|
+
@react.component
|
|
16
|
+
let make = (~name) => {
|
|
17
|
+
<PlaygroundRouter.Link
|
|
18
|
+
route={Components(Details(name))}
|
|
19
|
+
className="p-4 rounded-lg border bg-white hover:border-primary-700 w-64">
|
|
20
|
+
<strong className="capitalize"> {name->React.string} </strong>
|
|
21
|
+
</PlaygroundRouter.Link>
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@react.component
|
|
26
|
+
let make = () => {
|
|
27
|
+
let (search, setSearch) = React.useState(() => "")
|
|
28
|
+
|
|
29
|
+
<div>
|
|
30
|
+
<h1 className="text-4xl font-bold font-display mb-4 flex flex-row gap-4 items-center">
|
|
31
|
+
{"Components"->React.string}
|
|
32
|
+
<input
|
|
33
|
+
type_="search"
|
|
34
|
+
placeholder="Search"
|
|
35
|
+
value={search}
|
|
36
|
+
onChange={event => {
|
|
37
|
+
let target = event->ReactEvent.Form.target
|
|
38
|
+
|
|
39
|
+
setSearch(_ => target["value"])
|
|
40
|
+
}}
|
|
41
|
+
className="bg-white text-sm font-sans px-4 font-normal rounded-md border border-neutral-300 focus:border-primary-700 h-10 w-60"
|
|
42
|
+
/>
|
|
43
|
+
</h1>
|
|
44
|
+
<div className="flex flex-row flex-wrap gap-4">
|
|
45
|
+
{components
|
|
46
|
+
->Array.keep(((name, _)) => name->Js.String2.toLowerCase->Js.String2.includes(search))
|
|
47
|
+
->Array.map(((name, _)) => <ComponentLink name key={name} />)
|
|
48
|
+
->React.array}
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module Details = {
|
|
55
|
+
module Component = {
|
|
56
|
+
@react.component
|
|
57
|
+
let make = (~component: module(Config)) => {
|
|
58
|
+
let module(Config) = component
|
|
59
|
+
<div>
|
|
60
|
+
<ReachUi.Tabs>
|
|
61
|
+
<ReachUi.TabList className="mb-4">
|
|
62
|
+
<ReachUi.Tab> {"Example"->React.string} </ReachUi.Tab>
|
|
63
|
+
<ReachUi.Tab> {"Code example"->React.string} </ReachUi.Tab>
|
|
64
|
+
<ReachUi.Tab> {"API"->React.string} </ReachUi.Tab>
|
|
65
|
+
</ReachUi.TabList>
|
|
66
|
+
<ReachUi.TabPanels>
|
|
67
|
+
<ReachUi.TabPanel>
|
|
68
|
+
<Config />
|
|
69
|
+
</ReachUi.TabPanel>
|
|
70
|
+
<ReachUi.TabPanel>
|
|
71
|
+
<Playground_CodeBlock code={Config.codeExample} />
|
|
72
|
+
</ReachUi.TabPanel>
|
|
73
|
+
<ReachUi.TabPanel>
|
|
74
|
+
<Playground_CodeBlock code={Config.resi} />
|
|
75
|
+
</ReachUi.TabPanel>
|
|
76
|
+
</ReachUi.TabPanels>
|
|
77
|
+
</ReachUi.Tabs>
|
|
78
|
+
</div>
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@react.component
|
|
83
|
+
let make = (~component: string) => {
|
|
84
|
+
PlaygroundRouter.Breadcrumb.use([
|
|
85
|
+
{
|
|
86
|
+
route: Components(List),
|
|
87
|
+
text: "Components"->React.string,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
route: Components(Details(component)),
|
|
91
|
+
text: <span className="capitalize"> {`${component}`->React.string} </span>,
|
|
92
|
+
},
|
|
93
|
+
])
|
|
94
|
+
<div>
|
|
95
|
+
<h1 className="text-4xl font-bold font-display mb-4 capitalize">
|
|
96
|
+
{component->React.string}
|
|
97
|
+
</h1>
|
|
98
|
+
<div>
|
|
99
|
+
{components
|
|
100
|
+
->Array.getBy(((name, _)) => {
|
|
101
|
+
component === name
|
|
102
|
+
})
|
|
103
|
+
->Option.mapWithDefault("unknown"->React.string, ((_, playgroundModule)) => {
|
|
104
|
+
<Component component={playgroundModule} />
|
|
105
|
+
})}
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -8,10 +8,16 @@ module RouterConfig = {
|
|
|
8
8
|
| Requests
|
|
9
9
|
| Form
|
|
10
10
|
|
|
11
|
+
type designRoutes =
|
|
12
|
+
| Fonts
|
|
13
|
+
| Colors
|
|
14
|
+
| MediaQueries
|
|
15
|
+
|
|
11
16
|
type t =
|
|
12
17
|
| Home
|
|
13
18
|
| Docs(docRoutes)
|
|
14
19
|
| Components(componentRoutes)
|
|
20
|
+
| DesignSystem(designRoutes)
|
|
15
21
|
| NotFound
|
|
16
22
|
|
|
17
23
|
let make = (url: RescriptReactRouter.url) => {
|
|
@@ -25,6 +31,13 @@ module RouterConfig = {
|
|
|
25
31
|
| list{"requests"} => Docs(Requests)
|
|
26
32
|
| _ => NotFound
|
|
27
33
|
}
|
|
34
|
+
| list{"design", ...rest} =>
|
|
35
|
+
switch rest {
|
|
36
|
+
| list{"fonts"} => DesignSystem(Fonts)
|
|
37
|
+
| list{"colors"} => DesignSystem(Colors)
|
|
38
|
+
| list{"mediaQueries"} => DesignSystem(MediaQueries)
|
|
39
|
+
| _ => NotFound
|
|
40
|
+
}
|
|
28
41
|
| list{"components", ...rest} =>
|
|
29
42
|
switch rest {
|
|
30
43
|
| list{} => Components(List)
|
|
@@ -50,6 +63,16 @@ module RouterConfig = {
|
|
|
50
63
|
}
|
|
51
64
|
}
|
|
52
65
|
|
|
66
|
+
| DesignSystem(designRoute) => {
|
|
67
|
+
let base = "/design"
|
|
68
|
+
|
|
69
|
+
switch designRoute {
|
|
70
|
+
| Fonts => `${base}/fonts`
|
|
71
|
+
| Colors => `${base}/colors`
|
|
72
|
+
| MediaQueries => `${base}/mediaQueries`
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
53
76
|
| Components(route) => {
|
|
54
77
|
let base = "/components"
|
|
55
78
|
|
|
@@ -3,34 +3,30 @@ module HighlightJs = {
|
|
|
3
3
|
external registerLanguage: (string, 'a) => unit = "registerLanguage"
|
|
4
4
|
@module("highlight.js") @scope("default")
|
|
5
5
|
external highlightAll: unit => unit = "highlightAll"
|
|
6
|
+
|
|
7
|
+
type result = {value: string}
|
|
8
|
+
@module("highlight.js") @scope("default")
|
|
9
|
+
external highlight: (string, 'a) => result = "highlight"
|
|
6
10
|
}
|
|
7
11
|
|
|
8
12
|
@module("../../../playground/utils/rescript-highlight")
|
|
9
13
|
external rescriptModule: 'a = "default"
|
|
10
|
-
@module("highlight.js/lib/languages/bash")
|
|
11
|
-
external bashModule: 'a = "default"
|
|
12
|
-
@module("highlight.js/lib/languages/javascript")
|
|
13
|
-
external javascriptModule: 'a = "default"
|
|
14
14
|
|
|
15
15
|
HighlightJs.registerLanguage("rescript", rescriptModule)
|
|
16
|
-
HighlightJs.registerLanguage("bash", bashModule)
|
|
17
|
-
HighlightJs.registerLanguage("js", javascriptModule)
|
|
18
16
|
|
|
19
17
|
@react.component
|
|
20
|
-
let make = (~
|
|
21
|
-
React.useEffect0(() => {
|
|
22
|
-
HighlightJs.highlightAll()
|
|
23
|
-
|
|
24
|
-
None
|
|
25
|
-
})
|
|
26
|
-
|
|
18
|
+
let make = (~code) => {
|
|
27
19
|
<div className="Code border rounded-lg mb-6 relative">
|
|
28
20
|
<pre className="p-4">
|
|
29
|
-
<code
|
|
21
|
+
<code
|
|
22
|
+
dangerouslySetInnerHTML={
|
|
23
|
+
"__html": HighlightJs.highlight(code, {"language": "rescript"}).value,
|
|
24
|
+
}
|
|
25
|
+
/>
|
|
30
26
|
</pre>
|
|
31
27
|
<button
|
|
32
|
-
className="absolute right-0
|
|
33
|
-
onClick={_ => Browser.Navigator.Clipboard.writeText(Obj.magic(
|
|
28
|
+
className="absolute right-0 top-0 bg-white rounded-tl rounded-br text-sm px-2 border-b border-l hover:bg-neutral-200"
|
|
29
|
+
onClick={_ => Browser.Navigator.Clipboard.writeText(Obj.magic(code))}>
|
|
34
30
|
{"Copy"->React.string}
|
|
35
31
|
</button>
|
|
36
32
|
</div>
|
package/playground/{stories/IntroductionColors.stories.mdx → design/DesignSystem_Colors.mdx}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Fonts = {
|
|
2
|
+
@module("../../../../playground/design/DesignSystem_Fonts.mdx") @react.component
|
|
3
|
+
external make: unit => React.element = "default"
|
|
4
|
+
}
|
|
5
|
+
module Colors = {
|
|
6
|
+
@module("../../../../playground/design/DesignSystem_Colors.mdx") @react.component
|
|
7
|
+
external make: unit => React.element = "default"
|
|
8
|
+
}
|
|
9
|
+
module MediaQueries = {
|
|
10
|
+
@module("../../../../playground/design/DesignSystem_MediaQueries.mdx") @react.component
|
|
11
|
+
external make: unit => React.element = "default"
|
|
12
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Decode content from API result
|
|
2
|
+
|
|
3
|
+
## API
|
|
4
|
+
|
|
5
|
+
### Decode an enumeration
|
|
6
|
+
|
|
7
|
+
```rescript
|
|
8
|
+
module LiftEnum = {
|
|
9
|
+
@deriving(jsConverter)
|
|
10
|
+
type enum = [
|
|
11
|
+
| #withLift
|
|
12
|
+
| #withoutLift
|
|
13
|
+
| #unknown
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module Lift = Toolkit.Decoder.Enum(LiftEnum)
|
|
18
|
+
|
|
19
|
+
@decco
|
|
20
|
+
type response = {lift: Lift.t}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Decode a date
|
|
24
|
+
|
|
25
|
+
```rescript
|
|
26
|
+
@decco
|
|
27
|
+
type response = {
|
|
28
|
+
createdAt: Toolkit.Decoder.Date.t
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Decode unit measure
|
|
33
|
+
|
|
34
|
+
There are 2 options :
|
|
35
|
+
|
|
36
|
+
- the field has the unit like : `19 mm`
|
|
37
|
+
- the field has only the value
|
|
38
|
+
|
|
39
|
+
#### Automatic unit handling
|
|
40
|
+
|
|
41
|
+
```rescript
|
|
42
|
+
[@decco]
|
|
43
|
+
type response = {
|
|
44
|
+
length: Toolkit.Decoder.UnitMeasure.Dimension.WithUnit.t
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Known unit
|
|
49
|
+
|
|
50
|
+
```rescript
|
|
51
|
+
[@decco]
|
|
52
|
+
type response = {
|
|
53
|
+
weight: Toolkit.Decoder.UnitMeasure.Weight.Kg.t
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Decode an Array written as a String
|
|
58
|
+
|
|
59
|
+
This codec is intended for encoding the array params of API requests of scala services.
|
|
60
|
+
|
|
61
|
+
```rescript
|
|
62
|
+
@decco
|
|
63
|
+
type params = {
|
|
64
|
+
lengths: Toolkit.Decoder.StringArray<Toolkit.Decoder.UnitMeasure.Dimension.WithUnit.t>
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
let params = {lengths:[#cm(1),#m(40), #km(3)]};
|
|
68
|
+
let encodedParams = params->params_encode; // "1.00 cm,40.00 m,3.00 km"
|
|
69
|
+
let decodedParams = encodedParams->params_decode; // Ok([#cm(1),#m(40),#km(3)])
|
|
70
|
+
```
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Handling forms
|
|
2
|
+
|
|
3
|
+
We have created a fork of [reform@9.8.0](https://github.com/Astrocoders/reform) we had some features :
|
|
4
|
+
|
|
5
|
+
- `onSubmit` must return a `Promise.promise(result('a, 'e))`
|
|
6
|
+
- `SubmitFailed(option('error'))` to the `formState('error)` variant
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
### Define a FormState
|
|
11
|
+
|
|
12
|
+
The module must contains an `error` type and an include of `state` type with `%lenses`
|
|
13
|
+
|
|
14
|
+
```rescript
|
|
15
|
+
module FormState = {
|
|
16
|
+
type error = ColiswebApi.V5.Store.Contact.CreateContact.Request.error;
|
|
17
|
+
include [%lenses
|
|
18
|
+
type state = {
|
|
19
|
+
firstName: string,
|
|
20
|
+
lastName: string,
|
|
21
|
+
email: string,
|
|
22
|
+
phone1: string,
|
|
23
|
+
phone2: string,
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
module FormApi = Toolkit.Form.Make(FormState);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Use the form in React
|
|
32
|
+
|
|
33
|
+
```rescript
|
|
34
|
+
// ...
|
|
35
|
+
@react.component
|
|
36
|
+
let make = () => {
|
|
37
|
+
|
|
38
|
+
let initialState =
|
|
39
|
+
FormState.{
|
|
40
|
+
firstName: "",
|
|
41
|
+
lastName: "",
|
|
42
|
+
phone1: "",
|
|
43
|
+
phone2: "",
|
|
44
|
+
email: "",
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
let schema =
|
|
48
|
+
FormApi.Form.Validation.Schema([
|
|
49
|
+
StringNonEmpty(FirstName),
|
|
50
|
+
StringNonEmpty(LastName),
|
|
51
|
+
Email(Email),
|
|
52
|
+
]);
|
|
53
|
+
|
|
54
|
+
let onSubmit = (form: FormApi.Form.onSubmitAPI) => {
|
|
55
|
+
let {values}: FormApi.Form.state = form.state;
|
|
56
|
+
|
|
57
|
+
ColiswebApi.V5.Store.Contact.CreateContact.Config.exec((
|
|
58
|
+
clientId,
|
|
59
|
+
storeId,
|
|
60
|
+
{
|
|
61
|
+
firstName: values.firstName->OptionUtils.fromString,
|
|
62
|
+
lastName: values.lastName->OptionUtils.fromString,
|
|
63
|
+
email: values.email,
|
|
64
|
+
phone1: values.phone1->OptionUtils.fromString,
|
|
65
|
+
phone2: values.phone2->OptionUtils.fromString,
|
|
66
|
+
},
|
|
67
|
+
))
|
|
68
|
+
->Promise.flatMapOk(result =>
|
|
69
|
+
reloadContact()->Promise.map(_ => Ok(result))
|
|
70
|
+
)
|
|
71
|
+
->Promise.tapOk(_ => hide())
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
let form = FormApi.Form.use(~initialState, ~schema, ~onSubmit, ());
|
|
75
|
+
|
|
76
|
+
<FormApi.Form.Provider value=form>
|
|
77
|
+
<form onSubmit={event => {
|
|
78
|
+
ReactEvent.Synthetic.preventDefault(event);
|
|
79
|
+
form.submit();
|
|
80
|
+
}}>
|
|
81
|
+
|
|
82
|
+
<Form.Field
|
|
83
|
+
field
|
|
84
|
+
render={({handleChange, error, value, validate}) => {
|
|
85
|
+
let isInvalid = error->Option.isSome;
|
|
86
|
+
<>
|
|
87
|
+
<input value onChange={BsReform.Helpers.handleChange(handleChange)} />
|
|
88
|
+
|
|
89
|
+
{
|
|
90
|
+
error->Option.mapWithDefault(React.null, e => <p>e->React.string</p>)
|
|
91
|
+
}
|
|
92
|
+
</>;
|
|
93
|
+
}}
|
|
94
|
+
/>;
|
|
95
|
+
|
|
96
|
+
<Button
|
|
97
|
+
type_="submit"
|
|
98
|
+
color=#primary
|
|
99
|
+
isLoading={form.state.formState === Submitting}
|
|
100
|
+
onClick={_ => form.submit()}>
|
|
101
|
+
<FormattedMessage
|
|
102
|
+
id="forms.controls.confirm"
|
|
103
|
+
defaultMessage="Confirm"
|
|
104
|
+
/>
|
|
105
|
+
</Button>
|
|
106
|
+
</form>
|
|
107
|
+
</FormApi.Form.Provider>;
|
|
108
|
+
}
|
|
109
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Avoid string type with unique identifiers
|
|
2
|
+
|
|
3
|
+
Convert a string or an int in an opaque type with a decco decoder.
|
|
4
|
+
|
|
5
|
+
### `string` identifier
|
|
6
|
+
|
|
7
|
+
```rescript
|
|
8
|
+
module DeliveryId = Toolkit.Identifier.MakeString({});
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
somewhere
|
|
12
|
+
**/
|
|
13
|
+
@decco
|
|
14
|
+
type response = {
|
|
15
|
+
deliveryId: DeliveryId.t
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
let deliveryId = DeliveryId.make("some-id");
|
|
19
|
+
deliveryId->DeliveryId.toString // "some-id"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### `int` identifier
|
|
23
|
+
|
|
24
|
+
```rescript
|
|
25
|
+
module DeliveryId = Toolkit.Identifier.MakeInt({});
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
somewhere
|
|
29
|
+
**/
|
|
30
|
+
@decco
|
|
31
|
+
type response = {
|
|
32
|
+
deliveryId: DeliveryId.t
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let deliveryId = DeliveryId.make(12);
|
|
36
|
+
deliveryId->DeliveryId.toString; // "12"
|
|
37
|
+
deliveryId->DeliveryId.toInt; // 12
|
|
38
|
+
```
|