VAlert.mjs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import { mergeProps as _mergeProps, resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue";
  2. // Styles
  3. import "./VAlert.css";
  4. // Components
  5. import { VAlertTitle } from "./VAlertTitle.mjs";
  6. import { VBtn } from "../VBtn/index.mjs";
  7. import { VDefaultsProvider } from "../VDefaultsProvider/index.mjs";
  8. import { VIcon } from "../VIcon/index.mjs"; // Composables
  9. import { useTextColor } from "../../composables/color.mjs";
  10. import { makeComponentProps } from "../../composables/component.mjs";
  11. import { makeDensityProps, useDensity } from "../../composables/density.mjs";
  12. import { makeDimensionProps, useDimension } from "../../composables/dimensions.mjs";
  13. import { makeElevationProps, useElevation } from "../../composables/elevation.mjs";
  14. import { IconValue } from "../../composables/icons.mjs";
  15. import { useLocale } from "../../composables/locale.mjs";
  16. import { makeLocationProps, useLocation } from "../../composables/location.mjs";
  17. import { makePositionProps, usePosition } from "../../composables/position.mjs";
  18. import { useProxiedModel } from "../../composables/proxiedModel.mjs";
  19. import { makeRoundedProps, useRounded } from "../../composables/rounded.mjs";
  20. import { makeTagProps } from "../../composables/tag.mjs";
  21. import { makeThemeProps, provideTheme } from "../../composables/theme.mjs";
  22. import { genOverlays, makeVariantProps, useVariant } from "../../composables/variant.mjs"; // Utilities
  23. import { computed, toRef } from 'vue';
  24. import { genericComponent, propsFactory } from "../../util/index.mjs"; // Types
  25. const allowedTypes = ['success', 'info', 'warning', 'error'];
  26. export const makeVAlertProps = propsFactory({
  27. border: {
  28. type: [Boolean, String],
  29. validator: val => {
  30. return typeof val === 'boolean' || ['top', 'end', 'bottom', 'start'].includes(val);
  31. }
  32. },
  33. borderColor: String,
  34. closable: Boolean,
  35. closeIcon: {
  36. type: IconValue,
  37. default: '$close'
  38. },
  39. closeLabel: {
  40. type: String,
  41. default: '$vuetify.close'
  42. },
  43. icon: {
  44. type: [Boolean, String, Function, Object],
  45. default: null
  46. },
  47. modelValue: {
  48. type: Boolean,
  49. default: true
  50. },
  51. prominent: Boolean,
  52. title: String,
  53. text: String,
  54. type: {
  55. type: String,
  56. validator: val => allowedTypes.includes(val)
  57. },
  58. ...makeComponentProps(),
  59. ...makeDensityProps(),
  60. ...makeDimensionProps(),
  61. ...makeElevationProps(),
  62. ...makeLocationProps(),
  63. ...makePositionProps(),
  64. ...makeRoundedProps(),
  65. ...makeTagProps(),
  66. ...makeThemeProps(),
  67. ...makeVariantProps({
  68. variant: 'flat'
  69. })
  70. }, 'VAlert');
  71. export const VAlert = genericComponent()({
  72. name: 'VAlert',
  73. props: makeVAlertProps(),
  74. emits: {
  75. 'click:close': e => true,
  76. 'update:modelValue': value => true
  77. },
  78. setup(props, _ref) {
  79. let {
  80. emit,
  81. slots
  82. } = _ref;
  83. const isActive = useProxiedModel(props, 'modelValue');
  84. const icon = computed(() => {
  85. if (props.icon === false) return undefined;
  86. if (!props.type) return props.icon;
  87. return props.icon ?? `$${props.type}`;
  88. });
  89. const variantProps = computed(() => ({
  90. color: props.color ?? props.type,
  91. variant: props.variant
  92. }));
  93. const {
  94. themeClasses
  95. } = provideTheme(props);
  96. const {
  97. colorClasses,
  98. colorStyles,
  99. variantClasses
  100. } = useVariant(variantProps);
  101. const {
  102. densityClasses
  103. } = useDensity(props);
  104. const {
  105. dimensionStyles
  106. } = useDimension(props);
  107. const {
  108. elevationClasses
  109. } = useElevation(props);
  110. const {
  111. locationStyles
  112. } = useLocation(props);
  113. const {
  114. positionClasses
  115. } = usePosition(props);
  116. const {
  117. roundedClasses
  118. } = useRounded(props);
  119. const {
  120. textColorClasses,
  121. textColorStyles
  122. } = useTextColor(toRef(props, 'borderColor'));
  123. const {
  124. t
  125. } = useLocale();
  126. const closeProps = computed(() => ({
  127. 'aria-label': t(props.closeLabel),
  128. onClick(e) {
  129. isActive.value = false;
  130. emit('click:close', e);
  131. }
  132. }));
  133. return () => {
  134. const hasPrepend = !!(slots.prepend || icon.value);
  135. const hasTitle = !!(slots.title || props.title);
  136. const hasClose = !!(slots.close || props.closable);
  137. return isActive.value && _createVNode(props.tag, {
  138. "class": ['v-alert', props.border && {
  139. 'v-alert--border': !!props.border,
  140. [`v-alert--border-${props.border === true ? 'start' : props.border}`]: true
  141. }, {
  142. 'v-alert--prominent': props.prominent
  143. }, themeClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, variantClasses.value, props.class],
  144. "style": [colorStyles.value, dimensionStyles.value, locationStyles.value, props.style],
  145. "role": "alert"
  146. }, {
  147. default: () => [genOverlays(false, 'v-alert'), props.border && _createVNode("div", {
  148. "key": "border",
  149. "class": ['v-alert__border', textColorClasses.value],
  150. "style": textColorStyles.value
  151. }, null), hasPrepend && _createVNode("div", {
  152. "key": "prepend",
  153. "class": "v-alert__prepend"
  154. }, [!slots.prepend ? _createVNode(VIcon, {
  155. "key": "prepend-icon",
  156. "density": props.density,
  157. "icon": icon.value,
  158. "size": props.prominent ? 44 : 28
  159. }, null) : _createVNode(VDefaultsProvider, {
  160. "key": "prepend-defaults",
  161. "disabled": !icon.value,
  162. "defaults": {
  163. VIcon: {
  164. density: props.density,
  165. icon: icon.value,
  166. size: props.prominent ? 44 : 28
  167. }
  168. }
  169. }, slots.prepend)]), _createVNode("div", {
  170. "class": "v-alert__content"
  171. }, [hasTitle && _createVNode(VAlertTitle, {
  172. "key": "title"
  173. }, {
  174. default: () => [slots.title?.() ?? props.title]
  175. }), slots.text?.() ?? props.text, slots.default?.()]), slots.append && _createVNode("div", {
  176. "key": "append",
  177. "class": "v-alert__append"
  178. }, [slots.append()]), hasClose && _createVNode("div", {
  179. "key": "close",
  180. "class": "v-alert__close"
  181. }, [!slots.close ? _createVNode(VBtn, _mergeProps({
  182. "key": "close-btn",
  183. "icon": props.closeIcon,
  184. "size": "x-small",
  185. "variant": "text"
  186. }, closeProps.value), null) : _createVNode(VDefaultsProvider, {
  187. "key": "close-defaults",
  188. "defaults": {
  189. VBtn: {
  190. icon: props.closeIcon,
  191. size: 'x-small',
  192. variant: 'text'
  193. }
  194. }
  195. }, {
  196. default: () => [slots.close?.({
  197. props: closeProps.value
  198. })]
  199. })])]
  200. });
  201. };
  202. }
  203. });
  204. //# sourceMappingURL=VAlert.mjs.map