@ilokesto/utilinent 0.0.21 → 0.0.23

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 CHANGED
@@ -23,7 +23,7 @@ pnpm add @ilokesto/utilinent
23
23
  기본적으로 다음 컴포넌트들을 가져와 사용할 수 있습니다.
24
24
 
25
25
  ```tsx
26
- import { Show, For, Repeat, Observer, OptionalWrapper } from '@ilokesto/utilinent';
26
+ import { Show, For, Repeat, Observer, OptionalWrapper, useIntersectionObserver } from '@ilokesto/utilinent';
27
27
  ```
28
28
 
29
29
  #### `<Show>`
@@ -134,12 +134,35 @@ function Post({ post, withLink }) {
134
134
  }
135
135
  ```
136
136
 
137
+ ### 훅(Hooks)
138
+
139
+ #### `useIntersectionObserver`
140
+
141
+ Intersection Observer API를 React 훅으로 감싼 것입니다. 컴포넌트의 뷰포트 내 가시성을 추적하는 데 사용됩니다.
142
+
143
+ **사용 예시:**
144
+
145
+ ```tsx
146
+ import { useIntersectionObserver } from '@ilokesto/utilinent';
147
+ import { useRef } from 'react';
148
+
149
+ function MyComponent() {
150
+ const { ref, isIntersecting } = useIntersectionObserver({ threshold: 0.5 });
151
+
152
+ return (
153
+ <div ref={ref} style={{ transition: 'opacity 0.5s', opacity: isIntersecting ? 1 : 0.2 }}>
154
+ {isIntersecting ? '이제 화면에 보입니다!' : '화면 밖에 있습니다.'}
155
+ </div>
156
+ );
157
+ }
158
+ ```
159
+
137
160
  ### 실험적 기능
138
161
 
139
162
  실험적인 컴포넌트 및 훅은 `experimental` 경로에서 가져올 수 있습니다. 이 기능들은 API가 변경될 수 있습니다.
140
163
 
141
164
  ```tsx
142
- import { Mount, Slacker, createSwitcher, useIntersectionObserver, Slot, Slottable } from '@ilokesto/utilinent/experimental';
165
+ import { Mount, Slacker, createSwitcher, Slot, Slottable } from '@ilokesto/utilinent/experimental';
143
166
  ```
144
167
 
145
168
  #### `<Slot>` 및 `<Slottable>`
@@ -257,27 +280,6 @@ function Media() {
257
280
  }
258
281
  ```
259
282
 
260
- #### `useIntersectionObserver`
261
-
262
- Intersection Observer API를 React 훅으로 감싼 것입니다. 컴포넌트의 뷰포트 내 가시성을 추적하는 데 사용됩니다.
263
-
264
- **사용 예시:**
265
-
266
- ```tsx
267
- import { useIntersectionObserver } from '@ilokesto/utilinent/experimental';
268
- import { useRef } from 'react';
269
-
270
- function MyComponent() {
271
- const { ref, isIntersecting } = useIntersectionObserver({ threshold: 0.5 });
272
-
273
- return (
274
- <div ref={ref} style={{ transition: 'opacity 0.5s', opacity: isIntersecting ? 1 : 0.2 }}>
275
- {isIntersecting ? '이제 화면에 보입니다!' : '화면 밖에 있습니다.'}
276
- </div>
277
- );
278
- }
279
- ```
280
-
281
283
  ## 라이선스
282
284
 
283
285
  [MIT](./LICENSE)
@@ -1,14 +1,16 @@
1
- import { createElement } from "react";
1
+ import { createElement, forwardRef } from "react";
2
2
  import { htmlTags } from "../constants/htmlTags";
3
3
  function BaseFor({ each, children, fallback = null, }) {
4
4
  return each && each.length > 0 ? each.map(children) : fallback;
5
5
  }
6
- const renderForTag = (tag) => ({ each, children, fallback = null, ...props }) => {
6
+ const renderForTag = (tag) =>
7
+ // forward ref so consumers can attach a ref to the underlying DOM element
8
+ forwardRef(({ each, children, fallback = null, ...props }, ref) => {
7
9
  if (!each || each.length === 0)
8
10
  return fallback;
9
11
  const content = each.map(children);
10
- return createElement(tag, props, content);
11
- };
12
+ return createElement(tag, { ...props, ref }, content);
13
+ });
12
14
  const tagEntries = htmlTags.reduce((acc, tag) => {
13
15
  acc[tag] = renderForTag(tag);
14
16
  return acc;
@@ -1,5 +1,5 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
- import { createElement } from "react";
2
+ import { createElement, forwardRef } from "react";
3
3
  import { htmlTags } from "../constants/htmlTags";
4
4
  function BaseRepeat({ times, children, fallback = null }) {
5
5
  if (!times || times <= 0 || !Number.isInteger(times)) {
@@ -7,13 +7,15 @@ function BaseRepeat({ times, children, fallback = null }) {
7
7
  }
8
8
  return _jsx(_Fragment, { children: Array.from({ length: times }, (_, i) => children(i)) });
9
9
  }
10
- const renderForTag = (tag) => ({ times, children, fallback = null, ...props }) => {
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) => {
11
13
  if (!times || times <= 0 || !Number.isInteger(times)) {
12
14
  return fallback ?? null;
13
15
  }
14
16
  const content = Array.from({ length: times }, (_, i) => children(i));
15
- return createElement(tag, props, content);
16
- };
17
+ return createElement(tag, { ...props, ref }, content);
18
+ });
17
19
  const tagEntries = htmlTags.reduce((acc, tag) => {
18
20
  acc[tag] = renderForTag(tag);
19
21
  return acc;
@@ -1,4 +1,4 @@
1
- import { createElement } from "react";
1
+ import { createElement, forwardRef } from "react";
2
2
  import { htmlTags } from "../constants/htmlTags";
3
3
  const BaseShow = ({ when, children, fallback = null }) => {
4
4
  const shouldRender = Array.isArray(when) ? when.every(Boolean) : !!when;
@@ -8,13 +8,15 @@ const BaseShow = ({ when, children, fallback = null }) => {
8
8
  : children
9
9
  : fallback;
10
10
  };
11
- const renderForTag = (tag) => ({ when, children, fallback = null, ...props }) => {
11
+ const renderForTag = (tag) =>
12
+ // forward ref so consumers like Observer can pass a ref to the real DOM element
13
+ forwardRef(function Render({ when, children, fallback = null, ...props }, ref) {
12
14
  const shouldRender = Array.isArray(when) ? when.every(Boolean) : !!when;
13
15
  if (!shouldRender)
14
16
  return fallback;
15
17
  const content = typeof children === "function" ? children(when) : children;
16
- return createElement(tag, props, content);
17
- };
18
+ return createElement(tag, { ...props, ref }, content);
19
+ });
18
20
  const tagEntries = htmlTags.reduce((acc, tag) => {
19
21
  acc[tag] = renderForTag(tag);
20
22
  return acc;
@@ -2,4 +2,3 @@ export * from './experimental/Mount';
2
2
  export * from './experimental/Slacker';
3
3
  export * from './experimental/Switch';
4
4
  export * from './experimental/Slot';
5
- export * from './hooks/useIntersectionObserver';
@@ -2,4 +2,3 @@ export * from './experimental/Mount';
2
2
  export * from './experimental/Slacker';
3
3
  export * from './experimental/Switch';
4
4
  export * from './experimental/Slot';
5
- export * from './hooks/useIntersectionObserver';
package/dist/index.d.ts CHANGED
@@ -3,3 +3,4 @@ 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 './hooks/useIntersectionObserver';
package/dist/index.js CHANGED
@@ -3,3 +3,4 @@ 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 './hooks/useIntersectionObserver';
@@ -5,7 +5,7 @@ export interface ForProps<T extends Array<unknown>> extends Fallback {
5
5
  children: (item: T[number], index: number) => React.ReactNode;
6
6
  }
7
7
  type ForTagHelper<K extends keyof JSX.IntrinsicElements> = {
8
- <T extends Array<unknown>>(props: ForProps<T> & ComponentPropsWithRef<K>): React.ReactNode;
8
+ <T extends Array<unknown>>(props: ForProps<T> & Omit<ComponentPropsWithRef<K>, 'children'>): React.ReactNode;
9
9
  };
10
10
  export interface ForType {
11
11
  <T extends Array<unknown>>(props: ForProps<T>): React.ReactNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ilokesto/utilinent",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ilokesto/utilinent.git"