From 1cf516f8fbeda54809d7fc865598fc92a08fcc80 Mon Sep 17 00:00:00 2001 From: Sangeetha Babu <58620134+sangeethababu9223@users.noreply.github.com> Date: Fri, 16 Feb 2024 12:58:58 +0530 Subject: [PATCH 1/7] feat(slider):two handle slider --- .../src/components/slider/slider-input.ts | 7 +- .../src/components/slider/slider-story.ts | 23 ++ .../src/components/slider/slider.ts | 379 +++++++++++++----- 3 files changed, 302 insertions(+), 107 deletions(-) diff --git a/packages/carbon-web-components/src/components/slider/slider-input.ts b/packages/carbon-web-components/src/components/slider/slider-input.ts index 4d9b934484a..ca2ba4f2de9 100644 --- a/packages/carbon-web-components/src/components/slider/slider-input.ts +++ b/packages/carbon-web-components/src/components/slider/slider-input.ts @@ -45,6 +45,8 @@ class CDSSliderInput extends FocusMixin(LitElement) { * Handles `change` event to fire a normalized custom event. */ private _handleChange({ target }: Event) { + console.log('here 1'); + this.dispatchEvent( new CustomEvent((this.constructor as typeof CDSSliderInput).eventChange, { bubbles: true, @@ -60,6 +62,8 @@ class CDSSliderInput extends FocusMixin(LitElement) { * Handles `input` event to fire a normalized custom event. */ private _handleInput({ target }: Event) { + console.log('here 2'); + this.dispatchEvent( new CustomEvent((this.constructor as typeof CDSSliderInput).eventChange, { bubbles: true, @@ -164,6 +168,8 @@ class CDSSliderInput extends FocusMixin(LitElement) { _handleChange: handleChange, _handleInput: handleInput, } = this; + console.log('here mainxss'); + console.log('value',value); const classes = classMap({ [`${prefix}--text-input`]: true, @@ -179,7 +185,6 @@ class CDSSliderInput extends FocusMixin(LitElement) { const warnIcon = WarningAltFilled16({ class: `${prefix}--slider__invalid-icon ${prefix}--slider__invalid-icon--warning`, }); - return html` { `; }; +export const TwoHandleSlider = () => { + return html` + + + + + + + `; +}; + export const skeleton = () => html` diff --git a/packages/carbon-web-components/src/components/slider/slider.ts b/packages/carbon-web-components/src/components/slider/slider.ts index 72601ce1475..127b777c96a 100644 --- a/packages/carbon-web-components/src/components/slider/slider.ts +++ b/packages/carbon-web-components/src/components/slider/slider.ts @@ -82,6 +82,16 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { * `true` if dragging of thumb is in progress. */ private _dragging = false; + /** + * `true` if dragging of thumb upper is in progress. + */ + private _draggingUpper = false; + + /** + * The Upper value. + */ + @property({ type: Number, attribute: 'value-upper' }) + valueUpper; /** * The rate of the thumb position in the track. @@ -106,12 +116,40 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { ) * Number(step); } + /** + * The rate of the thumb position in the track. + * When we try to set a new value, we adjust the value considering `step` property. + */ + private get _rateUpper() { + const { max, min, valueUpper } = this; + // Copes with out-of-range value coming programmatically or from `` + return ( + (Math.min(Number(max), Math.max(Number(min), valueUpper)) - Number(min)) / + (Number(max) - Number(min)) + ); + } + + private set _rateUpper(rateUpper: number) { + const { max, min, step } = this; + this.valueUpper = + Number(min) + + Math.round( + ((Number(max) - Number(min)) * Math.min(1, Math.max(0, rateUpper))) / + Number(step) + ) * + Number(step); + } /** * The DOM element of the thumb. */ @query('#thumb') private _thumbNode!: HTMLDivElement; + /** + * The DOM element of the thumb upper. + */ + @query('#thumb-upper') + private _thumbNodeUpper!: HTMLDivElement; /** * The DOM element of the track. @@ -137,7 +175,9 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { /** * Handles `keydown` event on the thumb to increase/decrease the value. */ - private _handleKeydown({ key, shiftKey }: KeyboardEvent) { + private _handleKeydown( event: KeyboardEvent) { + const eventContainer = (event.target as HTMLElement).id; + const { key, shiftKey } = event; if (!this.disabled) { if (key in THUMB_DIRECTION) { const { @@ -146,6 +186,7 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { step: rawStep, stepMultiplier: rawstepMultiplier, value, + valueUpper, } = this; const max = Number(rawMax); const min = Number(rawMin); @@ -154,25 +195,46 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { const diff = (!shiftKey ? step : (max - min) / stepMultiplier) * THUMB_DIRECTION[key]; - const stepCount = (value + diff) / step; - // Snaps to next - this.value = Math.min( - max, - Math.max( - min, - (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step - ) - ); - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.value, - intermediate: false, - }, - }) - ); + // Snaps to next + if(eventContainer == 'thumb-upper'){ + const stepCount = (valueUpper + diff) / step; + this.valueUpper = Math.min( + max, + Math.max( + min, + (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step + ) + ); + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.valueUpper, + intermediate: false, + }, + }) + ); + }else{ + const stepCount = (value + diff) / step; + this.value = Math.min( + max, + Math.max( + min, + (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step + ) + ); + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.value, + intermediate: false, + }, + }) + ); + } } } } @@ -180,15 +242,22 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { /** * Handles `pointerdown` event on the thumb to start dragging. */ - private _startDrag() { - this._dragging = true; - this._thumbNode.style.touchAction = 'none'; + private _startDrag(event: PointerEvent) { + const eventContainer = (event.target as HTMLElement).id; + if (eventContainer === 'thumb') { + this._dragging = true; + this._thumbNode.style.touchAction = 'none'; + } else { + this._draggingUpper = true; + this._thumbNodeUpper.style.touchAction = 'none'; + } } /** * Handles `pointerdown` event on the track to update the thumb position and the value as necessary. */ private _handleClick(event: PointerEvent) { + const eventContainer = (event.target as HTMLInputElement).id; if (!this.disabled) { const { _trackNode: trackNode } = this; const isRtl = @@ -198,19 +267,35 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { const thumbPosition = event.clientX; const { left: trackLeft, width: trackWidth } = trackNode.getBoundingClientRect(); - this._rate = - (isRtl - ? trackLeft + trackWidth - thumbPosition - : thumbPosition - trackLeft) / trackWidth; - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.value, - }, - }) - ); + if (eventContainer === 'thumb-upper') { + this._rateUpper = + (isRtl + ? trackLeft + trackWidth - thumbPosition + : thumbPosition - trackLeft) / trackWidth; + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.valueUpper, + }, + }) + ); + } else if (eventContainer === 'thumb') { + this._rate = + (isRtl + ? trackLeft + trackWidth - thumbPosition + : thumbPosition - trackLeft) / trackWidth; + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.value, + }, + }) + ); + } } } @@ -222,8 +307,12 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { @HostListener('document:pointermove') // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to private _handlePointermove = (event: PointerEvent) => { - const { disabled, _dragging: dragging } = this; - if (!disabled && dragging) { + const { + disabled, + _dragging: dragging, + _draggingUpper: draggingUpper, + } = this; + if (!disabled && (dragging || draggingUpper)) { this._throttledHandlePointermoveImpl!(event); } }; @@ -234,8 +323,13 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { * @param event The event. */ private _handlePointermoveImpl(event: PointerEvent) { - const { disabled, _dragging: dragging, _trackNode: trackNode } = this; - if (!disabled && dragging) { + const { + disabled, + _dragging: dragging, + _trackNode: trackNode, + _draggingUpper: draggingUpper, + } = this; + if (!disabled) { const isRtl = trackNode .ownerDocument!.defaultView!.getComputedStyle(trackNode) @@ -243,20 +337,37 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { const thumbPosition = event.clientX; const { left: trackLeft, width: trackWidth } = this._trackNode.getBoundingClientRect(); - this._rate = - (isRtl - ? trackLeft + trackWidth - thumbPosition - : thumbPosition - trackLeft) / trackWidth; - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.value, - intermediate: true, - }, - }) - ); + if (dragging) { + this._rate = + (isRtl + ? trackLeft + trackWidth - thumbPosition + : thumbPosition - trackLeft) / trackWidth; + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.value, + intermediate: true, + }, + }) + ); + } else if (draggingUpper) { + this._rateUpper = + (isRtl + ? trackLeft + trackWidth - thumbPosition + : thumbPosition - trackLeft) / trackWidth; + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.valueUpper, + intermediate: true, + }, + }) + ); + } } } @@ -276,6 +387,18 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { ); this._dragging = false; this._thumbNode.style.touchAction = ''; + } else if (this._draggingUpper) { + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.valueUpper, + }, + }) + ); + this._draggingUpper = false; + this._thumbNodeUpper.style.touchAction = ''; } }; @@ -284,19 +407,37 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { */ @HostListener('eventChangeInput') // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to - private _handleChangeInput = ({ detail }: CustomEvent) => { + private _handleChangeInput = (event: CustomEvent) => { + const eventContainer = (event.target as HTMLElement).id; + const { detail } = event; const { intermediate, value } = detail; - this.value = value; - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value, - intermediate, - }, - }) - ); + if (eventContainer === 'upper') { + console.log('yes'); + + this.valueUpper = value; + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.valueUpper, + intermediate, + }, + }) + ); + } else { + this.value = value; + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value, + intermediate, + }, + }) + ); + } }; /** @@ -483,55 +624,65 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { } shouldUpdate(changedProperties) { - const input = this.querySelector( + const inputs = this.querySelectorAll( (this.constructor as typeof CDSSlider).selectorInput - ) as CDSSliderInput; - if (changedProperties.has('disabled')) { - if (input) { - input.disabled = this.disabled; + ) as NodeListOf; + inputs.forEach((input, index) => { + if (changedProperties.has('disabled')) { + if (input) { + input.disabled = this.disabled; + } + if (this.disabled) { + this._dragging = false; + } } - if (this.disabled) { - this._dragging = false; + if (changedProperties.has('readonly')) { + if (input) { + input.readonly = this.readonly; + } + if (this.readonly) { + this._dragging = false; + } } - } - if (changedProperties.has('readonly')) { if (input) { - input.readonly = this.readonly; - } - if (this.readonly) { - this._dragging = false; - } - } - if (input) { - ['max', 'min', 'step', 'value'].forEach((name) => { - if (changedProperties.has(name)) { - input[name] = this[name]; - } - }); - - if ( - changedProperties.has('value') || - changedProperties.has('invalid') || - changedProperties.has('warn') || - changedProperties.has('readonly') - ) { - const innerInput = input?.shadowRoot?.querySelector('input'); - - this.isValid = this._getInputValidity(innerInput); - - if (!this.readonly && !this.isValid) { - input.invalid = true; + if (this.valueUpper && index > 0) { + ['max', 'min', 'step', 'value'].forEach((name) => { + if (changedProperties.has(name)) { + input[name] = name === 'value' ? this.valueUpper : this[name]; + } + }); } else { - input.invalid = false; + ['max', 'min', 'step', 'value'].forEach((name) => { + if (changedProperties.has(name)) { + input[name] = this[name]; + } + }); } - if (!this.readonly && !this.invalid && this.warn && this.isValid) { - input.warn = true; - } else { - input.warn = false; + if ( + changedProperties.has('value') || + changedProperties.has('invalid') || + changedProperties.has('warn') || + changedProperties.has('readonly') + ) { + const innerInput = input?.shadowRoot?.querySelector('input'); + + this.isValid = this._getInputValidity(innerInput); + + if (!this.readonly && !this.isValid) { + input.invalid = true; + } else { + input.invalid = false; + } + + if (!this.readonly && !this.invalid && this.warn && this.isValid) { + input.warn = true; + } else { + input.warn = false; + } } } - } + }); return true; } @@ -551,7 +702,9 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { warn, warnText, value, + valueUpper, _rate: rate, + _rateUpper: rateUpper, _handleClickLabel: handleClickLabel, _handleKeydown: handleKeydown, _handleClick: handleClick, @@ -595,6 +748,20 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { aria-valuenow="${value}" style="left: ${rate * 100}%" @pointerdown="${startDrag}"> + ${valueUpper + ? html` +
+ ` + : html``}
Date: Thu, 22 Feb 2024 11:49:10 +0530 Subject: [PATCH 2/7] feat(slider): two knobs --- .../src/components/slider/slider-input.ts | 15 ++-- .../src/components/slider/slider.ts | 90 ++++++++++--------- 2 files changed, 56 insertions(+), 49 deletions(-) diff --git a/packages/carbon-web-components/src/components/slider/slider-input.ts b/packages/carbon-web-components/src/components/slider/slider-input.ts index ca2ba4f2de9..2ce218dbfe7 100644 --- a/packages/carbon-web-components/src/components/slider/slider-input.ts +++ b/packages/carbon-web-components/src/components/slider/slider-input.ts @@ -45,14 +45,13 @@ class CDSSliderInput extends FocusMixin(LitElement) { * Handles `change` event to fire a normalized custom event. */ private _handleChange({ target }: Event) { - console.log('here 1'); - + this.value = Number((target as HTMLInputElement).value); this.dispatchEvent( new CustomEvent((this.constructor as typeof CDSSliderInput).eventChange, { bubbles: true, composed: true, detail: { - value: Number((target as HTMLInputElement).value), + value: this.value, }, }) ); @@ -62,14 +61,13 @@ class CDSSliderInput extends FocusMixin(LitElement) { * Handles `input` event to fire a normalized custom event. */ private _handleInput({ target }: Event) { - console.log('here 2'); - + this.value = Number((target as HTMLInputElement).value); this.dispatchEvent( new CustomEvent((this.constructor as typeof CDSSliderInput).eventChange, { bubbles: true, composed: true, detail: { - value: Number((target as HTMLInputElement).value), + value: this.value, intermediate: true, }, }) @@ -168,9 +166,8 @@ class CDSSliderInput extends FocusMixin(LitElement) { _handleChange: handleChange, _handleInput: handleInput, } = this; - console.log('here mainxss'); - console.log('value',value); - + console.log(value,'value'); + const classes = classMap({ [`${prefix}--text-input`]: true, [`${prefix}--slider-text-input`]: true, diff --git a/packages/carbon-web-components/src/components/slider/slider.ts b/packages/carbon-web-components/src/components/slider/slider.ts index 127b777c96a..edf4bc61982 100644 --- a/packages/carbon-web-components/src/components/slider/slider.ts +++ b/packages/carbon-web-components/src/components/slider/slider.ts @@ -216,24 +216,45 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { }) ); }else{ - const stepCount = (value + diff) / step; - this.value = Math.min( - max, - Math.max( - min, - (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step - ) - ); - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.value, - intermediate: false, - }, - }) - ); + if(eventContainer == 'thumb-upper'){ + const stepCount = (valueUpper + diff) / step; + this.valueUpper = Math.min( + max, + Math.max( + min, + (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step + ) + ); + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.valueUpper, + intermediate: false, + }, + }) + ); + }else{ + const stepCount = (value + diff) / step; + this.value = Math.min( + max, + Math.max( + min, + (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step + ) + ); + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.value, + intermediate: false, + }, + }) + ); + } } } } @@ -412,32 +433,21 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { const { detail } = event; const { intermediate, value } = detail; if (eventContainer === 'upper') { - console.log('yes'); - this.valueUpper = value; - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.valueUpper, - intermediate, - }, - }) - ); } else { this.value = value; - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value, - intermediate, - }, - }) - ); } + const valueMain = eventContainer === 'upper' ? this.valueUpper : this.value; + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: valueMain, + intermediate, + }, + }) + ); }; /** From d3d400401015d3af98e05fcfdd560fc24ee4dcd5 Mon Sep 17 00:00:00 2001 From: Sangeetha Babu <58620134+sangeethababu9223@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:31:00 +0530 Subject: [PATCH 3/7] feat(slider): support two knobs --- .../src/components/slider/slider-input.ts | 1 - .../src/components/slider/slider.ts | 33 +++++-------------- 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/packages/carbon-web-components/src/components/slider/slider-input.ts b/packages/carbon-web-components/src/components/slider/slider-input.ts index 2ce218dbfe7..a0dcf603846 100644 --- a/packages/carbon-web-components/src/components/slider/slider-input.ts +++ b/packages/carbon-web-components/src/components/slider/slider-input.ts @@ -166,7 +166,6 @@ class CDSSliderInput extends FocusMixin(LitElement) { _handleChange: handleChange, _handleInput: handleInput, } = this; - console.log(value,'value'); const classes = classMap({ [`${prefix}--text-input`]: true, diff --git a/packages/carbon-web-components/src/components/slider/slider.ts b/packages/carbon-web-components/src/components/slider/slider.ts index edf4bc61982..ea9c3675015 100644 --- a/packages/carbon-web-components/src/components/slider/slider.ts +++ b/packages/carbon-web-components/src/components/slider/slider.ts @@ -117,7 +117,7 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { Number(step); } /** - * The rate of the thumb position in the track. + * The rate of the upper thumb position in the track. * When we try to set a new value, we adjust the value considering `step` property. */ private get _rateUpper() { @@ -216,27 +216,7 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { }) ); }else{ - if(eventContainer == 'thumb-upper'){ - const stepCount = (valueUpper + diff) / step; - this.valueUpper = Math.min( - max, - Math.max( - min, - (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step - ) - ); - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.valueUpper, - intermediate: false, - }, - }) - ); - }else{ - const stepCount = (value + diff) / step; + const stepCount = (value + diff) / step; this.value = Math.min( max, Math.max( @@ -254,7 +234,6 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { }, }) ); - } } } } @@ -656,9 +635,13 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { } if (input) { if (this.valueUpper && index > 0) { - ['max', 'min', 'step', 'value'].forEach((name) => { + ['max', 'min', 'step', 'valueUpper'].forEach((name) => { if (changedProperties.has(name)) { - input[name] = name === 'value' ? this.valueUpper : this[name]; + if(name === 'valueUpper'){ + input.value = this.valueUpper + }else{ + this[name] + } } }); } else { From 9ba98bdfe07648de22294c04dc8ae7663034a5d4 Mon Sep 17 00:00:00 2001 From: Sangeetha Babu <58620134+sangeethababu9223@users.noreply.github.com> Date: Mon, 26 Feb 2024 14:30:47 +0530 Subject: [PATCH 4/7] feat(slider): update slider functionality for two knobs --- .../src/components/slider/slider-story.ts | 2 +- .../src/components/slider/slider.ts | 74 +++++++++++++------ 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/packages/carbon-web-components/src/components/slider/slider-story.ts b/packages/carbon-web-components/src/components/slider/slider-story.ts index 136b3adecee..c302ac6c02b 100644 --- a/packages/carbon-web-components/src/components/slider/slider-story.ts +++ b/packages/carbon-web-components/src/components/slider/slider-story.ts @@ -128,7 +128,7 @@ export const TwoHandleSlider = () => { + id="lower" slot="lower-input"> this.value ? position - this.value : this.value - position; + const differenceValueUpper = position > this.valueUpper ? position - this.valueUpper : this.valueUpper - position; + differenceValue > differenceValueUpper ? this._rateUpper = position/100 : this._rate = position/100; + this.dispatchEvent( + new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + bubbles: true, + composed: true, + detail: { + value: this.value, + }, + }) + ); + + } } } } @@ -636,18 +656,24 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { if (input) { if (this.valueUpper && index > 0) { ['max', 'min', 'step', 'valueUpper'].forEach((name) => { - if (changedProperties.has(name)) { - if(name === 'valueUpper'){ - input.value = this.valueUpper - }else{ - this[name] - } + if(name === 'valueUpper'){ + input.value = this.valueUpper + }else if(name === 'min'){ + input[name] = this.value; + } + else{ + this[name] } + }); } else { ['max', 'min', 'step', 'value'].forEach((name) => { if (changedProperties.has(name)) { - input[name] = this[name]; + if(this.valueUpper && name === 'max'){ + input[name] = this.valueUpper; + }else{ + input[name] = this[name]; + } } }); } @@ -720,6 +746,10 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { ${labelText}
+ ${valueUpper ? + html ` + ` + : '' } ${formatMinText(min, minLabel)} From ddd82ff843be0bd27a9f69bec7c7c333687421b6 Mon Sep 17 00:00:00 2001 From: Sangeetha Babu <58620134+sangeethababu9223@users.noreply.github.com> Date: Mon, 26 Feb 2024 14:40:09 +0530 Subject: [PATCH 5/7] feat(slider): fomat files --- .../src/components/slider/slider-input.ts | 2 +- .../src/components/slider/slider-story.ts | 3 +- .../src/components/slider/slider.ts | 140 ++++++++++-------- 3 files changed, 81 insertions(+), 64 deletions(-) diff --git a/packages/carbon-web-components/src/components/slider/slider-input.ts b/packages/carbon-web-components/src/components/slider/slider-input.ts index a0dcf603846..27e60ce4e66 100644 --- a/packages/carbon-web-components/src/components/slider/slider-input.ts +++ b/packages/carbon-web-components/src/components/slider/slider-input.ts @@ -166,7 +166,7 @@ class CDSSliderInput extends FocusMixin(LitElement) { _handleChange: handleChange, _handleInput: handleInput, } = this; - + const classes = classMap({ [`${prefix}--text-input`]: true, [`${prefix}--slider-text-input`]: true, diff --git a/packages/carbon-web-components/src/components/slider/slider-story.ts b/packages/carbon-web-components/src/components/slider/slider-story.ts index c302ac6c02b..f74fba7317e 100644 --- a/packages/carbon-web-components/src/components/slider/slider-story.ts +++ b/packages/carbon-web-components/src/components/slider/slider-story.ts @@ -128,7 +128,8 @@ export const TwoHandleSlider = () => { + id="lower" + slot="lower-input"> = 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step - ) - ); - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + // Snaps to next + if (eventContainer == 'thumb-upper') { + const stepCount = (valueUpper + diff) / step; + this.valueUpper = Math.min( + max, + Math.max( + min, + (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step + ) + ); + this.dispatchEvent( + new CustomEvent( + (this.constructor as typeof CDSSlider).eventChange, + { bubbles: true, composed: true, detail: { value: this.valueUpper, intermediate: false, }, - }) - ); - }else{ + } + ) + ); + } else { const stepCount = (value + diff) / step; - this.value = Math.min( - max, - Math.max( - min, - (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step - ) - ); - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { + this.value = Math.min( + max, + Math.max( + min, + (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step + ) + ); + this.dispatchEvent( + new CustomEvent( + (this.constructor as typeof CDSSlider).eventChange, + { bubbles: true, composed: true, detail: { value: this.value, intermediate: false, }, - }) - ); + } + ) + ); } } } @@ -281,39 +287,54 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { }, }) ); - } else{ - if(!this.valueUpper){ + } else { + if (!this.valueUpper) { this._rate = (isRtl ? trackLeft + trackWidth - thumbPosition : thumbPosition - trackLeft) / trackWidth; this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.value, - }, - }) + new CustomEvent( + (this.constructor as typeof CDSSlider).eventChange, + { + bubbles: true, + composed: true, + detail: { + value: this.value, + }, + } + ) ); - }else{ + } else { const position = ((isRtl ? trackLeft + trackWidth - thumbPosition - : thumbPosition - trackLeft) / trackWidth)*100; - const differenceValue = position > this.value ? position - this.value : this.value - position; - const differenceValueUpper = position > this.valueUpper ? position - this.valueUpper : this.valueUpper - position; - differenceValue > differenceValueUpper ? this._rateUpper = position/100 : this._rate = position/100; + : thumbPosition - trackLeft) / + trackWidth) * + 100; + const differenceValue = + position > this.value + ? position - this.value + : this.value - position; + const differenceValueUpper = + position > this.valueUpper + ? position - this.valueUpper + : this.valueUpper - position; + differenceValue > differenceValueUpper + ? (this._rateUpper = position / 100) + : (this._rate = position / 100); this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.value, - }, - }) + new CustomEvent( + (this.constructor as typeof CDSSlider).eventChange, + { + bubbles: true, + composed: true, + detail: { + value: this.value, + }, + } + ) ); - } } } @@ -656,22 +677,20 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { if (input) { if (this.valueUpper && index > 0) { ['max', 'min', 'step', 'valueUpper'].forEach((name) => { - if(name === 'valueUpper'){ - input.value = this.valueUpper - }else if(name === 'min'){ + if (name === 'valueUpper') { + input.value = this.valueUpper; + } else if (name === 'min') { input[name] = this.value; + } else { + this[name]; } - else{ - this[name] - } - }); } else { ['max', 'min', 'step', 'value'].forEach((name) => { if (changedProperties.has(name)) { - if(this.valueUpper && name === 'max'){ + if (this.valueUpper && name === 'max') { input[name] = this.valueUpper; - }else{ + } else { input[name] = this[name]; } } @@ -746,10 +765,7 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { ${labelText}
- ${valueUpper ? - html ` - ` - : '' } + ${valueUpper ? html` ` : ''} ${formatMinText(min, minLabel)} From 30767a7d71ed15d06112d0c713c09df589baec5c Mon Sep 17 00:00:00 2001 From: Sangeetha Babu <58620134+sangeethababu9223@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:20:04 +0530 Subject: [PATCH 6/7] feat(slider): hadnle style and function update --- .../src/components/slider/slider-input.ts | 1 - .../src/components/slider/slider-story.ts | 6 +- .../src/components/slider/slider.scss | 2 +- .../src/components/slider/slider.ts | 178 ++++++++++++++---- 4 files changed, 142 insertions(+), 45 deletions(-) diff --git a/packages/carbon-web-components/src/components/slider/slider-input.ts b/packages/carbon-web-components/src/components/slider/slider-input.ts index 27e60ce4e66..b149043d197 100644 --- a/packages/carbon-web-components/src/components/slider/slider-input.ts +++ b/packages/carbon-web-components/src/components/slider/slider-input.ts @@ -166,7 +166,6 @@ class CDSSliderInput extends FocusMixin(LitElement) { _handleChange: handleChange, _handleInput: handleInput, } = this; - const classes = classMap({ [`${prefix}--text-input`]: true, [`${prefix}--slider-text-input`]: true, diff --git a/packages/carbon-web-components/src/components/slider/slider-story.ts b/packages/carbon-web-components/src/components/slider/slider-story.ts index f74fba7317e..dd59723f7d4 100644 --- a/packages/carbon-web-components/src/components/slider/slider-story.ts +++ b/packages/carbon-web-components/src/components/slider/slider-story.ts @@ -123,15 +123,15 @@ export const TwoHandleSlider = () => { max="100" min="0" step="1" - value="50" + value="10" value-upper="90"> diff --git a/packages/carbon-web-components/src/components/slider/slider.scss b/packages/carbon-web-components/src/components/slider/slider.scss index f4ef412b652..1e580f356e6 100644 --- a/packages/carbon-web-components/src/components/slider/slider.scss +++ b/packages/carbon-web-components/src/components/slider/slider.scss @@ -33,7 +33,7 @@ $css--plex: true !default; transform: translate(-50%, -50%) #{'/*rtl:ignore*/'}; } - + .#{$prefix}--slider__thumb:focus ~ .#{$prefix}-ce--slider__filled-track-container .#{$prefix}--slider__filled-track { diff --git a/packages/carbon-web-components/src/components/slider/slider.ts b/packages/carbon-web-components/src/components/slider/slider.ts index cf852487b37..f37816b19d1 100644 --- a/packages/carbon-web-components/src/components/slider/slider.ts +++ b/packages/carbon-web-components/src/components/slider/slider.ts @@ -198,13 +198,16 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { // Snaps to next if (eventContainer == 'thumb-upper') { const stepCount = (valueUpper + diff) / step; - this.valueUpper = Math.min( + const position = Math.min( max, Math.max( min, (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step ) ); + if (position >= this.value) { + this.valueUpper = position; + } this.dispatchEvent( new CustomEvent( (this.constructor as typeof CDSSlider).eventChange, @@ -220,13 +223,16 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { ); } else { const stepCount = (value + diff) / step; - this.value = Math.min( + const position = Math.min( max, Math.max( min, (diff >= 0 ? Math.floor(stepCount) : Math.ceil(stepCount)) * step ) ); + if (!this.valueUpper || position <= this.valueUpper) { + this.value = position; + } this.dispatchEvent( new CustomEvent( (this.constructor as typeof CDSSlider).eventChange, @@ -249,7 +255,17 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { * Handles `pointerdown` event on the thumb to start dragging. */ private _startDrag(event: PointerEvent) { - const eventContainer = (event.target as HTMLElement).id; + let eventContainer = (event.target as HTMLElement).id; + if (!eventContainer) { + const element = (event.target as HTMLInputElement).nodeName; + if (element == 'path' || element == 'svg') { + eventContainer = ( + ( + (event.target as HTMLInputElement).parentElement as HTMLElement + ).closest('.cds--slider__thumb-wrapper') as HTMLInputElement + ).id; + } + } if (eventContainer === 'thumb') { this._dragging = true; this._thumbNode.style.touchAction = 'none'; @@ -263,7 +279,17 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { * Handles `pointerdown` event on the track to update the thumb position and the value as necessary. */ private _handleClick(event: PointerEvent) { - const eventContainer = (event.target as HTMLInputElement).id; + let eventContainer = (event.target as HTMLInputElement).id; + if (!eventContainer) { + const element = (event.target as HTMLInputElement).nodeName; + if (element == 'path' || element == 'svg') { + eventContainer = ( + ( + (event.target as HTMLInputElement).parentElement as HTMLElement + ).closest('.cds--slider__thumb-wrapper') as HTMLInputElement + ).id; + } + } if (!this.disabled) { const { _trackNode: trackNode } = this; const isRtl = @@ -320,9 +346,19 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { position > this.valueUpper ? position - this.valueUpper : this.valueUpper - position; - differenceValue > differenceValueUpper - ? (this._rateUpper = position / 100) - : (this._rate = position / 100); + if (differenceValue > differenceValueUpper) { + this._rateUpper = position / 100; + } else if (differenceValue < differenceValueUpper) { + this._rate = position / 100; + } else if ( + !this._dragging && + !this._draggingUpper && + differenceValue === differenceValueUpper + ) { + Math.round(position) > this.valueUpper + ? (this._rateUpper = position / 100) + : (this._rate = position / 100); + } this.dispatchEvent( new CustomEvent( (this.constructor as typeof CDSSlider).eventChange, @@ -379,35 +415,47 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { const { left: trackLeft, width: trackWidth } = this._trackNode.getBoundingClientRect(); if (dragging) { - this._rate = + const position = (isRtl ? trackLeft + trackWidth - thumbPosition : thumbPosition - trackLeft) / trackWidth; - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.value, - intermediate: true, - }, - }) - ); + if (!this.valueUpper || position * 100 <= this.valueUpper) { + this._rate = position; + this.dispatchEvent( + new CustomEvent( + (this.constructor as typeof CDSSlider).eventChange, + { + bubbles: true, + composed: true, + detail: { + value: this.value, + intermediate: true, + }, + } + ) + ); + } } else if (draggingUpper) { - this._rateUpper = + const position = (isRtl ? trackLeft + trackWidth - thumbPosition : thumbPosition - trackLeft) / trackWidth; - this.dispatchEvent( - new CustomEvent((this.constructor as typeof CDSSlider).eventChange, { - bubbles: true, - composed: true, - detail: { - value: this.valueUpper, - intermediate: true, - }, - }) - ); + if (position * 100 >= this.value) { + this._rateUpper = position; + this.dispatchEvent( + new CustomEvent( + (this.constructor as typeof CDSSlider).eventChange, + { + bubbles: true, + composed: true, + detail: { + value: this.valueUpper, + intermediate: true, + }, + } + ) + ); + } } } } @@ -687,12 +735,10 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { }); } else { ['max', 'min', 'step', 'value'].forEach((name) => { - if (changedProperties.has(name)) { - if (this.valueUpper && name === 'max') { - input[name] = this.valueUpper; - } else { - input[name] = this[name]; - } + if (this.valueUpper && name === 'max') { + input[name] = this.valueUpper; + } else { + input[name] = this[name]; } }); } @@ -779,33 +825,85 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { role="presentation">
+ @pointerdown="${startDrag}"> + ${valueUpper + ? html` +
+ + + + + + + + + + + +
+ ` + : ``} +
${valueUpper ? html`
+ @pointerdown="${startDrag}"> +
+ + + + + + + + + + + +
+
` : html``}
+ style="transform: ${valueUpper + ? `translate(${rate * 100}%, -50%) scaleX(${rateUpper - rate})` + : `translate(0%, -50%) scaleX(${rate})`}">
From 069ae2942fda1d598414b0faf5c951cc3555f8c0 Mon Sep 17 00:00:00 2001 From: Sangeetha Babu <58620134+sangeethababu9223@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:58:51 +0530 Subject: [PATCH 7/7] feat(slider): Two handle slider style update --- .../src/components/slider/slider.scss | 10 ++++++- .../src/components/slider/slider.ts | 26 ++++++++++++++----- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/carbon-web-components/src/components/slider/slider.scss b/packages/carbon-web-components/src/components/slider/slider.scss index 1e580f356e6..6423e8b2bf5 100644 --- a/packages/carbon-web-components/src/components/slider/slider.scss +++ b/packages/carbon-web-components/src/components/slider/slider.scss @@ -33,7 +33,7 @@ $css--plex: true !default; transform: translate(-50%, -50%) #{'/*rtl:ignore*/'}; } - + .#{$prefix}--slider__thumb:focus ~ .#{$prefix}-ce--slider__filled-track-container .#{$prefix}--slider__filled-track { @@ -53,3 +53,11 @@ $css--plex: true !default; background-color: transparent; } } +.#{$prefix}--slider__thumb-wrapper:focus-within + .#{$prefix}--slider__thumb-icon { + display: none; +} +.#{$prefix}--slider__thumb-wrapper:focus-within + .#{$prefix}--slider__thumb-icon--focus { + display: block; +} diff --git a/packages/carbon-web-components/src/components/slider/slider.ts b/packages/carbon-web-components/src/components/slider/slider.ts index f37816b19d1..cb1fb8e8d9f 100644 --- a/packages/carbon-web-components/src/components/slider/slider.ts +++ b/packages/carbon-web-components/src/components/slider/slider.ts @@ -898,13 +898,25 @@ class CDSSlider extends HostListenerMixin(FormMixin(FocusMixin(LitElement))) { ` : html``}
-
-
-
+ ${valueUpper + ? html` +
+ ` + : html`
+
+
`} ${formatMaxText(max, maxLabel)}