Skip to content

Add more exports#760

Open
guilhermesimoes wants to merge 1 commit intolightning-js:mainfrom
guilhermesimoes:add-lightning3-exports
Open

Add more exports#760
guilhermesimoes wants to merge 1 commit intolightning-js:mainfrom
guilhermesimoes:add-lightning3-exports

Conversation

@guilhermesimoes
Copy link

Add type exports TextRenderer, CoreNodeProps and CoreTextNodeProps.

Also export CoreNode and CoreTextNode since we can't use stage.createNode() or stage.createTextNode().

Peacock has been using Lightning v2's Element for several years now, so all our components extend that class. In order to migrate to Lightning v3, we need access to the new building blocks, CoreNode and CoreTextNode, so that our components can extend those.

export type { AnimationSettings } from '../src/core/animations/CoreAnimation.js';
export type { TimingFunction } from '../src/core/utils.js';
export type { Inspector } from '../src/main-api/Inspector.js';
export type { CoreNodeRenderState } from '../src/core/CoreNode.js';
Copy link
Author

@guilhermesimoes guilhermesimoes Mar 13, 2026

Choose a reason for hiding this comment

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

I'd also like to report something here.

Is it intended for consumers of lightningjs/renderer to be able to do:

import { CoreNodeRenderState } from '@lightningjs/renderer';

if (renderState === CoreNodeRenderState.InViewport) { ... }

?

Because if so, then this isn't working. All enums are being exported as export declare enum X. In order to preserve enums for consumers, preserveConstEnums must be used.

@elsassph
Copy link
Contributor

@guilhermesimoes I think you aren't approaching that correctly - to create nodes you should be go through the renderer instance:

Both the official Blits and unofficial SolidJS frameworks use this API, and in both cases they don't directly extend those objects, which is potentially a departure from the Lightning 2 approach where you can extend the base Element type.

@guilhermesimoes
Copy link
Author

guilhermesimoes commented Mar 16, 2026

The entire Peacock codebase is written in a class based approach, more or less like this:

import { Component, Element } from '@lightningjs/core';

export class SomePage extends Component {
  private title: TextElement;

  constructor(stage: Stage) {
    super(stage);

    const title = (this.title = new Element(stage));
    title.y = SOME_PAGE_TITLE_Y;
    title.x = HORIZONTAL_SAFE_ZONE;
    title.text = 'Hello World';
  }
}

As you can imagine, migrating over 300 components is not an easy task. We could create our own Component and Element classes like so:

import {
  type Stage,
  type CoreNode // note, we can't even do this import
} from '@lightningjs/renderer';

export class Element {
  private node: CoreNode;

  constructor(stage: Stage, props = {} as CoreNodeProps) {
    this.node = stage.createNode(props);
  }

  set x(x) {
    this.node.x = x;
  }

  get x() {
    return this.node.x;
  }

  // etc ...
}

But this approach has several disadvantages:

  1. For each element, we now create 2 class instances instead of only 1: our own Element and Lightning 3's CoreNode.
  2. We need to delegate all functions and properties, getters and setters, from Element down to CoreNode. If in a future Lightning release a new field is added to CoreNode, we need to make sure that we also add it to Element and delegate it accordingly. If we forget to add it, things may fail.

As such, we believe a better approach for a progressive migration from Lightning 2 to 3 is like so:

import {
  type Stage,
  type CoreNodeProps, // we also need this import, which doesn't work
  CoreNode
} from '@lightningjs/renderer';

export class Element extends CoreNode {
  constructor(stage: Stage, props = {} as CoreNodeProps) {
    super(stage, stage.resolveNodeDefaults(props));
  }
}

This approach:

  1. Does not create one extra class instance
  2. Does not require any delegation, it already extends the primitive CoreNode, so Lightning 3 can already accept it and render it.

We understand this may not fit in the Lightning team's vision of a declarative approach such as SolidJS or Blits, which at build time transform templates into nested calls to stage.createNode(). We want to get there too, but we have a long way to get there. We need to migrate to Lightning 3 first 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants