Skip to content

Commit 2c1d9ae

Browse files
committed
feat(CascadeSelect): Add new Form Element
1 parent 6409206 commit 2c1d9ae

File tree

5 files changed

+154
-1
lines changed

5 files changed

+154
-1
lines changed

src/components/app/AppTopbar.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const items = ref([
5050
{
5151
label: 'Select',
5252
items: [
53+
{ label: 'CascadeSelect', icon: 'pi pi-fw pi-user-edit', route: '/demo/cascadeSelect' },
5354
{ label: 'Dropdown', icon: 'pi pi-fw pi-user-edit', route: '/demo/dropdown' },
5455
{ label: 'Listbox', icon: 'pi pi-fw pi-user-edit', route: '/demo/listbox' },
5556
{ label: 'MultiSelect', icon: 'pi pi-fw pi-user-edit', route: '/demo/multiSelect' },
@@ -113,7 +114,7 @@ const items = ref([
113114
</nav>
114115
<MegaMenu :model="items" class="w-134">
115116
<template #item="{ item }">
116-
<router-link v-if="item.route" v-slot="{ href, navigate }" class="ml-2" :to="item.route" custom>
117+
<router-link v-if="item.route" v-slot="{ href, navigate }" :to="item.route" custom>
117118
<a v-ripple :href="href" class="text-lg" @click="navigate">
118119
<span :class="item.icon" />
119120
<span class="ml-2">{{ item.label }}</span>

src/formkit/PrimeCascadeSelect.vue

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<script setup lang='ts'>
2+
const props = defineProps({
3+
context: Object,
4+
})
5+
6+
const context = props.context
7+
const attrs = computed(() => context?.attrs)
8+
9+
function handleInput(e: any) {
10+
context?.node.input(props.context?._value)
11+
}
12+
13+
const styleClass = computed(() => (context?.state.validationVisible && !context?.state.valid) ? `${attrs.value?.class} p-invalid` : attrs.value?.class)
14+
</script>
15+
16+
<template>
17+
<div class="p-formkit">
18+
<CascadeSelect
19+
:id="context.id"
20+
v-model="context._value"
21+
:disabled="attrs._disabled ?? false"
22+
:readonly="attrs._readonly ?? false"
23+
:list-style="attrs.style"
24+
:class="styleClass"
25+
:tabindex="attrs.tabindex"
26+
:aria-label="attrs.ariaLabel"
27+
:aria-labelledby="attrs.ariaLabelledby"
28+
:options="attrs?.options"
29+
:option-label="attrs.optionLabel"
30+
:option-value="attrs.optionValue"
31+
:option-group-label="attrs.optionGroupLabel"
32+
:option-group-children="attrs.optionGroupChildren"
33+
:placeholder="attrs.placeholder"
34+
:pt="attrs.pt"
35+
:pt-options="attrs.ptOptions"
36+
:unstyled="attrs.unstyled ?? false"
37+
@change="handleInput"
38+
/>
39+
</div>
40+
</template>

src/formkit/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createInput } from '@formkit/vue'
33

44
import PrimeAutoComplete from './PrimeAutoComplete.vue'
55
import PrimeCalendar from './PrimeCalendar.vue'
6+
import PrimeCascadeSelect from './PrimeCascadeSelect.vue'
67
import PrimeCheckbox from './PrimeCheckbox.vue'
78
import PrimeChips from './PrimeChips.vue'
89
import PrimeColorPicker from './PrimeColorPicker.vue'
@@ -108,6 +109,9 @@ export const primeSelectButtonDefinition: FormKitTypeDefinition = createInput(Pr
108109
export const primeTriStateCheckboxDefinition: FormKitTypeDefinition = createInput(PrimeTriStateCheckbox, {
109110
props: [],
110111
})
112+
export const primeCascadeSelectDefinition: FormKitTypeDefinition = createInput(PrimeCascadeSelect, {
113+
props: [],
114+
})
111115

112116
export const primeInputs = {
113117
primeAutoComplete: primeAutoCompleteDefinition,
@@ -132,4 +136,5 @@ export const primeInputs = {
132136
primeListbox: primeListboxDefinition,
133137
primeSelectButton: primeSelectButtonDefinition,
134138
primeTriStateCheckbox: primeTriStateCheckboxDefinition,
139+
primeCascadeSelect: primeCascadeSelectDefinition,
135140
}

src/modules/primevue.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Breadcrumb from 'primevue/breadcrumb'
99
import Calendar from 'primevue/calendar'
1010
import Card from 'primevue/card'
1111
import Carousel from 'primevue/carousel'
12+
import CascadeSelect from 'primevue/cascadeselect'
1213
import Chart from 'primevue/chart'
1314
import Checkbox from 'primevue/checkbox'
1415
import Chip from 'primevue/chip'
@@ -114,6 +115,7 @@ export const install: UserModule = ({ app, router, isClient }) => {
114115
app.component('Calendar', Calendar)
115116
app.component('Card', Card)
116117
app.component('Carousel', Carousel)
118+
app.component('CascadeSelect', CascadeSelect)
117119
app.component('Chart', Chart)
118120
app.component('Checkbox', Checkbox)
119121
app.component('Chip', Chip)

src/pages/demo/CascadeSelect.vue

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<script setup lang='ts'>
2+
import PrimeInput from '@/components/demo/PrimeInput.vue'
3+
4+
const primeAttributes = 'placeholder, options, filter, optionLabel, optionValue, multiple'
5+
6+
const options = ref([
7+
{
8+
name: 'Australia',
9+
code: 'AU',
10+
states: [
11+
{
12+
name: 'New South Wales',
13+
cities: [
14+
{ cname: 'Sydney', code: 'A-SY' },
15+
{ cname: 'Newcastle', code: 'A-NE' },
16+
{ cname: 'Wollongong', code: 'A-WO' },
17+
],
18+
},
19+
{
20+
name: 'Queensland',
21+
cities: [
22+
{ cname: 'Brisbane', code: 'A-BR' },
23+
{ cname: 'Townsville', code: 'A-TO' },
24+
],
25+
},
26+
],
27+
},
28+
{
29+
name: 'Canada',
30+
code: 'CA',
31+
states: [
32+
{
33+
name: 'Quebec',
34+
cities: [
35+
{ cname: 'Montreal', code: 'C-MO' },
36+
{ cname: 'Quebec City', code: 'C-QU' },
37+
],
38+
},
39+
{
40+
name: 'Ontario',
41+
cities: [
42+
{ cname: 'Ottawa', code: 'C-OT' },
43+
{ cname: 'Toronto', code: 'C-TO' },
44+
],
45+
},
46+
],
47+
},
48+
{
49+
name: 'United States',
50+
code: 'US',
51+
states: [
52+
{
53+
name: 'California',
54+
cities: [
55+
{ cname: 'Los Angeles', code: 'US-LA' },
56+
{ cname: 'San Diego', code: 'US-SD' },
57+
{ cname: 'San Francisco', code: 'US-SF' },
58+
],
59+
},
60+
{
61+
name: 'Florida',
62+
cities: [
63+
{ cname: 'Jacksonville', code: 'US-JA' },
64+
{ cname: 'Miami', code: 'US-MI' },
65+
{ cname: 'Tampa', code: 'US-TA' },
66+
{ cname: 'Orlando', code: 'US-OR' },
67+
],
68+
},
69+
{
70+
name: 'Texas',
71+
cities: [
72+
{ cname: 'Austin', code: 'US-AU' },
73+
{ cname: 'Dallas', code: 'US-DA' },
74+
{ cname: 'Houston', code: 'US-HO' },
75+
],
76+
},
77+
],
78+
},
79+
])
80+
81+
const schema
82+
= [
83+
{
84+
$formkit: 'primeCascadeSelect',
85+
name: 'city',
86+
label: 'Cascade Select',
87+
optionLabel: 'cname',
88+
optionGroupLabel: 'name',
89+
optionGroupChildren: ['states', 'cities'],
90+
options,
91+
placeholder: 'Select a City',
92+
},
93+
]
94+
95+
const data = { }
96+
</script>
97+
98+
<template>
99+
<div>
100+
<PrimeInput
101+
header="CascadeSelect" :schema="schema" :data="data"
102+
:prime-attributes="primeAttributes"
103+
/>
104+
</div>
105+
</template>

0 commit comments

Comments
 (0)