@koine/react 2.0.0-beta.80 → 2.0.0-beta.83

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.
Files changed (63) hide show
  1. package/FaviconTags.cjs.js +10 -3
  2. package/FaviconTags.esm.js +10 -3
  3. package/Meta.cjs.js +10 -3
  4. package/Meta.esm.js +10 -3
  5. package/NoJs.cjs.js +1 -5
  6. package/NoJs.esm.js +1 -5
  7. package/calendar.cjs.js +97 -534
  8. package/calendar.esm.js +97 -534
  9. package/classed.cjs.js +42 -39
  10. package/classed.esm.js +42 -39
  11. package/createUseMediaQueryWidth.cjs.js +15 -34
  12. package/createUseMediaQueryWidth.d.ts +1 -1
  13. package/createUseMediaQueryWidth.esm.js +15 -34
  14. package/extendComponent.cjs.js +5 -7
  15. package/extendComponent.d.ts +1 -1
  16. package/extendComponent.esm.js +5 -7
  17. package/forms/antispam.d.ts +1 -1
  18. package/forms.cjs.js +27 -27
  19. package/forms.esm.js +27 -27
  20. package/mergeRefs.cjs.js +1 -12
  21. package/mergeRefs.d.ts +1 -1
  22. package/mergeRefs.esm.js +1 -12
  23. package/package.json +3 -3
  24. package/useAsyncFn.cjs.js +4 -23
  25. package/useAsyncFn.esm.js +4 -23
  26. package/useFirstMountState.cjs.js +3 -8
  27. package/useFirstMountState.esm.js +3 -8
  28. package/useFixedOffset.cjs.js +12 -37
  29. package/useFixedOffset.esm.js +13 -38
  30. package/useFocus.cjs.js +3 -7
  31. package/useFocus.esm.js +3 -7
  32. package/useInterval.cjs.js +6 -17
  33. package/useInterval.esm.js +6 -17
  34. package/useIsomorphicLayoutEffect.cjs.js +3 -1
  35. package/useIsomorphicLayoutEffect.esm.js +3 -1
  36. package/useKeyUp.cjs.js +6 -13
  37. package/useKeyUp.esm.js +6 -13
  38. package/useMeasure.cjs.js +33 -115
  39. package/useMeasure.esm.js +33 -115
  40. package/useMountedState.cjs.js +3 -11
  41. package/useMountedState.esm.js +3 -11
  42. package/useNavigateAway.cjs.js +47 -22
  43. package/useNavigateAway.esm.js +47 -22
  44. package/usePrevious.cjs.js +1 -7
  45. package/usePrevious.esm.js +1 -7
  46. package/usePreviousRef.cjs.js +1 -7
  47. package/usePreviousRef.esm.js +1 -7
  48. package/useScrollPosition.cjs.js +7 -53
  49. package/useScrollPosition.esm.js +7 -53
  50. package/useScrollThreshold.cjs.js +4 -22
  51. package/useScrollThreshold.esm.js +4 -22
  52. package/useScrollTo.cjs.js +3 -16
  53. package/useScrollTo.esm.js +3 -16
  54. package/useSmoothScroll.cjs.js +6 -27
  55. package/useSmoothScroll.esm.js +6 -27
  56. package/useSpinDelay.cjs.js +12 -34
  57. package/useSpinDelay.esm.js +12 -34
  58. package/useTraceUpdate.cjs.js +4 -15
  59. package/useTraceUpdate.esm.js +4 -15
  60. package/useUpdateEffect.cjs.js +4 -8
  61. package/useUpdateEffect.esm.js +4 -8
  62. package/useWindowSize.cjs.js +9 -17
  63. package/useWindowSize.esm.js +9 -17
package/classed.cjs.js CHANGED
@@ -4,45 +4,48 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var react = require('react');
6
6
 
7
- let classed = (component) => {
8
- const type = component.type || component;
9
- return function (strings, ...args) {
10
- const WrappedComponent = react.forwardRef(function (props, ref) {
11
- const argResolved = args
12
- .map((arg, index) => {
13
- let result = "";
14
- if (typeof arg === "function") {
15
- result = arg(props);
16
- }
17
- else if (typeof arg !== "undefined") {
18
- result = arg.toString();
19
- }
20
- return strings[index] + result;
21
- })
22
- .join("");
23
- const isNativeHtmlElement = typeof type === "string";
24
- const propsToForward = isNativeHtmlElement
25
- ? {}
26
- : props;
27
- if (isNativeHtmlElement) {
28
- for (const key in props) {
29
- if (!key.startsWith("$")) {
30
- propsToForward[key] = props[key];
31
- }
32
- }
33
- }
34
- let className = argResolved || strings[0];
35
- className = className.match(/class="([^"]*)/)?.[1] || className;
36
- className += props?.className ? " " + props?.className : "";
37
- return react.createElement(type, {
38
- ...propsToForward,
39
- className: className || undefined,
40
- ref,
41
- });
42
- });
43
- return WrappedComponent;
44
- };
45
- };
7
+ // React.ComponentProps<typeof Component>
8
+ // ? @see https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase/#props-extracting-prop-types-of-a-component
9
+ // type ClassedComponent<Props = {}> =
10
+ // | React.ElementType<Props>
11
+ // | OverridableComponent<any>
12
+ // | React.Component<Props>
13
+ // | React.FunctionComponent<Props>
14
+ // | React.ReactElement<Props>
15
+ // | React.ReactHTMLElement<any>
16
+ // | string // | JSX.IntrinsicElements
17
+ // | ((props: Props) => JSX.Element);
18
+ /**
19
+ * This utility allows to extend a component a là `styled-components` but for
20
+ * a className based styling solution like Tailwind,
21
+ *
22
+ * It also plays nicely with tailwind intellisense:
23
+ * - https://github.com/tailwindlabs/tailwindcss-intellisense#tailwindcssclassattributes
24
+ *
25
+ * For references about tagged functions:
26
+ * - https://javascript.plainenglish.io/how-css-in-js-libraries-work-da4145b1b6c7
27
+ * - https://makersden.io/blog/reverse-engineering-styled-components
28
+ * - https://typesafe.blog/article/the-logic-behind-javascript-tag-functions
29
+ * - https://flaming.codes/posts/typescript-and-javascript-tagged-template-strings
30
+ *
31
+ * Similar projects:
32
+ * - https://reactjsexample.com/style-radix-ui-components-with-tailwindcss/
33
+ *
34
+ * Discussions and Q/A:
35
+ * - https://stackoverflow.com/q/73055695/1938970
36
+ */let classed=r=>{// @ts-expect-error nevermind for now...
37
+ let s=r.type||r;return function(r,...a){// FIXME: not sure if this is needed
38
+ // WrappedComponent.displayName = type.toString();
39
+ return /*#__PURE__*/react.forwardRef(// Props
40
+ function(e,n){let o=a.map((t,s)=>{let a="";return "function"==typeof t?a=t(e):void 0!==t&&(a=t.toString()),r[s]+a}).join(""),l="string"==typeof s,i=l?{}:e;if(l)for(let t in e)// like styled-components `transient` props
41
+ t.startsWith("$")||// FIXME: for react 18 we need: @ts-expect-error
42
+ (i[t]=e[t]);// get the tagged function string outcome
43
+ let c=o||r[0];return(// add the custom classes from props
44
+ c=// check if we need to clean it or not from the optional structure `< class="..."`
45
+ (c.match(/class="([^"]*)/)?.[1]||c)+(e?.className?" "+e?.className:""),/*#__PURE__*/react.createElement(s,{// ...props,
46
+ ...i,// only add ot props if it is not an empty string
47
+ className:c||void 0,// add ref to props
48
+ ref:n}))})}};// as unknown as React.ReactElement<typeof props>;
46
49
 
47
50
  exports.classed = classed;
48
51
  exports["default"] = classed;
package/classed.esm.js CHANGED
@@ -1,43 +1,46 @@
1
1
  import { forwardRef, createElement } from 'react';
2
2
 
3
- let classed = (component) => {
4
- const type = component.type || component;
5
- return function (strings, ...args) {
6
- const WrappedComponent = forwardRef(function (props, ref) {
7
- const argResolved = args
8
- .map((arg, index) => {
9
- let result = "";
10
- if (typeof arg === "function") {
11
- result = arg(props);
12
- }
13
- else if (typeof arg !== "undefined") {
14
- result = arg.toString();
15
- }
16
- return strings[index] + result;
17
- })
18
- .join("");
19
- const isNativeHtmlElement = typeof type === "string";
20
- const propsToForward = isNativeHtmlElement
21
- ? {}
22
- : props;
23
- if (isNativeHtmlElement) {
24
- for (const key in props) {
25
- if (!key.startsWith("$")) {
26
- propsToForward[key] = props[key];
27
- }
28
- }
29
- }
30
- let className = argResolved || strings[0];
31
- className = className.match(/class="([^"]*)/)?.[1] || className;
32
- className += props?.className ? " " + props?.className : "";
33
- return createElement(type, {
34
- ...propsToForward,
35
- className: className || undefined,
36
- ref,
37
- });
38
- });
39
- return WrappedComponent;
40
- };
41
- };
3
+ // React.ComponentProps<typeof Component>
4
+ // ? @see https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase/#props-extracting-prop-types-of-a-component
5
+ // type ClassedComponent<Props = {}> =
6
+ // | React.ElementType<Props>
7
+ // | OverridableComponent<any>
8
+ // | React.Component<Props>
9
+ // | React.FunctionComponent<Props>
10
+ // | React.ReactElement<Props>
11
+ // | React.ReactHTMLElement<any>
12
+ // | string // | JSX.IntrinsicElements
13
+ // | ((props: Props) => JSX.Element);
14
+ /**
15
+ * This utility allows to extend a component a là `styled-components` but for
16
+ * a className based styling solution like Tailwind,
17
+ *
18
+ * It also plays nicely with tailwind intellisense:
19
+ * - https://github.com/tailwindlabs/tailwindcss-intellisense#tailwindcssclassattributes
20
+ *
21
+ * For references about tagged functions:
22
+ * - https://javascript.plainenglish.io/how-css-in-js-libraries-work-da4145b1b6c7
23
+ * - https://makersden.io/blog/reverse-engineering-styled-components
24
+ * - https://typesafe.blog/article/the-logic-behind-javascript-tag-functions
25
+ * - https://flaming.codes/posts/typescript-and-javascript-tagged-template-strings
26
+ *
27
+ * Similar projects:
28
+ * - https://reactjsexample.com/style-radix-ui-components-with-tailwindcss/
29
+ *
30
+ * Discussions and Q/A:
31
+ * - https://stackoverflow.com/q/73055695/1938970
32
+ */let classed=r=>{// @ts-expect-error nevermind for now...
33
+ let s=r.type||r;return function(r,...a){// FIXME: not sure if this is needed
34
+ // WrappedComponent.displayName = type.toString();
35
+ return /*#__PURE__*/forwardRef(// Props
36
+ function(e,n){let o=a.map((t,s)=>{let a="";return "function"==typeof t?a=t(e):void 0!==t&&(a=t.toString()),r[s]+a}).join(""),l="string"==typeof s,i=l?{}:e;if(l)for(let t in e)// like styled-components `transient` props
37
+ t.startsWith("$")||// FIXME: for react 18 we need: @ts-expect-error
38
+ (i[t]=e[t]);// get the tagged function string outcome
39
+ let c=o||r[0];return(// add the custom classes from props
40
+ c=// check if we need to clean it or not from the optional structure `< class="..."`
41
+ (c.match(/class="([^"]*)/)?.[1]||c)+(e?.className?" "+e?.className:""),/*#__PURE__*/createElement(s,{// ...props,
42
+ ...i,// only add ot props if it is not an empty string
43
+ className:c||void 0,// add ref to props
44
+ ref:n}))})}};// as unknown as React.ReactElement<typeof props>;
42
45
 
43
46
  export { classed, classed as default };
@@ -6,40 +6,21 @@ var react = require('react');
6
6
  var utils = require('@koine/utils');
7
7
  var useIsomorphicLayoutEffect = require('./useIsomorphicLayoutEffect.cjs.js');
8
8
 
9
- let createUseMediaQueryWidth = (customBreakpoints) => {
10
- const queryResolvers = utils.getMediaQueryWidthResolvers(customBreakpoints);
11
- return function useMediaQueryWidth(media, serverValue) {
12
- const definition = media.substring(1);
13
- let [rule, ruleBreakpoint] = definition.split("-");
14
- if (utils.isUndefined(ruleBreakpoint)) {
15
- ruleBreakpoint = rule;
16
- }
17
- if (utils.isUndefined(rule)) {
18
- rule = "min";
19
- }
20
- const [br1, br2] = ruleBreakpoint.split("_");
21
- const query = queryResolvers[rule](br1, br2);
22
- const [matches, setMatches] = react.useState(utils.isUndefined(serverValue) ? null : serverValue);
23
- useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
24
- const mq = window.matchMedia(query);
25
- const handleChange = (event) => {
26
- setMatches(event.matches);
27
- };
28
- setMatches(mq.matches);
29
- if (!mq.addEventListener) {
30
- mq.addListener(handleChange);
31
- return () => {
32
- mq.removeListener(handleChange);
33
- };
34
- }
35
- mq.addEventListener("change", handleChange);
36
- return () => {
37
- mq.removeEventListener("change", handleChange);
38
- };
39
- }, [query]);
40
- return matches;
41
- };
42
- };
9
+ /**
10
+ * Use `null` instead of `false` as default value, @see https://observablehq.com/@werehamster/avoiding-hydration-mismatch-when-using-react-hooks
11
+ *
12
+ * @param customBreakpoints
13
+ * @returns
14
+ */let createUseMediaQueryWidth=n=>{let a=utils.getMediaQueryWidthResolvers(n);return function(t,n){let[o,s]=t.substring(1).split("-");utils.isUndefined(s)&&(s=o),utils.isUndefined(o)&&(o="min");// with the hook creator approach these breakpoint types cannot be deduced
15
+ // const [br1, br2] = ruleBreakpoint.split("-") as Split<
16
+ // typeof ruleBreakpoint,
17
+ // "-"
18
+ // >;
19
+ let[d,m]=s.split("_"),u=a[o](d,m),[c,l]=react.useState(utils.isUndefined(n)?null:n);return useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(()=>{let e=window.matchMedia(u),t=e=>{l(e.matches);};return(// Safari < 14 can't use addEventListener on a MediaQueryList
20
+ // https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList#Browser_compatibility
21
+ (l(e.matches),e.addEventListener)?(e.addEventListener("change",t),()=>{e.removeEventListener("change",t);}):(// Update the state whenever the media query match state changes
22
+ e.addListener(t),// Clean up on unmount and if the query changes
23
+ ()=>{e.removeListener(t);}))},[u]),c}};//// without creator it would be:
43
24
 
44
25
  exports.createUseMediaQueryWidth = createUseMediaQueryWidth;
45
26
  exports["default"] = createUseMediaQueryWidth;
@@ -2,5 +2,5 @@ import { type GetMediaQueryWidthResolversBreakpoints } from "@koine/utils";
2
2
  type _MediaQuerWidthDefExplicit<TBreakpoint extends string> = `min-${TBreakpoint}` | `max-${TBreakpoint}` | `up-${TBreakpoint}` | `down-${TBreakpoint}` | `between-${TBreakpoint}_${TBreakpoint}` | `only-${TBreakpoint}`;
3
3
  export type MediaQuerWidthDef<TBreakpoint extends string> = `${TBreakpoint}` | _MediaQuerWidthDefExplicit<TBreakpoint>;
4
4
  export type MediaQueryWidth<TBreakpoint extends string> = `@${MediaQuerWidthDef<TBreakpoint>}`;
5
- export declare let createUseMediaQueryWidth: <TBreakpointsConfig extends GetMediaQueryWidthResolversBreakpoints>(customBreakpoints: TBreakpointsConfig) => <TBreakpoints extends Extract<keyof TBreakpointsConfig, string>>(media: `@${TBreakpoints}` | `@min-${TBreakpoints}` | `@max-${TBreakpoints}` | `@up-${TBreakpoints}` | `@down-${TBreakpoints}` | `@between-${TBreakpoints}_${TBreakpoints}` | `@only-${TBreakpoints}`, serverValue?: null | boolean) => boolean | null;
5
+ export declare let createUseMediaQueryWidth: <TBreakpointsConfig extends GetMediaQueryWidthResolversBreakpoints>(customBreakpoints: TBreakpointsConfig) => <TBreakpoints extends Extract<keyof TBreakpointsConfig, string>>(media: MediaQueryWidth<TBreakpoints>, serverValue?: null | boolean) => boolean | null;
6
6
  export default createUseMediaQueryWidth;
@@ -2,39 +2,20 @@ import { useState } from 'react';
2
2
  import { getMediaQueryWidthResolvers, isUndefined } from '@koine/utils';
3
3
  import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect.esm.js';
4
4
 
5
- let createUseMediaQueryWidth = (customBreakpoints) => {
6
- const queryResolvers = getMediaQueryWidthResolvers(customBreakpoints);
7
- return function useMediaQueryWidth(media, serverValue) {
8
- const definition = media.substring(1);
9
- let [rule, ruleBreakpoint] = definition.split("-");
10
- if (isUndefined(ruleBreakpoint)) {
11
- ruleBreakpoint = rule;
12
- }
13
- if (isUndefined(rule)) {
14
- rule = "min";
15
- }
16
- const [br1, br2] = ruleBreakpoint.split("_");
17
- const query = queryResolvers[rule](br1, br2);
18
- const [matches, setMatches] = useState(isUndefined(serverValue) ? null : serverValue);
19
- useIsomorphicLayoutEffect(() => {
20
- const mq = window.matchMedia(query);
21
- const handleChange = (event) => {
22
- setMatches(event.matches);
23
- };
24
- setMatches(mq.matches);
25
- if (!mq.addEventListener) {
26
- mq.addListener(handleChange);
27
- return () => {
28
- mq.removeListener(handleChange);
29
- };
30
- }
31
- mq.addEventListener("change", handleChange);
32
- return () => {
33
- mq.removeEventListener("change", handleChange);
34
- };
35
- }, [query]);
36
- return matches;
37
- };
38
- };
5
+ /**
6
+ * Use `null` instead of `false` as default value, @see https://observablehq.com/@werehamster/avoiding-hydration-mismatch-when-using-react-hooks
7
+ *
8
+ * @param customBreakpoints
9
+ * @returns
10
+ */let createUseMediaQueryWidth=n=>{let a=getMediaQueryWidthResolvers(n);return function(t,n){let[o,s]=t.substring(1).split("-");isUndefined(s)&&(s=o),isUndefined(o)&&(o="min");// with the hook creator approach these breakpoint types cannot be deduced
11
+ // const [br1, br2] = ruleBreakpoint.split("-") as Split<
12
+ // typeof ruleBreakpoint,
13
+ // "-"
14
+ // >;
15
+ let[d,m]=s.split("_"),u=a[o](d,m),[c,l]=useState(isUndefined(n)?null:n);return useIsomorphicLayoutEffect(()=>{let e=window.matchMedia(u),t=e=>{l(e.matches);};return(// Safari < 14 can't use addEventListener on a MediaQueryList
16
+ // https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList#Browser_compatibility
17
+ (l(e.matches),e.addEventListener)?(e.addEventListener("change",t),()=>{e.removeEventListener("change",t);}):(// Update the state whenever the media query match state changes
18
+ e.addListener(t),// Clean up on unmount and if the query changes
19
+ ()=>{e.removeListener(t);}))},[u]),c}};//// without creator it would be:
39
20
 
40
21
  export { createUseMediaQueryWidth, createUseMediaQueryWidth as default };
@@ -4,13 +4,11 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var react = require('react');
6
6
 
7
- let extendComponent = (component, defaultProps) => {
8
- const NewComponent = (props) => react.createElement(component, props);
9
- return Object.assign(NewComponent, {
10
- ...defaultProps,
11
- defaultProps,
12
- });
13
- };
7
+ let extendComponent=(t,o)=>// const NewComponent = forwardRef<React.ComponentProps<Component>, Component>(
8
+ // (props, ref) => createElement(component, { ...props, ref })
9
+ // );
10
+ Object.assign(// FIXME: check if we need to forwardRef or not
11
+ o=>react.createElement(t,o),{...o,defaultProps:o});
14
12
 
15
13
  exports["default"] = extendComponent;
16
14
  exports.extendComponent = extendComponent;
@@ -1,5 +1,5 @@
1
1
  export type ExtendableComponent<Props = any> = React.ForwardRefExoticComponent<Props> | React.ExoticComponent<Props> | React.FC<Props> | ((props: Props) => JSX.Element);
2
- export declare let extendComponent: <Component extends ExtendableComponent<any>, DefaultProps extends {}>(component: Component, defaultProps: DefaultProps) => ((props: import("react").ComponentProps<Component>) => import("react").FunctionComponentElement<any>) & DefaultProps & {
2
+ export declare let extendComponent: <Component extends ExtendableComponent<any>, DefaultProps extends {}>(component: Component, defaultProps: DefaultProps) => ((props: React.ComponentProps<Component>) => import("react").FunctionComponentElement<any>) & DefaultProps & {
3
3
  defaultProps: DefaultProps;
4
4
  };
5
5
  export interface OverridableComponents {
@@ -1,11 +1,9 @@
1
1
  import { createElement } from 'react';
2
2
 
3
- let extendComponent = (component, defaultProps) => {
4
- const NewComponent = (props) => createElement(component, props);
5
- return Object.assign(NewComponent, {
6
- ...defaultProps,
7
- defaultProps,
8
- });
9
- };
3
+ let extendComponent=(t,o)=>// const NewComponent = forwardRef<React.ComponentProps<Component>, Component>(
4
+ // (props, ref) => createElement(component, { ...props, ref })
5
+ // );
6
+ Object.assign(// FIXME: check if we need to forwardRef or not
7
+ o=>createElement(t,o),{...o,defaultProps:o});
10
8
 
11
9
  export { extendComponent as default, extendComponent };
@@ -24,4 +24,4 @@ export declare let encodeForm: <T extends ObjectShape = {}>(validationRules: T)
24
24
  }, "">;
25
25
  encodedNames: Record<keyof T, string>;
26
26
  };
27
- export declare let decodeForm: <ReturnAs extends Record<string, unknown> = {}, FormData_1 extends Record<string, unknown> = {}>(formData: FormData_1) => ReturnAs;
27
+ export declare let decodeForm: <ReturnAs extends Record<string, unknown> = {}, FormData extends Record<string, unknown> = {}>(formData: FormData) => ReturnAs;
package/forms.cjs.js CHANGED
@@ -5,33 +5,33 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var yup = require('@kuus/yup');
6
6
  var utils = require('@koine/utils');
7
7
 
8
- let encodeForm = (validationRules) => {
9
- const encoded = {};
10
- const encodedNames = {};
11
- for (const name in validationRules) {
12
- if (!name.startsWith("_")) {
13
- const encodedName = utils.encode(name);
14
- encoded[encodedName] = validationRules[name];
15
- encodedNames[name] = encodedName;
16
- }
17
- }
18
- const encodedSchema = yup.object(encoded).required();
19
- return { encodedSchema, encodedNames };
20
- };
21
- let decodeForm = (formData) => {
22
- const json = {};
23
- for (const encodedName in formData) {
24
- const decodedName = utils.decode(encodedName);
25
- if (encodedName.startsWith("_")) {
26
- json[encodedName.substring(1)] = formData[encodedName];
27
- }
28
- else if (!utils.isUndefined(formData[encodedName]) &&
29
- formData[decodedName] === "") {
30
- json[decodedName] = formData[encodedName];
31
- }
32
- }
33
- return json;
34
- };
8
+ /**
9
+ * Encode form
10
+ *
11
+ * Takes a record of yup validations and outputs a `yup` schema with encoded
12
+ * names (antispam technique) and a record of the encoded/decoded input `name`s.
13
+ *
14
+ * We skip the names prefixed wth an underscore which are considered programmatic
15
+ * form data not created by user input.
16
+ *
17
+ * FIXME: types https://github.com/jquense/yup/issues/1700
18
+ */let encodeForm=t=>{let o={},i={};for(let e in t)if(!e.startsWith("_")){let l=utils.encode(e);o[l]=t[e],i[e]=l;}return {encodedSchema:// we need `.required()` to correctly infer the type @see
19
+ // https://github.com/jquense/yup/issues/946
20
+ yup.object(o).required(),encodedNames:i}};/**
21
+ * Decode form data
22
+ *
23
+ * This function is meant to be used inside an api endpoint to gather an encoded
24
+ * form submit data and transform it to the decoded desired json data.
25
+ *
26
+ * Here too we skip encoding/decoding process for names prefixed wth an underscore
27
+ * which are considered programmatic form data not created by user input.
28
+ */let decodeForm=e=>{let r={};for(let i in e){let l=utils.decode(i);// always add underscore prefixed names as they are treated as internal
29
+ // private inputs outside of the honeypot system, normalise them here removing
30
+ // the underscore prefix
31
+ i.startsWith("_")?// @ts-expect-error nevermind
32
+ r[i.substring(1)]=e[i]:utils.isUndefined(e[i])||""!==e[l]||// @ts-expect-error nevermind
33
+ (r[l]=e[i]);}// console.log(formData, decoded, json);
34
+ return r};
35
35
 
36
36
  exports.decodeForm = decodeForm;
37
37
  exports.encodeForm = encodeForm;
package/forms.esm.js CHANGED
@@ -1,32 +1,32 @@
1
1
  import { object } from '@kuus/yup';
2
2
  import { encode, decode, isUndefined } from '@koine/utils';
3
3
 
4
- let encodeForm = (validationRules) => {
5
- const encoded = {};
6
- const encodedNames = {};
7
- for (const name in validationRules) {
8
- if (!name.startsWith("_")) {
9
- const encodedName = encode(name);
10
- encoded[encodedName] = validationRules[name];
11
- encodedNames[name] = encodedName;
12
- }
13
- }
14
- const encodedSchema = object(encoded).required();
15
- return { encodedSchema, encodedNames };
16
- };
17
- let decodeForm = (formData) => {
18
- const json = {};
19
- for (const encodedName in formData) {
20
- const decodedName = decode(encodedName);
21
- if (encodedName.startsWith("_")) {
22
- json[encodedName.substring(1)] = formData[encodedName];
23
- }
24
- else if (!isUndefined(formData[encodedName]) &&
25
- formData[decodedName] === "") {
26
- json[decodedName] = formData[encodedName];
27
- }
28
- }
29
- return json;
30
- };
4
+ /**
5
+ * Encode form
6
+ *
7
+ * Takes a record of yup validations and outputs a `yup` schema with encoded
8
+ * names (antispam technique) and a record of the encoded/decoded input `name`s.
9
+ *
10
+ * We skip the names prefixed wth an underscore which are considered programmatic
11
+ * form data not created by user input.
12
+ *
13
+ * FIXME: types https://github.com/jquense/yup/issues/1700
14
+ */let encodeForm=t=>{let o={},i={};for(let e in t)if(!e.startsWith("_")){let l=encode(e);o[l]=t[e],i[e]=l;}return {encodedSchema:// we need `.required()` to correctly infer the type @see
15
+ // https://github.com/jquense/yup/issues/946
16
+ object(o).required(),encodedNames:i}};/**
17
+ * Decode form data
18
+ *
19
+ * This function is meant to be used inside an api endpoint to gather an encoded
20
+ * form submit data and transform it to the decoded desired json data.
21
+ *
22
+ * Here too we skip encoding/decoding process for names prefixed wth an underscore
23
+ * which are considered programmatic form data not created by user input.
24
+ */let decodeForm=e=>{let r={};for(let i in e){let l=decode(i);// always add underscore prefixed names as they are treated as internal
25
+ // private inputs outside of the honeypot system, normalise them here removing
26
+ // the underscore prefix
27
+ i.startsWith("_")?// @ts-expect-error nevermind
28
+ r[i.substring(1)]=e[i]:isUndefined(e[i])||""!==e[l]||// @ts-expect-error nevermind
29
+ (r[l]=e[i]);}// console.log(formData, decoded, json);
30
+ return r};
31
31
 
32
32
  export { decodeForm, encodeForm };
package/mergeRefs.cjs.js CHANGED
@@ -2,18 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- let mergeRefs = (refs) => {
6
- return (value) => {
7
- refs.forEach((ref) => {
8
- if (typeof ref === "function") {
9
- ref(value);
10
- }
11
- else if (ref != null) {
12
- ref.current = value;
13
- }
14
- });
15
- };
16
- };
5
+ let mergeRefs=e=>r=>{e.forEach(e=>{"function"==typeof e?e(r):null!=e&&(e.current=r);});};
17
6
 
18
7
  exports["default"] = mergeRefs;
19
8
  exports.mergeRefs = mergeRefs;
package/mergeRefs.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare let mergeRefs: <T = Element>(refs: (import("react").MutableRefObject<T> | import("react").LegacyRef<T>)[]) => (instance: T | null) => void;
1
+ export declare let mergeRefs: <T = Element>(refs: Array<React.MutableRefObject<T> | React.LegacyRef<T>>) => React.RefCallback<T>;
2
2
  export default mergeRefs;
package/mergeRefs.esm.js CHANGED
@@ -1,14 +1,3 @@
1
- let mergeRefs = (refs) => {
2
- return (value) => {
3
- refs.forEach((ref) => {
4
- if (typeof ref === "function") {
5
- ref(value);
6
- }
7
- else if (ref != null) {
8
- ref.current = value;
9
- }
10
- });
11
- };
12
- };
1
+ let mergeRefs=e=>r=>{e.forEach(e=>{"function"==typeof e?e(r):null!=e&&(e.current=r);});};
13
2
 
14
3
  export { mergeRefs as default, mergeRefs };
package/package.json CHANGED
@@ -2,8 +2,8 @@
2
2
  "name": "@koine/react",
3
3
  "sideEffects": false,
4
4
  "dependencies": {
5
- "@koine/dom": "2.0.0-beta.80",
6
- "@koine/utils": "2.0.0-beta.80"
5
+ "@koine/dom": "2.0.0-beta.83",
6
+ "@koine/utils": "2.0.0-beta.83"
7
7
  },
8
8
  "peerDependencies": {
9
9
  "@kuus/yup": "1.0.0-beta.7",
@@ -190,5 +190,5 @@
190
190
  },
191
191
  "module": "./index.esm.js",
192
192
  "main": "./index.cjs.js",
193
- "version": "2.0.0-beta.80"
193
+ "version": "2.0.0-beta.83"
194
194
  }
package/useAsyncFn.cjs.js CHANGED
@@ -5,29 +5,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var react = require('react');
6
6
  var useMountedState = require('./useMountedState.cjs.js');
7
7
 
8
- let useAsyncFn = (fn, deps = [], initialState = { loading: false }) => {
9
- const lastCallId = react.useRef(0);
10
- const isMounted = useMountedState.useMountedState();
11
- const [state, set] = react.useState(initialState);
12
- const callback = react.useCallback((...args) => {
13
- const callId = ++lastCallId.current;
14
- if (!state.loading) {
15
- set((prevState) => ({ ...prevState, loading: true }));
16
- }
17
- return fn(...args).then((value) => {
18
- isMounted() &&
19
- callId === lastCallId.current &&
20
- set({ value, loading: false });
21
- return value;
22
- }, (error) => {
23
- isMounted() &&
24
- callId === lastCallId.current &&
25
- set({ error, loading: false });
26
- return error;
27
- });
28
- }, deps);
29
- return [state, callback];
30
- };
8
+ /**
9
+ * @borrows [streamich/react-use](https://github.com/streamich/react-use/blob/master/src/useAsyncFn.ts)
10
+ */let useAsyncFn=(o,u=[],l={loading:!1})=>{let a=react.useRef(0),d=useMountedState.useMountedState(),[i,c]=react.useState(l),g=react.useCallback((...e)=>{let t=++a.current;return i.loading||c(e=>({...e,loading:!0})),o(...e).then(e=>(d()&&t===a.current&&c({value:e,loading:!1}),e),e=>(d()&&t===a.current&&c({error:e,loading:!1}),e))},// eslint-disable-next-line react-hooks/exhaustive-deps
11
+ u);return [i,g]};
31
12
 
32
13
  exports["default"] = useAsyncFn;
33
14
  exports.useAsyncFn = useAsyncFn;
package/useAsyncFn.esm.js CHANGED
@@ -1,28 +1,9 @@
1
1
  import { useRef, useState, useCallback } from 'react';
2
2
  import { useMountedState } from './useMountedState.esm.js';
3
3
 
4
- let useAsyncFn = (fn, deps = [], initialState = { loading: false }) => {
5
- const lastCallId = useRef(0);
6
- const isMounted = useMountedState();
7
- const [state, set] = useState(initialState);
8
- const callback = useCallback((...args) => {
9
- const callId = ++lastCallId.current;
10
- if (!state.loading) {
11
- set((prevState) => ({ ...prevState, loading: true }));
12
- }
13
- return fn(...args).then((value) => {
14
- isMounted() &&
15
- callId === lastCallId.current &&
16
- set({ value, loading: false });
17
- return value;
18
- }, (error) => {
19
- isMounted() &&
20
- callId === lastCallId.current &&
21
- set({ error, loading: false });
22
- return error;
23
- });
24
- }, deps);
25
- return [state, callback];
26
- };
4
+ /**
5
+ * @borrows [streamich/react-use](https://github.com/streamich/react-use/blob/master/src/useAsyncFn.ts)
6
+ */let useAsyncFn=(o,u=[],l={loading:!1})=>{let a=useRef(0),d=useMountedState(),[i,c]=useState(l),g=useCallback((...e)=>{let t=++a.current;return i.loading||c(e=>({...e,loading:!0})),o(...e).then(e=>(d()&&t===a.current&&c({value:e,loading:!1}),e),e=>(d()&&t===a.current&&c({error:e,loading:!1}),e))},// eslint-disable-next-line react-hooks/exhaustive-deps
7
+ u);return [i,g]};
27
8
 
28
9
  export { useAsyncFn as default, useAsyncFn };