Skip to content

Commit

Permalink
enhancement: add static method create
Browse files Browse the repository at this point in the history
Adds a static method that creates a new SplitType instance. This
provides a way to create a splitType instance without using the
new keyword.
  • Loading branch information
lukePeavey committed May 1, 2022
1 parent 4aac4b9 commit 153044e
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 54 deletions.
75 changes: 42 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# SplitType

[![npm version](https://badge.fury.io/js/split-type.svg)](https://www.npmjs.com/package/split-type)

SplitType is a small javascript library that splits HTML text into elements so that lines, words, and characters can be animated independently. It was inspired by GSAP's SplitText plugin, and can be used with any animation library.
SplitType is a small javascript library that splits HTML text into elements so that lines, words, and characters can be animated independently. It was inspired by GSAP's SplitText plugin, and can be used with any animation library.

- [Installation](#installation)
- [Usage](#usage)
- [API Reference](#api-reference)
- [Examples](#examples)

## Installation

**Yarn/NPM**
Expand All @@ -17,23 +18,34 @@ You can install SplitType as a dependency using yarn or npm.
```SHELL
yarn add 'split-type'
```

```js
import SplitType from 'split-type'
```

**CDN**

Or, include the following `<script>` tag to load SplitType from a CDN. In this case, the `SplitType` constructor will be attached to `window` object.
Or, include the following `<script>` tag to load SplitType from a CDN. In this case, the `SplitType` constructor will be attached to `window` object.

```html
<!-- Minified UMD bundle -->
<script src="https://unpkg.com/split-type"></script>
```

## Usage

## Usage
`SplitType` splits the text content of the target element(s) using the provided [options](#options). It returns a new `SplitType` instance which provides access to the split text nodes. Under the hood, it simply wraps each line, word, and/or character in an element without changing the visual appearance of the text.

`SplitType` splits the text content of the target element(s) using the provided [options](#options). It returns a new `SplitType` instance which provides access to the split text nodes. Under the hood, it simply wraps each line, word, and/or character in an element without changing the visual appearance of the text.
```js
const text = new SplitType('#target')
```

Note: if want to create a SplitType instance without using the `new` keyword, you can use the static method `create`

```js
// Creates a new SplitType instance without using the new keyword.
const text = SplitType.create('.target')
```

**Split Types**

Expand Down Expand Up @@ -64,24 +76,22 @@ console.log(text.chars)
**Absolute vs Relative position**
By default, split text nodes are set to relative position and `display:inline-block`. This allows split text to reflow naturally if the container is resized. SplitType also supports absolute position for split text nodes by settings `{absolute: true}`. This can improve performance for animations. But split text will not automatically reflow if the container size changes. To reposition text after browser is resized, you can use the `split` method to re-split text.
By default, split text nodes are set to relative position and `display:inline-block`. This allows split text to reflow naturally if the container is resized. SplitType also supports absolute position for split text nodes by settings `{absolute: true}`. This can improve performance for animations. But split text will not automatically reflow if the container size changes. To reposition text after browser is resized, you can use the `split` method to re-split text.
```js
// Splits text using absolute position for split text elements
const text = new SplitType('#target', { absolute: true })
```
## API Reference
## API Reference
### SplitType(target, [options])
### Arguments
#### `target`
**`target`**
The target elements for the SplitType call. This can be a selector, a single element, or an ArrayLike object (ie NodeList, jQuery Object, etc). SplitType does not currently support nested HTML inside target elements. So the elements passed to `SplitType` should directly contain the text that you wish to split.
The target elements for the SplitType call. This can be a selector, a single element, or an ArrayLike object (ie NodeList, jQuery Object, etc). SplitType does not currently support nested HTML inside target elements. So the elements passed to `SplitType` should directly contain the text that you wish to split.
#### `options`
**`options`**
| name | type | default | description |
| ---------- | --------- | ----------------------- | ---------------------------------------------------------------- |
Expand All @@ -94,52 +104,51 @@ The target elements for the SplitType call. This can be a selector, a single ele
| types | `string` | `"lines, words, chars"` | Comma separated list of types |
| split | `string` | "" | Alias for `types` |
### Instance Properties
### Instance Properties
#### `instance.lines: HTMLElement[]`
**`instance.lines: HTMLElement[]`**
An array of the split line elements in the splitType instance
#### `instance.words: HTMLElement[]`
**`instance.words: HTMLElement[]`**
An array of the split word elements in the splitType instance
#### `instance.chars: HTMLElement[]`
**`instance.chars: HTMLElement[]`**
An array of the split character elements
### Instance Methods
#### `instance.split(options): void`
**`instance.split(options): void`**
This method is automatically called by the SplitType constructor. But it can be called manually to re-split text using new options.
This method is automatically called by the SplitType constructor. But it can be called manually to re-split text using different options.
#### `revert(): void`
**`instance.revert(): void`**
Restores target elements to their original text content. It also clears cached data associated with the split text nodes.
Restores the target elements associated with this SplitType instance to their original text content. It also clears cached data associated with the split text nodes.
### Static Properties
#### `get SplitType.defaults`
**`SplitType.defaults`**
Gets the default settings for all SplitType calls
Gets the current default settings for all SplitType instances. The default settings can be modified using the `setDefaults` methods.
#### `set SplitType.defaults`
### Static Methods
Set the defaults settings. The value should be object containing specific settings to override. The value will be merged with the existing defaults object.
**`SplitType.setDefaults(options: any)`**
Sets the default options for all `SplitType` instances. **The provided object will be merged with the existing `SplitType.defaults` object**. Returns the new defaults object.
**`SplitType.create(target, options)`**
Creates a new `SplitType` instance using the provided parameters. This method can be used to call SplitType without using the `new` keyword.
```js
// To have splitType use absolute position by default.
SplitType.defaults = { absolute: true }
```
## Examples
**Text Animation with GSAP**
``` js
```js
// Split text into characters using absolute positioning.
const text = new SplitType('#target', {
types: 'chars',
Expand Down
39 changes: 35 additions & 4 deletions lib/SplitType.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,45 @@ export default class SplitType {
* existing defaults.
*
* @param {Object} settings an object containing the settings to override
*
* @deprecated
* @example
* SplitType.defaults = { "position": "absolute" }
*/
static set defaults(options) {
_defaults = extend(_defaults, parseSettings(options))
}

/**
* Sets the default settings for all SplitType instances.
* The provided object will be merged with the existing defaults objects.
*
* @param {Object} settings an object containing the settings to override
* @returns {Object} the new default settings
* @example
* SplitType.setDefaults({ "position": "absolute" })
*/
static setDefaults(options) {
_defaults = extend(_defaults, parseSettings(options))
return defaults
}

/**
* Creates a new SplitType instance with the given parameters
* This static method provides a way to create a splitType instance without
* using the new keyword.
*
* @param {any} target The target elements to split. can be one of:
* - {string} A css selector
* - {HTMLElement} A single element
* - {ArrayLike<HTMLElement>} A collection of elements
* - {Array<HTMLElement | ArrayLike<HTMLElement>>} A nested array of elements
* @param {Object} [options] Settings for the SplitType instance
* @return {SplitType} the SplitType instance
*/
static create(target, options) {
return new SplitType(target, options)
}

/**
* Creates a new `SplitType` instance
*
Expand All @@ -49,9 +80,9 @@ export default class SplitType {

if (this.elements.length) {
// Store the original HTML content of each target element
this.originals = this.elements.map((element) => {
return Data(element, 'html', Data(element).html || element.innerHTML)
})
this.originals = this.elements.map((element) =>
Data(element, 'html', Data(element).html || element.innerHTML)
)
if (this.settings.types) {
// Initiate the split operation.
this.split()
Expand Down
36 changes: 26 additions & 10 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ declare module 'split-type' {
split: string
}

type TargetElement =
| string
| HTMLElement
| ArrayLike<HTMLElement>
| Array<HTMLElement | ArrayLike<HTMLElement>>

export default class SplitType {
/**
* An array of the split line elements in the splitType instance
Expand All @@ -33,25 +39,35 @@ declare module 'split-type' {
* override. The value will be merged with the existing defaults object.
*/
static defaults: Partial<SplitTypeOptions>
/**
* Sets global defaults for all SplitType instances. The provided object
* is merged with the existing settings.
*/
static setDefaults(options: Partial<SplitTypeOptions>): SplitTypeOptions

/**
* Creates a new `SplitType` instance
*
* This static method provides a way to call `SplitType` without using the
* new keyword.
*/
static create(
target: TargetElement,
options?: Partial<SplitTypeOptions>
): SplitType

/**
* Creates a new `SplitType` instance
*
* @param target The target elements to split. can be one of:
* - {string} A css selector
* - {HTMLElement} A single element
* - {HTMLElement} A single element node
* - {ArrayLike<HTMLElement>} A collection of elements
* - {Array<HTMLElement | ArrayLike<HTMLElement>>} A nested array of elements
* - {Array<HTMLElement | ArrayLike<HTMLElement>>} An array containing
* HTML elements and/or collections of HTML elements.
* @param [options] Settings for the SplitType instance
*/
constructor(
target:
| string
| HTMLElement
| ArrayLike<HTMLElement>
| Array<HTMLElement | ArrayLike<HTMLElement>>,
options?: Partial<SplitTypeOptions>
)
constructor(target: TargetElement, options?: Partial<SplitTypeOptions>)

/**
* Splits the text in all target elements. This method is called
Expand Down
4 changes: 3 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export { default } from './SplitType'
import SplitType from './SplitType'

export default SplitType
6 changes: 3 additions & 3 deletions lib/split.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ export default function splitSingleElement(element, settings) {
if (types.chars) {
// Iterate through the characters in the current word
// TODO: support emojis in text
characterElementsForCurrentWord = toChars(WORD).map((CHAR) => {
return createElement(TAG_NAME, {
characterElementsForCurrentWord = toChars(WORD).map((CHAR) =>
createElement(TAG_NAME, {
class: `${settings.splitClass} ${settings.charClass}`,
style: 'display: inline-block;',
textContent: CHAR,
})
})
)

// push the character nodes for this word onto the array of
// all character nodes
Expand Down
4 changes: 1 addition & 3 deletions lib/utils/flatten.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@ import toArray from './toArray'
* Flattens nested ArrayLike object (max 2 levels deep)
*/
export default function flatten(obj) {
return toArray(obj).reduce((result, item) => {
return result.concat(toArray(item))
}, [])
return toArray(obj).reduce((result, item) => result.concat(toArray(item)), [])
}

0 comments on commit 153044e

Please sign in to comment.