Skip to content

Commit

Permalink
feat: TUP-700 @tacc/core-components - use, test, fix (#465)
Browse files Browse the repository at this point in the history
* fix: revert FormikFieldWrapper→FieldWrapperFormik

* fix: support .js imports

* chore: use index.js when component is .jsx

* fix: make FormikCheck useField like other fields

* fix: FieldWrapper… TACC-Cloud/Hazmapper form crash

TACC-Cloud/hazmapper's only form crashed.
If checkbox is removed, then now it doesn't.

Expect checkbox fix in next commit.

TACC-Cloud/hazmapper#239

* fix: FieldWrapper…  TACC-Cloud/Hazmapper checkbox

TACC-Cloud/hazmapper's only checkbox field crashed. Now it doesn't.

TACC-Cloud/hazmapper#239

* fix: FormikCheck not supporting ID attr

* chore: npx nx format:write

* fix: FieldWrapper… ID fallback support incomplete

* fix: remove unused prop

* refactor: use Formik field wrappers as components

* fix: FieldWrapper… ID fallback support STILL incomplete

* docs: update author, add contributors

* Move to peer dependencies (#484)

* Move to peer dependencies

Also add vite for building as we want to make stand-alone

* Make 0.0.3 prelease

* Bump postcss and postcss-preset-env to match core styles requirements

* Fix pretty issue

* Add vite-plugin-lib-inject-css

* Make uuid only as a dependeny allow any 8 or 9 version

---------

Co-authored-by: Wesley B <[email protected]>

---------

Co-authored-by: Nathan Franklin <[email protected]>
  • Loading branch information
wesleyboar and nathanfranklin authored Oct 18, 2024
1 parent fd993c2 commit bb8571d
Show file tree
Hide file tree
Showing 33 changed files with 5,867 additions and 3,721 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { FormikInput } from '@tacc/core-components';
import * as Yup from 'yup';
import { UIWizardStep, useWizardValues, InitialValueGenerator } from '..';
import { Field } from 'formik';

export const StepOne: React.FC = () => {
const { extra } = useWizardValues();
return (
<div>
<h2>Step One: Extra value two is {extra.extraTwo}</h2>
<FormikInput
<Field
component={FormikInput}
name="fieldOne"
required={true}
label="Field One"
description="The first form field"
/>
<FormikInput
<Field
component={FormikInput}
name="fieldTwo"
required={false}
label="Field Two"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import React from 'react';
import { FormGroup } from 'reactstrap';
import { Collapse, Button } from '@tacc/core-components';
import { FieldArray, useFormikContext, FieldArrayRenderProps } from 'formik';
import {
FieldArray,
useFormikContext,
FieldArrayRenderProps,
Field,
} from 'formik';
import { FormikInput, FormikCheck } from '@tacc/core-components';
import * as Yup from 'yup';
import fieldArrayStyles from './FieldArray.module.css';
Expand Down Expand Up @@ -34,13 +39,15 @@ const UIWizardComplexFieldRender: React.FC<UIWizardComplexFieldRenderProps> = ({
note="more values inside"
className={fieldArrayStyles.item}
>
<FormikInput
<Field
component={FormikInput}
name={`${innerKey}.name`}
label="Name"
required={true}
description="Name field of this object"
/>
<FormikCheck
<Field
component={FormikCheck}
name={`${innerKey}.include`}
label="Include"
required={false}
Expand Down Expand Up @@ -114,7 +121,8 @@ const OuterItemRender: React.FC<FieldArrayOfArraysRenderProps> = ({
title={`Field Array ${outerIndex}`}
className={fieldArrayStyles.item}
>
<FormikInput
<Field
component={FormikInput}
name={`fieldArrayOfArrays.${outerIndex}.name`}
label="Name"
required={true}
Expand Down
13 changes: 10 additions & 3 deletions apps/ui-patterns/src/app/UIPatternsComplexWizard/steps/StepTwo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import React from 'react';
import { Button } from '@tacc/core-components';
import fieldArrayStyles from './FieldArray.module.css';
import { Collapse } from '@tacc/core-components';
import { FieldArray, useFormikContext, FieldArrayRenderProps } from 'formik';
import {
FieldArray,
useFormikContext,
FieldArrayRenderProps,
Field,
} from 'formik';
import { FormikInput, FormikCheck } from '@tacc/core-components';
import {
UIWizardStep,
Expand Down Expand Up @@ -37,13 +42,15 @@ const UIWizardComplexFieldRender: React.FC<UIWizardComplexFieldProps> = ({
note="more values inside"
className={fieldArrayStyles.item}
>
<FormikInput
<Field
component={FormikInput}
name={`fieldArray.${index}.name`}
label="Name"
required={true}
description="Name field of this object"
/>
<FormikCheck
<Field
component={FormikCheck}
name={`fieldArray.${index}.include`}
label="Include"
required={false}
Expand Down
7 changes: 5 additions & 2 deletions apps/ui-patterns/src/app/UIPatternsWizard/steps/StepOne.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ import { FormikInput } from '@tacc/core-components';
import { WizardStep } from '@tacc/core-components';
import * as Yup from 'yup';
import { useWizardValues, UIWizardSchema } from '..';
import { Field } from 'formik';

export const StepOne: React.FC = () => {
return (
<div>
<h2>Step One</h2>
<FormikInput
<Field
component={FormikInput}
name="fieldOne"
required={true}
label="Name"
description="The first form field"
/>
<FormikInput
<Field
component={FormikInput}
name="fieldTwo"
required={false}
label="Description"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { FormikInput } from '@tacc/core-components';
import { WizardStep } from '@tacc/core-components';
import * as Yup from 'yup';
import { useWizardValues, UIWizardSchema } from '..';
import { Field } from 'formik';

export const StepThree: React.FC = () => {
return (
<div>
<h2>Step Three</h2>
<FormikInput
<Field
component={FormikInput}
name="fieldFour"
required={true}
label="Field Four"
Expand Down
4 changes: 3 additions & 1 deletion apps/ui-patterns/src/app/UIPatternsWizard/steps/StepTwo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { FormikInput } from '@tacc/core-components';
import { WizardStep } from '@tacc/core-components';
import * as Yup from 'yup';
import { useWizardValues, UIWizardSchema } from '..';
import { Field } from 'formik';

export const StepTwo: React.FC = () => {
return (
<div>
<h2>Step Two</h2>
<FormikInput
<Field
component={FormikInput}
name="fieldThree"
required={true}
label="Field Three"
Expand Down
24 changes: 16 additions & 8 deletions libs/core-components/package.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
{
"name": "@tacc/core-components",
"version": "0.0.2",
"version": "0.0.3-beta.0",
"license": "MIT",
"author": "TACC ACI WMA <[email protected]>",
"author": "TACC ACI WMA <[email protected]>",
"contributors": [
"TACC COA CMD <[email protected]>"
],
"description": "React component library for TACC applications.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"homepage": "https://github.com/TACC/tup-ui/libs/core-components",
"scripts": {
"build": "vite build --outDir dist"
},
"dependencies": {
"uuid": "^8 || ^9"
},
"peerDependencies": {
"formik": "^2.2.9",
"react": "18.2.0",
"react-dom": "18.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-resize-detector": "^7.1.2",
"react-router-dom": "6.11.2",
"react-router-dom": "^6.11.2",
"react-step-wizard": "^5.3.11",
"react-table": "^7.8.0",
"reactstrap": "^9.1.5",
"uuid": "^8.3.2"
"reactstrap": "^9.1.5"
},
"devDependencies": {
"@nx/react": "^17.2.8",
Expand All @@ -30,7 +38,7 @@
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.5.2",
"@vitejs/plugin-react-swc": "^3.5.0",
"uuid": "^8.3.2",
"vite": "^5.0.11",
"vite-plugin-dts": "^2.3.0",
"vite-plugin-lib-inject-css": "^2.1.1",
"vite-tsconfig-paths": "^4.2.0"
Expand Down
4 changes: 2 additions & 2 deletions libs/core-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ export { default as SubmitWrapper } from './lib/SubmitWrapper';
export { default as Wizard, useWizard, WizardNavigation } from './lib/Wizard';
export type WizardStep<T> = WizardStepType<T>;
export {
FormikFieldWrapper,
FieldWrapperFormik,
FormikInput,
FormikSelect,
FormikCheck,
FormikTextarea,
FormikFileInput,
} from './lib/FormikFieldWrapper';
} from './lib/FieldWrapperFormik';

export { default as withBuilder } from './utils/withBuilder';
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
import React from 'react';
import { ErrorMessage } from 'formik';
import { FieldProps } from 'formik';
import { Badge } from 'reactstrap';

import './FormikFieldWrapper.global.css';
import './FieldWrapperFormik.global.css';

export type FieldWrapperProps = {
name: string;
id?: string;
label: React.ReactNode;
required?: boolean;
className?: string;
description?: React.ReactNode;
formik: FieldProps;
};

const FieldWrapper: React.FC<React.PropsWithChildren<FieldWrapperProps>> = ({
name,
id,
label,
required,
description,
className,
children,
formik: { field, form },
}) => {
return (
<div
className={`c-form__field ${required ? 'has-required' : ''} ${className}`}
>
<label htmlFor={name}>
<label htmlFor={id || field.name}>
{label}
{required && <Badge color="danger">Required</Badge>}
</label>
{children}
<ErrorMessage name={name}>
{(msg) => {
return (
<ul className="c-form__errors">
<li>{msg}</li>
</ul>
);
}}
</ErrorMessage>
{form.touched[field.name] && form.errors[field.name] ? (
<ul className="c-form__errors">
{/* https://github.com/jaredpalmer/formik/issues/3683#issuecomment-1752751768 */}
<li>{String(form.errors[field.name])}</li>
</ul>
) : null}
{description && <div className="c-form__help">{description}</div>}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import FieldWrapper from '../FieldWrapperFormik';
import { FormikInputProps } from '.';

const FormikCheck: React.FC<FormikInputProps> = ({
id,
name,
label,
required,
description,
field,
form,
meta,
...props
}: FormikInputProps) => {
return (
<FieldWrapper
id={id || field.name}
label={label}
required={required}
description={description}
formik={{ field, form, meta }}
className="has-type-check"
>
<input
{...field}
{...props}
type="checkbox"
checked={field.value}
id={id || field.name}
/>
</FieldWrapper>
);
};

export default FormikCheck;
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { InlineMessage, Button } from '../../../..';
import styles from './FileDropzone.module.css';

interface FileInputDropzoneProps {
id: string;
files: File[];
onDrop: (files: File[]) => void;
onRemoveFile: (index: number) => void;
Expand All @@ -18,6 +19,7 @@ interface FileInputDropzoneProps {
* and user can manage (e.g. delete those files) directly in this component.
*/
const FileInputDropZone: React.FC<FileInputDropzoneProps> = ({
id,
files,
onDrop,
maxSize,
Expand Down Expand Up @@ -60,7 +62,7 @@ const FileInputDropZone: React.FC<FileInputDropzoneProps> = ({
return (
// eslint-disable-next-line react/jsx-props-no-spreading
<div {...getRootProps()} className={styles['dropzone-area']}>
<input {...getInputProps()} data-testid="dropzone-input" />
<input {...getInputProps()} data-testid="dropzone-input" id={id} />
{!showFileList && (
<div className={styles['no-attachment-view']}>
<i className="icon icon-upload" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/* FP-993: Allow use by DataFilesUploadModal */
import React from 'react';
import { useField } from 'formik';
import { useField, FieldProps } from 'formik';
import FileInputDropZone from './FileDropzone';
import FieldWrapper from '../../FormikFieldWrapper';
import FieldWrapper from '../../FieldWrapperFormik';

interface FormikFileInputProps {
interface FormikFileInputProps extends FieldProps {
id: string;
name: string;
label: string;
required: boolean;
Expand All @@ -14,14 +15,18 @@ interface FormikFileInputProps {
}

const FileInputDropZoneFormField: React.FC<FormikFileInputProps> = ({
id,
name,
label,
description,
maxSizeMessage,
maxSize,
required,
field,
form,
meta,
}) => {
const [field, , helpers] = useField<File[]>(name);
const [, , helpers] = useField<File[]>(name);

const onSetFiles = (acceptedFiles: File[]) => {
const newAcceptedFiles = acceptedFiles.filter(
Expand All @@ -35,12 +40,14 @@ const FileInputDropZoneFormField: React.FC<FormikFileInputProps> = ({
};
return (
<FieldWrapper
name={name}
id={id || field.name}
label={label}
required={required}
description={description}
formik={{ field, form, meta }}
>
<FileInputDropZone
id={id || field.name}
files={field.value}
onDrop={onSetFiles}
onRemoveFile={onRemoveFile}
Expand Down
Loading

0 comments on commit bb8571d

Please sign in to comment.