Focus input inside stencil web-component from outside - web-component

Is it possible to propagate a focus() call on the html element of a web-component to its children (input)?
The web-component contains an input:
render() {
return (
<Host>
<div>
<input
...
/>
</div>
</Host>
);
}
I tried to call focus() on the web-component itself and to find the input element in the shadowdom and call focus() there but it didn't work. Is it not possible to focus an element inside shadow-dom?

Related

Vuetify how to add CSS class to HTML <input>

I have a <v-text-field> which collects user e-mail address and I need to add ym-record-keys CSS class to <input> element according to Yandex Metrica guideline. So I tried to add it like this but it adds class to the parent div. How can I add ym-record-keys class to HTML input element?
<v-text-field
v-model="item.customer.mail"
type="email"
:rules="emailRules"
hide-details="auto"
class="ym-record-keys"
solo
>
</v-text-field>
I need to achieve this output:
<input id="input-1055" type="email" class="ym-record-keys">
I needed this ability as well because another plugin I was using expects a certain class to exist on my input elements.
In order to achieve this I created a simple wrapper around Vuetify's v-text-field that adds the ability to pass in a class to the input element:
Create a TextInput.vue component:
<script>
import { VTextField } from 'vuetify/lib';
export default {
name: 'text-input',
extends: VTextField,
props: {
inputClass: {
note: 'A class that gets applied to the input',
},
},
mounted() {
// Applying the `class` to the input
// element below if it has values
const inputEl = this.$el.querySelector('input');
if (this.inputClass) {
inputEl.classList.add(this.inputClass);
}
},
};
</script>
Then used like this:
<text-input v-model="myModel" input-class="my-css-class" />
Which results in your input looking like this:
<input id="idGeneratedFromVuetify" type="text" class="my-css-class">
You can modify this to fit any other attributes you may want, or you could make it more dynamic if your use case needs that by using the spread operator with props.
You can try the following to bind the class
:class=["ym-record-keys"]
or
:class="'ym-record-keys'"

How to make autosuggest field look like bootstrap input?

How can I make the <vue-autosuggest> input look like the input from BootstrapVue (<b-input>)?
To apply the form-control class to vue-autosuggest's inner <input>, as required for the Bootstrap <input> styles, you could use the inputProps prop (automatically applied to the <input>):
<template>
<vue-autosuggest :input-props="inputProps">
...
</vue-autosuggest>
</template>
<script>
export default {
data() {
return {
inputProps: {
class: 'form-control',
}
}
}
}
</script>
Interestingly, that class used to be added by default in vue-autosuggest 1.x, but was removed in 2.x.
demo
You need to modify the the <input> tag of the vue-autosuggest component to include the class form-control from Vue-Bootstrap.
You will not be able to add this class directly to the component as the component wraps the input within a div block. Bootstrap CSS requires the the element to be of type input to properly match the CSS selectors.
If we look here https://github.com/darrenjennings/vue-autosuggest/blob/master/src/Autosuggest.vue at the component itself we see
<input
:type="internal_inputProps.type"
:value="internalValue"
:autocomplete="internal_inputProps.autocomplete"
:class="[isOpen ? `${componentAttrPrefix}__input--open` : '', internal_inputProps['class']]"
v-bind="internal_inputProps"
aria-autocomplete="list"
:aria-activedescendant="isOpen && currentIndex !== null ? `${componentAttrPrefix}__results-item--${currentIndex}` : ''"
:aria-controls="`${componentAttrIdAutosuggest}-${componentAttrPrefix}__results`"
#input="inputHandler"
#keydown="handleKeyStroke"
v-on="listeners"
>
This must be modified in your local version to include the bootstrap class.

Cannot data bind to <input> in Polymer 2.0

I am trying to get the user input from my <paper-input-container> using this code:
<paper-input-container id="nameInput">
<label slot="label">Your name</label>
<iron-input slot="input">
<input on-keydown="keypressed" value="{{first}}" id="nameBox">
</iron-input>
</paper-input-container>
In my properties, I have:
static get properties() {
return {
first:{
type:String,
value:''
}
}
}
and my keypressed function is:
keypressed(e) {
console.log(this.first);
}
I've been able to get it to work with the <paper-input> element, but I wasn't able to style it the way I wanted to. If you know how to increase the user input text size on paper-input in Polymer 2.0, that would also help.
Polymer's change notification requires an event naming convention that the native <input> does not follow, so the two-way data binding you seek requires special syntax, as shown here:
target-prop="{{hostProp::target-change-event}}"
In your case, that would be:
<input value="{{first::input}}>
This tells Polymer to set first equal to value when the input event occurs from the <input>. This is equivalent to:
const inputEl = this.shadowRoot.querySelector('input');
inputEl.addEventListener('input', () => this.first = value);
demo
Alternatively, you could bind first to <iron-input>.bindValue, which reflects the value of <input>:
<iron-input bind-value="{{first}}">
<input>
</iron-input>
demo
if you know how to increase the user input text size on paper-input in polymer 2.0, that would also help
The font-size of the <paper-input>'s inner <input> can be styled with the --paper-input-container-input CSS property of <paper-input-container>:
<dom-module id="x-foo">
<template>
<style>
paper-input {
--paper-input-container-input: {
font-size: 40px;
};
}
</style>
<paper-input label="My label" value="My value"></paper-input>
</template>
</dom-module>
demo

React css layouting inner components

Imagine that I have such html code:
<header>
<div class="header__logo logo">
<img class="logo__img" ...>
<span class="logo__status"...>
</div>
</header>
Here
.logo - is class that has styles, special for logo component.
.header-logo - has styles positioning logo inside the header.
So in react inside header component I would like to have something like:
<header>
<Logo className="header__logo" />
<header/>
But I can't since react is not automaticly handle className property.
Here I see this options:
Create a div wrapper to the Logo component and add this class to wrapper. As for me it is not an elegant way because it produce a lot of unnecessary divs.
Add logic to the Logo component, that will handle className property and append all outer classes to the root div inside the component. This is also ugly, because I have to add this boilerplate logic each time I want to layout a component inside some other component.
What is the react approach for solving such problems?
Yes, you cannot provide className attribute to a react Component. If you want to provide custom class to the same component, you can provide the className as a prop to the component which is added as a className in the child component.
I believe u need to do something like this.
var Header = React.createClass({
render: function() {
return (
<header>
<Logo customClass="header__logo logo"/>
</header>
);
}
});
var Logo = React.createClass({
render: function() {
return (
<div className={this.props.customClass}>
<img className="logo__img" />
<span className="logo__status" ></span>
</div>
);
}
});
Let me know if this is what you wanted to know or something else.

Changing CSS Dynamically in Angular Directive?

I have a directive that I am currently making that is an input field of type text. Now I would like this field's width to grow dynamically if the text gets too big for the input field. Below is my directive:
.directive('dynamicInput', function () {
return {
restrict: 'E',
template: '<input type="text" style="display: inherit;" class="form-control" required />',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
console.log('ATTRS: ', attrs);
console.log('ELEMENT: ', element);
if(attrs.width){
console.log('WiDTH: ', attrs);
}
}
}
});
Here is the plunker:
Change Width Dynamically.
I know you can change the CSS class youre using on your element object, however, I dont just want to change the class I want to basically dynamically change the width as the text increases inside the box. So the question is: How can I change the CSS on every fire of the 'onchange' event to the length of the text being entered? Also, I would like to keep this contained within a directive, so that I am not relying on anything within the parent scope in which its declared in.
You can get your input element, and then do whatever you want with it using vanilla javascript or angular object element.
Like this (link function):
var inputEl = angular.element(element.children()[0]);
inputEl.on('keydown', function() {
inputEl.attr('size', inputEl.val().length);
});
This does not do exactly what you want I think, but you get the idea.
You have access to the element inside the directive, so this kind of logic is very easy to implement without depending on anything else but itself.
Modified plunker.

Resources