Merge pull request #67 from webzard-io/cep/radio

feat: impl radio and radioGroup
This commit is contained in:
tanbowensg 2021-09-17 10:11:49 +08:00 committed by GitHub
commit 7894db3215
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 401 additions and 57 deletions

View File

@ -0,0 +1,140 @@
<!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: radio component</title>
</head>
<body>
<div id="root"></div>
<script type="module">
import renderApp from '../../src/main.tsx';
renderApp({
version: 'example/v1',
metadata: {
name: 'radio',
description: 'radio',
},
spec: {
components: [
{
id: 'root',
type: 'chakra_ui/v1/root',
properties: {},
traits: [],
},
{
id: 'radio_group',
type: 'chakra_ui/v1/radio_group',
properties: {
defaultValue: 1,
isNumerical: true,
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'root',
slot: 'root',
},
},
},
],
},
{
id: 'stack',
type: 'chakra_ui/v1/stack',
properties: {
direction: 'row',
spacing: 8,
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'radio_group',
slot: 'content',
},
},
},
],
},
{
id: 'radio_1',
type: 'chakra_ui/v1/radio',
properties: {
text: {
raw: 'Radio1',
format: 'plain',
},
value: 1,
size: 'sm',
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'stack',
slot: 'content',
},
},
},
],
},
{
id: 'radio_2',
type: 'chakra_ui/v1/radio',
properties: {
text: {
raw: 'Radio2',
format: 'plain',
},
value: 2,
size: 'md',
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'stack',
slot: 'content',
},
},
},
],
},
{
id: 'radio_3',
type: 'chakra_ui/v1/radio',
properties: {
text: {
raw: 'Radio3',
format: 'plain',
},
value: 3,
size: 'lg',
isDisabled: true
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'stack',
slot: 'content',
},
},
},
],
},
],
},
});
</script>
</body>
</html>

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>meta-ui runtime example: checkbox component</title>
<title>meta-ui runtime example: select component</title>
</head>
<body>
<div id="root"></div>

View File

@ -1,13 +1,23 @@
import React, { useState, useEffect } from 'react';
import { createComponent } from '@meta-ui/core';
import { Static, Type } from '@sinclair/typebox';
import { Checkbox as BaseCheckbox } from '@chakra-ui/react';
import {
Checkbox as BaseCheckbox,
useCheckboxGroupContext,
} from '@chakra-ui/react';
import { ComponentImplementation } from '../../registry';
import Text, { TextProps, TextPropertySchema } from '../_internal/Text';
import { ColorSchemePropertySchema } from './Types/ColorScheme';
import _ from 'lodash';
const ValueSchema = Type.Union([Type.String(), Type.Number()]);
const DefaultIsCheckedSchema = Type.Optional(Type.Boolean());
export const IsDisabledSchema = Type.Optional(Type.Boolean());
const IsFocusableSchema = Type.Optional(Type.Boolean());
const IsInvalidSchema = Type.Optional(Type.Boolean());
const IsReadOnlySchema = Type.Optional(Type.Boolean());
const IsRequiredSchema = Type.Optional(Type.Boolean());
const SpacingSchema = Type.Optional(Type.String());
export const SizePropertySchema = Type.KeyOf(
Type.Object({
sm: Type.String(),
@ -15,53 +25,56 @@ export const SizePropertySchema = Type.KeyOf(
lg: Type.String(),
})
);
const IsFocusableSchema = Type.Optional(Type.Boolean());
const IsInvalidSchema = Type.Optional(Type.Boolean());
const IsReadOnlySchema = Type.Optional(Type.Boolean());
const IsRequiredSchema = Type.Optional(Type.Boolean());
const SpacingSchema = Type.Optional(Type.String());
const IsCheckedSchema = Type.Optional(Type.Boolean());
const IsIndeterminateSchema = Type.Optional(Type.Boolean());
const ValueSchema = Type.Optional(Type.Union([Type.String(), Type.Number()]));
const StateSchema = Type.Object({
value: Type.String(),
});
const Checkbox: ComponentImplementation<{
text: TextProps['value'];
value: Static<typeof ValueSchema>;
defaultIsChecked?: Static<typeof DefaultIsCheckedSchema>;
isDisabled?: Static<typeof IsDisabledSchema>;
isFocusable?: Static<typeof IsFocusableSchema>;
isInValid?: Static<typeof IsInvalidSchema>;
isReadOnly?: Static<typeof IsReadOnlySchema>;
isRequired?: Static<typeof IsRequiredSchema>;
colorScheme?: Static<typeof ColorSchemePropertySchema>;
size?: Static<typeof SizePropertySchema>;
isInValid?: Static<typeof IsInvalidSchema>;
spacing?: Static<typeof SpacingSchema>;
isChecked?: Static<typeof IsCheckedSchema>;
isIndeterminate?: Static<typeof IsIndeterminateSchema>;
value?: Static<typeof ValueSchema>;
colorScheme?: Static<typeof ColorSchemePropertySchema>;
}> = ({
text,
value,
defaultIsChecked,
isDisabled,
isFocusable,
isInValid,
isReadOnly,
isRequired,
colorScheme,
size,
isInValid,
spacing,
isChecked,
isIndeterminate,
value,
colorScheme,
mergeState,
}) => {
const [checked, setChecked] = useState(defaultIsChecked);
const groupContext = useCheckboxGroupContext();
let _defaultIsChecked = false;
if (typeof defaultIsChecked === 'boolean') {
_defaultIsChecked = defaultIsChecked;
} else if (groupContext) {
_defaultIsChecked = groupContext.value.some(val => val === value);
}
const [checked, setChecked] = useState(_defaultIsChecked);
useEffect(() => {
mergeState({ value: text.raw });
mergeState({ text: text.raw });
}, [text.raw]);
useEffect(() => {
mergeState({ value: checked });
mergeState({ value });
}, [value]);
useEffect(() => {
mergeState({ checked });
}, [checked]);
const args: {
@ -73,17 +86,16 @@ const Checkbox: ComponentImplementation<{
return (
<BaseCheckbox
{...args}
value={value}
defaultChecked={defaultIsChecked}
isDisabled={isDisabled}
isFocusable={isFocusable}
isInvalid={isInValid}
isReadOnly={isReadOnly}
isRequired={isRequired}
isInvalid={isInValid}
size={size}
spacing={spacing}
isChecked={isChecked}
isIndeterminate={isIndeterminate}
value={value}
colorScheme={colorScheme}
onChange={e => {
setChecked(e.target.checked);
}}>
@ -105,6 +117,10 @@ export default {
name: 'text',
...TextPropertySchema,
},
{
name: 'value',
...ValueSchema,
},
{
name: 'defaultIsChecked',
...DefaultIsCheckedSchema,
@ -117,6 +133,10 @@ export default {
name: 'isFocusable',
...IsFocusableSchema,
},
{
name: 'isInValid',
...IsInvalidSchema,
},
{
name: 'isReadOnly',
...IsReadOnlySchema,
@ -125,37 +145,21 @@ export default {
name: 'isRequired',
...IsReadOnlySchema,
},
{
name: 'colorScheme',
...ColorSchemePropertySchema,
},
{
name: 'size',
...SizePropertySchema,
},
{
name: 'isInValid',
...IsInvalidSchema,
},
{
name: 'spacing',
...SpacingSchema,
},
{
name: 'isChecked',
...IsCheckedSchema,
},
{
name: 'isIndeterminate',
...IsIndeterminateSchema,
},
{
name: 'value',
...ValueSchema,
name: 'colorScheme',
...ColorSchemePropertySchema,
},
],
acceptTraits: [],
state: {},
state: StateSchema,
methods: [],
},
}),

View File

@ -5,19 +5,20 @@ import { CheckboxGroup as BaseCheckboxGroup } from '@chakra-ui/react';
import { ComponentImplementation } from '../../registry';
import Slot from '../_internal/Slot';
import { SizePropertySchema, IsDisabledSchema } from './Checkbox';
import { ColorSchemePropertySchema } from './Types/ColorScheme';
const DefaultValueSchema = Type.Optional(
Type.Array(Type.Union([Type.String(), Type.Number()]))
);
const StateSchema = Type.Object({
value: Type.String(),
});
const CheckboxGroup: ComponentImplementation<{
colorScheme?: Static<typeof ColorSchemePropertySchema>;
size?: Static<typeof SizePropertySchema>;
defaultValue?: Static<typeof DefaultValueSchema>;
isDisabled?: Static<typeof IsDisabledSchema>;
}> = ({
colorScheme,
size,
defaultValue,
isDisabled,
@ -31,7 +32,6 @@ const CheckboxGroup: ComponentImplementation<{
return (
<BaseCheckboxGroup
colorScheme={colorScheme}
size={size}
defaultValue={defaultValue}
isDisabled={isDisabled}
@ -50,10 +50,6 @@ export default {
},
spec: {
properties: [
{
name: 'colorScheme',
...ColorSchemePropertySchema,
},
{
name: 'size',
...SizePropertySchema,
@ -68,7 +64,7 @@ export default {
},
],
acceptTraits: [],
state: {},
state: StateSchema,
methods: [],
},
}),

View File

@ -0,0 +1,140 @@
import React, { useEffect } from 'react';
import { createComponent } from '@meta-ui/core';
import { Static, Type } from '@sinclair/typebox';
import { Radio as BaseRadio } from '@chakra-ui/react';
import { ComponentImplementation } from '../../registry';
import Text, { TextProps, TextPropertySchema } from '../_internal/Text';
import { ColorSchemePropertySchema } from './Types/ColorScheme';
const IsDisabledSchema = Type.Optional(Type.Boolean());
const IsFocusableSchema = Type.Optional(Type.Boolean());
const IsInvalidSchema = Type.Optional(Type.Boolean());
const IsReadOnlySchema = Type.Optional(Type.Boolean());
const IsRequiredSchema = Type.Optional(Type.Boolean());
const NameSchema = Type.Optional(Type.String());
const ValueSchema = Type.Union([Type.String(), Type.Number()]);
const SizePropertySchema = Type.KeyOf(
Type.Object({
sm: Type.String(),
md: Type.String(),
lg: Type.String(),
})
);
const SpacingSchema = Type.Optional(Type.String());
const StateSchema = Type.Object({
value: Type.String(),
});
const Radio: ComponentImplementation<{
text: TextProps['value'];
value: Static<typeof ValueSchema>;
isDisabled?: Static<typeof IsDisabledSchema>;
isFocusable?: Static<typeof IsFocusableSchema>;
isInValid?: Static<typeof IsInvalidSchema>;
isReadOnly?: Static<typeof IsReadOnlySchema>;
isRequired?: Static<typeof IsRequiredSchema>;
name?: Static<typeof NameSchema>;
size?: Static<typeof SizePropertySchema>;
spacing?: Static<typeof SpacingSchema>;
colorScheme?: Static<typeof ColorSchemePropertySchema>;
}> = ({
text,
value,
isDisabled,
isFocusable,
isInValid,
isReadOnly,
isRequired,
name,
size,
spacing,
colorScheme,
mergeState,
}) => {
useEffect(() => {
mergeState({ text: text.raw });
}, [text.raw]);
useEffect(() => {
mergeState({ value });
}, [value]);
return (
<BaseRadio
value={value}
isDisabled={isDisabled}
isFocusable={isFocusable}
isInvalid={isInValid}
isReadOnly={isReadOnly}
isRequired={isRequired}
name={name}
size={size}
spacing={spacing}
colorScheme={colorScheme}>
<Text value={text} />
</BaseRadio>
);
};
export default {
...createComponent({
version: 'chakra_ui/v1',
metadata: {
name: 'radio',
description: 'chakra-ui radio',
},
spec: {
properties: [
{
name: 'text',
...TextPropertySchema,
},
{
name: 'value',
...ValueSchema,
},
{
name: 'isDisabled',
...IsDisabledSchema,
},
{
name: 'isFocusable',
...IsFocusableSchema,
},
{
name: 'isInValid',
...IsInvalidSchema,
},
{
name: 'isReadOnly',
...IsReadOnlySchema,
},
{
name: 'isRequired',
...IsReadOnlySchema,
},
{
name: 'name',
...NameSchema,
},
{
name: 'size',
...SizePropertySchema,
},
{
name: 'spacing',
...SpacingSchema,
},
{
name: 'colorScheme',
...ColorSchemePropertySchema,
},
],
acceptTraits: [],
state: StateSchema,
methods: [],
},
}),
impl: Radio,
};

View File

@ -0,0 +1,56 @@
import React, { useState, useEffect } from 'react';
import { createComponent } from '@meta-ui/core';
import { Static, Type } from '@sinclair/typebox';
import { RadioGroup as BaseRadioGroup } from '@chakra-ui/react';
import { ComponentImplementation } from '../../registry';
import Slot from '../_internal/Slot';
const DefaultValueSchema = Type.Union([Type.String(), Type.Number()]);
const IsNumericalSchema = Type.Optional(Type.Boolean());
const StateSchema = Type.Object({
value: Type.String(),
});
const RadioGroup: ComponentImplementation<{
defaultValue?: Static<typeof DefaultValueSchema>;
isNumerical?: Static<typeof IsNumericalSchema>;
}> = ({ defaultValue, isNumerical, slotsMap, mergeState }) => {
const [value, setValue] = useState(defaultValue);
useEffect(() => {
mergeState({ value });
}, [value]);
return (
<BaseRadioGroup
value={value}
onChange={val => setValue(isNumerical ? Number(val) : val)}>
<Slot slotsMap={slotsMap} slot="content" />
</BaseRadioGroup>
);
};
export default {
...createComponent({
version: 'chakra_ui/v1',
metadata: {
name: 'radio_group',
description: 'chakra-ui radio group',
},
spec: {
properties: [
{
name: 'defaultValue',
...DefaultValueSchema,
},
{
name: 'isNumerical',
...IsNumericalSchema,
},
],
acceptTraits: [],
state: StateSchema,
methods: [],
},
}),
impl: RadioGroup,
};

View File

@ -35,6 +35,10 @@ const VariantSchema = Type.KeyOf(
})
);
const StateSchema = Type.Object({
value: Type.String(),
});
const Select: ComponentImplementation<{
options: Static<typeof OptionsSchema>;
placeholder?: Static<typeof PlaceholderSchema>;
@ -144,7 +148,7 @@ export default {
},
],
acceptTraits: [],
state: {},
state: StateSchema,
methods: [],
},
}),

View File

@ -31,6 +31,8 @@ import ChakraUIVStack from './components/chakra-ui/VStack';
import ChakraUIImage from './components/chakra-ui/Image';
import ChakraUIDialog from './components/chakra-ui/Dialog';
import ChakraUISelect from './components/chakra-ui/Select';
import ChakraUIRadioGroup from './components/chakra-ui/RadioGroup';
import ChakraUIRadio from './components/chakra-ui/Radio';
/* --- lab --- */
import LabEditor from './components/lab/Editor';
// traits
@ -158,6 +160,8 @@ registry.registerComponent(ChakraUIVStack);
registry.registerComponent(ChakraUIImage);
registry.registerComponent(ChakraUIDialog);
registry.registerComponent(ChakraUISelect);
registry.registerComponent(ChakraUIRadioGroup);
registry.registerComponent(ChakraUIRadio);
registry.registerComponent(LabEditor);
registry.registerComponent(CoreRouter);
registry.registerComponent(CoreDummy);