Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 34 additions & 20 deletions examples/next-ts/pages/navigation-menu-nested.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,23 @@ export default function Page() {
Products
<ChevronDown />
</button>
<span {...rootMenu.getTriggerProxyProps({ value: "products" })} />
</div>

<div {...rootMenu.getItemProps({ value: "company" })}>
<button {...rootMenu.getTriggerProps({ value: "company" })}>
Company
<ChevronDown />
</button>
<span {...rootMenu.getTriggerProxyProps({ value: "company" })} />
</div>

<div {...rootMenu.getItemProps({ value: "developers", disabled: true })}>
<button {...rootMenu.getTriggerProps({ value: "developers", disabled: true })}>
Developers
<ChevronDown />
</button>
<span {...rootMenu.getTriggerProxyProps({ value: "developers" })} />
</div>

<div {...rootMenu.getItemProps({ value: "pricing" })}>
Expand All @@ -77,14 +80,17 @@ export default function Page() {
<div {...productSubmenu.getListProps()}>
<div {...productSubmenu.getItemProps({ value: "extensibility" })}>
<button {...productSubmenu.getTriggerProps({ value: "extensibility" })}>Extensibility</button>
<span {...productSubmenu.getTriggerProxyProps({ value: "extensibility" })} />
</div>

<div {...productSubmenu.getItemProps({ value: "security" })}>
<button {...productSubmenu.getTriggerProps({ value: "security" })}>Security</button>
<span {...productSubmenu.getTriggerProxyProps({ value: "security" })} />
</div>

<div {...productSubmenu.getItemProps({ value: "authentication" })}>
<button {...productSubmenu.getTriggerProps({ value: "authentication" })}>Authentication</button>
<span {...productSubmenu.getTriggerProxyProps({ value: "authentication" })} />
</div>
<div {...productSubmenu.getIndicatorProps()} />
</div>
Expand All @@ -99,15 +105,15 @@ export default function Page() {
>
{renderLinks(productSubmenu, {
value: "extensibility",
items: ["Donec quis dui", "Vestibulum", "Nunc dignissim"],
items: ["API Extensions", "Plugin System", "Custom Hooks", "Integration Tools"],
})}
{renderLinks(productSubmenu, {
value: "extensibility",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque"],
items: ["Webhooks", "Event Handlers", "Middleware", "SDKs"],
})}
{renderLinks(productSubmenu, {
value: "extensibility",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque"],
items: ["Connectors", "Adapters", "Bridges", "Extensions"],
})}
</Presence>

Expand All @@ -119,15 +125,15 @@ export default function Page() {
>
{renderLinks(productSubmenu, {
value: "security",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque", "Vestibulum"],
items: ["Authentication", "Authorization", "Encryption", "SSL/TLS"],
})}
{renderLinks(productSubmenu, {
value: "security",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque"],
items: ["Firewall", "DDoS Protection", "Security Audit"],
})}
{renderLinks(productSubmenu, {
value: "security",
items: ["Fusce pellentesque", "Aliquam porttitor"],
items: ["Access Control", "Identity Management"],
})}
</Presence>

Expand All @@ -139,15 +145,15 @@ export default function Page() {
>
{renderLinks(productSubmenu, {
value: "authentication",
items: ["Donec quis dui", "Vestibulum", "Nunc dignissim"],
items: ["OAuth", "SAML", "JWT", "Multi-factor Auth"],
})}
{renderLinks(productSubmenu, {
value: "authentication",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque"],
items: ["Social Login", "Passwordless", "Biometrics"],
})}
{renderLinks(productSubmenu, {
value: "authentication",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque"],
items: ["SSO", "User Management", "Role-based Access"],
})}
</Presence>
</Presence>
Expand All @@ -160,14 +166,17 @@ export default function Page() {
<div {...companySubmenu.getListProps()}>
<div {...companySubmenu.getItemProps({ value: "customers" })}>
<button {...companySubmenu.getTriggerProps({ value: "customers" })}>Customers</button>
<span {...companySubmenu.getTriggerProxyProps({ value: "customers" })} />
</div>

<div {...companySubmenu.getItemProps({ value: "partners" })}>
<button {...companySubmenu.getTriggerProps({ value: "partners" })}>Partners</button>
<span {...companySubmenu.getTriggerProxyProps({ value: "partners" })} />
</div>

<div {...companySubmenu.getItemProps({ value: "enterprise" })}>
<button {...companySubmenu.getTriggerProps({ value: "enterprise" })}>Enterprise</button>
<span {...companySubmenu.getTriggerProxyProps({ value: "enterprise" })} />
</div>
</div>
<div {...companySubmenu.getIndicatorProps()} />
Expand All @@ -182,11 +191,11 @@ export default function Page() {
>
{renderLinks(companySubmenu, {
value: "customers",
items: ["Donec quis dui", "Vestibulum", "Nunc dignissim"],
items: ["Customer Stories", "Case Studies", "Testimonials", "Success Metrics"],
})}
{renderLinks(companySubmenu, {
value: "customers",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque"],
items: ["Customer Support", "Help Center", "Documentation"],
})}
</Presence>

Expand All @@ -198,11 +207,11 @@ export default function Page() {
>
{renderLinks(companySubmenu, {
value: "partners",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque", "Vestibulum"],
items: ["Partner Program", "Channel Partners", "Technology Partners", "Resellers"],
})}
{renderLinks(companySubmenu, {
value: "partners",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque"],
items: ["Integration Partners", "Consulting Partners", "System Integrators"],
})}
</Presence>

Expand All @@ -214,11 +223,16 @@ export default function Page() {
>
{renderLinks(companySubmenu, {
value: "enterprise",
items: ["Donec quis dui", "Vestibulum", "Nunc dignissim"],
items: [
"Enterprise Solutions",
"Large Scale Deployments",
"Custom Development",
"Dedicated Teams",
],
})}
{renderLinks(companySubmenu, {
value: "enterprise",
items: ["Fusce pellentesque", "Aliquam porttitor", "Pellentesque"],
items: ["Enterprise Support", "SLA Agreements", "Compliance"],
})}
</Presence>
</Presence>
Expand All @@ -228,11 +242,11 @@ export default function Page() {
<Presence {...rootMenu.getContentProps({ value: "developers" })}>
{renderLinks(rootMenu, {
value: "developers",
items: ["Donec quis dui", "Vestibulum", "Fusce pellentesque", "Aliquam porttitor"],
items: ["Documentation", "API Reference", "SDKs", "Code Samples"],
})}
{renderLinks(rootMenu, {
value: "developers",
items: ["Fusce pellentesque", "Aliquam porttitor"],
items: ["GitHub", "Changelog", "Release Notes"],
})}
</Presence>
</Presence>
Expand All @@ -241,9 +255,9 @@ export default function Page() {
</main>

<Toolbar viz>
<StateVisualizer state={rootService} label="root" />
<StateVisualizer state={productService} label="product" />
<StateVisualizer state={companyService} label="company" />
<StateVisualizer state={rootService} label="root" context={["value", "previousValue"]} />
<StateVisualizer state={productService} label="product" context={["value", "previousValue", "isSubmenu"]} />
<StateVisualizer state={companyService} label="company" context={["value", "previousValue", "isSubmenu"]} />
</Toolbar>
</>
)
Expand Down
55 changes: 31 additions & 24 deletions examples/next-ts/pages/navigation-menu-viewport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,20 @@ export default function Page() {
return (
<>
<main className="navigation-menu viewport">
<Navbar>
<div
style={{
position: "relative",
display: "flex",
boxSizing: "border-box",
alignItems: "center",
padding: "15px 20px",
justifyContent: "space-between",
width: "100%",
backgroundColor: "white",
boxShadow: "0 50px 100px -20px rgba(50,50,93,0.1),0 30px 60px -30px rgba(0,0,0,0.2)",
}}
>
<button>Logo</button>
<div {...api.getRootProps()}>
<div {...api.getIndicatorTrackProps()}>
<div {...api.getListProps()}>
Expand All @@ -39,20 +52,26 @@ export default function Page() {
Products
<ChevronDown />
</button>
<span {...api.getTriggerProxyProps({ value: "products" })} />
<span {...api.getViewportProxyProps({ value: "products" })} />
</div>

<div {...api.getItemProps({ value: "company" })}>
<button {...api.getTriggerProps({ value: "company" })}>
Company
<ChevronDown />
</button>
<span {...api.getTriggerProxyProps({ value: "company" })} />
<span {...api.getViewportProxyProps({ value: "company" })} />
</div>

<div {...api.getItemProps({ value: "developers" })}>
<button {...api.getTriggerProps({ value: "developers" })}>
Developers
<ChevronDown />
</button>
<span {...api.getTriggerProxyProps({ value: "developers" })} />
<span {...api.getViewportProxyProps({ value: "developers" })} />
</div>

<div {...api.getItemProps({ value: "pricing" })}>
Expand Down Expand Up @@ -138,7 +157,17 @@ export default function Page() {
</Presence>
</div>
</div>
</Navbar>
<button>Login</button>
</div>

<header>
<h1>Heading</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos.</p>
<div>
<button>Get Started</button>
<a href="#">Learn More</a>
</div>
</header>
</main>

<Toolbar controls={controls.ui} viz>
Expand All @@ -147,25 +176,3 @@ export default function Page() {
</>
)
}

const Navbar = ({ children }: { children: React.ReactNode }) => {
return (
<div
style={{
position: "relative",
display: "flex",
boxSizing: "border-box",
alignItems: "center",
padding: "15px 20px",
justifyContent: "space-between",
width: "100%",
backgroundColor: "white",
boxShadow: "0 50px 100px -20px rgba(50,50,93,0.1),0 30px 60px -30px rgba(0,0,0,0.2)",
}}
>
<button>Logo</button>
{children}
<button>Login</button>
</div>
)
}
40 changes: 40 additions & 0 deletions examples/nuxt-ts/app/components/Presence.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script lang="ts" setup>
import * as presence from "@zag-js/presence"
import { normalizeProps, useMachine } from "@zag-js/vue"
import type { VNodeRef } from "vue"
import { computed, mergeProps, ref, watch } from "vue"

defineOptions({
inheritAttrs: false,
})

const attrs = useAttrs()

const present = computed(() => !attrs.hidden)
const service = useMachine(
presence.machine,
computed(() => ({ present: present.value })),
)
const api = computed(() => presence.connect(service, normalizeProps))

const nodeRef = ref<VNodeRef | null>(null)
watch(nodeRef, () => {
if (nodeRef.value) {
api.value.setNode(nodeRef.value)
}
})

const mergedProps = computed(() =>
mergeProps({ "data-scope": "presence" }, attrs, {
hidden: !api.value.present,
"data-state": api.value.skip ? undefined : present.value ? "open" : "closed",
ref: nodeRef,
}),
)
</script>

<template>
<div v-bind="mergedProps">
<slot />
</div>
</template>
Loading
Loading