How to extend a react component from a library - javascript

I want to extend the FormControl component from react-bootstrap. Importantly though, I want my extended component to replace the react-bootstrap component, so that importing from the react-bootstrap package actually imports my extended component.
Mostly I need to change the render method to include an absolutely-positioned counter for input[type=text] and textarea nodes, by looking at their inputRef prop.
What is the best way to do this?

Reacts core idea is composability over inheritance . So you wrap you component around the bootstrap component and use your component everywhere .

For extending, this should do:
import MyComponent from 'react-bootstrap'
class NewComponent extends MyComponent {
}
Pretty sure you can't overwrite an import from a package like you want though because it makes no sense to do so. Just import from the new component instead.
Why exactly do you want to overwrite the existing instead of just providing a wrapping component that inherits it?

Related

How to invoke Quasar dialog from external component?

I'm using Vue.js 2.x + Quasar 1.x with http-vue-loader (so no build tools) at the moment.
I put a q-dialog in a separate component - let's call it MyComponent, and when I just hook it up in a parent component like so:
<my-component></my-component>
then nothing happens, it's not even in the DOM... When I just insert the whole q-dialog template into the parent component, without having its separate external component, everything works just fine with a simple v-model.
So I imported the component successfully, that part is fine.
I was trying to invoke it when I click on a button, but I can't really communicate with the component this way.
Now I've come across two separate ways of creating dialogs in Quasar, the first one is using the component when it's not in its separate component. The second one seems to be the one I might need for a separate dialog component. The problem is that importing an external component with vue-http-loader looks like this:
components: {
'my-component': httpVueLoader('/components/MyComponent.vue'),
},
while according to the Quasar docs, it should look like this:
import CustomComponent from '..path.to.component..'
...
this.$q.dialog({
component: CustomComponent,
...
The docs are a bit confusing to me as well. :/
Unfortunately, I can't see the CustomComponent code, which is required to be created following an interface, which is described in this docpage under the warning. Make sure that CustomComponent is valid.
P.S. - Both of those ways do the same thing but in different ways. With the first one, you'll import that component to another and set him in the template, but with the second one, you'll call a tool, that creates a new modal with passed parameters. But the second one doesn't have all functionality compared to the first one.

Importing CSS in one component is adding CSS affect to other Components. How and Why?

I am from Angular Background and as far as I know. Each component has its own beauty and till we import a CSS file inside itthose CSS classes should not be applied even if we add to HTML Elements to the component in case we have not added or imported any CSS files for classes used inside this new/2nd component.
What I did in React was made 2 components - Home1.js and Home2.js. When I am importing a css file named Home.css to Home1 Component and NOT to Home2.js component - How in the world is those CSS classes affect being applied even too Home2 Component. This is sheer absurd.
That's why I am importing someFile.css **specifically** to the component where I want its affect to be there. This provided a kind of encapsulation affect, which I am seeing is failing. Now, someone can explain me how in the world, wherever I am not importing someFile.css, there also the classes are having affect?
Home1.js
import React, { Component } from 'react';
import './home.css';
class Home1 extends Component {
render() {
return (
<div>
<div className="red">1...</div>
<div className="green">2...</div>
<button>click</button>
</div>
)
}
}
export default Home1;
Home2.js
import React, {useState} from 'react';
const Home2 = () => {
return (
<div>
<div className="red">1..</div>
<div className="green">2...</div>
<button>click</button>
</div>
)
}
export default Home2;
Result:
Angular does it through viewEncapsulation, but this notion does not exists in react. You either need to scope your css manually by adding a main class on the top node of your component, or use a library that can do it for you (haven't tried it, you can refer to #Abdelrhman Arnos comment).
In React, like someone already had commented, you need the CSS modules to handle your problem. Actually, it's already included in the css-loader, which is a very basic module you need for webpack to handle the CSS files in the bundling process. I am not sure if you build your React app from the ground up, but I am quite sure you already had this module in your project.
{
loader: 'css-loader',
...
options: {
// Automatically enable css modules for files satisfying `/\.module\.\w+$/i` RegExp.
modules: { auto: true },
},
},
I believe you are an experienced web app programmer, and just complaining about the design of the React, but I would like to provide a little basic knowledge of browser rendering mechanism here for whom just start learning web programming and thinking about the same question.
The basic of the rendering engine in the browser is interpreting the HTML, XML documents. After loading assets by such as <script>, <style>. There are a couple of steps to complete the rendering. The step to apply CSS rules on pixels is Style calculations.
What browser does is very simple, it takes the CSS files, applies the rules, something about the scope of the styles really rely on the practice of library/framework, you can imagine that the best they can do is preprocessing the CSS files and add some unique properties to each CSS rules corresponding to the specific class names it can find in your code.
Where to import the CSS file is just for readability and maintainability. In the old times, when people still program web app with jQuery or pure JS, you just include the CSS file in the .html file, maybe it forces you to care about the naming of the classes and styles earlier, but actually we also have the same problems when you try to separate it for bigger projects.

Is npm react-bootstrap automatically scoped to a component?

I am using react with react-bootstrap. My question now is, are react-bootstrap components automatically scoped to the component that you are using it in? Or am I asking a totally wrong question here? Because as I am aware that those bootstrap components are native react components, I am normally importing them like this:
import {Navbar, Nav, NavItem} from 'react-bootstrap';
but would it also be possible, to customize them or create own styles in a .css file (and overwrite other react-boostrap component styles) and import them into another component? I know they would not be react-bootstrap components then anymore, but would this be possible? E.g I could customize a button react-bootstrap component class in some .css file and import it in my module, would it overwrite native react-bootstrap classes?

How to list registered icons in angular components?

If Component A registered Icon X using
import { MatIconRegistry } from '#angular/material';
import { DomSanitizer } from '#angular/platform-browser';
and if I want to use Icon X in Component B without registering.
so how can I list all registered icons from all available components? so that I can see registered icons and use from that list.
I know one solution would be registering icons in app.component.ts or root-component would solve this problem, but I have some implementation restriction and don't want to do this way.
Looking at the implementation, these are the only getters MatIconRegistry has:
So, no it doesn't seem to be possible. You can get an icon if you know its' URL or name.

Using ReactJS to render components within Aurelia

Goal
To create, what is in my opinion, an almost perfect framework I want to use Aurelia in combination with ReactJS (mainly just creating components which can be used within Aurelia).
To achieve this there are several options (See http://ilikekillnerds.com/2015/03/how-to-use-react-js-in-aurelia/ and https://github.com/bryanrsmith/aurelia-react-loader)
The first option has the downside that the component is wrapped within a custom element, which I don't want to do for all elements I plan on creating. The second option is pretty nice, wasn't it that the component is generated from a component instance (instead of the html markup).
Work already done
The thing I've been trying to do now is to create a custom attribute which makes ReactJS render the innerHTML of the specific element.
import { customAttribute, inject } from 'aurelia-framework';
import React from 'react';
import ReactDOM from 'react-dom';
// ToDo: have one file to import all dependent components
import { MyReactComponent } from 'components/my-react-component';
#inject(Element)
#customAttribute('react-content')
export default class ReactCustomAttribute {
constructor (element) {
console.log(element.innerHTML);
this.element = element;
ReactDOM.render(
<div dangerouslySetInnerHTML={{__html: this.element.innerHTML}}></div>,
this.element);
// ReactDOM.render(
// <MyReactComponent><h2>lol</h2><h2>lol</h2></MyReactComponent>,
// this.element);
}
}
If the solution above would work I'd be absolutely happy. But, as Aurelia wants to comply to web standards it puts all element names to lowercase. (this.element.innerHTML returns <myreactcomponent><h2>lol</h2><h2>lol</h2></myreactcomponent>) This way ReactJS can't render the components.
The piece I've commented out in the code snippet above actually works.
Questions
How can I get ReactJS to properly render these components?
Is it possible to configure Aurelia to not turn element names to lowercase?
Is it possible for ReactJS to see the relationship between html elements written in kebab-case and javascript class names?
How can I get ReactJS to properly render these components?
You have to do that in attached() method of your aurelia view model.
Is it possible to configure Aurelia to not turn element names to lowercase?
The correct answer is "there is no case"
Tag and attribute names are case insensitive in HTML.
And Aurelia is standards based.
Is it possible for ReactJS to see the relationship between html elements written in kebab-case and javascript class names?
This one will need some teaching.
You can look at how Aurelia treats naming conventions in the source
https://github.com/aurelia/templating/blob/master/src/html-behavior.js
Attached method of aurelia will not wait until complete DOM is ready, if we are doing any DOM manipulations inside attached will fail..

Categories

Resources