mirror of
https://github.com/Steffo99/bluelib.git
synced 2024-12-22 11:34:21 +00:00
✨ Add forms
This commit is contained in:
parent
d63828ae78
commit
a989c0164e
18 changed files with 291 additions and 52 deletions
43
package-lock.json
generated
43
package-lock.json
generated
|
@ -21,7 +21,8 @@
|
|||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-syntax-highlighter": "^15.4.3",
|
||||
"strip-indent": "^3.0.0"
|
||||
"strip-indent": "^3.0.0",
|
||||
"uuid": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nwb": "0.25.x",
|
||||
|
@ -12560,12 +12561,6 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/react-docgen/node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "17.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz",
|
||||
|
@ -12758,12 +12753,6 @@
|
|||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-styleguidist/node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/react-styleguidist/node_modules/copy-webpack-plugin": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz",
|
||||
|
@ -14949,12 +14938,6 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/terser/node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/terser/node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
|
@ -15652,7 +15635,6 @@
|
|||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"uuid": "bin/uuid"
|
||||
}
|
||||
|
@ -27650,12 +27632,6 @@
|
|||
"requires": {
|
||||
"tslib": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -27853,12 +27829,6 @@
|
|||
"webpack-merge": "^4.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"copy-webpack-plugin": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz",
|
||||
|
@ -29638,12 +29608,6 @@
|
|||
"source-map-support": "~0.5.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
|
@ -30336,8 +30300,7 @@
|
|||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||
},
|
||||
"value-equal": {
|
||||
"version": "1.0.1",
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-syntax-highlighter": "^15.4.3",
|
||||
"strip-indent": "^3.0.0"
|
||||
"strip-indent": "^3.0.0",
|
||||
"uuid": "^3.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^17.0.2"
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit a47f83b53638e503b0740e6b9a6350ed0c7275be
|
||||
Subproject commit ee8915c10907275555947ceb54588ed50227c755
|
|
@ -3,16 +3,17 @@ import useBluelibClassNames from "../../hooks/useBluelibClassNames"
|
|||
import classNames from "classnames"
|
||||
|
||||
|
||||
export default function Button({children, className, disabled, ...props}) {
|
||||
export default function Button({children, className, disabled, onClick, ...props}) {
|
||||
return (
|
||||
<button
|
||||
className={useBluelibClassNames(
|
||||
classNames(
|
||||
className={
|
||||
useBluelibClassNames(
|
||||
"button",
|
||||
disabled ? "status-disabled" : "status-clickable"
|
||||
),
|
||||
className
|
||||
)}
|
||||
disabled ? "status-disabled" : "status-clickable",
|
||||
className,
|
||||
)
|
||||
}
|
||||
onClick={disabled ? null : onClick}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
|
|
27
src/components/Form/Readme.md
Normal file
27
src/components/Form/Readme.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
A form where the user can input things.
|
||||
|
||||
```jsx
|
||||
import Bluelib from "../Bluelib";
|
||||
import Color from "../Color";
|
||||
import FormElement from "../FormElement";
|
||||
import FormSubmit from "../FormSubmit";
|
||||
|
||||
|
||||
<Bluelib>
|
||||
<Form>
|
||||
<FormElement label={"Username"} placeholder={"Steffo"} required={true}/>
|
||||
<FormElement label={"Email"} type={"email"} placeholder={"me@steffo.eu"}/>
|
||||
<FormElement label={"Password"} type={"password"} placeholder={"hunter2"} required={true}/>
|
||||
<FormElement label={"Phone"} type={"tel"} placeholder={"+39 123 456 7890"}/>
|
||||
<FormElement label={"Antani"} placeholder={"eh?"} disabled/>
|
||||
<Form.Buttons>
|
||||
<Color builtin={"red"}>
|
||||
<FormSubmit>Cancel</FormSubmit>
|
||||
</Color>
|
||||
<Color builtin={"lime"}>
|
||||
<FormSubmit>Submit</FormSubmit>
|
||||
</Color>
|
||||
</Form.Buttons>
|
||||
</Form>
|
||||
</Bluelib>
|
||||
```
|
33
src/components/Form/index.js
Normal file
33
src/components/Form/index.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import React from "react"
|
||||
import useBluelibClassNames from "../../hooks/useBluelibClassNames"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
|
||||
export default function Form({children, className, ...props}) {
|
||||
return (
|
||||
<form className={useBluelibClassNames("form", className)} {...props}>
|
||||
{children}
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Form.Buttons = function FormButtons({children, className, ...props}) {
|
||||
return (
|
||||
<div className={useBluelibClassNames("form-buttons", className)} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Form.propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
}
|
||||
|
||||
|
||||
Form.Buttons.propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
}
|
15
src/components/FormElement/FormField/Readme.md
Normal file
15
src/components/FormElement/FormField/Readme.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
The input of a [FormElement](#formelement).
|
||||
|
||||
```jsx
|
||||
import Bluelib from "../../Bluelib";
|
||||
import Form from "../../Form";
|
||||
|
||||
|
||||
<Bluelib>
|
||||
<Form>
|
||||
<FormField placeholder={"Optional input"}/>
|
||||
<FormField placeholder={"Required input"} required/>
|
||||
<FormField placeholder={"Disabled input"} disabled/>
|
||||
</Form>
|
||||
</Bluelib>
|
||||
```
|
23
src/components/FormElement/FormField/index.js
Normal file
23
src/components/FormElement/FormField/index.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import React from "react"
|
||||
import useBluelibClassNames from "../../../hooks/useBluelibClassNames"
|
||||
import InputField from "../../InputField"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
|
||||
export default function FormField({children, className, disabled, ...props}) {
|
||||
return (
|
||||
<InputField
|
||||
disabled={disabled}
|
||||
className={useBluelibClassNames("form-field", className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</InputField>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
FormField.propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
}
|
14
src/components/FormElement/FormLabel/Readme.md
Normal file
14
src/components/FormElement/FormLabel/Readme.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
The label of a [FormElement](#formelement).
|
||||
|
||||
```jsx
|
||||
import Bluelib from "../../Bluelib";
|
||||
import Form from "../../Form";
|
||||
|
||||
<Bluelib>
|
||||
<Form>
|
||||
<FormLabel>
|
||||
Label
|
||||
</FormLabel>
|
||||
</Form>
|
||||
</Bluelib>
|
||||
```
|
18
src/components/FormElement/FormLabel/index.js
Normal file
18
src/components/FormElement/FormLabel/index.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import React from "react"
|
||||
import useBluelibClassNames from "../../../hooks/useBluelibClassNames"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
|
||||
export default function FormLabel({children, className, ...props}) {
|
||||
return (
|
||||
<label className={useBluelibClassNames("form-label", className)} {...props}>
|
||||
{children}
|
||||
</label>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
FormLabel.propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
}
|
19
src/components/FormElement/Readme.md
Normal file
19
src/components/FormElement/Readme.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
An element of a [Form](#form), containing both a [FormLabel](#formlabel) and a [FormInput](#forminput).
|
||||
|
||||
Automatically handles the pairing of [FormLabel](#formlabel) and [FormInput](#forminput) via UUIDv1.
|
||||
|
||||
```jsx
|
||||
import Bluelib from "../Bluelib";
|
||||
import Form from "../Form";
|
||||
|
||||
|
||||
<Bluelib>
|
||||
<Form>
|
||||
<FormElement label={"Username"} placeholder={"Steffo"} required/>
|
||||
<FormElement label={"Email"} type={"email"} placeholder={"me@steffo.eu"}/>
|
||||
<FormElement label={"Password"} type={"password"} placeholder={"hunter2"} required/>
|
||||
<FormElement label={"Phone"} type={"tel"} placeholder={"+39 123 456 7890"}/>
|
||||
<FormElement label={"Antani"} placeholder={"eh?"} disabled/>
|
||||
</Form>
|
||||
</Bluelib>
|
||||
```
|
35
src/components/FormElement/index.js
Normal file
35
src/components/FormElement/index.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
import React, { useMemo } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import UUID from "uuid";
|
||||
import FormLabel from "./FormLabel"
|
||||
import FormField from "./FormField"
|
||||
|
||||
|
||||
export default function FormElement({label, labelProps, className, required, ...props}) {
|
||||
let element_id = useMemo(() => UUID.v1(), []);
|
||||
|
||||
if(!required) {
|
||||
label = <i>{label}</i>
|
||||
}
|
||||
|
||||
return <>
|
||||
<FormLabel
|
||||
htmlFor={element_id}
|
||||
{...labelProps}
|
||||
>
|
||||
{label}
|
||||
</FormLabel>
|
||||
<FormField
|
||||
id={element_id}
|
||||
{...props}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
FormElement.propTypes = {
|
||||
label: PropTypes.string,
|
||||
labelProps: PropTypes.object,
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
}
|
17
src/components/FormSubmit/Readme.md
Normal file
17
src/components/FormSubmit/Readme.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
A button for a [Form](#form).
|
||||
|
||||
For best results, insert it inside a [FormButtons](#formbuttons) container.
|
||||
|
||||
```jsx
|
||||
import Bluelib from "../Bluelib";
|
||||
import Form from "../Form";
|
||||
|
||||
|
||||
<Bluelib>
|
||||
<Form>
|
||||
<Form.Buttons>
|
||||
<FormSubmit>Submit</FormSubmit>
|
||||
</Form.Buttons>
|
||||
</Form>
|
||||
</Bluelib>
|
||||
```
|
19
src/components/FormSubmit/index.js
Normal file
19
src/components/FormSubmit/index.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import React from "react"
|
||||
import useBluelibClassNames from "../../hooks/useBluelibClassNames"
|
||||
import PropTypes from "prop-types"
|
||||
import Button from "../Button"
|
||||
|
||||
|
||||
export default function FormSubmit({children, className, ...props}) {
|
||||
return (
|
||||
<Button className={useBluelibClassNames("form-submit", className)} {...props}>
|
||||
{children}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
FormSubmit.propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
}
|
9
src/components/InputField/Readme.md
Normal file
9
src/components/InputField/Readme.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
Makes the text bold (like a `<b>` element), while applying bold styles from the selected bluelib skin.
|
||||
|
||||
```jsx
|
||||
import Bluelib from "../Bluelib";
|
||||
|
||||
<Bluelib>
|
||||
To <Bold>boldly</Bold> go where no library has gone before!
|
||||
</Bluelib>
|
||||
```
|
42
src/components/InputField/index.js
Normal file
42
src/components/InputField/index.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import React from "react"
|
||||
import useBluelibClassNames from "../../hooks/useBluelibClassNames"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
|
||||
export default function InputField(
|
||||
{
|
||||
children,
|
||||
className,
|
||||
type = "text",
|
||||
disabled = false,
|
||||
onChange,
|
||||
...props
|
||||
}) {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
className={
|
||||
useBluelibClassNames(
|
||||
[
|
||||
"input-field",
|
||||
disabled ? "status-disabled" : null,
|
||||
],
|
||||
className,
|
||||
)
|
||||
}
|
||||
disabled={disabled}
|
||||
onChange={disabled ? null : onChange}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</input>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
InputField.propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
}
|
|
@ -25,3 +25,6 @@ export {default as VisualErrorBoundary} from "./VisualErrorBoundary"
|
|||
export {default as VisualLog} from "./VisualLog"
|
||||
export {default as Button} from "./Button"
|
||||
export {default as ButtonToggle} from "./ButtonToggle"
|
||||
export {default as Form} from "./Form"
|
||||
export {default as FormElement} from "./FormElement"
|
||||
export {default as FormSubmit} from "./FormSubmit"
|
||||
|
|
|
@ -18,13 +18,13 @@ export default function useBluelibClassNames(cn, extra) {
|
|||
}
|
||||
|
||||
if(!bluelibSkin) {
|
||||
console.warn("bluelibSkin is invalid: ", bluelibSkin)
|
||||
console.warn("Trying to access .", cn, " of bluelibSkin ", bluelibSkin)
|
||||
return null
|
||||
}
|
||||
|
||||
return classNames(bluelibSkin[c])
|
||||
return bluelibSkin[c]
|
||||
});
|
||||
|
||||
// Return all the class names
|
||||
return classNames(...cn, extra);
|
||||
return classNames(cn, extra);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue