@ilokesto/utilinent 0.0.15 → 0.0.16

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.
@@ -1,2 +1,9 @@
1
+ import { ComponentPropsWithRef } from "react";
1
2
  import type { ForProps } from "../types";
2
- export declare function For<T extends Array<unknown>>({ each, children, fallback, }: ForProps<T>): string | number | boolean | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null;
3
+ type ForType = {
4
+ <T extends Array<unknown>>(props: ForProps<T>): React.ReactNode;
5
+ } & {
6
+ [K in keyof JSX.IntrinsicElements]: <T extends Array<unknown>>(props: ForProps<T> & ComponentPropsWithRef<K>) => React.ReactNode;
7
+ };
8
+ export declare const For: ForType;
9
+ export {};
@@ -1,5 +1,12 @@
1
- export function For({ each, children, fallback = null, }) {
2
- return (each && each.length > 0)
3
- ? each?.map(children)
4
- : fallback;
1
+ import { createElement } from "react";
2
+ import { htmlTags } from "../constants/htmlTags";
3
+ function BaseFor({ each, children, fallback = null, }) {
4
+ return each && each.length > 0 ? each.map(children) : fallback;
5
5
  }
6
+ const renderForTag = (tag) => ({ each, children, fallback = null, ...props }) => {
7
+ if (!each || each.length === 0)
8
+ return fallback;
9
+ const content = each.map(children);
10
+ return createElement(tag, props, content);
11
+ };
12
+ export const For = Object.assign(BaseFor, Object.fromEntries(htmlTags.map(tag => [tag, renderForTag(tag)])));
@@ -8,7 +8,7 @@ export function Observer({ children, fallback = null, threshold = 0, rootMargin
8
8
  freezeOnceVisible,
9
9
  onChange,
10
10
  });
11
- return (_jsx("div", { ref: ref, style:
11
+ return (_jsx(Show.div, { ref: ref, style:
12
12
  // fallback이 없고 isIntersecting이 false인 경우
13
13
  !fallback && !isIntersecting
14
14
  ? {
@@ -17,5 +17,5 @@ export function Observer({ children, fallback = null, threshold = 0, rootMargin
17
17
  flexShrink: 0, // flex 컨테이너에서 축소되지 않도록
18
18
  display: "block", // inline 요소가 되지 않도록
19
19
  }
20
- : undefined, children: _jsx(Show, { when: isIntersecting, fallback: fallback, children: typeof children === "function" ? children(isIntersecting) : children }) }));
20
+ : undefined, when: isIntersecting, fallback: fallback, children: typeof children === "function" ? children(isIntersecting) : children }));
21
21
  }
@@ -1,2 +1,9 @@
1
- import type { RepeatProps } from "../types";
2
- export declare function Repeat({ times, children, fallback }: RepeatProps): string | number | true | Iterable<import("react").ReactNode> | import("react/jsx-runtime").JSX.Element | null;
1
+ import { ComponentPropsWithRef } from "react";
2
+ import { RepeatProps } from "../types";
3
+ type RepeatType = {
4
+ (props: RepeatProps): React.ReactNode;
5
+ } & {
6
+ [K in keyof JSX.IntrinsicElements]: (props: RepeatProps & ComponentPropsWithRef<K>) => React.ReactNode;
7
+ };
8
+ export declare const Repeat: RepeatType;
9
+ export {};
@@ -1,8 +1,17 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
- export function Repeat({ times, children, fallback }) {
3
- // times가 0 이하이거나 유효하지 않은 경우 fallback 렌더링
2
+ import { createElement } from "react";
3
+ import { htmlTags } from "../constants/htmlTags";
4
+ function BaseRepeat({ times, children, fallback = null }) {
4
5
  if (!times || times <= 0 || !Number.isInteger(times)) {
5
- return fallback || null;
6
+ return fallback ?? null;
6
7
  }
7
- return (_jsx(_Fragment, { children: Array.from({ length: times }, (_, index) => children(index)) }));
8
+ return _jsx(_Fragment, { children: Array.from({ length: times }, (_, i) => children(i)) });
8
9
  }
10
+ const renderForTag = (tag) => ({ times, children, fallback = null, ...props }) => {
11
+ if (!times || times <= 0 || !Number.isInteger(times)) {
12
+ return fallback ?? null;
13
+ }
14
+ const content = Array.from({ length: times }, (_, i) => children(i));
15
+ return createElement(tag, props, content);
16
+ };
17
+ export const Repeat = Object.assign(BaseRepeat, Object.fromEntries(htmlTags.map(tag => [tag, renderForTag(tag)])));
@@ -1,3 +1,13 @@
1
- import type { ShowProps, ShowPropsArray } from "../types";
2
- export declare function Show<T extends unknown[]>({ when, children, fallback }: ShowPropsArray<T>): React.ReactNode;
3
- export declare function Show<T extends unknown>({ when, children, fallback }: ShowProps<T>): React.ReactNode;
1
+ import { ComponentPropsWithRef } from "react";
2
+ import { ShowProps, ShowPropsArray } from "../types";
3
+ type ShowType = {
4
+ <T extends unknown[]>(props: ShowPropsArray<T>): React.ReactNode;
5
+ <T extends unknown>(props: ShowProps<T>): React.ReactNode;
6
+ } & {
7
+ [K in keyof JSX.IntrinsicElements]: {
8
+ <T extends unknown[]>(props: ShowPropsArray<T> & ComponentPropsWithRef<K>): React.ReactNode;
9
+ <T extends unknown>(props: ShowProps<T> & ComponentPropsWithRef<K>): React.ReactNode;
10
+ };
11
+ };
12
+ export declare const Show: ShowType;
13
+ export {};
@@ -1,9 +1,18 @@
1
- export function Show({ when, children, fallback = null }) {
1
+ import { createElement } from "react";
2
+ import { htmlTags } from "../constants/htmlTags";
3
+ const BaseShow = ({ when, children, fallback = null }) => {
2
4
  const shouldRender = Array.isArray(when) ? when.every(Boolean) : !!when;
3
5
  return shouldRender
4
6
  ? typeof children === "function"
5
7
  ? children(when)
6
8
  : children
7
9
  : fallback;
8
- }
9
- ;
10
+ };
11
+ const renderForTag = (tag) => ({ when, children, fallback = null, ...props }) => {
12
+ const shouldRender = Array.isArray(when) ? when.every(Boolean) : !!when;
13
+ if (!shouldRender)
14
+ return fallback;
15
+ const content = typeof children === "function" ? children(when) : children;
16
+ return createElement(tag, props, content);
17
+ };
18
+ export const Show = Object.assign(BaseShow, Object.fromEntries(htmlTags.map(tag => [tag, renderForTag(tag)])));
@@ -0,0 +1 @@
1
+ export declare const htmlTags: string[];
@@ -0,0 +1,3 @@
1
+ export const htmlTags = [
2
+ "a", "abbr", "address", "article", "aside", "b", "bdi", "bdo", "blockquote", "button", "canvas", "cite", "code", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hr", "i", "img", "input", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "menu", "meter", "nav", "ol", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "section", "select", "small", "span", "strong", "sub", "summary", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "time", "tr", "u", "ul", "var", "video"
3
+ ];
@@ -0,0 +1,4 @@
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,69 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Children, cloneElement, forwardRef, isValidElement } from 'react';
3
+ function mergeProps(slotProps, childProps) {
4
+ const merged = { ...childProps };
5
+ for (const propName in slotProps) {
6
+ const slotProp = slotProps[propName];
7
+ const childProp = merged[propName];
8
+ if (/^on[A-Z]/.test(propName) && typeof slotProp === 'function' && typeof childProp === 'function') {
9
+ merged[propName] = (...args) => {
10
+ childProp(...args);
11
+ slotProp(...args);
12
+ };
13
+ }
14
+ else if (propName === 'style' && typeof slotProp === 'object' && typeof childProp === 'object') {
15
+ merged[propName] = { ...childProp, ...slotProp };
16
+ }
17
+ else if (propName === 'className' && typeof slotProp === 'string' && typeof childProp === 'string') {
18
+ merged[propName] = [childProp, slotProp].filter(Boolean).join(' ');
19
+ }
20
+ else {
21
+ merged[propName] = slotProp;
22
+ }
23
+ }
24
+ return merged;
25
+ }
26
+ function composeRefs(...refs) {
27
+ return (node) => {
28
+ for (const ref of refs) {
29
+ if (typeof ref === 'function') {
30
+ ref(node);
31
+ }
32
+ else if (ref != null) {
33
+ ref.current = node;
34
+ }
35
+ }
36
+ };
37
+ }
38
+ export const Slot = forwardRef((props, ref) => {
39
+ const { children, ...slotProps } = props;
40
+ const childrenArray = Children.toArray(children);
41
+ const slottable = childrenArray.find(isSlottable);
42
+ if (slottable) {
43
+ const newElement = cloneElement(slottable, {
44
+ ...mergeProps(slotProps, slottable.props),
45
+ ref: composeRefs(ref, slottable.ref)
46
+ });
47
+ const newChildren = childrenArray.map((child) => {
48
+ if (child === slottable) {
49
+ return newElement;
50
+ }
51
+ return child;
52
+ });
53
+ return _jsx(_Fragment, { children: newChildren });
54
+ }
55
+ const [child] = childrenArray;
56
+ if (!isValidElement(child)) {
57
+ return null;
58
+ }
59
+ return cloneElement(child, {
60
+ ...mergeProps(slotProps, child.props),
61
+ ref: composeRefs(ref, child.ref)
62
+ });
63
+ });
64
+ function isSlottable(child) {
65
+ return isValidElement(child) && child.type === Slottable;
66
+ }
67
+ export const Slottable = ({ children }) => {
68
+ return _jsx(_Fragment, { children: children });
69
+ };
@@ -0,0 +1,5 @@
1
+ export * from './experimental/Mount';
2
+ export * from './experimental/Slacker';
3
+ export * from './experimental/Switch';
4
+ export * from './experimental/Slot';
5
+ export * from './hooks/useIntersectionObserver';
@@ -0,0 +1,5 @@
1
+ export * from './experimental/Mount';
2
+ export * from './experimental/Slacker';
3
+ export * from './experimental/Switch';
4
+ export * from './experimental/Slot';
5
+ export * from './hooks/useIntersectionObserver';
package/dist/index.d.ts CHANGED
@@ -3,7 +3,3 @@ export * from './components/Observer';
3
3
  export * from './components/OptionalWrapper';
4
4
  export * from './components/Repeat';
5
5
  export * from './components/Show';
6
- export * from './experimental/Mount';
7
- export * from './experimental/Slacker';
8
- export * from './experimental/Switch';
9
- export * from './hooks/useIntersectionObserver';
package/dist/index.js CHANGED
@@ -3,7 +3,3 @@ export * from './components/Observer';
3
3
  export * from './components/OptionalWrapper';
4
4
  export * from './components/Repeat';
5
5
  export * from './components/Show';
6
- export * from './experimental/Mount';
7
- export * from './experimental/Slacker';
8
- export * from './experimental/Switch';
9
- export * from './hooks/useIntersectionObserver';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ilokesto/utilinent",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ilokesto/utilinent.git"
@@ -8,6 +8,16 @@
8
8
  "sideEffects": false,
9
9
  "types": "dist/index.d.ts",
10
10
  "module": "dist/index.js",
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ },
16
+ "./experimental": {
17
+ "import": "./dist/experimental.js",
18
+ "types": "./dist/experimental.d.ts"
19
+ }
20
+ },
11
21
  "files": [
12
22
  "dist"
13
23
  ],