passing from specific class to props function sccs and vuejs - vue.js

I want to pass a class according to a props without having to duplicate the scss code
indeed if I duplicate the code by putting the class it works but I would only like to modify certain value by adding the appropriate class
components
``` :class="[
theme === 'darkModeTheme'
? 'darkModeTheme'
: theme === 'toggleLanguage'
? 'toggleLanguage'
: ''
]"
// props
theme: { type: String }
```
here is an example of the scss
```
&:checked {
background: color(menu);
background-repeat: no-repeat;
background-size: 80px 40px;
.darkModeTheme { //class to be taken into account if defined on the component to call
background: url("../../../assets/img/sky-stars.jpg");
}
&::before {
.toggleLanguage {
background-image: url("~#/assets/img/en.png");
}
// background-image: url("~#/assets/img/en.png");
left: 40px;
}
}
&:before {
content: "";
position: absolute;
width: 30px;
height: 30px;
border-radius: 50%;
left: 0;
background-size: 30px;
background-repeat: no-repeat;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.8);
#include easeOut;
cursor: pointer;
// background-image: url("~#/assets/img/fr.svg");
.darkModeTheme { //class to be taken into account if defined on the component to call
background-image: color(toggleTheme);
}
.toggleLanguage { //class to be taken into account if defined on the component to call
background-image: url("~#/assets/img/fr.svg");
}
}```

In your template, the dynamic class should be defined like
:class="{
'darkModeTheme': theme === 'darkModeTheme',
'toggleLanguage': theme === 'toggleLanguage'
}"

Related

How to add a top alert banner on Docusaurus 1.x?

I want to show some global message on my Docusaurus site. Something like:
https://codesandbox.io/s/duudl
https://next.ant.design/components/alert/
Is this possible?
You will have to inject the DOM via scripts. An example is React Native website where they injected feedback banners at the bottom of the page - https://facebook.github.io/react-native/docs/getting-started
Look at their repo and the script they used.
Update: you can now add it to the docusaurus.config.js file:
themeConfig:
/** #type {import('#docusaurus/preset-classic').ThemeConfig} */
({
announcementBar: {
id: 'support_ukraine',
content:
'Support Ukraine πŸ‡ΊπŸ‡¦ <a target="_blank" rel="noopener noreferrer" href="https://opensource.facebook.com/support-ukraine"> Help Provide Humanitarian Aid to Ukraine</a>.',
backgroundColor: '#20232a',
textColor: '#fff',
isCloseable: false,
},
...
You can style it with these CSS selectors in src/css/customTheme.scss:
/* Announcement banner */
:root {
--docusaurus-announcement-bar-height: auto !important;
}
div[class^="announcementBar"][role="banner"] {
border-bottom-color: var(--deepdark);
button.close {
svg {
fill: white;
}
}
}
div[class^="announcementBarContent"] {
line-height: 40px;
font-size: 20px;
font-weight: bold;
padding: 8px 30px;
a {
text-decoration: underline;
display: inline-block;
color: var(--brand) !important;
&:hover {
color: var(--ifm-color-primary) !important;
}
}
}
#media only screen and (max-width: 768px) {
.announcement {
font-size: 18px;
}
}
#media only screen and (max-width: 500px) {
.announcement {
font-size: 15px;
line-height: 22px;
padding: 6px 30px;
}
}

Bootstrap Vue Animate Dropdowns

I am using bootstrap vue and am trying to animate/transition the drop downs. This is proving to be fairly difficult as they do not use v-if or v-show so the transition will not work. Alternatively because the way the components work if you use v-if the drop down trigger will be hidden. I can't find anything online to bootstrap vue specifically on this but I feel this shouldn't be as tough as it has turned out to be. thanks for any help you can give
<div id="app">
<b-navbar type="dark" fixed>
<b-navbar-nav class="ml-auto">
<b-nav-item-dropdown text="Tools">
<b-dropdown-item to="/navItem1">Item 1</b-dropdown-item>
<b-dropdown-item to="/export"> Item 2</b-dropdown-item>
</b-nav-item-dropdown>
// This won't work as it hides the main dropdown trigger right form the start
<b-nav-item-dropdown text="Tools" v-if="toggleDropdown">
<b-dropdown-item to="/navItem1">Item 1</b-dropdown-item>
<b-dropdown-item to="/export"> Item 2</b-dropdown-item>
</b-nav-item-dropdown>
</b-navbar-nav>
</b-navbar>
</div>
<script>
export default {
name: 'nav',
data () {
return { toggleDropdown: false }
},
mounted: function () {
// I can listen for events here but I still can't trigger the transition
this.$root.$on('bv::dropdown::show', bvEvent => {
this.toggleDropdown = true
})
this.$root.$on('bv::dropdown::hide', bvEvent => {
this.toggleDropdown = false
})
}
}
</script>
<style lang="scss">
.navbar {
.dropdown-menu {
transform-origin: top;
transition: transform 10s ease-in-out;;
}
}
.dd-slide-enter,
.dd-slide-leave-to { transform: scaleY(0); }
</style>
It's pretty hard to achieve a clean slide-up/down animation because BootstrapVue uses display:none/block to hide/show the dropdown menu. What you can do it's manipulate the max-height of the element as explained here.
I added an 'animated' class to the parent element, for example your b-navbar to select which dropdown has to be animated. Then i removed display: none from the default status of the dropdown and hidden it setting its max-height and padding to 0 and its border to none. When you click the button the dropdown gets the class 'show'so you can give it a max-height different than 0, as explained in the answer i've linked to you, you have to set it higher than the actual height of the dropdown menu otherwise it gets cropped out.
.animated {
.dropdown-menu {
overflow: hidden;
display: block!important;
max-height: 0!important;
&:not(.show) {
padding: 0;
border: none;
}
&.show {
transition: max-height 300ms ease-in-out;
max-height: 500px!important; //this must have to be higher than the max height of the dropdown list
}
}
}
Just came across this same issue.
Ended up following with previous example, but this one works for both up/down transitions and doesn't mess with overflows in case you want to add triangles.
.dropdown-menu {
border: 1px solid #ebeef5;
box-shadow: 0 5px 25px 0 rgba(0, 0, 0, 0.25);
// Slide down transtion
display: block !important;
&:not(.show) {
padding: 0px;
border-width: 0px;
border-color: transparent;
box-shadow: none;
transition: padding 1.3s ease, border-width 1.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
> li {
max-height: 0px;
overflow: hidden;
transition: max-height 0.3s ease;
}
&.show {
> li {
max-height: 100px;
}
}
// Add chevron to top
&[x-placement^="bottom"] {
&::before {
content:"";
position: absolute;
right: 11px;
top: -5px;
width: 0;
height: 0;
border-style: solid;
border-width: 0 5px 5px 5px;
border-color: transparent transparent #fff transparent;
z-index: 99999999;
}
}
// Add chevron to bottom
&[x-placement^="top"] {
&::after {
content:"";
position: absolute;
right: 11px;
bottom: -5px;
width: 0;
height: 0;
border-style: solid;
border-width: 5px 5px 0 5px;
border-color: #fff transparent transparent transparent;
z-index: 99999999;
}
}
}

Apply style to an HTML element added dynamically by v-for using Vuejs

I'm adding elements to a list dynamically using v-for.
<ol>
<li v-for="light in lights">
<input type="range" min="0" max="255" v-model="light.currentBrightness" v-on:change="setBrightness(light)" />
</li>
</ol>
I want to decorate the slider using rangeslider.
Problem is, when a new element is added after the DOM is initialized, it's not taking the style specified in rangeslider.js. Way to fix this is to call the reinitialize method in rangeslider.js which will redecorate all the slider elements.
I'm not sure how to call the javascript method when the element is added dynamically during the runtime. Does anyone how to do it? To me, it seems like a very common problem but I could not find a solution by Googling.
My issue is same as discussed in github.
If you're new to JavaScript and Vue, you're diving in pretty close to the deep end. The rangeslider isn't just styling (like CSS), it's a widget that replaces the built-in range input.
One basic idea behind Vue is that it controls the DOM and you only modify your model, but there are some carefully controlled exceptions. Components have lifecycle hooks where you are allowed to insert and modify DOM elements owned by the component.
Some instructions for v-model support:
So for a component to work with v-model, it should (these can be
configured in 2.2.0+):
accept a value prop
emit an input event with the new value
So we make a component whose template is a range input element. We give it a value prop. In the mounted hook, we initialize the rangeslider on the input element (made available as el), then set it up to emit input events on change.
new Vue({
el: '#app',
data: {
lights: [{
currentBrightness: 10
},
{
currentBrightness: 30
}
]
},
methods: {
addRange: function() {
this.lights.push({
currentBrightness: 50
});
}
},
components: {
rangeSlider: {
props: ['value', 'min', 'max'],
template: '<input min="{{min}}" max="{{max}}" type=range />',
mounted: function() {
var vm = this
$(this.$el)
.val(this.value)
// init rangeslider
.rangeslider({
polyfill: false
})
// emit event on change.
.on('change', function() {
vm.$emit('input', this.value)
})
}
}
}
});
<link href="//cdnjs.cloudflare.com/ajax/libs/rangeslider.js/2.3.0/rangeslider.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.2/vue.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/rangeslider.js/2.3.0/rangeslider.min.js"></script>
<div id="app">
<ol>
<li v-for="light in lights">
<range-slider v-model="light.currentBrightness" min="0" max="255"></range-slider>
<div>{{light.currentBrightness}}</div>
</li>
</ol>
<button #click="addRange">Add Range</button>
</div>
You can use the below CSS codes to apply some stylings in the html5 range input:
body {
padding: 30px;
}
input[type=range] {
/*removes default webkit styles*/
-webkit-appearance: none;
/*fix for FF unable to apply focus style bug */
border: 1px solid white;
/*required for proper track sizing in FF*/
width: 300px;
}
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 5px;
background: #ddd;
border: none;
border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
border: none;
height: 16px;
width: 16px;
border-radius: 50%;
background: goldenrod;
margin-top: -4px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #ccc;
}
input[type=range]::-moz-range-track {
width: 300px;
height: 5px;
background: #ddd;
border: none;
border-radius: 3px;
}
input[type=range]::-moz-range-thumb {
border: none;
height: 16px;
width: 16px;
border-radius: 50%;
background: goldenrod;
}
/*hide the outline behind the border*/
input[type=range]:-moz-focusring{
outline: 1px solid white;
outline-offset: -1px;
}
input[type=range]::-ms-track {
width: 300px;
height: 5px;
/*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */
background: transparent;
/*leave room for the larger thumb to overflow with a transparent border */
border-color: transparent;
border-width: 6px 0;
/*remove default tick marks*/
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #777;
border-radius: 10px;
}
input[type=range]::-ms-fill-upper {
background: #ddd;
border-radius: 10px;
}
input[type=range]::-ms-thumb {
border: none;
height: 16px;
width: 16px;
border-radius: 50%;
background: goldenrod;
}
input[type=range]:focus::-ms-fill-lower {
background: #888;
}
input[type=range]:focus::-ms-fill-upper {
background: #ccc;
}

How to change text in nav menu when user change width of screen? Bootstrap 3

How to change text in nav menu when user change width of screen?
I try:
<li>
<p class="navbar-text visible-lg underline">Contacts & Delivery</p>
<p class="navbar-text hidden-lg underline">Contacts</p>
</li>
It's work, but text start text moves up. I can fix it using tag 'a' instead 'p', but i don't wont link in nav menu.
If i understand your problem well, it should be fixed when appending the following CSS code after Bootstrap's CSS:
.navbar-text { margin-left: 15px; margin-right: 15px; }
When you are using Less:
.navbar-text {
margin-left: #navbar-padding-horizontal;
margin-right: #navbar-padding-horizontal;
}
Also see: https://github.com/twbs/bootstrap/pull/15239
update
From https://github.com/twbs/bootstrap/pull/15239 follows that you should not use the .navbar-text inside a li or any other tag. An alternative for the above solution, which keep the .navbar-text as intended, will be to create a new class for texts inside the li 's
less
.navbar-nav-text {
&:extend(.nav > li > a);
&:extend(.navbar-nav > li > a);
p& {
margin: 0;
}
}
.navbar-default {
.navbar-nav-text {
color: #navbar-default-color;
}
}
.navbar-inverse {
.navbar-nav-text {
color: #navbar-inverse-color;
}
}
or css
.navbar-nav-text {
position: relative;
display: block;
padding: 10px 15px;
line-height: 20px;
}
#media (min-width: 768px) {
.navbar-nav-text {
padding-top: 15px;
padding-bottom: 15px;
}
}
p.navbar-nav-text {
margin: 0;
}
.navbar-default .navbar-nav-text {
color: #777777;
}
.navbar-inverse .navbar-nav-text {
color: #9d9d9d;
}

Can I override global variables from the calling scope

I need to override some global variables used within a mixin. However I'm reluctant to just change the variables in global space (wouldn't be overriding then)
Consider this given mixin with the required variable defined.
// Mixin and adjust the regular image class
.thumbnail {
display: block;
padding: #thumbnail-padding;
margin-bottom: #line-height-computed;
line-height: #line-height-base;
background-color: #thumbnail-bg;
border: 1px solid #thumbnail-border;
border-radius: #thumbnail-border-radius;
.transition(all .2s ease-in-out);
> img,
a > img {
.img-responsive();
margin-left: auto;
margin-right: auto;
}
// Add a hover state for linked versions only
a&:hover,
a&:focus,
a&.active {
border-color: #link-color;
}
// Image captions
.caption {
padding: #thumbnail-caption-padding;
color: #thumbnail-caption-color;
}
}
Yep, from Bootstrap... Now I want that mixin to work with different variables, without changing the global scoped ones. Can this be done?
article.publications {
.news-thumb {
#thumbnail-padding: 10px;
#line-height-computed: 20px;
#line-height-base: 30px;
#thumbnail-bg : black;
.thumbnail();
}
}