ReactJS MaterialUI Stepper breaks on overflow - javascript

I have been trying to convince the Material UI Stepper component to fit my needs, that is to say display severl steps and overflow, but it continues doing this:
I don't know how to explain the error... the separators are doing weird things on horizontal overflow. Here is the sandbox. How can I get this working?

TL;DR: 1) Word-break your labels (<StepLabel style={{ wordBreak: "break-all" }}>) so they don't invade layouts among steps and 2) provide an initial width to the stepper (<Stepper ... style={{ width: 64*16 }}>) so it does not use the parent width to do so.
I fixed your pastebin:
NL;PR: You had two styles missing to handle long words and content within a scrollable container:
For 1) the labels' words were bigger than the allotted space to render the steps since 550px is too tight for 16 steps, so they broke the layout, play it safe by not letting lengthy words overflow the label.
For 2) consider given the Stepper component a proportional value (64 (stepper min-width)* 16(stepper count)), and since you want to have a scroller, the width of the scrollable container is used as the initial width of the content, thus you must specify the content(Stepper) so it is not shrunk too much before overflowing.
Note: Those styles I provided are examples, you can customize them to your needs. Also, consider passing those changes via classes.

Related

Propertional width with constant spaces in responsive design

I am having trouble coming out with a responsive component that scales some buttons with a proportional width, but with constant spaces.
In the example below, the small arrows are all 15px and I want the buttons to scale up or down depending on the max width of my box, but the spaces to stay constant.
I tried this property: calc((100% / ${allEleemnts}) - (${spaces} / 2)),
But I don't quite obtain the exact same space between all the elements when the page scales up or down.
I would really appreciate some feedback on my try and from people who succeeded in scaling some elements' width while keeping some constant spaces between them.
A better way to implement this would be through CSS Grid where you will get access to a css property
gap: 10px; /* 10px is just an example*/
This will give you more control of your layout and give consistent spaces which makes it more responsive.
You can learn about CSS Grid through:
https://www.w3schools.com/css/css_grid.asp

Header flickering and freezing issue with material table (implemented with react window + react window infinite loader)

I have implemented an Infinite scrolling table with react-window (based on #60) and material UI.
The table seems to be fulfilling the main objective but there are few issues with it -
header is not sticking on the top in spite of having styles in place (stickyHeader prop).
header is flashing/flickering while scrolling quickly towards up direction.
[Steps to reproduce - scroll 50% down then do fast scroll up and observe the header movement ].
Here's the codesandbox example - https://codesandbox.io/s/react-window-with-table-elements-forked-huti6?file=/src/index.tsx:514-542
Use default value for TableContainer overflow-x and the sticky header should work
import { makeStyles } from '#material-ui/core/styles'
const useStyles = makeStyles({
tableContainer: {
overflowX: "initial"
}
})
function Inner({ children, ...rest }, ref) {
const { header, footer, top } = useContext(VirtualTableContext)
const classes = useStyles();
return (
<TableContainer classes={{root: classes.tableContainer}} {...rest} ref={ref}>
...
As an alternative to your implementation, the Material UI docs have a working example of a virtualized table which achieves what you're looking for using react-virtualized. That is, the header is sticky and there is no flashing/flickering of the header during scroll.
Below is a codesandbox
containing a working example to reflect your desired layout.
First about the react-window: The Scollbars in the react-window are for the outercontainer not for InnerContainer. Now don't try to replace the outer container itself, unless you want to handle everything yourself. All the scroll events a few more things are attached to the outercontainer.
Think of it like outer container decides/takes the size and the larger inner container gets scrolled inside it.
Now looking at your case I assume you are trying to make the table behave like any other grid where headers are fixed and content is scrolled if it's getting overflow. your table header is way lower in the element hierarchy than the inner container, so no way you can write any simple css (or js logic) to achieve in current hierarchy.
that's why even though you have set the stickyheader for the MaterialUI table, it won't stick. Cause your whole table (MaterialUI table) is getting scrolled inside the outer container of react-window.
I would suggest you to move your table header outside of the react-window and only place the rows in the react-widow. that's the way it's suppose to behave (i.e. react window treats everything in it as scrollable content). See one of the presentation below:
A little tip on redesigning of your table (guess the alignment can be improved by additional css)

DHTMLX Scheduler timeline view - labels with longer text don't appear in tree mode

I have a question to which I can't find the answer for some time.
It's about DHTMLX scheduler timeline view in tree mode. The problem is that labels with longer text than the available space for the folder elements of the tree(these which have children) disappear, they are not shown in the first column of the timeline view. I can't understand why is this happening. Is there some kind of a setting on the scheduler, which I'm missing. It is important to note that styling of the scheduler has to be with the dhtmlxscheduler_material.css file or in other words material design.
Here is an image of the scheduler with the problem shown
I also provide a code sample which simulates the problem.
https://docs.dhtmlx.com/scheduler/snippet/9445edbf
This behavior can be fixed by the following style:
.dhx_scell_expand{
position:absolute!important;
}
Also in material skin, it requires some additional styling to make it look better, which may look like this fragment:
.dhx_scell_expand{
position:absolute!important;
}
.dhx_scell_name{
margin-left: 26px;
text-align: left !important;
}
Of cause, you can experiment with it to make appropriate for your project.
Also, in a case with long section names, you can change the default width of the section names column through the "dx" parameter:
scheduler.createTimelineView({
...
dx: 300, //200 by default
...
});
Here is an example with additional styling, and the resized names section :
http://snippet.dhtmlx.com/5/a3da39a40
Also, you can separate the section name using the </br> tag, change the height of the section through the "folder_dy" property, and align multiline text through CSS(line-height/ margin), like in the following example:
http://snippet.dhtmlx.com/5/87845739f

How to use ScrollPanel with relative size

I'm trying to use a ScrollPanel of GWT in a page. Since most of the contents are in the ScrollPanel, I want it to take an as-large-as-possible part of the page and resize as the page may resize. Naturally I would want to set it a relative size, i.e. setSize("100%","100%"). However the document says it can only be set a size in absolute CSS units (e.g. "10px", "1em", but not "50%")
I cannot understand why ScrollPanel cannot take relative size in GWT. After searching and reading a lot, someone suggests just set the element's size to "100%" (see GWT Relative Width). I may give it a try but not sure if it will affect ScrollPanel's other function - as I will also control the scroll of the panel.
ScrollPanel myScrollPanel = new ScrollPanel();
myScrollPanel.setSize("2112px", "150px"); // Arbitrary width.
myScrollPanel.getElement().getStyle().setProperty("width", "100%");
So here's my questions:
(1) Why??? (this is driving me mad as I cannot understand, maybe someone with deeper understanding of the GWT inside mechanism can enlighten me)
(2) How to work around?
ScrollPanel implements RequiresResize interface, which means that it needs to get it size from its parent, or its size has to be set explicitly. Thus, you have two options.
(1) Use a parent widget that implements ProvidesResize interface - for example, LayoutPanel. It's important, however, that ProvidesResize - RequiresResize chain remains unbroken all the way from RootPanel to your ScrollPanel.
In a typical implementation, LayoutPanel (or its variant) represents your entire page. Then you can add various children to it, e.g. "header", "main view", "left menu", etc. For each child you can set the preferred size. For example:
myLayoutPanel.setWidgetTopBottom(myScrollPanel, 32, Unit.PX, 0, Unit.PX);
In this example your ScrollPanel will take all available space on a page starting from 32px at the top and all the way to the bottom. You can set its position in percentages or other units instead.
(2) You can accomplish the same layout with pure CSS. If you don't care about very old browsers, the best option is to use flexbox layout model. In this case you set display: flex on your parent widget, and flex-grow: 1 on your ScrollPanel - telling it to take all available space (unless there are other flex-grow siblings, in which case they will split the extra space).
The answer to your first question is very simple. When using the relative size for an element you are referring to the size of a parent element. So when you set height: 100% it means that your element should be 100% size of its parent.
And there are some ways to get what you want:
use the Viewport-percentage lengths - you can set height: 100vh which means 100% of the viewport height - this is the easiest way but may be not yet supported by all browsers
set both the html and body elements 100% height - this will allow you to use the relative height on child elements
use GWT DockLayoutPanel or DockPanel and add your scroll panel to the center pane - it will take all the remaining space
First, ScrollPanel is something not acting as other widget for reason I don't know why. Cannot set relative size (50%), and if I give it some style, it's lost somewhere and cannot be found from page.
My solution is to use a ResizeLayoutPanel. Andrei suggested using something ProvidesResize but requires the provide / require resize chain remain unbroken, which can be very tricky. I found this ResizeLayoutPanel "ProvidesResize to its one child, but does not RequiresResize", which is the perfect candidate for the root panel of my composite. Then, I just extend the ScrollPanel to resize itself in the "onResize" method whenever it's called by the parent ResizeLayoutPanel.
Still no answer to my first question: by ScrollPanel behave like this in the first place? I tried to find answer in its source code but was not successful (though I didn't spend enough time studying the source code).
public class My100PctScrollPanel extends ScrollPanel {
#Override
public void onResize() {
// Window.alert("on resize");
this.setWidth(this.getParent().getOffsetWidth()+"px");
this.setHeight(this.getParent().getOffsetHeight()+"px");
super.onResize();
}
}
........
compositeRoot = new ResizeLayoutPanel();
........
scrollPanel = new My100PctScrollPanel();
compositeRoot.clear();
compositeRoot.add(scrollPanel);

Dealing with scroll bars and jquery .width() method

jQuery's .width() method doesn't seem to account for scroll bars. This is problematic for me, since I'd like to set the width of some children to equal the width of their parent. I used jQuery similar to the following:
$('#contentDiv').width($('#containerDiv').width())
In this example, #contentDiv is the element I'd like to size, and I want to set it to have the width of #containerDiv, which is its parent element. My problem is that this cuts off the side of #contentDiv, as seen in this fiddle.
In my actual code, I have several elements that I'm sizing with jQuery, which all need to fit in the scrollable div, so just setting the css of #contentDiv to 100% is not an option. What's the best way of dealing with scroll bar widths of divs in jQuery?
The best solution I found while working around this solution is this:
http://chris-spittles.co.uk/?p=531
jQuery is all powerful and everything but sometimes a small dash of native JS is all you need to render pixel perfect pages... I hope you will find this solution helpful!
UPDATED:
None of the jQuery width-finding methods account for the scroll bar. In my original example, using .innerWidth(true) LOOKS like it works, but only because it returns and object, which causes width to fail and the inner contents size themselves to fit in the available space, because the example wasn't very good. However, it's possible to write a function to compute the available space in a div with a scroll bar in it, which can then be used to position the contents as you wish.
To write that function, I took advantage of the fact that, when a div is appended to a div with a scroll bar in it, it takes up the full available width (i.e. the inner width of the parent minus the width of the scroll bar).
The function looks like this:
function noScrollWidth(div){
var measureDiv = $('<div id="measureDiv">');
div.append(measureDiv);
var width = measureDiv.outerWidth();
measureDiv.remove();
return width
};
I then use this to size my content div:
$('#contentDiv').width(noScrollWidth($('#containerDiv')));
Working fiddle.
Try this:
$('#contentDiv').width($('#containerDiv')[0].clientWidth)
For more information about that solution, see this StackOverflow answer.
Another approach I'd try is setting both elements' box-sizing property to 'border-box', and see whether setting your contentDiv's width to 100% then works the way you want.
Now that fewer projects worry about crufty old browsers anymore, 'border-box' can make things easier to work with. Be sure to test multiple browsers on multiple platforms, though, because I'm not sure they all handle scrollbars the same way.

Categories