Go to file
Astrian Zheng 0b3b957e9c
All checks were successful
Quality Check & Publish / quality (push) Successful in 26s
Quality Check & Publish / quality-failed-webhook (push) Has been skipped
Quality Check & Publish / publish (push) Successful in 31s
Quality Check & Publish / publish-failed-webhook (push) Has been skipped
Merge branch 'main' into dev
2025-05-22 12:44:57 +10:00
.gitea/workflows chore: remove husky tests from CI workflows to streamline quality checks 2025-05-22 11:53:58 +10:00
.github Merge branch 'main' into dev 2025-05-22 12:44:57 +10:00
src refactor: improve code readability by adding braces for conditional statements 2025-05-22 11:48:27 +10:00
.gitignore chore: ignore vim swap file 2025-05-21 13:38:35 +10:00
.npmignore Add .npmignore to exclude src/ and .gitea directories 2025-05-16 10:47:15 +10:00
biome.json chore: update CI workflow and dependencies; enhance linter rules and add husky for pre-commit checks 2025-05-22 11:36:44 +10:00
LICENSE Add license 2025-05-15 06:34:13 +00:00
package-lock.json chore: update CI workflow and dependencies; enhance linter rules and add husky for pre-commit checks 2025-05-22 11:36:44 +10:00
package.json chore: update CI workflow and dependencies; enhance linter rules and add husky for pre-commit checks 2025-05-22 11:36:44 +10:00
readme.md Fix formatting in README for clarity 2025-05-16 10:25:55 +10:00
rollup.config.js fix: rollup compress the utils folder 2025-05-21 22:12:32 +10:00
tsconfig.json fix: type challenges gived up ˊ_>ˋ 2025-05-21 22:53:44 +10:00

Laterano

Lateranians love sweets, and it is said that a qualified Lateranian knows how to make at least twenty kinds of desserts.

Lateranians have even created the unique dessert “Cactus Tart,” which is loved by the Pope.

ref

Laterano is a front-end framework based on the native support of vanilla-favoured Web Component feature. It allows you to adapt modern MVVM development workflows with the features, abilities, and benefits of Shadow DOM, including native componentized support, styling management, and more.

Note: Laterano was developed for learning purposes originally and is still under active development. We do not recommend using it inside a production environment.

How to use

  1. Create a vanilla front-end project with Vite. Input npm init vite inside the terminal, then choose “Vanilla” and “TypeScript”
  2. Install Laterano through npm
  3. Define your component and use it inside your HTML
  4. Done!

Here is a sample code for a simple to-do app:

import defineComponent from 'laterano'
import './style.css'

defineComponent({
  tag: 'x-todolist',
  template: `
    <div class="container">
      <h1>Todo List</h1>
      <input type="text" placeholder="Add a new todo" %connect="todoinput" @keyup="e => this.triggerFunc('keyDownListener', e)" />

      <ul class="todo-list">
        <li %if="todos.length === 0">
          <span class="empty">
            No todos yet! Add one above.
          </span>
        </li>
        <li %for="item in todos" %key="item.time" class="todo-item">
          <button @click="this.triggerFunc('removeTodo', item.time)">
            {{ item.name }}
          </button>
        </li>
      </ul>

      
    </div>
  `,
  style: `
    div.container {
      display: flex;
      flex-direction: column;
      align-items: center;
      min-height: 100vh;
      background-color: #f0f0f0;
    }
    div.container input {
      width: 20rem;
      padding: 0.75rem;
      margin-bottom: 1.5rem;
      border: 1px solid #ccc;
      border-radius: 0.5rem;
      font-size: 1rem;
    }
    div.container input:focus {
      border-color: #007bff;
      outline: none;
    }

    div.container ul.todo-list {
      list-style-type: none;
      padding: 0;
      width: 20rem;
      border: 1px solid #ccc;
      border-radius: 0.5rem;
      overflow: hidden;
    }
    div.container ul.todo-list li {
      padding: 10px;
      border-bottom: 1px solid #ccc;
      background-color: #fff;
    }
    div.container ul.todo-list li.todo-item {
      cursor: pointer;
    }
    div.container ul.todo-list li:hover {
      background-color: #f9f9f9;
    }
    div.container ul.todo-list li:last-child {
      border-bottom: none;
    }

    div.container ul.todo-list li button {
      background: none;
      border: none;
      width: 100%;
      text-align: left;
      font-size: 1rem;
      cursor: pointer;
    }

    span.empty {
      color: #999;
      cursor: default;
    }
  `,
  states: {
    todos: [
      
    ],
    todoinput: ''
  },
  funcs: {
    keyDownListener: function (event: KeyboardEvent) {
      if(event.key !== 'Enter') return
      if ((this as any).getState('todoinput') === "") return
      this.setState("todos", [
        ...(this as any).getState('todos'),
        {
          name: (this as any).getState('todoinput'),
          time: new Date().getTime()
        }
      ])
      this.setState("todoinput", "")
    },
    removeTodo: function (time: number) {
      const todos = (this as any).getState('todos')
      let list = structuredClone(todos)
      const index = list.findIndex((item: { time: number }) => item.time === time)
      if (index !== -1) {
        list.splice(index, 1)
        this.setState('todos', list)
      }

    }
  }
})
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + TS</title>
  </head>
  <body>
    <div id="app">
      <div>
        <x-todolist></x-todolist>
      </div>
    </div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>