implement tooltip component

This commit is contained in:
Bowen Tan 2021-09-10 17:15:39 +08:00
parent 3e8f26496e
commit 25525f9951
8 changed files with 234 additions and 77 deletions

View File

@ -0,0 +1,72 @@
<!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: tooltip</title>
</head>
<body>
<div id="root"></div>
<script type="module">
import renderApp from '../../src/main.tsx';
renderApp({
version: 'example/v1',
metadata: {
name: 'tooltip',
description: 'tooltip',
},
spec: {
components: [
{
id: 'root',
type: 'chakra_ui/v1/root',
properties: {},
traits: [],
},
{
id: 'tooltip',
type: 'chakra_ui/v1/tooltip',
properties: {
text: 'hello, tooltip!',
shouldWrapChildren: true,
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'root',
slot: 'root',
},
},
},
],
},
{
id: 'button',
type: 'chakra_ui/v1/button',
properties: {
text: {
raw: 'hover me!',
format: 'plain',
},
},
traits: [
{
type: 'core/v1/slot',
properties: {
container: {
id: 'tooltip',
slot: 'trigger',
},
},
},
],
},
],
},
});
</script>
</body>
</html>

View File

@ -1,16 +1,8 @@
import React, { import React, { useCallback, useEffect, useMemo, useState } from 'react';
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { import {
Application, Application,
ComponentTrait,
createApplication, createApplication,
RuntimeApplication, RuntimeApplication,
Trait,
} from '@meta-ui/core'; } from '@meta-ui/core';
import { merge } from 'lodash'; import { merge } from 'lodash';
import { registry, TraitResult } from './registry'; import { registry, TraitResult } from './registry';

View File

@ -4,6 +4,7 @@ import { Static, Type } from '@sinclair/typebox';
import { Button as BaseButton } from '@chakra-ui/react'; import { Button as BaseButton } from '@chakra-ui/react';
import Text, { TextProps, TextPropertySchema } from '../_internal/Text'; import Text, { TextProps, TextPropertySchema } from '../_internal/Text';
import { ComponentImplementation } from '../../registry'; import { ComponentImplementation } from '../../registry';
import { ColorSchemePropertySchema } from './Types/ColorScheme';
const Button: ComponentImplementation<{ const Button: ComponentImplementation<{
text: TextProps['value']; text: TextProps['value'];
@ -40,30 +41,6 @@ const Button: ComponentImplementation<{
); );
}; };
const ColorSchemePropertySchema = Type.Optional(
Type.KeyOf(
Type.Object({
whiteAlpha: Type.String(),
blackAlpha: Type.String(),
gray: Type.String(),
red: Type.String(),
orange: Type.String(),
yellow: Type.String(),
green: Type.String(),
teal: Type.String(),
blue: Type.String(),
cyan: Type.String(),
purple: Type.String(),
pink: Type.String(),
linkedin: Type.String(),
facebook: Type.String(),
messenger: Type.String(),
whatsapp: Type.String(),
twitter: Type.String(),
telegram: Type.String(),
})
)
);
const IsLoadingPropertySchema = Type.Optional(Type.Boolean()); const IsLoadingPropertySchema = Type.Optional(Type.Boolean());
const StateSchema = Type.Object({ const StateSchema = Type.Object({

View File

@ -4,33 +4,10 @@ import { Static, Type } from '@sinclair/typebox';
import { Checkbox as BaseCheckbox } from '@chakra-ui/react'; import { Checkbox as BaseCheckbox } from '@chakra-ui/react';
import { ComponentImplementation } from '../../registry'; import { ComponentImplementation } from '../../registry';
import Text, { TextProps, TextPropertySchema } from '../_internal/Text'; import Text, { TextProps, TextPropertySchema } from '../_internal/Text';
import { ColorSchemePropertySchema } from './Types/ColorScheme';
const DefaultIsCheckedSchema = Type.Optional(Type.Boolean()); const DefaultIsCheckedSchema = Type.Optional(Type.Boolean());
export const IsDisabledSchema = Type.Optional(Type.Boolean()); export const IsDisabledSchema = Type.Optional(Type.Boolean());
export const ColorSchemePropertySchema = Type.Optional(
Type.KeyOf(
Type.Object({
whiteAlpha: Type.String(),
blackAlpha: Type.String(),
gray: Type.String(),
red: Type.String(),
orange: Type.String(),
yellow: Type.String(),
green: Type.String(),
teal: Type.String(),
blue: Type.String(),
cyan: Type.String(),
purple: Type.String(),
pink: Type.String(),
linkedin: Type.String(),
facebook: Type.String(),
messenger: Type.String(),
whatsapp: Type.String(),
twitter: Type.String(),
telegram: Type.String(),
})
)
);
export const SizePropertySchema = Type.KeyOf( export const SizePropertySchema = Type.KeyOf(
Type.Object({ Type.Object({
sm: Type.String(), sm: Type.String(),

View File

@ -1,14 +1,11 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from 'react';
import { createComponent } from "@meta-ui/core"; import { createComponent } from '@meta-ui/core';
import { Static, Type } from "@sinclair/typebox"; import { Static, Type } from '@sinclair/typebox';
import { CheckboxGroup as BaseCheckboxGroup } from "@chakra-ui/react"; import { CheckboxGroup as BaseCheckboxGroup } from '@chakra-ui/react';
import { ComponentImplementation } from "../../registry"; import { ComponentImplementation } from '../../registry';
import Slot from "../_internal/Slot"; import Slot from '../_internal/Slot';
import { import { SizePropertySchema, IsDisabledSchema } from './Checkbox';
ColorSchemePropertySchema, import { ColorSchemePropertySchema } from './Types/ColorScheme';
SizePropertySchema,
IsDisabledSchema,
} from "./Checkbox";
const DefaultValueSchema = Type.Optional( const DefaultValueSchema = Type.Optional(
Type.Array(Type.Union([Type.String(), Type.Number()])) Type.Array(Type.Union([Type.String(), Type.Number()]))
@ -38,8 +35,7 @@ const CheckboxGroup: ComponentImplementation<{
size={size} size={size}
defaultValue={defaultValue} defaultValue={defaultValue}
isDisabled={isDisabled} isDisabled={isDisabled}
onChange={(val) => setValue(val)} onChange={val => setValue(val)}>
>
<Slot slotsMap={slotsMap} slot="content" /> <Slot slotsMap={slotsMap} slot="content" />
</BaseCheckboxGroup> </BaseCheckboxGroup>
); );
@ -47,27 +43,27 @@ const CheckboxGroup: ComponentImplementation<{
export default { export default {
...createComponent({ ...createComponent({
version: "chakra_ui/v1", version: 'chakra_ui/v1',
metadata: { metadata: {
name: "checkbox_group", name: 'checkbox_group',
description: "chakra-ui checkbox group", description: 'chakra-ui checkbox group',
}, },
spec: { spec: {
properties: [ properties: [
{ {
name: "colorScheme", name: 'colorScheme',
...ColorSchemePropertySchema, ...ColorSchemePropertySchema,
}, },
{ {
name: "size", name: 'size',
...SizePropertySchema, ...SizePropertySchema,
}, },
{ {
name: "isDisabled", name: 'isDisabled',
...IsDisabledSchema, ...IsDisabledSchema,
}, },
{ {
name: "defaultValue", name: 'defaultValue',
...DefaultValueSchema, ...DefaultValueSchema,
}, },
], ],

View File

@ -0,0 +1,115 @@
import React from 'react';
import { createComponent } from '@meta-ui/core';
import { Static, Type } from '@sinclair/typebox';
import { Tooltip } from '@chakra-ui/react';
import { TextProps, TextPropertySchema } from '../_internal/Text';
import { ComponentImplementation } from '../../registry';
import Slot from '../_internal/Slot';
import { ColorSchemePropertySchema } from './Types/ColorScheme';
const TooltipImpl: ComponentImplementation<{
text: TextProps['value'];
shouldWrapChildren: boolean;
placement: Static<typeof PlacementPropertySchema>;
isOpen: boolean;
hasArrow: boolean;
isDisabled: boolean;
defaultIsOpen: boolean;
}> = ({
text,
shouldWrapChildren,
placement = 'auto',
isOpen,
hasArrow,
isDisabled,
defaultIsOpen,
slotsMap,
}) => {
return (
/*
Chakra tooltip requires children to be created by forwardRef.
If not, should add shouldWrapChildren.
*/
<Tooltip
label={text}
placement={placement}
isOpen={isOpen}
hasArrow={hasArrow}
isDisabled={isDisabled}
defaultIsOpen={defaultIsOpen}
shouldWrapChildren={shouldWrapChildren}>
<Slot slotsMap={slotsMap} slot="trigger" />
</Tooltip>
);
};
export const PlacementPropertySchema = Type.Optional(
Type.KeyOf(
Type.Object({
top: Type.String(),
right: Type.String(),
bottom: Type.String(),
left: Type.String(),
auto: Type.String(),
'auto-start': Type.String(),
'auto-end': Type.String(),
'top-start': Type.String(),
'top-end': Type.String(),
'bottom-start': Type.String(),
'bottom-end': Type.String(),
'right-start': Type.String(),
'right-end': Type.String(),
'left-start': Type.String(),
'left-end': Type.String(),
})
)
);
export default {
...createComponent({
version: 'chakra_ui/v1',
metadata: {
name: 'tooltip',
description: 'chakra-ui tooltip',
},
spec: {
properties: [
{
name: 'text',
...TextPropertySchema,
},
{
name: 'colorScheme',
...ColorSchemePropertySchema,
},
{
name: 'shouldWrapChildren',
...Type.Boolean(),
},
{
name: 'defaultIsOpen',
...Type.Boolean(),
},
{
name: 'hasArrow',
...Type.Boolean(),
},
{
name: 'isDisabled',
...Type.Boolean(),
},
{
name: 'isOpen',
...Type.Boolean(),
},
{
name: 'placement',
...PlacementPropertySchema,
},
],
acceptTraits: [],
state: {},
methods: [],
},
}),
impl: TooltipImpl,
};

View File

@ -0,0 +1,26 @@
import { Type } from '@sinclair/typebox';
export const ColorSchemePropertySchema = Type.Optional(
Type.KeyOf(
Type.Object({
whiteAlpha: Type.String(),
blackAlpha: Type.String(),
gray: Type.String(),
red: Type.String(),
orange: Type.String(),
yellow: Type.String(),
green: Type.String(),
teal: Type.String(),
blue: Type.String(),
cyan: Type.String(),
purple: Type.String(),
pink: Type.String(),
linkedin: Type.String(),
facebook: Type.String(),
messenger: Type.String(),
whatsapp: Type.String(),
twitter: Type.String(),
telegram: Type.String(),
})
)
);

View File

@ -19,6 +19,7 @@ import ChakraUINumberInput from './components/chakra-ui/NumberInput';
import ChakraUICheckboxGroup from './components/chakra-ui/CheckboxGroup'; import ChakraUICheckboxGroup from './components/chakra-ui/CheckboxGroup';
import ChakraUICheckbox from './components/chakra-ui/Checkbox'; import ChakraUICheckbox from './components/chakra-ui/Checkbox';
import ChakraUIStack from './components/chakra-ui/Stack'; import ChakraUIStack from './components/chakra-ui/Stack';
import ChakraUITooltip from './components/chakra-ui/Tooltip';
import ChakraUIHStack from './components/chakra-ui/HStack'; import ChakraUIHStack from './components/chakra-ui/HStack';
import ChakraUIVStack from './components/chakra-ui/VStack'; import ChakraUIVStack from './components/chakra-ui/VStack';
import ChakraUIImage from './components/chakra-ui/Image'; import ChakraUIImage from './components/chakra-ui/Image';
@ -139,6 +140,7 @@ registry.registerComponent(ChakraUINumberInput);
registry.registerComponent(ChakraUICheckbox); registry.registerComponent(ChakraUICheckbox);
registry.registerComponent(ChakraUICheckboxGroup); registry.registerComponent(ChakraUICheckboxGroup);
registry.registerComponent(ChakraUIStack); registry.registerComponent(ChakraUIStack);
registry.registerComponent(ChakraUITooltip);
registry.registerComponent(ChakraUIHStack); registry.registerComponent(ChakraUIHStack);
registry.registerComponent(ChakraUIVStack); registry.registerComponent(ChakraUIVStack);
registry.registerComponent(ChakraUIImage); registry.registerComponent(ChakraUIImage);