Skip to main content

Developer guidelines

In this document is described some guidelines and best practices for the front-end.

Field

Form field

Every form Field.vue be wrapped inside the <FieldWrapper> component. If this is ignored, you will have to manage everything yourself (label, validation, tooltip etc.).

It is important that your field respect some defaults. For example, let's take a look at TextField:

<InputText
v-model="localValue"
@input="$emit('update:modelValue', localValue)"
v-bind="inputProps"
v-focus="config.autofocus"
/>

Important here is the inputProps, which looks something like this:

const inputProps = computed(() => {
return {
id: `field_${props.config.name}`, // Makes clicking on the label focus the input
invalid: fieldErrors.fieldHasValidationMessages.value, // Adds a red border
class: {
'w-full': true // Makes it full width
},
...props.config.attributes // Adds any other attributes
}
})

General elements

In front-end v1 (Quasar) you had the option to pass on a :to property to q-btn. This is not possible in the Button component of PrimeVue. Instead, you should do it like this:

<RouterLink class="router-link" :to="{ name: 'login' }">
{{ $t('auth.Back to login') }}
</RouterLink>

You could optionally put a <Button> inside the <RouterLink> if you want to style it like a button.

Tabs

Keep in mind that tabs are not "lazy", by default. Meaning, the Vue component will be mounted even when the tab view is not active/clicked on. You can put the lazy prop on it to avoid this.

When using PrimeVue TabView, keep in mind that there is horizontal padding for the content. This horizontal padding is unnecessary for mobile (small screens) in most cases. You can remove it:

<TabView :pt="{ panelContainer: { class: $q.ui.screen.lt.md ? 'px-0' : '' } }">

Theming

Widths, heights, margins and paddings

The ui store exposes multiple properties for widths, heights, margins, paddings and states like sideBarDesktopOpen etc:

state: () => ({
darkMode: false,
themeName: 'lara-light',
scale: 14,
windowWidth: 800,
windowHeight: 600,
sideBarWidth: 17,
topBarHeight: 4,
menuTabsHeight: 3.5,
fieldsGap: 4,
fieldLabelGap: 2,
sideBarDesktopOpen: true,
sideBarMobileOpen: false
})

It is good practise to apply consistency throughout the application. For example, when you display a set of fields below each other:

<div class="flex flex-col gap-4">
<TextField />
<TextField />
<TextField />
</div>

It is better to use the ui store for the gap:

<div :class="`flex flex-col gap-${$q.ui.fieldsGap}`">
<TextField />
<TextField />
<TextField />
</div>