Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontity Flow component - Html2React experiment 馃И #67

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/frontity-org-theme/src/index.ts
Expand Up @@ -19,6 +19,8 @@ import { polygonBackground } from "./processors/polygon-background";
import { scrollingSection } from "./processors/scrolling-section";
import { section } from "./processors/section";
import { specialIcons } from "./processors/special-icons";
// import { switchElement } from "./processors/switch";
import { switchElement as switchElement2 } from "./processors/switch2";
import { terminal } from "./processors/terminal";
import { textColor } from "./processors/text-color";

Expand Down Expand Up @@ -77,6 +79,8 @@ const frontityOrg: FrontityOrg = {
scrollingSection,
section,
specialIcons,
// switchElement
switchElement2,
],
},
},
Expand Down
71 changes: 71 additions & 0 deletions packages/frontity-org-theme/src/processors/switch.tsx
@@ -0,0 +1,71 @@
import { Node, Processor } from "@frontity/html2react/types";
import { connect } from "frontity";
import { Connect } from "frontity/types";
import React, { useState } from "react";

import FrontityOrg from "../../types";

const Switch: React.FC<Connect<
FrontityOrg,
{
html: string;
}
>> = connect(({ libraries, html }) => {
const Html2React = libraries.html2react.Component;

const [state, setState] = useState(true);

// `match()`
//
// 1. Match a part of html tree
// 2. Remove that part of the HTML from the `html` parameter
// 3. Then, it will create a "slot" in the "html" that you can "fill"
// using the returned Component (param 1.) You can think of a "slot" like a placeholder of somthing similar to `children` in react or slots in Vue: https://vuejs.org/v2/guide/components-slots.html
//
// Returns 2 params:
// 1. a React component
// 2. The HTML under the node that was matched
const [SwitchButton, buttonHtml] = match("div.switchButton", html);
const [Content, contentHtml] = match("div.content", html);

return (
// 2. We need to extend Html2React to be able to handle the "slots"
<Html2React html={html}>
{/* We can pass several children and let Html2React figure out
where to put them in the HTML, according to the slots */}
<SwitchButton onClick={() => setState((state) => !state)}>
<Html2React html={buttonHtml} />
</SwitchButton>

<Content>
{state ? "on" : "off"}
<Html2React html={contentHtml} />
</Content>
</Html2React>
);
});

export const switchElement: Processor<
React.HTMLProps<HTMLElement>,
FrontityOrg
> = {
name: "switch",
test: ({ node }) =>
node.type === "element" &&
node.props?.className?.split(" ").includes("switch"),
processor: ({ node, html }) => {
if (node.type !== "element") return node;

const element: Node<React.HTMLProps<HTMLElement> & { html: string }> = {
type: "element",
component: Switch,
props: {
// `html` should be provided as an extra parameter in the
// callback from the processor. Would have to modify html2React for this.
html,
},
};

return element;
},
};
53 changes: 53 additions & 0 deletions packages/frontity-org-theme/src/processors/switch2.tsx
@@ -0,0 +1,53 @@
import { Node, Processor } from "@frontity/html2react/types";
import { connect, css } from "frontity";
import { Connect } from "frontity/types";
import React, { useState } from "react";

import FrontityOrg from "../../types";

const Switch: React.FC<Connect<FrontityOrg>> = connect(({ node }) => {
const [state, setState] = useState(true);

// Let's say that have HTMl like this:
// <div class="switch">
// <div class="switch-button"></div>
// <div class="switch-value"></div>
// </div>
//
// We want to manage the state here in <Switch/>
// and pass it down to a child component. How to do it?

return (
<>
hello
<node.component state={state}>
{/*
Here we want to pass the state down to the child
with the `switch-value` class. How to do it?
*/}
</node.component>
</>
);
});

export const switchElement: Processor<
React.HTMLProps<HTMLElement>,
FrontityOrg
> = {
name: "switch",
test: ({ node }) =>
node.type === "element" &&
node.props?.className?.split(" ").includes("switch"),
processor: ({ node }) => {
if (node.type !== "element") return node;

const element: any = {
type: "element",
component: Switch,
props: { node },
children: node.children,
};

return element;
},
};