Skip to content

Commit 38472bd

Browse files
committed
chore: wip
1 parent 781cd8a commit 38472bd

File tree

15 files changed

+932
-188
lines changed

15 files changed

+932
-188
lines changed

bun.lock

Lines changed: 55 additions & 57 deletions
Large diffs are not rendered by default.

storage/framework/core/components/popover/src/App.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Footer from './Footer.vue'
33
import Hero from './Hero.vue'
44
import Installation from './Installation.vue'
55
import Styling from './Styling.vue'
6-
import PopoverDemo from './PopoverDemo.vue'
6+
import Example from './Example.vue'
77
import { useSEOHeader } from './composables/useSEOHeader'
88
99
useSEOHeader()
@@ -22,7 +22,7 @@ useSEOHeader()
2222
<Installation />
2323
<Usage />
2424
<Styling />
25-
<PopoverDemo />
25+
<Example />
2626
</main>
2727
<Footer />
2828
</div>

storage/framework/core/components/radio-group/src/App.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts" setup>
2-
import RadioGroupDemo from './RadioGroupDemo.vue'
2+
import Example from './Example.vue'
33
import Footer from './Footer.vue'
44
import Hero from './Hero.vue'
55
import Usage from './Usage.vue'
@@ -22,7 +22,7 @@ useSEOHeader()
2222
>
2323
<Installation />
2424
<Usage />
25-
<RadioGroupDemo />
25+
<Example />
2626
<Styling />
2727
</main>
2828
<Footer />

storage/framework/defaults/components/Docs/Demo/DocsPlayground.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ const isPreviewMode = ref(true);
66
</script>
77

88
<template>
9-
<div class="flex flex-col gap-4 ">
9+
<div class="flex flex-col gap-4">
1010
<div class="flex flex-col gap-2">
11-
<div class="bg-gray-100 dark:bg-gray-800 rounded-lg overflow-hidden">
11+
<div class="bg-gray-100 dark:bg-gray-800 rounded-lg relative">
1212
<div class="flex items-stretch justify-end rounded-t-[10px] px-3 py-1 md:m-1 md:rounded-lg bg-gray-100 dark:bg-gray-800">
1313
<button
1414
class="pointer-events-auto mr-1 flex rounded-md px-3 py-2 text-xs font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/50"
@@ -26,13 +26,13 @@ const isPreviewMode = ref(true);
2626
</button>
2727
</div>
2828

29-
<div class="overflow-auto h-[350px]">
30-
<div v-if="isPreviewMode" >
29+
<div class=" ">
30+
<div v-if="isPreviewMode" class="relative h-full py-4 px-4 relative z-30">
3131
<slot />
3232
</div>
3333

34-
<div v-else class="text-sm">
35-
<slot name="code" />
34+
<div v-else class="overflow-auto h-[350px] text-sm relative z-30 h-">
35+
<slot name="code" />
3636
</div>
3737
</div>
3838
</div>
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
```vue
2+
<script lang="ts" setup>
3+
import { ref } from 'vue'
4+
import { Dropdown, DropdownButton, DropdownItem, DropdownItems } from '@stacksjs/dropdown'
5+
6+
interface MenuItem {
7+
icon?: string
8+
label?: string
9+
action?: () => void
10+
divider?: boolean
11+
variant?: 'danger' | 'default'
12+
}
13+
14+
type MenuSection = (MenuItem | { divider: true })[]
15+
16+
const menuItems: MenuSection = [
17+
{ icon: 'i-hugeicons-pencil-20-solid', label: 'Edit', action: () => console.log('Edit clicked') },
18+
{ icon: 'i-hugeicons-document-duplicate-20-solid', label: 'Duplicate', action: () => console.log('Duplicate clicked') },
19+
{ divider: true },
20+
{ icon: 'i-hugeicons-archive-box-20-solid', label: 'Archive', action: () => console.log('Archive clicked') },
21+
{ icon: 'i-hugeicons-arrow-path-20-solid', label: 'Move', action: () => console.log('Move clicked') },
22+
{ divider: true },
23+
{ icon: 'i-hugeicons-trash-20-solid', label: 'Delete', variant: 'danger', action: () => console.log('Delete clicked') },
24+
]
25+
26+
const isOpen = ref(false)
27+
28+
function groupMenuItems(items: MenuSection): MenuItem[][] {
29+
return items.reduce((acc: MenuItem[][], item) => {
30+
if ('divider' in item && item.divider && acc.length > 0) {
31+
acc.push([])
32+
} else if (!('divider' in item) || !item.divider) {
33+
if (acc.length === 0) acc.push([])
34+
acc[acc.length - 1].push(item as MenuItem)
35+
}
36+
return acc
37+
}, [])
38+
}
39+
</script>
40+
41+
<template>
42+
<Dropdown v-model="isOpen" as="div" class="relative inline-block text-left">
43+
<DropdownButton
44+
class="inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-lg shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-all duration-200"
45+
>
46+
Options
47+
<div
48+
class="i-hugeicons-chevron-down-20-solid w-5 h-5 transition-transform duration-200"
49+
:class="{ 'rotate-180': isOpen }"
50+
/>
51+
</DropdownButton>
52+
53+
<transition
54+
enter-active-class="transition duration-100 ease-out"
55+
enter-from-class="transform scale-95 opacity-0"
56+
enter-to-class="transform scale-100 opacity-100"
57+
leave-active-class="transition duration-75 ease-in"
58+
leave-from-class="transform scale-100 opacity-100"
59+
leave-to-class="transform scale-95 opacity-0"
60+
>
61+
<DropdownItems
62+
class="absolute right-0 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-lg bg-white shadow-lg ring-1 ring-black/5 focus:outline-none"
63+
>
64+
<div
65+
v-for="(section, index) in groupMenuItems(menuItems)"
66+
:key="index"
67+
class="p-1"
68+
>
69+
<DropdownItem
70+
v-for="(item, itemIndex) in section"
71+
:key="itemIndex"
72+
v-slot="{ active }"
73+
@click="item.action?.()"
74+
>
75+
<button
76+
type="button"
77+
class="group relative flex w-full items-center rounded-md px-2 py-2 text-sm outline-none transition-colors"
78+
:class="[
79+
active
80+
? item.variant === 'danger'
81+
? 'bg-red-500 text-white'
82+
: 'bg-indigo-500 text-white'
83+
: item.variant === 'danger'
84+
? 'text-red-600 hover:bg-red-50'
85+
: 'text-gray-700 hover:bg-gray-50',
86+
]"
87+
>
88+
<div
89+
v-if="item.icon"
90+
:class="[
91+
item.icon,
92+
'mr-2 h-5 w-5',
93+
active
94+
? 'text-white'
95+
: item.variant === 'danger'
96+
? 'text-red-600'
97+
: 'text-gray-500 group-hover:text-gray-700'
98+
]"
99+
/>
100+
{{ item.label }}
101+
</button>
102+
</DropdownItem>
103+
</div>
104+
</DropdownItems>
105+
</transition>
106+
</Dropdown>
107+
</template>
108+
109+
```

storage/framework/defaults/components/Docs/Demo/DropdownDemo.vue

Lines changed: 73 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script lang="ts" setup>
22
import { ref } from 'vue'
33
import { Dropdown, DropdownButton, DropdownItem, DropdownItems } from '@stacksjs/dropdown'
4+
import DocsPlayground from './DocsPlayground.vue'
5+
import DropdownCode from './DropdownCode.md'
46
57
interface MenuItem {
68
icon?: string
@@ -38,78 +40,81 @@ function groupMenuItems(items: MenuSection): MenuItem[][] {
3840
</script>
3941

4042
<template>
41-
<div class="max-w-md mt-2">
42-
<div class="space-y-4 ">
43-
<div class="flex flex-col">
44-
<p class="text-gray-600 mt-1">Click the button below to show the dropdown menu</p>
45-
</div>
46-
</div>
47-
48-
<Dropdown v-model="isOpen" as="div" class="relative inline-block text-left">
49-
<DropdownButton
50-
class="inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-lg shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-all duration-200"
51-
>
52-
Options
53-
<div
54-
class="i-hugeicons-chevron-down-20-solid w-5 h-5 transition-transform duration-200"
55-
:class="{ 'rotate-180': isOpen }"
56-
/>
57-
</DropdownButton>
43+
<div class="max-w-4xl">
44+
<DocsPlayground>
45+
<div class="space-y-4 mb-12 flex flex-col items-center justify-center items-center h-[200px]">
46+
<Dropdown v-model="isOpen" as="div" class="relative inline-block text-left">
47+
<DropdownButton
48+
class="inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium rounded-lg shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-all duration-200"
49+
>
50+
Options
51+
<div
52+
class="i-hugeicons-chevron-down-20-solid w-5 h-5 transition-transform duration-200"
53+
:class="{ 'rotate-180': isOpen }"
54+
/>
55+
</DropdownButton>
5856

59-
<transition
60-
enter-active-class="transition duration-100 ease-out"
61-
enter-from-class="transform scale-95 opacity-0"
62-
enter-to-class="transform scale-100 opacity-100"
63-
leave-active-class="transition duration-75 ease-in"
64-
leave-from-class="transform scale-100 opacity-100"
65-
leave-to-class="transform scale-95 opacity-0"
66-
>
67-
<DropdownItems
68-
class="absolute right-0 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-lg bg-white shadow-lg ring-1 ring-black/5 focus:outline-none"
69-
>
70-
<div
71-
v-for="(section, index) in groupMenuItems(menuItems)"
72-
:key="index"
73-
class="p-1"
57+
<transition
58+
enter-active-class="transition duration-100 ease-out"
59+
enter-from-class="transform scale-95 opacity-0"
60+
enter-to-class="transform scale-100 opacity-100"
61+
leave-active-class="transition duration-75 ease-in"
62+
leave-from-class="transform scale-100 opacity-100"
63+
leave-to-class="transform scale-95 opacity-0"
7464
>
75-
<DropdownItem
76-
v-for="(item, itemIndex) in section"
77-
:key="itemIndex"
78-
v-slot="{ active }"
79-
@click="item.action?.()"
65+
<DropdownItems
66+
class="absolute right-0 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-lg bg-white shadow-lg ring-1 ring-black/5 focus:outline-none"
8067
>
81-
<button
82-
type="button"
83-
class="group relative flex w-full items-center rounded-md px-2 py-2 text-sm outline-none transition-colors"
84-
:class="[
85-
active
86-
? item.variant === 'danger'
87-
? 'bg-red-500 text-white'
88-
: 'bg-indigo-500 text-white'
89-
: item.variant === 'danger'
90-
? 'text-red-600 hover:bg-red-50'
91-
: 'text-gray-700 hover:bg-gray-50',
92-
]"
68+
<div
69+
v-for="(section, index) in groupMenuItems(menuItems)"
70+
:key="index"
71+
class="p-1"
9372
>
94-
<div
95-
v-if="item.icon"
96-
:class="[
97-
item.icon,
98-
'mr-2 h-5 w-5',
99-
active
100-
? 'text-white'
101-
: item.variant === 'danger'
102-
? 'text-red-600'
103-
: 'text-gray-500 group-hover:text-gray-700'
104-
]"
105-
/>
106-
{{ item.label }}
107-
</button>
108-
</DropdownItem>
109-
</div>
110-
</DropdownItems>
111-
</transition>
112-
</Dropdown>
73+
<DropdownItem
74+
v-for="(item, itemIndex) in section"
75+
:key="itemIndex"
76+
v-slot="{ active }"
77+
@click="item.action?.()"
78+
>
79+
<button
80+
type="button"
81+
class="group relative flex w-full items-center rounded-md px-2 py-2 text-sm outline-none transition-colors"
82+
:class="[
83+
active
84+
? item.variant === 'danger'
85+
? 'bg-red-500 text-white'
86+
: 'bg-indigo-500 text-white'
87+
: item.variant === 'danger'
88+
? 'text-red-600 hover:bg-red-50'
89+
: 'text-gray-700 hover:bg-gray-50',
90+
]"
91+
>
92+
<div
93+
v-if="item.icon"
94+
:class="[
95+
item.icon,
96+
'mr-2 h-5 w-5',
97+
active
98+
? 'text-white'
99+
: item.variant === 'danger'
100+
? 'text-red-600'
101+
: 'text-gray-500 group-hover:text-gray-700'
102+
]"
103+
/>
104+
{{ item.label }}
105+
</button>
106+
</DropdownItem>
107+
</div>
108+
</DropdownItems>
109+
</transition>
110+
</Dropdown>
111+
</div>
112+
113+
<template #code>
114+
<DropdownCode />
115+
</template>
116+
117+
</DocsPlayground>
113118
</div>
114119
</template>
115120

0 commit comments

Comments
 (0)