@tanwan/utils 1.0.0 → 1.2.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/CHANGELOG.md +19 -0
- package/dist/addClass.cjs +19 -0
- package/dist/addClass.d.cts +16 -0
- package/dist/addClass.d.ts +17 -0
- package/dist/addClass.js +19 -0
- package/dist/{string/camelCase.cjs → camelCase.cjs} +0 -1
- package/dist/{string/camelCase.d.cts → camelCase.d.cts} +1 -2
- package/dist/{string/camelCase.d.ts → camelCase.d.ts} +1 -2
- package/dist/{string/camelCase.js → camelCase.js} +0 -3
- package/dist/{string/capitalize.cjs → capitalize.cjs} +1 -1
- package/dist/{string/capitalize.d.cts → capitalize.d.cts} +2 -3
- package/dist/{string/capitalize.d.ts → capitalize.d.ts} +2 -3
- package/dist/{string/capitalize.js → capitalize.js} +1 -3
- package/dist/{array/chunk.cjs → chunk.cjs} +1 -1
- package/dist/{array/chunk.d.cts → chunk.d.cts} +2 -3
- package/dist/{array/chunk.d.ts → chunk.d.ts} +2 -3
- package/dist/{array/chunk.js → chunk.js} +1 -3
- package/dist/{number/clamp.cjs → clamp.cjs} +1 -1
- package/dist/{number/clamp.d.cts → clamp.d.cts} +2 -3
- package/dist/{number/clamp.d.ts → clamp.d.ts} +2 -3
- package/dist/{number/clamp.js → clamp.js} +1 -3
- package/dist/convertCurrencyToChinese.cjs +56 -0
- package/dist/convertCurrencyToChinese.d.cts +18 -0
- package/dist/convertCurrencyToChinese.d.ts +19 -0
- package/dist/convertCurrencyToChinese.js +56 -0
- package/dist/copyToClipboard.cjs +38 -0
- package/dist/copyToClipboard.d.cts +17 -0
- package/dist/copyToClipboard.d.ts +18 -0
- package/dist/copyToClipboard.js +38 -0
- package/dist/createElement.cjs +27 -0
- package/dist/createElement.d.cts +21 -0
- package/dist/createElement.d.ts +22 -0
- package/dist/createElement.js +27 -0
- package/dist/{function/debounce.cjs → debounce.cjs} +1 -1
- package/dist/{function/debounce.d.cts → debounce.d.cts} +2 -3
- package/dist/{function/debounce.d.ts → debounce.d.ts} +2 -3
- package/dist/{function/debounce.js → debounce.js} +1 -3
- package/dist/debounceSubmit.cjs +34 -0
- package/dist/debounceSubmit.d.cts +22 -0
- package/dist/debounceSubmit.d.ts +23 -0
- package/dist/debounceSubmit.js +34 -0
- package/dist/decodeBase64.cjs +19 -0
- package/dist/decodeBase64.d.cts +16 -0
- package/dist/decodeBase64.d.ts +17 -0
- package/dist/decodeBase64.js +19 -0
- package/dist/{base/deepClone.cjs → deepClone.cjs} +3 -3
- package/dist/{base/deepClone.d.cts → deepClone.d.cts} +2 -3
- package/dist/{base/deepClone.d.ts → deepClone.d.ts} +2 -3
- package/dist/{base/deepClone.js → deepClone.js} +1 -3
- package/dist/deepMerge.cjs +39 -0
- package/dist/deepMerge.d.cts +25 -0
- package/dist/deepMerge.d.ts +26 -0
- package/dist/deepMerge.js +39 -0
- package/dist/delay.cjs +8 -0
- package/dist/delay.d.cts +18 -0
- package/dist/delay.d.ts +19 -0
- package/dist/delay.js +8 -0
- package/dist/difference.cjs +24 -0
- package/dist/difference.d.cts +20 -0
- package/dist/difference.d.ts +21 -0
- package/dist/difference.js +24 -0
- package/dist/downloadFile.cjs +31 -0
- package/dist/downloadFile.d.cts +20 -0
- package/dist/downloadFile.d.ts +21 -0
- package/dist/downloadFile.js +31 -0
- package/dist/encodeBase64.cjs +20 -0
- package/dist/encodeBase64.d.cts +17 -0
- package/dist/encodeBase64.d.ts +18 -0
- package/dist/encodeBase64.js +20 -0
- package/dist/{array/flatten.cjs → flatten.cjs} +1 -1
- package/dist/{array/flatten.d.cts → flatten.d.cts} +2 -3
- package/dist/{array/flatten.d.ts → flatten.d.ts} +2 -3
- package/dist/{array/flatten.js → flatten.js} +1 -3
- package/dist/formatBankCard.cjs +19 -0
- package/dist/formatBankCard.d.cts +16 -0
- package/dist/formatBankCard.d.ts +17 -0
- package/dist/formatBankCard.js +19 -0
- package/dist/formatCurrency.cjs +7 -0
- package/dist/formatCurrency.d.cts +27 -0
- package/dist/formatCurrency.d.ts +28 -0
- package/dist/formatCurrency.js +7 -0
- package/dist/{date/formatDate.cjs → formatDate.cjs} +1 -1
- package/dist/{date/formatDate.d.cts → formatDate.d.cts} +2 -3
- package/dist/{date/formatDate.d.ts → formatDate.d.ts} +2 -3
- package/dist/{date/formatDate.js → formatDate.js} +1 -3
- package/dist/formatFileSize.cjs +33 -0
- package/dist/formatFileSize.d.cts +19 -0
- package/dist/formatFileSize.d.ts +20 -0
- package/dist/formatFileSize.js +33 -0
- package/dist/formatIdCard.cjs +21 -0
- package/dist/formatIdCard.d.cts +17 -0
- package/dist/formatIdCard.d.ts +18 -0
- package/dist/formatIdCard.js +21 -0
- package/dist/formatPhone.cjs +21 -0
- package/dist/formatPhone.d.cts +17 -0
- package/dist/formatPhone.d.ts +18 -0
- package/dist/formatPhone.js +21 -0
- package/dist/{number/formatThousands.cjs → formatThousands.cjs} +1 -1
- package/dist/{number/formatThousands.d.cts → formatThousands.d.cts} +2 -3
- package/dist/{number/formatThousands.d.ts → formatThousands.d.ts} +2 -3
- package/dist/{number/formatThousands.js → formatThousands.js} +1 -3
- package/dist/generateCode.cjs +29 -0
- package/dist/generateCode.d.cts +19 -0
- package/dist/generateCode.d.ts +20 -0
- package/dist/generateCode.js +29 -0
- package/dist/getAge.cjs +30 -0
- package/dist/getAge.d.cts +18 -0
- package/dist/getAge.d.ts +19 -0
- package/dist/getAge.js +30 -0
- package/dist/getByPath.cjs +29 -0
- package/dist/getByPath.d.cts +20 -0
- package/dist/getByPath.d.ts +21 -0
- package/dist/getByPath.js +29 -0
- package/dist/getCssVar.cjs +22 -0
- package/dist/getCssVar.d.cts +18 -0
- package/dist/getCssVar.d.ts +19 -0
- package/dist/getCssVar.js +22 -0
- package/dist/{date/getRelativeTime.cjs → getRelativeTime.cjs} +1 -1
- package/dist/{date/getRelativeTime.d.cts → getRelativeTime.d.cts} +2 -3
- package/dist/{date/getRelativeTime.d.ts → getRelativeTime.d.ts} +2 -3
- package/dist/{date/getRelativeTime.js → getRelativeTime.js} +1 -3
- package/dist/getScrollTop.cjs +28 -0
- package/dist/getScrollTop.d.cts +18 -0
- package/dist/getScrollTop.d.ts +19 -0
- package/dist/getScrollTop.js +28 -0
- package/dist/getStorage.cjs +27 -0
- package/dist/getStorage.d.cts +18 -0
- package/dist/getStorage.d.ts +19 -0
- package/dist/getStorage.js +27 -0
- package/dist/getStyle.cjs +20 -0
- package/dist/getStyle.d.cts +17 -0
- package/dist/getStyle.d.ts +18 -0
- package/dist/getStyle.js +20 -0
- package/dist/getTextWidth.cjs +26 -0
- package/dist/getTextWidth.d.cts +16 -0
- package/dist/getTextWidth.d.ts +17 -0
- package/dist/getTextWidth.js +26 -0
- package/dist/groupBy.cjs +36 -0
- package/dist/groupBy.d.cts +26 -0
- package/dist/groupBy.d.ts +27 -0
- package/dist/groupBy.js +36 -0
- package/dist/hasClass.cjs +19 -0
- package/dist/hasClass.d.cts +16 -0
- package/dist/hasClass.d.ts +17 -0
- package/dist/hasClass.js +19 -0
- package/dist/index.cjs +180 -36
- package/dist/index.d.cts +91 -19
- package/dist/index.d.ts +91 -19
- package/dist/index.iife.js +1 -1
- package/dist/index.js +91 -19
- package/dist/insertAfter.cjs +19 -0
- package/dist/insertAfter.d.cts +15 -0
- package/dist/insertAfter.d.ts +16 -0
- package/dist/insertAfter.js +19 -0
- package/dist/intersection.cjs +24 -0
- package/dist/intersection.d.cts +20 -0
- package/dist/intersection.d.ts +21 -0
- package/dist/intersection.js +24 -0
- package/dist/invert.cjs +21 -0
- package/dist/invert.d.cts +16 -0
- package/dist/invert.d.ts +17 -0
- package/dist/invert.js +21 -0
- package/dist/{base/isArray.cjs → isArray.cjs} +1 -1
- package/dist/{base/isArray.d.cts → isArray.d.cts} +2 -3
- package/dist/{base/isArray.d.ts → isArray.d.ts} +2 -3
- package/dist/{base/isArray.js → isArray.js} +1 -3
- package/dist/isBrowser.cjs +17 -0
- package/dist/isBrowser.d.cts +14 -0
- package/dist/isBrowser.d.ts +15 -0
- package/dist/isBrowser.js +17 -0
- package/dist/isDate.cjs +18 -0
- package/dist/isDate.d.cts +15 -0
- package/dist/isDate.d.ts +16 -0
- package/dist/isDate.js +18 -0
- package/dist/isEmpty.cjs +42 -0
- package/dist/isEmpty.d.cts +33 -0
- package/dist/isEmpty.d.ts +34 -0
- package/dist/isEmpty.js +42 -0
- package/dist/isFunction.cjs +19 -0
- package/dist/isFunction.d.cts +16 -0
- package/dist/isFunction.d.ts +17 -0
- package/dist/isFunction.js +19 -0
- package/dist/isInViewport.cjs +22 -0
- package/dist/isInViewport.d.cts +17 -0
- package/dist/isInViewport.d.ts +18 -0
- package/dist/isInViewport.js +22 -0
- package/dist/isNil.cjs +19 -0
- package/dist/isNil.d.cts +16 -0
- package/dist/isNil.d.ts +17 -0
- package/dist/isNil.js +19 -0
- package/dist/isNumber.cjs +19 -0
- package/dist/isNumber.d.cts +16 -0
- package/dist/isNumber.d.ts +17 -0
- package/dist/isNumber.js +19 -0
- package/dist/{base/isObject.cjs → isObject.cjs} +1 -1
- package/dist/{base/isObject.d.cts → isObject.d.cts} +2 -3
- package/dist/{base/isObject.d.ts → isObject.d.ts} +2 -3
- package/dist/{base/isObject.js → isObject.js} +1 -3
- package/dist/isPrimitive.cjs +21 -0
- package/dist/isPrimitive.d.cts +18 -0
- package/dist/isPrimitive.d.ts +19 -0
- package/dist/isPrimitive.js +21 -0
- package/dist/isPromise.cjs +18 -0
- package/dist/isPromise.d.cts +15 -0
- package/dist/isPromise.d.ts +16 -0
- package/dist/isPromise.js +18 -0
- package/dist/{base/isString.cjs → isString.cjs} +1 -1
- package/dist/{base/isString.d.cts → isString.d.cts} +2 -3
- package/dist/{base/isString.d.ts → isString.d.ts} +2 -3
- package/dist/{base/isString.js → isString.js} +1 -3
- package/dist/joinUrl.cjs +25 -0
- package/dist/joinUrl.d.cts +19 -0
- package/dist/joinUrl.d.ts +20 -0
- package/dist/joinUrl.js +25 -0
- package/dist/{string/kebabCase.d.cts → kebabCase.d.cts} +1 -2
- package/dist/{string/kebabCase.d.ts → kebabCase.d.ts} +1 -2
- package/dist/{string/kebabCase.js → kebabCase.js} +0 -2
- package/dist/lazyLoadImages.cjs +36 -0
- package/dist/lazyLoadImages.d.cts +19 -0
- package/dist/lazyLoadImages.d.ts +20 -0
- package/dist/lazyLoadImages.js +36 -0
- package/dist/listToTree.cjs +25 -0
- package/dist/listToTree.d.cts +32 -0
- package/dist/listToTree.d.ts +33 -0
- package/dist/listToTree.js +25 -0
- package/dist/mapValues.cjs +25 -0
- package/dist/mapValues.d.cts +20 -0
- package/dist/mapValues.d.ts +21 -0
- package/dist/mapValues.js +25 -0
- package/dist/maskString.cjs +28 -0
- package/dist/maskString.d.cts +24 -0
- package/dist/maskString.d.ts +25 -0
- package/dist/maskString.js +28 -0
- package/dist/memoize.cjs +32 -0
- package/dist/memoize.d.cts +22 -0
- package/dist/memoize.d.ts +23 -0
- package/dist/memoize.js +32 -0
- package/dist/off.cjs +22 -0
- package/dist/off.d.cts +19 -0
- package/dist/off.d.ts +20 -0
- package/dist/off.js +22 -0
- package/dist/omit.cjs +23 -0
- package/dist/omit.d.cts +17 -0
- package/dist/omit.d.ts +18 -0
- package/dist/omit.js +23 -0
- package/dist/on.cjs +21 -0
- package/dist/on.d.cts +18 -0
- package/dist/on.d.ts +19 -0
- package/dist/on.js +21 -0
- package/dist/once.cjs +31 -0
- package/dist/once.d.cts +20 -0
- package/dist/once.d.ts +21 -0
- package/dist/once.js +31 -0
- package/dist/parseQueryString.cjs +48 -0
- package/dist/parseQueryString.d.cts +21 -0
- package/dist/parseQueryString.d.ts +22 -0
- package/dist/parseQueryString.js +48 -0
- package/dist/pascalCase.cjs +18 -0
- package/dist/pascalCase.d.cts +15 -0
- package/dist/pascalCase.d.ts +16 -0
- package/dist/pascalCase.js +18 -0
- package/dist/pick.cjs +22 -0
- package/dist/pick.d.cts +17 -0
- package/dist/pick.d.ts +18 -0
- package/dist/pick.js +22 -0
- package/dist/{number/randomInt.cjs → randomInt.cjs} +1 -1
- package/dist/{number/randomInt.d.cts → randomInt.d.cts} +2 -3
- package/dist/{number/randomInt.d.ts → randomInt.d.ts} +2 -3
- package/dist/{number/randomInt.js → randomInt.js} +1 -3
- package/dist/range.cjs +27 -0
- package/dist/range.d.cts +20 -0
- package/dist/range.d.ts +21 -0
- package/dist/range.js +27 -0
- package/dist/removeClass.cjs +19 -0
- package/dist/removeClass.d.cts +16 -0
- package/dist/removeClass.d.ts +17 -0
- package/dist/removeClass.js +19 -0
- package/dist/removeElement.cjs +17 -0
- package/dist/removeElement.d.cts +14 -0
- package/dist/removeElement.d.ts +15 -0
- package/dist/removeElement.js +17 -0
- package/dist/removeStorage.cjs +19 -0
- package/dist/removeStorage.d.cts +14 -0
- package/dist/removeStorage.d.ts +15 -0
- package/dist/removeStorage.js +19 -0
- package/dist/retry.cjs +27 -0
- package/dist/retry.d.cts +17 -0
- package/dist/retry.d.ts +18 -0
- package/dist/retry.js +27 -0
- package/dist/sample.cjs +20 -0
- package/dist/sample.d.cts +16 -0
- package/dist/sample.d.ts +17 -0
- package/dist/sample.js +20 -0
- package/dist/scrollToElement.cjs +23 -0
- package/dist/scrollToElement.d.cts +16 -0
- package/dist/scrollToElement.d.ts +17 -0
- package/dist/scrollToElement.js +23 -0
- package/dist/setCssVar.cjs +22 -0
- package/dist/setCssVar.d.cts +18 -0
- package/dist/setCssVar.d.ts +19 -0
- package/dist/setCssVar.js +22 -0
- package/dist/setStorage.cjs +25 -0
- package/dist/setStorage.d.cts +17 -0
- package/dist/setStorage.d.ts +18 -0
- package/dist/setStorage.js +25 -0
- package/dist/setStyle.cjs +22 -0
- package/dist/setStyle.d.cts +19 -0
- package/dist/setStyle.d.ts +20 -0
- package/dist/setStyle.js +22 -0
- package/dist/{array/shuffle.cjs → shuffle.cjs} +1 -1
- package/dist/{array/shuffle.d.cts → shuffle.d.cts} +2 -3
- package/dist/{array/shuffle.d.ts → shuffle.d.ts} +2 -3
- package/dist/{array/shuffle.js → shuffle.js} +1 -3
- package/dist/snakeCase.cjs +18 -0
- package/dist/snakeCase.d.cts +15 -0
- package/dist/snakeCase.d.ts +16 -0
- package/dist/snakeCase.js +18 -0
- package/dist/sortBy.cjs +30 -0
- package/dist/sortBy.d.cts +20 -0
- package/dist/sortBy.d.ts +21 -0
- package/dist/sortBy.js +30 -0
- package/dist/stringifyQueryString.cjs +38 -0
- package/dist/stringifyQueryString.d.cts +21 -0
- package/dist/stringifyQueryString.d.ts +22 -0
- package/dist/stringifyQueryString.js +38 -0
- package/dist/{function/throttle.cjs → throttle.cjs} +1 -1
- package/dist/{function/throttle.d.cts → throttle.d.cts} +2 -3
- package/dist/{function/throttle.d.ts → throttle.d.ts} +2 -3
- package/dist/{function/throttle.js → throttle.js} +1 -3
- package/dist/toggleClass.cjs +22 -0
- package/dist/toggleClass.d.cts +19 -0
- package/dist/toggleClass.d.ts +20 -0
- package/dist/toggleClass.js +22 -0
- package/dist/treeFind.cjs +34 -0
- package/dist/treeFind.d.cts +25 -0
- package/dist/treeFind.d.ts +26 -0
- package/dist/treeFind.js +34 -0
- package/dist/treeToList.cjs +33 -0
- package/dist/treeToList.d.cts +24 -0
- package/dist/treeToList.d.ts +25 -0
- package/dist/treeToList.js +33 -0
- package/dist/truncate.cjs +23 -0
- package/dist/truncate.d.cts +19 -0
- package/dist/truncate.d.ts +20 -0
- package/dist/truncate.js +23 -0
- package/dist/uniqBy.cjs +30 -0
- package/dist/uniqBy.d.cts +20 -0
- package/dist/uniqBy.d.ts +21 -0
- package/dist/uniqBy.js +30 -0
- package/dist/{array/unique.cjs → unique.cjs} +1 -1
- package/dist/{array/unique.d.cts → unique.d.cts} +2 -3
- package/dist/{array/unique.d.ts → unique.d.ts} +2 -3
- package/dist/{array/unique.js → unique.js} +1 -3
- package/dist/uuid.cjs +23 -0
- package/dist/uuid.d.cts +16 -0
- package/dist/uuid.d.ts +17 -0
- package/dist/uuid.js +23 -0
- package/dist/validateEmail.cjs +19 -0
- package/dist/validateEmail.d.cts +16 -0
- package/dist/validateEmail.d.ts +17 -0
- package/dist/validateEmail.js +19 -0
- package/dist/validateIdCard.cjs +62 -0
- package/dist/validateIdCard.d.cts +15 -0
- package/dist/validateIdCard.d.ts +16 -0
- package/dist/validateIdCard.js +62 -0
- package/dist/validatePhone.cjs +19 -0
- package/dist/validatePhone.d.cts +16 -0
- package/dist/validatePhone.d.ts +17 -0
- package/dist/validatePhone.js +19 -0
- package/package.json +351 -58
- package/dist/array/chunk.d.cts.map +0 -1
- package/dist/array/chunk.d.ts.map +0 -1
- package/dist/array/chunk.js.map +0 -1
- package/dist/array/flatten.d.cts.map +0 -1
- package/dist/array/flatten.d.ts.map +0 -1
- package/dist/array/flatten.js.map +0 -1
- package/dist/array/shuffle.d.cts.map +0 -1
- package/dist/array/shuffle.d.ts.map +0 -1
- package/dist/array/shuffle.js.map +0 -1
- package/dist/array/unique.d.cts.map +0 -1
- package/dist/array/unique.d.ts.map +0 -1
- package/dist/array/unique.js.map +0 -1
- package/dist/base/deepClone.d.cts.map +0 -1
- package/dist/base/deepClone.d.ts.map +0 -1
- package/dist/base/deepClone.js.map +0 -1
- package/dist/base/isArray.d.cts.map +0 -1
- package/dist/base/isArray.d.ts.map +0 -1
- package/dist/base/isArray.js.map +0 -1
- package/dist/base/isObject.d.cts.map +0 -1
- package/dist/base/isObject.d.ts.map +0 -1
- package/dist/base/isObject.js.map +0 -1
- package/dist/base/isString.d.cts.map +0 -1
- package/dist/base/isString.d.ts.map +0 -1
- package/dist/base/isString.js.map +0 -1
- package/dist/date/formatDate.d.cts.map +0 -1
- package/dist/date/formatDate.d.ts.map +0 -1
- package/dist/date/formatDate.js.map +0 -1
- package/dist/date/getRelativeTime.d.cts.map +0 -1
- package/dist/date/getRelativeTime.d.ts.map +0 -1
- package/dist/date/getRelativeTime.js.map +0 -1
- package/dist/function/debounce.d.cts.map +0 -1
- package/dist/function/debounce.d.ts.map +0 -1
- package/dist/function/debounce.js.map +0 -1
- package/dist/function/throttle.d.cts.map +0 -1
- package/dist/function/throttle.d.ts.map +0 -1
- package/dist/function/throttle.js.map +0 -1
- package/dist/number/clamp.d.cts.map +0 -1
- package/dist/number/clamp.d.ts.map +0 -1
- package/dist/number/clamp.js.map +0 -1
- package/dist/number/formatThousands.d.cts.map +0 -1
- package/dist/number/formatThousands.d.ts.map +0 -1
- package/dist/number/formatThousands.js.map +0 -1
- package/dist/number/randomInt.d.cts.map +0 -1
- package/dist/number/randomInt.d.ts.map +0 -1
- package/dist/number/randomInt.js.map +0 -1
- package/dist/string/camelCase.d.cts.map +0 -1
- package/dist/string/camelCase.d.ts.map +0 -1
- package/dist/string/camelCase.js.map +0 -1
- package/dist/string/capitalize.d.cts.map +0 -1
- package/dist/string/capitalize.d.ts.map +0 -1
- package/dist/string/capitalize.js.map +0 -1
- package/dist/string/kebabCase.d.cts.map +0 -1
- package/dist/string/kebabCase.d.ts.map +0 -1
- package/dist/string/kebabCase.js.map +0 -1
- /package/dist/{string/kebabCase.cjs → kebabCase.cjs} +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/storage/getStorage/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* 安全地从 localStorage 读取并解析 JSON
|
|
4
|
+
*
|
|
5
|
+
* @param key - 存储键名
|
|
6
|
+
* @param defaultValue - 读取失败或不存在时的默认值
|
|
7
|
+
* @returns 解析后的值或默认值
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getStorage from '@tanwan/utils/getStorage'
|
|
12
|
+
* localStorage.setItem('user', '{"name":"Alice"}')
|
|
13
|
+
* getStorage('user') // { name: 'Alice' }
|
|
14
|
+
* getStorage('notExist', 'default') // 'default'
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function getStorage(key, defaultValue) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = localStorage.getItem(key);
|
|
20
|
+
if (raw === null) return defaultValue ?? null;
|
|
21
|
+
return JSON.parse(raw);
|
|
22
|
+
} catch {
|
|
23
|
+
return defaultValue ?? null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
module.exports = getStorage;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/storage/getStorage/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 安全地从 localStorage 读取并解析 JSON
|
|
4
|
+
*
|
|
5
|
+
* @param key - 存储键名
|
|
6
|
+
* @param defaultValue - 读取失败或不存在时的默认值
|
|
7
|
+
* @returns 解析后的值或默认值
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getStorage from '@tanwan/utils/getStorage'
|
|
12
|
+
* localStorage.setItem('user', '{"name":"Alice"}')
|
|
13
|
+
* getStorage('user') // { name: 'Alice' }
|
|
14
|
+
* getStorage('notExist', 'default') // 'default'
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
declare function getStorage<T = unknown>(key: string, defaultValue?: T): T | null;
|
|
18
|
+
export = getStorage;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/storage/getStorage/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 安全地从 localStorage 读取并解析 JSON
|
|
4
|
+
*
|
|
5
|
+
* @param key - 存储键名
|
|
6
|
+
* @param defaultValue - 读取失败或不存在时的默认值
|
|
7
|
+
* @returns 解析后的值或默认值
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getStorage from '@tanwan/utils/getStorage'
|
|
12
|
+
* localStorage.setItem('user', '{"name":"Alice"}')
|
|
13
|
+
* getStorage('user') // { name: 'Alice' }
|
|
14
|
+
* getStorage('notExist', 'default') // 'default'
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
declare function getStorage<T = unknown>(key: string, defaultValue?: T): T | null;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { getStorage as default };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/storage/getStorage/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* 安全地从 localStorage 读取并解析 JSON
|
|
4
|
+
*
|
|
5
|
+
* @param key - 存储键名
|
|
6
|
+
* @param defaultValue - 读取失败或不存在时的默认值
|
|
7
|
+
* @returns 解析后的值或默认值
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getStorage from '@tanwan/utils/getStorage'
|
|
12
|
+
* localStorage.setItem('user', '{"name":"Alice"}')
|
|
13
|
+
* getStorage('user') // { name: 'Alice' }
|
|
14
|
+
* getStorage('notExist', 'default') // 'default'
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function getStorage(key, defaultValue) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = localStorage.getItem(key);
|
|
20
|
+
if (raw === null) return defaultValue ?? null;
|
|
21
|
+
return JSON.parse(raw);
|
|
22
|
+
} catch {
|
|
23
|
+
return defaultValue ?? null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { getStorage as default };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/dom/getStyle/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* 获取元素的计算样式
|
|
4
|
+
*
|
|
5
|
+
* @param el - DOM 元素
|
|
6
|
+
* @param property - CSS 属性名(camelCase),如 `'fontSize'`
|
|
7
|
+
* @returns 计算后的样式值
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getStyle from '@tanwan/utils/getStyle'
|
|
12
|
+
* getStyle(el, 'fontSize') // '16px'
|
|
13
|
+
* getStyle(el, 'color') // 'rgb(0, 0, 0)'
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
function getStyle(el, property) {
|
|
17
|
+
return window.getComputedStyle(el).getPropertyValue(property);
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
module.exports = getStyle;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/dom/getStyle/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 获取元素的计算样式
|
|
4
|
+
*
|
|
5
|
+
* @param el - DOM 元素
|
|
6
|
+
* @param property - CSS 属性名(camelCase),如 `'fontSize'`
|
|
7
|
+
* @returns 计算后的样式值
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getStyle from '@tanwan/utils/getStyle'
|
|
12
|
+
* getStyle(el, 'fontSize') // '16px'
|
|
13
|
+
* getStyle(el, 'color') // 'rgb(0, 0, 0)'
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare function getStyle(el: Element, property: string): string;
|
|
17
|
+
export = getStyle;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/dom/getStyle/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 获取元素的计算样式
|
|
4
|
+
*
|
|
5
|
+
* @param el - DOM 元素
|
|
6
|
+
* @param property - CSS 属性名(camelCase),如 `'fontSize'`
|
|
7
|
+
* @returns 计算后的样式值
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getStyle from '@tanwan/utils/getStyle'
|
|
12
|
+
* getStyle(el, 'fontSize') // '16px'
|
|
13
|
+
* getStyle(el, 'color') // 'rgb(0, 0, 0)'
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare function getStyle(el: Element, property: string): string;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { getStyle as default };
|
package/dist/getStyle.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/dom/getStyle/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* 获取元素的计算样式
|
|
4
|
+
*
|
|
5
|
+
* @param el - DOM 元素
|
|
6
|
+
* @param property - CSS 属性名(camelCase),如 `'fontSize'`
|
|
7
|
+
* @returns 计算后的样式值
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getStyle from '@tanwan/utils/getStyle'
|
|
12
|
+
* getStyle(el, 'fontSize') // '16px'
|
|
13
|
+
* getStyle(el, 'color') // 'rgb(0, 0, 0)'
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
function getStyle(el, property) {
|
|
17
|
+
return window.getComputedStyle(el).getPropertyValue(property);
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { getStyle as default };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/dom/getTextWidth/index.ts
|
|
2
|
+
let ctx = null;
|
|
3
|
+
function getContext() {
|
|
4
|
+
if (!ctx) ctx = document.createElement("canvas").getContext("2d");
|
|
5
|
+
return ctx;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 获取文本渲染宽度(canvas 测量)
|
|
9
|
+
*
|
|
10
|
+
* @param text - 待测量文本
|
|
11
|
+
* @param font - CSS font 字符串,如 `'bold 16px sans-serif'`
|
|
12
|
+
* @returns 文本宽度(px)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import getTextWidth from '@tanwan/utils/getTextWidth'
|
|
17
|
+
* getTextWidth('Hello World', '16px Arial')
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
function getTextWidth(text, font) {
|
|
21
|
+
const context = getContext();
|
|
22
|
+
context.font = font;
|
|
23
|
+
return context.measureText(text).width;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
module.exports = getTextWidth;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/dom/getTextWidth/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 获取文本渲染宽度(canvas 测量)
|
|
4
|
+
*
|
|
5
|
+
* @param text - 待测量文本
|
|
6
|
+
* @param font - CSS font 字符串,如 `'bold 16px sans-serif'`
|
|
7
|
+
* @returns 文本宽度(px)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getTextWidth from '@tanwan/utils/getTextWidth'
|
|
12
|
+
* getTextWidth('Hello World', '16px Arial')
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
declare function getTextWidth(text: string, font: string): number;
|
|
16
|
+
export = getTextWidth;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/dom/getTextWidth/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 获取文本渲染宽度(canvas 测量)
|
|
4
|
+
*
|
|
5
|
+
* @param text - 待测量文本
|
|
6
|
+
* @param font - CSS font 字符串,如 `'bold 16px sans-serif'`
|
|
7
|
+
* @returns 文本宽度(px)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import getTextWidth from '@tanwan/utils/getTextWidth'
|
|
12
|
+
* getTextWidth('Hello World', '16px Arial')
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
declare function getTextWidth(text: string, font: string): number;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { getTextWidth as default };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/dom/getTextWidth/index.ts
|
|
2
|
+
let ctx = null;
|
|
3
|
+
function getContext() {
|
|
4
|
+
if (!ctx) ctx = document.createElement("canvas").getContext("2d");
|
|
5
|
+
return ctx;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 获取文本渲染宽度(canvas 测量)
|
|
9
|
+
*
|
|
10
|
+
* @param text - 待测量文本
|
|
11
|
+
* @param font - CSS font 字符串,如 `'bold 16px sans-serif'`
|
|
12
|
+
* @returns 文本宽度(px)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import getTextWidth from '@tanwan/utils/getTextWidth'
|
|
17
|
+
* getTextWidth('Hello World', '16px Arial')
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
function getTextWidth(text, font) {
|
|
21
|
+
const context = getContext();
|
|
22
|
+
context.font = font;
|
|
23
|
+
return context.measureText(text).width;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { getTextWidth as default };
|
package/dist/groupBy.cjs
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/array/groupBy/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* 根据指定的 key 或迭代函数对数组进行分组
|
|
4
|
+
*
|
|
5
|
+
* @param arr - 待分组的数组
|
|
6
|
+
* @param iteratee - 分组依据:可以是属性名或返回分组 key 的函数
|
|
7
|
+
* @returns 分组后的对象
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import groupBy from '@tanwan/utils/groupBy'
|
|
12
|
+
* // 按属性名分组
|
|
13
|
+
* groupBy([{ type: 'a', val: 1 }, { type: 'b', val: 2 }, { type: 'a', val: 3 }], 'type')
|
|
14
|
+
* // { a: [{ type: 'a', val: 1 }, { type: 'a', val: 3 }], b: [{ type: 'b', val: 2 }] }
|
|
15
|
+
*
|
|
16
|
+
* // 按函数分组
|
|
17
|
+
* groupBy([1.2, 2.3, 3.4], Math.floor)
|
|
18
|
+
* // { 1: [1.2], 2: [2.3], 3: [3.4] }
|
|
19
|
+
*
|
|
20
|
+
* // 按条件分组
|
|
21
|
+
* groupBy([1, 2, 3, 4, 5], (n) => (n % 2 === 0 ? 'even' : 'odd'))
|
|
22
|
+
* // { even: [2, 4], odd: [1, 3, 5] }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function groupBy(arr, iteratee) {
|
|
26
|
+
const result = {};
|
|
27
|
+
const getKey = typeof iteratee === "function" ? iteratee : (item) => String(item[iteratee]);
|
|
28
|
+
for (const item of arr) {
|
|
29
|
+
const key = String(getKey(item));
|
|
30
|
+
if (!result[key]) result[key] = [];
|
|
31
|
+
result[key].push(item);
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
module.exports = groupBy;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/array/groupBy/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 根据指定的 key 或迭代函数对数组进行分组
|
|
4
|
+
*
|
|
5
|
+
* @param arr - 待分组的数组
|
|
6
|
+
* @param iteratee - 分组依据:可以是属性名或返回分组 key 的函数
|
|
7
|
+
* @returns 分组后的对象
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import groupBy from '@tanwan/utils/groupBy'
|
|
12
|
+
* // 按属性名分组
|
|
13
|
+
* groupBy([{ type: 'a', val: 1 }, { type: 'b', val: 2 }, { type: 'a', val: 3 }], 'type')
|
|
14
|
+
* // { a: [{ type: 'a', val: 1 }, { type: 'a', val: 3 }], b: [{ type: 'b', val: 2 }] }
|
|
15
|
+
*
|
|
16
|
+
* // 按函数分组
|
|
17
|
+
* groupBy([1.2, 2.3, 3.4], Math.floor)
|
|
18
|
+
* // { 1: [1.2], 2: [2.3], 3: [3.4] }
|
|
19
|
+
*
|
|
20
|
+
* // 按条件分组
|
|
21
|
+
* groupBy([1, 2, 3, 4, 5], (n) => (n % 2 === 0 ? 'even' : 'odd'))
|
|
22
|
+
* // { even: [2, 4], odd: [1, 3, 5] }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare function groupBy<T>(arr: T[], iteratee: keyof T | ((item: T) => string | number)): Record<string, T[]>;
|
|
26
|
+
export = groupBy;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/array/groupBy/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 根据指定的 key 或迭代函数对数组进行分组
|
|
4
|
+
*
|
|
5
|
+
* @param arr - 待分组的数组
|
|
6
|
+
* @param iteratee - 分组依据:可以是属性名或返回分组 key 的函数
|
|
7
|
+
* @returns 分组后的对象
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import groupBy from '@tanwan/utils/groupBy'
|
|
12
|
+
* // 按属性名分组
|
|
13
|
+
* groupBy([{ type: 'a', val: 1 }, { type: 'b', val: 2 }, { type: 'a', val: 3 }], 'type')
|
|
14
|
+
* // { a: [{ type: 'a', val: 1 }, { type: 'a', val: 3 }], b: [{ type: 'b', val: 2 }] }
|
|
15
|
+
*
|
|
16
|
+
* // 按函数分组
|
|
17
|
+
* groupBy([1.2, 2.3, 3.4], Math.floor)
|
|
18
|
+
* // { 1: [1.2], 2: [2.3], 3: [3.4] }
|
|
19
|
+
*
|
|
20
|
+
* // 按条件分组
|
|
21
|
+
* groupBy([1, 2, 3, 4, 5], (n) => (n % 2 === 0 ? 'even' : 'odd'))
|
|
22
|
+
* // { even: [2, 4], odd: [1, 3, 5] }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare function groupBy<T>(arr: T[], iteratee: keyof T | ((item: T) => string | number)): Record<string, T[]>;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { groupBy as default };
|
package/dist/groupBy.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/array/groupBy/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* 根据指定的 key 或迭代函数对数组进行分组
|
|
4
|
+
*
|
|
5
|
+
* @param arr - 待分组的数组
|
|
6
|
+
* @param iteratee - 分组依据:可以是属性名或返回分组 key 的函数
|
|
7
|
+
* @returns 分组后的对象
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import groupBy from '@tanwan/utils/groupBy'
|
|
12
|
+
* // 按属性名分组
|
|
13
|
+
* groupBy([{ type: 'a', val: 1 }, { type: 'b', val: 2 }, { type: 'a', val: 3 }], 'type')
|
|
14
|
+
* // { a: [{ type: 'a', val: 1 }, { type: 'a', val: 3 }], b: [{ type: 'b', val: 2 }] }
|
|
15
|
+
*
|
|
16
|
+
* // 按函数分组
|
|
17
|
+
* groupBy([1.2, 2.3, 3.4], Math.floor)
|
|
18
|
+
* // { 1: [1.2], 2: [2.3], 3: [3.4] }
|
|
19
|
+
*
|
|
20
|
+
* // 按条件分组
|
|
21
|
+
* groupBy([1, 2, 3, 4, 5], (n) => (n % 2 === 0 ? 'even' : 'odd'))
|
|
22
|
+
* // { even: [2, 4], odd: [1, 3, 5] }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function groupBy(arr, iteratee) {
|
|
26
|
+
const result = {};
|
|
27
|
+
const getKey = typeof iteratee === "function" ? iteratee : (item) => String(item[iteratee]);
|
|
28
|
+
for (const item of arr) {
|
|
29
|
+
const key = String(getKey(item));
|
|
30
|
+
if (!result[key]) result[key] = [];
|
|
31
|
+
result[key].push(item);
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { groupBy as default };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/dom/hasClass/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* 判断元素是否包含指定 CSS class
|
|
4
|
+
*
|
|
5
|
+
* @param el - DOM 元素
|
|
6
|
+
* @param className - CSS class 名称
|
|
7
|
+
* @returns 是否包含
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import hasClass from '@tanwan/utils/hasClass'
|
|
12
|
+
* hasClass(document.getElementById('box'), 'active')
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
function hasClass(el, className) {
|
|
16
|
+
return el.classList.contains(className);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
module.exports = hasClass;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/dom/hasClass/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 判断元素是否包含指定 CSS class
|
|
4
|
+
*
|
|
5
|
+
* @param el - DOM 元素
|
|
6
|
+
* @param className - CSS class 名称
|
|
7
|
+
* @returns 是否包含
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import hasClass from '@tanwan/utils/hasClass'
|
|
12
|
+
* hasClass(document.getElementById('box'), 'active')
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
declare function hasClass(el: Element, className: string): boolean;
|
|
16
|
+
export = hasClass;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/dom/hasClass/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 判断元素是否包含指定 CSS class
|
|
4
|
+
*
|
|
5
|
+
* @param el - DOM 元素
|
|
6
|
+
* @param className - CSS class 名称
|
|
7
|
+
* @returns 是否包含
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import hasClass from '@tanwan/utils/hasClass'
|
|
12
|
+
* hasClass(document.getElementById('box'), 'active')
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
declare function hasClass(el: Element, className: string): boolean;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { hasClass as default };
|
package/dist/hasClass.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/dom/hasClass/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* 判断元素是否包含指定 CSS class
|
|
4
|
+
*
|
|
5
|
+
* @param el - DOM 元素
|
|
6
|
+
* @param className - CSS class 名称
|
|
7
|
+
* @returns 是否包含
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import hasClass from '@tanwan/utils/hasClass'
|
|
12
|
+
* hasClass(document.getElementById('box'), 'active')
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
function hasClass(el, className) {
|
|
16
|
+
return el.classList.contains(className);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { hasClass as default };
|