Semantic-Org / Semantic-UI

Semantic is a UI component framework based around useful principles from natural language.
http://www.semantic-ui.com
MIT License
51.1k stars 4.95k forks source link

[Table] Dropdown menu gets clipped when a dropdown is placed inside a fixed table #3246

Closed brunotourinho closed 6 years ago

brunotourinho commented 8 years ago

Hello guys!

I have a dropdown menu (column selector) inside the header of a table, when I set the table to FIXED layout the menu won't show... Thanks in advance

Table set to Fixed <table class="ui single line fixed table"> menu

Regular Table <table class="ui single line table"> menuregular

bcroq commented 8 years ago

Same problem for me with a dropdown select: https://jsfiddle.net/bcroq/55ptqzg6/

paper777 commented 8 years ago

change overflow to visible

<td style="overflow:visible;">
IonutBajescu commented 8 years ago

Thanks @bcroq for the test case.

In case anyone else experiences this problem, @paper777's fix should work.

In the meantime, @jlukic do we plan to keep the current behaviour of .fixed.table? To me, it looks like it'd be more appropriate to move it inside of .single.line.table.

selection_158

If the response is negative, I suppose we should close the issue.

awgv commented 7 years ago

There’s also a representative test case in #5054: http://jsfiddle.net/c599ak7p/6/ Since the direction detection will be accounting for overflow containers at some point in the future #1340, these issues might be related.

ziaratban commented 7 years ago

.dropdown > .menu must be added to body.

avremel commented 6 years ago

My solution for using react-table:

                    getTdProps={() => {
                        return {
                            style: {
                                overflow: 'visible'
                            }
                        }
                    }}
baronnoraz commented 6 years ago

@avremel could you share the configuration for your react-table? I have Dropdown in a table header and am seeing the same behavior as you were. I've tried using getTheadThProps, etc, but I haven't been able to get this to work.

I have a simple illustration of the problem here, and would LOVE any help you or others could provide. Thanks!!!!

https://codesandbox.io/s/82z5385m2l

avremel commented 6 years ago

@baronnoraz You want getTdProps as a prop to the component, not as part of the columns variable.

const App = () => (
  <div style={styles}>
    <ReactTable
      columns={columns}
      data={data}
      loading={false}
      showPagination={false}
      getTdProps={() => {
        return {
          style: {
            overflow: 'visible'
          }
        }
      }}

    />
  </div>
);
baronnoraz commented 6 years ago

Thanks @avremel. That was stupid on my part. But I did move the function to the ReactTable component, and it still didn't work. I figured that I had the wrong props function and that I would need to modify the getThProps or something. I literally tried everyone of the get* component decorators from the react-table documentation, but none of them did the trick.

I revised the code, https://codesandbox.io/s/82z5385m2l

I'm simply at a loss as to what I'm missing. Thanks for trying to get me going.

avremel commented 6 years ago

Here is my configuration:

import React from 'react';
import ReactTable from 'react-table';
import { Dropdown} from 'semantic-ui-react';
import 'react-table/react-table.css'
import matchSorter from 'match-sorter'
import { getValueFromEvent } from '../common/utilities.js';
import * as Options from './options.js';
import '../App.css';
import FormModal from './form_modal';

class FormsTable extends React.Component {
    state = {
        status: {}
    }

    onInputChange = (e, result='') => {
        e.preventDefault()

        const newValues = getValueFromEvent(e)
        const name = newValues.name;
        const value = newValues.value;
        const status = this.state.status
        status[name] = value;
        this.setState({ status });
    };

    renderTable = () => {

        const columns = [{
            Header: props => <b>Date</b>,
            accessor: 'created_at',
            minWidth: 30,
            headerStyle: {textAlign: 'left'},
            style: {textAlign: 'left'},
            Cell: row => (
                <div>{row.value.split('T')[0]}</div>)
        }, {
            Header: props => <b>Tag #</b>,
            accessor: 'new_tag',
            minWidth: 30,
            headerStyle: {textAlign: 'left'},
            style: {textAlign: 'left'},
            filterMethod: (filter, rows) =>
                matchSorter(rows, filter.value, { keys: ["new_tag"] }),
            filterAll: true
        }, {
            Header: props => <b>First Name</b>,
            accessor: 'first_name',
            minWidth: 150,
            headerStyle: {textAlign: 'left'},
            style: {textAlign: 'left'},
            filterMethod: (filter, rows) =>
                matchSorter(rows, filter.value, { keys: ["first_name"] }),
            filterAll: true
        }, {
            Header: props => <b>Last Name</b>,
            accessor: 'last_name',
            minWidth: 100,
            headerStyle: {textAlign: 'left'},
            style: {textAlign: 'left'},
            filterMethod: (filter, rows) =>
                matchSorter(rows, filter.value, { keys: ["last_name"] }),
            filterAll: true
        }, {
            Header: props => <b>Member Type</b>,
            accessor: 'member_type',
            minWidth: 100,
            headerStyle: {textAlign: 'left'},
            style: {textAlign: 'left'},
            Cell: row => (
                <div>{row.value ? row.value.split(' ')[0] : null}</div>),
            filterMethod: (filter, rows) =>
                matchSorter(rows, filter.value, { keys: ["member_type"] }),
            filterAll: true
        }, {
            Header: props => <b>Status</b>,
            minWidth: 100,
            headerStyle: {textAlign: 'left'},
            style: {textAlign: 'left'},
            accessor: 'id',
            Cell: row => (
                <Dropdown
                    selection
                    fluid
                    name={row.value}
                    options={Options.statusOptions}
                    placeholder="Select Status"
                    onChange={this.onInputChange}
                />
            ),
        }, {
            Header: props => <b>Form</b>,
            minWidth: 50,
            headerStyle: {textAlign: 'left'},
            style: {textAlign: 'left'},
            accessor: 'id',
            Cell: row => (
                <FormModal
                    form={row.value}
                />
            ),
        }]

        return (
                <ReactTable
                    filterable
                    defaultFilterMethod={(filter, row) =>
                        String(row[filter.id]) === filter.value}
                    data={this.props.forms}
                    columns={columns}
                    defaultPageSize={10}
                    className="-highlight ReactTable"
                    defaultSorted={[
                        {
                            id: "date",
                            desc: true
                        }
                    ]}
                    getTdProps={() => {
                        return {
                            style: {
                                overflow: 'visible'
                            }
                        }
                    }}
                />
        )
    }

    render() {
        return (

            <div style={{'margin': '60px'}}>
                {this.renderTable()}
            </div>
        )
    }
}

export default FormsTable;
avremel commented 6 years ago

@baronnoraz Curious what would happen if you had the dropdown in a non header row and used getTdProps. Also, did you inspect source of page in chrome dev tools (Elements) to see if it overflow was added to the CSS?

baronnoraz commented 6 years ago

@avremel wow thanks! I'll check again, but I'm pretty certain I did see the overflow. But in answer to your question - it works fine when the drop down is in a non header row.

If I change my code from "Header: () =>" to "Cell: () =>" and add your getTdProps component function, it works. I do have to have the getTdProps function though.

It doesn't work for the Header row though. I also tried putting in a single header row, instead of the two levels I have, but it didn't work in either header.

avremel commented 6 years ago

@baronnoraz I can confirm that overflow: visible won't help for the header, and I'm not sure why. Also, I confirmed that getThProps doesn't add the CSS to the header.

baronnoraz commented 6 years ago

@avremel Ok, so I must not have seen that in all my trial and error. I opened up my codesandbox example in a new window and walked through it with Chrome's Developer Tools. The generated code looks like this...

<div class"rt-th rt-resizable-header -cursor-pointer" role="header" style="flex: 300 0 auto; width: 300px; max-width: 300px;">
    <div class="rt-resizable-header-content">
        <div>
            <div role="listbox" aria-expanded="true" class="ui active visible fluid selection dropdown" tab index="0">...</div
        </div>
    </div>
</div>

If I edit the styles with developer tools and add overflow: visible to the first div it works. The style I edited was...

.ReactTable .rt-head .rt-resizable-header:last-child {
    overflow: visible;
}

Assuming that I can figure out how to make that happen, I should be good.

baronnoraz commented 6 years ago

@avremel Victory!!!! I had to include my own CSS file and overwrite the .rt-th class and add !important.

.rt-th {
  overflow: visible !important;
}

Adding this made it work in the header. I'm not sure why getThProps() didn't work, but hopefully this tweak to .rt-th won't have adverse effects anywhere else.

stale[bot] commented 6 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 30 days if no further activity occurs. Thank you for your contributions.

mbenhalima commented 5 years ago

thanks @baronnoraz ! this saved me a lot of headaches. Just to add more details, if you customize the actual react-table css, this is the CSS to modify:

.ReactTable .rt-thead .rt-resizable-header-content { text-overflow: ellipsis; overflow: visible !important; }

This may explain why getThProps() is not working. The CSS code applies to both 'thead' and 'resizable-header-content'

cristoh commented 5 years ago

This is more general, but I don't think it will work if you need a horizontally scroll-able table. By that I mean, there are many columns, and you require a scrollbar with fixed width. In that case, you cannot use overflow: visible, you've got to use overflow-x: scroll. I have not yet found a solution to this problem (it's been weeks of trial&error).

Thanks edit: here's a plunkr I have been experimenting with. Similar to this conversation in that it is a "dropdown" not a "select". http://plnkr.co/edit/q3rqVlt7W0yVvqQBSDxZ?p=preview

abhishekkumarchaturvedi commented 5 years ago

@avremel you have mentioned import * as Options from './options.js'; in you configuration , can you please breif whats in that options.js file.

avremel commented 5 years ago

App specific data, I think it's values for a drop-down.

On Mon, May 27, 2019, 4:08 AM abhishekkumarchaturvedi < notifications@github.com> wrote:

@avremel https://github.com/avremel you have mentioned import * as Options from './options.js'; in you configuration , can you please breif whats in that options.js file.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Semantic-Org/Semantic-UI/issues/3246?email_source=notifications&email_token=ACQY7QM6BLFFU43WFTZRXRLPXOJGXA5CNFSM4BSWULPKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWJDHNA#issuecomment-496120756, or mute the thread https://github.com/notifications/unsubscribe-auth/ACQY7QOTVYCLTQJO4TH4MKDPXOJGXANCNFSM4BSWULPA .

MFRamon-zz commented 4 years ago

Encountered this issue while using semantic on Vue.js.

Currently using this class : ui fixed single line celled table

Applied this to fix it : <td style="overflow:visible;">