-
-
Notifications
You must be signed in to change notification settings - Fork 257
Expand file tree
/
Copy pathUtil.res
More file actions
106 lines (88 loc) · 2.98 KB
/
Util.res
File metadata and controls
106 lines (88 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
module Unsafe = {
external elementAsString: React.element => string = "%identity"
}
module String = {
let camelCase: string => string = %raw("str => {
return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
}")
let kebabCase = string =>
string
->String.replaceAllRegExp(/([a-z])([A-Z])/g, "$1-$2")
->String.toLowerCase
->String.replaceAll(" ", "-")
let capitalize: string => string = %raw("str => {
return str && str.charAt(0).toUpperCase() + str.substring(1);
}")
let capitalizeSentence = str =>
str
->String.split(" ")
->Array.map(str => str->String.length > 2 ? str->String.capitalize : str)
->Array.join(" ")
let leadingSlash = str => str->String.startsWith("/") ? str : "/" ++ str
let trailingSlash = str => str->String.endsWith("/") ? str : str ++ "/"
let removeTrailingSlash = str => str->String.replaceRegExp(/\/$/, "")
}
module Url = {
let isAbsolute = (str: string): bool => {
let regex = /^(?:[a-z]+:)?\/\//i
regex->RegExp.test(str)
}
let getRootPath = path => {
if path->Stdlib.String.includes("docs/manual") {
"/docs/manual"
} else if path->Stdlib.String.includes("docs/react") {
"/docs/react"
} else {
""
}
}
let createRelativePath = (currentPath, href) => {
if (
href->Stdlib.String.includes("docs/manual") ||
href->Stdlib.String.includes("docs/react") ||
href->Stdlib.String.includes("community") ||
href->Stdlib.String.includes("blog") ||
href->Stdlib.String.includes("try") ||
href->Stdlib.String.includes("/llms/") ||
href->Stdlib.String.startsWith("#")
) {
href
} else {
let rootPath = getRootPath(currentPath)
let href = href->Stdlib.String.replace("docs/manual", "")
(rootPath ++ href->String.leadingSlash)->Stdlib.String.replaceAll("//", "/")
}
}
let removeBaseUrl = str => str->Stdlib.String.replace(Env.root_url, "")
// Cloudflare links have to include a trailing slash or they will redirect
let normalizeUrl = str => {
// separate the anchor if there is any
let splitUrl = str->Stdlib.String.split("#")
`${splitUrl[0]->Option.getOr("")}/${splitUrl[1]
->Option.map(anchor => "#" ++ anchor->String.removeTrailingSlash)
->Option.getOr("")}`->removeBaseUrl
}
}
module Date = {
type intl
@new @scope("Intl")
external dateTimeFormat: (string, {"month": string, "day": string, "year": string}) => intl =
"DateTimeFormat"
@send external format: (intl, Date.t) => string = "format"
let toDayMonthYear = (date: Date.t) => {
dateTimeFormat("en-US", {"month": "short", "day": "numeric", "year": "numeric"})->format(date)
}
}
/**
* 防抖
* @param fn the func to debounce
* @param delay milliseconds
* @returns new debounced function
*/
let debounce = (fn: unit => unit, delay: int) => {
let timer = ref(None)
() => {
timer.contents->Option.forEach(clearTimeout)
timer := Some(setTimeout(~handler=fn, ~timeout=delay))
}
}