Skip to content

Commit

Permalink
Convert form components to TypeScript (#246)
Browse files Browse the repository at this point in the history
  • Loading branch information
moust authored Jan 21, 2025
1 parent a860292 commit 310ffee
Show file tree
Hide file tree
Showing 81 changed files with 2,536 additions and 2,269 deletions.
23 changes: 19 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,31 @@ version: 2
defaults: &defaults
working_directory: ~/repo
docker:
- image: cimg/node:21.6.1
- image: cimg/node:lts

jobs:
test:
<<: *defaults
steps:
- checkout
- run: npm ci
- run: npm run build
- run: npm run test
- run:
name: Install dependencies
command: npm ci
- run:
name: Build package
command: npm run build
- run:
name: Install JUnit coverage reporter
command: npm i -D jest-junit
- run:
name: Run tests
command: |
npx jest --listTests | circleci tests run --command="JEST_JUNIT_ADD_FILE_ATTRIBUTE=true xargs npx jest --config jest.config.ts --runInBand --reporters=default --reporters=jest-junit --" --verbose --split-by=timings
environment:
JEST_JUNIT_OUTPUT_DIR: ./reports/
JEST_JUNIT_ADD_FILE_ATTRIBUTE: "true"
- store_test_results:
path: ./reports/
- persist_to_workspace:
root: ~/repo
paths:
Expand Down
4 changes: 2 additions & 2 deletions src/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { I18nMessages } from './core/i18n';
import { UserError } from './helpers/errors';
import { logError } from './helpers/logger';

import { ErrorMessage } from './components/error'
import { ErrorText } from './components/miscComponent'
import type { Context, I18nProps, ThemeProps } from './components/widget/widget'

import authWidget, { type AuthWidgetProps } from './widgets/auth/authWidget';
Expand Down Expand Up @@ -154,7 +154,7 @@ export class UiClient {
}
} catch (error) {
const message = this.adaptError(error);
root.render(<ErrorMessage>{message}</ErrorMessage>)
root.render(<ErrorText>{message}</ErrorText>)
this.handleError(error)
}
}
Expand Down
78 changes: 30 additions & 48 deletions src/components/form/buttonComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,53 @@
import React, { MouseEventHandler, PropsWithChildren } from 'react';
import React, { PropsWithChildren } from 'react';

import styled, { useTheme, type DefaultTheme } from 'styled-components';
import { darken } from 'polished';
import classes from 'classnames';

const buttonTheme =
<P extends { theme: DefaultTheme, themePrefix?: ThemePrefix },
<
ThemePrefix extends 'button' | 'socialButton',
Attr extends keyof DefaultTheme[ThemePrefix]
>({ theme, themePrefix = 'button' as ThemePrefix }: P, attr: Attr): DefaultTheme[ThemePrefix][Attr] =>
>(theme: DefaultTheme, themePrefix: ThemePrefix = 'button' as ThemePrefix, attr: Attr): DefaultTheme[ThemePrefix][Attr] =>
theme[themePrefix][attr]

export type ButtonProps = {
tagname?: 'button' | 'div'
className?: classes.Argument
extendedClasses?: classes.Argument
title?: HTMLButtonElement['title']
disabled?: HTMLButtonElement['disabled']
type?: HTMLButtonElement['type']
dataTestId?: string
onClick?: MouseEventHandler<HTMLButtonElement> & MouseEventHandler<HTMLDivElement>
color?: string
background?: string
border?: string
themePrefix?: 'button' | 'socialButton'
export type ExtraButtonProps = {
$color?: string
$background?: string
$border?: string
$themePrefix?: 'button' | 'socialButton'
}

export const Button = styled(({ tagname = 'button', className, extendedClasses, title, disabled, type, dataTestId, onClick, children }: PropsWithChildren<ButtonProps>) => {
const Tagname = tagname;
export type ButtonProps = React.ComponentProps<typeof Button>

return (
<Tagname className={classes([extendedClasses, className])}
disabled={disabled}
type={type}
data-testid={dataTestId ?? type}
onClick={onClick}
{...(title ? { title } : {})}>{children}</Tagname>
);
})`
export const Button = styled.button<ExtraButtonProps>`
display: block;
width: 100%;
box-sizing: border-box;
text-align: center;
font-weight: ${props => buttonTheme(props, 'fontWeight')};
font-weight: ${props => buttonTheme(props.theme, props.$themePrefix, 'fontWeight')};
vertical-align: middle;
user-select: none;
touch-action: manipulation;
cursor: pointer;
color: ${props => props.color ?? '#ffffff'};
background-color: ${props => props.background};
border: ${props => buttonTheme(props, 'borderWidth')}px solid ${props => props.border};
padding: ${props => buttonTheme(props, 'paddingY')}px ${props => buttonTheme(props, 'paddingX')}px;
font-size: ${props => buttonTheme(props, 'fontSize')}px;
line-height: ${props => buttonTheme(props, 'lineHeight')};
border-radius: ${props => buttonTheme(props, 'borderRadius')}px;
color: ${props => props.$color ?? '#ffffff'};
background-color: ${props => props.$background};
border: ${props => buttonTheme(props.theme, props.$themePrefix, 'borderWidth')}px solid ${props => props.$border};
padding: ${props => buttonTheme(props.theme, props.$themePrefix, 'paddingY')}px ${props => buttonTheme(props.theme, props.$themePrefix, 'paddingX')}px;
font-size: ${props => buttonTheme(props.theme, props.$themePrefix, 'fontSize')}px;
line-height: ${props => buttonTheme(props.theme, props.$themePrefix, 'lineHeight')};
border-radius: ${props => buttonTheme(props.theme, props.$themePrefix, 'borderRadius')}px;
transition: all .15s ease-in-out;
&:focus {
outline: 0;
box-shadow: ${props => buttonTheme(props, 'focusBoxShadow')(props.border)};
box-shadow: ${props => buttonTheme(props.theme, props.$themePrefix, 'focusBoxShadow')(props.$border)};
}
&:hover,
&:active {
color: ${props => props.color};
background-color: ${props => darken(0.08, props.background ?? props.theme.backgroundColor)};
border-color: ${props => darken(0.08, props.border ?? props.theme.borderColor)};
color: ${props => props.$color};
background-color: ${props => darken(0.08, props.$background ?? props.theme.backgroundColor)};
border-color: ${props => darken(0.08, props.$border ?? props.theme.borderColor)};
}
&[disabled] {
Expand All @@ -75,27 +57,27 @@ export const Button = styled(({ tagname = 'button', className, extendedClasses,

interface DefaultButtonProps extends Omit<ButtonProps, 'background' | 'border' | 'color'> {}

export const DefaultButton = ({ children, ...props }: PropsWithChildren<DefaultButtonProps>) => {
export function DefaultButton({ children, ...props }: PropsWithChildren<DefaultButtonProps>) {
const theme = useTheme()
return (
<Button {...props} background="#ffffff" border={theme.borderColor} color={theme.textColor}>
<Button {...props} $background="#ffffff" $border={theme.borderColor} $color={theme.textColor}>
{children}
</Button>
)
};
}

interface PrimaryButtonProps extends Omit<ButtonProps, 'background' | 'border'> {}

export const PrimaryButton = ({ children, type = "submit", ...props }: PropsWithChildren<PrimaryButtonProps>) => {
export function PrimaryButton({ children, type = 'submit', ...props }: PropsWithChildren<PrimaryButtonProps>) {
const theme = useTheme()
return (
<Button
{...props}
type={type}
background={theme.primaryColor}
border={theme.primaryColor}
{...props}
$background={theme.primaryColor}
$border={theme.primaryColor}
>
{children}
</Button>
)
};
}
73 changes: 0 additions & 73 deletions src/components/form/fieldCreator.d.ts

This file was deleted.

66 changes: 0 additions & 66 deletions src/components/form/fieldCreator.jsx

This file was deleted.

Loading

0 comments on commit 310ffee

Please sign in to comment.