Skip to content

Commit

Permalink
Merge pull request #9 from PaulZhemanov/editable_titles
Browse files Browse the repository at this point in the history
Editable titles
  • Loading branch information
PaulZhemanov authored Oct 13, 2023
2 parents cda94dc + e73718b commit 63cce3c
Show file tree
Hide file tree
Showing 18 changed files with 588 additions and 226 deletions.
310 changes: 158 additions & 152 deletions config/webpack.config.js

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "todolist2.0",
"version": "0.1.0",
"private": true,
"homepage": "https://paulzhemanov.github.io/todolist2.0/",
"dependencies": {
"@babel/core": "^7.16.0",
"@emotion/styled": "^11.11.0",
Expand Down Expand Up @@ -37,6 +38,8 @@
"jest-resolve": "^27.4.2",
"jest-watch-typeahead": "^1.0.0",
"mini-css-extract-plugin": "^2.4.5",
"mobx": "^6.10.2",
"mobx-react": "^9.0.1",
"postcss": "^8.4.4",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-loader": "^6.2.1",
Expand Down Expand Up @@ -66,7 +69,9 @@
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
"test": "node scripts/test.js",
"deploy": "gh-pages -d build",
"predeploy": "npm run build"
},
"eslintConfig": {
"extends": [
Expand Down
14 changes: 7 additions & 7 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from "react"
import "./App.css"
import styled from "@emotion/styled"
import TodoList from "./components/Todolist"
import SizedBox from "./components/SizeBox"
import Header from "./components/Header"
import TodoList from "@components/Todolist"
import SizedBox from "@components/SizeBox"
import Header from "@components/Header"

const Root = styled.div`
display: flex;
Expand All @@ -30,10 +30,10 @@ function App() {
<Header />
<Body>
<TodoList />
<SizedBox width={10} />
<TodoList />
<SizedBox width={10} />
<TodoList />
{/*<SizedBox width={10} />*/}
{/*<TodoList />*/}
{/*<SizedBox width={10} />*/}
{/*<TodoList />*/}
</Body>
</Root>
)
Expand Down
92 changes: 92 additions & 0 deletions src/components/EditableTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import styled from "@emotion/styled"
import React, { ChangeEvent, useEffect, useRef, useState } from "react"
import {IEditableInputProps, StyledInput, StyledText} from "@components/StyledInput";

interface IProps extends IEditableInputProps{
onChange?: (str: string) => void
title?: string
}

const Root = styled.div`
display: flex;
flex-direction: column;
width: auto;
height: 27px;
`

const EditableTitle: React.FC<IProps> = ({
fontSize,
color,
fontWeight,
textTransform,
showUnderline = false,
opacity,
title = "",
inputLength,
...rest
}) => {
// const [title, setTitle] = useState<string>(startTitle)
// const inputStore = new InputStore()
const [editing, setEditing] = useState<boolean>(false)
const inputRef = useRef<HTMLInputElement>(null)

const handleTitleClick = () => {
setEditing(true)
}

const handleTitleChange = (event: ChangeEvent<HTMLInputElement>) => {
rest.onChange && rest.onChange(event?.target.value ?? "")
}

const handleTitleFix = () => {
if (title.trim() !== "") {
setEditing(false)
}
}

const handleTitleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === "Enter" || event.key === "Escape") {
handleTitleFix()
}
}

useEffect(() => {
if (editing && inputRef.current) {
inputRef.current.focus()
const length = title.length
inputRef.current.setSelectionRange(length, length)
}
}, [editing, title])
return (
<Root>
{editing ? (
<StyledInput
ref={inputRef}
value={title}
onChange={handleTitleChange}
onBlur={handleTitleFix}
onKeyDown={handleTitleKeyDown}
fontSize={fontSize}
color={color}
fontWeight={fontWeight}
textTransform={textTransform}
showUnderline={showUnderline}
opacity={opacity}
maxLength={inputLength}
/>
) : (
<StyledText
onDoubleClick={handleTitleClick}
fontSize={fontSize}
textTransform={textTransform}
opacity={opacity}
fontWeight={fontWeight}
color={color}
>
{title}
</StyledText>
)}
</Root>
)
}
export default EditableTitle
20 changes: 10 additions & 10 deletions src/components/Flex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ export const Row = styled.div<IFlexProps>`
mainAxisSize === "fit-content" ? "fit-content" : "100%"};
`;

export const Column = styled.div<IFlexProps>`
display: flex;
flex-direction: column;
justify-content: ${({ justifyContent }) => justifyContent ?? "start"};
align-items: ${({ alignItems }) => alignItems ?? "start"};
width: ${({ crossAxisSize }) =>
crossAxisSize === "max" ? "100%" : "fit-content"};
height: ${({ mainAxisSize }) =>
mainAxisSize === "stretch" ? "100%" : "fit-content"};
`;
// export const Column = styled.div<IFlexProps>`
// display: flex;
// flex-direction: column;
// justify-content: ${({ justifyContent }) => justifyContent ?? "start"};
// align-items: ${({ alignItems }) => alignItems ?? "start"};
// width: ${({ crossAxisSize }) =>
// crossAxisSize === "max" ? "100%" : "fit-content"};
// height: ${({ mainAxisSize }) =>
// mainAxisSize === "stretch" ? "100%" : "fit-content"};
// `;
13 changes: 11 additions & 2 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import React from "react"
import { Text } from "./Text"
import { Row } from "./Flex"
import SizedBox from "./SizeBox"
import add from "../assets/icons/Add.svg"
import add from "@assets/icons/Add.svg"
import {useStores} from "@stores";
import Task from "@components/Task";
import {TASK_STATUS, TTask} from "@stores/TaskStore";

interface IProps {}

Expand Down Expand Up @@ -38,14 +41,20 @@ const StyledRow = styled(Row)`
`

const Header: React.FC<IProps> = () => {
const {taskStore} = useStores()
let defaultTask: TTask = {
title: "New task",
description: "Blablabla",
status: TASK_STATUS.ACTIVE
}
return (
<Root>
<Title>Project name</Title>
<SizedBox height={24} />

<StyledRow>
<SubTitile>Add new column</SubTitile>
<Add />
<Add onClick={() => taskStore.addTask(defaultTask)} />
</StyledRow>
</Root>
)
Expand Down
39 changes: 39 additions & 0 deletions src/components/StyledInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {Text} from "@components/Text";
import styled from "@emotion/styled";

export interface IEditableInputProps {
fontSize?: string
color?: string
fontWeight?: string
textTransform?: string
showUnderline?: boolean
opacity?: string
startTitle?: string
inputLength?: number | undefined
}

export const StyledInput = styled.input<IEditableInputProps>`
border: none;
outline: none;
background: transparent;
font-size: ${(props) => (props.fontSize ? props.fontSize : "inherit")};
opacity: ${(props) => (props.opacity ? props.opacity : "inherit")};
color: ${(props) => (props.color ? props.color : "inherit")};
font-weight: ${(props) => (props.fontWeight ? props.fontWeight : "inherit")};
text-transform: ${(props) =>
props.textTransform ? props.textTransform : "inherit"};
border-bottom: ${(props) =>
props.showUnderline ? "2px solid #000" : "none"};
maxlength: ${(props) => (props.inputLength ? props.inputLength : "inherit")};
`


export const StyledText = styled(Text)<IEditableInputProps>`
font-size: ${(props) => (props.fontSize ? props.fontSize : "inherit")};
text-transform: ${(props) =>
props.textTransform ? props.textTransform : "inherit"};
opacity: ${(props) => (props.opacity ? props.opacity : "inherit")};
font-weight: ${(props) => (props.fontWeight ? props.fontWeight : "inherit")};
color: ${(props) => (props.color ? props.color : "inherit")};
`
Loading

0 comments on commit 63cce3c

Please sign in to comment.