Skip to content

Commit

Permalink
v1.3.8
Browse files Browse the repository at this point in the history
  • Loading branch information
Nickolay Stepanov (Nick) committed Feb 1, 2022
1 parent 81a9d28 commit c762dc0
Show file tree
Hide file tree
Showing 17 changed files with 387 additions and 35 deletions.
2 changes: 1 addition & 1 deletion doc/src/ui/HelpUs/HelpUs.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
height: 50px;
width: 100%;
bottom: 0;
background-color: #ff6f6f;
background-color: #ffc5c5;;
text-align: center;
display: flex;
flex-direction: row;
Expand Down
18 changes: 14 additions & 4 deletions experiments/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Basic } from './controlled/Basic/Basic';
import { Edit } from './controlled/Edit/Edit';
import { Basic as BasicUncontrolled } from './uncontrolled/Basic/Basic';
import { Edit as EditUncontrolled } from './uncontrolled/Edit/Edit';
import {Combined as CombinedBasic} from "./controlled/Combined/Combined";
import './index.css'

const App = () => {
Expand All @@ -17,16 +18,19 @@ const App = () => {
<nav>
<ul>
<li>
<Link to="/controlled">Controlled</Link>
<Link to="/controlled">Basic</Link>
</li>
<li>
<Link to="/uncontrolled">Uncontrolled</Link>
<Link to="/uncontrolled">Smart</Link>
</li>
<li>
<Link to="/edit-controlled">Edit Controlled</Link>
<Link to="/edit-controlled">Edit smart</Link>
</li>
<li>
<Link to="/edit-uncontrolled">Edit Uncontrolled</Link>
<Link to="/edit-uncontrolled">Edit smart</Link>
</li>
<li>
<Link to="/combined-basic">Combined basic</Link>
</li>
</ul>
</nav>
Expand All @@ -44,6 +48,12 @@ const App = () => {
<Route path="/edit-uncontrolled">
<EditUncontrolled />
</Route>
<Route path="/edit-uncontrolled">
<EditUncontrolled />
</Route>
<Route path="/combined-basic">
<CombinedBasic/>
</Route>
</Switch>
</div>
</Router>)
Expand Down
23 changes: 23 additions & 0 deletions experiments/src/controlled/Combined/Combined.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.form {
width: 100%;
max-width: 360px;
border: 1px solid #b5b5b5;
background-color: #fff;
border-radius: 4px;
}
.buttons {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 10px;
}
.count {
display: inline-flex;
width: 100%;
padding: 0 10px;
box-sizing: border-box;
flex-direction: row;
justify-content: flex-end;
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
}
99 changes: 99 additions & 0 deletions experiments/src/controlled/Combined/Combined.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React, { useMemo } from 'react';
import {useFormMod, useCountRender, Types} from "formmod";
import { Button, SearchSelect} from "../ui";
import { Item } from "../ui/SearchSelect/SearchSelect";
import FORM_SCHEME from "./scheme";
import styles from './Combined.module.css';

export function Combined({formValue}: any) {
const {
validate,
resetForm,
setViewMode,
isViewMode,
setValues,
getValue,
setValue,
getError,
} = useFormMod(
FORM_SCHEME,
);
// edit mode here
if(formValue){
setValues(formValue, true);
}

const handleSubmit = (event: React.SyntheticEvent) => {
if(event && event.preventDefault) {
event.preventDefault();
}
validate(true, (valid: boolean | null, formValue: Types.FormValue) => {
if(valid) {
//setViewMode(true);
console.log(formValue, 'RESULT TRUE');
} else {
console.log(formValue, 'RESULT FALSE');
}
});
};

const setDefault = (event: any) => {
if(event && event.preventDefault) {
event.preventDefault();
}
resetForm();
};

// count of render
const {getCountRender, counter} = useCountRender();
counter();
// count of render [END]

const edit = () => {
setViewMode(false);
};

const items = useMemo(() => [
{
id: "1",
value: "Student 1"
},
{
id: "2",
value: "Student 2"
},
{
id: "3",
value: "Student 3"
},
{
id: "4",
value: "Student 4"
},
{
id: "5",
value: "Student 5"
},
],[]);

return (
<form onSubmit={handleSubmit} className={styles.form}>
<div className={styles.count}>Count render: {getCountRender()}</div>
<SearchSelect
label="Select student from list"
selectedItem={getValue("student") as Item}
items={items}
onChangeItem={(item: Item) => setValue("student", item)}
onReset={() => {setValue("student", "", undefined, undefined, true)}}
error={getError("student")}
/>
{!isViewMode() && <div className={styles.buttons}>
<Button type="submit" title="Submit"/>
<Button theme="LIGHT" onClick={setDefault} title="Reset"/>
</div>}
{isViewMode() && <div className={styles.buttons}>
<Button onClick={edit} title="Edit"/>
</div>}
</form>
)
}
21 changes: 21 additions & 0 deletions experiments/src/controlled/Combined/scheme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Item } from "../ui/SearchSelect/SearchSelect";

export default {
valid: null,
formValue: {
student: null,
},
rules: {
student: [
{
name: "func",
params: {
func: (item: Item | null) => {
return item?.value !== undefined
}
},
message: "Please, select a student"
}
]
}
}
61 changes: 61 additions & 0 deletions experiments/src/controlled/ui/SearchSelect/SearchSelect.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
.container {
width: 100%;
padding: 10px;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.list {
width: 100%;
border: 1px solid #333;
border-radius: 5px;
overflow: hidden;
}
.item {
height: 30px;
display: flex;
flex-direction: row;
align-items: center;
padding: 0 20px;
box-sizing: border-box;
cursor: pointer;
}
.item:hover {
background-color: rgb(212, 212, 212);
}
.selectedContainer {
width: 100%;
padding: 10px;
display: flex;
flex-direction: column;
box-sizing: border-box;
position: relative;
}
.selectedLabel {
color: #54c270;
font-family: Arial;
font-size: 16px;
}
.selected {
width: 100%;
max-width: 360px;
height: 36px;
line-height: 36px;
background: #FFFFFF;
border: 1px solid #8a8a8a;
box-sizing: border-box;
border-radius: 4px;
padding-left: 6px;
font-family: Open Sans;
font-size: 14px;
color: #244D51;
box-sizing: border-box;
}
.reset {
position: absolute;
top: 36px;
right: 16px;
border: unset;
background-color: transparent;
cursor: pointer;
}
100 changes: 100 additions & 0 deletions experiments/src/controlled/ui/SearchSelect/SearchSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from 'react';
import {TextInput} from '../';
import {useFormMod} from "formmod";
import styles from './SearchSelect.module.css';

export type Item = {
id: string,
value: string
};

export type SearchSelectParams = {
label: string;
selectedItem: Item;
items: Array<Item>;
onChangeItem: (item: Item) => void;
onReset: () => void;
error: string | null;
};

export const SearchSelect = (props: SearchSelectParams) => {
const {
label,
selectedItem,
items,
onChangeItem,
onReset,
error,
} = props;
const SCHEME = {
valid: null,
formValue: {
searchText: "",
},
rules: {
searchText: [
{
name: "empty",
message: "first name is required"
}
]
}
};
const {
useRefMod,
getValue,
getError,
setValue,
} = useFormMod(
SCHEME,
);
const searchTextRef = useRefMod("searchText");
const handleSubmit = (event: React.KeyboardEvent<HTMLInputElement>) => {
if(event.key === 'Enter') {
event.preventDefault();

}
};

const resetInput = () => {
setValue("searchText", "", undefined, undefined, true);
onReset();
};

const onChangeInput = (value: string) => {
setValue("searchText", value);
}

const changeItem = (item: Item) => {
onChangeItem(item);
setValue("searchText", "", undefined, undefined, true);
};

const renderList = () => {
return items.filter((item) => {
return item.value.toLocaleLowerCase().indexOf(searchTextRef.getValue().toLocaleLowerCase()) > -1
}).map((item) => {
return <div onClick={() => changeItem(item)} key={item.id} className={styles.item}>{item.value}</div>
});
}

return (
<div onSubmit={handleSubmit} className={styles.container}>
{selectedItem ? <div className={styles.selectedContainer}>
<div className={styles.selectedLabel}>{label}</div>
<div className={styles.selected}>{selectedItem.value}</div>
<button onClick={resetInput} type='button' className={styles.reset}>x</button>
</div>:<TextInput
autoFocus
label={label}
value={getValue("searchText")}
error={error || getError("searchText")}
onChange={onChangeInput}
/>}
{!selectedItem && getValue("searchText") && <div className={styles.list}>
{renderList()}
</div>}
</div>
)
}

4 changes: 2 additions & 2 deletions experiments/src/controlled/ui/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {useRef} from "react";
import styles from './TextInput.module.css';

export function TextInput(props: any) {
const {error, onChange, value, label, visible, viewMode} = props;
const {error, onChange, value, label, visible, viewMode, autoFocus} = props;
const inputRef = useRef<any>(null);
const {onChangeOptimized, onBlurOptimized} = useOptimisationInput({onChange, value, inputRef});

Expand All @@ -25,7 +25,7 @@ export function TextInput(props: any) {
return (
<div className={styles.textInput}>
{label && <label className={styles.label}>{label}</label>}
<input className={styles.input} onBlur={onBlurOptimized} onChange={onChangeOptimized} defaultValue={value} ref={inputRef}/>
<input autoFocus={autoFocus} className={styles.input} onBlur={onBlurOptimized} onChange={onChangeOptimized} defaultValue={value} ref={inputRef}/>
{error && <span className={styles.error}>{error}</span>}
</div>
)
Expand Down
3 changes: 2 additions & 1 deletion experiments/src/controlled/ui/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export {TextInput} from "./TextInput/TextInput";
export {Button} from "./Button/Button";
export {OptionBox} from "./OptionBox/OptionBox";
export {OptionBox} from "./OptionBox/OptionBox";
export {SearchSelect} from "./SearchSelect/SearchSelect";
Loading

0 comments on commit c762dc0

Please sign in to comment.