impl number input component

This commit is contained in:
Shengjie Yang 2021-08-03 22:56:20 +08:00
parent 3177aea766
commit 56763dfa7f
5 changed files with 217 additions and 8 deletions

View File

@ -55,13 +55,6 @@
slot: "root",
},
},
},
{
type: "core/v1/state",
properties: {
key: "value",
initialValue: "",
},
}
],
}

View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>meta-ui runtime example: number input component</title>
</head>
<body>
<div id="root"></div>
<script type="module">
import renderApp from "../../src/main.tsx";
renderApp({
version: "example/v1",
metadata: {
name: "number_input_component",
description: "number input component example",
},
spec: {
components: [
{
id: "root",
type: "chakra_ui/v1/root",
properties: {},
traits: [],
},
{
id: "number_input",
type: "chakra_ui/v1/number_input",
properties: {
min: 10,
max: 100,
step: 5,
precision: 2,
clampValueOnBlur: false,
allowMouseWheel: true,
size: 'sm',
customerIncrement: {
bg: "green.200",
_active: { bg: "green.300" },
children: "+"
},
customerDecrement: {
bg: "pink.200",
_active: { bg: "pink.300" },
children: "-"
}
},
traits: [
{
type: "core/v1/slot",
properties: {
container: {
id: "root",
slot: "root",
},
},
}
],
}
],
},
});
</script>
</body>
</html>

View File

@ -62,7 +62,7 @@ const Input: ComponentImplementation<{
right,
mergeState
}) => {
const [value, setValue] = React.useState(""); // TODO: number input and pin input
const [value, setValue] = React.useState(""); // TODO: pin input
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => setValue(event.target.value);
useEffect(() => {

View File

@ -0,0 +1,148 @@
import React, { useState, useEffect } from "react";
import {
NumberInput as BaseNumberInput,
NumberInputField,
NumberInputStepper,
NumberIncrementStepper,
NumberDecrementStepper,
} from "@chakra-ui/react";
import { createComponent } from "@meta-ui/core";
import { Static, Type } from "@sinclair/typebox";
import { ComponentImplementation } from "../../registry";
const DefaultValuePropertySchema = Type.Optional(Type.Number());
const MinPropertySchema = Type.Optional(Type.Number());
const MaxPropertySchema = Type.Optional(Type.Number());
const StepPropertySchema = Type.Optional(Type.Number());
const PrecisionPropertySchema = Type.Optional(Type.Number());
const ClampValueOnBlurPropertySchema = Type.Optional(Type.Boolean());
const AllowMouseWheelPropertySchema = Type.Optional(Type.Boolean());
const SizePropertySchema = Type.KeyOf(
Type.Object({
sm: Type.String(),
md: Type.String(),
lg: Type.String(),
xs: Type.String()
})
);
const CustomerStepStylePropertySchema = Type.Object({
bg: Type.Optional(Type.String()),
children: Type.Optional(Type.String()),
_active: Type.Object(Type.Object({ bg: Type.String() })),
})
const NumberInput: ComponentImplementation<{
defaultValue?: Static<typeof DefaultValuePropertySchema>
min?: Static<typeof MinPropertySchema>
max?: Static<typeof MaxPropertySchema>
step?: Static<typeof StepPropertySchema>
precision?: Static<typeof PrecisionPropertySchema>
clampValueOnBlur?: Static<typeof ClampValueOnBlurPropertySchema>
allowMouseWheel?: Static<typeof AllowMouseWheelPropertySchema>
size?: Static<typeof SizePropertySchema>
customerIncrement?: Static<typeof CustomerStepStylePropertySchema>
customerDecrement?: Static<typeof CustomerStepStylePropertySchema>
}> = ({
defaultValue = 0,
min,
max,
step,
precision,
clampValueOnBlur = true,
allowMouseWheel = false,
size,
customerIncrement,
customerDecrement,
mergeState
}) => {
const [value, setValue] = useState(defaultValue)
const onChange = (valueAsString: string, valueAsNumber: number) => setValue(valueAsNumber);
useEffect(() => {
mergeState({ value });
}, [value]);
return (
<BaseNumberInput
defaultValue={defaultValue}
min={min}
max={max}
step={step}
precision={precision}
clampValueOnBlur={clampValueOnBlur}
allowMouseWheel={allowMouseWheel}
size={size}
onChange={onChange}
>
<NumberInputField />
<NumberInputStepper>
<NumberIncrementStepper {...customerIncrement} />
<NumberDecrementStepper {...customerDecrement} />
</NumberInputStepper>
</BaseNumberInput>
);
}
const StateSchema = Type.Object({
value: Type.Number(),
});
export default {
...createComponent({
version: "chakra_ui/v1",
metadata: {
name: "number_input",
description: "chakra_ui number input",
},
spec: {
properties: [
{
name: 'defaultValue',
...DefaultValuePropertySchema
},
{
name: 'min',
...MinPropertySchema
},
{
name: 'max',
...MaxPropertySchema
},
{
name: 'step',
...StepPropertySchema
},
{
name: 'precision',
...PrecisionPropertySchema
},
{
name: 'clampValueOnBlur',
...ClampValueOnBlurPropertySchema
},
{
name: 'allowMouseWheel',
...AllowMouseWheelPropertySchema
},
{
name: 'size',
...SizePropertySchema
},
{
name: 'customerIncrement',
...CustomerStepStylePropertySchema
},
{
name: 'customerDecrement',
...CustomerStepStylePropertySchema
},
],
acceptTraits: [],
state: StateSchema,
methods: [],
}
}),
impl: NumberInput,
}

View File

@ -15,6 +15,7 @@ import ChakraUITable from "./components/chakra-ui/Table";
import ChakraUIInput from "./components/chakra-ui/Input";
import ChakraUIBox from "./components/chakra-ui/Box";
import ChakraUIKbd from "./components/chakra-ui/Kbd";
import ChakraUINumberInput from "./components/chakra-ui/NumberInput";
// traits
import CoreState from "./traits/core/state";
import CoreEvent from "./traits/core/event";
@ -112,6 +113,7 @@ registry.registerComponent(ChakraUITable);
registry.registerComponent(ChakraUIInput);
registry.registerComponent(ChakraUIBox);
registry.registerComponent(ChakraUIKbd);
registry.registerComponent(ChakraUINumberInput);
registry.registerTrait(CoreState);
registry.registerTrait(CoreEvent);