freeblox/packages/editor/src/components/form/AssetPicker.vue

93 lines
1.8 KiB
Vue

<template>
<div class="form-field-asset">
<label class="form-field-asset-label" :for="id">{{ label }}</label>
<div class="form-field-asset-input">
<Menu
:id="id"
class="form-field-asset-button"
:items="pickable"
overflowing
position="top-right"
>Assign Texture</Menu
>
</div>
</div>
</template>
<script setup lang="ts">
import { assetManager } from '@freeblox/engine';
import { computed, ref } from 'vue';
import AssetPickerAsset from './AssetPickerAsset.vue';
import Menu from '../menu/Menu.vue';
import { MenuItem } from '../../types/menu.interface';
const props = defineProps<{
name: string;
label: string;
value?: string;
}>();
const modelValueId = ref(props.value);
const emit = defineEmits<{
(e: 'update', value?: string): void;
}>();
const id = computed(() => `form-${props.name}`);
const pickable = computed<MenuItem[]>(() => [
{
id: 'texture-none',
label: 'None',
onClick: () => {
modelValueId.value = undefined;
emit('update', undefined);
},
},
...assetManager.assets.map((item) => ({
id: item.path || item.name,
label: item.name,
asset: item,
component: AssetPickerAsset,
onClick: () => {
modelValueId.value = item.path;
emit('update', item.path);
},
})),
]);
</script>
<style lang="scss">
.form-field-asset {
display: grid;
grid-template-columns: 1fr 1fr;
&-label {
padding: 8px;
text-transform: capitalize;
user-select: none;
}
&-input {
position: relative;
display: flex;
margin: 2px 0;
}
&-button {
width: 100%;
> .menu-button {
appearance: none;
cursor: pointer;
border: 0;
background-color: #ffffff;
padding: 8px;
width: 100%;
margin: 2px 0;
font-size: 0.75rem;
border-radius: 4px;
}
}
}
</style>