VProgressLinear.mjs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import { createVNode as _createVNode } from "vue";
  2. // Styles
  3. import "./VProgressLinear.css";
  4. // Composables
  5. import { useBackgroundColor, useTextColor } from "../../composables/color.mjs";
  6. import { makeComponentProps } from "../../composables/component.mjs";
  7. import { useIntersectionObserver } from "../../composables/intersectionObserver.mjs";
  8. import { useRtl } from "../../composables/locale.mjs";
  9. import { makeLocationProps, useLocation } from "../../composables/location.mjs";
  10. import { useProxiedModel } from "../../composables/proxiedModel.mjs";
  11. import { makeRoundedProps, useRounded } from "../../composables/rounded.mjs";
  12. import { makeTagProps } from "../../composables/tag.mjs";
  13. import { makeThemeProps, provideTheme } from "../../composables/theme.mjs"; // Utilities
  14. import { computed, Transition } from 'vue';
  15. import { clamp, convertToUnit, genericComponent, IN_BROWSER, propsFactory, useRender } from "../../util/index.mjs";
  16. export const makeVProgressLinearProps = propsFactory({
  17. absolute: Boolean,
  18. active: {
  19. type: Boolean,
  20. default: true
  21. },
  22. bgColor: String,
  23. bgOpacity: [Number, String],
  24. bufferValue: {
  25. type: [Number, String],
  26. default: 0
  27. },
  28. bufferColor: String,
  29. bufferOpacity: [Number, String],
  30. clickable: Boolean,
  31. color: String,
  32. height: {
  33. type: [Number, String],
  34. default: 4
  35. },
  36. indeterminate: Boolean,
  37. max: {
  38. type: [Number, String],
  39. default: 100
  40. },
  41. modelValue: {
  42. type: [Number, String],
  43. default: 0
  44. },
  45. opacity: [Number, String],
  46. reverse: Boolean,
  47. stream: Boolean,
  48. striped: Boolean,
  49. roundedBar: Boolean,
  50. ...makeComponentProps(),
  51. ...makeLocationProps({
  52. location: 'top'
  53. }),
  54. ...makeRoundedProps(),
  55. ...makeTagProps(),
  56. ...makeThemeProps()
  57. }, 'VProgressLinear');
  58. export const VProgressLinear = genericComponent()({
  59. name: 'VProgressLinear',
  60. props: makeVProgressLinearProps(),
  61. emits: {
  62. 'update:modelValue': value => true
  63. },
  64. setup(props, _ref) {
  65. let {
  66. slots
  67. } = _ref;
  68. const progress = useProxiedModel(props, 'modelValue');
  69. const {
  70. isRtl,
  71. rtlClasses
  72. } = useRtl();
  73. const {
  74. themeClasses
  75. } = provideTheme(props);
  76. const {
  77. locationStyles
  78. } = useLocation(props);
  79. const {
  80. textColorClasses,
  81. textColorStyles
  82. } = useTextColor(props, 'color');
  83. const {
  84. backgroundColorClasses,
  85. backgroundColorStyles
  86. } = useBackgroundColor(computed(() => props.bgColor || props.color));
  87. const {
  88. backgroundColorClasses: bufferColorClasses,
  89. backgroundColorStyles: bufferColorStyles
  90. } = useBackgroundColor(computed(() => props.bufferColor || props.bgColor || props.color));
  91. const {
  92. backgroundColorClasses: barColorClasses,
  93. backgroundColorStyles: barColorStyles
  94. } = useBackgroundColor(props, 'color');
  95. const {
  96. roundedClasses
  97. } = useRounded(props);
  98. const {
  99. intersectionRef,
  100. isIntersecting
  101. } = useIntersectionObserver();
  102. const max = computed(() => parseFloat(props.max));
  103. const height = computed(() => parseFloat(props.height));
  104. const normalizedBuffer = computed(() => clamp(parseFloat(props.bufferValue) / max.value * 100, 0, 100));
  105. const normalizedValue = computed(() => clamp(parseFloat(progress.value) / max.value * 100, 0, 100));
  106. const isReversed = computed(() => isRtl.value !== props.reverse);
  107. const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition');
  108. const isForcedColorsModeActive = IN_BROWSER && window.matchMedia?.('(forced-colors: active)').matches;
  109. function handleClick(e) {
  110. if (!intersectionRef.value) return;
  111. const {
  112. left,
  113. right,
  114. width
  115. } = intersectionRef.value.getBoundingClientRect();
  116. const value = isReversed.value ? width - e.clientX + (right - width) : e.clientX - left;
  117. progress.value = Math.round(value / width * max.value);
  118. }
  119. useRender(() => _createVNode(props.tag, {
  120. "ref": intersectionRef,
  121. "class": ['v-progress-linear', {
  122. 'v-progress-linear--absolute': props.absolute,
  123. 'v-progress-linear--active': props.active && isIntersecting.value,
  124. 'v-progress-linear--reverse': isReversed.value,
  125. 'v-progress-linear--rounded': props.rounded,
  126. 'v-progress-linear--rounded-bar': props.roundedBar,
  127. 'v-progress-linear--striped': props.striped
  128. }, roundedClasses.value, themeClasses.value, rtlClasses.value, props.class],
  129. "style": [{
  130. bottom: props.location === 'bottom' ? 0 : undefined,
  131. top: props.location === 'top' ? 0 : undefined,
  132. height: props.active ? convertToUnit(height.value) : 0,
  133. '--v-progress-linear-height': convertToUnit(height.value),
  134. ...(props.absolute ? locationStyles.value : {})
  135. }, props.style],
  136. "role": "progressbar",
  137. "aria-hidden": props.active ? 'false' : 'true',
  138. "aria-valuemin": "0",
  139. "aria-valuemax": props.max,
  140. "aria-valuenow": props.indeterminate ? undefined : normalizedValue.value,
  141. "onClick": props.clickable && handleClick
  142. }, {
  143. default: () => [props.stream && _createVNode("div", {
  144. "key": "stream",
  145. "class": ['v-progress-linear__stream', textColorClasses.value],
  146. "style": {
  147. ...textColorStyles.value,
  148. [isReversed.value ? 'left' : 'right']: convertToUnit(-height.value),
  149. borderTop: `${convertToUnit(height.value / 2)} dotted`,
  150. opacity: parseFloat(props.bufferOpacity),
  151. top: `calc(50% - ${convertToUnit(height.value / 4)})`,
  152. width: convertToUnit(100 - normalizedBuffer.value, '%'),
  153. '--v-progress-linear-stream-to': convertToUnit(height.value * (isReversed.value ? 1 : -1))
  154. }
  155. }, null), _createVNode("div", {
  156. "class": ['v-progress-linear__background', !isForcedColorsModeActive ? backgroundColorClasses.value : undefined],
  157. "style": [backgroundColorStyles.value, {
  158. opacity: parseFloat(props.bgOpacity),
  159. width: props.stream ? 0 : undefined
  160. }]
  161. }, null), _createVNode("div", {
  162. "class": ['v-progress-linear__buffer', !isForcedColorsModeActive ? bufferColorClasses.value : undefined],
  163. "style": [bufferColorStyles.value, {
  164. opacity: parseFloat(props.bufferOpacity),
  165. width: convertToUnit(normalizedBuffer.value, '%')
  166. }]
  167. }, null), _createVNode(Transition, {
  168. "name": transition.value
  169. }, {
  170. default: () => [!props.indeterminate ? _createVNode("div", {
  171. "class": ['v-progress-linear__determinate', !isForcedColorsModeActive ? barColorClasses.value : undefined],
  172. "style": [barColorStyles.value, {
  173. width: convertToUnit(normalizedValue.value, '%')
  174. }]
  175. }, null) : _createVNode("div", {
  176. "class": "v-progress-linear__indeterminate"
  177. }, [['long', 'short'].map(bar => _createVNode("div", {
  178. "key": bar,
  179. "class": ['v-progress-linear__indeterminate', bar, !isForcedColorsModeActive ? barColorClasses.value : undefined],
  180. "style": barColorStyles.value
  181. }, null))])]
  182. }), slots.default && _createVNode("div", {
  183. "class": "v-progress-linear__content"
  184. }, [slots.default({
  185. value: normalizedValue.value,
  186. buffer: normalizedBuffer.value
  187. })])]
  188. }));
  189. return {};
  190. }
  191. });
  192. //# sourceMappingURL=VProgressLinear.mjs.map