1
0
mirror of https://gitlab.nic.cz/turris/reforis/foris-js.git synced 2025-06-16 13:46:16 +02:00

Format all files with Prettier

This commit is contained in:
Aleksandr Gumroian
2020-08-18 15:39:00 +02:00
parent e41da48b1a
commit f8726e6012
80 changed files with 933 additions and 804 deletions

View File

@ -35,12 +35,16 @@ Alert.defaultProps = {
type: ALERT_TYPES.DANGER,
};
export function Alert({
type, onDismiss, children,
}) {
export function Alert({ type, onDismiss, children }) {
return (
<div className={`alert alert-dismissible alert-${type}`}>
{onDismiss ? <button type="button" className="close" onClick={onDismiss}>&times;</button> : false}
{onDismiss ? (
<button type="button" className="close" onClick={onDismiss}>
&times;
</button>
) : (
false
)}
{children}
</div>
);

View File

@ -1,21 +1,21 @@
Bootstrap alert component.
```jsx
import {useState} from 'react';
import { useState } from "react";
function AlertExample(){
function AlertExample() {
const [alert, setAlert] = useState(true);
if (alert)
return <Alert
type='warning'
onDismiss={()=>setAlert(false)}
>
Some warning out there!
</Alert>;
return <button
className='btn btn-secondary'
onClick={()=>setAlert(true)}
>Show alert again</button>;
};
<AlertExample/>
return (
<Alert type="warning" onDismiss={() => setAlert(false)}>
Some warning out there!
</Alert>
);
return (
<button className="btn btn-secondary" onClick={() => setAlert(true)}>
Show alert again
</button>
);
}
<AlertExample />;
```

View File

@ -25,22 +25,29 @@ Button.propTypes = {
};
export function Button({
className, loading, forisFormSize, children, ...props
className,
loading,
forisFormSize,
children,
...props
}) {
let buttonClass = className ? `btn ${className}` : "btn btn-primary ";
if (forisFormSize) {
buttonClass = `${buttonClass} col-sm-12 col-md-3 col-lg-2`;
}
const span = loading
? <span className="spinner-border spinner-border-sm" role="status" aria-hidden="true" /> : null;
const span = loading ? (
<span
className="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
/>
) : null;
return (
<button type="button" className={buttonClass} {...props}>
{span}
{" "}
{span ? " " : null}
{" "}
{children}
</button>
);

View File

@ -11,5 +11,7 @@ Can be used without parameters:
Using loading spinner:
```jsx
<Button loading disabled>Loading...</Button>
<Button loading disabled>
Loading...
</Button>
```

View File

@ -22,9 +22,7 @@ CheckBox.defaultProps = {
disabled: false,
};
export function CheckBox({
label, helpText, disabled, ...props
}) {
export function CheckBox({ label, helpText, disabled, ...props }) {
const uid = useUID();
return (
<div className="form-group">
@ -34,12 +32,15 @@ export function CheckBox({
type="checkbox"
id={uid}
disabled={disabled}
{...props}
/>
<label className="custom-control-label" htmlFor={uid}>
{label}
{helpText && <small className="form-text text-muted">{helpText}</small>}
{helpText && (
<small className="form-text text-muted">
{helpText}
</small>
)}
</label>
</div>
</div>

View File

@ -1,16 +1,17 @@
Checkbox with label Bootstrap component with predefined sizes and structure for using in foris forms.
All additional `props` are passed to the `<input type="checkbox">` HTML component.
Checkbox with label Bootstrap component with predefined sizes and structure for
using in foris forms.
All additional `props` are passed to the `<input type="checkbox">` HTML
component.
```js
import {useState} from 'react';
import { useState } from "react";
const [value, setValue] = useState(false);
<CheckBox
value={value}
label="Some label"
label="Some label"
helpText="Read the small text!"
onChange={event =>setValue(event.target.value)}
/>
onChange={(event) => setValue(event.target.value)}
/>;
```

View File

@ -38,14 +38,17 @@ const DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
const DEFAULT_TIME_FORMAT = "HH:mm:ss";
export function DataTimeInput({
value, onChange, isValidDate, dateFormat, timeFormat, children, ...props
value,
onChange,
isValidDate,
dateFormat,
timeFormat,
children,
...props
}) {
function renderInput(datetimeProps) {
return (
<Input
{...props}
{...datetimeProps}
>
<Input {...props} {...datetimeProps}>
{children}
</Input>
);
@ -54,8 +57,12 @@ export function DataTimeInput({
return (
<Datetime
locale={ForisTranslations.locale}
dateFormat={dateFormat !== undefined ? dateFormat : DEFAULT_DATE_FORMAT}
timeFormat={timeFormat !== undefined ? timeFormat : DEFAULT_TIME_FORMAT}
dateFormat={
dateFormat !== undefined ? dateFormat : DEFAULT_DATE_FORMAT
}
timeFormat={
timeFormat !== undefined ? timeFormat : DEFAULT_TIME_FORMAT
}
value={value}
onChange={onChange}
isValidDate={isValidDate}

View File

@ -1,25 +1,26 @@
Adopted from `react-datetime/DateTime` datatime picker component.
It uses `momentjs` see example.
Adopted from `react-datetime/DateTime` datatime picker component. It uses
`momentjs` see example.
It requires `ForisTranslations.locale` to be defined in order to use right locale.
It requires `ForisTranslations.locale` to be defined in order to use right
locale.
```js
ForisTranslations={locale:'en'};
ForisTranslations = { locale: "en" };
import {useState, useEffect} from 'react';
import moment from 'moment/moment';
import { useState, useEffect } from "react";
import moment from "moment/moment";
const [dataTime, setDataTime] = useState(moment());
const [error, setError] = useState();
useEffect(()=>{
dataTime.isValid() ? setError(null) : setError('Invalid value!');
},[dataTime]);
useEffect(() => {
dataTime.isValid() ? setError(null) : setError("Invalid value!");
}, [dataTime]);
<DataTimeInput
label='Time to sleep'
label="Time to sleep"
value={dataTime}
error={error}
helpText='Example helptext...'
onChange={value => setDataTime(value)}
/>
helpText="Example helptext..."
onChange={(value) => setDataTime(value)}
/>;
```

View File

@ -23,11 +23,7 @@ DownloadButton.defaultProps = {
export function DownloadButton({ href, className, children }) {
return (
<a
href={href}
className={`btn ${className}`.trim()}
download
>
<a href={href} className={`btn ${className}`.trim()} download>
{children}
</a>
);

View File

@ -1,6 +1,9 @@
Hyperlink with apperance of a button.
It has `download` attribute, which prevents closing WebSocket connection on Firefox. See [related issue](https://bugzilla.mozilla.org/show_bug.cgi?id=858538) for more details.
It has `download` attribute, which prevents closing WebSocket connection on
Firefox. See
[related issue](https://bugzilla.mozilla.org/show_bug.cgi?id=858538) for more
details.
```js
<DownloadButton href="example.zip">Download</DownloadButton>

View File

@ -1,18 +1,19 @@
Bootstrap component of email input with label with predefined sizes and structure for using in foris forms.
It use built-in browser email address checking. It's only meaningful using inside `<form>`.
Bootstrap component of email input with label with predefined sizes and
structure for using in foris forms. It use built-in browser email address
checking. It's only meaningful using inside `<form>`.
All additional `props` are passed to the `<input type="email">` HTML component.
```js
import {useState} from 'react';
const [email, setEmail] = useState('Wrong email');
<form onSubmit={e=>e.preventDefault()}>
import { useState } from "react";
const [email, setEmail] = useState("Wrong email");
<form onSubmit={(e) => e.preventDefault()}>
<EmailInput
value={email}
label="Some label"
label="Some label"
helpText="Read the small text!"
onChange={event =>setEmail(event.target.value)}
onChange={(event) => setEmail(event.target.value)}
/>
<button type="submit">Try to submit</button>
</form>
</form>;
```

View File

@ -1,9 +1,10 @@
Bootstrap component for file input. Includes label and has predefined sizes and structure for using in foris forms.
Bootstrap component for file input. Includes label and has predefined sizes and
structure for using in foris forms.
All additional `props` are passed to the `<input type="file">` HTML component.
```js
import { useState } from 'react';
import { useState } from "react";
const [files, setFiles] = useState([]);
@ -15,27 +16,33 @@ const label = files.length === 1 ? files[0].name : "Choose file";
files={files}
label={label}
helpText="Will be uploaded"
onChange={event=>setFiles(event.target.files)}
onChange={(event) => setFiles(event.target.files)}
/>
</form>
</form>;
```
### FileInput with multiple files
```js
import { useState } from 'react';
import { useState } from "react";
const [files, setFiles] = useState([]);
// Note that files is not an array but FileList.
const label = files.length > 0 ? Array.from(files).map(file=>file.name).join(", ") : "Choose files";
const label =
files.length > 0
? Array.from(files)
.map((file) => file.name)
.join(", ")
: "Choose files";
<form className="col">
<FileInput
files={files}
label={label}
helpText="Will be uploaded"
onChange={event=>setFiles(event.target.files)}
onChange={(event) => setFiles(event.target.files)}
multiple
/>
</form>
</form>;
```

View File

@ -25,25 +25,38 @@ Input.propTypes = {
/** Base bootstrap input component. */
export function Input({
type, label, helpText, error, className, children, labelClassName, groupClassName, ...props
type,
label,
helpText,
error,
className,
children,
labelClassName,
groupClassName,
...props
}) {
const uid = useUID();
const inputClassName = `form-control ${className || ""} ${(error ? "is-invalid" : "")}`.trim();
const inputClassName = `form-control ${className || ""} ${
error ? "is-invalid" : ""
}`.trim();
return (
<div className="form-group">
<label className={labelClassName} htmlFor={uid}>{label}</label>
<label className={labelClassName} htmlFor={uid}>
{label}
</label>
<div className={`input-group ${groupClassName || ""}`.trim()}>
<input
className={inputClassName}
type={type}
id={uid}
{...props}
/>
{children}
</div>
{error ? <div className="invalid-feedback">{error}</div> : null}
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
{helpText ? (
<small className="form-text text-muted">{helpText}</small>
) : null}
</div>
);
}

View File

@ -10,6 +10,6 @@
.modal.show {
display: block;
animation-name: modalFade;
animation-duration: .3s;
animation-duration: 0.3s;
background: rgba(0, 0, 0, 0.2);
}

View File

@ -26,9 +26,7 @@ Modal.propTypes = {
]).isRequired,
};
export function Modal({
shown, setShown, scrollable, children,
}) {
export function Modal({ shown, setShown, scrollable, children }) {
const dialogRef = useRef();
useClickOutside(dialogRef, () => setShown(false));
@ -38,12 +36,12 @@ export function Modal({
<div className={`modal fade ${shown ? "show" : ""}`} role="dialog">
<div
ref={dialogRef}
className={`modal-dialog modal-dialog-centered${scrollable ? " modal-dialog-scrollable" : ""}`}
className={`modal-dialog modal-dialog-centered${
scrollable ? " modal-dialog-scrollable" : ""
}`}
role="document"
>
<div className="modal-content">
{children}
</div>
<div className="modal-content">{children}</div>
</div>
</div>
</Portal>
@ -59,7 +57,11 @@ export function ModalHeader({ setShown, title }) {
return (
<div className="modal-header">
<h5 className="modal-title">{title}</h5>
<button type="button" className="close" onClick={() => setShown(false)}>
<button
type="button"
className="close"
onClick={() => setShown(false)}
>
<span aria-hidden="true">&times;</span>
</button>
</div>
@ -85,9 +87,5 @@ ModalFooter.propTypes = {
};
export function ModalFooter({ children }) {
return (
<div className="modal-footer">
{children}
</div>
);
return <div className="modal-footer">{children}</div>;
}

View File

@ -1,31 +1,36 @@
Bootstrap modal component.
it's required to have an element `<div id={"modal-container"}/>` somewhere on the page since modals are rendered in portals.
it's required to have an element `<div id={"modal-container"}/>` somewhere on
the page since modals are rendered in portals.
```js
<div id="modal-container"/>
<div id="modal-container" />
```
```js
import {ModalHeader, ModalBody, ModalFooter} from './Modal';
import { ModalHeader, ModalBody, ModalFooter } from "./Modal";
import {useState} from 'react';
import { useState } from "react";
const [shown, setShown] = useState(false);
<>
<Modal setShown={setShown} shown={shown}>
<ModalHeader setShown={setShown} title='Warning!'/>
<ModalBody><p>Bla bla bla...</p></ModalBody>
<ModalHeader setShown={setShown} title="Warning!" />
<ModalBody>
<p>Bla bla bla...</p>
</ModalBody>
<ModalFooter>
<button
className='btn btn-secondary'
<button
className="btn btn-secondary"
onClick={() => setShown(false)}
>Skip it</button>
>
Skip it
</button>
</ModalFooter>
</Modal>
<button className='btn btn-secondary' onClick={()=>setShown(true)}>
<button className="btn btn-secondary" onClick={() => setShown(true)}>
Show modal
</button>
</>
</>;
```

View File

@ -4,7 +4,7 @@ input[type="number"] {
appearance: textfield;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
}

View File

@ -20,10 +20,7 @@ NumberInput.propTypes = {
/** Help text message. */
helpText: PropTypes.string,
/** Number value. */
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/** Function called when value changes. */
onChange: PropTypes.func.isRequired,
/** Additional description dispaled to the right of input value. */
@ -34,15 +31,21 @@ NumberInput.defaultProps = {
value: 0,
};
export function NumberInput({
onChange, inlineText, value, ...props
}) {
export function NumberInput({ onChange, inlineText, value, ...props }) {
function updateValue(initialValue, difference) {
onChange({ target: { value: initialValue + difference } });
}
const enableIncrease = useConditionalTimeout({ callback: updateValue }, value, 1);
const enableDecrease = useConditionalTimeout({ callback: updateValue }, value, -1);
const enableIncrease = useConditionalTimeout(
{ callback: updateValue },
value,
1
);
const enableDecrease = useConditionalTimeout(
{ callback: updateValue },
value,
-1
);
return (
<Input type="number" onChange={onChange} value={value} {...props}>

View File

@ -1,17 +1,18 @@
Bootstrap component of number input with label with predefined sizes and structure for using in foris forms.
Bootstrap component of number input with label with predefined sizes and
structure for using in foris forms.
All additional `props` are passed to the `<input type="number">` HTML component.
```js
import {useState} from 'react';
import { useState } from "react";
const [value, setValue] = useState(42);
<NumberInput
value={value}
label="Some number"
label="Some number"
helpText="Read the small text!"
min='33'
max='54'
onChange={event =>setValue(event.target.value)}
/>
min="33"
max="54"
onChange={(event) => setValue(event.target.value)}
/>;
```

View File

@ -31,22 +31,24 @@ export function PasswordInput({ withEye, ...props }) {
autoComplete={isHidden ? "new-password" : null}
{...props}
>
{withEye
? (
<div className="input-group-append">
<button
type="button"
className="input-group-text"
onClick={(e) => {
e.preventDefault();
setHidden((shouldBeHidden) => !shouldBeHidden);
}}
>
<i className={`fa ${isHidden ? "fa-eye" : "fa-eye-slash"}`} />
</button>
</div>
)
: null}
{withEye ? (
<div className="input-group-append">
<button
type="button"
className="input-group-text"
onClick={(e) => {
e.preventDefault();
setHidden((shouldBeHidden) => !shouldBeHidden);
}}
>
<i
className={`fa ${
isHidden ? "fa-eye" : "fa-eye-slash"
}`}
/>
</button>
</div>
) : null}
</Input>
);
}

View File

@ -1,17 +1,18 @@
Password Bootstrap component input with label and predefined sizes and structure for using in foris forms.
Can be used with "eye" button, see example.
Password Bootstrap component input with label and predefined sizes and structure
for using in foris forms. Can be used with "eye" button, see example.
All additional `props` are passed to the `<input type="password">` HTML component.
All additional `props` are passed to the `<input type="password">` HTML
component.
```js
import {useState} from 'react';
const [value, setValue] = useState('secret');
import { useState } from "react";
const [value, setValue] = useState("secret");
<PasswordInput
withEye
value={value}
label="Some password"
label="Some password"
helpText="Read the small text!"
onChange={event =>setValue(event.target.value)}
/>
onChange={(event) => setValue(event.target.value)}
/>;
```

View File

@ -15,26 +15,27 @@ RadioSet.propTypes = {
/** RadioSet label . */
label: PropTypes.string,
/** Choices . */
choices: PropTypes.arrayOf(PropTypes.shape({
/** Choice lable . */
label: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
PropTypes.node,
PropTypes.arrayOf(PropTypes.node),
]).isRequired,
/** Choice value . */
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
})).isRequired,
choices: PropTypes.arrayOf(
PropTypes.shape({
/** Choice lable . */
label: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element,
PropTypes.node,
PropTypes.arrayOf(PropTypes.node),
]).isRequired,
/** Choice value . */
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
.isRequired,
})
).isRequired,
/** Initial value . */
value: PropTypes.string,
/** Help text message . */
helpText: PropTypes.string,
};
export function RadioSet({
name, label, choices, value, helpText, ...props
}) {
export function RadioSet({ name, label, choices, value, helpText, ...props }) {
const uid = useUID();
const radios = choices.map((choice, key) => {
const id = `${name}-${key}`;
@ -47,7 +48,6 @@ export function RadioSet({
value={choice.value}
helpText={choice.helpText}
checked={choice.value === value}
{...props}
/>
);
@ -55,9 +55,15 @@ export function RadioSet({
return (
<div className="form-group">
{label && <label htmlFor={uid} className="d-block">{label}</label>}
{label && (
<label htmlFor={uid} className="d-block">
{label}
</label>
)}
{radios}
{helpText && <small className="form-text text-muted">{helpText}</small>}
{helpText && (
<small className="form-text text-muted">{helpText}</small>
)}
</div>
);
}
@ -73,21 +79,28 @@ Radio.propTypes = {
helpText: PropTypes.string,
};
export function Radio({
label, id, helpText, ...props
}) {
export function Radio({ label, id, helpText, ...props }) {
return (
<>
<div className={`custom-control custom-radio ${!helpText ? "custom-control-inline" : ""}`.trim()}>
<div
className={`custom-control custom-radio ${
!helpText ? "custom-control-inline" : ""
}`.trim()}
>
<input
id={id}
className="custom-control-input"
type="radio"
{...props}
/>
<label className="custom-control-label" htmlFor={id}>{label}</label>
{helpText && <small className="form-text text-muted mt-0 mb-3">{helpText}</small>}
<label className="custom-control-label" htmlFor={id}>
{label}
</label>
{helpText && (
<small className="form-text text-muted mt-0 mb-3">
{helpText}
</small>
)}
</div>
</>
);

View File

@ -1,15 +1,16 @@
Set of radio Bootstrap component input with label and predefined sizes and structure for using in foris forms.
Set of radio Bootstrap component input with label and predefined sizes and
structure for using in foris forms.
All additional `props` are passed to the `<input type="number">` HTML component.
Unless `helpText` is set for one of the options they are displayed inline.
```js
import {useState} from 'react';
const CHOICES=[
{value:'one',label:'1'},
{value:'two',label:'2'},
{value:'three',label:'3'},
import { useState } from "react";
const CHOICES = [
{ value: "one", label: "1" },
{ value: "two", label: "2" },
{ value: "three", label: "3" },
];
const [value, setValue] = useState(CHOICES[0].value);
@ -17,10 +18,10 @@ const [value, setValue] = useState(CHOICES[0].value);
{/*Yeah, it gets event, not value!*/}
<RadioSet
value={value}
name='some-radio'
name="some-radio"
choices={CHOICES}
onChange={event =>setValue(event.target.value)}
onChange={(event) => setValue(event.target.value)}
/>
<p>Selected value: {value}</p>
</>
</>;
```

View File

@ -15,35 +15,30 @@ Select.propTypes = {
/** Choices if form of {value : "Label",...}. */
choices: PropTypes.object.isRequired,
/** Current value. */
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]).isRequired,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
/** Help text message. */
helpText: PropTypes.string,
};
export function Select({
label, choices, helpText, ...props
}) {
export function Select({ label, choices, helpText, ...props }) {
const uid = useUID();
const options = Object.keys(choices).sort(
(a, b) => a - b || a.toString().localeCompare(b.toString()),
).map(
(key) => <option key={key} value={key}>{choices[key]}</option>,
);
const options = Object.keys(choices)
.sort((a, b) => a - b || a.toString().localeCompare(b.toString()))
.map((key) => (
<option key={key} value={key}>
{choices[key]}
</option>
));
return (
<div className="form-group">
<label htmlFor={uid}>{label}</label>
<select
className="custom-select"
id={uid}
{...props}
>
<select className="custom-select" id={uid} {...props}>
{options}
</select>
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
{helpText ? (
<small className="form-text text-muted">{helpText}</small>
) : null}
</div>
);
}

View File

@ -1,13 +1,14 @@
Select with options Bootstrap component input with label and predefined sizes and structure for using in foris forms.
Select with options Bootstrap component input with label and predefined sizes
and structure for using in foris forms.
All additional `props` are passed to the `<select>` HTML component.
```js
import {useState} from 'react';
const CHOICES={
apple:'Apple',
banana:'Banana',
peach:'Peach',
import { useState } from "react";
const CHOICES = {
apple: "Apple",
banana: "Banana",
peach: "Peach",
};
const [value, setValue] = useState(Object.keys(CHOICES)[0]);
@ -17,9 +18,9 @@ const [value, setValue] = useState(Object.keys(CHOICES)[0]);
label="Fruit"
value={value}
choices={CHOICES}
onChange={event=>setValue(event.target.value)}
onChange={(event) => setValue(event.target.value)}
/>
<p>Selected choice label: {CHOICES[value]}</p>
<p>Selected choice value: {value}</p>
</>
</>;
```

View File

@ -5,7 +5,7 @@
}
.spinner-fs-background {
background-color: rgba(2, 2, 2, .5);
background-color: rgba(2, 2, 2, 0.5);
color: rgb(230, 230, 230);
position: fixed;
width: 100%;

View File

@ -25,12 +25,12 @@ Spinner.defaultProps = {
fullScreen: false,
};
export function Spinner({
fullScreen, children, className,
}) {
export function Spinner({ fullScreen, children, className }) {
if (!fullScreen) {
return (
<div className={`spinner-wrapper ${className || "my-3 text-center"}`}>
<div
className={`spinner-wrapper ${className || "my-3 text-center"}`}
>
<SpinnerElement>{children}</SpinnerElement>
</div>
);
@ -61,7 +61,9 @@ export function SpinnerElement({ small, className, children }) {
return (
<>
<div
className={`spinner-border ${small ? "spinner-border-sm" : ""} ${className || ""}`.trim()}
className={`spinner-border ${
small ? "spinner-border-sm" : ""
} ${className || ""}`.trim()}
role="status"
>
<span className="sr-only" />

View File

@ -16,29 +16,33 @@ Switch.propTypes = {
PropTypes.node,
PropTypes.arrayOf(PropTypes.node),
]).isRequired,
id: PropTypes.string.isRequired,
helpText: PropTypes.string,
switchHeading: PropTypes.string,
switchHeading: PropTypes.bool,
};
export function Switch({
label, id, helpText, switchHeading, ...props
}) {
export function Switch({ label, helpText, switchHeading, ...props }) {
const uid = useUID();
return (
<div className="form-group">
<div className={`custom-control custom-switch ${!helpText ? "custom-control-inline" : ""} ${switchHeading ? "switch-heading" : ""}`.trim()}>
<div
className={`custom-control custom-switch ${
!helpText ? "custom-control-inline" : ""
} ${switchHeading ? "switch-heading" : ""}`.trim()}
>
<input
type="checkbox"
className="custom-control-input"
id={uid}
{...props}
/>
<label className="custom-control-label" htmlFor={uid}>
{label}
</label>
{helpText && <small className="form-text text-muted mt-0 mb-3">{helpText}</small>}
{helpText && (
<small className="form-text text-muted mt-0 mb-3">
{helpText}
</small>
)}
</div>
</div>
);

View File

@ -1,15 +1,16 @@
Text Bootstrap component input with label and predefined sizes and structure for using in foris forms.
Text Bootstrap component input with label and predefined sizes and structure for
using in foris forms.
All additional `props` are passed to the `<input type="text">` HTML component.
```js
import {useState} from 'react';
const [value, setValue] = useState('Bla bla');
import { useState } from "react";
const [value, setValue] = useState("Bla bla");
<TextInput
value={value}
label="Some text"
label="Some text"
helpText="Read the small text!"
onChange={event =>setValue(event.target.value)}
/>
onChange={(event) => setValue(event.target.value)}
/>;
```

View File

@ -14,19 +14,18 @@ import { Button } from "../Button";
describe("<Button />", () => {
it("Render button correctly", () => {
const { container } = render(<Button>Test Button</Button>);
expect(container.firstChild)
.toMatchSnapshot();
expect(container.firstChild).toMatchSnapshot();
});
it("Render button with custom classes", () => {
const { container } = render(<Button className="one two three">Test Button</Button>);
expect(container.firstChild)
.toMatchSnapshot();
const { container } = render(
<Button className="one two three">Test Button</Button>
);
expect(container.firstChild).toMatchSnapshot();
});
it("Render button with spinner", () => {
const { container } = render(<Button loading>Test Button</Button>);
expect(container.firstChild)
.toMatchSnapshot();
expect(container.firstChild).toMatchSnapshot();
});
});

View File

@ -18,22 +18,16 @@ describe("<Checkbox/>", () => {
label="Test label"
checked
helpText="Some help text"
onChange={() => {
}}
/>,
onChange={() => {}}
/>
);
expect(container.firstChild)
.toMatchSnapshot();
expect(container.firstChild).toMatchSnapshot();
});
it("Render uncheked checkbox", () => {
const { container } = render(
<CheckBox
label="Test label"
helpText="Some help text"
/>,
<CheckBox label="Test label" helpText="Some help text" />
);
expect(container.firstChild)
.toMatchSnapshot();
expect(container.firstChild).toMatchSnapshot();
});
});

View File

@ -13,7 +13,11 @@ import { DownloadButton } from "../DownloadButton";
describe("<DownloadButton />", () => {
it("should have download attribute", () => {
const { container } = render(<DownloadButton href="http://example.com">Test Button</DownloadButton>);
const { container } = render(
<DownloadButton href="http://example.com">
Test Button
</DownloadButton>
);
expect(container.firstChild.getAttribute("download")).not.toBeNull();
});
});

View File

@ -7,9 +7,7 @@
import React from "react";
import {
render, fireEvent, getByLabelText, wait,
} from "customTestRender";
import { render, fireEvent, getByLabelText, wait } from "customTestRender";
import { NumberInput } from "../NumberInput";
@ -24,7 +22,7 @@ describe("<NumberInput/>", () => {
helpText="Some help text"
value={1}
onChange={onChangeMock}
/>,
/>
);
componentContainer = container;
});
@ -36,12 +34,16 @@ describe("<NumberInput/>", () => {
it("Increase number with button", async () => {
const increaseButton = getByLabelText(componentContainer, "Increase");
fireEvent.mouseDown(increaseButton);
await wait(() => expect(onChangeMock).toHaveBeenCalledWith({ target: { value: 2 } }));
await wait(() =>
expect(onChangeMock).toHaveBeenCalledWith({ target: { value: 2 } })
);
});
it("Decrease number with button", async () => {
const decreaseButton = getByLabelText(componentContainer, "Decrease");
fireEvent.mouseDown(decreaseButton);
await wait(() => expect(onChangeMock).toHaveBeenCalledWith({ target: { value: 0 } }));
await wait(() =>
expect(onChangeMock).toHaveBeenCalledWith({ target: { value: 0 } })
);
});
});

View File

@ -18,11 +18,9 @@ describe("<PasswordInput/>", () => {
label="Test label"
helpText="Some help text"
value="Some password"
onChange={() => {
}}
/>,
onChange={() => {}}
/>
);
expect(container.firstChild)
.toMatchSnapshot();
expect(container.firstChild).toMatchSnapshot();
});
});

View File

@ -35,11 +35,9 @@ describe("<RadioSet/>", () => {
value="value"
choices={TEST_CHOICES}
helpText="Some help text"
onChange={() => {
}}
/>,
onChange={() => {}}
/>
);
expect(container.firstChild)
.toMatchSnapshot();
expect(container.firstChild).toMatchSnapshot();
});
});

View File

@ -8,7 +8,10 @@
import React from "react";
import {
fireEvent, getByDisplayValue, getByText, render,
fireEvent,
getByDisplayValue,
getByText,
render,
} from "customTestRender";
import { Select } from "../Select";
@ -29,29 +32,24 @@ describe("<Select/>", () => {
value="1"
choices={TEST_CHOICES}
helpText="Help text"
onChange={onChangeHandler}
/>,
/>
);
selectContainer = container;
});
it("Test with snapshot.", () => {
expect(selectContainer)
.toMatchSnapshot();
expect(selectContainer).toMatchSnapshot();
});
it("Test onChange handling.", () => {
const select = getByDisplayValue(selectContainer, "one");
expect(select.value)
.toBe("1");
expect(select.value).toBe("1");
fireEvent.change(select, { target: { value: "2" } });
const option = getByText(selectContainer, "two");
expect(onChangeHandler)
.toBeCalled();
expect(onChangeHandler).toBeCalled();
expect(option.value)
.toBe("2");
expect(option.value).toBe("2");
});
});

View File

@ -18,11 +18,9 @@ describe("<TextInput/>", () => {
label="Test label"
helpText="Some help text"
value="Some text"
onChange={() => {
}}
/>,
onChange={() => {}}
/>
);
expect(container.firstChild)
.toMatchSnapshot();
expect(container.firstChild).toMatchSnapshot();
});
});

View File

@ -5,8 +5,6 @@ exports[`<Button /> Render button correctly 1`] = `
class="btn btn-primary "
type="button"
>
Test Button
</button>
`;
@ -16,8 +14,6 @@ exports[`<Button /> Render button with custom classes 1`] = `
class="btn one two three"
type="button"
>
Test Button
</button>
`;
@ -33,8 +29,6 @@ exports[`<Button /> Render button with spinner 1`] = `
role="status"
/>
Test Button
</button>
`;