Skip to content

Instantly share code, notes, and snippets.

@Lucifier129
Created August 17, 2020 08:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lucifier129/c4556602c8d8525e5d2bb783ce01a64e to your computer and use it in GitHub Desktop.
Save Lucifier129/c4556602c8d8525e5d2bb783ce01a64e to your computer and use it in GitHub Desktop.
export type Renderable = {
renderable: true;
};
type RenderableVStack = {
elems: Renderable[];
} & Renderable;
const VStack = (...elems: Renderable[]): RenderableVStack => {
return {
renderable: true,
elems,
};
};
type RenderableText = {
state: {
content: string;
font: string;
bold: boolean;
};
font: (type: string) => RenderableText;
bold: () => RenderableText;
} & Renderable;
const Text = (content: string): RenderableText => {
let state = {
content,
font: "",
bold: false,
};
let text: RenderableText = {
renderable: true,
state,
font: (font) => {
state.font = font;
return text;
},
bold: () => {
state.bold = true;
return text;
},
};
return text;
};
enum ModalType {
default,
text,
header,
header_body,
header_body_footer,
}
type Modal<
T extends ModalType = ModalType.default
> =
T extends ModalType.default
? {
kind: ModalType.default;
header: (header: string) => Modal<ModalType.header>;
text: (text: string) => Modal<ModalType.text>;
}
: T extends ModalType.header
? {
kind: ModalType.header;
body: (body: string) => Modal<ModalType.header_body>;
}
: T extends ModalType.header_body
? {
kind: ModalType.header_body;
footer: (footer: string) => Modal<ModalType.header_body_footer>;
}
: T extends ModalType.header_body_footer
? {
kind: ModalType.header_body_footer;
header: string;
body: string;
footer: string;
} & Renderable
: T extends ModalType.text
? {
kind: ModalType.text;
text: string;
} & Renderable
: never;
const Default_Modal = (): Modal => {
return {
kind: ModalType.default,
header: (title) => Header_Modal(title),
text: (text) => Text_Modal(text),
};
};
const Text_Modal = (text: string): Modal<ModalType.text> => {
return {
kind: ModalType.text,
text,
renderable: true,
};
};
const Header_Modal = (header: string): Modal<ModalType.header> => {
return {
kind: ModalType.header,
body: (body) => Header_Body_Modal(header, body),
};
};
const Header_Body_Modal = (
header: string,
body: string
): Modal<ModalType.header_body> => {
return {
kind: ModalType.header_body,
footer: (footer) => Header_Body_Footer_Modal(header, body, footer),
};
};
const Header_Body_Footer_Modal = (
header: string,
body: string,
footer: string
): Modal<ModalType.header_body_footer> => {
return {
kind: ModalType.header_body_footer,
header,
body,
footer,
renderable: true,
};
};
const Modal = Default_Modal;
const render = (elem: Renderable) => {};
const UI = VStack(
VStack(
Text("Detail Page").font("font name").bold()
),
VStack(
VStack(
Text("Product Title")
)
),
Modal()
.text("modal text"),
Modal()
.header("my header")
.body("my body")
.footer("my footer")
);
render(UI)
// uncomment to see type error
// render(Modal())
// render(Modal().text(''))
// render(Modal().header('xxx'))
@Lucifier129
Copy link
Author

it's similar to graphql

query UI {
  text(text: "my text") {
    view
  }
  header(header: "my header") {
    body(body: "my body") {
      footer(footer: "my footer") {
        view
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment