VEmptyState.mjs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { createVNode as _createVNode, Fragment as _Fragment } from "vue";
  2. // Styles
  3. import "./VEmptyState.css";
  4. // Components
  5. import { VBtn } from "../VBtn/index.mjs";
  6. import { VDefaultsProvider } from "../VDefaultsProvider/index.mjs";
  7. import { VIcon } from "../VIcon/index.mjs";
  8. import { VImg } from "../VImg/index.mjs"; // Composables
  9. import { useBackgroundColor } from "../../composables/color.mjs";
  10. import { makeComponentProps } from "../../composables/component.mjs";
  11. import { makeDimensionProps, useDimension } from "../../composables/dimensions.mjs";
  12. import { useDisplay } from "../../composables/display.mjs";
  13. import { IconValue } from "../../composables/icons.mjs";
  14. import { makeSizeProps } from "../../composables/size.mjs";
  15. import { makeThemeProps, provideTheme } from "../../composables/theme.mjs"; // Utilities
  16. import { toRef } from 'vue';
  17. import { convertToUnit, genericComponent, propsFactory, useRender } from "../../util/index.mjs"; // Types
  18. // Types
  19. export const makeVEmptyStateProps = propsFactory({
  20. actionText: String,
  21. bgColor: String,
  22. color: String,
  23. icon: IconValue,
  24. image: String,
  25. justify: {
  26. type: String,
  27. default: 'center'
  28. },
  29. headline: String,
  30. title: String,
  31. text: String,
  32. textWidth: {
  33. type: [Number, String],
  34. default: 500
  35. },
  36. href: String,
  37. to: String,
  38. ...makeComponentProps(),
  39. ...makeDimensionProps(),
  40. ...makeSizeProps({
  41. size: undefined
  42. }),
  43. ...makeThemeProps()
  44. }, 'VEmptyState');
  45. export const VEmptyState = genericComponent()({
  46. name: 'VEmptyState',
  47. props: makeVEmptyStateProps(),
  48. emits: {
  49. 'click:action': e => true
  50. },
  51. setup(props, _ref) {
  52. let {
  53. emit,
  54. slots
  55. } = _ref;
  56. const {
  57. themeClasses
  58. } = provideTheme(props);
  59. const {
  60. backgroundColorClasses,
  61. backgroundColorStyles
  62. } = useBackgroundColor(toRef(props, 'bgColor'));
  63. const {
  64. dimensionStyles
  65. } = useDimension(props);
  66. const {
  67. displayClasses
  68. } = useDisplay();
  69. function onClickAction(e) {
  70. emit('click:action', e);
  71. }
  72. useRender(() => {
  73. const hasActions = !!(slots.actions || props.actionText);
  74. const hasHeadline = !!(slots.headline || props.headline);
  75. const hasTitle = !!(slots.title || props.title);
  76. const hasText = !!(slots.text || props.text);
  77. const hasMedia = !!(slots.media || props.image || props.icon);
  78. const size = props.size || (props.image ? 200 : 96);
  79. return _createVNode("div", {
  80. "class": ['v-empty-state', {
  81. [`v-empty-state--${props.justify}`]: true
  82. }, themeClasses.value, backgroundColorClasses.value, displayClasses.value, props.class],
  83. "style": [backgroundColorStyles.value, dimensionStyles.value, props.style]
  84. }, [hasMedia && _createVNode("div", {
  85. "key": "media",
  86. "class": "v-empty-state__media"
  87. }, [!slots.media ? _createVNode(_Fragment, null, [props.image ? _createVNode(VImg, {
  88. "key": "image",
  89. "src": props.image,
  90. "height": size
  91. }, null) : props.icon ? _createVNode(VIcon, {
  92. "key": "icon",
  93. "color": props.color,
  94. "size": size,
  95. "icon": props.icon
  96. }, null) : undefined]) : _createVNode(VDefaultsProvider, {
  97. "key": "media-defaults",
  98. "defaults": {
  99. VImg: {
  100. src: props.image,
  101. height: size
  102. },
  103. VIcon: {
  104. size,
  105. icon: props.icon
  106. }
  107. }
  108. }, {
  109. default: () => [slots.media()]
  110. })]), hasHeadline && _createVNode("div", {
  111. "key": "headline",
  112. "class": "v-empty-state__headline"
  113. }, [slots.headline?.() ?? props.headline]), hasTitle && _createVNode("div", {
  114. "key": "title",
  115. "class": "v-empty-state__title"
  116. }, [slots.title?.() ?? props.title]), hasText && _createVNode("div", {
  117. "key": "text",
  118. "class": "v-empty-state__text",
  119. "style": {
  120. maxWidth: convertToUnit(props.textWidth)
  121. }
  122. }, [slots.text?.() ?? props.text]), slots.default && _createVNode("div", {
  123. "key": "content",
  124. "class": "v-empty-state__content"
  125. }, [slots.default()]), hasActions && _createVNode("div", {
  126. "key": "actions",
  127. "class": "v-empty-state__actions"
  128. }, [_createVNode(VDefaultsProvider, {
  129. "defaults": {
  130. VBtn: {
  131. class: 'v-empty-state__action-btn',
  132. color: props.color ?? 'surface-variant',
  133. text: props.actionText
  134. }
  135. }
  136. }, {
  137. default: () => [slots.actions?.({
  138. props: {
  139. onClick: onClickAction
  140. }
  141. }) ?? _createVNode(VBtn, {
  142. "onClick": onClickAction
  143. }, null)]
  144. })])]);
  145. });
  146. return {};
  147. }
  148. });
  149. //# sourceMappingURL=VEmptyState.mjs.map