mirror of
https://gitlab.nic.cz/turris/reforis/foris-js.git
synced 2025-06-16 13:46:16 +02:00
Set babel.
This commit is contained in:
29
src/bootstrap/__tests__/Button.test.js
Normal file
29
src/bootstrap/__tests__/Button.test.js
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {render} from 'customTestRender';
|
||||
|
||||
import Button from '../components/Button'
|
||||
|
||||
describe('<Button />', () => {
|
||||
it('Render button correctly', () => {
|
||||
const {container} = render(<Button>Test Button</Button>);
|
||||
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()
|
||||
});
|
||||
|
||||
it('Render button with spinner', () => {
|
||||
const {container} = render(<Button loading={true}>Test Button</Button>)
|
||||
expect(container.firstChild).toMatchSnapshot()
|
||||
});
|
||||
});
|
36
src/bootstrap/__tests__/Checkbox.test.js
Normal file
36
src/bootstrap/__tests__/Checkbox.test.js
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {render} from 'customTestRender';
|
||||
|
||||
import Checkbox from '../components/Checkbox'
|
||||
|
||||
describe('<Checkbox/>', () => {
|
||||
it('Render checkbox', () => {
|
||||
const {container} = render(
|
||||
<Checkbox
|
||||
label="Test label"
|
||||
checked
|
||||
helpText="Some help text"
|
||||
onChange={()=>{}}
|
||||
/>
|
||||
);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Render uncheked checkbox', () => {
|
||||
const {container} = render(
|
||||
<Checkbox
|
||||
label="Test label"
|
||||
helpText="Some help text"
|
||||
/>
|
||||
);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
28
src/bootstrap/__tests__/NumberInput.test.js
Normal file
28
src/bootstrap/__tests__/NumberInput.test.js
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {render} from 'customTestRender';
|
||||
|
||||
import NumberInput from '../components/NumberInput';
|
||||
|
||||
|
||||
describe('<NumberInput/>', () => {
|
||||
it('Render number input', () => {
|
||||
const {container} = render(
|
||||
<NumberInput
|
||||
label="Test label"
|
||||
helpText="Some help text"
|
||||
value={1123}
|
||||
onChange={() => {
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
27
src/bootstrap/__tests__/PasswordInput.test.js
Normal file
27
src/bootstrap/__tests__/PasswordInput.test.js
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {render} from 'customTestRender';
|
||||
|
||||
import PasswordInput from '../components/PasswordInput';
|
||||
|
||||
describe('<PasswordInput/>', () => {
|
||||
it('Render password input', () => {
|
||||
const {container} = render(
|
||||
<PasswordInput
|
||||
label="Test label"
|
||||
helpText="Some help text"
|
||||
value="Some password"
|
||||
onChange={() => {
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
35
src/bootstrap/__tests__/RadioSet.test.js
Normal file
35
src/bootstrap/__tests__/RadioSet.test.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {render} from 'customTestRender';
|
||||
|
||||
import RadioSet from '../components/RadioSet';
|
||||
|
||||
const TEST_CHOICES = [
|
||||
{label: 'label', value: 'value'},
|
||||
{label: 'another label', value: 'another value'},
|
||||
{label: 'another one label', value: 'another on value'}
|
||||
];
|
||||
|
||||
describe('<RadioSet/>', () => {
|
||||
it('Render radio set', () => {
|
||||
const {container} = render(
|
||||
<RadioSet
|
||||
name={'test_name'}
|
||||
label='Radios set label'
|
||||
value='value'
|
||||
choices={TEST_CHOICES}
|
||||
helpText={'Some help text'}
|
||||
onChange={() => {
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
51
src/bootstrap/__tests__/Select.test.js
Normal file
51
src/bootstrap/__tests__/Select.test.js
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {fireEvent, getByDisplayValue, getByText, render} from 'customTestRender';
|
||||
|
||||
import Select from '../components/Select';
|
||||
|
||||
const TEST_CHOICES = {
|
||||
'1': 'one',
|
||||
'2': 'two',
|
||||
'3': 'three',
|
||||
};
|
||||
|
||||
describe('<Select/>', () => {
|
||||
var selectContainer;
|
||||
const onChangeHandler = jest.fn();
|
||||
beforeEach(() => {
|
||||
const {container} = render(
|
||||
<Select
|
||||
label='Test label'
|
||||
value='1'
|
||||
choices={TEST_CHOICES}
|
||||
helpText='Help text'
|
||||
|
||||
onChange={onChangeHandler}
|
||||
/>
|
||||
);
|
||||
selectContainer = container;
|
||||
});
|
||||
|
||||
it('Test with snapshot.', () => {
|
||||
expect(selectContainer).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Test onChange handling.', () => {
|
||||
const select = getByDisplayValue(selectContainer, 'one');
|
||||
expect(select.value).toBe('1');
|
||||
fireEvent.change(select, {target: {value: '2'}});
|
||||
|
||||
const option = getByText(selectContainer, 'two');
|
||||
expect(onChangeHandler).toBeCalled();
|
||||
|
||||
expect(option.value).toBe('2');
|
||||
})
|
||||
});
|
27
src/bootstrap/__tests__/TextInput.test.js
Normal file
27
src/bootstrap/__tests__/TextInput.test.js
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {render} from 'customTestRender';
|
||||
|
||||
import TextInput from '../components/TextInput';
|
||||
|
||||
describe('<TextInput/>', () => {
|
||||
it('Render text input', () => {
|
||||
const {container} = render(
|
||||
<TextInput
|
||||
label="Test label"
|
||||
helpText="Some help text"
|
||||
value="Some text"
|
||||
onChange={() => {
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
37
src/bootstrap/__tests__/__snapshots__/Button.test.js.snap
Normal file
37
src/bootstrap/__tests__/__snapshots__/Button.test.js.snap
Normal file
@ -0,0 +1,37 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Button /> Render button correctly 1`] = `
|
||||
<button
|
||||
class="btn btn-primary "
|
||||
>
|
||||
|
||||
|
||||
Test Button
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`<Button /> Render button with custom classes 1`] = `
|
||||
<button
|
||||
class="btn one two three"
|
||||
>
|
||||
|
||||
|
||||
Test Button
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`<Button /> Render button with spinner 1`] = `
|
||||
<button
|
||||
class="btn btn-primary "
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="spinner-border spinner-border-sm"
|
||||
role="status"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
Test Button
|
||||
</button>
|
||||
`;
|
62
src/bootstrap/__tests__/__snapshots__/Checkbox.test.js.snap
Normal file
62
src/bootstrap/__tests__/__snapshots__/Checkbox.test.js.snap
Normal file
@ -0,0 +1,62 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Checkbox/> Render checkbox 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
style="margin-bottom: 1rem;"
|
||||
>
|
||||
<div
|
||||
class="custom-control custom-checkbox"
|
||||
style="margin-bottom: 0px;"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="custom-control-input"
|
||||
id="1"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
class="custom-control-label"
|
||||
for="1"
|
||||
style="margin-bottom: 0px;"
|
||||
>
|
||||
Test label
|
||||
</label>
|
||||
</div>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<Checkbox/> Render uncheked checkbox 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
style="margin-bottom: 1rem;"
|
||||
>
|
||||
<div
|
||||
class="custom-control custom-checkbox"
|
||||
style="margin-bottom: 0px;"
|
||||
>
|
||||
<input
|
||||
class="custom-control-input"
|
||||
id="1"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
class="custom-control-label"
|
||||
for="1"
|
||||
style="margin-bottom: 0px;"
|
||||
>
|
||||
Test label
|
||||
</label>
|
||||
</div>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</div>
|
||||
`;
|
@ -0,0 +1,32 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<NumberInput/> Render number input 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
>
|
||||
<div
|
||||
class="form-group"
|
||||
>
|
||||
<label
|
||||
for="1"
|
||||
>
|
||||
Test label
|
||||
</label>
|
||||
<div
|
||||
class="input-group"
|
||||
>
|
||||
<input
|
||||
class="form-control"
|
||||
id="1"
|
||||
type="number"
|
||||
value="1123"
|
||||
/>
|
||||
</div>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -0,0 +1,33 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<PasswordInput/> Render password input 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
>
|
||||
<div
|
||||
class="form-group"
|
||||
>
|
||||
<label
|
||||
for="1"
|
||||
>
|
||||
Test label
|
||||
</label>
|
||||
<div
|
||||
class="input-group"
|
||||
>
|
||||
<input
|
||||
autocomplete="new-password"
|
||||
class="form-control"
|
||||
id="1"
|
||||
type="password"
|
||||
value="Some password"
|
||||
/>
|
||||
</div>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
73
src/bootstrap/__tests__/__snapshots__/RadioSet.test.js.snap
Normal file
73
src/bootstrap/__tests__/__snapshots__/RadioSet.test.js.snap
Normal file
@ -0,0 +1,73 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<RadioSet/> Render radio set 1`] = `
|
||||
<div
|
||||
class="form-group col-sm-12 offset-lg-1 col-lg-10"
|
||||
style="margin-bottom: 1rem;"
|
||||
>
|
||||
<label
|
||||
class="col-12"
|
||||
for="1"
|
||||
style="padding-left: 0px;"
|
||||
>
|
||||
Radios set label
|
||||
</label>
|
||||
<div
|
||||
class="custom-control custom-radio custom-control-inline"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="custom-control-input"
|
||||
id="test_name-0"
|
||||
name="test_name"
|
||||
type="radio"
|
||||
value="value"
|
||||
/>
|
||||
<label
|
||||
class="custom-control-label"
|
||||
for="test_name-0"
|
||||
>
|
||||
label
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="custom-control custom-radio custom-control-inline"
|
||||
>
|
||||
<input
|
||||
class="custom-control-input"
|
||||
id="test_name-1"
|
||||
name="test_name"
|
||||
type="radio"
|
||||
value="another value"
|
||||
/>
|
||||
<label
|
||||
class="custom-control-label"
|
||||
for="test_name-1"
|
||||
>
|
||||
another label
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="custom-control custom-radio custom-control-inline"
|
||||
>
|
||||
<input
|
||||
class="custom-control-input"
|
||||
id="test_name-2"
|
||||
name="test_name"
|
||||
type="radio"
|
||||
value="another on value"
|
||||
/>
|
||||
<label
|
||||
class="custom-control-label"
|
||||
for="test_name-2"
|
||||
>
|
||||
another one label
|
||||
</label>
|
||||
</div>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</div>
|
||||
`;
|
40
src/bootstrap/__tests__/__snapshots__/Select.test.js.snap
Normal file
40
src/bootstrap/__tests__/__snapshots__/Select.test.js.snap
Normal file
@ -0,0 +1,40 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Select/> Test with snapshot. 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="form-group col-sm-12 offset-lg-1 col-lg-10"
|
||||
>
|
||||
<label
|
||||
for="1"
|
||||
>
|
||||
Test label
|
||||
</label>
|
||||
<select
|
||||
class="custom-select"
|
||||
id="1"
|
||||
>
|
||||
<option
|
||||
value="1"
|
||||
>
|
||||
one
|
||||
</option>
|
||||
<option
|
||||
value="2"
|
||||
>
|
||||
two
|
||||
</option>
|
||||
<option
|
||||
value="3"
|
||||
>
|
||||
three
|
||||
</option>
|
||||
</select>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Help text
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
32
src/bootstrap/__tests__/__snapshots__/TextInput.test.js.snap
Normal file
32
src/bootstrap/__tests__/__snapshots__/TextInput.test.js.snap
Normal file
@ -0,0 +1,32 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<TextInput/> Render text input 1`] = `
|
||||
<div
|
||||
class="col-sm-12 offset-lg-1 col-lg-10"
|
||||
>
|
||||
<div
|
||||
class="form-group"
|
||||
>
|
||||
<label
|
||||
for="1"
|
||||
>
|
||||
Test label
|
||||
</label>
|
||||
<div
|
||||
class="input-group"
|
||||
>
|
||||
<input
|
||||
class="form-control"
|
||||
id="1"
|
||||
type="text"
|
||||
value="Some text"
|
||||
/>
|
||||
</div>
|
||||
<small
|
||||
class="form-text text-muted"
|
||||
>
|
||||
Some help text
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
31
src/bootstrap/components/Alert.js
Normal file
31
src/bootstrap/components/Alert.js
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
Alert.propTypes = {
|
||||
/** Type of the alert it adds as `alert-${type}` class.*/
|
||||
type: PropTypes.string.isRequired,
|
||||
/** Alert message.*/
|
||||
message: PropTypes.string,
|
||||
/** Alert content.*/
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
]),
|
||||
/** onDismiss handler.*/
|
||||
onDismiss: PropTypes.func
|
||||
};
|
||||
|
||||
export default function Alert({type, message, onDismiss, children}) {
|
||||
return <div className={`alert alert-dismissible alert-${type}`}>
|
||||
{onDismiss ? <button type="button" className="close" onClick={onDismiss}>×</button> : false}
|
||||
{message}
|
||||
{children}
|
||||
</div>
|
||||
}
|
20
src/bootstrap/components/Alert.md
Normal file
20
src/bootstrap/components/Alert.md
Normal file
@ -0,0 +1,20 @@
|
||||
Bootstrap alert component.
|
||||
```jsx
|
||||
import {useState} from 'react';
|
||||
|
||||
function AlertExample(){
|
||||
const [alert, setAlert] = useState(true);
|
||||
if (alert)
|
||||
return <Alert
|
||||
type='warning'
|
||||
message='Some warning out there!'
|
||||
onDismiss={()=>setAlert(false)}
|
||||
/>;
|
||||
return <button
|
||||
className='btn btn-secondary'
|
||||
onClick={()=>setAlert(true)}
|
||||
>Show alert again</button>;
|
||||
};
|
||||
<AlertExample/>
|
||||
|
||||
```
|
43
src/bootstrap/components/Button.js
Normal file
43
src/bootstrap/components/Button.js
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const OFFSET = 8;
|
||||
const SIZE = 3;
|
||||
const SIZE_CLASS = ' offset-lg-' + OFFSET + ' col-lg-' + SIZE;
|
||||
const SIZE_CLASS_SM = ' col-sm-12';
|
||||
|
||||
Button.propTypes = {
|
||||
/** Additional class name. */
|
||||
className: PropTypes.string,
|
||||
/** Use foris form size and offset. */
|
||||
forisFormSize: PropTypes.bool,
|
||||
/** Show loading icon. */
|
||||
loading: PropTypes.bool,
|
||||
/** Button content. */
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.element,
|
||||
PropTypes.node,
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
]).isRequired
|
||||
};
|
||||
|
||||
export default function Button({className, loading, forisFormSize, children, ...props}) {
|
||||
className = className ? 'btn ' + className : 'btn btn-primary ';
|
||||
if (forisFormSize)
|
||||
className += SIZE_CLASS + SIZE_CLASS_SM;
|
||||
|
||||
const span = loading ?
|
||||
<span className='spinner-border spinner-border-sm' role='status' aria-hidden='true'/> : null;
|
||||
|
||||
return <button className={className} {...props}>
|
||||
{span} {span ? ' ' : null} {children}
|
||||
</button>;
|
||||
}
|
15
src/bootstrap/components/Button.md
Normal file
15
src/bootstrap/components/Button.md
Normal file
@ -0,0 +1,15 @@
|
||||
Bootstrap button component.
|
||||
|
||||
All additional `props` are passed to the `<button>` HTML component.
|
||||
|
||||
Can be used without parameters:
|
||||
|
||||
```jsx
|
||||
<Button>Click</Button>
|
||||
```
|
||||
|
||||
Using loading spinner:
|
||||
|
||||
```jsx
|
||||
<Button loading disabled>Loading...</Button>
|
||||
```
|
46
src/bootstrap/components/Checkbox.js
Normal file
46
src/bootstrap/components/Checkbox.js
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {useUID} from 'react-uid/dist/es5/index';
|
||||
|
||||
import {formFieldsSize} from './constants';
|
||||
|
||||
CheckBox.propTypes = {
|
||||
/** Label message */
|
||||
label: PropTypes.string.isRequired,
|
||||
/** Help text message */
|
||||
helpText: PropTypes.string,
|
||||
/** Apply default size (full-width) */
|
||||
useDefaultSize: PropTypes.bool,
|
||||
/** Control if checkbox is clickable */
|
||||
disabled: PropTypes.bool
|
||||
};
|
||||
|
||||
CheckBox.defaultProps = {
|
||||
useDefaultSize: true,
|
||||
disabled: false
|
||||
};
|
||||
|
||||
export default function CheckBox({label, helpText, useDefaultSize, disabled, ...props}) {
|
||||
const uid = useUID();
|
||||
return <div className={useDefaultSize ? formFieldsSize : ""} style={{marginBottom: '1rem'}}>
|
||||
<div className='custom-control custom-checkbox' style={{marginBottom: '0'}}>
|
||||
<input
|
||||
className='custom-control-input'
|
||||
type='checkbox'
|
||||
id={uid}
|
||||
disabled={disabled}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
<label className='custom-control-label' htmlFor={uid} style={helpText ? {marginBottom: '0'} : null}>{label}</label>
|
||||
</div>
|
||||
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
|
||||
</div>
|
||||
}
|
16
src/bootstrap/components/Checkbox.md
Normal file
16
src/bootstrap/components/Checkbox.md
Normal file
@ -0,0 +1,16 @@
|
||||
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';
|
||||
const [value, setValue] = useState(false);
|
||||
|
||||
<CheckBox
|
||||
value={value}
|
||||
label="Some label"
|
||||
helpText="Read the small text!"
|
||||
onChange={value => setValue(value)}
|
||||
/>
|
||||
```
|
57
src/bootstrap/components/DataTimeInput.js
Normal file
57
src/bootstrap/components/DataTimeInput.js
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Datetime from 'react-datetime/DateTime';
|
||||
import moment from 'moment/moment';
|
||||
|
||||
import Input from './Input';
|
||||
|
||||
DataTimeInput.propTypes = {
|
||||
/** Field label. */
|
||||
label: PropTypes.string.isRequired,
|
||||
/** Error message. */
|
||||
error: PropTypes.string,
|
||||
/** DataTime or Data or Time value. Can be `moment` or string.*/
|
||||
value: PropTypes.oneOfType([PropTypes.objectOf(moment), PropTypes.string]),
|
||||
/** Help text message. */
|
||||
helpText: PropTypes.string,
|
||||
/** Content. */
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
]),
|
||||
isValidDate: PropTypes.bool,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
dateFormat: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
|
||||
timeFormat: PropTypes.string
|
||||
};
|
||||
|
||||
const DEFAULT_DATE_FORMAT = 'YYYY-MM-DD';
|
||||
const DEFAULT_TIME_FORMAT = 'HH:mm:ss';
|
||||
|
||||
export default function DataTimeInput({value, onChange, isValidDate, dateFormat, timeFormat, children, ...props}) {
|
||||
function renderInput(datetimeProps) {
|
||||
return <Input
|
||||
{...props}
|
||||
{...datetimeProps}
|
||||
>
|
||||
{children}
|
||||
</Input>
|
||||
}
|
||||
|
||||
return <Datetime
|
||||
locale={ForisTranslations.locale}
|
||||
dateFormat={dateFormat !== undefined ? dateFormat : DEFAULT_DATE_FORMAT}
|
||||
timeFormat={timeFormat !== undefined ? timeFormat : DEFAULT_TIME_FORMAT}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
isValidDate={isValidDate}
|
||||
renderInput={renderInput}
|
||||
/>;
|
||||
}
|
25
src/bootstrap/components/DataTimeInput.md
Normal file
25
src/bootstrap/components/DataTimeInput.md
Normal file
@ -0,0 +1,25 @@
|
||||
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.
|
||||
|
||||
```js
|
||||
ForisTranslations={locale:'en'};
|
||||
|
||||
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]);
|
||||
|
||||
<DataTimeInput
|
||||
label='Time to sleep'
|
||||
value={dataTime}
|
||||
error={error}
|
||||
helpText='Example helptext...'
|
||||
onChange={value => setDataTime(value)}
|
||||
/>
|
||||
```
|
27
src/bootstrap/components/EmailInput.js
Normal file
27
src/bootstrap/components/EmailInput.js
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Input from './Input';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const EmailInput = ({...props}) => <Input type="email" {...props}/>;
|
||||
|
||||
|
||||
EmailInput.propTypes = {
|
||||
/** Field label. */
|
||||
label: PropTypes.string.isRequired,
|
||||
/** Error message. */
|
||||
error: PropTypes.string,
|
||||
/** Help text message. */
|
||||
helpText: PropTypes.string,
|
||||
/** Email value. */
|
||||
value: PropTypes.string,
|
||||
};
|
||||
|
||||
export default EmailInput;
|
18
src/bootstrap/components/EmailInput.md
Normal file
18
src/bootstrap/components/EmailInput.md
Normal file
@ -0,0 +1,18 @@
|
||||
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()}>
|
||||
<EmailInput
|
||||
value={email}
|
||||
label="Some label"
|
||||
helpText="Read the small text!"
|
||||
onChange={target => setEmail(target.value)}
|
||||
/>
|
||||
<button type="submit">Try to submit</button>
|
||||
</form>
|
||||
```
|
46
src/bootstrap/components/Input.js
Normal file
46
src/bootstrap/components/Input.js
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {useUID} from 'react-uid/dist/es5/index';
|
||||
import {formFieldsSize} from './constants';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
Input.propTypes = {
|
||||
type: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
helpText: PropTypes.string,
|
||||
error: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
])
|
||||
}
|
||||
|
||||
/** Base bootstrap input component. */
|
||||
export default function Input({type, label, helpText, error, className, children, ...props}) {
|
||||
const uid = useUID();
|
||||
const inputClassName = `form-control ${className ? className : ''} ${(error ? 'is-invalid' : '')}`.trim();
|
||||
return <div className={formFieldsSize}>
|
||||
<div className='form-group'>
|
||||
<label htmlFor={uid}>{label}</label>
|
||||
<div className='input-group'>
|
||||
<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}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
88
src/bootstrap/components/Modal.js
Normal file
88
src/bootstrap/components/Modal.js
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React, {useEffect, useRef} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Portal from 'utils/Portal';
|
||||
|
||||
Modal.propTypes = {
|
||||
/** Is modal shown value */
|
||||
shown: PropTypes.bool.isRequired,
|
||||
/** Callback to manage modal visibility */
|
||||
setShown: PropTypes.func.isRequired,
|
||||
|
||||
/** Modal content use following: `ModalHeader`, `ModalBody`, `ModalFooter` */
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
]).isRequired
|
||||
};
|
||||
|
||||
export function Modal({shown, setShown, children}) {
|
||||
const dialogRef = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
function handleClickOutsideDialog(e) {
|
||||
if (!dialogRef.current.contains(e.target))
|
||||
setShown(false);
|
||||
}
|
||||
|
||||
document.addEventListener("mousedown", handleClickOutsideDialog);
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", handleClickOutsideDialog);
|
||||
};
|
||||
}, [setShown]);
|
||||
|
||||
|
||||
return <Portal containerId="modal_container">
|
||||
<div className={'modal fade ' + (shown ? 'show' : '')} role="dialog">
|
||||
<div ref={dialogRef} className="modal-dialog" role="document">
|
||||
<div className="modal-content">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Portal>
|
||||
}
|
||||
|
||||
ModalHeader.propTypes = {
|
||||
setShown: PropTypes.func.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export function ModalHeader({setShown, title}) {
|
||||
return <div className="modal-header">
|
||||
<h5 className="modal-title">{title}</h5>
|
||||
<button type="button" className="close" onClick={() => setShown(false)}>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
ModalBody.propTypes = {
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
]).isRequired
|
||||
};
|
||||
|
||||
export function ModalBody({children}) {
|
||||
return <div className="modal-body">{children}</div>
|
||||
}
|
||||
|
||||
ModalFooter.propTypes = {
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
]).isRequired
|
||||
};
|
||||
|
||||
export function ModalFooter({children}) {
|
||||
return <div className="modal-footer">
|
||||
{children}
|
||||
</div>
|
||||
}
|
27
src/bootstrap/components/Modal.md
Normal file
27
src/bootstrap/components/Modal.md
Normal file
@ -0,0 +1,27 @@
|
||||
Bootstrap modal component.
|
||||
|
||||
I have no idea why example doesn't work here but you can investigate HTML code...
|
||||
```js
|
||||
import {ModalHeader, ModalBody, ModalFooter} from './Modal';
|
||||
|
||||
import {useState} from 'react';
|
||||
const [shown, setShown] = useState(false);
|
||||
|
||||
<>
|
||||
<Modal shown={shown}>
|
||||
<ModalHeader setShown={setShown} title='Warning!'/>
|
||||
<ModalBody><p>Bla bla bla...</p></ModalBody>
|
||||
<ModalFooter>
|
||||
<button
|
||||
className='btn btn-secondary'
|
||||
onClick={() => setShown(false)}
|
||||
>Skip it</button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
|
||||
<button
|
||||
className='btn btn-secondary'
|
||||
onClick={()=>setShown(true)}
|
||||
>Show modal</button>
|
||||
</>
|
||||
```
|
29
src/bootstrap/components/NumberInput.js
Normal file
29
src/bootstrap/components/NumberInput.js
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Input from './Input';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const NumberInput = ({...props}) => <Input type="number" {...props}/>;
|
||||
|
||||
NumberInput.propTypes = {
|
||||
/** Field label. */
|
||||
label: PropTypes.string.isRequired,
|
||||
/** Error message. */
|
||||
error: PropTypes.string,
|
||||
/** Help text message. */
|
||||
helpText: PropTypes.string,
|
||||
/** Number value. */
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
]),
|
||||
};
|
||||
|
||||
export default NumberInput;
|
17
src/bootstrap/components/NumberInput.md
Normal file
17
src/bootstrap/components/NumberInput.md
Normal file
@ -0,0 +1,17 @@
|
||||
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';
|
||||
const [value, setValue] = useState(42);
|
||||
|
||||
<NumberInput
|
||||
value={value}
|
||||
label="Some number"
|
||||
helpText="Read the small text!"
|
||||
min='33'
|
||||
max='54'
|
||||
onChange={target => setValue(target.value)}
|
||||
/>
|
||||
```
|
44
src/bootstrap/components/PasswordInput.js
Normal file
44
src/bootstrap/components/PasswordInput.js
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React, {useState} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Input from './Input';
|
||||
|
||||
PasswordInput.propTypes = {
|
||||
/** Field label. */
|
||||
label: PropTypes.string.isRequired,
|
||||
/** Error message. */
|
||||
error: PropTypes.string,
|
||||
/** Password value. */
|
||||
value: PropTypes.string,
|
||||
/** Help text message. */
|
||||
helpText: PropTypes.string,
|
||||
/** Use show/hide password button. */
|
||||
withEye: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default function PasswordInput({withEye, ...props}) {
|
||||
const [isHidden, setHidden] = useState(true);
|
||||
return <Input
|
||||
type={withEye ? isHidden ? 'password' : 'text' : 'password'}
|
||||
autoComplete={isHidden ? 'new-password' : null}
|
||||
{...props}
|
||||
>
|
||||
{withEye ?
|
||||
<div className="input-group-append">
|
||||
<button className="input-group-text" onClick={e => {
|
||||
e.preventDefault();
|
||||
setHidden(isHidden => !isHidden);
|
||||
}}>
|
||||
<i className={'fa ' + (isHidden ? 'fa-eye' : 'fa-eye-slash')}/>
|
||||
</button>
|
||||
</div>
|
||||
: null}
|
||||
</Input>
|
||||
}
|
17
src/bootstrap/components/PasswordInput.md
Normal file
17
src/bootstrap/components/PasswordInput.md
Normal file
@ -0,0 +1,17 @@
|
||||
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.
|
||||
|
||||
```js
|
||||
import {useState} from 'react';
|
||||
const [value, setValue] = useState('secret');
|
||||
|
||||
<PasswordInput
|
||||
withEye
|
||||
value={value}
|
||||
label="Some password"
|
||||
helpText="Read the small text!"
|
||||
onChange={target => setValue(target.value)}
|
||||
/>
|
||||
```
|
80
src/bootstrap/components/RadioSet.js
Normal file
80
src/bootstrap/components/RadioSet.js
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {useUID} from 'react-uid/dist/es5/index';
|
||||
|
||||
import {formFieldsSize} from './constants';
|
||||
|
||||
|
||||
RadioSet.propTypes = {
|
||||
/** Name attribute of the input HTML tag.*/
|
||||
name: PropTypes.string.isRequired,
|
||||
/** RadioSet label .*/
|
||||
label: PropTypes.string,
|
||||
/** Choices .*/
|
||||
choices: PropTypes.arrayOf(PropTypes.shape({
|
||||
/** Choice lable .*/
|
||||
label: PropTypes.string.isRequired,
|
||||
/** Choice value .*/
|
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
})).isRequired,
|
||||
/** Initial value .*/
|
||||
value: PropTypes.string,
|
||||
/** Help text message .*/
|
||||
helpText: PropTypes.string,
|
||||
};
|
||||
|
||||
export default function RadioSet({name, label, choices, value, helpText, ...props}) {
|
||||
const uid = useUID();
|
||||
const radios = choices.map((choice, key) =>
|
||||
<Radio
|
||||
id={`${name}-${key}`}
|
||||
key={key}
|
||||
name={name}
|
||||
label={choice.label}
|
||||
value={choice.value}
|
||||
helpText={choice.helpText}
|
||||
checked={choice.value === value}
|
||||
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
return <div className={`form-group ${formFieldsSize}`} style={{marginBottom: '1rem'}}>
|
||||
{label ?
|
||||
<label className='col-12' htmlFor={uid} style={{paddingLeft: '0'}}>
|
||||
{label}
|
||||
</label>
|
||||
: null}
|
||||
{radios}
|
||||
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
|
||||
</div>;
|
||||
}
|
||||
|
||||
Radio.propTypes = {
|
||||
label: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
helpText: PropTypes.string
|
||||
};
|
||||
|
||||
function Radio({label, id, helpText, ...props}) {
|
||||
return <>
|
||||
<div className='custom-control custom-radio custom-control-inline'>
|
||||
<input
|
||||
id={id}
|
||||
className='custom-control-input'
|
||||
type='radio'
|
||||
|
||||
{...props}
|
||||
/>
|
||||
<label className='custom-control-label' htmlFor={id}>{label}</label>
|
||||
</div>
|
||||
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
|
||||
</>
|
||||
}
|
24
src/bootstrap/components/RadioSet.md
Normal file
24
src/bootstrap/components/RadioSet.md
Normal file
@ -0,0 +1,24 @@
|
||||
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.
|
||||
|
||||
```js
|
||||
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);
|
||||
|
||||
<>
|
||||
{/*Yeah, it gets event, not value!*/}
|
||||
<RadioSet
|
||||
value={value}
|
||||
name='some-radio'
|
||||
choices={CHOICES}
|
||||
onChange={event=>setValue(event.target.value)}
|
||||
/>
|
||||
<p>Selected value: {value}</p>
|
||||
</>
|
||||
```
|
45
src/bootstrap/components/Select.js
Normal file
45
src/bootstrap/components/Select.js
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {useUID} from 'react-uid/dist/es5/index';
|
||||
|
||||
|
||||
Select.propTypes = {
|
||||
/** Select field Label. */
|
||||
label: PropTypes.string.isRequired,
|
||||
/** Choices if form of {value : "Label",...}.*/
|
||||
choices: PropTypes.object.isRequired,
|
||||
/** Current value. */
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
]).isRequired,
|
||||
/** Help text message. */
|
||||
helpText: PropTypes.string,
|
||||
};
|
||||
|
||||
export default function Select({label, choices, helpText, ...props}) {
|
||||
const uid = useUID();
|
||||
|
||||
const options = Object.keys(choices).map(
|
||||
key => <option key={key} value={key}>{choices[key]}</option>
|
||||
);
|
||||
|
||||
return <div className='form-group col-sm-12 offset-lg-1 col-lg-10'>
|
||||
<label htmlFor={uid}>{label}</label>
|
||||
<select
|
||||
className='custom-select'
|
||||
id={uid}
|
||||
{...props}
|
||||
>
|
||||
{options}
|
||||
</select>
|
||||
{helpText ? <small className="form-text text-muted">{helpText}</small> : null}
|
||||
</div>;
|
||||
}
|
25
src/bootstrap/components/Select.md
Normal file
25
src/bootstrap/components/Select.md
Normal file
@ -0,0 +1,25 @@
|
||||
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',
|
||||
};
|
||||
const [value, setValue] = useState(Object.keys(CHOICES)[0]);
|
||||
|
||||
<>
|
||||
{/*Yeah, it gets event, not value!*/}
|
||||
<Select
|
||||
label="Fruit"
|
||||
value={value}
|
||||
choices={CHOICES}
|
||||
onChange={event=>setValue(event.target.value)}
|
||||
/>
|
||||
<p>Selected choice label: {CHOICES[value]}</p>
|
||||
<p>Selected choice value: {value}</p>
|
||||
</>
|
||||
```
|
57
src/bootstrap/components/Spinner.js
Normal file
57
src/bootstrap/components/Spinner.js
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
Spinner.propTypes = {
|
||||
/** Children components put into `div` with "spinner-text" class. */
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
]),
|
||||
/** Render component with full-screen mode (using apropriate `.css` styles) */
|
||||
fullScreen: PropTypes.bool.isRequired,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
Spinner.defaultProps = {
|
||||
fullScreen: false,
|
||||
};
|
||||
|
||||
export default function Spinner({fullScreen, children, className, ...props}) {
|
||||
if (!fullScreen) {
|
||||
return <div className={'spinner-wrapper ' + (className ? className : '')} {...props}>
|
||||
<SpinnerElement>{children}</SpinnerElement>
|
||||
</div>;
|
||||
}
|
||||
|
||||
return <div className="spinner-fs-wrapper" {...props}>
|
||||
<div className="spinner-fs-background">
|
||||
<SpinnerElement>{children}</SpinnerElement>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
SpinnerElement.propTypes = {
|
||||
/** Spinner's size */
|
||||
small: PropTypes.bool,
|
||||
/** Children components */
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
]),
|
||||
};
|
||||
|
||||
export function SpinnerElement({small, children}) {
|
||||
return <>
|
||||
<div className={'spinner-border ' + (small ? 'spinner-border-sm' : '')} role="status">
|
||||
<span className="sr-only"/>
|
||||
</div>
|
||||
<div className="spinner-text">{children}</div>
|
||||
</>
|
||||
}
|
5
src/bootstrap/components/Spinner.md
Normal file
5
src/bootstrap/components/Spinner.md
Normal file
@ -0,0 +1,5 @@
|
||||
Spiner Bootstrap component.
|
||||
|
||||
```js
|
||||
<Spinner>You can put text inside or any component you wish.</Spinner>
|
||||
```
|
26
src/bootstrap/components/TextInput.js
Normal file
26
src/bootstrap/components/TextInput.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Input from './Input';
|
||||
|
||||
|
||||
const TextInput = ({...props}) => <Input type="text" {...props}/>;
|
||||
|
||||
|
||||
TextInput.propTypes = {
|
||||
/** Field label. */
|
||||
label: PropTypes.string.isRequired,
|
||||
/** Error text. */
|
||||
error: PropTypes.string,
|
||||
/** Help text message. */
|
||||
helpText: PropTypes.string,
|
||||
};
|
||||
|
||||
export default TextInput;
|
15
src/bootstrap/components/TextInput.md
Normal file
15
src/bootstrap/components/TextInput.md
Normal file
@ -0,0 +1,15 @@
|
||||
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');
|
||||
|
||||
<TextInput
|
||||
value={value}
|
||||
label="Some text"
|
||||
helpText="Read the small text!"
|
||||
onChange={event => setValue(event.target.value)}
|
||||
/>
|
||||
```
|
9
src/bootstrap/components/constants.js
Normal file
9
src/bootstrap/components/constants.js
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
/** Bootstrap column size for form fields */
|
||||
export const formFieldsSize = 'col-sm-12 offset-lg-1 col-lg-10';
|
31
src/bootstrap/index.js
Normal file
31
src/bootstrap/index.js
Normal file
@ -0,0 +1,31 @@
|
||||
import * as Alert from "./components/Alert";
|
||||
import * as Button from "./components/Button";
|
||||
import * as Checkbox from "./components/Checkbox";
|
||||
import * as constants from "./components/constants";
|
||||
import * as DataTimeInput from "./components/DataTimeInput";
|
||||
import * as EmailInput from "./components/EmailInput";
|
||||
import * as Input from "./components/Input";
|
||||
import * as Modal from "./components/Modal";
|
||||
import * as NumberInput from "./components/NumberInput";
|
||||
import * as PasswordInput from "./components/PasswordInput";
|
||||
import * as RadioSet from "./components/RadioSet";
|
||||
import * as Select from "./components/Select";
|
||||
import * as Spinner from "./components/Spinner";
|
||||
import * as TextInput from "./components/TextInput";
|
||||
|
||||
export {
|
||||
Alert,
|
||||
Button,
|
||||
Checkbox,
|
||||
constants,
|
||||
DataTimeInput,
|
||||
EmailInput,
|
||||
Input,
|
||||
Modal,
|
||||
NumberInput,
|
||||
PasswordInput,
|
||||
RadioSet,
|
||||
Select,
|
||||
Spinner,
|
||||
TextInput,
|
||||
}
|
Reference in New Issue
Block a user