Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core-styles): extend root postcss config #16

Closed
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
fb99d12
task/TUP-272 - core components fixup (#7)
jchuahtacc Jun 16, 2022
39ca073
task/TUP-280 -- UI patterns (#12)
jchuahtacc Jun 20, 2022
bf53fe8
task/TUP-280, 282, 283 -- UI patterns (fixes), CSS vars, styles (#14)
wesleyboar Jun 22, 2022
f4948b6
feat(core-styles): use root postcss config
wesleyboar Jun 22, 2022
a44b7be
Merge branch 'main' into milestone/001--core-components
wesleyboar Jun 24, 2022
8baf3fd
fix(core-components): missing dependency, dependency alternative (#13)
wesleyboar Jun 27, 2022
0071c50
Merge branch 'main' of github.com:TACC/tup-ui into milestone/001--cor…
jchuahtacc Jun 27, 2022
60df0dd
Merge branch 'milestone/001--core-components' of github.com:TACC/tup-…
jchuahtacc Jun 27, 2022
879717e
task/TUP - 284 -- core wrappers (#15)
jchuahtacc Jul 5, 2022
de81d57
Merge branch 'milestone/001--core-components' into milestone/001--cor…
wesleyboar Jul 6, 2022
a37a7da
fix(core-styles): load root css config after base
wesleyboar Jul 8, 2022
8e4279a
Merge branch 'main' into milestone/001--core-components
wesleyboar Jul 10, 2022
e1c776c
Merge branch 'milestone/001--core-components' into milestone/001--cor…
wesleyboar Jul 10, 2022
2bd2ac7
Merge branch 'main' into milestone/001--core-components
wesleyboar Jul 23, 2022
d3d3e69
Merge branch 'milestone/001--core-components' into milestone/001--cor…
wesleyboar Jul 23, 2022
3334f1f
Merge branch 'main' into milestone/001--core-components--core-postcss…
wesleyboar Jul 25, 2022
42c4325
Merge branch 'main' into milestone/001--core-components--core-postcss…
wesleyboar Aug 11, 2022
9891f60
Merge branch 'main' into milestone/001--core-components--core-postcss…
wesleyboar Oct 20, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
{
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@nrwl/nx/typescript"],
"rules": {}
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
},
{
"files": ["*.js", "*.jsx"],
Expand Down
16 changes: 0 additions & 16 deletions apps/ui-patterns/.browserslistrc

This file was deleted.

4 changes: 2 additions & 2 deletions apps/ui-patterns/jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-disable */
export default {
displayName: 'tup-ui',
displayName: 'ui-patterns',
preset: '../../jest.preset.js',
transform: {
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
'^.+\\.[tj]sx?$': 'babel-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/apps/tup-ui',
coverageDirectory: '../../coverage/apps/ui-patterns',
};
8 changes: 4 additions & 4 deletions apps/ui-patterns/src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import UIPatterns from './UIPatterns';

const App: React.FC = () => {
return (
<Router>
<Switch>
<Route path="/" component={UIPatterns} />
</Switch>
<Routes>
<Route path="/" element={<UIPatterns />} />
</Routes>
</Router>
);
};
Expand Down
12 changes: 11 additions & 1 deletion apps/ui-patterns/src/app/UIPatterns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import UIPatternsShowMore from './UIPatternsShowMore';
import UIPatternsPaginator from './UIPatternsPaginator';
import UIPatternsButton from './UIPatternsButton';
import UIPatternsSidebar from './UIPatternsSidebar';
import styles from './UIPatterns.module.scss';
import UIPatternsWizard from './UIPatternsWizard';
import UIPatternsComplexWizard from './UIPatternsComplexWizard';
import styles from './UIPatterns.module.css';

const UIPatterns: React.FC = () => {
return (
Expand Down Expand Up @@ -55,6 +57,14 @@ const UIPatterns: React.FC = () => {
<h6>Sidebar</h6>
<UIPatternsSidebar />
</div>
<div className={styles['list-item']}>
<h6>Wizard</h6>
<UIPatternsWizard />
</div>
<div className={styles['list-item']}>
<h6>Complex Wizard</h6>
<UIPatternsComplexWizard />
</div>
</>
}
contentLayoutName="oneColumn"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* UIPatternsComplexWizard.tsx
*
* Example of how to create a wizard that supports extra values passed in (possibly via hook)
* that are used in initial value generation and custom step validation. This also includes
* examples of how to use Field Arrays in Formik
*/
import React, { useCallback, useMemo } from 'react';
import useWizardValues, { UIWizardProvider } from './useWizardValues';
import { UIWizardStep, UIWizardSchema, UIWizardExtra } from '.';
import { Wizard, WizardStep } from '@tacc/core-wrappers';
import wizardSteps from './steps';

export const UIPatternsComplexWizardRender: React.FC<{
wizardSteps: Array<UIWizardStep>;
}> = ({ wizardSteps }) => {
const { values, add, extra } = useWizardValues();

// The submit button rendered by the Wizard should add values to the
// wizard value context
const formSubmit = useCallback(
(value: Partial<UIWizardSchema>) => {
console.log('Adding', value);
add(value);
},
[add]
);

// Map Array of UIWizardSteps into an array of @tacc/core-wrappers/WizardStep
const steps: Array<WizardStep<UIWizardSchema>> = useMemo(() => {
return wizardSteps.map((jobStep) => {
const { generateInitialValues, validateThunk, ...stepProps } = jobStep;
return {
// Call the step's custom initial value generator to pass in the extra hook values
initialValues: generateInitialValues({ values, extra }),
// generate a validation function from the UIWizardSteps's validateThunk, given the current extra hook values
validate: validateThunk ? validateThunk(extra) : undefined,
...stepProps,
};
});
}, [wizardSteps, extra]);

return (
<Wizard steps={steps} memo={`${extra.memo}`} formSubmit={formSubmit} />
);
};

const UIPatternsComplexWizard: React.FC = () => {
const defaultValues: Partial<UIWizardSchema> = {
fieldArray: [{ name: 'item one', include: true }],
fieldArrayOfArrays: [
{
name: 'outer item',
fieldArray: [{ name: 'inner item one', include: true }],
},
],
};
const extra: UIWizardExtra = {
extraOne: 'extra value one',
extraTwo: 'extra value two',
memo: 'wizard.memo',
};
return (
<UIWizardProvider value={{ defaultValues, extra }}>
<UIPatternsComplexWizardRender wizardSteps={wizardSteps} />
</UIWizardProvider>
);
};

export default UIPatternsComplexWizard;
54 changes: 54 additions & 0 deletions apps/ui-patterns/src/app/UIPatternsComplexWizard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export { default } from './UIPatternsComplexWizard';
export {
default as useWizardValues,
UIWizardProvider,
} from './useWizardValues';

export type UIWizardComplexField = {
name: string;
include?: boolean;
};

export type UIWizardArrayOfComplexFields = {
name: string;
fieldArray: Array<UIWizardComplexField>;
};

export type UIWizardSchema = {
fieldOne: string;
fieldTwo: string;
fieldThree: string;
fieldFour: number;
fieldArray: Array<UIWizardComplexField>;
fieldArrayOfArrays: Array<UIWizardArrayOfComplexFields>;
};

export type UIWizardExtra = {
extraOne: string;
extraTwo: string;
memo: string;
};

export type InitialValueGenerator = (hookValues: {
values: Partial<UIWizardSchema>;
extra: UIWizardExtra;
}) => Partial<UIWizardSchema>;

// An adapter type for mapping additional values to @tacc/core-wrappers/Wizard
export type UIWizardStep = {
id: string;
name: string;
render: React.ReactNode;
summary: React.ReactNode;
// A generator for initial values. Due to the way Formik renders with respect to step skipping,
// a generator is needed to create an initialValues object
generateInitialValues: InitialValueGenerator;
// A custom validator thunk for a step that requires extra values
// (This returns a custom validation function)
validateThunk?: (
extra: UIWizardExtra
/* eslint-disable-next-line */
) => (values: Partial<UIWizardSchema>) => any;
/* eslint-disable-next-line */
validationSchema: any;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.array {
border: 1px solid gray;
padding: 0.5em 0.5em 0.5em 0.5em;
margin-bottom: 0.5em;
}

.item {
border: 1px dotted lightgray;
padding: 0.5em 0.5em 0.5em 0.5em;
margin-bottom: 1em;
}

.array-group {
margin-bottom: 0.5em;
}

.description {
font-style: italic;
font-size: smaller;
margin-bottom: 0.5em;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, { useCallback, useState, useMemo } from 'react';
import * as Yup from 'yup';
import { UIWizardStep, UIWizardSchema, InitialValueGenerator } from '..';
import { Button } from '@tacc/core-components';
import { SubmitWrapper } from '@tacc/core-wrappers';
import { validationSchema as stepOneValidationSchema } from './StepOne';
import { validationSchema as stepTwoValidationSchema } from './StepTwo';
import { validationSchema as stepThreeValidationSchema } from './StepThree';
import { useWizardValues } from '../../UIPatternsWizard';

export const LastStep: React.FC = () => {
const [submitResult, setSubmitResult] = useState({
data: undefined as undefined | string,
isLoading: false,
error: null,
});

const onSubmit = useCallback(() => {
setSubmitResult({ data: 'Submitted!', isLoading: false, error: null });
}, [setSubmitResult]);

const { data: formData } = useWizardValues();

const valid = useMemo(() => {
try {
const concatSchema = [
stepOneValidationSchema,
stepTwoValidationSchema,
stepThreeValidationSchema,
].reduce((previous, current) => previous.concat(current), Yup.object());
return concatSchema.validateSync(formData);
} catch {
return false;
}
}, [formData]);

const { error, data, isLoading } = submitResult;
return (
<div>
<h2>Last Step</h2>
<div>
<SubmitWrapper error={error} isLoading={isLoading} success={data}>
<Button
type="primary"
onClick={onSubmit}
size="long"
disabled={!valid}
>
Submit
</Button>
</SubmitWrapper>
</div>
</div>
);
};

export const LastStepSummary: React.FC = () => {
return null;
};

const generateInitialValues: InitialValueGenerator =
(): Partial<UIWizardSchema> => ({});

// Form steps require a validation schema
const validationSchema = Yup.object({});

const lastStep: UIWizardStep = {
id: 'stepLast',
name: 'Last Step',
render: <LastStep />,
summary: <LastStepSummary />,
generateInitialValues,
validationSchema,
};

export default lastStep;
61 changes: 61 additions & 0 deletions apps/ui-patterns/src/app/UIPatternsComplexWizard/steps/StepOne.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { FormikInput } from '@tacc/core-wrappers';
import * as Yup from 'yup';
import {
UIWizardStep,
useWizardValues,
UIWizardSchema,
InitialValueGenerator,
} from '..';

export const StepOne: React.FC = () => {
const { extra } = useWizardValues();
return (
<div>
<h2>Step One: Extra value two is {extra.extraTwo}</h2>
<FormikInput
name="fieldOne"
required={true}
label="Field One"
description="The first form field"
/>
<FormikInput
name="fieldTwo"
required={false}
label="Field Two"
description="The second form field"
/>
</div>
);
};

export const StepOneSummary: React.FC = () => {
// Retrieve the current values in the wizard to render a summary
const { values } = useWizardValues();
return (
<ul>
<li>Field One: {values.fieldOne}</li>
<li>Field Two: {values.fieldTwo}</li>
</ul>
);
};

const generateInitialValues: InitialValueGenerator = ({ values, extra }) => ({
fieldOne: values?.fieldOne ?? extra.extraOne,
});

// Form steps require a validation schema
export const validationSchema = Yup.object({
fieldOne: Yup.string().required().min(1).max(64),
fieldTwo: Yup.string(),
});

const stepOne: UIWizardStep = {
id: 'stepOne',
name: 'Step One',
render: <StepOne />,
summary: <StepOneSummary />,
generateInitialValues,
validationSchema,
};

export default stepOne;
Loading