impl static table component #5

This commit is contained in:
Yanzhen Yu 2021-07-29 11:15:20 +08:00
parent 6be1af76dc
commit 49e71a5dfc
3 changed files with 181 additions and 0 deletions

View File

@ -0,0 +1,82 @@
<!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: table component</title>
</head>
<body>
<div id="root"></div>
<script type="module">
import renderApp from "../../src/main.tsx";
renderApp({
version: "example/v1",
metadata: {
name: "table_component",
description: "table component example",
},
spec: {
components: [
{
id: "root",
type: "chakra_ui/v1/root",
properties: {},
traits: [],
},
{
id: "table",
type: "chakra_ui/v1/table",
properties: {
size: "sm",
data: [
{
id: 1,
name: "Hanson Deck",
email: "hanson@deck.com",
sales: 37,
},
{
id: 2,
name: "Max Conversation",
email: "Max@conversation.com",
sales: 424,
},
{
id: 3,
name: "Jason Response",
email: "jason@response.com",
sales: 55,
},
{
id: 4,
name: "Sue Shei",
email: "sueshei@example.com",
sales: 550,
},
{
id: 5,
name: "Eric Widget",
email: "eric@widget.org",
sales: 243,
},
],
},
traits: [
{
type: "core/v1/slot",
properties: {
container: {
id: "root",
slot: "root",
},
},
},
],
},
],
},
});
</script>
</body>
</html>

View File

@ -0,0 +1,97 @@
import React, { useEffect } from "react";
import { Table as BaseTable, Thead, Tr, Th, Tbody, Td } from "@chakra-ui/react";
import { ComponentImplementation } from "../../registry";
import { createComponent } from "@meta-ui/core";
import { Static, Type } from "@sinclair/typebox";
function normalizeData(data: Static<typeof DataPropertySchema>): {
normalizedData: Array<Record<string, string>>;
keys: string[];
} {
const normalizedData: Array<Record<string, string>> = [];
const keys = new Set<string>();
for (const item of data) {
if (typeof data !== "object") {
normalizedData.push({});
} else {
normalizedData.push(item);
Object.keys(item).forEach((key) => keys.add(key));
}
}
return {
normalizedData,
keys: Array.from(keys),
};
}
const Table: ComponentImplementation<{
data: Static<typeof DataPropertySchema>;
size: Static<typeof SizePropertySchema>;
}> = ({ data, size, mergeState }) => {
const { normalizedData, keys } = normalizeData(data);
useEffect(() => {
mergeState({ data });
}, [data]);
return (
<BaseTable size={size}>
<Thead>
<Tr>
{keys.map((key) => (
<Th key={key}>{key}</Th>
))}
</Tr>
</Thead>
<Tbody>
{normalizedData.map((item, idx) => {
return (
<Tr key={idx}>
{keys.map((key) => (
<Td key={key}>{item[key] ?? "-"}</Td>
))}
</Tr>
);
})}
</Tbody>
</BaseTable>
);
};
const DataPropertySchema = Type.Array(Type.Any());
const SizePropertySchema = Type.KeyOf(
Type.Object({
sm: Type.String(),
md: Type.String(),
lg: Type.String(),
})
);
const StateSchema = Type.Object({
data: Type.Array(Type.Any()),
});
export default {
...createComponent({
version: "chakra_ui/v1",
metadata: {
name: "table",
description: "chakra-ui table",
},
spec: {
properties: [
{
name: "data",
...DataPropertySchema,
},
{
name: "size",
...SizePropertySchema,
},
],
acceptTraits: [],
state: StateSchema,
methods: [],
},
}),
impl: Table,
};

View File

@ -10,6 +10,7 @@ import CoreText from "./components/core/Text";
import ChakraUIRoot from "./components/chakra-ui/Root";
import ChakraUIButton from "./components/chakra-ui/Button";
import ChakraUITabs from "./components/chakra-ui/Tabs";
import ChakraUITable from "./components/chakra-ui/Table";
// traits
import CoreState from "./traits/core/state";
import CoreEvent from "./traits/core/event";
@ -102,6 +103,7 @@ registry.registerComponent(CoreText);
registry.registerComponent(ChakraUIRoot);
registry.registerComponent(ChakraUIButton);
registry.registerComponent(ChakraUITabs);
registry.registerComponent(ChakraUITable);
registry.registerTrait(CoreState);
registry.registerTrait(CoreEvent);