Как убрать правую и левую границы со стола, оставив только внутренние? - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть пользовательская таблица, сделанная в Реагировать с Постом CSS, которую я не сделал (поэтому немного сбивает с толку. Мне нужно удалить слева и справа border .

table

Я хочу удалить обе границы слева и справа (на изображении мне удалось удалить одну (красный < - ->) и просто оставьте внутренние.

Вот мой пост CSS код: (это своего рода пользовательская таблица )

.datatable-wrapper {
  background : #ffffff;
  min-height: 41rem;

  .filter-column{
    border-right: 1px solid var(--clear-grey);
  }

  .btn-filter_view{
    cursor: pointer;
    display: flex;
    align-items: center;
  }

  >.container {
      padding: .3rem .7rem .3rem .8rem;
  }
    .badge {
      border: 1px solid;
      border-radius: 4px;
      display: inline-flex;
      font-size: 0.75rem;
      line-height: 1.125rem;
      padding: 0.1875rem 0.6875rem 0.1875rem 0.6875rem;
      width: -moz-fit-content;
      width: fit-content;
    }

    .selected-items {
      padding-left: 1.0625rem;
      padding-right: 2.125rem;
      height : 3.5rem;
      border-radius: .25rem;
      background-color: #0f4aa1;
      font-size: 0.875rem;
      font-weight: 500;
      color: #ffffff;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .actions{
        >span:nth-child(2){
          margin-left: 3.6875rem;
        }
      }
    }
    .hidden-selected-items {
      display: none;
      overflow: hidden;
      transition: max-height 0.6s ease;
    }

    .search {
      min-height : 2.75rem;
      color : #9ea0a5;
      font-size: .75rem;
      vertical-align: middle;
      /* border: 1px solid var(--clear-grey); */
      margin-right: 5px;

      .form-group {
        min-width : 100%;
      }
      .form-control {
        color : #9ea0a5;
        font-size: .75rem;
        min-width : 100%;
        height : 100%;
      }

      .group-search{
        width:100%;
        padding-left: 1.6875rem;
        >.form-group {
          background:transparent;
          >.input-group{
            display: flex;
            flex-direction: row;
            flex-wrap: nowrap;
            justify-content: center;
            align-items: center;
            align-content: center;
            padding: .2rem;
            width: 10.875rem;
          }
        }
      }

      >.search-info {
        padding: .5rem;
        .dropdown-toggle {
          min-width : 3.5rem;
          min-height : 1.8rem;

          font-size: .75rem;
          padding-right: 1.5rem;
        }
        .dropdown-item {
          font-size: .75rem;
          height : 1.8rem;
        }
      }

      > [class^="col-xs-"] {
        /* padding: 0.5625rem 1.6875rem 0.5625rem 1.6875rem; */
        font-size: 0.875rem;
        display: flex;
        flex-direction: row;
        flex-wrap: nowrap;
        justify-content: space-between;
        align-items: center;
        align-content: stretch;
        .input-group-append {
          display: initial;
          margin-left: -1rem;
        }
        >.uikon {
          padding : .250rem;
        }

      }
    }
    .hidden-search {
      display: none;
      overflow: hidden;
      transition: max-height 0.6s ease;
    }

    .filter {
      color : #9ea0a5;
      font-size: .75rem;
      border-top: 1px solid var(--clear-grey);
      border-radius: 4px;
      padding: .5rem;

      > [class^="col-xs-12"] {

        >.filter-elements {
          display: flex;
          align-items: center;
          >.form-group {
            width: inherit;
            margin: 0 .5rem 0 0;
            .form-control {
              color : #9ea0a5;
              font-size: .75rem;
              /* min-width : 100%; */
              height : 100%;
              width: 9.375rem;
            }
            >.btn {
              position: relative;
              float: right;
              color : #9ea0a5;
              font-size: .75rem;
            }
          }

          .dropdown-toggle {
            min-height : 1.8rem;
            width: 9.375rem;
            /* width: 100%; */
            font-size: .75rem;
            padding-right: 1.5rem;
          }
          .dropdown-item {
            font-size: 0.875rem;
            height: auto;
            padding-bottom: 0.625rem;
            padding-top: 0.625rem;
          }
        }
      }
    }

    .hidden-filter {
      display: none;
      overflow: hidden;
      transition: max-height 0.6s ease;
    }


    .head {
      cursor: pointer;
      border-top: 1px solid var(--clear-grey);
      border-bottom: 1px solid var(--clear-grey);
      min-height : 2.75rem;
      color : #9ea0a5;
      font-size: 0.75rem;
      vertical-align: middle;
      width: 100%;

      > [class^="col-xs-"] {
        font-size: 0.75rem;
        display: flex;
        flex-direction: row;
        flex-wrap: nowrap;
        justify-content: flex-start;
        align-items: center;
        align-content: stretch;
        /* border-left: 1px solid var(--clear-grey); */
        border-right: 1px solid var(--clear-grey);
        padding-left: 0.93125rem;
      }
    }

    .body {
      /* min-height : 4.375rem; */
      color : #3e3f42;
      font-size: .75rem;
      vertical-align: middle;
      width: 100%;

      > [class^="col-xs-"] {
        border-right: 1px solid var(--clear-grey);
        border-bottom: 1px solid var(--clear-grey);
        padding-top: 1.5rem;
        font-size: 0.875rem;
        padding-bottom: 1.5rem;
        /* width: 7.99375rem; */
        display: flex;
        flex-direction: row;
        flex-wrap: nowrap;
        /* justify-content: flex-start; */
        padding-left: 0.93125rem;
        align-items: center;
        align-content: flex-start;
      }

      .check {
        min-height : 2.75rem;
        /* border: 1px solid var(--clear-grey); */
        display: flex;
        flex-direction: row;
        flex-wrap: nowrap;
        align-items: center;
        align-content: flex-start;
      }
    }

    .datatable {
      min-width: 100%;
      padding-right: 2.25rem;
    }
}

Вот мой .jsx код (только там, где реализована таблица ):

// @flow
import * as React from 'react';
import classnames from 'classnames';
import { t as typy } from 'typy';
import { Button, Checkbox, TextField, Select } from '@duik/it'
import Icon from '@duik/icon'
import arrowdown from '__/images/arrowdown.svg';
import { Grid, Row, Col, } from 'react-flexbox-grid';
import { Formik, Field } from 'formik';
import { DUIKSelectDate, DUIKSelect, DUIKTextField } from 'produceUI';
import { Pagination } from 'produceUI/atoms';

type Props = {
  /**
   * A simple definition of each column, so we know what will be displayed and how.
   * This requires an 'elementKey', which is they key to be used on each element of
   * the 'data' list to get and display a value. In case an 'elementKey' is not given,
   * or the 'elementKey' points to something different than a number or a string
   * 'renderCell' should be present. */
  columns: {
    className?: string,
    elementKey?: string,
    title?: string,
    invisible?: boolean,
    filterable?: boolean,
    sortable?: boolean,
    width?: number,
    selectable?: boolean,
    cols?: number,
    capitalLetters: Boolean,
    renderCell?: (element: Object, rowIndex: number, key: string) => React.Node,
    showDetail?: (element: Object, rowIndex: number, key: string) => React.Node,
  }[],
  /** Filter the data elements with this field */
  filter?: string | number,
  /** An array of JSON Objects. Nesting objects is allowed. */
  placeholderSearch?: string,
  filteredLabelForMany?: string,
  filteredLabelForOne?: string,
  data: { [string]: any },
  /** Every row needs an unique identifier. What is the key for it? */
  dataID?: string,
  /** Should it have checkboxes? */
  selectable?: boolean,
  /** Functional component to be rendered on the bottom of the table when
   * "selectable" is true AND when there is at least one selected row. The selected
   * elements are passed as a parameter so this logic is managed from the parent component.
   */
  actionsForSelected?: (elements: { [string]: any }) => React.Node,
  /** A React element to be rendered in case the data is empty */
  renderEmpty?: React.Node,

  totalPages?: number,
  currentPage?: number,
  pagesLimit?: number,
  onChangePage?: (page: number) => void,
  idToShow?: number,
  onClickDelete?: (ids: []) => void,
  handleSort?: (elementKey: string) => void,
  debounceOnSearch?: (textToFilter: string) => void,
  onFilter?: (values: object) => void,
  onClickFilter?: () => void,
  shouldFilter?: boolean,
  shouldSearch?: boolean,
};

function getID(element, key): string | number {
  const value = typy(element, key);
  return value.isString
    ? value.safeString
    : value.isNumber
      ? value.safeNumber
      : 0;
}

const Table = (props: Props) => {
  const {
    columns = [], data = [],
    placeholderSearch, filter, selectable,
    filteredLabelForMany, filteredLabelForOne,
    renderEmpty, actionsForSelected,
    dataID, idToShow,
    totalPages, currentPage, pagesLimit,
    onChangePage, onClickDelete, debounceOnSearch,
    handleSort, onFilter, onClickFilter,
    shouldFilter, shouldSearch
  } = props;

  const [selected, setSelected] = React.useState([]);
  const [dataToShow, setDataToShow] = React.useState(data);
  const [selectedId, setSelectedId] = React.useState(0);
  const [selectAll, setSelectAll] = React.useState(false);
  const [activeOption, setActiveOption] = React.useState()

  const convertPagesToArrayPages = () => {
    let idx = 1;
    let tmpArray = [];
    while (idx <= totalPages) {
      tmpArray.push({ label: `${idx}`, value: idx++ });
    }
    return tmpArray;
  };

  const arrayPages = convertPagesToArrayPages();

  React.useEffect(() => {
    const ids = data.map(d => getID(d, dataID));
    const newSelected = selected.filter(s => ids.indexOf(getID(s, dataID)));
    setDataToShow(data);
    setSelected(newSelected);
  }, [JSON.stringify(data), dataID]); // This is because the data variable is always a new one.

  React.useEffect(() => {
    setSelectedId(idToShow);
  }, [idToShow]); // This is because the data variable is always a new one.

  const filterKeys = columns.filter(col => (col.filterable)).map(col => (col.elementKey));

  const initialFilterFields = () => {
    let values = {};

    columns.map((item, index) => {
      if (item.filterable) {
        if (item.type === 'select') {
          values[item.elementKey] = item.activeElinSelect;
        } else
          values[item.elementKey] = '';
      }
    });
    return values;
  };

  const renderHeaders = () => {
    return (
      <React.Fragment>
        <Row className={selected.length > 0 ? "selected-items" : "hidden-selected-items"}>
          <Col xs={10}>
            {`${selected.length} ${selected.length > 1 ? filteredLabelForOne : filteredLabelForMany} Seleccionada(s) `}
          </Col>
          <Col xs={1}>
            {`Descargar `}
          </Col>
          <Col xs={1}>
            <a onClick={(ev) => onClickDelete(selected)} href="#"><span>Rechazar</span></a>
          </Col>
        </Row>

        <Row className={shouldFilter ? "filter" : "hidden-filter"}>
          <Col xs={12} >
            <Formik
              initialValues={initialFilterFields()}
              render={({ values }) => {
                return (
                  <div className='filter-elements'>
                    {columns.map((item, index) => {
                      if (item.filterable) {
                        return (
                          item.type === 'select' ?
                            <div className="form-group" key={`selecteFilterField_${item.elementKey}`}>
                              <Field
                                activeOption={item.activeElinSelect}
                                options={item.data}
                                id={item.elementKey}
                                name={item.elementKey}
                                placeholder={item.title}
                                component={DUIKSelect}
                              />
                            </div>
                            : item.type === 'date'
                              ?
                              <div className="form-group" key={`datedFilterField_${item.elementKey}`}>
                                <Field
                                  placeholder={item.title}
                                  format="dd/mm/yyyy"
                                  id={item.elementKey}
                                  name={item.elementKey}
                                  type='text'
                                  component={DUIKSelectDate}
                                />
                              </div>
                              :
                              <Field
                                key={`textFilterField_${index}`}
                                placeholder={item.title}
                                id={item.elementKey}
                                name={item.elementKey}
                                type='text'
                                component={DUIKTextField}
                              />
                        );
                      }
                    })
                    }
                    <div className="form-group">
                      <Button onClick={() => {
                        /* onFilter(values); */
                        /*
                          if(status !== null || PF !== null){}
                        */
                      }}>
                        Filtrar
                      </Button>
                    </div>
                  </div>
                )
              }}
            >
            </Formik>
          </Col>
        </Row>

        {/*Fila de filtro, búsqueda, etc.*/}
        <Row className={shouldSearch ? "search" : "hidden-search"}>
          {/* Filtro */}
          <Col className='filter-column' xs={1} onClick={() => { onClickFilter() }}>
            <span className='btn-filter_view'><Icon mr>view_list</Icon>Filtrar</span>
          </Col>
          {/* Búsqueda */}
          <Col xs={3}>
            <div className='group-search'>
              <TextField
                placeholder={placeholderSearch}
                rightEl={<Icon mr>search_left</Icon>}
                onChange={e => {
                  debounceOnSearch(e.target.value);
                }}
              />
            </div>
          </Col>
          <Col xs={5} xsOffset={3} className='search-info'>
            <span>
              {`${dataToShow.length <= 0 ? 'No existen datos ' : dataToShow.length} ${dataToShow.length === 1 ? filteredLabelForOne : filteredLabelForMany}`}
            </span>
            <Pagination
              pages={totalPages}
              currentPage={currentPage}
              limit={pagesLimit}
              onChange={onChangePage}
            />
            <b>Ir a página</b>
            <Select
              activeOption={arrayPages.length > 0 ? arrayPages[0] : { label: 'Seleccione opcion', value: 0 }}
              defaultOption={arrayPages.length > 0 ? arrayPages[0] : null}
              options={arrayPages}
            />
          </Col>
        </Row>

        <Row className='head'>
        {/* Checkbox maestro */}
          <Col xs={1}>
            {selectable ?
              <Checkbox
                value={selectAll}
                onChange={(ev) => {
                  const checked = typy(ev, 'target.checked').safeBoolean;
                  if (!checked) setSelected([]);
                  else {
                    let tmp = [];
                    dataToShow.map((item, index) => {
                      tmp.push(item.id);
                    })
                    setSelected(tmp);
                  }
                  setSelectAll(checked);
                }}
              /> :
              null
            }
          </Col>
          {columns.map((item, index) => {
            return (
              <Col xs={item.cols} key={`col_${index}`}
                onClick={
                  data.length > 2 ? () => handleSort(item.elementKey) : null
                }>
                {item.title}
              </Col>
            )
          })
          }
        </Row>
      </React.Fragment>
    );
  };


  const shouldShowRow = (element) => {
    if (filter) {
      return filterKeys.some((key) => {
        const field = typy(element, key);
        if (field.isNumber) return `${field.safeNumber}`.includes(`${filter}`);
        if (field.isString) return field.safeString.includes(filter);
        return false;
      });
    }
    return true;
  };

  const renderBody = () => dataToShow.reduce((accum: any[] = [], rowData, rindex) => {
    if (!shouldShowRow(rowData)) return accum;
    const cols = columns.map((col, cindex) => {
      const renderer = col.renderCell
        ? col.renderCell
        : (element, rowIndex, key) => {
          const field = typy(element, key);
          if (field.isNumber) return field.safeNumber;
          if (field.isString) return col.capitalLetters ? field.safeString.toUpperCase() : field.safeString;
          return undefined;
        };
      const content = (
        <Col xs={col.cols}
          style={{ justifyContent: col.position }}
          key={cindex}
        >
          {renderer(rowData, rindex, typy(col, 'elementKey').safeString)
          }
        </Col>
      );

      return content;
    });
    const eid = getID(rowData, dataID);
    const checkboxCell = selectable
      ? (
        <Col xs={1} className='check'>
          <div className="icon-arrow">
            <img
              onClick={() => {
                const checked = true;
                setSelectedId(eid === selectedId ? 0 : eid);
              }}
              src={arrowdown}
              className={eid === selectedId ? 'arrow_up' : 'arrow_down'}
            />
          </div>

          <Checkbox
            id={`check-${rindex}`}
            name={`check-${rindex}`}
            value={selected.indexOf(eid) > -1}
            checked={selected.indexOf(eid) > -1}
            onChange={(ev) => {
              const checked = typy(ev, 'target.checked').safeBoolean;
              if (!checked) setSelected(selected.filter(s => s !== eid));
              else if (selected.indexOf(eid) === -1) setSelected([...selected, eid]);
            }}
          />
        </Col>
      )
      : undefined;
    return [
      ...accum,
      (<Row className='body' key={rindex}>{checkboxCell}{cols}
        <div className='panel'>
          <div className={eid === selectedId ? 'showed-panel' : 'hidden-panel'}>
            {
              rowData.detailComponent
                ? (<rowData.detailComponent />)
                : ''
            }
          </div>
        </div>
      </Row>),
    ];
  }, []);

  let content = null;
  let pagination = null;

  if (data && data.length > 0) {
    content = (
      <Grid fluid>
        {renderHeaders()}
        {renderBody()}
      </Grid>
    );
  } else {
    content = (
      <Grid fluid>
        {renderHeaders()}
        {renderEmpty}
      </Grid>
    );
  }

  return (
    <div className='datatable-wrapper'>
      {content}
      {pagination}
      <div className={classnames('datatable-actions')}>
        {actionsForSelected && selected.some(t => t)
          ? actionsForSelected(data.filter(d => selected.indexOf(getID(d, dataID)) > -1))
          : null
        }
      </div>
    </div>
  );
};

Table.defaultProps = {
  filter: undefined,
  selectable: false,
  renderEmpty: undefined,
  actionsForSelected: undefined,
  dataID: 'id',
  placeholderSearch: 'Buscar',
  filteredLabelForMany: 'Elementos',
  filteredLabelForOne: 'Elemento',
  idToShow: 0,
};

export default Table;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...