Skip to content

Commit

Permalink
Finish the missing docs
Browse files Browse the repository at this point in the history
  • Loading branch information
sneridagh committed Feb 22, 2024
1 parent 6b98d6c commit 675e0af
Show file tree
Hide file tree
Showing 3 changed files with 298 additions and 4 deletions.
92 changes: 90 additions & 2 deletions docs/source/configuration/slots.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ A slot component must have the following parameters.

`slot`
: The name of the slot, where the slot components are stored.

`name`
: The name of the slot component that we are registering.

Expand Down Expand Up @@ -108,7 +108,7 @@ export function RouteCondition(path: string, exact?: boolean) {

The `RouteCondition` predicate helper renders a slot if the specified route matches.
It accepts the following parameters.

`path`
: Required. String. The route.

Expand All @@ -134,3 +134,91 @@ It accepts a list of possible content types.
You can create your own predicate helpers to determine whether your slot component should render.
The `SlotRenderer` will pass down the current `content` and the `pathname` into your custom predicate helper.
You can also tailor your own `SlotRenderer`s, or shadow the original `SlotRenderer`, to satisfy your requirements.

## Manage registered slots and slot components

### `getSlotComponents`

It returns the list of components registered per slot.
This is useful to debug what is registered an in what order, and later change the order, if needed.
This is the signature:

```ts
config.getSlotComponents(slot: string): string[]

```

`slot`
: The name of the slot, where the slot components are stored.

### `reorderSlotComponent`

It reorders the list of components registered per slot.
This is the signature:

```ts
config.reorderSlotComponent(slot: string, name: string, position: number): void
```

`slot`
: The name of the slot, where the slot components are stored.

`name`
: The name of the slot component we want to reorder.

`position`
: The destination position in the registered list of slot components that we want to move the slot component.


### `getSlotComponent`

It returns the list of registered components per slot component name.
This is useful to debug what is registered an in what order, and later remove a registration, if needed.
This is the signature:

```ts
config.getSlotComponent(slot: string, name: string): SlotComponent[]
```

`slot`
: The name of the slot, where the slot components are stored.

`name`
: The name of the slot component we want to retrieve.

### `unRegisterSlotComponent`

It removes a registration for a specific component, given its registration position.
This is the signature:

```ts
config.unRegisterSlotComponent(slot: string, name: string, position: number): void
```

`slot`
: The name of the slot, where the slot components are stored.

`name`
: The name of the slot component inside it's the component we want to unregister.

`position`
: The component position that we want to remove in the slot component registration. Use `getSlotComponent` to find out the position of the registered component that you want to remove.

### `getSlot`

It returns the components that should be rendered per named slot.
You should use this method in case you are building you own slot renderer, or customizing the existing one (`SlotRenderer`).
You can take the implementation of `SlotRenderer` as template.
This is the signature:

```ts
config.getSlot<T>(name: string, args: T): SlotComponent['component'][] | undefined
```

It must have the following parameters.

`name`
: The name of the slot we want to render.

`options`
: An object containing the arguments that you want to pass to the predicates.
48 changes: 46 additions & 2 deletions packages/registry/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ class Config {
currentSlot.data[name] = [];
}

const currentSlotComponent = currentSlot.data[name];
const currentSlotComponents = currentSlot.data[name];
if (!currentSlot.slots.includes(name)) {
currentSlot.slots.push(name);
}
Expand All @@ -283,7 +283,51 @@ class Config {
);
}

currentSlotComponent.push(slotComponentData);
currentSlotComponents.push(slotComponentData);
}

getSlotComponent(slot: string, name: string) {
const currentSlot = this._data.slots[slot];
if (!slot || !currentSlot) {
throw new Error(`No slot ${slot} found`);
}
const currentSlotComponents = currentSlot.data[name];
if (!currentSlotComponents) {
throw new Error(`No slot component ${name} in slot ${slot} found`);
}
return currentSlotComponents;
}

getSlotComponents(slot: string) {
const currentSlot = this._data.slots[slot];
if (!slot || !currentSlot) {
throw new Error(`No slot ${slot} found`);
}
return currentSlot.slots;
}

reorderSlotComponent(slot: string, name: string, position: number) {
const currentSlot = this._data.slots[slot];
if (!slot || !currentSlot) {
throw new Error(`No slot ${slot} found`);
}

const origin = currentSlot.slots.indexOf(name);
currentSlot.slots = currentSlot.slots
.toSpliced(origin, 1)
.toSpliced(position, 0, name);
}

unRegisterSlotComponent(slot: string, name: string, position: number) {
const currentSlot = this._data.slots[slot];
if (!slot || !currentSlot) {
throw new Error(`No slot ${slot} found`);
}
const currentSlotComponents = currentSlot.data[name];
if (!currentSlotComponents) {
throw new Error(`No slot component ${name} in slot ${slot} found`);
}
currentSlot.data[name] = currentSlotComponents.toSpliced(position, 1);
}
}

Expand Down
162 changes: 162 additions & 0 deletions packages/registry/src/registry.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,166 @@ describe('Slots registry', () => {
'this is a toolbar edit component with true predicate',
]);
});

it('getSlotComponents - registers 2 + 2 slot components with predicates', () => {
config.registerSlotComponent({
slot: 'toolbar',
name: 'save',
component: 'this is a toolbar save component with a true predicate',
predicates: [RouteConditionTrue('/de')],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'save',
component: 'this is a toolbar component with two false predicate',
predicates: [
RouteConditionFalse('/folder/path'),
ContentTypeConditionFalse(['News Item']),
],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'edit',
component: 'this is a toolbar component with a false predicate',
predicates: [RouteConditionFalse('/de')],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'edit',
component: 'this is a toolbar edit component with true predicate',
predicates: [
RouteConditionTrue('/folder/path'),
ContentTypeConditionTrue(['News Item']),
],
});
expect(config.getSlotComponents('toolbar').length).toEqual(2);
expect(config.getSlotComponents('toolbar')).toEqual(['save', 'edit']);
});

it('getSlotComponent - registers 2 + 2 slot components with predicates', () => {
config.registerSlotComponent({
slot: 'toolbar',
name: 'save',
component: 'this is a toolbar save component with a true predicate',
predicates: [RouteConditionTrue('/de')],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'save',
component: 'this is a toolbar component with two false predicate',
predicates: [
RouteConditionFalse('/folder/path'),
ContentTypeConditionFalse(['News Item']),
],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'edit',
component: 'this is a toolbar component with a false predicate',
predicates: [RouteConditionFalse('/de')],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'edit',
component: 'this is a toolbar edit component with true predicate',
predicates: [
RouteConditionTrue('/folder/path'),
ContentTypeConditionTrue(['News Item']),
],
});
expect(config.getSlotComponent('toolbar', 'save').length).toEqual(2);
expect(config.getSlotComponent('toolbar', 'save')[0].component).toEqual(
'this is a toolbar save component with a true predicate',
);
});

it('reorderSlotComponent - registers 2 + 2 slot components with predicates', () => {
config.registerSlotComponent({
slot: 'toolbar',
name: 'save',
component: 'this is a toolbar save component with a true predicate',
predicates: [RouteConditionTrue('/de')],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'save',
component: 'this is a toolbar component with two false predicate',
predicates: [
RouteConditionFalse('/folder/path'),
ContentTypeConditionFalse(['News Item']),
],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'edit',
component: 'this is a toolbar component with a false predicate',
predicates: [RouteConditionFalse('/de')],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'edit',
component: 'this is a toolbar edit component with true predicate',
predicates: [
RouteConditionTrue('/folder/path'),
ContentTypeConditionTrue(['News Item']),
],
});
expect(config.getSlotComponent('toolbar', 'save').length).toEqual(2);
expect(config.getSlotComponent('toolbar', 'save')[0].component).toEqual(
'this is a toolbar save component with a true predicate',
);
config.reorderSlotComponent('toolbar', 'save', 1);
expect(config.getSlotComponents('toolbar')).toEqual(['edit', 'save']);
});

it('unRegisterSlotComponent - registers 2 + 2 slot components with predicates', () => {
config.registerSlotComponent({
slot: 'toolbar',
name: 'save',
component: 'this is a toolbar save component with a true predicate',
predicates: [RouteConditionTrue('/de')],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'save',
component: 'this is a toolbar component with two false predicate',
predicates: [
RouteConditionFalse('/folder/path'),
ContentTypeConditionFalse(['News Item']),
],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'edit',
component: 'this is a toolbar component with a false predicate',
predicates: [RouteConditionFalse('/de')],
});

config.registerSlotComponent({
slot: 'toolbar',
name: 'edit',
component: 'this is a toolbar edit component with true predicate',
predicates: [
RouteConditionTrue('/folder/path'),
ContentTypeConditionTrue(['News Item']),
],
});
expect(config.getSlotComponent('toolbar', 'save').length).toEqual(2);
expect(config.getSlotComponent('toolbar', 'save')[0].component).toEqual(
'this is a toolbar save component with a true predicate',
);
config.unRegisterSlotComponent('toolbar', 'save', 1);
expect(config.getSlotComponent('toolbar', 'save').length).toEqual(1);
});
});

0 comments on commit 675e0af

Please sign in to comment.