Как я могу имитировать внешний вид контура и метки из выделенного текстового поля Material-UI? - PullRequest
2 голосов
/ 07 марта 2019

Я пытаюсь имитировать выделенное текстовое поле из Material-UI, но не знаю, как скрыть границу за текстом заголовка.

На изображении ниже обратите внимание на то, как «Дата / Время исполнения» берется из библиотеки Material-UI, а заголовок скрывает границу за ним, но когда я попытался имитировать его с помощью пользовательского компонента, я просто не смог скрыть граница.

В качестве альтернативы, есть ли лучший способ использовать этот эскизный проект вместо простой реализации его с помощью CSS?

Мой текущий компонент выглядит так:

<div style={inputContainerStyle}>
        <div style={{
          ...titleStyle,
          transform: 'translate(-43px, -11px) scale(0.75)',
          fontSize: '17px',
          color: 'rgba(0, 0, 0, 0.54)',
          position: 'absolute',
        }}
        >
          Color
        </div>
        <div
          className="flex-row"
          style={{
            border: '1px solid rgba(0, 0, 0, 0.23)',
            padding: '18.5px 14px',
            borderRadius: '4px',
          }}
        >
          {
            availableColors.map(color => <div style={colorCircleStyle(color)} />)
          }
        </div>
      </div>

Ответы [ 3 ]

2 голосов
/ 07 марта 2019

Существует большая гибкость в том, что вы можете сделать с TextField. TextField поддерживает подключение к различным типам входов (например, Select, input, пользовательские средства выбора) через свойство inputComponent. Вы можете использовать это, чтобы поместить что-либо в помеченный контур, создав специальный компонент, подобный этому OutlinedDiv:

import React from "react";

import TextField from "@material-ui/core/TextField";

const InputComponent = ({ inputRef, ...other }) => <div {...other} />;
const OutlinedDiv = ({ children, label }) => {
  return (
    <TextField
      variant="outlined"
      label={label}
      multiline
      InputLabelProps={{ shrink: true }}
      InputProps={{
        inputComponent: InputComponent
      }}
      inputProps={{ children: children }}
    />
  );
};
export default OutlinedDiv;

className, переданный inputComponent, заботится о CSS, который заставляет все это работать. Затем вы можете использовать это следующим образом:

import React from "react";
import ReactDOM from "react-dom";

import OutlinedDiv from "./OutlinedDiv";
import Avatar from "@material-ui/core/Avatar";
import deepOrange from "@material-ui/core/colors/deepOrange";
import deepPurple from "@material-ui/core/colors/deepPurple";
import red from "@material-ui/core/colors/red";
import green from "@material-ui/core/colors/green";
import blue from "@material-ui/core/colors/blue";
import Grid from "@material-ui/core/Grid";

function App() {
  return (
    <div className="App">
      <OutlinedDiv label="Color Picker">
        <Grid container justify="center" alignItems="center">
          <Avatar style={{ backgroundColor: deepOrange[500] }} />
          <Avatar style={{ backgroundColor: deepPurple[500] }} />
          <Avatar style={{ backgroundColor: red[500] }} />
          <Avatar style={{ backgroundColor: green[500] }} />
          <Avatar style={{ backgroundColor: blue[500] }} />
        </Grid>
      </OutlinedDiv>
      <br />
      <br />
      <OutlinedDiv label="Custom Outlined Thing">
        You can put whatever you want in here.
      </OutlinedDiv>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit Custom Outlined Component

0 голосов
/ 08 марта 2019

Выделенное текстовое поле было действительно сложно реализовать.При нажатии на эту функцию нам пришлось рассмотреть несколько вариантов, каждый из которых имел свои недостатки

  1. Элемент SVG

Легко создавать и анимировать, но сложно масштабировать с окружающимэлементы.Если бы мы пошли по этому пути, нам нужно было бы прослушивать какое-либо событие изменения размера, что означало бы либо использование события изменения размера окна, которое не является надежным, либо использование более новой и менее поддерживаемой функции, такой как ResizeObserver / MutationObserver.Существуют полифилы, но это увеличило бы размер пакета примерно на 2 КБ для относительно небольшой функции.

Вероятно, что в будущем будет использоваться маршрут SVG.Также стоит отметить, что именно так Google Material Components Web решает эту проблему.

Обычная старая рамка с фоном на ярлыке

Это, безусловно, самый простой подход, но он также несколько негибкий.Вы можете увидеть пример этого в новом потоке входа в Google.Там они фактически устанавливают цвет фона на белый.Это, вероятно, хороший подход для большого количества пользователей, но, конечно, не сработает, если ваш фон имеет градиент или какой-то подобный крайний случай.Тем не менее, не нужно беспокоиться об изменении размера, потому что это просто граница.

Fieldset и легенды

Это то, чем мы закончили, во многом благодаря его гибкости для конечных пользователей.Fieldset и его компонент легенды являются встроенными способами достижения в значительной степени этой точной функциональности.Большой недостаток этого заключается в том, что стилизация в разных браузерах жесткая, а свойства, которые мы будем анимировать, не эффективны, такие как ширина легенды.Кроме того, всегда лучше использовать семантический HTML, конечно, это не так, что означает, что нам нужно использовать aria-hidden, чтобы указывать программам чтения с экрана игнорировать элемент.

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

0 голосов
/ 07 марта 2019

Просто примените тот же цвет фона к color div , как родительский цвет фона , вы можете сделать это с помощью background-color: наследовать как это:

<div style={inputContainerStyle}>
        <div style={{
          ...titleStyle,
          transform: 'translate(-43px, -11px) scale(0.75)',
          fontSize: '17px',
          color: 'rgba(0, 0, 0, 0.54)',
          position: 'absolute',
          background-color:'inherit' **(just add this line)**
        }}
        >
          Color
        </div>
        <div
          className="flex-row"
          style={{
            border: '1px solid rgba(0, 0, 0, 0.23)',
            padding: '18.5px 14px',
            borderRadius: '4px',
          }}
        >
          {
            availableColors.map(color => <div style={colorCircleStyle(color)} />)
          }
        </div>
      </div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...