fetta 1.4.4 → 1.5.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.
- package/README.md +169 -25
- package/dist/chunk-FP4I6OR2.js +43 -0
- package/dist/chunk-ORMEWXMH.js +33 -0
- package/dist/chunk-UPF3IYHC.js +1762 -0
- package/dist/helpers.d.ts +46 -0
- package/dist/helpers.js +121 -0
- package/dist/index-c1UKfWWK.d.ts +144 -0
- package/dist/index.d.ts +1 -137
- package/dist/index.js +2 -1
- package/dist/initialStyles-BGuPp5CS.d.ts +23 -0
- package/dist/motion.d.ts +185 -0
- package/dist/motion.js +2116 -0
- package/dist/react.d.ts +37 -76
- package/dist/react.js +136 -101
- package/package.json +26 -2
- package/dist/chunk-Y4GCLM4K.js +0 -1077
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ Split text into characters, words, and lines while preserving the original typog
|
|
|
17
17
|
- **Accessible** — Automatic screen reader support, even when splitting text with nested links or emphasis
|
|
18
18
|
- **TypeScript** — Full type definitions included
|
|
19
19
|
- **React Component** — Declarative wrapper for React projects
|
|
20
|
-
- **Built-in
|
|
20
|
+
- **Built-in Viewport** — Viewport detection for scroll-triggered animations in React
|
|
21
21
|
- **Library Agnostic** — Works with Motion, GSAP, or any animation library
|
|
22
22
|
|
|
23
23
|
## Installation
|
|
@@ -26,7 +26,10 @@ Split text into characters, words, and lines while preserving the original typog
|
|
|
26
26
|
npm install fetta
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
**Bundle size
|
|
29
|
+
**Bundle size** (minified + brotli)
|
|
30
|
+
- `fetta`: ~5.4 kB
|
|
31
|
+
- `fetta/react`: ~6.7 kB
|
|
32
|
+
- `fetta/motion`: ~11.2 kB
|
|
30
33
|
|
|
31
34
|
## Quick Start
|
|
32
35
|
|
|
@@ -83,13 +86,13 @@ const result = splitText(element, options);
|
|
|
83
86
|
| `lineClass` | `string` | `"split-line"` | CSS class for line elements |
|
|
84
87
|
| `mask` | `string` | — | Wrap elements in `overflow: clip` container: `"chars"`, `"words"`, or `"lines"` |
|
|
85
88
|
| `autoSplit` | `boolean` | `false` | Re-split on container resize |
|
|
86
|
-
| `
|
|
87
|
-
| `onSplit` | `function` | — | Callback after initial split |
|
|
89
|
+
| `onResplit` | `function` | — | Callback after autoSplit/full-resplit replaces split output elements |
|
|
90
|
+
| `onSplit` | `function` | — | Callback after initial split. Return animation/promise for `revertOnComplete` |
|
|
88
91
|
| `revertOnComplete` | `boolean` | `false` | Auto-revert when animation completes |
|
|
89
92
|
| `propIndex` | `boolean` | `false` | Add CSS custom properties: `--char-index`, `--word-index`, `--line-index` |
|
|
90
93
|
| `disableKerning` | `boolean` | `false` | Skip kerning compensation (no margin adjustments) |
|
|
91
94
|
| `initialStyles` | `object` | — | Apply initial inline styles to chars/words/lines after split. Values can be objects or `(el, index) => object` functions |
|
|
92
|
-
| `initialClasses` | `object` | — | Apply initial CSS classes to chars/words/lines
|
|
95
|
+
| `initialClasses` | `object` | — | Apply initial CSS classes to chars/words/lines. Values are strings |
|
|
93
96
|
|
|
94
97
|
#### Return Value
|
|
95
98
|
|
|
@@ -102,13 +105,57 @@ const result = splitText(element, options);
|
|
|
102
105
|
}
|
|
103
106
|
```
|
|
104
107
|
|
|
108
|
+
### `createSplitClones(splitResult, options)` (`fetta/helpers`)
|
|
109
|
+
|
|
110
|
+
Builds swap/reveal DOM layers (clones + optional wrappers) without coupling to any animation library.
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { splitText } from "fetta";
|
|
114
|
+
import { createSplitClones } from "fetta/helpers";
|
|
115
|
+
|
|
116
|
+
const split = splitText(element, { type: "chars", mask: "chars" });
|
|
117
|
+
const layers = createSplitClones(split, { unit: "chars", wrap: true });
|
|
118
|
+
|
|
119
|
+
// Animate with Motion, GSAP, WAAPI, or CSS
|
|
120
|
+
// ...
|
|
121
|
+
|
|
122
|
+
layers.cleanup(); // removes clones/wrappers, keeps split DOM
|
|
123
|
+
// layers.cleanup({ revertSplit: true }) // also calls split.revert()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
#### Behavior
|
|
127
|
+
|
|
128
|
+
- Clone is always appended to the **current parent** of the original split node.
|
|
129
|
+
- `wrap: false` (default): clone is appended to existing parent (often the mask wrapper).
|
|
130
|
+
- `wrap: true`: original is first moved into a track wrapper, then clone is appended there.
|
|
131
|
+
- Helper never calls `splitText` and never performs animation.
|
|
132
|
+
|
|
133
|
+
#### Options
|
|
134
|
+
|
|
135
|
+
| Option | Type | Default | Description |
|
|
136
|
+
|--------|------|---------|-------------|
|
|
137
|
+
| `unit` | `"chars" \| "words" \| "lines"` | — | Which split nodes to layer |
|
|
138
|
+
| `wrap` | `boolean` | `false` | Wrap each original in a track wrapper (`position: relative`) |
|
|
139
|
+
| `display` | `"auto" \| "inline-block" \| "block"` | `"auto"` | Track display when `wrap: true` (`lines` => `block`, others => `inline-block`) |
|
|
140
|
+
| `cloneOffset.axis` | `"x" \| "y"` | `"y"` | Axis used for initial clone offset |
|
|
141
|
+
| `cloneOffset.direction` | `"start" \| "end"` | `"start"` | Offset direction (`start` => negative) |
|
|
142
|
+
| `cloneOffset.distance` | `string` | `"100%"` | Offset distance |
|
|
143
|
+
| `trackClassName` / `cloneClassName` | `string \| (ctx) => string` | — | Class names (static or per-item) |
|
|
144
|
+
| `trackStyle` / `cloneStyle` | `object \| (ctx) => object` | — | Inline styles (static or per-item) |
|
|
145
|
+
|
|
146
|
+
For reveal/swap effects, use matching `mask` in `splitText` (`"chars"`, `"words"`, or `"lines"`).
|
|
147
|
+
|
|
105
148
|
### `<SplitText>` (React)
|
|
106
149
|
|
|
107
150
|
```tsx
|
|
108
151
|
import { SplitText } from 'fetta/react';
|
|
109
152
|
```
|
|
110
153
|
|
|
111
|
-
|
|
154
|
+
`fetta/react` forwards common wrapper DOM props (`id`, `role`, `tabIndex`, `aria-*`, `data-*`, and event handlers like `onClick`) to the wrapper element.
|
|
155
|
+
|
|
156
|
+
`fetta/react` props:
|
|
157
|
+
|
|
158
|
+
#### React Props
|
|
112
159
|
|
|
113
160
|
| Prop | Type | Default | Description |
|
|
114
161
|
|------|------|---------|-------------|
|
|
@@ -117,21 +164,35 @@ import { SplitText } from 'fetta/react';
|
|
|
117
164
|
| `className` | `string` | — | Class name for wrapper element |
|
|
118
165
|
| `style` | `CSSProperties` | — | Additional styles for wrapper element |
|
|
119
166
|
| `ref` | `Ref<HTMLElement>` | — | Ref to container element |
|
|
120
|
-
| `onSplit` | `(result) =>
|
|
121
|
-
| `
|
|
122
|
-
| `options` | `
|
|
167
|
+
| `onSplit` | `(result) => CallbackReturn` | — | Called after text is split |
|
|
168
|
+
| `onResplit` | `(result) => void` | — | Called when autoSplit/full-resplit replaces split output elements |
|
|
169
|
+
| `options` | `SplitTextOptions` | — | Split options (type, classes, mask, propIndex, disableKerning) |
|
|
123
170
|
| `autoSplit` | `boolean` | `false` | Re-split on container resize |
|
|
171
|
+
| `waitForFonts` | `boolean` | `true` | Wait for `document.fonts.ready` before splitting (recommended for stable kerning). Set `false` for immediate split. |
|
|
124
172
|
| `revertOnComplete` | `boolean` | `false` | Revert after animation completes |
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
173
|
+
| `onRevert` | `() => void` | — | Called when split text is reverted (manual or automatic) |
|
|
174
|
+
| `viewport` | `ViewportOptions` | — | Configure viewport detection |
|
|
175
|
+
| `onViewportEnter` | `(result) => CallbackReturn` | — | Called when element enters viewport |
|
|
176
|
+
| `onViewportLeave` | `(result) => CallbackReturn` | — | Called when element leaves viewport |
|
|
128
177
|
| `initialStyles` | `object` | — | Apply initial inline styles to chars/words/lines. Values can be objects or `(el, index) => object` functions |
|
|
129
|
-
| `initialClasses` | `object` | — | Apply initial CSS classes to chars/words/lines. Values
|
|
130
|
-
| `
|
|
178
|
+
| `initialClasses` | `object` | — | Apply initial CSS classes to chars/words/lines. Values are strings |
|
|
179
|
+
| `resetOnViewportLeave` | `boolean` | `false` | Re-apply initialStyles/initialClasses when leaving viewport |
|
|
180
|
+
|
|
181
|
+
#### Shared `SplitTextOptions` (`options` prop)
|
|
182
|
+
|
|
183
|
+
| Option | Type | Default | Description |
|
|
184
|
+
|------|------|---------|-------------|
|
|
185
|
+
| `type` | `SplitType` | `"chars,words,lines"` | What to split: `"chars"`, `"words"`, `"lines"`, or combinations |
|
|
186
|
+
| `charClass` | `string` | `"split-char"` | CSS class for character spans |
|
|
187
|
+
| `wordClass` | `string` | `"split-word"` | CSS class for word spans |
|
|
188
|
+
| `lineClass` | `string` | `"split-line"` | CSS class for line spans |
|
|
189
|
+
| `mask` | `"lines" \| "words" \| "chars"` | — | Wrap elements in `overflow: clip` mask containers |
|
|
190
|
+
| `propIndex` | `boolean` | `false` | Add CSS index variables (`--char-index`, `--word-index`, `--line-index`) |
|
|
191
|
+
| `disableKerning` | `boolean` | `false` | Skip kerning compensation (no margin adjustments) |
|
|
131
192
|
|
|
132
193
|
#### Callback Signature
|
|
133
194
|
|
|
134
|
-
All callbacks (`onSplit`, `
|
|
195
|
+
All callbacks (`onSplit`, `onResplit`, `onViewportEnter`, `onViewportLeave`) receive:
|
|
135
196
|
|
|
136
197
|
```ts
|
|
137
198
|
{
|
|
@@ -142,16 +203,85 @@ All callbacks (`onSplit`, `onResize`, `onInView`, `onLeaveView`) receive the sam
|
|
|
142
203
|
}
|
|
143
204
|
```
|
|
144
205
|
|
|
145
|
-
|
|
206
|
+
```ts
|
|
207
|
+
type CallbackReturn =
|
|
208
|
+
| void
|
|
209
|
+
| Promise<unknown>
|
|
210
|
+
| { finished: Promise<unknown> }
|
|
211
|
+
| { then: (onFulfilled?: ((result: unknown) => unknown) | undefined) => unknown }
|
|
212
|
+
| CallbackReturn[];
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
When using `autoSplit` with `lines` in scroll-linked or scroll-triggered animations, re-attach scroll/timeline logic inside `onResplit` so it binds to the new split element references.
|
|
216
|
+
|
|
217
|
+
`onRevert` is a separate zero-argument callback that fires when a split cycle actually reverts.
|
|
218
|
+
|
|
219
|
+
#### Viewport Options
|
|
146
220
|
|
|
147
221
|
```ts
|
|
148
222
|
{
|
|
149
|
-
amount?: number
|
|
150
|
-
|
|
151
|
-
|
|
223
|
+
amount?: number | "some" | "all"; // Enter threshold, default: 0
|
|
224
|
+
leave?: number | "some" | "all"; // Leave threshold, default: 0
|
|
225
|
+
margin?: string; // Root margin, default: "0px"
|
|
226
|
+
once?: boolean; // Only trigger once, default: false
|
|
227
|
+
root?: RefObject<Element>; // Optional root element
|
|
152
228
|
}
|
|
153
229
|
```
|
|
154
230
|
|
|
231
|
+
### `<SplitText>` (Motion)
|
|
232
|
+
|
|
233
|
+
```tsx
|
|
234
|
+
import { SplitText } from "fetta/motion";
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
`fetta/motion` includes all props from `fetta/react`, plus Motion variant props. It also forwards standard Motion/DOM wrapper props (`id`, `role`, `tabIndex`, `layout`, `drag`, `data-*`, etc.) to the wrapper.
|
|
238
|
+
|
|
239
|
+
Animate on exit with Motion's `AnimatePresence` (make `SplitText` the direct child):
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
import { AnimatePresence } from "motion/react";
|
|
243
|
+
|
|
244
|
+
<AnimatePresence>
|
|
245
|
+
{isVisible && (
|
|
246
|
+
<SplitText
|
|
247
|
+
variants={{
|
|
248
|
+
enter: { opacity: 1, y: 0 },
|
|
249
|
+
exit: { opacity: 0, y: 12 },
|
|
250
|
+
}}
|
|
251
|
+
initial="enter"
|
|
252
|
+
animate="enter"
|
|
253
|
+
exit="exit"
|
|
254
|
+
options={{ type: "words" }}
|
|
255
|
+
>
|
|
256
|
+
<h1>Goodbye</h1>
|
|
257
|
+
</SplitText>
|
|
258
|
+
)}
|
|
259
|
+
</AnimatePresence>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### Motion-only Props
|
|
263
|
+
|
|
264
|
+
| Prop | Type | Default | Description |
|
|
265
|
+
|------|------|---------|-------------|
|
|
266
|
+
| `variants` | `Record<string, VariantDefinition<TCustom>>` | — | Named variant definitions |
|
|
267
|
+
| `initial` | `string \| VariantDefinition<TCustom> \| false` | — | Initial variant applied instantly after split |
|
|
268
|
+
| `animate` | `string \| VariantDefinition<TCustom>` | — | Base variant |
|
|
269
|
+
| `exit` | `string \| VariantDefinition<TCustom> \| false` | — | Exit variant (AnimatePresence) |
|
|
270
|
+
| `whileInView` | `string \| VariantDefinition<TCustom>` | — | Variant while element is in view |
|
|
271
|
+
| `whileOutOfView` | `string \| VariantDefinition<TCustom>` | — | Variant after element leaves view |
|
|
272
|
+
| `whileScroll` | `string \| VariantDefinition<TCustom>` | — | Scroll-driven variant (highest trigger priority) |
|
|
273
|
+
| `whileHover` | `string \| VariantDefinition<TCustom>` | — | Variant on hover |
|
|
274
|
+
| `whileTap` | `string \| VariantDefinition<TCustom>` | — | Variant on tap/press |
|
|
275
|
+
| `whileFocus` | `string \| VariantDefinition<TCustom>` | — | Variant on focus |
|
|
276
|
+
| `animateOnResplit` | `boolean` | `false` | Replay initial->animate on autoSplit/full-resplit |
|
|
277
|
+
| `scroll` | `{ offset?, axis?, container? }` | — | Scroll tracking options for `whileScroll` |
|
|
278
|
+
| `transition` | `AnimationOptions` | — | Global/default transition for variants |
|
|
279
|
+
| `custom` | `TCustom` | — | Custom data forwarded to function variants |
|
|
280
|
+
| `delayScope` | `"global" \| "local"` | `"global"` | Delay-function index scope (`globalIndex` vs relative `index`) |
|
|
281
|
+
| `reducedMotion` | `"user" \| "always" \| "never"` | — | Reduced-motion behavior for this component |
|
|
282
|
+
| `onHoverStart` | `() => void` | — | Called when hover starts |
|
|
283
|
+
| `onHoverEnd` | `() => void` | — | Called when hover ends |
|
|
284
|
+
|
|
155
285
|
## Examples
|
|
156
286
|
|
|
157
287
|
### Vanilla JavaScript
|
|
@@ -243,7 +373,7 @@ splitText(element, { type: 'chars', propIndex: true });
|
|
|
243
373
|
</SplitText>
|
|
244
374
|
```
|
|
245
375
|
|
|
246
|
-
#### Scroll-Triggered with
|
|
376
|
+
#### Scroll-Triggered with Viewport
|
|
247
377
|
|
|
248
378
|
```tsx
|
|
249
379
|
<SplitText
|
|
@@ -251,11 +381,11 @@ splitText(element, { type: 'chars', propIndex: true });
|
|
|
251
381
|
initialStyles={{
|
|
252
382
|
words: { opacity: '0', transform: 'translateY(20px)' }
|
|
253
383
|
}}
|
|
254
|
-
|
|
255
|
-
|
|
384
|
+
viewport={{ amount: 0.5 }}
|
|
385
|
+
onViewportEnter={({ words }) => {
|
|
256
386
|
animate(words, { opacity: 1, y: 0 }, { delay: stagger(0.03) });
|
|
257
387
|
}}
|
|
258
|
-
|
|
388
|
+
resetOnViewportLeave
|
|
259
389
|
>
|
|
260
390
|
<p>Animates when scrolled into view</p>
|
|
261
391
|
</SplitText>
|
|
@@ -284,7 +414,10 @@ Default classes applied to split elements:
|
|
|
284
414
|
| `.split-word` | Words | Inline positioning |
|
|
285
415
|
| `.split-line` | Lines | Block display |
|
|
286
416
|
|
|
287
|
-
|
|
417
|
+
Split elements receive typed index attributes:
|
|
418
|
+
- Characters: `data-char-index`
|
|
419
|
+
- Words: `data-word-index`
|
|
420
|
+
- Lines: `data-line-index`
|
|
288
421
|
|
|
289
422
|
## Font Loading
|
|
290
423
|
|
|
@@ -297,7 +430,17 @@ document.fonts.ready.then(() => {
|
|
|
297
430
|
});
|
|
298
431
|
```
|
|
299
432
|
|
|
300
|
-
|
|
433
|
+
React and Motion components wait for fonts by default (`waitForFonts={true}`), which gives the most stable kerning.
|
|
434
|
+
|
|
435
|
+
If you notice a visual shift after splitting, keep the default waiting behavior enabled.
|
|
436
|
+
|
|
437
|
+
If you need immediate splitting (for example, responsiveness-first UI), you can opt out with `waitForFonts={false}`:
|
|
438
|
+
|
|
439
|
+
```tsx
|
|
440
|
+
<SplitText waitForFonts={false}>
|
|
441
|
+
<h1>Split Immediately</h1>
|
|
442
|
+
</SplitText>
|
|
443
|
+
```
|
|
301
444
|
|
|
302
445
|
## Accessibility
|
|
303
446
|
|
|
@@ -332,6 +475,7 @@ Pre-existing `aria-label` attributes are always preserved.
|
|
|
332
475
|
## Notes
|
|
333
476
|
|
|
334
477
|
- **Ligatures are disabled** (`font-variant-ligatures: none`) because ligatures cannot span multiple elements.
|
|
478
|
+
- **Authored hard breaks are preserved** — Explicit `<br>` and block-level descendants are treated as hard boundaries. In `chars`/`words` modes, hard boundaries are normalized to `<br>` in the split output.
|
|
335
479
|
|
|
336
480
|
## Browser Support
|
|
337
481
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// src/internal/initialStyles.ts
|
|
2
|
+
function reapplyInitialStyles(elements, style) {
|
|
3
|
+
if (!style || elements.length === 0) return;
|
|
4
|
+
const isFn = typeof style === "function";
|
|
5
|
+
for (let i = 0; i < elements.length; i++) {
|
|
6
|
+
const el = elements[i];
|
|
7
|
+
const styles = isFn ? style(el, i) : style;
|
|
8
|
+
for (const [key, value] of Object.entries(styles)) {
|
|
9
|
+
if (value == null) continue;
|
|
10
|
+
if (key === "cssText") {
|
|
11
|
+
if (typeof value === "string") {
|
|
12
|
+
el.style.cssText = value;
|
|
13
|
+
}
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (typeof value !== "string" && typeof value !== "number") continue;
|
|
17
|
+
const cssValue = typeof value === "number" ? String(value) : value;
|
|
18
|
+
const cssKey = key.startsWith("--") ? key : key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
19
|
+
el.style.setProperty(cssKey, cssValue);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function reapplyInitialClasses(elements, className) {
|
|
24
|
+
if (!className || elements.length === 0) return;
|
|
25
|
+
const classes = className.split(/\s+/).filter(Boolean);
|
|
26
|
+
for (const el of elements) {
|
|
27
|
+
el.classList.add(...classes);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/internal/waitForFontsReady.ts
|
|
32
|
+
async function waitForFontsReady(waitForFonts) {
|
|
33
|
+
if (!waitForFonts) return;
|
|
34
|
+
const fonts = document.fonts;
|
|
35
|
+
const ready = fonts == null ? void 0 : fonts.ready;
|
|
36
|
+
if (!ready || typeof ready.then !== "function") return;
|
|
37
|
+
try {
|
|
38
|
+
await ready;
|
|
39
|
+
} catch (e) {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { reapplyInitialClasses, reapplyInitialStyles, waitForFontsReady };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __objRest = (source, exclude) => {
|
|
21
|
+
var target = {};
|
|
22
|
+
for (var prop in source)
|
|
23
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
24
|
+
target[prop] = source[prop];
|
|
25
|
+
if (source != null && __getOwnPropSymbols)
|
|
26
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
27
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
}
|
|
30
|
+
return target;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { __objRest, __spreadProps, __spreadValues };
|