@benev/slate
Advanced tools
Comparing version 0.0.0-dev.4 to 0.0.0-dev.5
{ | ||
"name": "@benev/slate", | ||
"version": "0.0.0-dev.4", | ||
"version": "0.0.0-dev.5", | ||
"description": "frontend web stuff", | ||
@@ -26,3 +26,3 @@ "license": "MIT", | ||
"@benev/turtle": "^0.5.0", | ||
"@rollup/plugin-node-resolve": "^15.2.1", | ||
"@rollup/plugin-node-resolve": "^15.2.2", | ||
"chokidar": "^3.5.3", | ||
@@ -35,4 +35,4 @@ "chokidar-cli": "^3.0.0", | ||
"npm-run-all": "^4.1.5", | ||
"rollup": "^3.29.1", | ||
"terser": "^5.19.4", | ||
"rollup": "^4.0.0", | ||
"terser": "^5.21.0", | ||
"typescript": "^5.2.2" | ||
@@ -39,0 +39,0 @@ }, |
@@ -24,5 +24,5 @@ | ||
1. install slate into your project | ||
1. install slate (and lit) into your project | ||
```sh | ||
npm i @benev/slate | ||
npm i @benev/slate lit | ||
``` | ||
@@ -34,3 +34,3 @@ 1. establish a "context" for your app | ||
export class Context extends BaseContext { | ||
export class Context implements BaseContext { | ||
@@ -83,3 +83,3 @@ // state management system | ||
// component auto rerenders on state changes | ||
#increment => () => { | ||
#increment = () => { | ||
this.#state.count++ | ||
@@ -129,3 +129,3 @@ } | ||
#increment => () => { | ||
#increment = () => { | ||
this.#state.count++ | ||
@@ -132,0 +132,0 @@ } |
@@ -44,11 +44,11 @@ | ||
case String: | ||
return raw | ||
return raw ?? undefined | ||
case Number: | ||
return raw && Number(raw) | ||
return raw !== null | ||
? Number(raw) | ||
: undefined | ||
case Boolean: | ||
return raw | ||
? raw !== "false" | ||
: false | ||
return raw !== null | ||
@@ -55,0 +55,0 @@ default: |
export class MetallicElement extends HTMLElement { | ||
import {mixinSetups} from "./mixin_setups.js" | ||
#setups = new Set<() => () => void>() | ||
.add(() => this.setup()) | ||
export class MetallicElement extends mixinSetups(HTMLElement) {} | ||
#setdowns = new Set<() => void>() | ||
register_setup(setup: () => () => void) { | ||
this.#setups.add(setup) | ||
} | ||
setup() { | ||
return () => {} | ||
} | ||
connectedCallback() { | ||
for (const setup of this.#setups) | ||
this.#setdowns.add(setup()) | ||
} | ||
disconnectedCallback() { | ||
for (const setdown of this.#setdowns) | ||
setdown() | ||
this.#setdowns.clear() | ||
} | ||
} | ||
@@ -31,3 +31,4 @@ | ||
export * from "./view/shale.js" | ||
export * from "./view/clay.js" | ||
export * from "./view/parts/types.js" | ||
@@ -6,6 +6,7 @@ | ||
import {Flat} from "../flatstate/flat.js" | ||
import {ClayViewClass} from "../view/clay.js" | ||
import {apply} from "../base/helpers/apply.js" | ||
import {View} from "../view/parts/types.js" | ||
import {BaseElementClass} from "../base/element.js" | ||
import {ShaleViewClass, shale_view} from "../view/shale.js" | ||
import {ShaleView, ShaleViewClass} from "../view/shale.js" | ||
import {LightView, View, ViewParams} from "../view/parts/types.js" | ||
import {requirement, RequirementGroup, RequirementGroupProvided} from "../tools/requirement.js" | ||
@@ -17,30 +18,38 @@ | ||
export const prepare_frontend = <C extends BaseContext>() => { | ||
export const prepare_frontend = <C extends BaseContext>() => ({ | ||
component: <E extends BaseElementClass>(fun: (context: C) => E) => fun, | ||
return ({ | ||
component: <E extends BaseElementClass>(fun: (context: C) => E) => fun, | ||
components: <E extends RequirementGroup<C, BaseElementClass>>( | ||
context: C, | ||
elements: E | ||
) => ( | ||
Pipe.with(elements) | ||
.to(requirement.provide(context)) | ||
.to(apply.flat(context.flat)) | ||
.to(apply.theme(context.theme)) | ||
.done() as RequirementGroupProvided<E> | ||
), | ||
components: <E extends RequirementGroup<C, BaseElementClass>>( | ||
context: C, | ||
elements: E | ||
) => ( | ||
Pipe.with(elements) | ||
.to(requirement.provide(context)) | ||
.to(apply.flat(context.flat)) | ||
.to(apply.theme(context.theme)) | ||
.done() as RequirementGroupProvided<E> | ||
), | ||
view: <V extends (ShaleViewClass | ClayViewClass)>( | ||
fun: (context: C) => V | ||
) => (context: C): V extends ShaleViewClass ? View<ViewParams<V>> : LightView<ViewParams<V>> => { | ||
view: <V extends ShaleViewClass>(fun: (context: C) => V) => (context: C) => shale_view({ | ||
View: fun(context), | ||
flat: context.flat, | ||
theme: context.theme, | ||
}), | ||
const {flat, theme} = context | ||
const UnknownView = fun(context) | ||
views: <V extends RequirementGroup<C, View<any>>>( | ||
context: C, | ||
viewgroup: V, | ||
) => requirement.provide(context)(viewgroup), | ||
}) | ||
} | ||
if (UnknownView.prototype instanceof ShaleView) { | ||
const View = UnknownView as ShaleViewClass | ||
return View.directive(View, {flat, theme}) as any | ||
} | ||
else { | ||
const View = UnknownView as ClayViewClass | ||
return View.directive(View, {flat}) as any | ||
} | ||
}, | ||
views: <V extends RequirementGroup<C, View<any> | LightView<any>>>( | ||
context: C, | ||
viewgroup: V, | ||
) => requirement.provide(context)(viewgroup), | ||
}) | ||
import {css, html} from "lit" | ||
import {ClayView} from "./view/clay.js" | ||
import {Flat} from "./flatstate/flat.js" | ||
@@ -17,10 +19,2 @@ import {ShaleView} from "./view/shale.js" | ||
export const MyComponent = component(_ => class extends GoldElement { | ||
render() { | ||
} | ||
}) | ||
export type MyComponentClass = ComponentClass<typeof MyComponent> | ||
export type MyComponentInstance = ComponentInstance<typeof MyComponent> | ||
export const MyView = view(context => class extends ShaleView { | ||
@@ -38,2 +32,8 @@ static name = "my-view" | ||
export const MyClay = view(context => class extends ClayView { | ||
render(greeting: string) { | ||
return html`<p>${greeting}</p>` | ||
} | ||
}) | ||
export const MyView2 = view(context => class extends ShaleView { | ||
@@ -74,2 +74,20 @@ static name = "my-view-2" | ||
export const MyComponent = component(context => class extends GoldElement { | ||
#views = views(context, { | ||
MyView, | ||
MyView2, | ||
MyClay, | ||
}) | ||
render() { | ||
return html` | ||
${this.#views.MyView({props: [123]})} | ||
${this.#views.MyClay("hello")} | ||
` | ||
} | ||
}) | ||
export type MyComponentClass = ComponentClass<typeof MyComponent> | ||
export type MyComponentInstance = ComponentInstance<typeof MyComponent> | ||
const context = new Context() | ||
@@ -76,0 +94,0 @@ |
@@ -5,4 +5,14 @@ | ||
import {ViewUse} from "./use.js" | ||
import {BaseView} from "./base_view.js" | ||
import {Flat} from "../../flatstate/flat.js" | ||
export type ViewClass = { | ||
new(...p: any[]): BaseView | ||
directive: (...args: any[]) => any | ||
} | ||
export type ViewParams<V extends ViewClass> = ( | ||
Parameters<InstanceType<V>["render"]> | ||
) | ||
export type ViewAttributes = { | ||
@@ -38,4 +48,10 @@ [key: string]: string | number | boolean | undefined | ||
export type View<P extends any[]> = (data: ViewInputs<P>) => (TemplateResult | void) | ||
export type View<P extends any[]> = ( | ||
(data: ViewInputs<P>) => (TemplateResult | void) | ||
) | ||
export type LightView<P extends any[]> = ( | ||
(...props: P) => (TemplateResult | void) | ||
) | ||
export type ViewHooksSetupDetails<R> = { | ||
@@ -42,0 +58,0 @@ result: R |
import {AsyncDirective} from "lit/async-directive.js" | ||
import {CSSResultGroup, Part, TemplateResult} from "lit" | ||
import {CSSResultGroup, Part, TemplateResult, css} from "lit" | ||
import {Flat} from "../flatstate/flat.js" | ||
import {BaseView} from "./parts/base_view.js" | ||
import {make_view_root} from "./parts/root.js" | ||
import {ViewInputs, View} from "./parts/types.js" | ||
import {AsyncDirective} from "lit/async-directive.js" | ||
import {apply_details} from "./parts/apply_details.js" | ||
import {custom_directive_with_detail_input} from "./parts/custom_directive_with_detail_input.js" | ||
import {View, ViewInputs, ViewParams} from "./parts/types.js" | ||
import {custom_directive_with_detail_input} from "./parts/custom_directives.js" | ||
export abstract class ShaleView { | ||
static name: string | ||
static styles: CSSResultGroup | ||
abstract render(...args: any[]): TemplateResult | void | ||
export type ShaleViewClass = ({ | ||
new(...p: ConstructorParameters<typeof ShaleView>): ShaleView | ||
} & typeof ShaleView) | ||
export abstract class ShaleView extends BaseView { | ||
static name = "unknown" | ||
static styles: CSSResultGroup = css`` | ||
default_auto_exportparts = true | ||
#root: ReturnType<typeof make_view_root> | ||
@@ -21,2 +25,3 @@ #rerender: () => void | ||
constructor(root: ReturnType<typeof make_view_root>, rerender: () => void) { | ||
super() | ||
this.#root = root | ||
@@ -29,71 +34,78 @@ this.#rerender = rerender | ||
requestUpdate() { this.#rerender() } | ||
} | ||
abstract render(...props: any[]): TemplateResult | void | ||
export type ShaleViewClass = { | ||
new(...params: ConstructorParameters<typeof ShaleView>): ShaleView | ||
name: string | ||
styles: CSSResultGroup | ||
} | ||
static directive<V extends ShaleViewClass>( | ||
View: ShaleViewClass, | ||
{flat, theme}: { | ||
flat: Flat | ||
theme: CSSResultGroup | ||
}, | ||
) { | ||
export function shale_view<V extends ShaleViewClass>({flat, theme, View}: { | ||
flat: Flat | ||
theme: CSSResultGroup | ||
View: V | ||
}): View<Parameters<InstanceType<V>["render"]>> { | ||
type P = ViewParams<V> | ||
type P = Parameters<InstanceType<V>["render"]> | ||
return custom_directive_with_detail_input(class extends AsyncDirective { | ||
#recent_input?: ViewInputs<P> | ||
#rerender = () => { | ||
if (this.#recent_input) | ||
this.setValue( | ||
this.#root.render_into_shadow( | ||
this.render(this.#recent_input!) | ||
return custom_directive_with_detail_input(class extends AsyncDirective { | ||
#recent_input?: ViewInputs<P> | ||
#rerender = () => { | ||
if (this.#recent_input) | ||
this.setValue( | ||
this.#root.render_into_shadow( | ||
this.render(this.#recent_input!) | ||
) | ||
) | ||
) | ||
} | ||
#stop: (() => void) | undefined | ||
#root = make_view_root(View.name, [theme, View.styles]) | ||
#view = new View(this.#root, this.#rerender) | ||
} | ||
#stop: (() => void) | undefined | ||
#root = make_view_root(View.name, [theme, View.styles]) | ||
#view = new View(this.#root, this.#rerender) | ||
update(_: Part, props: [ViewInputs<P>]) { | ||
return this.#root.render_into_shadow(this.render(...props)) | ||
} | ||
constructor(...args: ConstructorParameters<typeof AsyncDirective>) { | ||
super(...args) | ||
this.#view.connectedCallback() | ||
} | ||
render(input: ViewInputs<P>) { | ||
apply_details(this.#root.container, input, this.#recent_input) | ||
this.#recent_input = input | ||
this.#root.auto_exportparts = ( | ||
input.auto_exportparts ?? this.#view.default_auto_exportparts | ||
) | ||
update(_: Part, props: [ViewInputs<P>]) { | ||
return this.#root.render_into_shadow(this.render(...props)) | ||
} | ||
if (this.#stop) | ||
this.#stop() | ||
render(input: ViewInputs<P>) { | ||
apply_details(this.#root.container, input, this.#recent_input) | ||
this.#recent_input = input | ||
this.#root.auto_exportparts = ( | ||
input.auto_exportparts ?? this.#view.default_auto_exportparts | ||
) | ||
let result: TemplateResult | void = undefined | ||
if (this.#stop) | ||
this.#stop() | ||
this.#stop = flat.manual({ | ||
debounce: true, | ||
discover: false, | ||
collector: () => { | ||
const props = this.#recent_input!.props | ||
result = this.#view.render(...props) | ||
}, | ||
responder: () => { | ||
this.#rerender() | ||
}, | ||
}) | ||
let result: TemplateResult | void = undefined | ||
return result | ||
} | ||
this.#stop = flat.manual({ | ||
debounce: true, | ||
discover: false, | ||
collector: () => { | ||
const props = this.#recent_input!.props | ||
result = this.#view.render(...props) | ||
}, | ||
responder: () => { | ||
this.#rerender() | ||
}, | ||
}) | ||
disconnected() { | ||
if (this.#stop) { | ||
this.#stop() | ||
this.#stop = undefined | ||
return result | ||
} | ||
} | ||
}) as View<P> | ||
disconnected() { | ||
this.#view.disconnectedCallback() | ||
if (this.#stop) { | ||
this.#stop() | ||
this.#stop = undefined | ||
} | ||
} | ||
reconnected() { | ||
this.#view.connectedCallback() | ||
} | ||
}) as View<P> | ||
} | ||
} | ||
@@ -10,9 +10,9 @@ import { ShaleView } from "../../view/shale.js"; | ||
case String: | ||
return raw; | ||
return raw ?? undefined; | ||
case Number: | ||
return raw && Number(raw); | ||
return raw !== null | ||
? Number(raw) | ||
: undefined; | ||
case Boolean: | ||
return raw | ||
? raw !== "false" | ||
: false; | ||
return raw !== null; | ||
default: | ||
@@ -19,0 +19,0 @@ throw new Error(`invalid attribute type for "${name}"`); |
@@ -1,7 +0,17 @@ | ||
export declare class MetallicElement extends HTMLElement { | ||
#private; | ||
register_setup(setup: () => () => void): void; | ||
setup(): () => void; | ||
connectedCallback(): void; | ||
disconnectedCallback(): void; | ||
declare const MetallicElement_base: { | ||
new (...args: any[]): { | ||
[x: string]: any; | ||
"__#7@#setups": Set<() => () => void>; | ||
"__#7@#setdowns": Set<() => void>; | ||
register_setup(setup: () => () => void): void; | ||
setup(): () => void; | ||
connectedCallback(): void; | ||
disconnectedCallback(): void; | ||
}; | ||
} & { | ||
new (): HTMLElement; | ||
prototype: HTMLElement; | ||
}; | ||
export declare class MetallicElement extends MetallicElement_base { | ||
} | ||
export {}; |
@@ -1,21 +0,4 @@ | ||
export class MetallicElement extends HTMLElement { | ||
#setups = new Set() | ||
.add(() => this.setup()); | ||
#setdowns = new Set(); | ||
register_setup(setup) { | ||
this.#setups.add(setup); | ||
} | ||
setup() { | ||
return () => { }; | ||
} | ||
connectedCallback() { | ||
for (const setup of this.#setups) | ||
this.#setdowns.add(setup()); | ||
} | ||
disconnectedCallback() { | ||
for (const setdown of this.#setdowns) | ||
setdown(); | ||
this.#setdowns.clear(); | ||
} | ||
import { mixinSetups } from "./mixin_setups.js"; | ||
export class MetallicElement extends mixinSetups(HTMLElement) { | ||
} | ||
//# sourceMappingURL=metallic.js.map |
@@ -24,2 +24,3 @@ export * from "./base/addons/attributes.js"; | ||
export * from "./view/shale.js"; | ||
export * from "./view/clay.js"; | ||
export * from "./view/parts/types.js"; |
@@ -24,3 +24,4 @@ export * from "./base/addons/attributes.js"; | ||
export * from "./view/shale.js"; | ||
export * from "./view/clay.js"; | ||
export * from "./view/parts/types.js"; | ||
//# sourceMappingURL=index.js.map |
import { CSSResultGroup } from "lit"; | ||
import { Flat } from "../flatstate/flat.js"; | ||
import { View } from "../view/parts/types.js"; | ||
import { ClayViewClass } from "../view/clay.js"; | ||
import { BaseElementClass } from "../base/element.js"; | ||
import { ShaleViewClass } from "../view/shale.js"; | ||
import { LightView, View, ViewParams } from "../view/parts/types.js"; | ||
import { RequirementGroup, RequirementGroupProvided } from "../tools/requirement.js"; | ||
@@ -16,4 +17,4 @@ export type BaseContext = { | ||
components: <E_1 extends RequirementGroup<C, BaseElementClass>>(context: C, elements: E_1) => RequirementGroupProvided<E_1>; | ||
view: <V extends ShaleViewClass>(fun: (context: C) => V) => (context: C) => View<Parameters<InstanceType<V>["render"]>>; | ||
views: <V_1 extends RequirementGroup<C, View<any>>>(context: C, viewgroup: V_1) => RequirementGroupProvided<V_1>; | ||
view: <V extends ShaleViewClass | ClayViewClass>(fun: (context: C) => V) => (context: C) => V extends ShaleViewClass ? View<ViewParams<V>> : LightView<ViewParams<V>>; | ||
views: <V_1 extends RequirementGroup<C, View<any> | LightView<any>>>(context: C, viewgroup: V_1) => RequirementGroupProvided<V_1>; | ||
}; |
import { Pipe } from "../tools/pipe.js"; | ||
import { apply } from "../base/helpers/apply.js"; | ||
import { shale_view } from "../view/shale.js"; | ||
import { ShaleView } from "../view/shale.js"; | ||
import { requirement } from "../tools/requirement.js"; | ||
export const prepare_frontend = () => { | ||
return ({ | ||
component: (fun) => fun, | ||
components: (context, elements) => Pipe.with(elements) | ||
.to(requirement.provide(context)) | ||
.to(apply.flat(context.flat)) | ||
.to(apply.theme(context.theme)) | ||
.done(), | ||
view: (fun) => (context) => shale_view({ | ||
View: fun(context), | ||
flat: context.flat, | ||
theme: context.theme, | ||
}), | ||
views: (context, viewgroup) => requirement.provide(context)(viewgroup), | ||
}); | ||
}; | ||
export const prepare_frontend = () => ({ | ||
component: (fun) => fun, | ||
components: (context, elements) => Pipe.with(elements) | ||
.to(requirement.provide(context)) | ||
.to(apply.flat(context.flat)) | ||
.to(apply.theme(context.theme)) | ||
.done(), | ||
view: (fun) => (context) => { | ||
const { flat, theme } = context; | ||
const UnknownView = fun(context); | ||
if (UnknownView.prototype instanceof ShaleView) { | ||
const View = UnknownView; | ||
return View.directive(View, { flat, theme }); | ||
} | ||
else { | ||
const View = UnknownView; | ||
return View.directive(View, { flat }); | ||
} | ||
}, | ||
views: (context, viewgroup) => requirement.provide(context)(viewgroup), | ||
}); | ||
//# sourceMappingURL=frontend.js.map |
@@ -7,5 +7,14 @@ import { Flat } from "./flatstate/flat.js"; | ||
} | ||
export declare const MyView: (context: Context) => import("./index.js").View<[count: number]>; | ||
export declare const MyClay: (context: Context) => import("./index.js").LightView<[greeting: string]>; | ||
export declare const MyView2: (context: Context) => import("./index.js").View<[]>; | ||
export declare const MyComponent: (context: Context) => { | ||
new (): { | ||
render(): void; | ||
[x: string]: any; | ||
"__#18@#views": import("./index.js").RequirementGroupProvided<{ | ||
MyView: (context: Context) => import("./index.js").View<[count: number]>; | ||
MyView2: (context: Context) => import("./index.js").View<[]>; | ||
MyClay: (context: Context) => import("./index.js").LightView<[greeting: string]>; | ||
}>; | ||
render(): import("lit-html").TemplateResult<1>; | ||
"__#12@#root": ShadowRoot; | ||
@@ -24,4 +33,4 @@ "__#12@#init"?: { | ||
connectedCallback(): void; | ||
"__#11@#setups": Set<() => () => void>; | ||
"__#11@#setdowns": Set<() => void>; | ||
"__#7@#setups": Set<() => () => void>; | ||
"__#7@#setdowns": Set<() => void>; | ||
register_setup(setup: () => () => void): void; | ||
@@ -357,3 +366,1 @@ setup(): () => void; | ||
export type MyComponentInstance = ComponentInstance<typeof MyComponent>; | ||
export declare const MyView: (context: Context) => import("./index.js").View<[count: number]>; | ||
export declare const MyView2: (context: Context) => import("./index.js").View<[]>; |
import { css, html } from "lit"; | ||
import { ClayView } from "./view/clay.js"; | ||
import { Flat } from "./flatstate/flat.js"; | ||
@@ -13,6 +14,2 @@ import { ShaleView } from "./view/shale.js"; | ||
const { component, components, view, views } = prepare_frontend(); | ||
export const MyComponent = component(_ => class extends GoldElement { | ||
render() { | ||
} | ||
}); | ||
export const MyView = view(context => class extends ShaleView { | ||
@@ -28,2 +25,7 @@ static name = "my-view"; | ||
}); | ||
export const MyClay = view(context => class extends ClayView { | ||
render(greeting) { | ||
return html `<p>${greeting}</p>`; | ||
} | ||
}); | ||
export const MyView2 = view(context => class extends ShaleView { | ||
@@ -58,4 +60,17 @@ static name = "my-view-2"; | ||
}); | ||
export const MyComponent = component(context => class extends GoldElement { | ||
#views = views(context, { | ||
MyView, | ||
MyView2, | ||
MyClay, | ||
}); | ||
render() { | ||
return html ` | ||
${this.#views.MyView({ props: [123] })} | ||
${this.#views.MyClay("hello")} | ||
`; | ||
} | ||
}); | ||
const context = new Context(); | ||
register_to_dom(components(context, { MyComponent })); | ||
//# sourceMappingURL=sketch.js.map |
import { CSSResultGroup, TemplateResult } from "lit"; | ||
import { ViewUse } from "./use.js"; | ||
import { BaseView } from "./base_view.js"; | ||
import { Flat } from "../../flatstate/flat.js"; | ||
export type ViewClass = { | ||
new (...p: any[]): BaseView; | ||
directive: (...args: any[]) => any; | ||
}; | ||
export type ViewParams<V extends ViewClass> = (Parameters<InstanceType<V>["render"]>); | ||
export type ViewAttributes = { | ||
@@ -27,3 +33,4 @@ [key: string]: string | number | boolean | undefined; | ||
}; | ||
export type View<P extends any[]> = (data: ViewInputs<P>) => (TemplateResult | void); | ||
export type View<P extends any[]> = ((data: ViewInputs<P>) => (TemplateResult | void)); | ||
export type LightView<P extends any[]> = ((...props: P) => (TemplateResult | void)); | ||
export type ViewHooksSetupDetails<R> = { | ||
@@ -30,0 +37,0 @@ result: R; |
import { CSSResultGroup, TemplateResult } from "lit"; | ||
import { Flat } from "../flatstate/flat.js"; | ||
import { BaseView } from "./parts/base_view.js"; | ||
import { make_view_root } from "./parts/root.js"; | ||
import { View } from "./parts/types.js"; | ||
export declare abstract class ShaleView { | ||
import { View, ViewParams } from "./parts/types.js"; | ||
export type ShaleViewClass = ({ | ||
new (...p: ConstructorParameters<typeof ShaleView>): ShaleView; | ||
} & typeof ShaleView); | ||
export declare abstract class ShaleView extends BaseView { | ||
#private; | ||
static name: string; | ||
static styles: CSSResultGroup; | ||
abstract render(...args: any[]): TemplateResult | void; | ||
default_auto_exportparts: boolean; | ||
@@ -15,12 +18,7 @@ constructor(root: ReturnType<typeof make_view_root>, rerender: () => void); | ||
requestUpdate(): void; | ||
abstract render(...props: any[]): TemplateResult | void; | ||
static directive<V extends ShaleViewClass>(View: ShaleViewClass, { flat, theme }: { | ||
flat: Flat; | ||
theme: CSSResultGroup; | ||
}): View<ViewParams<V>>; | ||
} | ||
export type ShaleViewClass = { | ||
new (...params: ConstructorParameters<typeof ShaleView>): ShaleView; | ||
name: string; | ||
styles: CSSResultGroup; | ||
}; | ||
export declare function shale_view<V extends ShaleViewClass>({ flat, theme, View }: { | ||
flat: Flat; | ||
theme: CSSResultGroup; | ||
View: V; | ||
}): View<Parameters<InstanceType<V>["render"]>>; |
@@ -0,8 +1,10 @@ | ||
import { css } from "lit"; | ||
import { BaseView } from "./parts/base_view.js"; | ||
import { make_view_root } from "./parts/root.js"; | ||
import { AsyncDirective } from "lit/async-directive.js"; | ||
import { make_view_root } from "./parts/root.js"; | ||
import { apply_details } from "./parts/apply_details.js"; | ||
import { custom_directive_with_detail_input } from "./parts/custom_directive_with_detail_input.js"; | ||
export class ShaleView { | ||
static name; | ||
static styles; | ||
import { custom_directive_with_detail_input } from "./parts/custom_directives.js"; | ||
export class ShaleView extends BaseView { | ||
static name = "unknown"; | ||
static styles = css ``; | ||
default_auto_exportparts = true; | ||
@@ -12,2 +14,3 @@ #root; | ||
constructor(root, rerender) { | ||
super(); | ||
this.#root = root; | ||
@@ -19,44 +22,52 @@ this.#rerender = rerender; | ||
requestUpdate() { this.#rerender(); } | ||
} | ||
export function shale_view({ flat, theme, View }) { | ||
return custom_directive_with_detail_input(class extends AsyncDirective { | ||
#recent_input; | ||
#rerender = () => { | ||
if (this.#recent_input) | ||
this.setValue(this.#root.render_into_shadow(this.render(this.#recent_input))); | ||
}; | ||
#stop; | ||
#root = make_view_root(View.name, [theme, View.styles]); | ||
#view = new View(this.#root, this.#rerender); | ||
update(_, props) { | ||
return this.#root.render_into_shadow(this.render(...props)); | ||
} | ||
render(input) { | ||
apply_details(this.#root.container, input, this.#recent_input); | ||
this.#recent_input = input; | ||
this.#root.auto_exportparts = (input.auto_exportparts ?? this.#view.default_auto_exportparts); | ||
if (this.#stop) | ||
this.#stop(); | ||
let result = undefined; | ||
this.#stop = flat.manual({ | ||
debounce: true, | ||
discover: false, | ||
collector: () => { | ||
const props = this.#recent_input.props; | ||
result = this.#view.render(...props); | ||
}, | ||
responder: () => { | ||
this.#rerender(); | ||
}, | ||
}); | ||
return result; | ||
} | ||
disconnected() { | ||
if (this.#stop) { | ||
this.#stop(); | ||
this.#stop = undefined; | ||
static directive(View, { flat, theme }) { | ||
return custom_directive_with_detail_input(class extends AsyncDirective { | ||
#recent_input; | ||
#rerender = () => { | ||
if (this.#recent_input) | ||
this.setValue(this.#root.render_into_shadow(this.render(this.#recent_input))); | ||
}; | ||
#stop; | ||
#root = make_view_root(View.name, [theme, View.styles]); | ||
#view = new View(this.#root, this.#rerender); | ||
constructor(...args) { | ||
super(...args); | ||
this.#view.connectedCallback(); | ||
} | ||
} | ||
}); | ||
update(_, props) { | ||
return this.#root.render_into_shadow(this.render(...props)); | ||
} | ||
render(input) { | ||
apply_details(this.#root.container, input, this.#recent_input); | ||
this.#recent_input = input; | ||
this.#root.auto_exportparts = (input.auto_exportparts ?? this.#view.default_auto_exportparts); | ||
if (this.#stop) | ||
this.#stop(); | ||
let result = undefined; | ||
this.#stop = flat.manual({ | ||
debounce: true, | ||
discover: false, | ||
collector: () => { | ||
const props = this.#recent_input.props; | ||
result = this.#view.render(...props); | ||
}, | ||
responder: () => { | ||
this.#rerender(); | ||
}, | ||
}); | ||
return result; | ||
} | ||
disconnected() { | ||
this.#view.disconnectedCallback(); | ||
if (this.#stop) { | ||
this.#stop(); | ||
this.#stop = undefined; | ||
} | ||
} | ||
reconnected() { | ||
this.#view.connectedCallback(); | ||
} | ||
}); | ||
} | ||
} | ||
//# sourceMappingURL=shale.js.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
231461
243
4638