mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2024-11-21 03:15:49 +08:00
Merge pull request #67 from webzard-io/cep/radio
feat: impl radio and radioGroup
This commit is contained in:
commit
7894db3215
140
packages/runtime/example/radio/index.html
Normal file
140
packages/runtime/example/radio/index.html
Normal 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>
|
@ -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>
|
||||
|
@ -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: [],
|
||||
},
|
||||
}),
|
||||
|
@ -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: [],
|
||||
},
|
||||
}),
|
||||
|
140
packages/runtime/src/components/chakra-ui/Radio.tsx
Normal file
140
packages/runtime/src/components/chakra-ui/Radio.tsx
Normal 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,
|
||||
};
|
56
packages/runtime/src/components/chakra-ui/RadioGroup.tsx
Normal file
56
packages/runtime/src/components/chakra-ui/RadioGroup.tsx
Normal 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,
|
||||
};
|
@ -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: [],
|
||||
},
|
||||
}),
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user