mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-04-06 01:25:33 +00:00
Merge branch 'main' of github.com:utopia-os/utopia-ui
This commit is contained in:
commit
1bd3a8a33b
32
src/Components/Input/ComboBoxInput.spec.tsx
Normal file
32
src/Components/Input/ComboBoxInput.spec.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { render, screen, fireEvent } from '@testing-library/react'
|
||||||
|
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||||
|
|
||||||
|
import ComboBoxInput from './ComboBoxInput'
|
||||||
|
|
||||||
|
describe('<ComboBoxInput />', () => {
|
||||||
|
let wrapper: ReturnType<typeof render>
|
||||||
|
|
||||||
|
const updateFormValue = vi.fn()
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks()
|
||||||
|
wrapper = render(
|
||||||
|
<ComboBoxInput
|
||||||
|
value={'option-1'}
|
||||||
|
onValueChange={updateFormValue}
|
||||||
|
options={['Option 1', 'Option 2']}
|
||||||
|
/>,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders properly', () => {
|
||||||
|
expect(wrapper.container.firstChild).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('handleChange', () => {
|
||||||
|
it('calls updateFormValue with new value', () => {
|
||||||
|
fireEvent.change(screen.getByRole('combobox'), { target: { value: 'Option 2' } })
|
||||||
|
expect(updateFormValue).toBeCalledWith('Option 2')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -1,74 +0,0 @@
|
|||||||
import InformationCircleIcon from '@heroicons/react/24/outline/InformationCircleIcon'
|
|
||||||
import { useState } from 'react'
|
|
||||||
|
|
||||||
interface SelectBoxProps {
|
|
||||||
labelTitle?: string
|
|
||||||
labelStyle?: string
|
|
||||||
type?: string
|
|
||||||
containerStyle?: string
|
|
||||||
defaultValue: string
|
|
||||||
placeholder?: string
|
|
||||||
|
|
||||||
updateFormValue: (value: string) => void
|
|
||||||
|
|
||||||
options: { name: string; value: string }[]
|
|
||||||
labelDescription?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @category Input
|
|
||||||
*/
|
|
||||||
export function SelectBox(props: SelectBoxProps) {
|
|
||||||
const {
|
|
||||||
labelTitle,
|
|
||||||
labelDescription,
|
|
||||||
defaultValue,
|
|
||||||
containerStyle,
|
|
||||||
placeholder,
|
|
||||||
labelStyle,
|
|
||||||
options,
|
|
||||||
updateFormValue,
|
|
||||||
} = props
|
|
||||||
|
|
||||||
const [value, setValue] = useState(defaultValue || '')
|
|
||||||
|
|
||||||
const updateValue = (newValue: string) => {
|
|
||||||
updateFormValue(newValue)
|
|
||||||
setValue(newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={`tw-inline-block ${containerStyle ?? ''}`}>
|
|
||||||
{labelTitle ? (
|
|
||||||
<label className={`tw-label ${labelStyle ?? ''}`}>
|
|
||||||
<div className='tw-label-text'>
|
|
||||||
{labelTitle}
|
|
||||||
{labelDescription && (
|
|
||||||
<div className='tw-tooltip tw-tooltip-right' data-tip={labelDescription}>
|
|
||||||
<InformationCircleIcon className='tw-w-4 tw-h-4' />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
) : (
|
|
||||||
''
|
|
||||||
)}
|
|
||||||
<select
|
|
||||||
className='tw-select tw-select-bordered tw-w-full'
|
|
||||||
value={value}
|
|
||||||
onChange={(e) => updateValue(e.target.value)}
|
|
||||||
>
|
|
||||||
<option disabled value='PLACEHOLDER'>
|
|
||||||
{placeholder}
|
|
||||||
</option>
|
|
||||||
{options.map((o, k) => {
|
|
||||||
return (
|
|
||||||
<option value={o.value || o.name} key={k}>
|
|
||||||
{o.name}
|
|
||||||
</option>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
33
src/Components/Input/TextAreaInput.spec.tsx
Normal file
33
src/Components/Input/TextAreaInput.spec.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { render, screen, fireEvent } from '@testing-library/react'
|
||||||
|
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||||
|
|
||||||
|
import { TextAreaInput } from './TextAreaInput'
|
||||||
|
|
||||||
|
describe('<TextAreaInput />', () => {
|
||||||
|
let wrapper: ReturnType<typeof render>
|
||||||
|
|
||||||
|
const updateFormValue = vi.fn()
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks()
|
||||||
|
wrapper = render(<TextAreaInput defaultValue={''} updateFormValue={updateFormValue} />)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders properly', () => {
|
||||||
|
expect(wrapper.container.firstChild).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('handleChange', () => {
|
||||||
|
it('calls updateFormValue with new value', () => {
|
||||||
|
fireEvent.change(screen.getByRole('textbox'), { target: { value: 'test' } })
|
||||||
|
expect(updateFormValue).toBeCalledWith('test')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('labelTitle', () => {
|
||||||
|
it('sets label', () => {
|
||||||
|
wrapper.rerender(<TextAreaInput defaultValue={''} labelTitle='My Title' />)
|
||||||
|
expect(wrapper.container.firstChild).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -1,7 +1,5 @@
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
|
||||||
import { useTags } from '#components/Map/hooks/useTags'
|
|
||||||
|
|
||||||
interface TextAreaProps {
|
interface TextAreaProps {
|
||||||
labelTitle?: string
|
labelTitle?: string
|
||||||
labelStyle?: string
|
labelStyle?: string
|
||||||
@ -14,8 +12,6 @@ interface TextAreaProps {
|
|||||||
updateFormValue?: (value: string) => void
|
updateFormValue?: (value: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyValue = Record<string, string>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @category Input
|
* @category Input
|
||||||
*/
|
*/
|
||||||
@ -33,14 +29,6 @@ export function TextAreaInput({
|
|||||||
const ref = useRef<HTMLTextAreaElement>(null)
|
const ref = useRef<HTMLTextAreaElement>(null)
|
||||||
const [inputValue, setInputValue] = useState<string>(defaultValue)
|
const [inputValue, setInputValue] = useState<string>(defaultValue)
|
||||||
|
|
||||||
const tags = useTags()
|
|
||||||
|
|
||||||
const values: KeyValue[] = []
|
|
||||||
|
|
||||||
tags.forEach((tag) => {
|
|
||||||
values.push({ key: tag.name, value: tag.name, color: tag.color })
|
|
||||||
})
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInputValue(defaultValue)
|
setInputValue(defaultValue)
|
||||||
}, [defaultValue])
|
}, [defaultValue])
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
|
exports[`<ComboBoxInput /> > renders properly 1`] = `
|
||||||
|
<select
|
||||||
|
class="tw-form-select tw-block tw-w-full tw-py-2 tw-px-4 tw-border tw-border-gray-300 rounded-md tw-shadow-sm tw-text-sm focus:tw-outline-none focus:tw-ring-indigo-500 focus:tw-border-indigo-500 sm:tw-text-sm"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value="Option 1"
|
||||||
|
>
|
||||||
|
Option 1
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="Option 2"
|
||||||
|
>
|
||||||
|
Option 2
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
`;
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
|
exports[`<TextAreaInput /> > labelTitle > sets label 1`] = `
|
||||||
|
<div
|
||||||
|
class="tw-form-control tw-w-full "
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="tw-label"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="tw-label-text tw-text-base-content "
|
||||||
|
>
|
||||||
|
My Title
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
class="tw-textarea tw-textarea-bordered tw-w-full tw-leading-5 "
|
||||||
|
placeholder=""
|
||||||
|
required=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<TextAreaInput /> > renders properly 1`] = `
|
||||||
|
<div
|
||||||
|
class="tw-form-control tw-w-full "
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
class="tw-textarea tw-textarea-bordered tw-w-full tw-leading-5 "
|
||||||
|
placeholder=""
|
||||||
|
required=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
@ -1,3 +1,2 @@
|
|||||||
export { TextAreaInput } from './TextAreaInput'
|
export { TextAreaInput } from './TextAreaInput'
|
||||||
export { TextInput } from './TextInput'
|
export { TextInput } from './TextInput'
|
||||||
export { SelectBox } from './SelectBox'
|
|
||||||
|
|||||||
@ -53,6 +53,13 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
|||||||
})
|
})
|
||||||
formItem.position = { type: 'Point', coordinates: [props.position.lng, props.position.lat] }
|
formItem.position = { type: 'Point', coordinates: [props.position.lng, props.position.lat] }
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
|
|
||||||
|
const name = formItem.name ? formItem.name : user?.first_name
|
||||||
|
if (!name) {
|
||||||
|
toast.error('Name is must be defined')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
setSpinner(true)
|
setSpinner(true)
|
||||||
|
|
||||||
formItem.text &&
|
formItem.text &&
|
||||||
@ -98,8 +105,8 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
|||||||
;(!props.layer.userProfileLayer || !item) &&
|
;(!props.layer.userProfileLayer || !item) &&
|
||||||
(await props.layer.api?.createItem!({
|
(await props.layer.api?.createItem!({
|
||||||
...formItem,
|
...formItem,
|
||||||
|
name,
|
||||||
id: uuid,
|
id: uuid,
|
||||||
name: formItem.name ? formItem.name : user?.first_name,
|
|
||||||
}))
|
}))
|
||||||
success = true
|
success = true
|
||||||
// eslint-disable-next-line no-catch-all/no-catch-all
|
// eslint-disable-next-line no-catch-all/no-catch-all
|
||||||
|
|||||||
@ -32,7 +32,6 @@ import { GratitudeControl } from './Subcomponents/Controls/GratitudeControl'
|
|||||||
import { LayerControl } from './Subcomponents/Controls/LayerControl'
|
import { LayerControl } from './Subcomponents/Controls/LayerControl'
|
||||||
import { SearchControl } from './Subcomponents/Controls/SearchControl'
|
import { SearchControl } from './Subcomponents/Controls/SearchControl'
|
||||||
import { TagsControl } from './Subcomponents/Controls/TagsControl'
|
import { TagsControl } from './Subcomponents/Controls/TagsControl'
|
||||||
import { PopupButton } from './Subcomponents/ItemPopupComponents/PopupButton'
|
|
||||||
import { TextView } from './Subcomponents/ItemPopupComponents/TextView'
|
import { TextView } from './Subcomponents/ItemPopupComponents/TextView'
|
||||||
import { SelectPosition } from './Subcomponents/SelectPosition'
|
import { SelectPosition } from './Subcomponents/SelectPosition'
|
||||||
|
|
||||||
@ -80,7 +79,9 @@ export function UtopiaMapInner({
|
|||||||
itemId=''
|
itemId=''
|
||||||
rawText={'Support us building free opensource maps and help us grow 🌱☀️'}
|
rawText={'Support us building free opensource maps and help us grow 🌱☀️'}
|
||||||
/>
|
/>
|
||||||
<PopupButton url={'https://opencollective.com/utopia-project'} text={'Donate'} />
|
<a href='https://opencollective.com/utopia-project'>
|
||||||
|
<div className='tw-btn tw-btn-sm tw-float-right'>Donate</div>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</>,
|
</>,
|
||||||
{ autoClose: false },
|
{ autoClose: false },
|
||||||
|
|||||||
@ -82,7 +82,6 @@ function useItemsManager(initialItems: Item[]): {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
result.map((item) => {
|
result.map((item) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
||||||
dispatch({ type: 'ADD', item: { ...item, layer } })
|
dispatch({ type: 'ADD', item: { ...item, layer } })
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|||||||
3
src/types/LayerProps.d.ts
vendored
3
src/types/LayerProps.d.ts
vendored
@ -18,8 +18,7 @@ export interface LayerProps {
|
|||||||
markerShape: string
|
markerShape: string
|
||||||
markerDefaultColor: string
|
markerDefaultColor: string
|
||||||
markerDefaultColor2?: string
|
markerDefaultColor2?: string
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
api?: ItemsApi<Item>
|
||||||
api?: ItemsApi<any>
|
|
||||||
itemType: ItemType
|
itemType: ItemType
|
||||||
userProfileLayer?: boolean
|
userProfileLayer?: boolean
|
||||||
customEditLink?: string
|
customEditLink?: string
|
||||||
|
|||||||
@ -12,12 +12,12 @@ export default defineConfig({
|
|||||||
coverage: {
|
coverage: {
|
||||||
all: true,
|
all: true,
|
||||||
include: ['src/**/*.{js,jsx,ts,tsx}'],
|
include: ['src/**/*.{js,jsx,ts,tsx}'],
|
||||||
exclude: [...configDefaults.exclude],
|
exclude: [...configDefaults.exclude, 'src/**/*.cy.tsx'],
|
||||||
thresholds: {
|
thresholds: {
|
||||||
lines: 0,
|
lines: 1,
|
||||||
functions: 61,
|
functions: 59,
|
||||||
branches: 62,
|
branches: 62,
|
||||||
statements: 0,
|
statements: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user