Giter VIP home page Giter VIP logo

reactui's Introduction

🪶 ReactUI

A simple react add-on to write React just like SwiftUI.

📦 Install

npm install @iandx/reactui

❓What brings ReactUI?

React is a great framework, and function hooks make it even more elegant. But not HTML or CSS! It's 2022! React uses jsx to replace the ugly HTML and CSS, but...... What the difference between JSX and HTML! Why can't we code modern?

That was what in my mind when I first used SwiftUI back in 2019. Though it was(and still) just a toy and though I've heard its idea was exactly from React, still, it's modern and elegant. So why don't we take a little bit back to React? Here comes ReactUI...

Here is an example to create a list of buttons using jsx and reactui

  • JSX
    const JsxButtons = ({num}:any) => 
        <div>
            {num.map((num: number) => 
                <button 
                    onClick={()=>{
                        console.log(`This is button ${num}`)
                    }}
                    key={num}>
                    {num}
                </button>)}
        </div>
  • ReactUI
    const RUIButtons = RUI(({nums}:any) => 
        List(nums, (num:number) =>
            Button(num)
                .key(num)
                .onClick(() => {
                    console.log(`This is button ${num}`)
                })
        )
    )

Except the way ReactUI sets props, everything is the same with React functions.

Basically every prop in React and CSSProperty can be used in ReactUI as 'dot' function, and IDEs will autocomplete for you! (if there's some specific properties from third-party components, use setProp(key, value)to set additional prop)

const MyText = RUI(() =>
    Text("test")
        .fontSize("20px")
        .fontWeight("bold")
        .width("30px")
        .color("red")
        .className("rui-text")
        .id("text-12abc")
        .setProp("other_prop", 123)
)

⚡️ Quick Start

(try codesandbox here https://codesandbox.io/s/cool-boyd-1w8rr1?file=/src/App.tsx)

// ---- src/App.tsx
import ReactUIApp from 'ReactUIApp';
function App() {
  return ReactUIApp().asReactElement()
}

export default App;
// ---- src/ReactUIApp.ts
import ReactUIApp from './ReactUIApp';
import {RUI} from "@iandx/reactui";
import {Text, Button, VStack} from "@iandx/reactui/component";
import {useState} from "react";

const MyComponent = RUI(({defaultNum}: any) => {
  let [num, setNum] = useState(defaultNum)
  return (
      Button(num)
        .onClick(()=>{setNum(num+1)})
  )
})

const ReactUIApp = RUI(() =>
  VStack(
      MyComponent({defaultNum: 10}),
      Text("Hello")
  )
    .alignment("center")
)

export default ReactUIApp;
  • Every ReactUI instance can convert to React element using .asReactElement()

  • Every ReactUI instance can take

    1. another ReactUI instance
    2. a react element
    3. jsx element

    => as its children, e.g.:

    const MySecondComponent = RUI(() =>
        VStack(
            Text("This is ReactUI"),
            React.createElement("p", null, "This is React"),
            <p>This is JSX</p>
        )     
    )

🤖 Advanced

RUITag

Turn every react component into reactui instance no matter if it's a custom react function or a html tag

const RUIDiv = RUITag("div")
const RUIComponent = RUITag(YourReactFunction)

ConditionView

Use this view to build a dynamic controllable page simple and fast.

const MyCondition = RUI(() => {
    const displayIdx = useRUIState(0)
    
    return (
        VStack(
            Button("change")
                .onClick(() => {
                    displayIdx.value = displayIdx.value == 2 ? 0 : displayIdx.value+1
                }),
            ConditionView(displayIdx.value, {
                0: Text("This is the default view"),
                1: Text("This is view 1"),
                2: Text("This is the second view")
            })
        )
    )
})

Router

Using react-router 6, the NavigationView in ReactUI is pretty easy to use and supports regex path (which react-router 6 doesn't support).

const MyPage = RUI(() =>
    VStack(
        Text("this will show whatever the route is"),
        NavigationView({
          "": Text("this is home"),
          "what": Text("this is what"),
          ":abc+": (path: string) => Text(`this matches abcccccc: ${path}`),
          ":": (path: string) => Text(`this matches everything else: ${path}`)
        })
    )
)

ThemeView

A pretty strong view wrapper to manage all your customized components, the main concepts is: "5 colors are enough for a theme!"

The development and test is already done, but I don't know how to explain it in a straight way, so just leave it here....

Custom ReactUI Element

This part is to show you an advanced usage of how to define a ReactUI Element apart from the simple RUI() and RUITag().

Here's an example of an internal Button written in ReactUI

// ---- src/component/Input/Button.ts
import {ReactUIElement, RUIProp} from "../../base/ReactUIElement";
import {Div} from "../../base/HTMLTags";
import {ReactUIThemeColor} from "../../base/Interfaces";
import {useRUIState} from "../../base/Utils";

class Button extends ReactUIElement {
  Body = ({title}: any) => {
    const button = Div(title).registerBy(this)
    const mouseState = useRUIState("out")

    button
      .boxSizing("border-box")
      .border("solid")
      .borderRadius(button.S.borderRadius ?? "5px")
      .borderWidth(button.S.borderWidth ?? "1px")
      .height(button.S.height ?? "max-content")
      .width(button.S.width ?? "max-content")
      .padding("5px 10px")
      .textAlign("center")
      .verticalAlign("middle")
      .lineHeight(button.S.height === "max-content" ? "" :
              `calc(${button.S.height} - 2 * ${button.S.borderWidth} - 10px`)
      .userSelect("none")
      .cursor("pointer")
      .backgroundColor(this.themeColor.first.dark!)
      .color(this.themeColor.first.light!)
      .borderColor(this.themeColor.first.light!)
      .opacity(mouseState.value === "out" ? "1" : "0.5")
      .onMouseDown(() => {
        mouseState.value = "down"
      })
      .onMouseUp(() => {
        mouseState.value = "out"
      })
      .onMouseOut(() => {
        mouseState.value = "out"
      })

    if (this.C.disable ?? false) {
      button.pointerEvents("none").opacity("0.5")
    }

    return button
  }

  // ---- these are custom dot function that can be called outside and be used as this.C.xx in Body
  @RUIProp
  disable(value: boolean=true) {return this}
}

export default function (title: string) {
  return new Button({title})
}

☑️Todo

  • Build an internal component library with theme and animation.
    • VStack/HStack/ZStack
    • Button
    • Toggle
    • TextField
    • List
    • pogress
    • Select
    • AutoComplete

reactui's People

Contributors

iandxssxx avatar

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.