@resee-movies/nuxt-ux 0.4.1 → 0.6.0

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.
Files changed (75) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +9 -2
  3. package/dist/runtime/components/Button.vue +15 -9
  4. package/dist/runtime/components/Button.vue.d.ts +2 -12
  5. package/dist/runtime/components/Card.vue.d.ts +1 -4
  6. package/dist/runtime/components/Dialog.vue.d.ts +1 -13
  7. package/dist/runtime/components/Drawer.vue.d.ts +1 -4
  8. package/dist/runtime/components/Heading.vue.d.ts +1 -4
  9. package/dist/runtime/components/Icon.vue +27 -15
  10. package/dist/runtime/components/Icon.vue.d.ts +4 -6
  11. package/dist/runtime/components/IconTextPair.vue +22 -19
  12. package/dist/runtime/components/IconTextPair.vue.d.ts +5 -12
  13. package/dist/runtime/components/Image.vue +1 -1
  14. package/dist/runtime/components/Image.vue.d.ts +1 -17
  15. package/dist/runtime/components/LayoutPageColumn.vue.d.ts +1 -4
  16. package/dist/runtime/components/LayoutPageContainer.vue +12 -2
  17. package/dist/runtime/components/LayoutPageContainer.vue.d.ts +4 -5
  18. package/dist/runtime/components/Lorem.vue.d.ts +1 -11
  19. package/dist/runtime/components/Menu.vue +28 -20
  20. package/dist/runtime/components/Menu.vue.d.ts +4 -7
  21. package/dist/runtime/components/Message.vue.d.ts +2 -2
  22. package/dist/runtime/components/NotificationContainer.vue +0 -1
  23. package/dist/runtime/components/ProgressBar.vue.d.ts +1 -5
  24. package/dist/runtime/components/ProgressSpinner.vue.d.ts +1 -3
  25. package/dist/runtime/components/Tag.vue.d.ts +1 -7
  26. package/dist/runtime/components/ToggleButton.vue +45 -0
  27. package/dist/runtime/components/ToggleButton.vue.d.ts +30 -0
  28. package/dist/runtime/components/form/Form.vue +79 -0
  29. package/dist/runtime/components/form/Form.vue.d.ts +35 -0
  30. package/dist/runtime/components/form/FormField.vue +96 -0
  31. package/dist/runtime/components/form/FormField.vue.d.ts +42 -0
  32. package/dist/runtime/components/form/FormFieldCheckbox.vue +56 -0
  33. package/dist/runtime/components/form/FormFieldCheckbox.vue.d.ts +17 -0
  34. package/dist/runtime/components/form/FormFieldSelect.vue +86 -0
  35. package/dist/runtime/components/form/FormFieldSelect.vue.d.ts +40 -0
  36. package/dist/runtime/components/form/FormFieldSelectButton.vue +76 -0
  37. package/dist/runtime/components/form/FormFieldSelectButton.vue.d.ts +16 -0
  38. package/dist/runtime/components/form/FormFieldText.vue +56 -0
  39. package/dist/runtime/components/form/FormFieldText.vue.d.ts +16 -0
  40. package/dist/runtime/components/form/FormFieldToggleSwitch.vue +47 -0
  41. package/dist/runtime/components/form/FormFieldToggleSwitch.vue.d.ts +15 -0
  42. package/dist/runtime/components/form/FormLabelInputPair.vue +42 -0
  43. package/dist/runtime/components/form/FormLabelInputPair.vue.d.ts +22 -0
  44. package/dist/runtime/components/form/FormSubmitButton.vue +26 -0
  45. package/dist/runtime/components/form/FormSubmitButton.vue.d.ts +8 -0
  46. package/dist/runtime/components/form/FormValidationMessage.vue +24 -0
  47. package/dist/runtime/components/form/FormValidationMessage.vue.d.ts +15 -0
  48. package/dist/runtime/components/form/element/FormElementSelectButton.vue +110 -0
  49. package/dist/runtime/components/form/element/FormElementSelectButton.vue.d.ts +33 -0
  50. package/dist/runtime/components/form/element/FormElementSelectOptions.vue +256 -0
  51. package/dist/runtime/components/form/element/FormElementSelectOptions.vue.d.ts +24 -0
  52. package/dist/runtime/composables/use-load-image.js +1 -0
  53. package/dist/runtime/composables/use-resee-ux.d.ts +25 -0
  54. package/dist/runtime/composables/use-resee-ux.js +23 -0
  55. package/dist/runtime/constants.d.ts +3 -0
  56. package/dist/runtime/constants.js +3 -0
  57. package/dist/runtime/server/plugins/teleport-targets.d.ts +3 -0
  58. package/dist/runtime/server/plugins/teleport-targets.js +6 -0
  59. package/dist/runtime/theme/css/brand/form.css +3 -0
  60. package/dist/runtime/theme/css/brand/menu.css +1 -0
  61. package/dist/runtime/theme/css/brand/mobile.css +1 -0
  62. package/dist/runtime/theme/css/brand/transition.css +1 -1
  63. package/dist/runtime/theme/css/brand/utilities.css +1 -1
  64. package/dist/runtime/theme/css/styles.css +1 -1
  65. package/dist/runtime/types/form.d.ts +23 -0
  66. package/dist/runtime/types/form.js +0 -0
  67. package/dist/runtime/utils/dom.d.ts +9 -0
  68. package/dist/runtime/utils/dom.js +25 -0
  69. package/dist/runtime/utils/form.d.ts +34 -0
  70. package/dist/runtime/utils/form.js +34 -0
  71. package/dist/runtime/utils/string.d.ts +6 -0
  72. package/dist/runtime/utils/string.js +3 -0
  73. package/dist/runtime/utils/validation.d.ts +21 -0
  74. package/dist/runtime/utils/validation.js +56 -0
  75. package/package.json +26 -24
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <FormField v-bind="props" :validator="validatorFunction">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+
7
+ <template #default="{ inputId, messageId, disabled, readonly }">
8
+ <PrimeInputText
9
+ :id = "inputId"
10
+ :aria-describedby = "messageId"
11
+ :disabled = "disabled"
12
+ :readonly = "readonly"
13
+ :type = "props.type"
14
+ :required = "props.required"
15
+ :minlength = "props.minLength"
16
+ :maxlength = "props.maxLength"
17
+ class = "input-control"
18
+ />
19
+ </template>
20
+ </FormField>
21
+ </template>
22
+
23
+ <script>
24
+ import {} from "./FormField.vue";
25
+ </script>
26
+
27
+ <script setup>
28
+ import PrimeInputText from "primevue/inputtext";
29
+ import { computed } from "vue";
30
+ import FormField from "./FormField.vue";
31
+ import { createTextValidator } from "../../utils/validation";
32
+ const props = defineProps({
33
+ type: { type: String, required: false, default: "text" },
34
+ minLength: { type: [String, Number], required: false, default: void 0 },
35
+ maxLength: { type: [String, Number], required: false, default: void 0 },
36
+ name: { type: String, required: true },
37
+ label: { type: String, required: false },
38
+ is: { type: String, required: false },
39
+ initialValue: { type: null, required: false },
40
+ required: { type: Boolean, required: false },
41
+ disabled: { type: Boolean, required: false },
42
+ readonly: { type: Boolean, required: false },
43
+ fauxLabel: { type: Boolean, required: false },
44
+ labelSrOnly: { type: Boolean, required: false },
45
+ labelPosition: { type: String, required: false },
46
+ class: { type: null, required: false }
47
+ });
48
+ const validatorFunction = computed(() => {
49
+ return () => createTextValidator({
50
+ required: props.required,
51
+ type: props.type,
52
+ minLength: props.minLength,
53
+ maxLength: props.maxLength
54
+ });
55
+ });
56
+ </script>
@@ -0,0 +1,16 @@
1
+ import { type FormFieldProps } from './FormField.vue.js';
2
+ export interface FormFieldTextProps extends Omit<FormFieldProps, 'validator'> {
3
+ type?: 'text' | 'url' | 'email';
4
+ minLength?: string | number;
5
+ maxLength?: string | number;
6
+ }
7
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormFieldTextProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormFieldTextProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
8
+ label?: (props: {}) => any;
9
+ }>;
10
+ declare const _default: typeof __VLS_export;
11
+ export default _default;
12
+ type __VLS_WithSlots<T, S> = T & {
13
+ new (): {
14
+ $slots: S;
15
+ };
16
+ };
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <FormField v-bind="props" :validator="validatorFunction">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+
7
+ <template #default="{ inputId, messageId, disabled, readonly }">
8
+ <PrimeToggleSwitch
9
+ :input-id = "inputId"
10
+ :aria-describedby = "messageId"
11
+ :disabled = "disabled || readonly"
12
+ :readonly = "readonly"
13
+ class = "input-group toggle-switch"
14
+ pt:slider:class = "slider"
15
+ />
16
+ </template>
17
+ </FormField>
18
+ </template>
19
+
20
+ <script>
21
+
22
+ </script>
23
+
24
+ <script setup>
25
+ import PrimeToggleSwitch from "primevue/toggleswitch";
26
+ import { computed } from "vue";
27
+ import FormField from "./FormField.vue";
28
+ import { createBooleanValidator } from "../../utils/validation";
29
+ const props = defineProps({
30
+ trueValue: { type: null, required: false, default: () => true },
31
+ falseValue: { type: null, required: false, default: () => false },
32
+ name: { type: String, required: true },
33
+ label: { type: String, required: false },
34
+ is: { type: String, required: false },
35
+ initialValue: { type: null, required: false, default: () => false },
36
+ required: { type: Boolean, required: false },
37
+ disabled: { type: Boolean, required: false },
38
+ readonly: { type: Boolean, required: false },
39
+ fauxLabel: { type: Boolean, required: false },
40
+ labelSrOnly: { type: Boolean, required: false },
41
+ labelPosition: { type: String, required: false, default: "after" },
42
+ class: { type: null, required: false }
43
+ });
44
+ const validatorFunction = computed(() => {
45
+ return () => createBooleanValidator({ required: props.required });
46
+ });
47
+ </script>
@@ -0,0 +1,15 @@
1
+ import type { FormFieldProps } from './FormField.vue.js';
2
+ export interface FormFieldToggleSwitchProps extends Omit<FormFieldProps, 'validator'> {
3
+ trueValue?: unknown;
4
+ falseValue?: unknown;
5
+ }
6
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormFieldToggleSwitchProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormFieldToggleSwitchProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
7
+ label?: (props: {}) => any;
8
+ }>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
11
+ type __VLS_WithSlots<T, S> = T & {
12
+ new (): {
13
+ $slots: S;
14
+ };
15
+ };
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <div :class="['input-label-pair', `label-${props.labelPosition}`]">
3
+ <Component
4
+ :is = "props.fauxLabel ? 'span' : 'label'"
5
+ :id = "props.labelId"
6
+ :for = "props.fauxLabel ? void 0 : props.inputId"
7
+ :class = "[
8
+ 'input-label',
9
+ {
10
+ 'sr-only': props.labelSrOnly,
11
+ disabled: props.disabled,
12
+ required: props.required
13
+ }
14
+ ]"
15
+ >
16
+ <slot name="label">
17
+ {{ props.labelText }}
18
+ </slot>
19
+ </Component>
20
+
21
+ <div>
22
+ <slot name="input" />
23
+ </div>
24
+ </div>
25
+ </template>
26
+
27
+ <script>
28
+
29
+ </script>
30
+
31
+ <script setup>
32
+ const props = defineProps({
33
+ inputId: { type: String, required: false },
34
+ labelId: { type: String, required: false },
35
+ labelText: { type: String, required: false },
36
+ labelPosition: { type: String, required: false, default: "above" },
37
+ labelSrOnly: { type: Boolean, required: false, default: false },
38
+ required: { type: Boolean, required: false, default: false },
39
+ disabled: { type: Boolean, required: false, default: false },
40
+ fauxLabel: { type: Boolean, required: false, default: false }
41
+ });
42
+ </script>
@@ -0,0 +1,22 @@
1
+ export interface FormLabelInputPairProps {
2
+ inputId?: string;
3
+ labelId?: string;
4
+ labelText?: string;
5
+ labelPosition?: 'above' | 'below' | 'before' | 'after';
6
+ labelSrOnly?: boolean;
7
+ required?: boolean;
8
+ disabled?: boolean;
9
+ fauxLabel?: boolean;
10
+ }
11
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormLabelInputPairProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormLabelInputPairProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
12
+ label?: (props: {}) => any;
13
+ } & {
14
+ input?: (props: {}) => any;
15
+ }>;
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;
18
+ type __VLS_WithSlots<T, S> = T & {
19
+ new (): {
20
+ $slots: S;
21
+ };
22
+ };
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <Button
3
+ type = "submit"
4
+ :text = "props.text ?? locale.form.submitButtonLabel"
5
+ :loading = "formState.isSubmitting.value"
6
+ :disabled = "formState.isDisabled.value"
7
+ :bordered = "props.bordered"
8
+ icon-transition-name = "grow-x"
9
+ />
10
+ </template>
11
+
12
+ <script>
13
+
14
+ </script>
15
+
16
+ <script setup>
17
+ import { useReseeUx } from "../../composables/use-resee-ux";
18
+ import { injectFormInstance } from "../../utils/form";
19
+ import Button from "../Button.vue";
20
+ const props = defineProps({
21
+ text: { type: String, required: false, default: void 0 },
22
+ bordered: { type: Boolean, required: false, default: true }
23
+ });
24
+ const formState = injectFormInstance();
25
+ const { locale } = useReseeUx();
26
+ </script>
@@ -0,0 +1,8 @@
1
+ import type { ButtonProps } from '../Button.vue.js';
2
+ export interface FormSubmitButtonProps extends /* @vue-ignore */ Omit<ButtonProps, 'onClick' | 'loading'> {
3
+ text?: string;
4
+ bordered?: boolean;
5
+ }
6
+ declare const __VLS_export: import("vue").DefineComponent<FormSubmitButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormSubmitButtonProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <div
3
+ :id = "props.id"
4
+ aria-atomic = "true"
5
+ aria-live = "polite"
6
+ :class = "['input-validation', props.visible ? 'visible' : 'invisible']"
7
+ >
8
+ <slot name="default">
9
+ {{ props.message }}
10
+ </slot>
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+
16
+ </script>
17
+
18
+ <script setup>
19
+ const props = defineProps({
20
+ id: { type: String, required: false, default: void 0 },
21
+ visible: { type: Boolean, required: false, default: false },
22
+ message: { type: String, required: false, default: void 0 }
23
+ });
24
+ </script>
@@ -0,0 +1,15 @@
1
+ export interface FormValidationMessageProps {
2
+ id?: string;
3
+ visible?: boolean;
4
+ message?: string;
5
+ }
6
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormValidationMessageProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormValidationMessageProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
7
+ default?: (props: {}) => any;
8
+ }>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
11
+ type __VLS_WithSlots<T, S> = T & {
12
+ new (): {
13
+ $slots: S;
14
+ };
15
+ };
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <div
3
+ role = "group"
4
+ class = "input-group input-button-bar"
5
+ :aria-labelledby = "props.ariaLabelledby"
6
+ :aria-describedby = "props.ariaDescribedby"
7
+ >
8
+ <template v-for="(option, index) of props.options" :key="getOptionRenderKey(option) ?? index">
9
+ <ToggleButton
10
+ severity = "unset"
11
+ :pressed = "getSelectedOptionIndex(option) !== -1"
12
+ :text = "props.iconOnly ? void 0 : getOptionLabel(option)"
13
+ :icon = "getOptionIcon(option)"
14
+ :disabled = "getOptionDisabled(option)"
15
+ :aria-label = "props.iconOnly ? getOptionLabel(option) : void 0"
16
+ :tooltip = "props.iconOnly ? getOptionLabel(option) : void 0"
17
+ @click = "(pressed) => handleToggleChange(option, pressed)"
18
+ />
19
+ </template>
20
+ </div>
21
+ </template>
22
+
23
+ <script>
24
+ export class ChangeEvent extends Event {
25
+ value;
26
+ constructor(value) {
27
+ super("change");
28
+ this.value = value;
29
+ }
30
+ }
31
+ </script>
32
+
33
+ <script setup>
34
+ import { equals, resolveFieldData } from "@primeuix/utils/object";
35
+ import { isNumber } from "@resee-movies/utilities/numbers/is-number";
36
+ import { isString } from "@resee-movies/utilities/strings/is-string";
37
+ import ToggleButton from "../../ToggleButton.vue";
38
+ const props = defineProps({
39
+ options: { type: Array, required: true },
40
+ optionLabel: { type: String, required: false },
41
+ optionIcon: { type: String, required: false },
42
+ optionValue: { type: String, required: false },
43
+ optionDisabled: { type: String, required: false },
44
+ optionDataKey: { type: String, required: false },
45
+ iconOnly: { type: Boolean, required: false, default: false },
46
+ multiple: { type: Boolean, required: false, default: false },
47
+ ariaLabelledby: { type: String, required: false },
48
+ ariaDescribedby: { type: String, required: false },
49
+ disabled: { type: Boolean, required: false, default: false },
50
+ readonly: { type: Boolean, required: false, default: false },
51
+ selectionLimit: { type: Number, required: false }
52
+ });
53
+ const emits = defineEmits(["change"]);
54
+ const value = defineModel("value", { type: null, ...{ default: null } });
55
+ function getOptionLabel(option) {
56
+ return String(props.optionLabel ? resolveFieldData(option, props.optionLabel) : option);
57
+ }
58
+ function getOptionValue(option) {
59
+ return props.optionValue ? resolveFieldData(option, props.optionValue) : option;
60
+ }
61
+ function getOptionIcon(option) {
62
+ return props.optionIcon ? String(resolveFieldData(option, props.optionIcon)) : void 0;
63
+ }
64
+ function getOptionDisabled(option) {
65
+ if (props.disabled || props.readonly) {
66
+ return true;
67
+ }
68
+ if (props.optionDisabled && resolveFieldData(option, props.optionDisabled)) {
69
+ return true;
70
+ }
71
+ if (props.multiple) {
72
+ const limit = props.selectionLimit ?? Number.POSITIVE_INFINITY;
73
+ const length = Array.isArray(value.value) ? value.value.length : 0;
74
+ if (limit <= length && getSelectedOptionIndex(option) === -1) {
75
+ return true;
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+ function getOptionRenderKey(option) {
81
+ const result = props.optionDataKey ? resolveFieldData(option, props.optionDataKey) : getOptionLabel(option);
82
+ return isString(result) || isNumber(result) ? result : void 0;
83
+ }
84
+ function getSelectedOptionIndex(option) {
85
+ if (!value.value) {
86
+ return -1;
87
+ }
88
+ const equalityKey = props.optionValue ? void 0 : props.optionDataKey;
89
+ const optionValue = getOptionValue(option);
90
+ if (Array.isArray(value.value)) {
91
+ return value.value.findIndex((entry) => equals(getOptionValue(entry), optionValue, equalityKey));
92
+ }
93
+ return equals(getOptionValue(value.value), optionValue, equalityKey) ? 0 : -1;
94
+ }
95
+ function handleToggleChange(option, pressed) {
96
+ if (props.multiple) {
97
+ const selectedIndex = getSelectedOptionIndex(option);
98
+ const selectedItems = Array.isArray(value.value) ? [...value.value] : [];
99
+ if (selectedIndex === -1) {
100
+ selectedItems.push(getOptionValue(option));
101
+ } else {
102
+ selectedItems.splice(selectedIndex, 1);
103
+ }
104
+ value.value = selectedItems.length === 0 ? null : selectedItems;
105
+ } else {
106
+ value.value = pressed ? getOptionValue(option) : null;
107
+ }
108
+ emits("change", new ChangeEvent(value.value));
109
+ }
110
+ </script>
@@ -0,0 +1,33 @@
1
+ export interface FormElementSelectButtonProps {
2
+ options: unknown[];
3
+ optionLabel?: string;
4
+ optionIcon?: string;
5
+ optionValue?: string;
6
+ optionDisabled?: string;
7
+ optionDataKey?: string;
8
+ iconOnly?: boolean;
9
+ multiple?: boolean;
10
+ ariaLabelledby?: string;
11
+ ariaDescribedby?: string;
12
+ disabled?: boolean;
13
+ readonly?: boolean;
14
+ selectionLimit?: number;
15
+ }
16
+ export declare class ChangeEvent extends Event {
17
+ readonly value: unknown;
18
+ constructor(value: unknown);
19
+ }
20
+ declare const __VLS_export: import("vue").DefineComponent<FormElementSelectButtonProps & {
21
+ value?: unknown | unknown[];
22
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
23
+ "update:value": (value: unknown) => any;
24
+ } & {
25
+ change: (event: ChangeEvent) => any;
26
+ }, string, import("vue").PublicProps, Readonly<FormElementSelectButtonProps & {
27
+ value?: unknown | unknown[];
28
+ }> & Readonly<{
29
+ onChange?: ((event: ChangeEvent) => any) | undefined;
30
+ "onUpdate:value"?: ((value: unknown) => any) | undefined;
31
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
+ declare const _default: typeof __VLS_export;
33
+ export default _default;
@@ -0,0 +1,256 @@
1
+ <template>
2
+ <Component
3
+ :is = "props.multiple ? PrimeMultiSelect : PrimeSelect"
4
+ :name = "props.name"
5
+ :input-id = "props.inputId"
6
+ :disabled = "props.disabled || props.readonly"
7
+ :class = "['input-group']"
8
+ :options = "props.options"
9
+ :option-label = "props.optionLabel"
10
+ :option-value = "props.optionValue"
11
+ :option-disabled = "props.optionDisabled"
12
+ :placeholder = "props.placeholder"
13
+ :selection-limit = "props.multiple ? props.selectionLimit : void 0"
14
+ :show-clear = "props.showClear"
15
+ :show-toggle-all = "showSelectAllCheckbox"
16
+ :filter = "showFilter"
17
+ :filter-placeholder = "props.filterPlaceholder ?? locale.form.filterPlaceholder"
18
+ :loading = "props.loading"
19
+ :pt = "props.multiple ? multiSelectPassthroughProps : selectPassthroughProps"
20
+ :append-to = "TeleportId"
21
+ checkbox-icon = "i-ph-check-bold"
22
+ >
23
+ <template #value="{ value, placeholder }">
24
+ <template v-if="value">
25
+ {{ toLabel(value) }}
26
+ </template>
27
+
28
+ <span v-else class="placeholder">
29
+ {{ placeholder || "\u200B" }}
30
+ </span>
31
+ </template>
32
+
33
+ <template #loadingicon>
34
+ <ProgressSpinner />
35
+ </template>
36
+
37
+ <template #dropdownicon>
38
+ <Icon name="i-ph-caret-down-bold" />
39
+ </template>
40
+
41
+ <template #clearicon="{ clearCallback }">
42
+ <Button
43
+ severity = "unset"
44
+ icon = "i-ph-x"
45
+ class = "input-group-addon"
46
+ @click = "clearCallback"
47
+ :data-pc-section = "
48
+ 'clearicon'
49
+ /* used internally by Primevue. No idea why they offer the slot like this. */
50
+ "
51
+ />
52
+ </template>
53
+
54
+ <template #filtericon>
55
+ <Icon name="i-ph-magnifying-glass" />
56
+ </template>
57
+
58
+ <template #emptyfilter>
59
+ <span>{{ locale.form.filterNoResults }}</span>
60
+ </template>
61
+
62
+ <template #empty>
63
+ <span>{{ locale.form.noOptionsAvailable }}</span>
64
+ </template>
65
+
66
+ <template #option="{ option, selected, index }" v-if="slots.option">
67
+ <slot name="option" :option="option" :selected="selected" :index="index" />
68
+ </template>
69
+ </Component>
70
+ </template>
71
+
72
+ <script>
73
+ import {} from "primevue/select";
74
+ </script>
75
+
76
+ <script setup>
77
+ import { equals, resolveFieldData } from "@primeuix/utils/object";
78
+ import { useBreakpoints, breakpointsTailwind } from "@vueuse/core";
79
+ import PrimeMultiSelect from "primevue/multiselect";
80
+ import PrimeSelect from "primevue/select";
81
+ import { computed, useSlots } from "vue";
82
+ import { useReseeUx } from "../../../composables/use-resee-ux";
83
+ import { TeleportId } from "../../../constants";
84
+ import { blockBodyScroll } from "../../../utils/dom";
85
+ import { swapStringPlaceholders } from "../../../utils/string";
86
+ import Button from "../../Button.vue";
87
+ import Icon from "../../Icon.vue";
88
+ import ProgressSpinner from "../../ProgressSpinner.vue";
89
+ const props = defineProps({
90
+ inputId: { type: String, required: false },
91
+ labelId: { type: String, required: false },
92
+ multiple: { type: Boolean, required: false, default: false },
93
+ readonly: { type: Boolean, required: false, default: false },
94
+ showOptionFilter: { type: Boolean, required: false, default: void 0 },
95
+ ariaDescribedby: { type: String, required: false },
96
+ selectionLimit: { type: [String, Number], required: false, default: void 0 },
97
+ modelValue: { type: null, required: false },
98
+ defaultValue: { type: null, required: false },
99
+ name: { type: null, required: false },
100
+ options: { type: Array, required: false },
101
+ optionLabel: { type: [String, Function], required: false, skipCheck: true },
102
+ optionValue: { type: [String, Function], required: false, skipCheck: true },
103
+ optionDisabled: { type: [String, Function], required: false, skipCheck: true },
104
+ scrollHeight: { type: null, required: false },
105
+ filter: { type: Boolean, required: false, skipCheck: true },
106
+ filterPlaceholder: { type: null, required: false },
107
+ filterLocale: { type: null, required: false },
108
+ filterMatchMode: { type: null, required: false },
109
+ filterFields: { type: null, required: false },
110
+ editable: { type: Boolean, required: false, skipCheck: true },
111
+ placeholder: { type: null, required: false },
112
+ size: { type: null, required: false },
113
+ invalid: { type: Boolean, required: false, skipCheck: true },
114
+ disabled: { type: Boolean, required: false, skipCheck: true },
115
+ variant: { type: null, required: false },
116
+ dataKey: { type: null, required: false },
117
+ showClear: { type: Boolean, required: false, skipCheck: true, default: true },
118
+ fluid: { type: Boolean, required: false, skipCheck: true },
119
+ inputStyle: { type: null, required: false },
120
+ inputClass: { type: null, required: false },
121
+ labelStyle: { type: null, required: false },
122
+ labelClass: { type: null, required: false },
123
+ panelStyle: { type: null, required: false },
124
+ panelClass: { type: null, required: false },
125
+ overlayStyle: { type: null, required: false },
126
+ overlayClass: { type: null, required: false },
127
+ appendTo: { type: null, required: false },
128
+ loading: { type: Boolean, required: false, skipCheck: true },
129
+ clearIcon: { type: null, required: false },
130
+ dropdownIcon: { type: null, required: false },
131
+ filterIcon: { type: null, required: false },
132
+ loadingIcon: { type: null, required: false },
133
+ resetFilterOnHide: { type: Boolean, required: false },
134
+ resetFilterOnClear: { type: Boolean, required: false },
135
+ virtualScrollerOptions: { type: Object, required: false },
136
+ autoOptionFocus: { type: Boolean, required: false, skipCheck: true },
137
+ autoFilterFocus: { type: Boolean, required: false, skipCheck: true },
138
+ selectOnFocus: { type: Boolean, required: false, skipCheck: true },
139
+ focusOnHover: { type: Boolean, required: false, skipCheck: true },
140
+ highlightOnSelect: { type: Boolean, required: false, skipCheck: true },
141
+ checkmark: { type: Boolean, required: false, skipCheck: true },
142
+ filterMessage: { type: null, required: false },
143
+ selectionMessage: { type: null, required: false },
144
+ emptySelectionMessage: { type: null, required: false },
145
+ emptyFilterMessage: { type: null, required: false },
146
+ emptyMessage: { type: null, required: false },
147
+ tabindex: { type: null, required: false },
148
+ ariaLabel: { type: null, required: false },
149
+ ariaLabelledby: { type: null, required: false },
150
+ formControl: { type: null, required: false },
151
+ dt: { type: null, required: false },
152
+ pt: { type: null, required: false },
153
+ ptOptions: { type: Object, required: false },
154
+ unstyled: { type: Boolean, required: false }
155
+ });
156
+ const slots = useSlots();
157
+ const { locale } = useReseeUx();
158
+ const isSmall = useBreakpoints(breakpointsTailwind).smallerOrEqual("sm");
159
+ const showFilter = computed(() => {
160
+ return props.showOptionFilter ?? (props.options?.length ?? 0) > 20;
161
+ });
162
+ const showSelectAllCheckbox = computed(() => {
163
+ return props.multiple ? showFilter.value : void 0;
164
+ });
165
+ let unblockScroll = void 0;
166
+ const sharedPassthroughProps = computed(() => {
167
+ return {
168
+ header: { class: "menu-prefix input-menu-header" },
169
+ overlay: { class: "menu input-menu" },
170
+ dropdown: { class: "input-group-addon" },
171
+ listContainer: { class: "menu-list" },
172
+ pcFilterContainer: { root: { class: "input-menu-filter" } },
173
+ pcFilterIconContainer: { root: { class: "input-group-addon" } },
174
+ emptyMessage: { "aria-disabled": "true" },
175
+ transition: {
176
+ name: isSmall.value ? "slide-in-bottom" : "fade",
177
+ onBeforeEnter() {
178
+ if (isSmall.value) {
179
+ unblockScroll = blockBodyScroll();
180
+ }
181
+ },
182
+ onAfterLeave() {
183
+ unblockScroll?.();
184
+ unblockScroll = void 0;
185
+ }
186
+ }
187
+ };
188
+ });
189
+ const selectPassthroughProps = computed(() => {
190
+ return {
191
+ ...sharedPassthroughProps.value,
192
+ label: {
193
+ "class": "input-control min-w-0 select-none truncate",
194
+ "aria-describedby": props.ariaDescribedby,
195
+ "aria-labelledby": props.labelId,
196
+ "aria-readonly": props.readonly
197
+ }
198
+ };
199
+ });
200
+ const multiSelectPassthroughProps = computed(() => {
201
+ return {
202
+ ...sharedPassthroughProps.value,
203
+ labelContainer: {
204
+ class: "input-control min-w-0"
205
+ },
206
+ label: {
207
+ class: "select-none truncate"
208
+ },
209
+ hiddenInput: {
210
+ "aria-describedby": props.ariaDescribedby,
211
+ "aria-labelledby": props.labelId,
212
+ "aria-readonly": props.readonly
213
+ },
214
+ pcHeaderCheckbox: {
215
+ root: {
216
+ class: "input-group"
217
+ },
218
+ input: {
219
+ "id": `${props.inputId}_select_all`,
220
+ "aria-label": locale.form.selectAllOptions
221
+ }
222
+ },
223
+ pcOptionCheckbox: {
224
+ root: {
225
+ class: "input-group"
226
+ }
227
+ }
228
+ };
229
+ });
230
+ function getOptionValue(option) {
231
+ return props.optionValue ? resolveFieldData(option, props.optionValue) : option;
232
+ }
233
+ function getOptionLabel(option) {
234
+ return props.optionLabel ? resolveFieldData(option, props.optionLabel) : option;
235
+ }
236
+ function findOptionByValue(value) {
237
+ return props.options?.find(
238
+ (option) => equals(getOptionValue(option), value, props.optionValue ? void 0 : props.dataKey)
239
+ );
240
+ }
241
+ function toLabel(value) {
242
+ if (!value) {
243
+ return void 0;
244
+ }
245
+ if (!Array.isArray(value)) {
246
+ return getOptionLabel(findOptionByValue(value));
247
+ }
248
+ if (value.length === 0) {
249
+ return void 0;
250
+ }
251
+ if (value.length === 1) {
252
+ return getOptionLabel(findOptionByValue(value[0]));
253
+ }
254
+ return swapStringPlaceholders(locale.form.numOptionsSelected, { count: value.length });
255
+ }
256
+ </script>