what is the proper way to interact with inner components within the shadowDom using lit-element? - polymer-3.x

I am trying to use paper-dialog within my custom component.
I want to be able to open the dialog from outside the component. What is the best way to do this? (all the examples work directly on the component)
Also the dialog requires me to call "open()" on it to open it.
In the examples I found I found:
this.$.dialog.open();
But this doesn't seem to work with lit-element
I got it to work using shadowRoot, not sure this is the best option:
render() {
return html`
<style>
</style>
<paper-dialog id="dialog">
<h2>Content</h2>
</paper-dialog>
`;
}
firstUpdated(changedProperties) {
console.log("firstUpdated called")
if (this.shown == "true")
{
// this.$.dialog.open();
this.shadowRoot.getElementById("dialog").open()
}
}
I added a property to my element called "shown"
static get properties() {
return {
shown: Boolean,
Thinking I could pass this from the outside into my component, but it doesnt seem to do the trick either (I can set it once with the custom element propery, but changes to it from the out side dont seem to work.

Generally, if you are aggregating a dialog within an element that has other UI elements then you shouldn't be showing/hiding the dialog from outside the element - the event that triggers the dialog should be raised and handled with the containing element.
That said, if it's absolutely necessary, then I prefer a "showDialog" method (not a property). Closing the dialog should be triggered by a dialog button or loss of focus, so you don't need to expose a close method.

Related

Disable all horizontal scrollbars in Cypress

Is there a way to apply a style to all elements in Cypress? Like one would do with the star selector:
* {
overflow-x: hidden;
}
I need this for visual regression snapshots, because of scrollbars that appear, and haven't been able to find something simple and elegant in Cypress. Currently doing something like this:
cy.get('[data-cy="some-tag"]').invoke('css', 'overflow-x', 'hidden');
But of course this isn't great, because every element that has scrollbars has to be targetted and set.
You can change the DOM just before any screenshot is taken by using onBeforeScreenshot and onAfterScreenshot callbacks. This will hide the scrollbar on the element the screenshot command was called on, and restore it afterwards:
Cypress.Screenshot.defaults({
onBeforeScreenshot($el) {
$el.css('overflow', 'hidden');
},
onAfterScreenshot($el, props) {
$el.css('overflow', 'auto');
},
});
You can put this function in support/index.js file since it is loaded before any test files.
Note: if you just call cy.screenshot() then the $el will be the document and you can use .find(<selector>) command to get any child elements within the page.
Works great with cypress-visual-regression plugin.
Reference: https://docs.cypress.io/api/cypress-api/screenshot-api#Change-the-DOM-using-onBeforeScreenshot-and-onAfterScreenshot

Nextjs: removing element on unmount of a component

Any idea how does one remove an element from the dom in nextjs on componentwillunmount?
I'm using the Head component to load a JS script that generates an element on a page.
When I navigate to another page, that element still stays so I need to remove it.
I thought of using componentwillunmount and document.getelementbyclassname, but it doesn't work in nextjs for some reason.
Any thoughts on how to solve it?
This doesn't do anything, even though the button is being picked up:
componentDidMount() {
oldButton2 = document.getElementsByClassName("button");
}
componentWillUnmount() {
if (oldButton2.parentNode) {
oldButton2.parentNode.removeChild(oldButton2);
}
}

How to add custom css to ngx-bootstrap modal with modalService useage(see reasons below)?

I have a very niche use-case. I have to add a modal animation like this:
regular css animation
But I need to have a component (our own filter component for a datatable) inside said modal.
So I need to use the ModalService. But this service is only attaching my custom config like this:
toggleFilter = () => {
const modalOptions: ModalOptions = {
initialState: {
labels: this.datatableLabels, // needed for filter to have labels
filterGroups: this.filterGroups // needed to add filterGroups
},
class: 'filter-modal' // this sould be my custom class
};
this.bsModalRef = this.modalService.show(FilterComponent, modalOptions);
}
to modal-content and the above mentioned animation and styling uses divs above that. Not only it's working when encapsulation set toViewEncapsulation.None then it screws our other modals as well, since I cannot apply correct classes to the one I need to mess with.
How can I overcome this issue I'm having?
Instead of using the ModalService and open desired embedded component within the modal. You can basically inject the desired component into the body of the modal while using directive instead -> Here you are declaring the whole modal layout -> you can modify all the related classes so it's easier to modify a modal and have your ViewEncapsulation untuched so other modals are unaffected.

How can I verify that a clicked element is a GoJS picture part and not an overlaid element?

I'm trying to implement a mask over my GoJS diagram when a details sidepanel is shown. This requires stopping propagation of click events to diagram parts beneath. How can I verify that the event target is the picture part and not the mask element which overlays it?
I've tried using the pointer-events CSS property, but that doesn't do the job.
Simplified markup:
<div id="diagramWrapper"></div>
<div id="sidebar-mask"></div>
Script snippet:
buildGo(go.Picture, {
source: 'images/icons/simplify-icon.png',
...,
click: function (e, node) {
if (e.diagram === node.part) { <-- this, right here, isn't right
let nodesToRemove = getLinkedNodes(e, node.part.data.key);
removeNodes(nodesToRemove);
}
}
})
I haven't gotten my head around the two-letter object properties that GoJS uses, which prevents me from easily finding the right property. Any insight into that would help greatly.
I suggest that you just set Diagram.isEnabled to false when you show a modal dialog. Be sure to set it back to true when the modal UI goes away for any reason. More possibilites are listed at https://gojs.net/latest/intro/permissions.html.
As documented at https://gojs.net/latest/intro/index.html#DevelopingYourDiagram, you should only be using documented API names in your code -- not the minified two character names which will change with each build.

Ember Responsive iFrame component

I'm embedding a PPT into my app, so I'd like a responsive iFrame. Can't get this working with the CSS based approached I've looked at here.
I'm thinking the best way would be just to make a simple component with height and width properties. Can I make these computed properties / observers that listen and update on the browser resize?
Or would I need to create a resize event and update the properties on the event?
A little code example would be much appreciated!
Thanks
I would recommend to use a CSS based approach, but you can use a component and use the resize event. Basically you would add the event listeners to window in your didInsertElement hook, and remove them in your willDestroyElement hook. Just use jQuery's .on() and .off().
onResize() {
// do whatever you want to calculate your values
set(this, 'my-frame-with', ...);
},
init() {
set(this, 'boundOnResize', get(this, 'onResize').bind(this));
},
didInsertElement() {
jQuery(window).on('resize', get(this, 'boundOnResize'));
},
willDestroyElement() {
jQuery(window).off('resize', get(this, 'boundOnResize'));
}
You can not use computed properties for this because they need to depend on observable properties. This will not work for plain JS properties, because this in an ember functionality. So you need to kind of wrap them like this.

Resources