@diskette/use-render 0.12.0 → 0.13.0

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.
@@ -12,7 +12,7 @@ export interface RenderSlotOptions<T extends ElementType> {
12
12
  }
13
13
  /**
14
14
  * Pure function for rendering slot elements with render prop support and prop merging.
15
- * RSC-compatible version of useRenderSlot without ref handling.
15
+ * RSC-compatible version of useRenderSlot. Composes refs from baseProps and props via mergeRefs.
16
16
  *
17
17
  * @example
18
18
  * ```tsx
@@ -1,8 +1,8 @@
1
1
  import { createElement, isValidElement } from 'react';
2
- import { cloneRenderElement, cx, isFunction, isString, mergeProps } from "../utils.js";
2
+ import { cloneRenderElement, cx, isFunction, isString, mergeProps, mergeRefs } from "../utils.js";
3
3
  /**
4
4
  * Pure function for rendering slot elements with render prop support and prop merging.
5
- * RSC-compatible version of useRenderSlot without ref handling.
5
+ * RSC-compatible version of useRenderSlot. Composes refs from baseProps and props via mergeRefs.
6
6
  *
7
7
  * @example
8
8
  * ```tsx
@@ -26,8 +26,8 @@ import { cloneRenderElement, cx, isFunction, isString, mergeProps } from "../uti
26
26
  export function renderSlot(tag, options = {}) {
27
27
  const baseProps = (options.baseProps ?? {});
28
28
  const props = (options.props ?? {});
29
- const { className: baseClassName, style: baseStyle, children: baseChildren, ...base } = baseProps;
30
- const { className, style, children, render, ...rest } = props;
29
+ const { className: baseClassName, style: baseStyle, children: baseChildren, ref: baseRef, ...base } = baseProps;
30
+ const { className, style, children, render, ref, ...rest } = props;
31
31
  const resolvedClassName = cx(baseClassName, className);
32
32
  const resolvedStyle = baseStyle || style ? { ...baseStyle, ...style } : undefined;
33
33
  const resolvedProps = {
@@ -39,6 +39,9 @@ export function renderSlot(tag, options = {}) {
39
39
  if (typeof resolvedStyle === 'object') {
40
40
  resolvedProps.style = resolvedStyle;
41
41
  }
42
+ if (baseRef || ref) {
43
+ resolvedProps.ref = mergeRefs([baseRef, ref]);
44
+ }
42
45
  const resolvedChildren = children ?? baseChildren;
43
46
  // For `<Component render={<a />} />`
44
47
  if (isValidElement(render)) {
@@ -1,11 +1,5 @@
1
- import { type Ref, type RefCallback } from 'react';
2
- /**
3
- * Assigns a value to a ref.
4
- * @param ref The ref to assign the value to.
5
- * @param value The value to assign to the ref.
6
- * @returns The ref cleanup callback, if any.
7
- */
8
- export declare function assignRef<T>(ref: Ref<T> | undefined | null, value: T | null): ReturnType<RefCallback<T>>;
1
+ import { type Ref } from 'react';
2
+ export { assignRef } from './utils.ts';
9
3
  type RefInput<T> = Ref<T> | undefined | (Ref<T> | undefined)[];
10
4
  /**
11
5
  * Composes multiple refs into a single one and memoizes the result to avoid refs execution on each render.
@@ -14,4 +8,3 @@ type RefInput<T> = Ref<T> | undefined | (Ref<T> | undefined)[];
14
8
  * @returns Merged ref.
15
9
  */
16
10
  export declare function useComposedRef<T>(...refs: RefInput<T>[]): Ref<T>;
17
- export {};
@@ -1,32 +1,6 @@
1
1
  import { useMemo } from 'react';
2
- /**
3
- * Assigns a value to a ref.
4
- * @param ref The ref to assign the value to.
5
- * @param value The value to assign to the ref.
6
- * @returns The ref cleanup callback, if any.
7
- */
8
- export function assignRef(ref, value) {
9
- if (typeof ref === 'function') {
10
- return ref(value);
11
- }
12
- else if (ref) {
13
- ref.current = value;
14
- }
15
- }
16
- function mergeRefs(refs) {
17
- return (value) => {
18
- const cleanups = [];
19
- for (const ref of refs) {
20
- const cleanup = assignRef(ref, value);
21
- const isCleanup = typeof cleanup === 'function';
22
- cleanups.push(isCleanup ? cleanup : () => assignRef(ref, null));
23
- }
24
- return () => {
25
- for (const cleanup of cleanups)
26
- cleanup();
27
- };
28
- };
29
- }
2
+ import { mergeRefs } from "./utils.js";
3
+ export { assignRef } from "./utils.js";
30
4
  /**
31
5
  * Composes multiple refs into a single one and memoizes the result to avoid refs execution on each render.
32
6
  * Accepts individual refs or arrays of refs, which are flattened automatically.
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { CSSProperties, ReactElement, ReactNode } from 'react';
1
+ import type { CSSProperties, ReactElement, ReactNode, Ref, RefCallback } from 'react';
2
2
  import type { ClassName, Style } from './types.ts';
3
3
  export declare const isString: (value: unknown) => value is string;
4
4
  export declare const isFunction: (value: unknown) => value is Function;
@@ -27,6 +27,14 @@ export declare function resolveStyle<State>(state: State, defaultStyle?: Style<S
27
27
  * Returns a string with the truthy values of `args` separated by space.
28
28
  */
29
29
  export declare function cx(...args: Array<string | null | false | 0 | undefined>): string | undefined;
30
+ /**
31
+ * Assigns a value to a ref.
32
+ */
33
+ export declare function assignRef<T>(ref: Ref<T> | undefined | null, value: T | null): ReturnType<RefCallback<T>>;
34
+ /**
35
+ * Composes multiple refs into a single ref callback.
36
+ */
37
+ export declare function mergeRefs<T>(refs: (Ref<T> | undefined)[]): Ref<T>;
30
38
  /**
31
39
  * Clones a React element, merging its props with resolved props.
32
40
  * - className values are merged via `cx`
package/dist/utils.js CHANGED
@@ -74,6 +74,34 @@ export function resolveStyle(state, defaultStyle, propsStyle) {
74
74
  export function cx(...args) {
75
75
  return args.filter(Boolean).join(' ') || undefined;
76
76
  }
77
+ /**
78
+ * Assigns a value to a ref.
79
+ */
80
+ export function assignRef(ref, value) {
81
+ if (typeof ref === 'function') {
82
+ return ref(value);
83
+ }
84
+ else if (ref) {
85
+ ref.current = value;
86
+ }
87
+ }
88
+ /**
89
+ * Composes multiple refs into a single ref callback.
90
+ */
91
+ export function mergeRefs(refs) {
92
+ return (value) => {
93
+ const cleanups = [];
94
+ for (const ref of refs) {
95
+ const cleanup = assignRef(ref, value);
96
+ const isCleanup = typeof cleanup === 'function';
97
+ cleanups.push(isCleanup ? cleanup : () => assignRef(ref, null));
98
+ }
99
+ return () => {
100
+ for (const cleanup of cleanups)
101
+ cleanup();
102
+ };
103
+ };
104
+ }
77
105
  /**
78
106
  * Clones a React element, merging its props with resolved props.
79
107
  * - className values are merged via `cx`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@diskette/use-render",
3
3
  "type": "module",
4
- "version": "0.12.0",
4
+ "version": "0.13.0",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
7
7
  "./fns": "./dist/fns/index.js"