feat: feature/mvp-sprint-1 Progress commit on editable text
This commit is contained in:
parent
804f356adc
commit
b20c4eb091
@ -5,6 +5,9 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
react-contenteditable:
|
||||
specifier: ^3.3.7
|
||||
version: 3.3.7(react@18.2.0)
|
||||
smarts:
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
@ -351,6 +354,10 @@ packages:
|
||||
engines: {node: '>=0.8.0'}
|
||||
dev: false
|
||||
|
||||
/fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: false
|
||||
|
||||
/gensync@1.0.0-beta.2:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@ -386,6 +393,13 @@ packages:
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/loose-envify@1.4.0:
|
||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
dev: false
|
||||
|
||||
/lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
dependencies:
|
||||
@ -400,6 +414,11 @@ packages:
|
||||
resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==}
|
||||
dev: false
|
||||
|
||||
/object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/picocolors@1.0.0:
|
||||
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
|
||||
dev: false
|
||||
@ -410,6 +429,35 @@ packages:
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/prop-types@15.8.1:
|
||||
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
react-is: 16.13.1
|
||||
dev: false
|
||||
|
||||
/react-contenteditable@3.3.7(react@18.2.0):
|
||||
resolution: {integrity: sha512-GA9NbC0DkDdpN3iGvib/OMHWTJzDX2cfkgy5Tt98JJAbA3kLnyrNbBIpsSpPpq7T8d3scD39DHP+j8mAM7BIfQ==}
|
||||
peerDependencies:
|
||||
react: '>=16.3'
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/react-is@16.13.1:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
dev: false
|
||||
|
||||
/react@18.2.0:
|
||||
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
dev: false
|
||||
|
||||
/regenerator-runtime@0.13.11:
|
||||
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||
dev: false
|
||||
|
@ -156,15 +156,19 @@ export const Commander = (props) => {
|
||||
}, [inputValue])
|
||||
|
||||
const suggestions = React.useMemo(() => {
|
||||
const fuse = new Fuse(paths)
|
||||
try {
|
||||
const fuse = new Fuse(paths)
|
||||
|
||||
const results = fuse.search(inputValue)
|
||||
const results = fuse.search(inputValue)
|
||||
|
||||
const mappedResults = results?.map((result) => {
|
||||
return result?.item
|
||||
})
|
||||
const mappedResults = results?.map((result) => {
|
||||
return result?.item
|
||||
})
|
||||
|
||||
return mappedResults
|
||||
return mappedResults
|
||||
} catch (err) {
|
||||
console.error("nik fuse error", err)
|
||||
}
|
||||
}, [inputValue, paths])
|
||||
|
||||
const selectSuggestion = React.useCallback(
|
||||
@ -230,96 +234,101 @@ export const Commander = (props) => {
|
||||
else if (e?.code === "Escape") {
|
||||
closeCommander()
|
||||
}
|
||||
// if arrow keys then move selection
|
||||
else if (e?.code === "ArrowUp") {
|
||||
// move selection up
|
||||
const curSuggestionIdx =
|
||||
typeof hoveredSuggestion === "number"
|
||||
? hoveredSuggestion
|
||||
: suggestions?.length
|
||||
const newSuggestionIdx = curSuggestionIdx - 1
|
||||
if (newSuggestionIdx >= 0) {
|
||||
setHoveredSuggestion(newSuggestionIdx)
|
||||
} else {
|
||||
setHoveredSuggestion(suggestions?.length - 1)
|
||||
}
|
||||
} else if (e?.code === "ArrowDown") {
|
||||
// move selection down
|
||||
const curSuggestionIdx =
|
||||
typeof hoveredSuggestion === "number" ? hoveredSuggestion : -1
|
||||
const newSuggestionIdx = curSuggestionIdx + 1
|
||||
if (newSuggestionIdx < suggestions?.length) {
|
||||
setHoveredSuggestion(newSuggestionIdx)
|
||||
} else {
|
||||
setHoveredSuggestion(0)
|
||||
}
|
||||
} else if (e?.code === "Enter") {
|
||||
// if selection is active then select it
|
||||
const curSuggestionIdx = hoveredSuggestion
|
||||
if (curSuggestionIdx !== null) {
|
||||
selectSuggestion(curSuggestionIdx)
|
||||
}
|
||||
if (commanderActive) {
|
||||
try {
|
||||
// console.log("nik Commander onEnter")
|
||||
// console.log("nik commandIsAction", commandIsAction)
|
||||
// console.log("nik commandContainsPath", commandContainsPath)
|
||||
|
||||
// console.log("nik onEnter commandPath", commandPath)
|
||||
// only run these if commander active
|
||||
|
||||
if (commandIsAction) {
|
||||
// nothing
|
||||
const prevVal = getThingtime(commandPath)
|
||||
const parentPath = getParentPath(commandPath) || "thingtime"
|
||||
try {
|
||||
// first try to execute literal javscript
|
||||
const fn = `() => { return ${commandValue} }`
|
||||
const evalFn = eval(fn)
|
||||
const realVal = evalFn()
|
||||
// console.log("nik realVal", realVal)
|
||||
// console.log("nik prevVal", prevVal)
|
||||
// console.log("nik parentPath", parentPath)
|
||||
// console.log("nik commandPath", commandPath)
|
||||
setThingtime(commandPath, realVal)
|
||||
} catch (err) {
|
||||
console.log(
|
||||
"Caught error after trying to execute literal javascript",
|
||||
err
|
||||
)
|
||||
if (commanderActive) {
|
||||
// if arrow keys then move selection
|
||||
if (e?.code === "ArrowUp") {
|
||||
// move selection up
|
||||
const curSuggestionIdx =
|
||||
typeof hoveredSuggestion === "number"
|
||||
? hoveredSuggestion
|
||||
: suggestions?.length
|
||||
const newSuggestionIdx = curSuggestionIdx - 1
|
||||
if (newSuggestionIdx >= 0) {
|
||||
setHoveredSuggestion(newSuggestionIdx)
|
||||
} else {
|
||||
setHoveredSuggestion(suggestions?.length - 1)
|
||||
}
|
||||
} else if (e?.code === "ArrowDown") {
|
||||
// move selection down
|
||||
const curSuggestionIdx =
|
||||
typeof hoveredSuggestion === "number" ? hoveredSuggestion : -1
|
||||
const newSuggestionIdx = curSuggestionIdx + 1
|
||||
if (newSuggestionIdx < suggestions?.length) {
|
||||
setHoveredSuggestion(newSuggestionIdx)
|
||||
} else {
|
||||
setHoveredSuggestion(0)
|
||||
}
|
||||
} else if (e?.code === "Enter") {
|
||||
// if selection is active then select it
|
||||
const curSuggestionIdx = hoveredSuggestion
|
||||
if (curSuggestionIdx !== null) {
|
||||
selectSuggestion(curSuggestionIdx)
|
||||
}
|
||||
if (commanderActive) {
|
||||
try {
|
||||
// console.log("nik Commander onEnter")
|
||||
// console.log("nik commandIsAction", commandIsAction)
|
||||
// console.log("nik commandContainsPath", commandContainsPath)
|
||||
|
||||
// likely literaly javascript wasn't valid
|
||||
// console.log("nik onEnter commandPath", commandPath)
|
||||
|
||||
if (commandIsAction) {
|
||||
// nothing
|
||||
const prevVal = getThingtime(commandPath)
|
||||
const parentPath = getParentPath(commandPath) || "thingtime"
|
||||
try {
|
||||
const fn = `() => { return ${escapedCommandValue} }`
|
||||
// first try to execute literal javscript
|
||||
const fn = `() => { return ${commandValue} }`
|
||||
const evalFn = eval(fn)
|
||||
const realVal = evalFn()
|
||||
const prevVal = getThingtime(commandPath)
|
||||
const parentPath = getParentPath(commandPath)
|
||||
// console.log("nik realVal", realVal)
|
||||
// console.log("nik prevVal", prevVal)
|
||||
// console.log("nik parentPath", parentPath)
|
||||
// console.log("nik commandPath", commandPath)
|
||||
setThingtime(commandPath, realVal)
|
||||
} catch {
|
||||
// something very bad went wrong
|
||||
} catch (err) {
|
||||
console.log(
|
||||
"Caught error after trying to execute escaped literal javascript",
|
||||
"Caught error after trying to execute literal javascript",
|
||||
err
|
||||
)
|
||||
|
||||
// likely literaly javascript wasn't valid
|
||||
try {
|
||||
const fn = `() => { return ${escapedCommandValue} }`
|
||||
const evalFn = eval(fn)
|
||||
const realVal = evalFn()
|
||||
const prevVal = getThingtime(commandPath)
|
||||
const parentPath = getParentPath(commandPath)
|
||||
setThingtime(commandPath, realVal)
|
||||
} catch {
|
||||
// something very bad went wrong
|
||||
console.log(
|
||||
"Caught error after trying to execute escaped literal javascript",
|
||||
err
|
||||
)
|
||||
}
|
||||
}
|
||||
if (!prevVal) {
|
||||
setContextPath(commandPath)
|
||||
setShowContext(true, "commandIsAction check")
|
||||
}
|
||||
}
|
||||
if (!prevVal) {
|
||||
// if (commandContainsPath)
|
||||
else {
|
||||
// const prevValue = getThingtime(commandPath)
|
||||
|
||||
// const newValue = setThingtime(commandPath, prevValue)
|
||||
|
||||
console.log("Setting context path", commandPath)
|
||||
setContextPath(commandPath)
|
||||
setShowContext(true, "commandIsAction check")
|
||||
setShowContext(true, "commandContainsPath check")
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Caught error on commander onEnter", err)
|
||||
}
|
||||
// if (commandContainsPath)
|
||||
else {
|
||||
// const prevValue = getThingtime(commandPath)
|
||||
|
||||
// const newValue = setThingtime(commandPath, prevValue)
|
||||
|
||||
console.log("Setting context path", commandPath)
|
||||
setContextPath(commandPath)
|
||||
setShowContext(true, "commandContainsPath check")
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Caught error on commander onEnter", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -334,7 +343,6 @@ export const Commander = (props) => {
|
||||
thingtimeRef,
|
||||
commanderActive,
|
||||
commandIsAction,
|
||||
commandContainsPath,
|
||||
commandPath,
|
||||
commandValue,
|
||||
escapedCommandValue,
|
||||
@ -439,16 +447,18 @@ export const Commander = (props) => {
|
||||
)
|
||||
})}
|
||||
</Flex>
|
||||
<Flex
|
||||
display={showContext ? "flex" : "none"}
|
||||
maxWidth="100%"
|
||||
background="grey"
|
||||
borderRadius="12px"
|
||||
pointerEvents="all"
|
||||
paddingY={3}
|
||||
>
|
||||
<Thingtime path={contextPath} thing={contextValue}></Thingtime>
|
||||
</Flex>
|
||||
{showContext && (
|
||||
<Flex
|
||||
display={showContext ? "flex" : "none"}
|
||||
maxWidth="100%"
|
||||
background="grey"
|
||||
borderRadius="12px"
|
||||
pointerEvents="all"
|
||||
paddingY={3}
|
||||
>
|
||||
<Thingtime path={contextPath} thing={contextValue}></Thingtime>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Center
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from "react"
|
||||
import ContentEditable from "react-contenteditable"
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
@ -27,6 +28,8 @@ export const Thingtime = (props) => {
|
||||
|
||||
const [circular, setCircular] = React.useState(props?.circular)
|
||||
|
||||
const contentEditableRef = React.useRef(null)
|
||||
|
||||
const depth = React.useMemo(() => {
|
||||
return props?.depth || 1
|
||||
}, [props?.depth])
|
||||
@ -221,6 +224,7 @@ export const Thingtime = (props) => {
|
||||
mode,
|
||||
circular,
|
||||
seen,
|
||||
fullPath,
|
||||
depth,
|
||||
thing,
|
||||
props,
|
||||
@ -236,6 +240,7 @@ export const Thingtime = (props) => {
|
||||
<Flex
|
||||
flexDirection="row"
|
||||
flexShrink={1}
|
||||
width="100%"
|
||||
paddingLeft={pl}
|
||||
fontSize="20px"
|
||||
border="none"
|
||||
@ -251,6 +256,22 @@ export const Thingtime = (props) => {
|
||||
[pl]
|
||||
)
|
||||
|
||||
const updatedRef = React.useRef(false)
|
||||
|
||||
const [contentEditableThing, setContentEditableThing] = React.useState(thing)
|
||||
|
||||
React.useEffect(() => {
|
||||
console.log("nik detected thing changed")
|
||||
console.log("nik thing", thing)
|
||||
console.log("nik contentEditableThing", contentEditableThing)
|
||||
console.log("nik updatedRef?.current", updatedRef?.current)
|
||||
if (!updatedRef?.current && contentEditableThing !== thing) {
|
||||
console.log("nik setting content editable thing", thing)
|
||||
setContentEditableThing(thing)
|
||||
}
|
||||
updatedRef.current = false
|
||||
}, [thing, updatedRef, contentEditableThing, contentEditableRef])
|
||||
|
||||
const updateValue = React.useCallback(
|
||||
(args) => {
|
||||
const { value } = args
|
||||
@ -259,11 +280,13 @@ export const Thingtime = (props) => {
|
||||
console.log("nik props?.fullPath", fullPath)
|
||||
|
||||
setThingtime(fullPath, value)
|
||||
updatedRef.current = true
|
||||
},
|
||||
[fullPath, setThingtime]
|
||||
)
|
||||
|
||||
const atomicValue = React.useMemo(() => {
|
||||
console.log("nik contentEditableThing", contentEditableThing)
|
||||
if (props?.edit) {
|
||||
if (type === "boolean") {
|
||||
return (
|
||||
@ -321,9 +344,41 @@ export const Thingtime = (props) => {
|
||||
</AtomicWrapper>
|
||||
)
|
||||
}
|
||||
if (type === "string") {
|
||||
return (
|
||||
<AtomicWrapper>
|
||||
<Box
|
||||
ref={contentEditableRef}
|
||||
width="100%"
|
||||
border="none"
|
||||
outline="none"
|
||||
contentEditable={true}
|
||||
onInput={(value) => {
|
||||
console.log("nik value", value)
|
||||
|
||||
const innerText = value?.target?.innerText
|
||||
|
||||
if (typeof innerText === "string") {
|
||||
updateValue({ value: innerText })
|
||||
}
|
||||
}}
|
||||
>
|
||||
{contentEditableThing}
|
||||
</Box>
|
||||
</AtomicWrapper>
|
||||
)
|
||||
}
|
||||
}
|
||||
return <AtomicWrapper>{renderableValue}</AtomicWrapper>
|
||||
}, [renderableValue, AtomicWrapper, type, props?.edit, thing, updateValue])
|
||||
}, [
|
||||
renderableValue,
|
||||
contentEditableThing,
|
||||
AtomicWrapper,
|
||||
type,
|
||||
props?.edit,
|
||||
thing,
|
||||
updateValue,
|
||||
])
|
||||
|
||||
const contextMenu = (
|
||||
<Flex
|
||||
|
@ -25,6 +25,7 @@
|
||||
"lodash-es": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-click-away-listener": "^2.2.3",
|
||||
"react-contenteditable": "^3.3.7",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^4.10.1",
|
||||
"tinygradient": "^1.1.5",
|
||||
@ -50,6 +51,9 @@
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"typescript": "^4.9.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "^17.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
|
@ -56,6 +56,9 @@ dependencies:
|
||||
react-click-away-listener:
|
||||
specifier: ^2.2.3
|
||||
version: 2.2.3(react-dom@18.2.0)(react@18.2.0)
|
||||
react-contenteditable:
|
||||
specifier: ^3.3.7
|
||||
version: 3.3.7(react@18.2.0)
|
||||
react-dom:
|
||||
specifier: ^18.2.0
|
||||
version: 18.2.0(react@18.2.0)
|
||||
@ -6017,7 +6020,6 @@ packages:
|
||||
|
||||
/fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: true
|
||||
|
||||
/fast-diff@1.3.0:
|
||||
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
|
||||
@ -8536,6 +8538,16 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/react-contenteditable@3.3.7(react@18.2.0):
|
||||
resolution: {integrity: sha512-GA9NbC0DkDdpN3iGvib/OMHWTJzDX2cfkgy5Tt98JJAbA3kLnyrNbBIpsSpPpq7T8d3scD39DHP+j8mAM7BIfQ==}
|
||||
peerDependencies:
|
||||
react: '>=16.3'
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/react-dom@18.2.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
|
||||
peerDependencies:
|
||||
|
Loading…
Reference in New Issue
Block a user