-
-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integrated CTA Node Component into Koenig-Lexical (#1413)
ref https://linear.app/ghost/issue/PLG-310/configure-lexical-nodes-for-new-cta-card https://linear.app/ghost/issue/PLG-311/wire-up-ui-components-to-cta-nodes - Started integrating the CTA node into Koenig Lexical - Wired up the initial UI component to access the new `call-to-action` card from the koenig selector. - Added the visibility of the CTA card behind a flag. - Added test to check that the card can be rendered. At the moment it's static and features need to build on top of it.
- Loading branch information
1 parent
885a303
commit 31ad767
Showing
11 changed files
with
268 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import CalloutCardIcon from '../assets/icons/kg-card-type-callout.svg?react'; | ||
import KoenigCardWrapper from '../components/KoenigCardWrapper'; | ||
import {BASIC_NODES} from '../index.js'; | ||
import {CallToActionNode as BaseCallToActionNode} from '@tryghost/kg-default-nodes'; | ||
import {CallToActionNodeComponent} from './CallToActionNodeComponent'; | ||
import {createCommand} from 'lexical'; | ||
import {populateNestedEditor, setupNestedEditor} from '../utils/nested-editors'; | ||
|
||
export const INSERT_CTA_COMMAND = createCommand(); | ||
|
||
export class CallToActionNode extends BaseCallToActionNode { | ||
__htmlEditor; | ||
__htmlEditorInitialState; | ||
// TODO: Improve the copy of the menu item | ||
static kgMenu = { | ||
label: 'Call to Action', | ||
desc: 'Add a call to action to your post', | ||
Icon: CalloutCardIcon, // TODO: Replace with correct icon | ||
insertCommand: INSERT_CTA_COMMAND, | ||
matches: ['cta', 'call-to-action'], | ||
priority: 10, | ||
shortcut: '/cta', | ||
isHidden: ({config}) => { | ||
return !(config?.feature?.contentVisibilityAlpha === true); | ||
} | ||
}; | ||
|
||
static getType() { | ||
return 'call-to-action'; | ||
} | ||
|
||
getIcon() { | ||
// TODO: replace with correct icon | ||
return CalloutCardIcon; | ||
} | ||
|
||
constructor(dataset = {}, key) { | ||
super(dataset, key); | ||
|
||
// set up nested editor instances | ||
setupNestedEditor(this, '__htmlEditor', {editor: dataset.htmlEditor, nodes: BASIC_NODES}); | ||
|
||
// populate nested editors on initial construction | ||
if (!dataset.htmlEditor) { | ||
populateNestedEditor(this, '__htmlEditor', dataset.html || '<p>Hey <code>{first_name, "there"}</code>,</p>'); | ||
} | ||
} | ||
|
||
decorate() { | ||
return ( | ||
<KoenigCardWrapper | ||
nodeKey={this.getKey()} | ||
wrapperStyle="wide" | ||
> | ||
<CallToActionNodeComponent | ||
backgroundColor={this.backgroundColor} | ||
buttonColor={this.buttonColor} | ||
buttonText={this.buttonText} | ||
buttonUrl={this.buttonUrl} | ||
hasBackground={this.hasBackground} | ||
hasImage={this.hasImage} | ||
hasSponsorLabel={this.hasSponsorLabel} | ||
htmlEditor={this.__htmlEditor} | ||
imageUrl={this.imageUrl} | ||
layout={this.layout} | ||
nodeKey={this.getKey()} | ||
showButton={this.showButton} | ||
textValue={this.textValue} | ||
/> | ||
</KoenigCardWrapper> | ||
); | ||
} | ||
} | ||
|
||
export function $createCallToActionNode(dataset) { | ||
return new CallToActionNode(dataset); | ||
} | ||
|
||
export function $isCallToActionNode(node) { | ||
return node instanceof CallToActionNode; | ||
} |
85 changes: 85 additions & 0 deletions
85
packages/koenig-lexical/src/nodes/CallToActionNodeComponent.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import CardContext from '../context/CardContext'; | ||
import KoenigComposerContext from '../context/KoenigComposerContext.jsx'; | ||
import React from 'react'; | ||
import {ActionToolbar} from '../components/ui/ActionToolbar.jsx'; | ||
import {CtaCard} from '../components/ui/cards/CtaCard'; | ||
import {SnippetActionToolbar} from '../components/ui/SnippetActionToolbar.jsx'; | ||
import {ToolbarMenu, ToolbarMenuItem, ToolbarMenuSeparator} from '../components/ui/ToolbarMenu.jsx'; | ||
|
||
export const CallToActionNodeComponent = ({ | ||
nodeKey, | ||
backgroundColor, | ||
buttonText, | ||
buttonUrl, | ||
hasBackground, | ||
hasImage, | ||
hasSponsorLabel, | ||
imageUrl, | ||
layout, | ||
showButton, | ||
textValue, | ||
buttonColor, | ||
htmlEditor | ||
}) => { | ||
// const [editor] = useLexicalComposerContext(); | ||
const {isEditing, isSelected, setEditing} = React.useContext(CardContext); | ||
const {cardConfig} = React.useContext(KoenigComposerContext); | ||
const [showSnippetToolbar, setShowSnippetToolbar] = React.useState(false); | ||
const handleToolbarEdit = (event) => { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
setEditing(true); | ||
}; | ||
return ( | ||
<> | ||
<CtaCard | ||
buttonColor={buttonColor} | ||
buttonText={buttonText} | ||
buttonUrl={buttonUrl} | ||
color={backgroundColor} | ||
handleButtonColor={() => {}} | ||
handleColorChange={() => {}} | ||
hasBackground={hasBackground} | ||
hasImage={hasImage} | ||
hasSponsorLabel={hasSponsorLabel} | ||
htmlEditor={htmlEditor} | ||
imageSrc={imageUrl} | ||
isEditing={isEditing} | ||
isSelected={isSelected} | ||
layout={layout} | ||
setEditing={setEditing} | ||
showButton={showButton} | ||
text={textValue} | ||
updateButtonText={() => {}} | ||
updateButtonUrl={() => {}} | ||
updateHasSponsorLabel={() => {}} | ||
updateLayout={() => {}} | ||
updateShowButton={() => {}} | ||
/> | ||
<ActionToolbar | ||
data-kg-card-toolbar="button" | ||
isVisible={showSnippetToolbar} | ||
> | ||
<SnippetActionToolbar onClose={() => setShowSnippetToolbar(false)} /> | ||
</ActionToolbar> | ||
|
||
<ActionToolbar | ||
data-kg-card-toolbar="button" | ||
isVisible={isSelected && !isEditing} | ||
> | ||
<ToolbarMenu> | ||
<ToolbarMenuItem dataTestId="edit-button-card" icon="edit" isActive={false} label="Edit" onClick={handleToolbarEdit} /> | ||
<ToolbarMenuSeparator hide={!cardConfig.createSnippet} /> | ||
<ToolbarMenuItem | ||
dataTestId="create-snippet" | ||
hide={!cardConfig.createSnippet} | ||
icon="snippet" | ||
isActive={false} | ||
label="Save as snippet" | ||
onClick={() => setShowSnippetToolbar(true)} | ||
/> | ||
</ToolbarMenu> | ||
</ActionToolbar> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
packages/koenig-lexical/src/plugins/CallToActionPlugin.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import React from 'react'; | ||
import {$createCallToActionNode, CallToActionNode, INSERT_CTA_COMMAND} from '../nodes/CallToActionNode'; | ||
import {COMMAND_PRIORITY_LOW} from 'lexical'; | ||
import {INSERT_CARD_COMMAND} from './KoenigBehaviourPlugin'; | ||
import {mergeRegister} from '@lexical/utils'; | ||
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext'; | ||
|
||
export const CallToActionPlugin = () => { | ||
const [editor] = useLexicalComposerContext(); | ||
|
||
React.useEffect(() => { | ||
if (!editor.hasNodes([CallToActionNode])){ | ||
console.error('CallToActionPlugin: CallToActionNode not registered'); // eslint-disable-line no-console | ||
return; | ||
} | ||
return mergeRegister( | ||
editor.registerCommand( | ||
INSERT_CTA_COMMAND, | ||
async (dataset) => { | ||
const cardNode = $createCallToActionNode(dataset); | ||
editor.dispatchCommand(INSERT_CARD_COMMAND, {cardNode, openInEditMode: true}); | ||
|
||
return true; | ||
}, | ||
COMMAND_PRIORITY_LOW | ||
) | ||
); | ||
}, [editor]); | ||
|
||
return null; | ||
}; | ||
|
||
export default CallToActionPlugin; |
Oops, something went wrong.