Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/lifeart/ember-ref-bucket

This is list of handy ember primitives, created to simplify class-based dom workflow
https://github.com/lifeart/ember-ref-bucket

addon dom-manipulation ember ember-addon

Last synced: 4 days ago
JSON representation

This is list of handy ember primitives, created to simplify class-based dom workflow

Awesome Lists containing this project

README

        

ember-ref-bucket
==============================================================================

This addon was created as a rethinking of [ember-ref-modifier](https://github.com/lifeart/ember-ref-modifier), with a more simplified API and without some of the downsides of the previous implementation.

The addon allows users to get access to DOM nodes inside components, including accessing wrapping/destroying logic.

A simple use case:

* applying `ref` modifier with passed name to an element.
```hbs

hello

```

* gain access to it inside the component class as a decorated property
```js
import Component from '@glimmer/component';
import { ref } from 'ember-ref-bucket';

export default class MyComponent extends Component {
@ref("FavouriteNode") node;
// this.node === "

hello
"
}
```

--------

API differences, comparing to `ember-ref-modifier`:

In `ember-ref-modifier` ref modifier accept 2 positional arguments `{{ref this "property"}}`:
1. context to set path (`this`)
2. path to set on context (`"property"`)

In `ember-ref-bucket` ref modifier accept 1 positional argument `{{create-ref "field"}}`:
1. reference name (`"field"`)

reference name should be passed as an argument to the `@ref("field")` decorator, to allow it to find the reference by name.

Compatibility
------------------------------------------------------------------------------

* Ember.js v3.24 or above
* Ember CLI v3.24 or above
* Node.js v14 or above

Installation
------------------------------------------------------------------------------

```
ember install ember-ref-bucket
```

Usage
------------------------------------------------------------------------------

## Examples

### Simple player

```hbs

Play
```
```js
import Component from '@glimmer/component';
import { ref } from 'ember-ref-bucket';
import { action } from '@ember/object';

export class Player extends Component {
@ref('player') audioNode;
@action onPlay() {
this.audioNode.play()
}
}

```

### Link `div` to `node` property.

```hbs


```

```ts
import Component from '@glimmer/component';
import { ref } from 'ember-ref-bucket';

export default class MyComponent extends Component {
@ref("field") node = null;
}
```

### Dynamically show `div` content updates

```hbs

hello

{{get (tracked-ref-to "field") "textContent"}}

```

### Use `div` as component argument

```hbs

hello

```

### Use `registerNodeDestructor`

This method is very useful if you want to wrap the node and control its lifecycle.

```hbs


```

```js
import Component from '@glimmer/component';
import { ref, registerNodeDestructor } from 'ember-ref-bucket';

class NodeWrapper {
constructor(node) {
this.node = node;
}
destroy() {
this.node = null;
}
value() {
return this.node.textContent;
}
}

export default class WrappedNodeComponent extends Component {
@ref('field', (node) => {
const instance = new NodeWrapper(node);
registerNodeDestructor(node, () => instance.destroy());
return instance;
}) node = null;
get value() {
return this.node?.value();
}
}
```

## Available decorators:

```js
import { ref, globalRef, trackedRef, trackedGlobalRef } from 'ember-ref-bucket';

/*
ref - usage: @ref('foo', nodeWrapFn?), ref to bucket with current component context
globalRef - usage: @globalRef('foo', nodeWrapFn?), ref to global context (app)
trackedRef - usage: @trackedRef('foo', nodeWrapFn?), tracked ref to local context
trackedGlobalRef - usage: @trackedGlobalRef('foo', nodeWrapFn?), tracked ref to global context (app)

*/
```

## Available methods:

```js
import { registerNodeDestructor, unregisterNodeDestructor } from 'ember-ref-bucket';

/*
registerNodeDestructor(node, fn) - to assign any ref-node destructor
unregisterNodeDestructor(node, fn) - to remove assigned ref-node destructor

usage will be like:

@ref('field', (node) => {
const item = new InputMask(node);
registerNodeDestructor(node, () => item.destroy());
return item;
});
*/

```

```js
/*
nodeFor - functional low-level primitive to get node access
*/

import { nodeFor } from 'ember-ref-bucket';

const domNode = nodeFor(this, 'field');
```

## Definition of `@trackedRef` decorators

* If you use dom node in `@tracked` chain calculations, you should use `trackedRef`.

* If you don't need to rerun the tracked chain (for example, you use `ref` only for some event-based dom access), you should not use `trackedRef`.

## Definition of `{{create-tracked-ref}}` modifiers

* If you need to watch for node changes (resize, content, attributes), you can use the `create-tracked-ref` modifier. It can add observe resizing and mutations for the associated element and will mark it as "dirty" for any mutation.

Options:
* `resize` - default: `false`, if truthy observes the resizing of the DOM element.
* `attributes` - default: `false`, if truthy observes the changing of any attribute on the DOM element.
* `character` - default: `false`, if truthy observes the change of the innerText of the DOM element. Note that setting innerText can change the children or the character depending on the current content of the element.
* `children` - default: `false`, if truthy observes changes to the list of direct children of the DOM element.
* `subtree` - default: `false`, if truthy observes the above options on the entire DOM subtree, not just the element decorated by the modifier.

## Definition of `{{tracked-ref-to}}` helpers

* If you need to recalculate helper if some dom node changes (size, children, attributes), you need to use `tracked-ref-to` helper.
* If you don't need it (you need to just have ref to dom node), you should choose `ref-to` helper.

## Template-only components

* `create-ref` modifier and `ref-to` helpers will not work in template-only components (because of no context). You should use `create-global-ref` and `global-ref-to` instead. You can also provide a `bucket` param to the `create-ref` modifier / helper.

-----------

_The addon provide only 1 modifier (`create-ref`) and 1 helper (`ref-to`). Other derivatives will be transformed, and are described below:_

### Modifiers will be transformed according to this table:

| Invocation | Will be transformed to |
|------------------------------|---------------------------------------------|
| `{{create-ref "foo"}}` | `{{create-ref "foo" bucket=this}}` |
| `{{create-tracked-ref "foo"}}` | `{{create-ref "foo" bucket=this tracked=true}}` |
| `{{create-global-ref "foo"}} ` | `{{create-ref "foo" bucket=undefined}}` |
| `{{create-tracked-global-ref "foo"}}` | `{{create-ref "foo" bucket=undefined tracked=true}}` |

## Helpers will be transformed according to this table:

| Invocation | Will be transformed to |
|------------------------------|---------------------------------------------|
| `{{ref-to "foo"}}` | `{{ref-to "foo" bucket=this}}` |
| `{{tracked-ref-to "foo"}}` | `{{ref-to "foo" bucket=this tracked=true}}` |
| `{{global-ref-to "foo"}} ` | `{{ref-to "foo" bucket=undefined}}` |
| `{{tracked-global-ref-to "foo"}}` | `{{ref-to "foo" bucket=undefined tracked=true}}` |

-----------

Contributing
------------------------------------------------------------------------------

See the [Contributing](CONTRIBUTING.md) guide for details.

Version matrix:

Ember-Modifier 4 - v5;
Ember 3.28 - v4;
Ember 3.24 - v3

License
------------------------------------------------------------------------------

This project is licensed under the [MIT License](LICENSE.md).