2
0

build: add pnpm

This commit is contained in:
Baptiste Arnaud
2022-08-08 08:21:36 +02:00
parent 8c3b5058f1
commit ee338f62dc
183 changed files with 19442 additions and 18364 deletions

View File

@ -1,5 +1,6 @@
import { Box, BoxProps, HStack } from '@chakra-ui/react'
import { EditorState, EditorView, basicSetup } from '@codemirror/basic-setup'
import { EditorView, basicSetup } from 'codemirror'
import { EditorState } from '@codemirror/state'
import { json, jsonParseLinter } from '@codemirror/lang-json'
import { css } from '@codemirror/lang-css'
import { javascript } from '@codemirror/lang-javascript'
@ -43,7 +44,7 @@ export const CodeEditor = ({
setPlainTextValue(value)
onChange && onChange(value)
},
env('E2E_TEST') === 'enabled' ? 0 : debounceTimeout
env('E2E_TEST') === 'true' ? 0 : debounceTimeout
)
useEffect(

View File

@ -1,4 +1,4 @@
import { useEventListener } from '@chakra-ui/hooks'
import { useEventListener } from '@chakra-ui/react'
import assert from 'assert'
import {
useGraph,

View File

@ -1,4 +1,4 @@
import { chakra } from '@chakra-ui/system'
import { chakra } from '@chakra-ui/react'
import { colors } from 'libs/theme'
import { Edge as EdgeProps } from 'models'
import React from 'react'

View File

@ -3,7 +3,6 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'
import {
Plate,
selectEditor,
serializeHtml,
TEditor,
TElement,
Value,
@ -16,6 +15,7 @@ import { parseHtmlStringToPlainText } from 'services/utils'
import { defaultTextBubbleContent, TextBubbleContent, Variable } from 'models'
import { VariableSearchInput } from 'components/shared/VariableSearchInput'
import { ReactEditor } from 'slate-react'
import { serializeHtml } from '@udecode/plate-serializer-html'
type Props = {
initialValue: TElement[]
@ -98,7 +98,7 @@ export const TextBubbleEditor = ({ initialValue, onClose }: Props) => {
setValue(val)
setIsVariableDropdownOpen(false)
}
const handleKeyDown = (e: React.KeyboardEvent) => {
const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.shiftKey) return
if (e.key === 'Enter') closeEditor()
}

View File

@ -1,4 +1,4 @@
import { StackProps, HStack, Button } from '@chakra-ui/react'
import { StackProps, HStack, Button, IconButton } from '@chakra-ui/react'
import {
MARK_BOLD,
MARK_ITALIC,
@ -7,7 +7,13 @@ import {
import { getPluginType, PlateEditor, Value } from '@udecode/plate-core'
import { LinkToolbarButton } from '@udecode/plate-ui-link'
import { MarkToolbarButton } from '@udecode/plate-ui-toolbar'
import { BoldIcon, ItalicIcon, UnderlineIcon, LinkIcon } from 'assets/icons'
import {
BoldIcon,
ItalicIcon,
UnderlineIcon,
LinkIcon,
UserIcon,
} from 'assets/icons'
type Props = {
editor: PlateEditor<Value>
@ -33,9 +39,12 @@ export const ToolBar = ({
borderBottomWidth={1}
{...props}
>
<Button size="sm" onMouseDown={handleVariablesButtonMouseDown}>
Variables
</Button>
<IconButton
aria-label="Insert variable"
size="sm"
onMouseDown={handleVariablesButtonMouseDown}
icon={<UserIcon />}
/>
<span data-testid="bold-button">
<MarkToolbarButton
type={getPluginType(editor, MARK_BOLD)}

View File

@ -1,22 +1,12 @@
import { ChangeEvent, useState } from 'react'
import {
Button,
Flex,
HStack,
Stack,
Text,
Input as ClassicInput,
SimpleGrid,
GridItem,
} from '@chakra-ui/react'
import { useState } from 'react'
import { Button, Flex, HStack, Stack, Text } from '@chakra-ui/react'
import { SearchContextManager } from '@giphy/react-components'
import { UploadButton } from '../buttons/UploadButton'
import { GiphySearch } from './GiphySearch'
import { useTypebot } from 'contexts/TypebotContext'
import { BaseEmoji, emojiIndex } from 'emoji-mart'
import { emojis } from './emojis'
import { Input } from '../Textbox/Input'
import { env, isEmpty } from 'utils'
import { EmojiSearchableList } from './emoji/EmojiSearchableList'
type Props = {
url?: string
@ -101,7 +91,7 @@ const BodyContent = ({
case 'giphy':
return <GiphyContent onNewUrl={onSubmit} />
case 'emoji':
return <EmojiContent onEmojiSelected={onSubmit} />
return <EmojiSearchableList onEmojiSelected={onSubmit} />
}
}
@ -133,55 +123,6 @@ const EmbedLinkContent = ({ initialUrl, onNewUrl }: ContentProps) => (
</Stack>
)
const EmojiContent = ({
onEmojiSelected,
}: {
onEmojiSelected: (emoji: string) => void
}) => {
const [searchValue, setSearchValue] = useState('')
const [filteredEmojis, setFilteredEmojis] = useState<string[]>(emojis)
const handleEmojiClick = (emoji: string) => () => onEmojiSelected(emoji)
const handleSearchChange = (e: ChangeEvent<HTMLInputElement>) => {
setSearchValue(e.target.value)
setFilteredEmojis(
emojiIndex.search(e.target.value)?.map((o) => (o as BaseEmoji).native) ??
emojis
)
}
return (
<Stack>
<ClassicInput
placeholder="Search..."
value={searchValue}
onChange={handleSearchChange}
/>
<SimpleGrid
maxH="350px"
overflowY="scroll"
overflowX="hidden"
spacing={0}
columns={7}
>
{filteredEmojis.map((emoji) => (
<GridItem key={emoji}>
<Button
onClick={handleEmojiClick(emoji)}
variant="ghost"
size="sm"
fontSize="xl"
>
{emoji}
</Button>
</GridItem>
))}
</SimpleGrid>
</Stack>
)
}
const GiphyContent = ({ onNewUrl }: ContentProps) => {
if (isEmpty(env('GIPHY_API_KEY')))
return <Text>NEXT_PUBLIC_GIPHY_API_KEY is missing in environment</Text>

View File

@ -0,0 +1,199 @@
import emojis from './emojiList.json'
import emojiTagsData from 'emojilib'
import {
Stack,
SimpleGrid,
GridItem,
Button,
Input as ClassicInput,
Text,
} from '@chakra-ui/react'
import { useState, ChangeEvent, useEffect, useRef } from 'react'
const emojiTags = emojiTagsData as Record<string, string[]>
const people = emojis['Smileys & Emotion'].concat(emojis['People & Body'])
const nature = emojis['Animals & Nature']
const food = emojis['Food & Drink']
const activities = emojis['Activities']
const travel = emojis['Travel & Places']
const objects = emojis['Objects']
const symbols = emojis['Symbols']
const flags = emojis['Flags']
export const EmojiSearchableList = ({
onEmojiSelected,
}: {
onEmojiSelected: (emoji: string) => void
}) => {
const scrollContainer = useRef<HTMLDivElement>(null)
const bottomElement = useRef<HTMLDivElement>(null)
const [isSearching, setIsSearching] = useState(false)
const [filteredPeople, setFilteredPeople] = useState(people)
const [filteredAnimals, setFilteredAnimals] = useState(nature)
const [filteredFood, setFilteredFood] = useState(food)
const [filteredTravel, setFilteredTravel] = useState(travel)
const [filteredActivities, setFilteredActivities] = useState(activities)
const [filteredObjects, setFilteredObjects] = useState(objects)
const [filteredSymbols, setFilteredSymbols] = useState(symbols)
const [filteredFlags, setFilteredFlags] = useState(flags)
const [totalDisplayedCategories, setTotalDisplayedCategories] = useState(1)
useEffect(() => {
if (!bottomElement.current) return
const observer = new IntersectionObserver(handleObserver, {
root: scrollContainer.current,
})
if (bottomElement.current) observer.observe(bottomElement.current)
return () => {
observer.disconnect()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [bottomElement.current])
const handleObserver = (entities: IntersectionObserverEntry[]) => {
const target = entities[0]
if (target.isIntersecting) setTotalDisplayedCategories((c) => c + 1)
}
const handleSearchChange = async (e: ChangeEvent<HTMLInputElement>) => {
const searchValue = e.target.value
if (searchValue.length <= 2 && isSearching) return resetEmojiList()
setIsSearching(true)
setTotalDisplayedCategories(8)
const byTag = (emoji: string) =>
emojiTags[emoji].find((tag) => tag.includes(searchValue))
setFilteredPeople(people.filter(byTag))
setFilteredAnimals(nature.filter(byTag))
setFilteredFood(food.filter(byTag))
setFilteredTravel(travel.filter(byTag))
setFilteredActivities(activities.filter(byTag))
setFilteredObjects(objects.filter(byTag))
setFilteredSymbols(symbols.filter(byTag))
setFilteredFlags(flags.filter(byTag))
}
const resetEmojiList = () => {
setTotalDisplayedCategories(1)
setIsSearching(false)
setFilteredPeople(people)
setFilteredAnimals(nature)
setFilteredFood(food)
setFilteredTravel(travel)
setFilteredActivities(activities)
setFilteredObjects(objects)
setFilteredSymbols(symbols)
setFilteredFlags(flags)
}
return (
<Stack>
<ClassicInput placeholder="Search..." onChange={handleSearchChange} />
<Stack ref={scrollContainer} overflow="scroll" maxH="350px" spacing={4}>
{filteredPeople.length > 0 && (
<Stack>
<Text fontSize="sm" pl="2">
People
</Text>
<EmojiGrid emojis={filteredPeople} onEmojiClick={onEmojiSelected} />
</Stack>
)}
{filteredAnimals.length > 0 && totalDisplayedCategories >= 2 && (
<Stack>
<Text fontSize="sm" pl="2">
Animals & Nature
</Text>
<EmojiGrid
emojis={filteredAnimals}
onEmojiClick={onEmojiSelected}
/>
</Stack>
)}
{filteredFood.length > 0 && totalDisplayedCategories >= 3 && (
<Stack>
<Text fontSize="sm" pl="2">
Food & Drink
</Text>
<EmojiGrid emojis={filteredFood} onEmojiClick={onEmojiSelected} />
</Stack>
)}
{filteredTravel.length > 0 && totalDisplayedCategories >= 4 && (
<Stack>
<Text fontSize="sm" pl="2">
Travel & Places
</Text>
<EmojiGrid emojis={filteredTravel} onEmojiClick={onEmojiSelected} />
</Stack>
)}
{filteredActivities.length > 0 && totalDisplayedCategories >= 5 && (
<Stack>
<Text fontSize="sm" pl="2">
Activities
</Text>
<EmojiGrid
emojis={filteredActivities}
onEmojiClick={onEmojiSelected}
/>
</Stack>
)}
{filteredObjects.length > 0 && totalDisplayedCategories >= 6 && (
<Stack>
<Text fontSize="sm" pl="2">
Objects
</Text>
<EmojiGrid
emojis={filteredObjects}
onEmojiClick={onEmojiSelected}
/>
</Stack>
)}
{filteredSymbols.length > 0 && totalDisplayedCategories >= 7 && (
<Stack>
<Text fontSize="sm" pl="2">
Symbols
</Text>
<EmojiGrid
emojis={filteredSymbols}
onEmojiClick={onEmojiSelected}
/>
</Stack>
)}
{filteredFlags.length > 0 && totalDisplayedCategories >= 8 && (
<Stack>
<Text fontSize="sm" pl="2">
Flags
</Text>
<EmojiGrid emojis={filteredFlags} onEmojiClick={onEmojiSelected} />
</Stack>
)}
<div ref={bottomElement} />
</Stack>
</Stack>
)
}
const EmojiGrid = ({
emojis,
onEmojiClick,
}: {
emojis: string[]
onEmojiClick: (emoji: string) => void
}) => {
const handleClick = (emoji: string) => () => onEmojiClick(emoji)
return (
<SimpleGrid spacing={0} columns={7}>
{emojis.map((emoji) => (
<GridItem
as={Button}
onClick={handleClick(emoji)}
variant="ghost"
size="sm"
fontSize="xl"
key={emoji}
>
{emoji}
</GridItem>
))}
</SimpleGrid>
)
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@ export const SearchableDropdown = ({
const debounced = useDebouncedCallback(
// eslint-disable-next-line @typescript-eslint/no-empty-function
onValueChange ? onValueChange : () => {},
env('E2E_TEST') === 'enabled' ? 0 : debounceTimeout
env('E2E_TEST') === 'true' ? 0 : debounceTimeout
)
const [filteredItems, setFilteredItems] = useState([
...items

View File

@ -23,7 +23,7 @@ export const SmartNumberInput = ({
const [currentValue, setCurrentValue] = useState(value?.toString() ?? '')
const debounced = useDebouncedCallback(
onValueChange,
env('E2E_TEST') === 'enabled' ? 0 : debounceTimeout
env('E2E_TEST') === 'true' ? 0 : debounceTimeout
)
useEffect(

View File

@ -36,7 +36,7 @@ export const TextBox = ({
(value) => {
onChange(value)
},
env('E2E_TEST') === 'enabled' ? 0 : debounceTimeout
env('E2E_TEST') === 'true' ? 0 : debounceTimeout
)
useEffect(() => {

View File

@ -1,5 +1,9 @@
import { Editable, EditablePreview, EditableInput } from '@chakra-ui/editable'
import { Tooltip } from '@chakra-ui/tooltip'
import {
Editable,
EditablePreview,
EditableInput,
Tooltip,
} from '@chakra-ui/react'
import React, { useEffect, useState } from 'react'
type EditableProps = {

View File

@ -47,7 +47,7 @@ export const VariableSearchInput = ({
const variable = variables.find((v) => v.name === value)
if (variable) onSelectVariable(variable)
},
env('E2E_TEST') === 'enabled' ? 0 : debounceTimeout
env('E2E_TEST') === 'true' ? 0 : debounceTimeout
)
const [filteredItems, setFilteredItems] = useState<Variable[]>(
variables ?? []

View File

@ -1,4 +1,4 @@
import { useToast as useChakraToast, UseToastOptions } from '@chakra-ui/toast'
import { useToast as useChakraToast, UseToastOptions } from '@chakra-ui/react'
export const useToast = () => {
const toast = useChakraToast()