Skip to content

feat: add alpine-ts example (WIP)#2870

Draft
niLPotential wants to merge 147 commits intochakra-ui:mainfrom
niLPotential:alpine-ts
Draft

feat: add alpine-ts example (WIP)#2870
niLPotential wants to merge 147 commits intochakra-ui:mainfrom
niLPotential:alpine-ts

Conversation

@niLPotential
Copy link
Copy Markdown

@niLPotential niLPotential commented Nov 24, 2025

📝 Description

Adds an example project using Zag with Alpine.js.

examples/alpine-ts contains a nitro app compatible with e2e tests.
lib contains the adapter logic mostly similar to other frameworks.
lib/plugin.ts contains a usePlugin hook which connects a Zag machine to Alpine.js as a plugin.
scripts contains the client scripts and server/routes contains the jsx for SSR.

⛳️ Current behavior (updates)

None

🚀 New behavior

// script.ts
import * as component from "@zag-js/component";
import Alpine from "alpinejs"
import { usePlugin } from "../lib"

// component-name should be kebab-case
Alpine.plugin(usePlugin("component-name", component)
Alpine.start()
<!-- index.html -->
<div id="root" x-data x-component-name="{ ...props }">
  <div x-component-name:part-name="{ ...partProps }" />
  <div x-component-name:another-part-name />
  <button x-on:click="$componentName().method()>Click</button>

  <div id="nested" x-component-name.modifier="{ ...props }">
    <div x-component-name:part-name.modifier="{ ...partProps }" />
    <button x-on:click="$componentName('modifier').method()>Click</button>
    <!-- this triggers method of root component from inside nested component -->
    <button x-on:click="$componentName().method()>Click</button>
  </div>
</div>

The name passed in when defining the plugin is used through out for directives and magic.
Names and Values of directives should be kebab-case.
The expression, when present, is passed as arguments to the getComponentPartProps function.
Other api methods are available by calling the corresponding magic. Name of magic is camelCase.
When components need to be more specific (such as when nesting), optional modifiers can be used.
x-data must be defined for components to work.

💣 Is this a breaking change (Yes/No):

No

📝 Additional Information

Last updated: Mar 17, 2026

e2e status
accordion
angle-slider
avatar
carousel
cascade-select
checkbox
clipboard
collapsible
color-picker
combobox
context-menu
date-input ⚠️
date-picker
dialog
drawer-indent
drawer
editable
file-upload
floating-panel
hover-card
image-cropper
listbox
menu-nested
menu-option
menu
navigation-menu
number-input ⚠️
pagination
password-input
pin-input
popover
radio-group
rating-group
select ⚠️
slider
splitter
switch
tabs
tags-input
toast
toggle-group
tooltip
tour
tree-view
  • date-input: onKeyDown event for segment needs additional check event.isComposing since event is already native
  • number-input: rapid input does not sync input well with raf
  • select: autofill does not trigger input event

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants