Skip to content

Commit

Permalink
feat: add composable for select input context
Browse files Browse the repository at this point in the history
  • Loading branch information
EdieLemoine committed Feb 27, 2023
1 parent acc0fce commit c1bb84f
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 7 deletions.
11 changes: 7 additions & 4 deletions apps/admin-components/src/components/DefaultSelectInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
<select
:id="id"
v-model="model"
:disabled="element.isDisabled || element.isSuspended">
:disabled="options.length === 1 || element.isDisabled || element.isSuspended">
<option
v-for="(item, index) in element.props?.options ?? []"
v-for="(item, index) in options"
:key="index"
:disabled="item.disabled || element.isDisabled || element.isSuspended"
:disabled="item.disabled"
:value="item.value"
v-text="item.label" />
</select>
Expand All @@ -17,7 +17,7 @@
* A select box. Renders a list of options which each have their own value.
*/
import {generateFieldId, useElement} from '@myparcel-pdk/frontend-core/src';
import {generateFieldId, useElement, useSelectInputContext} from '@myparcel-pdk/frontend-core/src';
import {useVModel} from '@vueuse/core';
// eslint-disable-next-line vue/no-unused-properties
Expand All @@ -28,4 +28,7 @@ const model = useVModel(props, undefined, emit);
const element = useElement();
const id = generateFieldId();
// @ts-expect-error props are not typed
const {options} = useSelectInputContext(model, element.props?.options ?? []);
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@
:id="id"
v-model="model"
:class="{
disabled: element.props?.options?.length === 1 || element.isDisabled || element.isSuspended,
disabled: options.length === 1 || element.isDisabled || element.isSuspended,
}"
class="custom-select form-control">
<option
v-for="(item, index) in element.props?.options ?? []"
v-for="(item, index) in options"
:key="index"
:disabled="item.disabled"
:value="item.value"
v-text="item.label" />
</select>
</template>

<script setup lang="ts">
import {generateFieldId, useElement} from '@myparcel-pdk/frontend-core/src';
import {generateFieldId, useElement, useSelectInputContext} from '@myparcel-pdk/frontend-core/src';
import {useVModel} from '@vueuse/core';
// eslint-disable-next-line vue/no-unused-properties
Expand All @@ -26,4 +27,7 @@ const model = useVModel(props, undefined, emit);
const element = useElement();
const id = generateFieldId();
// @ts-expect-error props are not typed
const {options} = useSelectInputContext(model, element.props?.options ?? []);
</script>
1 change: 1 addition & 0 deletions apps/admin/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export {
useModalStore,
useNotificationStore,
usePdfWindow,
useSelectInputContext,
useWeekdays,
webhooksDeleteAction,
} from '@myparcel-pdk/frontend-core/src';
Expand Down
1 change: 1 addition & 0 deletions libs/frontend/core/src/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export * from './useGlobalPdkAdmin';
export * from './useLoading';
export * from './useLogger';
export * from './useOrderData';
export * from './useSelectInputContext';
export * from './useShipmentData';
export * from './useStoreContextQuery';
export * from './useStoreQuery';
Expand Down
40 changes: 40 additions & 0 deletions libs/frontend/core/src/composables/useSelectInputContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {ComputedRef, WritableComputedRef, computed, onMounted, watch} from 'vue';
import {SelectOption} from '@myparcel-pdk/common/src';
import {useLanguage} from './translations';

type UseSelectInputContext = (
model: WritableComputedRef<string | number>,
options: SelectOption[],
) => {
options: ComputedRef<SelectOption[]>;
};

export const useSelectInputContext: UseSelectInputContext = (model, options) => {
const {translate} = useLanguage();

const computedOptions = computed<SelectOption[]>(() => {
return options
.map((item) => ({...item, label: translate(item.label)}))
.sort((itemA, itemB) => String(itemA.label).localeCompare(itemB.label));
});

onMounted(() => {
watch(
computedOptions,
(newOptions) => {
const hasExistingValue = model.value && newOptions.some((option) => option.value === model.value);

if (hasExistingValue || newOptions.length === 0) {
return;
}

model.value = newOptions[0].value;
},
{immediate: Number(computedOptions.value?.length) > 0},
);
});

return {
options: computedOptions,
};
};

0 comments on commit c1bb84f

Please sign in to comment.