From 5295e6896d32254f4f03e2939a4e2fcb81e0ad06 Mon Sep 17 00:00:00 2001 From: Elliott Marquez Date: Wed, 27 Sep 2023 14:27:08 -0700 Subject: [PATCH] fix(slider): slider knob has size to drag on ios safari fixes #5016 PiperOrigin-RevId: 568960672 --- slider/internal/_slider.scss | 48 ++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/slider/internal/_slider.scss b/slider/internal/_slider.scss index a1ac7939217..0bb2fc99bfa 100644 --- a/slider/internal/_slider.scss +++ b/slider/internal/_slider.scss @@ -55,6 +55,43 @@ $_md-sys-shape: tokens.md-sys-shape-values(); } } +// Webkit on iOS requires _some_ size on the thumb. We want to make this the +// same as --_handle-size but also be centered on the handle. +// +// the layout is similar to this: +// [()---[()===========]----] +// +// where - is the native input and the == is the material track +// at 0 we want to shift the native knob right (padding + knob-size / 2): +// [----[(())===========]----] +// +// at the end we want to shift the native knob left by the same amount: +// [----[===========(())]----] +// +// Therefore we can do `layout-shift - 2 * `percent-fraction` * `layout-shift` +// and in RTL we want to do the the same * -1 +@mixin _get-safari-knob-translate($start-or-end) { + input.#{$start-or-end}::-webkit-slider-thumb { + // AKA `layout-shift` in the equations above + --_track-and-knob-padding: calc( + (var(--_state-layer-size) - var(--_handle-width)) / 2 + ); + --_x-translate: calc( + var(--_track-and-knob-padding) - 2 * var(--_#{$start-or-end}-fraction) * + var(--_track-and-knob-padding) + ); + transform: translateX(var(--_x-translate)); + } + + @each $_rtl-selectors + in _get-rtl-selectors('input.#{$start-or-end}', '::-webkit-slider-thumb') + { + #{$_rtl-selectors} { + transform: translateX(calc(-1 * var(--_x-translate))); + } + } +} + @mixin styles() { $tokens: tokens.md-comp-slider-values(); @@ -430,15 +467,16 @@ $_md-sys-shape: tokens.md-sys-shape-values(); ::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; - // note, this is sized to align with thumb but is 0 width so that - // fine adjustments are possible - block-size: var(--_state-layer-size); - inline-size: var(--_state-layer-size); - transform: scaleX(0); + // note, this is sized to align with thumb + block-size: var(--_handle-height); + inline-size: var(--_handle-width); opacity: 0; z-index: 2; } + @include _get-safari-knob-translate('end'); + @include _get-safari-knob-translate('start'); + ::-moz-range-thumb { appearance: none; block-size: var(--_state-layer-size);