Add stepper component to bbui for numeric values
This commit is contained in:
parent
7c2b5b6f04
commit
5d1374bfa2
|
@ -65,6 +65,7 @@
|
|||
"@spectrum-css/search": "^3.0.2",
|
||||
"@spectrum-css/sidenav": "^3.0.2",
|
||||
"@spectrum-css/statuslight": "^3.0.2",
|
||||
"@spectrum-css/stepper": "^3.0.3",
|
||||
"@spectrum-css/switch": "^1.0.2",
|
||||
"@spectrum-css/table": "^3.0.1",
|
||||
"@spectrum-css/tabs": "^3.0.1",
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
<script>
|
||||
import "@spectrum-css/textfield/dist/index-vars.css"
|
||||
import "@spectrum-css/actionbutton/dist/index-vars.css"
|
||||
import "@spectrum-css/stepper/dist/index-vars.css"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
|
||||
export let value = null
|
||||
export let placeholder = null
|
||||
export let disabled = false
|
||||
export let error = null
|
||||
export let id = null
|
||||
export let readonly = false
|
||||
export let updateOnChange = true
|
||||
export let quiet = false
|
||||
export let min
|
||||
export let max
|
||||
export let step
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let focus = false
|
||||
|
||||
// We need to keep the field value bound to a different variable in order
|
||||
// to properly handle erroneous values. If we don't do this then it is
|
||||
// possible for the field to show stale text which does not represent the
|
||||
// real value. The reactive statement is to ensure that external changes to
|
||||
// the value prop are reflected.
|
||||
let fieldValue = value
|
||||
$: fieldValue = value
|
||||
|
||||
// Ensure step is always a numeric value defaulting to 1
|
||||
$: step = step == null || isNaN(step) ? 1 : step
|
||||
|
||||
const updateValue = value => {
|
||||
if (readonly) {
|
||||
return
|
||||
}
|
||||
const float = parseFloat(value)
|
||||
value = isNaN(float) ? null : float
|
||||
if (value != null) {
|
||||
if (min != null && value < min) {
|
||||
value = min
|
||||
} else if (max != null && value > max) {
|
||||
value = max
|
||||
}
|
||||
}
|
||||
dispatch("change", value)
|
||||
fieldValue = value
|
||||
}
|
||||
|
||||
const onFocus = () => {
|
||||
if (readonly) {
|
||||
return
|
||||
}
|
||||
focus = true
|
||||
}
|
||||
|
||||
const onBlur = event => {
|
||||
if (readonly) {
|
||||
return
|
||||
}
|
||||
focus = false
|
||||
updateValue(event.target.value)
|
||||
}
|
||||
|
||||
const onInput = event => {
|
||||
if (readonly || !updateOnChange) {
|
||||
return
|
||||
}
|
||||
updateValue(event.target.value)
|
||||
}
|
||||
|
||||
const updateValueOnEnter = event => {
|
||||
if (readonly) {
|
||||
return
|
||||
}
|
||||
if (event.key === "Enter") {
|
||||
updateValue(event.target.value)
|
||||
}
|
||||
}
|
||||
|
||||
const stepUp = () => {
|
||||
if (value == null || isNaN(value)) {
|
||||
updateValue(step)
|
||||
} else {
|
||||
updateValue(value + step)
|
||||
}
|
||||
}
|
||||
|
||||
const stepDown = () => {
|
||||
if (value == null || isNaN(value)) {
|
||||
updateValue(step)
|
||||
} else {
|
||||
updateValue(value - step)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="spectrum-Stepper"
|
||||
class:spectrum-Stepper--quiet={quiet}
|
||||
class:is-invalid={!!error}
|
||||
class:is-disabled={disabled}
|
||||
class:is-focused={focus}
|
||||
>
|
||||
{#if error}
|
||||
<svg
|
||||
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
|
||||
focusable="false"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<use xlink:href="#spectrum-icon-18-Alert" />
|
||||
</svg>
|
||||
{/if}
|
||||
|
||||
<div class="spectrum-Textfield spectrum-Stepper-textfield">
|
||||
<input
|
||||
{disabled}
|
||||
{readonly}
|
||||
{id}
|
||||
bind:value={fieldValue}
|
||||
placeholder={placeholder || ""}
|
||||
type="number"
|
||||
class="spectrum-Textfield-input spectrum-Stepper-input"
|
||||
on:click
|
||||
on:blur
|
||||
on:focus
|
||||
on:input
|
||||
on:keyup
|
||||
on:blur={onBlur}
|
||||
on:focus={onFocus}
|
||||
on:input={onInput}
|
||||
on:keyup={updateValueOnEnter}
|
||||
/>
|
||||
</div>
|
||||
<span class="spectrum-Stepper-buttons">
|
||||
<button
|
||||
class="spectrum-ActionButton spectrum-ActionButton--sizeM spectrum-Stepper-stepUp"
|
||||
tabindex="-1"
|
||||
on:click={stepUp}
|
||||
>
|
||||
<svg
|
||||
class="spectrum-Icon spectrum-UIIcon-ChevronUp75"
|
||||
focusable="false"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<use xlink:href="#spectrum-css-icon-Chevron75" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
class="spectrum-ActionButton spectrum-ActionButton--sizeM spectrum-Stepper-stepDown"
|
||||
tabindex="-1"
|
||||
on:click={stepDown}
|
||||
>
|
||||
<svg
|
||||
class="spectrum-Icon spectrum-UIIcon-ChevronDown75"
|
||||
focusable="false"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<use xlink:href="#spectrum-css-icon-Chevron75" />
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.spectrum-Stepper {
|
||||
width: 100%;
|
||||
}
|
||||
.spectrum-Stepper::before {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
|
@ -9,3 +9,4 @@ export { default as CoreSwitch } from "./Switch.svelte"
|
|||
export { default as CoreSearch } from "./Search.svelte"
|
||||
export { default as CoreDatePicker } from "./DatePicker.svelte"
|
||||
export { default as CoreDropzone } from "./Dropzone.svelte"
|
||||
export { default as CoreStepper } from "./Stepper.svelte"
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<script>
|
||||
import Field from "./Field.svelte"
|
||||
import Stepper from "./Core/Stepper.svelte"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
|
||||
export let value = null
|
||||
export let label = null
|
||||
export let labelPosition = "above"
|
||||
export let placeholder = null
|
||||
export let disabled = false
|
||||
export let readonly = false
|
||||
export let error = null
|
||||
export let updateOnChange = true
|
||||
export let quiet = false
|
||||
export let min = null
|
||||
export let max = null
|
||||
export let step = 1
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const onChange = e => {
|
||||
value = e.detail
|
||||
dispatch("change", e.detail)
|
||||
}
|
||||
</script>
|
||||
|
||||
<Field {label} {labelPosition} {error}>
|
||||
<Stepper
|
||||
{updateOnChange}
|
||||
{error}
|
||||
{disabled}
|
||||
{readonly}
|
||||
{value}
|
||||
{placeholder}
|
||||
{quiet}
|
||||
{min}
|
||||
{max}
|
||||
{step}
|
||||
on:change={onChange}
|
||||
on:click
|
||||
on:input
|
||||
on:blur
|
||||
on:focus
|
||||
on:keyup
|
||||
/>
|
||||
</Field>
|
|
@ -5,6 +5,7 @@ import "@spectrum-css/icon/dist/index-vars.css"
|
|||
|
||||
// Components
|
||||
export { default as Input } from "./Form/Input.svelte"
|
||||
export { default as Stepper } from "./Form/Stepper.svelte"
|
||||
export { default as TextArea } from "./Form/TextArea.svelte"
|
||||
export { default as Select } from "./Form/Select.svelte"
|
||||
export { default as Combobox } from "./Form/Combobox.svelte"
|
||||
|
|
|
@ -206,6 +206,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@spectrum-css/statuslight/-/statuslight-3.0.2.tgz#dc54b6cd113413dcdb909c486b5d7bae60db65c5"
|
||||
integrity sha512-xodB8g8vGJH20XmUj9ZsPlM1jHrGeRbvmVXkz0q7YvQrYAhim8pP3W+XKKZAletPFAuu8cmUOc6SWn6i4X4z6w==
|
||||
|
||||
"@spectrum-css/stepper@^3.0.3":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/stepper/-/stepper-3.0.3.tgz#ae89846886431e3edeee060207b8f81540f73a34"
|
||||
integrity sha512-prAD61ImlOTs9b6PfB3cB08x4lAfxtvnW+RZiTYky0E8GgZdrc/MfCkL5/oqQaIQUtyQv/3Lb7ELAf/0K8QTXw==
|
||||
|
||||
"@spectrum-css/switch@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@spectrum-css/switch/-/switch-1.0.2.tgz#f0b4c69271964573e02b08e90998096e49e1de44"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Checkbox, Input, Select } from "@budibase/bbui"
|
||||
import { Checkbox, Input, Select, Stepper } from "@budibase/bbui"
|
||||
import DataSourceSelect from "./DataSourceSelect.svelte"
|
||||
import DataProviderSelect from "./DataProviderSelect.svelte"
|
||||
import EventsEditor from "./EventsEditor"
|
||||
|
@ -22,7 +22,7 @@ const componentMap = {
|
|||
dataSource: DataSourceSelect,
|
||||
dataProvider: DataProviderSelect,
|
||||
boolean: Checkbox,
|
||||
number: Input,
|
||||
number: Stepper,
|
||||
event: EventsEditor,
|
||||
table: TableSelect,
|
||||
color: ColorPicker,
|
||||
|
|
|
@ -1725,6 +1725,12 @@
|
|||
"label": "Custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Number of steps",
|
||||
"key": "steps",
|
||||
"defaultValue": 1
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"label": "Disabled",
|
||||
|
|
Loading…
Reference in New Issue