use ListBox for size select

This commit is contained in:
Sanster 2022-02-05 21:41:32 +08:00
parent 920bf27ccb
commit 8eeb350f49
2 changed files with 78 additions and 45 deletions

View File

@ -402,9 +402,10 @@ export default function Editor(props: EditorProps) {
].join(' ')} ].join(' ')}
> >
<SizeSelector <SizeSelector
value={sizeLimit} value={sizeLimit!}
onChange={onSizeLimitChange} onChange={onSizeLimitChange}
originalSize={`${original.naturalWidth}x${original.naturalHeight}`} originalWidth={original.naturalWidth}
originalHeight={original.naturalHeight}
/> />
<Slider <Slider
label={ label={

View File

@ -1,56 +1,88 @@
import React from 'react' import React from 'react'
import { RadioGroup } from '@headlessui/react' import { Listbox } from '@headlessui/react'
import { CheckIcon, SelectorIcon } from '@heroicons/react/solid'
const sizes = [ const sizes = ['1080', '2000', 'Original']
['1080', '1080'],
['2000', '2k'],
['Original', 'Original'],
]
type SizeSelectorProps = { type SizeSelectorProps = {
value?: string value: string
originalSize: string originalWidth: number
originalHeight: number
onChange: (value: string) => void onChange: (value: string) => void
} }
export default function SizeSelector(props: SizeSelectorProps) { export default function SizeSelector(props: SizeSelectorProps) {
const { value, originalSize, onChange } = props const { value, originalHeight, originalWidth, onChange } = props
const getSizeShowName = (size: string) => {
if (size === 'Original') {
return `${originalWidth}x${originalHeight}(${size})`
}
const length: number = parseInt(size, 10)
const longSide: number =
originalWidth > originalHeight ? originalWidth : originalHeight
const scale = length / longSide
if (originalWidth > originalHeight) {
const newHeight = Math.ceil(scale * originalHeight)
return `${size}x${newHeight}`
}
const newWidth = Math.ceil(scale * originalWidth)
return `${newWidth}x${size}`
}
return ( return (
<RadioGroup <div className="w-52">
className="my-4 flex items-center space-x-2" <Listbox value={value} onChange={onChange}>
value={value} <div className="relative">
onChange={onChange} <Listbox.Options
style={{ top: '-112px' }}
className="absolute mb-1 w-full overflow-auto text-base bg-black backdrop-blur backdrop-filter md:bg-opacity-10 rounded-md max-h-60 ring-opacity-50 focus:outline-none sm:text-sm"
> >
<RadioGroup.Label>Resize</RadioGroup.Label> {sizes.map((size, _) => (
{sizes.map(size => ( <Listbox.Option
<RadioGroup.Option key={size[0]} value={size[0]}> key={size}
{({ checked }) => ( className={({ active }) =>
<div `${active ? 'bg-black bg-opacity-10' : 'text-gray-900'}
className={[ cursor-default select-none relative py-2 pl-10 pr-4`
checked ? 'bg-gray-200' : 'border-opacity-10', }
'border-3 px-2 py-2 rounded-md', value={size}
].join(' ')}
> >
<div className="flex items-center space-x-4"> {({ selected, active }) => (
<div <>
className={[ <span
'rounded-full w-5 h-5 border-4 ', className={`${
checked selected ? 'font-medium' : 'font-normal'
? 'border-primary bg-black' } block truncate`}
: 'border-black border-opacity-10', >
].join(' ')} {getSizeShowName(size)}
/> </span>
{size[0] === 'Original' ? ( {selected ? (
<span>{`${size[1]}(${originalSize})`}</span> <span
) : ( className={`${
<span>{size[1]}</span> active ? 'text-amber-600' : 'text-amber-600'
}
absolute inset-y-0 left-0 flex items-center pl-3`}
>
<CheckIcon className="w-5 h-5" aria-hidden="true" />
</span>
) : null}
</>
)} )}
</div> </Listbox.Option>
</div>
)}
</RadioGroup.Option>
))} ))}
</RadioGroup> </Listbox.Options>
<Listbox.Button className="relative w-full inline-flex w-full px-4 py-2 text-sm font-medium bg-black rounded-md bg-opacity-10 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
<span className="block truncate">{getSizeShowName(value)}</span>
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<SelectorIcon
className="w-5 h-5 text-gray-400"
aria-hidden="true"
/>
</span>
</Listbox.Button>
</div>
</Listbox>
</div>
) )
} }