Giter VIP home page Giter VIP logo

nano's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nano's Issues

[BUG]: Function declarations/expressions are rendered as class components

Function declaration/expressions like class do have prototype and constructor. If you define functional components using function declaration/expressions, nano tries to render them as class components and it throws. The same rules don't apply to arrow functions and they work just fine.

As a solution, we can distinguish classes from function declarations by checking their string representation of prototype.constructor. For example:

Example:

class F {} // F.prototype.constructor -> class F {}
function f () {} // f.prototype.constructor -> function f()

I opened a PR to reference this issue.

Images are not displayed with Img component

Describe the bug
I tried using the v23 Img component with .svg, .png and .jpg, but the images are not shown.

import { Img } from 'nano-jsx/lib/components/img'
...
<Img class="footer-logo" src="/public/img/footer-logo.png" alt="Logo" />
...

Checked the HTML in inspector. It's kind of getting crippled:

<div style=";" class="footer-logo" alt=""></div>

jsx typing problem

I am using vscode, and the follow code

export const Article = ({ html }: { html: string }) => {
  return jsx`<div class="article-content">${html}</div>`;
};

results
image
in vscode.

The type defining of jsx accepts just one param named statics, can it be fixed?

export const build = function (statics: any) {

Improve dangerouslySetInnerHTML

Use

<div innerHTML={{ __dangerousHtml: html }} />

instead of

<div dangerouslySetInnerHTML={{ __html: html }} />

Why?

  • easier to read
  • looking just at { __dangerousHtml: html } lets the user suspect a danger

TODOs

  • #78
  • Implement modern __dangerousHtml syntax.

Body not expected

hi, i try SSR with Deno but body not expected. thanks.

Code :

/** @jsx h */

import { h, renderSSR, Helmet } from 'https://deno.land/x/[email protected]/mod.ts';

const App = () => {
    const handle = () => { console.log('hello'); };
    return <button onClick={handle} class="hello world">Click</button>;
}

const app = renderSSR(<App />);
const { body } = Helmet.SSR(app);

console.log(body);

// <button onClick="()= class="hello world">{ console.log('hello'); }">Click</button>

[Enhancement] Add optional CSS class to Router.Link

Describe
Currently it's not possible to add a CSS class like class="nav-link" to Router.Link.

(alias) const Link: FC<{
    to: string;
    replace?: boolean | undefined;
    children?: any;
}>

My current workaround:

<Link to="/about" cssClass="nav-link">About</Link>
export const Link: Nano.FC<{ to: string; cssClass: any; children?: any }> = ({ to, cssClass, children }) => {
  const handleClick = (e: Event) => {
    ...
  }

  return (
    <a href={to} class={cssClass} onClick={(e: Event) => handleClick(e)}>
      {children}
    </a>
  )
}

Have a question?
If im not wrong, it would be great if you could add an optional CSS class to the Router.Link.

[Feature Proposal] nano-jsx cli to provide better developer experience.

Motivation πŸ”₯

Currently, mastering nano-jsx is a difficult task for a beginner web developer (I am not going to offend you).

To improve this situation, How about nano-jsx providing a cli?

Cli’s feature (?)

  • easier setup: nano-jsx create [APP]
    • nano-jsx create should only handle a very simple setup. I think a more detailed setup to ask questions by dialog should be done with create-nano-jsx-app
  • easier serve: nano-jsx serve with express6
  • earsier build: nano-jsx build
  • easier dev server: nano-jsx start or nano-jsx dev
  • earsier deploy: nano-jsx deploy with "Node.js & vercel" or "deno & Deno Deploy”
  • and more (docs, info, help)

How about do you think about this? If it looks good, I want to start to work on this little by little.

`undefined` attributes are not elided during SSR

Describe the bug

In React and Preact, setting an attribute to undefined will cause that attribute to be elided from the rendered output (client and server side). NanoJSX does not do this, instead setting the attribute with a literal "undefined" string value. For example <button disabled={undefined}>Hey</button> would render an enabled button in React/Preact, while rendering a disabled button in nanojsx.

Router from array error

hi, how to render router from array ? i see console browser Cannot destructure property 'path' of 'child.props' as it is undefined..

Code :

/* @jsx Nano.h */ // tells Babel to convert JSX to Nano.h() calls

// normally below is just:  import Nano, { Component } from 'nano-jsx';

const Nano = nanoJSX;
const { Component, Router } = Nano;
const { Switch, Route, Link } = Router;
const Navbar = () => (
  <nav>
    <Link to={"/"}>Home</Link>
    <Link to={"/about"}>About</Link>
  </nav>
);
const Home = () => <h1>Home</h1>;
const About = () => <h1>About</h1>;

const routes = [
  {
    path: "/",
    exact: true,
    Comp: Home
  },
  {
    path: "/about",
    exact: false,
    Comp: About
  }
];

const App = () => (
  <Switch fallback={() => <div>404 (not found)</div>}>
    {routes.map(({ exact, path, Comp }) => {
      return (
        <Route exact={exact} path={path}>
          <Comp />
        </Route>
      );
    })}
  </Switch>
);

Nano.render(<App />, document.body);

Codepen => https://codepen.io/herudi/pen/ExbQrLv

Error when using SVG with Deno

Steps to reproduce:

Take the Deno example https://github.com/nanojsx/nano-jsx-deno-example
Add a svg anywhere

// components/Hello.tsx
import { Component, h } from "../nano.ts";

export const Hello = () => {
  return (
    <h1>
      <svg width="100" height="100">
        <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
      </svg>
      Hello Nano App!
    </h1>
  );
};

You will get the following error:

error: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
  for (let i = attrs.length - 1; i >= 0; i--) {
                     ^
    at SVG (https://deno.land/x/[email protected]/core.ts:73:22)
    at _render (https://deno.land/x/[email protected]/core.ts:132:68)
    at https://deno.land/x/[email protected]/core.ts:50:17
    at Array.forEach (<anonymous>)
    at appendChildren (https://deno.land/x/[email protected]/core.ts:45:12)
    at h (https://deno.land/x/[email protected]/core.ts:250:3)
    at Hello (file:///Users/iury/git-repos/iurypiva/nano-jsx-deno-example/components/Hello.tsx:4:9)
    at renderFunctionalComponent (https://deno.land/x/[email protected]/core.ts:167:18)
    at _render (https://deno.land/x/[email protected]/core.ts:141:70)
    at render (https://deno.land/x/[email protected]/core.ts:87:12)

Using [email protected] and [email protected].

inputs lose focus on... well, input

Description
Whenever I type into an input-element (like the one below), the input loses focus, and I have to re-click to type on.

here's an example of what I'm doing:

<input
  type="text"
  value={this.state.message}
  onInput={(event: any) => this.setState({ message: event.target.value }, true)}
/>

Am I doing something wrong, or is this sort of thing supposed to work?

Visual Studio Code: There is no interface "JSX.IntrinsicElements" ([email protected])

Describe the bug

This is maybe not related to Nano JSX at all, but when I npm i [email protected] I get the following message in VSCode, when creating HTML-Elements like <div> in .tsx files.

The JSX element implicitly contains the type "any" because there is no interface "JSX.IntrinsicElements".

Have a question?

I was searching on Google how to fix the Issue in VSCode, but I havn't found any working solution. ATM I downgraded to 0.0.20, since the Issue is resolved with it.

Automatically cancel store

Cancels all registered stores.

const myStore = new Store({ test: 'abc' })

class Test extends Component {
  store = myStore.use()
  store2 = myStore.use()

  cancelAllStores() {
    const hasProp = (obj: any, ...prop: string[]) => {
      for (const p of prop) if (!Object.prototype.hasOwnProperty.call(obj, p)) return false
      return true
    }

    Object.keys(this).forEach(k => {
      const obj = (this as any)[k]
      if (hasProp(obj, 'setState', 'subscribe', 'cancel')) {
        console.log('cancel')
        obj.cancel()
      }
    })
  }

  didUnmount() {
    this.cancelAllStores()
  }

  render() {
    return <p>test</p>
  }
}

Originally posted by @yandeu in #13 (comment)

[Analysis] customElementsMode.js Types and behaviour of attributeChangedCallback()

customElementsMode.js prop key types = always string

I tested a lot whith CustomElements.js. First I created a simple counter component, but without passing a value (props). It was working as expected, but i had to call this.update() inside the changeValue() function, to update the component.

Then I passed the props key value to the component. It was not working as expected, since the type of value was always string. I tried different approaches to change the value type to number or convert to Int/Number, but nothing worked.

Behaviour of attributeChangedCallback()

After I read all the docs about Custom Webcomponents, I was wondering, why actually I had to call this.update() at all, since attributeChangedCallback actually should update the component itself. I analysed the code of CustomElements.
In my understanding, the function attributeChangedCallback in customElementsMode.js will NEVER get executed in your code, because it NEEDS to call setAttribute to execute. Please read here.

Have a question?
I don't know maybe I was just trying too many hours to archive the desired results.
But I have setup a repo with 3 different demonstrations.

https://github.com/jrson83/nanojsx-elements-test

  • counter_simple.tsx : for demonstrating prop key type is always string
  • counter.tsx : more advanced approach with more debuging
  • word.tsx : for demonstrating that attributeChangedCallback actually only works with setAttribute

There are also comments inside the files, for more information. To change the compiled file just change the entry in webpack.config.js.
It would be great if you checkout the repo and give some feedback on my thougts.

<html> tag in <Helmet> is not handled properly on SSR

Describe the bug

/** @jsx Nano.h */
/** @jsxFrag Nano.Fragment */
/// <reference no-default-lib="true" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/// <reference lib="deno.ns" />
/// <reference lib="deno.unstable" />

import * as Nano from "https://deno.land/x/[email protected]/mod.ts";

const App = () => (
  <>
    <Nano.Helmet>
      <html prefix="og: https://ogp.me/ns#" />
      <meta charset="utf-8" />
      <title>Title</title>
      <meta property="og:type" content="website" />
    </Nano.Helmet>
    <h1>Hello, world!</h1>
  </>
);
const { body, head } = Nano.Helmet.SSR(Nano.renderSSR(() => <App />));
console.log(head);  // ['<html prefix="og: https://ogp.me/ns#"></html><meta charset="utf-8" /><title>Title</title><meta conte...']
console.log(body);  // <h1>Hello, world!</h1>

Nano.Helmet#didMount handles <html> tag, so it won't work for SSR, resulting to emit incorrect <html> tag in head property of the returning object of Nano.Helmet.SSR().

To prevent this, Nano JSX should at least delete <html> tag or raise an error on Nano.Helmet.SSR(). It would be better if it returns htmlAttributes and bodyAttributes like react-helmet does.

(Deno) Cannot set "location"

I'm using Deno (1.7.0) and cant use renderSSR because window.location cant be set

import { Component, h, renderSSR } from "https://deno.land/x/[email protected]/mod.ts";

class App extends Component {
  render() {
    return (
      <div>ayy</div>
    )
  }
}

renderSSR(<App />);
error: Uncaught NotSupportedError: Cannot set "location".
        throw new DOMException(`Cannot set "location".`, "NotSupportedError");
              ^
    at set (deno:op_crates/web/12_location.js:340:15)
    at initSSR (<https://deno.land/x/[email protected]/ssr.ts>:25:1)
    at renderSSR (<https://deno.land/x/[email protected]/ssr.ts>:39:1)

New JSX Transform API won't work on deno

Describe the bug
Putting /** @jsxImportSource https://deno.land/x/[email protected] */ at the first line of a .tsx file won't work because no such file (404) as https://deno.land/x/[email protected]/jsx-runtime.
The same for esm.sh(500 for error: parseCJSModuleExports: Can't resolve 'nano-jsx/jsx-runtime'), cdn.skypack.dev(404), unpkg.com(404).

None of the CDNs above can resolve nano-jsx/lib/jsx-runtime either.

On v0.0.21, which is the first release after #29 got merged, esm.sh can resolve [email protected].
However it causes compile error TS7026 [ERROR]: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. as already reported at #52 (and fixed at f2b72f4).

[Bug] defineAsCustomElements component

Describe the bug
No matter what I try I get this error when using customElements:

customElements.define(componentName, class extends HTMLElement {
    ^

ReferenceError: customElements is not defined

Here is a Sandbox Link

Also the usage of CustomElementsMode on the docs is missing some really usefull required information like import module, export component and actuall usage example.

Have a question?
Can you please fix it, or describe how to use it right if it's not a bug?
If the usage is working I would like to provide some more infos for the docs.

Todo

renderSSR error when using a component defined with a regular JS function

This is the Oak route that tries to render a NanoJSX component.

import { App } from "./views/App.jsx"
router.get("/", (ctx) => {
  ctx.response.body = `<html><body>${Nano.renderSSR(Nano.h(App), null)}</body></html>`
});

A component defined as an arrow function works fine, without issues:

export const App = () => {
  return <h1> Hello App </h1>
}

A component defined as a regular (named or anon) JS function doesn't work.

export function App () {
  return <h1> Hello App </h1>
}

This is the error:

Component.willMount is not a function

TypeError: Component.willMount is not a function
    at renderComponent (core.ts:124:15)
    at render (core.ts:69:12)
    at Module.renderSSR (ssr.ts:12:10)

tsconfig

{
  "compilerOptions": {
    "lib": ["esnext", "dom", "dom.iterable", "deno.ns", "deno.unstable"]
    "strictPropertyInitialization": false,
    "jsx": "react",
    "jsxFactory": "Nano.h"
  }
}

Cannot use html tags inside renderSSR

Describe the bug

Consider this code:

import { h, renderSSR } from "https://deno.land/x/[email protected]/mod.ts";

type AppProps = {
  title: string;
  children?: any;
};

const App = ({ title, children }: AppProps) => {
  return (
    <div>
      <h1>{title}</h1>
      <section>{children}</section>
    </div>
  );
};

const html = renderSSR(<App title="Hello stats" />);

console.log(html);

So the output is: <div><h1>Hello stats</h1><section></section></div>

But using this code:

import { h, renderSSR } from "https://deno.land/x/[email protected]/mod.ts";

type AppProps = {
  title: string;
  children?: any;
};

const App = ({ title, children }: AppProps) => {
  return (
    <div>
      <h1>{title}</h1>
      <section>{children}</section>
    </div>
  );
};

const html = renderSSR(
  <App title="Hello world">
    <h2>Other content</h2>
  </App>,
);

console.log(html);

It throws:

image

[Bug] New Helmet client-side TypeError with external template file

Describe the bug

When using Helmet on the client side only, with an external template file, it is throwing an error as soon as you add more then one tag to the <Helmet />. This was not an issue before the new helmet update.

<Helmet>
  <title>{this.props.title ? this.props.title : '404 Error'} - Nano JSX</title>
  {/* Helmet crashing, when using an external template file, and adding more then one tag to the helmet */}
  <meta name="description" content="Nano-JSX application" />
</Helmet>

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')

Pointing to this line of code:

for (let r = 0; r < e.attributes.length; r++)

Just to demonstrate I created a repo.

[Feature Request(ui)] ui/Dialog accesibility

Hi! @yandeu
I noticed some nano-jsx/lib/ui/Dialog's accessibility fault when I read nano's code, such below

  • dialog was not removed when a user push Escape key
  • a user traversing a web site only with a keyboard cannot close dialog because action button in Dialog can not ne focused on traversing with keyboard.
  • dialog's background should be attached with aria-hidden prop because this is helpful for a screen-reader user
  • dialog's background should be fixed with the current scrolling position
  • dialog should be closed when overlay is clicked
  • the first interactive element in Dialog should be focused when Dialog appear
  • UPDATE: the interactive element which a user focused on the last time before Dialog appear should be focues after Dialog disappear (remove this from list because this should be done on an application, not on library)

These features are implemented in react-spectrum or mui and are helpful for anyone.

I want to implement this feature into nano-jsx/lib-ui/Dialog, but I want to hear your opinion on this before I implement it.

Import errors when running with Deno

I am importing Nano as shown on the website to use as an SSR library.

import * as Nano from 'https://deno.land/x/[email protected]/mod.ts'

This is my tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "jsx": "react",
    "jsxFactory": "Nano.h"
  }
}     

But it seems that Nano wants browser stuff and Deno just gives up with 67 errors πŸ˜”

Click here to see the output.
error: TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
  const tmpNode = document.createElement('div')
                  ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/helpers.ts:2:19

TS2304 [ERROR]: Cannot find name 'MutationObserver'.
  var observer = new MutationObserver((mutationsList) => {
                     ~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/helpers.ts:13:22

TS7006 [ERROR]: Parameter 'mutationsList' implicitly has an 'any' type.
  var observer = new MutationObserver((mutationsList) => {
                                       ~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/helpers.ts:13:40

TS7006 [ERROR]: Parameter 'mutation' implicitly has an 'any' type.
    mutationsList.forEach((mutation) => {
                           ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/helpers.ts:14:28

TS7006 [ERROR]: Parameter 'removed' implicitly has an 'any' type.
      mutation.removedNodes.forEach((removed) => {
                                     ~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/helpers.ts:15:38

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
  observer.observe(document, {
                   ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/helpers.ts:26:20

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
export const removeAllChildNodes = (parent: HTMLElement) => {
                                            ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:17:45

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
      let c = renderComponent(child) as HTMLElement
                                        ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:38:41

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
      else element.appendChild(c.nodeType == null ? document.createTextNode(c.toString()) : c)
                                                    ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:42:53

TS2304 [ERROR]: Cannot find name 'SVGElement'.
  const child = props.children[0] as SVGElement
                                     ~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:51:38

TS2304 [ERROR]: Cannot find name 'SVGElement'.
  const svg = hNS('svg') as SVGElement
                            ~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:54:29

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
export const hydrate = (component: any, parent: HTMLElement | null = null, removeChildNodes = true) => {
                                                ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:63:49

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
export const render = (component: any, parent: HTMLElement | null = null, removeChildNodes = true) => {
                                               ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:68:48

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
  if (el.component) return renderComponent(el) as HTMLElement
                                                  ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:156:51

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
  return document.createElementNS('http://www.w3.org/2000/svg', tag) as SVGElement
         ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:161:10

TS2304 [ERROR]: Cannot find name 'SVGElement'.
  return document.createElementNS('http://www.w3.org/2000/svg', tag) as SVGElement
                                                                        ~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:161:73

TS2304 [ERROR]: Cannot find name 'SVGElement'.
      ? (hNS('svg') as SVGElement)
                       ~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:174:24

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
      : (document.createElement(tagNameOrComponent) as HTMLElement)
         ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:175:10

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
      : (document.createElement(tagNameOrComponent) as HTMLElement)
                                                       ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/core.ts:175:56

TS2304 [ERROR]: Cannot find name 'HTMLCollection'.
  private _elements: HTMLCollection
                     ~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/component.ts:11:22

TS2304 [ERROR]: Cannot find name 'HTMLCollection'.
  public get elements(): HTMLCollection {
                         ~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/component.ts:48:26

TS2304 [ERROR]: Cannot find name 'HTMLCollection'.
  public set elements(e: HTMLCollection) {
                         ~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/component.ts:52:26

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
    const parent = nodeElements[0].parentElement as HTMLElement
                                                    ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/component.ts:108:53

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
    rendered.forEach((r: HTMLElement) => {
                         ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/component.ts:111:26

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
    nodeElements.forEach((t: HTMLElement) => {
                             ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/component.ts:118:30

TS2304 [ERROR]: Cannot find name 'IntersectionObserver'.
    const observer = new IntersectionObserver(
                         ~~~~~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/visible.ts:8:26

TS7006 [ERROR]: Parameter 'entries' implicitly has an 'any' type.
      (entries, observer) => {
       ~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/visible.ts:9:8

TS7006 [ERROR]: Parameter 'observer' implicitly has an 'any' type.
      (entries, observer) => {
                ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/visible.ts:9:17

TS7006 [ERROR]: Parameter 'entry' implicitly has an 'any' type.
        entries.forEach((entry) => {
                         ~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/visible.ts:10:26

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
    this.props.children.forEach((element: HTMLElement) => {
                                          ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:30:43

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
      let parent = this.props.footer ? document.body : document.head
                                       ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:31:40

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
      let parent = this.props.footer ? document.body : document.head
                                                       ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:31:56

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
        const htmlTag = document.getElementsByTagName(tag)[0]
                        ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:46:25

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
        const titleTags = document.getElementsByTagName('TITLE') as HTMLCollectionOf<HTMLTitleElement>
                          ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:52:27

TS2304 [ERROR]: Cannot find name 'HTMLCollectionOf'.
        const titleTags = document.getElementsByTagName('TITLE') as HTMLCollectionOf<HTMLTitleElement>
                                                                    ~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:52:69

TS2304 [ERROR]: Cannot find name 'HTMLTitleElement'.
        const titleTags = document.getElementsByTagName('TITLE') as HTMLCollectionOf<HTMLTitleElement>
                                                                                     ~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:52:86

TS2304 [ERROR]: Cannot find name 'HTMLTitleElement'.
          let e = element as HTMLTitleElement
                             ~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:54:30

TS2304 [ERROR]: Cannot find name 'HTMLTitleElement'.
          let titleTag = h('title', null, element.innerHTML) as HTMLTitleElement
                                                                ~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:57:65

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
      const el: HTMLElement[] = document.getElementsByTagName(tag) as any
                ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:67:17

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
      const el: HTMLElement[] = document.getElementsByTagName(tag) as any
                                ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:67:33

TS2339 [ERROR]: Property 'document' does not exist on type 'Window & typeof globalThis'.
    const isSSR = !(typeof window !== 'undefined' && window.document)
                                                            ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/helmet.ts:90:61

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
export const hydrateLazy = (component: any, parent: HTMLElement | null = null, removeChildNodes = true) => {
                                                    ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/lazy.ts:4:53

TS2304 [ERROR]: Cannot find name 'localStorage'.
    if (storage === 'memory' || typeof localStorage === 'undefined') return
                                       ~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/store.ts:22:40

TS2304 [ERROR]: Cannot find name 'localStorage'.
    const Storage = storage === 'local' ? localStorage : sessionStorage
                                          ~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/store.ts:24:43

TS2304 [ERROR]: Cannot find name 'sessionStorage'.
    const Storage = storage === 'local' ? localStorage : sessionStorage
                                                         ~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/store.ts:24:58

TS2304 [ERROR]: Cannot find name 'localStorage'.
    const Storage = this._storage === 'local' ? localStorage : sessionStorage
                                                ~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/store.ts:37:49

TS2304 [ERROR]: Cannot find name 'sessionStorage'.
    const Storage = this._storage === 'local' ? localStorage : sessionStorage
                                                               ~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/store.ts:37:64

TS2304 [ERROR]: Cannot find name 'HTMLImageElement'.
  image: HTMLImageElement
         ~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/img.ts:6:10

TS2304 [ERROR]: Cannot find name 'IntersectionObserver'.
    const observer = new IntersectionObserver(
                         ~~~~~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/img.ts:11:26

TS7006 [ERROR]: Parameter 'entries' implicitly has an 'any' type.
      (entries, observer) => {
       ~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/img.ts:12:8

TS7006 [ERROR]: Parameter 'observer' implicitly has an 'any' type.
      (entries, observer) => {
                ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/img.ts:12:17

TS7006 [ERROR]: Parameter 'entry' implicitly has an 'any' type.
        entries.forEach((entry) => {
                         ~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/img.ts:13:26

TS2304 [ERROR]: Cannot find name 'HTMLImageElement'.
            this.image = h('img', { ...rest }) as HTMLImageElement
                                                  ~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/img.ts:16:51

TS2304 [ERROR]: Cannot find name 'HTMLImageElement'.
    if (typeof lazy === 'boolean' && lazy === false) return h('img', { src, ...rest }) as HTMLImageElement
                                                                                          ~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/img.ts:32:91

TS2304 [ERROR]: Cannot find name 'IntersectionObserver'.
    const observer = new IntersectionObserver(
                         ~~~~~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:17:26

TS7006 [ERROR]: Parameter 'entries' implicitly has an 'any' type.
      (entries, observer) => {
       ~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:18:8

TS7006 [ERROR]: Parameter 'observer' implicitly has an 'any' type.
      (entries, observer) => {
                ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:18:17

TS7006 [ERROR]: Parameter 'entry' implicitly has an 'any' type.
        entries.forEach((entry) => {
                         ~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:19:26

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
    const links = document.getElementsByTagName('link')
                  ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:35:19

TS2304 [ERROR]: Cannot find name 'HTMLElement'.
      const prefetch = h('link', { rel: 'prefetch', href: this.props.href, as: 'document' }) as HTMLElement
                                                                                                ~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:44:97

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
      document.head.appendChild(prefetch)
      ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:45:7

TS2304 [ERROR]: Cannot find name 'HTMLLinkElement'.
        const target = e.target as HTMLLinkElement
                                   ~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:55:36

TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
        if (target.href === document.referrer) window.history.back()
                            ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:56:29

TS2339 [ERROR]: Property 'history' does not exist on type 'Window & typeof globalThis'.
        if (target.href === document.referrer) window.history.back()
                                                      ~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:56:55

TS2339 [ERROR]: Property 'location' does not exist on type 'Window & typeof globalThis'.
        else window.location.href = target.href
                    ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:57:21

TS2339 [ERROR]: Property 'location' does not exist on type 'Window & typeof globalThis'.
        setTimeout(() => (window.location.href = href), delay)
                                 ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:63:34

TS2339 [ERROR]: Property 'document' does not exist on type 'Window & typeof globalThis'.
    if (prefetch === true && !(typeof window !== 'undefined' && window.document)) {
                                                                       ~~~~~~~~
    at https://deno.land/x/[email protected]/deno_lib/components/link.ts:84:72

Found 67 errors.

Deno version:

deno 1.5.2 (71d7482, release, x86_64-unknown-linux-gnu)
v8 8.7.220.3
typescript 4.0.5

Render to and from AST

Would be nice to convert Nano JSX to and from an AST.

const App = () => {
  return (
    <div>
      <h1 style="color: blue;">title</h1>
      <p>paragraph</p>
    </div>
  )
}

const tree = renderToTree(<App />)

// tree would be something like this:
{
  type: 'FC',
  name: 'App',
  children: [
    {
      type: 'html',
      name: 'div',
      children: [
        { type: 'html', name: 'h1', body: 'title', props: { style: 'color: blue;' } },
        { type: 'html', name: 'p', body: 'paragraph' }
      ]
    }
  ]
}

// modify the tree if needed and render it to html
const html = renderFromTree(tree)

[Bug] didUnmount() event console.log() fired too late on page change

Describe the bug
Install the router listener example and add a didUnmount() with console.log() to every component, like there is already for the didMount():

didUnmount() {
  console.log('[HomePage] didUnmount')
}

Run the app, click on About then Blog 219. You will see the console output in this order:

07:52:14.738 [HomePage] constructor
07:52:14.741 [HomePage] didMount
-> Click About

07:52:17.285 [AboutPage] constructor
07:52:17.285 [AboutPage] didMount
07:52:17.285 [HomePage] didUnmount
-> Click Blog 219

07:52:19.238 [BlogPage] constructor
07:52:19.238 [BlogPage] didMount
07:52:19.239 [AboutPage] didUnmount

Have a question?
This might not be a big issue but this is very confusing. I spent hours testing with jest why components on my adapter unmount for no reason. Finally when I reproduced with router listener example, I recognized this is default behaviour.
It would be great if we can fix this issue, since it might confuse people when debugging. If this is and should be default behaviour this should be written as notice in the docs.

[Bug] Hydrate/render recreates server rendered tags in production

Describe the bug
This issue can be recreated with nanojsx/template.
I found this issue on react-helmet, dealing with the same problem.

When using the nanojsx/template in production, the server side rendered script tag for /public/js/home.hydrate.js gets recreated, when using hydrate/render on the <HomePage /> component.

Steps to recreate:

  1. Install template
  2. Open file ./src/pages/HomePage.tsx
  3. Make changes to the code:
import * as Nano from 'nano-jsx/lib/core'
import { printVersion } from 'nano-jsx/lib/helpers'
//import TodoList from '../components/TodoList'
import { HomePage } from '../pages/HomePage'

const hydrate = async () => {
  //Nano.hydrate(<TodoList />, document.getElementById('todo-list'))
  
  Nano.render(<HomePage />, document.getElementById('content'))
  ...
}

hydrate()
  1. Run npm run build
  2. Run npm run serve
  3. Check inspector & console in DevTools

bug-01

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.