How to show a table on hovering a button in react? - css

I tried
class MyColorPicker extends React.Component {
render() {
const darkColors = ['#B80000', '#DB3E00', '#FCCB00', '#008B02', '#006B76', '#1273DE', '#004DCF', '#5300EB'];
const lightColors = ['#EB9694', '#FAD0C3', '#FEF3BD', '#C1E1C5', '#BEDADC', '#C4DEF6', '#BED3F3', '#D4C4FB'];
return (<div>
<button id="color">Select color</button>
<div className="picker">Text</div>
<div className="picker">
<table>
<tbody>
<tr>
{darkColors.map(color =>
<td style={{backgroundColor: color, width: 20, height: 20}} key={color}>{" "}</td>)}
</tr>
<tr>
{lightColors.map(color =>
<td style={{backgroundColor: color, width: 20, height: 20}} key={color}>{" "}</td>)}
</tr>
</tbody>
</table>
</div>
</div>);
}
}
css
.picker{
display: none;
}
#color:hover + .picker{
display: block !important;
}
The table does not show. I also tried adding a className to GithubPicker from react-color. Didn't work.
I don't want to set a state on hover because I have many components where I want to attach a button and a color picker. In this case, on hovering one button, all the other color pickers will show. I just want one color picker to show. How can I achieve this?

#color:hover + .picker work for element with class .picker just after #color:hover. In your case you have two .picker element. So first .picker will shown but as css second element will not show.
Please wrap both .picker div into a one div and put .picker class on wrapped div element.
Still you will get one more issue. As css you are trying to put hover css for button. When your mouse will move to picker, button hover will clear and again .picker will disappear.
So we have to wrap all element in one div and put hover css for wrapped div.
JSX
<div>
<div className="picker">
<button id="color">Select color</button>
<div className="picker-colors">
<div>Text</div>
<div>
<table>
<tbody>
<tr>
{darkColors.map(color => (
<td
style={{
backgroundColor: color,
width: 20,
height: 20
}}
key={color}
>
{" "}
</td>
))}
</tr>
<tr>
{lightColors.map(color => (
<td
style={{
backgroundColor: color,
width: 20,
height: 20
}}
key={color}
>
{" "}
</td>
))}
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
CSS
.picker-colors {
display: none;
}
.picker:hover .picker-colors {
display: block;
}
Here's a working example https://codesandbox.io/s/9yrr9wx60r

Related

How to apply a class to a specific label in a row based on truthy value

I'm new to Vue 3. I have a table with rows. See screenshot below. Each row has a checkbox and a label in it. All I want to do is upon initial loading of the page view, have the correct class apply to the label depending on whether the child.status of that row is true-thy or not. Child status true is present. False = absent. Problem: when I initially load the page view all the labels are green regardless whether the child.status false or true.
Currently the Vue 3 code I have got so far works great, except for initial load. If I check the checkbox, I get the data I need and the label gets its green background. If I uncheck a checkbox, the green class disappears. Check it again and the green background reappears - Great. All's well except for initial page load where all the labels are green.
To help you understand I included a screenshot. You will notice behind each label there is a 1 or 0 to indicate whether it is truthy are not. You will see that even the false ones are green.
<template>
<div class="container">
<h5 class="heading ml-4">Children Absent / Present</h5>
<div class="border_charts">
<table class="table ">
<thead>
<tr class="col-4">
<th class="tableHeading col-4">First Name</th>
<th class="tableHeading col-4">Last Name</th>
<th class="tableHeading col-4 ">Absent / Present</th>
</tr>
</thead>
<tbody>
<tr v-for="child in Children" :key="child.child_id">
<td class="col-4"><a :href="'/getchild/'+ child.child_id">{{child.childFirstName}}</a></td>
<td class="col-4"> {{child.childLastName}}</td>
<td class="col-4">
<div class="form-check form-switch" >
<input
type="checkbox"
class="form-check-input"
role="switch"
:id="child.child_id"
v-model="child.status"
:true-value="1"
:false-value="0"
#change="updateChild(child)"
>
<label
class="form-check-label"
v-bind:for="child.child_id "
:class="{present:child.status}"
:true-value="1"
:false-value="0"
> {{ child.status ? absentPresent : absentPresent }}
</label>
{{child.status}}
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
export default {
props: {
Children:{
Children:Array
},
},
data() {
return {
active:false,
inputClass: 'present',
absentPresent:'Absent/Present'
}
},
methods:{
updateChild(child){
this.changedChild = child;
console.log( this.changedChild);
this.inputClass = 'present'
this.active = ! this.active
},
},
}
</script>
<style scoped>
.present{
background-color: #5ba17a;
border-radius:0.25rem;
width:auto;
color:white;
text-align: center;
margin: 2px;
padding: 0px 5px 0px 5px;
}
.absent{
width:auto;
color:darkblue;
text-align: center;}
</style>
My guess is that child.status is initially loaded as string, so it is '0' instead of 0, and as with any non-empty string, Boolean('0') is true.
Check if you need to convert the values to numbers after loading, or if you can change the data source to send you numbers instead of strings.

Is there any CSS hack to stop a dropdown menu from causing an overflow?

My problem: https://i.gyazo.com/152caf74df3c484e770f9e8c34f5471e.mp4
If I click on the button, then it causes an overflow. I want to menu to appear without the overflow.
Sandbox: https://stackblitz.com/edit/react-ts-8aq1rq?file=App.tsx,index.html
Code:
import * as React from 'react';
import './style.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { NavDropdown, Button } from 'react-bootstrap';
// #ts-nocheck
export default function App() {
return (
<div className="table-responsive">
<div className="table">
<table
id="user-list-table"
className="table table-striped"
role="grid"
data-toggle="data-table"
>
<thead>
<tr className="light">
<th>Col one</th>
<th>Col two</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>
<NavDropdown
id="basic-nav-dropdown"
title={
<Button className="btn btn-sm btn-icon" variant="primary">
click
</Button>
}
>
<NavDropdown.Item>Option 1</NavDropdown.Item>
<NavDropdown.Item>Option 2</NavDropdown.Item>
<NavDropdown.Item>Option 3</NavDropdown.Item>
</NavDropdown>
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
}
Is there another bootstrap component that does this so that I can swap NavDropdown to it? If not, is there something else like a CSS hack that lets me do this?
The issue is that there isn't enough room to dropdown the nav list inside the div with the class of table-responsive. You can give it some min height or padding, but that might be weird if you have content below it. So you can add a negative margin to counter the additional padding:
.table-responsive {
padding-bottom: 100px;
margin-bottom: -100px;
}
Demo

Styling cells in table with react-bootstrap components

I'm rendering a table in which each cell corresponds to a Button component of react-bootstrap.
<>
<Table borderless className='below-nav table-style' responsive="sm">
<tbody>
{Array.from({ length: rows }).map((_, row_index) => (
<tr key={row_index}>
{Array.from({ length: columns }).map((_, column_index) => (
<Button className="td-style button-style" variant="warning">
<td key={column_index}>
ciao
</td>
</Button>
))}
</tr>
))}
</tbody>
</Table>
</>
The problem is that it renders buttons that are not fulfilled with the color selected: variant="warning", but just the border is of that color. There is another issue: bottom-border of each cell is not rendered at all so it seems clearly that something is overlayed on something else but i don't know why.
CSS like this seems not to work:
.table-style {
border-collapse: separate;
border-spacing: 1px ;
border-width: 1px;
}
.td-style {
margin: 5px ;
}
You are wrapping the <td> with the <Button>, this is not the correct way to use a table. This is how it should work:
<>
<Table responsive="sm">
<tbody>
{Array.from({ length: rows }).map((_, row_index) => (
<tr key={row_index}>
{Array.from({ length: columns }).map((_, column_index) => (
<td key={column_index}>
<Button variant="warning">
ciao
</Button>
</td>
))}
</tr>
))}
</tbody>
</Table>
</>
Basic DEMO of a table https://codesandbox.io/s/serene-knuth-qhpuu?file=/src/App.js

Custom control width when flex css style used

I custom control has a text box and a icon next to the text box
return (
<div className="useFlex">
<TextInput></TextInput>
<div>
<Icon></Icon>
</div>
</div>
);
Style
.useFlex {
display: flex;
}
It works perfectly
But the issue is : when I use this custom control in my page, text box width is not getting expanded and it remains fixed.
<Table width="100%">
<tr>
<td><MyCustomControl> </MyCustomControl></td>
</tr>
</Table>
could you please tell me what I am missing here?
Try to add
.useFlex
{
display:flex;
flex-grow: 1;
}

Understanding of CSS: Position

I have a question about the CSS property: Position
As I was creating a page that looks this:
As you can see, there is a table and div next to each other. The following codes shows that how I achieve this:
Code Structure:
<div className="daily-task-view">
<table{...getTableProps()}>
<thead >
{headerGroups.map(headerGroup => (
<tr className="table-header-row"{...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps(column.getSortByToggleProps())} className={
column.isSorted
? column.isSortedDesc
? "sort-desc"
: "sort-asc"
: ""
} ><h5 className="table-header-head"><b>{column.render("Header")}
</b></h5></th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td className="table-content" {...cell.getCellProps()}>{cell.render("Cell")}</td>;
})}
</tr>
);
})}
</tbody>
</table>
<div className="search">
<GlobalFilter filter={globalFilter} setFilter={setGlobalFilter}/>
<Button variant="success" className="button-to-add-dailytask">Add Daily Task</Button>
</div>
</div>
CSS:
.search{
margin-left:200px;
border-radius: 20px;
background-color: white;
width:fit-content;
position: absolute;
top: 10px;
left: 780px;
}
.daily-task-view{
padding-top: 10px;
padding-left: 20px;
position: relative;}
So far, the CSS that I have did presented the view that I want BUT when I Zoom In or Zoom Out, The Search which is the div tag didn't follow the action like moving the same way as the table been moving instead it didn't move and stick at that position that I set.
As I want the table and div be together so that that can act the same way (such as Zoom in/Zoom out)
What can I do, I used Absolute and Relative. Based on my understanding, both need to be together but in my case, it doesn't act that way.
Is my understanding of these 2 properties wrong?
Please Help
In your code now, you have the .search div inside the .daily-task-view one. This might be the issue
Here is an example of how you could achieve what I think you have in mind, by using a wrapper div and giving that display: flex, and then making .daily-task-view + .search separate and not .search inside the other. In my example I have also set widths for the div's, but it could be fit-content as well, or what you prefer.
https://codepen.io/akmalmo/pen/BapeXra
HTML
<div class="wrapper"><div class="daily-task-view">
Table
</div>
<div class="search">
Search
</div>
</div>
CSS
.wrapper{display:flex}
.search{
border-radius: 20px;
width:40%;background:red;
margin-left:20px;}
.daily-task-view{
padding-top: 10px;width:60%;background:blue;}
.daily-task-view, .search{padding:20px;}
Does this help?

Resources