Split out aliases components
This commit is contained in:
parent
a7568c1bb2
commit
26d5677546
121
src/App.tsx
121
src/App.tsx
@ -1,18 +1,10 @@
|
||||
import {
|
||||
ChangeEventHandler, Dispatch,
|
||||
KeyboardEventHandler,
|
||||
MouseEventHandler,
|
||||
ReactNode, SetStateAction,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState
|
||||
} from "react";
|
||||
import {ReactNode, useCallback, useState} from "react";
|
||||
import {FixedSizeList as List} from "react-window";
|
||||
import Select, {createFilter, MenuListProps} from "react-select";
|
||||
import * as R from 'ramda';
|
||||
|
||||
import {useQuery} from "@tanstack/react-query";
|
||||
import {Alias, CustomAlias, Option} from "./aliases";
|
||||
|
||||
// TODO: Fix this for wrapping items, esp on phones
|
||||
const height = 35;
|
||||
@ -44,15 +36,6 @@ function MenuList(props: MenuListProps) {
|
||||
</List>);
|
||||
}
|
||||
|
||||
interface Option {
|
||||
label: string,
|
||||
value: string,
|
||||
data: {
|
||||
backlinks: unknown[]
|
||||
aliases?: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export function LargeSelect() {
|
||||
const {
|
||||
data: options,
|
||||
@ -110,103 +93,3 @@ export function LargeSelect() {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CustomAlias({selected}: {
|
||||
selected: Option
|
||||
}) {
|
||||
const [alias, setAlias] = useState('');
|
||||
|
||||
// Reset when selection changes
|
||||
useEffect(() => {
|
||||
setAlias('');
|
||||
}, [selected.value]);
|
||||
|
||||
const onClick: MouseEventHandler = useCallback((e) => {
|
||||
if ((e.target as HTMLElement).tagName == 'SPAN' && alias.length > 0) {
|
||||
navigator.clipboard.writeText(`[[${selected!.label}|${alias}]]`);
|
||||
}
|
||||
}, [selected.value, selected.label, alias]);
|
||||
|
||||
return (
|
||||
<span onClick={onClick} className={"rounded-md p-1 hover:bg-slate-100"}>
|
||||
<span className={"text-slate-300 p-0.5"}>[[</span>
|
||||
<span>{selected.label}</span>
|
||||
<span className={"text-slate-300 p-0.5"}>|</span>
|
||||
<span>
|
||||
<CustomAliasField content={alias} setContent={setAlias} selected={selected}/>
|
||||
</span>
|
||||
<span className={"text-slate-300 p-0.5"}>]]</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
function CustomAliasField({
|
||||
selected,
|
||||
content,
|
||||
setContent
|
||||
}: {
|
||||
selected: Option,
|
||||
content: string,
|
||||
setContent: Dispatch<SetStateAction<string>>,
|
||||
}) {
|
||||
const [width, setWidth] = useState<any>(0);
|
||||
const span = useRef<HTMLSpanElement>(null);
|
||||
|
||||
// Resize on change of content
|
||||
useEffect(() => {
|
||||
setWidth(span.current!.offsetWidth);
|
||||
// setWidth(content.length + 'ch');
|
||||
}, [content]);
|
||||
|
||||
const changeHandler: ChangeEventHandler<HTMLInputElement> = useCallback(evt => {
|
||||
setContent(evt.target.value);
|
||||
}, []);
|
||||
|
||||
const onCustomElementKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback((e) => {
|
||||
if (e.key == 'Enter') {
|
||||
navigator.clipboard.writeText(`[[${selected!.label}|${content}]]`);
|
||||
(e.target as HTMLInputElement).blur()
|
||||
}
|
||||
}, [selected.value, selected.label, content]);
|
||||
|
||||
return (
|
||||
<span>
|
||||
<span style={{
|
||||
position: 'absolute',
|
||||
opacity: 0,
|
||||
zIndex: -100,
|
||||
whiteSpace: 'pre',
|
||||
}} ref={span}>{content}</span>
|
||||
<input
|
||||
className={"border-none p-0 px-1"}
|
||||
type="text" style={{width: `calc(${width}px + 0.25rem)`}} autoFocus onChange={changeHandler}
|
||||
onKeyDown={onCustomElementKeyDown}/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function Alias({
|
||||
original,
|
||||
alias
|
||||
}: {
|
||||
original: string,
|
||||
alias?: string
|
||||
}) {
|
||||
const onClick = useCallback(() => {
|
||||
if (alias) {
|
||||
navigator.clipboard.writeText(`[[${original}|${alias}]]`)
|
||||
} else {
|
||||
navigator.clipboard.writeText(`[[${original}]]`)
|
||||
}
|
||||
}, [original, alias]);
|
||||
|
||||
return (
|
||||
<span className={"rounded-md p-1 hover:bg-slate-100"} onClick={onClick}>
|
||||
<span className={"text-slate-300 p-0.5"}>[[</span>
|
||||
<span>{original}</span>
|
||||
{alias && <><span className={"text-slate-300 p-0.5"}>|</span>
|
||||
<span>{alias}</span></>}
|
||||
<span className={"text-slate-300 p-0.5"}>]]</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
120
src/aliases.tsx
Normal file
120
src/aliases.tsx
Normal file
@ -0,0 +1,120 @@
|
||||
import {
|
||||
ChangeEventHandler,
|
||||
Dispatch,
|
||||
KeyboardEventHandler,
|
||||
MouseEventHandler,
|
||||
SetStateAction,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState
|
||||
} from "react";
|
||||
|
||||
export interface Option {
|
||||
label: string,
|
||||
value: string,
|
||||
data: {
|
||||
backlinks: unknown[]
|
||||
aliases?: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export function CustomAlias({selected}: {
|
||||
selected: Option
|
||||
}) {
|
||||
const [alias, setAlias] = useState('');
|
||||
|
||||
// Reset when selection changes
|
||||
useEffect(() => {
|
||||
setAlias('');
|
||||
}, [selected.value]);
|
||||
|
||||
const onClick: MouseEventHandler = useCallback((e) => {
|
||||
if ((e.target as HTMLElement).tagName == 'SPAN' && alias.length > 0) {
|
||||
navigator.clipboard.writeText(`[[${selected!.label}|${alias}]]`);
|
||||
}
|
||||
}, [selected.value, selected.label, alias]);
|
||||
|
||||
return (
|
||||
<span onClick={onClick} className={"rounded-md p-1 hover:bg-slate-100"}>
|
||||
<span className={"text-slate-300 p-0.5"}>[[</span>
|
||||
<span>{selected.label}</span>
|
||||
<span className={"text-slate-300 p-0.5"}>|</span>
|
||||
<span>
|
||||
<CustomAliasField content={alias} setContent={setAlias} selected={selected}/>
|
||||
</span>
|
||||
<span className={"text-slate-300 p-0.5"}>]]</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
function CustomAliasField({
|
||||
selected,
|
||||
content,
|
||||
setContent
|
||||
}: {
|
||||
selected: Option,
|
||||
content: string,
|
||||
setContent: Dispatch<SetStateAction<string>>,
|
||||
}) {
|
||||
const [width, setWidth] = useState<any>(0);
|
||||
const span = useRef<HTMLSpanElement>(null);
|
||||
|
||||
// Resize on change of content
|
||||
useEffect(() => {
|
||||
setWidth(span.current!.offsetWidth);
|
||||
// setWidth(content.length + 'ch');
|
||||
}, [content]);
|
||||
|
||||
const changeHandler: ChangeEventHandler<HTMLInputElement> = useCallback(evt => {
|
||||
setContent(evt.target.value);
|
||||
}, []);
|
||||
|
||||
const onCustomElementKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback((e) => {
|
||||
if (e.key == 'Enter') {
|
||||
navigator.clipboard.writeText(`[[${selected!.label}|${content}]]`);
|
||||
(e.target as HTMLInputElement).blur()
|
||||
}
|
||||
}, [selected.value, selected.label, content]);
|
||||
|
||||
return (
|
||||
<span>
|
||||
<span style={{
|
||||
position: 'absolute',
|
||||
opacity: 0,
|
||||
zIndex: -100,
|
||||
whiteSpace: 'pre',
|
||||
}} ref={span}>{content}</span>
|
||||
<input
|
||||
className={"border-none p-0 px-1"}
|
||||
type="text" style={{width: `calc(${width}px + 0.25rem)`}} autoFocus onChange={changeHandler}
|
||||
onKeyDown={onCustomElementKeyDown}/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export function Alias({
|
||||
original,
|
||||
alias
|
||||
}: {
|
||||
original: string,
|
||||
alias?: string
|
||||
}) {
|
||||
const onClick = useCallback(() => {
|
||||
if (alias) {
|
||||
navigator.clipboard.writeText(`[[${original}|${alias}]]`)
|
||||
} else {
|
||||
navigator.clipboard.writeText(`[[${original}]]`)
|
||||
}
|
||||
}, [original, alias]);
|
||||
|
||||
return (
|
||||
<span className={"rounded-md p-1 hover:bg-slate-100"} onClick={onClick}>
|
||||
<span className={"text-slate-300 p-0.5"}>[[</span>
|
||||
<span>{original}</span>
|
||||
{alias && <><span className={"text-slate-300 p-0.5"}>|</span>
|
||||
<span>{alias}</span></>}
|
||||
<span className={"text-slate-300 p-0.5"}>]]</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user