mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-03-01 12:44:17 +00:00
optimizing flex layout & styling inputs
This commit is contained in:
parent
758730b523
commit
47322f277a
@ -1,3 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import { Image } from '@tiptap/extension-image'
|
||||
import { Placeholder } from '@tiptap/extension-placeholder'
|
||||
@ -29,11 +32,8 @@ export function RichTextEditor({
|
||||
containerStyle,
|
||||
defaultValue,
|
||||
placeholder,
|
||||
required = true,
|
||||
updateFormValue,
|
||||
}: RichTextEditorProps) {
|
||||
console.log(placeholder, required)
|
||||
|
||||
const handleChange = () => {
|
||||
const newValue: string | undefined = editor?.storage.markdown.getMarkdown()
|
||||
if (updateFormValue && newValue) {
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import BoldIcon from '@heroicons/react/24/solid/BoldIcon'
|
||||
import CodeBracketIcon from '@heroicons/react/24/solid/CodeBracketIcon'
|
||||
import H1Icon from '@heroicons/react/24/solid/H1Icon'
|
||||
import H2Icon from '@heroicons/react/24/solid/H2Icon'
|
||||
import H3Icon from '@heroicons/react/24/solid/H3Icon'
|
||||
@ -7,9 +6,7 @@ import ItalicIcon from '@heroicons/react/24/solid/ItalicIcon'
|
||||
import ListBulletIcon from '@heroicons/react/24/solid/ListBulletIcon'
|
||||
import NumberedListIcon from '@heroicons/react/24/solid/NumberedListIcon'
|
||||
import { useEditorState } from '@tiptap/react'
|
||||
import { FaQuoteLeft } from 'react-icons/fa6'
|
||||
import { MdUndo, MdRedo, MdHorizontalRule } from 'react-icons/md'
|
||||
import { LiaTextHeightSolid } from 'react-icons/lia'
|
||||
|
||||
import type { Editor } from '@tiptap/react'
|
||||
|
||||
@ -44,42 +41,16 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
},
|
||||
})
|
||||
|
||||
const addYoutubeVideo = () => {
|
||||
const url = prompt('Enter YouTube URL')
|
||||
|
||||
if (url) {
|
||||
editor.commands.setYoutubeVideo({
|
||||
src: url,
|
||||
width: Math.max(320) || 640,
|
||||
height: Math.max(180) || 480,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ul className='tw:menu tw:p-1 tw:menu-horizontal tw:flex-none tw:bg-base-200 tw:rounded-box tw:w-full tw:rounded-b-none'>
|
||||
<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'
|
||||
}
|
||||
>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1 ${editorState.canUndo ? '' : 'tw:opacity-50'}`}
|
||||
data-tip='Undo'
|
||||
onClick={() => editor.chain().focus().undo().run()}
|
||||
>
|
||||
<MdUndo className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1 ${editorState.canRedo ? '' : 'tw:opacity-50'}`}
|
||||
data-tip='Redo'
|
||||
onClick={() => editor.chain().focus().redo().run()}
|
||||
>
|
||||
<MdRedo className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1 ${editorState.isBold ? 'tw:bg-base-content/10' : ''}`}
|
||||
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()}
|
||||
>
|
||||
@ -88,7 +59,7 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1 ${editorState.isItalic ? 'tw:bg-base-content/10' : ''}`}
|
||||
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()}
|
||||
>
|
||||
@ -96,45 +67,36 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<details className='tw:z-10000'>
|
||||
<summary>
|
||||
<LiaTextHeightSolid className='tw:w-5 tw:h-5' />
|
||||
</summary>
|
||||
<ul>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1 ${editorState.isHeading1 ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Heading 1'
|
||||
onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
|
||||
>
|
||||
<H1Icon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1 ${editorState.isHeading2 ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Heading 2'
|
||||
onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
|
||||
>
|
||||
<H2Icon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1 ${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>
|
||||
</ul>
|
||||
</details>
|
||||
<div
|
||||
className={`tw: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()}
|
||||
>
|
||||
<H1Icon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw: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()}
|
||||
>
|
||||
<H2Icon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw: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:tooltip tw:px-1 ${editorState.isBulletList ? 'tw:bg-base-content/10' : ''}`}
|
||||
className={`tw: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()}
|
||||
>
|
||||
@ -143,22 +105,13 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:tooltip tw:px-1 ${editorState.isOrderedList ? 'tw:bg-base-content/10' : ''}`}
|
||||
className={`tw: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:tooltip tw:px-1 ${editorState.isBlockquote ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Quote'
|
||||
onClick={() => editor.chain().focus().toggleBlockquote().run()}
|
||||
>
|
||||
<FaQuoteLeft className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className='tw:tooltip tw:px-1'
|
||||
@ -168,6 +121,25 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
<MdHorizontalRule className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<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'}`}
|
||||
data-tip='Undo'
|
||||
onClick={() => editor.chain().focus().undo().run()}
|
||||
>
|
||||
<MdUndo className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</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'}`}
|
||||
data-tip='Redo'
|
||||
onClick={() => editor.chain().focus().redo().run()}
|
||||
>
|
||||
<MdRedo className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
{/** <div className='control-group tiptap-toolbar'>
|
||||
<div className='button-group'>
|
||||
|
||||
@ -6,6 +6,7 @@ import type { Item } from '#types/Item'
|
||||
export interface StartEndInputProps {
|
||||
item?: Item
|
||||
showLabels?: boolean
|
||||
labelStyle?: string
|
||||
updateStartValue?: (value: string) => void
|
||||
updateEndValue?: (value: string) => void
|
||||
}
|
||||
@ -16,6 +17,7 @@ export interface StartEndInputProps {
|
||||
export const PopupStartEndInput = ({
|
||||
item,
|
||||
showLabels = true,
|
||||
labelStyle,
|
||||
updateStartValue,
|
||||
updateEndValue,
|
||||
}: StartEndInputProps) => {
|
||||
@ -27,6 +29,7 @@ export const PopupStartEndInput = ({
|
||||
dataField='start'
|
||||
inputStyle='tw:text-sm tw:px-2'
|
||||
labelTitle={showLabels ? 'Start' : ''}
|
||||
labelStyle={labelStyle}
|
||||
defaultValue={item && item.start ? item.start.substring(0, 10) : ''}
|
||||
autocomplete='one-time-code'
|
||||
updateFormValue={updateStartValue}
|
||||
@ -37,6 +40,7 @@ export const PopupStartEndInput = ({
|
||||
dataField='end'
|
||||
inputStyle='tw:text-sm tw:px-2'
|
||||
labelTitle={showLabels ? 'End' : ''}
|
||||
labelStyle={labelStyle}
|
||||
defaultValue={item && item.end ? item.end.substring(0, 10) : ''}
|
||||
autocomplete='one-time-code'
|
||||
updateFormValue={updateEndValue}
|
||||
|
||||
@ -178,7 +178,7 @@ export function ProfileForm() {
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div className='tw:flex tw:flex-col tw:flex-1'>
|
||||
<div className='tw:flex tw:flex-col tw:flex-1 pb-4'>
|
||||
<FormHeader item={item} state={state} setState={setState} />
|
||||
|
||||
{template === 'onepager' && (
|
||||
@ -204,7 +204,7 @@ export function ProfileForm() {
|
||||
></TabsForm>
|
||||
)}
|
||||
|
||||
<div className='tw:mt-6 tw:flex-none'>
|
||||
<div className='tw:mb-4 tw:mt-6 tw:flex-none'>
|
||||
<button
|
||||
className={`${loading ? ' tw:loading tw:btn tw:float-right' : 'tw:btn tw:float-right'}`}
|
||||
type='submit'
|
||||
|
||||
@ -43,7 +43,7 @@ export const ProfileTextForm = ({
|
||||
<div className='tw:flex tw:justify-between tw:items-center'>
|
||||
<label
|
||||
htmlFor='nextAppointment'
|
||||
className='tw:block tw:text-sm tw:font-medium tw:text-gray-500 tw:mb-1'
|
||||
className='tw:block tw:text-sm tw:font-medium tw:text-base-content/50 tw:mb-1'
|
||||
>
|
||||
{heading || 'Text'}:
|
||||
</label>
|
||||
|
||||
@ -44,6 +44,7 @@ export const TabsForm = ({
|
||||
<PopupStartEndInput
|
||||
item={item}
|
||||
showLabels={true}
|
||||
labelStyle={'tw:text-base-content/50'}
|
||||
updateEndValue={(e) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
@ -61,6 +62,7 @@ export const TabsForm = ({
|
||||
|
||||
<RichTextEditor
|
||||
labelTitle='About'
|
||||
labelStyle={'tw:text-base-content/50'}
|
||||
placeholder='about ...'
|
||||
defaultValue={item?.text ? item.text : ''}
|
||||
updateFormValue={(v) =>
|
||||
@ -73,6 +75,7 @@ export const TabsForm = ({
|
||||
/>
|
||||
<RichTextEditor
|
||||
labelTitle='Contact Info'
|
||||
labelStyle={'tw:text-base-content/50'}
|
||||
placeholder='contact info ...'
|
||||
defaultValue={state.contact || ''}
|
||||
updateFormValue={(c) =>
|
||||
|
||||
@ -43,7 +43,7 @@ export const TabsView = ({
|
||||
unlinkItem: (id: string) => Promise<void>
|
||||
}) => {
|
||||
const addFilterTag = useAddFilterTag()
|
||||
const [activeTab, setActiveTab] = useState<number>()
|
||||
const [activeTab, setActiveTab] = useState<number>(0)
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [addItemPopupType] = useState<string>('')
|
||||
@ -80,7 +80,7 @@ export const TabsView = ({
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search)
|
||||
const urlTab = params.get('tab')
|
||||
setActiveTab(urlTab ? Number(urlTab) : 1)
|
||||
setActiveTab(urlTab ? Number(urlTab) : 0)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [location.search])
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ export const Tabs: React.FC<TabsProps> = ({ items, setUrlParams }: TabsProps) =>
|
||||
|
||||
navigate(newUrl, { replace: false })
|
||||
},
|
||||
[location, navigate],
|
||||
[location.pathname, location.search, navigate, setUrlParams],
|
||||
)
|
||||
|
||||
return (
|
||||
|
||||
@ -20,9 +20,10 @@
|
||||
}
|
||||
|
||||
.tiptap p.is-editor-empty:first-child::before {
|
||||
color: #adb5bd;
|
||||
color: var(--color-base-content);
|
||||
opacity: 0.5;
|
||||
content: attr(data-placeholder);
|
||||
float: left;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user