Skip to content

Commit

Permalink
docs(composables): add docs for class & classes composables
Browse files Browse the repository at this point in the history
  • Loading branch information
homj committed Nov 7, 2023
1 parent 74d6e1d commit d975a18
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 89 deletions.
144 changes: 55 additions & 89 deletions libs/composables/class/docs/class.composable.md
Original file line number Diff line number Diff line change
@@ -1,171 +1,137 @@
# `useAttribute`
# Class Composable

This composable is used to get and set the value of an attribute of an element.
It will return a writable signal that can be used to change the value of the attribute.
- [`useClass`](#useclass)
- [`bindClass`](#bindclass)

## Parameters
## `useClass`

| Name | Type | Optional? | Description |
|------------------------|----------|-----------|---------------------------------------------------------------------------------------------------------------------------|
| `attributeName` | `string` | no | The name of the attribute to bind to. |
| `options` | `object` | yes | Options to customize the behavior. |
| `options.namespace` | `string` | yes | The namespace of the attribute. |
| `options.defaultValue` | `string` | yes | The default value of the attribute. Will be applied when no attribute value has been set in the template or on the signal |
| `options.initialValue` | `string` | yes | The initial value of the attribute. Will force the initial value and override any value set in the template |
This composable is used to add or remove a specific class on the host element.
It will return a writable signal that can be used to change whether the class should be added or removed.

### Parameters

## Usage
| Name | Type | Optional? | Description |
|------------------------|-----------|-----------|---------------------------------------------|
| `clazz` | `string` | no | The name of the class. |
| `options` | `object` | yes | Options to customize the behavior. |
| `options.initialValue` | `boolean` | yes | Whether the class should initially be added |

### Default behavior

By default, this composable will read the value of the attribute from the usage in the template
### Usage

```ts
import { useAttribute } from '@bynary/angular-composables/attribute';

@Component({
selector: 'my-component'
})
class MyComponent {

label = useAttribute('label');
}
```

```html
<my-component #myComponent label="foo"></my-component>
#### Default behavior

{{ myComponent.label }}
```

will render as

```html
<my-component label="foo"></my-component>

foo
```

### Default value

To set a default value, you can use the `options.defaultValue` parameter:
By default, this composable will add the class to the host element

```ts
import { useAttribute } from '@bynary/angular-composables/attribute';
import { useClass } from '@bynary/angular-composables/class';

@Component({
selector: 'my-component'
})
class MyComponent {

label = useAttribute('label', { defaultValue: 'foo' });
isLoading = useClass('loading');
}
```

```html
<my-component #myComponent></my-component>

{{ myComponent.label }}
{{ myComponent.isLoading }}
```

and will render as
will render as

```html
<my-component label="foo"></my-component>
<my-component class="loading"></my-component>

foo
true
```

### Force initial value
#### Override initial value

You may override any template-defined value by setting `options.initialValue`:
If you don't want to add the class initially, set `options.initialValue` to `false`:

```ts
import { useAttribute } from '@bynary/angular-composables/attribute';
import { useClass } from '@bynary/angular-composables/class';

@Component({
selector: 'my-component'
})
class MyComponent {

label = useAttribute('label', { initialValue: 'bar' });
isLoading = useClass('label', { initialValue: false });
}
```

```html
<my-component #myComponent label="foo"></my-component>
<my-component #myComponent></my-component>

{{ myComponent.label }}
{{ myComponent.isLoading }}
```

will render as

```html
<my-component label="bar"></my-component>
<my-component></my-component>

bar
false
```

### Custom namespace
#### Programmatically set the value

You may also use a custom namespace for the attribute:
By changing the value of the signal, you can add / remove the class programmatically

```ts
import { useAttribute } from '@bynary/angular-composables/attribute';
import { useClass } from '@bynary/angular-composables/class';

@Component({
selector: 'my-component'
})
class MyComponent {

label = useAttribute('label', { namespace: 'my', initialValue: 'baz' });
isLoading = useClass('loading', { initialValue: false });

startLoading() {
this.isLoading.set(true);
}

stopLoading() {
this.isLoading.set(false);
}
}
```

```html
<my-component #myComponent></my-component>

{{ myComponent.label }}
```
## `bindClass`

will render as
Toggles a class on the host element based on the value of a signal. Similar to `useClass`, but accepts a boolean signal as an input instead of creating a new one.
Will return the signal that has been passed in.

```html
<my-component my:label="baz"></my-component>
### Parameters

baz
```
| Name | Type | Optional? | Description |
|---------|----------|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `clazz` | `string` | no | The name of the class. |
| `value` | `Signal` | no | The signal to determine whether the class should be added or removed. When the signal's value is true, the class will be applied. Else it will be removed. |

### Programmatically set the value
### Usage

You can also change the value of the attribute programmatically by using the returned signal:
`bindClass` can be used inside a directive or component:

```ts
import { useAttribute } from '@bynary/angular-composables/attribute';
import { bindClass } from '@bynary/angular-composables/class';

@Component({
selector: 'my-component'
})
class MyComponent {

label = useAttribute('label');
isLoading: Signal<boolean> = signal(false);

constructor() {
this.label.set('programmatically set value');
bindClass('loading', this.isLoading);
}
}
```

```html
<my-component #myComponent></my-component>

{{ myComponent.label }}
```

will render as

```html
<my-component label="programmatically set value"></my-component>

programmatically set value
```
128 changes: 128 additions & 0 deletions libs/composables/class/docs/classes.composable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Classes Composable

- [`useClasses`](#useclasses)
- [`bindClasses`](#bindclasses)

## `useClasses`

This composable is used to add or remove a set of classes on the host element.
It will return a writable signal that can be used to change whether the class should be added or removed.

### Parameters

| Name | Type | Optional? | Description |
|----------------|----------------------|-----------|--------------------------------------------------------------------|
| `initialValue` | `string \| string[]` | yes | The list of classes to apply initially. Defaults to an empty array |


### Usage

#### Default behavior

By default, this composable will add the classes to the host element

```ts
import { useClasses } from '@bynary/angular-composables/class';

@Component({
selector: 'my-component'
})
class MyComponent {

classes = useClasses(['my-component', 'primary', 'focusable']);
}
```

```html
<my-component #myComponent></my-component>
```

will render as

```html
<my-component class="my-component primary focusable"></my-component>
```

#### String as initial value

You may also pass a string as the initial value. The string will be split by spaces and each part will be added as a class.
Multiple spaces will be ignored.

```ts
import { useClasses } from '@bynary/angular-composables/class';

@Component({
selector: 'my-component'
})
class MyComponent {

isLoading = useClasses('my-component primary focusable');
}
```

```html
<my-component #myComponent></my-component>
```

will render as

```html
<my-component class="my-component primary focusable"></my-component>
```

#### Programmatically set the value

By changing the value of the signal, you can add / remove classes programmatically.
Each previously set class will be removed and the new classes will be added.
Classes set form somewhere else (e.g. the template) will be untouched, except for ones that are contained in new or previous list.

```ts
import { useClasses } from '@bynary/angular-composables/class';

@Component({
selector: 'my-component',
host: {
class: 'my-component'
}
})
class MyComponent {

classes = useClasses('primary focusable'); // initially, these classes will be set on the host: `my-component`, `primary`, `focusable`

changeClasses() {
this.classes.set('accent'); // will remove `primary` and `focusable`, resulting in these classes set on the host: `my-component`, `accent`
}
}
```


## `bindClasses`

Binds a set of class to the host element based on the value of a signal. Similar to `useClasses`, but accepts a signal as an input instead of creating a new one.
Will return the signal that has been passed in.

### Parameters

| Name | Type | Optional? | Description |
|---------|----------|-----------|--------------------------------------------------------|
| `value` | `Signal` | no | The signal containing the classes to bind to the host. |

### Usage

`bindClasses` can be used inside a directive or component:

```ts
import { bindClasses } from '@bynary/angular-composables/class';

@Component({
selector: 'my-component'
})
class MyComponent {

classes = signal([ 'foo', 'bar' ]);

constructor() {
bindClasses(this.classes);
}
}
```

0 comments on commit d975a18

Please sign in to comment.