Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Existing Effects & Refs #196

Merged
merged 10 commits into from
Jun 30, 2022
2 changes: 1 addition & 1 deletion integration-tests/test-app/focus-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const html = registerHtml();
*/
const focusInput: TramOneComponent = () => {
useEffect((ref) => {
(ref as unknown as HTMLElement).focus();
ref.focus();
});
return html`<input placeholder="Input for automatic focus" />`;
};
Expand Down
6 changes: 3 additions & 3 deletions src/dom-wrappers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { registerDom } from './dom';

import { Registry } from './types';
import { Registry, TramOneHTMLElement, TramOneSVGElement } from './types';

/**
* @name registerHtml
Expand All @@ -13,7 +13,7 @@ import { Registry } from './types';
* @return tagged template function that builds HTML components
*/
export const registerHtml = (registry?: Registry) => {
return registerDom(null, registry);
return registerDom<TramOneHTMLElement>(null, registry);
};

/**
Expand All @@ -26,5 +26,5 @@ export const registerHtml = (registry?: Registry) => {
* @return tagged template function that builds SVG components
*/
export const registerSvg = (registry?: Registry) => {
return registerDom('http://www.w3.org/2000/svg', registry);
return registerDom<TramOneSVGElement>('http://www.w3.org/2000/svg', registry);
};
9 changes: 6 additions & 3 deletions src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import observeTag from './observe-tag';
import processHooks from './process-hooks';
import { TRAM_TAG, TRAM_TAG_NEW_EFFECTS, TRAM_TAG_CLEANUP_EFFECTS } from './node-names';

import { Registry, Props, DOMTaggedTemplateFunction, Children } from './types';
import { Registry, Props, DOMTaggedTemplateFunction, Children, TramOneHTMLElement, TramOneSVGElement } from './types';

/**
* This function takes in a namespace and registry of custom components,
Expand All @@ -25,7 +25,10 @@ import { Registry, Props, DOMTaggedTemplateFunction, Children } from './types';
* @param registry mapping of tag names to component functions
* @param namespace namespace to create nodes in (by default XHTML namespace)
*/
export const registerDom = (namespace: string | null, registry: Registry = {}): DOMTaggedTemplateFunction => {
export const registerDom = <ElementType extends TramOneHTMLElement | TramOneSVGElement>(
namespace: string | null,
registry: Registry = {}
) => {
// modify the registry so that each component function updates the hook working key
const hookedRegistry = Object.keys(registry).reduce((newRegistry, tagName) => {
const tagFunction = registry[tagName];
Expand Down Expand Up @@ -68,5 +71,5 @@ export const registerDom = (namespace: string | null, registry: Registry = {}):
return { ...newRegistry, [tagName]: hookedTagFunction };
}, {});

return rbel(hyperx, nanohtml(namespace), hookedRegistry);
return rbel(hyperx, nanohtml(namespace), hookedRegistry) as DOMTaggedTemplateFunction<ElementType>;
};
4 changes: 2 additions & 2 deletions src/mutation-observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
TRAM_TAG_STORE_KEYS,
} from './node-names';
import { buildNamespace } from './namespace';
import { CleanupEffect, TramOneElement } from './types';
import { CleanupEffect, TramOneElement, TramOneHTMLElement, TramOneSVGElement } from './types';
import { getObservableStore } from './observable-store';
import { TRAM_OBSERVABLE_STORE, TRAM_KEY_STORE } from './engine-names';
import { decrementKeyStoreValue, getKeyStore, incrementKeyStoreValue } from './key-store';
Expand All @@ -25,7 +25,7 @@ import { decrementKeyStoreValue, getKeyStore, incrementKeyStoreValue } from './k
* process side-effects for new tram-one nodes
* (this includes calling effects, and keeping track of stores)
*/
const processTramTags = (node: Node | TramOneElement) => {
const processTramTags = (node: Node | (TramOneHTMLElement | TramOneSVGElement)) => {
// if this element doesn't have a TRAM_TAG, it's not a Tram-One Element
if (!(TRAM_TAG in node)) {
return;
Expand Down
9 changes: 6 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export type ElementOrSelector = [string | HTMLElement][0];
* Type for our template renderers (either html or svg).
* This is not wrapped in an indexed alias, because everything should be provided automatically.
*/
export type DOMTaggedTemplateFunction = (
export type DOMTaggedTemplateFunction<TramOneElementType extends TramOneElement> = (
strings: TemplateStringsArray,
...elementsAndAttributes: any[]
) => TramOneElement;
) => TramOneElementType;

/**
* Type for custom Tram One Components.
Expand Down Expand Up @@ -54,7 +54,7 @@ export type CleanupEffect = [() => unknown][0];
* Type for the effect function.
* This is passed into the useEffect hook
*/
export type Effect = [(ref: TramOneElement) => unknown][0];
export type Effect = [(ref: TramOneHTMLElement | TramOneSVGElement) => unknown][0];

/**
* The Props interface for custom Tram One Components.
Expand Down Expand Up @@ -108,6 +108,9 @@ export interface TramOneElement extends Element {
[TRAM_TAG_STORE_KEYS]: string[];
}

export type TramOneHTMLElement = TramOneElement & HTMLElement;
export type TramOneSVGElement = TramOneElement & SVGElement;

Comment on lines +111 to +113
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new type definitions, because TramOneElement is too generic, and in reality (right now) it's always an HTMLElement or SVGElement.

If we ever expose registerDOM, people should be able to make their own TramOneElement definitions (which shouldn't be too hard to do).

/**
* Type for the Root TramOneComponent,
* it can have no props or children, since it is the root element
Expand Down