Skip to content

Commit

Permalink
Refine @sgrud/shell/component prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
schlusslicht committed Mar 22, 2022
1 parent 00ee496 commit b962e4b
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 37 deletions.
6 changes: 3 additions & 3 deletions packages/shell/index.ts
Expand Up @@ -4,7 +4,7 @@
* @packageDocumentation
*/

export * from './src/element/attribute';
export * from './src/element/component';
export * from './src/element/jsx-runtime';
export * from './src/component/attribute';
export * from './src/component/component';
export * from './src/component/jsx-runtime';
export * from './src/router/router';
File renamed without changes.
@@ -1,4 +1,5 @@
import { elementClose, elementOpen, patch, text } from 'incremental-dom';
import { patch } from 'incremental-dom';
import { createElement } from './jsx-runtime';

/**
* Interface describing the shape of a component.
Expand Down Expand Up @@ -107,22 +108,24 @@ export function Component<S extends keyof HTMLElementTagNameMap>(
if (super.renderComponent) {
super.renderComponent();
} else if (this.shadowRoot) {
const { styles, template } = this;
const {
styles = [],
template = []
} = this;

patch(this.shadowRoot, () => {
if (styles) {
elementOpen('style');
text(styles.join(' '));
elementClose('style');
}
if (!template.length) {
template.push(...createElement('slot'));
}

if (template) {
for (const factory of template) {
factory();
}
} else {
elementOpen('slot');
elementClose('slot');
if (styles.length) {
template.push(...createElement('style', {
children: styles
}));
}

patch(this.shadowRoot, () => {
for (const incrementalDom of template) {
incrementalDom();
}
});
}
Expand Down
@@ -1,11 +1,10 @@
import { TypeOf } from '@sgrud/core';
import { elementClose, elementOpen, Key, text } from 'incremental-dom';
import { elementClose, elementOpen, text } from 'incremental-dom';

declare global {

/**
* Intrinsic JSX namespace containing the list of {@link IntrinsicElements}
* and the JSX {@link Element} type.
* Intrinsic JSX namespace.
*
* @see https://www.typescriptlang.org/docs/handbook/jsx.html
*/
Expand All @@ -18,12 +17,12 @@ declare global {
type Element = (() => Node)[];

/**
* Intrinsic list of JSX elements. Uses the global `HTMLElementTagNameMap`
* while allowing to specify an element rendering key.
* Intrinsic list of known JSX elements, comprised of the global
* `HTMLElementTagNameMap`.
*/
type IntrinsicElements = {
[K in keyof HTMLElementTagNameMap]: Partial<HTMLElementTagNameMap[K]> & {
key?: Key;
key?: string | number | null;
};
};

Expand All @@ -35,20 +34,20 @@ declare global {
* @param type - Element type.
* @param props - Element properties.
* @param ref - Element rendering key.
* @returns Array of `incremental-dom` calls.
* @returns Array of bound calls.
*/
export function createElement(
type: keyof JSX.IntrinsicElements | Function,
props?: Record<string, any>,
ref?: Key
ref?: string | number | null
): JSX.Element {
if (TypeOf.function(type)) {
return type(props);
}

const attributes = [];
const children = [];
const elements = [];
const element = [];

for (const key in props) {
switch (key) {
Expand All @@ -70,30 +69,37 @@ export function createElement(
}
}

elements.push(elementOpen.bind(null, type, ref, null, ...attributes));
element.push(elementOpen.bind(null, type, ref, null, ...attributes));

for (const child of children) {
if (TypeOf.function(child)) {
elements.push(child);
element.push(child);
} else {
elements.push(text.bind(null, child));
element.push(text.bind(null, child));
}
}

elements.push(elementClose.bind(null, type));
element.push(elementClose.bind(null, type));

return elements;
return element;
}

/**
* @param props - Fragment properties.
* @returns Array of `incremental-dom` calls.
* @returns Array of bound calls.
*/
export function createFragment(props?: Record<string, any>): JSX.Element {
return props?.children ? [props.children].flat(Infinity).filter(Boolean) : [];
const fragment = [];

if (props?.children) {
fragment.push(...[props.children].flat(Infinity).filter(Boolean));
}

return fragment;
}

export {
JSX,
createElement as jsx,
createElement as jsxs,
createFragment as Fragment
Expand Down
Expand Up @@ -6,7 +6,7 @@ globalThis.HTMLElement = new Proxy(HTMLElement, {
}
});

describe('@sgrud/shell/element/attribute', () => {
describe('@sgrud/shell/component/attribute', () => {

class TestClass extends HTMLElement {
@Attribute() public attribute?: string;
Expand Down
Expand Up @@ -6,7 +6,7 @@ globalThis.HTMLElement = new Proxy(HTMLElement, {
}
});

describe('@sgrud/shell/element/component', () => {
describe('@sgrud/shell/component/component', () => {

@Component('class-one')
class ClassOne extends HTMLElement { }
Expand Down
@@ -1,6 +1,6 @@
import { Fragment, jsx } from '@sgrud/shell';

describe('@sgrud/shell/element/jsx-runtime', () => {
describe('@sgrud/shell/component/jsx-runtime', () => {

describe('creating a jsx element', () => {
const jsxElement = jsx('main', {
Expand Down

0 comments on commit b962e4b

Please sign in to comment.