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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add typescript; Add CRUDE themebuilder docs #17

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"fictoan-react": "^0.33.10",
"ace-builds": "^1.4.13",
"acorn": "^8.6.0",
"deep-diff": "^1.0.2",
"fictoan-react": "^0.35.3",
"polished": "^4.0.4",
"react": "^16.13.1",
"react-ace": "^9.5.0",
"react-dom": "^16.13.1",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.1",
Expand All @@ -34,5 +38,13 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/acorn": "^4.0.6",
"@types/node": "^16.11.11",
"@types/react": "^17.0.37",
"@types/react-dom": "^17.0.11",
"@types/styled-components": "^5.1.16",
"typescript": "^4.5.2"
}
}
7 changes: 7 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { TableDocs } from "./pages/Components/Table/Table";
// Local assets
import { Sidebar } from "./components/Sidebar/Sidebar";
import { ThemeDocs } from "./pages/03Theme/Theme";
import { ThemeEditorDocs } from "./pages/03ThemeBuilder/ThemeEditor";
import { CodeBlockDocs } from "./pages/Components/CodeBlock/CodeBlock";
import { BaseElementDocs } from "./pages/BaseElement/BaseElement";
import { InfoPanelDocs } from "./pages/Components/InfoPanel/InfoPanel";
Expand Down Expand Up @@ -91,6 +92,12 @@ export const App = () => {
component={ ThemeDocs }
/>

<Route
exact
path="/theme-editor"
component={ ThemeEditorDocs }
/>

<Route
exact
path="/base-element"
Expand Down
63 changes: 26 additions & 37 deletions src/components/Sidebar/Sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import React, { useState } from "react";
import { NavLink } from "react-router-dom";

import {
ExpandableContent,
HRule,
SidebarFooter,
SidebarHeader,
SidebarItem,
SidebarItemIcon,
SidebarItemsGroup,
SidebarItemsGroupHeader,
SidebarItemText, SidebarLinksWrapper,
SidebarNestedLinks,
SidebarItemText,
SidebarWrapper,
Text
} from "fictoan-react";
Expand Down Expand Up @@ -43,7 +41,7 @@ export const Sidebar = ({toggleTheme}) => {
</SidebarHeader>

{/* COMPONENTS ============================================= */}
<SidebarLinksWrapper>
<>
<NavLink exact to="/">
<SidebarItem>
<SidebarItemIcon iconType="stroked">
Expand Down Expand Up @@ -286,41 +284,32 @@ export const Sidebar = ({toggleTheme}) => {
</NavLink>

{/* SIDEBAR ================================================ */}
<SidebarItemsGroup>
<SidebarItemsGroupHeader open>
<ExpandableContent summary="Sidebar" paddingLeft="micro">
<NavLink exact to="/components/sidebar-wrapper">
<SidebarItem>
<SidebarItemIcon iconType="stroked">
</SidebarItemIcon>
<SidebarItemText weight="400" linkText="Sidebar" />
<SidebarItemText weight="400" linkText="Wrapper" />
</SidebarItem>
</SidebarItemsGroupHeader>

<SidebarNestedLinks>
<NavLink exact to="/components/sidebar-wrapper">
<SidebarItem>
<SidebarItemIcon iconType="stroked">
</SidebarItemIcon>
<SidebarItemText weight="400" linkText="Wrapper" />
</SidebarItem>
</NavLink>

<NavLink exact to="/components/sidebar-header">
<SidebarItem>
<SidebarItemIcon iconType="stroked">
</SidebarItemIcon>
<SidebarItemText weight="400" linkText="Item" />
</SidebarItem>
</NavLink>

<NavLink exact to="/components/sidebar-header">
<SidebarItem>
<SidebarItemIcon iconType="stroked">
</SidebarItemIcon>
<SidebarItemText weight="400" linkText="Expandable group" />
</SidebarItem>
</NavLink>
</SidebarNestedLinks>
</SidebarItemsGroup>
</NavLink>

<NavLink exact to="/components/sidebar-header">
<SidebarItem>
<SidebarItemIcon iconType="stroked">
</SidebarItemIcon>
<SidebarItemText weight="400" linkText="Item" />
</SidebarItem>
</NavLink>

<NavLink exact to="/components/expandable-group">
<SidebarItem>
<SidebarItemIcon iconType="stroked">
</SidebarItemIcon>
<SidebarItemText weight="400" linkText="Expandable group" />
</SidebarItem>
</NavLink>
</ExpandableContent>


{/* TABS =================================================== */}
<NavLink exact to="/components/tabs">
Expand All @@ -339,7 +328,7 @@ export const Sidebar = ({toggleTheme}) => {
<SidebarItemText weight="400" linkText="Table" />
</SidebarItem>
</NavLink>
</SidebarLinksWrapper>
</>

{/* FOOTER ================================================= */}
<SidebarFooter>
Expand Down
73 changes: 73 additions & 0 deletions src/pages/03ThemeBuilder/CodeManipulation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { DeepDiff } from "deep-diff";
import dep2 from "polished/lib/color/lighten";
import dep3 from "polished/lib/color/darken";
import { defaultColours as dep1 } from "fictoan-react";
import { ThemeVisitor, JSVisitor } from "./Visitor";

interface DiffType {
kind: "E" | "N" | "D" | "A";
path: string[];
lhs: any;
rhs: any;
index?: number;
item?: any;
}

function templatize(val: string): string {
return `{{${val}}}`;
}

function unTemplatize(val: string): string {
return val.replaceAll(/\'\{\{([^\{\}]+)\}\}\'/g, "$1");
}

function setDeepValue(obj: any, path: string[], value: string) {
const key = path.shift();
if (!key) {
return value;
}
obj[key] = setDeepValue(obj[key] ? obj[key] : {}, path, value);
return obj;
}

export function evaluateJS(javascriptCode: string) {
const defaultColours = dep1;
const lighten = dep2;
const darken = dep3;
return eval(`(
function () {
${javascriptCode}
return Theme;
}
)();`);
}

export function performDiff(newJavascriptCode: string, oldJavascriptCode: string) {
const newCode = evaluateJS(newJavascriptCode);
const newCodeVisitor = new ThemeVisitor(newJavascriptCode);
const oldCode = evaluateJS(oldJavascriptCode);
const oldCodeVisitor = new ThemeVisitor(oldJavascriptCode);
const deepDiffs = DeepDiff(oldCode, newCode);

const diffs = deepDiffs
? DeepDiff(oldCode, newCode)
.filter((diff: DiffType) => diff.path[0] != "customColours")
.map((diff: DiffType) => {
const _newVal = newCodeVisitor.getValueAtPath([ "Theme", ...diff.path ]);
const _oldVal = oldCodeVisitor.getValueAtPath([ "Theme", ...diff.path ]);
if (_newVal.trim() !== _oldVal.trim())
return {path : diff.path, val : _newVal}
return undefined;
}).filter(Boolean)
: [];

const minifiedTheme = diffs.reduce((acc: object, curr: { path: string[], val: string }) => {
return setDeepValue(acc, curr.path.map(templatize), templatize(curr.val))
}, {[templatize("customColours")] : templatize("customColours")});

const v = new JSVisitor(newJavascriptCode);
return (
`${v.getAllVariableDeclarations()}
\nconst Theme = ${unTemplatize(JSON.stringify(minifiedTheme, null, "\t"))}`
)
}
52 changes: 52 additions & 0 deletions src/pages/03ThemeBuilder/Editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { FunctionComponent, useRef } from "react";
import AceEditor from "react-ace";
import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/theme-tomorrow";
import { Button } from "fictoan-react";
import { STRINGIFIED_FICTOAN_THEME } from "./Theme";
import { evaluateJS, performDiff } from "./CodeManipulation";

interface EditorProps {
setTheme: Function;
setMinified: Function;
}

export const Editor: FunctionComponent<EditorProps> = ({setTheme, setMinified}) => {

const editorRef = useRef<any>();

function handleClick() {
if (editorRef.current) {
const code = editorRef.current.editor.getValue();
const theme = evaluateJS(code);
setTheme(theme);
}
}

function handleMinify() {
if (editorRef.current) {
const codeString = editorRef.current.editor.getValue();
const minified = performDiff(codeString, STRINGIFIED_FICTOAN_THEME);
setMinified(minified);
}
}

return (
<>
<AceEditor
ref={editorRef}
mode="javascript"
theme="tomorrow"
defaultValue={STRINGIFIED_FICTOAN_THEME}
name="UNIQUE_ID_OF_DIV"
width="100%"
height="1080px"
showPrintMargin={false}
editorProps={{$blockScrolling : true}}
/>
<Button onClick={handleClick}>Apply</Button>
<Button onClick={handleMinify}>Minify</Button>
</>
)
}

59 changes: 59 additions & 0 deletions src/pages/03ThemeBuilder/Result.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { ReactElement, useState } from "react";
import {
Element,
Button,
Card,
FormWrapper,
Heading,
InputField,
ProgressBar,
Text,
ThemeProvider,
} from "fictoan-react";
import { evaluateJS } from "./CodeManipulation";
import { STRINGIFIED_FICTOAN_THEME } from "./Theme";

export const FictoanThemeOutputSample = () => {
const [json, setJson] = useState<any>(() => evaluateJS(STRINGIFIED_FICTOAN_THEME));

return (
<ThemeProvider theme={json}>
<Element
as="img"
src={"http://acmelogos.com/images/logo-3.svg"}
className="icon-large"
/>
<Heading as="h2">ACME CORP</Heading>

<ProgressBar
label="Loading..."
value={30}
max="100"
shape="rounded"
/>

<Card padding="micro" shape="rounded" marginTop="micro">
<Heading as="h4"> This is a heading</Heading>

<Text marginTop="nano">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua.
</Text>

<FormWrapper>
<InputField
placeholder="Text input"
marginTop="nano"
marginBottom="nano"
/>
</FormWrapper>

<Button kind="primary">Primary Button</Button>

<Button kind="secondary" marginLeft="nano">Secondary Button</Button>

<Button kind="tertiary" marginLeft="nano">Tertiary Button</Button>
</Card>
</ThemeProvider>
)
}
Loading