@koine/react 2.0.0-beta.73 → 2.0.0-beta.75
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/FaviconTags.d.ts +9 -0
- package/FaviconTags.js +5 -0
- package/Meta.d.ts +5 -0
- package/Meta.js +5 -0
- package/NoJs.d.ts +3 -0
- package/NoJs.js +7 -0
- package/Polymorphic.d.ts +26 -0
- package/Polymorphic.js +1 -0
- package/classed.d.ts +8 -0
- package/classed.js +41 -0
- package/createUseMediaQueryWidth.d.ts +6 -0
- package/createUseMediaQueryWidth.js +38 -0
- package/extendComponent.d.ts +16 -0
- package/extendComponent.js +9 -0
- package/index.cjs.js +33 -23
- package/index.d.ts +28 -3
- package/index.esm.js +33 -26
- package/index.js +26 -3
- package/mergeRefs.d.ts +2 -0
- package/mergeRefs.js +13 -0
- package/package.json +245 -5
- package/useAsyncFn.d.ts +24 -0
- package/useAsyncFn.js +26 -0
- package/useFirstMountState.d.ts +2 -0
- package/useFirstMountState.js +10 -0
- package/useFixedOffset.d.ts +2 -0
- package/useFixedOffset.js +42 -0
- package/useFocus.d.ts +2 -0
- package/useFocus.js +9 -0
- package/useInterval.d.ts +2 -0
- package/useInterval.js +20 -0
- package/useIsomorphicLayoutEffect.d.ts +3 -0
- package/useIsomorphicLayoutEffect.js +4 -0
- package/useKeyUp.d.ts +2 -0
- package/useKeyUp.js +16 -0
- package/useMeasure.d.ts +22 -0
- package/useMeasure.js +119 -0
- package/useMountedState.d.ts +2 -0
- package/useMountedState.js +13 -0
- package/useNavigateAway.d.ts +3 -0
- package/useNavigateAway.js +25 -0
- package/usePrevious.d.ts +2 -0
- package/usePrevious.js +9 -0
- package/usePreviousRef.d.ts +2 -0
- package/usePreviousRef.js +9 -0
- package/useReveal.d.ts +13 -0
- package/useReveal.js +42 -0
- package/useScrollPosition.d.ts +7 -0
- package/useScrollPosition.js +58 -0
- package/useScrollThreshold.d.ts +2 -0
- package/useScrollThreshold.js +26 -0
- package/useScrollTo.d.ts +2 -0
- package/useScrollTo.js +18 -0
- package/useSmoothScroll.d.ts +2 -0
- package/useSmoothScroll.js +32 -0
- package/useSpinDelay.d.ts +2 -0
- package/useSpinDelay.js +36 -0
- package/useTraceUpdate.d.ts +2 -0
- package/useTraceUpdate.js +17 -0
- package/useUpdateEffect.d.ts +3 -0
- package/useUpdateEffect.js +11 -0
- package/useWindowSize.d.ts +3 -0
- package/useWindowSize.js +20 -0
package/FaviconTags.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type FaviconTagsProps = {
|
|
2
|
+
name: string;
|
|
3
|
+
color?: string;
|
|
4
|
+
safariTabColor?: string;
|
|
5
|
+
tileColor?: string;
|
|
6
|
+
themeColor?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare let FaviconTags: ({ name, color, safariTabColor, tileColor, themeColor, }: FaviconTagsProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export default FaviconTags;
|
package/FaviconTags.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export let FaviconTags = ({ name, color, safariTabColor, tileColor, themeColor, }) => {
|
|
3
|
+
return (_jsxs(_Fragment, { children: [_jsx("link", { rel: "shortcut icon", href: "/favicon.ico", type: "image/x-icon" }), _jsx("link", { rel: "apple-touch-icon", sizes: "180x180", href: "/apple-touch-icon.png" }), _jsx("link", { rel: "icon", type: "image/png", sizes: "32x32", href: "/favicon-32x32.png" }), _jsx("link", { rel: "icon", type: "image/png", sizes: "16x16", href: "/favicon-16x16.png" }), _jsx("link", { rel: "manifest", href: "/site.webmanifest" }), _jsx("link", { rel: "mask-icon", href: "/safari-pinned-tab.svg", color: safariTabColor || color }), _jsx("meta", { name: "apple-mobile-web-app-title", content: name }), _jsx("meta", { name: "application-name", content: name }), _jsx("meta", { name: "msapplication-TileColor", content: tileColor || color }), _jsx("meta", { name: "theme-color", content: themeColor || color })] }));
|
|
4
|
+
};
|
|
5
|
+
export default FaviconTags;
|
package/Meta.d.ts
ADDED
package/Meta.js
ADDED
package/NoJs.d.ts
ADDED
package/NoJs.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export let NoJs = (_props) => {
|
|
3
|
+
return (_jsx("script", { id: "no-js", dangerouslySetInnerHTML: {
|
|
4
|
+
__html: `document.querySelector("html").className=document.querySelector("html").className.replace(/no-js/,"") + "js";`,
|
|
5
|
+
} }));
|
|
6
|
+
};
|
|
7
|
+
export default NoJs;
|
package/Polymorphic.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare namespace Polymorphic {
|
|
2
|
+
type Merge<P1 = Record<string, never>, P2 = Record<string, never>> = Omit<P1, keyof P2> & P2;
|
|
3
|
+
type ComponentTypes = React.ComponentClass<any> | React.FunctionComponent<any> | keyof JSX.IntrinsicElements;
|
|
4
|
+
type InferProps<TComponent extends ComponentTypes> = TComponent extends React.ComponentClass<infer Props> ? Props : TComponent extends React.FunctionComponent<infer Props> ? Props : TComponent extends React.ForwardRefExoticComponent<infer Props> ? Props : TComponent extends keyof JSX.IntrinsicElements ? React.ComponentPropsWithoutRef<TComponent> : never;
|
|
5
|
+
type AsProp<TComponent extends React.ElementType> = {
|
|
6
|
+
as?: TComponent;
|
|
7
|
+
};
|
|
8
|
+
export type Ref<TComponent extends React.ElementType> = React.ComponentPropsWithRef<TComponent>["ref"];
|
|
9
|
+
export type Props<TComponent extends React.ElementType, Props = Record<string, never>> = Omit<InferProps<TComponent>, keyof Props> & AsProp<TComponent> & Props;
|
|
10
|
+
export type PropsWithRef<TComponent extends React.ElementType, TProps = Record<string, never>> = Props<TComponent, TProps> & {
|
|
11
|
+
ref?: Ref<TComponent>;
|
|
12
|
+
};
|
|
13
|
+
type ForwardRefExoticComponent<TComponent, OwnProps> = React.ForwardRefExoticComponent<Merge<TComponent extends React.ElementType ? React.ComponentPropsWithRef<TComponent> : never, OwnProps & {
|
|
14
|
+
as?: TComponent;
|
|
15
|
+
}>>;
|
|
16
|
+
export type ComponentForwarded<TComponent, TProps = Record<string, never>> = ForwardRefExoticComponent<TComponent, TProps> & {
|
|
17
|
+
<As = TComponent>(props: As extends "" ? {
|
|
18
|
+
as: keyof JSX.IntrinsicElements;
|
|
19
|
+
} : As extends React.ComponentType<infer P> ? Merge<P, TProps & {
|
|
20
|
+
as: As;
|
|
21
|
+
}> : As extends keyof JSX.IntrinsicElements ? Merge<JSX.IntrinsicElements[As], TProps & {
|
|
22
|
+
as: As;
|
|
23
|
+
}> : never): React.ReactElement | null;
|
|
24
|
+
};
|
|
25
|
+
export {};
|
|
26
|
+
}
|
package/Polymorphic.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/classed.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
type ClassedAugmentedProps<Props> = Props & {
|
|
3
|
+
className?: string;
|
|
4
|
+
ref?: React.Ref<any>;
|
|
5
|
+
};
|
|
6
|
+
type ClassedFinalProps<Props, Component> = Component extends React.ReactHTML ? React.HTMLProps<Component> & ClassedAugmentedProps<Props> : ClassedAugmentedProps<Props>;
|
|
7
|
+
export declare let classed: <Props, Component extends React.ElementType<any, keyof React.JSX.IntrinsicElements> = any>(component: Component) => (strings: TemplateStringsArray, ...args: ((props: Props) => string)[] | string[]) => React.ForwardRefExoticComponent<React.PropsWithoutRef<ClassedFinalProps<Props, Component>> & React.RefAttributes<Component>>;
|
|
8
|
+
export default classed;
|
package/classed.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { createElement, forwardRef } from "react";
|
|
2
|
+
export let classed = (component) => {
|
|
3
|
+
const type = component.type || component;
|
|
4
|
+
return function (strings, ...args) {
|
|
5
|
+
const WrappedComponent = forwardRef(function (props, ref) {
|
|
6
|
+
const argResolved = args
|
|
7
|
+
.map((arg, index) => {
|
|
8
|
+
let result = "";
|
|
9
|
+
if (typeof arg === "function") {
|
|
10
|
+
result = arg(props);
|
|
11
|
+
}
|
|
12
|
+
else if (typeof arg !== "undefined") {
|
|
13
|
+
result = arg.toString();
|
|
14
|
+
}
|
|
15
|
+
return strings[index] + result;
|
|
16
|
+
})
|
|
17
|
+
.join("");
|
|
18
|
+
const isNativeHtmlElement = typeof type === "string";
|
|
19
|
+
const propsToForward = isNativeHtmlElement
|
|
20
|
+
? {}
|
|
21
|
+
: props;
|
|
22
|
+
if (isNativeHtmlElement) {
|
|
23
|
+
for (const key in props) {
|
|
24
|
+
if (!key.startsWith("$")) {
|
|
25
|
+
propsToForward[key] = props[key];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
let className = argResolved || strings[0];
|
|
30
|
+
className = className.match(/class="([^"]*)/)?.[1] || className;
|
|
31
|
+
className += props?.className ? " " + props?.className : "";
|
|
32
|
+
return createElement(type, {
|
|
33
|
+
...propsToForward,
|
|
34
|
+
className: className || undefined,
|
|
35
|
+
ref,
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
return WrappedComponent;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export default classed;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type GetMediaQueryWidthResolversBreakpoints } from "@koine/utils";
|
|
2
|
+
type _MediaQuerWidthDefExplicit<TBreakpoint extends string> = `min-${TBreakpoint}` | `max-${TBreakpoint}` | `up-${TBreakpoint}` | `down-${TBreakpoint}` | `between-${TBreakpoint}_${TBreakpoint}` | `only-${TBreakpoint}`;
|
|
3
|
+
export type MediaQuerWidthDef<TBreakpoint extends string> = `${TBreakpoint}` | _MediaQuerWidthDefExplicit<TBreakpoint>;
|
|
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;
|
|
6
|
+
export default createUseMediaQueryWidth;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { getMediaQueryWidthResolvers, isUndefined, } from "@koine/utils";
|
|
3
|
+
import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";
|
|
4
|
+
export let createUseMediaQueryWidth = (customBreakpoints) => {
|
|
5
|
+
const queryResolvers = getMediaQueryWidthResolvers(customBreakpoints);
|
|
6
|
+
return function useMediaQueryWidth(media, serverValue) {
|
|
7
|
+
const definition = media.substring(1);
|
|
8
|
+
let [rule, ruleBreakpoint] = definition.split("-");
|
|
9
|
+
if (isUndefined(ruleBreakpoint)) {
|
|
10
|
+
ruleBreakpoint = rule;
|
|
11
|
+
}
|
|
12
|
+
if (isUndefined(rule)) {
|
|
13
|
+
rule = "min";
|
|
14
|
+
}
|
|
15
|
+
const [br1, br2] = ruleBreakpoint.split("_");
|
|
16
|
+
const query = queryResolvers[rule](br1, br2);
|
|
17
|
+
const [matches, setMatches] = useState(isUndefined(serverValue) ? null : serverValue);
|
|
18
|
+
useIsomorphicLayoutEffect(() => {
|
|
19
|
+
const mq = window.matchMedia(query);
|
|
20
|
+
const handleChange = (event) => {
|
|
21
|
+
setMatches(event.matches);
|
|
22
|
+
};
|
|
23
|
+
setMatches(mq.matches);
|
|
24
|
+
if (!mq.addEventListener) {
|
|
25
|
+
mq.addListener(handleChange);
|
|
26
|
+
return () => {
|
|
27
|
+
mq.removeListener(handleChange);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
mq.addEventListener("change", handleChange);
|
|
31
|
+
return () => {
|
|
32
|
+
mq.removeEventListener("change", handleChange);
|
|
33
|
+
};
|
|
34
|
+
}, [query]);
|
|
35
|
+
return matches;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
export default createUseMediaQueryWidth;
|
|
@@ -0,0 +1,16 @@
|
|
|
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 & {
|
|
3
|
+
defaultProps: DefaultProps;
|
|
4
|
+
};
|
|
5
|
+
export interface OverridableComponents {
|
|
6
|
+
[key: string]: {
|
|
7
|
+
type: React.ElementType;
|
|
8
|
+
props: any;
|
|
9
|
+
motionable?: boolean;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export type WithComponents<Props, Components extends OverridableComponents> = Props & {
|
|
13
|
+
[Name in keyof Components]: NonNullable<Components[Name]["type"] extends keyof JSX.IntrinsicElements ? React.ElementType<Components[Name]["motionable"] extends true ? Omit<React.ComponentPropsWithoutRef<Components[Name]["type"]>, HtmlAttributesCollidingWithMotionProps> & Components[Name]["props"] : React.ComponentPropsWithoutRef<Components[Name]["type"]> & Components[Name]["props"]> : Components[Name]["type"]>;
|
|
14
|
+
};
|
|
15
|
+
type HtmlAttributesCollidingWithMotionProps = "style" | "onDrag" | "onDragStart" | "onDragEnd" | "onAnimationStart" | "onAnimationEnd";
|
|
16
|
+
export default extendComponent;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createElement } from "react";
|
|
2
|
+
export let extendComponent = (component, defaultProps) => {
|
|
3
|
+
const NewComponent = (props) => createElement(component, props);
|
|
4
|
+
return Object.assign(NewComponent, {
|
|
5
|
+
...defaultProps,
|
|
6
|
+
defaultProps,
|
|
7
|
+
});
|
|
8
|
+
};
|
|
9
|
+
export default extendComponent;
|
package/index.cjs.js
CHANGED
|
@@ -4,54 +4,64 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var utils = require('@koine/utils');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
8
|
var dom = require('@koine/dom');
|
|
8
9
|
|
|
9
|
-
let
|
|
10
|
+
let classed=r=>{let s=r.type||r;return function(r,...a){return react.forwardRef(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)t.startsWith("$")||(i[t]=e[t]);let c=o||r[0];return c=(c.match(/class="([^"]*)/)?.[1]||c)+(e?.className?" "+e?.className:""),react.createElement(s,{...i,className:c||void 0,ref:n})})}};
|
|
10
11
|
|
|
11
|
-
let
|
|
12
|
+
let useIsomorphicLayoutEffect=utils.isBrowser?react.useLayoutEffect:react.useEffect;
|
|
12
13
|
|
|
13
|
-
let
|
|
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");let[d,m]=s.split("_"),u=a[o](d,m),[c,l]=react.useState(utils.isUndefined(n)?null:n);return useIsomorphicLayoutEffect(()=>{let e=window.matchMedia(u),t=e=>{l(e.matches);};return (l(e.matches),e.addEventListener)?(e.addEventListener("change",t),()=>{e.removeEventListener("change",t);}):(e.addListener(t),()=>{e.removeListener(t);})},[u]),c}};
|
|
14
15
|
|
|
15
|
-
let
|
|
16
|
+
let extendComponent=(t,o)=>Object.assign(o=>react.createElement(t,o),{...o,defaultProps:o});
|
|
16
17
|
|
|
17
|
-
let
|
|
18
|
+
let FaviconTags=({name:a,color:t,safariTabColor:o,tileColor:c,themeColor:l})=>jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("link",{rel:"shortcut icon",href:"/favicon.ico",type:"image/x-icon"}),jsxRuntime.jsx("link",{rel:"apple-touch-icon",sizes:"180x180",href:"/apple-touch-icon.png"}),jsxRuntime.jsx("link",{rel:"icon",type:"image/png",sizes:"32x32",href:"/favicon-32x32.png"}),jsxRuntime.jsx("link",{rel:"icon",type:"image/png",sizes:"16x16",href:"/favicon-16x16.png"}),jsxRuntime.jsx("link",{rel:"manifest",href:"/site.webmanifest"}),jsxRuntime.jsx("link",{rel:"mask-icon",href:"/safari-pinned-tab.svg",color:o||t}),jsxRuntime.jsx("meta",{name:"apple-mobile-web-app-title",content:a}),jsxRuntime.jsx("meta",{name:"application-name",content:a}),jsxRuntime.jsx("meta",{name:"msapplication-TileColor",content:c||t}),jsxRuntime.jsx("meta",{name:"theme-color",content:l||t})]});
|
|
18
19
|
|
|
19
|
-
let
|
|
20
|
+
let mergeRefs=e=>r=>{e.forEach(e=>{"function"==typeof e?e(r):null!=e&&(e.current=r);});};
|
|
20
21
|
|
|
21
|
-
let
|
|
22
|
+
let Meta=({zoom:t})=>jsxRuntime.jsx("meta",{name:"viewport",content:`width=device-width, initial-scale=1, maximum-scale=1${t?"":", user-scalable=0"}`});
|
|
22
23
|
|
|
23
|
-
let
|
|
24
|
+
let NoJs=t=>jsxRuntime.jsx("script",{id:"no-js",dangerouslySetInnerHTML:{__html:'document.querySelector("html").className=document.querySelector("html").className.replace(/no-js/,"") + "js";'}});
|
|
24
25
|
|
|
25
|
-
let
|
|
26
|
+
let useMountedState=()=>{let u=react.useRef(!1),n=react.useCallback(()=>u.current,[]);return react.useEffect(()=>(u.current=!0,()=>{u.current=!1;}),[]),n};
|
|
26
27
|
|
|
27
|
-
let
|
|
28
|
+
let useAsyncFn=(o,u=[],l={loading:!1})=>{let a=react.useRef(0),d=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))},u);return [i,g]};
|
|
28
29
|
|
|
29
|
-
let
|
|
30
|
+
let useFirstMountState=()=>{let r=react.useRef(!0);return r.current?(r.current=!1,!0):r.current};
|
|
30
31
|
|
|
31
|
-
let
|
|
32
|
+
let n$1=e=>{dom.injectCss("useFixedOffset",`html{scroll-padding-top: ${e}px}`);};let useFixedOffset=i=>{let l=react.useRef(0);return useIsomorphicLayoutEffect(()=>{let e=()=>{let e=dom.calculateFixedOffset();l.current=e,n$1(e);};if(e(),!ResizeObserver)return dom.listenResizeDebounced(0,e);{let e=new ResizeObserver(e=>{let r=0;e.forEach(e=>{r+=e.contentRect.height;}),l.current=r,utils.debounce(()=>n$1(r),400,!0)();});return dom.$each(i||"[data-fixed]",t=>{e&&e.observe(t);}),()=>{e?.disconnect();}}},[i]),l};
|
|
32
33
|
|
|
33
|
-
let
|
|
34
|
+
let useFocus=()=>{let r=react.useRef(null);return [r,()=>{r.current&&r.current.focus();}]};
|
|
34
35
|
|
|
35
|
-
let
|
|
36
|
+
let useInterval=(n,l,u=[])=>{let o=react.useRef();react.useEffect(()=>{o.current=n;},[n,...u]),react.useEffect(()=>{if(null!==l){let r=setInterval(function(){o.current&&o.current();},l);return ()=>clearInterval(r)}return utils.noop},[l]);};
|
|
36
37
|
|
|
37
|
-
let
|
|
38
|
+
let useKeyUp=(o,r=[])=>{react.useEffect(()=>dom.on(window,"keyup",e=>{e.ctrlKey||e.altKey||e.shiftKey||e.metaKey||o(e);}),[o,...r]);};
|
|
38
39
|
|
|
39
|
-
let
|
|
40
|
+
let e;let m=e=>{let t=[];if(!e||e===document.body)return t;let{overflow:r,overflowX:n,overflowY:u}=window.getComputedStyle(e);return [r,n,u].some(e=>"auto"===e||"scroll"===e)&&t.push(e),[...t,...m(e.parentElement)]},p=["x","y","top","bottom","left","right","width","height"],d=(e,t)=>p.every(r=>e[r]===t[r]);let useMeasure=p=>{let{scroll:h=!1}=p||{},[a,b]=react.useState({left:0,top:0,width:0,height:0,bottom:0,right:0,x:0,y:0}),g=react.useRef([null,null,null,a]),v=react.useRef(!1);react.useEffect(()=>(v.current=!0,()=>void(v.current=!1)),[]);let[w,,y]=react.useMemo(()=>{let e=(...e)=>{let[t,,,r]=g.current;if(!t)return;let n=t.getBoundingClientRect();Object.freeze(n),v.current&&!d(r,n)&&(g.current[3]=n,b(n));},t=utils.debounce(e);return [e,t,t]},[b]);function x(){let[,e,t]=g.current;e&&(e.forEach(e=>dom.off(e,"scroll",y)),g.current[1]=null),t&&(t.disconnect(),g.current[2]=null);}function z(){let[t,r]=g.current;t&&!e&&ResizeObserver&&(e=new ResizeObserver(y),g.current[2]=e,e.observe(t),h&&r&&r.forEach(e=>dom.on(e,"scroll",y,{capture:!0,passive:!0})));}return react.useEffect(()=>h?dom.listenScrollDebounced(0,w,100):utils.noop,[h,w]),react.useEffect(()=>dom.listenResizeDebounced(0,w,100),[w]),react.useEffect(()=>{x(),z();},[h]),react.useEffect(()=>(w(),x),[]),[e=>{e&&e!==g.current[0]&&(x(),g.current[0]=e,g.current[1]=m(e),z());},a,w]};
|
|
40
41
|
|
|
41
|
-
let
|
|
42
|
+
let useNavigateAway=a=>{let o=react.useRef();react.useEffect(()=>{o.current=e=>{let t=a(e);return (t&&e.preventDefault(),"string"==typeof t)?e.returnValue=t:e.defaultPrevented?e.returnValue="":void 0};},[a]),react.useEffect(()=>dom.on(window,"beforeunload",e=>o.current?.(e)),[]);};
|
|
42
43
|
|
|
43
|
-
let
|
|
44
|
+
let usePrevious=(r,t)=>{let[o,u]=react.useState([r,t]);return o[1]!==r&&u([o[1],r]),o[0]};
|
|
44
45
|
|
|
45
|
-
let
|
|
46
|
+
let usePreviousRef=t=>{let u=react.useRef();return react.useEffect(()=>{u.current=t;}),u.current};
|
|
46
47
|
|
|
47
|
-
let
|
|
48
|
+
let l={x:0,y:0},n=t=>t?.getBoundingClientRect(),u=(t,e)=>{if(!utils.isBrowser)return l;if(!e)return {x:window.scrollX,y:window.scrollY};let o=n(t?.current||document.body),u=n(e.current);return o?u?{x:(u.x||0)-(o.x||0),y:(u.y||0)-(o.y||0)}:{x:o.left,y:o.top}:l};let useScrollPosition=(l,n=[],i,c,m)=>{let f=react.useRef(u(null,c)),s=null,d=()=>{let t=u(i,c);l(t,f.current),f.current=t,s=null;};useIsomorphicLayoutEffect(()=>{if(!utils.isBrowser)return;let t=dom.listenScroll(()=>{m?null===s&&(s=window.setTimeout(d,m)):d();},c?.current);return ()=>{t(),s&&clearTimeout(s);}},n);};
|
|
48
49
|
|
|
49
|
-
let
|
|
50
|
+
let useScrollThreshold=(i,m)=>{let[u,f]=react.useState(!1),n=react.useCallback(()=>{if(i){let r=window.scrollY,e=r<i,o=r>i;f(o),m&&m(e,o);}},[i,m]);return react.useEffect(()=>{if(i){let r=dom.listenScroll(n);return n(),r}return utils.noop},[i,n]),u};
|
|
50
51
|
|
|
51
|
-
let
|
|
52
|
+
let useSmoothScroll=m=>{let i=useFixedOffset();return react.useCallback((e,l,f,u,n)=>{let c;let p=!1;if(utils.isNumber(e))c=e;else if(e){let t=document.getElementById(e);t&&(c=dom.getOffsetTopSlim(t)-i.current,p=!0);}utils.isNumber(c)&&dom.scrollTo(c=c+(l||0)+(m||p?0:i.current),f,u,n);},[m,i])};
|
|
52
53
|
|
|
53
|
-
let
|
|
54
|
+
let useSpinDelay=(u,c=500,i=200)=>{let[n,o]=react.useState(0),l=react.useRef();return react.useEffect(()=>{u&&0===n&&(clearTimeout(l.current),l.current=setTimeout(()=>{if(!u)return o(0);l.current=setTimeout(()=>{o(3);},i),o(2);},c),o(1)),u||2===n||(clearTimeout(l.current),o(0));},[u,n,c,i]),react.useEffect(()=>()=>clearTimeout(l.current),[]),2===n||3===n};
|
|
55
|
+
|
|
56
|
+
let useTraceUpdate=r=>{let c=react.useRef(r);react.useEffect(()=>{let e=Object.entries(r).reduce((e,[t,r])=>(c.current[t]!==r&&(e[t]=[c.current[t],r]),e),{});Object.keys(e).length>0&&console.info("[@koine/react:useTraceUpdate] changed props:",e),c.current=r;});};
|
|
57
|
+
|
|
58
|
+
let useUpdateEffect=(r,f)=>{let o=useFirstMountState();react.useEffect(()=>{if(!o)return r()},f);};
|
|
59
|
+
|
|
60
|
+
let useWindowSize=(o,n)=>{let[d,w]=react.useState(0),[m,u]=react.useState(0);return react.useEffect(()=>{let e=()=>{w(window.innerWidth),u(window.innerHeight);},i=o?dom.listenResizeDebounced(0,e,o,n):dom.listenResize(e);return e(),i},[o,n]),[d,m]};
|
|
54
61
|
|
|
62
|
+
exports.FaviconTags = FaviconTags;
|
|
63
|
+
exports.Meta = Meta;
|
|
64
|
+
exports.NoJs = NoJs;
|
|
55
65
|
exports.classed = classed;
|
|
56
66
|
exports.createUseMediaQueryWidth = createUseMediaQueryWidth;
|
|
57
67
|
exports.extendComponent = extendComponent;
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
1
|
+
export { classed } from "./classed";
|
|
2
|
+
export { createUseMediaQueryWidth, type MediaQuerWidthDef, type MediaQueryWidth, } from "./createUseMediaQueryWidth";
|
|
3
|
+
export { type ExtendableComponent, type OverridableComponents, type WithComponents, extendComponent, } from "./extendComponent";
|
|
4
|
+
export { FaviconTags, type FaviconTagsProps } from "./FaviconTags";
|
|
5
|
+
export { mergeRefs } from "./mergeRefs";
|
|
6
|
+
export { Meta, type MetaProps } from "./Meta";
|
|
7
|
+
export { NoJs, type NoJsProps } from "./NoJs";
|
|
8
|
+
export type { Polymorphic } from "./Polymorphic";
|
|
9
|
+
export { useAsyncFn, type UseAsyncFnReturn, type UseAsyncState, } from "./useAsyncFn";
|
|
10
|
+
export { useFirstMountState } from "./useFirstMountState";
|
|
11
|
+
export { useFixedOffset } from "./useFixedOffset";
|
|
12
|
+
export { useFocus } from "./useFocus";
|
|
13
|
+
export { useInterval } from "./useInterval";
|
|
14
|
+
export { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";
|
|
15
|
+
export { useKeyUp } from "./useKeyUp";
|
|
16
|
+
export { useMeasure, type UseMeasureOptions, type UseMeasureReturn, } from "./useMeasure";
|
|
17
|
+
export { useMountedState } from "./useMountedState";
|
|
18
|
+
export { useNavigateAway, type UseNavigateAwayHandler, } from "./useNavigateAway";
|
|
19
|
+
export { usePrevious } from "./usePrevious";
|
|
20
|
+
export { usePreviousRef } from "./usePreviousRef";
|
|
21
|
+
export { useScrollPosition } from "./useScrollPosition";
|
|
22
|
+
export { useScrollThreshold } from "./useScrollThreshold";
|
|
23
|
+
export { useSmoothScroll } from "./useSmoothScroll";
|
|
24
|
+
export { useSpinDelay } from "./useSpinDelay";
|
|
25
|
+
export { useTraceUpdate } from "./useTraceUpdate";
|
|
26
|
+
export { useUpdateEffect } from "./useUpdateEffect";
|
|
27
|
+
export { useWindowSize } from "./useWindowSize";
|
|
28
|
+
export type { KoineComponentProps, KoineComponent } from "./types";
|
package/index.esm.js
CHANGED
|
@@ -1,51 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isBrowser,
|
|
1
|
+
import { forwardRef, createElement, useLayoutEffect, useEffect, useState, useRef, useCallback, useMemo } from 'react';
|
|
2
|
+
import { isBrowser, getMediaQueryWidthResolvers, isUndefined, debounce, noop, isNumber } from '@koine/utils';
|
|
3
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
4
|
import { listenResizeDebounced, $each, calculateFixedOffset, injectCss, on, listenScrollDebounced, off, listenScroll, getOffsetTopSlim, scrollTo, listenResize } from '@koine/dom';
|
|
4
5
|
|
|
5
|
-
let
|
|
6
|
+
let classed=r=>{let s=r.type||r;return function(r,...a){return forwardRef(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)t.startsWith("$")||(i[t]=e[t]);let c=o||r[0];return c=(c.match(/class="([^"]*)/)?.[1]||c)+(e?.className?" "+e?.className:""),createElement(s,{...i,className:c||void 0,ref:n})})}};
|
|
6
7
|
|
|
7
|
-
let
|
|
8
|
+
let useIsomorphicLayoutEffect=isBrowser?useLayoutEffect:useEffect;
|
|
8
9
|
|
|
9
|
-
let
|
|
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");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 (l(e.matches),e.addEventListener)?(e.addEventListener("change",t),()=>{e.removeEventListener("change",t);}):(e.addListener(t),()=>{e.removeListener(t);})},[u]),c}};
|
|
10
11
|
|
|
11
|
-
let
|
|
12
|
+
let extendComponent=(t,o)=>Object.assign(o=>createElement(t,o),{...o,defaultProps:o});
|
|
12
13
|
|
|
13
|
-
let
|
|
14
|
+
let FaviconTags=({name:a,color:t,safariTabColor:o,tileColor:c,themeColor:l})=>jsxs(Fragment,{children:[jsx("link",{rel:"shortcut icon",href:"/favicon.ico",type:"image/x-icon"}),jsx("link",{rel:"apple-touch-icon",sizes:"180x180",href:"/apple-touch-icon.png"}),jsx("link",{rel:"icon",type:"image/png",sizes:"32x32",href:"/favicon-32x32.png"}),jsx("link",{rel:"icon",type:"image/png",sizes:"16x16",href:"/favicon-16x16.png"}),jsx("link",{rel:"manifest",href:"/site.webmanifest"}),jsx("link",{rel:"mask-icon",href:"/safari-pinned-tab.svg",color:o||t}),jsx("meta",{name:"apple-mobile-web-app-title",content:a}),jsx("meta",{name:"application-name",content:a}),jsx("meta",{name:"msapplication-TileColor",content:c||t}),jsx("meta",{name:"theme-color",content:l||t})]});
|
|
14
15
|
|
|
15
|
-
let
|
|
16
|
+
let mergeRefs=e=>r=>{e.forEach(e=>{"function"==typeof e?e(r):null!=e&&(e.current=r);});};
|
|
16
17
|
|
|
17
|
-
let
|
|
18
|
+
let Meta=({zoom:t})=>jsx("meta",{name:"viewport",content:`width=device-width, initial-scale=1, maximum-scale=1${t?"":", user-scalable=0"}`});
|
|
18
19
|
|
|
19
|
-
let
|
|
20
|
+
let NoJs=t=>jsx("script",{id:"no-js",dangerouslySetInnerHTML:{__html:'document.querySelector("html").className=document.querySelector("html").className.replace(/no-js/,"") + "js";'}});
|
|
20
21
|
|
|
21
|
-
let
|
|
22
|
+
let useMountedState=()=>{let u=useRef(!1),n=useCallback(()=>u.current,[]);return useEffect(()=>(u.current=!0,()=>{u.current=!1;}),[]),n};
|
|
22
23
|
|
|
23
|
-
let
|
|
24
|
+
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))},u);return [i,g]};
|
|
24
25
|
|
|
25
|
-
let
|
|
26
|
+
let useFirstMountState=()=>{let r=useRef(!0);return r.current?(r.current=!1,!0):r.current};
|
|
26
27
|
|
|
27
|
-
let
|
|
28
|
+
let n$1=e=>{injectCss("useFixedOffset",`html{scroll-padding-top: ${e}px}`);};let useFixedOffset=i=>{let l=useRef(0);return useIsomorphicLayoutEffect(()=>{let e=()=>{let e=calculateFixedOffset();l.current=e,n$1(e);};if(e(),!ResizeObserver)return listenResizeDebounced(0,e);{let e=new ResizeObserver(e=>{let r=0;e.forEach(e=>{r+=e.contentRect.height;}),l.current=r,debounce(()=>n$1(r),400,!0)();});return $each(i||"[data-fixed]",t=>{e&&e.observe(t);}),()=>{e?.disconnect();}}},[i]),l};
|
|
28
29
|
|
|
29
|
-
let
|
|
30
|
+
let useFocus=()=>{let r=useRef(null);return [r,()=>{r.current&&r.current.focus();}]};
|
|
30
31
|
|
|
31
|
-
let
|
|
32
|
+
let useInterval=(n,l,u=[])=>{let o=useRef();useEffect(()=>{o.current=n;},[n,...u]),useEffect(()=>{if(null!==l){let r=setInterval(function(){o.current&&o.current();},l);return ()=>clearInterval(r)}return noop},[l]);};
|
|
32
33
|
|
|
33
|
-
let
|
|
34
|
+
let useKeyUp=(o,r=[])=>{useEffect(()=>on(window,"keyup",e=>{e.ctrlKey||e.altKey||e.shiftKey||e.metaKey||o(e);}),[o,...r]);};
|
|
34
35
|
|
|
35
|
-
let
|
|
36
|
+
let e;let m=e=>{let t=[];if(!e||e===document.body)return t;let{overflow:r,overflowX:n,overflowY:u}=window.getComputedStyle(e);return [r,n,u].some(e=>"auto"===e||"scroll"===e)&&t.push(e),[...t,...m(e.parentElement)]},p=["x","y","top","bottom","left","right","width","height"],d=(e,t)=>p.every(r=>e[r]===t[r]);let useMeasure=p=>{let{scroll:h=!1}=p||{},[a,b]=useState({left:0,top:0,width:0,height:0,bottom:0,right:0,x:0,y:0}),g=useRef([null,null,null,a]),v=useRef(!1);useEffect(()=>(v.current=!0,()=>void(v.current=!1)),[]);let[w,,y]=useMemo(()=>{let e=(...e)=>{let[t,,,r]=g.current;if(!t)return;let n=t.getBoundingClientRect();Object.freeze(n),v.current&&!d(r,n)&&(g.current[3]=n,b(n));},t=debounce(e);return [e,t,t]},[b]);function x(){let[,e,t]=g.current;e&&(e.forEach(e=>off(e,"scroll",y)),g.current[1]=null),t&&(t.disconnect(),g.current[2]=null);}function z(){let[t,r]=g.current;t&&!e&&ResizeObserver&&(e=new ResizeObserver(y),g.current[2]=e,e.observe(t),h&&r&&r.forEach(e=>on(e,"scroll",y,{capture:!0,passive:!0})));}return useEffect(()=>h?listenScrollDebounced(0,w,100):noop,[h,w]),useEffect(()=>listenResizeDebounced(0,w,100),[w]),useEffect(()=>{x(),z();},[h]),useEffect(()=>(w(),x),[]),[e=>{e&&e!==g.current[0]&&(x(),g.current[0]=e,g.current[1]=m(e),z());},a,w]};
|
|
36
37
|
|
|
37
|
-
let
|
|
38
|
+
let useNavigateAway=a=>{let o=useRef();useEffect(()=>{o.current=e=>{let t=a(e);return (t&&e.preventDefault(),"string"==typeof t)?e.returnValue=t:e.defaultPrevented?e.returnValue="":void 0};},[a]),useEffect(()=>on(window,"beforeunload",e=>o.current?.(e)),[]);};
|
|
38
39
|
|
|
39
|
-
let
|
|
40
|
+
let usePrevious=(r,t)=>{let[o,u]=useState([r,t]);return o[1]!==r&&u([o[1],r]),o[0]};
|
|
40
41
|
|
|
41
|
-
let
|
|
42
|
+
let usePreviousRef=t=>{let u=useRef();return useEffect(()=>{u.current=t;}),u.current};
|
|
42
43
|
|
|
43
|
-
let
|
|
44
|
+
let l={x:0,y:0},n=t=>t?.getBoundingClientRect(),u=(t,e)=>{if(!isBrowser)return l;if(!e)return {x:window.scrollX,y:window.scrollY};let o=n(t?.current||document.body),u=n(e.current);return o?u?{x:(u.x||0)-(o.x||0),y:(u.y||0)-(o.y||0)}:{x:o.left,y:o.top}:l};let useScrollPosition=(l,n=[],i,c,m)=>{let f=useRef(u(null,c)),s=null,d=()=>{let t=u(i,c);l(t,f.current),f.current=t,s=null;};useIsomorphicLayoutEffect(()=>{if(!isBrowser)return;let t=listenScroll(()=>{m?null===s&&(s=window.setTimeout(d,m)):d();},c?.current);return ()=>{t(),s&&clearTimeout(s);}},n);};
|
|
44
45
|
|
|
45
|
-
let
|
|
46
|
+
let useScrollThreshold=(i,m)=>{let[u,f]=useState(!1),n=useCallback(()=>{if(i){let r=window.scrollY,e=r<i,o=r>i;f(o),m&&m(e,o);}},[i,m]);return useEffect(()=>{if(i){let r=listenScroll(n);return n(),r}return noop},[i,n]),u};
|
|
46
47
|
|
|
47
|
-
let
|
|
48
|
+
let useSmoothScroll=m=>{let i=useFixedOffset();return useCallback((e,l,f,u,n)=>{let c;let p=!1;if(isNumber(e))c=e;else if(e){let t=document.getElementById(e);t&&(c=getOffsetTopSlim(t)-i.current,p=!0);}isNumber(c)&&scrollTo(c=c+(l||0)+(m||p?0:i.current),f,u,n);},[m,i])};
|
|
48
49
|
|
|
49
|
-
let
|
|
50
|
+
let useSpinDelay=(u,c=500,i=200)=>{let[n,o]=useState(0),l=useRef();return useEffect(()=>{u&&0===n&&(clearTimeout(l.current),l.current=setTimeout(()=>{if(!u)return o(0);l.current=setTimeout(()=>{o(3);},i),o(2);},c),o(1)),u||2===n||(clearTimeout(l.current),o(0));},[u,n,c,i]),useEffect(()=>()=>clearTimeout(l.current),[]),2===n||3===n};
|
|
51
|
+
|
|
52
|
+
let useTraceUpdate=r=>{let c=useRef(r);useEffect(()=>{let e=Object.entries(r).reduce((e,[t,r])=>(c.current[t]!==r&&(e[t]=[c.current[t],r]),e),{});Object.keys(e).length>0&&console.info("[@koine/react:useTraceUpdate] changed props:",e),c.current=r;});};
|
|
53
|
+
|
|
54
|
+
let useUpdateEffect=(r,f)=>{let o=useFirstMountState();useEffect(()=>{if(!o)return r()},f);};
|
|
55
|
+
|
|
56
|
+
let useWindowSize=(o,n)=>{let[d,w]=useState(0),[m,u]=useState(0);return useEffect(()=>{let e=()=>{w(window.innerWidth),u(window.innerHeight);},i=o?listenResizeDebounced(0,e,o,n):listenResize(e);return e(),i},[o,n]),[d,m]};
|
|
50
57
|
|
|
51
|
-
export { classed, createUseMediaQueryWidth, extendComponent, mergeRefs, useAsyncFn, useFirstMountState, useFixedOffset, useFocus, useInterval, useIsomorphicLayoutEffect, useKeyUp, useMeasure, useMountedState, useNavigateAway, usePrevious, usePreviousRef, useScrollPosition, useScrollThreshold, useSmoothScroll, useSpinDelay, useTraceUpdate, useUpdateEffect, useWindowSize };
|
|
58
|
+
export { FaviconTags, Meta, NoJs, classed, createUseMediaQueryWidth, extendComponent, mergeRefs, useAsyncFn, useFirstMountState, useFixedOffset, useFocus, useInterval, useIsomorphicLayoutEffect, useKeyUp, useMeasure, useMountedState, useNavigateAway, usePrevious, usePreviousRef, useScrollPosition, useScrollThreshold, useSmoothScroll, useSpinDelay, useTraceUpdate, useUpdateEffect, useWindowSize };
|
package/index.js
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
1
|
+
export { classed } from "./classed";
|
|
2
|
+
export { createUseMediaQueryWidth, } from "./createUseMediaQueryWidth";
|
|
3
|
+
export { extendComponent, } from "./extendComponent";
|
|
4
|
+
export { FaviconTags } from "./FaviconTags";
|
|
5
|
+
export { mergeRefs } from "./mergeRefs";
|
|
6
|
+
export { Meta } from "./Meta";
|
|
7
|
+
export { NoJs } from "./NoJs";
|
|
8
|
+
export { useAsyncFn, } from "./useAsyncFn";
|
|
9
|
+
export { useFirstMountState } from "./useFirstMountState";
|
|
10
|
+
export { useFixedOffset } from "./useFixedOffset";
|
|
11
|
+
export { useFocus } from "./useFocus";
|
|
12
|
+
export { useInterval } from "./useInterval";
|
|
13
|
+
export { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";
|
|
14
|
+
export { useKeyUp } from "./useKeyUp";
|
|
15
|
+
export { useMeasure, } from "./useMeasure";
|
|
16
|
+
export { useMountedState } from "./useMountedState";
|
|
17
|
+
export { useNavigateAway, } from "./useNavigateAway";
|
|
18
|
+
export { usePrevious } from "./usePrevious";
|
|
19
|
+
export { usePreviousRef } from "./usePreviousRef";
|
|
20
|
+
export { useScrollPosition } from "./useScrollPosition";
|
|
21
|
+
export { useScrollThreshold } from "./useScrollThreshold";
|
|
22
|
+
export { useSmoothScroll } from "./useSmoothScroll";
|
|
23
|
+
export { useSpinDelay } from "./useSpinDelay";
|
|
24
|
+
export { useTraceUpdate } from "./useTraceUpdate";
|
|
25
|
+
export { useUpdateEffect } from "./useUpdateEffect";
|
|
26
|
+
export { useWindowSize } from "./useWindowSize";
|
package/mergeRefs.d.ts
ADDED
package/mergeRefs.js
ADDED