diff --git a/src/components/inputs/Area.stories.jsx b/src/components/inputs/Area.stories.jsx
new file mode 100644
index 0000000..2f0e2da
--- /dev/null
+++ b/src/components/inputs/Area.stories.jsx
@@ -0,0 +1,26 @@
+import * as React from "react"
+import * as ReactDOM from "react-dom"
+import * as Decorators from "../../utils/Decorators"
+import { Area } from "./Area"
+
+
+export default {
+ component: Area,
+ title: "Inputs/Area",
+ decorators: [Decorators.Bluelib],
+ argTypes: {
+ customColor: {
+ control: {type: "color"},
+ },
+ },
+}
+
+
+export const Default = props => (
+
+)
+Default.args = {
+ placeholder: "Enter multiline text here\n\nThis component can be resized",
+ disabled: false,
+ required: false,
+}
diff --git a/src/components/inputs/Area.tsx b/src/components/inputs/Area.tsx
new file mode 100644
index 0000000..c04ce33
--- /dev/null
+++ b/src/components/inputs/Area.tsx
@@ -0,0 +1,41 @@
+import * as React from "react"
+import * as ReactDOM from "react-dom"
+import * as Types from "../../types"
+import {BaseElement} from "../BaseElement"
+import mergeClassNames from "classnames"
+
+
+interface AreaProps {
+ placeholder: string,
+ required?: boolean,
+ disabled?: boolean,
+
+ onChange: (contents: string) => boolean,
+ value?: string,
+
+ [props: string]: any,
+}
+
+
+export function Area({onChange, ...props}: AreaProps): JSX.Element {
+ props.bluelibClassNames = mergeClassNames(props.bluelibClassNames, "input", "input-area")
+
+ const onChangeWrapper = React.useCallback(
+
+ (event: React.ChangeEvent): boolean => {
+ const contents = event.target.value
+
+ if(onChange) {
+ return onChange(contents)
+ }
+
+ return false
+ },
+
+ [onChange]
+ )
+
+ return (
+
+ )
+}
diff --git a/src/components/inputs/Field.stories.jsx b/src/components/inputs/Field.stories.jsx
index 693a1e0..94ba8a8 100644
--- a/src/components/inputs/Field.stories.jsx
+++ b/src/components/inputs/Field.stories.jsx
@@ -12,9 +12,6 @@ export default {
customColor: {
control: {type: "color"},
},
- disabled: {
- control: {type: "boolean"},
- },
},
}
diff --git a/src/components/inputs/Field.tsx b/src/components/inputs/Field.tsx
index cf44796..c27b452 100644
--- a/src/components/inputs/Field.tsx
+++ b/src/components/inputs/Field.tsx
@@ -10,28 +10,32 @@ interface FieldProps {
required?: boolean,
disabled?: boolean,
- onChange?: (event: React.FormEvent) => boolean,
- onInput?: (event: React.FormEvent) => boolean,
- onInvalid?: (event: React.FormEvent) => boolean,
- onReset?: (event: React.FormEvent) => boolean,
- onSubmit?: (event: React.FormEvent) => boolean,
+ onChange: (contents: string) => boolean,
+ value?: string,
[props: string]: any,
}
-export function Field({onChange, onInput, onInvalid, ...props}: FieldProps): JSX.Element {
-
+export function Field({onChange, value, ...props}: FieldProps): JSX.Element {
props.bluelibClassNames = mergeClassNames(props.bluelibClassNames, "input", "input-field")
- // Propagate change events only if the element is enabled
- if(!props.disabled) {
- props.onChange = onChange
- props.onInput = onInput
- props.onInvalid = onInvalid
- }
+ const onChangeWrapper = React.useCallback(
+
+ (event: React.ChangeEvent): boolean => {
+ const contents = event.target.value
+
+ if(onChange) {
+ return onChange(contents)
+ }
+
+ return false
+ },
+
+ [onChange]
+ )
return (
-
+
)
}
diff --git a/src/components/inputs/Multiselect.stories.jsx b/src/components/inputs/Multiselect.stories.jsx
new file mode 100644
index 0000000..78b60cd
--- /dev/null
+++ b/src/components/inputs/Multiselect.stories.jsx
@@ -0,0 +1,49 @@
+import * as React from "react"
+import * as ReactDOM from "react-dom"
+import * as Decorators from "../../utils/Decorators"
+import { Option } from "./Option"
+import { OptionGroup } from "./OptionGroup"
+import { Multiselect } from "./Multiselect"
+
+
+export default {
+ component: Multiselect,
+ title: "Inputs/Multiselect",
+ decorators: [Decorators.Bluelib],
+ argTypes: {
+ customColor: {
+ control: {type: "color"},
+ },
+ },
+}
+
+
+export const Default = props => (
+
+
+)
+Default.args = {
+ disabled: false,
+}
+
+
+export const WithGroups = props => (
+
+
+
+
+
+
+)
+WithGroups.args = {
+ disabled: false,
+}
\ No newline at end of file
diff --git a/src/components/inputs/Multiselect.tsx b/src/components/inputs/Multiselect.tsx
new file mode 100644
index 0000000..a820d8f
--- /dev/null
+++ b/src/components/inputs/Multiselect.tsx
@@ -0,0 +1,24 @@
+import * as React from "react"
+import * as ReactDOM from "react-dom"
+import * as Types from "../../types"
+import {BaseElement} from "../BaseElement"
+import mergeClassNames from "classnames"
+
+
+interface MultiselectProps {
+ disabled?: boolean,
+
+ onChange?: (event: React.FormEvent) => boolean,
+
+ [props: string]: any,
+}
+
+
+export function Multiselect({...props}: MultiselectProps): JSX.Element {
+
+ props.bluelibClassNames = mergeClassNames(props.bluelibClassNames, "input", "input-multiselect")
+
+ return (
+
+ )
+}
diff --git a/src/components/inputs/Option.tsx b/src/components/inputs/Option.tsx
new file mode 100644
index 0000000..413a1cf
--- /dev/null
+++ b/src/components/inputs/Option.tsx
@@ -0,0 +1,23 @@
+import * as React from "react"
+import * as ReactDOM from "react-dom"
+import * as Types from "../../types"
+import {BaseElement} from "../BaseElement"
+import mergeClassNames from "classnames"
+
+
+interface OptionProps {
+ label: string,
+
+ [props: string]: any,
+}
+
+
+export function Option({label, ...props}: OptionProps): JSX.Element {
+ props.bluelibClassNames = mergeClassNames(props.bluelibClassNames, "input-option")
+
+ return (
+
+ {label}
+
+ )
+}
diff --git a/src/components/inputs/OptionGroup.tsx b/src/components/inputs/OptionGroup.tsx
new file mode 100644
index 0000000..9ec12a4
--- /dev/null
+++ b/src/components/inputs/OptionGroup.tsx
@@ -0,0 +1,22 @@
+import * as React from "react"
+import * as ReactDOM from "react-dom"
+import * as Types from "../../types"
+import {BaseElement} from "../BaseElement"
+import mergeClassNames from "classnames"
+
+
+interface OptionGroupProps {
+ label: string,
+
+ [props: string]: any,
+}
+
+
+export function OptionGroup({...props}: OptionGroupProps): JSX.Element {
+
+ props.bluelibClassNames = mergeClassNames(props.bluelibClassNames, "input-optgroup")
+
+ return (
+
+ )
+}
diff --git a/src/components/inputs/Select.stories.jsx b/src/components/inputs/Select.stories.jsx
new file mode 100644
index 0000000..b9f3298
--- /dev/null
+++ b/src/components/inputs/Select.stories.jsx
@@ -0,0 +1,50 @@
+import * as React from "react"
+import * as ReactDOM from "react-dom"
+import * as Decorators from "../../utils/Decorators"
+import { Select } from "./Select"
+import { Option } from "./Option"
+import { OptionGroup } from "./OptionGroup"
+
+
+export default {
+ component: Select,
+ title: "Inputs/Select",
+ decorators: [Decorators.Bluelib],
+ argTypes: {
+ customColor: {
+ control: {type: "color"},
+ },
+ },
+}
+
+
+export const Default = props => (
+
+)
+Default.args = {
+ disabled: false,
+}
+
+
+export const WithGroups = props => (
+
+)
+WithGroups.args = {
+ disabled: false,
+}
\ No newline at end of file
diff --git a/src/components/inputs/Select.tsx b/src/components/inputs/Select.tsx
new file mode 100644
index 0000000..e6873c0
--- /dev/null
+++ b/src/components/inputs/Select.tsx
@@ -0,0 +1,43 @@
+import * as React from "react"
+import * as ReactDOM from "react-dom"
+import * as Types from "../../types"
+import {BaseElement} from "../BaseElement"
+import mergeClassNames from "classnames"
+
+
+interface SelectProps {
+ disabled?: boolean,
+
+ onChange?: (contents: string) => boolean,
+ value?: string,
+
+ children: React.ReactNode,
+
+ [props: string]: any,
+}
+
+
+export function Select({onChange, children, ...props}: SelectProps): JSX.Element {
+ props.bluelibClassNames = mergeClassNames(props.bluelibClassNames, "input", "input-select")
+
+ const onChangeWrapper = React.useCallback(
+
+ (event: React.ChangeEvent): boolean => {
+ const contents = event.target.value
+
+ if(onChange) {
+ return onChange(contents)
+ }
+
+ return false
+ },
+
+ [onChange]
+ )
+
+ return (
+
+ // TODO
+
+ )
+}