gkz / LiveScript

LiveScript is a language which compiles to JavaScript. It has a straightforward mapping to JavaScript and allows you to write expressive code devoid of repetitive boilerplate. While LiveScript adds many features to assist in functional style programming, it also has many improvements for object oriented and imperative programming.
http://livescript.net
MIT License
2.31k stars 155 forks source link

Livescript Extension for React + Pug #970

Closed askucher closed 7 years ago

askucher commented 7 years ago

Hi Everyone.

I figured out that people love React (and we love) but Livescript does not support it. We are going to build a company (today we gonna have first round funds) and definitely want to use livescript and react So decided to implement the library reactify-ls

notice! it uses pug syntax for html tree

How to install

npm i lsxc -g

Here is example of todo list

# todo.ls
require! {
  \mobx-react : { observer }
  \mobx : { observable }
  \react-dom : { render }
  \react
}

btn = ({click, text})->
    style =
        color: \red
        padding-left: \5px
    a.vv.btn(target='blank' on-click=click style=style) #{text} 

input = ({store})->
  handle-enter-click = (event) -> 
    return if event.key-code isnt 13 
    store.todos.push text: event.target.value
    event.target.value = ''
  input.vv(on-key-down=handle-enter-click)  

Main = observer ({store})->
  remove = (todo, _)-->
      index = store.todos.index-of todo
      return if index < 0
      store.todos.splice 1, index
  .vv
    h3.vv Tasks
    for todo in store.todos
      .vv 
        span.vv #{todo.text}
        span.vv
          btn {text: 'Remove', click: remove todo}
    input {store}
    hr.vv 

window.onload = ->
  store = observable do
      todos:
        * text: 'Do dishes'
        ...
  render do
    Main.vv(store=store)
    document.body.append-child document.create-element \app

Compile

lsxc -hbc todo
#created index.html -> just open it :)

We would like to propose to add such syntax into the livescript but for now you can use our library and collaborate.

In September we are going to raise 2 million dollars and then will hire first people from collaborators.

vendethiel commented 7 years ago

relevant: https://github.com/jashkenas/coffeescript/pull/4553

vendethiel commented 7 years ago

If you actually plan to do it, definitely go for HAML. % is much easier to parse, where .xx is always ambiguous

askucher commented 7 years ago

It is already done. But we will add sass + dynamic classes support later and personally I do not prefer %. as for me better to use fake class vv

vendethiel commented 7 years ago

Except your converter has ambiguities.

  remove = (todo, _)-->
      index = store.todos.index-of todo
      return if index < 0
      store.todos.splice 1, index
  .vv

is already valid LS code

just like

a.vv.btn() text

also is valid.

I know where you're coming from with this – I made the exact same tool in 2013. Doesn't work at bigger scale.

vendethiel commented 7 years ago

or do you mean you always need to see .vv to detect a line? That's still regex-based matching, alas. Why not use % and not be ambiguous? (much less)

askucher commented 7 years ago

Yesh. I just parse line.match(/.vv/) and convert it into the react.createElement. Still brainstorming about best decision. The idea was to make livescript + react code compatible with jade/pug. Because a lot of code is already written there and actually pug is consistent with saas

askucher commented 7 years ago

@vendethiel will try

vendethiel commented 7 years ago

I think it's best if you manage to adapt the HAML PR still. No need for regex hacks, so you have better luck to make everything work.

askucher commented 7 years ago

Little update. We added support of sass as well. And renamed .vv to .pug for better reading. We did not consider % because it is invalid selector when pug is valid selector

require! {
  \mobx-react : { observer }
  \mobx : { observable }
  \react-dom : { render }
  \react
}

btn:sass =
  color: red
  padding-left: 5px
  &:hover
    color: orange

btn = ({click, text})->
    a.pug.btn(target='blank' on-click=click) #{text} 

input = ({store})->
  handle-enter-click = (event) -> 
    return if event.key-code isnt 13 
    store.todos.push text: event.target.value
    event.target.value = ''
  input.pug(on-key-down=handle-enter-click)  

Main = observer ({store})->
  remove = (todo, _)-->
      index = store.todos.index-of todo
      return if index < 0
      store.todos.splice 1, index
  .pug
    h3.pug Tasks
    for todo in store.todos
      .pug 
        span.pug #{todo.text}
        span.pug
          btn {text: 'Remove', click: remove todo}
    input {store}
    hr.pug 

window.onload = ->
  store = observable do
      todos:
        * text: 'Do dishes'
        ...
  render do
    Main.pug(store=store)
    document.body.append-child document.create-element \app

Compile

lsxc -skhbc file
askucher commented 7 years ago

https://gitter.im/lsxc/Lobby# Who would like ask me questions. Please do