Несколько слайдеров пользовательского интерфейса материалов на 1 странице, разделяющих цветные реквизиты

#javascript #material-ui #slider

Вопрос:

Я создал компонент «SliderBox», который возвращает div со слайдером пользовательского интерфейса Material, реализующим createMuiTheme, и компонентом ввода.

Компонент «SliderBox» применяет метод onHover к родительскому div, который изменяет состояние цвета компонента. В принципе, я меняю цвет с красного на синий, а цвет B-с синего на красный. К сожалению, когда эта функция вызывается в одном экземпляре «SliderBox», она применяет изменение цвета к каждому «Слайдеру». Изменение цвета управляется внутри и не влияет за пределами компонента «SliderBox».

Рисунок А представляет собой представление трех компонентов «SliderBox» в их состоянии по умолчанию.Рисунок А, вид 3 компонентов quot;SliderBoxquot; в их состоянии по умолчанию.

На рисунке В показан вид трех компонентов «Слайдербокса», в то время как на самом верхнем компоненте наведен курсор. Обратите внимание, что изменение цвета, по-видимому, применяется ко всем трем компонентам «Слайдера», но не к содержащему их компоненту «Слайдербокс».На рисунке B показан вид 3 компонентов quot;SliderBoxquot;, в то время как на самом верхнем компоненте наведен курсор.

Я попытался добавить уникальные ключевые значения в оба компонента «SliderBox», которые не показали никаких изменений в поведении.

Я попытался добавить уникальное значение ключа с помощью заголовка и Math.random() в дочерний компонент «Слайдер» без каких-либо изменений.

Я попытался передать уникальное значение ключа в каждый компонент «SliderBox» с надписью «sliderKey», а затем добавил ключ как «props.sliderKey», который не показал никаких изменений в ошибочном поведении.

Я попытался отделить компонент «Слайдер» от компонента «Слайдербокс», чтобы он возвращал компонент «Пользовательский слайдер», который реализован внутри «Слайдербокса» вместо «Слайдера». Некоторые изменения замечены, например, изменение значения мерцающего цвета, но все компоненты слайдера по-прежнему имеют одинаковые значения.

Я даже добавил базовый компонент «Слайдер» в свой родительский компонент верхнего уровня, который реализует «SliderBox», и стили, применяемые к дочернему компоненту «SliderBox», также применяются к компоненту «Слайдер» в родительском компоненте компонента «SliderBox».

Предположения, основанные на моем тестировании, я пришел к предположению, что проблема связана с функцией «createMuiTheme», которая реализована в компоненте «SliderBox». Я не могу изменить «createMuiTheme», так как он обладает очень уникальным свойством в «переопределениях:MuiSlider:root:’amp; .MuiSlider-Метка значения’:’amp; *’:» Цвет фона и цвет, которые позволяют мне изменять цвет текста большого пальца, как показано на рисунках A и B. Цвет текста большого пальца является обязательным для моего веб-сайта. У меня не может быть компонента «Слайдер» с большим пальцем, на котором есть белый текст.

Мое другое предположение связано с компонентом, который возвращается из «импорта { слайдера } из» @material-ui/core»;» импорт. Одно из моих убеждений заключается в том, что «@material-ui/core» не возвращает уникальный компонент, или они могут не применять уникальные ключи к своим компонентам, что приводит к потере цвета при реализации нескольких компонентов «Слайдера».

Мои личные недостатки Я считаю, что смогу исправить это ошибочное поведение, если я реализоваю свой слайдер внутри класса JavaScript, но я никогда не использовал «компонент расширения», поэтому я буду надеяться, что другой пользователь сталкивался и решал эту проблему раньше.

Ответ №1:

Не совсем тот ответ на пользовательский интерфейс материала, который я хотел …но у меня было много негативного опыта с использованием компонентов пользовательского интерфейса материала, поэтому я пошел и создал свою собственную форму, тщетно ожидая ответа на свой вопрос.

Моя версия понятна и полностью настраиваема …Я даже реализую переменные css, о которых в большинстве сообщений говорится, что их не существует.

С этого момента я буду публиковать свой надежный код, чтобы любой мог копировать и вставлять, избегая тиранического пользовательского интерфейса материалов и их недостаточной настраиваемости.

Примечание для воинов кода: Это мой код для меня. Если вам это не нравится, мои соглашения об именах, использование крючка и т. Д., То вы более чем вольны взять его и написать свою собственную версию. Но я бы не оценил ваше мнение по этому поводу. Я делюсь своим кодом для других, кто страдает от диапазонов ввода

Примеры изображений моего компонента:: Пример Изображения 1Пример Изображения 2

SliderBar.jsx::

 import React, {useState, useEffect} from "react";
import "./SliderBar.css";

export default function SliderBar(props){
  const backgroundColor = props.backgroundColor?props.backgroundColor:"#000";
  const textColor = props.textColor?props.textColor:"#fff";
  const hoverColor = props.hoverColor?props.hoverColor:"#888";
  const initialState = props.value?props.value:0;
  const min = props.min?props.min:0;
  const max = props.max?props.max:20;
  const bubbleClassName = props.bubbleClassName?props.bubbleClassName:("SliderBar-bubble-" (Math.floor(Math.random()*100000001)));
  const bubbleSize = props.bubbleSize?props.bubbleSize:"30px";
  const cssValueChanger = {};

  const [sliderValue, sliderUpdate] = useState(initialState);
  const [textColorValue, textColorUpdate] = useState(textColor);
  const [oppositeColorValue, oppositeColorUpdate] = useState(backgroundColor);
  const [thumbColorValue, thumbColorUpdate] = useState(hoverColor)
  cssValueChanger["--color"] = props.hoverColor?props.hoverColor:thumbColorValue;

  useEffect(()=>{
    const element = document.querySelector(`.${bubbleClassName}`);

    if(element){
      const newVal = Number(((props.value?props.value:sliderValue - min) * 100) / (max - min));
      element.innerHTML = props.value?props.value:sliderValue;

      // Sorta magic numbers based on size of the native UI thumb
      element.style.left = `calc(${newVal}%   (${8 - newVal * 0.15}px))`;
    }
  });

  function onChange(event){
    sliderUpdate(event.target.value);
    if(props.onChange){
      props.onChange(event.target.value);
    }
  }

  function onMouseOver(){
    if(!props.over){
      textColorUpdate(hoverColor);
      oppositeColorUpdate(textColor);
      thumbColorUpdate(textColor);
    }
  }

  function onMouseOut(){
    if(!props.out){
      textColorUpdate(textColor);
      oppositeColorUpdate(backgroundColor);
      thumbColorUpdate(hoverColor);
    }
  }

  return(<div style={props.outerStyle}>
    <div onMouseOut={onMouseOut} onMouseOver={onMouseOver} style={{width:"200px", margin:"auto", position:"relative"}}>
      <input
        type="range"
        className="range"
        min={min}
        max={max}
        style={{
          ...cssValueChanger,
          width:"100%",
          background: props.textColor?props.textColor:textColorValue,
          color: props.backgroundColor?props.backgroundColor:oppositeColorValue,
        }}
        value={props.value?props.value:sliderValue}
        onChange={onChange}
      />
      <output
        value={props.value?props.value:sliderValue}
        className={bubbleClassName}
        style={{
          background: props.textColor?props.textColor:textColorValue,
          color: props.backgroundColor?props.backgroundColor:oppositeColorValue,
          position: "absolute",
          borderRadius: "100%",
          left: "50%",
          transform: "translateX(-50%)",
          top:"-30px",
          lineHeight:bubbleSize,
          width:bubbleSize,
          height:bubbleSize,
        }}
      />
    </div>
  </div>);
}
 

SliderBar.css::

 input[type="range"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  width: 300px;
  height: 5px;
  padding: 0;
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}

/*Chrome thumb*/

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  -moz-appearance: none;
  -webkit-border-radius: 5px;
  /*16x16px adjusted to be same as 14x14px on moz*/
  height: 16px;
  width: 16px;
  border-radius: 5px;
  background: var(--color);
  border: 1px solid var(--color);
}


/*Mozilla thumb*/

input[type="range"]::-moz-range-thumb {
  -webkit-appearance: none;
  -moz-appearance: none;
  -moz-border-radius: 5px;
  height: 14px;
  width: 14px;
  border-radius: 5px;
  background: var(--color);
  border: 1px solid var(--color);
}


/*IE amp; Edge input*/

input[type=range]::-ms-track {
  width: 300px;
  height: 6px;
  /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */
  background: transparent;
  /*leave room for the larger thumb to overflow with a transparent border */
  border-color: transparent;
  border-width: 2px 0;
  /*remove default tick marks*/
  color: transparent;
}


/*IE amp; Edge thumb*/

input[type=range]::-ms-thumb {
  height: 14px;
  width: 14px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*IE amp; Edge left side*/

input[type=range]::-ms-fill-lower {
  background: #919e4b;
  border-radius: 2px;
}


/*IE amp; Edge right side*/

input[type=range]::-ms-fill-upper {
  background: #c5c5c5;
  border-radius: 2px;
}


/*IE disable tooltip*/

input[type=range]::-ms-tooltip {
  display: none;
}

input[type="text"] {
  border: none;
}
 

SliderBox.jsx::

 import React, {useState} from "react";
import SliderBar from "./slider/SliderBar";
import "./SliderBox.css";

/***
  <SliderBox
    title={"TextValue"}
    value={"TextValue"}
    onChange={function onChange()}
    textColor={"#ffffffff"}
    backgroundColor={"#00000000"}
    hoverColor={"#ff808080"}
    min={0}
    max={20}
  />
*/
export default function SliderBox(props){
  const initialState = props.value?props.value:0;
  const backgroundColor = props.backgroundColor?props.backgroundColor:"#000";
  const textColor = props.textColor?props.textColor:"#fff";
  const hoverColor = props.hoverColor?props.hoverColor:"#888";
  const min = props.min?props.min:0;
  const max = props.max?props.max:20;

  const [sliderValue, sliderUpdate] = useState(initialState);
  const [textColorValue, textColorUpdate] = useState(textColor);
  const [oppositeColorValue, oppositeColorUpdate] = useState(backgroundColor);

  function sliderChange(event){
    sliderUpdate(event);
    if(props.onChange!==undefined){
      props.onChange(event);
    }
  }

  function inputChange(event){
    let value = event.target.value;

    value = value.replace(/^0 /, '')

    if(value===""){
      value="0";
    }
    else if(!/^d $/.test(value)){
      return;
    }

    if(value > max){
      value = max;
    }else if(value < min){
      value = min;
    }

    sliderUpdate(value);
    if(props.onChange!==undefined){
      props.onChange(value);
    }
  }

  //selected Or Blur
  function onFocusOrMouseOut(){
    textColorUpdate(textColor);
    oppositeColorUpdate(backgroundColor);
  }

  function onBlur(){
    if(sliderValue.length<1){
      sliderUpdate(0);
    }
  }

  //hover
  function onMouseOver(){
    textColorUpdate(hoverColor);
    oppositeColorUpdate(textColor);
  }

  return(<div
    onMouseOver={onMouseOver}
    onMouseOut={onFocusOrMouseOut}
    onFocus={onFocusOrMouseOut}
    onBlur={onBlur}
    style={{
      width:"200px",
      margin:"auto",
      display:"table",
      height:"50px",
      padding:"35px 20px 15px",
      border:"1px solid " textColorValue,
      borderRadius:"5px",
      position:"relative"
    }}
  >
    <p style={{
      position: "absolute",
      top: "-20px",
      margin: "0px",
      backgroundColor: backgroundColor,
      padding: "5px",
      borderRadius: "5px"
    }}>{props.title}</p>
    <SliderBar
      outerStyle={{padding:"20px", display:"table-cell"}}
      value={sliderValue}
      min={min}
      max={max}
      onChange={sliderChange}
      textColor={textColorValue}
      hoverColor={hoverColor}
      backgroundColor={oppositeColorValue}
    />
    <div
      style={{
        display:"table-cell",
        verticalAlign:"middle",
        width:"50px"
      }}
    >
      <input
        value={sliderValue}
        onChange={inputChange}
        style={{
          outline:"none",
          color:textColor,
          textAlign:"center",
          backgroundColor: backgroundColor,
          border: "1px solid " textColorValue,
          borderRadius:"5px",
          width:"30px",
          height:"30px",
          "amp;:hover :selected":{
            outline:"none",
            color:textColorValue,
            backgroundColor: backgroundColor,
            border: "1px solid " textColorValue,
          }
        }}
      />
    </div>
  </div>);
}
 

SliderBox.css

 .PrivateValueLabel-label-900{
  color: "orange";
}
.MuiSlider-root .MuiSlider-valueLabel *{
  color: green;
  background-color: red;
}
[class^="PrivateValueLabel-label-"]{
  color: red;
}