Skip to content

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

Draft
niLPotential wants to merge 192 commits into
chakra-ui:mainfrom
niLPotential:alpine-ts
Draft

feat: add alpine-ts example (WIP)#2870
niLPotential wants to merge 192 commits into
chakra-ui:mainfrom
niLPotential:alpine-ts

Conversation

@niLPotential

@niLPotential niLPotential commented Nov 24, 2025

Copy link
Copy Markdown

📝 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 and service 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: June 27, 2026

e2e status
accordion
angle-slider
avatar
carousel
cascade-select
checkbox
clipboard
collapsible
color-picker
combobox
context-menu-multiple-trigger
context-menu
date-input ⚠️
date-picker
dialog-multiple-trigger
dialog
drawer-indent
drawer-swipe-area ⚠️
drawer ⚠️
editable
file-upload
floating-panel
hover-card-multiple-trigger
hover-card
image-cropper
listbox
menu-multiple-trigger
menu-nested
menu-option
menu
navigation-menu
number-input ⚠️
pagination
password-input
pin-input ⚠️
popover-multiple-trigger
popover
radio-group
rating-group
select ⚠️
slider
splitter
switch
tabs
tags-input
toast
toggle-group
tooltip-multiple-trigger
tooltip
tour
tree-view
  • date-input, drawer, drawer-swipe-area, number-input: flaky
  • pin-input: getInputProps > onBeforeInput prevents input event
  • select: SelectModel.autofill does not dispatch input event
  • cascate-select, tree-view: recusive structure

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