diff --git a/src/qComponents/QOption/src/QOption.vue b/src/qComponents/QOption/src/QOption.vue index ceed71ab..b919605e 100644 --- a/src/qComponents/QOption/src/QOption.vue +++ b/src/qComponents/QOption/src/QOption.vue @@ -3,12 +3,8 @@ v-show="isVisible" ref="root" class="q-option" - :class="{ - 'q-option_selected': isSelected, - 'q-option_disabled': isDisabled, - 'q-option_with-checkbox': multiple - }" - :tabindex="isDisabled ? null : '-1'" + :class="qOptionClasses" + :tabindex="isDisabled ? undefined : '-1'" @mouseenter="handleMouseEnter" @click.stop="handleOptionClick" > @@ -38,23 +34,26 @@ import { defineComponent, inject, onBeforeUnmount, - PropType, ref, reactive, toRefs, onMounted } from 'vue'; +import type { PropType } from 'vue'; import { QCheckbox } from '@/qComponents/QCheckbox'; import type { QSelectProvider } from '@/qComponents/QSelect'; -import type { Nullable } from '#/helpers'; +import type { Nullable, ClassValue } from '#/helpers'; import type { QOptionPropValue, - QOptionInstance, + QOptionPropLabel, + QOptionPropCreated, + QOptionPropDisabled, QOptionProps, - QOptionModel + QOptionModel, + QOptionInstance } from './types'; export default defineComponent({ @@ -69,15 +68,15 @@ export default defineComponent({ required: true }, label: { - type: [String, Number], + type: [String, Number] as PropType, default: null }, created: { - type: Boolean, + type: Boolean as PropType, default: false }, disabled: { - type: Boolean, + type: Boolean as PropType, default: false } }, @@ -168,6 +167,12 @@ export default defineComponent({ } }; + const qOptionClasses = computed(() => ({ + 'q-option_selected': isSelected.value, + 'q-option_disabled': isDisabled.value, + 'q-option_with-checkbox': multiple + })); + onBeforeUnmount(() => { qSelect?.removeOption(self); }); @@ -185,7 +190,8 @@ export default defineComponent({ handleMouseEnter, handleOptionClick, multiple, - root + root, + qOptionClasses }; } }); diff --git a/src/qComponents/QOption/src/types.ts b/src/qComponents/QOption/src/types.ts index 497d7e12..a53c4a95 100644 --- a/src/qComponents/QOption/src/types.ts +++ b/src/qComponents/QOption/src/types.ts @@ -1,26 +1,19 @@ import type { Ref, ComputedRef } from 'vue'; -import type { Nullable } from '#/helpers'; +import type { Nullable, Nillable, ClassValue } from '#/helpers'; -export type QOptionPropValue = string | number | Record; - -export interface QOptionInstance { - multiple: boolean; - preparedLabel: ComputedRef; - isVisible: ComputedRef>; - isSelected: ComputedRef; - isLimitReached: ComputedRef; - isDisabled: ComputedRef; - handleMouseEnter: () => void; - handleOptionClick: () => void; - root: Ref>; -} +export type QOptionPropValue = Nillable< + string | number | Record +>; +export type QOptionPropLabel = Nillable; +export type QOptionPropCreated = Nullable; +export type QOptionPropDisabled = Nullable; export interface QOptionProps { - value: Nullable; - label: Nullable; - created: Nullable; - disabled: Nullable; + value: QOptionPropValue; + label: QOptionPropLabel; + created: QOptionPropCreated; + disabled: QOptionPropDisabled; } export interface QOptionModel extends QOptionProps { @@ -32,3 +25,16 @@ export interface QOptionModel extends QOptionProps { key: string | number; root: Nullable; } + +export interface QOptionInstance { + multiple: boolean; + preparedLabel: ComputedRef; + isVisible: ComputedRef>; + isSelected: ComputedRef; + isLimitReached: ComputedRef; + isDisabled: ComputedRef; + handleMouseEnter: () => void; + handleOptionClick: () => void; + root: Ref>; + qOptionClasses: ComputedRef; +} diff --git a/src/qComponents/QSelect/index.ts b/src/qComponents/QSelect/index.ts index ede98c2c..7ba09023 100644 --- a/src/qComponents/QSelect/index.ts +++ b/src/qComponents/QSelect/index.ts @@ -5,9 +5,29 @@ import Select from './src/QSelect.vue'; export const QSelect = withInstall(Select); export type { - QSelectPropModelValue, NewOption, QSelectProvider, QSelectState, - QSelectProps + QSelectProps, + QSelectPropModelValue, + QSelectPropAutocomplete, + QSelectPropCanLoadMore, + QSelectPropDisabled, + QSelectPropClearable, + QSelectPropFilterable, + QSelectPropAllowCreate, + QSelectPropLoading, + QSelectPropRemote, + QSelectPropLoadingText, + QSelectPropLoadMoreText, + QSelectPropNoMatchText, + QSelectPropNoDataText, + QSelectPropMultiple, + QSelectPropMultipleLimit, + QSelectPropPlaceholder, + QSelectPropSelectAllShown, + QSelectPropSelectAllText, + QSelectPropValueKey, + QSelectPropCollapseTags, + QSelectPropTeleportTo } from './src/types'; diff --git a/src/qComponents/QSelect/src/QSelect.vue b/src/qComponents/QSelect/src/QSelect.vue index bee33faf..6b50fa46 100644 --- a/src/qComponents/QSelect/src/QSelect.vue +++ b/src/qComponents/QSelect/src/QSelect.vue @@ -63,7 +63,7 @@ ref="dropdown" :shown="state.isDropdownShown" :width="state.inputWidth" - :select-all-shown="selectAllShown" + :select-all-shown="Boolean(selectAllShown)" :select-all-text="selectAllText || t('QSelect.selectAll')" :show-empty-content="showEmptyContent" :empty-text="emptyText" @@ -124,21 +124,42 @@ import type { QOptionModel, QOptionPropValue } from '@/qComponents/QOption'; import type { Nullable, Optional, UnwrappedInstance } from '#/helpers'; -import QSelectDropdown from './QSelectDropdown.vue'; -import QSelectTags from './QSelectTags.vue'; +import QSelectDropdown from './components/QSelectDropdown'; +import type { QSelectDropdownInstance } from './components/QSelectDropdown'; +import QSelectTags from './components/QSelectTags'; +import type { QSelectTagsInstance } from './components/QSelectTags'; import type { QSelectPropModelValue, - NewOption, + QSelectPropAutocomplete, + QSelectPropCanLoadMore, + QSelectPropDisabled, + QSelectPropClearable, + QSelectPropFilterable, + QSelectPropAllowCreate, + QSelectPropLoading, + QSelectPropRemote, + QSelectPropLoadingText, + QSelectPropLoadMoreText, + QSelectPropNoMatchText, + QSelectPropNoDataText, + QSelectPropMultiple, + QSelectPropMultipleLimit, + QSelectPropPlaceholder, + QSelectPropSelectAllShown, + QSelectPropSelectAllText, + QSelectPropValueKey, + QSelectPropCollapseTags, + QSelectPropTeleportTo, + QSelectProps, QSelectInstance, + NewOption, QSelectProvider, - QSelectState, - QSelectProps, - QSelectTagsInstance, - QSelectDropdownInstance + QSelectState } from './types'; export default defineComponent({ name: 'QSelect', + componentName: 'QSelect', components: { @@ -154,88 +175,168 @@ export default defineComponent({ type: [String, Number, Object, Array] as PropType, default: null }, + /** * the autocomplete attribute of select input */ - autocomplete: { type: String as PropType<'on' | 'off'>, default: 'off' }, + autocomplete: { + type: String as PropType, + default: 'off' + }, + /** * whether loadMoreText is shown */ - canLoadMore: { type: Boolean, default: false }, + canLoadMore: { + type: Boolean as PropType, + default: false + }, + /** * whether Select is disabled */ - disabled: { type: Boolean, default: false }, + disabled: { + type: Boolean as PropType, + default: false + }, + /** * whether select can be cleared */ - clearable: { type: Boolean, default: false }, + clearable: { + type: Boolean as PropType, + default: false + }, + /** * whether Select is filterable */ - filterable: { type: Boolean, default: false }, + filterable: { + type: Boolean as PropType, + default: false + }, + /** * whether creating new items is allowed. To use this, `filterable` must be true */ - allowCreate: { type: Boolean, default: false }, + allowCreate: { + type: Boolean as PropType, + default: false + }, + /** * whether Select is loading data from server */ - loading: { type: Boolean, default: false }, + loading: { + type: Boolean as PropType, + default: false + }, + /** * whether options are loaded from server */ - remote: { type: Boolean, default: false }, + remote: { + type: Boolean as PropType, + default: false + }, + /** * text that is shown when `loading` is true */ - loadingText: { type: String, default: null }, + loadingText: { + type: String as PropType, + default: null + }, + /** * text that is shown when `canLoadMore` is true */ - loadMoreText: { type: String, default: null }, + loadMoreText: { + type: String as PropType, + default: null + }, + /** * text of no match state */ - noMatchText: { type: String, default: null }, + noMatchText: { + type: String as PropType, + default: null + }, + /** * text of no data state */ - noDataText: { type: String, default: null }, + noDataText: { + type: String as PropType, + default: null + }, + /** * whether multiple-select is activated */ - multiple: { type: Boolean, default: false }, + multiple: { + type: Boolean as PropType, + default: false + }, + /** * maximum number of options user can select when `multiple` is true. No `limit` when set to 0 */ - multipleLimit: { type: Number, default: 0 }, + multipleLimit: { + type: Number as PropType, + default: 0 + }, + /** * placeholder */ - placeholder: { type: String, default: '' }, + placeholder: { + type: String as PropType, + default: '' + }, + /** * whether select all button is shown */ - selectAllShown: { type: Boolean, default: false }, + selectAllShown: { + type: Boolean as PropType, + default: false + }, + /** * text of select all button */ - selectAllText: { type: String, default: null }, + selectAllText: { + type: String as PropType, + default: null + }, + /** * unique identity key name for value, required when option's value is an object */ - valueKey: { type: String, default: 'value' }, + valueKey: { + type: String as PropType, + default: 'value' + }, + /** * whether to collapse tags to a text when multiple selecting */ - collapseTags: { type: Boolean, default: false }, + collapseTags: { + type: Boolean as PropType, + default: false + }, + /** * Specifies a target element where QSelect will be moved. * (has to be a valid query selector, or an HTMLElement) */ teleportTo: { - type: [String, isServer ? Object : HTMLElement], + type: [ + String, + isServer ? Object : HTMLElement + ] as PropType, default: null } }, diff --git a/src/qComponents/QSelect/src/components/QSelectDropdown/index.ts b/src/qComponents/QSelect/src/components/QSelectDropdown/index.ts new file mode 100644 index 00000000..5fb08cdf --- /dev/null +++ b/src/qComponents/QSelect/src/components/QSelectDropdown/index.ts @@ -0,0 +1,5 @@ +import QSelectDropdown from './index.vue'; + +export default QSelectDropdown; + +export type { QSelectDropdownProps, QSelectDropdownInstance } from './types'; diff --git a/src/qComponents/QSelect/src/QSelectDropdown.vue b/src/qComponents/QSelect/src/components/QSelectDropdown/index.vue similarity index 97% rename from src/qComponents/QSelect/src/QSelectDropdown.vue rename to src/qComponents/QSelect/src/components/QSelectDropdown/index.vue index 4cda69b6..a6183991 100644 --- a/src/qComponents/QSelect/src/QSelectDropdown.vue +++ b/src/qComponents/QSelect/src/components/QSelectDropdown/index.vue @@ -64,7 +64,8 @@