@refineui/utilities 0.0.1 → 0.0.3
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 +86 -0
- package/lib/index.cjs +41 -0
- package/lib/index.d.cts +8 -2
- package/lib/index.d.ts +8 -2
- package/lib/index.js +44 -0
- package/lib/react.cjs +41 -0
- package/lib/react.d.cts +9 -2
- package/lib/react.d.ts +9 -2
- package/lib/react.js +44 -0
- package/package.json +60 -58
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# @refineui/utilities
|
|
2
|
+
|
|
3
|
+
Shared helpers behind [RefineUI](https://ui.pelagornis.com) components — token references, DOM attribute normalization, and React composition primitives.
|
|
4
|
+
|
|
5
|
+
This package holds the logic that would otherwise be duplicated across components. It depends only on `@refineui/version`, never on `@refineui/tokens`, so token packages stay at the bottom of the dependency graph.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @refineui/utilities
|
|
11
|
+
yarn add @refineui/utilities
|
|
12
|
+
pnpm add @refineui/utilities
|
|
13
|
+
bun add @refineui/utilities
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
React 18+ is a peer dependency, required only for the `react` entry point.
|
|
17
|
+
|
|
18
|
+
## Entry points
|
|
19
|
+
|
|
20
|
+
| Import | Contents |
|
|
21
|
+
|--------|----------|
|
|
22
|
+
| `@refineui/utilities` | animation + color + dom + react + typography |
|
|
23
|
+
| `@refineui/utilities/color` | Color token refs, CSS var resolution, `hexToRgba`, `shadowWithColor` |
|
|
24
|
+
| `@refineui/utilities/typography` | Semantic text and Foundation typography token refs |
|
|
25
|
+
| `@refineui/utilities/animation` | Motion presets, transition/animation style builders, reduced-motion query |
|
|
26
|
+
| `@refineui/utilities/react` | `useComposedRefs`, `composeRefs`, `acquireBodyScrollLock`, `getMergeableTriggerChild` |
|
|
27
|
+
|
|
28
|
+
Subpath imports keep React out of the bundle when you only need token helpers.
|
|
29
|
+
|
|
30
|
+
## Color tokens
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import {
|
|
34
|
+
hexToRgba,
|
|
35
|
+
resolveColorTokenValue,
|
|
36
|
+
semanticColorToken,
|
|
37
|
+
} from "@refineui/utilities/color";
|
|
38
|
+
|
|
39
|
+
const surface = semanticColorToken("background-surface");
|
|
40
|
+
resolveColorTokenValue(surface); // var(--refineui-color-alias-background-surface)
|
|
41
|
+
hexToRgba("#1a1a1a", 0.6); // rgba(26, 26, 26, 0.6)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Raw strings pass through `resolveColorTokenValue` unchanged, so a token ref and a literal can share one prop type.
|
|
45
|
+
|
|
46
|
+
## Motion
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { createTransitionStyle, getReducedMotionQuery } from "@refineui/utilities/animation";
|
|
50
|
+
|
|
51
|
+
const style = createTransitionStyle({
|
|
52
|
+
properties: ["opacity", "transform"],
|
|
53
|
+
duration: "fast", // instant | fast | normal | slow | toast
|
|
54
|
+
easing: "standard", // standard | emphasized | linear
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Durations and easings resolve to token CSS variables, so motion stays in step with `@refineui/tokens`. Pass `reduceMotion: true` to collapse a transition to `instant`, and use `getReducedMotionQuery()` — which returns the `@media (prefers-reduced-motion: reduce)` at-rule — when emitting the same contract in a stylesheet.
|
|
59
|
+
|
|
60
|
+
## React composition
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { useComposedRefs, acquireBodyScrollLock } from "@refineui/utilities/react";
|
|
64
|
+
|
|
65
|
+
const ref = useComposedRefs(localRef, forwardedRef);
|
|
66
|
+
|
|
67
|
+
// Overlay surfaces lock the body once and release on the last unmount.
|
|
68
|
+
useEffect(() => acquireBodyScrollLock(), []);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`acquireBodyScrollLock` is reference counted, so nested Dialog and Drawer instances do not fight over `overflow`.
|
|
72
|
+
|
|
73
|
+
## DOM attributes
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { ariaAttr, dataAttr } from "@refineui/utilities";
|
|
77
|
+
|
|
78
|
+
dataAttr(isSelected); // "" | undefined → renders data-selected only when true
|
|
79
|
+
ariaAttr(isDisabled); // "true" | undefined → omits aria-disabled when false
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Development
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
bun run build # one tsup pass per entry point
|
|
86
|
+
```
|
package/lib/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
Slot: () => Slot,
|
|
33
34
|
acquireBodyScrollLock: () => acquireBodyScrollLock,
|
|
34
35
|
ariaAttr: () => ariaAttr,
|
|
35
36
|
buttonProps: () => buttonProps,
|
|
@@ -297,6 +298,45 @@ function getMergeableTriggerChild(children) {
|
|
|
297
298
|
return node;
|
|
298
299
|
}
|
|
299
300
|
|
|
301
|
+
// src/Slot.tsx
|
|
302
|
+
var import_react2 = require("react");
|
|
303
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
304
|
+
function mergeProps(slotProps, childProps) {
|
|
305
|
+
const merged = { ...slotProps };
|
|
306
|
+
for (const key of Object.keys(childProps)) {
|
|
307
|
+
if (key === "ref" || key === "children") continue;
|
|
308
|
+
const slotValue = slotProps[key];
|
|
309
|
+
const childValue = childProps[key];
|
|
310
|
+
const isEvent = key.startsWith("on") && typeof slotValue === "function" && typeof childValue === "function";
|
|
311
|
+
if (key === "className" || key === "aria-describedby") {
|
|
312
|
+
merged[key] = [slotValue, childValue].filter(Boolean).join(" ");
|
|
313
|
+
} else if (key === "style") {
|
|
314
|
+
merged.style = { ...slotValue ?? {}, ...childValue ?? {} };
|
|
315
|
+
} else if (isEvent) {
|
|
316
|
+
merged[key] = (event) => {
|
|
317
|
+
childValue(event);
|
|
318
|
+
if (!event?.defaultPrevented) slotValue(event);
|
|
319
|
+
};
|
|
320
|
+
} else {
|
|
321
|
+
merged[key] = childValue;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return merged;
|
|
325
|
+
}
|
|
326
|
+
var Slot = (0, import_react2.forwardRef)(function Slot2({ children, ...slotProps }, forwardedRef) {
|
|
327
|
+
if (!(0, import_react2.isValidElement)(children)) {
|
|
328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
|
|
329
|
+
}
|
|
330
|
+
const child = children;
|
|
331
|
+
const childProps = { ...child.props ?? {} };
|
|
332
|
+
const childRef = child.ref ?? childProps.ref;
|
|
333
|
+
delete childProps.ref;
|
|
334
|
+
delete childProps.children;
|
|
335
|
+
const merged = mergeProps(slotProps, childProps);
|
|
336
|
+
merged.ref = composeRefs(forwardedRef, childRef);
|
|
337
|
+
return (0, import_react2.cloneElement)(child, merged);
|
|
338
|
+
});
|
|
339
|
+
|
|
300
340
|
// src/typography.ts
|
|
301
341
|
function semanticTextToken(name) {
|
|
302
342
|
return { type: "semantic-text", name };
|
|
@@ -314,6 +354,7 @@ function isSemanticTextTokenRef(value) {
|
|
|
314
354
|
}
|
|
315
355
|
// Annotate the CommonJS export names for ESM import in node:
|
|
316
356
|
0 && (module.exports = {
|
|
357
|
+
Slot,
|
|
317
358
|
acquireBodyScrollLock,
|
|
318
359
|
ariaAttr,
|
|
319
360
|
buttonProps,
|
package/lib/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { CSSProperties, Ref, ReactNode, ReactElement } from 'react';
|
|
2
|
+
import { CSSProperties, Ref, ReactNode, ReactElement, HTMLAttributes } from 'react';
|
|
3
3
|
|
|
4
4
|
declare const motionDurations: {
|
|
5
5
|
readonly instant: "var(--refineui-motion-duration-instant)";
|
|
@@ -115,6 +115,12 @@ declare const composeRef: typeof composeRefs;
|
|
|
115
115
|
*/
|
|
116
116
|
declare function getMergeableTriggerChild(children: ReactNode): ReactElement | null;
|
|
117
117
|
|
|
118
|
+
interface SlotProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
119
|
+
children?: any;
|
|
120
|
+
}
|
|
121
|
+
/** Merges its props onto the single child. Used for `asChild`. */
|
|
122
|
+
declare const Slot: React.ForwardRefExoticComponent<SlotProps & React.RefAttributes<HTMLElement | null>>;
|
|
123
|
+
|
|
118
124
|
type SemanticTextTokenRef<TName extends string = string> = Readonly<{
|
|
119
125
|
type: "semantic-text";
|
|
120
126
|
name: TName;
|
|
@@ -129,4 +135,4 @@ declare function foundationTypographyToken<TName extends string>(name: TName): F
|
|
|
129
135
|
declare function foundationTypographyUtilityClass(foundationKey: string): string;
|
|
130
136
|
declare function isSemanticTextTokenRef(value: unknown): value is SemanticTextTokenRef;
|
|
131
137
|
|
|
132
|
-
export { type AnimationStyleOptions, type ColorTokenRef, type ColorTokenValue, type FoundationTypographyTokenRef, type MotionDuration, type MotionEasing, type MotionPresetName, type PaletteColorTokenRef, type SemanticColorTokenRef, type SemanticTextTokenRef, type TransitionStyleOptions, acquireBodyScrollLock, ariaAttr, buttonProps, composeRef, composeRefs, createAnimationStyle, createTransitionStyle, dataAttr, elementProps, foundationTypographyToken, foundationTypographyUtilityClass, getMergeableTriggerChild, getReducedMotionQuery, hexToRgba, imgProps, inputProps, isColorTokenRef, isSemanticTextTokenRef, labelProps, motionDurations, motionEasings, motionKeyframesCss, motionMsToNumber, motionPresets, paletteColorCssVar, paletteColorToken, resolveColorToken, resolveColorTokenValue, semanticColorCssVar, semanticColorToken, semanticTextToken, shadowWithColor, toKebab, useComposedRefs };
|
|
138
|
+
export { type AnimationStyleOptions, type ColorTokenRef, type ColorTokenValue, type FoundationTypographyTokenRef, type MotionDuration, type MotionEasing, type MotionPresetName, type PaletteColorTokenRef, type SemanticColorTokenRef, type SemanticTextTokenRef, Slot, type SlotProps, type TransitionStyleOptions, acquireBodyScrollLock, ariaAttr, buttonProps, composeRef, composeRefs, createAnimationStyle, createTransitionStyle, dataAttr, elementProps, foundationTypographyToken, foundationTypographyUtilityClass, getMergeableTriggerChild, getReducedMotionQuery, hexToRgba, imgProps, inputProps, isColorTokenRef, isSemanticTextTokenRef, labelProps, motionDurations, motionEasings, motionKeyframesCss, motionMsToNumber, motionPresets, paletteColorCssVar, paletteColorToken, resolveColorToken, resolveColorTokenValue, semanticColorCssVar, semanticColorToken, semanticTextToken, shadowWithColor, toKebab, useComposedRefs };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { CSSProperties, Ref, ReactNode, ReactElement } from 'react';
|
|
2
|
+
import { CSSProperties, Ref, ReactNode, ReactElement, HTMLAttributes } from 'react';
|
|
3
3
|
|
|
4
4
|
declare const motionDurations: {
|
|
5
5
|
readonly instant: "var(--refineui-motion-duration-instant)";
|
|
@@ -115,6 +115,12 @@ declare const composeRef: typeof composeRefs;
|
|
|
115
115
|
*/
|
|
116
116
|
declare function getMergeableTriggerChild(children: ReactNode): ReactElement | null;
|
|
117
117
|
|
|
118
|
+
interface SlotProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
119
|
+
children?: any;
|
|
120
|
+
}
|
|
121
|
+
/** Merges its props onto the single child. Used for `asChild`. */
|
|
122
|
+
declare const Slot: React.ForwardRefExoticComponent<SlotProps & React.RefAttributes<HTMLElement | null>>;
|
|
123
|
+
|
|
118
124
|
type SemanticTextTokenRef<TName extends string = string> = Readonly<{
|
|
119
125
|
type: "semantic-text";
|
|
120
126
|
name: TName;
|
|
@@ -129,4 +135,4 @@ declare function foundationTypographyToken<TName extends string>(name: TName): F
|
|
|
129
135
|
declare function foundationTypographyUtilityClass(foundationKey: string): string;
|
|
130
136
|
declare function isSemanticTextTokenRef(value: unknown): value is SemanticTextTokenRef;
|
|
131
137
|
|
|
132
|
-
export { type AnimationStyleOptions, type ColorTokenRef, type ColorTokenValue, type FoundationTypographyTokenRef, type MotionDuration, type MotionEasing, type MotionPresetName, type PaletteColorTokenRef, type SemanticColorTokenRef, type SemanticTextTokenRef, type TransitionStyleOptions, acquireBodyScrollLock, ariaAttr, buttonProps, composeRef, composeRefs, createAnimationStyle, createTransitionStyle, dataAttr, elementProps, foundationTypographyToken, foundationTypographyUtilityClass, getMergeableTriggerChild, getReducedMotionQuery, hexToRgba, imgProps, inputProps, isColorTokenRef, isSemanticTextTokenRef, labelProps, motionDurations, motionEasings, motionKeyframesCss, motionMsToNumber, motionPresets, paletteColorCssVar, paletteColorToken, resolveColorToken, resolveColorTokenValue, semanticColorCssVar, semanticColorToken, semanticTextToken, shadowWithColor, toKebab, useComposedRefs };
|
|
138
|
+
export { type AnimationStyleOptions, type ColorTokenRef, type ColorTokenValue, type FoundationTypographyTokenRef, type MotionDuration, type MotionEasing, type MotionPresetName, type PaletteColorTokenRef, type SemanticColorTokenRef, type SemanticTextTokenRef, Slot, type SlotProps, type TransitionStyleOptions, acquireBodyScrollLock, ariaAttr, buttonProps, composeRef, composeRefs, createAnimationStyle, createTransitionStyle, dataAttr, elementProps, foundationTypographyToken, foundationTypographyUtilityClass, getMergeableTriggerChild, getReducedMotionQuery, hexToRgba, imgProps, inputProps, isColorTokenRef, isSemanticTextTokenRef, labelProps, motionDurations, motionEasings, motionKeyframesCss, motionMsToNumber, motionPresets, paletteColorCssVar, paletteColorToken, resolveColorToken, resolveColorTokenValue, semanticColorCssVar, semanticColorToken, semanticTextToken, shadowWithColor, toKebab, useComposedRefs };
|
package/lib/index.js
CHANGED
|
@@ -228,6 +228,49 @@ function getMergeableTriggerChild(children) {
|
|
|
228
228
|
return node;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
+
// src/Slot.tsx
|
|
232
|
+
import {
|
|
233
|
+
cloneElement,
|
|
234
|
+
forwardRef,
|
|
235
|
+
isValidElement as isValidElement2
|
|
236
|
+
} from "react";
|
|
237
|
+
import { Fragment as Fragment2, jsx } from "react/jsx-runtime";
|
|
238
|
+
function mergeProps(slotProps, childProps) {
|
|
239
|
+
const merged = { ...slotProps };
|
|
240
|
+
for (const key of Object.keys(childProps)) {
|
|
241
|
+
if (key === "ref" || key === "children") continue;
|
|
242
|
+
const slotValue = slotProps[key];
|
|
243
|
+
const childValue = childProps[key];
|
|
244
|
+
const isEvent = key.startsWith("on") && typeof slotValue === "function" && typeof childValue === "function";
|
|
245
|
+
if (key === "className" || key === "aria-describedby") {
|
|
246
|
+
merged[key] = [slotValue, childValue].filter(Boolean).join(" ");
|
|
247
|
+
} else if (key === "style") {
|
|
248
|
+
merged.style = { ...slotValue ?? {}, ...childValue ?? {} };
|
|
249
|
+
} else if (isEvent) {
|
|
250
|
+
merged[key] = (event) => {
|
|
251
|
+
childValue(event);
|
|
252
|
+
if (!event?.defaultPrevented) slotValue(event);
|
|
253
|
+
};
|
|
254
|
+
} else {
|
|
255
|
+
merged[key] = childValue;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return merged;
|
|
259
|
+
}
|
|
260
|
+
var Slot = forwardRef(function Slot2({ children, ...slotProps }, forwardedRef) {
|
|
261
|
+
if (!isValidElement2(children)) {
|
|
262
|
+
return /* @__PURE__ */ jsx(Fragment2, { children });
|
|
263
|
+
}
|
|
264
|
+
const child = children;
|
|
265
|
+
const childProps = { ...child.props ?? {} };
|
|
266
|
+
const childRef = child.ref ?? childProps.ref;
|
|
267
|
+
delete childProps.ref;
|
|
268
|
+
delete childProps.children;
|
|
269
|
+
const merged = mergeProps(slotProps, childProps);
|
|
270
|
+
merged.ref = composeRefs(forwardedRef, childRef);
|
|
271
|
+
return cloneElement(child, merged);
|
|
272
|
+
});
|
|
273
|
+
|
|
231
274
|
// src/typography.ts
|
|
232
275
|
function semanticTextToken(name) {
|
|
233
276
|
return { type: "semantic-text", name };
|
|
@@ -244,6 +287,7 @@ function isSemanticTextTokenRef(value) {
|
|
|
244
287
|
return candidate.type === "semantic-text" && typeof candidate.name === "string";
|
|
245
288
|
}
|
|
246
289
|
export {
|
|
290
|
+
Slot,
|
|
247
291
|
acquireBodyScrollLock,
|
|
248
292
|
ariaAttr,
|
|
249
293
|
buttonProps,
|
package/lib/react.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/react.ts
|
|
31
31
|
var react_exports = {};
|
|
32
32
|
__export(react_exports, {
|
|
33
|
+
Slot: () => Slot,
|
|
33
34
|
acquireBodyScrollLock: () => acquireBodyScrollLock,
|
|
34
35
|
composeRef: () => composeRef,
|
|
35
36
|
composeRefs: () => composeRefs,
|
|
@@ -117,8 +118,48 @@ function getMergeableTriggerChild(children) {
|
|
|
117
118
|
}
|
|
118
119
|
return node;
|
|
119
120
|
}
|
|
121
|
+
|
|
122
|
+
// src/Slot.tsx
|
|
123
|
+
var import_react2 = require("react");
|
|
124
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
125
|
+
function mergeProps(slotProps, childProps) {
|
|
126
|
+
const merged = { ...slotProps };
|
|
127
|
+
for (const key of Object.keys(childProps)) {
|
|
128
|
+
if (key === "ref" || key === "children") continue;
|
|
129
|
+
const slotValue = slotProps[key];
|
|
130
|
+
const childValue = childProps[key];
|
|
131
|
+
const isEvent = key.startsWith("on") && typeof slotValue === "function" && typeof childValue === "function";
|
|
132
|
+
if (key === "className" || key === "aria-describedby") {
|
|
133
|
+
merged[key] = [slotValue, childValue].filter(Boolean).join(" ");
|
|
134
|
+
} else if (key === "style") {
|
|
135
|
+
merged.style = { ...slotValue ?? {}, ...childValue ?? {} };
|
|
136
|
+
} else if (isEvent) {
|
|
137
|
+
merged[key] = (event) => {
|
|
138
|
+
childValue(event);
|
|
139
|
+
if (!event?.defaultPrevented) slotValue(event);
|
|
140
|
+
};
|
|
141
|
+
} else {
|
|
142
|
+
merged[key] = childValue;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return merged;
|
|
146
|
+
}
|
|
147
|
+
var Slot = (0, import_react2.forwardRef)(function Slot2({ children, ...slotProps }, forwardedRef) {
|
|
148
|
+
if (!(0, import_react2.isValidElement)(children)) {
|
|
149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
|
|
150
|
+
}
|
|
151
|
+
const child = children;
|
|
152
|
+
const childProps = { ...child.props ?? {} };
|
|
153
|
+
const childRef = child.ref ?? childProps.ref;
|
|
154
|
+
delete childProps.ref;
|
|
155
|
+
delete childProps.children;
|
|
156
|
+
const merged = mergeProps(slotProps, childProps);
|
|
157
|
+
merged.ref = composeRefs(forwardedRef, childRef);
|
|
158
|
+
return (0, import_react2.cloneElement)(child, merged);
|
|
159
|
+
});
|
|
120
160
|
// Annotate the CommonJS export names for ESM import in node:
|
|
121
161
|
0 && (module.exports = {
|
|
162
|
+
Slot,
|
|
122
163
|
acquireBodyScrollLock,
|
|
123
164
|
composeRef,
|
|
124
165
|
composeRefs,
|
package/lib/react.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Ref, ReactNode, ReactElement, HTMLAttributes } from 'react';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Root document scroll lock with ref-counting for nested overlays.
|
|
@@ -24,4 +25,10 @@ declare const composeRef: typeof composeRefs;
|
|
|
24
25
|
*/
|
|
25
26
|
declare function getMergeableTriggerChild(children: ReactNode): ReactElement | null;
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
interface SlotProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
29
|
+
children?: any;
|
|
30
|
+
}
|
|
31
|
+
/** Merges its props onto the single child. Used for `asChild`. */
|
|
32
|
+
declare const Slot: react.ForwardRefExoticComponent<SlotProps & react.RefAttributes<HTMLElement | null>>;
|
|
33
|
+
|
|
34
|
+
export { Slot, type SlotProps, acquireBodyScrollLock, composeRef, composeRefs, getMergeableTriggerChild, useComposedRefs };
|
package/lib/react.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Ref, ReactNode, ReactElement, HTMLAttributes } from 'react';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Root document scroll lock with ref-counting for nested overlays.
|
|
@@ -24,4 +25,10 @@ declare const composeRef: typeof composeRefs;
|
|
|
24
25
|
*/
|
|
25
26
|
declare function getMergeableTriggerChild(children: ReactNode): ReactElement | null;
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
interface SlotProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
29
|
+
children?: any;
|
|
30
|
+
}
|
|
31
|
+
/** Merges its props onto the single child. Used for `asChild`. */
|
|
32
|
+
declare const Slot: react.ForwardRefExoticComponent<SlotProps & react.RefAttributes<HTMLElement | null>>;
|
|
33
|
+
|
|
34
|
+
export { Slot, type SlotProps, acquireBodyScrollLock, composeRef, composeRefs, getMergeableTriggerChild, useComposedRefs };
|
package/lib/react.js
CHANGED
|
@@ -77,7 +77,51 @@ function getMergeableTriggerChild(children) {
|
|
|
77
77
|
}
|
|
78
78
|
return node;
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
// src/Slot.tsx
|
|
82
|
+
import {
|
|
83
|
+
cloneElement,
|
|
84
|
+
forwardRef,
|
|
85
|
+
isValidElement as isValidElement2
|
|
86
|
+
} from "react";
|
|
87
|
+
import { Fragment as Fragment2, jsx } from "react/jsx-runtime";
|
|
88
|
+
function mergeProps(slotProps, childProps) {
|
|
89
|
+
const merged = { ...slotProps };
|
|
90
|
+
for (const key of Object.keys(childProps)) {
|
|
91
|
+
if (key === "ref" || key === "children") continue;
|
|
92
|
+
const slotValue = slotProps[key];
|
|
93
|
+
const childValue = childProps[key];
|
|
94
|
+
const isEvent = key.startsWith("on") && typeof slotValue === "function" && typeof childValue === "function";
|
|
95
|
+
if (key === "className" || key === "aria-describedby") {
|
|
96
|
+
merged[key] = [slotValue, childValue].filter(Boolean).join(" ");
|
|
97
|
+
} else if (key === "style") {
|
|
98
|
+
merged.style = { ...slotValue ?? {}, ...childValue ?? {} };
|
|
99
|
+
} else if (isEvent) {
|
|
100
|
+
merged[key] = (event) => {
|
|
101
|
+
childValue(event);
|
|
102
|
+
if (!event?.defaultPrevented) slotValue(event);
|
|
103
|
+
};
|
|
104
|
+
} else {
|
|
105
|
+
merged[key] = childValue;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return merged;
|
|
109
|
+
}
|
|
110
|
+
var Slot = forwardRef(function Slot2({ children, ...slotProps }, forwardedRef) {
|
|
111
|
+
if (!isValidElement2(children)) {
|
|
112
|
+
return /* @__PURE__ */ jsx(Fragment2, { children });
|
|
113
|
+
}
|
|
114
|
+
const child = children;
|
|
115
|
+
const childProps = { ...child.props ?? {} };
|
|
116
|
+
const childRef = child.ref ?? childProps.ref;
|
|
117
|
+
delete childProps.ref;
|
|
118
|
+
delete childProps.children;
|
|
119
|
+
const merged = mergeProps(slotProps, childProps);
|
|
120
|
+
merged.ref = composeRefs(forwardedRef, childRef);
|
|
121
|
+
return cloneElement(child, merged);
|
|
122
|
+
});
|
|
80
123
|
export {
|
|
124
|
+
Slot,
|
|
81
125
|
acquireBodyScrollLock,
|
|
82
126
|
composeRef,
|
|
83
127
|
composeRefs,
|
package/package.json
CHANGED
|
@@ -1,66 +1,68 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@refineui/utilities",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "RefineUI React utilities for building components",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
"scripts": {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
},
|
|
20
|
-
"exports": {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
},
|
|
26
|
-
"./color": {
|
|
27
|
-
"types": "./lib/color.d.ts",
|
|
28
|
-
"import": "./lib/color.js",
|
|
29
|
-
"require": "./lib/color.cjs"
|
|
30
|
-
},
|
|
31
|
-
"./typography": {
|
|
32
|
-
"types": "./lib/typography.d.ts",
|
|
33
|
-
"import": "./lib/typography.js",
|
|
34
|
-
"require": "./lib/typography.cjs"
|
|
35
|
-
},
|
|
36
|
-
"./animation": {
|
|
37
|
-
"types": "./lib/animation.d.ts",
|
|
38
|
-
"import": "./lib/animation.js",
|
|
39
|
-
"require": "./lib/animation.cjs"
|
|
40
|
-
},
|
|
41
|
-
"./react": {
|
|
42
|
-
"types": "./lib/react.d.ts",
|
|
43
|
-
"import": "./lib/react.js",
|
|
44
|
-
"require": "./lib/react.cjs"
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"main": "./lib/index.cjs",
|
|
48
|
-
"files": [
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
"react
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/pelagornis/refineui",
|
|
11
|
+
"directory": "packages/utilities"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsup src/color.ts --format cjs,esm --dts --clean --out-dir lib --external react --external react-dom && tsup src/typography.ts --format cjs,esm --dts --out-dir lib --external react --external react-dom && tsup src/animation.ts --format cjs,esm --dts --out-dir lib --external react --external react-dom && tsup src/react.ts --format cjs,esm --dts --out-dir lib --external react --external react-dom && tsup src/index.ts --format cjs,esm --dts --out-dir lib --external react --external react-dom",
|
|
15
|
+
"build:color": "tsup src/color.ts --format cjs,esm --dts --clean --out-dir lib --external react --external react-dom",
|
|
16
|
+
"build:animation": "tsup src/animation.ts --format cjs,esm --dts --out-dir lib --external react --external react-dom",
|
|
17
|
+
"build:react": "tsup src/react.ts --format cjs,esm --dts --out-dir lib --external react --external react-dom",
|
|
18
|
+
"build:index": "tsup src/index.ts --format cjs,esm --dts --out-dir lib --external react --external react-dom"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./lib/index.d.ts",
|
|
23
|
+
"import": "./lib/index.js",
|
|
24
|
+
"require": "./lib/index.cjs"
|
|
25
|
+
},
|
|
26
|
+
"./color": {
|
|
27
|
+
"types": "./lib/color.d.ts",
|
|
28
|
+
"import": "./lib/color.js",
|
|
29
|
+
"require": "./lib/color.cjs"
|
|
30
|
+
},
|
|
31
|
+
"./typography": {
|
|
32
|
+
"types": "./lib/typography.d.ts",
|
|
33
|
+
"import": "./lib/typography.js",
|
|
34
|
+
"require": "./lib/typography.cjs"
|
|
35
|
+
},
|
|
36
|
+
"./animation": {
|
|
37
|
+
"types": "./lib/animation.d.ts",
|
|
38
|
+
"import": "./lib/animation.js",
|
|
39
|
+
"require": "./lib/animation.cjs"
|
|
40
|
+
},
|
|
41
|
+
"./react": {
|
|
42
|
+
"types": "./lib/react.d.ts",
|
|
43
|
+
"import": "./lib/react.js",
|
|
44
|
+
"require": "./lib/react.cjs"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"main": "./lib/index.cjs",
|
|
48
|
+
"files": [
|
|
49
|
+
"lib"
|
|
50
|
+
],
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@refineui/version": "1.0.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"react": ">=18.0.0",
|
|
56
|
+
"react-dom": ">=18.0.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/react": "^18.3.20",
|
|
60
|
+
"react": "^18.3.1",
|
|
61
|
+
"react-dom": "^18.3.1",
|
|
62
|
+
"tsup": "^8.0.0",
|
|
63
|
+
"typescript": "^5.0.0"
|
|
64
|
+
},
|
|
65
|
+
"publishConfig": {
|
|
66
|
+
"access": "public"
|
|
67
|
+
}
|
|
66
68
|
}
|