The EntityAttributeNumberField component is a specialized attribute field dedicated to handling numeric attributes within an entity.
It is built on Quasar’s QInput component configured for numeric input and integrates with the lin-pulsar-core design system and
scoped i18n to provide a consistent, localized, and customizable number field.
- Renders a numeric attribute using a number input
- Automatically casts user input to a number
- Synchronizes the numeric value with the entity model
- Emits normalized entity updates on value changes
- Supports scoped translations for labels and helper texts
- Enables UI customization through the design system
- Supports disabling the field via
inputSettings.disable
The component uses the shared AttributeFieldProps interface with FieldNumberSettings.
| Prop | Type | Required | Description |
|---|---|---|---|
instanceId |
string |
Yes | Identifier used for contextual data |
i18nScope |
string |
Yes | I18n scope for localizing the component |
uiNamespace |
string |
Yes | Base UI design namespace for styling |
definition |
LinPulsarAttributeConfiguration<FieldNumberSettings> |
Yes | Attribute definition (name, type, input configuration) |
entity |
Record<string, unknown> |
Yes | Entity object containing the numeric attribute value |
ignoreRules |
boolean |
No | Indicates whether to bypass validation rules for this field (default: false) |
export interface AttributeFieldProps<T = Record<string, unknown>> extends CommonComponentProps {
/** Identifier of the instance used for contextual data. */
instanceId: string;
/** Attribute configuration describing how the field should be rendered. */
definition: LinPulsarAttributeConfiguration<T>;
/** Entity object holding the attribute value. */
entity: Record<string, unknown>;
/**
* Indicates whether to bypass validation rules for this field.
* When set to true, validation rules will not be applied.
* @default false
*/
ignoreRules?: boolean;
}export interface FieldNumberSettings extends FieldSettings {
/** Minimum value allowed for the input. */
min?: number;
/** Maximum value allowed for the input. */
max?: number;
/** Indicates whether to bypass validation rules for this field. */
ignoreRules?: boolean;
/** When true, the input is rendered as non-interactive (disabled state). */
disable?: boolean;
}| Event | Payload | Description |
|---|---|---|
update:entity |
Record<string, unknown> |
Emitted when the numeric value changes and the entity is updated |
- Emits a new entity object with the updated numeric value
- Avoids mutating the original entity reference
- Keeps state ownership in the parent component
The component uses useScopedI18n to resolve translations for UI text elements.
`${i18nScope}.fields.${definition.name}`;| Key | Usage in UI |
|---|---|
label |
Input label |
hint |
Helper text |
prefix |
Input prefix |
suffix |
Input suffix |
translateOrDefault('', 'label');- Returns the translated value if the key exists
- Falls back to the provided default value when missing
- Prevents untranslated keys from appearing in the UI
UI customization is handled through the lin-pulsar-core design system via useUiDesign().
`${uiNamespace}.${definition.name}`;- Quasar component:
q-input - Input type:
number - Props type:
LinPulsarQInputProps
Example:
uiNamespace = 'entity-editor'
// Final UI namespace
entity-editor.age → q-input (type="number")This allows precise styling and behavior customization per numeric attribute.
The component implements automatic validation based on the attribute's inputSettings, the definition.required property, and the definition.hasValidations property.
Validation rules are generated automatically using useQuasarRules:
const rules = computed(() => (!props.ignoreRules && !props.definition.inputSettings?.ignoreRules ? useQuasarRules(props.instanceId, props.definition, ['min', 'max'], localI18nScope) : []));The validation rules are executed in a specific order to ensure proper validation flow:
-
Required validation (if applicable)
- Depends on the
definition.requiredproperty - If
definition.requiredistrue, this validation is automatically added as the first rule in the validation chain - Ensures that the field is not empty before proceeding to other validations
- Depends on the
-
Specific validation rules (in order)
- The rules specified in the
useQuasarRulesparameters (currently['min', 'max']for number fields) - These rules are executed in the order specified in the array
- Execute after the required validation (if present)
- The rules specified in the
-
Backend API validations (if applicable)
- Depends on the
definition.hasValidationsproperty - If
definition.hasValidationsistrue, backend validation rules are added - These validations are executed last, after all client-side validations pass
- Used for server-side validation logic (e.g., checking uniqueness, business rules)
- Depends on the
| Setting | Description | Example |
|---|---|---|
required |
Marks the field as mandatory. Setting comes from the definition.required property. |
required: true |
min |
Minimum value allowed | min: 0 |
max |
Maximum value allowed | max: 100 |
ignoreRules |
Bypass validation when set to true |
ignoreRules: true |
- If
ignoreRules(prop) anddefinition.inputSettings.ignoreRulesare bothfalseor undefined, validation rules are applied - If
ignoreRules(prop) ordefinition.inputSettings.ignoreRulesesttrue, no validation is performed - Validation messages are automatically translated using the instance's i18n scope
The attribute name supports dot notation to target values located inside sub-objects of the entity (e.g. extraParameters.login):
- The initial value is read from the nested path (
getNestedValuefrom lin-pulsar-core) - Updates rewrite only the targeted nested property, preserving the rest of the entity structure (
setNestedValuefrom lin-pulsar-core) - Missing intermediate objects are created when updating; intermediate values that are not objects are replaced by objects
- The
update:entityevent still emits the complete updated entity object
- Initial value is read from the entity at the path
definition.name(dot notation supported) - User enters a numeric value
v-model.numbercasts the input to a numberlocalValueupdates reactivelyupdateValue()emitsupdate:entitywith a new entity object
QInput (number) → localValue → updateValue → update:entity
const localValue = ref(getNestedValue(props.entity, props.definition.name) ?? null);- Maintains a local reactive copy of the attribute value
- Supports
nullwhen the numeric attribute is initially undefined - A
watchon() => getNestedValue(props.entity, props.definition.name)keepslocalValuein sync when the parent updates the entity — it only triggers when the specific attribute value changes, not when other fields of the entity change
<script setup lang="ts">
import EntityAttributeNumberField from '@/components/field/EntityAttributeNumberField.vue';
const entity = reactive({
age: 30,
});
const definition = {
name: 'age',
input: 'Number',
type: 'Integer',
required: true,
hasValidations: true,
inputSettings: {
min: 18,
max: 120,
ignoreRules: false,
},
};
const onUpdateEntity = (updatedEntity: Record<string, unknown>) => {
Object.assign(entity, updatedEntity);
};
</script>
<template>
<EntityAttributeNumberField
ui-namespace="entity-editor"
instance-id="user-1"
:definition="definition"
:entity="entity"
@update:entity="onUpdateEntity"
/>
</template>- Type-aware input: Ensures values are treated as numbers
- Immutable updates: Emits new entity objects instead of mutating state
- Localized UI: Fully supports scoped translations
- Customizable: Integrates with the UI design system
- Reusable: Works with any numeric attribute definition
- Framework-aligned: Built with Vue 3 Composition API and Quasar best practices
- Verify numeric casting via
v-model.number - Assert
update:entityemission on value change - Mock
useScopedI18nto control translated output - Shallow mount the component to isolate behavior from UI rendering
- Verify that
localValueis updated when the entity value atdefinition.namechanges - Verify that
localValueis not overwritten when only other entity attributes change - Verify the input is rendered as disabled when
definition.inputSettings.disableistrue
- The component assumes
definition.input === 'Number' - Uses
FieldNumberSettingstype forinputSettings, which supportsmin,max,ignoreRules, anddisable - Validation is handled internally using
useQuasarRulesand can be configured viainputSettings - The field is rendered as non-interactive when
definition.inputSettings.disableistrue - Missing translations gracefully fall back to default values
- Intended for use via
EntityAttributeFieldin most scenarios
EntityAttributeNumberField is a leaf component in the entity attribute rendering system.
Its sole responsibilities are:
- Rendering a numeric input
- Managing local numeric state
- Emitting normalized entity updates
All higher-level concerns such as validation, layout, and schema orchestration are delegated to parent components, ensuring a clean and scalable architecture.