Skip to content

Dev #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 25, 2025
Merged

Dev #35

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/documentation/components/examples/ButtonsFieldExample.vue
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ const pages = computed(() => [
{
fields: [
{
align: buttonAlignModel,
block: buttonBlock,
align: buttonAlignModel.value,
block: buttonBlock.value,
label: 'I like buttons',
name: 'iLikeButtons',
options: [
Expand Down Expand Up @@ -309,8 +309,8 @@ const pages = computed(() => [
type: 'buttons' as const,
},
{
align: buttonAlignModel,
block: buttonBlock,
align: buttonAlignModel.value,
block: buttonBlock.value,
label: 'I like...',
multiple: true,
name: 'animalsILike',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
<template>
<VStepperForm
v-model="answers"
color="primary"
:pages="pages"
@submit="submitForm"
/>

<AnswersDialog
v-model="dialog"
:answers="answers"
/>
</template>

<script setup lang="ts">
import type { MaybeRef } from 'vue';
import AnswersDialog from '../AnswersDialog.vue';


const dialog = ref(false);
const answers = ref<{
foobar: string | null;
name: string | null;
slug: string | null;
}>({
foobar: null,
name: null,
slug: null,
});

watch(() => answers.value.name, (newVal) => {
setTimeout(() => {
answers.value.slug = newVal ? useSlugifyString(newVal) : '';
}, 1);

if (newVal === 'foo' || answers.value.slug === '') {
selectItems.value = fooItems;
}

if (newVal === 'bar') {
selectItems.value = barItems;
}
});

const fooItems = [
{
title: 'Foo',
value: 'foo',
},
{
title: 'Fiz',
value: 'fiz',
},
];

const barItems = [
{
title: 'Baz',
value: 'baz',
},
{
title: 'Biz',
value: 'biz',
},
];

const selectItems = ref(fooItems);

const pages = computed(() => {
return [
{
fields: [
{
label: 'Name',
name: 'name',
type: 'text' as const,
},
{
label: 'Slug',
name: 'slug',
type: 'text' as const,
},
{
items: selectItems.value,
label: 'Foobar',
name: 'foobar',
type: 'select' as const,
},
],
},
];
});

const useSlugifyString: UseSlugifyString = (string, divider = '_') => {
if (divider !== '_' && divider !== '-') {
throw new Error('[slugifyStringHelper]: Divider must be either "_" or "-"');
}

const unrefString = unref(string);

const a = 'àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/-,:;';
const b = 'aaaaaaaaaacccddeeeeeeeegghiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz------';
const p = new RegExp(a.split('').join('|'), 'g');

let response = unrefString.toString().toLowerCase()
// Replace spaces with divider //
.replace(/\s+/g, divider)
.replace(p, (c) => b.charAt(a.indexOf(c)))
.replace(/&/g, `${divider}and${divider}`)
.replace(/[^\w-]+/g, '');

if (divider === '_') {
response = response.replace(/-+/g, '_')
.replace(/__+/g, '_')
.replace(/^_/, '')
.replace(/^-+/, '')
.replace(/-+$/, '');
}

if (divider === '-') {
response = response.replace(/_+/g, '-')
.replace(/--+/g, '-')
.replace(/^-/, '')
.replace(/^_+/, '')
.replace(/_+$/, '');
}

return response;
};

export interface UseSlugifyString {
(
string: MaybeRef<string>,
divider?: string,
): string;
};

function submitForm(): void {
dialog.value = true;
}

const templateCode = computed(() => (
`<template>
<VStepperForm
v-model="answers"
color="primary"
:pages="pages"
@submit="submitForm"
/>
</template>`
));

const scriptCode = computed(() => (
`\<script setup\>
const answers = ref<{
foobar: string | null;
name: string | null;
slug: string | null;
}>({
foobar: null,
name: null,
slug: null,
});

watch(() => answers.value.name, (newVal) => {
// Ensure the slug value updates correctly by using a setTimeout //
setTimeout(() => {
answers.value.slug = newVal ? useSlugifyString(newVal) : '';
}, 1);

if (newVal === 'foo' || answers.value.slug === '') {
selectItems.value = fooItems;
}

if (newVal === 'bar') {
selectItems.value = barItems;
}
});

const fooItems = [
{
title: 'Foo',
value: 'foo',
},
{
title: 'Fiz',
value: 'fiz',
},
];

const barItems = [
{
title: 'Baz',
value: 'baz',
},
{
title: 'Biz',
value: 'biz',
},
];

const selectItems = ref(fooItems);

const pages = computed(() => {
return [
{
fields: [
{
label: 'Name',
name: 'name',
type: 'text' as const,
},
{
label: 'Slug',
name: 'slug',
type: 'text' as const,
},
{
items: selectItems.value,
label: 'Foobar',
name: 'foobar',
type: 'select' as const,
},
],
},
];
});

const useSlugifyString: UseSlugifyString = (string, divider = '_') => {
if (divider !== '_' && divider !== '-') {
throw new Error('[slugifyStringHelper]: Divider must be either "_" or "-"');
}

const unrefString = unref(string);

const a = 'àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/-,:;';
const b = 'aaaaaaaaaacccddeeeeeeeegghiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz------';
const p = new RegExp(a.split('').join('|'), 'g');

let response = unrefString.toString().toLowerCase()
// Replace spaces with divider //
.replace(/\s+/g, divider)
.replace(p, (c) => b.charAt(a.indexOf(c)))
.replace(/&/g, \`$\{divider}and$\{divider}\`)
.replace(/[^\w-]+/g, '');

if (divider === '_') {
response = response.replace(/-+/g, '_')
.replace(/__+/g, '_')
.replace(/^_/, '')
.replace(/^-+/, '')
.replace(/-+$/, '');
}

if (divider === '-') {
response = response.replace(/_+/g, '-')
.replace(/--+/g, '-')
.replace(/^-/, '')
.replace(/^_+/, '')
.replace(/_+$/, '');
}

return response;
};

export interface UseSlugifyString {
(
string: MaybeRef<string>,
divider?: string,
): string;
};
\</script\>`
));

const exampleCode = computed(() => ({
desc: 'This example showcases how to build a form with dynamic questions and responses. When you enter "foo" or "bar" in the name field, the select field updates automatically.<br /><br />To ensure the "slug" value updates correctly, use a setTimeout function within the watcher to modify its value after the name field changes.',
name: 'Dynamic Answers and Questions',
script: scriptCode.value,
template: templateCode.value,
}));

defineExpose({
exampleCode: exampleCode.value,
});
</script>


<style lang="scss" scoped></style>
2 changes: 2 additions & 0 deletions src/documentation/components/examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import ButtonsFieldExample from './ButtonsFieldExample.vue';
import ColumnsExample from './ColumnsExample.vue';
import ConditionalFieldExample from './ConditionalFieldExample.vue';
import ConditionalPageExample from './ConditionalPageExample.vue';
import DynamicAnswersQuestionsExample from './DynamicAnswersQuestionsExample.vue';
import FieldSlotExample from './FieldSlotExample.vue';
import SimpleExample from './SimpleExample.vue';
import SummaryPageExample from './SummaryPageExample.vue';
Expand All @@ -14,6 +15,7 @@ export {
ColumnsExample,
ConditionalFieldExample,
ConditionalPageExample,
DynamicAnswersQuestionsExample,
FieldSlotExample,
SimpleExample,
SummaryPageExample,
Expand Down
15 changes: 14 additions & 1 deletion src/documentation/sections/ExampleSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
</h2>
</v-col>


<ExampleContainer
:code="getTemplateCode('SimpleExampleRef')"
:codeBlockSettings="codeBlockSettings"
Expand Down Expand Up @@ -116,6 +115,17 @@
:open="refElementsOpen.ConditionalFieldExampleRef"
/>
</ExampleContainer>

<ExampleContainer
:code="getTemplateCode('DynamicAnswersQuestionsExampleRef')"
:codeBlockSettings="codeBlockSettings"
@closePicker="closePicker('DynamicAnswersQuestionsExampleRef');"
>
<Example.DynamicAnswersQuestionsExample
ref="DynamicAnswersQuestionsExampleRef"
:open="refElementsOpen.DynamicAnswersQuestionsExampleRef"
/>
</ExampleContainer>
</v-row>
</template>

Expand All @@ -136,6 +146,7 @@ const ConditionalFieldExampleRef = ref(null);
const ConditionalPageExampleRef = ref(null);
const SummaryPageExampleRef = ref(null);
const TooltipExampleRef = ref(null);
const DynamicAnswersQuestionsExampleRef = ref(null);

const ButtonsFieldExampleRef = ref(null);
const ButtonsFieldExampleCode = ref();
Expand All @@ -145,6 +156,7 @@ const refElements = ref({
ColumnsExampleRef,
ConditionalFieldExampleRef,
ConditionalPageExampleRef,
DynamicAnswersQuestionsExampleRef,
FieldSlotExampleRef,
SimpleExampleRef,
SummaryPageExampleRef,
Expand All @@ -157,6 +169,7 @@ const refElementsOpen = ref({
ColumnsExampleRef: null,
ConditionalFieldExampleRef: null,
ConditionalPageExampleRef: null,
DynamicAnswersQuestionsExampleRef: null,
FieldSlotExampleRef: null,
SimpleExampleRef: null,
SummaryPageExampleRef: null,
Expand Down
Loading