Skip to content

Commit b00b453

Browse files
[DEV] Added reverse transition
1 parent 2791c3f commit b00b453

File tree

9 files changed

+441
-151
lines changed

9 files changed

+441
-151
lines changed

src/plugin/VStepperForm.vue

Lines changed: 233 additions & 93 deletions
Large diffs are not rendered by default.

src/plugin/components/fields/VSFFancyRadio/VSFFancyRadio.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ const props = defineProps<VSFFancyRadioProps>();
7474
const { field, settings } = toRefs(props);
7575
7676
77-
console.group('VSFFancyRadio');
78-
console.log('field', field);
79-
console.log('settings', settings);
80-
console.groupEnd();
77+
// console.group('VSFFancyRadio');
78+
// console.log('field', field);
79+
// console.log('settings', settings);
80+
// console.groupEnd();
8181
8282
8383
const densityHeight = {
@@ -91,7 +91,7 @@ const densityHeight = {
9191
const fieldVariant = ref(field.value?.variant ?? 'filled');
9292
9393
const fieldColor = computed(() => {
94-
let colorAdjustment = field.value?.color ?? settings.value?.color ?? 'primary';
94+
let colorAdjustment = field.value?.color ?? settings.value?.color;
9595
colorAdjustment = colorAdjustment === 'default' || colorAdjustment === 'surface' ? 'on-surface' : colorAdjustment;
9696
9797
return colorAdjustment;

src/plugin/components/fields/VSFTextField/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type VSFTextField from './VSFTextField.vue';
99
interface InternalField extends Omit<Field,
1010
'inline' | 'inlineSpacing' | 'labelPositionLeft'
1111
> {
12+
color?: VTextField['color'];
1213
density?: VTextField['density'];
1314
hideDetails?: VTextField['hideDetails'];
1415
variant?: VTextField['variant'];

src/plugin/components/shared/PageContainer.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,14 @@
160160
<script setup lang="ts">
161161
import * as Fields from '../fields/index';
162162
import type {
163-
FormSettings,
164163
Page,
164+
Settings,
165165
} from '../../types/index';
166166
167167
export interface FieldLabelProps {
168168
index: number;
169169
page: Page;
170-
settings: FormSettings;
170+
settings: Settings;
171171
}
172172
173173
const { index, page } = defineProps<FieldLabelProps>();
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<template>
2+
<v-row v-if="page.title">
3+
<v-col>
4+
<h3>
5+
{{ page.title }}
6+
</h3>
7+
</v-col>
8+
</v-row>
9+
10+
<v-row v-if="page.text">
11+
<v-col>
12+
{{ page.text }}
13+
</v-col>
14+
</v-row>
15+
16+
<v-row>
17+
<v-col>
18+
<v-list lines="two">
19+
<v-card
20+
v-for="field in allFieldsArray"
21+
:key="field.name"
22+
class="mb-2"
23+
color="background"
24+
>
25+
<v-list-item
26+
v-if="canReview"
27+
:ripple="canReview"
28+
:title="field.label"
29+
@click="canReview ? goToQuestion(field) : null"
30+
>
31+
<v-list-item-subtitle :class="`text-${settings.color}`">
32+
{{ modelValue[field.name] }}
33+
</v-list-item-subtitle>
34+
</v-list-item>
35+
36+
<v-list-item
37+
v-else
38+
:ripple="false"
39+
:title="field.label"
40+
>
41+
<v-list-item-subtitle :class="`text-${settings.color}`">
42+
{{ modelValue[field.name] }}
43+
</v-list-item-subtitle>
44+
</v-list-item>
45+
</v-card>
46+
</v-list>
47+
48+
</v-col>
49+
</v-row>
50+
51+
52+
<v-row>
53+
<v-col>
54+
<v-btn
55+
:color="settings.color"
56+
@click="submitForm"
57+
>Submit</v-btn>
58+
</v-col>
59+
</v-row>
60+
</template>
61+
62+
<script setup lang="ts">
63+
import type {
64+
Field,
65+
Page,
66+
Settings,
67+
} from '../../types/index';
68+
69+
export interface PageReviewContainerProps {
70+
canReview: boolean;
71+
page: Page;
72+
pages: Page[];
73+
settings: Settings;
74+
}
75+
76+
const { page, pages } = defineProps<PageReviewContainerProps>();
77+
78+
const emit = defineEmits([
79+
'goToQuestion',
80+
'submit',
81+
]);
82+
83+
const modelValue = defineModel<any>();
84+
85+
const allFieldsArray = ref<Field[]>([]);
86+
87+
Object.values(pages).forEach((p) => {
88+
Object.values(p.fields).forEach((field: Field) => {
89+
allFieldsArray.value.push(field as Field);
90+
});
91+
});
92+
93+
function goToQuestion(field: Field) {
94+
let pageIndex = pages.findIndex(page => page.fields.some(f => f.name === field.name));
95+
96+
if (pages[pageIndex]?.editable === false) {
97+
return;
98+
}
99+
100+
pageIndex = pageIndex + 1;
101+
102+
emit('goToQuestion', pageIndex);
103+
}
104+
105+
106+
function submitForm() {
107+
// console.log('PageViewContainer submitForm');
108+
109+
emit('submit');
110+
}
111+
112+
// function callback() {
113+
// console.log('callback');
114+
// }
115+
</script>
116+
117+
<style lang="scss" scoped></style>

src/plugin/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ import FieldLabel from './components/shared/FieldLabel.vue';
88
export const globalOptions = Symbol();
99

1010
export function createVStepperForm(options: GlobalOptions = {
11-
settings: {
12-
color: 'primary',
13-
density: 'default' as const,
14-
},
11+
// color: 'primary',
12+
// density: 'default' as const,
1513
}) {
1614
const install = (app: App) => {
1715
app.provide(globalOptions, options);

src/plugin/types/index.ts

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import type {
88
// VIcon,
99
VRadio,
1010
VSelect,
11+
VStepper,
12+
VStepperItem,
13+
// VStepperActions,
14+
VStepperWindowItem,
1115
VSwitch,
1216
VTextField,
1317
VTextarea,
@@ -74,57 +78,84 @@ export interface Field {
7478
labelPositionLeft?: boolean; // ? Checkboxes
7579
}
7680

77-
export interface FormSettings {
78-
color?: string;
79-
density?: GlobalDensity;
80-
hideDetails?: boolean;
81-
validateOn?: Field['validateOn'];
82-
variant?: string;
83-
}
8481

85-
export interface WelcomeScreen {
86-
attachment?: object;
87-
ref?: string;
88-
title: string;
89-
properties?: {
90-
buttonText?: string;
91-
description?: string;
92-
showButton?: boolean;
93-
};
82+
// ! TS Issue with this, possible bug makes it not work ! //
83+
// export interface VStepperProps extends Pick<VStepper,
84+
// 'altLabels' |
85+
// 'bgColor' |
86+
// 'border' |
87+
// 'disabled' |
88+
// 'editable' |
89+
// 'editIcon' |
90+
// 'nextText' |
91+
// 'prevText' |
92+
// 'rounded' |
93+
// 'width'
94+
// > { }
95+
96+
export interface VStepperProps {
97+
altLabels?: VStepper['altLabels'];
98+
bgColor?: VStepper['bgColor'];
99+
border?: VStepper['border'];
100+
disabled?: VStepper['disabled'];
101+
editIcon?: VStepper['editIcon'];
102+
editable?: VStepper['editable'];
103+
elevation?: VStepper['elevation'];
104+
flat?: VStepper['flat'];
105+
height?: VStepper['height'];
106+
hideActions?: VStepper['hideActions'];
107+
maxHeight?: VStepper['maxHeight'];
108+
maxWidth?: VStepper['maxWidth'];
109+
minHeight?: VStepper['minHeight'];
110+
minWidth?: VStepper['minWidth'];
111+
nextText?: VStepper['nextText'];
112+
prevText?: VStepper['prevText'];
113+
rounded?: VStepper['rounded'];
114+
selectedClass?: VStepper['selectedClass'];
115+
theme?: VStepper['theme'];
116+
tile?: VStepper['tile'];
117+
width?: VStepper['width'];
94118
}
95119

96-
export interface Page {
97-
fields: Field[];
98-
title?: string;
99-
text?: string;
120+
interface VStepperWindowItemProps {
121+
transition?: VStepperWindowItem['transition'];
100122
}
101123

124+
102125
// -------------------------------------------------- Props //
103-
export interface Props {
104-
fields?: Field[];
105-
hidden?: Field[];
106-
settings?: FormSettings;
107-
title?: string;
108-
welcomeScreens?: WelcomeScreen[];
126+
export interface Props extends VStepperProps, VStepperWindowItemProps {
127+
// Required //
109128
pages: Page[];
129+
130+
// Optional //
131+
// TODO: Determine a better prop name for canReview //
132+
canReview?: boolean;
133+
color?: string;
134+
density?: GlobalDensity;
135+
direction?: string;
136+
hideDetails?: boolean;
137+
title?: string;
138+
validateOn?: Field['validateOn'];
139+
variant?: string;
140+
width?: string;
110141
}
111142

112143
export interface GlobalOptions extends Partial<Props> { }
144+
export interface Settings extends Partial<Omit<Props, 'pages'>> { }
113145

114146

115147
// -------------------------------------------------- Components //
116148
export interface SharedProps {
117149
field: Field;
118-
settings?: Props['settings'];
150+
settings?: Settings;
119151
}
120152

121-
// -------------------------------------------------- Composables //
122-
export interface UseComposableName {
123-
(
124-
options: {
125-
foo?: string;
126-
}
127-
): Props;
153+
export interface Page {
154+
fields: Field[];
155+
isReview?: boolean;
156+
editable?: VStepperItem['editable'];
157+
title?: string;
158+
text?: string;
128159
}
129160

130161
// ------------------------- Helpers //

src/plugin/utils/emits.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export default [
22
// 'error',
33
// 'update',
4+
'submit',
45
'update:model-value',
56
];

src/plugin/utils/props.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
export const AllProps = {
2-
fields: () => [],
3-
hidden: () => [],
4-
settings: () => ({}),
2+
altLabels: false,
3+
bgColor: undefined,
4+
border: undefined,
5+
canReview: true,
6+
color: 'primary',
7+
density: 'default' as const,
8+
disabled: false,
9+
editable: false,
10+
hideDetails: false,
11+
nextText: '$vuetify.stepper.next',
12+
pages: () => [],
13+
prevText: '$vuetify.stepper.prev',
514
title: undefined,
6-
welcomeScreens: () => [{
7-
attachment: undefined,
8-
properties: {
9-
buttonText: 'Start',
10-
description: undefined,
11-
showButton: true,
12-
},
13-
ref: undefined,
14-
title: '',
15-
}],
15+
transition: 'fade-transition',
16+
variant: undefined,
17+
width: '100%',
1618
};

0 commit comments

Comments
 (0)