反应 css 网格或从样式组件到 css 的转换问题?有点不知所措

react css grid or conversion from styled-components to css issue? a little overwhelmed

我尝试将 Glad Chinda 的 great react datepicker/calendar component 3/5 pages ((x)DatePicker, (x)DatePickerStyle, Calendar, CalendarStyle, Helpers) 组合成一个组件,这样我就可以使用自己的按钮来切换月份。

我还没有使用过 proptypes、styledcomponents(所以我把它变成了 css 文件)或辅助概念 - 我无法判断错误是否与这三个中的任何一个有关。

import React from "react";
import "./FullCalBackdrop.css";
import "./CalendarStyle.css";
import PropTypes from "prop-types";

export const THIS_YEAR = +(new Date().getFullYear());
export const THIS_MONTH = +(new Date().getMonth()) + 1;

export const WEEK_DAYS = {
    Sunday: "Sun",
    Monday: "Mon",
    Tuesday: "Tue",
    Wednesday: "Wed",
    Thursday: "Thu",
    Friday: "Fri",
    Saturday: "Sat"
}

export const CALENDAR_MONTHS = {
    January: "Jan",
    February: "Feb",
    March: "Mar",
    April: "Apr",
    May: "May",
    June: "Jun",
    July: "Jul",
    August: "Aug",
    September: "Sep",
    October: "Oct",
    November: "Nov",
    December: "Dec"
}

export const CALENDAR_WEEKS = 6;

export const zeroPad = (value, length) => `${value}`.padStart(length, '0')

export const isDate = date => {
    const isDate = Object.prototype.toString.call(date) === '[object Date]';
    const isValidDate = date && !Number.isNaN(date.valueOf());
    return isDate && isValidDate;
}

export const getDateISO = (date = new Date) => {
    if (!isDate(date)) return null;

    return [
        date.getFullYear(),
        zeroPad(+date.getMonth() + 1, 2),
        zeroPad(+date.getDate(), 2)
    ].join('-');
}

export const getMonthDays = (month = THIS_MONTH, year = THIS_YEAR) => {
    const months30 = [4, 6, 9, 11];
    const leapYear = year % 4 === 0;

    return month === 2
        ? leapYear
            ? 29
            : 28
        : months30.includes(month)
            ? 30
            : 31;
}

export const getMonthFirstDay = (month = THIS_MONTH, year = THIS_YEAR) => {
    return +(new Date(`${year}-${zeroPad(month, 2)}-01`).getDay()) + 1;
}

export const isSameMonth = (date, basedate = new Date()) => {
    if (!(isDate(date) && isDate(basedate))) return false;

    const basedateMonth = +(basedate.getMonth()) + 1;
    const basedateYear = basedate.getFullYear();

    const dateMonth = +(date.getMonth()) + 1;
    const dateYear = date.getFullYear();

    return (+basedateMonth === +dateMonth) && (+basedateYear === +dateYear);
}

export const isSameDay = (date, basedate = new Date()) => {
    if (!(isDate(date) && isDate(basedate))) return false;

    const basedateDate = basedate.getDate();
    const basedateMonth = +(basedate.getMonth()) + 1;
    const basedateYear = basedate.getFullYear();

    const dateDate = date.getDate();
    const dateMonth = +(date.getMonth()) + 1;
    const dateYear = date.getFullYear();

    return (+basedateDate === +dateDate) && (+basedateMonth === +dateMonth) && (+basedateYear === +dateYear);
}

export const getPreviousMonth = (month, year) => {
    const prevMonth = (month > 1) ? month - 1 : 12;
    const prevMonthYear = (month > 1) ? year : year - 1;

    return { month: prevMonth, year: prevMonthYear };
}

export const getNextMonth = (month, year) => {
    const nextMonth = (month < 12) ? month + 1 : 1;
    const nextMonthYear = (month < 12) ? year : year + 1;

    return { month: nextMonth, year: nextMonthYear };
}

export const calendar = (month = THIS_MONTH, year = THIS_YEAR) => {
    const monthDays = getMonthDays(month, year);
    const monthFirstDay = getMonthFirstDay(month, year);

    const daysFromPrevMonth = monthFirstDay - 1;
    const daysFromNextMonth = (CALENDAR_WEEKS * 7) - (daysFromPrevMonth + monthDays);

    const { month: prevMonth, year: prevMonthYear } = getPreviousMonth(month, year);
    const { month: nextMonth, year: nextMonthYear } = getNextMonth(month, year);

    const prevMonthDays = getMonthDays(prevMonth, prevMonthYear);

    const prevMonthDates = [...new Array(daysFromPrevMonth)].map((n, index) => {
        const day = index + 1 + (prevMonthDays - daysFromPrevMonth);
        return [ prevMonthYear, zeroPad(prevMonth, 2), zeroPad(day, 2) ];
    });

    const thisMonthDates = [...new Array(monthDays)].map((n, index) => {
        const day = index + 1;
        return [year, zeroPad(month, 2), zeroPad(day, 2)];
    });

    const nextMonthDates = [...new Array(daysFromNextMonth)].map((n, index) => {
        const day = index + 1;
        return [nextMonthYear, zeroPad(nextMonth, 2), zeroPad(day, 2)];
    });

    return [ ...prevMonthDates, ...thisMonthDates, ...nextMonthDates ];
}

class FullCalSlideDrawer extends React.Component {
  state = {
    date: null,
    calendarOpen: false,
    ...this.resolveStateFromProp(),
    today: new Date()
  };

  toggleCalendar = () =>
    this.setState({ calendarOpen: !this.state.calendarOpen });

  handleChange = evt => evt.preventDefault();

  handleDateChange = date => {
    const { onDateChanged } = this.props;
    const { date: currentDate } = this.state;
    const newDate = date ? getDateISO(date) : null;

    currentDate !== newDate &&
      this.setState({ date: newDate, calendarOpen: false }, () => {
        typeof onDateChanged === "function" && onDateChanged(this.state.date);
      });
  };
  resolveStateFromDate(date) {
    const isDateObject = isDate(date);
    const _date = isDateObject ? date : new Date();

    return {
      current: isDateObject ? date : null,
      month: +_date.getMonth() + 1,
      year: _date.getFullYear()
    };
  }

  resolveStateFromProp() {
    return this.resolveStateFromDate(this.props.date);
  }

  getCalendarDates = () => {
    const { current, month, year } = this.state;
    const calendarMonth = month || +current.getMonth() + 1;
    const calendarYear = year || current.getFullYear();

    return calendar(calendarMonth, calendarYear);
  };

  gotoDate = date => evt => {
    evt && evt.preventDefault();
    const { current } = this.state;
    const { onDateChanged } = this.props;

    !(current && isSameDay(date, current)) &&
      this.setState(this.resolveStateFromDate(date), () => {
        typeof onDateChanged === "function" && onDateChanged(date);
      });
  };

  gotoPreviousMonth = () => {
    const { month, year } = this.state;
    this.setState(getPreviousMonth(month, year));
  };

  gotoNextMonth = () => {
    const { month, year } = this.state;
    this.setState(getNextMonth(month, year));
  };

  gotoPreviousYear = () => {
    const { year } = this.state;
    this.setState({ year: year - 1 });
  };

  gotoNextYear = () => {
    const { year } = this.state;
    this.setState({ year: year + 1 });
  };

  handlePressure = fn => {
    if (typeof fn === "function") {
      fn();
      this.pressureTimeout = setTimeout(() => {
        this.pressureTimer = setInterval(fn, 100);
      }, 500);
    }
  };

  clearPressureTimer = () => {
    this.pressureTimer && clearInterval(this.pressureTimer);
    this.pressureTimeout && clearTimeout(this.pressureTimeout);
  };

  clearDayTimeout = () => {
    this.dayTimeout && clearTimeout(this.dayTimeout);
  };

  handlePrevious = evt => {
    evt && evt.preventDefault();
    const fn = evt.shiftKey ? this.gotoPreviousYear : this.gotoPreviousMonth;
    this.handlePressure(fn);
  };

  handleNext = evt => {
    evt && evt.preventDefault();
    const fn = evt.shiftKey ? this.gotoNextYear : this.gotoNextMonth;
    this.handlePressure(fn);
  };

  renderMonthAndYear = () => {
    const { month, year } = this.state;
    const monthname = Object.keys(CALENDAR_MONTHS)[
      Math.max(0, Math.min(month - 1, 11))
    ];

    return (
      <div className="CalendarHeader">
        <div className="CalendarMonth">
          {monthname} {year}
        </div>
      </div>
    );
  };

  renderDayLabel = (day, index) => {
    const daylabel = WEEK_DAYS[day].toUpperCase();
    return (
      <div className="CalendarDay" key={daylabel} index={index}>
        {daylabel}
      </div>
    );
  };

  renderCalendarDate = (date, index) => {
    const { current, month, year, today } = this.state;
    const _date = new Date(date.join("-"));

    const isToday = isSameDay(_date, today);
    const isCurrent = current && isSameDay(_date, current);
    const inMonth =
      month && year && isSameMonth(_date, new Date([year, month, 1].join("-")));

    const onClick = this.gotoDate(_date);

    const props = { index, inMonth, onClick, title: _date.toDateString() };

    return (
      <div className={isCurrent ? "HighlightedCalendarDate" : isToday ? "TodayCalendarDate" : "CalendarDate"} key={getDateISO(_date)} {...props}>
        {_date.getDate()}
      </div>
    );
  };
  componentDidMount(date) {
    //const { value: date } = this.props;
    const newDate = date && new Date(date);
    isDate(newDate) && this.setState({ date: getDateISO(newDate) });

    const now = new Date();
    const tomorrow = new Date().setHours(0, 0, 0, 0) + 24 * 60 * 60 * 1000;
    const ms = tomorrow - now;

    this.dayTimeout = setTimeout(() => {
      this.setState({ today: new Date() }, this.clearDayTimeout);
    }, ms);
  }

  componentDidUpdate(prevProps) {
    const { value: date } = this.props;
    const { value: prevDate } = prevProps;
    const dateISO = getDateISO(new Date(date));
    const prevDateISO = getDateISO(new Date(prevDate));
    dateISO !== prevDateISO && this.setState({ date: dateISO });

    //const { date: prevDate } = prevProps;
    const dateMatch = date == prevDate || isSameDay(date, prevDate);
    !dateMatch &&
      this.setState(this.resolveStateFromDate(date), () => {
        typeof onDateChanged === "function" && onDateChanged(date);
      });
  }

  componentWillUnmount() {
    this.clearPressureTimer();
    this.clearDayTimeout();
  }

  render() {
    const date = this.state;
    return (
      <div
        className={
          this.props.show1
            ? "fullcal_slide-drawer open"
            : "fullcal_slide-drawer"
        }
      >
        <div>
            <div className="CalendarContainer">
              {this.renderMonthAndYear()}

              <div className="CalendarGrid">
                <div>
                  {Object.keys(WEEK_DAYS).map(this.renderDayLabel)}
                </div>

                <div>
                  {this.getCalendarDates().map(this.renderCalendarDate)}
                </div>
              </div>
            </div>
        </div>
        <div className="monthlyskip">
          <div
            className="weeklylcal"
            onClick={this.handlePrevious}
            onMouseUp={this.clearPressureTimer}
          >
            Last
            <br />
            Month
          </div>
          <div className="closecal" onClick={this.props.close}>
            Close
          </div>
          <div
            className="weeklyrcal"
            onClick={this.handleNext}
            onMouseUp={this.clearPressureTimer}
          >
            Next
            <br />
            Month
          </div>
        </div>
      </div>
    );
  }
}

FullCalSlideDrawer.propTypes = {
  date: PropTypes.instanceOf(Date),
  label: PropTypes.string,
  value: PropTypes.string,
  onDateChanged: PropTypes.func
};

export default FullCalSlideDrawer;

CalendarStyle.css

.CalendarContainer {
    font-size: 5px;
    border: 2px solid #06c;
    border-radius: 5px;
    overflow: hidden;
}

.CalendarHeader {
  display: flex;
    align-items: center;
    justify-content: space-between;
}

.CalendarGrid {
  display: inline-grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}

.CalendarMonth {
  font-weight: 500;
    font-size: 5em;
    color: #06c;
    text-align: center;
    padding: 0.5em 0.25em;
    word-spacing: 5px;
    user-select: none;
}

.CalendarCell {
  text-align: center;
    align-self: center;
  height: 9.5vw;
    letter-spacing: 0.1rem;
    padding: 0.6em 0.25em;
  user-select: none;
  grid-column:12vw;
  /*grid-column: ${props => (props.index % 7) + 1} / span 1;*/
}

.CalendarDay {
  font-weight: 600;
    font-size: 2.25em;
    color: #06c;
    border-top: 2px solid #06c;
  border-bottom: 2px solid #06c;
    /*border-right: ${props => (props.index % 7) + 1 === 7 ? `none` : `2px solid #06c`};*/
}

.CalendarDate {
  /*font-weight: ${props => props.inMonth ? 500 : 300};*/
    font-size: 4em;
    cursor: pointer;
    /*border-bottom: ${props => ((props.index + 1) / 7) <= 5 ? `1px solid #ddd` : `none`};
    border-right: ${props => (props.index % 7) + 1 === 7 ? `none` : `1px solid #ddd`};
    color: ${props => props.inMonth ? `#333` : `#ddd`};
  grid-row: ${props => Math.floor(props.index / 7) + 2} / span 1;*/
  grid-row:12vw;
    transition: all .4s ease-out;
    :hover {
        color: #06c;
        background: rgba(0, 102, 204, 0.075);
}

.HighlightedCalendarDate {
  color: #fff !important;
    background: #06c !important;
    position: relative;
    ::before {
        content: '';
        position: absolute;
        top: -1px;
        left: -1px;
        width: calc(100% + 2px);
        height: calc(100% + 2px);
        border: 2px solid #06c;
    }
}

.TodayCalendarDate {
  color: #06c !important;
    background: transparent !important;
    ::after {
        content: '';
        position: absolute;
        right: 0;
        bottom: 0;
        border-bottom: 0.75em solid #06c;
        border-left: 0.75em solid transparent;
        border-top: 0.75em solid transparent;
    }
    :hover {
        color: #06c !important;
        background: rgba(0, 102, 204, 0.075) !important;
    }
}

转到 https://1c31n.csb.app/planner,单击左上角的徽标图标,然后单击左上角的日历图标,看看它(以及之后的任何改进)正在呈现什么

带着格子进去

首先div(星期日星期一...)和第二个添加:

display: grid;
grid-template-columns: repeat(7, 1fr);

你可以玩这个,如果你有别的意思,请告诉我。

还有一个不错的网格游戏(https://cssgridgarden.com)