How to increase the size of vuetify v-switch - vue.js

I want to increase the size of whole vuetify v-switch component,as it is not listed in v-switch api
i tried to change the sass variables but it change the entire switches that the application have
click to see the current size

When you are changing SASS variables, it must affect all the elements in the application.
To change the only one v-switch, you can write something like:
<template>
<v-switch
v-model="switch1"
class="custom-switch"
:label="`Switch 1: ${switch1.toString()}`"
></v-switch>
</template>
<style>
.v-input--switch__track {
border-radius: 15px;
width: 48px;
height: 29px;
top: -2px;
}
.v-input--switch__thumb {
left: 6px;
}
.custom-switch .v-input__slot .v-label {
left: 6px !important
}
.v-input--selection-controls__ripple {
height: 0;
width: 0
}
</style>
CodePen demo is here.

Related

How to prevent Vue.js hidden element pop-in on page load?

I'm new to Vue.js and I have a (block) element that should be initially hidden on page load. I'm coming from a pure JS mixed with JQuery background so normally I would initially set display:none on the element use JQuery's show/hide methods etc.
I have the showing and hiding working correctly with Vue but a side effect is that the element flashes on the screen briefly on page load until the Vue setup is complete and it knows to hide the element. Setting display:none breaks the show/hide presumably because the elements class prop has higher precedence. Setting opacity:0 also seems to be overriding anything Vue is doing so that breaks the show/hide too. !important on the Vue animation classes does not help either.
The embedded sandbox below might not be the best way to reproduce this, and I suppose it might be system dependent too (speed, memory etc.) but surely this must be a common enough situation with some solution that I've missed.
VUE = new Vue({
el: '#app',
data: {
showFullpageSpinner: false
}
});
setTimeout(function() {
VUE.showFullpageSpinner = true;
setTimeout(function() { VUE.showFullpageSpinner = false; }, 1500);
}, 1500);
.fullpage-spinner-underlay {
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0,0,0,0.65);
z-index: 9999;
}
.fullpageSpinner-enter-active, .fullpageSpinner-leave-active {
transition: opacity .25s;
}
.fullpageSpinner-enter, .fullpageSpinner-leave-to {
opacity: 0;
}
.css-spinner {
position: absolute;
display: inline-block;
}
.css-spinner:before {
content: 'Loading...';
position: absolute;
}
.css-spinner:not(:required):before {
content: '';
border-radius: 50%;
border-top: 3px solid #daac35;
border-right: 3px solid transparent;
animation: spinner .7s linear infinite;
-webkit-animation: spinner .7s linear infinite;
}
#keyframes spinner {
to {-ms-transform: rotate(360deg);}
to {transform: rotate(360deg);}
}
#-webkit-keyframes spinner {
to {-webkit-transform: rotate(360deg);}
to {transform: rotate(360deg);}
}
#-moz-keyframes spinner {
to {-moz-transform: rotate(360deg);}
to {transform: rotate(360deg);}
}
.fullpage-loading-spinner {
left: 50%;
top: 45%;
margin-left: -40px;
margin-top: -55px;
}
.fullpage-loading-spinner:BEFORE {
width: 55px;
height: 55px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<transition name="fullpageSpinner">
<div v-if="showFullpageSpinner" class="fullpage-spinner-underlay">
<div class="css-spinner fullpage-loading-spinner"></div>
</div>
</transition>
</div>
Your problem seems to be solvable with the v-cloak directive.
This directive will remain on the element until the associated Vue instance finishes compilation. Combined with CSS rules such as [v-cloak] { display: none }, this directive can be used to hide un-compiled mustache bindings until the Vue instance is ready.
Example:
[v-cloak] {
display: none;
}
<div v-if="showFullpageSpinner" class="fullpage-spinner-underlay" v-cloak>
<div class="css-spinner fullpage-loading-spinner"></div>
</div>

Ionic 4 component library ion-radio css customisation

I have a question regarding the ion-radio component from the Ionic 4 component library.
Unfortunately this component https://ionicframework.com/docs/api/radio allows very little access to customise it's CSS through CSS variables. What i'm trying to achieve is to set the style of this checkbox icon to match this https://i.stack.imgur.com/PQnkY.png . Currently the style is the default one which corresponds to this https://i.stack.imgur.com/Vm9UQ.png. I've tried targeting the inner classes to no avail. I think it's because the divs are rendered inside the shadow-dom of the component ion-radio itself.I know this could be done with javascript, i would rather keep this as a last resort. Does anyone know of any other solution of achieving the same styling using this component?
Thank you
There is Ionic issue #20140 that will introduce new variable properties --border-radius and --inner-border-radius to the ion-radio component. The PR has been accepted is included in 5.0.0-beta.3.
Although the inner border radius is set to 50% if you're not using 5.0.0-beta.3 or higher, you can still change the CSS to address some of your needs. Maybe something like this?
ion-radio {
--color-checked:green;
--color:green;
margin-top: 20px;
width: 30px;
height: 30px;
}
Hope this helps.
You can play around with CSS to achieve this. Hide the ion-radio:
ion-radio {
opacity: 0;
width: 0px;
margin: 0px;
}
Place your custom radio button/shape inside ion-item:
<ion-radio-group>
<ion-item>
<ion-radio slot="start" value="foo" checked></ion-radio>
<ion-icon slot="start" mode="ios" name="radio-button-off" />
<ion-label>foo</ion-label>
</ion-item>
<ion-item>
<ion-radio slot="start" value="bar" checked></ion-radio>
<ion-icon slot="start" mode="ios" name="radio-button-off" />
<ion-label>bar</ion-label>
</ion-item>
</ion-radio-group>
Use the Ionic .item-radio-checked class:
ion-radio-group .item-radio-checked ion-icon {
fill: teal;
}
ion-radio-group ion-icon::after {
content: "";
width: 14px;
height: 14px;
background: teal;
position: absolute;
top: 5px;
left: 5px;
border-radius: 50%;
transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1) 0s;
transform: scale(0);
}
ion-radio-group .item-radio-checked ion-icon::after {
transform: scale(1);
}
This works for md mode only, but you can customize it further for ios with CSS.

Append child to $slot.default

I have a component that I need display some custom modal on screen. I don't know where I should put this dialog content, so I did something like that:
<template>
<div class="ComponentItself">
<div v-show="false" ref="ModalContent">
Hello!
</div>
<button v-on:click="showModal">Show modal</button>
</div>
</template>
[...]
Note: I could not set the tag name of [ref=ModalContent] to template because the vue reserves this tag to another feature.
My idea is when I click on "show modal" it open creates an instance of another component (v-dialog) that I have created with the [ref=ModalContent] content (it should be compiled to support nested vue components).
import Dialog from './Dialog';
const DialogCtor = Vue.extend(Dialog);
const dialog = new DialogCtor({ propsData: {...} });
dialog['$slots'].default = [ this.$refs['templateNewFolder'].innerHTML ];
{something like document.body.appendChild(dialog.$el)}
This another component have a slot that could receives the HTML content to be displayed inside of that. And it just not works. The modal is displayed, but the slot content is undefined or the HTML content not parsed.
<div class="Dialog">
[...]
<slot></slot>
[...]
</div>
The current result is something like:
What I need:
I need to know if I am on the right way. I have about the component feature, but I could not identify or understand if it is/could resolve my problem;
What I could do to make it work;
Some similar project could help it, but I could not found anyone;
Maybe I could resolve my problem if is possible I just .appendChild() directly to $slot.default, but it is not possible;
It seems to me this might be a case of an XY problem.
What probably happens is that you do not need to manually fill $slot.default, but use your Dialog component a more standard way. Since there is little detail about the latter in your question, that component might also need some refactoring to fit this "standard way".
So a more standard approach would be to directly use your <custom-dialog> component in the template of your parent, instead of using a placeholder (the one you reference as ModalContent) that you have to hide. That way, whatever HTML you pass within that <custom-dialog> will be fed into your Dialog's <slot> (designed beaviour of slot).
That way you also save the hassle of having to manually instantiate your Dialog component.
Then you can toggle your <custom-dialog> visibility (with v-if or v-show) or even manipulate its position in the DOM as you mention in your code; you can access its DOM node as $el: this.$refs.ModalContent.$el when ModalContent is a Vue instance.
You could also factorize the showModal method by delegating it to the Dialog component.
Code example:
Vue.component('modal-dialog', {
template: '#modal-dialog',
data() {
return {
modalShown: false,
};
},
methods: {
showModal() {
this.modalShown = true;
},
hideModal() {
this.modalShown = false;
},
},
});
new Vue({
el: '#app',
methods: {
showModal() {
this.$refs.ModalContent.showModal();
},
},
});
/*
https://sabe.io/tutorials/how-to-create-modal-popup-box
MIT License https://sabe.io/terms#Licensing
*/
.modal {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
visibility: hidden;
transform: scale(1.1);
transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s;
}
.modal-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 1rem 1.5rem;
width: 24rem;
border-radius: 0.5rem;
}
.close-button {
float: right;
width: 1.5rem;
line-height: 1.5rem;
text-align: center;
cursor: pointer;
border-radius: 0.25rem;
background-color: lightgray;
}
.close-button:hover {
background-color: darkgray;
}
.show-modal {
opacity: 1;
visibility: visible;
transform: scale(1.0);
transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
}
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<modal-dialog ref="ModalContent">
Hello!
</modal-dialog>
<h1>Hello World</h1>
<button v-on:click="showModal">Show modal</button>
</div>
<template id="modal-dialog">
<div class="modal" :class="{'show-modal': modalShown}" #click="hideModal">
<div class="modal-content">
<span class="close-button" ref="closeButton" #click="hideModal">×</span>
<slot></slot>
</div>
</div>
</template>
Now if you really want to fiddle with $slot, #Sphinx's linked answer in the question comments is an acceptable approach. Note that the accepted answer there also favours the standard usage. It seems to me this is also what #Sphinx implies in their 2nd comment.

How to make a link as a file input in vue.js 2?

My vue component like this :
<template>
...
<a href="javascript:;" class="thumbs"
:title="upload">
<span class="fa fa-plus fa-2x"></span>
</a>
...
</template>
<script>
export default {
props: ['...'],
data() {
return {
...
};
},
computed:{
...
}
}
</script>
I want if click the a link, it can upload file
In javascript, I know it. If javascript like this : How to make a link act as a file input
But How can I do it in vue.js 2?
I believe there is a small misunderstanding: Vue.js 2 is still javascript. Its goal is not the same as Polymer with its fancy components - it is supposed to enhance JS, not replace it with a different structure altogether.
#David Hallberg Jönsson's answer will work perfectly fine in Vue.js 2 perfectly fine. If you want it specifically in Vue's component structure:
<template>
<!-- ... -->
<a class="fileContainer">
Click here to trigger the file uploader!
<input type="file">
</a>
<!-- ... -->
</template>
<script>
export default {
props: ['...'],
data() {
return {
...
};
},
computed:{
...
}
}
</script>
<style>
a.fileContainer {
overflow: hidden;
position: relative;
cursor: pointer;
display: inline-block;
color: lightskyblue;
}
a.fileContainer:hover {
text-decoration: underline;
color: blue;
}
a.fileContainer > input[type=file] {
cursor: inherit;
filter: alpha(opacity=0);
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: right;
}
</style>
If you want to use the programmatic way in your link, it's not going to be easy because some browsers don't allow you to trigger click events on input type="file" elements. Your best bet would be to go this way.
(Also, technically you can still use jQuery with Vue, so the code in that link could still work if you wanted it to.)
If you want to know how to handle uploading files, there are many tutorials and some components already pre-made.
You can actually do this using only CSS, as explained here.
Example (from the link above):
.fileContainer {
overflow: hidden;
position: relative;
}
.fileContainer [type=file] {
cursor: inherit;
display: block;
font-size: 999px;
filter: alpha(opacity=0);
min-height: 100%;
min-width: 100%;
opacity: 0;
position: absolute;
right: 0;
text-align: right;
top: 0;
}
/* Example stylistic flourishes */
.fileContainer {
background: red;
border-radius: .5em;
float: left;
padding: .5em;
}
.fileContainer [type=file] {
cursor: pointer;
}
}
<p>So various methods prevent file upload inputs from being styled conveniently. But that needn't be the case!</p>
<label class="fileContainer">
Click here to trigger the file uploader!
<input type="file"/>
</label>

Vuejs carousel simple example not working

I am using Vuejs with Vue-carousel-3d for the carousel. I have the most basic simple carousel component from one of the examples:
<template>
<div id="carousel-wrapper">
<carousel-3d>
<slide v-for="(i, slide) in slides" :index="i" :key="i">
<img src="https://placehold.it/360x270">
</slide>
</carousel-3d>
</div>
</template>
<script>
import { Carousel3d, Slide } from 'vue-carousel-3d';
export default {
name: 'carousel-wrapper',
components: {
'carousel-3d': Carousel3d,
'slide': Slide
},
data: function () {
return {
slides: 7
}
}
}
</script>
<style scoped>
#carousel-wrapper {
outline: 5px solid red;
}
.carousel-3d-container figure {
margin: 0;
}
.carousel-3d-container figcaption {
position: absolute;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
bottom: 0;
padding: 15px;
font-size: 12px;
min-width: 100%;
box-sizing: border-box;
}
</style>
There was an error regarding passing a key in each slide in a for loop, but after correcting it by passing :key="i", now there's no error. But the carousel is not displaying in the browser. If I inspect in developer mode, there is the carousel divs, but in the browser, there's only the 2px solid red outline that I gave for testing purpose. Its working in their example page, but not in mine. I am new to Vuejs so I may be doing something wrong. What am I missing here?