Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
ddc35a1
feat(DropdownMenu): add filter component
praburangki Apr 15, 2026
f71a479
feat(MonthPicker,YearPicker): add month and year pickers
praburangki Apr 16, 2026
525bafa
feat(Checkbox/Switch): add support for custom true/false values
praburangki Apr 16, 2026
5b01174
fix(useForwardExpose): sync currentElement on DOM update
praburangki Apr 16, 2026
aee83b3
fix(Calendar): parity + docs regen
praburangki Apr 16, 2026
6efb98a
feat: color components
praburangki Apr 16, 2026
00b3e51
feat: new TimeRangeField Component
praburangki Apr 16, 2026
33b1335
fix(Toast): resolve accessibility issues flagged by axe-core
praburangki Apr 16, 2026
3978c82
fix(DismissableLayer): guard against non-Element targets in isLayerExist
praburangki Apr 16, 2026
40700be
fix(useBodyScrollLock): prevent permanent scroll lock on rapid toggle
praburangki Apr 16, 2026
9e9c5b8
- fix(useHideOthers): edge case with useHideOthers when nested in a n…
praburangki Apr 16, 2026
157542d
fix(Splitter): emit correct units for pixel-sized panels in events
praburangki Apr 16, 2026
9852de1
chore(Menu): add aria-labelledby to MenuGroup
praburangki Apr 16, 2026
b049d7c
fix(Combobox): close content when focus moves outside with openOnFocus
praburangki Apr 16, 2026
c4d60c3
fix(Splitter): nested px group ignores defaultSize & percentage drift
praburangki Apr 16, 2026
1a058ae
fix(useHideOthers): handle browsers without :popover-open support (Sa…
praburangki Apr 16, 2026
42b4cb9
fix(PinInput): paste only numeric text in numeric mode
praburangki Apr 16, 2026
4be3965
fix(Combobox): prevent addOnBlur from adding raw input when selecting…
praburangki Apr 16, 2026
95a49fd
fix(useGraceArea): add nil guard for hover target in grace area creation
praburangki Apr 16, 2026
52f0c1e
fix(Autocomplete): add IME composition input handling
praburangki Apr 16, 2026
97f609f
fix(FocusScope): don't move focus if DOM mutation occurred before any…
praburangki Apr 16, 2026
02fd30c
fix(tooltip,hovercard): close when scrollable ancestor is scrolled
praburangki Apr 16, 2026
752f395
fix(Listbox): restore highlightOnHover behavior
praburangki Apr 16, 2026
2de7139
fix(useForwardProps): return Partial<T> to correctly type optional bo…
praburangki Apr 16, 2026
4078808
fix(Select): normalize hidden control
praburangki Apr 16, 2026
d80ed42
fix(DateField): fixed direct incorrect passing of date values to inpu…
praburangki Apr 16, 2026
e3ee901
chore(deps): update vue (major)
praburangki Apr 16, 2026
558f093
fix(ListboxVirtualizer): ignore non-element VNodes in slot children
praburangki Apr 16, 2026
d16db04
fix(MonthPicker, YearPicker): preserve day/month when selecting
praburangki Apr 16, 2026
7d9d1e6
chore: lint
praburangki Apr 16, 2026
b80100d
chore: update deps
praburangki Apr 17, 2026
cf8e7b4
chore: version mismatch
praburangki Apr 17, 2026
a4daa29
chore: fix vitest version
praburangki Apr 17, 2026
60f9170
fix: test files
praburangki Apr 17, 2026
6726919
fix: generate script for namespaced
praburangki Apr 17, 2026
e5a69df
chore: fix typos
praburangki Apr 17, 2026
6c2b3dc
chore: update actions version
praburangki Apr 17, 2026
141a2c9
chore: remove all catalogs
praburangki Apr 18, 2026
2ede4cf
chore: remove happy dom
praburangki Apr 18, 2026
527a929
chore: update perkakas
praburangki Apr 20, 2026
1e5039e
chore: sync theme files
praburangki Apr 20, 2026
640456a
chore: add resolutions to pohon
praburangki Apr 20, 2026
15c885f
chore: scan utils dir
praburangki Apr 20, 2026
0b56124
chore(pohon): sync locales and types
praburangki Apr 20, 2026
e859b10
chore(pohon): sync composables
praburangki Apr 21, 2026
63d7cf6
wip: checkpoint for accordion
praburangki Apr 21, 2026
c8900aa
wip: sync components
praburangki Apr 21, 2026
dcfd6d4
chore: sync color mode components
praburangki Apr 21, 2026
35c8a37
chore: sync partial components
praburangki Apr 21, 2026
fafb21b
chore: sync all components
praburangki Apr 22, 2026
ab59568
chore: sync vue ports
praburangki Apr 22, 2026
72d0d5a
chore: refactor isString
praburangki Apr 22, 2026
cb2edc6
chore: use perkakas utils function
praburangki Apr 22, 2026
3d8e4b2
wip: dump all test files
praburangki Apr 22, 2026
959d7e6
chore: fix test for vue env
praburangki Apr 24, 2026
476741f
chore: add component names
praburangki Apr 24, 2026
bcdfdfc
chore: lint components
praburangki Apr 24, 2026
9629918
chore: sync nuxt test files
praburangki Apr 24, 2026
a4a4c0a
chore: add playground files
praburangki Apr 27, 2026
91b8227
chore: rename to pascal case
praburangki Apr 27, 2026
8a256f2
chore: fix test case for nuxt env
praburangki Apr 27, 2026
b399d2b
chore: fix vue files
praburangki Apr 27, 2026
c900fb1
chore: fix select test case
praburangki Apr 27, 2026
9f31d6b
fix(ChatMessage/ChatMessages): preserve generic message type in slot …
praburangki Apr 27, 2026
0fd777f
chore: fix typo
praburangki Apr 27, 2026
7abb7fb
chore: wip docs
praburangki May 1, 2026
fb4647a
chore: extract pohon
praburangki May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
36 changes: 36 additions & 0 deletions .changeset/shaky-books-spend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
"akar": minor
"pohon-ui": minor
---

- feat(DropdownMenu): add filter component
- feat(Checkbox/Switch): add support for custom true/false values
- fix(useForwardExpose): sync currentElement on DOM update
- fix(Calendar): parity + docs regen
- feat: color components
- feat: new TimeRangeField Component
- fix(Toast): resolve accessibility issues flagged by axe-core
- fix(DismissableLayer): guard against non-Element targets in isLayerExist
- fix(useBodyScrollLock): prevent permanent scroll lock on rapid toggle
- fix(useHideOthers): edge case with useHideOthers when nested in a native popover
- fix(Splitter): emit correct units for pixel-sized panels in events
- chore(Menu): add aria-labelledby to MenuGroup
- fix(Combobox): close content when focus moves outside with openOnFocus
- fix(Calendar): add role="application" to fix NVDA keyboard navigation
- fix(Splitter): nested px group ignores defaultSize & percentage drift
- fix(useHideOthers): handle browsers without :popover-open support (Safari 18)
- fix(PinInput): paste only numeric text in numeric mode
- fix(Combobox): prevent addOnBlur from adding raw input when selecting item
- fix(useGraceArea): add nil guard for hover target in grace area creation
- fix(Autocomplete): add IME composition input handling
- fix(FocusScope): don't move focus if DOM mutation occurred before any nodes had focus
- fix(tooltip,hovercard): close when scrollable ancestor is scrolled
- fix(Listbox): restore highlightOnHover behavior
- fix(useForwardProps): return Partial<T> to correctly type optional boolean props
- fix(Select): normalize hidden control
- fix(DateField): fixed direct incorrect passing of date values to input element
- chore(deps): update vue (major)
- fix(TimeField,DateField): avoid changing focus prematurely with previous segment value of 0
- fix(ListboxVirtualizer): ignore non-element VNodes in slot children
- fix(TimeField): change focus after pressing 0 more than once on hour segment with 12 hour locales
- fix(MonthPicker, YearPicker): preserve day/month when selecting
2 changes: 1 addition & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ runs:

steps:
- name: Install pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@v5

- name: Setup Node.js environment
uses: actions/setup-node@v6
Expand Down
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe('given ComponentName', () => {
## Important File Locations

- Component constants: `packages/core/constant/components.ts`
- Primitive base: `packages/core/src/primitive/primitive.ts`
- APrimitive base: `packages/core/src/primitive/primitive.ts`
- Pohon module entry: `packages/pohon/src/module.ts`
- Docs config: `docs/nuxt.config.ts`
- Root scripts: `package.json` (workspace root)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
pohon: ${{ steps.filter.outputs.pohon }}
docs: ${{ steps.filter.outputs.docs }}
steps:
- uses: dorny/paths-filter@v3
- uses: dorny/paths-filter@v4
id: filter
with:
filters: |
Expand Down
93 changes: 38 additions & 55 deletions docs/app/app.vue
Original file line number Diff line number Diff line change
@@ -1,37 +1,15 @@
<script lang="ts" setup>
import { PApp } from '#components';
import {
computed,
provide,
queryCollectionNavigation,
queryCollectionSearchSections,
useAppConfig,
useAsyncData,
useColorMode,
useFaviconFromTheme,
useHead,
useLazyAsyncData,
useNavigation,
useRoute,
useSeoMeta,
} from '#imports';
import LayoutHeaderSearch from './components/header/layout-header-search.vue';
import LayoutHeader from './components/header/layout-header.vue';
import LayoutFooter from './components/layout-footer.vue';
import { colors } from 'unocss/preset-mini';

const route = useRoute();
const appConfig = useAppConfig();
const colorMode = useColorMode();
const { style, link } = useTheme();

const { data: navigation } = useAsyncData(
const { data: navigation } = await useAsyncData(
'navigation',
() => queryCollectionNavigation('docs', [
'framework',
'category',
'description',
]),
() => queryCollectionNavigation('docs', ['framework', 'category', 'description']),
);

const { data: files } = useLazyAsyncData(
'search',
() => queryCollectionSearchSections('docs', {
Expand All @@ -42,32 +20,27 @@ const { data: files } = useLazyAsyncData(
},
);

const color = computed(() => colorMode.value === 'dark' ? 'black' : 'white');
const radius = computed(() => `:root { --pohon-ui-radius: ${appConfig.theme.radius}rem; }`);
const blackAsPrimary = computed(() => appConfig.theme.blackAsPrimary ? ':root { --akar-primary: black; } .dark { --akar-primary: white; }' : ':root {}');
const color = computed(() => colorMode.value === 'dark' ? (colors as any)[appConfig.pohon.colors.neutral][900] : 'white');

useHead({
meta: [
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ key: 'theme-color', name: 'theme-color', content: color },
],
style: [
{ innerHTML: radius, id: 'pohon-ui-radius', tagPriority: -2 },
{ innerHTML: blackAsPrimary, id: 'pohon-ui-black-as-primary', tagPriority: -2 },
],
link: computed(() => [
// { rel: 'icon', type: 'image/svg+xml', href: '/icon.svg' },
{ rel: 'canonical', href: `https://ui.nuxt.com${withoutTrailingSlash(route.path)}` },
...link.value,
]),
style,
htmlAttrs: {
lang: 'en',
},
});

useSeoMeta({
author: 'praburangki',
title: 'Akar',
ogTitle: 'Akar & Pohon UI',
description: 'Create beautiful, responsive & accessible web apps quickly with Vue or Nuxt.',
ogDescription: 'Create beautiful, responsive & accessible web apps quickly with Vue or Nuxt.',
useServerSeoMeta({
ogSiteName: 'Akar',
twitterCard: 'summary_large_image',
twitterCreator: '@praburangki',
});

useFaviconFromTheme();
Expand All @@ -80,30 +53,40 @@ provide('navigation', rootNavigation);
<template>
<PApp
:toaster="appConfig.toaster"
:tooltip="{
delayDuration: 300,
}"
>
<NuxtLoadingIndicator
color="var(--akar-primary)"
color="var(--pohon-primary)"
:height="2"
/>

<div :class="{ root: route.path.startsWith('/docs/') }">
<LayoutHeader v-if="!route.path.startsWith('/examples')" />
<div class="flex">
<div
class="flex-1 min-w-0"
:class="[route.path.startsWith('/docs/') && 'root']"
>
<template v-if="!route.path.startsWith('/examples')">
<Header />
</template>

<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>

<template v-if="!route.path.startsWith('/examples')">
<LayoutFooter />
<template v-if="!route.path.startsWith('/examples')">
<Footer />

<ClientOnly>
<Search
:files="files"
:navigation="navigationByFramework"
/>
</ClientOnly>
</template>
</div>

<template v-if="!route.path.startsWith('/examples')">
<ClientOnly>
<LayoutHeaderSearch
:files="files"
:navigation="navigationByFramework"
/>
<Chat />
</ClientOnly>
</template>
</div>
Expand Down
4 changes: 2 additions & 2 deletions docs/app/components/content/examples/akar/a-pin-input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { APinInputInput, APinInputRoot } from 'akar';
import { ref } from 'vue';

const value = ref<Array<string>>([]);
function handleComplete(e: Array<string>) {
alert(e.join(''));
function handleComplete(event: Array<string>) {
alert(event.join(''));
}
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ const items = [
content: 'Yes! While optimized for Nuxt, Pohon UI works perfectly with standalone Vue projects via our Vite plugin. You can follow the [installation guide](/docs/pohon/getting-started/installation/vue) to get started.',
},
{
label: 'Will Pohon UI work with other CSS frameworks like Tailwind CSS?',
label: 'Will Pohon UI work with other CSS frameworks like UnoCSS?',
icon: 'i-lucide:circle-help',
content: 'No. Pohon UI is designed exclusively for UnoCSS. Tailwind CSS support would require significant architecture changes due to different class naming conventions.',
content: 'No. Pohon UI is designed exclusively for UnoCSS. UnoCSS support would require significant architecture changes due to different class naming conventions.',
},
{
label: 'How does Pohon UI handle accessibility?',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PLink
to="https://github.com/praburangki"
target="_blank"
class="hover:ring-primary transition"
class="transition hover:ring-primary"
raw
>
<PAvatar
Expand All @@ -15,7 +15,7 @@
<PLink
to="https://github.com/wahyu-ivan"
target="_blank"
class="hover:ring-primary transition"
class="transition hover:ring-primary"
raw
>
<PAvatar
Expand All @@ -27,7 +27,7 @@
<PLink
to="https://github.com/GunawanAhmad"
target="_blank"
class="hover:ring-primary transition"
class="transition hover:ring-primary"
raw
>
<PAvatar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,26 @@ const groups = [{
label: 'New file',
icon: 'i-lucide:file-plus',
suffix: 'Create a new file in the current directory',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'New file created!' });
},
kbds: ['meta', 'N'],
}, {
label: 'New folder',
icon: 'i-lucide:folder-plus',
suffix: 'Create a new folder in the current directory',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'New folder created!' });
},
kbds: ['meta', 'F'],
}, {
label: 'New project',
icon: 'i-lucide:folder-git',
suffix: 'Create a new project from a template',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'New project created!' });
},
kbds: ['meta', 'P'],
Expand All @@ -44,17 +44,17 @@ const groups = [{
label: 'Copy link',
icon: 'i-lucide:link',
suffix: 'Copy a link to the current item',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'Link copied to clipboard!' });
},
kbds: ['meta', 'L'],
}, {
label: 'Share via email',
icon: 'i-lucide:mail',
suffix: 'Share the current item via email',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'Share via email dialog opened!' });
},
}, {
Expand All @@ -64,22 +64,22 @@ const groups = [{
children: [{
label: 'Twitter',
icon: 'i-simple-icons:twitter',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'Shared on Twitter!' });
},
}, {
label: 'LinkedIn',
icon: 'i-simple-icons:linkedin',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'Shared on LinkedIn!' });
},
}, {
label: 'Facebook',
icon: 'i-simple-icons:facebook',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'Shared on Facebook!' });
},
}],
Expand All @@ -91,24 +91,24 @@ const groups = [{
label: 'General',
icon: 'i-lucide:sliders',
suffix: 'Configure general settings',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'General settings opened!' });
},
}, {
label: 'Appearance',
icon: 'i-lucide:palette',
suffix: 'Customize the appearance',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'Appearance settings opened!' });
},
}, {
label: 'Security',
icon: 'i-lucide:shield',
suffix: 'Manage security settings',
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
toast.add({ title: 'Security settings opened!' });
},
}],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const items = computed<Array<PContextMenuItem>>(() => [{
onUpdateChecked(checked: boolean) {
showSidebar.value = checked;
},
onSelect(e: Event) {
e.preventDefault();
onSelect(event: Event) {
event.preventDefault();
},
}, {
label: 'Show Toolbar',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const items: Array<Array<PContextMenuItem>> = [
:items="items"
:pohon="{ content: 'w-48' }"
>
<div class="border-border-accented text-sm border rounded-md border-dashed flex w-72 aspect-video items-center justify-center">
<div class="text-sm border border-border-accented rounded-md border-dashed flex w-72 aspect-video items-center justify-center">
Right click here
</div>
</PContextMenu>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const items = [
:items="items"
:pohon="{ content: 'w-48' }"
>
<div class="border-border-accented text-sm border rounded-md border-dashed flex w-72 aspect-video items-center justify-center">
<div class="text-sm border border-border-accented rounded-md border-dashed flex w-72 aspect-video items-center justify-center">
Right click here
</div>

Expand Down
Loading
Loading