0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-24 23:48:13 -05:00

Added first version for accordion card

refs https://github.com/TryGhost/Team/issues/1209

Added first version for toggle cards with heading and content input and basic rendering in Editor
This commit is contained in:
Rishabh 2021-11-09 20:36:01 +05:30
parent 1bf14c2cc3
commit da4641f9b3
4 changed files with 177 additions and 0 deletions

View file

@ -0,0 +1,75 @@
<KoenigCard
@icon={{"koenig/card-indicator-email"}}
@class={{concat (kg-style "container-card") " kg-email-card kg-email-cta-card mih10 miw-100 relative"}}
@headerOffset={{@headerOffset}}
@toolbar={{this.toolbar}}
@payload={{@payload}}
@isSelected={{@isSelected}}
@isEditing={{@isEditing}}
@selectCard={{@selectCard}}
@deselectCard={{@deselectCard}}
@editCard={{@editCard}}
@hasEditMode={{true}}
@saveCard={{@saveCard}}
@saveAsSnippet={{@saveAsSnippet}}
@onLeaveEdit={{this.leaveEditMode}}
@addParagraphAfterCard={{@addParagraphAfterCard}}
@moveCursorToPrevSection={{@moveCursorToPrevSection}}
@moveCursorToNextSection={{@moveCursorToNextSection}}
@editor={{@editor}}
{{did-insert this.registerElement}}
as |card|
>
{{#if @isEditing}}
{{!-- edit mode view --}}
<div style="height: 50px;padding: 12px 0">
<div style="font-weight: bold;min-height: 24px">{{@payload.heading}}</div>
<div style="padding-left: 12px;min-height: 24px">{{@payload.content}}</div>
</div>
<KoenigSettingsPanel>
<div class="kg-settings-panel-control">
<label class="kg-settings-panel-control-label" for="heading-text-input">Heading</label>
<div class="kg-settings-panel-control-input">
<input
type="text"
class="gh-input"
id="heading-text-input"
name="heading-text"
value={{@payload.heading}}
placeholder="Add button text"
{{on "input" this.setHeading}}
{{on-key "Enter" (fn this.focusElement "#content-text-input")}}
>
</div>
</div>
<div class="kg-settings-panel-control">
<label class="kg-settings-panel-control-label" for="content-text-input">Content</label>
<div class="kg-settings-panel-control-input">
<input
type="text"
class="gh-input"
id="content-text-input"
name="content-text"
value={{@payload.content}}
placeholder="Add content"
{{on "input" this.setContent}}
>
</div>
</div>
</KoenigSettingsPanel>
{{else}}
{{!-- rendered (non-edit) mode view --}}
<div style="height: 50px;padding: 12px 0">
<div style="font-weight: bold;min-height: 24px">{{@payload.heading}}</div>
<div style="padding-left: 2px;min-height: 24px">{{@payload.content}}</div>
</div>
{{/if}}
</KoenigCard>

View file

@ -0,0 +1,87 @@
import Component from '@glimmer/component';
import {action} from '@ember/object';
import {isBlank} from '@ember/utils';
import {run} from '@ember/runloop';
import {inject as service} from '@ember/service';
import {set} from '@ember/object';
export default class KoenigCardAccordionComponent extends Component {
@service config;
@service feature;
@service store;
@service membersUtils;
@service ui;
get toolbar() {
if (this.args.isEditing) {
return false;
}
return {
items: [{
buttonClass: 'fw4 flex items-center white',
icon: 'koenig/kg-edit',
iconClass: 'fill-white',
title: 'Edit',
text: '',
action: run.bind(this, this.args.editCard)
}]
};
}
constructor() {
super(...arguments);
this.args.registerComponent(this);
const payloadDefaults = {};
Object.entries(payloadDefaults).forEach(([key, value]) => {
if (this.args.payload[key] === undefined) {
this._updatePayloadAttr(key, value);
}
});
}
// required for snippet rects to be calculated - editor reaches in to component,
// expecting a non-Glimmer component with a .element property
@action
registerElement(element) {
this.element = element;
}
@action
setContent(event) {
this._updatePayloadAttr('content', event.target.value);
}
@action
setHeading(event) {
this._updatePayloadAttr('heading', event.target.value);
}
@action
leaveEditMode() {
const {html, content, heading} = this.args.payload;
if (isBlank(html) && isBlank(heading) && isBlank(content)) {
// afterRender is required to avoid double modification of `isSelected`
// TODO: see if there's a way to avoid afterRender
run.scheduleOnce('afterRender', this, this.args.deleteCard);
}
}
@action
focusElement(selector, event) {
event.preventDefault();
document.querySelector(selector)?.focus();
}
_updatePayloadAttr(attr, value) {
let payload = this.args.payload;
set(payload, attr, value);
// update the mobiledoc and stay in edit mode
this.args.saveCard?.(payload, false);
}
}

View file

@ -15,6 +15,7 @@ export const CARD_COMPONENT_MAP = {
button: 'koenig-card-button',
callout: 'koenig-card-callout',
nft: 'koenig-card-nft',
toggle: 'koenig-card-accordion',
'email-cta': 'koenig-card-email-cta',
paywall: 'koenig-card-paywall'
};
@ -34,6 +35,7 @@ export const CARD_ICON_MAP = {
button: 'koenig/kg-card-type-gen-embed',
callout: 'koenig/kg-card-type-gen-embed',
nft: 'koenig/kg-card-type-gen-embed',
toggle: 'koenig/kg-card-type-gen-embed',
'email-cta': 'koenig/kg-card-type-gen-embed',
paywall: 'koenig/kg-card-type-divider'
};
@ -63,6 +65,9 @@ export default [
return !card.payload.calloutText;
}}),
createComponentCard('nft', {hasEditMode: false}),
createComponentCard('toggle', {deleteIfEmpty(card) {
return !card.payload.header && !card.payload.content;
}}),
createComponentCard('paywall', {hasEditMode: false, selectAfterInsert: false})
];
@ -171,6 +176,15 @@ export const CARD_MENU = [
type: 'card',
replaceArg: 'callout',
feature: 'calloutCard'
},
{
label: 'Toggle',
icon: 'koenig/kg-card-type-paywall',
desc: 'Add collapsible content',
matches: ['toggle'],
type: 'card',
replaceArg: 'toggle',
feature: 'accordionCard'
}]
},
{

View file

@ -0,0 +1 @@
export {default} from 'koenig-editor/components/koenig-card-accordion';