a599c6447e7d7d1c2687021484455c42f404dc2358841e5a5376e28cc7c0219b9f354f13527838ed4b7b6679de25e3bf7be71537c93f9bfcb7a2ce7b257008 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import { defineComponent, ref, reactive, computed, watch, openBlock, createElementBlock, unref, normalizeClass, createElementVNode, normalizeStyle, Fragment, renderList, renderSlot, createTextVNode, toDisplayString, createCommentVNode } from 'vue';
  2. import { useActiveElement, useResizeObserver } from '@vueuse/core';
  3. import { segmentedProps, segmentedEmits, defaultProps } from './segmented.mjs';
  4. import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
  5. import { useNamespace } from '../../../hooks/use-namespace/index.mjs';
  6. import { useId } from '../../../hooks/use-id/index.mjs';
  7. import { useFormSize, useFormDisabled } from '../../form/src/hooks/use-form-common-props.mjs';
  8. import { useFormItem, useFormItemInputId } from '../../form/src/hooks/use-form-item.mjs';
  9. import { isObject } from '@vue/shared';
  10. import { debugWarn } from '../../../utils/error.mjs';
  11. import { UPDATE_MODEL_EVENT, CHANGE_EVENT } from '../../../constants/event.mjs';
  12. const __default__ = defineComponent({
  13. name: "ElSegmented"
  14. });
  15. const _sfc_main = /* @__PURE__ */ defineComponent({
  16. ...__default__,
  17. props: segmentedProps,
  18. emits: segmentedEmits,
  19. setup(__props, { emit }) {
  20. const props = __props;
  21. const ns = useNamespace("segmented");
  22. const segmentedId = useId();
  23. const segmentedSize = useFormSize();
  24. const _disabled = useFormDisabled();
  25. const { formItem } = useFormItem();
  26. const { inputId, isLabeledByFormItem } = useFormItemInputId(props, {
  27. formItemContext: formItem
  28. });
  29. const segmentedRef = ref(null);
  30. const activeElement = useActiveElement();
  31. const state = reactive({
  32. isInit: false,
  33. width: 0,
  34. height: 0,
  35. translateX: 0,
  36. translateY: 0,
  37. focusVisible: false
  38. });
  39. const handleChange = (item) => {
  40. const value = getValue(item);
  41. emit(UPDATE_MODEL_EVENT, value);
  42. emit(CHANGE_EVENT, value);
  43. };
  44. const aliasProps = computed(() => ({ ...defaultProps, ...props.props }));
  45. const intoAny = (item) => item;
  46. const getValue = (item) => {
  47. return isObject(item) ? item[aliasProps.value.value] : item;
  48. };
  49. const getLabel = (item) => {
  50. return isObject(item) ? item[aliasProps.value.label] : item;
  51. };
  52. const getDisabled = (item) => {
  53. return !!(_disabled.value || (isObject(item) ? item[aliasProps.value.disabled] : false));
  54. };
  55. const getSelected = (item) => {
  56. return props.modelValue === getValue(item);
  57. };
  58. const getOption = (value) => {
  59. return props.options.find((item) => getValue(item) === value);
  60. };
  61. const getItemCls = (item) => {
  62. return [
  63. ns.e("item"),
  64. ns.is("selected", getSelected(item)),
  65. ns.is("disabled", getDisabled(item))
  66. ];
  67. };
  68. const updateSelect = () => {
  69. if (!segmentedRef.value)
  70. return;
  71. const selectedItem = segmentedRef.value.querySelector(".is-selected");
  72. const selectedItemInput = segmentedRef.value.querySelector(".is-selected input");
  73. if (!selectedItem || !selectedItemInput) {
  74. state.width = 0;
  75. state.height = 0;
  76. state.translateX = 0;
  77. state.translateY = 0;
  78. state.focusVisible = false;
  79. return;
  80. }
  81. state.isInit = true;
  82. if (props.direction === "vertical") {
  83. state.height = selectedItem.offsetHeight;
  84. state.translateY = selectedItem.offsetTop;
  85. } else {
  86. state.width = selectedItem.offsetWidth;
  87. state.translateX = selectedItem.offsetLeft;
  88. }
  89. try {
  90. state.focusVisible = selectedItemInput.matches(":focus-visible");
  91. } catch (e) {
  92. }
  93. };
  94. const segmentedCls = computed(() => [
  95. ns.b(),
  96. ns.m(segmentedSize.value),
  97. ns.is("block", props.block)
  98. ]);
  99. const selectedStyle = computed(() => ({
  100. width: props.direction === "vertical" ? "100%" : `${state.width}px`,
  101. height: props.direction === "vertical" ? `${state.height}px` : "100%",
  102. transform: props.direction === "vertical" ? `translateY(${state.translateY}px)` : `translateX(${state.translateX}px)`,
  103. display: state.isInit ? "block" : "none"
  104. }));
  105. const selectedCls = computed(() => [
  106. ns.e("item-selected"),
  107. ns.is("disabled", getDisabled(getOption(props.modelValue))),
  108. ns.is("focus-visible", state.focusVisible)
  109. ]);
  110. const name = computed(() => {
  111. return props.name || segmentedId.value;
  112. });
  113. useResizeObserver(segmentedRef, updateSelect);
  114. watch(activeElement, updateSelect);
  115. watch(() => props.modelValue, () => {
  116. var _a;
  117. updateSelect();
  118. if (props.validateEvent) {
  119. (_a = formItem == null ? void 0 : formItem.validate) == null ? void 0 : _a.call(formItem, "change").catch((err) => debugWarn());
  120. }
  121. }, {
  122. flush: "post"
  123. });
  124. return (_ctx, _cache) => {
  125. return _ctx.options.length ? (openBlock(), createElementBlock("div", {
  126. key: 0,
  127. id: unref(inputId),
  128. ref_key: "segmentedRef",
  129. ref: segmentedRef,
  130. class: normalizeClass(unref(segmentedCls)),
  131. role: "radiogroup",
  132. "aria-label": !unref(isLabeledByFormItem) ? _ctx.ariaLabel || "segmented" : void 0,
  133. "aria-labelledby": unref(isLabeledByFormItem) ? unref(formItem).labelId : void 0
  134. }, [
  135. createElementVNode("div", {
  136. class: normalizeClass([unref(ns).e("group"), unref(ns).m(props.direction)])
  137. }, [
  138. createElementVNode("div", {
  139. style: normalizeStyle(unref(selectedStyle)),
  140. class: normalizeClass(unref(selectedCls))
  141. }, null, 6),
  142. (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.options, (item, index) => {
  143. return openBlock(), createElementBlock("label", {
  144. key: index,
  145. class: normalizeClass(getItemCls(item))
  146. }, [
  147. createElementVNode("input", {
  148. class: normalizeClass(unref(ns).e("item-input")),
  149. type: "radio",
  150. name: unref(name),
  151. disabled: getDisabled(item),
  152. checked: getSelected(item),
  153. onChange: ($event) => handleChange(item)
  154. }, null, 42, ["name", "disabled", "checked", "onChange"]),
  155. createElementVNode("div", {
  156. class: normalizeClass(unref(ns).e("item-label"))
  157. }, [
  158. renderSlot(_ctx.$slots, "default", {
  159. item: intoAny(item)
  160. }, () => [
  161. createTextVNode(toDisplayString(getLabel(item)), 1)
  162. ])
  163. ], 2)
  164. ], 2);
  165. }), 128))
  166. ], 2)
  167. ], 10, ["id", "aria-label", "aria-labelledby"])) : createCommentVNode("v-if", true);
  168. };
  169. }
  170. });
  171. var Segmented = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "segmented.vue"]]);
  172. export { Segmented as default };
  173. //# sourceMappingURL=segmented2.mjs.map