diff --git a/packages/preset-view/src/emoji.ts b/packages/preset-view/src/emoji.ts new file mode 100644 index 00000000..f0da710c --- /dev/null +++ b/packages/preset-view/src/emoji.ts @@ -0,0 +1,41 @@ +import { classes } from './cdk/core'; +import { html } from './cdk/html'; +import emojiDataJson from 'emoji-datasource/emoji.json'; + +export interface PmpEmoji { + name: string; + unified: string; + non_qualified: string; + docomo: string; + au: string; + softbank: string; + google: string; + image: string; + sheet_x: number; + sheet_y: number; + short_name: string; + short_names: string[]; + text: string | null; + texts: string[] | null; + category: string; + subcategory: string; + sort_order: number; + added_in: string; + has_img_apple: boolean; + has_img_google: boolean; + has_img_twitter: boolean; + has_img_facebook: boolean; +} + +const emojis = emojiDataJson as PmpEmoji[]; +console.log(emojis); + +export interface PmpEmojiPickerProps {} + +export const PmpEmojiPicker = (props: PmpEmojiPickerProps) => { + return html` +
+
emoji
+
+ `; +}; diff --git a/packages/preset-view/src/index.ts b/packages/preset-view/src/index.ts index 19b37f66..92a90312 100644 --- a/packages/preset-view/src/index.ts +++ b/packages/preset-view/src/index.ts @@ -13,3 +13,4 @@ export * from './command'; export * from './image'; export * from './cdk/html'; export * from './menubar'; +export * from './emoji'; \ No newline at end of file diff --git a/packages/preset-view/src/menubar.ts b/packages/preset-view/src/menubar.ts index 806fbe6c..b3766919 100644 --- a/packages/preset-view/src/menubar.ts +++ b/packages/preset-view/src/menubar.ts @@ -41,6 +41,7 @@ import { } from 'prosemirror-preset-image'; import { classes } from './cdk/core'; import { html } from './cdk/html'; +import { PmpEmojiPicker } from './emoji'; export interface PmpMenubarProps { editorView: EditorView; @@ -130,10 +131,16 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { selectedIndex: number; } | null>(null); + const [emojiLayerRef, setEmojiLayerRef] = useState<{ + top: number; + left: number; + } | null>(null); + const textColorButtonRef = useRef(null); const linkButtonRef = useRef(null); const commandButtonRef = useRef(null); const imageInputRef = useRef(null); + const emojiButtonRef = useRef(null); const onImageChange = async (e: TargetedEvent) => { const target = e.target as HTMLInputElement; @@ -221,13 +228,13 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { onClick=${() => props.onUndoClick()} > - + <${PmpButton} disabled=${!props.canRedo} onClick=${() => props.onRedoClick()} > - + <${PmpSeparator} className="pmp-view-menubar-separator" /> <${PmpButton} @@ -236,49 +243,49 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { onClick=${() => props.onParagraphClick()} > - + <${PmpButton} disabled=${!props.canNormalText} className=${props.activeH1 ? 'selected' : ''} onClick=${() => props.onHeadingClick(1)} > - + <${PmpButton} disabled=${!props.canNormalText} className=${props.activeH2 ? 'selected' : ''} onClick=${() => props.onHeadingClick(2)} > - + <${PmpButton} disabled=${!props.canNormalText} className=${props.activeH3 ? 'selected' : ''} onClick=${() => props.onHeadingClick(3)} > - + <${PmpButton} disabled=${!props.canNormalText} className=${props.activeH4 ? 'selected' : ''} onClick=${() => props.onHeadingClick(4)} > - + <${PmpButton} disabled=${!props.canNormalText} className=${props.activeH5 ? 'selected' : ''} onClick=${() => props.onHeadingClick(5)} > - + <${PmpButton} disabled=${!props.canNormalText} className=${props.activeH6 ? 'selected' : ''} onClick=${() => props.onHeadingClick(6)} > - + <${PmpSeparator} className="pmp-view-menubar-separator" /> <${PmpButton} @@ -286,25 +293,25 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { onClick=${() => props.toggleBold()} > - + <${PmpButton} className=${props.activeItalic ? 'selected' : ''} onClick=${() => props.toggleItalic()} > - + <${PmpButton} className=${props.activeStrikethrough ? 'selected' : ''} onClick=${() => props.toggleStrikethrough()} > - + <${PmpButton} className=${props.activeInlineCode ? 'selected' : ''} onClick=${() => props.toggleInlineCode()} > - + <${PmpButton} ref=${textColorButtonRef} onClick=${() => { @@ -316,7 +323,7 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { }} > - + ${ textColorLayerRef && html` @@ -333,7 +340,7 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { props.onTextColorClick(color); }} /> - + ` } <${PmpSeparator} className="pmp-view-menubar-separator" /> @@ -344,21 +351,21 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { onClick=${() => props.onAlignClick('left')} > - + <${PmpButton} disabled=${!props.canAlign} className=${props.activeAlignCenter ? 'selected' : ''} onClick=${() => props.onAlignClick('center')} > - + <${PmpButton} disabled=${!props.canAlign} className=${props.activeAlignRight ? 'selected' : ''} onClick=${() => props.onAlignClick('right')} > - + <${PmpSeparator} className="pmp-view-menubar-separator" /> <${PmpButton} @@ -367,31 +374,31 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { onClick=${() => props.onOrderedListClick()} > - + <${PmpButton} className=${props.activeUnorderedList ? 'selected' : ''} disabled=${!props.canBulletList} onClick=${() => props.onUnorderedListClick()} > - + <${PmpButton} disabled=${!props.canDeindent} onClick=${() => props.onDecreaseIndentClick()} > - + <${PmpButton} disabled=${!props.canIndent} onClick=${() => props.onIncreaseIndentClick()} > - + <${PmpSeparator} className="pmp-view-menubar-separator" /> <${PmpButton} disabled=${true}> - + <${PmpButton} ref=${linkButtonRef} disabled=${!props.canLink} @@ -410,7 +417,7 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { }} > - + ${ linkLayerRef && html` @@ -431,7 +438,7 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { }} onCancel=${() => setLinkLayerRef(null)} /> - + ` } <${PmpInput} @@ -450,7 +457,7 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { }} > - + <${PmpButton} disabled=${!props.canMention} onClick=${() => { @@ -458,27 +465,47 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { }} > - + <${PmpButton} onClick=${() => { props.onBlockQuoteClick(); }} > - - <${PmpButton} disabled=${true}> + + <${PmpButton} ref=${emojiButtonRef} onClick=${() => { + const rect = emojiButtonRef.current!.getBoundingClientRect(); + setEmojiLayerRef({ + top: rect.top + rect.height + 10, + left: rect.left, + }); + }}> - + + ${ + emojiLayerRef && + html` + <${PmpLayer} + top=${emojiLayerRef.top} + left=${emojiLayerRef.left} + closeOnEsc=${true} + outerMousedown=${() => setEmojiLayerRef(null)} + onClose=${() => setEmojiLayerRef(null)} + > + <${PmpEmojiPicker}>emoji + + ` + } <${PmpButton} onClick=${() => { props.onTableClick(); }} > - + <${PmpButton} disabled=${true}> - + <${PmpButton} ref=${commandButtonRef} onClick=${() => { @@ -491,7 +518,7 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { }} > - + ${ commandLayerRef && html` @@ -517,7 +544,7 @@ export const PmpMenubar = forwardRef((props: PmpMenubarProps) => { setCommandLayerRef(null); }} /> - + ` } diff --git a/packages/preset-view/styles/emoji.scss b/packages/preset-view/styles/emoji.scss new file mode 100644 index 00000000..a88f2690 --- /dev/null +++ b/packages/preset-view/styles/emoji.scss @@ -0,0 +1,3 @@ +.pmp-view-emoji-picker { + color: red; +} \ No newline at end of file diff --git a/packages/preset-view/styles/view.scss b/packages/preset-view/styles/view.scss index f2e6d432..6ae74ba6 100644 --- a/packages/preset-view/styles/view.scss +++ b/packages/preset-view/styles/view.scss @@ -2,6 +2,7 @@ @import './button.scss'; @import './color.scss'; @import './command.scss'; +@import './emoji.scss'; @import './image.scss'; @import './input.scss'; @import './label.scss'; diff --git a/packages/preset-view/tsconfig.json b/packages/preset-view/tsconfig.json index a7166693..88cd106c 100644 --- a/packages/preset-view/tsconfig.json +++ b/packages/preset-view/tsconfig.json @@ -4,6 +4,8 @@ "baseUrl": "./src", "outDir": "./dist", "declaration": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, "paths": { "prosemirror-preset-core": ["../../preset-core/src/index.ts"], "prosemirror-preset-mention": ["../../preset-mention/src/index.ts"],