Skip to content

Commit e6391df

Browse files
Updating search field to have props and events passed to the component
1 parent 6f9bf56 commit e6391df

File tree

5 files changed

+111
-71
lines changed

5 files changed

+111
-71
lines changed

src/plugin/VDrilldownTable.vue

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
:items="loadedDrilldown.items"
4444
:level="loadedDrilldown.level"
4545
:loading="loadedDrilldown.loading"
46+
:search-container-cols="loadedDrilldown.searchContainerCols"
47+
:search-events="loadedDrilldown.searchEvents"
4648
:search-props="loadedDrilldown.searchProps"
4749
:show-search="loadedDrilldown.showSearch ?? false"
4850
:slot-props="props"
@@ -594,24 +596,47 @@ function updatePage(val: Props['page']) {
594596
}
595597
596598
// ------------ Search //
599+
const searchDebounce = {
600+
debounce: loadedDrilldown.searchDebounce as number,
601+
maxWait: loadedDrilldown.searchMaxWait as number,
602+
};
603+
604+
// ? Using top.left slot //
597605
watchDebounced(
598606
() => props.search,
599607
() => {
600-
levelSearch.value = props.search || '';
601-
602-
const options = updatedOptions(loadedDrilldown);
603-
const drilldown = { ...props, ...options, ...{ search: levelSearch.value } };
604-
const data = { drilldown, search: levelSearch.value };
605-
606-
optionsBus.emit(data);
607-
emit('update:search', data);
608+
searchUpdated();
608609
},
609-
{
610-
debounce: loadedDrilldown.searchDebounce as number,
611-
maxWait: loadedDrilldown.searchMaxWait as number,
610+
searchDebounce,
611+
);
612+
613+
// ? Not using top.left slot //
614+
watchDebounced(
615+
levelSearch,
616+
() => {
617+
searchUpdated();
612618
},
619+
searchDebounce,
613620
);
614621
622+
// Search - Updated //
623+
function searchUpdated() {
624+
if (!slots['top.left']) {
625+
loadedDrilldown.search = levelSearch.value;
626+
}
627+
628+
if (slots['top.left']) {
629+
levelSearch.value = props.search || '';
630+
}
631+
632+
const options = updatedOptions(loadedDrilldown);
633+
const drilldown = { ...props, ...options, ...{ search: levelSearch.value } };
634+
const data = { drilldown, search: levelSearch.value };
635+
636+
optionsBus.emit(data);
637+
emit('update:search', data);;
638+
}
639+
615640
// ------------ Column Sorting //
616641
function updateSortBy(val: Props['sortBy']) {
617642
loadedDrilldown.sortBy = val;

src/plugin/slots/TopSlot.vue

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,15 @@
1919
<v-col
2020
v-else-if="showSearch"
2121
class="d-flex align-center justify-end"
22-
:class="searchFieldClasses"
22+
:class="searchContainerCols"
2323
>
2424
<!-- =========================== Search -->
2525
<v-text-field
2626
v-if="showSearch"
27+
v-bind="boundSearchProps"
2728
v-model="levelSearch"
2829
class="mt-0 pt-0"
29-
:density="searchProps.density"
30-
hide-details
31-
label="Search"
32-
single-line
33-
:variant="searchProps.variant"
30+
v-on="searchEvents"
3431
></v-text-field>
3532
</v-col>
3633

@@ -44,11 +41,7 @@
4441
</template>
4542

4643
<script setup lang="ts">
47-
import {
48-
SearchProps,
49-
SearchPropCols,
50-
TopSlotProps,
51-
} from '@/types';
44+
import { TopSlotProps } from '@/types';
5245
import { componentName } from '@/plugin/utils/globals';
5346
import { watchDebounced } from '@vueuse/core';
5447
@@ -59,20 +52,8 @@ const emit = defineEmits([
5952
'update:search',
6053
]);
6154
62-
const props = withDefaults(defineProps<TopSlotProps>(), {
63-
searchProps: () => ({
64-
cols: {
65-
lg: 3,
66-
md: 6,
67-
sm: 12,
68-
xl: 3,
69-
xs: 12,
70-
xxl: 2,
71-
},
72-
density: 'comfortable',
73-
variant: 'underlined',
74-
})
75-
});
55+
const props = withDefaults(defineProps<TopSlotProps>(), {});
56+
7657
7758
const levelSearch = ref<string>('');
7859
const showTopContent = ref<boolean>(true);
@@ -131,18 +112,30 @@ watchDebounced(
131112
{ debounce: 750, maxWait: 1000 },
132113
);
133114
134-
const searchFieldClasses = computed<object>(() => {
135-
const searchProps = props.searchProps as SearchProps;
136-
const searchCols = searchProps.cols as SearchPropCols;
115+
const boundSearchProps = computed(() => {
116+
return {
117+
...{
118+
density: 'compact',
119+
hideDetails: true,
120+
label: 'Search',
121+
singleLine: true,
122+
variant: 'underlined',
123+
},
124+
...props.searchProps,
125+
};
126+
});
127+
128+
const searchContainerCols = computed<object>(() => {
129+
const col = props.searchContainerCols;
137130
138131
const classes = {
139132
[`${componentName}--search-field`]: true,
140-
[`v-col-${searchCols.xs}`]: searchCols.xs,
141-
[`v-col-sm-${searchCols.sm}`]: searchCols.sm,
142-
[`v-col-md-${searchCols.md}`]: searchCols.md,
143-
[`v-col-lg-${searchCols.lg}`]: searchCols.lg,
144-
[`v-col-xl-${searchCols.xl}`]: searchCols.xl,
145-
[`v-col-xxl-${searchCols.xxl}`]: searchCols.xxl,
133+
[`v-col-${col.xs}`]: true,
134+
[`v-col-sm-${col.sm}`]: true,
135+
[`v-col-md-${col.md}`]: true,
136+
[`v-col-lg-${col.lg}`]: true,
137+
[`v-col-xl-${col.xl}`]: true,
138+
[`v-col-xxl-${col.xxl}`]: true,
146139
};
147140
148141
return classes;

src/plugin/utils/props.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,21 +100,19 @@ export const AllProps = {
100100
page: 1,
101101
returnObject: true, // * Works - Needs to be set to `true`
102102
// rowHeight: undefined, // ? Doesn't seem to work
103-
search: '', // ? Need to test this when top slot is used over showSearch prop
103+
search: '',
104+
searchContainerCols: () => ({
105+
lg: 3,
106+
md: 6,
107+
sm: 12,
108+
xl: 3,
109+
xs: 12,
110+
xxl: 2,
111+
}),
104112
searchDebounce: 750,
113+
searchEvents: () => ({}),
105114
searchMaxWait: 1000,
106-
searchProps: () => ({
107-
cols: {
108-
lg: 3,
109-
md: 6,
110-
sm: 12,
111-
xl: 3,
112-
xs: 12,
113-
xxl: 2,
114-
},
115-
density: 'comfortable',
116-
variant: 'underlined',
117-
}) as const,
115+
searchProps: () => ({}),
118116
selectStrategy: 'page' as const,
119117
separator: 'default' as const,
120118
server: false,

src/stores/props.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,21 +142,40 @@ export const usePropsStore = defineStore('props', () => {
142142
name: 'search',
143143
type: 'string | undefined',
144144
},
145+
{
146+
default: `{
147+
lg: 3,
148+
md: 6,
149+
sm: 12,
150+
xl: 3,
151+
xs: 12,
152+
xxl: 2,
153+
}`,
154+
desc: 'Sets the cols prop of the <code class="inline-code">VCol</code> component that wraps the search input inside the <code class="inline-code"><a href="#slots-top-left">top.left</a></code> slot. This is useful if you want to change the width of the search input.',
155+
name: 'search-container-cols',
156+
type: 'string | undefined',
157+
},
145158
{
146159
default: 750,
147160
desc: 'The delay before the search filters the items',
148161
name: 'search-debounce',
149162
type: 'number | undefined | null',
150163
},
164+
{
165+
default: undefined,
166+
desc: 'Used to bind events to the <code class="inline-code">VTextField</code> used for the search field. You can see an example of how to do this in the Playground <code class="inline-code">tableDefaults.ts</code> file.',
167+
name: 'search-events',
168+
type: 'object',
169+
},
151170
{
152171
default: 1000,
153172
desc: 'The maximum time to wait before the search filters the items',
154173
name: 'search-max-wait',
155174
type: 'number | undefined | null',
156175
},
157176
{
158-
default: 'tbd',
159-
desc: 'The <code class="inline-code">VTextField</code> props',
177+
default: undefined,
178+
desc: 'Used to bind the props of the <code class="inline-code">VTextField</code> used for the search field',
160179
name: 'search-props',
161180
type: 'SearchProps',
162181
},
@@ -186,7 +205,7 @@ export const usePropsStore = defineStore('props', () => {
186205
},
187206
{
188207
default: false,
189-
desc: 'Determines if the table should show the <code class="inline-code">VDrilldownTable</code> built in <code class="inline-code">VTextField</code> in the <code class="inline-code">top</code> slot. Limited <code class="inline-code">VTextField</code> props are supported. If you would like more customization of the search field, we suggest using the available <code class="inline-code"><a href="#slots-supported-top">top</a></code> or <code class="inline-code"><a href="#slots-top-left">top.left</a></code> slots.',
208+
desc: 'Determines if the table should show the <code class="inline-code">VDrilldownTable</code> built in <code class="inline-code">VTextField</code> in the <code class="inline-code">top</code> slot. You can use the prop <code class="inline-code"><a href="#props-all-search-props">search-props</a></code> to customize the <code class="inline-code">VTextField</code>.',
190209
name: 'show-search',
191210
type: 'boolean',
192211
},
@@ -198,7 +217,6 @@ export const usePropsStore = defineStore('props', () => {
198217
},
199218
];
200219

201-
202220
return {
203221
allProps,
204222
tableLoaderProps,

src/types/index.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { CSSProperties, JSXComponent, StyleValue, MaybeRef } from 'vue';
44
import { IconOptions, ThemeInstance } from 'vuetify';
55
import type { EventBusKey } from '@vueuse/core';
6-
import type { VTextField, VProgressCircular, VProgressLinear } from 'vuetify/components';
6+
import type { VProgressCircular, VProgressLinear } from 'vuetify/components';
77
import type { VDataTable, VDataTableServer, VDataTableRow } from 'vuetify/labs/components';
88

99

@@ -97,7 +97,7 @@ export type RGBColor = [number, number, number];
9797

9898

9999
// -------------------------------------------------- Search //
100-
export type SearchPropCols = {
100+
export type SearchContainerCols = {
101101
lg?: number;
102102
md?: number;
103103
sm?: number;
@@ -106,28 +106,30 @@ export type SearchPropCols = {
106106
xxl?: number;
107107
};
108108

109-
export type SearchProps = {
110-
cols?: SearchPropCols;
111-
density?: VTextField['$props']['density'];
112-
variant?: VTextField['$props']['variant'];
109+
export type SearchEvents<T = any> = {
110+
[key: string]: T;
111+
};
112+
113+
export type SearchProps<T = any> = {
114+
[key: string]: T;
113115
};
114116

115117

116118
// -------------------------------------------------- Cell Rendering //
117119
interface CellRender {
118120
(
119-
key?: string,
120121
column?: object,
121122
index?: number,
123+
key?: string,
122124
): void;
123125
};
124126

125127
interface ItemCellRender {
126128
(
127-
itemValue?: string,
128-
item?: object,
129129
column?: object,
130130
index?: number,
131+
item?: object,
132+
itemValue?: string,
131133
): void;
132134
};
133135

@@ -204,7 +206,9 @@ export interface Props {
204206
page?: VDataTable['$props']['page'];
205207
returnObject?: VDataTable['$props']['returnObject'];
206208
search?: string | undefined;
209+
searchContainerCols?: SearchContainerCols;
207210
searchDebounce?: number | undefined | null;
211+
searchEvents?: SearchEvents;
208212
searchMaxWait?: number | undefined | null;
209213
searchProps?: SearchProps;
210214
separator?: 'default' | 'horizontal' | 'vertical' | 'cell' | undefined;
@@ -266,6 +270,8 @@ export interface TopSlotProps extends VDataTableSlotProps {
266270
items: Props['items'];
267271
level: Props['level'];
268272
loading: Props['loading'];
273+
searchContainerCols: SearchContainerCols;
274+
searchEvents?: SearchEvents;
269275
searchProps?: SearchProps;
270276
showSearch: boolean;
271277
};

0 commit comments

Comments
 (0)