diff --git a/packages/primer-components/src/Tree/Tree.stories.tsx b/packages/primer-components/src/Tree/Tree.stories.tsx new file mode 100644 index 00000000..775768db --- /dev/null +++ b/packages/primer-components/src/Tree/Tree.stories.tsx @@ -0,0 +1,105 @@ +import { ComponentStory, ComponentMeta } from "@storybook/react"; + +import { Tree, TreeI } from "./Tree"; + +export default { + title: "Application/Component Library/Tree", + component: Tree, + argTypes: { + tree: { control: "object", name: "Tree to display" }, + }, +} as ComponentMeta; + +/* We have this indirection so storybook renders the whole json description of + * a tree as one control. (As having three separate controls for 'label', 'id' + * and 'subtrees' is not particularly useful.) + */ +interface TreeArgs { + tree: TreeI; +} + +const Template: ComponentStory<(args: TreeArgs) => JSX.Element> = (args) => ( + +); + +export const Tree1 = Template.bind({}); +Tree1.args = { tree: { nodeId: 0, childTrees: [], label: "EmptyHole" } }; + +export const Tree2 = Template.bind({}); +Tree2.args = { + tree: { + nodeId: 0, + childTrees: [{ nodeId: 1, childTrees: [], label: "Var x" }], + label: "Lam x", + }, +}; + +export const Tree3 = Template.bind({}); +Tree3.args = { + tree: { + nodeId: 0, + childTrees: [{ nodeId: 1, childTrees: [], label: "Var y" }], + label: "Lam y", + }, +}; + +export const Tree4 = Template.bind({}); +Tree4.args = { + tree: { + nodeId: 0, + childTrees: [ + { + nodeId: 1, + childTrees: [ + { + nodeId: 2, + childTrees: [ + { + nodeId: 3, + childTrees: [{ nodeId: 4, childTrees: [], label: "Var x" }], + label: "Lam x", + }, + ], + label: "LAM a", + }, + { + nodeId: 5, + childTrees: [ + { + nodeId: 6, + childTrees: [ + { nodeId: 7, childTrees: [], label: "TVar a" }, + { nodeId: 8, childTrees: [], label: "TVar a" }, + ], + label: "TFun", + }, + ], + label: "TForall", + }, + ], + label: "Ann", + }, + { nodeId: 9, childTrees: [], label: "Con Unit" }, + ], + label: "App", + }, +}; + +export const Tree5 = Template.bind({}); +Tree5.args = { + tree: { + nodeId: 0, + childTrees: [ + { + nodeId: 1, + childTrees: [ + { nodeId: 2, childTrees: [], label: "Var x" }, + { nodeId: 3, childTrees: [], label: "EmptyHole" }, + { nodeId: 6, childTrees: [], label: "EmptyHole" }, + ], + label: "Case", + }, + ], + label: "Lam x", + }, +}; diff --git a/packages/primer-components/src/Tree/Tree.tsx b/packages/primer-components/src/Tree/Tree.tsx new file mode 100644 index 00000000..349b8e54 --- /dev/null +++ b/packages/primer-components/src/Tree/Tree.tsx @@ -0,0 +1,30 @@ +import "@/index.css"; + +export interface TreeI { + nodeId: number; + label: string; + /* NB: 'children' is treated specially by react, leading to weird errors. + * Let's avoid that word. + */ + childTrees: TreeI[]; +} + +export const Tree = (tree: TreeI): JSX.Element => ( + +); + +function ChildTrees({ trees }: { trees: TreeI[] }): JSX.Element { + if (trees.length > 0) { + return ( + + ); + } + return <>; +} diff --git a/packages/primer-components/src/Tree/index.tsx b/packages/primer-components/src/Tree/index.tsx new file mode 100644 index 00000000..efc9829d --- /dev/null +++ b/packages/primer-components/src/Tree/index.tsx @@ -0,0 +1,3 @@ +import { Tree } from "./Tree"; + +export default Tree; diff --git a/packages/primer-components/src/index.ts b/packages/primer-components/src/index.ts index 09a066d8..32117d75 100644 --- a/packages/primer-components/src/index.ts +++ b/packages/primer-components/src/index.ts @@ -8,4 +8,5 @@ export { default as SearchBar } from "@/SearchBar"; export { default as SessionList } from "@/SessionList"; export { default as SessionPreview } from "@/SessionPreview"; export { default as SessionsNavBar } from "@/SessionsNavBar"; +export { default as Tree } from "@/Tree"; export { default as UIButton } from "@/UIButton";