Created
August 6, 2020 01:34
-
-
Save LukasFB/2a58b496fc7469db86f2858a1ea05568 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from "react" | |
import PropTypes from 'prop-types' | |
import "./input.css" | |
import TypingIndicator from "./TypingIndicator" | |
const input = (props) => { | |
const styles = ["plank", "staggered", "split"] | |
const [stateIsFocused, setStateIsFocused] = useState(false) | |
const [stateIsClear, setStateIsClear] = useState(props.initialValue === "") | |
const [stateTypingTrigger, setStateTypingTrigger] = useState("") | |
const [stateStyle, setStateStyle] = useState(styles[Math.floor(Math.random() * styles.length)]) | |
const handleChange = e => { | |
const value = e.target.value | |
setStateTypingTrigger(Math.random()) | |
if (value === "") { | |
setStateIsClear(true) | |
} else { | |
setStateIsClear(false) | |
} | |
props.onChange(value) | |
} | |
const classes = ["kc-input"] | |
if (stateIsFocused) classes.push("kc-input__focused") | |
if (stateIsClear && !stateIsFocused) classes.push("kc-input__clear") | |
return <div className={classes.join(" ")}> | |
<div className={"kc-input_label"}>{props.label}</div> | |
<div className={"kc-input_typing-wrapper"}> | |
{ | |
stateIsFocused | |
? <TypingIndicator | |
trigger={stateTypingTrigger} | |
style={stateStyle} | |
/> | |
: null | |
} | |
</div> | |
<input | |
autoComplete={"off"} | |
onChange={handleChange} | |
onFocus={() => { | |
setStateStyle(styles[Math.floor(Math.random() * styles.length)]) | |
setStateIsFocused(true) | |
}} | |
onBlur={() => setStateIsFocused(false)} | |
/> | |
</div> | |
} | |
input.propTypes = { | |
onChange: PropTypes.func.isRequired, | |
label: PropTypes.string.isRequired, | |
initialValue: PropTypes.string, | |
} | |
input.defaultProps = { | |
initialValue: "", | |
} | |
export default input |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.kc-input | |
position: relative | |
background-color: rgba(white, 0.2) | |
transition: all 0.2s | |
padding: 10px 10px | |
padding-top: 25px | |
.kc-input_label | |
position: absolute | |
top: 0px | |
font-size: 14px | |
transition: all 0.3s | |
.kc-input_typing-wrapper | |
position: absolute | |
bottom: 39px | |
right: 10px | |
opacity: 0 | |
transition: all 0.2s | |
input | |
width: 100% | |
background-color: transparent | |
border: none | |
border-bottom: 1px solid #ccc | |
transition: all 0.3s | |
outline: none | |
&.kc-input__focused | |
input | |
border-bottom-color: $color | |
.kc-input_typing-wrapper | |
opacity: 1 | |
&.kc-input__clear | |
.kc-input_label | |
position: absolute | |
top: 16px | |
font-size: 19px |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useEffect, useState } from "react" | |
import PropTypes from 'prop-types' | |
import "./typingIndicator.css" | |
import TypingIndicatorRow from "./TypingIndicatorRow" | |
const typingIndicator = (props) => { | |
let rows = ["o1", "o2", "o3", "o4"] | |
switch (props.style) { | |
case "staggered": | |
rows = ["s1", "s2", "s3", "s4"] | |
break | |
case "split": | |
rows = ["p1", "p2", "p3", "p4"] | |
break | |
} | |
const [stateTriggers, setStateTriggers] = useState(new Map()) | |
useEffect(() => { | |
if (props.trigger !== "") { | |
const randomRowName = rows[Math.floor(Math.random() * rows.length)] | |
setStateTriggers(oldMap => { | |
const newMap = new Map(oldMap) | |
newMap.set(randomRowName, Math.random()) | |
return newMap | |
}) | |
} | |
l("effect 1") | |
}, [props.trigger]) | |
const classes = ["typing"] | |
return <div className={classes.join(" ")}> | |
{rows.map((rowStyle, rowIndex) => { | |
let trigger = "" | |
if (stateTriggers.has(rowStyle)) trigger = stateTriggers.get(rowStyle) | |
return <TypingIndicatorRow | |
trigger={trigger} | |
key={rowIndex} | |
style={rowStyle} | |
/> | |
})} | |
</div> | |
} | |
typingIndicator.propTypes = { | |
trigger: PropTypes.any, | |
rows: PropTypes.arrayOf(PropTypes.string), | |
} | |
typingIndicator.defaultProps = { | |
} | |
export default typingIndicator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$color: #ab7d2e | |
.typing | |
.typing-row | |
height: 8px | |
.typing-key | |
display: inline-block | |
height: 5px | |
background-color: #ccc | |
border-radius: 1px | |
border-top-left-radius: 3px | |
border-top-right-radius: 3px | |
transition: all 0.3s | |
position: relative | |
top: 0px | |
&.pressed | |
background-color: $color | |
top: 3px | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useEffect, useState } from "react" | |
import PropTypes from 'prop-types' | |
const typingIndicatorKey = (props) => { | |
const [stateIsPressed, setStateIsPressed] = useState(false) | |
let width = 5 | |
let marginRight = 2 | |
let opacity = 1 | |
let transform = "" | |
let splitSpacing = 30 | |
const marginLeft = 0 | |
switch (props.style) { | |
case "p1": | |
case "p2": | |
switch (props.index) { | |
case 0: | |
case 11: | |
width = 9 | |
break | |
case 6: | |
marginRight = marginRight + 5 | |
width = 0 | |
break | |
case 5: | |
marginRight = 5 + splitSpacing | |
width = 0 | |
break | |
} | |
break | |
case "p3": | |
switch (props.index) { | |
case 0: | |
case 11: | |
width = 9 | |
break | |
case 5: | |
marginRight = splitSpacing | |
transform = "rotate(30deg) scaleY(2.5) translate(13px, 3px)" | |
break | |
case 6: | |
transform = "rotate(-30deg) scaleY(2.5) translate(-13px, 3px)" | |
break | |
} | |
break | |
case "p4": | |
switch (props.index) { | |
case 0: | |
case 11: | |
width = 9 | |
break | |
case 5: | |
marginRight = splitSpacing | |
transform = "rotate(30deg) scaleY(2.5) translate(1px, 0px)" | |
break | |
case 6: | |
transform = "rotate(-30deg) scaleY(2.5) translate(-1px, 0px)" | |
break | |
} | |
break | |
case "o4": | |
switch (props.index) { | |
case 3: | |
case 4: | |
width = 5 + 5 + marginRight | |
} | |
break | |
case "s1": | |
switch (props.index) { | |
case 9: | |
width = 12 + marginRight | |
break | |
} | |
break | |
case "s2": | |
switch (props.index) { | |
case 0: | |
width = 8 + marginRight | |
break | |
case 9: | |
width = 8 + marginRight | |
break | |
} | |
break | |
case "s3": | |
switch (props.index) { | |
case 0: | |
width = 10 + marginRight | |
break | |
case 8: | |
width = 12 + marginRight | |
break | |
} | |
break | |
case "s4": | |
switch (props.index) { | |
case 0: | |
width = 7 + marginRight | |
break | |
case 3: | |
width = 5*6 + marginRight | |
} | |
break | |
} | |
useEffect(() => { | |
if (props.trigger !== "") { | |
setStateIsPressed(true) | |
const timer = window.setTimeout(() => { | |
setStateIsPressed(false) | |
}, 200) | |
return function () { | |
window.clearTimeout(timer) | |
} | |
} | |
}, [props.trigger]) | |
const classes = ["typing-key"] | |
if (stateIsPressed) classes.push("pressed") | |
return <div style={ | |
{ | |
width: width+"px", | |
marginRight: marginRight+"px", | |
marginLeft: marginLeft+"px", | |
opacity: opacity, | |
transform: transform | |
} | |
} className={classes.join(" ")}> | |
</div> | |
} | |
typingIndicatorKey.propTypes = { | |
trigger: PropTypes.any, | |
style: PropTypes.string, | |
index: PropTypes.number, | |
} | |
typingIndicatorKey.defaultProps = { | |
} | |
export default typingIndicatorKey |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useEffect } from "react" | |
import PropTypes from 'prop-types' | |
import TypingIndicatorKey from "./TypingIndicatorKey" | |
const typingIndicatorRow = (props) => { | |
const [stateTriggers, setStateTriggers] = useState(new Map()) | |
let keys = 10 | |
switch (props.style) { | |
case "p1": | |
case "p2": | |
case "p3": | |
case "p4": | |
keys = 12 | |
break | |
case "o4": | |
keys = 8 | |
break | |
case "s3": | |
keys = 9 | |
break | |
case "s4": | |
keys = 7 | |
break | |
} | |
const randomInRange = (min, max) => { | |
return Math.floor(Math.random() * (max - min + 1)) + min; | |
} | |
useEffect(() => { | |
if (props.trigger !== "") { | |
const offset = randomInRange(0, keys-1) | |
setStateTriggers(oldMap => { | |
const newMap = new Map(oldMap) | |
newMap.set(offset, Math.random()) | |
return newMap | |
}) | |
} | |
}, [props.trigger]) | |
const renderKeys = () => { | |
const returnArray = [] | |
for (let i = 0; i < keys; i++) { | |
let trigger = "" | |
if (stateTriggers.has(i)) trigger = stateTriggers.get(i) | |
returnArray.push(<TypingIndicatorKey | |
key={i} | |
index={i} | |
style={props.style} | |
trigger={trigger} | |
/>) | |
} | |
return returnArray | |
} | |
const classes = ["typing-row"] | |
return <div className={classes.join(" ")}> | |
{ | |
renderKeys() | |
} | |
</div> | |
} | |
typingIndicatorRow.propTypes = { | |
style: PropTypes.string, | |
} | |
typingIndicatorRow.defaultProps = { | |
} | |
export default typingIndicatorRow |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment