Skip to content

Commit

Permalink
button dropdown and rang input
Browse files Browse the repository at this point in the history
  • Loading branch information
Bowen7 committed Jul 30, 2024
1 parent f66d030 commit b4a7155
Show file tree
Hide file tree
Showing 12 changed files with 1,670 additions and 256 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
"@vitejs/plugin-react-swc": "^3.7.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"hex-rgb": "^5.0.0",
"i18next": "^21.6.16",
"i18next-browser-languagedetector": "^6.1.4",
"i18next-http-backend": "^1.4.0",
Expand All @@ -39,6 +38,7 @@
"jotai-immer": "^0.4.1",
"nanoid": "^3.1.16",
"react": "^18.1.0",
"react-aria": "^3.34.1",
"react-dom": "^18.1.0",
"react-i18next": "^11.16.7",
"react-resizable-panels": "^2.0.20",
Expand Down
1,521 changes: 1,469 additions & 52 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions src/components/button-dropdown/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { CaretDownIcon } from '@radix-ui/react-icons'
import { Button } from '@/components/ui/button'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'

interface Props {
children: React.ReactNode
buttonProps?: React.ComponentProps<typeof Button>
}

export const ButtonDropdownItem = DropdownMenuItem

export function ButtonDropdown(props: Props) {
const { buttonProps, children } = props
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon" {...buttonProps}>
<CaretDownIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuGroup>
{children}
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}
File renamed without changes.
152 changes: 37 additions & 115 deletions src/components/range-input/index.tsx
Original file line number Diff line number Diff line change
@@ -1,137 +1,59 @@
import React, { useMemo, useRef, useState } from 'react'
import { TrashIcon } from '@radix-ui/react-icons'; import { useOnClickOutside } from 'usehooks-ts'
import Input from '../input'
import React from 'react'
import { Trash as TrashIcon } from '@phosphor-icons/react'
import clsx from 'clsx'
import { Input } from '@/components/ui/input'
import { useFocus } from '@/utils/hooks/use-focus'
import { useHover } from '@/utils/hooks/use-hover'

interface Prop {
className?: string
start: string
end: string
startPlaceholder?: string
endPlaceholder?: string
width?: number
removable?: boolean
controlled?: boolean
onChange: (start: string, end: string) => void
onRemove?: () => void
validate?: (start: string, end: string) => null | string
}
const RangeOption: React.FC<Prop> = ({
export const RangeInput: React.FC<Prop> = ({
className,
start,
end,
startPlaceholder = '',
endPlaceholder = '',
width = 186,
removable = false,
controlled = true,
removable = true,
onChange,
onRemove,
validate,
}) => {
// const { palette } = useTheme()
const { hovered, hoverProps } = useHover()
const { focused, focusProps } = useFocus()
const removeBtnVisible = hovered || focused

const [focused, setFocused] = useState(false)
const [hovered, setHovered] = useState(false)
const [error, setError] = useState<null | string>(null)

const [defaultStart] = useState(start)
const [defaultEnd] = useState(end)

const wrapRef = useRef<HTMLDivElement>(null)
const startRef = useRef<string>(start)
const endRef = useRef<string>(end)

// const borderColor = useMemo(() => {
// if (error) {
// return palette.error
// }
// if (focused) {
// return palette.success
// }
// return palette.accents_2
// }, [palette, focused, error])

useOnClickOutside(wrapRef, () => setFocused(false))
const handleWrapperClick = () => setFocused(true)

const handleInputChange = (key: 'start' | 'end', value: string) => {
if (key === 'start') {
startRef.current = value
}
else {
endRef.current = value
}
const error
= (validate && validate(startRef.current, endRef.current)) || null
setError(error)
if (error === null) {
onChange(startRef.current, endRef.current)
}
}
return (
<>
<div
ref={wrapRef}
className="range-wrapper"
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
<div
className="range-content"
onClick={handleWrapperClick}
style={{ width }}
>
<Input
value={controlled ? start : defaultStart}
placeholder={startPlaceholder}
onChange={(value: string) => handleInputChange('start', value)}
/>
<span>{' - '}</span>
<Input
value={controlled ? end : defaultEnd}
placeholder={endPlaceholder}
onChange={(value: string) => handleInputChange('end', value)}
/>
</div>
{removable && (focused || hovered) && (
<span className="operations">
{/* <TrashIcon size={18} color={palette.accents_6} onClick={onRemove} /> */}
</span>
)}
<div {...hoverProps} {...focusProps} className={clsx('flex items-center', className)}>
<div className="flex items-center space-x-2">
<Input
className="flex-1"
value={start}
placeholder={startPlaceholder}
onChange={(value: string) => handleInputChange('start', value)}
/>
<span>{' - '}</span>
<Input
className="flex-1"
value={end}
placeholder={endPlaceholder}
onChange={(value: string) => handleInputChange('end', value)}
/>
</div>
{error && <div className="error-msg">{error}</div>}
{/* <style jsx>
{`
.range-wrapper {
display: flex;
align-items: center;
}
.range-content {
display: flex;
align-items: center;
border: 1px solid ${borderColor};
border-radius: 5px;
}
.range-content :global(.input-wrapper) {
border: none;
}
.range-content :global(input) {
text-align: center;
}
.operations {
display: inline-block;
padding: 0 12px;
}
.operations > :global(svg) {
vertical-align: middle;
}
.error-msg {
color: ${palette.error};
}
`}
</style> */}
</>
{removable && (
<span className={clsx('p-2 cursor-pointer', {
invisible: !removeBtnVisible,
})}
>
<TrashIcon className="w-4 h-4" onClick={onRemove} />
</span>
)}
</div>
)
}
export default RangeOption
2 changes: 1 addition & 1 deletion src/modules/editor/features/content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const ContentEditor: React.FC<Prop> = ({ content, id, quantifier }) => {
}

return (
<Cell label={t('Content')} className="space-y-4">
<Cell label={t('Content')} className="space-y-6">
<Cell.Item label={t('Type')}>
<div className="flex items-center space-x-2">
<Select value={content.kind} onValueChange={onTypeChange}>
Expand Down
58 changes: 40 additions & 18 deletions src/modules/editor/features/content/ranges.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import { PlusCircledIcon } from '@radix-ui/react-icons'
import { useSetAtom } from 'jotai'
import RangeOption from '@/components/range-option'
import { Button } from '@/components/ui/button'
import { RangeInput } from '@/components/range-input'
import Cell from '@/components/cell'
import type { AST } from '@/parser'
import { updateContentAtom } from '@/atom'
import { ButtonDropdown, ButtonDropdownItem } from '@/components/button-dropdown'

interface Prop {
ranges: AST.Range[]
negate: boolean
}

const commonUsedRanges = [
{ from: '', to: '', desc: 'A Empty Range' },
// { from: '', to: '', desc: 'An Empty Range' },
{ from: '0', to: '9', desc: '0 - 9' },
{ from: 'a', to: 'z', desc: 'a - z' },
{ from: 'A', to: 'Z', desc: 'A - Z' },
Expand Down Expand Up @@ -64,17 +67,35 @@ const Ranges: React.FC<Prop> = ({ ranges, negate }) => {

return (
<Cell.Item label={t('Ranges')}>
<div className="range-options">
{ranges.map((range, index) => (
<RangeOption
range={range}
key={index}
onChange={(range: AST.Range) => handleRangeChange(index, range)}
onRemove={() => handleRemove(index)}
/>
))}
</div>
{/* <Spacer h={0.5} />
<div className="space-y-4">
<div className="space-y-2">
{ranges.map((range, index) => (
<RangeInput
start={range.from}
end={range.to}
key={index}
onChange={(range: AST.Range) => handleRangeChange(index, range)}
onRemove={() => handleRemove(index)}
/>
))}
</div>
<div className="flex items-center space-x-2">
<Button variant="outline" className="font-normal">
<PlusCircledIcon className="mr-2 h-4 w-4" />
An Empty Range
</Button>
<ButtonDropdown>
{commonUsedRanges.map(({ from, to, desc }, index) => (
<ButtonDropdownItem
onClick={() => handleAdd([{ from, to }])}
key={index}
>
{desc}
</ButtonDropdownItem>
))}
</ButtonDropdown>
</div>
{/* <Spacer h={0.5} />
<ButtonDropdown scale={0.75}>
{commonUsedRanges.map(({ from, to, desc }, index) => (
<ButtonDropdown.Item
Expand All @@ -86,13 +107,13 @@ const Ranges: React.FC<Prop> = ({ ranges, negate }) => {
</ButtonDropdown.Item>
))}
</ButtonDropdown> */}
<Cell.Item label="Negate">
{/* <Checkbox checked={negate} onChange={onGreedyChange}>
<Cell.Item label="Negate">
{/* <Checkbox checked={negate} onChange={onGreedyChange}>
{t('negate')}
</Checkbox> */}
<></>
</Cell.Item>
{/* <style jsx>
<></>
</Cell.Item>
{/* <style jsx>
{`
h6 {
color: ${palette.secondary};
Expand All @@ -103,6 +124,7 @@ const Ranges: React.FC<Prop> = ({ ranges, negate }) => {
}
`}
</style> */}
</div>
</Cell.Item>
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/editor/features/content/simple-string.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const SimpleString: React.FC<Props> = ({ value, quantifier }) => {
<Cell.Item label={t('Value')}>
<div className="space-y-2">
<Alert className="p-2">
<RocketIcon className="h-5 w-5" />
<RocketIcon className="h-4 w-4" />
<AlertDescription className="!pl-9">
{t('The input will be escaped automatically.')}
</AlertDescription>
Expand Down
4 changes: 2 additions & 2 deletions src/modules/editor/features/insert/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Cell from '@/components/cell'
import ShowMore from '@/components/show-more'
import type { AST } from '@/parser'
import { groupSelectedAtom, insertAtom, lookAroundSelectedAtom } from '@/atom'
import { ButtonGroup } from '@/components/ui/button-group'
import { ButtonGroup } from '@/components/button-group'
import { Button } from '@/components/ui/button'

interface Props {
Expand Down Expand Up @@ -109,7 +109,7 @@ const Insert: React.FC<Props> = ({ nodes }) => {
lookAroundSelected(kind as 'lookahead' | 'lookbehind')

return (
<div className="space-y-4">
<div className="space-y-6">
{insertOptions.length > 0 && (
<Cell label={t('Insert around')}>
<ButtonGroup variant="outline">
Expand Down
Loading

0 comments on commit b4a7155

Please sign in to comment.