@weareconceptstudio/form 0.1.5 → 0.1.7

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.
@@ -1,12 +1,5 @@
1
1
  export default ErrorMessage;
2
- declare function ErrorMessage({ as, errors, name, message, render, ...rest }: {
3
- [x: string]: any;
4
- as: any;
5
- errors: any;
6
- name: any;
7
- message: any;
8
- render: any;
9
- }): any;
2
+ declare function ErrorMessage(props: any): any;
10
3
  declare namespace ErrorMessage {
11
4
  let displayName: string;
12
5
  }
@@ -1,23 +1,24 @@
1
1
  import React, { Fragment, isValidElement, cloneElement, createElement } from 'react';
2
2
  import { useFormContext, get } from 'react-hook-form';
3
- const ErrorMessage = ({ as, errors, name, message, render, ...rest }) => {
3
+ const ErrorMessage = (props) => {
4
+ const { as, errors, name, message, render, ...rest } = props;
4
5
  const methods = useFormContext();
5
6
  const error = get(errors || methods.formState.errors, name);
6
7
  if (!error) {
7
8
  return null;
8
9
  }
9
10
  const { message: messageFromRegister, types } = error;
10
- const props = Object.assign({}, rest, {
11
+ const inlineProps = Object.assign({}, rest, {
11
12
  children: messageFromRegister || message,
12
13
  });
13
14
  return isValidElement(as)
14
- ? cloneElement(as, props)
15
+ ? cloneElement(as, inlineProps)
15
16
  : render
16
17
  ? render({
17
18
  message: messageFromRegister || message,
18
19
  messages: types,
19
20
  })
20
- : createElement(as || Fragment, props);
21
+ : createElement(as || Fragment, inlineProps);
21
22
  };
22
23
  if (process.env.NODE_ENV !== 'production') {
23
24
  ErrorMessage.displayName = 'ErrorMessage';
@@ -1,30 +1,44 @@
1
- import React, { cloneElement, isValidElement } from 'react';
1
+ import React, { cloneElement, isValidElement, useRef } from 'react';
2
2
  import lodashGet from 'lodash.get';
3
3
  import classNames from 'classnames';
4
- import { useTranslation } from '@weareconceptstudio/core';
4
+ import { isForwardRefChild, useTranslation } from '@weareconceptstudio/core';
5
5
  import ErrorMessage from '../../error-message';
6
6
  import { useInput } from '../hooks/useInput';
7
7
  import { useRules } from '../hooks/rules';
8
8
  const FormItem = ({ label, name, children, className, errorKey, required = true, requiredMessage, rules = [] }) => {
9
+ if (!isValidElement(children)) {
10
+ return null;
11
+ }
12
+ const childRef = useRef(null);
9
13
  const { translate } = useTranslation();
10
14
  const { formState } = useInput({
11
15
  name,
12
- rules: useRules({ rules, required, requiredMessage }),
16
+ rules: useRules({
17
+ rules,
18
+ required,
19
+ requiredMessage,
20
+ errorKey: errorKey || label,
21
+ // @ts-ignore
22
+ childType: childRef?.current?.childType || '',
23
+ }),
13
24
  errorKey: errorKey || label,
14
25
  });
15
26
  const hasError = !!lodashGet(formState.errors, name);
16
27
  const classString = classNames('form-item', {
17
28
  [className]: className,
18
29
  'has-error': hasError,
19
- disabled: isValidElement(children) && children.props.disabled,
30
+ // @ts-ignore
31
+ disabled: children.props.disabled,
20
32
  });
33
+ // @ts-ignore
34
+ const inlineProps = isForwardRefChild(children) ? { ref: childRef, name } : { name };
21
35
  return (React.createElement("div", { className: classString },
22
36
  React.createElement("div", { className: 'form-item-row' },
23
37
  label ? (React.createElement("div", { className: 'form-item-label' },
24
38
  React.createElement("label", { htmlFor: name, "data-required": required },
25
39
  translate(label),
26
40
  required ? React.createElement("span", { className: 'required-symbol' }, "*") : null))) : null,
27
- React.createElement("div", { className: 'form-item-control' }, isValidElement(children) && cloneElement(children, { name })),
41
+ React.createElement("div", { className: 'form-item-control' }, cloneElement(children, inlineProps)),
28
42
  React.createElement(ErrorMessage, { name: name, as: React.createElement("div", { className: 'error-message' }) }))));
29
43
  };
30
44
  export default FormItem;
@@ -7,5 +7,11 @@ export function validationPatterns({ type, pattern, message, translate }: {
7
7
  value: any;
8
8
  message: any;
9
9
  };
10
- export function useRules(props: any): any[];
10
+ export function useRules({ rules, required, requiredMessage, childType, errorKey }: {
11
+ rules: any;
12
+ required: any;
13
+ requiredMessage: any;
14
+ childType: any;
15
+ errorKey: any;
16
+ }): any[];
11
17
  export function mapValidationRules(errorKey: any, rules: any): any;
@@ -12,20 +12,23 @@ export const validationPatterns = ({ type, pattern, message, translate }) => {
12
12
  return { value: pattern, message };
13
13
  }
14
14
  };
15
- export const useRules = (props) => {
15
+ export const useRules = ({ rules, required, requiredMessage, childType, errorKey }) => {
16
+ const { translate } = useTranslation();
16
17
  return useMemo(() => {
17
- let r = [...props.rules];
18
- if (props.required) {
19
- r.unshift({ required: true, message: props.requiredMessage });
18
+ let r = [...rules];
19
+ if (required) {
20
+ r.unshift({ required: true, message: requiredMessage });
21
+ if (childType.toLowerCase() === 'input' || childType.toLowerCase() === 'textarea') {
22
+ r.push({
23
+ validator: (value) => {
24
+ return value?.trim().length > 0 || translate('validateMessages.whitespace', { errorKey: translate(errorKey) });
25
+ },
26
+ });
27
+ }
20
28
  }
21
- // TODO: Whitespace
22
- // validator: (value) => {
23
- // return !!value.trim();
24
- // },
25
29
  return r;
26
- }, [props]);
30
+ }, [rules, required, requiredMessage, childType, errorKey]);
27
31
  };
28
- // TODO: rule messages from translations
29
32
  export const mapValidationRules = (errorKey, rules) => {
30
33
  const { translate } = useTranslation();
31
34
  return rules?.reduce((acc, rule) => {
@@ -1,6 +1,3 @@
1
1
  export default Input;
2
- declare function Input(props: any): React.JSX.Element;
3
- declare namespace Input {
4
- let displayName: string;
5
- }
2
+ declare const Input: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
6
3
  import React from 'react';
@@ -1,8 +1,9 @@
1
- import React from 'react';
1
+ import React, { forwardRef, useImperativeHandle } from 'react';
2
2
  import BaseInput from './BaseInput';
3
3
  import { useInput } from '../form/hooks/useInput';
4
4
  import { useTranslation } from '@weareconceptstudio/core';
5
- const Input = (props) => {
5
+ const Input = forwardRef((props, ref) => {
6
+ useImperativeHandle(ref, () => ({ childType: 'input' }));
6
7
  const { name, autoComplete = 'new-password', onChange, onFocus, onBlur, onKeyDown, onKeyUp, disabled, className, type = 'text', placeholder } = props;
7
8
  const { translate } = useTranslation();
8
9
  const { field } = useInput({
@@ -13,7 +14,7 @@ const Input = (props) => {
13
14
  });
14
15
  return (React.createElement(BaseInput, { ...props, value: field.value, disabled: disabled },
15
16
  React.createElement("input", { type: type, onFocus: onFocus, onKeyUp: onKeyUp, disabled: disabled, className: className, onKeyDown: onKeyDown, placeholder: translate(placeholder), autoComplete: autoComplete, ...field })));
16
- };
17
+ });
17
18
  if (process.env.NODE_ENV !== 'production') {
18
19
  Input.displayName = 'Input';
19
20
  }
@@ -1,6 +1,3 @@
1
1
  export default TextArea;
2
- declare function TextArea(props: any): React.JSX.Element;
3
- declare namespace TextArea {
4
- let displayName: string;
5
- }
2
+ declare const TextArea: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
6
3
  import React from 'react';
@@ -1,8 +1,9 @@
1
- import React from 'react';
1
+ import React, { forwardRef, useImperativeHandle } from 'react';
2
2
  import BaseInput from '../BaseInput';
3
3
  import { useInput } from '../../form/hooks/useInput';
4
4
  import { useTranslation } from '@weareconceptstudio/core';
5
- const TextArea = (props) => {
5
+ const TextArea = forwardRef((props, ref) => {
6
+ useImperativeHandle(ref, () => ({ childType: 'textarea' }));
6
7
  const { translate } = useTranslation();
7
8
  const { name, placeholder, rows = 5, onChange, onFocus, onBlur, onKeyDown, onKeyUp, disabled, className, autoComplete } = props;
8
9
  const input = name ? useInput({ name, onChange, onBlur }) : null;
@@ -12,7 +13,7 @@ const TextArea = (props) => {
12
13
  };
13
14
  return (React.createElement(BaseInput, { ...props },
14
15
  React.createElement("textarea", { ...field, rows: rows, onFocus: onFocus, onKeyUp: onKeyUp, disabled: disabled, className: className, onKeyDown: onKeyDown, autoComplete: autoComplete, placeholder: translate(placeholder) })));
15
- };
16
+ });
16
17
  if (process.env.NODE_ENV !== 'production') {
17
18
  TextArea.displayName = 'TextArea';
18
19
  }
@@ -31,15 +31,14 @@ const FormStyle = createGlobalStyle `${css `
31
31
  }
32
32
  }
33
33
 
34
- .react-select__menu,
35
- .react-select__menu-list {
34
+ /* .react-select__menu-list {
36
35
  scrollbar-width: none;
37
36
  -ms-overflow-style: none;
38
37
 
39
38
  &::-webkit-scrollbar {
40
39
  display: none;
41
40
  }
42
- }
41
+ } */
43
42
 
44
43
  input::-webkit-outer-spin-button,
45
44
  input::-webkit-inner-spin-button,
@@ -286,7 +285,7 @@ const FormStyle = createGlobalStyle `${css `
286
285
  .react-select__option {
287
286
  color: var(--form_selectOptionColor);
288
287
  line-height: var(--form_lineHeight);
289
- font-size: var(--form_p2);
288
+ font-size: var(--form_p3);
290
289
  font-family: var(--form_Font);
291
290
  font-weight: 500;
292
291
  padding: var(--form_inputPadTBL) var(--form_inputPadR) var(--form_inputPadTBL) var(--form_inputPadTBL);
@@ -396,6 +395,11 @@ const FormStyle = createGlobalStyle `${css `
396
395
  font-weight: 400;
397
396
  color: var(--form_errorMessageColor);
398
397
  transform: translateY(var(--form_errorDistance));
398
+ text-transform: lowercase;
399
+
400
+ &::first-letter {
401
+ text-transform: uppercase;
402
+ }
399
403
  }
400
404
 
401
405
  /* //! Disabled Styles */
@@ -3,7 +3,7 @@ import { rawFileToAsset } from '../utils';
3
3
  import UploadButtonStyle from './style';
4
4
  const UploadButton = (props) => {
5
5
  const { accept, disabled, multiple, setFileList } = props;
6
- const inputRef = useRef();
6
+ const inputRef = useRef(null);
7
7
  const handleFiles = async (files) => {
8
8
  const newFiles = [];
9
9
  for (let i = 0; i < files.length; i++) {
@@ -1,4 +1,4 @@
1
- export function typeFromMime(mime: any): "document" | "image" | "video" | "audio" | "pdf";
1
+ export function typeFromMime(mime: any): "audio" | "video" | "image" | "document" | "pdf";
2
2
  export function rawFileToAsset({ rawFile, isReplace }: {
3
3
  rawFile: any;
4
4
  isReplace?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weareconceptstudio/form",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Concept Studio Form",
5
5
  "author": "Concept Studio",
6
6
  "license": "ISC",