Add EditableCell
This commit is contained in:
16
front/package-lock.json
generated
16
front/package-lock.json
generated
@ -24,6 +24,7 @@
|
|||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"libphonenumber-js": "^1.10.26",
|
"libphonenumber-js": "^1.10.26",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-contenteditable": "^3.3.7",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-router-dom": "^6.4.4",
|
"react-router-dom": "^6.4.4",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
@ -13257,8 +13258,7 @@
|
|||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/fast-diff": {
|
"node_modules/fast-diff": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
@ -22371,6 +22371,18 @@
|
|||||||
"react-dom": ">=16.8.0"
|
"react-dom": ">=16.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-contenteditable": {
|
||||||
|
"version": "3.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-contenteditable/-/react-contenteditable-3.3.7.tgz",
|
||||||
|
"integrity": "sha512-GA9NbC0DkDdpN3iGvib/OMHWTJzDX2cfkgy5Tt98JJAbA3kLnyrNbBIpsSpPpq7T8d3scD39DHP+j8mAM7BIfQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"prop-types": "^15.7.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-dev-utils": {
|
"node_modules/react-dev-utils": {
|
||||||
"version": "12.0.1",
|
"version": "12.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"libphonenumber-js": "^1.10.26",
|
"libphonenumber-js": "^1.10.26",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-contenteditable": "^3.3.7",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-router-dom": "^6.4.4",
|
"react-router-dom": "^6.4.4",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
|
|||||||
68
front/src/components/table/EditableCell.tsx
Normal file
68
front/src/components/table/EditableCell.tsx
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
import * as React from 'react';
|
||||||
|
import ContentEditable, { ContentEditableEvent } from 'react-contenteditable';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
content: string;
|
||||||
|
changeHandler: (updated: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledEditable = styled.div`
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -1px;
|
||||||
|
left: -1px;
|
||||||
|
width: calc(100% + 2px);
|
||||||
|
height: calc(100% + 2px);
|
||||||
|
border: 1px solid ${(props) => props.theme.text20};
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 4px;
|
||||||
|
pointer-events: none;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:hover::before {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
[contenteditable] {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Container = styled.span`
|
||||||
|
padding-left: ${(props) => props.theme.spacing(2)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
function escapeHTML(unsafeText: string): string {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.innerText = unsafeText;
|
||||||
|
return div.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EditableCell({ content, changeHandler }: OwnProps) {
|
||||||
|
const ref = React.createRef<HTMLElement>();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledEditable>
|
||||||
|
<Container>
|
||||||
|
<ContentEditable
|
||||||
|
innerRef={ref}
|
||||||
|
html={escapeHTML(content)}
|
||||||
|
disabled={false}
|
||||||
|
onChange={(e: ContentEditableEvent) => changeHandler(e.target.value)}
|
||||||
|
tagName="span"
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
|
</StyledEditable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditableCell;
|
||||||
Reference in New Issue
Block a user