Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-gtm-module": "^2.0.11",
"react-responsive-modal": "^6.2.0",
"react-router-dom": "^6.2.1",
"react-scripts": "5.0.0",
"react-toastify": "^8.2.0",
Expand Down
4 changes: 4 additions & 0 deletions src/header/Header.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@
@include xl {
grid-template-columns: $left-col-width-xl 1fr auto;
}

@include xxl {
grid-template-columns: $left-col-width-xl 1fr auto;
}
}
17 changes: 11 additions & 6 deletions src/lib/avatar/Avatar.module.scss
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
@import '../../lib/styles';

$avatar-size-sm: 32px;
$border-size-sm: $border;
$avatar-size-xl: 120px;
$border-size-xl: $pad-xs;

.avatar-container {
overflow: hidden;
background-color: $tc-white;
border-radius: 50%;

&.sm {
height: calc($avatar-size-sm + 2 * $border);
width: calc($avatar-size-sm + 2 * $border);
height: calc($avatar-size-sm + 2 * $border-size-sm);
width: calc($avatar-size-sm + 2 * $border-size-sm);
}

&.xl {
height: calc($avatar-size-xl + 2 * $border);
width: calc($avatar-size-xl + 2 * $border);
height: calc($avatar-size-xl + 2 * $border-size-xl);
width: calc($avatar-size-xl + 2 * $border-size-xl);
}

.avatar {
background-color: $tc-white;
border-radius: 50%;
border: 2px solid $tc-white;
border: solid $tc-white;

&.sm {
border-width: $border-size-sm;
height: $avatar-size-sm;
width: $avatar-size-sm;
}

&.xl {
border-width: $border-size-xl;
height: $avatar-size-xl;
width: $avatar-size-xl;
}
Expand All @@ -48,7 +52,8 @@ $avatar-size-xl: 120px;
}

&.xl {
font-size: 48px;
@extend h1;
padding: 0;
}
}
}
39 changes: 38 additions & 1 deletion src/lib/button/Button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
line-height: 24px;

&:focus {
outline: 2px solid $turq-140;
outline: $border solid $turq-140;
}

&.button-sm {
Expand Down Expand Up @@ -98,6 +98,43 @@
}
}

&.link {
margin: 0;
padding: 0;
display: flex;
align-items: center;
font-size: 16px;
color: $turq-160;
background-color: $tc-white;
border: none;
outline: none;
border-radius: 0;

&:focus {
outline: $border solid $turq-140;
}

&:hover {
color: $turq-120;
}

&:active {
color: $turq-180;
}

&.disabled {
color: $black-60;
background-color: $tc-white;
border-color: $black-5;
}

svg {
margin-left: $pad-xs;
height: $pad-lg;
width: $pad-lg;
}
}

&.text {
border-color: transparent;
}
Expand Down
5 changes: 4 additions & 1 deletion src/lib/button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import classNames from 'classnames'
import { FC } from 'react'
import { Link } from 'react-router-dom'

import { IconOutline } from '../svgs'

import styles from './Button.module.scss'

export type ButtonSize = 'sm' | 'md' | 'lg' | 'xl'
export type ButtonStyle = 'primary' | 'secondary' | 'tertiary' | 'text'
export type ButtonStyle = 'link' | 'primary' | 'secondary' | 'tertiary' | 'text'
export type ButtonType = 'button' | 'submit'

export interface ButtonProps {
Expand Down Expand Up @@ -61,6 +63,7 @@ const Button: FC<ButtonProps> = (props: ButtonProps) => {
type={props.type || 'button'}
>
{props.label}
{props.buttonStyle === 'link' && <IconOutline.ArrowRightIcon />}
</button>
)
}
Expand Down
18 changes: 16 additions & 2 deletions src/lib/content-layout/ContentLayout.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,33 @@

.content {
@include content-height;
padding: 0;
padding: 0 $pad-content-lg;
display: grid;
grid-template-columns: 1fr;
justify-content: center;

@include xxl {
padding: 0;
}

@include md {
padding: 0 $pad-xxl;
}

@include ltesm {
padding: 0;
}

.content-outer {
display: flex;
justify-content: center;

.content-inner {
flex: 1;
max-width: $xl-max-content;
max-width: $xl-max;
padding: 0;
display: flex;
flex-direction: column;
}
}
}
11 changes: 6 additions & 5 deletions src/lib/form/Form.module.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
@import '../../lib/styles';

.form-fields {
display: grid;
grid-template-columns: .5fr;
justify-content: flex-end;
form {
flex: 1;
display: flex;
flex-direction: column;

@include ltemd {
.form-fields {
display: grid;
grid-template-columns: 1fr;
justify-content: center;
}
Expand Down
32 changes: 19 additions & 13 deletions src/lib/form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
FormErrorMessage,
formGetInputModel,
formInitializeValues,
formOnChange,
formReset,
formSubmitAsync,
formValidateAndUpdateAsync,
} from './form-functions'
import { InputText, InputTextarea } from './form-input'
import { FormInputModel } from './form-input.model'
Expand All @@ -22,13 +22,14 @@ interface FormProps<ValueType, RequestType> {
readonly requestGenerator: (inputs: ReadonlyArray<FormInputModel>) => RequestType
readonly resetOnError: boolean
readonly save: (value: RequestType) => Promise<void>
readonly succeeded?: () => void
}

const Form: <ValueType extends any, RequestType extends any>(props: FormProps<ValueType, RequestType>) => JSX.Element
= <ValueType extends any, RequestType extends any>(props: FormProps<ValueType, RequestType>) => {

const [disableSave, setDisableSave]: [boolean, Dispatch<SetStateAction<boolean>>]
= useState<boolean>(true)
= useState<boolean>(false)

const [formDef, setFormDef]: [FormDefinition, Dispatch<SetStateAction<FormDefinition>>]
= useState<FormDefinition>({ ...props.formDef })
Expand All @@ -48,14 +49,14 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va
}

async function onChange(event: FormEvent<HTMLFormElement>): Promise<void> {
const isValid: boolean = await formValidateAndUpdateAsync(event, formDef.inputs)
const isValid: boolean = await formOnChange(event, formDef.inputs)
setFormDef({ ...formDef })
setDisableSave(!isValid)
}

function onFocus(event: FocusEvent<HTMLInputElement | HTMLTextAreaElement>): void {
const inputDef: FormInputModel = formGetInputModel(props.formDef.inputs, event.target.name)
inputDef.dirtyOrTouched = true
inputDef.touched = true
setFormDef({ ...formDef })
}

Expand All @@ -67,7 +68,7 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va

async function onSubmit(event: FormEvent<HTMLFormElement>): Promise<void> {
const values: RequestType = props.requestGenerator(formDef.inputs)
formSubmitAsync<RequestType, void>(event, formDef.inputs, props.formDef.title, values, props.save, setDisableSave)
formSubmitAsync<RequestType, void>(event, formDef.inputs, props.formDef.title, values, props.save, setDisableSave, props.succeeded)
.then(() => {
setFormKey(Date.now())
formReset(formDef.inputs, props.formValues)
Expand All @@ -85,9 +86,10 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va

formInitializeValues(formDef.inputs, props.formValues)

const formInputs: Array<JSX.Element> = props.formDef.inputs
.map(input => formGetInputModel(props.formDef.inputs, input.name))
const formInputs: Array<JSX.Element> = formDef.inputs
.map(input => formGetInputModel(formDef.inputs, input.name))
.map((inputModel, index) => {
const tabIndex: number = inputModel.notTabbable ? -1 : index + 1 + (formDef.tabIndexStart || 0)
switch (inputModel.type) {
case 'textarea':
return (
Expand All @@ -96,7 +98,7 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va
key={inputModel.name}
onBlur={onBlur}
onFocus={onFocus}
tabIndex={inputModel.notTabbable ? -1 : index + 1}
tabIndex={tabIndex}
value={inputModel.value}
/>
)
Expand All @@ -107,7 +109,7 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va
key={inputModel.name}
onBlur={onBlur}
onFocus={onFocus}
tabIndex={inputModel.notTabbable ? -1 : index + 1}
tabIndex={tabIndex}
type={inputModel.type || 'text'}
value={inputModel.value}
/>
Expand All @@ -116,7 +118,7 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va

})

const buttons: Array<JSX.Element> = props.formDef.buttons
const buttons: Array<JSX.Element> = formDef.buttons
.map((button, index) => {
// if this is a reset button, set its onclick to reset
if (!!button.isReset) {
Expand All @@ -130,7 +132,7 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va
{...button}
disable={button.isSave && disableSave}
key={button.label}
tabIndex={button.notTabble ? -1 : index + props.formDef.inputs.length}
tabIndex={button.notTabble ? -1 : index + formDef.inputs.length + (formDef.tabIndexStart || 0)}
/>
)
})
Expand All @@ -145,12 +147,16 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va

<h2>{props.formDef.title}</h2>

<hr />

<div className={styles['form-fields']}>
{formInputs}
</div>

<div className='button-container'>
{buttons}
<div className='button-container-outer'>
<div className='button-container-inner'>
{buttons}
</div>
</div>

</form>
Expand Down
2 changes: 1 addition & 1 deletion src/lib/form/form-button.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface FormButton {
readonly label: string
readonly notTabble?: boolean
readonly onClick?: (event?: any) => void
route?: string
readonly route?: string
readonly size?: ButtonSize
readonly type?: ButtonType
readonly url?: string
Expand Down
1 change: 1 addition & 0 deletions src/lib/form/form-definition.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ import { FormInputModel } from './form-input.model'
export interface FormDefinition {
readonly buttons: ReadonlyArray<FormButton>
readonly inputs: ReadonlyArray<FormInputModel>
readonly tabIndexStart?: number
readonly title: string
}
Loading