VFileUploadItem.mjs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import { mergeProps as _mergeProps, createVNode as _createVNode, Fragment as _Fragment } from "vue";
  2. // Components
  3. import { VAvatar } from "../../components/VAvatar/VAvatar.mjs";
  4. import { VBtn } from "../../components/VBtn/VBtn.mjs";
  5. import { VDefaultsProvider } from "../../components/VDefaultsProvider/VDefaultsProvider.mjs";
  6. import { makeVListItemProps, VListItem } from "../../components/VList/VListItem.mjs"; // Utilities
  7. import { computed, ref, watchEffect } from 'vue';
  8. import { genericComponent, humanReadableFileSize, propsFactory, useRender } from "../../util/index.mjs"; // Types
  9. export const makeVFileUploadItemProps = propsFactory({
  10. clearable: Boolean,
  11. file: {
  12. type: Object,
  13. default: null
  14. },
  15. fileIcon: {
  16. type: String,
  17. // TODO: setup up a proper aliased icon
  18. default: 'mdi-file-document'
  19. },
  20. showSize: Boolean,
  21. ...makeVListItemProps({
  22. border: true,
  23. rounded: true,
  24. lines: 'two'
  25. })
  26. }, 'VFileUploadItem');
  27. export const VFileUploadItem = genericComponent()({
  28. name: 'VFileUploadItem',
  29. props: makeVFileUploadItemProps(),
  30. emits: {
  31. 'click:remove': () => true,
  32. click: e => true
  33. },
  34. setup(props, _ref) {
  35. let {
  36. emit,
  37. slots
  38. } = _ref;
  39. const preview = ref();
  40. const base = computed(() => typeof props.showSize !== 'boolean' ? props.showSize : undefined);
  41. function onClickRemove() {
  42. emit('click:remove');
  43. }
  44. watchEffect(() => {
  45. preview.value = props.file?.type.startsWith('image') ? URL.createObjectURL(props.file) : undefined;
  46. });
  47. useRender(() => {
  48. const listItemProps = VListItem.filterProps(props);
  49. return _createVNode(VListItem, _mergeProps(listItemProps, {
  50. "title": props.title ?? props.file?.name,
  51. "subtitle": props.showSize ? humanReadableFileSize(props.file?.size, base.value) : props.file?.type,
  52. "class": "v-file-upload-item"
  53. }), {
  54. ...slots,
  55. prepend: slotProps => _createVNode(_Fragment, null, [!slots.prepend ? _createVNode(VAvatar, {
  56. "icon": props.fileIcon,
  57. "image": preview.value,
  58. "rounded": true
  59. }, null) : _createVNode(VDefaultsProvider, {
  60. "defaults": {
  61. VAvatar: {
  62. image: preview.value,
  63. icon: !preview.value ? props.fileIcon : undefined,
  64. rounded: true
  65. }
  66. }
  67. }, {
  68. default: () => [slots.prepend?.(slotProps) ?? _createVNode(VAvatar, null, null)]
  69. })]),
  70. append: slotProps => _createVNode(_Fragment, null, [props.clearable && _createVNode(_Fragment, null, [!slots.clear ? _createVNode(VBtn, {
  71. "icon": "$clear",
  72. "density": "comfortable",
  73. "variant": "text",
  74. "onClick": onClickRemove
  75. }, null) : _createVNode(VDefaultsProvider, {
  76. "defaults": {
  77. VBtn: {
  78. icon: '$clear',
  79. density: 'comfortable',
  80. variant: 'text'
  81. }
  82. }
  83. }, {
  84. default: () => [slots.clear?.({
  85. ...slotProps,
  86. props: {
  87. onClick: onClickRemove
  88. }
  89. }) ?? _createVNode(VBtn, null, null)]
  90. })]), slots.append?.(slotProps)])
  91. });
  92. });
  93. }
  94. });
  95. //# sourceMappingURL=VFileUploadItem.mjs.map