ion-segment-view.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
  5. const segmentViewIosCss = ":host{display:-ms-flexbox;display:flex;height:100%;overflow-x:scroll;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none}:host::-webkit-scrollbar{display:none}:host(.segment-view-disabled){-ms-touch-action:none;touch-action:none;overflow-x:hidden}:host(.segment-view-scroll-disabled){pointer-events:none}:host(.segment-view-disabled){opacity:0.3}";
  6. const IonSegmentViewIosStyle0 = segmentViewIosCss;
  7. const segmentViewMdCss = ":host{display:-ms-flexbox;display:flex;height:100%;overflow-x:scroll;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none}:host::-webkit-scrollbar{display:none}:host(.segment-view-disabled){-ms-touch-action:none;touch-action:none;overflow-x:hidden}:host(.segment-view-scroll-disabled){pointer-events:none}:host(.segment-view-disabled){opacity:0.3}";
  8. const IonSegmentViewMdStyle0 = segmentViewMdCss;
  9. const SegmentView = /*@__PURE__*/ proxyCustomElement(class SegmentView extends HTMLElement {
  10. constructor() {
  11. super();
  12. this.__registerHost();
  13. this.__attachShadow();
  14. this.ionSegmentViewScroll = createEvent(this, "ionSegmentViewScroll", 7);
  15. this.scrollEndTimeout = null;
  16. this.isTouching = false;
  17. this.disabled = false;
  18. this.isManualScroll = undefined;
  19. }
  20. handleScroll(ev) {
  21. var _a;
  22. const { scrollLeft, scrollWidth, clientWidth } = ev.target;
  23. const scrollRatio = scrollLeft / (scrollWidth - clientWidth);
  24. this.ionSegmentViewScroll.emit({
  25. scrollRatio,
  26. isManualScroll: (_a = this.isManualScroll) !== null && _a !== void 0 ? _a : true,
  27. });
  28. // Reset the timeout to check for scroll end
  29. this.resetScrollEndTimeout();
  30. }
  31. /**
  32. * Handle touch start event to know when the user is actively dragging the segment view.
  33. */
  34. handleScrollStart() {
  35. if (this.scrollEndTimeout) {
  36. clearTimeout(this.scrollEndTimeout);
  37. this.scrollEndTimeout = null;
  38. }
  39. this.isTouching = true;
  40. }
  41. /**
  42. * Handle touch end event to know when the user is no longer dragging the segment view.
  43. */
  44. handleTouchEnd() {
  45. this.isTouching = false;
  46. }
  47. /**
  48. * Reset the scroll end detection timer. This is called on every scroll event.
  49. */
  50. resetScrollEndTimeout() {
  51. if (this.scrollEndTimeout) {
  52. clearTimeout(this.scrollEndTimeout);
  53. this.scrollEndTimeout = null;
  54. }
  55. this.scrollEndTimeout = setTimeout(() => {
  56. this.checkForScrollEnd();
  57. },
  58. // Setting this to a lower value may result in inconsistencies in behavior
  59. // across browsers (particularly Firefox).
  60. // Ideally, all of this logic is removed once the scroll end event is
  61. // supported on all browsers (https://caniuse.com/?search=scrollend)
  62. 100);
  63. }
  64. /**
  65. * Check if the scroll has ended and the user is not actively touching.
  66. * If the conditions are met (active content is enabled and no active touch),
  67. * reset the scroll position and emit the scroll end event.
  68. */
  69. checkForScrollEnd() {
  70. // Only emit scroll end event if the active content is not disabled and
  71. // the user is not touching the segment view
  72. if (!this.isTouching) {
  73. this.isManualScroll = undefined;
  74. }
  75. }
  76. /**
  77. * @internal
  78. *
  79. * This method is used to programmatically set the displayed segment content
  80. * in the segment view. Calling this method will update the `value` of the
  81. * corresponding segment button.
  82. *
  83. * @param id: The id of the segment content to display.
  84. * @param smoothScroll: Whether to animate the scroll transition.
  85. */
  86. async setContent(id, smoothScroll = true) {
  87. const contents = this.getSegmentContents();
  88. const index = contents.findIndex((content) => content.id === id);
  89. if (index === -1)
  90. return;
  91. this.isManualScroll = false;
  92. this.resetScrollEndTimeout();
  93. const contentWidth = this.el.offsetWidth;
  94. this.el.scrollTo({
  95. top: 0,
  96. left: index * contentWidth,
  97. behavior: smoothScroll ? 'smooth' : 'instant',
  98. });
  99. }
  100. getSegmentContents() {
  101. return Array.from(this.el.querySelectorAll('ion-segment-content'));
  102. }
  103. render() {
  104. const { disabled, isManualScroll } = this;
  105. return (h(Host, { key: 'fa528d2d9ae0f00fc3067defe2a047dce77c814a', class: {
  106. 'segment-view-disabled': disabled,
  107. 'segment-view-scroll-disabled': isManualScroll === false,
  108. } }, h("slot", { key: '74dc8b4d073caeff1bab272d11b9ea3e1a215954' })));
  109. }
  110. get el() { return this; }
  111. static get style() { return {
  112. ios: IonSegmentViewIosStyle0,
  113. md: IonSegmentViewMdStyle0
  114. }; }
  115. }, [33, "ion-segment-view", {
  116. "disabled": [4],
  117. "isManualScroll": [32],
  118. "setContent": [64]
  119. }, [[1, "scroll", "handleScroll"], [1, "touchstart", "handleScrollStart"], [1, "touchend", "handleTouchEnd"]]]);
  120. function defineCustomElement$1() {
  121. if (typeof customElements === "undefined") {
  122. return;
  123. }
  124. const components = ["ion-segment-view"];
  125. components.forEach(tagName => { switch (tagName) {
  126. case "ion-segment-view":
  127. if (!customElements.get(tagName)) {
  128. customElements.define(tagName, SegmentView);
  129. }
  130. break;
  131. } });
  132. }
  133. const IonSegmentView = SegmentView;
  134. const defineCustomElement = defineCustomElement$1;
  135. export { IonSegmentView, defineCustomElement };