I'm new to Vaadin and trying to create an instance that hides the vaadin-text-field from the component vaadin-date-picker.
I started out by reading the documentation for vaadin-date-picker about the shadow DOM property stated here.
I tried with "Scoping Styles in a Theme Module" but the whole thing including the calendar icon disappeared.
Current code as below,
render() {
return html`
<dom-module id="trim-inputbox" theme-for="vaadin-date-picker">
<template>
<style>
:host(.special_field) [part="text-field"] {
visibility:hidden;
}
</style>
</template>
</dom-module>
<vaadin-date-picker class="special_field"></vaadin-date-picker>
`;
}
Thanks so much again for any kind help.
As you noticed already a calendar icon is part of a text-field itself.
In Styling section there is an example of using <vaadin-date-picker-light>:
<style>
.my-input2 input {
border: none;
font-size: 14px;
background: none;
}
</style>
<vaadin-date-picker-light>
<div class="my-input2">
<iron-icon icon="event"></iron-icon>
CHECK-IN:
<iron-input>
<input size="10">
</iron-input>
</div>
</vaadin-date-picker-light>
Maybe you could use this instead?
Related
The issue
https://streamable.com/e/9z6lev (the flickering in the video is caused by the overlay being reopened every time meal plan is selected)
It "feels" like during the initial overlay open it's not the focused element and as result is's children can be clicked through :sad:
Overlay Template
The logic for the overlay is quite simple, and allow to nest any type of content inside:
<template>
<div class='swipeableWrapper'
#click.stop.prevent // not original code, just attempt to fix the issue
#touch.stop.prevent> // not original code, just attempt to fix the issue
<slot />
</div>
</template>
.swipeableWrapper {
height: 100%;
left: 0;
min-height: 100%;
position: fixed;
top: 0;
width: 100%;
z-index: 100;
}
Items List Template
<template>
<div>
...
<ListProduct v-for='(product, index) in products'
...
:showProduct='showProduct'
:key='index' />
</div>
<template>
// List Item
<template>
<div class='listProduct'
...
#click='showProduct'>
...
</div>
</template>
Intended approaches:
The following logic added to the overlay template to prevent events from bubbling:
#click.stop.prevent
#touch.stop.prevent
Global logic that will listen to opened overlay and add the following CSS class to the body element, in order to allow click on the overlay items, but still not much luck
.overlayOpened {
& * {
pointer-events: none;
touch-action: none;
}
.swipeableWrapper {
&,
& * {
pointer-events: auto;
touch-action: auto;
}
}
}
I am a bit puzzled with this dark magic behaviour and will really appreciate your opinion on the origin of the behaviour and possible solutions :bow:
Try this
#click.self.prevent="function"
Edited:
For the list item and function as prop
:showProduct="() => showProduct(item/index)"
I need to create a CSS class with media queries based on input image. The react script to create the css should look something like this:
const getBackgroungImageSet = (image) => {
return `.mycontainer {
background-image:url("${image}?mw=500"); // big image
}
#media(max-width: 768px){
.mycontainer {
background-image:url("${image}?mw=250"); // small image
}
}`;
}
Is it possible to add this class to the document in react?
Here's a way to add your styles via a style tag. The actual method is based on something shown in the docs for React Helmet. Which is a good way of getting your style tags to the document head instead of arbitrarily in the middle of the dom.
For the style tag, you need to use type="text/css" and use a string so that there aren't syntax errors due to CSS syntax not being valid in JSX.
function Example() {
return (
<div>
<span>This should be purple</span>
<br/>
<span>This should have a blue border</span>
<style type="text/css">{`
span {
color: purple;
}
span:nth-of-type(2){
color: inherit;
border: 2px solid blue;
}
`}</style>
</div>
);
}
ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"/>
I can't change style in ant-tooltip on nuxtjs. I access to class ant-tooltip-inner but it don't changing.
<div class="box-form-input">
<a-tooltip placement="topRight" trigger="focus">
<template slot="title">
<span>Please fill in your Fullname</span>
</template>
<a-input
v-model="full_name"
/>
</a-tooltip>
</div>
<style>
.ant-tooltip-inner {
background-color: red;
}
</style>
Overriding Antd tooltip in vue.js works as expected.
<template>
<div id="app">
<!-- remove h3 tag causes wrong arrow direction -->
<h3>try to remove this element.
<br>After removed, the tooltip arrow changed direction.
</h3>
<a-tooltip placement="left" title="wrong arrow direction">
<span>why don't use popper.js</span>
</a-tooltip>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld";
export default {
name: "App",
components: {
HelloWorld
}
};
</script>
<style>
.ant-tooltip-inner {
background-color: red;
}
</style>
See working CodeSandBox.
I'm using Bootstrap-Vue in a VueJS project, and it's being impossible using a class..
I have the next input
<div class="input__wrapper">
<b-form-input
v-model="idOrNameSelected"
class="textfield"
:class="{'input--empty': idOrNameSelected != null}"
#keydown.enter.native="onSubmit" />
<label
class="input__label">Service id or name</label>
</div>
In my script section I defined idOrNameSelected like:
data () {
return {
idOrNameSelected: ''
}
}
In my scss file I have a rule like
&:focus ~ .input__label,
&:not([value=""]) ~ .input__label {
top: 8px;
pointer-events: none;
}
And when I put any text in my input never is using this css rule, why?????
Thanks
Here's the problem. The CSS logic doesn't know about Vue observers or v-model so it doesn't update the way you think. Take a step back and try this simple example:
HTML
<input class="in" type="text" value="bar" />
<label class="lab">Test</label>
CSS
.in:not([value="foo"]) ~ .lab {
color: crimson;
}
As you can see, the label is now red. Now try changing the value="foo" you'll see the label switches colors. But, what you should note here is that it doesn't have any sort of 2-way binding on the CSS itself, but actually just takes the current value in the actual DOM.
To provide you with an actual solution, I would use a class binding in this case.
You can read about them here: https://v2.vuejs.org/v2/guide/class-and-style.html
Essentially, it allows you to dynamically add/remove a class based on some true condition. And you can actually use your v-model in there.
Here's an example of how I would do it:
<template>
<div id="app">
<input type="text" v-model="model">
<label :class="{error: model === ''}">Label</label>
</div>
</template>
<script>
export default {
name: "App",
data() {
return { model: "" };
}
};
</script>
<style scoped>
.error {
color: crimson;
}
</style>
#dev-cyprium is correct regarding Vue not placing the attribute value on the input element when using v-model (value is actually a domProp on the element)
There is a trick you can do with data attributes though:
<template>
<div>
<b-form-input id="the-input" v-model="value" :data-value="value"></b-form-input>
<label for="the-input">Hello World</label>
</div>
</template>
<style>
input.form-control ~ label {
color: red;
}
input.form-control[data-value=""] ~ label {
color: blue;
}
</style>
<script>
export default {
data() {
return {
value: ''
}
}
}
</script>
Mozilla says Web components consist of three main technologies:
Custom elements
Shadow DOM
HTML templates
Is number 3, "HTML templates", even necessary in light of ECMAscript's Template Literals?
Look at this example I got from James Milner:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Web Component</title>
<script type="text/javascript">
// We define an ES6 class that extends HTMLElement
class CounterElement extends HTMLElement{
constructor() {
super();
// Initialise the counter value
this.counter = 0;
// We attach an open shadow root to the custom element
const shadowRoot= this.attachShadow({mode: 'open'});
// We define some inline styles using a template string
const styles=`
:host {
position: relative;
font-family: sans-serif;
}
#counter-increment, #counter-decrement {
width: 60px;
height: 30px;
margin: 20px;
background: none;
border: 1px solid black;
}
#counter-value {
font-weight: bold;
}
`;
// We provide the shadow root with some HTML
shadowRoot.innerHTML = `
<style>${styles}</style>
<h3>Counter</h3>
<slot name='counter-content'>Button</slot>
<button id='counter-increment'> - </button>
<span id='counter-value'> 0 </span>
<button id='counter-decrement'> + </button>
`;
// We can query the shadow root for internal elements
// in this case the button
this.incrementButton = this.shadowRoot.querySelector('#counter-increment');
this.decrementButton = this.shadowRoot.querySelector('#counter-decrement');
this.counterValue = this.shadowRoot.querySelector('#counter-value');
// We can bind an event which references one of the class methods
this.incrementButton.addEventListener("click", this.decrement.bind(this));
this.decrementButton.addEventListener("click", this.increment.bind(this));
}
increment() {
this.counter++
this.invalidate();
}
decrement() {
this.counter--
this.invalidate();
}
// Call when the counter changes value
invalidate() {
this.counterValue.innerHTML = this.counter;
}
}
// This is where the actual element is defined for use in the DOM
customElements.define('counter-element', CounterElement);
</script>
</head>
<body>
<counter-element></counter-element>
</body>
</html>
Notice how he doesn't use an HTML template, but instead uses an ecmascript template literal to set the innerHTML of the shadowRoot.
After this, he uses querySelector to get internal elements of the shadowRoot and he ultimately adds event listeners to the increment and decrement buttons.
If you were to use a HTML template, instead of an ecmascript template literal, what does this gain you?
Conceptually, I'm struggling to find a situation where I'd prefer an HTML Template Element over an Ecmascript Template Literal.
Please advise.
The template tag is not 'required' for Web Components per se. It probably made more sense when HTML Imports were being pushed, allowing for importing and reusing HTML snippets, but that has since ceased. Here you could have imported a template and reused that.
It's important to note the specifications are designed to be standalone and can be used interdependently of each other also, which makes them versatile. The HTML tag has use cases outside of the realm of Web Components; it's useful because it allows you to define a piece of markup that doesn't render until instantiated via JavaScript later on. Indeed you can use templates without using any of the other specifications (Custom Elements, Shadow DOM etc).
The template tag can certainly be used in conjunction with the other specs. For example, we could have used it in the example shown to arguably make the code less imperative and more markup focused like so:
<template id="counterTemplate">
<style>
:host {
position: relative;
font-family: sans-serif;
}
#counter-increment, #counter-decrement {
width: 60px;
height: 30px;
margin: 20px;
background: none;
border: 1px solid black;
}
#counter-value {
font-weight: bold;
}
</style>
<h3>Counter</h3>
<slot name='counter-content'>Button</slot>
<button id='counter-increment'> - </button>
<span id='counter-value'> 0 </span>
<button id='counter-decrement'> + </button>
</template>
And then use this later in JavaScript like so:
const template = document.querySelector('#counterTemplate');
const counter = document.cloneNode(template);
shadowRoot.appendChild(counter);
The downside here is that it would require that the template existed in the DOM prior to the instantiation as it is relying on the #counterTemplate template being there. In some ways this makes the Custom Element less portable, hence why template literal might be more desirable. I haven't tested the performance of both, but my gut tells me that the template would possibly be more performant.
Disclaimer: I wrote the original blog post