VSwitch.mjs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import { mergeProps as _mergeProps, Fragment as _Fragment, createVNode as _createVNode } from "vue";
  2. // Styles
  3. import "./VSwitch.css";
  4. // Components
  5. import { VScaleTransition } from "../transitions/index.mjs";
  6. import { VDefaultsProvider } from "../VDefaultsProvider/VDefaultsProvider.mjs";
  7. import { VIcon } from "../VIcon/index.mjs";
  8. import { makeVInputProps, VInput } from "../VInput/VInput.mjs";
  9. import { VProgressCircular } from "../VProgressCircular/index.mjs";
  10. import { makeVSelectionControlProps, VSelectionControl } from "../VSelectionControl/VSelectionControl.mjs"; // Composables
  11. import { useFocus } from "../../composables/focus.mjs";
  12. import { LoaderSlot, useLoader } from "../../composables/loader.mjs";
  13. import { useProxiedModel } from "../../composables/proxiedModel.mjs"; // Utilities
  14. import { computed, ref } from 'vue';
  15. import { filterInputAttrs, genericComponent, getUid, IN_BROWSER, propsFactory, useRender } from "../../util/index.mjs"; // Types
  16. export const makeVSwitchProps = propsFactory({
  17. indeterminate: Boolean,
  18. inset: Boolean,
  19. flat: Boolean,
  20. loading: {
  21. type: [Boolean, String],
  22. default: false
  23. },
  24. ...makeVInputProps(),
  25. ...makeVSelectionControlProps()
  26. }, 'VSwitch');
  27. export const VSwitch = genericComponent()({
  28. name: 'VSwitch',
  29. inheritAttrs: false,
  30. props: makeVSwitchProps(),
  31. emits: {
  32. 'update:focused': focused => true,
  33. 'update:modelValue': value => true,
  34. 'update:indeterminate': value => true
  35. },
  36. setup(props, _ref) {
  37. let {
  38. attrs,
  39. slots
  40. } = _ref;
  41. const indeterminate = useProxiedModel(props, 'indeterminate');
  42. const model = useProxiedModel(props, 'modelValue');
  43. const {
  44. loaderClasses
  45. } = useLoader(props);
  46. const {
  47. isFocused,
  48. focus,
  49. blur
  50. } = useFocus(props);
  51. const control = ref();
  52. const isForcedColorsModeActive = IN_BROWSER && window.matchMedia('(forced-colors: active)').matches;
  53. const loaderColor = computed(() => {
  54. return typeof props.loading === 'string' && props.loading !== '' ? props.loading : props.color;
  55. });
  56. const uid = getUid();
  57. const id = computed(() => props.id || `switch-${uid}`);
  58. function onChange() {
  59. if (indeterminate.value) {
  60. indeterminate.value = false;
  61. }
  62. }
  63. function onTrackClick(e) {
  64. e.stopPropagation();
  65. e.preventDefault();
  66. control.value?.input?.click();
  67. }
  68. useRender(() => {
  69. const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
  70. const inputProps = VInput.filterProps(props);
  71. const controlProps = VSelectionControl.filterProps(props);
  72. return _createVNode(VInput, _mergeProps({
  73. "class": ['v-switch', {
  74. 'v-switch--flat': props.flat
  75. }, {
  76. 'v-switch--inset': props.inset
  77. }, {
  78. 'v-switch--indeterminate': indeterminate.value
  79. }, loaderClasses.value, props.class]
  80. }, rootAttrs, inputProps, {
  81. "modelValue": model.value,
  82. "onUpdate:modelValue": $event => model.value = $event,
  83. "id": id.value,
  84. "focused": isFocused.value,
  85. "style": props.style
  86. }), {
  87. ...slots,
  88. default: _ref2 => {
  89. let {
  90. id,
  91. messagesId,
  92. isDisabled,
  93. isReadonly,
  94. isValid
  95. } = _ref2;
  96. const slotProps = {
  97. model,
  98. isValid
  99. };
  100. return _createVNode(VSelectionControl, _mergeProps({
  101. "ref": control
  102. }, controlProps, {
  103. "modelValue": model.value,
  104. "onUpdate:modelValue": [$event => model.value = $event, onChange],
  105. "id": id.value,
  106. "aria-describedby": messagesId.value,
  107. "type": "checkbox",
  108. "aria-checked": indeterminate.value ? 'mixed' : undefined,
  109. "disabled": isDisabled.value,
  110. "readonly": isReadonly.value,
  111. "onFocus": focus,
  112. "onBlur": blur
  113. }, controlAttrs), {
  114. ...slots,
  115. default: _ref3 => {
  116. let {
  117. backgroundColorClasses,
  118. backgroundColorStyles
  119. } = _ref3;
  120. return _createVNode("div", {
  121. "class": ['v-switch__track', !isForcedColorsModeActive ? backgroundColorClasses.value : undefined],
  122. "style": backgroundColorStyles.value,
  123. "onClick": onTrackClick
  124. }, [slots['track-true'] && _createVNode("div", {
  125. "key": "prepend",
  126. "class": "v-switch__track-true"
  127. }, [slots['track-true'](slotProps)]), slots['track-false'] && _createVNode("div", {
  128. "key": "append",
  129. "class": "v-switch__track-false"
  130. }, [slots['track-false'](slotProps)])]);
  131. },
  132. input: _ref4 => {
  133. let {
  134. inputNode,
  135. icon,
  136. backgroundColorClasses,
  137. backgroundColorStyles
  138. } = _ref4;
  139. return _createVNode(_Fragment, null, [inputNode, _createVNode("div", {
  140. "class": ['v-switch__thumb', {
  141. 'v-switch__thumb--filled': icon || props.loading
  142. }, props.inset || isForcedColorsModeActive ? undefined : backgroundColorClasses.value],
  143. "style": props.inset ? undefined : backgroundColorStyles.value
  144. }, [slots.thumb ? _createVNode(VDefaultsProvider, {
  145. "defaults": {
  146. VIcon: {
  147. icon,
  148. size: 'x-small'
  149. }
  150. }
  151. }, {
  152. default: () => [slots.thumb({
  153. ...slotProps,
  154. icon
  155. })]
  156. }) : _createVNode(VScaleTransition, null, {
  157. default: () => [!props.loading ? icon && _createVNode(VIcon, {
  158. "key": String(icon),
  159. "icon": icon,
  160. "size": "x-small"
  161. }, null) : _createVNode(LoaderSlot, {
  162. "name": "v-switch",
  163. "active": true,
  164. "color": isValid.value === false ? undefined : loaderColor.value
  165. }, {
  166. default: slotProps => slots.loader ? slots.loader(slotProps) : _createVNode(VProgressCircular, {
  167. "active": slotProps.isActive,
  168. "color": slotProps.color,
  169. "indeterminate": true,
  170. "size": "16",
  171. "width": "2"
  172. }, null)
  173. })]
  174. })])]);
  175. }
  176. });
  177. }
  178. });
  179. });
  180. return {};
  181. }
  182. });
  183. //# sourceMappingURL=VSwitch.mjs.map