Zoho Lyte framework guidelines for component structure, template syntax, routing, data store, mixins, observers, and UI components. Use when working with Lyte components, templates, routes, or any .html/.js files in this project.
This project uses the Zoho Lyte framework (@zoho/lyte v3.5.x) — a component-based client framework with three decoupled layers: Router, Component, and Data Store.
Every component consists of three co-located files with matching kebab-case names:
| File | Location | Purpose |
|---|---|---|
my-comp.js | components/javascript/ | Registration, data, actions, methods, lifecycle |
my-comp.html | components/templates/ | Template markup and bindings |
my-comp.css | components/styles/ | Scoped styles (global — no shadow DOM) |
Lyte.Component.register(
'my-comp',
{
data: function () {
return {
propName: Lyte.attr('string', { default: '' }),
items: Lyte.attr('array', { default: [] }),
isOpen: Lyte.attr('boolean', { default: false }),
config: Lyte.attr('object', { default: {} }),
count: Lyte.attr('number', { default: 0 })
};
},
actions: {
onButtonClick: function (arg1, arg2) {
// handle template events
}
},
methods: {
onDropdownChange: function (selected) {
// callback for Lyte UI component events
}
},
init() {
// runs on component initialization (before DOM)
},
didConnect() {
// runs after component is connected to DOM
}
},
{ mixins: ['my-mixin'] }
);
register() must match the tag-name attribute in the HTML templateLyte.attr(type, options) for all data properties — valid types: 'string', 'number', 'boolean', 'array', 'object'this.getData('propName') and this.setData('propName', value)data block is accessible from templates; actions and methods require helpers ({{action(...)}} / {{method(...)}})this.executeMethod('methodName', ...args)this.getMethods('methodName') before executeMethod*-comp suffix convention (e.g., modal-comp, button-comp)lyte-* prefix (e.g., lyte-modal, lyte-dropdown)Templates are HTML files wrapped in a root <template> tag:
<template tag-name="my-comp">
<!-- component markup here -->
</template>
| Syntax | Purpose | Example |
|---|---|---|
{{propName}} | One-way binding (read-only) | {{title}} |
{{lbind(propName)}} | Two-way binding (read/write) | {{lbind(isOpen)}} |
{{action('name', arg1)}} | Bind action as event handler | onclick="{{action('onClick', event)}}" |
{{method('name')}} | Bind method as callback | on-change="{{method('onSelect')}}" |
{{unescape(value)}} | Render raw HTML | {{unescape(htmlContent)}} |
{{if(cond, trueVal, falseVal)}} | Inline conditional | class="{{if(active, 'bg-blue', 'bg-gray')}}" |
{{concat(a, '-', b)}} | String concatenation | id="{{concat('item-', index)}}" |
{{ifEquals(a, b)}} | Equality check (returns boolean) | {{if(ifEquals(status, 'done'), 'green', 'red')}} |
<template lyte-if="{{isLoggedIn}}">
<p>Welcome back</p>
</template>
<template lyte-else>
<p>Please log in</p>
</template>
Also supports lyte-else-if:
<template lyte-if="{{state == 'loading'}}">...</template>
<template lyte-else-if="{{state == 'error'}}">...</template>
<template lyte-else>...</template>
Array iteration:
<template lyte-for="{{items}} as item index">
<div>{{index}}: {{item.label}}</div>
</template>
Object iteration:
<template lyte-for-in="{{config}} as value key">
<div>{{key}}: {{value}}</div>
</template>
<template lyte-switch="{{status}}">
<template
lyte-case="active"
lyte-break>
Active
</template>
<template
lyte-case="inactive"
lyte-break>
Inactive
</template>
<template lyte-default>Unknown</template>
</template>
Multi-word property names must be hyphenated in HTML attributes (browser limitation), but defined in camelCase in JS:
<!-- HTML: hyphenated -->
<child-comp
my-data="{{parentData}}"
is-visible="{{show}}"></child-comp>
// JS: camelCase