1
Fork 0
mirror of https://github.com/Steffo99/bluelib.git synced 2024-12-22 11:34:21 +00:00

Add forms

This commit is contained in:
Steffo 2021-07-19 23:59:53 +02:00
parent d63828ae78
commit a989c0164e
Signed by: steffo
GPG key ID: 6965406171929D01
18 changed files with 291 additions and 52 deletions

43
package-lock.json generated
View file

@ -21,7 +21,8 @@
"react-router": "^5.2.0", "react-router": "^5.2.0",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-syntax-highlighter": "^15.4.3", "react-syntax-highlighter": "^15.4.3",
"strip-indent": "^3.0.0" "strip-indent": "^3.0.0",
"uuid": "^3.4.0"
}, },
"devDependencies": { "devDependencies": {
"nwb": "0.25.x", "nwb": "0.25.x",
@ -12560,12 +12561,6 @@
"node": ">=4" "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": { "node_modules/react-dom": {
"version": "17.0.1", "version": "17.0.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz",
@ -12758,12 +12753,6 @@
"react-dom": ">=16.8" "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": { "node_modules/react-styleguidist/node_modules/copy-webpack-plugin": {
"version": "6.4.1", "version": "6.4.1",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz",
@ -14949,12 +14938,6 @@
"node": ">=0.10.0" "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": { "node_modules/terser/node_modules/source-map": {
"version": "0.6.1", "version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -15652,7 +15635,6 @@
"version": "3.4.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"dev": true,
"bin": { "bin": {
"uuid": "bin/uuid" "uuid": "bin/uuid"
} }
@ -27650,12 +27632,6 @@
"requires": { "requires": {
"tslib": "^2.0.1" "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" "webpack-merge": "^4.2.2"
}, },
"dependencies": { "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": { "copy-webpack-plugin": {
"version": "6.4.1", "version": "6.4.1",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz", "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" "source-map-support": "~0.5.12"
}, },
"dependencies": { "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": { "source-map": {
"version": "0.6.1", "version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -30336,8 +30300,7 @@
"uuid": { "uuid": {
"version": "3.4.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
"dev": true
}, },
"value-equal": { "value-equal": {
"version": "1.0.1", "version": "1.0.1",

View file

@ -29,7 +29,8 @@
"react-router": "^5.2.0", "react-router": "^5.2.0",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-syntax-highlighter": "^15.4.3", "react-syntax-highlighter": "^15.4.3",
"strip-indent": "^3.0.0" "strip-indent": "^3.0.0",
"uuid": "^3.4.0"
}, },
"peerDependencies": { "peerDependencies": {
"react": "^17.0.2" "react": "^17.0.2"

@ -1 +1 @@
Subproject commit a47f83b53638e503b0740e6b9a6350ed0c7275be Subproject commit ee8915c10907275555947ceb54588ed50227c755

View file

@ -3,16 +3,17 @@ import useBluelibClassNames from "../../hooks/useBluelibClassNames"
import classNames from "classnames" import classNames from "classnames"
export default function Button({children, className, disabled, ...props}) { export default function Button({children, className, disabled, onClick, ...props}) {
return ( return (
<button <button
className={useBluelibClassNames( className={
classNames( useBluelibClassNames(
"button", "button",
disabled ? "status-disabled" : "status-clickable" disabled ? "status-disabled" : "status-clickable",
), className,
className )
)} }
onClick={disabled ? null : onClick}
{...props} {...props}
> >
{children} {children}

View 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>
```

View 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,
}

View 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>
```

View 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,
}

View 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>
```

View 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,
}

View 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>
```

View 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,
}

View 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>
```

View 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,
}

View 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>
```

View 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,
}

View file

@ -25,3 +25,6 @@ export {default as VisualErrorBoundary} from "./VisualErrorBoundary"
export {default as VisualLog} from "./VisualLog" export {default as VisualLog} from "./VisualLog"
export {default as Button} from "./Button" export {default as Button} from "./Button"
export {default as ButtonToggle} from "./ButtonToggle" export {default as ButtonToggle} from "./ButtonToggle"
export {default as Form} from "./Form"
export {default as FormElement} from "./FormElement"
export {default as FormSubmit} from "./FormSubmit"

View file

@ -18,13 +18,13 @@ export default function useBluelibClassNames(cn, extra) {
} }
if(!bluelibSkin) { if(!bluelibSkin) {
console.warn("bluelibSkin is invalid: ", bluelibSkin) console.warn("Trying to access .", cn, " of bluelibSkin ", bluelibSkin)
return null return null
} }
return classNames(bluelibSkin[c]) return bluelibSkin[c]
}); });
// Return all the class names // Return all the class names
return classNames(...cn, extra); return classNames(cn, extra);
} }