react-component / slider

@@ -62,6 +62,10 @@
Loading
62 62
    return 0;
63 63
  }
64 64
65 +
  positionGetValue = (position): number[] => {
66 +
    return [];
67 +
  };
68 +
65 69
  calcOffset(value: number) {
66 70
    return 0;
67 71
  }
@@ -246,7 +250,7 @@
Loading
246 250
      ariaLabelledBy: ariaLabelledByForHandle,
247 251
      ariaValueTextFormatter: ariaValueTextFormatterForHandle,
248 252
      style: handleStyle[0] || handleStyle,
249 -
      ref: h => this.saveHandle(0, h),
253 +
      ref: (h) => this.saveHandle(0, h),
250 254
    });
251 255
252 256
    const trackOffset = startPoint !== undefined ? this.calcOffset(startPoint) : 0;

@@ -70,6 +70,10 @@
Loading
70 70
71 71
    onMouseUpListener: any;
72 72
73 +
    dragTrack: boolean;
74 +
75 +
    startBounds: number[];
76 +
73 77
    constructor(props: Props) {
74 78
      super(props);
75 79
@@ -97,44 +101,64 @@
Loading
97 101
      this.removeDocumentEvents();
98 102
    }
99 103
104 +
    onDown = (e, position) => {
105 +
      let p = position;
106 +
      const { draggableTrack, vertical: isVertical } = this.props;
107 +
      const { bounds } = this.state;
108 +
109 +
      const value = draggableTrack && this.positionGetValue ? this.positionGetValue(p) || [] : [];
110 +
111 +
      const inPoint = utils.isEventFromHandle(e, this.handlesRefs);
112 +
      this.dragTrack =
113 +
        draggableTrack &&
114 +
        bounds.length >= 2 &&
115 +
        !inPoint &&
116 +
        !value
117 +
          .map((n, i) => {
118 +
            const v = !i ? n >= bounds[i] : true;
119 +
            return i === value.length - 1 ? n <= bounds[i] : v;
120 +
          })
121 +
          .some((c) => !c);
122 +
123 +
      if (this.dragTrack) {
124 +
        this.dragOffset = p;
125 +
        this.startBounds = [...bounds];
126 +
      } else {
127 +
        if (!inPoint) {
128 +
          this.dragOffset = 0;
129 +
        } else {
130 +
          const handlePosition = utils.getHandleCenterPosition(isVertical, e.target);
131 +
          this.dragOffset = p - handlePosition;
132 +
          p = handlePosition;
133 +
        }
134 +
        this.onStart(p);
135 +
      }
136 +
    };
137 +
100 138
    onMouseDown = (e: any) => {
101 139
      if (e.button !== 0) {
102 140
        return;
103 141
      }
104 -
      const isVertical = this.props.vertical;
105 -
      let position = utils.getMousePosition(isVertical, e);
106 -
      if (!utils.isEventFromHandle(e, this.handlesRefs)) {
107 -
        this.dragOffset = 0;
108 -
      } else {
109 -
        const handlePosition = utils.getHandleCenterPosition(isVertical, e.target);
110 -
        this.dragOffset = position - handlePosition;
111 -
        position = handlePosition;
112 -
      }
142 +
113 143
      this.removeDocumentEvents();
114 -
      this.onStart(position);
144 +
      const isVertical = this.props.vertical;
145 +
      const position = utils.getMousePosition(isVertical, e);
146 +
      this.onDown(e, position);
115 147
      this.addDocumentMouseEvents();
116 148
    };
117 149
118 150
    onTouchStart = (e: any) => {
119 151
      if (utils.isNotTouchEvent(e)) return;
120 -
121 152
      const isVertical = this.props.vertical;
122 -
      let position = utils.getTouchPosition(isVertical, e);
123 -
      if (!utils.isEventFromHandle(e, this.handlesRefs)) {
124 -
        this.dragOffset = 0;
125 -
      } else {
126 -
        const handlePosition = utils.getHandleCenterPosition(isVertical, e.target);
127 -
        this.dragOffset = position - handlePosition;
128 -
        position = handlePosition;
129 -
      }
130 -
      this.onStart(position);
153 +
      const position = utils.getTouchPosition(isVertical, e);
154 +
      this.onDown(e, position);
131 155
      this.addDocumentTouchEvents();
132 156
      utils.pauseEvent(e);
133 157
    };
134 158
135 159
    onFocus = (e: React.FocusEvent<HTMLDivElement>) => {
136 160
      const { onFocus, vertical } = this.props;
137 -
      if (utils.isEventFromHandle(e, this.handlesRefs)) {
161 +
      if (utils.isEventFromHandle(e, this.handlesRefs) && !this.dragTrack) {
138 162
        const handlePosition = utils.getHandleCenterPosition(vertical, e.target);
139 163
        this.dragOffset = 0;
140 164
        this.onStart(handlePosition);
@@ -147,7 +171,10 @@
Loading
147 171
148 172
    onBlur = (e: React.FocusEvent<HTMLDivElement>) => {
149 173
      const { onBlur } = this.props;
150 -
      this.onEnd();
174 +
      if (!this.dragTrack) {
175 +
        this.onEnd();
176 +
      }
177 +
151 178
      if (onBlur) {
152 179
        onBlur(e);
153 180
      }
@@ -165,7 +192,7 @@
Loading
165 192
        return;
166 193
      }
167 194
      const position = utils.getMousePosition(this.props.vertical, e);
168 -
      this.onMove(e, position - this.dragOffset);
195 +
      this.onMove(e, position - this.dragOffset, this.dragTrack, this.startBounds);
169 196
    };
170 197
171 198
    onTouchMove = (e: React.TouchEvent<HTMLDivElement>) => {
@@ -175,7 +202,7 @@
Loading
175 202
      }
176 203
177 204
      const position = utils.getTouchPosition(this.props.vertical, e);
178 -
      this.onMove(e, position - this.dragOffset);
205 +
      this.onMove(e, position - this.dragOffset, this.dragTrack, this.startBounds);
179 206
    };
180 207
181 208
    onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
@@ -243,7 +270,7 @@
Loading
243 270
      if (this.props.disabled) {
244 271
        return;
245 272
      }
246 -
      Object.keys(this.handlesRefs).forEach(key => {
273 +
      Object.keys(this.handlesRefs).forEach((key) => {
247 274
        this.handlesRefs[key]?.blur?.();
248 275
      });
249 276
    }

@@ -58,6 +58,7 @@
Loading
58 58
  ariaLabelledByGroupForHandles?: string | Array<string>;
59 59
  ariaValueTextFormatterGroupForHandles?: string | Array<string>;
60 60
  handle?: SliderProps['handle'];
61 +
  draggableTrack?: boolean;
61 62
}
62 63
63 64
interface RangeState extends GenericSliderState {
@@ -76,6 +77,10 @@
Loading
76 77
    return 0;
77 78
  }
78 79
80 +
  getSliderLength() {
81 +
    return 0;
82 +
  }
83 +
79 84
  calcOffset(value: number) {
80 85
    return 0;
81 86
  }
@@ -91,6 +96,7 @@
Loading
91 96
    count: 1,
92 97
    allowCross: true,
93 98
    pushable: false,
99 +
    draggableTrack: false,
94 100
    tabIndex: [],
95 101
    ariaLabelGroupForHandles: [],
96 102
    ariaLabelledByGroupForHandles: [],
@@ -107,6 +113,8 @@
Loading
107 113
108 114
  handlesRefs: Record<number, any>;
109 115
116 +
  dragTrack: boolean;
117 +
110 118
  constructor(props: RangeProps) {
111 119
    super(props);
112 120
@@ -204,6 +212,19 @@
Loading
204 212
    props.onChange(changedValue);
205 213
  }
206 214
215 +
  positionGetValue = (position): number[] => {
216 +
    const bounds = this.getValue();
217 +
    const value = this.calcValueByPos(position);
218 +
    const closestBound = this.getClosestBound(value);
219 +
    const index = this.getBoundNeedMoving(value, closestBound);
220 +
    const prevValue = bounds[index];
221 +
    if (value === prevValue) return null;
222 +
223 +
    const nextBounds = [...bounds];
224 +
    nextBounds[index] = value;
225 +
    return nextBounds;
226 +
  };
227 +
207 228
  onStart(position) {
208 229
    const { props, state } = this;
209 230
    const bounds = this.getValue();
@@ -233,6 +254,9 @@
Loading
233 254
    const { handle } = this.state;
234 255
    this.removeDocumentEvents();
235 256
257 +
    if (!handle) {
258 +
      this.dragTrack = false;
259 +
    }
236 260
    if (handle !== null || force) {
237 261
      this.props.onAfterChange(this.getValue());
238 262
    }
@@ -242,10 +266,27 @@
Loading
242 266
    });
243 267
  };
244 268
245 -
  onMove(e, position) {
269 +
  onMove(e, position, dragTrack, startBounds) {
246 270
    utils.pauseEvent(e);
247 -
    const { state } = this;
248 -
271 +
    const { state, props } = this;
272 +
    const maxValue = props.max || 100;
273 +
    const minValue = props.min || 0;
274 +
    if (dragTrack) {
275 +
      let pos = props.vertical ? -position : position;
276 +
      pos = props.reverse ? -pos : pos;
277 +
      const max = maxValue - Math.max(...startBounds);
278 +
      const min = minValue - Math.min(...startBounds);
279 +
      const ratio = Math.min(Math.max(pos / (this.getSliderLength() / 100), min), max);
280 +
      const nextBounds = startBounds.map(v =>
281 +
        Math.floor(Math.max(Math.min(v + ratio, maxValue), minValue)),
282 +
      );
283 +
      if (state.bounds.map((c, i) => c === nextBounds[i]).some(c => !c)) {
284 +
        this.onChange({
285 +
          bounds: nextBounds,
286 +
        });
287 +
      }
288 +
      return;
289 +
    }
249 290
    const value = this.calcValueByPos(position);
250 291
    const oldValue = state.bounds[state.handle];
251 292
    if (value === oldValue) return;
Files Coverage
src 88.49%
Project Totals (11 files) 88.49%

No yaml found.

Create your codecov.yml to customize your Codecov experience

Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading