quasar-ui-danx 0.4.9 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/danx.es.js +5745 -5699
- package/dist/danx.es.js.map +1 -1
- package/dist/danx.umd.js +7 -7
- package/dist/danx.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/ActionTable/Form/Fields/FieldLabel.vue +18 -15
- package/src/components/ActionTable/Form/Fields/LabelValueBlock.vue +44 -15
- package/src/components/ActionTable/Form/Fields/MultiKeywordField.vue +12 -13
- package/src/components/ActionTable/Form/Fields/NumberField.vue +41 -55
- package/src/components/ActionTable/Form/Fields/SelectField.vue +4 -3
- package/src/components/ActionTable/Form/Fields/TextField.vue +31 -12
- package/src/helpers/formats.ts +79 -9
- package/src/helpers/utils.ts +2 -0
- package/src/styles/quasar-reset.scss +2 -0
- package/src/styles/themes/danx/forms.scss +1 -19
- package/src/types/fields.d.ts +10 -9
package/package.json
CHANGED
@@ -1,27 +1,30 @@
|
|
1
1
|
<template>
|
2
|
-
<
|
2
|
+
<div class="dx-field-label">
|
3
3
|
<slot>
|
4
|
-
|
5
|
-
|
4
|
+
<div class="dx-field-label-text">
|
5
|
+
<div class="dx-field-label-label">
|
6
|
+
{{ label }}
|
7
|
+
</div>
|
8
|
+
<div
|
9
|
+
v-if="name"
|
10
|
+
class="dx-field-label-name"
|
11
|
+
>
|
12
|
+
({{ name }})
|
13
|
+
</div>
|
14
|
+
</div>
|
6
15
|
</slot>
|
7
16
|
<span
|
8
|
-
v-if="
|
17
|
+
v-if="required"
|
9
18
|
class="dx-field-required"
|
10
|
-
>{{ requiredLabel }}</span>
|
11
|
-
</
|
19
|
+
>{{ requiredLabel || "*" }}</span>
|
20
|
+
</div>
|
12
21
|
</template>
|
13
22
|
|
14
23
|
<script setup lang="ts">
|
15
|
-
|
16
|
-
import { FormField } from "../../../../types";
|
17
|
-
|
18
|
-
const props = defineProps<{
|
19
|
-
field?: FormField;
|
24
|
+
defineProps<{
|
20
25
|
label?: string;
|
21
|
-
|
26
|
+
name?: string;
|
22
27
|
required?: boolean;
|
28
|
+
requiredLabel?: string;
|
23
29
|
}>();
|
24
|
-
|
25
|
-
const labelText = computed(() => props.label || props.field?.label);
|
26
|
-
const requiredLabel = computed(() => props.field?.required_group || (props.required || props.field?.required ? "*" : ""));
|
27
30
|
</script>
|
@@ -1,22 +1,51 @@
|
|
1
1
|
<template>
|
2
2
|
<div>
|
3
|
-
<div class="text-xs font-bold">
|
4
|
-
|
5
|
-
|
3
|
+
<div class="text-xs font-bold">
|
4
|
+
{{ label }}
|
5
|
+
</div>
|
6
|
+
<div :class="valueClass">
|
7
|
+
<a
|
8
|
+
v-if="url"
|
9
|
+
target="_blank"
|
10
|
+
:href="url"
|
11
|
+
:class="valueClass"
|
12
|
+
>
|
13
|
+
<slot>{{ formattedValue }}</slot>
|
14
|
+
</a>
|
15
|
+
<template v-else>
|
16
|
+
<slot>{{ formattedValue }}</slot>
|
17
|
+
</template>
|
6
18
|
</div>
|
7
19
|
</div>
|
8
20
|
</template>
|
9
|
-
<script setup>
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
<script setup lang="ts">
|
22
|
+
import { computed } from "vue";
|
23
|
+
import { fBoolean, fNumber } from "../../../../helpers";
|
24
|
+
|
25
|
+
export interface LabelValueBlockProps {
|
26
|
+
label: string;
|
27
|
+
value: string | number | boolean;
|
28
|
+
url?: string;
|
29
|
+
dense?: boolean;
|
30
|
+
nowrap?: boolean;
|
31
|
+
}
|
32
|
+
|
33
|
+
const props = withDefaults(defineProps<LabelValueBlockProps>(), {
|
34
|
+
value: "",
|
35
|
+
url: ""
|
36
|
+
});
|
37
|
+
|
38
|
+
const valueClass = computed(() => ({ "mt-2": !props.dense, "mt-1": props.dense, "text-no-wrap": props.nowrap }));
|
39
|
+
const formattedValue = computed(() => {
|
40
|
+
switch (typeof props.value) {
|
41
|
+
case "boolean":
|
42
|
+
return fBoolean(props.value);
|
43
|
+
|
44
|
+
case "number":
|
45
|
+
return fNumber(props.value);
|
46
|
+
|
47
|
+
default:
|
48
|
+
return props.value || "-";
|
49
|
+
}
|
21
50
|
});
|
22
51
|
</script>
|
@@ -12,7 +12,6 @@
|
|
12
12
|
:field="field"
|
13
13
|
:no-label="!field.label"
|
14
14
|
label-class="text-xs font-bold text-zinc-800"
|
15
|
-
parent-class="tight-label"
|
16
15
|
input-class="!py-0"
|
17
16
|
dense
|
18
17
|
type="textarea"
|
@@ -29,29 +28,29 @@ import TextField from "./TextField";
|
|
29
28
|
|
30
29
|
const emit = defineEmits(["update:model-value"]);
|
31
30
|
const props = defineProps({
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
modelValue: {
|
32
|
+
type: [String, Number, Object],
|
33
|
+
default: ""
|
34
|
+
},
|
35
|
+
field: {
|
36
|
+
type: Object,
|
37
|
+
default: null
|
38
|
+
}
|
40
39
|
});
|
41
40
|
|
42
41
|
const selectedFieldName = ref(props.field.defaultOption);
|
43
42
|
const searchList = computed(() => props.modelValue && props.modelValue[selectedFieldName.value]);
|
44
43
|
const textInput = ref(formatModelValue());
|
45
44
|
function onChange() {
|
46
|
-
|
47
|
-
|
45
|
+
textInput.value = textInput.value?.replace(/\n/g, ",").replace(/,{2,}/g, ",") || "";
|
46
|
+
emit("update:model-value", textInput.value ? { [selectedFieldName.value]: textInput.value.split(",") } : undefined);
|
48
47
|
}
|
49
48
|
|
50
49
|
function formatModelValue() {
|
51
|
-
|
50
|
+
return Array.isArray(searchList.value) ? searchList.value?.join(",") : "";
|
52
51
|
}
|
53
52
|
|
54
53
|
watch(() => props.modelValue, () => {
|
55
|
-
|
54
|
+
textInput.value = formatModelValue();
|
56
55
|
});
|
57
56
|
</script>
|
@@ -1,72 +1,49 @@
|
|
1
1
|
<template>
|
2
|
-
<
|
3
|
-
class="dx-number-field
|
4
|
-
|
2
|
+
<TextField
|
3
|
+
class="dx-number-field"
|
4
|
+
v-bind="$props"
|
5
5
|
:model-value="numberVal"
|
6
|
-
:data-testid="'number-field-' + fieldOptions.id"
|
7
|
-
:placeholder="fieldOptions.placeholder"
|
8
|
-
outlined
|
9
|
-
dense
|
10
|
-
inputmode="numeric"
|
11
|
-
:input-class="inputClass"
|
12
6
|
@update:model-value="onInput"
|
13
|
-
|
14
|
-
<template #prepend>
|
15
|
-
<FieldLabel
|
16
|
-
:field="fieldOptions"
|
17
|
-
:show-name="showName"
|
18
|
-
/>
|
19
|
-
</template>
|
20
|
-
</QInput>
|
7
|
+
/>
|
21
8
|
</template>
|
22
9
|
|
23
|
-
<script setup>
|
10
|
+
<script setup lang="ts">
|
24
11
|
import { useDebounceFn } from "@vueuse/core";
|
25
|
-
import {
|
12
|
+
import { nextTick, ref, watch } from "vue";
|
26
13
|
import { fNumber } from "../../../../helpers";
|
27
|
-
import
|
14
|
+
import { AnyObject, TextFieldProps } from "../../../../types";
|
15
|
+
import TextField from "./TextField";
|
28
16
|
|
29
17
|
const emit = defineEmits(["update:model-value", "update"]);
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
},
|
47
|
-
inputClass: {
|
48
|
-
type: [String, Object],
|
49
|
-
default: ""
|
50
|
-
},
|
51
|
-
delay: {
|
52
|
-
type: Number,
|
53
|
-
default: 1000
|
54
|
-
},
|
55
|
-
hidePrependLabel: Boolean,
|
56
|
-
currency: Boolean,
|
57
|
-
showName: Boolean
|
18
|
+
|
19
|
+
export interface NumberFieldProps extends TextFieldProps {
|
20
|
+
precision?: number;
|
21
|
+
delay?: number;
|
22
|
+
currency?: boolean;
|
23
|
+
min?: number;
|
24
|
+
max?: number;
|
25
|
+
}
|
26
|
+
|
27
|
+
const props = withDefaults(defineProps<NumberFieldProps>(), {
|
28
|
+
modelValue: "",
|
29
|
+
precision: 2,
|
30
|
+
label: undefined,
|
31
|
+
delay: 1000,
|
32
|
+
min: undefined,
|
33
|
+
max: undefined
|
58
34
|
});
|
59
35
|
|
60
36
|
const numberVal = ref(format(props.modelValue));
|
61
|
-
watch(() => props.modelValue, () => numberVal.value = format(props.modelValue));
|
62
37
|
|
63
|
-
|
38
|
+
watch(() => props.modelValue, () => numberVal.value = format(props.modelValue));
|
64
39
|
|
65
40
|
function format(number) {
|
66
41
|
if (!number && number !== 0 && number !== "0") return number;
|
67
42
|
|
43
|
+
if (props.type === "number") return number;
|
44
|
+
|
68
45
|
const minimumFractionDigits = Math.min(props.precision, ("" + number).split(".")[1]?.length || 0);
|
69
|
-
let options = {
|
46
|
+
let options: AnyObject = {
|
70
47
|
minimumFractionDigits
|
71
48
|
};
|
72
49
|
|
@@ -80,14 +57,15 @@ function format(number) {
|
|
80
57
|
return fNumber(number, options);
|
81
58
|
}
|
82
59
|
|
83
|
-
const onUpdateDebounced = useDebounceFn((val) => emit("update", val), props.delay);
|
60
|
+
const onUpdateDebounced = useDebounceFn((val: number | string | undefined) => emit("update", val), props.delay);
|
84
61
|
|
85
62
|
function onInput(value) {
|
86
|
-
let number =
|
63
|
+
let number: number | undefined = undefined;
|
87
64
|
|
88
65
|
// Prevent invalid characters
|
89
66
|
if (value.match(/[^\d.,$]/)) {
|
90
67
|
const oldVal = numberVal.value;
|
68
|
+
|
91
69
|
// XXX: To get QInput to show only the value we want
|
92
70
|
numberVal.value += " ";
|
93
71
|
return nextTick(() => numberVal.value = oldVal);
|
@@ -95,11 +73,19 @@ function onInput(value) {
|
|
95
73
|
|
96
74
|
if (value !== "") {
|
97
75
|
value = value.replace(/[^\d.]/g, "");
|
98
|
-
number =
|
76
|
+
number = +value;
|
77
|
+
|
78
|
+
if (props.min) {
|
79
|
+
number = Math.max(number, props.min);
|
80
|
+
}
|
81
|
+
if (props.max) {
|
82
|
+
number = Math.min(number, props.max);
|
83
|
+
}
|
84
|
+
|
85
|
+
console.log("formattinged", number, value);
|
99
86
|
numberVal.value = format(number);
|
100
87
|
}
|
101
88
|
|
102
|
-
number = number === "" ? undefined : number;
|
103
89
|
emit("update:model-value", number);
|
104
90
|
|
105
91
|
// Delay the change event, so we only see the value after the user has finished
|
@@ -37,8 +37,8 @@
|
|
37
37
|
<template #selected>
|
38
38
|
<div
|
39
39
|
v-if="$props.multiple"
|
40
|
-
class="flex gap-y-1 overflow-hidden"
|
41
|
-
:class="{'flex-nowrap gap-y-0': chipLimit === 1, [selectionClass]: true}"
|
40
|
+
class="flex gap-y-1 overflow-hidden dx-selected-label"
|
41
|
+
:class="{'flex-nowrap gap-y-0': chipLimit === 1, 'dx-selected-chips': chipOptions.length > 0, [selectionClass]: true}"
|
42
42
|
>
|
43
43
|
<template v-if="chipOptions.length > 0">
|
44
44
|
<QChip
|
@@ -62,6 +62,7 @@
|
|
62
62
|
<div
|
63
63
|
v-else
|
64
64
|
:class="selectionClass"
|
65
|
+
class="dx-selected-label"
|
65
66
|
>
|
66
67
|
{{ selectedLabel }}
|
67
68
|
</div>
|
@@ -254,8 +255,8 @@ function onUpdate(value) {
|
|
254
255
|
|
255
256
|
value = value === "__null__" ? null : value;
|
256
257
|
|
257
|
-
emit("update", value);
|
258
258
|
emit("update:model-value", value);
|
259
|
+
emit("update", value);
|
259
260
|
}
|
260
261
|
|
261
262
|
/** XXX: This tells us when we should apply the filter. QSelect likes to trigger a new filter everytime you open the dropdown
|
@@ -1,15 +1,21 @@
|
|
1
1
|
<template>
|
2
2
|
<div>
|
3
3
|
<FieldLabel
|
4
|
-
|
4
|
+
v-if="!prependLabel"
|
5
5
|
:label="label"
|
6
|
-
:
|
6
|
+
:required="required"
|
7
|
+
:required-label="requiredLabel"
|
7
8
|
:class="labelClass"
|
8
|
-
:value="readonly ? modelValue : ''"
|
9
9
|
/>
|
10
|
-
<
|
10
|
+
<div
|
11
|
+
v-if="readonly"
|
12
|
+
class="dx-text-field-readonly-value"
|
13
|
+
>
|
14
|
+
{{ modelValue }}
|
15
|
+
</div>
|
16
|
+
<template v-else>
|
11
17
|
<QInput
|
12
|
-
:placeholder="
|
18
|
+
:placeholder="placeholder || (placeholder === '' ? '' : `Enter ${label}`)"
|
13
19
|
outlined
|
14
20
|
dense
|
15
21
|
:readonly="readonly"
|
@@ -17,18 +23,31 @@
|
|
17
23
|
:disable="disabled"
|
18
24
|
:label-slot="!noLabel"
|
19
25
|
:input-class="inputClass"
|
20
|
-
:class="
|
26
|
+
:class="{'dx-input-prepend-label': prependLabel}"
|
21
27
|
stack-label
|
22
28
|
:type="type"
|
23
29
|
:model-value="modelValue"
|
24
|
-
:maxlength="allowOverMax ? undefined :
|
30
|
+
:maxlength="allowOverMax ? undefined : maxLength"
|
25
31
|
:debounce="debounce"
|
26
32
|
@keydown.enter="$emit('submit')"
|
27
33
|
@update:model-value="$emit('update:model-value', $event)"
|
28
|
-
|
34
|
+
>
|
35
|
+
<template
|
36
|
+
v-if="prependLabel"
|
37
|
+
#prepend
|
38
|
+
>
|
39
|
+
<FieldLabel
|
40
|
+
class="dx-prepended-label"
|
41
|
+
:label="label"
|
42
|
+
:required="required"
|
43
|
+
:required-label="requiredLabel"
|
44
|
+
:class="labelClass"
|
45
|
+
/>
|
46
|
+
</template>
|
47
|
+
</QInput>
|
29
48
|
<MaxLengthCounter
|
30
|
-
:length="modelValue
|
31
|
-
:max-length="
|
49
|
+
:length="(modelValue + '').length || 0"
|
50
|
+
:max-length="maxLength"
|
32
51
|
/>
|
33
52
|
</template>
|
34
53
|
</div>
|
@@ -46,9 +65,9 @@ withDefaults(defineProps<TextFieldProps>(), {
|
|
46
65
|
type: "text",
|
47
66
|
label: "",
|
48
67
|
labelClass: "",
|
49
|
-
parentClass: "",
|
50
68
|
inputClass: "",
|
51
69
|
maxLength: null,
|
52
|
-
debounce: 0
|
70
|
+
debounce: 0,
|
71
|
+
placeholder: null
|
53
72
|
});
|
54
73
|
</script>
|
package/src/helpers/formats.ts
CHANGED
@@ -29,10 +29,9 @@ export function remoteDateTime(dateTimeString: string) {
|
|
29
29
|
}
|
30
30
|
|
31
31
|
/**
|
32
|
-
*
|
33
|
-
* @returns {DateTime|*}
|
32
|
+
* Parses a date string into a Luxon DateTime object
|
34
33
|
*/
|
35
|
-
export function parseDateTime(dateTime: string | DateTime) {
|
34
|
+
export function parseDateTime(dateTime: string | DateTime | null): DateTime {
|
36
35
|
if (typeof dateTime === "string") {
|
37
36
|
dateTime = dateTime.replace("T", " ").replace(/\//g, "-");
|
38
37
|
return DateTime.fromSQL(dateTime);
|
@@ -91,8 +90,8 @@ export function fDateTime(
|
|
91
90
|
dateTime: string | DateTime | null = null,
|
92
91
|
{ format = "M/d/yy h:mma", empty = "- -" }: fDateOptions = {}
|
93
92
|
) {
|
94
|
-
const formatted =
|
95
|
-
return
|
93
|
+
const formatted = parseDateTime(dateTime).toFormat(format).toLowerCase();
|
94
|
+
return ["Invalid DateTime", "invalid datetime"].includes(formatted) ? empty : formatted;
|
96
95
|
}
|
97
96
|
|
98
97
|
/**
|
@@ -151,16 +150,87 @@ export function fCurrency(amount: number, options?: object) {
|
|
151
150
|
}).format(amount);
|
152
151
|
}
|
153
152
|
|
153
|
+
/**
|
154
|
+
* Formats an amount into USD currency format without cents
|
155
|
+
*/
|
156
|
+
export function fCurrencyNoCents(amount: number, options?: object) {
|
157
|
+
return fCurrency(amount, {
|
158
|
+
maximumFractionDigits: 0,
|
159
|
+
...options
|
160
|
+
});
|
161
|
+
}
|
162
|
+
|
154
163
|
/**
|
155
164
|
* Formats a number into a human-readable format
|
156
|
-
* @param number
|
157
|
-
* @param options
|
158
|
-
* @returns {string}
|
159
165
|
*/
|
160
|
-
export function fNumber(number: number, options
|
166
|
+
export function fNumber(number: number, options?: object) {
|
161
167
|
return new Intl.NumberFormat("en-US", options).format(number);
|
162
168
|
}
|
163
169
|
|
170
|
+
/**
|
171
|
+
* Formats a currency into a shorthand human-readable format (ie: $1.2M or $5K)
|
172
|
+
*/
|
173
|
+
export function fShortCurrency(value: string | number, options?: { round: boolean }) {
|
174
|
+
return "$" + fShortNumber(value, options);
|
175
|
+
}
|
176
|
+
|
177
|
+
/**
|
178
|
+
* Formats a number into a shorthand human-readable format (ie: 1.2M or 5K)
|
179
|
+
*/
|
180
|
+
export function fShortNumber(value: string | number, options?: { round: boolean }) {
|
181
|
+
const shorts = [
|
182
|
+
{ pow: 3, unit: "K" },
|
183
|
+
{ pow: 6, unit: "M" },
|
184
|
+
{ pow: 9, unit: "B" },
|
185
|
+
{ pow: 12, unit: "T" },
|
186
|
+
{ pow: 15, unit: "Q" }
|
187
|
+
];
|
188
|
+
|
189
|
+
let n = Math.round(+value);
|
190
|
+
|
191
|
+
const short = shorts.find(({ pow }) => Math.pow(10, pow) < n && Math.pow(10, pow + 3) > n) || null;
|
192
|
+
|
193
|
+
if (short) {
|
194
|
+
n = n / Math.pow(10, short.pow);
|
195
|
+
return options?.round
|
196
|
+
? n + short.unit
|
197
|
+
: n.toFixed(n > 100 ? 0 : 1) + short.unit;
|
198
|
+
}
|
199
|
+
|
200
|
+
return n;
|
201
|
+
}
|
202
|
+
|
203
|
+
/**
|
204
|
+
* Formats a number into a human-readable size format (ie: 1.2MB or 5KB)
|
205
|
+
*/
|
206
|
+
export function fShortSize(value: string | number) {
|
207
|
+
const powers = [
|
208
|
+
{ pow: 0, unit: "B" },
|
209
|
+
{ pow: 10, unit: "KB" },
|
210
|
+
{ pow: 20, unit: "MB" },
|
211
|
+
{ pow: 30, unit: "GB" },
|
212
|
+
{ pow: 40, unit: "TB" },
|
213
|
+
{ pow: 50, unit: "PB" },
|
214
|
+
{ pow: 60, unit: "EB" },
|
215
|
+
{ pow: 70, unit: "ZB" },
|
216
|
+
{ pow: 80, unit: "YB" }
|
217
|
+
];
|
218
|
+
|
219
|
+
const n = Math.round(+value);
|
220
|
+
const power = powers.find((p, i) => {
|
221
|
+
const nextPower = powers[i + 1];
|
222
|
+
return !nextPower || n < Math.pow(2, nextPower.pow + 10);
|
223
|
+
}) || powers[powers.length - 1];
|
224
|
+
|
225
|
+
const div = Math.pow(2, power.pow);
|
226
|
+
|
227
|
+
return Math.round(n / div) + " " + power.unit;
|
228
|
+
}
|
229
|
+
|
230
|
+
export function fBoolean(value: boolean) {
|
231
|
+
return value ? "Yes" : "No";
|
232
|
+
}
|
233
|
+
|
164
234
|
/**
|
165
235
|
* Truncates the string by removing chars from the middle of the string
|
166
236
|
* @param str
|
package/src/helpers/utils.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
.dx-field-label {
|
2
|
-
@apply text-xs
|
2
|
+
@apply text-xs mb-1.5 flex items-center space-x-1;
|
3
3
|
|
4
4
|
.dx-field-required {
|
5
5
|
@apply text-red-900 ml-0.5 bottom-1 relative;
|
@@ -10,22 +10,4 @@
|
|
10
10
|
.q-field__label {
|
11
11
|
@apply text-sm text-gray-700;
|
12
12
|
}
|
13
|
-
|
14
|
-
&.dx-number-field {
|
15
|
-
&.dx-prepend-label {
|
16
|
-
@apply text-xs text-black font-normal;
|
17
|
-
}
|
18
|
-
|
19
|
-
&.dx-no-prepend-label {
|
20
|
-
@apply w-32;
|
21
|
-
|
22
|
-
.q-field__native {
|
23
|
-
@apply bg-white text-right;
|
24
|
-
}
|
25
|
-
|
26
|
-
.q-field__prepend {
|
27
|
-
padding: 0;
|
28
|
-
}
|
29
|
-
}
|
30
|
-
}
|
31
13
|
}
|
package/src/types/fields.d.ts
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
import { QInputProps } from "quasar";
|
2
|
-
import { FormField } from "./forms";
|
3
2
|
|
4
3
|
export interface TextFieldProps {
|
5
|
-
modelValue?: string
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
4
|
+
modelValue?: string | number;
|
5
|
+
type?: QInputProps["type"];
|
6
|
+
label?: string;
|
7
|
+
required?: boolean;
|
8
|
+
requiredLabel?: string;
|
9
|
+
prependLabel?: boolean;
|
10
|
+
placeholder?: string;
|
11
|
+
labelClass?: string | object;
|
12
|
+
inputClass?: string | object;
|
13
|
+
allowOverMax?: boolean;
|
13
14
|
maxLength?: number;
|
14
15
|
autogrow?: boolean;
|
15
16
|
noLabel?: boolean;
|