@hellobetterdigitalnz/selwynui 0.0.1-37 → 0.0.1-39

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.
Files changed (73) hide show
  1. package/dist/Components/DataDisplay/ChatItenaryBlock/ChatItenaryBlockProps.d.ts +8 -1
  2. package/dist/Components/DataDisplay/PathwayBlock/PathwayBlockProps.d.ts +9 -0
  3. package/dist/Components/Form/Checkbox/Checkbox.d.ts +3 -0
  4. package/dist/Components/Form/Checkbox/CheckboxProps.d.ts +22 -0
  5. package/dist/Components/Form/EmailField/EmailField.d.ts +3 -0
  6. package/dist/Components/Form/EmailField/EmailField.stories.d.ts +13 -0
  7. package/dist/Components/Form/FormFieldHolder/FormFieldHolder.d.ts +3 -0
  8. package/dist/Components/Form/FormFieldHolder/FormFieldHolderProps.d.ts +13 -0
  9. package/dist/Components/Form/InputProps.d.ts +27 -0
  10. package/dist/Components/Form/LoadingInput/LoadingInput.d.ts +2 -0
  11. package/dist/Components/Form/SimpleForm/SimpleForm.d.ts +3 -0
  12. package/dist/Components/Form/SimpleForm/SimpleFormProps.d.ts +9 -0
  13. package/dist/Components/Form/SimpleForm/simple-form-bg-design.d.ts +2 -0
  14. package/dist/Components/Form/TextField/TextField.d.ts +3 -0
  15. package/dist/Components/Form/TextField/TextField.stories.d.ts +13 -0
  16. package/dist/Components/Form/TextField/TextFieldProps.d.ts +6 -0
  17. package/dist/Components/Form/Textarea/Textarea.d.ts +3 -0
  18. package/dist/Components/Form/Textarea/Textarea.stories.d.ts +14 -0
  19. package/dist/Components/Form/Textarea/TextareaProps.d.ts +26 -0
  20. package/dist/Components/Form/index.d.ts +3 -0
  21. package/dist/Components/Layout/Footer/FooterProps.d.ts +1 -1
  22. package/dist/index.cjs.js +12 -12
  23. package/dist/index.cjs.js.map +1 -1
  24. package/dist/index.es.js +1515 -1408
  25. package/dist/index.es.js.map +1 -1
  26. package/dist/selwynui.css +1 -1
  27. package/package.json +3 -1
  28. package/src/Components/DataDisplay/Accordion/accordion.module.scss +49 -36
  29. package/src/Components/DataDisplay/ChatItenaryBlock/ChatItenaryBlock.stories.tsx +36 -6
  30. package/src/Components/DataDisplay/ChatItenaryBlock/ChatItenaryBlock.tsx +39 -20
  31. package/src/Components/DataDisplay/ChatItenaryBlock/ChatItenaryBlockProps.tsx +8 -1
  32. package/src/Components/DataDisplay/ChatItenaryBlock/chatItenaryBlock.module.scss +98 -41
  33. package/src/Components/DataDisplay/ImageContent/ImageContent.tsx +0 -1
  34. package/src/Components/DataDisplay/KPIBlock/kpiBlock.module.scss +96 -7
  35. package/src/Components/DataDisplay/ListingDetailBlock/ListingDetailBlock.tsx +5 -2
  36. package/src/Components/DataDisplay/ListingDetailBlock/listingDetailBlock.module.scss +130 -15
  37. package/src/Components/DataDisplay/PathwayBlock/PathwayBlock.stories.tsx +6 -0
  38. package/src/Components/DataDisplay/PathwayBlock/PathwayBlock.tsx +4 -1
  39. package/src/Components/DataDisplay/PathwayBlock/PathwayBlockProps.tsx +9 -0
  40. package/src/Components/DataDisplay/TestimonyCard/TestimonyCard.stories.tsx +2 -1
  41. package/src/Components/DataDisplay/TestimonyCard/TestimonyCard.tsx +1 -1
  42. package/src/Components/DataDisplay/TestimonyCard/testimonyCard.module.scss +1 -3
  43. package/src/Components/Form/Checkbox/Checkbox.stories.tsx +51 -0
  44. package/src/Components/Form/Checkbox/Checkbox.tsx +111 -0
  45. package/src/Components/Form/Checkbox/CheckboxProps.tsx +24 -0
  46. package/src/Components/Form/Checkbox/checkbox.module.scss +105 -0
  47. package/src/Components/Form/EmailField/EmailField.stories.ts +23 -0
  48. package/src/Components/Form/EmailField/EmailField.tsx +56 -0
  49. package/src/Components/Form/FormFieldHolder/FormFieldHolder.stories.tsx +31 -0
  50. package/src/Components/Form/FormFieldHolder/FormFieldHolder.tsx +55 -0
  51. package/src/Components/Form/FormFieldHolder/FormFieldHolderProps.tsx +15 -0
  52. package/src/Components/Form/FormFieldHolder/formHolder.module.scss +68 -0
  53. package/src/Components/Form/InputProps.tsx +30 -0
  54. package/src/Components/Form/LoadingInput/LoadingInput.tsx +12 -0
  55. package/src/Components/Form/LoadingInput/loadingInput.module.scss +15 -0
  56. package/src/Components/Form/SimpleForm/SimpleForm.stories.tsx +54 -0
  57. package/src/Components/Form/SimpleForm/SimpleForm.tsx +55 -0
  58. package/src/Components/Form/SimpleForm/SimpleFormProps.tsx +11 -0
  59. package/src/Components/Form/SimpleForm/simple-form-bg-design.svg +14 -0
  60. package/src/Components/Form/SimpleForm/simple-form-bg-design.tsx +21 -0
  61. package/src/Components/Form/SimpleForm/simpleForm.module.scss +36 -0
  62. package/src/Components/Form/TextField/TextField.stories.ts +22 -0
  63. package/src/Components/Form/TextField/TextField.tsx +62 -0
  64. package/src/Components/Form/TextField/TextFieldProps.tsx +8 -0
  65. package/src/Components/Form/Textarea/Textarea.stories.ts +31 -0
  66. package/src/Components/Form/Textarea/Textarea.tsx +74 -0
  67. package/src/Components/Form/Textarea/TextareaProps.tsx +28 -0
  68. package/src/Components/Form/Textarea/textarea.module.scss +48 -0
  69. package/src/Components/Form/index.ts +6 -1
  70. package/src/Components/Form/inputs.module.scss +172 -0
  71. package/src/Components/Layout/Footer/Footer.tsx +0 -1
  72. package/src/Components/Layout/Footer/FooterProps.tsx +1 -1
  73. package/src/Components/Shared/Container/container.module.scss +1 -1
@@ -0,0 +1,56 @@
1
+ import cx from 'classnames';
2
+ import styles from '../inputs.module.scss' ;
3
+ import InputProps from "../InputProps";
4
+ import LoadingInput from "../LoadingInput/LoadingInput.tsx";
5
+
6
+ const EmailField = (props: InputProps) => {
7
+ const {
8
+ name,
9
+ id,
10
+ value,
11
+ placeholder,
12
+ extraClass,
13
+ disabled,
14
+ error,
15
+ ariaLabel,
16
+ required,
17
+ readonly,
18
+ autoComplete,
19
+ loading,
20
+ ...args
21
+ } = props;
22
+
23
+ const classes = [styles.input];
24
+ if (error) {
25
+ classes.push(styles.error);
26
+ }
27
+ if (extraClass) {
28
+ classes.push(extraClass);
29
+ }
30
+
31
+ return <div className={styles.field}>
32
+ {loading && <LoadingInput />}
33
+ <input
34
+ className={cx(classes)}
35
+ id={id}
36
+ name={name}
37
+ type='email'
38
+ value={value}
39
+ placeholder={placeholder}
40
+ disabled={disabled}
41
+ readOnly={readonly}
42
+ required={required}
43
+ autoComplete={autoComplete ? "on" : "off"}
44
+ aria-label={ariaLabel ? ariaLabel : name}
45
+ aria-required={required ? "true" : "false"}
46
+ aria-invalid={error ? "true" : "false"}
47
+ aria-disabled={disabled ? "true" : "false"}
48
+ aria-readonly={readonly ? "true" : "false"}
49
+ aria-autocomplete={autoComplete ? "list" : "none"}
50
+ {...args}
51
+ />
52
+ </div>
53
+ };
54
+
55
+
56
+ export default EmailField;
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import { Meta, StoryObj } from "@storybook/react";
3
+ import FormFieldHolder from "./FormFieldHolder";
4
+ import TextField from "../TextField/TextField";
5
+
6
+ const meta: Meta = {
7
+ title: "Form / FormFieldHolder",
8
+ component: FormFieldHolder,
9
+ parameters: {
10
+ layout: "centered",
11
+ },
12
+ tags: ["autodocs"],
13
+ };
14
+
15
+ export default meta;
16
+
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ const FormFieldHolderTemplate: Story = {
20
+ render: () => {
21
+ return (
22
+ <FormFieldHolder optional={true} label="Name" description={"helper text"}>
23
+ <TextField placeholder="Placeholder" />
24
+ </FormFieldHolder>
25
+ );
26
+ },
27
+ };
28
+
29
+ export const FormFieldHolderComponent = {
30
+ ...FormFieldHolderTemplate,
31
+ };
@@ -0,0 +1,55 @@
1
+ import WarningCircle from "../../Icons/SecurityAndWarnings/WarningCircle/WarningCircle";
2
+ import FormFieldHolderProps from "./FormFieldHolderProps";
3
+ import styles from "./formHolder.module.scss";
4
+
5
+ const FormFieldHolder = (props: FormFieldHolderProps) => {
6
+ const {
7
+ icon,
8
+ label,
9
+ bilingualLabel,
10
+ description,
11
+ extraClass = "",
12
+ children,
13
+ error ,
14
+ require,
15
+ optional
16
+ } = props;
17
+
18
+ return (
19
+ <div
20
+ className={`field-holder ${extraClass} ${styles.holder} ${
21
+ error ? styles.holderError : ""
22
+ }`}
23
+ >
24
+ {!!label && (
25
+ <div className={styles.label}>
26
+ {!!icon && (
27
+ <div className={styles.iconAction}>
28
+ {icon}
29
+ </div>
30
+ )}
31
+ <label>{label} {bilingualLabel && (<span>- {bilingualLabel}</span>)} {require && <span>*</span>} {optional && <span>Optional</span>}</label>
32
+ </div>
33
+ )}
34
+ <div className={styles.field}>{children}</div>
35
+
36
+ {!!description && (
37
+ <div className={styles.description}>
38
+ <>
39
+ {error && (
40
+ <div className={styles.helperIcon}>
41
+ <WarningCircle />
42
+ </div>
43
+ )}
44
+ </>
45
+ <>
46
+ {typeof description === "string" && <p>{description}</p>}
47
+ {typeof description !== "string" && <>{description}</>}
48
+ </>
49
+ </div>
50
+ )}
51
+ </div>
52
+ );
53
+ };
54
+
55
+ export default FormFieldHolder;
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from "react";
2
+
3
+ interface FormFieldHolderProps {
4
+ label?: string | any;
5
+ bilingualLabel?: string;
6
+ description?: string | ReactNode;
7
+ extraClass?: string;
8
+ error?: boolean;
9
+ children: ReactNode;
10
+ icon?: ReactNode;
11
+ require?:boolean;
12
+ optional?:boolean;
13
+ }
14
+
15
+ export default FormFieldHolderProps;
@@ -0,0 +1,68 @@
1
+ .holder {
2
+ margin-bottom: 48px;
3
+ width: 100%;
4
+ }
5
+
6
+ .iconAction{
7
+ display: flex;
8
+ align-items: center;
9
+ margin-right: calc(var(--space-unit) * 2);
10
+ }
11
+
12
+ .holderError{
13
+ label{
14
+ color: var(--color-visit);
15
+ }
16
+ }
17
+
18
+ .label {
19
+ display: inline-flex;
20
+ align-items: center;
21
+ margin-bottom: calc(var(--space-unit) * 3);
22
+
23
+ label {
24
+ font-size: var(--font-size-label);
25
+ line-height: var(--line-height-body-regular);
26
+ font-weight: var(--font-weight-bold);
27
+
28
+ span{
29
+ font-size: var(--font-size-optional-label);
30
+ color:var(--color-gray-600);
31
+ line-height: var(--line-height-optional-label);
32
+ font-weight: var(--font-weight-optional-label);
33
+ }
34
+
35
+ }
36
+ }
37
+
38
+
39
+ .description {
40
+ display: flex;
41
+ align-items: center;
42
+ font-size: var(--font-size-body-sm);
43
+ line-height: var(--line-height-body-sm);
44
+ font-weight: var(--font-weight-body-sm);
45
+ padding-top: calc(var(--space-unit) * 2);
46
+ color: var(--color-description);
47
+
48
+ p {
49
+ font-size: var(--font-size-body-sm);
50
+ line-height: var(--line-height-body-sm);
51
+ font-weight: var(--font-weight-body-sm);
52
+ }
53
+
54
+ .helperIcon {
55
+ margin-right: var(--space-unit);
56
+ display: flex;
57
+ align-items: center;
58
+
59
+ svg {
60
+ width: 16px;
61
+ height: 16px;
62
+ }
63
+ }
64
+
65
+ .holderError & {
66
+ color: var(--color-error);
67
+ }
68
+ }
@@ -0,0 +1,30 @@
1
+ import {FocusEvent, ChangeEvent, MouseEvent, KeyboardEvent} from "react";
2
+
3
+ interface InputProps {
4
+ name?: string;
5
+ id?: string;
6
+ value?: string | number | bigint | any;
7
+ extraClass?: string;
8
+ placeholder?: string;
9
+ error?: boolean;
10
+ disabled?:boolean;
11
+ readonly?: boolean;
12
+ autoComplete?: boolean;
13
+ required?: boolean;
14
+ ariaLabel?: string;
15
+ min?: string,
16
+ max?: string,
17
+ minLength?: number;
18
+ maxLength?: number;
19
+ ariaLabeledby?: string;
20
+ ariaDescribedby?: string;
21
+ onClick?: (e: MouseEvent) => void;
22
+ onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
23
+ onFocus?: (e: FocusEvent) => void;
24
+ onBlur?: (e: FocusEvent) => void;
25
+ onKeyDown?:(e: KeyboardEvent<HTMLInputElement>) => void;
26
+ loading?:boolean;
27
+
28
+ }
29
+
30
+ export default InputProps;
@@ -0,0 +1,12 @@
1
+
2
+
3
+ import Skeleton from "react-loading-skeleton";
4
+ import styles from "./loadingInput.module.scss";
5
+
6
+ const LoadingInput = () =>{
7
+ return <div className={styles.loadingInput}>
8
+ <Skeleton className={styles.skeleton} width={`100%`} height={'100%'}/>
9
+ </div>
10
+ }
11
+
12
+ export default LoadingInput;
@@ -0,0 +1,15 @@
1
+ .loadingInput{
2
+ display: flex;
3
+ width: 100%;
4
+ position: absolute;
5
+ top: 0;
6
+ right: 0;
7
+ left: 0;
8
+ bottom: 0;
9
+ z-index: 10;
10
+
11
+ .skeleton{
12
+ position: absolute;
13
+ }
14
+
15
+ }
@@ -0,0 +1,54 @@
1
+ import React from "react";
2
+ import { Meta, StoryObj } from "@storybook/react-vite"
3
+ import SimpleForm from "./SimpleForm"
4
+ import { ElementHolder } from "../../Shared";
5
+ import TextField from "../TextField/TextField";
6
+ import EmailField from "../EmailField/EmailField";
7
+ import Textarea from "../Textarea/Textarea";
8
+ import Checkbox from "../Checkbox/Checkbox";
9
+ import Button from "../Button/Button";
10
+ import ArrowRight from "../../Icons/Arrows/ArrowRight/ArrowRight";
11
+ import FormFieldHolder from "../FormFieldHolder/FormFieldHolder";
12
+
13
+
14
+ const meta: Meta = {
15
+ title: "Form / SimpleForm",
16
+ component: SimpleForm,
17
+ parameters: {
18
+ layout: 'fullscreen',
19
+ },
20
+ tags: ["autodocs"]
21
+ };
22
+
23
+ export default meta;
24
+
25
+ type Story = StoryObj<typeof meta>
26
+
27
+ const SimpleFormTemplate: Story = {
28
+ render: () => {
29
+ return (
30
+ <ElementHolder paddingTop="sm" paddingBottom="md" pillar="visit" level="light">
31
+ <SimpleForm
32
+ formTitle={'Send us a message'}
33
+ formText={'We appreciate you taking the time to get in touch. We’ll get back to you within the next day.'}
34
+ children={
35
+ <>
36
+ <FormFieldHolder label={'Name*'} >
37
+ <TextField required/>
38
+ </FormFieldHolder>
39
+ <FormFieldHolder label={'Email*'}><EmailField required/></FormFieldHolder>
40
+ <FormFieldHolder label={'Phone number'}><TextField /></FormFieldHolder>
41
+ <FormFieldHolder label={'Your message'}><Textarea /></FormFieldHolder>
42
+ <Checkbox label={"I’d love to receive updates about events and happenings in Selwyn."} />
43
+ </>
44
+ }
45
+ action={<Button label="SUBMIT" secondaryIcon={<ArrowRight />} />}
46
+ />
47
+ </ElementHolder>
48
+ )
49
+ }
50
+ }
51
+
52
+ export const SimpleFormComponent = {
53
+ ...SimpleFormTemplate
54
+ }
@@ -0,0 +1,55 @@
1
+ import cx from 'classnames';
2
+ import { Container } from "../../Shared";
3
+ import SimpleFormProps from "./SimpleFormProps";
4
+ import SimpleFormBgDesign from "./simple-form-bg-design";
5
+ import styles from "./simpleForm.module.scss"
6
+
7
+ const SimpleForm = (props: SimpleFormProps) => {
8
+ const {
9
+ formTitle,
10
+ formText,
11
+ extraClass,
12
+ children,
13
+ action
14
+ } = props
15
+
16
+ const classes = [
17
+ "button"
18
+ ]
19
+
20
+ if (extraClass) {
21
+ classes.push(extraClass)
22
+ }
23
+ return (
24
+ <div className={`${styles.simpleFormBlock} ${extraClass}`}>
25
+ <Container>
26
+ <div className={styles.simpleFormBlockWrapper}>
27
+ <h1>{formTitle}</h1>
28
+ <h2>{formText}</h2>
29
+
30
+ <div className={styles.simpleFormBgDesignContainer}>
31
+ <SimpleFormBgDesign />
32
+ </div>
33
+
34
+ <div className={styles.simpleFormInputsWrapper}>
35
+ {children}
36
+
37
+ {/* <div className={`${styles.simpleFormButtonWrapper} ${extraClass} ${cx(classes)}`}>
38
+ {action}
39
+ </div> */}
40
+ <div className={cx(
41
+ styles.simpleFormButtonWrapper,
42
+ extraClass,
43
+ "button"
44
+ )}>
45
+ {action}
46
+ </div>
47
+ </div>
48
+ </div>
49
+
50
+ </Container>
51
+ </div>
52
+ )
53
+ }
54
+
55
+ export default SimpleForm;
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from "react";
2
+
3
+ interface SimpleFormProps {
4
+ formTitle?: string
5
+ formText?: string
6
+ extraClass?: string
7
+ children?: ReactNode
8
+ action?: ReactNode
9
+ }
10
+
11
+ export default SimpleFormProps;
@@ -0,0 +1,14 @@
1
+ <svg width="787" height="361" viewBox="0 0 787 361" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g opacity="0.05">
3
+ <path opacity="0.5" d="M0 120.333C66.601 120.333 120.606 169.838 120.606 230.889H0V120.333Z" fill="#23461F"/>
4
+ <path opacity="0.25" d="M251.772 120.333C185.171 120.333 131.166 169.838 131.166 230.889H251.772V120.333Z" fill="#23461F"/>
5
+ <path opacity="0.5" d="M776.44 230.889C709.839 230.889 655.834 181.384 655.834 120.333H776.44V230.889Z" fill="#23461F"/>
6
+ <path opacity="0.75" d="M131.166 240.667C197.767 240.667 251.772 290.171 251.772 351.222H131.166V240.667Z" fill="#23461F"/>
7
+ <path opacity="0.5" d="M262.334 351.222C328.935 351.222 382.94 301.717 382.94 240.667H262.334V351.222Z" fill="#23461F"/>
8
+ <path opacity="0.25" d="M514.105 351.222C447.504 351.222 393.499 301.718 393.499 240.667H514.105V351.222Z" fill="#23461F"/>
9
+ <path opacity="0.75" d="M645.273 240.667C578.672 240.667 524.667 290.171 524.667 351.222H645.273V240.667Z" fill="#23461F"/>
10
+ <path opacity="0.25" d="M524.666 4.88878C591.267 4.88878 645.272 54.3934 645.272 115.444H524.666V4.88878Z" fill="#23461F"/>
11
+ <path opacity="0.5" d="M393.499 230.889C460.1 230.889 514.105 181.384 514.105 120.333H393.499V230.889Z" fill="#23461F"/>
12
+ <path opacity="0.75" d="M262.334 110.556C328.935 110.556 382.94 61.0509 382.94 0H262.334V110.556Z" fill="#23461F"/>
13
+ </g>
14
+ </svg>
@@ -0,0 +1,21 @@
1
+ const SimpleFormBgDesign = () => {
2
+ return (
3
+ <svg width="787" height="361" viewBox="0 0 787 361" fill="none" xmlns="http://www.w3.org/2000/svg">
4
+ <g opacity="0.05">
5
+ <path opacity="0.5" d="M0 120.333C66.601 120.333 120.606 169.838 120.606 230.889H0V120.333Z" fill="#23461F" />
6
+ <path opacity="0.25" d="M251.772 120.333C185.171 120.333 131.166 169.838 131.166 230.889H251.772V120.333Z" fill="#23461F" />
7
+ <path opacity="0.5" d="M776.44 230.889C709.839 230.889 655.834 181.384 655.834 120.333H776.44V230.889Z" fill="#23461F" />
8
+ <path opacity="0.75" d="M131.166 240.667C197.767 240.667 251.772 290.171 251.772 351.222H131.166V240.667Z" fill="#23461F" />
9
+ <path opacity="0.5" d="M262.334 351.222C328.935 351.222 382.94 301.717 382.94 240.667H262.334V351.222Z" fill="#23461F" />
10
+ <path opacity="0.25" d="M514.105 351.222C447.504 351.222 393.499 301.718 393.499 240.667H514.105V351.222Z" fill="#23461F" />
11
+ <path opacity="0.75" d="M645.273 240.667C578.672 240.667 524.667 290.171 524.667 351.222H645.273V240.667Z" fill="#23461F" />
12
+ <path opacity="0.25" d="M524.666 4.88878C591.267 4.88878 645.272 54.3934 645.272 115.444H524.666V4.88878Z" fill="#23461F" />
13
+ <path opacity="0.5" d="M393.499 230.889C460.1 230.889 514.105 181.384 514.105 120.333H393.499V230.889Z" fill="#23461F" />
14
+ <path opacity="0.75" d="M262.334 110.556C328.935 110.556 382.94 61.0509 382.94 0H262.334V110.556Z" fill="#23461F" />
15
+ </g>
16
+ </svg>
17
+
18
+ )
19
+ }
20
+
21
+ export default SimpleFormBgDesign;
@@ -0,0 +1,36 @@
1
+ .simpleFormBlock {
2
+ max-width: 910px;
3
+
4
+ .simpleFormBlockWrapper {
5
+ h1 {
6
+ font-size: var(--font-size-h4);
7
+ font-weight: var(--font-weight-h4);
8
+ line-height: var(--line-height-h4);
9
+ }
10
+
11
+ h2 {
12
+ padding-block: 72px;
13
+ font-size: var(--font-size-h6);
14
+ font-weight: var(--font-weight-h4);
15
+ line-height: var(--line-height-h6);
16
+ }
17
+
18
+ .simpleFormBgDesignContainer {
19
+ display: block;
20
+ position: absolute;
21
+ top: -120px;
22
+ bottom: 0;
23
+ right: 0;
24
+ }
25
+
26
+ .simpleFormInputsWrapper {
27
+ .simpleFormButtonWrapper {
28
+ button {
29
+ color: var(--color-sand);
30
+ margin-top: 72px;
31
+ }
32
+ }
33
+
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,22 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+
3
+ import TextField from "./TextField.tsx";
4
+
5
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
6
+ const meta = {
7
+ title: "Form / TextField",
8
+ component: TextField,
9
+ parameters: {
10
+ layout: "centered",
11
+ },
12
+ tags: ["autodocs"],
13
+ } satisfies Meta<typeof TextField>;
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof TextField>;
17
+
18
+ export const Example: Story = {
19
+ args: {
20
+ placeholder: "Placeholder",
21
+ },
22
+ };
@@ -0,0 +1,62 @@
1
+ import cx from "classnames";
2
+ import styles from "../inputs.module.scss";
3
+ import TextFieldProps from "./TextFieldProps";
4
+ import LoadingInput from "../LoadingInput/LoadingInput";
5
+
6
+ const TextField = (props: TextFieldProps) => {
7
+ const {
8
+ name,
9
+ id,
10
+ value,
11
+ placeholder,
12
+ extraClass,
13
+ disabled,
14
+ error,
15
+ ariaLabel,
16
+ required,
17
+ readonly,
18
+ autoComplete,
19
+ icon,
20
+ loading,
21
+ ...args
22
+ } = props;
23
+
24
+ const classes = [styles.input];
25
+ if (error) {
26
+ classes.push(styles.error);
27
+ }
28
+ if (extraClass) {
29
+ classes.push(extraClass);
30
+ }
31
+
32
+
33
+ return (
34
+ <div className={`${icon ? styles.textField : ""} ${loading ? styles.fieldLoading : ""}`}>
35
+ <div className={styles.field}>
36
+ {loading && <LoadingInput />}
37
+ <input
38
+ className={cx(classes)}
39
+ id={id}
40
+ name={name}
41
+ type="text"
42
+ value={value}
43
+ placeholder={placeholder}
44
+ disabled={disabled}
45
+ readOnly={readonly}
46
+ required={required}
47
+ autoComplete={autoComplete ? "on" : "off"}
48
+ aria-label={ariaLabel ? ariaLabel : name}
49
+ aria-required={required ? "true" : "false"}
50
+ aria-invalid={error ? "true" : "false"}
51
+ aria-disabled={disabled ? "true" : "false"}
52
+ aria-readonly={readonly ? "true" : "false"}
53
+ aria-autocomplete={autoComplete ? "list" : "none"}
54
+ {...args}
55
+ />
56
+ </div>
57
+ {!!icon && <div className={styles.textFieldIcon}>{icon}</div>}
58
+ </div>
59
+ );
60
+ };
61
+
62
+ export default TextField;
@@ -0,0 +1,8 @@
1
+ import { ReactNode } from "react";
2
+ import InputProps from "../InputProps";
3
+
4
+ interface TextFieldProps extends InputProps {
5
+ icon?: ReactNode;
6
+ }
7
+
8
+ export default TextFieldProps;
@@ -0,0 +1,31 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import Textarea from './Textarea.tsx';
4
+
5
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
6
+ const meta = {
7
+ title: 'Form / Textarea',
8
+ component: Textarea,
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ tags: ['autodocs'],
13
+ } satisfies Meta<typeof Textarea>;
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof Textarea>;
17
+
18
+ export const Example:Story = {
19
+ args: {
20
+ placeholder: 'Placeholder'
21
+ },
22
+ };
23
+
24
+ export const MaxLength:Story = {
25
+ args: {
26
+ placeholder: 'Placeholder',
27
+ maxLength: 500,
28
+ displayChars: true
29
+ },
30
+ };
31
+