@dtdot/lego 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export interface ITextAreaProps {
3
+ 'name'?: string;
4
+ 'label'?: string;
5
+ 'placeholder'?: string;
6
+ 'autoFocus'?: boolean;
7
+ 'value'?: string;
8
+ 'error'?: string;
9
+ 'onChange'?: (value: any) => void;
10
+ 'onFocus'?: () => void;
11
+ 'onBlur'?: () => void;
12
+ 'data-cy'?: string;
13
+ }
14
+ declare const TextArea: React.ForwardRefExoticComponent<ITextAreaProps & React.RefAttributes<HTMLTextAreaElement>>;
15
+ export default TextArea;
@@ -0,0 +1,107 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
2
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
+ import React, { useState } from 'react';
4
+ import { faExclamationCircle } from '@fortawesome/free-solid-svg-icons';
5
+ import { motion } from 'framer-motion';
6
+ import styled from 'styled-components';
7
+ import getThemeControlColours from '../../theme/helpers/getThemeControlColours';
8
+ import useFormNode, { getValue } from '../Form/useFormNode.hook';
9
+ import { InputStyles } from '../Input/Input.component';
10
+ const TextAreaContainer = styled.div `
11
+ position: relative;
12
+ `;
13
+ const TextAreaLabel = styled.label `
14
+ display: block;
15
+ padding-bottom: 8px;
16
+
17
+ color: ${(props) => getThemeControlColours(props.theme).font};
18
+ font-family: ${(props) => props.theme.fonts.default.family};
19
+ font-size: ${(props) => props.theme.fonts.default.size};
20
+ `;
21
+ const StyledTextArea = styled(motion.textarea) `
22
+ ${InputStyles}
23
+ height: initial;
24
+ width: 100% !important;
25
+ min-height: 144px;
26
+ padding: 12px;
27
+ `;
28
+ const ErrorMessage = styled(motion.div) `
29
+ position: absolute;
30
+ left: 38px;
31
+ top: 16px;
32
+
33
+ pointer-events: none;
34
+ touch-action: none;
35
+
36
+ font-family: ${(props) => props.theme.fonts.default.family};
37
+ font-size: ${(props) => props.theme.fonts.default.size};
38
+ color: ${(props) => props.theme.colours.statusDanger.main};
39
+ `;
40
+ const ErrorContainer = styled(motion.div) `
41
+ position: absolute;
42
+ left: 0;
43
+ top: 0;
44
+ height: 42px;
45
+ display: flex;
46
+ align-items: center;
47
+
48
+ pointer-events: none;
49
+ touch-action: none;
50
+
51
+ color: ${(props) => props.theme.colours.statusDanger.main};
52
+ `;
53
+ const ErrorInner = styled.div `
54
+ width: 24px;
55
+ height: 24px;
56
+
57
+ display: flex;
58
+ justify-content: center;
59
+ align-items: center;
60
+ cursor: pointer;
61
+ `;
62
+ const errorVariants = {
63
+ show: { opacity: 1, x: 10 },
64
+ };
65
+ const textAreaVariants = {
66
+ error: { paddingLeft: '38px' },
67
+ errorFocus: { paddingLeft: '38px', paddingTop: '32px' },
68
+ };
69
+ const messageVariants = {
70
+ errorFocus: { opacity: 1, y: -4 },
71
+ };
72
+ const TextArea = React.forwardRef(function ForwardRefTextArea(props, ref) {
73
+ const { label, name, placeholder, autoFocus, value, 'error': propsError, onChange, onFocus, onBlur, 'data-cy': dataCy, } = props;
74
+ const [isFocused, setIsFocused] = useState(false);
75
+ const { value: contextValue, error: contextError, onChange: contextOnChange } = useFormNode(name);
76
+ const error = contextError || propsError;
77
+ const handleChange = (e) => {
78
+ if (onChange) {
79
+ onChange(e.target.value);
80
+ }
81
+ if (contextOnChange) {
82
+ contextOnChange(e.target.value);
83
+ }
84
+ };
85
+ const handleFocus = () => {
86
+ setIsFocused(true);
87
+ if (onFocus) {
88
+ onFocus();
89
+ }
90
+ };
91
+ const handleBlur = () => {
92
+ setIsFocused(false);
93
+ if (onBlur) {
94
+ onBlur();
95
+ }
96
+ };
97
+ const animationVariant = error ? (isFocused ? 'errorFocus' : 'error') : undefined;
98
+ return (React.createElement("div", null,
99
+ label && React.createElement(TextAreaLabel, { htmlFor: name }, label),
100
+ React.createElement(TextAreaContainer, { "data-cy": dataCy },
101
+ React.createElement(StyledTextArea, { ref: ref, animate: animationVariant, variants: textAreaVariants, transition: { type: 'spring', duration: 0.3 }, name: name, placeholder: placeholder, value: getValue(value, contextValue), onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, autoFocus: autoFocus, "data-cy": 'text-area' }),
102
+ React.createElement(ErrorContainer, { animate: error ? 'show' : undefined, style: { opacity: 0 }, variants: errorVariants, transition: { type: 'spring', duration: 0.3 }, "data-cy": 'error-indicator' },
103
+ React.createElement(ErrorInner, null,
104
+ React.createElement(FontAwesomeIcon, { icon: faExclamationCircle }))),
105
+ error && (React.createElement(ErrorMessage, { style: { opacity: 0, y: 0 }, animate: animationVariant, variants: messageVariants, transition: { type: 'spring', duration: 0.3 }, "data-cy": 'error-message' }, error)))));
106
+ });
107
+ export default TextArea;
package/build/index.d.ts CHANGED
@@ -36,6 +36,7 @@ export { default as SquareButton } from './components/SquareButton/SquareButton.
36
36
  export { default as Swimlane } from './components/Swimlane/Swimlane.component';
37
37
  export { default as Table } from './components/Table/Table.component';
38
38
  export { default as Text } from './components/Text/Text.component';
39
+ export { default as TextArea } from './components/TextArea/TextArea.component';
39
40
  export { default as LoginScreen } from './screens/Login/Login.screen';
40
41
  export { default as RegisterScreen } from './screens/Register/Register.screen';
41
42
  export { default as VerificationScreen } from './screens/Verification/Verification.screen';
package/build/index.js CHANGED
@@ -36,6 +36,7 @@ export { default as SquareButton } from './components/SquareButton/SquareButton.
36
36
  export { default as Swimlane } from './components/Swimlane/Swimlane.component';
37
37
  export { default as Table } from './components/Table/Table.component';
38
38
  export { default as Text } from './components/Text/Text.component';
39
+ export { default as TextArea } from './components/TextArea/TextArea.component';
39
40
  export { default as LoginScreen } from './screens/Login/Login.screen';
40
41
  export { default as RegisterScreen } from './screens/Register/Register.screen';
41
42
  export { default as VerificationScreen } from './screens/Verification/Verification.screen';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dtdot/lego",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Some reusable components for building my applications",
5
5
  "main": "build/index.js",
6
6
  "scripts": {