mirror of
https://github.com/nvms/soma3.git
synced 2025-12-15 15:10:53 +00:00
390 lines
11 KiB
TypeScript
390 lines
11 KiB
TypeScript
import { App } from ".";
|
|
import { computed } from "./reactivity/computed";
|
|
import { reactive } from "./reactivity/reactive";
|
|
import { ref } from "./reactivity/ref";
|
|
import { html } from "./util";
|
|
|
|
// ------------------------------------------------
|
|
// Slots, multiple default and named, :if and :for
|
|
// const card = {
|
|
// template: html`<div>
|
|
// <h3><slot /></h3>
|
|
// <slot name="body" />
|
|
// </div>`,
|
|
// };
|
|
|
|
// const main = {
|
|
// template: html`
|
|
// <div>
|
|
// <h1>card below</h1>
|
|
// <card>
|
|
// card title
|
|
// <template slot="body">Card body content</template>
|
|
// </card>
|
|
// </div>
|
|
// `,
|
|
// };
|
|
|
|
// const app = new App();
|
|
// app.register("card", card);
|
|
// app.mount(main, "#app");
|
|
|
|
// ------------------------------------------------
|
|
// Slots, multiple default and named, :if and :for
|
|
const app = new App();
|
|
|
|
const parent = {
|
|
template: html`
|
|
<div>
|
|
<h1>parent, bool: {{bool}}</h1>
|
|
<card>
|
|
<!-- default -->
|
|
<div :if="bool">
|
|
<div :teleport="body" id="teleported">
|
|
<div>showing 1-3 because bool is true</div>
|
|
<div>1</div>
|
|
<div>2</div>
|
|
<div>3</div>
|
|
</div>
|
|
</div>
|
|
content 1 always shown
|
|
<div :if="bool">
|
|
content 2, animals:
|
|
<div :for="animal in animals">animal: {{animal}}</div>
|
|
</div>
|
|
|
|
<!-- body -->
|
|
<template slot="body">card body from parent</template>
|
|
</card>
|
|
</div>
|
|
`,
|
|
main() {
|
|
const bool = ref(true);
|
|
const animals = reactive(["dog", "cat", "bear"]);
|
|
|
|
setInterval(() => {
|
|
bool.value = !bool.value;
|
|
}, 2000);
|
|
|
|
return { bool, animals };
|
|
},
|
|
};
|
|
const card = {
|
|
template: html`<div>
|
|
<h2>card</h2>
|
|
<h3><slot /></h3>
|
|
<slot name="body" />
|
|
</div>`,
|
|
};
|
|
app.register("card", card);
|
|
const parentBlock = app.mount(parent, "body");
|
|
const cardBlock = parentBlock.context.blocks[0];
|
|
|
|
// ------------------------------------------------
|
|
// Component pros, mirror and spread, bind and no bind
|
|
// const child = {
|
|
// template: html`<div>Animal: {{animal}} {{index}}</div>`,
|
|
// props: { animal: { default: "cat" }, index: { default: 0 } },
|
|
// main({ animal, index }) {
|
|
// return { animal, index };
|
|
// },
|
|
// };
|
|
|
|
// const parent = {
|
|
// template: html`
|
|
// <div class="sans-serif">
|
|
// <child :if="true" :for="x in list" />
|
|
// mirror, no bind:
|
|
// <child {animal} />
|
|
// <hr />
|
|
// mirror, bind:
|
|
// <child {animal:bind} />
|
|
// <hr />
|
|
// spread, no bind:
|
|
// <child ...spread />
|
|
// <hr />
|
|
// spread, bind:
|
|
// <child ...spread:bind />
|
|
// <hr />
|
|
// regular prop:
|
|
// <child .animal="animal" />
|
|
// <hr />
|
|
// regular prop, bind:
|
|
// <child .animal:bind="animal" />
|
|
// <hr />
|
|
// <div .id="animal">div has "id" set to animal.value</div>
|
|
// <hr />
|
|
// <div .id:bind="animal">div has "id" set and bound to animal.value</div>
|
|
// <hr />
|
|
// <div {animal}>div has "animal" set to animal.value</div>
|
|
// <hr />
|
|
// <div {animal:bind}>div has "animal" set and bound to animal.value</div>
|
|
// <hr />
|
|
// <div ...spread>div has "animal" spread</div>
|
|
// <hr />
|
|
// <div ...spread:bind>div has "animal" spread and bound</div>
|
|
// <hr />
|
|
// <hr />
|
|
// <hr />
|
|
// <hr />
|
|
// if bool, mirror, no bind:
|
|
// <child :if="bool" {animal} />
|
|
// if bool, mirror, bind:
|
|
// <child :if="bool" {animal:bind} />
|
|
// <hr />
|
|
// for list, mirror, no bind:
|
|
// <child :for="item in list" {animal} />
|
|
// <hr />
|
|
// for list, mirror, bind:
|
|
// <child :for="item in list" {animal:bind} />
|
|
// if bool, for list, mirror, no bind: these have the value "DOG!" because by the time for :for directive is evaluated, animal.value is "DOG!", and no longer "dog".
|
|
// <div :if="bool">
|
|
// <child :for="item in list" {animal} />
|
|
// </div>
|
|
// </div>
|
|
// `,
|
|
// main() {
|
|
// const bool = ref(false);
|
|
// const animal = ref("dog");
|
|
// const spread = reactive({ animal: "panther" });
|
|
// const list = reactive([1, 2, 3]);
|
|
|
|
// setTimeout(() => {
|
|
// spread.animal = "PANTHER!";
|
|
// animal.value = "DOG!";
|
|
// bool.value = true;
|
|
// }, 500);
|
|
|
|
// setTimeout(() => {
|
|
// animal.value = "DOG!!!!!";
|
|
// }, 1000);
|
|
|
|
// return { animal, spread, bool, list };
|
|
// },
|
|
// };
|
|
|
|
// const app = new App();
|
|
// app.register("child", child);
|
|
// app.mount(parent, "#app");
|
|
|
|
// ------------------------------------------------
|
|
// Event directive
|
|
// const counter = {
|
|
// template: html`
|
|
// <div class="sans-serif">
|
|
// <div :teleport="body">
|
|
// <div :if="style.color === 'gray'">color is gray</div>
|
|
// <div :if="style.color === 'white'">color is white</div>
|
|
// <div>{{style.color}}</div>
|
|
// </div>
|
|
// <h3 {style:bind}>Count: {{count}}{{count >= 2 ? '!!!' : ''}}</h3>
|
|
// <button @click="increment" class="padding-x-1 padding-y-0_5">+</button>
|
|
// <button @click="decrement" class="padding-x-1 padding-y-0_5">-</button>
|
|
// <div :teleport="body">
|
|
// <div :for="color in ['red', 'green', 'blue']">{{color}}</div>
|
|
// </div>
|
|
// </div>
|
|
// `,
|
|
// main() {
|
|
// const count = ref(0);
|
|
// const style = reactive({ color: "gray" });
|
|
// const increment = () => count.value++;
|
|
// const decrement = () => count.value--;
|
|
|
|
// setInterval(() => {
|
|
// style.color = style.color === "gray" ? "white" : "gray";
|
|
// }, 500);
|
|
|
|
// return { count, increment, decrement, style };
|
|
// },
|
|
// };
|
|
|
|
// const app = new App();
|
|
// app.mount(counter, "#app");
|
|
|
|
// ------------------------------------------------
|
|
// :if above :for
|
|
// :if with :teleport
|
|
// const main = {
|
|
// template: html`
|
|
// <div>
|
|
// <div :if="bool">
|
|
// <div :teleport="body">
|
|
// <div :for="item in items">{{item}}</div>
|
|
// </div>
|
|
// </div>
|
|
// <div :if="bool">
|
|
// <div :teleport="body">if bool teleported! {{items}}</div>
|
|
// </div>
|
|
// </div>
|
|
// `,
|
|
// main() {
|
|
// const items = reactive([1, 2, 3, 4, 5]);
|
|
// const bool = ref(true);
|
|
// setInterval(() => (bool.value = !bool.value), 2050);
|
|
// return { items, bool };
|
|
// },
|
|
// };
|
|
|
|
// const app = new App();
|
|
// app.mount(main, "#app");
|
|
|
|
// ------------------------------------------------
|
|
// :html
|
|
// const main = {
|
|
// template: html`<div :html="html"></div>`,
|
|
// main() {
|
|
// const html = ref("<h1>hello</h1>");
|
|
|
|
// setTimeout(() => {
|
|
// if (html.value === "<h1>hello</h1>") {
|
|
// html.value = "<h1>world</h1>";
|
|
// }
|
|
// }, 1000);
|
|
|
|
// return { html };
|
|
// },
|
|
// };
|
|
|
|
// const app = new App();
|
|
// app.mount(main, "#app");
|
|
|
|
// ------------------------------------------------
|
|
// Colors from css framework
|
|
// const main = {
|
|
// template: html`
|
|
// <div class="sans-serif margin-y-3 container" style="--column-gap: .5rem; --row-gap: .5rem;">
|
|
// <h1 class="f1 margin-bottom-1 color-60">phase</h1>
|
|
// <h2 class="f3 margin-bottom-1 color-peach-50">Colors</h2>
|
|
// <grid columns="6" class="f6 white-space-nowrap">
|
|
// <div :for="variant in ['base', 'accent', 'red', 'rose', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'lavender', 'violet', 'purple', 'plum', 'fuchsia', 'pink', 'peach']" class="border-color-30 border-2px">
|
|
// <div :for="rank, index in ranks">
|
|
// <div .style:bind="bg(variant, rank, index)" class="padding-1">{{variant}}-{{rank}}</div>
|
|
// </div>
|
|
// </div>
|
|
// </grid>
|
|
// </div>
|
|
// `,
|
|
// main() {
|
|
// const ranks = reactive(["5", "10", "20", "30", "40", "50", "60", "70", "80", "90"]);
|
|
// const basesReverse = computed(() => Array.from(ranks).reverse());
|
|
// const bg = (variant: string, rank: string, index: number) => ({ backgroundColor: `var(--${variant}-${rank})`, color: `var(--${variant}-${basesReverse.value[index]})` });
|
|
//
|
|
// return { ranks, bg };
|
|
// },
|
|
// };
|
|
//
|
|
// const app = new App();
|
|
// app.mount(main, "#app");
|
|
|
|
// ------------------------------------------------
|
|
// :scope
|
|
// const child = {
|
|
// template: html`
|
|
// <div>
|
|
// I am child and I have a cheeseburger: "{{food}}" (does not inherit)
|
|
// <div>
|
|
// <slot />
|
|
// </div>
|
|
// </div>
|
|
// `,
|
|
// main() {
|
|
// // Comment this out to implicitly inherit the
|
|
// // provided :scope value from the parent.
|
|
// const food = ref("🍔");
|
|
// return { food };
|
|
// },
|
|
// };
|
|
//
|
|
// const main = {
|
|
// template: html`
|
|
// <div class="hero sans-serif f2" :scope:provide="{ drink: '🍹' }">
|
|
// <div :scope:provide="{ food: '🍕' }">
|
|
// <div>Parent has pizza: {{food}} and scoped drink: {{drink}}</div>
|
|
// <child>Child slot, food: {{food}} {{drink}}</child>
|
|
// </div>
|
|
// </div>
|
|
// `,
|
|
// main() {
|
|
// // return { food: ref("nothing") };
|
|
// },
|
|
// };
|
|
//
|
|
// const app = new App();
|
|
// app.register("child", child);
|
|
// app.mount(main, "#app");
|
|
|
|
// ------------------------------------------------
|
|
// Practical :scope demo
|
|
// const main = {
|
|
// template: html`
|
|
// <div class="hero sans-serif f2" :scope="{ visible: true }">
|
|
// <div :show="visible">ON</div>
|
|
// <div :show="!visible">OFF</div>
|
|
// <button @click="visible = !visible" class="padding-x-1 padding-y-0_5 border-radius-0_25">Toggle</button>
|
|
// <div>visible: {{visible}} / foo: {{foo}}</div>
|
|
// </div>
|
|
// `,
|
|
// main() {
|
|
// const foo = ref("bar");
|
|
// return { foo };
|
|
// },
|
|
// };
|
|
|
|
// const app = new App();
|
|
// app.mount(main, "#app");
|
|
|
|
// --------
|
|
// weird issue
|
|
// const child = {
|
|
// template: html`<div>child{{thing}}</div>`,
|
|
// props: { thing: { default: 1 } },
|
|
// main({ thing }) {
|
|
// return { thing };
|
|
// },
|
|
// };
|
|
//
|
|
// const counter = {
|
|
// template: html`
|
|
// <div class="sans-serif">
|
|
// <div :if="true">
|
|
// <div :teleport="body">
|
|
// <div :for="color in colors">{{color}}</div>
|
|
// </div>
|
|
// <child :teleport="body" .thing="5" />
|
|
// </div>
|
|
// </div>
|
|
// `,
|
|
// main() {
|
|
// const colors = reactive(["red", "orange"]);
|
|
// return { colors };
|
|
// },
|
|
// };
|
|
//
|
|
// const app = new App();
|
|
// app.register("child", child);
|
|
// app.mount(counter, "#app");
|
|
|
|
// ------------------------------------------------
|
|
// <template>
|
|
// const templateTest = {
|
|
// template: html`
|
|
// <div>
|
|
// <!-- is dissolved -->
|
|
// <div :if="bool">hello</div>
|
|
//
|
|
// <template :if="bool">
|
|
// <span :for="num in [1,2,3]">{{num}}</span>
|
|
// </template>
|
|
// </div>
|
|
// `,
|
|
// main() {
|
|
// const bool = ref(true);
|
|
//
|
|
// return { bool };
|
|
// },
|
|
// };
|
|
//
|
|
// const app = new App();
|
|
// app.mount(templateTest, "#app");
|