diff --git a/.storybook/preview.js b/.storybook/preview.js
index 7029879d6..672ce88e9 100644
--- a/.storybook/preview.js
+++ b/.storybook/preview.js
@@ -2,6 +2,7 @@
import {withThemeByDataAttribute} from '@storybook/addon-themes';
import {mockDateDecorator} from 'storybook-mock-date-decorator';
+import PrimeVue from 'primevue/config';
import {setup} from '@storybook/vue3';
import GlobalMixins from '@/mixins/global.js';
@@ -51,6 +52,10 @@ initialize({
setup((app) => {
app.use(pinia);
+ app.use(PrimeVue, {
+ unstyled: true,
+ });
+
app.mixin(GlobalMixins);
app.use(FloatingVue, {
diff --git a/package-lock.json b/package-lock.json
index a0e975649..76bcb8b78 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,6 +26,7 @@
"moment": "^2.29.4",
"ofetch": "^1.3.3",
"pinia": "^2.1.7",
+ "primevue": "^3.50.0",
"tiny-emitter": "^2.1.0",
"tinymce": "^5.10.7",
"uuid": "^9.0.0",
@@ -13056,6 +13057,14 @@
"node": ">= 0.8"
}
},
+ "node_modules/primevue": {
+ "version": "3.50.0",
+ "resolved": "https://registry.npmjs.org/primevue/-/primevue-3.50.0.tgz",
+ "integrity": "sha512-vYpQzvIXSmF0hWUkviHEGnwbFY/G8jI2RSxoa75noJloI2rWhzOX+JarJ8iaesVOr7b2se31N/p7zOx6uh3ddQ==",
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
diff --git a/package.json b/package.json
index 48d404ae9..3acec471d 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"moment": "^2.29.4",
"ofetch": "^1.3.3",
"pinia": "^2.1.7",
+ "primevue": "^3.50.0",
"tiny-emitter": "^2.1.0",
"tinymce": "^5.10.7",
"uuid": "^9.0.0",
diff --git a/src/components/Form/FormFieldLabel.vue b/src/components/Form/FormFieldLabel.vue
index 10e877022..8db34a085 100644
--- a/src/components/Form/FormFieldLabel.vue
+++ b/src/components/Form/FormFieldLabel.vue
@@ -18,6 +18,7 @@
export default {
name: 'FormFieldLabel',
props: {
+ labelId: String,
controlId: String,
label: String,
localeLabel: String,
diff --git a/src/components/Form/FormGroup.vue b/src/components/Form/FormGroup.vue
index 5528f30e8..abc2fcedb 100644
--- a/src/components/Form/FormGroup.vue
+++ b/src/components/Form/FormGroup.vue
@@ -75,6 +75,7 @@ import FieldShowEnsuringLink from './fields/FieldShowEnsuringLink.vue';
import FieldText from './fields/FieldText.vue';
import FieldTextarea from './fields/FieldTextarea.vue';
import FieldUpload from './fields/FieldUpload.vue';
+import FieldSlider from './fields/FieldSlider.vue';
import FieldUploadImage from './fields/FieldUploadImage.vue';
export default {
@@ -101,6 +102,7 @@ export default {
FieldShowEnsuringLink,
FieldText,
FieldTextarea,
+ FieldSlider,
FieldUpload,
FieldUploadImage,
},
diff --git a/src/components/Form/fields/FieldBase.vue b/src/components/Form/fields/FieldBase.vue
index 025cb3fee..2b76ad80a 100644
--- a/src/components/Form/fields/FieldBase.vue
+++ b/src/components/Form/fields/FieldBase.vue
@@ -107,6 +107,15 @@ export default {
return this.isMultilingual ? this.name + '-' + this.localeKey : this.name;
},
+ /**
+ * In case field is not using input element, its necessary to reference the label via aria-labelby (for example FieldSlider)
+ *
+ * @return {String}
+ */
+ labelId() {
+ return this.compileId('control');
+ },
+
/**
* A unique id for the label and control
*
@@ -185,7 +194,7 @@ export default {
if (this.isMultilingual) {
ids.push(this.multilingualProgressId);
}
- return ids.length ? ids.join(' ') : false;
+ return ids.length ? ids.join(' ') : undefined;
},
/**
diff --git a/src/components/Form/fields/FieldSlider.mdx b/src/components/Form/fields/FieldSlider.mdx
new file mode 100644
index 000000000..867110f4c
--- /dev/null
+++ b/src/components/Form/fields/FieldSlider.mdx
@@ -0,0 +1,7 @@
+import {Primary, Controls, Stories, Meta, ArgTypes} from '@storybook/blocks';
+
+import * as FieldSliderStories from './FieldSlider.stories.js';
+
+
+
+# FieldSlider
diff --git a/src/components/Form/fields/FieldSlider.stories.js b/src/components/Form/fields/FieldSlider.stories.js
new file mode 100644
index 000000000..0b2a324cc
--- /dev/null
+++ b/src/components/Form/fields/FieldSlider.stories.js
@@ -0,0 +1,34 @@
+import FieldSlider from './FieldSlider.vue';
+
+import FieldBaseMock from '../mocks/field-base';
+import FieldSliderMock from '../mocks/field-slider';
+
+export default {
+ title: 'Forms/FieldSlider',
+ component: FieldSlider,
+ render: (args) => ({
+ components: {FieldSlider},
+ setup() {
+ function change(name, prop, newValue, localeKey) {
+ if (localeKey) {
+ args[prop][localeKey] = newValue;
+ } else {
+ args[prop] = newValue;
+ }
+ }
+
+ return {args, change};
+ },
+ template: `
+
+ `,
+ }),
+};
+
+export const Base = {
+ args: {
+ ...FieldBaseMock,
+ ...FieldSliderMock,
+ // description: 'slider description',
+ },
+};
diff --git a/src/components/Form/fields/FieldSlider.vue b/src/components/Form/fields/FieldSlider.vue
new file mode 100644
index 000000000..395bbb8e0
--- /dev/null
+++ b/src/components/Form/fields/FieldSlider.vue
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ minLabel || min }}
+
{{ maxLabel || max }}
+
+
+
+ {{ displayedValue }}
+
+
+
+
+
+
diff --git a/src/components/Form/mocks/field-slider.js b/src/components/Form/mocks/field-slider.js
new file mode 100644
index 000000000..da8996737
--- /dev/null
+++ b/src/components/Form/mocks/field-slider.js
@@ -0,0 +1,11 @@
+export default {
+ name: 'slider',
+ component: 'field-slider',
+ label: 'Review Request Response - Before Due Date',
+ value: 20,
+ min: 0,
+ minLabel: 'None',
+ max: 35,
+ valueLabel: '{$value} days after due date',
+ valueLabelMin: 'No reminder set',
+};
diff --git a/src/composables/useFiltersForm.js b/src/composables/useFiltersForm.js
index a96fb22f4..82ba31dd8 100644
--- a/src/composables/useFiltersForm.js
+++ b/src/composables/useFiltersForm.js
@@ -56,6 +56,14 @@ export function useFiltersForm(_filtersForm) {
label: option.label,
value: option.value,
});
+ } else if (field.component === 'field-slider') {
+ if (fieldValue !== field.min) {
+ list.push({
+ fieldLabel: field.label,
+ value: fieldValue,
+ label: fieldValue,
+ });
+ }
} else {
list.push({
fieldLabel: field.label,
diff --git a/src/composables/useForm.js b/src/composables/useForm.js
index ac299936c..0c91a01c4 100644
--- a/src/composables/useForm.js
+++ b/src/composables/useForm.js
@@ -6,6 +6,20 @@ function getField(form, name) {
return fields.find((field) => field.name === name);
}
+function getClearValue(field, localeKey = null) {
+ if (localeKey) {
+ if (field.component === 'field-slider') {
+ return field.min;
+ }
+ return Array.isArray(field.value[localeKey]) || field.selected ? [] : '';
+ }
+
+ if (field.component === 'field-slider') {
+ return field.min;
+ }
+ return Array.isArray(field.value) || field.selected ? [] : '';
+}
+
function mapFromSelectedToValue(selected) {
return selected.map((iv) => iv.value);
}
@@ -43,13 +57,12 @@ export function useForm(_form) {
const newValueMultilingual = {};
form.value.supportedFormLocales.forEach((localeObject) => {
const localeKey = localeObject.key;
- const newValue =
- Array.isArray(field.value[localeKey]) || field.selected ? [] : '';
+ const newValue = getClearValue(field, localeKey);
newValueMultilingual[localeKey] = newValue;
});
setValue(field.name, newValueMultilingual);
} else {
- const newValue = Array.isArray(field.value) || field.selected ? [] : '';
+ const newValue = getClearValue(field);
setValue(field.name, newValue);
}
});
diff --git a/tailwind.config.js b/tailwind.config.js
index f9b743739..5d954bca4 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -56,6 +56,7 @@ export default {
},
borderRadius: {
DEFAULT: '4px',
+ full: '9999px',
},
boxShadow: {
DEFAULT: '0 0 4px rgba(0, 0, 0, 0.5);',