@startlibs/utils 1.0.3 → 1.1.0
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/lib/ActionUtils.mjs +117 -0
- package/lib/ActionUtils.mjs.map +1 -0
- package/lib/FetchUtils.mjs +100 -0
- package/lib/FetchUtils.mjs.map +1 -0
- package/lib/createPressEvent.mjs +74 -0
- package/lib/createPressEvent.mjs.map +1 -0
- package/lib/fixMediaQuery.mjs +64 -0
- package/lib/fixMediaQuery.mjs.map +1 -0
- package/lib/formatDate.mjs +110 -0
- package/lib/formatDate.mjs.map +1 -0
- package/lib/formatUtils.mjs +64 -0
- package/lib/formatUtils.mjs.map +1 -0
- package/lib/getClosestOffsetScroll.mjs +15 -0
- package/lib/getClosestOffsetScroll.mjs.map +1 -0
- package/lib/hooks/useEventListener.mjs +27 -0
- package/lib/hooks/useEventListener.mjs.map +1 -0
- package/lib/index.cjs +1811 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.mjs +19 -0
- package/lib/index.mjs.map +1 -0
- package/lib/lodashUtils.mjs +131 -0
- package/lib/lodashUtils.mjs.map +1 -0
- package/lib/promiseUtils.mjs +92 -0
- package/lib/promiseUtils.mjs.map +1 -0
- package/lib/reactUtils.mjs +12 -0
- package/lib/reactUtils.mjs.map +1 -0
- package/lib/reduceUtils.mjs +14 -0
- package/lib/reduceUtils.mjs.map +1 -0
- package/lib/smoothScroll.mjs +59 -0
- package/lib/smoothScroll.mjs.map +1 -0
- package/lib/styled.mjs +234 -0
- package/lib/styled.mjs.map +1 -0
- package/lib/timeUtils.mjs +81 -0
- package/lib/timeUtils.mjs.map +1 -0
- package/lib/timerUtils.mjs +11 -0
- package/lib/timerUtils.mjs.map +1 -0
- package/lib/utils.mjs +386 -0
- package/lib/utils.mjs.map +1 -0
- package/lib/wrapLazy.mjs +132 -0
- package/lib/wrapLazy.mjs.map +1 -0
- package/package.json +44 -30
- package/src/ActionUtils.js +90 -0
- package/src/FetchUtils.js +87 -0
- package/src/createPressEvent.jsx +79 -0
- package/src/fixMediaQuery.js +71 -0
- package/src/formatDate.js +121 -0
- package/src/formatUtils.jsx +63 -0
- package/src/getClosestOffsetScroll.js +12 -0
- package/src/hooks/useEventListener.js +26 -0
- package/src/index.js +19 -0
- package/src/lodashUtils.jsx +110 -0
- package/src/promiseUtils.jsx +75 -0
- package/src/reactUtils.jsx +7 -0
- package/src/reduceUtils.jsx +6 -0
- package/src/smoothScroll.js +58 -0
- package/src/styled.js +177 -0
- package/src/timeUtils.jsx +57 -0
- package/src/timerUtils.jsx +10 -0
- package/src/utils.jsx +342 -0
- package/src/wrapLazy.jsx +122 -0
- package/.babelrc +0 -26
- package/lib/index.js +0 -2382
- package/rollup.config.js +0 -44
package/package.json
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@startlibs/utils",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Startlibs Utils",
|
|
5
|
-
"main": "lib/index.
|
|
5
|
+
"main": "lib/index.cjs",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"source": "./src/index.js",
|
|
9
|
+
"require": "./lib/index.cjs",
|
|
10
|
+
"import": "./lib/index.mjs",
|
|
11
|
+
"default": "./lib/index.mjs"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json",
|
|
14
|
+
"./*": {
|
|
15
|
+
"import": "./lib/*.mjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
6
18
|
"sideEffects": false,
|
|
7
|
-
"source":
|
|
19
|
+
"source": "./src/index.js",
|
|
8
20
|
"peerDependencies": {
|
|
9
|
-
"@
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"react-dom": "*",
|
|
14
|
-
"styled-components": "^5.1.1"
|
|
21
|
+
"@startlibs/core": "*",
|
|
22
|
+
"lodash": "^4.17.21",
|
|
23
|
+
"react": ">=16.8",
|
|
24
|
+
"styled-components": ">=5"
|
|
15
25
|
},
|
|
16
26
|
"devDependencies": {
|
|
17
|
-
"@babel/core": "^7.
|
|
18
|
-
"@babel/plugin-
|
|
19
|
-
"@babel/
|
|
20
|
-
"@babel/
|
|
21
|
-
"@babel/
|
|
22
|
-
"@babel/plugin-proposal-object-rest-spread": "^7.2.0",
|
|
23
|
-
"@babel/plugin-proposal-optional-chaining": "^7.12.0",
|
|
24
|
-
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
|
|
25
|
-
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
|
26
|
-
"@babel/plugin-syntax-import-meta": "^7.2.0",
|
|
27
|
-
"@babel/plugin-transform-runtime": "^7.2.0",
|
|
28
|
-
"@babel/plugin-transform-spread": "^7.2.0",
|
|
29
|
-
"@babel/plugin-transform-unicode-property-regex": "^7.27.1",
|
|
30
|
-
"@babel/preset-env": "^7.2.0",
|
|
31
|
-
"@babel/preset-flow": "^7.0.0",
|
|
32
|
-
"@babel/preset-react": "^7.0.0",
|
|
27
|
+
"@babel/core": "^7.26.0",
|
|
28
|
+
"@babel/plugin-transform-runtime": "^7.26.0",
|
|
29
|
+
"@babel/preset-env": "^7.26.0",
|
|
30
|
+
"@babel/preset-flow": "^7.25.0",
|
|
31
|
+
"@babel/preset-react": "^7.26.0",
|
|
33
32
|
"babel-plugin-lodash": "^3.3.4",
|
|
34
33
|
"babel-plugin-macros": "^2.4.2",
|
|
35
34
|
"babel-plugin-styled-components": "^1.10.0",
|
|
36
|
-
"
|
|
37
|
-
"rollup": "^2.
|
|
35
|
+
"lodash": "^4.17.21",
|
|
36
|
+
"rollup": "^2.79.2",
|
|
38
37
|
"rollup-plugin-auto-external": "^2.0.0",
|
|
39
38
|
"rollup-plugin-babel": "^4.0.3",
|
|
40
39
|
"rollup-plugin-commonjs": "^9.2.0",
|
|
41
|
-
"rollup-plugin-node-resolve": "^3.4.0"
|
|
40
|
+
"rollup-plugin-node-resolve": "^3.4.0",
|
|
41
|
+
"styled-components": "^5.3.11"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -59,7 +59,21 @@
|
|
|
59
59
|
},
|
|
60
60
|
"homepage": "https://github.com/felipeko/startlibs#readme",
|
|
61
61
|
"dependencies": {
|
|
62
|
+
"@babel/runtime": "^7.20.0",
|
|
62
63
|
"create-emotion": "10.0.27",
|
|
63
|
-
"
|
|
64
|
-
}
|
|
64
|
+
"polished": "^2.0.0 || ^3.0.0 || ^4.0.0"
|
|
65
|
+
},
|
|
66
|
+
"files": [
|
|
67
|
+
"lib",
|
|
68
|
+
"src"
|
|
69
|
+
],
|
|
70
|
+
"module": "lib/index.mjs",
|
|
71
|
+
"browserslist": [
|
|
72
|
+
"chrome >= 61",
|
|
73
|
+
"edge >= 79",
|
|
74
|
+
"firefox >= 60",
|
|
75
|
+
"safari >= 11",
|
|
76
|
+
"ios_saf >= 11",
|
|
77
|
+
"samsung >= 8.2"
|
|
78
|
+
]
|
|
65
79
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {useMemo} from 'react'
|
|
2
|
+
import {callIfFunction} from './utils'
|
|
3
|
+
import {_s} from './lodashUtils'
|
|
4
|
+
import _ from 'lodash/fp'
|
|
5
|
+
|
|
6
|
+
const isNotSelector = (v) => (typeof v !== 'function' || v.length === 0)
|
|
7
|
+
|
|
8
|
+
const toSelector = (v) => isNotSelector(v) ? (s) => _s.get(callIfFunction(v),s) : v
|
|
9
|
+
|
|
10
|
+
const mergeSelectors = (prev, next) => (v) => next(prev(v))
|
|
11
|
+
export const concatSelectors = (...paths) => paths.reduce(([selector, isSelector], path) =>
|
|
12
|
+
isNotSelector(path) && !isSelector
|
|
13
|
+
? [selector.concat(path), false]
|
|
14
|
+
: [mergeSelectors(toSelector(selector), path), true],
|
|
15
|
+
[[], false]
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
export const COMPLETE_ACTION = {}
|
|
19
|
+
export const REDUCE = {}
|
|
20
|
+
export const FETCH = {}
|
|
21
|
+
export const SKIP_FETCH = {}
|
|
22
|
+
export const SKIP_DISPATCH = {}
|
|
23
|
+
export const SKIPPED_ACTION = {}
|
|
24
|
+
|
|
25
|
+
const ACTION_TYPES = [COMPLETE_ACTION,REDUCE,FETCH,SKIP_FETCH,SKIP_DISPATCH]
|
|
26
|
+
|
|
27
|
+
export const selectPath = (useState, ...paths) => {
|
|
28
|
+
const [selector] = useMemo(() => concatSelectors(...paths), paths)
|
|
29
|
+
const [value] = useState(selector)
|
|
30
|
+
return value
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const Action = (fnOrArray, prevArgs = []) => {
|
|
34
|
+
const isArray = Array.isArray(fnOrArray)
|
|
35
|
+
if (isArray) {
|
|
36
|
+
// excessive paramaeters called on the action, used for options.
|
|
37
|
+
const actionType = _.last(prevArgs)
|
|
38
|
+
const [fetcher, reducer, rollbacker] = fnOrArray
|
|
39
|
+
if (actionType === REDUCE) {
|
|
40
|
+
return reducer(null,prevArgs)
|
|
41
|
+
} else if (actionType === FETCH) {
|
|
42
|
+
return fetcher()
|
|
43
|
+
} else {
|
|
44
|
+
return _.set('extra',fnOrArray.extra,[
|
|
45
|
+
actionType === SKIP_FETCH ? () => Promise.resolve() : fetcher,
|
|
46
|
+
actionType === SKIP_DISPATCH ? undefined : reducer,
|
|
47
|
+
].concat(rollbacker || []))
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
return prevArgs.length < fnOrArray.length ? (...moreArgs) => Action(fnOrArray,[...prevArgs,...moreArgs]) : Action(fnOrArray(...prevArgs),prevArgs)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const mapAction = (get, dispatcher, firstRun) => (action) => {
|
|
55
|
+
if (Array.isArray(action)) {
|
|
56
|
+
if (firstRun) {
|
|
57
|
+
return () => mapAction(get,dispatcher)(action)
|
|
58
|
+
}
|
|
59
|
+
const [fetcher, reducer, rollbacker] = action
|
|
60
|
+
const {skip} = action.extra || {}
|
|
61
|
+
if (skip && skip(get())) {
|
|
62
|
+
return Promise.resolve(SKIPPED_ACTION)
|
|
63
|
+
}
|
|
64
|
+
const fetched = fetcher()
|
|
65
|
+
if (rollbacker) {
|
|
66
|
+
dispatcher(prevState => {
|
|
67
|
+
const nextState = reducer(null)(prevState)
|
|
68
|
+
fetched.catch((response)=> {
|
|
69
|
+
dispatcher(rollbacker(prevState,nextState,response))
|
|
70
|
+
})
|
|
71
|
+
return nextState
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
if (reducer !== undefined) {
|
|
75
|
+
fetched.then((response) => dispatcher(reducer(response)))
|
|
76
|
+
}
|
|
77
|
+
return fetched
|
|
78
|
+
} else {
|
|
79
|
+
return (...moreMetas) => mapAction(get,dispatcher)(action(...moreMetas))
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const activateActions = (get, dispatcher, ...actions) => {
|
|
84
|
+
return actions.map(mapAction(get, dispatcher,true))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const SkipAction = (skip,action) => {
|
|
88
|
+
action.extra = {...action.extra,skip}
|
|
89
|
+
return action
|
|
90
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {callIfFunction} from './utils'
|
|
2
|
+
import _ from 'lodash/fp'
|
|
3
|
+
|
|
4
|
+
const resolveFetch = async (url, fetchOptions) => {
|
|
5
|
+
try {
|
|
6
|
+
const response = await fetch(url, {
|
|
7
|
+
credentials: 'same-origin',
|
|
8
|
+
...fetchOptions
|
|
9
|
+
})
|
|
10
|
+
const text = await response.text()
|
|
11
|
+
try {
|
|
12
|
+
const json = JSON.parse(text)
|
|
13
|
+
return [json, response]
|
|
14
|
+
} catch (eror) {
|
|
15
|
+
return [text, response]
|
|
16
|
+
}
|
|
17
|
+
} catch (error) {
|
|
18
|
+
return [error, false]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const innerFetcher = async (url, fetchOptions) => {
|
|
23
|
+
const [data, response] = await resolveFetch(url, fetchOptions)
|
|
24
|
+
if (!response || response.status >= 400) {
|
|
25
|
+
throw [data, response]
|
|
26
|
+
} else {
|
|
27
|
+
return [data, response]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export const queryStringToObj = (str = window.location.search) => Object.fromEntries(new URLSearchParams(str).entries())
|
|
31
|
+
|
|
32
|
+
export const addQueryString = (existingUrl = '',obj) => {
|
|
33
|
+
const [onlyUrl, otherQueryString] = existingUrl.split('?')
|
|
34
|
+
const params = new URLSearchParams(otherQueryString)
|
|
35
|
+
for (let key in obj) {
|
|
36
|
+
const value = obj[key]
|
|
37
|
+
if (value === null) {
|
|
38
|
+
params.delete(key)
|
|
39
|
+
} else {
|
|
40
|
+
params.set(key, obj[key])
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const paramsStr = params.toString()
|
|
44
|
+
if (!paramsStr) {
|
|
45
|
+
return onlyUrl
|
|
46
|
+
}
|
|
47
|
+
return onlyUrl + '?' + paramsStr
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const cleanNulls = (str) => str.replace(/\0/g, '')
|
|
51
|
+
|
|
52
|
+
// Cross-origin o X-Requested-With só custa: dispara preflight e impede o reuso do
|
|
53
|
+
// <link rel=preload as=fetch>, cujo request vai sem ele. Quem lê o header é servidor nosso.
|
|
54
|
+
const isSameOrigin = (url) => new URL(url, window.location.href).origin === window.location.origin
|
|
55
|
+
|
|
56
|
+
export let postFetcherWithResponse = async (url, jsonOrForm, fetchOptions = {}) => innerFetcher(url, {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
body: typeof jsonOrForm === 'string'
|
|
59
|
+
? jsonOrForm
|
|
60
|
+
: !jsonOrForm || jsonOrForm.constructor === window.FormData || jsonOrForm.constructor === window.File
|
|
61
|
+
? jsonOrForm
|
|
62
|
+
: cleanNulls(JSON.stringify(jsonOrForm)),
|
|
63
|
+
...fetchOptions,
|
|
64
|
+
headers:
|
|
65
|
+
(_.isPlainObject(fetchOptions.headers) || !fetchOptions.headers)
|
|
66
|
+
? {
|
|
67
|
+
...(jsonOrForm && (typeof jsonOrForm === 'string' || jsonOrForm.constructor === window.FormData) ? {} : {'Content-Type': 'application/json; charset=UTF-8'}),
|
|
68
|
+
...(isSameOrigin(url) ? {'X-Requested-With': 'XMLHttpRequest'} : {}),
|
|
69
|
+
...fetchOptions.headers
|
|
70
|
+
}
|
|
71
|
+
: fetchOptions.headers
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
export let getFetcherWithResponse = async (url, jsonParams, fetchOptions) => innerFetcher(addQueryString(url, jsonParams), {
|
|
75
|
+
method: 'GET',
|
|
76
|
+
...fetchOptions,
|
|
77
|
+
headers: {
|
|
78
|
+
...(isSameOrigin(url) ? {'X-Requested-With': 'XMLHttpRequest'} : {}),
|
|
79
|
+
...fetchOptions?.headers
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
export let postFetcher = async (url, json, options) => postFetcherWithResponse(url, json, options).then(([json]) => json)
|
|
84
|
+
export let getFetcher = async (url, json, options) => getFetcherWithResponse(url, json, options).then(([json]) => json)
|
|
85
|
+
|
|
86
|
+
export const formFetchWithResponse = (url, options) => (values, meta) => postFetcherWithResponse(callIfFunction(url, meta, values), values, callIfFunction(options, meta, values))
|
|
87
|
+
export const formFetch = (url, options) => (values, meta) => postFetcher(callIfFunction(url, meta, values), values, callIfFunction(options, meta, values))
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {callIfFunction, normalizePress} from './utils'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const disableSelect = (e) => {
|
|
6
|
+
e.preventDefault();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const createPressEvent = (onStart) => normalizePress((startEvent, info) => {
|
|
10
|
+
const onEnd = onStart(startEvent,info)
|
|
11
|
+
|
|
12
|
+
const finish = normalizePress((e,info) => {
|
|
13
|
+
callIfFunction(onEnd,e,info)
|
|
14
|
+
window.removeEventListener('selectstart', disableSelect)
|
|
15
|
+
window.removeEventListener('touchend',finish)
|
|
16
|
+
window.removeEventListener('mouseup',finish)
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
window.addEventListener('selectstart', disableSelect);
|
|
21
|
+
if (startEvent.touches) {
|
|
22
|
+
window.addEventListener('touchend', finish)
|
|
23
|
+
} else {
|
|
24
|
+
window.addEventListener("mouseup", finish);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
export const createPressAndHoldEvent = (onStart,interval) => createPressEvent((startEvent,info) => {
|
|
30
|
+
|
|
31
|
+
const [onInterval,onEnd] = [].concat(onStart(startEvent,info))
|
|
32
|
+
|
|
33
|
+
let i = 0;
|
|
34
|
+
if (interval) {
|
|
35
|
+
const intervalId = setInterval(() => {
|
|
36
|
+
onInterval(i++)
|
|
37
|
+
}, interval)
|
|
38
|
+
|
|
39
|
+
return normalizePress((e, info) => {
|
|
40
|
+
callIfFunction(onEnd, e, info)
|
|
41
|
+
clearInterval(intervalId)
|
|
42
|
+
})
|
|
43
|
+
} else {
|
|
44
|
+
let running = true
|
|
45
|
+
const run = () => window.requestAnimationFrame(() => {
|
|
46
|
+
if (running) {
|
|
47
|
+
onInterval(i++)
|
|
48
|
+
run()
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
run()
|
|
52
|
+
return normalizePress((e,info) => {
|
|
53
|
+
callIfFunction(onEnd, e, info)
|
|
54
|
+
running = false
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
export const createPressAndMoveEvent = (onStart) => createPressEvent((startEvent, info) => {
|
|
61
|
+
|
|
62
|
+
const [onMove,onEnd] = [].concat(onStart(startEvent,info))
|
|
63
|
+
|
|
64
|
+
const finish = normalizePress((e,info) => {
|
|
65
|
+
callIfFunction(onEnd,e,info)
|
|
66
|
+
window.removeEventListener('touchmove',move)
|
|
67
|
+
window.removeEventListener('mousemove',move)
|
|
68
|
+
})
|
|
69
|
+
const move = normalizePress(onMove,finish)
|
|
70
|
+
|
|
71
|
+
if (startEvent.touches) {
|
|
72
|
+
window.addEventListener('touchmove', move, {passive: false})
|
|
73
|
+
} else {
|
|
74
|
+
window.addEventListener("mousemove", move);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return finish
|
|
78
|
+
})
|
|
79
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
let fixed = false
|
|
2
|
+
export const scrollWidth = (function() {
|
|
3
|
+
if (!window.document) return 0
|
|
4
|
+
const html = document.documentElement
|
|
5
|
+
const oldOverflow = html.style.overflowY
|
|
6
|
+
html.style.overflowY = 'scroll'
|
|
7
|
+
const width = window.innerWidth - html.clientWidth
|
|
8
|
+
html.style.overflowY = oldOverflow
|
|
9
|
+
return width
|
|
10
|
+
})()
|
|
11
|
+
|
|
12
|
+
const fixMediaQueryFn = function() {
|
|
13
|
+
|
|
14
|
+
const fontSize = parseFloat(window.getComputedStyle(document.body).getPropertyValue('font-size'))
|
|
15
|
+
|
|
16
|
+
if (scrollWidth > 0) {
|
|
17
|
+
|
|
18
|
+
[].slice.call(document.styleSheets).filter(styleSheet => isValidExternal(styleSheet) || isInline(styleSheet)).forEach(stylesheet => {
|
|
19
|
+
try {
|
|
20
|
+
[].slice.call(stylesheet.cssRules || stylesheet.media).filter(rule => rule.constructor === window.CSSMediaRule).forEach(rule => {
|
|
21
|
+
rule.media.mediaText = rule.media.mediaText.replace(/m(in|ax)-width:\s*(\d|\.)+(px|em)/gi, function(strA) {
|
|
22
|
+
if (strA.match('px')) {
|
|
23
|
+
return strA.replace(/\d+px/gi, function(strB) {
|
|
24
|
+
return parseInt(strB, 10) + scrollWidth + 'px'
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return strA.replace(/\d.+?em/gi, function(strB) {
|
|
29
|
+
return ((parseFloat(strB) * fontSize) + scrollWidth) / fontSize + 'em'
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
} catch (e) {}
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fixed = true
|
|
39
|
+
|
|
40
|
+
function sameOrigin(url) {
|
|
41
|
+
const loc = window.location,
|
|
42
|
+
a = document.createElement('a')
|
|
43
|
+
a.href = url
|
|
44
|
+
return (a.hostname === loc.hostname && a.protocol === loc.protocol)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isInline(stylesheet) {
|
|
48
|
+
try {
|
|
49
|
+
return stylesheet.ownerNode.constructor === HTMLStyleElement && stylesheet.ownerNode.getAttribute("data-styled") === null
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return stylesheet.ownerNode.constructor === HTMLStyleElement
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isValidExternal(stylesheet) {
|
|
56
|
+
return stylesheet.href && (sameOrigin(stylesheet.href) || stylesheet.ownerNode?.crossOrigin === "anonymous")
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
export function fixMediaQuery() {
|
|
63
|
+
if (fixed || !document || !document.readyState)
|
|
64
|
+
return
|
|
65
|
+
if (process.env.NODE_ENV === 'test') { return }
|
|
66
|
+
if (document.readyState !== 'loading') {
|
|
67
|
+
fixMediaQueryFn()
|
|
68
|
+
} else {
|
|
69
|
+
document.addEventListener('DOMContentLoaded', fixMediaQueryFn)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
|
|
2
|
+
const escapedValidParts = /(^|[^\\])(dd?|DD?|mm?|LL?|hh?|MM?|ss|SSS|yy(?:yy)?)/g
|
|
3
|
+
const validParts = /(dd?|DD?|mm?|LL?|hh?|MM?|yy(?:yy)|yy|ss|SSS)$/
|
|
4
|
+
export const addZero = (v) => (v < 10 ? '0' : '') + v
|
|
5
|
+
|
|
6
|
+
const getSet = (index, ttype, plus = 0, format = (v) => v, parse = (v, defaultDate) => (v === '0' ? '' : v)) => ([
|
|
7
|
+
(date,_,noUTC) => format((typeof date === 'number' ? new Date(date) : date)['get'+(noUTC?'':'UTC') + ttype]() + plus),
|
|
8
|
+
(unformatedStr, date, _, failOnFormat, noUTC) => {
|
|
9
|
+
const str = parse(unformatedStr, date, failOnFormat)
|
|
10
|
+
if (str === '' || isNaN(date.getTime()))
|
|
11
|
+
return date
|
|
12
|
+
if (str=== '\0')
|
|
13
|
+
return date.setTime(NaN)
|
|
14
|
+
const utcSTR = noUTC ? '' : 'UTC'
|
|
15
|
+
const v = parseInt(str, 10) - plus
|
|
16
|
+
const prevDay = date['get'+utcSTR+'Date']()
|
|
17
|
+
if (ttype !== 'Date') {
|
|
18
|
+
date['set'+utcSTR+'Date'](1)
|
|
19
|
+
}
|
|
20
|
+
date['set'+ utcSTR + ttype](v)
|
|
21
|
+
if (date['get' + utcSTR + ttype]() !== v) {
|
|
22
|
+
date['set' + utcSTR + ttype](NaN)
|
|
23
|
+
return date
|
|
24
|
+
}
|
|
25
|
+
if (ttype !== 'Date') {
|
|
26
|
+
date['set'+utcSTR+'Date'](prevDay)
|
|
27
|
+
if (date['get' + utcSTR + ttype]() !== v) {
|
|
28
|
+
date['set'+utcSTR+'Date'](0)
|
|
29
|
+
return date
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return date
|
|
33
|
+
},
|
|
34
|
+
index
|
|
35
|
+
])
|
|
36
|
+
|
|
37
|
+
const getText = (type, total, slice = 99) => [
|
|
38
|
+
(date, messages,noUTC) => messages(type.toLowerCase(),date['get'+(noUTC? '': 'UTC') + type]()).slice(0, slice)
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
const yearParse = (y, date, failOnFormat) => {
|
|
42
|
+
const formattedY = y.length === 2 && y !== '20' ? '20' + y : y.length === 4 ? y : ''
|
|
43
|
+
if (formattedY === '') {
|
|
44
|
+
if (failOnFormat) {
|
|
45
|
+
const found = date.getUTCFullYear().toString().indexOf(y)
|
|
46
|
+
return found === 0 || found === 2 ? date.getUTCFullYear() : '\0'
|
|
47
|
+
} else {
|
|
48
|
+
return date.getUTCFullYear()
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
return formattedY
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const val = {
|
|
56
|
+
yyyy: getSet(0,'FullYear', 0, (v) => v, yearParse),
|
|
57
|
+
yy: getSet(0,'FullYear', 0, (v) => (v+"").slice(2,4), yearParse),
|
|
58
|
+
M: getSet(1,'Month', 1),
|
|
59
|
+
MM: getSet(1,'Month', 1, addZero),
|
|
60
|
+
L: getText('Month',12,3),
|
|
61
|
+
LL: getText('Month',12),
|
|
62
|
+
d: getSet(2,'Date'),
|
|
63
|
+
dd: getSet(2,'Date', 0, addZero),
|
|
64
|
+
D: getText('Day', 7, 3),
|
|
65
|
+
DD: getText('Day', 7),
|
|
66
|
+
m: getSet(4,'Minutes'),
|
|
67
|
+
mm: getSet(4,'Minutes', 0, addZero),
|
|
68
|
+
h: getSet(5,'Hours'),
|
|
69
|
+
hh: getSet(5,'Hours', 0, addZero),
|
|
70
|
+
ss: getSet(6,'Seconds', 0, addZero),
|
|
71
|
+
SSS: getSet(7,'Milliseconds', 0, addZero),
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function formatDateToPattern(format) {
|
|
76
|
+
return format.replace(escapedValidParts, (_, _1, _2) => _1 + (_2 === 'yy' ? '##' : _2 === 'yyyy' ? '####' : '0#'))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function formatDate(date, format, messages,noUTC) {
|
|
80
|
+
if (!date)
|
|
81
|
+
return ''
|
|
82
|
+
const separators = format.replace(escapedValidParts, '\0').split('\0')
|
|
83
|
+
const parts = format.match(escapedValidParts)
|
|
84
|
+
const formattedDate = parts.reduce((acc, part) =>
|
|
85
|
+
acc.concat(
|
|
86
|
+
separators.length ? [separators.shift()] : [],
|
|
87
|
+
part.replace(validParts, ''),
|
|
88
|
+
val[part.match(validParts)[0]][0](date, messages,noUTC)
|
|
89
|
+
),
|
|
90
|
+
[]
|
|
91
|
+
)
|
|
92
|
+
return formattedDate.join('').replace(/\\([dDmLhMy])/g, '$1')
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const now = () => new Date()
|
|
96
|
+
|
|
97
|
+
export function parseDate(str, possibleDate, format, messages, failOnFormat, noUTC) {
|
|
98
|
+
if (!str)
|
|
99
|
+
return possibleDate
|
|
100
|
+
const separators = format.replace(escapedValidParts, '\0').split('\0')
|
|
101
|
+
const parts = format.match(escapedValidParts)
|
|
102
|
+
const mutations = []
|
|
103
|
+
parts.reduce((rest, part, i) => {
|
|
104
|
+
const separator = (separators.length ? separators.shift() : '') + part.replace(validParts, '')
|
|
105
|
+
const current = rest.slice(separator.length)
|
|
106
|
+
if (current && separator === rest.slice(0, separator.length)) {
|
|
107
|
+
const setType = part.match(validParts)[0]
|
|
108
|
+
const nextSeparator = separators[0]
|
|
109
|
+
const nextStrIndex = current.indexOf(nextSeparator + (parts[i + 1] || '').replace(validParts, ''))
|
|
110
|
+
mutations[val[setType][2]] = [val[setType][1],nextStrIndex ? current.slice(0,nextStrIndex) : current]
|
|
111
|
+
return current.slice(nextStrIndex)
|
|
112
|
+
} else {
|
|
113
|
+
return ''
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
str
|
|
117
|
+
)
|
|
118
|
+
const date = possibleDate && possibleDate.getTime()!==-1 ? new Date(possibleDate) : now()
|
|
119
|
+
mutations.forEach(([setter,text])=> setter(text,date,messages,failOnFormat,noUTC))
|
|
120
|
+
return date
|
|
121
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import _ from 'lodash/fp'
|
|
3
|
+
|
|
4
|
+
export const formatJoin = (arr,separator = ', ', lastSeparator = ' e ') => [arr.slice(0,-1).join(separator),arr.slice(-1)].join(lastSeparator)
|
|
5
|
+
|
|
6
|
+
export const formatJoinArr = (arr,separator,lastSeparator) =>
|
|
7
|
+
arr.flatMap((v,i) => i < arr.length - 2 ? [v,separator] : (i < arr.length - 1 ? [v,lastSeparator] : [v]))
|
|
8
|
+
|
|
9
|
+
export const removeAccents = (str) => (str||"").normalize('NFD').replace(/\p{Diacritic}/gu, "")
|
|
10
|
+
export const asciify = (str) => removeAccents(str||"").replace(/[^\x00-\x7F]/g, "")
|
|
11
|
+
export const normalizeText = (str) => removeAccents(str).toLowerCase()
|
|
12
|
+
export const normalizeTextUrl = (str) => removeAccents(str).replace(/[\s.\u0022&/]/g, '-').replace(/-{2,}/g,'-').toLowerCase()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export const willFormatDecimal = (digits = 2,{max,min,padTo,zeroless,clean} = {}) => {
|
|
16
|
+
const splitRegex = new RegExp(`(\\d+)(\\d{${digits}})`)
|
|
17
|
+
const singleRegex = new RegExp(`/^([^,]*,\\d{0,${digits}).*/`)
|
|
18
|
+
const pad = (str) =>
|
|
19
|
+
padTo
|
|
20
|
+
? (str.indexOf(",") >= 0
|
|
21
|
+
? _.padCharsEnd("0", str.indexOf(",") + padTo + 1,str)
|
|
22
|
+
: _.padCharsEnd("0", str.length + 1 + padTo, str + ",")
|
|
23
|
+
)
|
|
24
|
+
: str
|
|
25
|
+
const constrain = (val) => {
|
|
26
|
+
if (_.isNumber(max) && parseFloat(val.replace(",",".")) > max) return max.toString()
|
|
27
|
+
if (_.isNumber(min) && parseFloat(val.replace(",",".")) < min) return min.toString()
|
|
28
|
+
return val
|
|
29
|
+
}
|
|
30
|
+
const cleaned = (val) =>
|
|
31
|
+
clean
|
|
32
|
+
? (val.replace(/,$/,'').replace(/^0*,/,'0,') || "0")
|
|
33
|
+
: val
|
|
34
|
+
|
|
35
|
+
return (v) => {
|
|
36
|
+
const skipZero = (finalV) => v!=='0' && zeroless && finalV === '0' ? '' : finalV.replace(/^0+([^,])/,'$1')
|
|
37
|
+
const formatted = _.flow(constrain,pad,skipZero,cleaned)
|
|
38
|
+
if (_.isNumber(v)) {
|
|
39
|
+
return formatted(v.toString().replace(".",","))
|
|
40
|
+
}
|
|
41
|
+
const fixComma = (v) => v.replace(/,/g, '').replace(splitRegex, "$1,$2")
|
|
42
|
+
|
|
43
|
+
const format = () => {
|
|
44
|
+
const allowedChars = (v||"").replace(/[^\d,]/g, "")
|
|
45
|
+
const commaIndex = allowedChars.indexOf(',')
|
|
46
|
+
if (commaIndex >= 0 && commaIndex < allowedChars.length - 1 - digits) {
|
|
47
|
+
const alteredComma = fixComma(allowedChars)
|
|
48
|
+
if (_.isNumber(max) && parseFloat(alteredComma.replace(",",".")) > max) {
|
|
49
|
+
return fixComma(allowedChars.slice(0, commaIndex + 1 + digits))
|
|
50
|
+
}
|
|
51
|
+
return alteredComma
|
|
52
|
+
}
|
|
53
|
+
const simpleNumber = allowedChars.replace(singleRegex, "$1")
|
|
54
|
+
if (_.isNumber(max) && parseInt(simpleNumber) > max) {
|
|
55
|
+
return simpleNumber.slice(0, -1)
|
|
56
|
+
}
|
|
57
|
+
return simpleNumber
|
|
58
|
+
}
|
|
59
|
+
const result = format()
|
|
60
|
+
return formatted(result)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export const parseDecimalToNumber = (v) => _.isString(v) ? Number(v.replace(/\./g,'').replace(',', ".")) : (v || 0)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const getClosestOffsetScroll = (node) => {
|
|
2
|
+
if (!node) {
|
|
3
|
+
return ((document.body))
|
|
4
|
+
}
|
|
5
|
+
const overflowY = window.getComputedStyle(node).overflowY
|
|
6
|
+
const isScrollable = overflowY !== 'visible' && overflowY !== 'hidden';
|
|
7
|
+
if (isScrollable && node.scrollHeight > node.clientHeight) {
|
|
8
|
+
return node;
|
|
9
|
+
} else {
|
|
10
|
+
return getClosestOffsetScroll((node.offsetParent));
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {useEffect} from 'react'
|
|
2
|
+
|
|
3
|
+
export const useEventListener = (eventName,callback,deps = []) => {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
window.addEventListener(eventName,callback)
|
|
6
|
+
return () => window.removeEventListener(eventName,callback)
|
|
7
|
+
},deps)
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const useEventListenerIf = (check,eventName,callback,deps = []) => {
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (!check()) return
|
|
14
|
+
window.addEventListener(eventName,callback)
|
|
15
|
+
return () => window.removeEventListener(eventName,callback)
|
|
16
|
+
},deps)
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const useEventListenerFor = (element,eventName,callback,deps = []) => {
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
element.addEventListener(eventName,callback)
|
|
23
|
+
return () => element.removeEventListener(eventName,callback)
|
|
24
|
+
},deps.concat(element))
|
|
25
|
+
|
|
26
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export * from './promiseUtils'
|
|
2
|
+
export * from './getClosestOffsetScroll'
|
|
3
|
+
export * from './smoothScroll'
|
|
4
|
+
export * from './fixMediaQuery'
|
|
5
|
+
export * from './FetchUtils'
|
|
6
|
+
export * from './styled'
|
|
7
|
+
export * from './formatDate'
|
|
8
|
+
export * from './lodashUtils'
|
|
9
|
+
export * from './ActionUtils'
|
|
10
|
+
export * from './reduceUtils'
|
|
11
|
+
export * from './reactUtils'
|
|
12
|
+
export * from './hooks/useEventListener'
|
|
13
|
+
export * from './utils'
|
|
14
|
+
export * from './createPressEvent'
|
|
15
|
+
export * from './wrapLazy'
|
|
16
|
+
export * from './timeUtils'
|
|
17
|
+
export * from './timerUtils'
|
|
18
|
+
export * from './formatUtils'
|
|
19
|
+
|