mirror of
https://github.com/Steffo99/bluelib.git
synced 2024-12-22 19:44:21 +00:00
🚧 Continue working on inputs
This commit is contained in:
parent
632048601b
commit
04e014ad8e
10 changed files with 296 additions and 17 deletions
26
src/components/inputs/Area.stories.jsx
Normal file
26
src/components/inputs/Area.stories.jsx
Normal file
|
@ -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 => (
|
||||
<Area {...props}/>
|
||||
)
|
||||
Default.args = {
|
||||
placeholder: "Enter multiline text here\n\nThis component can be resized",
|
||||
disabled: false,
|
||||
required: false,
|
||||
}
|
41
src/components/inputs/Area.tsx
Normal file
41
src/components/inputs/Area.tsx
Normal file
|
@ -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<HTMLInputElement>): boolean => {
|
||||
const contents = event.target.value
|
||||
|
||||
if(onChange) {
|
||||
return onChange(contents)
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
|
||||
[onChange]
|
||||
)
|
||||
|
||||
return (
|
||||
<BaseElement kind={"textarea"} onChange={onChangeWrapper} {...props}/>
|
||||
)
|
||||
}
|
|
@ -12,9 +12,6 @@ export default {
|
|||
customColor: {
|
||||
control: {type: "color"},
|
||||
},
|
||||
disabled: {
|
||||
control: {type: "boolean"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -10,28 +10,32 @@ interface FieldProps {
|
|||
required?: boolean,
|
||||
disabled?: boolean,
|
||||
|
||||
onChange?: (event: React.FormEvent<HTMLInputElement>) => boolean,
|
||||
onInput?: (event: React.FormEvent<HTMLInputElement>) => boolean,
|
||||
onInvalid?: (event: React.FormEvent<HTMLInputElement>) => boolean,
|
||||
onReset?: (event: React.FormEvent<HTMLInputElement>) => boolean,
|
||||
onSubmit?: (event: React.FormEvent<HTMLInputElement>) => 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<HTMLInputElement>): boolean => {
|
||||
const contents = event.target.value
|
||||
|
||||
if(onChange) {
|
||||
return onChange(contents)
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
|
||||
[onChange]
|
||||
)
|
||||
|
||||
return (
|
||||
<BaseElement kind={"input"} {...props}/>
|
||||
<BaseElement kind={"input"} onChange={onChangeWrapper} {...props}/>
|
||||
)
|
||||
}
|
||||
|
|
49
src/components/inputs/Multiselect.stories.jsx
Normal file
49
src/components/inputs/Multiselect.stories.jsx
Normal file
|
@ -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 => (
|
||||
<Multiselect {...props}>
|
||||
<Option label={"Yes"}/>
|
||||
<Option label={"Maybe"}/>
|
||||
<Option label={"No"}/>
|
||||
</Multiselect>
|
||||
)
|
||||
Default.args = {
|
||||
disabled: false,
|
||||
}
|
||||
|
||||
|
||||
export const WithGroups = props => (
|
||||
<Multiselect {...props}>
|
||||
<OptionGroup label={"A"}>
|
||||
<Option label={"Anchor"}/>
|
||||
<Option label={"Angel"}/>
|
||||
<Option label={"Anti-air"}/>
|
||||
</OptionGroup>
|
||||
<OptionGroup label={"B"}>
|
||||
<Option label={"Banana"}/>
|
||||
<Option label={"Boat"}/>
|
||||
<Option label={"Bus"}/>
|
||||
</OptionGroup>
|
||||
</Multiselect>
|
||||
)
|
||||
WithGroups.args = {
|
||||
disabled: false,
|
||||
}
|
24
src/components/inputs/Multiselect.tsx
Normal file
24
src/components/inputs/Multiselect.tsx
Normal file
|
@ -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<HTMLInputElement>) => boolean,
|
||||
|
||||
[props: string]: any,
|
||||
}
|
||||
|
||||
|
||||
export function Multiselect({...props}: MultiselectProps): JSX.Element {
|
||||
|
||||
props.bluelibClassNames = mergeClassNames(props.bluelibClassNames, "input", "input-multiselect")
|
||||
|
||||
return (
|
||||
<BaseElement kind={"select"} multiple={true} {...props}/>
|
||||
)
|
||||
}
|
23
src/components/inputs/Option.tsx
Normal file
23
src/components/inputs/Option.tsx
Normal file
|
@ -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 (
|
||||
<BaseElement kind={"option"} {...props}>
|
||||
{label}
|
||||
</BaseElement>
|
||||
)
|
||||
}
|
22
src/components/inputs/OptionGroup.tsx
Normal file
22
src/components/inputs/OptionGroup.tsx
Normal file
|
@ -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 (
|
||||
<BaseElement kind={"optgroup"} {...props}/>
|
||||
)
|
||||
}
|
50
src/components/inputs/Select.stories.jsx
Normal file
50
src/components/inputs/Select.stories.jsx
Normal file
|
@ -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 => (
|
||||
<Select {...props}>
|
||||
<Option label={"Yes"}/>
|
||||
<Option label={"Maybe"}/>
|
||||
<Option label={"No"}/>
|
||||
</Select>
|
||||
)
|
||||
Default.args = {
|
||||
disabled: false,
|
||||
}
|
||||
|
||||
|
||||
export const WithGroups = props => (
|
||||
<Select {...props}>
|
||||
<Option label={"Ungrouped"}/>
|
||||
<OptionGroup label={"A"}>
|
||||
<Option label={"Anchor"}/>
|
||||
<Option label={"Angel"}/>
|
||||
<Option label={"Anti-air"}/>
|
||||
</OptionGroup>
|
||||
<OptionGroup label={"B"}>
|
||||
<Option label={"Banana"}/>
|
||||
<Option label={"Boat"}/>
|
||||
<Option label={"Bus"}/>
|
||||
</OptionGroup>
|
||||
</Select>
|
||||
)
|
||||
WithGroups.args = {
|
||||
disabled: false,
|
||||
}
|
43
src/components/inputs/Select.tsx
Normal file
43
src/components/inputs/Select.tsx
Normal file
|
@ -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<HTMLInputElement>): boolean => {
|
||||
const contents = event.target.value
|
||||
|
||||
if(onChange) {
|
||||
return onChange(contents)
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
|
||||
[onChange]
|
||||
)
|
||||
|
||||
return (
|
||||
<BaseElement kind={"select"} multiple={false} {...props}>
|
||||
// TODO
|
||||
</BaseElement>
|
||||
)
|
||||
}
|
Loading…
Reference in a new issue