-
-
Notifications
You must be signed in to change notification settings - Fork 133
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
28c70e7
commit 0b5539a
Showing
18 changed files
with
864 additions
and
93 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,4 +22,6 @@ export const Blocks = { | |
updateBlock, | ||
toggleBlock, | ||
insertBlocks, | ||
// [TODO] | ||
// updateBlocks | ||
}; |
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
52 changes: 52 additions & 0 deletions
52
web/next-example/src/components/examples/withCustomPlugin/customPlugins/Carousel/index.tsx
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,52 @@ | ||
import { YooptaPlugin } from '@yoopta/editor'; | ||
import { BarcodeIcon } from 'lucide-react'; | ||
import { Carousel } from './renders/Carousel'; | ||
import { CarouselItem } from './renders/CarouselItem'; | ||
import { CarouselItemDescription } from './renders/CarouselItemDescription'; | ||
import { CarouselItemImage } from './renders/CarouselItemImage'; | ||
import { CarouselItemTitle } from './renders/CarouselItemTitle'; | ||
|
||
const CarouselPlugin = new YooptaPlugin({ | ||
type: 'Carousel', | ||
elements: { | ||
carousel: { | ||
render: Carousel, | ||
children: ['carousel-item'], | ||
asRoot: true, | ||
}, | ||
'carousel-item': { | ||
render: CarouselItem, | ||
children: ['carousel-item-title', 'carousel-item-description', 'carousel-item-image'], | ||
}, | ||
'carousel-item-image': { | ||
render: CarouselItemImage, | ||
props: { | ||
nodeType: 'void', | ||
src: null, | ||
}, | ||
}, | ||
'carousel-item-title': { | ||
render: CarouselItemTitle, | ||
}, | ||
'carousel-item-description': { | ||
render: CarouselItemDescription, | ||
}, | ||
}, | ||
options: { | ||
display: { | ||
title: 'Carousel', | ||
description: 'Create a carousel', | ||
icon: <BarcodeIcon size={24} />, | ||
}, | ||
shortcuts: ['carousel'], | ||
}, | ||
parsers: { | ||
html: { | ||
deserialize: { | ||
nodeNames: ['CAROUSEL'], | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
export { CarouselPlugin }; |
24 changes: 24 additions & 0 deletions
24
...mple/src/components/examples/withCustomPlugin/customPlugins/Carousel/renders/Carousel.tsx
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,24 @@ | ||
import { Carousel as CarouselRoot, CarouselContent, CarouselPrevious, CarouselNext } from '@/components/ui/carousel'; | ||
import { Elements, PluginElementRenderProps, useYooptaEditor, useYooptaReadOnly } from '@yoopta/editor'; | ||
import { PlusCircle } from 'lucide-react'; | ||
|
||
const Carousel = ({ children, element, blockId, attributes }: PluginElementRenderProps) => { | ||
const editor = useYooptaEditor(); | ||
|
||
const onAddCarouselItem = () => { | ||
Elements.createElement(editor, blockId, { type: 'carousel-item' }, { path: 'next', focus: true, split: false }); | ||
}; | ||
|
||
return ( | ||
<CarouselRoot {...attributes}> | ||
<CarouselContent>{children}</CarouselContent> | ||
<CarouselPrevious contentEditable={false} /> | ||
<CarouselNext contentEditable={false} /> | ||
<button type="button" onClick={onAddCarouselItem}> | ||
<PlusCircle /> | ||
</button> | ||
</CarouselRoot> | ||
); | ||
}; | ||
|
||
export { Carousel }; |
41 changes: 41 additions & 0 deletions
41
.../src/components/examples/withCustomPlugin/customPlugins/Carousel/renders/CarouselItem.tsx
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,41 @@ | ||
import { Card, CardContent } from '@/components/ui/card'; | ||
import { CarouselItem as CarouselRootItem } from '@/components/ui/carousel'; | ||
import { Elements, PluginElementRenderProps, useYooptaEditor } from '@yoopta/editor'; | ||
import { Trash } from 'lucide-react'; | ||
|
||
const CarouselItem = ({ element, blockId, attributes, children }: PluginElementRenderProps) => { | ||
const editor = useYooptaEditor(); | ||
|
||
const onDeleteItem = () => { | ||
const items = Elements.getElementChildren(editor, blockId, { type: 'carousel' }); | ||
if (items?.length === 1) { | ||
return editor.deleteBlock({ blockId }); | ||
} | ||
|
||
const elementPath = Elements.getElementPath(editor, blockId, element); | ||
if (elementPath) { | ||
Elements.deleteElement(editor, blockId, { path: elementPath, type: 'carousel-item' }); | ||
} | ||
}; | ||
|
||
return ( | ||
<CarouselRootItem key={element.id} {...attributes} className="md:basis-1/2 lg:basis-1/3 relative group"> | ||
<div className="p-1"> | ||
<Card> | ||
<CardContent className="flex flex-col aspect-square items-center p-4">{children}</CardContent> | ||
</Card> | ||
</div> | ||
{!editor.readOnly && ( | ||
<button | ||
type="button" | ||
onClick={onDeleteItem} | ||
className="absolute top-3 right-3 opacity-0 group-hover:opacity-100" | ||
> | ||
<Trash size={16} color="gray" /> | ||
</button> | ||
)} | ||
</CarouselRootItem> | ||
); | ||
}; | ||
|
||
export { CarouselItem }; |
11 changes: 11 additions & 0 deletions
11
...ents/examples/withCustomPlugin/customPlugins/Carousel/renders/CarouselItemDescription.tsx
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,11 @@ | ||
import { PluginElementRenderProps } from '@yoopta/editor'; | ||
|
||
const CarouselItemDescription = (props: PluginElementRenderProps) => { | ||
return ( | ||
<p {...props.attributes} className="w-full text-sm text-muted-foreground mb-[6px]"> | ||
{props.children} | ||
</p> | ||
); | ||
}; | ||
|
||
export { CarouselItemDescription }; |
92 changes: 92 additions & 0 deletions
92
...components/examples/withCustomPlugin/customPlugins/Carousel/renders/CarouselItemImage.tsx
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,92 @@ | ||
import { Elements, PluginElementRenderProps, useYooptaEditor, useYooptaReadOnly } from '@yoopta/editor'; | ||
import { ImageIcon, DeleteIcon, Delete, Trash2 } from 'lucide-react'; | ||
import { ChangeEvent, MouseEvent } from 'react'; | ||
|
||
const CarouselItemImage = ({ element, children, attributes, blockId }: PluginElementRenderProps) => { | ||
const editor = useYooptaEditor(); | ||
const readOnly = useYooptaReadOnly(); | ||
|
||
const onUploadFile = (event: ChangeEvent) => { | ||
if (readOnly) return; | ||
|
||
const target = event.target as HTMLInputElement; | ||
const file = target.files?.[0]; | ||
if (!file) return; | ||
|
||
const reader = new FileReader(); | ||
reader.onload = (e) => { | ||
const src = e.target?.result as string; | ||
|
||
const elementPath = Elements.getElementPath(editor, blockId, element); | ||
|
||
Elements.updateElement( | ||
editor, | ||
blockId, | ||
{ type: 'carousel-item-image', props: { ...element.props, src } }, | ||
{ path: elementPath }, | ||
); | ||
}; | ||
reader.readAsDataURL(file); | ||
}; | ||
|
||
const onDeleteImage = () => { | ||
if (readOnly) return; | ||
|
||
const elementPath = Elements.getElementPath(editor, blockId, element); | ||
|
||
Elements.updateElement( | ||
editor, | ||
blockId, | ||
{ type: 'carousel-item-image', props: { ...element.props, src: null } }, | ||
{ path: elementPath }, | ||
); | ||
}; | ||
|
||
return ( | ||
<div className="p-0 py-1 h-full w-full" {...attributes} contentEditable={false}> | ||
<div className="grid gap-2"> | ||
<label | ||
htmlFor={`${element.id}-uploader`} | ||
className="aspect-square w-full rounded-md object-cover cursor-pointer relative" | ||
onClick={(e) => e.stopPropagation()} | ||
> | ||
<input | ||
id={`${element.id}-uploader`} | ||
onChange={onUploadFile} | ||
type="file" | ||
className="hidden opacity-0" | ||
multiple={false} | ||
disabled={readOnly} | ||
accept="image/*" | ||
/> | ||
{element.props.src ? ( | ||
<> | ||
<img | ||
alt={`${element.id} image`} | ||
loading="lazy" | ||
width="100%" | ||
height="100%" | ||
decoding="async" | ||
data-nimg="1" | ||
className="aspect-square w-full rounded-md object-cover" | ||
src={element.props.src} | ||
/> | ||
{!readOnly && ( | ||
<button onClick={onDeleteImage} className="absolute top-1 right-1 z-10" type="button"> | ||
<Trash2 size={20} color="red" /> | ||
</button> | ||
)} | ||
</> | ||
) : ( | ||
<div className="aspect-square w-full h-full rounded-md bg-gray-200 relative"> | ||
<ImageIcon size={30} className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" /> | ||
</div> | ||
)} | ||
</label> | ||
</div> | ||
{children} | ||
</div> | ||
); | ||
}; | ||
|
||
export { CarouselItemImage }; |
11 changes: 11 additions & 0 deletions
11
...components/examples/withCustomPlugin/customPlugins/Carousel/renders/CarouselItemTitle.tsx
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,11 @@ | ||
import { PluginElementRenderProps } from '@yoopta/editor'; | ||
|
||
const CarouselItemTitle = (props: PluginElementRenderProps) => { | ||
return ( | ||
<h4 {...props.attributes} className="w-full font-semibold leading-none tracking-tight my-[8px]"> | ||
{props.children} | ||
</h4> | ||
); | ||
}; | ||
|
||
export { CarouselItemTitle }; |
25 changes: 25 additions & 0 deletions
25
web/next-example/src/components/examples/withCustomPlugin/customPlugins/Divider/index.tsx
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,25 @@ | ||
import { YooptaPlugin } from '@yoopta/editor'; | ||
import { SeparatorHorizontal } from 'lucide-react'; | ||
import { DividerRenderElement } from './renders/Divider'; | ||
|
||
const DividerPlugin = new YooptaPlugin({ | ||
type: 'Divider', | ||
elements: { | ||
divider: { | ||
render: DividerRenderElement, | ||
props: { | ||
nodeType: 'void', | ||
}, | ||
}, | ||
}, | ||
options: { | ||
shortcuts: ['--', '---'], | ||
display: { | ||
title: 'New Divider Plugin', | ||
description: 'Separate', | ||
icon: <SeparatorHorizontal />, | ||
}, | ||
}, | ||
}); | ||
|
||
export { DividerPlugin }; |
12 changes: 12 additions & 0 deletions
12
...xample/src/components/examples/withCustomPlugin/customPlugins/Divider/renders/Divider.tsx
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,12 @@ | ||
import { PluginElementRenderProps } from '@yoopta/editor'; | ||
|
||
const DividerRenderElement = ({ attributes, children, element, blockId }: PluginElementRenderProps) => { | ||
return ( | ||
<div {...attributes} className="w-full flex relative items-center h-[14px] my-1" contentEditable={false}> | ||
<hr className="absolute w-full" /> | ||
{children} | ||
</div> | ||
); | ||
}; | ||
|
||
export { DividerRenderElement }; |
Oops, something went wrong.