{"id":13531829,"url":"https://github.com/vimeshjs/vimesh-ui","last_synced_at":"2025-04-12T20:46:45.737Z","repository":{"id":59475660,"uuid":"461875746","full_name":"vimeshjs/vimesh-ui","owner":"vimeshjs","description":"Vimesh UI is an ultra lightweight library to build UI components for Alpine.js","archived":false,"fork":false,"pushed_at":"2025-03-07T03:00:59.000Z","size":662,"stargazers_count":150,"open_issues_count":10,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-04T00:08:20.879Z","etag":null,"topics":["alpinejs","ui"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vimeshjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-21T13:33:31.000Z","updated_at":"2025-04-03T11:22:48.000Z","dependencies_parsed_at":"2024-01-14T02:01:33.263Z","dependency_job_id":"cab8709b-f277-47a5-8188-0565e26881c5","html_url":"https://github.com/vimeshjs/vimesh-ui","commit_stats":{"total_commits":64,"total_committers":2,"mean_commits":32.0,"dds":0.015625,"last_synced_commit":"b0ee3af348b4138567a7deae4ea17a3dd6bfc4cf"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vimeshjs%2Fvimesh-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vimeshjs%2Fvimesh-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vimeshjs%2Fvimesh-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vimeshjs%2Fvimesh-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vimeshjs","download_url":"https://codeload.github.com/vimeshjs/vimesh-ui/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248631713,"owners_count":21136559,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alpinejs","ui"],"created_at":"2024-08-01T07:01:06.065Z","updated_at":"2025-04-12T20:46:45.713Z","avatar_url":"https://github.com/vimeshjs.png","language":"JavaScript","funding_links":[],"categories":["UI Frameworks"],"sub_categories":[],"readme":"# Why Vimesh UI\n\nI hate compiling frontend code with complex toolchains, like webpack, rollup, vite etc. Unfortunately, most frontend frameworks heavily depends on them. Alpine.js is clean, powerful and without extra build process. While it is a challenge to develop a UI library directly with Alpine.js. Vimesh UI is an ultra lightweight library to build UI components for Alpine.js.\n\n# Basic Usages\n\nJust add Vimesh UI CDN url before Alpine.js\n\n```html\n\u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n```\n\nNow there are three important Alpine.js directives to build your own UI components\n\n## x-component\n\nThis directive creates an HTML native custom element around Alpine.js template.\n\n```html\n\u003chead\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n\u003c/head\u003e\n\n\u003cbody\u003e\n  \u003cvui-greeting\u003eVimesh UI\u003c/vui-greeting\u003e\n\n  \u003ctemplate x-component=\"greeting\"\u003e\n    \u003ch1\u003eHello \u003cslot\u003e\u003c/slot\u003e\u003c/h1\u003e\n  \u003c/template\u003e\n\u003c/body\u003e\n```\n\n[Run on codepen](https://codepen.io/vimeshjs/pen/mdKKMpb)\n\nIt shows `Hello Vimesh UI`. The slots could have their default content. \n\n```html\n\u003chead\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n\u003c/head\u003e\n\n\u003cbody\u003e\n  \u003cvui-greeting\u003eVimesh UI\u003c/vui-greeting\u003e\n\n  \u003cvui-greeting\u003e\u003cspan slot=\"from\"\u003eTeam Vimesh\u003c/span\u003e\u003c/vui-greeting\u003e\n\n  \u003ctemplate x-component=\"greeting\"\u003e\n    \u003ch1\u003eHello \u003cslot\u003eWorld\u003c/slot\u003e from \u003cslot name=\"from\"\u003eTeam Default\u003c/slot\u003e\u003c/h1\u003e\n  \u003c/template\u003e\n\u003c/body\u003e\n```\nNow there are `Hello Vimesh UI from Team Default` and `Hello World from Team Vimesh`. \n\nLet's add some interaction logic. There are two magics `$api` and `$prop` for a Vimesh UI component. `$api` comes from the return object of the first `\u003cscript\u003e` inside of component template. `$prop` is function to get the passed value of component property:\n\n```html\n\u003chead\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n\u003c/head\u003e\n\n\u003cbody x-data=\"{name: 'Vimesh UI'}\"\u003e\n  \u003cvui-greeting greeting-word=\"Hi\" :who=\"name\"\u003e\u003c/vui-greeting\u003e\n\n  \u003ctemplate x-component=\"greeting\"\u003e\n    \u003ch1\u003e\n      \u003cspan x-text=\"$prop('greeting-word')\"\u003e\u003c/span\u003e\n      \u003cspan x-text=\"$prop('who')\"\u003e\u003c/span\u003e\n    \u003c/h1\u003e\n    \u003cbutton @click=\"$api.say()\"\u003eClick me\u003c/button\u003e\n    \u003cscript\u003e\n      return {\n        say() {\n          alert(this.$prop(\"greeting-word\") + \" \" + this.$prop(\"who\"));\n        },\n      };\n    \u003c/script\u003e\n  \u003c/template\u003e\n\u003c/body\u003e\n```\n\n[Run on codepen](https://codepen.io/vimeshjs/pen/JjZBvPy)\n\nThe default custom element namespace is `vui`, which could be modified in config. You could also give a different namespace with format `x-component:{namespace}=\"component name\"`\n\n```html\n\u003chead\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n  \u003cscript\u003e\n    $vui.config = {\n      namespace: \"myui\",\n    };\n  \u003c/script\u003e\n\u003c/head\u003e\n\n\u003cbody x-data\u003e\n  \u003cmyui-greeting\u003eMy UI\u003c/myui-greeting\u003e\n  \u003cnew-greeting\u003eMy UI\u003c/new-greeting\u003e\n\n  \u003ctemplate x-component=\"greeting\"\u003e\n    \u003ch1\u003eHello \u003cslot\u003e\u003c/slot\u003e\u003c/h1\u003e\n  \u003c/template\u003e\n\n  \u003ctemplate x-component:new=\"greeting\"\u003e\n    \u003ch1\u003eHi \u003cslot\u003e\u003c/slot\u003e\u003c/h1\u003e\n  \u003c/template\u003e\n\u003c/body\u003e\n```\n\n[Run on codepen](https://codepen.io/vimeshjs/pen/LYrrjdq)\n\nThe final html result will be\n\n```html\n...\n\n\u003cbody x-data\u003e\n  \u003cmyui-greeting\u003e\u003ch1\u003eHello My UI\u003c/h1\u003e\u003c/myui-greeting\u003e\n  \u003cnew-greeting\u003e\u003ch1\u003eHi My UI\u003c/h1\u003e\u003c/new-greeting\u003e\n\u003c/body\u003e\n```\n\nIn some cases, we do not want the component tag to exist in the result. We could just add an `unwrap` modifier in `x-component`.\n\n```html\n...\n\n\u003cbody x-data\u003e\n  \u003cmyui-greeting\u003eMy UI\u003c/myui-greeting\u003e\n  \u003cnew-greeting\u003eMy UI\u003c/new-greeting\u003e\n\n  \u003ctemplate x-component.unwrap=\"greeting\"\u003e\n    \u003ch1\u003eHello \u003cslot\u003e\u003c/slot\u003e\u003c/h1\u003e\n  \u003c/template\u003e\n\n  \u003ctemplate x-component:new.unwrap=\"greeting\"\u003e\n    \u003ch1\u003eHi \u003cslot\u003e\u003c/slot\u003e\u003c/h1\u003e\n  \u003c/template\u003e\n\u003c/body\u003e\n```\n\nThe component tags `myui-greeting` and `new-greeting` will no longer exist in the final html result\n\n```html\n...\n\n\u003cbody x-data\u003e\n  \u003ch1\u003eHello My UI\u003c/h1\u003e\n  \u003ch1\u003eHi My UI\u003c/h1\u003e\n\u003c/body\u003e\n```\n\n## x-import\n\nOf course, we don't want to embed common components in every page. The `x-import` directive helps to load remote components asynchronously. Let's extract the greeting component into a standalone file.\n\n\u003e /hello-remote.html\n\n```html\n\u003chead\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n  \u003cscript\u003e\n    $vui.config.importMap = {\n      \"*\": \"./components/${component}.html\",\n    };\n  \u003c/script\u003e\n  \u003cstyle\u003e\n    [x-cloak] {\n      display: none !important;\n    }\n  \u003c/style\u003e\n\u003c/head\u003e\n\n\u003cbody x-cloak x-import=\"greeting\"\u003e\n  \u003cvui-greeting\u003eVimesh UI\u003c/vui-greeting\u003e\n\u003c/body\u003e\n```\n\n\u003e /components/greeting.html\n\n```html\n\u003ctemplate x-component=\"greeting\"\u003e\n  \u003ch1\u003eCloud Hello \u003cslot\u003e\u003c/slot\u003e\u003c/h1\u003e\n\u003c/template\u003e\n```\n\nThe components could be loaded from anywhere, like\n\n```html\n\u003cscript\u003e\n  $vui.config.importMap = {\n    \"*\": \"https://unpkg.com/@vimesh/ui/examples/components/${component}.html\",\n  };\n\u003c/script\u003e\n```\n\n[Run on codepen](https://codepen.io/vimeshjs/pen/poKKrYd)\n\n`x-import` could load components from different namespaces. The syntax is `x-import=\"namespace1:comp11,comp12;namespace2:comp21,comp22;...\"`. For default namespace, it could be omitted.\nHere is a more complete example:\n\n\u003e /counters.html\n\n```html\n\u003chead\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/style\" defer\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n\n  \u003cscript\u003e\n    $vui.config.importMap = {\n      \"*\": \"./components/${component}.html\",\n    };\n  \u003c/script\u003e\n  \u003cstyle\u003e\n    [x-cloak] {\n      display: none !important;\n    }\n  \u003c/style\u003e\n\u003c/head\u003e\n\n\u003cbody\n  x-cloak\n  x-import=\"counter;counter-trigger\"\n  class=\"p-2\"\n  x-data=\"{name: 'Counter to rename', winner: 'Jacky'}\"\n\u003e\n  Rename the 2nd counter :\n  \u003cinput\n    type=\"text\"\n    x-model=\"name\"\n    class=\"rounded-md border-2 border-blue-500\"\n  /\u003e\n  \u003cvui-counter\n    x-data=\"{step: 1}\"\n    :primary=\"true\"\n    title=\"First\"\n    x-init=\"console.log('This is the first one')\"\n    owner-name=\"Tom\"\n  \u003e\u003c/vui-counter\u003e\n  \u003cvui-counter\n    x-data=\"{step: 5}\"\n    :title=\"name + ' @ ' + $prop('owner-name')\"\n    owner-name=\"Frank\"\n  \u003e\u003c/vui-counter\u003e\n  \u003cvui-counter x-data=\"{step: 10, value: 1000}\" :owner-name=\"winner\"\u003e\n    \u003cvui-counter-trigger\u003e\u003c/vui-counter-trigger\u003e\n  \u003c/vui-counter\u003e\n\u003c/body\u003e\n```\n\n\u003e /components/counter.html\n\n```html\n\u003ctemplate\n  x-component.unwrap=\"counter\"\n  :class=\"$prop('primary') ? 'text-red-500' : 'text-blue-500'\"\n  x-data=\"{ step : 1, value: 0}\"\n  x-init=\"$api \u0026\u0026 $api.init()\"\n  title=\"Counter\"\n  owner-name=\"nobody\"\n\u003e\n  \u003cdiv\u003e\n    \u003cspan x-text=\"$prop('title')\"\u003e\u003c/span\u003e\u003cbr /\u003e\n    Owner: \u003cspan x-text=\"$prop('owner-name')\"\u003e\u003c/span\u003e\u003cbr /\u003e\n    Step: \u003cspan x-text=\"step\"\u003e\u003c/span\u003e\u003cbr /\u003e\n    Value : \u003cspan x-text=\"value\"\u003e\u003c/span\u003e\u003cbr /\u003e\n    \u003cbutton\n      @click=\"$api.increase()\"\n      class=\"inline-block rounded-lg bg-indigo-600 px-4 py-1.5 text-white shadow ring-1 ring-indigo-600 hover:bg-indigo-700 hover:ring-indigo-700\"\n    \u003e\n      Increase\n    \u003c/button\u003e\n    \u003cslot\u003e\u003c/slot\u003e\n  \u003c/div\u003e\n  \u003cscript\u003e\n    return {\n      init() {\n        console.log(`Value : ${this.value} , Step : ${this.step}`);\n      },\n      increase() {\n        this.value += this.step;\n      },\n    };\n  \u003c/script\u003e\n\u003c/template\u003e\n```\n\n\u003e /components/counter-trigger.html\n\n```html\n\u003ctemplate x-component=\"counter-trigger\"\u003e\n  \u003cbutton\n    @click=\"$api.$of('counter').increase()\"\n    class=\"inline-block rounded-lg mt-2 bg-green-600 px-4 py-1.5 text-white shadow ring-1 ring-green-600 hover:bg-green-700 hover:ring-green-700\"\n  \u003e\n    Tigger from child element\n  \u003c/button\u003e\n\u003c/template\u003e\n```\n\n[Run on codepen](https://codepen.io/vimeshjs/pen/RwJBygE)\n\n### How to import dynamic components ?\n\nAdd `dynamic` modifier to `x-import`, it will evaluate the express to a string or array and then import all these components. Please refer the example in `examples/spa/app.html`.\n\n```html\n\u003ctemplate\n  x-component=\"router-view\"\n  x-shtml=\"$api \u0026\u0026 $api.pageContent || ''\"\n  x-import:dynamic=\"$api \u0026\u0026 $api.pageToImport\"\n\u003e\n  ...\n\u003c/template\u003e\n```\n\n### Auto import all components\n\nSet the `autoImport` config to `true`, Vimesh UI will automatically try to import all custom html elements. Most `x-import` could be omitted. For example the previous `counters.html` could be rewritten as\n\n```html\n\u003chead\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/style\" defer\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n\n  \u003cscript\u003e\n    $vui.config.importMap = {\n      \"*\": \"./components/${component}.html\",\n    };\n    $vui.config.autoImport = true;\n  \u003c/script\u003e\n  \u003cstyle\u003e\n    [x-cloak] {\n      display: none !important;\n    }\n  \u003c/style\u003e\n\u003c/head\u003e\n\n\u003cbody x-cloak class=\"p-2\" x-data=\"{name: 'Counter to rename', winner: 'Jacky'}\"\u003e\n  Rename the 2nd counter :\n  \u003cinput\n    type=\"text\"\n    x-model=\"name\"\n    class=\"rounded-md border-2 border-blue-500\"\n  /\u003e\n  \u003cvui-counter\n    x-data=\"{step: 1}\"\n    :primary=\"true\"\n    title=\"First\"\n    x-init=\"console.log('This is the first one')\"\n    owner-name=\"Tom\"\n  \u003e\u003c/vui-counter\u003e\n  \u003cvui-counter\n    x-data=\"{step: 5}\"\n    :title=\"name + ' @ ' + $prop('owner-name')\"\n    owner-name=\"Frank\"\n  \u003e\u003c/vui-counter\u003e\n  \u003cvui-counter x-data=\"{step: 10, value: 1000}\" :owner-name=\"winner\"\u003e\n    \u003cvui-counter-trigger\u003e\u003c/vui-counter-trigger\u003e\n  \u003c/vui-counter\u003e\n\u003c/body\u003e\n```\n\n## x-include\n\nSometimes we just need to load a piece of html. The `x-include` is convenient to use in this case. The `unwrap` modifier is used to remove the host html tag.\n\n\u003e /include-article.html\n\n```html\n\u003chead\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n\u003c/head\u003e\n\n\u003cbody x-data\u003e\n  Load into the external \"div\" tag:\u003cbr /\u003e\n  \u003cdiv style=\"background-color: #888;\" x-include=\"./static/article\"\u003e\u003c/div\u003e\n\n  Unwrap the external \"div\" tag:\u003cbr /\u003e\n  \u003cdiv\n    style=\"background-color: #888;\"\n    x-include.unwrap=\"./static/article\"\n  \u003e\u003c/div\u003e\n\u003c/body\u003e\n```\n\n\u003e /static/article.html\n\n```html\n\u003ch1\u003eTitle\u003c/h1\u003e\n\u003cp\u003eContent\u003c/p\u003e\n```\n\nThe final result will be\n\n```html\n\u003chead\u003e\n  \u003cscript src=\"https://unpkg.com/@vimesh/ui\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/alpinejs\" defer\u003e\u003c/script\u003e\n\u003c/head\u003e\n\n\u003cbody x-data\u003e\n  Load into the external \"div\" tag:\u003cbr /\u003e\n  \u003cdiv style=\"background-color: #888;\"\u003e\n    \u003ch1\u003eTitle\u003c/h1\u003e\n    \u003cp\u003eContent\u003c/p\u003e\n  \u003c/div\u003e\n\n  Unwrap the external \"div\" tag:\u003cbr /\u003e\n  \u003ch1\u003eTitle\u003c/h1\u003e\n  \u003cp\u003eContent\u003c/p\u003e\n\u003c/body\u003e\n```\n\n[Run on codepen](https://codepen.io/vimeshjs/pen/ExRpLbb)\n\n## x-shtml\n\nIn Vimesh UI, please use x-shtml instead of Alpine.js original x-html, which has wrong behaviors in case of complex component lifecycle.\n\n# Advanced Usage\n\n## $api for component\n\n`x-data` is very convenient to use. Its data is accessible to all descendant elements. There is no problems for simple static web page. When developping reusable components, `x-data` is too open to store component own states. We do not want the properties to be modified occasionally just because of name confliction. `$api` allows to define **private** properties and methods. `$api` is only available to current component. At the same time, it inherets from x-data. That means if `this.somePropOrMethod` does not exist in $api, it will check `somePropOrMethod` from x-data. `$api` has some predefined properties and methods:\n\n| Properties | Description                                                                |\n| ---------- | -------------------------------------------------------------------------- |\n| $meta      | Get the meta info of current component, including type, namespace, prefix. |\n| $parent    | Get the closest parent component element                                   |\n\n| Methods               | Description                                                                                                                                        |\n| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |\n| $of('component type') | Find the $api of specific component type of its ancestors. If the component type is empty, it will return the $api of its closest parent component |\n| $closest(filter)      | Find the closest ancestor component element according to the filter, which could be component type or a function                                   |\n| $find(filter)         | Find all descendant component element according to the filter, which could be component type or a function                                         |\n| $findOne(filter)      | It is similar to $find, but only return the first component element match the filter                                                               |\n\n`x-data` has two lifecycle hooks: init and destroy. `$api` has equivalents:\n| x-data | $api |\n| ----------- | ----------- |\n| init() | onMounted() |\n| destroy() | onUnmounted() |\n\n## $vui global variable\n\nOnce Vimesh UI is initialized, there is a global variable `$vui` attached to `window`.\n\n| Property/Method                               | Description                                                                                                                            |\n| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |\n| $vui.config                                   | A config object of `debug` mode flag and `importMap`                                                                                   |\n| $vui.\\_                                       | An utility object of some most used functions: `isString`, `isArray`, `isFunction`, `isPlainObject`, `each`, `map`, `filter`, `extend` |\n| $vui.getComponentMeta(element)                | Get component type and namespace from html element                                                                                     |\n| $vui.isComponent(element)                     | Return true if an html element is a Vimesh UI component                                                                                |\n| $vui.visitComponents(elContainer, callback)   | Recursively visit all components inside an html container element with callback                                                        |\n| $vui.findChildComponents(elContainer, filter) | Find all child component inside an html container element with specific filter, which could be component type or a function            |\n| $vui.getParentComponent(element)              | Get the parent component of specific html element                                                                                      |\n| $vui.findClosestComponent(element, filter)    | Find the closest ancestor component element according to the filter, which could be component type or a function                       |\n| $vui.$api(element)                            | Get $api of a component element                                                                                                        |\n| $vui.$data(element)                           | Alias of Alpine.$data(element)                                                                                                         |\n| $vui.setHtml(elContainer, html)               | Load html into a container element. And Vimesh UI components in the html will be correctly initialized                                 |\n| $vui.defer(callback)                          | Execute callback in next event loop.                                                                                                   |\n| $vui.dom(html)                                | Load a plain html into dom with Vimesh UI components correctly initialized                                                             |\n| $vui.nextTick(callback)                       | Alias of Alpine.nextTick(callback)                                                                                                     |\n| $vui.effect(callback)                         | Alias of Alpine.effect(callback)                                                                                                       |\n| $vui.focus(element, option)                   | Try to make an html element focused                                                                                                    |\n| $vui.scrollIntoView(element)                  | Try to scroll an html element into view                                                                                                |\n\n## Multi pages application\n\nCheck [mpa example](/examples/mpa)\n\n## Single page application\n\nCheck [spa example](/examples/spa/app.html)\n\n## Real UI components\n\n[Vimesh Headless UI](https://github.com/vimeshjs/vimesh-headless) includes some useful components, like Listbox, Combobox, Menu, Dialog, Tabs, Switch etc. It is a good start point for you to develop your own UI library.\n\n![](./assets/vimesh002.jpg)\n\n![](./assets/vimesh003.jpg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvimeshjs%2Fvimesh-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvimeshjs%2Fvimesh-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvimeshjs%2Fvimesh-ui/lists"}