Skip to content

Commit

Permalink
Progress on source view component
Browse files Browse the repository at this point in the history
  • Loading branch information
kasperisager committed Feb 10, 2021
1 parent 8344e4e commit 18a2cd1
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/alfa-interviewer-console/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
],
"dependencies": {
"@siteimprove/alfa-act": "^0.10.0",
"@siteimprove/alfa-dom": "^0.10.0",
"@siteimprove/alfa-future": "^0.10.0",
"@siteimprove/alfa-interviewer": "^0.10.0",
"@siteimprove/alfa-option": "^0.10.0",
Expand Down
182 changes: 182 additions & 0 deletions packages/alfa-interviewer-console/src/component/source.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import React, { FunctionComponent } from "react";

import * as ink from "ink";

import * as dom from "@siteimprove/alfa-dom";

export const Source: FunctionComponent<Source.Props> = ({ source }) => (
<Node source={source} />
);

export namespace Source {
export interface Props {
source: dom.Node;
}
}

const Node: FunctionComponent<Node.Props> = ({ source }) => {
if (dom.Element.isElement(source)) {
return <Element source={source} />;
}

if (dom.Attribute.isAttribute(source)) {
return <Attribute source={source} />;
}

if (dom.Text.isText(source)) {
return <Text source={source} />;
}

if (dom.Document.isDocument(source)) {
return <Document source={source} />;
}

if (dom.Type.isType(source)) {
return <Type source={source} />;
}

if (dom.Shadow.isShadow(source)) {
return <Shadow source={source} />;
}

return null;
};

namespace Node {
export interface Props {
source: dom.Node;
}
}

const Document: FunctionComponent<Document.Props> = ({ source }) => {
const children = source.children();

return (
<ink.Box flexDirection="column">
<ink.Text color="blackBright">#document</ink.Text>

<ink.Box marginLeft={2} flexDirection="column">
{children.isEmpty()
? null
: children.map((child, index) => <Node source={child} key={index} />)}
</ink.Box>
</ink.Box>
);
};

namespace Document {
export interface Props {
source: dom.Document;
}
}

const Type: React.FunctionComponent<Type.Props> = ({ source }) => (
<ink.Text color="blackBright">
{"<!doctype "}
{source.name}
{">"}
</ink.Text>
);

namespace Type {
export interface Props {
source: dom.Type;
}
}

const Shadow: React.FunctionComponent<Shadow.Props> = ({ source }) => {
const children = source.children();

return (
<ink.Box flexDirection="column">
<ink.Text>#shadow-root ({source.mode})</ink.Text>

<ink.Box marginLeft={2} flexDirection="column">
{children.isEmpty()
? null
: children.map((child, index) => <Node source={child} key={index} />)}
</ink.Box>
</ink.Box>
);
};

namespace Shadow {
export interface Props {
source: dom.Shadow;
}
}

const Element: React.FunctionComponent<Element.Props> = ({ source }) => {
const children = source.children({
composed: true,
nested: true,
});

return (
<ink.Box flexDirection="column">
<ink.Box>
<ink.Text>{"<"}</ink.Text>
<ink.Text color="red">{source.name}</ink.Text>

{[...source.attributes].map((attribute, index) => (
<ink.Box key={index} marginLeft={1}>
<Attribute source={attribute} />
</ink.Box>
))}

<ink.Text>{">"}</ink.Text>
</ink.Box>

<ink.Box marginLeft={2} flexDirection="column">
{children.isEmpty()
? null
: children.map((child, index) => <Node source={child} key={index} />)}
</ink.Box>

{source.isVoid() ? null : (
<ink.Box>
<ink.Text>{"</"}</ink.Text>
<ink.Text color="red">{source.name}</ink.Text>
<ink.Text>{">"}</ink.Text>
</ink.Box>
)}
</ink.Box>
);
};

namespace Element {
export interface Props {
source: dom.Element;
}
}

const Attribute: React.FunctionComponent<Attribute.Props> = ({ source }) => (
<ink.Box>
<ink.Text color="yellow">{source.name}</ink.Text>
<ink.Text>{'="'}</ink.Text>
<ink.Text color="blue">{source.value}</ink.Text>
<ink.Text>{'"'}</ink.Text>
</ink.Box>
);

namespace Attribute {
export interface Props {
source: dom.Attribute;
}
}

const Text: React.FunctionComponent<Text.Props> = ({ source }) => {
const { data } = source;

if (data.trim() === "") {
return null;
}

return <ink.Text>"{data}"</ink.Text>;
};

namespace Text {
export interface Props {
source: dom.Text;
}
}
28 changes: 28 additions & 0 deletions packages/alfa-interviewer-console/test/console.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";

import { render } from "ink";

import { h } from "@siteimprove/alfa-dom/h";

import { Source } from "../src/component/source";

render(
<Source
source={h.document([
h.type("html"),
h(
"html",
[],
[
h(
"body",
{
lang: "en",
},
[h("p", [], ["Hello world"])]
),
]
),
])}
/>
);
13 changes: 11 additions & 2 deletions packages/alfa-interviewer-console/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"esModuleInterop": true,
"jsxFactory": "React.createElement"
"jsxFactory": "React.createElement",
"jsxFragmentFactory": "React.Fragment"
},
"files": ["src/console.tsx", "src/index.ts"],
"files": [
"src/component/source.tsx",
"src/console.tsx",
"src/index.ts",
"test/console.spec.tsx"
],
"references": [
{
"path": "../alfa-act"
},
{
"path": "../alfa-dom"
},
{
"path": "../alfa-future"
},
Expand Down

0 comments on commit 18a2cd1

Please sign in to comment.