@jobber/components 6.50.0 → 6.51.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.
@@ -1,5 +1,2 @@
1
- import { CommonFormFieldProps, FormFieldProps } from "../FormField";
2
- type InputEmailProps = CommonFormFieldProps & Pick<FormFieldProps, "maxLength" | "readonly" | "validations" | "defaultValue">;
3
- export declare const validationMessage = "Please enter a valid email";
4
- export declare function InputEmail(props: InputEmailProps): JSX.Element;
5
- export {};
1
+ import { InputEmailLegacyProps } from "./InputEmail.types";
2
+ export declare function InputEmail(props: InputEmailLegacyProps): JSX.Element;
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import { InputEmailRebuiltProps } from "./InputEmail.types";
3
+ export declare const InputEmailRebuilt: React.ForwardRefExoticComponent<InputEmailRebuiltProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,33 @@
1
+ import { Clearable } from "@jobber/hooks";
2
+ import { CommonFormFieldProps, FormFieldProps } from "../FormField";
3
+ export type InputEmailLegacyProps = CommonFormFieldProps & Pick<FormFieldProps, "maxLength" | "readonly" | "validations" | "defaultValue">;
4
+ export declare const validationMessage = "Please enter a valid email";
5
+ export type InputEmailVersion = 1 | 2 | undefined;
6
+ /**
7
+ * Experimental version 2 of the InputEmail component.
8
+ * Do not use unless you have talked with Atlantis first.
9
+ */
10
+ export interface InputEmailRebuiltProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "onBlur" | "size" | "suffix" | "prefix" | "value" | "max" | "min" | "defaultValue"> {
11
+ readonly error?: string;
12
+ readonly invalid?: boolean;
13
+ readonly identifier?: string;
14
+ readonly autocomplete?: boolean | string;
15
+ readonly loading?: boolean;
16
+ readonly onKeyUp?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
17
+ readonly children?: React.ReactNode;
18
+ readonly clearable?: Clearable;
19
+ /**
20
+ * Version 2 is highly experimental. Avoid using it unless you have talked with Atlantis first.
21
+ */
22
+ readonly version: 2;
23
+ readonly onChange?: (newValue: string, event?: React.ChangeEvent<HTMLInputElement>) => void;
24
+ readonly onEnter?: FormFieldProps["onEnter"];
25
+ readonly onBlur?: FormFieldProps["onBlur"];
26
+ readonly value?: string;
27
+ readonly size?: FormFieldProps["size"];
28
+ readonly inline?: FormFieldProps["inline"];
29
+ readonly align?: FormFieldProps["align"];
30
+ readonly prefix?: FormFieldProps["prefix"];
31
+ readonly suffix?: FormFieldProps["suffix"];
32
+ readonly description?: FormFieldProps["description"];
33
+ }
@@ -0,0 +1,12 @@
1
+ import { ChangeEvent, FocusEvent, KeyboardEvent } from "react";
2
+ import { InputEmailRebuiltProps } from "../InputEmail.types";
3
+ export interface UseInputEmailActionsProps extends Pick<InputEmailRebuiltProps, "onChange" | "onEnter" | "onFocus" | "onBlur" | "onKeyDown"> {
4
+ inputRef?: React.RefObject<HTMLInputElement>;
5
+ }
6
+ export declare function useInputEmailActions({ onChange, inputRef, onEnter, onFocus, onBlur, onKeyDown, }: UseInputEmailActionsProps): {
7
+ handleClear: () => void;
8
+ handleChange: (event: ChangeEvent<HTMLInputElement>) => void;
9
+ handleKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
10
+ handleFocus: (event: FocusEvent<HTMLInputElement>) => void;
11
+ handleBlur: (event?: FocusEvent) => void;
12
+ };
@@ -0,0 +1,32 @@
1
+ import { ChangeEvent, FocusEvent, KeyboardEvent } from "react";
2
+ export interface UseInputEmailFormFieldProps {
3
+ readonly id: string;
4
+ readonly name: string;
5
+ readonly disabled?: boolean;
6
+ readonly autofocus?: boolean;
7
+ readonly error?: string;
8
+ readonly inline?: boolean;
9
+ readonly description?: string;
10
+ readonly invalid?: boolean;
11
+ readonly value?: string;
12
+ readonly handleChange: (event: ChangeEvent<HTMLInputElement>) => void;
13
+ readonly handleBlur: (event?: FocusEvent<HTMLInputElement>) => void;
14
+ readonly handleFocus: (event: FocusEvent<HTMLInputElement>) => void;
15
+ readonly handleKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
16
+ }
17
+ export interface UseInputEmailFormFieldReturn {
18
+ readonly fieldProps: {
19
+ readonly id: string;
20
+ readonly name: string;
21
+ readonly disabled?: boolean;
22
+ readonly autofocus?: boolean;
23
+ readonly onChange: (event: ChangeEvent<HTMLInputElement>) => void;
24
+ readonly onBlur: (event?: FocusEvent<HTMLInputElement>) => void;
25
+ readonly onFocus: (event: FocusEvent<HTMLInputElement>) => void;
26
+ readonly onKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
27
+ readonly value?: string;
28
+ readonly "aria-describedby"?: string;
29
+ };
30
+ readonly descriptionIdentifier: string;
31
+ }
32
+ export declare function useInputEmailFormField({ id, name, disabled, autofocus, description, inline, value, handleChange, handleBlur, handleFocus, handleKeyDown, error, ...rest }: UseInputEmailFormFieldProps): UseInputEmailFormFieldReturn;
@@ -1,23 +1,136 @@
1
1
  'use strict';
2
2
 
3
- var InputEmail = require('../InputEmail-cjs.js');
4
- require('react');
5
- require('../FormField-cjs.js');
3
+ var React = require('react');
4
+ var FormField = require('../FormField-cjs.js');
5
+ require('classnames');
6
+ var tslib_es6 = require('../tslib.es6-cjs.js');
7
+ require('react-hook-form');
6
8
  require('framer-motion');
7
9
  require('@jobber/design');
8
- require('classnames');
9
10
  require('../Button-cjs.js');
10
- require('react-router-dom');
11
- require('../tslib.es6-cjs.js');
12
11
  require('../Icon-cjs.js');
13
- require('../Typography-cjs.js');
14
12
  require('../Text-cjs.js');
13
+ require('../Typography-cjs.js');
15
14
  require('../useFormFieldFocus-cjs.js');
16
15
  require('../InputValidation-cjs.js');
17
16
  require('../Spinner-cjs.js');
18
- require('react-hook-form');
17
+ require('react-router-dom');
18
+
19
+ const validationMessage = "Please enter a valid email";
20
+
21
+ function InputEmail$1(props) {
22
+ const { validations } = props;
23
+ return (React.createElement(FormField.FormField, Object.assign({}, props, { type: "email", validations: Object.assign(Object.assign({}, validations), { validate: checkForValidEmail }) })));
24
+ function checkForValidEmail(value) {
25
+ const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
26
+ if (!value) {
27
+ return true;
28
+ }
29
+ if (!value.match(emailRegex)) {
30
+ return validationMessage;
31
+ }
32
+ return true;
33
+ }
34
+ }
35
+
36
+ function useInputEmailActions({ onChange, inputRef, onEnter, onFocus, onBlur, onKeyDown, }) {
37
+ function handleClear() {
38
+ var _a;
39
+ handleBlur();
40
+ onChange === null || onChange === void 0 ? void 0 : onChange("");
41
+ (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
42
+ }
43
+ function handleChange(event) {
44
+ const newValue = event.currentTarget.value;
45
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue, event);
46
+ }
47
+ function handleKeyDown(event) {
48
+ onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
49
+ if (!onEnter)
50
+ return;
51
+ if (event.key !== "Enter")
52
+ return;
53
+ if (event.shiftKey || event.ctrlKey)
54
+ return;
55
+ event.preventDefault();
56
+ onEnter === null || onEnter === void 0 ? void 0 : onEnter(event);
57
+ }
58
+ function handleFocus(event) {
59
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
60
+ }
61
+ function handleBlur(event) {
62
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
63
+ }
64
+ return {
65
+ handleClear,
66
+ handleChange,
67
+ handleKeyDown,
68
+ handleFocus,
69
+ handleBlur,
70
+ };
71
+ }
72
+
73
+ function useInputEmailFormField(_a) {
74
+ var { id, name, disabled, autofocus, description, inline, value, handleChange, handleBlur, handleFocus, handleKeyDown, error } = _a, rest = tslib_es6.__rest(_a, ["id", "name", "disabled", "autofocus", "description", "inline", "value", "handleChange", "handleBlur", "handleFocus", "handleKeyDown", "error"]);
75
+ const descriptionIdentifier = `descriptionUUID--${id}`;
76
+ const fieldProps = Object.assign(Object.assign(Object.assign({}, rest), { id,
77
+ name,
78
+ disabled, autoFocus: autofocus, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, onKeyDown: handleKeyDown, value, invalid: error || rest.invalid ? "true" : undefined }), (description &&
79
+ !inline && { "aria-describedby": descriptionIdentifier }));
80
+ return { fieldProps, descriptionIdentifier };
81
+ }
19
82
 
83
+ const InputEmailRebuilt = React.forwardRef(function InputEmailInternal(props, ref) {
84
+ var _a, _b, _c;
85
+ const id = React.useId();
86
+ const inputRef = (_a = ref) !== null && _a !== void 0 ? _a : React.useRef(null);
87
+ const wrapperRef = React.useRef(null);
88
+ const { inputStyle } = FormField.useFormFieldWrapperStyles({
89
+ size: props.size,
90
+ inline: props.inline,
91
+ align: props.align,
92
+ type: "email",
93
+ value: props.value,
94
+ invalid: props.invalid,
95
+ error: props.error,
96
+ maxLength: props.maxLength,
97
+ disabled: props.disabled,
98
+ placeholder: props.placeholder,
99
+ });
100
+ const { name } = FormField.useAtlantisFormFieldName({
101
+ nameProp: props.name,
102
+ id,
103
+ });
104
+ const { handleChange, handleBlur, handleFocus, handleKeyDown, handleClear } = useInputEmailActions({
105
+ onChange: props.onChange,
106
+ onBlur: props.onBlur,
107
+ onFocus: props.onFocus,
108
+ onKeyDown: props.onKeyDown,
109
+ onEnter: props.onEnter,
110
+ inputRef,
111
+ });
112
+ const { fieldProps, descriptionIdentifier } = useInputEmailFormField(Object.assign(Object.assign({}, props), { id,
113
+ name,
114
+ handleChange,
115
+ handleBlur,
116
+ handleFocus,
117
+ handleKeyDown }));
118
+ return (React.createElement(FormField.FormFieldWrapper, { error: props.error || "", invalid: props.invalid, identifier: props.identifier || id, descriptionIdentifier: descriptionIdentifier, size: props.size, inline: props.inline, align: props.align, prefix: props.prefix, suffix: props.suffix, description: props.description, clearable: (_b = props.clearable) !== null && _b !== void 0 ? _b : "never", onClear: handleClear, wrapperRef: wrapperRef, maxLength: props.maxLength, disabled: props.disabled, type: "email", value: props.value },
119
+ React.createElement("input", Object.assign({}, fieldProps, { ref: inputRef, type: "email", className: inputStyle, value: props.value, "data-testid": "ATL-InputEmail-input" })),
120
+ React.createElement(FormField.FormFieldPostFix, { variation: "spinner", visible: (_c = props.loading) !== null && _c !== void 0 ? _c : false }),
121
+ props.children));
122
+ });
20
123
 
124
+ function isNewInputEmailProps(props) {
125
+ return props.version === 2;
126
+ }
127
+ const InputEmail = React.forwardRef(function InputEmailShim(props, ref) {
128
+ if (isNewInputEmailProps(props)) {
129
+ return (React.createElement(InputEmailRebuilt, Object.assign({}, props, { ref: ref })));
130
+ }
131
+ else {
132
+ return React.createElement(InputEmail$1, Object.assign({}, props));
133
+ }
134
+ });
21
135
 
22
- exports.InputEmail = InputEmail.InputEmail;
23
- exports.validationMessage = InputEmail.validationMessage;
136
+ exports.InputEmail = InputEmail;
@@ -1 +1,5 @@
1
- export { InputEmail, validationMessage } from "./InputEmail";
1
+ import React from "react";
2
+ import { InputEmailLegacyProps, InputEmailRebuiltProps } from "./InputEmail.types";
3
+ export type InputEmailShimProps = InputEmailRebuiltProps | InputEmailLegacyProps;
4
+ export declare const InputEmail: React.ForwardRefExoticComponent<InputEmailShimProps & React.RefAttributes<HTMLInputElement>>;
5
+ export { InputEmailRebuiltProps, InputEmailLegacyProps };
@@ -1,16 +1,134 @@
1
- export { I as InputEmail, v as validationMessage } from '../InputEmail-es.js';
2
- import 'react';
3
- import '../FormField-es.js';
1
+ import React__default, { forwardRef, useId, useRef } from 'react';
2
+ import { k as FormField, j as useFormFieldWrapperStyles, b as useAtlantisFormFieldName, f as FormFieldWrapper, l as FormFieldPostFix } from '../FormField-es.js';
3
+ import 'classnames';
4
+ import { _ as __rest } from '../tslib.es6-es.js';
5
+ import 'react-hook-form';
4
6
  import 'framer-motion';
5
7
  import '@jobber/design';
6
- import 'classnames';
7
8
  import '../Button-es.js';
8
- import 'react-router-dom';
9
- import '../tslib.es6-es.js';
10
9
  import '../Icon-es.js';
11
- import '../Typography-es.js';
12
10
  import '../Text-es.js';
11
+ import '../Typography-es.js';
13
12
  import '../useFormFieldFocus-es.js';
14
13
  import '../InputValidation-es.js';
15
14
  import '../Spinner-es.js';
16
- import 'react-hook-form';
15
+ import 'react-router-dom';
16
+
17
+ const validationMessage = "Please enter a valid email";
18
+
19
+ function InputEmail$1(props) {
20
+ const { validations } = props;
21
+ return (React__default.createElement(FormField, Object.assign({}, props, { type: "email", validations: Object.assign(Object.assign({}, validations), { validate: checkForValidEmail }) })));
22
+ function checkForValidEmail(value) {
23
+ const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
24
+ if (!value) {
25
+ return true;
26
+ }
27
+ if (!value.match(emailRegex)) {
28
+ return validationMessage;
29
+ }
30
+ return true;
31
+ }
32
+ }
33
+
34
+ function useInputEmailActions({ onChange, inputRef, onEnter, onFocus, onBlur, onKeyDown, }) {
35
+ function handleClear() {
36
+ var _a;
37
+ handleBlur();
38
+ onChange === null || onChange === void 0 ? void 0 : onChange("");
39
+ (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
40
+ }
41
+ function handleChange(event) {
42
+ const newValue = event.currentTarget.value;
43
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue, event);
44
+ }
45
+ function handleKeyDown(event) {
46
+ onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
47
+ if (!onEnter)
48
+ return;
49
+ if (event.key !== "Enter")
50
+ return;
51
+ if (event.shiftKey || event.ctrlKey)
52
+ return;
53
+ event.preventDefault();
54
+ onEnter === null || onEnter === void 0 ? void 0 : onEnter(event);
55
+ }
56
+ function handleFocus(event) {
57
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
58
+ }
59
+ function handleBlur(event) {
60
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
61
+ }
62
+ return {
63
+ handleClear,
64
+ handleChange,
65
+ handleKeyDown,
66
+ handleFocus,
67
+ handleBlur,
68
+ };
69
+ }
70
+
71
+ function useInputEmailFormField(_a) {
72
+ var { id, name, disabled, autofocus, description, inline, value, handleChange, handleBlur, handleFocus, handleKeyDown, error } = _a, rest = __rest(_a, ["id", "name", "disabled", "autofocus", "description", "inline", "value", "handleChange", "handleBlur", "handleFocus", "handleKeyDown", "error"]);
73
+ const descriptionIdentifier = `descriptionUUID--${id}`;
74
+ const fieldProps = Object.assign(Object.assign(Object.assign({}, rest), { id,
75
+ name,
76
+ disabled, autoFocus: autofocus, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, onKeyDown: handleKeyDown, value, invalid: error || rest.invalid ? "true" : undefined }), (description &&
77
+ !inline && { "aria-describedby": descriptionIdentifier }));
78
+ return { fieldProps, descriptionIdentifier };
79
+ }
80
+
81
+ const InputEmailRebuilt = forwardRef(function InputEmailInternal(props, ref) {
82
+ var _a, _b, _c;
83
+ const id = useId();
84
+ const inputRef = (_a = ref) !== null && _a !== void 0 ? _a : useRef(null);
85
+ const wrapperRef = useRef(null);
86
+ const { inputStyle } = useFormFieldWrapperStyles({
87
+ size: props.size,
88
+ inline: props.inline,
89
+ align: props.align,
90
+ type: "email",
91
+ value: props.value,
92
+ invalid: props.invalid,
93
+ error: props.error,
94
+ maxLength: props.maxLength,
95
+ disabled: props.disabled,
96
+ placeholder: props.placeholder,
97
+ });
98
+ const { name } = useAtlantisFormFieldName({
99
+ nameProp: props.name,
100
+ id,
101
+ });
102
+ const { handleChange, handleBlur, handleFocus, handleKeyDown, handleClear } = useInputEmailActions({
103
+ onChange: props.onChange,
104
+ onBlur: props.onBlur,
105
+ onFocus: props.onFocus,
106
+ onKeyDown: props.onKeyDown,
107
+ onEnter: props.onEnter,
108
+ inputRef,
109
+ });
110
+ const { fieldProps, descriptionIdentifier } = useInputEmailFormField(Object.assign(Object.assign({}, props), { id,
111
+ name,
112
+ handleChange,
113
+ handleBlur,
114
+ handleFocus,
115
+ handleKeyDown }));
116
+ return (React__default.createElement(FormFieldWrapper, { error: props.error || "", invalid: props.invalid, identifier: props.identifier || id, descriptionIdentifier: descriptionIdentifier, size: props.size, inline: props.inline, align: props.align, prefix: props.prefix, suffix: props.suffix, description: props.description, clearable: (_b = props.clearable) !== null && _b !== void 0 ? _b : "never", onClear: handleClear, wrapperRef: wrapperRef, maxLength: props.maxLength, disabled: props.disabled, type: "email", value: props.value },
117
+ React__default.createElement("input", Object.assign({}, fieldProps, { ref: inputRef, type: "email", className: inputStyle, value: props.value, "data-testid": "ATL-InputEmail-input" })),
118
+ React__default.createElement(FormFieldPostFix, { variation: "spinner", visible: (_c = props.loading) !== null && _c !== void 0 ? _c : false }),
119
+ props.children));
120
+ });
121
+
122
+ function isNewInputEmailProps(props) {
123
+ return props.version === 2;
124
+ }
125
+ const InputEmail = forwardRef(function InputEmailShim(props, ref) {
126
+ if (isNewInputEmailProps(props)) {
127
+ return (React__default.createElement(InputEmailRebuilt, Object.assign({}, props, { ref: ref })));
128
+ }
129
+ else {
130
+ return React__default.createElement(InputEmail$1, Object.assign({}, props));
131
+ }
132
+ });
133
+
134
+ export { InputEmail };
package/dist/index.cjs CHANGED
@@ -61,7 +61,7 @@ var Grid = require('./Grid-cjs.js');
61
61
  var InlineLabel = require('./InlineLabel-cjs.js');
62
62
  var InputAvatar = require('./InputAvatar-cjs.js');
63
63
  var InputDate_index = require('./InputDate/index.cjs');
64
- var InputEmail = require('./InputEmail-cjs.js');
64
+ var InputEmail_index = require('./InputEmail/index.cjs');
65
65
  var InputFile = require('./InputFile-cjs.js');
66
66
  var InputGroup = require('./InputGroup-cjs.js');
67
67
  var InputNumber = require('./InputNumber-cjs.js');
@@ -282,8 +282,7 @@ exports.Grid = Grid.Grid;
282
282
  exports.InlineLabel = InlineLabel.InlineLabel;
283
283
  exports.InputAvatar = InputAvatar.InputAvatar;
284
284
  exports.InputDate = InputDate_index.InputDate;
285
- exports.InputEmail = InputEmail.InputEmail;
286
- exports.validationMessage = InputEmail.validationMessage;
285
+ exports.InputEmail = InputEmail_index.InputEmail;
287
286
  exports.InputFile = InputFile.InputFile;
288
287
  exports.InputFileContentContext = InputFile.InputFileContentContext;
289
288
  exports.updateFiles = InputFile.updateFiles;
package/dist/index.mjs CHANGED
@@ -59,7 +59,7 @@ export { G as GRID_TEST_ID, a as Grid } from './Grid-es.js';
59
59
  export { I as InlineLabel } from './InlineLabel-es.js';
60
60
  export { I as InputAvatar } from './InputAvatar-es.js';
61
61
  export { InputDate } from './InputDate/index.mjs';
62
- export { I as InputEmail, v as validationMessage } from './InputEmail-es.js';
62
+ export { InputEmail } from './InputEmail/index.mjs';
63
63
  export { I as InputFile, a as InputFileContentContext, u as updateFiles, b as useInputFileContentContext } from './InputFile-es.js';
64
64
  export { I as InputGroup } from './InputGroup-es.js';
65
65
  export { I as InputNumber } from './InputNumber-es.js';