Vuetify v-dialog - Dynamic width - css

is it possible to make the v-dialog have dynamic width? Currently the v-dialog by default has dynamic height which makes it shorten and lengthen depending on the length of content.
But can this be done with width?
I have a v-dialog that contains 4 tabs. 3 of those tabs don't require much width but the last tab contains a table so I'd like the dialog to widen as far as it needs to, to cater for the table, and then shorten again when clicking on either of the first 3 tabs.
Vuetify v-dialog: https://vuetifyjs.com/en/components/dialogs

Setting width to "unset" seems to work, haven't discovered any negative side effects yet.
<v-dialog v-model="dialog" width="unset">
<YourDialogContent></YourDialogContent>
</v-dialog>
or CSS
.v-dialog {
width: unset;
}

For Desktop
so I'd like the dialog to widen as far as it needs to, to cater for the table, and then shorten again when clicking on either of the first 3 tabs.
For desktop, we can set dynamic width for v-dialog based on contents inside the dialog easily, by manually setting the width="auto " (with extra space).
<template>
<v-dialog width="auto ">
...
</v-dialog>
</template>
For Mobile
Due to limited space, full-screen dialogs may be more appropriate for mobile devices than dialogs used on devices with larger screens. But need to set dialog to full-screen in mobile devices only. We can easily set dynamic full-screen using Vuetify breakpoints like:
<template>
<v-dialog :fullscreen="$vuetify.breakpoint.xsOnly">
...
</v-dialog>
</template>
Final Version
We can combine both the logics into one like:
<template>
<v-dialog width="auto " :fullscreen="$vuetify.breakpoint.xsOnly">
...
</v-dialog>
</template>
Working Demo | Code Pen
On Desktop
If we open the dialog using the click me button, we can see the dialog has a small width as the content of tab 1 & 2 is very small. But if we click on tab 3, which has a large data table, you can see the dialog width and height automatically increases. You can toggle between tabs and can see this again.
On Mobile
If you open this demo on mobile, you can see the dialog is opening in full-screen by default and the width is constant.

Write custom css rules and not set width or max-width props. e.g.:
I use a custom class in order to not apply rules to all v-dialog:
<v-dialog v-model="dialog" content-class="v-dialog--custom">
<!-- dialog content -->
</v-dialog>
And create your custom rules:
.v-dialog--custom {
width: 100%;
}
/* Desktop */
#media screen and (min-width: 768px) {
.v-dialog--custom {
width: 50%;
}
}
You can see this on codepen: https://codepen.io/hans-felix/pen/BajByxx

Are you talking about this part?:
<v-dialog
v-model="dialog"
width="500"
>
If so, why just don't remove the width="500" part and leave without one? I tested and it stretches dynamically. This option is not required and nothing is breaking if you remove it.
In case I misunderstood something, please feel free to add more details.

I think, what are you searching is the fullscreen (bool) property or depending on the needs the max-width (Number) property.
By setting one of those you control the width of the v-dialog depending on the surrounding element. The surrounding element width can be adjusted via css, e.g. flexbox.

Use what scientists are using.
Make width as a computed variable, and then return your value based on the breakpoints.
If you want to set width dynamically based on the contents in the dialog then just modify the width function to return the width based on the contents.
Copied from vuetify site: LINK
<v-dialog v-model="dialog" :width="width">
<v-img src="~~~"></v-img>
</v-dialog>
<script>
...
computed:{
width() {
switch (this.$vuetify.breakpoint.name) {
case 'xs': return 220
case 'sm': return 400
case 'md': return 500
case 'lg': return 600
case 'xl': return 800
}
},
}
</script>

Related

Do not make the width of the button proportionnel to the width of the popup window

I want to make a button in a popup window as Script Lab as follows. Note that, in Script Lab, the width of the button is enough to hold the sentence in one line, even though the popup window is not very wide:
I almost use the same code as ScriptLab:
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
... ...
return (
<div style={{ height: '100vh', display: 'flex', flexDirection: 'column'}}>
<PrimaryButton
style={{ margin: 'auto' }}
text="Open link in new window"
// tslint:disable-next-line: jsx-no-lambda
onClick={() => {
window.open(this.props.url);
}}
/>
</div>
);
Here is my result, where the width of the button is proportionnel to the width of the popup window. As a consequence, the sentence needs to be displayed in 2 rows, which is not what I want.
Does anyone know how to amend the code to get the effect like Script Lab?
Edit 1:
I have made a sandbox: https://codesandbox.io/s/relaxed-feather-i6jz6?file=/src/App.js
Now, the problem is, if we Open In New Window and open https://i6jz6.csb.app/ in a new browser tab several times, we may see a little adjustment of the font of the text in the button. Does anyone know how to avoid that?
On button width:
In order to not have the width of the button grow proportionately with the container you can enforce the width: auto on the button. This way it will only be as wide as it needs to be to contain the text. Value auto is also better than having a fixed width, because it can automatically wrap the text if the popup becomes too narrow to display the text in one line (with fixed width your button would overflow instead - which looks really bad).
On font adjustments
For the font adjustments you experience - this is a very common thing on web and it even has its own name - FOUT (Flash of Unstyled Text). It happens when you use custom fonts on the page, because these are files like any other and so they take some time to download. Browsers prefer displaying the content as early as possible (even without custom fonts loaded) to displaying the perfect content (by waiting on all resources) with some speed penalty.
The only way (at least that I know) to completely avoid FOUT is to use system fonts instead of custom fonts (github does that for example).
If that's not an option, you can minimize the FOUT by caching the fonts on client machines for long times. This way they will experience the flash briefly on the first visit, but not on subsequent ones.
You can also try to minimize the FOUT by telling the browser to try to preload the font files that will be needed for the page (part of the reason why FOUT happens is that browser discovers the fonts very late) https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
Set a fixed width to the button.Setting a fixed width will make it unproportional to the width of the pop-up window.
width:280px;
Second Option: If you use min-width, the button width will decrease to a point.
Third Option: If you use max-width, the button width will increase upto a point.
Fourth Option: You can also use '#media' queries to customize the width according to size of the screen.
You don't want the button's text to wrap, so you'll need to change the font size, which you can do when you find that the button's height increases when the text wraps. I suggest that you create a invisible, but not 'display: none', possibly 'off-screen' version of the button so that the real button's font is changed after you know the right size is needed. Alternatively, what about an image or glyph instead of text, and a Title for the button text?

make ng-select width adjust to selected items / available options?

I'm using ng-select in an Ionic3 / Angular5 project and I'm using its multiple selection configuration. The presentation of the select input is always considerably wider than it needs to be to contain the selected items or any of the available options.
I'd like it to be sized such that the width is at least the maximum width the component would have if any one of the available options were selected, and such that the otherwise the width is whatever is required to contain the actively selected options.
Is it possible to get ng-select to behave in that way?
I am not sure if ng-select has any build-in way to do what you want. But it is a block element which means you can control its width as you want. And in Angular, you can dynamically control style with ngStyle. For Example: define a getWidth() function with ngStyle.
<ng-select [items]="items"
[ngStyle]= "{width:getWidth()}"
>
</ng-select>
Now in getWidth function, you can return any value you want to control the width. you can loop through the items, and get maximum length of item, then translate into pixels. there's a ratio of string length to pixel which you might need to experiment.
And you can also listen to events and return the width based what is currently selected.
adding ng-select { .ng-dropdown-panel { width: auto !important; } } in CSS, it works but I would like to suggest adding a tooltip while hovering making a substring than adding css.
<ng-template ng-option-tmp let-item="item">
<div [ngbTooltip]="item.length > 15 ? item : ''" container="body">
{{item.length > 15 ? (item| slice:0:15) + '..' : item}}
</div>
</ng-template>

Dynamic height for material ui tab containers

I'm having a problem which at first I thought it was the general configuration of my app and the height I was giving to my page wrapping classes. But I made a simple out of the box material ui tab example and it seems this is natural to material ui Tabs Component.
Material UI tabs component gives their tab container the same height, being that height the largest of all its containers. So if you have one tab content with lots of content in it, it makes the other tab contents just as large, even though they may only have one text field and a button in them.
How can I make it that the height of the container adjusts to the content of its own tab?
Here is a visual
Here is why TAB ONE is so large, TAB TWO is setting the height
Here is a webpackBin for you to see the code working and mess with it.
One hack I've done so far is setting a definite height and overflow, but I don't want to do that because it creates a double scroll bar (one in the tab container, one in the body) besides, it's buggy looking.
I would like it if the tab container (the one with the green border) adjusts to the content as it does in TAB TWO, BUT individually.
Thanks in advance!
If you set the height based on the given element's current visibility you will be able to resolve this issue.
Example
.react-swipeable-view-container > div[aria-hidden="false"] {
height: 100%;
}
.react-swipeable-view-container > div[aria-hidden="true"] {
height: 0;
}
Note: this solution could be improved by using a better selector, something more descriptive like a class name. I suppose it's subjective though, using an attribute selector is not technically wrong and actually more specific than just a class.
Demonstration: https://www.webpackbin.com/bins/-Ky0z8h7PsdTYOddK3LG
animateHeight will animate height on tab change. if all tabs have different height it will show height accordingly.
Example:
<SwipeableViews
animateHeight // it will animate height on tab change
>
<div>{'slide 1'}</div>
<div>{'slide 2'}</div>
<div>{'slide 3'}</div>
</SwipeableViews>
Happy Coding ...!
There's a merge request that have been accepted here on the lib that could be interesting with a new method called updateHeight https://github.com/oliviertassinari/react-swipeable-views/pull/359
<SwipeableViews
action={actions => {
this.swipeableActions = actions;
}}
animateHeight
>
<div>{'slide n°1'}</div>
<div>{'slide n°2'}</div>
<div>{'slide n°3'}</div>
</SwipeableViews>
Then:
componentDidUpdate() {
this.swipeableActions.updateHeight();
}

Gentelella set nav-sm on start

setting nav-sm on body for making sidebar take least real state on any layout , it works on desktop size, but for tablet it does not hide it like nav-md or on phone it does not hide it like nav-md used to. what is the best way to set side-bar menu to take least real state as possible for any screen size.
Just change your body class from "nav-md" to "nav-sm"
So this will be the code:
<body class="nav-sm">
//
// your page content
//
</body>
You should be aware of classes in all dom element to have a responsive site, not just in body tag.

Polymer - Paper Toggle Button Layout

I'm learning Polymer. Currently, I have a paper-toggle-button element in my app defined like this:
<paper-toggle-button checked="{{ isEnabled }}">enable?</paper-toggle-button>
When this is rendered, it renders is like this:
[switch] enable?
My question is, is there a way to put the label to the left of the switch? In other words, I want to show the control like this:
enable? [switch]
How can someone do that?
Err can't you just put your label text before the toggle button?
<span>enable?</span><paper-toggle-button checked="{{isEnabled}}"></paper-toggle-button>
Thats currently not supported. You can create a feature request to add another insertion point for the label on the left, wrap the element in a custom element and add that feature or fork the paper-toggle-button and customize it.
This answer makes some assumptions about the relative size and positioning of your toggle button, but I've tried to defer to the Polymer & flex models.
The idea here is to put your left-adjusted label in a <span> and offset its right side by the width of the toggle button. The toggle button also needs to be padded left; I chose to pad at 33% because I was actually centering labels around the toggle.
Local CSS:
paper-toggle-button.date-toggle {
padding-left: calc(33% + 1em);
}
/* position the left label outside the containing box */
span.toggle-left-label {
position: absolute;
right: 7em; /* Based on a relatively safe render width of the toggle button */
/*right: 200%;*/ /* Depending on your use case, you might find percentages friendlier than ems */
}
Usage in a paper element:
(here I'm centering the toggle button between 2 labels, but you can just use the toggle-left-label span)
<paper-menu class="app-menu" attr-for-selected="" selected="">
<iron-icon icon="date-range"></iron-icon>
<span>Sort by date:</span><br />
<paper-toggle-button class="date-toggle">
<span class="toggle-left-label toggle-label">Newest</span>
<span>Oldest</span>
</paper-toggle-button>
</paper-menu>
The results maintain good positioning over media/query breakpoints and don't break any responsive views. The results:

Resources