I have a custom web element (my-button) created with stencil js with shadowDom.
<form>
<input type="text" name="field1"/>
<input type="password" name="field2"/>
<my-button type="submit">click me</my-button>
</form>
If i click "Enter" key in any of <input> fields - onsubmit event must be fired. But this doesn't happen if <my-button> uses shadowDom. Without shadowDom it works as a typical <button type="submit">.
Is there a way to make <my-button> with shadowDom works as native <button type="submit">?
Found few solutins here Submitting a form using a custom button using HTML Web Components but the first solution is for native web elements (didn't find how to imlement the same in Stencil Js), the second solution doesn't work in Safari since Safari doesn't support is attribute so far.
The two main options I've seen:
Don't use Shadow DOM on that component. Stencil has an option for scoped styles which will prevent the styles from affecting anything outside the component but the style can be changed from outside.
Add a hidden native button element as a sibling of the web component in your component's connectedCallback. This preserves the advantages of using Shadow DOM but it does "leak" HTML which might become a problem.
The ideal solution would be for Stencil to support formAssociated(). There is an open issue (including a first implementation and workarounds from the great #johnjenkins), give it a thumbs up if you'd like to see it: https://github.com/ionic-team/stencil/issues/2284
Related
I want to make a responsive website using react, should i use media queries for change layout and set display to 'none' for some components in mobile ( like regular html and css ), or do that in-react and don't render that component rather than don't display it using css ?
for example, for a menu, if user clicked on the menu button, change display property of menu from 'none' to 'block'
<ul id="menu">
<li>one</li>
<li>one</li>
</ul>
toggle the 'open' in the classList of the DOM Node
and in the css
.menu li {
display: none;
}
.menu.open li {
display: block;
}
or like this,
use state and if user clicked on the menu button, change the state and make react to render the menu
[open,setOpen] = useState(false);
open?<Menu />:'';
which one is a better approach ? which one is recommended
and one more question, using 'refs' for accessing the DOM nodes in react is better than use traditional document.getElementById() ?
My initial reaction is that you probably aren't building anything that absolutely requires the most performant solution, so hiding an element via CSS versus eliminating it from the DOM via React is not going to matter much in the long run. My recommendation is do whatever you can to get your project complete and then worry about performance if your use-case warrants it.
With regards to your specific example, it is probably better to just toggle the element's existence with React versus applying a class to toggle the display property. My reasoning for that is because both operations will require a DOM manipulation (React would have to either add the list element or it would have to update the className value). Using a CSS class to toggle the display will also have a secondary task of applying the new display value which causes another reflow of the content.
React solution: Update DOM to insert new node.
CSS solution: Update DOM to add className. Reflow content based on new display property.
Regarding your second question about $refs...
Using $refs will be better than document.getElementById. The $refs object maintains an in-memory reference to HTML nodes that need to be manipulated. document.getElementById will require traversing the DOM tree to find the element, where as using $refs simply looks up the node via a named property.
If it's possible to do in CSS, always use CSS. JS is expensive than CSS in terms of loading and rendering. For your requirement, you need layout change depending on the device it's loaded. So use media queries and CSS Grids to do that without using JS.
Refs is the react way to get DOM element. So please use that instead of using methods like document.getElementById().
I am new to the React javascript framework and have a question about styling using CSS.
Using jQuery, my old workflow was to pick an element on the screen, inspect it in Chrome, note the selector/s that triggered the styling, change the element styling in the browser, and then save it to css/sass etc. If the widget had a hover-state I could make the element visible to see what it looked like.
However using React, and especially for components that someone else has coded, where the component does a 'pop-up' etc, I can't manipulate the DOM to see the component because it is removed from the DOM before I can inspect it.
Now of course I could read the external library code, work out how it works, but CSS inheritance means it would take some time to work out exactly is happening and this seems to be slower than what I was doing before - especially for a simple change.
So my question is, what is the preferred workflow for overloading the CSS for DOM elements that are removed before they can be inspected?
I've written a few Polymer components so far and for my more complicated stuff I love how their styling is isolated from the rest of the page. It's been much easier to use them across multiple apps.
However, today I'm creating a super simple component, and I'm realizing that I'd really like to have the page's styles bleed in. I've got a component that packages up a bunch of logic, but just renders a basic <a href> link. Is it possible through CSS or other means to have that link inherit its styling from the rest of the page?
appyAuthorStyles used to be great for this. Unfortunately, it's no longer in the Shadow DOM spec.
Your two solutions are:
Create a small stylesheet (e.g. shared.css) that includes the common rules the page and component use.
Use ::shadow and /deep/ to style the link from the outside, the same way as the page styles its links.
On my ASP.NET site, <input type="file"> renders like this in IE11 (an oldschool look):
However, I want it to look like this (more modern look):
When trying <input type="file"> in the same IE11 elsewhere, in e.g. JSFiddle, it looks like I want it to (the more modern look).
I tried tracing CSS styles using F12 dev tools, but I cannot see any styles resulting in the oldschool look.
I'm using <!DOCTYPE html>.
My question: What might be causing the oldschool look?
IE11 Renders that way.
If you want to change it you should use CSS, but it usually isn't easy.
What I usually do is to create my own fake component, with an input type text and a button styled the way I want.
I also have a input type file hidden, when I push my styled button I send via javascript a click to hidden input type file. When the file is selected I update my styled input type text with selected file name.
I noticed my links are having ui-link appended to it. Interfering with CSS, as jQuery Mobile has styled it differently. I could overwrite, but all I need is to remove the class. Instead of removing after it has been added, is it possible to prevent jQuery Mobile from adding the class?
One way is http://forum.jquery.com/topic/a-s-still-styled-as-ui-link-despite-being-in-a-container-w-data-role-none but I prefer not to edit jQuery Mobile source
Just glancing at the jQuery Mobile source for v1.1.1... I see that links are enhanced in the pagecreate and create events except for the following:
.not(".ui-btn, .ui-link-inherit, :jqmData(role='none'), :jqmData(role='nojs')")
Meaning, you should be able to avoid enhancement by adding a .ui-btn or .ui-link-inherit class, or adding a data-role="none" or data-role="nojs" attribute to the links.
It also calls .jqmEnhanceable() on the links, which in turn calls $.mobile.enhanceable() and checks to make sure it is OK to enhance by traversing the parent elements. Have you tried adding data-role="none" to the links themselves or a wrapper element?
Of course, you can remove the classes after jQuery Mobile has initalized, however, I would advise against this as it may have a negative effect on some of jQM's features. I would venture a guess that jQM uses .ui-link for more than just styling.
$(document).bind('pageinit', function(event){
$('.ui-link').removeClass('ui-link');
});