fix(lib): fix labels (#278)

* fix labels

* more lables

* and the rest of the lables

* updated snapshots

* fix linting
This commit is contained in:
Anton Tranelis 2025-07-04 08:36:11 +02:00 committed by GitHub
parent 045ec726eb
commit 12aba6a67e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 268 additions and 266 deletions

View File

@ -0,0 +1,9 @@
export const InputLabel = ({ label }: { label: string }) => {
return (
<label className='tw:label tw:pb-1'>
<span className='tw:block tw:text-sm tw:font-medium tw:text-base-content/50 tw:mb-1'>
{label}:
</span>
</label>
)
}

View File

@ -10,6 +10,7 @@ import { StarterKit } from '@tiptap/starter-kit'
import { useEffect } from 'react' import { useEffect } from 'react'
import { Markdown } from 'tiptap-markdown' import { Markdown } from 'tiptap-markdown'
import { InputLabel } from './InputLabel'
import { TextEditorMenu } from './TextEditorMenu' import { TextEditorMenu } from './TextEditorMenu'
interface RichTextEditorProps { interface RichTextEditorProps {
@ -27,7 +28,6 @@ interface RichTextEditorProps {
*/ */
export function RichTextEditor({ export function RichTextEditor({
labelTitle, labelTitle,
labelStyle,
containerStyle, containerStyle,
defaultValue, defaultValue,
placeholder, placeholder,
@ -88,13 +88,7 @@ export function RichTextEditor({
<div <div
className={`tw:form-control tw:w-full tw:flex tw:flex-col tw:min-h-0 ${containerStyle ?? ''}`} className={`tw:form-control tw:w-full tw:flex tw:flex-col tw:min-h-0 ${containerStyle ?? ''}`}
> >
{labelTitle ? ( {labelTitle ? <InputLabel label={labelTitle} /> : null}
<label className='tw:label tw:pb-1'>
<span className={`tw:label-text tw:text-base-content ${labelStyle ?? ''}`}>
{labelTitle}
</span>
</label>
) : null}
<div <div
className={`editor-wrapper tw:border-base-content/20 tw:rounded-box tw:border tw:flex tw:flex-col tw:flex-1 tw:min-h-0`} className={`editor-wrapper tw:border-base-content/20 tw:rounded-box tw:border tw:flex tw:flex-col tw:flex-1 tw:min-h-0`}
> >

View File

@ -1,8 +1,9 @@
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import { InputLabel } from './InputLabel'
interface TextAreaProps { interface TextAreaProps {
labelTitle?: string labelTitle?: string
labelStyle?: string
containerStyle?: string containerStyle?: string
dataField?: string dataField?: string
inputStyle?: string inputStyle?: string
@ -18,7 +19,6 @@ interface TextAreaProps {
export function TextAreaInput({ export function TextAreaInput({
labelTitle, labelTitle,
dataField, dataField,
labelStyle,
containerStyle, containerStyle,
inputStyle, inputStyle,
defaultValue, defaultValue,
@ -43,13 +43,7 @@ export function TextAreaInput({
return ( return (
<div className={`tw:form-control tw:w-full ${containerStyle ?? ''}`}> <div className={`tw:form-control tw:w-full ${containerStyle ?? ''}`}>
{labelTitle ? ( {labelTitle ? <InputLabel label={labelTitle} /> : null}
<label className='tw:label'>
<span className={`tw:label-text tw:text-base-content ${labelStyle ?? ''}`}>
{labelTitle}
</span>
</label>
) : null}
<textarea <textarea
required={required} required={required}
ref={ref} ref={ref}

View File

@ -1,8 +1,9 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { InputLabel } from './InputLabel'
interface InputTextProps { interface InputTextProps {
labelTitle?: string labelTitle?: string
labelStyle?: string
type?: string type?: string
dataField?: string dataField?: string
containerStyle?: string containerStyle?: string
@ -20,7 +21,6 @@ interface InputTextProps {
*/ */
export function TextInput({ export function TextInput({
labelTitle, labelTitle,
labelStyle,
type, type,
dataField, dataField,
containerStyle, containerStyle,
@ -48,13 +48,7 @@ export function TextInput({
return ( return (
<div className={`tw:form-control ${containerStyle ?? ''}`}> <div className={`tw:form-control ${containerStyle ?? ''}`}>
{labelTitle ? ( {labelTitle ? <InputLabel label={labelTitle} /> : null}
<label className='tw:label'>
<span className={`tw:label-text tw:text-base-content ${labelStyle ?? ''}`}>
{labelTitle}
</span>
</label>
) : null}
<input <input
required={required} required={required}
pattern={pattern} pattern={pattern}

View File

@ -5,12 +5,13 @@ exports[`<TextAreaInput /> > labelTitle > sets label 1`] = `
class="tw:form-control tw:w-full " class="tw:form-control tw:w-full "
> >
<label <label
class="tw:label" class="tw:label tw:pb-1"
> >
<span <span
class="tw:label-text tw:text-base-content " class="tw:block tw:text-sm tw:font-medium tw:text-base-content/50 tw:mb-1"
> >
My Title My Title
:
</span> </span>
</label> </label>
<textarea <textarea

View File

@ -5,12 +5,13 @@ exports[`<TextInput /> > labelTitle > sets label 1`] = `
class="tw:form-control " class="tw:form-control "
> >
<label <label
class="tw:label" class="tw:label tw:pb-1"
> >
<span <span
class="tw:label-text tw:text-base-content " class="tw:block tw:text-sm tw:font-medium tw:text-base-content/50 tw:mb-1"
> >
My Title My Title
:
</span> </span>
</label> </label>
<input <input

View File

@ -1,2 +1,4 @@
export { TextAreaInput } from './TextAreaInput' export { TextAreaInput } from './TextAreaInput'
export { TextInput } from './TextInput' export { TextInput } from './TextInput'
export { InputLabel } from './InputLabel'
export { RichTextEditor } from './RichTextEditor'

View File

@ -6,7 +6,6 @@ import type { Item } from '#types/Item'
export interface StartEndInputProps { export interface StartEndInputProps {
item?: Item item?: Item
showLabels?: boolean showLabels?: boolean
labelStyle?: string
updateStartValue?: (value: string) => void updateStartValue?: (value: string) => void
updateEndValue?: (value: string) => void updateEndValue?: (value: string) => void
containerStyle?: string containerStyle?: string
@ -18,7 +17,6 @@ export interface StartEndInputProps {
export const PopupStartEndInput = ({ export const PopupStartEndInput = ({
item, item,
showLabels = true, showLabels = true,
labelStyle,
updateStartValue, updateStartValue,
updateEndValue, updateEndValue,
containerStyle, containerStyle,
@ -31,7 +29,6 @@ export const PopupStartEndInput = ({
dataField='start' dataField='start'
inputStyle='tw:text-sm tw:px-2' inputStyle='tw:text-sm tw:px-2'
labelTitle={showLabels ? 'Start' : ''} labelTitle={showLabels ? 'Start' : ''}
labelStyle={labelStyle}
defaultValue={item && item.start ? item.start.substring(0, 10) : ''} defaultValue={item && item.start ? item.start.substring(0, 10) : ''}
autocomplete='one-time-code' autocomplete='one-time-code'
updateFormValue={updateStartValue} updateFormValue={updateStartValue}
@ -42,7 +39,6 @@ export const PopupStartEndInput = ({
dataField='end' dataField='end'
inputStyle='tw:text-sm tw:px-2' inputStyle='tw:text-sm tw:px-2'
labelTitle={showLabels ? 'End' : ''} labelTitle={showLabels ? 'End' : ''}
labelStyle={labelStyle}
defaultValue={item && item.end ? item.end.substring(0, 10) : ''} defaultValue={item && item.end ? item.end.substring(0, 10) : ''}
autocomplete='one-time-code' autocomplete='one-time-code'
updateFormValue={updateEndValue} updateFormValue={updateEndValue}

View File

@ -1,4 +1,4 @@
import { TextInput } from '#components/Input' import { InputLabel, TextInput } from '#components/Input'
import type { FormState } from '#types/FormState' import type { FormState } from '#types/FormState'
@ -12,12 +12,7 @@ export const ContactInfoForm = ({
return ( return (
<div className='tw:mt-2 tw:space-y-2'> <div className='tw:mt-2 tw:space-y-2'>
<div> <div>
<label <InputLabel label='Email-Adresse (Kontakt)' />
htmlFor='email'
className='tw:block tw:text-sm tw:font-medium tw:text-gray-500 tw:mb-1'
>
Email-Adresse (Kontakt):
</label>
<TextInput <TextInput
placeholder='Email' placeholder='Email'
type='email' type='email'
@ -33,12 +28,7 @@ export const ContactInfoForm = ({
</div> </div>
<div> <div>
<label <InputLabel label='Telefonnummer (Kontakt)' />
htmlFor='telephone'
className='tw:block tw:text-sm tw:font-medium tw:text-gray-500 tw:mb-1'
>
Telefonnummer (Kontakt):
</label>
<TextInput <TextInput
placeholder='Telefonnummer' placeholder='Telefonnummer'
type='tel' type='tel'

View File

@ -1,4 +1,4 @@
import { TextInput } from '#components/Input' import { TextInput, InputLabel } from '#components/Input'
import type { FormState } from '#types/FormState' import type { FormState } from '#types/FormState'
@ -12,12 +12,7 @@ export const CrowdfundingForm = ({
return ( return (
<div className='tw:mt-4 tw:space-y-4'> <div className='tw:mt-4 tw:space-y-4'>
<div> <div>
<label <InputLabel label='Open Collective Slug' />
htmlFor='OpenCollectiveSlug'
className='tw:block tw:text-sm tw:font-medium tw:text-gray-500 tw:mb-1'
>
Open Collective Slug:
</label>
<TextInput <TextInput
placeholder='Open Collective Slug' placeholder='Open Collective Slug'
type='text' type='text'

View File

@ -5,6 +5,7 @@ import { useDropzone } from 'react-dropzone'
import { BiSolidImage } from 'react-icons/bi' import { BiSolidImage } from 'react-icons/bi'
import { useAppState } from '#components/AppShell/hooks/useAppState' import { useAppState } from '#components/AppShell/hooks/useAppState'
import { InputLabel } from '#components/Input/InputLabel'
import DialogModal from '#components/Templates/DialogModal' import DialogModal from '#components/Templates/DialogModal'
import { getImageDimensions } from '#utils/getImageDimensions' import { getImageDimensions } from '#utils/getImageDimensions'
@ -13,6 +14,7 @@ import type { FormState } from '#types/FormState'
interface Props { interface Props {
state: FormState state: FormState
setState: React.Dispatch<React.SetStateAction<FormState>> setState: React.Dispatch<React.SetStateAction<FormState>>
hideInputLabel?: boolean
} }
const compressionOptions = { const compressionOptions = {
@ -21,7 +23,7 @@ const compressionOptions = {
useWebWorker: true, useWebWorker: true,
} }
export const GalleryForm = ({ state, setState }: Props) => { export const GalleryForm = ({ state, setState, hideInputLabel = false }: Props) => {
const appState = useAppState() const appState = useAppState()
const [imageSelectedToDelete, setImageSelectedToDelete] = useState<number | null>(null) const [imageSelectedToDelete, setImageSelectedToDelete] = useState<number | null>(null)
@ -96,8 +98,9 @@ export const GalleryForm = ({ state, setState }: Props) => {
} }
return ( return (
<> <div className='tw:mt-3'>
<div className='tw:grid tw:grid-cols-2 tw:@md:grid-cols-3 tw:@lg:grid-cols-4 tw:gap-4 tw:my-4'> {!hideInputLabel && <InputLabel label='Media' />}
<div className='tw:grid tw:grid-cols-2 tw:@md:grid-cols-3 tw:@lg:grid-cols-4 tw:gap-4'>
{images.map((image, index) => ( {images.map((image, index) => (
<div key={index} className='tw:relative'> <div key={index} className='tw:relative'>
<img <img
@ -161,6 +164,6 @@ export const GalleryForm = ({ state, setState }: Props) => {
</div> </div>
</div> </div>
</DialogModal> </DialogModal>
</> </div>
) )
} }

View File

@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
import { useEffect } from 'react' import { useEffect } from 'react'
import { InputLabel } from '#components/Input'
import ComboBoxInput from '#components/Input/ComboBoxInput' import ComboBoxInput from '#components/Input/ComboBoxInput'
import type { FormState } from '#types/FormState' import type { FormState } from '#types/FormState'
@ -51,12 +52,7 @@ export const GroupSubheaderForm = ({
return ( return (
<div className='tw:grid tw:grid-cols-1 tw:@sm:grid-cols-2 tw:gap-2'> <div className='tw:grid tw:grid-cols-1 tw:@sm:grid-cols-2 tw:gap-2'>
<div> <div>
<label <InputLabel label='Gruppenstatus' />
htmlFor='status'
className='tw:block tw:text-sm tw:font-medium tw:text-gray-500 tw:mb-1'
>
Gruppenstatus:
</label>
<ComboBoxInput <ComboBoxInput
id='status' id='status'
options={groupStates || []} options={groupStates || []}
@ -70,12 +66,7 @@ export const GroupSubheaderForm = ({
/> />
</div> </div>
<div> <div>
<label <InputLabel label='Gruppenart' />
htmlFor='groupType'
className='tw:block tw:text-sm tw:font-medium tw:text-gray-500 tw:mb-1'
>
Gruppenart:
</label>
<ComboBoxInput <ComboBoxInput
id='groupType' id='groupType'
options={groupTypes?.map((gt) => gt.groupTypes_id.name) || []} options={groupTypes?.map((gt) => gt.groupTypes_id.name) || []}

View File

@ -4,7 +4,7 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { RichTextEditor } from '#components/Input/RichTextEditor' import { InputLabel, RichTextEditor } from '#components/Input'
import { MarkdownHint } from './MarkdownHint' import { MarkdownHint } from './MarkdownHint'
@ -13,11 +13,9 @@ import type { FormState } from '#types/FormState'
export const ProfileTextForm = ({ export const ProfileTextForm = ({
state, state,
setState, setState,
// Is this really used?
dataField, dataField,
heading, heading,
size, size,
hideInputLabel,
}: { }: {
state: FormState state: FormState
setState: React.Dispatch<React.SetStateAction<FormState>> setState: React.Dispatch<React.SetStateAction<FormState>>
@ -36,15 +34,10 @@ export const ProfileTextForm = ({
return ( return (
<div <div
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'}`} className={`tw:max-h-124 tw:md:max-h-full tw:flex tw:flex-col tw:mt-3 ${size === 'full' ? 'tw:flex-1 tw:min-h-42' : 'tw:h-30 tw:flex-none'}`}
> >
<div className='tw:flex tw:justify-between tw:items-center'> <div className='tw:flex tw:justify-between tw:items-center'>
<label <InputLabel label={heading || 'Text'} />
htmlFor='nextAppointment'
className='tw:block tw:text-sm tw:font-medium tw:text-base-content/50 tw:mb-1'
>
{heading || 'Text'}:
</label>
<MarkdownHint /> <MarkdownHint />
</div> </div>
<RichTextEditor <RichTextEditor
@ -58,7 +51,6 @@ export const ProfileTextForm = ({
})) }))
} }
showMenu={size === 'full'} showMenu={size === 'full'}
labelStyle={hideInputLabel ? 'tw:hidden' : ''}
containerStyle={size === 'full' ? 'tw:flex-1' : 'tw:h-24 tw:flex-none'} containerStyle={size === 'full' ? 'tw:flex-1' : 'tw:h-24 tw:flex-none'}
/> />
</div> </div>

View File

@ -3,99 +3,113 @@
exports[`GalleryForm > with previous images > renders 1`] = ` exports[`GalleryForm > with previous images > renders 1`] = `
<div> <div>
<div <div
class="tw:grid tw:grid-cols-2 tw:@md:grid-cols-3 tw:@lg:grid-cols-4 tw:gap-4 tw:my-4" class="tw:mt-3"
> >
<div <label
class="tw:relative" class="tw:label tw:pb-1"
> >
<img <span
alt="Gallery image 1" class="tw:block tw:text-sm tw:font-medium tw:text-base-content/50 tw:mb-1"
class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg "
src="undefined1.jpg"
/>
<button
class="tw:m-2 tw:bg-red-500 tw:text-white tw:p-2 tw:rounded-full tw:absolute tw:top-0 tw:right-0 tw:hover:bg-red-600 tw:cursor-pointer"
type="button"
> >
<svg Media
aria-hidden="true" :
class="tw:h-5 tw:w-5" </span>
data-slot="icon" </label>
data-testid="trash"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M16.5 4.478v.227a48.816 48.816 0 0 1 3.878.512.75.75 0 1 1-.256 1.478l-.209-.035-1.005 13.07a3 3 0 0 1-2.991 2.77H8.084a3 3 0 0 1-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 0 1-.256-1.478A48.567 48.567 0 0 1 7.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 0 1 3.369 0c1.603.051 2.815 1.387 2.815 2.951Zm-6.136-1.452a51.196 51.196 0 0 1 3.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 0 0-6 0v-.113c0-.794.609-1.428 1.364-1.452Zm-.355 5.945a.75.75 0 1 0-1.5.058l.347 9a.75.75 0 1 0 1.499-.058l-.346-9Zm5.48.058a.75.75 0 1 0-1.498-.058l-.347 9a.75.75 0 0 0 1.5.058l.345-9Z"
fill-rule="evenodd"
/>
</svg>
</button>
</div>
<div <div
class="tw:relative" class="tw:grid tw:grid-cols-2 tw:@md:grid-cols-3 tw:@lg:grid-cols-4 tw:gap-4"
> >
<img <div
alt="Gallery image 2" class="tw:relative"
class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg "
src="undefined2.jpg"
/>
<button
class="tw:m-2 tw:bg-red-500 tw:text-white tw:p-2 tw:rounded-full tw:absolute tw:top-0 tw:right-0 tw:hover:bg-red-600 tw:cursor-pointer"
type="button"
> >
<svg <img
aria-hidden="true" alt="Gallery image 1"
class="tw:h-5 tw:w-5" class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg "
data-slot="icon" src="undefined1.jpg"
data-testid="trash" />
fill="currentColor" <button
viewBox="0 0 24 24" class="tw:m-2 tw:bg-red-500 tw:text-white tw:p-2 tw:rounded-full tw:absolute tw:top-0 tw:right-0 tw:hover:bg-red-600 tw:cursor-pointer"
xmlns="http://www.w3.org/2000/svg" type="button"
> >
<path <svg
clip-rule="evenodd" aria-hidden="true"
d="M16.5 4.478v.227a48.816 48.816 0 0 1 3.878.512.75.75 0 1 1-.256 1.478l-.209-.035-1.005 13.07a3 3 0 0 1-2.991 2.77H8.084a3 3 0 0 1-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 0 1-.256-1.478A48.567 48.567 0 0 1 7.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 0 1 3.369 0c1.603.051 2.815 1.387 2.815 2.951Zm-6.136-1.452a51.196 51.196 0 0 1 3.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 0 0-6 0v-.113c0-.794.609-1.428 1.364-1.452Zm-.355 5.945a.75.75 0 1 0-1.5.058l.347 9a.75.75 0 1 0 1.499-.058l-.346-9Zm5.48.058a.75.75 0 1 0-1.498-.058l-.347 9a.75.75 0 0 0 1.5.058l.345-9Z" class="tw:h-5 tw:w-5"
fill-rule="evenodd" data-slot="icon"
/> data-testid="trash"
</svg> fill="currentColor"
</button> viewBox="0 0 24 24"
</div> xmlns="http://www.w3.org/2000/svg"
<div >
class="tw:flex tw:flex-col tw:items-center tw:justify-center tw:text-base-content/50 tw:w-full tw:h-full tw:cursor-pointer tw:card tw:card-body tw:border tw:border-current/50 tw:border-dashed tw:bg-base-200" <path
role="presentation" clip-rule="evenodd"
tabindex="0" d="M16.5 4.478v.227a48.816 48.816 0 0 1 3.878.512.75.75 0 1 1-.256 1.478l-.209-.035-1.005 13.07a3 3 0 0 1-2.991 2.77H8.084a3 3 0 0 1-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 0 1-.256-1.478A48.567 48.567 0 0 1 7.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 0 1 3.369 0c1.603.051 2.815 1.387 2.815 2.951Zm-6.136-1.452a51.196 51.196 0 0 1 3.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 0 0-6 0v-.113c0-.794.609-1.428 1.364-1.452Zm-.355 5.945a.75.75 0 1 0-1.5.058l.347 9a.75.75 0 1 0 1.499-.058l-.346-9Zm5.48.058a.75.75 0 1 0-1.498-.058l-.347 9a.75.75 0 0 0 1.5.058l.345-9Z"
> fill-rule="evenodd"
<input />
accept="image/jpeg,image/png" </svg>
data-testid="gallery-upload-input" </button>
multiple="" </div>
style="border: 0px; clip: rect(0, 0, 0, 0); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;" <div
tabindex="-1" class="tw:relative"
type="file" >
/> <img
<div> alt="Gallery image 2"
<svg class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg "
class="tw:h-16 tw:w-16 tw:m-auto tw:mb-2" src="undefined2.jpg"
fill="currentColor" />
height="1em" <button
stroke="currentColor" class="tw:m-2 tw:bg-red-500 tw:text-white tw:p-2 tw:rounded-full tw:absolute tw:top-0 tw:right-0 tw:hover:bg-red-600 tw:cursor-pointer"
stroke-width="0" type="button"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
> >
<path <svg
d="M19.999 4h-16c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm-13.5 3a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm5.5 10h-7l4-5 1.5 2 3-4 5.5 7h-7z" aria-hidden="true"
/> class="tw:h-5 tw:w-5"
</svg> data-slot="icon"
<span data-testid="trash"
class="tw:text-center" fill="currentColor"
> viewBox="0 0 24 24"
Upload Image xmlns="http://www.w3.org/2000/svg"
</span> >
<path
clip-rule="evenodd"
d="M16.5 4.478v.227a48.816 48.816 0 0 1 3.878.512.75.75 0 1 1-.256 1.478l-.209-.035-1.005 13.07a3 3 0 0 1-2.991 2.77H8.084a3 3 0 0 1-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 0 1-.256-1.478A48.567 48.567 0 0 1 7.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 0 1 3.369 0c1.603.051 2.815 1.387 2.815 2.951Zm-6.136-1.452a51.196 51.196 0 0 1 3.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 0 0-6 0v-.113c0-.794.609-1.428 1.364-1.452Zm-.355 5.945a.75.75 0 1 0-1.5.058l.347 9a.75.75 0 1 0 1.499-.058l-.346-9Zm5.48.058a.75.75 0 1 0-1.498-.058l-.347 9a.75.75 0 0 0 1.5.058l.345-9Z"
fill-rule="evenodd"
/>
</svg>
</button>
</div>
<div
class="tw:flex tw:flex-col tw:items-center tw:justify-center tw:text-base-content/50 tw:w-full tw:h-full tw:cursor-pointer tw:card tw:card-body tw:border tw:border-current/50 tw:border-dashed tw:bg-base-200"
role="presentation"
tabindex="0"
>
<input
accept="image/jpeg,image/png"
data-testid="gallery-upload-input"
multiple=""
style="border: 0px; clip: rect(0, 0, 0, 0); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;"
tabindex="-1"
type="file"
/>
<div>
<svg
class="tw:h-16 tw:w-16 tw:m-auto tw:mb-2"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19.999 4h-16c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm-13.5 3a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm5.5 10h-7l4-5 1.5 2 3-4 5.5 7h-7z"
/>
</svg>
<span
class="tw:text-center"
>
Upload Image
</span>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -105,77 +119,91 @@ exports[`GalleryForm > with previous images > renders 1`] = `
exports[`GalleryForm > with uploading images > renders 1`] = ` exports[`GalleryForm > with uploading images > renders 1`] = `
<div> <div>
<div <div
class="tw:grid tw:grid-cols-2 tw:@md:grid-cols-3 tw:@lg:grid-cols-4 tw:gap-4 tw:my-4" class="tw:mt-3"
> >
<div <label
class="tw:relative" class="tw:label tw:pb-1"
> >
<img
alt="Gallery image 1"
class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg tw:opacity-50"
src="blob-url-placeholder"
/>
<span <span
class="tw:loading tw:loading-spinner tw:absolute tw:inset-0 tw:m-auto" class="tw:block tw:text-sm tw:font-medium tw:text-base-content/50 tw:mb-1"
/> >
</div> Media
:
</span>
</label>
<div <div
class="tw:relative" class="tw:grid tw:grid-cols-2 tw:@md:grid-cols-3 tw:@lg:grid-cols-4 tw:gap-4"
> >
<img <div
alt="Gallery image 2" class="tw:relative"
class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg tw:opacity-50" >
src="blob-url-placeholder" <img
/> alt="Gallery image 1"
<span class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg tw:opacity-50"
class="tw:loading tw:loading-spinner tw:absolute tw:inset-0 tw:m-auto" src="blob-url-placeholder"
/> />
</div>
<div
class="tw:relative"
>
<img
alt="Gallery image 3"
class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg tw:opacity-50"
src="blob-url-placeholder"
/>
<span
class="tw:loading tw:loading-spinner tw:absolute tw:inset-0 tw:m-auto"
/>
</div>
<div
class="tw:flex tw:flex-col tw:items-center tw:justify-center tw:text-base-content/50 tw:w-full tw:h-full tw:cursor-pointer tw:card tw:card-body tw:border tw:border-current/50 tw:border-dashed tw:bg-base-200"
role="presentation"
tabindex="0"
>
<input
accept="image/jpeg,image/png"
data-testid="gallery-upload-input"
multiple=""
style="border: 0px; clip: rect(0, 0, 0, 0); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;"
tabindex="-1"
type="file"
/>
<div>
<svg
class="tw:h-16 tw:w-16 tw:m-auto tw:mb-2"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19.999 4h-16c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm-13.5 3a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm5.5 10h-7l4-5 1.5 2 3-4 5.5 7h-7z"
/>
</svg>
<span <span
class="tw:text-center" class="tw:loading tw:loading-spinner tw:absolute tw:inset-0 tw:m-auto"
> />
Upload Image </div>
</span> <div
class="tw:relative"
>
<img
alt="Gallery image 2"
class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg tw:opacity-50"
src="blob-url-placeholder"
/>
<span
class="tw:loading tw:loading-spinner tw:absolute tw:inset-0 tw:m-auto"
/>
</div>
<div
class="tw:relative"
>
<img
alt="Gallery image 3"
class="tw:w-full tw:h-full tw:object-cover tw:rounded-lg tw:opacity-50"
src="blob-url-placeholder"
/>
<span
class="tw:loading tw:loading-spinner tw:absolute tw:inset-0 tw:m-auto"
/>
</div>
<div
class="tw:flex tw:flex-col tw:items-center tw:justify-center tw:text-base-content/50 tw:w-full tw:h-full tw:cursor-pointer tw:card tw:card-body tw:border tw:border-current/50 tw:border-dashed tw:bg-base-200"
role="presentation"
tabindex="0"
>
<input
accept="image/jpeg,image/png"
data-testid="gallery-upload-input"
multiple=""
style="border: 0px; clip: rect(0, 0, 0, 0); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;"
tabindex="-1"
type="file"
/>
<div>
<svg
class="tw:h-16 tw:w-16 tw:m-auto tw:mb-2"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19.999 4h-16c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm-13.5 3a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm5.5 10h-7l4-5 1.5 2 3-4 5.5 7h-7z"
/>
</svg>
<span
class="tw:text-center"
>
Upload Image
</span>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -185,41 +213,55 @@ exports[`GalleryForm > with uploading images > renders 1`] = `
exports[`GalleryForm > without previous images > renders 1`] = ` exports[`GalleryForm > without previous images > renders 1`] = `
<div> <div>
<div <div
class="tw:grid tw:grid-cols-2 tw:@md:grid-cols-3 tw:@lg:grid-cols-4 tw:gap-4 tw:my-4" class="tw:mt-3"
> >
<div <label
class="tw:flex tw:flex-col tw:items-center tw:justify-center tw:text-base-content/50 tw:w-full tw:h-full tw:cursor-pointer tw:card tw:card-body tw:border tw:border-current/50 tw:border-dashed tw:bg-base-200" class="tw:label tw:pb-1"
role="presentation"
tabindex="0"
> >
<input <span
accept="image/jpeg,image/png" class="tw:block tw:text-sm tw:font-medium tw:text-base-content/50 tw:mb-1"
data-testid="gallery-upload-input" >
multiple="" Media
style="border: 0px; clip: rect(0, 0, 0, 0); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;" :
tabindex="-1" </span>
type="file" </label>
/> <div
<div> class="tw:grid tw:grid-cols-2 tw:@md:grid-cols-3 tw:@lg:grid-cols-4 tw:gap-4"
<svg >
class="tw:h-16 tw:w-16 tw:m-auto tw:mb-2" <div
fill="currentColor" class="tw:flex tw:flex-col tw:items-center tw:justify-center tw:text-base-content/50 tw:w-full tw:h-full tw:cursor-pointer tw:card tw:card-body tw:border tw:border-current/50 tw:border-dashed tw:bg-base-200"
height="1em" role="presentation"
stroke="currentColor" tabindex="0"
stroke-width="0" >
viewBox="0 0 24 24" <input
width="1em" accept="image/jpeg,image/png"
xmlns="http://www.w3.org/2000/svg" data-testid="gallery-upload-input"
> multiple=""
<path style="border: 0px; clip: rect(0, 0, 0, 0); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;"
d="M19.999 4h-16c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm-13.5 3a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm5.5 10h-7l4-5 1.5 2 3-4 5.5 7h-7z" tabindex="-1"
/> type="file"
</svg> />
<span <div>
class="tw:text-center" <svg
> class="tw:h-16 tw:w-16 tw:m-auto tw:mb-2"
Upload Image fill="currentColor"
</span> height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19.999 4h-16c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm-13.5 3a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm5.5 10h-7l4-5 1.5 2 3-4 5.5 7h-7z"
/>
</svg>
<span
class="tw:text-center"
>
Upload Image
</span>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -44,7 +44,6 @@ export const TabsForm = ({
<PopupStartEndInput <PopupStartEndInput
item={item} item={item}
showLabels={true} showLabels={true}
labelStyle={'tw:text-base-content/50'}
updateEndValue={(e) => updateEndValue={(e) =>
setState((prevState) => ({ setState((prevState) => ({
...prevState, ...prevState,
@ -62,7 +61,6 @@ export const TabsForm = ({
<RichTextEditor <RichTextEditor
labelTitle='About' labelTitle='About'
labelStyle={'tw:text-base-content/50'}
placeholder='about ...' placeholder='about ...'
defaultValue={item?.text ? item.text : ''} defaultValue={item?.text ? item.text : ''}
updateFormValue={(v) => updateFormValue={(v) =>