consul/ui-v2/lib/block-slots/addon/components/block-slot.js

56 lines
2.1 KiB
JavaScript

import Component from '@ember/component';
import { isPresent } from '@ember/utils';
import { get, set, computed, defineProperty } from '@ember/object';
import layout from '../templates/components/block-slot';
import Slots from '../mixins/slots';
import YieldSlot from './yield-slot';
const BlockSlot = Component.extend({
layout,
tagName: '',
didInsertElement: function() {
const slottedComponent = this.nearestOfType(Slots);
if (!slottedComponent._isRegistered(this._name)) {
slottedComponent._activateSlot(this._name);
set(this, 'slottedComponent', slottedComponent);
return;
}
const yieldSlot = this.nearestOfType(YieldSlot);
if (yieldSlot) {
set(this, '_yieldSlot', yieldSlot);
// The slotted component will yield multiple times - once to register
// the activate slots and once more per active slot - only display this
// block when its associated slot is the one yielding
const isTargetSlotYielding = yieldSlot._name === this._name;
set(this, 'isTargetSlotYielding', isTargetSlotYielding);
// If the associated slot has block params, create a computed property
// for each block param. Technically this could be an unlimited, but
// hbs lacks a spread operator so params are currently limited to 9
// (see the yield in the block-slot template)
//
// Spread PR: https://github.com/wycats/handlebars.js/pull/1149
if (isTargetSlotYielding && isPresent(yieldSlot._blockParams)) {
// p0 p1 p2...
yieldSlot._blockParams.forEach((param, index) => {
defineProperty(this, `p${index}`, computed.readOnly(`_yieldSlot._blockParams.${index}`));
});
}
}
},
willDestroyElement: function() {
const slottedComponent = get(this, 'slottedComponent');
if (slottedComponent) {
// Deactivate the yield slot using the slots interface when the block
// is destroyed to allow the yield slot default {{else}} to take effect
// dynamically
slottedComponent._deactivateSlot(this._name);
}
},
});
BlockSlot.reopenClass({
positionalParams: ['_name'],
});
export default BlockSlot;