У меня есть пользовательская таблица, сделанная в Реагировать с Постом CSS, которую я не сделал (поэтому немного сбивает с толку. Мне нужно удалить слева и справа border .
![table](https://i.stack.imgur.com/CXOdx.png)
Я хочу удалить обе границы слева и справа (на изображении мне удалось удалить одну (красный < - ->) и просто оставьте внутренние.
Вот мой пост 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;