Skip to content

Instantly share code, notes, and snippets.

@namse
Created September 4, 2021 08:41
Show Gist options
  • Save namse/419fba3478bfb5cf0f12c1ecf2b57f53 to your computer and use it in GitHub Desktop.
Save namse/419fba3478bfb5cf0f12c1ecf2b57f53 to your computer and use it in GitHub Desktop.
export {};
// 주제 : multiple counter
// update -> render -> event handling -> 반복
type State = {
counters: {
count: number;
}[];
};
type BaseRenderingData = {
id: Symbol;
};
type TextRenderingData = {
type: "text";
value: string;
} & BaseRenderingData;
type RectRenderingData = {
type: "rect";
x: number;
y: number;
width: number;
height: number;
} & BaseRenderingData;
type RenderingData = TextRenderingData | RectRenderingData;
type RenderingDataTree = (RenderingData | RenderingDataTree)[];
function index(state: State): RenderingDataTree {
return [
state.counters.map((counterState) =>
Counter({
state: counterState,
onRemove: () => {
// case 1. remove by index
// problem - what if remove 2 counters, index 3 and 5? it will remove original 3, 6 counter.
// case 2. remove by reference
state.counters.remove(counterState);
},
})
),
Button({
x: 20,
y: 0,
width: 20,
height: 20,
text: "add counter",
onClick: () => {
state.counters.push({ count: 0 });
},
}),
];
}
function Counter({
state,
onRemove,
}: {
state: { count: number };
onRemove: () => void;
}): RenderingDataTree {
return [
TextComponent(state.count),
Button({
x: 20,
y: 0,
width: 20,
height: 20,
text: "+",
onClick: () => {
state.count += 1;
},
}),
Button({
x: 40,
y: 0,
width: 20,
height: 20,
text: "remove",
onClick: () => {
onRemove();
},
}),
];
}
function TextComponent(value: string | number): RenderingData {
return {
id: Symbol(),
type: "text",
value: value.toString(),
};
}
function Button({
x,
y,
width,
height,
text,
onClick,
}: {
x: number;
y: number;
width: number;
height: number;
text: string;
onClick: () => void; // 이것을 아래 Rect와 연결해야해
}): RenderingDataTree {
return [
Rect({
x,
y,
width,
height,
onClick,
}),
TextComponent(text),
];
}
function Rect({
x,
y,
width,
height,
onClick,
}: {
x: number;
y: number;
width: number;
height: number;
onClick?: () => void;
}): RenderingData {
const id = Symbol();
onClick && register(id, onClick);
return {
id,
type: "rect",
x,
y,
width,
height,
};
}
function register(id: symbol, onClick: () => void) {
throw new Error("Function not implemented.");
}
declare global {
interface Array<T> {
remove(o: T): void;
}
}
Array.prototype.remove = function (element) {
const index = this.indexOf(element);
if (index > -1) {
this.splice(index, 1);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment