Editable tasks and project labels
This commit is contained in:
56
src/components/editable-text/index.tsx
Normal file
56
src/components/editable-text/index.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import { FunctionalComponent, h, Component, ComponentChild, Fragment } from "preact";
|
||||
import { Link } from "preact-router/match";
|
||||
import * as style from "./style.css";
|
||||
import { useState, useEffect } from "preact/hooks";
|
||||
|
||||
export interface EditableTextProps {
|
||||
value: string
|
||||
class?: string
|
||||
editIconClass?: string
|
||||
onChange?: (value: string) => void
|
||||
render: (value: string) => ComponentChild
|
||||
}
|
||||
|
||||
const EditableText: FunctionalComponent<EditableTextProps> = ({ onChange, value, render, ...props }) => {
|
||||
const [ internalValue, setInternalValue ] = useState(value);
|
||||
const [ editMode, setEditMode ] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (onChange) onChange(internalValue);
|
||||
}, [internalValue]);
|
||||
|
||||
const onEditIconClick = () => {
|
||||
setEditMode(true);
|
||||
};
|
||||
|
||||
const onValidateButtonClick = () => {
|
||||
setEditMode(false);
|
||||
}
|
||||
|
||||
const onValueChange = (evt: Event) => {
|
||||
const currentTarget = evt.currentTarget as HTMLInputElement;
|
||||
setInternalValue(currentTarget.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div class={`${style.editableText} ${props.class ? props.class : ''}`}>
|
||||
{
|
||||
editMode ?
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
<input class="input is-expanded" type="text" value={internalValue} onChange={onValueChange} />
|
||||
</div>
|
||||
<div class="control">
|
||||
<a class="button" onClick={onValidateButtonClick}>✔️</a>
|
||||
</div>
|
||||
</div> :
|
||||
<Fragment>
|
||||
{ render(internalValue) }
|
||||
<i class={`${style.editIcon} icon ${props.editIconClass ? props.editIconClass : ''}`} onClick={onEditIconClick}>🖋️</i>
|
||||
</Fragment>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditableText;
|
17
src/components/editable-text/style.css
Normal file
17
src/components/editable-text/style.css
Normal file
@ -0,0 +1,17 @@
|
||||
.editableText {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
.editableText > * {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.editIcon {
|
||||
visibility: hidden;
|
||||
margin-left: 0.25em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.editableText:hover > .editIcon {
|
||||
visibility: visible;
|
||||
}
|
3
src/components/editable-text/style.css.d.ts
vendored
Normal file
3
src/components/editable-text/style.css.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
// This file is automatically generated from your CSS. Any edits will be overwritten.
|
||||
export const editableText: string;
|
||||
export const editIcon: string;
|
Reference in New Issue
Block a user