(embed) Add size and icon picker in bubble settings (#508)

This commit is contained in:
Baptiste Arnaud
2023-05-15 15:22:04 +02:00
committed by GitHub
parent 123926f273
commit 0f91b34497
15 changed files with 256 additions and 108 deletions

View File

@@ -19,7 +19,7 @@ import tinyColor from 'tinycolor2'
const colorsSelection: `#${string}`[] = [
'#666460',
'#AFABA3',
'#FFFFFF',
'#A87964',
'#D09C46',
'#DE8031',
@@ -27,7 +27,7 @@ const colorsSelection: `#${string}`[] = [
'#4A8BB2',
'#9B74B7',
'#C75F96',
'#C75F96',
'#0042DA',
]
type Props = {
@@ -78,18 +78,19 @@ export const ColorPicker = ({ value, defaultValue, onColorChange }: Props) => {
</PopoverHeader>
<PopoverBody as={Stack}>
<SimpleGrid columns={5} spacing={2}>
{colorsSelection.map((c) => (
{colorsSelection.map((color) => (
<Button
key={c}
aria-label={c}
background={c}
key={color}
aria-label={color}
background={color}
height="22px"
width="22px"
padding={0}
minWidth="unset"
borderRadius={3}
_hover={{ background: c }}
onClick={handleClick(c)}
borderWidth={color === '#FFFFFF' ? 1 : undefined}
_hover={{ background: color }}
onClick={handleClick(color)}
/>
))}
</SimpleGrid>

View File

@@ -57,10 +57,9 @@ export const EditableEmojiOrImageIcon = ({
filePath={uploadFilePath}
defaultUrl={icon ?? ''}
onSubmit={onChangeIcon}
isGiphyEnabled={false}
isUnsplashEnabled={false}
isEmojiEnabled={true}
excludedTabs={['giphy', 'unsplash']}
onClose={onClose}
initialTab="icon"
/>
</PopoverContent>
</>

View File

@@ -26,6 +26,13 @@ export const IconPicker = ({ onIconSelected }: Props) => {
)
const searchQuery = useRef<string>('')
const [selectedColor, setSelectedColor] = useState(initialIconColor)
const isWhite = useMemo(
() =>
selectedColor.toLowerCase() === '#ffffff' ||
selectedColor.toLowerCase() === '#fff' ||
selectedColor === 'white',
[selectedColor]
)
useEffect(() => {
if (!bottomElement.current) return
@@ -68,10 +75,9 @@ export const IconPicker = ({ onIconSelected }: Props) => {
const selectIcon = async (iconName: string) => {
const svg = await (await fetch(`/icons/${iconName}.svg`)).text()
const dataUri = `data:image/svg+xml;utf8,${svg.replace(
'<svg',
`<svg fill='${encodeURIComponent(selectedColor)}'`
)}`
const dataUri = `data:image/svg+xml;utf8,${svg
.replace('<svg', `<svg fill='${encodeURIComponent(selectedColor)}'`)
.replace(/"/g, "'")}`
onIconSelected(dataUri)
}
@@ -96,8 +102,9 @@ export const IconPicker = ({ onIconSelected }: Props) => {
>
{displayedIconNames.map((iconName) => (
<Button
variant="ghost"
size="sm"
variant={isWhite ? 'solid' : 'ghost'}
colorScheme={isWhite ? 'blackAlpha' : undefined}
fontSize="xl"
w="38px"
h="38px"

View File

@@ -10,30 +10,52 @@ import { IconPicker } from './IconPicker'
type Tabs = 'link' | 'upload' | 'giphy' | 'emoji' | 'unsplash' | 'icon'
type Props = {
filePath: string
filePath: string | undefined
includeFileName?: boolean
defaultUrl?: string
isEmojiEnabled?: boolean
isGiphyEnabled?: boolean
isUnsplashEnabled?: boolean
imageSize?: 'small' | 'regular' | 'thumb'
initialTab?: Tabs
onSubmit: (url: string) => void
onClose?: () => void
}
} & (
| {
includedTabs?: Tabs[]
}
| {
excludedTabs?: Tabs[]
}
)
const defaultDisplayedTabs: Tabs[] = [
'link',
'upload',
'giphy',
'emoji',
'unsplash',
'icon',
]
export const ImageUploadContent = ({
filePath,
includeFileName,
defaultUrl,
onSubmit,
isEmojiEnabled = false,
isGiphyEnabled = true,
isUnsplashEnabled = true,
imageSize = 'regular',
onClose,
initialTab,
...props
}: Props) => {
const includedTabs =
'includedTabs' in props
? props.includedTabs ?? defaultDisplayedTabs
: defaultDisplayedTabs
const excludedTabs = 'excludedTabs' in props ? props.excludedTabs ?? [] : []
const displayedTabs = defaultDisplayedTabs.filter(
(tab) => !excludedTabs.includes(tab) && includedTabs.includes(tab)
)
const [currentTab, setCurrentTab] = useState<Tabs>(
isEmojiEnabled ? 'emoji' : 'link'
initialTab ?? displayedTabs[0]
)
const handleSubmit = (url: string) => {
@@ -44,7 +66,25 @@ export const ImageUploadContent = ({
return (
<Stack>
<HStack>
{isEmojiEnabled && (
{displayedTabs.includes('link') && (
<Button
variant={currentTab === 'link' ? 'solid' : 'ghost'}
onClick={() => setCurrentTab('link')}
size="sm"
>
Link
</Button>
)}
{displayedTabs.includes('upload') && (
<Button
variant={currentTab === 'upload' ? 'solid' : 'ghost'}
onClick={() => setCurrentTab('upload')}
size="sm"
>
Upload
</Button>
)}
{displayedTabs.includes('emoji') && (
<Button
variant={currentTab === 'emoji' ? 'solid' : 'ghost'}
onClick={() => setCurrentTab('emoji')}
@@ -53,21 +93,7 @@ export const ImageUploadContent = ({
Emoji
</Button>
)}
<Button
variant={currentTab === 'link' ? 'solid' : 'ghost'}
onClick={() => setCurrentTab('link')}
size="sm"
>
Link
</Button>
<Button
variant={currentTab === 'upload' ? 'solid' : 'ghost'}
onClick={() => setCurrentTab('upload')}
size="sm"
>
Upload
</Button>
{isGiphyEnabled && (
{displayedTabs.includes('giphy') && (
<Button
variant={currentTab === 'giphy' ? 'solid' : 'ghost'}
onClick={() => setCurrentTab('giphy')}
@@ -76,7 +102,7 @@ export const ImageUploadContent = ({
Giphy
</Button>
)}
{isUnsplashEnabled && (
{displayedTabs.includes('unsplash') && (
<Button
variant={currentTab === 'unsplash' ? 'solid' : 'ghost'}
onClick={() => setCurrentTab('unsplash')}
@@ -85,13 +111,15 @@ export const ImageUploadContent = ({
Unsplash
</Button>
)}
<Button
variant={currentTab === 'icon' ? 'solid' : 'ghost'}
onClick={() => setCurrentTab('icon')}
size="sm"
>
Icon
</Button>
{displayedTabs.includes('icon') && (
<Button
variant={currentTab === 'icon' ? 'solid' : 'ghost'}
onClick={() => setCurrentTab('icon')}
size="sm"
>
Icon
</Button>
)}
</HStack>
<BodyContent
@@ -115,14 +143,15 @@ const BodyContent = ({
onSubmit,
}: {
includeFileName?: boolean
filePath: string
filePath: string | undefined
tab: Tabs
defaultUrl?: string
imageSize: 'small' | 'regular' | 'thumb'
onSubmit: (url: string) => void
}) => {
switch (tab) {
case 'upload':
case 'upload': {
if (!filePath) return null
return (
<UploadFileContent
filePath={filePath}
@@ -130,6 +159,7 @@ const BodyContent = ({
onNewUrl={onSubmit}
/>
)
}
case 'link':
return <EmbedLinkContent defaultUrl={defaultUrl} onNewUrl={onSubmit} />
case 'giphy':