Material-ui: [Tabela] Definir a largura da coluna da tabela

Criado em 19 out. 2015  ·  54Comentários  ·  Fonte: mui-org/material-ui

É possível definir a largura das colunas da tabela?

DataGrid question

Comentários muito úteis

Na minha tabela HTML vanilla, a largura das colunas é definida automaticamente, dependendo do conteúdo. material-ui parece impor largura igual em todas as colunas. Existe uma maneira de definir a largura da coluna para ser dinâmico, como tabelas HTML vanilla?

Todos 54 comentários

+1

Nada muito especial sobre isso:

const colWidth {
    width: '2rem'
};

<TableRowColumn style={ colWidth }>
    ...
</TableRowColumn>
<TableRowColumn style={{ width: 100 }}>

não se comporta muito bem com TableHeaderColumn

Existe alguma maneira de atribuir dinamicamente a largura da coluna com base no conteúdo?

Na minha tabela HTML vanilla, a largura das colunas é definida automaticamente, dependendo do conteúdo. material-ui parece impor largura igual em todas as colunas. Existe uma maneira de definir a largura da coluna para ser dinâmico, como tabelas HTML vanilla?

@sanfilippopablo , <Table> usa o prop table-layout: 'fixed' css, levando a todas as colunas com a mesma largura, combinado com white-space: 'nowrap' em cada célula da tabela para lidar com o estouro.

Você não pode mudar com segurança para table-layout: 'auto' já que a tabela então cresce infinitamente com seu conteúdo, a menos que você remova o css prop de espaço em branco mencionado acima. E se você fizer isso,
você não pode mais usar o fixedHeader={true} prop, pois os cabeçalhos estão contidos em uma tabela separada: cry :

Agradecemos algum feedback.

O que venho fazendo para definir as larguras das colunas é para o

estilo, defina o layout da tabela como automático, como mencionado acima, então eu dou larguras em porcentagens para minhas colunas. ielargura 30% elargura 70%. Este seria um exemplo de layout de duas colunas, com colunas de cabeçalho de tabela na primeira coluna em vez de no cabeçalho.

Você não pode mudar com segurança para o layout da tabela: 'auto', uma vez que a tabela então cresce infinitamente com seu conteúdo

Que tal ajustar a largura do cabeçalho da tabela quando a largura da tableRowColumn muda com o conteúdo?
Não consigo configurá-lo para que os 2 estejam alinhados.

Eu acho que você usa fixedHeader={true} e não pode definir uma largura personalizada ou não e tem que manter seus cabeçalhos dentro de <TableBody> .

Ok, colocar o cabeçalho em tbody funciona! Agora preciso descobrir como fazer colunas de cabeçalho de várias linhas. Alguma dica?

Você está tentando conseguir algo parecido com isso ? (se não, você provavelmente pode encontrar o exemplo certo neste site)

Acho que você pode fazer praticamente tudo o que quiser com os atributos colSpan em TableHeaderColumn e TableRowColumn e rowSpan em TableRow .

Eu não entendo - por que isso está fechado?

Colocar TableHeader em TableBody não funciona para mim.

@ tvtri96
O que sugerimos foi colocar tableRow atuando como cabeçalho da tabela em tableBody,
mas parece que agora está funcionando bem.

é assim que parece agora no meu código:

<Table fixedHeader={true}>
          <TableHeader>
            <TableHeaderComponent schema={schema}/>
          </TableHeader>
          <TableBody displayRowCheckbox={false} showRowHover={true}>
            {this.props.data.map((item, index) => (
              <TableRowComponent key={index} schema={this.props.schema}
                item={item} onRemoveClick={this.handleRemoveItem}
                onEditClick={this.handleEditItem}
              />
            ))}
          </TableBody>
</Table>

e as colunas de cabeçalho estão alinhadas com as colunas do corpo corretamente.

Obrigado por me responder. O que está dentro de TableHeaderComponent? Eu acho que não é como um TableHeader normal, certo?
`` `

Timestamp

Sim, está embrulhado apenas por razões.

Alguma novidade sobre isso? Como posso deixar as colunas se ajustarem automaticamente ao conteúdo?

Isso funciona para mim, dimensionamento automático:

      <Table style={{tableLayout: 'auto'}}>

@arjan

 <Table style={{tableLayout: 'auto'}}>

Isso não tem efeito no cabeçalho.

<Table fixedHeader={false} style={{ tableLayout: 'auto' }}> funciona (dimensionamento dinâmico com base no conteúdo).

Eu precisava adicionar width: "auto" , o que resulta em:

<Table fixedHeader={false} style={{ width: "auto", tableLayout: "auto" }}>

@nathanmarks , reabra.

Table deve ter uma propriedade incorporada para permitir que ele seja dimensionado automaticamente para o conteúdo e não deve exigir a desativação de fixedHeader . Eu iria além e diria que o tamanho automático do conteúdo deve ser o comportamento padrão.

@devuxer Desculpe, mas não estamos adicionando recursos proativamente ao branch v0.x.

@mbrookes , Obrigado por nos informar. Você está dizendo que a tabela na v1.x resolve esse problema?

@devuxer Eu acredito que sim, foi reescrito do zero.

https://material-ui-next.com/demos/tables/

Eu tinha uma tabela com três colunas, onde a primeira e a terceira colunas sempre conteriam uma pequena quantidade de texto. Eu queria que a segunda coluna ocupasse a maior parte do espaço, de forma que a primeira e a terceira colunas fossem empurradas para as bordas esquerda e direita da tabela, respectivamente. Isso funcionou para mim (usando style aqui em vez de className por brevidade):

<Table style={{ tableLayout: "auto" }} />
<TableRowColumn style={{ width: "10%" }}>{text}</TableRowColumn>
<TableRowColumn style={{ width: "80%" }}>{text}</TableRowColumn>
<TableRowColumn style={{ width: "10%" }}>{text</TableRowColumn>

Achei uma solução melhor ... então, todas as colunas têm a mesma largura.
Digamos que eu tenha três colunas e quero que a primeira ocupe metade da largura total e a terceira ocupe cerca de um terço da linha; o do meio seja o menor:

  <TableRowColumn colSpan='3'>twice as big!</TableRowColumn>
  <TableRowColumn> I'm small</TableRowColumn>
  <TableRowColumn colSpan='2'>I'm in between</TableRowColumn>

Na verdade, eu tenho 7 colunas, mas a soma de meus colspans é igual a 20 - a última contém apenas um ícone para exclusão, a maioria dos outros são colspan 3 - o campo de texto grande é colspan 6, e um selectfield e um datepicker são no colspan 2 ...

Funciona como um encanto!

Isso é bom para ir na v1.4.3

const styles = { 
    narrowCell: {
        'width': '150px',
    }
};

<Table>
    <TableHead>
        <TableRow>
            <TableCell>Company Name</TableCell>
            <TableCell className={classes.narrowCell} numeric>Amount</TableCell>
        </TableRow>
    </TableHead>
    <TableBody>
    <TableRow>
        <TableCell> name 1 </TableCell>
        <TableCell className={classes.narrowCell}> $100 </TableCell>
    </TableRow>
    </TableBody>
</Table>


Também pode fornecer larguras percentuais, o resto das células se estendem igualmente

Como posso usar esta solução se preciso usar colspan={2} em uma linha TableHead?

Se eu adicionar colspan={2} todas as colunas terão a mesma largura. Algo assim:

const styles = { 
    narrowCell: {
        'width': '150px',
    },
    miniCell: {
        'width': '75px',
    },
};

<Table>
    <TableHead>
        <TableRow>
            <TableCell>Company Name</TableCell>
            <TableCell className={classes.narrowCell} numeric colspan={2}>Amounts</TableCell>
        </TableRow>
    </TableHead>
    <TableBody>
    <TableRow>
        <TableCell> name 1 </TableCell>
        <TableCell className={classes.miniCell}> $100 </TableCell>
        <TableCell className={classes.miniCell}> $100 </TableCell>
    </TableRow>
    </TableBody>
</Table>

@Bowfish Se você deseja alterar colspan = {2} a largura da célula, tente alterar a largura da tabela, pois ela abrange toda a tabela. As células menores podem ser ajustadas individualmente.

Aplicar este estilo de alguma forma me ajudou:
Eu apenas sentei diferentes maxWidth para diferentes cels na linha, mas o mesmo em cada coluna usando estilos embutidos.

const styles = (theme) => ({
  tableCell: {
    whiteSpace: 'nowrap',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    maxWidth: '40px',
  },
});

Nenhuma das soluções postadas acima funciona. Por que isso é tão difícil de conseguir?

  <Table fixedHeader={false} style={{tableLayout: "auto" }}>
        <colgroup>
            <col width="250px" />
            <col />
            <col width="40px" />
            <col width="40px" />
        </colgroup>
        <TableHead>
          <TableRow>

a segunda coluna é flexível

Não tenho certeza se alguém ainda está tendo problemas com isso, mas acabei usando withStyles e funcionou aqui está o pseudo Código:

import {withStyles} from '@material-ui/core/styles';  

const styles = theme => ({
    cell: {
        width:'20%'
    },
    cellLarge: {
        width:'60%'
    } 
});

<Table >
       <TableHead>
               <TableRow>
                        <TableCell className={this.props.classes.cell}>header 1</TableCell>
                         <TableCell className={this.props.classes.cell}>header 2</TableCell>
                         <TableCell className={this.props.classes.cellLarge}>header 3</TableCell>
                </TableRow>
          </TableHead>
                <TableBody>
                        <TableRow>
                            <TableCell>value 1</TableCell>
                            <TableCell>value 2</TableCell>
                            <TableCell>value 3</TableCell>
                        </TableRow>
               </TableBody>
   </Table>

export default withStyles(styles)({ComponentName})

Nenhuma das soluções postadas acima funciona. Por que isso é tão difícil de conseguir?

De alguma forma, eu reconheço por que não funciona, porque definimos apenas width apenas para TableHead ou TableBody ! Para fazer funcionar, devemos definir minWidth e maxWidth bot em TableCell em TableHead e TableBody , aqui o exemplo

<Table>
    <TableHead>
        <TableRow>
            <TableCell column='data1' style={{minWidth:100, maxWidth:100}}>{content}</TableCell>
            <TableCell column='data2' style={{minWidth:'200px', maxWidth:'200px'}}>{content}</TableCell>
        </TableRow>
    </TableHead>
    <TableBody>
            <TableRow>
            <TableCell column='data1' style={{minWidth:100, maxWidth:100}}>{content}</TableCell>
            <TableCell column='data2' style={{minWidth:200, maxWidth:200}}>{content}</TableCell>
            </TableRow>
    </TableBody>
</Table>

Como você pode ver, podemos usar ambos os valores para o estilo por inteiro e string. Mas para string, só funciona se você definir por px , se você usar porcentagem, como minWidth:'25%' , não vai funcionar , eu já experimentei.

Por que eu uso minWidth e maxWidth ? Não é width ? Porque eu já experimentei, se você quiser fazer sua coluna com largura fixa, você deve usar minWidth e maxWidth invés de width . Eu não sabia por que, mas width parece não funcionar para resolver este problema.

Nota: _Ambos de TableCell em TableHead e TableBody que contêm os mesmos dados , devem ter o mesmo estilo ! _

Espero que este código ajude vocês, pessoal

Eu literalmente defini largura: 10%, minWidth: 10% e maxWidth: 10% para cada TableCell, incluindo aquelas sob os cabeçalhos da tabela. Em seguida, comecei a criar <colgroup>..etc elementos e apliquei os mesmos estilos a eles também. Eu também defino o elemento Table como tableLayout: auto e width: auto. Eu tentei todas as soluções neste tópico e combinei todas para este resultado final. além disso, também usei a ferramenta "inspecionar elemento" no cromo e cortei cada elemento da mesa para usar a largura: 10% largura mínima: 10% e largura máxima: 10%. isso também se refletiu no inspetor React em devtools. literalmente me mostrou todos os elementos ive alterados como "largura 10%" etc.

resultado: ainda não ajusta a largura das colunas

Acho que agora é seguro presumir que realmente existe um impossível. e está neste mesmo tópico

Editar:

Na verdade, acabei fazendo algo que ia contra o que as pessoas neste tópico estavam sugerindo ... configurei autoLayout: consertado em minha tabela e começou a funcionar. O que no mundo é essa magia negra

Também está tendo problemas para definir larguras. Tive que definir a largura da caixa de seleção: 0,01% para ficar em uma largura razoável, nada mais funciona

Para aqueles que estão presos na versão antiga e lutando com o rodapé, adicionar fixedFooter = {false} à solução de

@nathanmarks Você pode pelo menos esclarecer porque fechou isso?
Este deve ser um recurso obrigatório muito recorrente.

@pbassut está certo. Este é um recurso muito básico para um componente de tabela ... Existe alguma atualização?
Ou uma explicação de por que é tão problemático implementar ...

@devenovil Em vez de maxWidth , se quiser usar % , você pode usar width como:

<TableCell style={{ width: '35%' }}>
  Table Data
</TableCell>
<TableCell>
  Another Table Data
</TableCell>

Para mim funcionou definir a largura apenas para as células no cabeçalho: <TableCell width={props.colWidths[index] + '%'}> , isso resulta nas colunas de toda a tabela se comportando conforme o esperado.

Eu defino as larguras das colunas com a porcentagem e meio que funciona, mas por algum motivo, ele adiciona uma coluna fantasma na extrema direita. Ao inspecionar o elemento, parece adicionar um elemento "TableStubCell" à tabela. Não tenho ideia de onde isso veio.

Tive problemas semelhantes com outras tabelas MUI e minhas soluções alternativas nunca são tão boas. Seria legal se vocês abrissem esse problema e o corrigissem ... claramente outras pessoas estão lutando com isso também.

editar: o TableStubCell veio do pacote dx-react-grid-material-ui npm, desculpe por apontar dedos!

Minha solução é fazer

<Table>
  <TableHeader>
    <TableRow>
      <TableCell>
        <Box width="200px">
          User Fullname
        </Box>
      </TableCell>
      {/* ...rest of the columns */}
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>
        April Mintac Pineda
      </TableCell>
      {/* ...rest of the columns */}
    </TableRow>
    {/* ...rest of the rows */}
  </TableBody>
</Table>

Mas seria bom se pudéssemos apenas fazer

<Table>
  <TableHeader>
    <TableRow>
      <TableCell width="200px">
        User Fullname
      </TableCell>
      {/* ...rest of the columns */}
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>
        April Mintac Pineda
      </TableCell>
      {/* ...rest of the columns */}
    </TableRow>
    {/* ...rest of the rows */}
  </TableBody>
</Table>

Isso funciona para mim com a versão "@material-ui/core": "4.9.0"

<TableContainer className={classes.container}>
          <Table className={classes.table} stickyHeader size="small">
            <TableHead>
              <TableRow>
                <TableCell width="30%">User Name</TableCell>
                <TableCell width="20%">Designation</TableCell>
                <TableCell width="10%">Nid</TableCell>
                <TableCell width="20%">Email</TableCell>
                <TableCell width="10%">Mobile</TableCell>
                <TableCell width="10%">Gender</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {props.isGridLoading && (
                <TableRow>
                  <TableCell colSpan={6}>
                    <LoadingGridSpinner open={props.isGridLoading} />
                  </TableCell>
                </TableRow>
              )}

              {props.profileObj.lists &&
                props.profileObj.lists.map(row => (
                  <TableRow key={row.userProfileId} hover={true}>
                    <TableCell width="30%">
                      {row.userName}
                    </TableCell>
                    <TableCell width="20%">{row.designation}</TableCell>
                    <TableCell width="10%">{row.nid}</TableCell>
                    <TableCell width="20%">{row.email}</TableCell>
                    <TableCell width="10%">{row.mobile}</TableCell>
                    <TableCell width="10%">{row.gender}</TableCell>
                  </TableRow>
                ))}
            </TableBody>
          </Table>

A abordagem usada por @nazrulcsebd e @crizant funcionou para mim. Este é o meu código:

<TableContainer component={Paper} style={{ marginTop: 10 }}>
          <Table style={{ width: 'auto', tableLayout: 'auto' }}>
          <TableHead>
            <TableRow>
              <TableCell>Team Member</TableCell>
              <TableCell align="left">Level</TableCell>
              <TableCell align="left">Last Login</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            { tableArray.map(({ id, name, accessLevel, login }) => (
              <TableRow key={id}>
                <TableCell component="th" scope="row" style={{ width: '35%' }}>
                  {name}
                </TableCell>
                <TableCell align="left">{accessLevel}</TableCell>
                <TableCell align="left">{login}</TableCell>
              </TableRow>
            ))
          }
          </TableBody>
        </Table>
      </TableContainer>

No meu caso, eu queria ter a menor coluna possível para conter um botão de "ação" no final da tabela. Adicionar style={{ width: 1 }} à TableCell no TableHead resolveu o problema.

        <TableContainer component={Paper}>
            <Table className={classes.table} aria-label="simple table">
                <TableHead>
                    <TableRow>
                        {header.map((th, i) => (
                            <TableCell key={i}>{th}</TableCell>
                        ))}
                        <TableCell style={{ width: 1 }}>actions</TableCell>
                    </TableRow>
                </TableHead>
                <TableBody>
                    {data.map((row, i) => (
                        <TableRow key={i} hover>
                            {header.map((h, i) => (
                                <TableCell key={i} align="left">{row[h]}</TableCell>
                            ))}
                            <TableCell>
                                <IconButton aria-label="edit">
                                    <MoreHorizIcon fontSize="small" />
                                </IconButton>
                            </TableCell>
                        </TableRow>
                    ))}
                </TableBody>
            </Table>
        </TableContainer>
const useStyles = makeStyles(theme => ({
  table: {
    "& tr:nth-child(2), & td:nth-child(2) {
      width: '32px',
    }
  }
}));

E então, use o estilo na raiz da tabela

 <Table
     ....
     className={classes.table}
>

Ainda não testei muito (cabeçalho corrigido, etc)

seria muito melhor se pudéssemos apenas fornecer o mesmo sistema de 12 colunas para tabelas, por exemplo:

   <TableContainer component={Paper}>
      <Table className={classes.table} aria-label="simple table">
        <TableHead>
          <TableRow>
            <TableCell>Dessert (100g serving)</TableCell>
            <TableCell align="right">Calories</TableCell>
            <TableCell align="right">Fat&nbsp;(g)</TableCell>
            <TableCell align="right">Carbs&nbsp;(g)</TableCell>
            <TableCell align="right">Protein&nbsp;(g)</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {rows.map((row) => (
            <TableRow key={row.name}>
              <TableCell component="th" scope="row" xs={4}>
                {row.name}
              </TableCell>
              <TableCell align="right" xs={2}>{row.calories}</TableCell>
              <TableCell align="right" xs={2}>{row.fat}</TableCell>
              <TableCell align="right" xs={2}>{row.carbs}</TableCell>
              <TableCell align="right" xs={2}>{row.protein}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>

Alguém conhece uma maneira de deixar a tabela rolar na direção x se houver muitas colunas? Só consigo fazer isso fornecendo minWidth = algo codificado (o que não é ótimo para um número desconhecido de colunas)

Parece que fixedHeader={false} style={{width: "auto", tableLayout: "auto"}} foram ignorados na última versão.

Alguma ideia?

Acabei com uma solução alternativa usando um elemento de lista dentro da tabela e definindo a largura do item de lista ...
Algo como:

<TableCell>
  <ul style={{ width: "150px" }}>
    <li>{row.whatever}</li>
    <li>{row.whatever1}</li>
    <li>{row.whatever2}</li>
  </ul>
</TableCell>

2020 e ainda difícil de alcançar, a parte mais estranha é que tento definir a largura de uma coluna, as outras colunas se ajustam automaticamente mesmo quando eu também defini a largura para elas! o que da? É como se a mesa estivesse garantindo que toda a largura da mesa não fosse além de 100%, o que está me deixando difícil. Se eu não estivesse usando a mesa de material-ui, isso seria muito fácil, parece que a interface de usuário de material apenas tornou isso difícil?

@aprilmintacpineda Você tentou com elementos nativos <table> ?

@oliviertassinari Eu não converti o código existente para o elemento <table> nativo.

Este exemplo funciona definindo a largura de todas as colunas
https://codesandbox.io/s/fragrant-framework-oy6uz?file=/src/App.js

Esta página foi útil?
0 / 5 - 0 avaliações