@ilokesto/utilinent 1.1.0 → 1.1.1
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/README.md +10 -1
- package/dist/components/For/index.d.ts +2 -0
- package/dist/components/{For.js → For/index.js} +2 -2
- package/dist/components/For/types.d.ts +13 -0
- package/dist/components/For/types.js +2 -0
- package/dist/components/Mount/index.d.ts +2 -0
- package/dist/components/{Mount.js → Mount/index.js} +3 -5
- package/dist/components/Mount/types.d.ts +13 -0
- package/dist/components/{Observer.d.ts → Observer/index.d.ts} +1 -1
- package/dist/components/{Observer.js → Observer/index.js} +2 -2
- package/dist/components/Observer/types.d.ts +8 -0
- package/dist/components/{OptionalWrapper.d.ts → OptionalWrapper/index.d.ts} +1 -1
- package/dist/components/{OptionalWrapper.js → OptionalWrapper/index.js} +1 -1
- package/dist/components/OptionalWrapper/types.d.ts +6 -0
- package/dist/components/Repeat/index.d.ts +2 -0
- package/dist/components/{Repeat.js → Repeat/index.js} +3 -5
- package/dist/components/Repeat/types.d.ts +13 -0
- package/dist/components/Show/index.d.ts +2 -0
- package/dist/components/{Show.js → Show/index.js} +4 -6
- package/dist/components/Show/types.d.ts +18 -0
- package/dist/components/{Slacker.d.ts → Slacker/index.d.ts} +1 -1
- package/dist/components/{Slacker.js → Slacker/index.js} +1 -1
- package/dist/components/Slacker/types.d.ts +16 -0
- package/dist/components/{Slot.d.ts → Slot/Slot.d.ts} +0 -3
- package/dist/components/Slot/Slot.js +37 -0
- package/dist/components/Slot/Slottable.d.ts +4 -0
- package/dist/components/Slot/Slottable.js +8 -0
- package/dist/components/Slot/composeRefs.d.ts +2 -0
- package/dist/components/Slot/composeRefs.js +12 -0
- package/dist/components/Slot/index.d.ts +2 -0
- package/dist/components/Slot/index.js +2 -0
- package/dist/components/Slot/mergeProps.d.ts +2 -0
- package/dist/components/Slot/mergeProps.js +23 -0
- package/dist/components/Slot/types.d.ts +1 -0
- package/dist/components/Slot/types.js +1 -0
- package/dist/components/Switch/Match.d.ts +3 -0
- package/dist/components/Switch/Match.js +11 -0
- package/dist/components/Switch/Switch.d.ts +2 -0
- package/dist/components/Switch/Switch.js +24 -0
- package/dist/components/Switch/flattenChildren.d.ts +1 -0
- package/dist/components/Switch/flattenChildren.js +7 -0
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/Switch/index.js +2 -0
- package/dist/components/Switch/types.d.ts +16 -0
- package/dist/components/Switch/types.js +1 -0
- package/dist/constants/htmlTags.d.ts +88 -2
- package/dist/constants/htmlTags.js +87 -3
- package/dist/core/PluginManager.d.ts +7 -8
- package/dist/core/PluginManager.js +20 -15
- package/dist/core/createProxy.d.ts +2 -0
- package/dist/core/{createTagProxy.js → createProxy.js} +2 -2
- package/dist/index.d.ts +5 -3
- package/dist/index.js +7 -2
- package/dist/types/RegistryCategory.d.ts +1 -0
- package/dist/types/RegistryCategory.js +1 -0
- package/dist/types/index.d.ts +4 -47
- package/dist/types/index.js +4 -1
- package/dist/types/register.d.ts +4 -18
- package/dist/types/tagHelper.d.ts +20 -0
- package/dist/types/tagHelper.js +1 -0
- package/dist/types/utils.d.ts +14 -0
- package/dist/types/utils.js +1 -0
- package/package.json +1 -1
- package/dist/components/For.d.ts +0 -2
- package/dist/components/Mount.d.ts +0 -2
- package/dist/components/Repeat.d.ts +0 -2
- package/dist/components/Show.d.ts +0 -2
- package/dist/components/Slot.js +0 -75
- package/dist/components/Switch.d.ts +0 -4
- package/dist/components/Switch.js +0 -39
- package/dist/core/createTagProxy.d.ts +0 -3
- package/dist/core/tagProxyTypes.d.ts +0 -1
- package/dist/types/for.d.ts +0 -23
- package/dist/types/mount.d.ts +0 -20
- package/dist/types/repeat.d.ts +0 -24
- package/dist/types/show.d.ts +0 -31
- package/dist/types/switch.d.ts +0 -27
- /package/dist/{core/tagProxyTypes.js → components/Mount/types.js} +0 -0
- /package/dist/{types/for.js → components/Observer/types.js} +0 -0
- /package/dist/{types/mount.js → components/OptionalWrapper/types.js} +0 -0
- /package/dist/{types/repeat.js → components/Repeat/types.js} +0 -0
- /package/dist/{types/show.js → components/Show/types.js} +0 -0
- /package/dist/{types/switch.js → components/Slacker/types.js} +0 -0
package/README.md
CHANGED
|
@@ -87,4 +87,13 @@ const UserListAfter = () => {
|
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
export default UserListAfter;
|
|
90
|
-
```
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## Custom proxy components
|
|
95
|
+
|
|
96
|
+
If you want to build your own `Show`-style component (for example, `Clickable`),
|
|
97
|
+
there is a short guide in the repo:
|
|
98
|
+
|
|
99
|
+
- `CUSTOM_CLICKABLE.md`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createElement, forwardRef } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { createProxy } from "../../core/createProxy";
|
|
3
3
|
function BaseFor({ each, children, fallback = null, }) {
|
|
4
4
|
return each && each.length > 0 ? each.map(children) : fallback;
|
|
5
5
|
}
|
|
@@ -9,4 +9,4 @@ forwardRef(({ each, children, fallback = null, ...props }, ref) => {
|
|
|
9
9
|
const content = BaseFor({ each, children, fallback });
|
|
10
10
|
return createElement(tag, { ...props, ref }, content);
|
|
11
11
|
});
|
|
12
|
-
export const For =
|
|
12
|
+
export const For = createProxy(BaseFor, renderForTag, "for");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BaseTypeHelperFn, Fallback, ProxyType } from "../../types";
|
|
2
|
+
export interface ForProps<T extends Array<unknown>> extends Fallback {
|
|
3
|
+
each: T | null | undefined;
|
|
4
|
+
children: (item: T[number], index: number) => React.ReactNode;
|
|
5
|
+
}
|
|
6
|
+
type BaseForType<X = object> = {
|
|
7
|
+
<const T extends Array<unknown>>(props: X & ForProps<T>): React.ReactNode;
|
|
8
|
+
};
|
|
9
|
+
interface BaseForTypeFn extends BaseTypeHelperFn {
|
|
10
|
+
type: BaseForType<this["props"]>;
|
|
11
|
+
}
|
|
12
|
+
export type ForType = ProxyType<BaseForTypeFn, "for">;
|
|
13
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createElement, forwardRef, useEffect, useLayoutEffect, useRef, useState, } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { createProxy } from "../../core/createProxy";
|
|
3
3
|
const isPromiseLike = (value) => (typeof value === "object" || typeof value === "function") &&
|
|
4
4
|
value !== null &&
|
|
5
5
|
typeof value.then === "function";
|
|
@@ -61,10 +61,8 @@ function BaseMount({ children, fallback = null, onError }) {
|
|
|
61
61
|
}, [children, onError]);
|
|
62
62
|
return status === "resolved" ? resolvedChildren : fallback;
|
|
63
63
|
}
|
|
64
|
-
const renderForTag = (tag) =>
|
|
65
|
-
// forward ref so consumers can attach a ref to the underlying DOM element
|
|
66
|
-
forwardRef(function Render({ children, fallback = null, onError, ...props }, ref) {
|
|
64
|
+
const renderForTag = (tag) => forwardRef(function Render({ children, fallback = null, onError, ...props }, ref) {
|
|
67
65
|
const content = BaseMount({ children, fallback, onError });
|
|
68
66
|
return createElement(tag, { ...props, ref }, content);
|
|
69
67
|
});
|
|
70
|
-
export const Mount =
|
|
68
|
+
export const Mount = createProxy(BaseMount, renderForTag, "mount");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BaseTypeHelperFn, Fallback, ProxyType } from "../../types";
|
|
2
|
+
export interface MountProps extends Fallback {
|
|
3
|
+
children: React.ReactNode | (() => React.ReactNode | Promise<React.ReactNode>);
|
|
4
|
+
onError?: (error: unknown) => void;
|
|
5
|
+
}
|
|
6
|
+
type BaseMountType<X = object> = {
|
|
7
|
+
(props: X & MountProps): React.ReactNode;
|
|
8
|
+
};
|
|
9
|
+
interface BaseMountTypeFn extends BaseTypeHelperFn {
|
|
10
|
+
type: BaseMountType<this["props"]>;
|
|
11
|
+
}
|
|
12
|
+
export type MountType = ProxyType<BaseMountTypeFn, "mount">;
|
|
13
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ObserverProps } from "./types";
|
|
2
2
|
export declare const Observer: import("react").ForwardRefExoticComponent<ObserverProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
3
3
|
ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
|
|
4
4
|
}, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useCallback } from "react";
|
|
3
|
-
import { useIntersectionObserver } from "
|
|
4
|
-
import { Show } from "
|
|
3
|
+
import { useIntersectionObserver } from "../../hooks/useIntersectionObserver";
|
|
4
|
+
import { Show } from "../Show";
|
|
5
5
|
export const Observer = forwardRef(function Observer({ children, fallback = null, threshold = 0, rootMargin = "0px", triggerOnce: freezeOnceVisible = false, onIntersect: onChange, style, ...props }, forwardedRef) {
|
|
6
6
|
const { ref: observerRef, isIntersecting } = useIntersectionObserver({
|
|
7
7
|
threshold,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Fallback } from "../../types";
|
|
2
|
+
export interface ObserverProps extends Fallback {
|
|
3
|
+
children?: React.ReactNode | ((isIntersecting: boolean) => React.ReactNode);
|
|
4
|
+
threshold?: number | number[];
|
|
5
|
+
rootMargin?: string;
|
|
6
|
+
triggerOnce?: boolean;
|
|
7
|
+
onIntersect?: (isIntersecting: boolean, entry: IntersectionObserverEntry) => void;
|
|
8
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { OptionalWrapperProps } from "
|
|
1
|
+
import { OptionalWrapperProps } from "./types";
|
|
2
2
|
export declare function OptionalWrapper<T>({ when, children, wrapper, fallback }: OptionalWrapperProps<T>): React.ReactNode;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Show } from "
|
|
2
|
+
import { Show } from "../Show";
|
|
3
3
|
export function OptionalWrapper({ when, children, wrapper, fallback }) {
|
|
4
4
|
return _jsx(Show, { when: when, fallback: fallback ? fallback(children) : children, children: wrapper(children) });
|
|
5
5
|
}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createElement, forwardRef } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { createProxy } from "../../core/createProxy";
|
|
4
4
|
function BaseRepeat({ times, children, fallback = null }) {
|
|
5
5
|
const content = times && times > 0 && Number.isInteger(times)
|
|
6
6
|
? Array.from({ length: times }, (_, i) => children(i))
|
|
7
7
|
: fallback ?? null;
|
|
8
8
|
return _jsx(_Fragment, { children: content });
|
|
9
9
|
}
|
|
10
|
-
const renderForTag = (tag) =>
|
|
11
|
-
// forward ref so consumers can attach a ref to the underlying DOM element
|
|
12
|
-
forwardRef(({ times, children, fallback = null, ...props }, ref) => {
|
|
10
|
+
const renderForTag = (tag) => forwardRef(({ times, children, fallback = null, ...props }, ref) => {
|
|
13
11
|
const content = BaseRepeat({ times, children, fallback });
|
|
14
12
|
return createElement(tag, { ...props, ref }, content);
|
|
15
13
|
});
|
|
16
|
-
export const Repeat =
|
|
14
|
+
export const Repeat = createProxy(BaseRepeat, renderForTag, "repeat");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BaseTypeHelperFn, Fallback, ProxyType } from "../../types";
|
|
2
|
+
export interface RepeatProps extends Fallback {
|
|
3
|
+
times: number;
|
|
4
|
+
children: (index: number) => React.ReactNode;
|
|
5
|
+
}
|
|
6
|
+
type BaseRepeatType<X = object> = {
|
|
7
|
+
(props: X & RepeatProps): React.ReactNode;
|
|
8
|
+
};
|
|
9
|
+
interface BaseRepeatTypeFn extends BaseTypeHelperFn {
|
|
10
|
+
type: BaseRepeatType<this["props"]>;
|
|
11
|
+
}
|
|
12
|
+
export type RepeatType = ProxyType<BaseRepeatTypeFn, "repeat">;
|
|
13
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createElement, forwardRef } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import { resolveWhen } from "
|
|
2
|
+
import { createProxy } from "../../core/createProxy";
|
|
3
|
+
import { resolveWhen } from "../../utils/resolveWhen";
|
|
4
4
|
const BaseShow = ({ when, children, fallback = null }) => {
|
|
5
5
|
const shouldRender = resolveWhen(when);
|
|
6
6
|
return shouldRender
|
|
@@ -9,10 +9,8 @@ const BaseShow = ({ when, children, fallback = null }) => {
|
|
|
9
9
|
: children
|
|
10
10
|
: fallback;
|
|
11
11
|
};
|
|
12
|
-
const renderForTag = (tag) =>
|
|
13
|
-
// forward ref so consumers like Observer can pass a ref to the real DOM element
|
|
14
|
-
forwardRef(function Render({ when, children, fallback = null, ...props }, ref) {
|
|
12
|
+
const renderForTag = (tag) => forwardRef(function Render({ when, children, fallback = null, ...props }, ref) {
|
|
15
13
|
const content = BaseShow({ when, children, fallback });
|
|
16
14
|
return createElement(tag, { ...props, ref }, content);
|
|
17
15
|
});
|
|
18
|
-
export const Show =
|
|
16
|
+
export const Show = createProxy(BaseShow, renderForTag, "show");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BaseTypeHelperFn, Fallback, NonNullableElements, ProxyType } from "../../types";
|
|
2
|
+
export interface ShowPropsArray<T extends unknown[]> extends Fallback {
|
|
3
|
+
when: T;
|
|
4
|
+
children: React.ReactNode | ((item: NonNullableElements<T>) => React.ReactNode);
|
|
5
|
+
}
|
|
6
|
+
export interface ShowProps<T = unknown> extends Fallback {
|
|
7
|
+
when: T;
|
|
8
|
+
children: React.ReactNode | ((item: NonNullable<T>) => React.ReactNode);
|
|
9
|
+
}
|
|
10
|
+
export type BaseShowType<X = object> = {
|
|
11
|
+
<const T extends Array<unknown>>(props: X & ShowPropsArray<T>): React.ReactNode;
|
|
12
|
+
<const T extends unknown>(props: X & ShowProps<T>): React.ReactNode;
|
|
13
|
+
};
|
|
14
|
+
interface BaseShowTypeFn extends BaseTypeHelperFn {
|
|
15
|
+
type: BaseShowType<this["props"]>;
|
|
16
|
+
}
|
|
17
|
+
export type ShowType = ProxyType<BaseShowTypeFn, "show">;
|
|
18
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { SlackerProps } from "
|
|
1
|
+
import { SlackerProps } from "./types";
|
|
2
2
|
export declare function Slacker<T = any>({ children, errorFallback, loadingFallback, loader, threshold, rootMargin, onError, maxRetries, retryDelay, }: SlackerProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useState } from "react";
|
|
3
|
-
import { Observer } from "
|
|
3
|
+
import { Observer } from "../Observer";
|
|
4
4
|
export function Slacker({ children, errorFallback, loadingFallback, loader, threshold = 0.1, rootMargin = "50px", onError, maxRetries = 0, retryDelay = 1000, }) {
|
|
5
5
|
const [loadedData, setLoadedData] = useState(null);
|
|
6
6
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type SlackerFallbackProps = {
|
|
2
|
+
isLoading: boolean;
|
|
3
|
+
error: Error | null;
|
|
4
|
+
retry: () => void;
|
|
5
|
+
};
|
|
6
|
+
export type SlackerProps<T = any> = {
|
|
7
|
+
children: (loaded: T) => React.ReactNode;
|
|
8
|
+
errorFallback?: React.ReactNode | ((props: SlackerFallbackProps) => React.ReactNode);
|
|
9
|
+
loadingFallback?: React.ReactNode;
|
|
10
|
+
threshold?: number | number[];
|
|
11
|
+
rootMargin?: string;
|
|
12
|
+
loader: () => Promise<T> | T;
|
|
13
|
+
onError?: (error: Error) => void;
|
|
14
|
+
maxRetries?: number;
|
|
15
|
+
retryDelay?: number;
|
|
16
|
+
};
|
|
@@ -1,4 +1 @@
|
|
|
1
1
|
export declare const Slot: import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLElement> & import("react").RefAttributes<HTMLElement>>;
|
|
2
|
-
export declare const Slottable: ({ children }: {
|
|
3
|
-
children: React.ReactNode;
|
|
4
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Children, cloneElement, forwardRef, isValidElement } from 'react';
|
|
3
|
+
import { composeRefs } from './composeRefs';
|
|
4
|
+
import { mergeProps } from './mergeProps';
|
|
5
|
+
import { isSlottable } from './Slottable';
|
|
6
|
+
export const Slot = forwardRef((props, ref) => {
|
|
7
|
+
const { children, ...slotProps } = props;
|
|
8
|
+
const childrenArray = Children.toArray(children);
|
|
9
|
+
const slottable = childrenArray.find(isSlottable);
|
|
10
|
+
if (slottable) {
|
|
11
|
+
// Slottable의 children을 가져와서 병합
|
|
12
|
+
const slottableChild = slottable.props.children;
|
|
13
|
+
if (!isValidElement(slottableChild)) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const newElement = cloneElement(slottableChild, {
|
|
17
|
+
...mergeProps(slotProps, slottableChild.props),
|
|
18
|
+
ref: ref ? composeRefs(ref, slottableChild.ref) : slottableChild.ref,
|
|
19
|
+
key: slottable.key
|
|
20
|
+
});
|
|
21
|
+
const newChildren = childrenArray.map((child) => {
|
|
22
|
+
if (child === slottable) {
|
|
23
|
+
return newElement;
|
|
24
|
+
}
|
|
25
|
+
return child;
|
|
26
|
+
});
|
|
27
|
+
return _jsx(_Fragment, { children: newChildren });
|
|
28
|
+
}
|
|
29
|
+
const [child] = childrenArray;
|
|
30
|
+
if (!isValidElement(child)) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return cloneElement(child, {
|
|
34
|
+
...mergeProps(slotProps, child.props),
|
|
35
|
+
ref: ref ? composeRefs(ref, child.ref) : child.ref
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { isValidElement } from "react";
|
|
3
|
+
export function isSlottable(child) {
|
|
4
|
+
return isValidElement(child) && child.type === Slottable;
|
|
5
|
+
}
|
|
6
|
+
export const Slottable = ({ children }) => {
|
|
7
|
+
return _jsx(_Fragment, { children: children });
|
|
8
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function mergeProps(slotProps, childProps) {
|
|
2
|
+
const merged = { ...childProps };
|
|
3
|
+
for (const propName in slotProps) {
|
|
4
|
+
const slotProp = slotProps[propName];
|
|
5
|
+
const childProp = merged[propName];
|
|
6
|
+
if (/^on[A-Z]/.test(propName) && typeof slotProp === 'function' && typeof childProp === 'function') {
|
|
7
|
+
merged[propName] = (...args) => {
|
|
8
|
+
childProp(...args);
|
|
9
|
+
slotProp(...args);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
else if (propName === 'style' && typeof slotProp === 'object' && typeof childProp === 'object') {
|
|
13
|
+
merged[propName] = { ...childProp, ...slotProp };
|
|
14
|
+
}
|
|
15
|
+
else if (propName === 'className' && typeof slotProp === 'string' && typeof childProp === 'string') {
|
|
16
|
+
merged[propName] = [childProp, slotProp].filter(Boolean).join(' ');
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
merged[propName] = slotProp;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return merged;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Props = Record<string, any>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { isValidElement } from "react";
|
|
2
|
+
import { resolveWhen } from "../../utils/resolveWhen";
|
|
3
|
+
export function Match({ when, children }) {
|
|
4
|
+
if (!resolveWhen(when)) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
return typeof children === "function"
|
|
8
|
+
? children(when)
|
|
9
|
+
: children;
|
|
10
|
+
}
|
|
11
|
+
export const isMatchElement = (child) => isValidElement(child) && child.type === Match;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createElement, forwardRef } from "react";
|
|
2
|
+
import { createProxy } from "../../core/createProxy";
|
|
3
|
+
import { resolveWhen } from "../../utils/resolveWhen";
|
|
4
|
+
import { flattenChildren } from "./flattenChildren";
|
|
5
|
+
import { isMatchElement } from "./Match";
|
|
6
|
+
function BaseSwitch({ children, fallback = null }) {
|
|
7
|
+
const childArray = flattenChildren(children);
|
|
8
|
+
for (const child of childArray) {
|
|
9
|
+
if (!isMatchElement(child)) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
const { when } = child.props;
|
|
13
|
+
if (!resolveWhen(when)) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
return child;
|
|
17
|
+
}
|
|
18
|
+
return fallback;
|
|
19
|
+
}
|
|
20
|
+
const renderForTag = (tag) => forwardRef(function Render({ children, fallback = null, ...props }, ref) {
|
|
21
|
+
const content = BaseSwitch({ children, fallback });
|
|
22
|
+
return createElement(tag, { ...props, ref }, content);
|
|
23
|
+
});
|
|
24
|
+
export const Switch = createProxy(BaseSwitch, renderForTag, "switch");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const flattenChildren: (nodes: React.ReactNode) => React.ReactNode[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Children, Fragment, isValidElement } from "react";
|
|
2
|
+
export const flattenChildren = (nodes) => Children.toArray(nodes).flatMap((child) => {
|
|
3
|
+
if (isValidElement(child) && child.type === Fragment) {
|
|
4
|
+
return flattenChildren(child.props.children);
|
|
5
|
+
}
|
|
6
|
+
return [child];
|
|
7
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BaseTypeHelperFn, Fallback, ProxyType } from "../../types";
|
|
2
|
+
export interface MatchProps<T = unknown> {
|
|
3
|
+
when: T | null | undefined | false;
|
|
4
|
+
children: React.ReactNode | ((item: NonNullable<T>) => React.ReactNode);
|
|
5
|
+
}
|
|
6
|
+
export interface SwitchProps extends Fallback {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
type BaseSwitchType<X = object> = {
|
|
10
|
+
(props: X & SwitchProps): React.ReactNode;
|
|
11
|
+
};
|
|
12
|
+
interface BaseSwitchTypeFn extends BaseTypeHelperFn {
|
|
13
|
+
type: BaseSwitchType<this["props"]>;
|
|
14
|
+
}
|
|
15
|
+
export type SwitchType = ProxyType<BaseSwitchTypeFn, "switch">;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,2 +1,88 @@
|
|
|
1
|
-
export declare const htmlTags:
|
|
2
|
-
|
|
1
|
+
export declare const htmlTags: {
|
|
2
|
+
readonly a: "a";
|
|
3
|
+
readonly abbr: "abbr";
|
|
4
|
+
readonly address: "address";
|
|
5
|
+
readonly article: "article";
|
|
6
|
+
readonly aside: "aside";
|
|
7
|
+
readonly b: "b";
|
|
8
|
+
readonly bdi: "bdi";
|
|
9
|
+
readonly bdo: "bdo";
|
|
10
|
+
readonly blockquote: "blockquote";
|
|
11
|
+
readonly button: "button";
|
|
12
|
+
readonly canvas: "canvas";
|
|
13
|
+
readonly cite: "cite";
|
|
14
|
+
readonly code: "code";
|
|
15
|
+
readonly data: "data";
|
|
16
|
+
readonly datalist: "datalist";
|
|
17
|
+
readonly dd: "dd";
|
|
18
|
+
readonly del: "del";
|
|
19
|
+
readonly details: "details";
|
|
20
|
+
readonly dfn: "dfn";
|
|
21
|
+
readonly dialog: "dialog";
|
|
22
|
+
readonly div: "div";
|
|
23
|
+
readonly dl: "dl";
|
|
24
|
+
readonly dt: "dt";
|
|
25
|
+
readonly em: "em";
|
|
26
|
+
readonly fieldset: "fieldset";
|
|
27
|
+
readonly figcaption: "figcaption";
|
|
28
|
+
readonly figure: "figure";
|
|
29
|
+
readonly footer: "footer";
|
|
30
|
+
readonly form: "form";
|
|
31
|
+
readonly h1: "h1";
|
|
32
|
+
readonly h2: "h2";
|
|
33
|
+
readonly h3: "h3";
|
|
34
|
+
readonly h4: "h4";
|
|
35
|
+
readonly h5: "h5";
|
|
36
|
+
readonly h6: "h6";
|
|
37
|
+
readonly header: "header";
|
|
38
|
+
readonly hr: "hr";
|
|
39
|
+
readonly i: "i";
|
|
40
|
+
readonly img: "img";
|
|
41
|
+
readonly input: "input";
|
|
42
|
+
readonly ins: "ins";
|
|
43
|
+
readonly kbd: "kbd";
|
|
44
|
+
readonly label: "label";
|
|
45
|
+
readonly legend: "legend";
|
|
46
|
+
readonly li: "li";
|
|
47
|
+
readonly main: "main";
|
|
48
|
+
readonly map: "map";
|
|
49
|
+
readonly mark: "mark";
|
|
50
|
+
readonly menu: "menu";
|
|
51
|
+
readonly meter: "meter";
|
|
52
|
+
readonly nav: "nav";
|
|
53
|
+
readonly ol: "ol";
|
|
54
|
+
readonly option: "option";
|
|
55
|
+
readonly output: "output";
|
|
56
|
+
readonly p: "p";
|
|
57
|
+
readonly picture: "picture";
|
|
58
|
+
readonly pre: "pre";
|
|
59
|
+
readonly progress: "progress";
|
|
60
|
+
readonly q: "q";
|
|
61
|
+
readonly rp: "rp";
|
|
62
|
+
readonly rt: "rt";
|
|
63
|
+
readonly ruby: "ruby";
|
|
64
|
+
readonly s: "s";
|
|
65
|
+
readonly samp: "samp";
|
|
66
|
+
readonly section: "section";
|
|
67
|
+
readonly select: "select";
|
|
68
|
+
readonly small: "small";
|
|
69
|
+
readonly span: "span";
|
|
70
|
+
readonly strong: "strong";
|
|
71
|
+
readonly sub: "sub";
|
|
72
|
+
readonly summary: "summary";
|
|
73
|
+
readonly sup: "sup";
|
|
74
|
+
readonly table: "table";
|
|
75
|
+
readonly tbody: "tbody";
|
|
76
|
+
readonly td: "td";
|
|
77
|
+
readonly textarea: "textarea";
|
|
78
|
+
readonly tfoot: "tfoot";
|
|
79
|
+
readonly th: "th";
|
|
80
|
+
readonly thead: "thead";
|
|
81
|
+
readonly time: "time";
|
|
82
|
+
readonly tr: "tr";
|
|
83
|
+
readonly u: "u";
|
|
84
|
+
readonly ul: "ul";
|
|
85
|
+
readonly var: "var";
|
|
86
|
+
readonly video: "video";
|
|
87
|
+
};
|
|
88
|
+
export type HtmlTag = (typeof htmlTags);
|