mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-03-01 12:44:17 +00:00
optimized layout
This commit is contained in:
parent
eb87b9344a
commit
3a690aaffa
@ -120,7 +120,7 @@ function MapContainer({ layers, map }: { layers: LayerProps[]; map: any }) {
|
||||
parameterField={
|
||||
layer.itemType.custom_profile_url ? 'extended.external_profile_id' : 'id'
|
||||
}
|
||||
text={layer.itemType.botton_label ?? 'Profile'}
|
||||
text={layer.itemType.button_label ?? 'Profile'}
|
||||
target={layer.itemType.custom_profile_url ? '_blank' : '_self'}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { MapPinIcon } from '@heroicons/react/24/solid'
|
||||
|
||||
import { useGeoDistance } from '#components/Map/hooks/useGeoDistance'
|
||||
@ -24,6 +25,9 @@ export function ItemTitle({
|
||||
}: ItemTitleProps) {
|
||||
const { distance } = useGeoDistance(item.position ?? undefined)
|
||||
const { formatDistance } = useFormatDistance()
|
||||
const titleRef = useRef<HTMLDivElement>(null)
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const [fontSize, setFontSize] = useState<string>('tw:text-xl')
|
||||
|
||||
const { address } = useReverseGeocode(
|
||||
item.position?.coordinates as [number, number] | undefined,
|
||||
@ -34,10 +38,71 @@ export function ItemTitle({
|
||||
const title = item.name ?? item.layer?.item_default_name
|
||||
const subtitle = item.subname
|
||||
|
||||
useEffect(() => {
|
||||
if (!containerRef.current || !title) {
|
||||
return
|
||||
}
|
||||
|
||||
const calculateFontSize = () => {
|
||||
const container = containerRef.current
|
||||
if (!container) return
|
||||
|
||||
const containerWidth = container.offsetWidth
|
||||
|
||||
// Create temporary element to measure text width
|
||||
const measureElement = document.createElement('span')
|
||||
measureElement.style.position = 'absolute'
|
||||
measureElement.style.visibility = 'hidden'
|
||||
measureElement.style.whiteSpace = 'nowrap'
|
||||
measureElement.style.fontWeight = '700' // font-bold
|
||||
measureElement.textContent = title
|
||||
document.body.appendChild(measureElement)
|
||||
|
||||
// Measure at different font sizes - include larger sizes only if big is true
|
||||
const fontSizes = big
|
||||
? [
|
||||
{ class: 'tw:text-2xl', pixels: 24 },
|
||||
{ class: 'tw:text-xl', pixels: 20 },
|
||||
{ class: 'tw:text-lg', pixels: 18 }
|
||||
]
|
||||
: [
|
||||
{ class: 'tw:text-xl', pixels: 20 },
|
||||
{ class: 'tw:text-lg', pixels: 18 }
|
||||
]
|
||||
|
||||
let selectedSize = 'tw:text-lg'
|
||||
|
||||
for (const size of fontSizes) {
|
||||
measureElement.style.fontSize = `${size.pixels}px`
|
||||
const textWidth = measureElement.offsetWidth
|
||||
|
||||
if (textWidth <= containerWidth) {
|
||||
selectedSize = size.class
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
document.body.removeChild(measureElement)
|
||||
setFontSize(selectedSize)
|
||||
}
|
||||
|
||||
// Initial calculation
|
||||
calculateFontSize()
|
||||
|
||||
// Watch for container size changes
|
||||
const resizeObserver = new ResizeObserver(calculateFontSize)
|
||||
resizeObserver.observe(containerRef.current)
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
}, [title, big])
|
||||
|
||||
return (
|
||||
<div className={`${hasAvatar ? 'tw:ml-3' : ''} tw:overflow-hidden tw:flex-1 tw:min-w-0 `}>
|
||||
<div ref={containerRef} className={`${hasAvatar ? 'tw:ml-3' : ''} tw:overflow-hidden tw:flex-1 tw:min-w-0 `}>
|
||||
<div
|
||||
className={`${big ? 'tw:xl:text-3xl tw:text-2xl' : 'tw:text-xl'} tw:font-bold`}
|
||||
ref={titleRef}
|
||||
className={`${fontSize} tw:font-bold`}
|
||||
title={title}
|
||||
data-cy='profile-title'
|
||||
>
|
||||
|
||||
@ -8,8 +8,8 @@ import type { Item } from '#types/Item'
|
||||
*/
|
||||
export const StartEndView = ({ item }: { item?: Item }) => {
|
||||
return (
|
||||
<div className='tw:flex tw:flex-row tw:mb-4 tw:mt-4'>
|
||||
<div className='tw:basis-2/5 tw:flex tw:flex-row'>
|
||||
<div className='tw:flex tw:flex-row tw:mb-4 tw:mt-4 tw:bg-base-300 tw:px-4 tw:py-3 tw:rounded-selector tw:w-full'>
|
||||
<div className='tw:basis-2/5 tw:flex tw:flex-row tw:font-bold'>
|
||||
<CalendarIcon className='tw:h-4 tw:w-4 tw:mr-2' />
|
||||
<time
|
||||
className='tw:align-middle'
|
||||
@ -21,7 +21,7 @@ export const StartEndView = ({ item }: { item?: Item }) => {
|
||||
<div className='tw:basis-1/5 tw:place-content-center'>
|
||||
<span>-</span>
|
||||
</div>
|
||||
<div className='tw:basis-2/5 tw:flex tw:flex-row'>
|
||||
<div className='tw:basis-2/5 tw:flex tw:flex-row tw:font-bold'>
|
||||
<CalendarIcon className='tw:h-4 tw:w-4 tw:mr-2' />
|
||||
<time
|
||||
className='tw:align-middle'
|
||||
|
||||
@ -174,7 +174,7 @@ export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi<any>
|
||||
<MapOverlayPage
|
||||
key={item.id}
|
||||
data-cy='profile-view'
|
||||
className={`tw:p-0! tw:overflow-scroll tw:m-4! tw:md:w-[calc(50%-32px)] tw:w-[calc(100%-32px)] tw:min-w-80 tw:max-w-3xl tw:left-0! tw:sm:left-auto! tw:top-0 tw:bottom-0 tw:transition-opacity tw:duration-500 ${!selectPosition ? 'tw:opacity-100 tw:pointer-events-auto' : 'tw:opacity-0 tw:pointer-events-none'} tw:max-h-[1000px]`}
|
||||
className={`tw:@container tw:p-0! tw:overflow-scroll tw:m-4! tw:md:w-[calc(50%-32px)] tw:w-[calc(100%-32px)] tw:min-w-80 tw:max-w-3xl tw:left-0! tw:sm:left-auto! tw:top-0 tw:bottom-0 tw:transition-opacity tw:duration-500 ${!selectPosition ? 'tw:opacity-100 tw:pointer-events-auto' : 'tw:opacity-0 tw:pointer-events-none'} tw:max-h-[1000px]`}
|
||||
>
|
||||
<>
|
||||
<div className={'tw:px-6 tw:pt-6'} data-cy='profile-header'>
|
||||
|
||||
@ -4,7 +4,7 @@ import type { Item } from '#types/Item'
|
||||
|
||||
export const ProfileStartEndView = ({ item }: { item: Item }) => {
|
||||
return (
|
||||
<div className='tw:mt-2 tw:px-6 tw:max-w-xs'>
|
||||
<div className='tw:mt-2 tw:px-6'>
|
||||
<StartEndView item={item}></StartEndView>
|
||||
</div>
|
||||
)
|
||||
|
||||
2
lib/src/types/ItemType.d.ts
vendored
2
lib/src/types/ItemType.d.ts
vendored
@ -18,7 +18,7 @@ export interface ItemType {
|
||||
questlog: boolean
|
||||
custom_profile_url?: string
|
||||
small_form_edit?: boolean
|
||||
botton_label?: string
|
||||
button_label?: string
|
||||
text_input_label?: string
|
||||
show_header_view_in_form?: boolean
|
||||
cta_button_label?: string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user