mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-04-26 07:47:48 +00:00
Compare commits
3 Commits
ff835d677c
...
e489438c57
| Author | SHA1 | Date | |
|---|---|---|---|
| e489438c57 | |||
| 8b47bba822 | |||
| 212456e5c2 |
46
package-lock.json
generated
46
package-lock.json
generated
@ -11,8 +11,11 @@
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@tanstack/react-query": "^5.17.8",
|
||||
"@tiptap/core": "^2.14.0",
|
||||
"@tiptap/extension-bubble-menu": "^2.14.0",
|
||||
"@tiptap/extension-color": "^2.12.0",
|
||||
"@tiptap/extension-image": "^2.12.0",
|
||||
"@tiptap/extension-image": "^2.14.0",
|
||||
"@tiptap/extension-link": "^2.14.0",
|
||||
"@tiptap/extension-placeholder": "^2.14.0",
|
||||
"@tiptap/extension-youtube": "^2.12.0",
|
||||
"@tiptap/pm": "^2.12.0",
|
||||
@ -2371,9 +2374,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/core": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.12.0.tgz",
|
||||
"integrity": "sha512-3qX8oGVKFFZzQ0vit+ZolR6AJIATBzmEmjAA0llFhWk4vf3v64p1YcXcJsOBsr5scizJu5L6RYWEFatFwqckRg==",
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.14.0.tgz",
|
||||
"integrity": "sha512-MBSMzGYRFlwYCocvx3dU7zpCBSDQ0qWByNtStaEzuBUgzCJ6wn2DP/xG0cMcLmE3Ia0VLM4nwbLOAAvBXOtylA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
@ -2410,9 +2413,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bubble-menu": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.12.0.tgz",
|
||||
"integrity": "sha512-DYijoE0igV0Oi+ZppFsp2UrQsM/4HZtmmpD78BJM9zfCbd1YvAUIxmzmXr8uqU18OHd1uQy+/zvuNoUNYyw67g==",
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.14.0.tgz",
|
||||
"integrity": "sha512-sN15n0RjPh+2Asvxs7l47hVEvX6c0aPempU8QQWcPUlHoGf1D/XkyHXy6GWVPSxZ5Rj5uAwgKvhHsG/FJ/YGKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tippy.js": "^6.3.7"
|
||||
@ -2593,9 +2596,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-image": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.12.0.tgz",
|
||||
"integrity": "sha512-wO+yrfMlnW3SYCb1Q1qAb+nt5WH6jnlQPTV6qdoIabRtW0puwMWULZDUgclPN5hxn8EXb9vBEu44egvH6hgkfQ==",
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.14.0.tgz",
|
||||
"integrity": "sha512-pYCUzZBgsxIvVGTzuW03cPz6PIrAo26xpoxqq4W090uMVoK0SgY5W5y0IqCdw4QyLkJ2/oNSFNc2EP9jVi1CcQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
@ -2618,6 +2621,23 @@
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-link": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.14.0.tgz",
|
||||
"integrity": "sha512-fsqW7eRD2xoD6xy7eFrNPAdIuZ3eicA4jKC45Vcft/Xky0DJoIehlVBLxsPbfmv3f27EBrtPkg5+msLXkLyzJA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"linkifyjs": "^4.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list-item": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.12.0.tgz",
|
||||
@ -8378,6 +8398,12 @@
|
||||
"uc.micro": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/linkifyjs": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.1.tgz",
|
||||
"integrity": "sha512-DRSlB9DKVW04c4SUdGvKK5FR6be45lTU9M76JnngqPeeGDqPwYc0zdUErtsNVMtxPXgUWV4HbXbnC4sNyBxkYg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/listr2": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz",
|
||||
|
||||
@ -99,8 +99,11 @@
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@tanstack/react-query": "^5.17.8",
|
||||
"@tiptap/core": "^2.14.0",
|
||||
"@tiptap/extension-bubble-menu": "^2.14.0",
|
||||
"@tiptap/extension-color": "^2.12.0",
|
||||
"@tiptap/extension-image": "^2.12.0",
|
||||
"@tiptap/extension-image": "^2.14.0",
|
||||
"@tiptap/extension-link": "^2.14.0",
|
||||
"@tiptap/extension-placeholder": "^2.14.0",
|
||||
"@tiptap/extension-youtube": "^2.12.0",
|
||||
"@tiptap/pm": "^2.12.0",
|
||||
|
||||
@ -13,7 +13,7 @@ const ComboBoxInput = ({ id, options, value, onValueChange }: ComboBoxProps) =>
|
||||
return (
|
||||
<select
|
||||
id={id}
|
||||
className='tw:select'
|
||||
className='tw:select tw:w-full'
|
||||
onChange={handleChange}
|
||||
value={value} // ← hier controlled statt defaultValue
|
||||
>
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import { Image } from '@tiptap/extension-image'
|
||||
import { Link } from '@tiptap/extension-link'
|
||||
import { Placeholder } from '@tiptap/extension-placeholder'
|
||||
import { Youtube } from '@tiptap/extension-youtube'
|
||||
import { EditorContent, useEditor } from '@tiptap/react'
|
||||
import { StarterKit } from '@tiptap/starter-kit'
|
||||
import { useEffect } from 'react'
|
||||
@ -18,8 +18,7 @@ interface RichTextEditorProps {
|
||||
containerStyle?: string
|
||||
defaultValue: string
|
||||
placeholder?: string
|
||||
required?: boolean
|
||||
size?: string
|
||||
showMenu?: boolean
|
||||
updateFormValue?: (value: string) => void
|
||||
}
|
||||
|
||||
@ -32,10 +31,14 @@ export function RichTextEditor({
|
||||
containerStyle,
|
||||
defaultValue,
|
||||
placeholder,
|
||||
showMenu = true,
|
||||
updateFormValue,
|
||||
}: RichTextEditorProps) {
|
||||
const handleChange = () => {
|
||||
const newValue: string | undefined = editor?.storage.markdown.getMarkdown()
|
||||
let newValue: string | undefined = editor?.storage.markdown.getMarkdown()
|
||||
|
||||
const regex = /!\[.*?\]\(.*?\)/g
|
||||
newValue = newValue?.replace(regex, (match: string) => match + '\n\n')
|
||||
if (updateFormValue && newValue) {
|
||||
updateFormValue(newValue)
|
||||
}
|
||||
@ -54,12 +57,13 @@ export function RichTextEditor({
|
||||
keepAttributes: false,
|
||||
},
|
||||
}),
|
||||
Markdown,
|
||||
Image,
|
||||
Youtube.configure({
|
||||
controls: false,
|
||||
nocookie: true,
|
||||
Markdown.configure({
|
||||
linkify: true,
|
||||
transformCopiedText: true,
|
||||
transformPastedText: true,
|
||||
}),
|
||||
Image,
|
||||
Link,
|
||||
Placeholder.configure({
|
||||
placeholder,
|
||||
emptyEditorClass: 'is-editor-empty',
|
||||
@ -96,7 +100,7 @@ export function RichTextEditor({
|
||||
>
|
||||
{editor ? (
|
||||
<>
|
||||
<TextEditorMenu editor={editor} />
|
||||
{showMenu ? <TextEditorMenu editor={editor} /> : null}
|
||||
<EditorContent editor={editor} />
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@ -31,6 +31,7 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
isHeading4: ctx.editor.isActive('heading', { level: 4 }),
|
||||
isHeading5: ctx.editor.isActive('heading', { level: 5 }),
|
||||
isHeading6: ctx.editor.isActive('heading', { level: 6 }),
|
||||
isHeading: ctx.editor.isActive('heading'),
|
||||
isBulletList: ctx.editor.isActive('bulletList'),
|
||||
isOrderedList: ctx.editor.isActive('orderedList'),
|
||||
isCodeBlock: ctx.editor.isActive('codeBlock'),
|
||||
@ -45,30 +46,12 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
<>
|
||||
<ul
|
||||
className={
|
||||
'tw:menu tw:p-1 tw:menu-horizontal tw:flex-nowrap tw:overflow-x-hidden tw:flex-none tw:bg-base-200 tw:rounded-box tw:w-full tw:rounded-b-none'
|
||||
'tw:menu tw:overflow-x-hidden tw:@sm:overflow-visible tw:menu-horizontal tw:flex-nowrap tw:flex-none tw:bg-base-200 tw:rounded-box tw:w-full tw:rounded-b-none'
|
||||
}
|
||||
>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isBold ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Bold'
|
||||
onClick={() => editor.chain().focus().toggleBold().run()}
|
||||
>
|
||||
<BoldIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isItalic ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Italic'
|
||||
onClick={() => editor.chain().focus().toggleItalic().run()}
|
||||
>
|
||||
<ItalicIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isHeading1 ? 'tw:bg-base-content/10' : ''}`}
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isHeading1 ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Heading 1'
|
||||
onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
|
||||
>
|
||||
@ -77,7 +60,7 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isHeading2 ? 'tw:bg-base-content/10' : ''}`}
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isHeading2 ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Heading 2'
|
||||
onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
|
||||
>
|
||||
@ -86,17 +69,40 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isHeading3 ? 'tw:bg-base-content/10' : ''}`}
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isHeading3 ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Heading 3'
|
||||
onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
|
||||
>
|
||||
<H3Icon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div className='tw:w-[1px] tw:p-0 tw:mx-1 tw:bg-base-content/10 tw:my-1' />
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isBulletList ? 'tw:bg-base-content/10' : ''}`}
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isBold ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Bold'
|
||||
onClick={() => editor.chain().focus().toggleBold().run()}
|
||||
>
|
||||
<BoldIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isItalic ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Italic'
|
||||
onClick={() => editor.chain().focus().toggleItalic().run()}
|
||||
>
|
||||
<ItalicIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div className='tw:w-[1px] tw:p-0 tw:mx-1 tw:bg-base-content/10 tw:my-1' />
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isBulletList ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='List'
|
||||
onClick={() => editor.chain().focus().toggleBulletList().run()}
|
||||
>
|
||||
@ -105,16 +111,24 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isOrderedList ? 'tw:bg-base-content/10' : ''}`}
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isOrderedList ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='List'
|
||||
onClick={() => editor.chain().focus().toggleOrderedList().run()}
|
||||
>
|
||||
<NumberedListIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div className='tw:w-[1px] tw:p-0 tw:mx-1 tw:bg-base-content/10 tw:my-1' />
|
||||
</li>
|
||||
{/* <li>
|
||||
<div className='tw:@sm:tooltip tw:px-1.5 tw:mx-0.5' data-tip='Image' onClick={addImage}>
|
||||
<PhotoIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li> */}
|
||||
<li>
|
||||
<div
|
||||
className='tw:tooltip tw:px-1'
|
||||
className='tw:@sm:tooltip tw:px-1'
|
||||
data-tip='Horizontal Line'
|
||||
onClick={() => editor.chain().focus().setHorizontalRule().run()}
|
||||
>
|
||||
@ -124,7 +138,7 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
<div className='tw:flex-grow'></div>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1.5 tw:mx-0.5 tw:hidden tw:sm:block tw:md:hidden tw:lg:block ${editorState.canUndo ? '' : 'tw:opacity-50'}`}
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 tw:hidden tw:@sm:block ${editorState.canUndo ? '' : 'tw:opacity-50'}`}
|
||||
data-tip='Undo'
|
||||
onClick={() => editor.chain().focus().undo().run()}
|
||||
>
|
||||
@ -133,7 +147,7 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1.5 tw:mx-0.5 tw:hidden tw:sm:block tw:md:hidden tw:lg:block ${editorState.canRedo ? '' : 'tw:opacity-50'}`}
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 tw:hidden tw:@sm:block ${editorState.canRedo ? '' : 'tw:opacity-50'}`}
|
||||
data-tip='Redo'
|
||||
onClick={() => editor.chain().focus().redo().run()}
|
||||
>
|
||||
@ -141,13 +155,6 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
{/** <div className='control-group tiptap-toolbar'>
|
||||
<div className='button-group'>
|
||||
<button id='add' className='btn btn-sm' onClick={addYoutubeVideo}>
|
||||
Add YouTube video
|
||||
</button>
|
||||
</div>
|
||||
</div> */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
exports[`<ComboBoxInput /> > renders properly 1`] = `
|
||||
<select
|
||||
class="tw:select"
|
||||
class="tw:select tw:w-full"
|
||||
>
|
||||
<option
|
||||
value="Option 1"
|
||||
|
||||
@ -53,22 +53,6 @@ export const TextView = ({
|
||||
|
||||
if (innerText) replacedText = fixUrls(innerText)
|
||||
|
||||
if (replacedText) {
|
||||
replacedText = replacedText.replace(/(?<!\]?\()https?:\/\/[^\s)]+(?!\))/g, (url) => {
|
||||
let shortUrl = url
|
||||
|
||||
if (url.match('^https://')) {
|
||||
shortUrl = url.split('https://')[1]
|
||||
}
|
||||
|
||||
if (url.match('^http://')) {
|
||||
shortUrl = url.split('http://')[1]
|
||||
}
|
||||
|
||||
return `[${shortUrl}](${url})`
|
||||
})
|
||||
}
|
||||
|
||||
if (replacedText) {
|
||||
replacedText = replacedText.replace(mailRegex, (url) => {
|
||||
return `[${url}](mailto:${url})`
|
||||
|
||||
@ -158,7 +158,7 @@ export function ProfileForm() {
|
||||
<>
|
||||
<MapOverlayPage
|
||||
backdrop
|
||||
className='tw:mx-4 tw:mt-4 tw:mb-4 tw:overflow-x-hidden tw:w-[calc(100%-32px)] tw:md:w-[calc(50%-32px)] tw:max-w-3xl tw:left-auto! tw:top-0 tw:bottom-0 tw:flex tw:flex-col tw:max-h-[calc(1000px)]'
|
||||
className='tw:mx-4 tw:mt-4 tw:mb-4 tw:@container tw:overflow-x-hidden tw:w-[calc(100%-32px)] tw:md:w-[calc(50%-32px)] tw:max-w-3xl tw:left-auto! tw:top-0 tw:bottom-0 tw:flex tw:flex-col'
|
||||
>
|
||||
<form
|
||||
className='tw:flex tw:flex-col tw:flex-1 tw:min-h-0'
|
||||
|
||||
@ -51,7 +51,7 @@ export const GroupSubheaderForm = ({
|
||||
}, [state.group_type, groupTypes])
|
||||
|
||||
return (
|
||||
<div className='tw:grid tw:grid-cols-1 tw:md:grid-cols-2 tw:gap-2'>
|
||||
<div className='tw:grid tw:grid-cols-1 tw:@sm:grid-cols-2 tw:gap-2'>
|
||||
<div>
|
||||
<label
|
||||
htmlFor='status'
|
||||
|
||||
@ -18,7 +18,6 @@ export const ProfileTextForm = ({
|
||||
heading,
|
||||
size,
|
||||
hideInputLabel,
|
||||
required,
|
||||
}: {
|
||||
state: FormState
|
||||
setState: React.Dispatch<React.SetStateAction<any>>
|
||||
@ -26,7 +25,6 @@ export const ProfileTextForm = ({
|
||||
heading: string
|
||||
size: string
|
||||
hideInputLabel: boolean
|
||||
required?: boolean
|
||||
}) => {
|
||||
const [field, setField] = useState<string>(dataField || 'text')
|
||||
|
||||
@ -38,7 +36,7 @@ export const ProfileTextForm = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`tw:min-h-36 tw:max-h-156 tw:flex tw:flex-col tw:mt-2 ${size === 'full' ? 'tw:flex-1' : 'tw:h-36 tw:flex-none'}`}
|
||||
className={`tw:max-h-124 tw:md:max-h-full tw:flex tw:flex-col tw:mt-2 ${size === 'full' ? 'tw:flex-1 tw:min-h-42' : 'tw:h-28 tw:flex-none'}`}
|
||||
>
|
||||
<div className='tw:flex tw:justify-between tw:items-center'>
|
||||
<label
|
||||
@ -59,9 +57,9 @@ export const ProfileTextForm = ({
|
||||
[field]: v,
|
||||
}))
|
||||
}
|
||||
showMenu={size === 'full'}
|
||||
labelStyle={hideInputLabel ? 'tw:hidden' : ''}
|
||||
containerStyle={size === 'full' ? 'tw:flex-1' : 'tw:h-32 tw:flex-none'}
|
||||
required={required}
|
||||
containerStyle={size === 'full' ? 'tw:flex-1' : 'tw:h-24 tw:flex-none'}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -85,7 +85,7 @@ export const TabsForm = ({
|
||||
}))
|
||||
}
|
||||
containerStyle='tw:pt-2 tw:h-36 tw:flex-none'
|
||||
required={false}
|
||||
showMenu={false}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
|
||||
@ -14,3 +14,30 @@
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Bubble menu */
|
||||
.bubble-menu {
|
||||
background-color: var(--color-base-100);
|
||||
border: 1px solid var(--color-base-200);
|
||||
border-radius: 0.7rem;
|
||||
box-shadow: var(--shadow);
|
||||
display: flex;
|
||||
padding: 0.2rem;
|
||||
|
||||
button {
|
||||
background-color: unset;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-base-300);
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: var(--color-base-200);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-base-300);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user