Yomguithereal / react-blessed

A react renderer for blessed.
MIT License
4.45k stars 177 forks source link

add mapping for jsx tag to solve tag conflict #85

Closed guoshencheng closed 5 years ago

guoshencheng commented 5 years ago

Add tag mapping to resolve react origin tag conflict

guoshencheng commented 5 years ago

Usage:

render(
  <App />
, screen, {
  jsxTagMapping: (type: string) => {
    switch(type) {
      case 'blessed-button':
        return 'button';
      case 'blessed-form':
        return 'form';
      default:
        return type;
    }
  }
});
Yomguithereal commented 5 years ago

Hello @guoshencheng. Thanks for the PR. Looking at it right now. Do you have an example of library where the same logic is applied so I can try to understand how it works?

guoshencheng commented 5 years ago

@Yomguithereal it's a Irregular solution, i'm sorry about that. i did not refer to any library. Here is a story Yesterday. i start to use react-blessed. it's good. but my project was written by typescript. when i use custom JSX tag for example box. typescript will report a compile bug like this

image

To resolve this problem i must add a type definition file

declare module 'react-blessed' {
  import { Widgets, screen } from 'blessed';
  import * as React from 'react';
  export function render(c: JSX.Element, s: Widgets.Screen): void;
}

declare namespace JSX {
  interface IntrinsicElements {
    'box': any
  }
}

oh yes! my code is running!

but not good for a long time. the next problem is appear, when i use a origin tag for example button. typescript will check the origin JSX tag PropType. error report like this

image

So a solution appeared in my mind. mapping the tag name

my code has been displayed and here place my usage

change interface in my react-blessed typescript definition file

declare module 'react-blessed' {
  import { Widgets, screen } from 'blessed';
  import * as React from 'react';
  export type JsxTagMapping = (origin: string) => string | undefined;
  export type renderOptions = {
    jsxTagMapping: JsxTagMapping,
  }
  export function render(c: JSX.Element, s: Widgets.Screen, options: renderOptions): void;
}

declare namespace JSX {
  interface IntrinsicElements {
    'box': any,
    'listtable': any,
    'blessed-button': any,
    'blessed-form': any
  }
}

And change code to render

import { render } from 'react-blessed';

render(
  <App />
, screen, {
  jsxTagMapping: (type: string) => {
    switch(type) {
      case 'blessed-button':
        return 'button';
      case 'blessed-form':
        return 'form';
      default:
        return type;
    }
  }
});

finally. use <blessed-button / > instead of <button / >

guoshencheng commented 5 years ago

It's a Irregular solution and i don't know if there is any solution by add a great type definition file

guoshencheng commented 5 years ago

Another better solution is to map all tag inner lib and provider a official type definition file. so that the developer will not add the definition by themselves.

guoshencheng commented 5 years ago

plan b

86

mmmeff commented 5 years ago

Types look good to me

guoshencheng commented 5 years ago

@mmmeff are you using typescript?