How can I style the arrow of react-multi-select-component? - javascript

I'm looking to customize the downward arrow icon in the react multi-select component. In the documentation, there is an attribute ArrowRenderer which takes reactNode as a value.
How to configure this to customize the styles?
Dropdown looks like:
Any help would be highly appreciated

Put your react node in div tag with specific class(Name) and then access that class by css selectors.
<MultiSelect
arrowRenderer={()=>
<div className="custom-arrow" >
<CustomArrowComponent />
</div>
}
/>

Related

Attach a sibling component using ref of a component

I am using a library in my page, I wish to update the input component of this library when it is rendered. More specifically I wish to add an icon to the input box of this library.
The library doesn't provide any slots to perform the same but what we it does give us a ref for the input element. I wish to use this to update the html by attaching an icon as a sibling of the ref.
I want to know if this is possible and a base guide as to how I achieve it
I have tried to use document to perform the same but I feel vue should be able to do it and the state will be consistent post that.
App.Vue
// App.vue (Parent)
<template>
<Component ref="componentRef" />
</template>
//Component.vue (Child)
<template>
<div id="iconMountPoint">
</div>
<input ref="inputEleRef">
</template>

Vue - Surround a component with a tag dynamically

What I'm trying to say is the v-if directive can make an entire component (and all its content) disappear based on a condition.
My question is:
is there a way to make only the surrounding tag or component disappear, without removing its content?
You can use dynamic component and :is prop with vue-fragment when you need a root-less component, or directly vue-fragment if that's just what you need.
Another option is to manipulate the DOM directly.
No, you can't do it. The first thing came to my mind is to move your content in separate component to avoid code duplicating and do something like this
<wrapper v-if="condition">
<child />
</wrapper>
<child v-else />
If you provide some details on why do you need this, probably we can find a better solution.
2022 Working solution:
Create a universal "template wrapper" component:
<!-- VTemplate.vue -->
<template>
<slot></slot>
</template>
Use it in pair with the <component> component:
<script setup>
import VTemplate from './VTemplate.vue'
</script>
<component :is="condition ? 'li' : VTemplate">Your content</component>
<!-- Where 'li' is your wrapper tag/component that you want to conditionally hide but not its content -->
Bonus:
<component :is="condition ? 'li' : VTemplate" :class={'list-item': condition}>
Your content
</component>
<!-- You can assign attributes like the class to it as well -->
P.s. Also, if anyone knows how to import the <template> component directly or at least how to use it in <component :is> please enlighten :)

How to pass class through an Angular Custom component

So I have a tooltip custom component that I need to be able to pass a class through to the underlying html, but not sure how to do it. Currently the tooltip (custom angular component) html looks like this:
<div role="tooltip" aria-haspopup="true" class="tooltip tooltip-md tooltip-bottom-right">
<clr-icon class="icon-shape is-solid" shape="info-circle" size="20"></clr-icon>
<div class="tooltip-content">
<ng-content></ng-content>
</div>
</div>
Using this custom component is like:
<tooltip>This is the text displayed.</tooltip>
What I need to be able to do is pass in a position so that the tooltip isn't always at bottom-right. So I need to pass either a property or class or something so that in the custom component I can change the class of my div to "tooltip-top-right", "tooltip-bottom-left", etc... like so:
<tooltip class="tooltip-bottom-left">Tooltip text</tooltip>
or
<tooltip position="bottom-left">Tooltip text</tooltip>
And then inside the component's .ts or .html, assign the appropriate class to my div.
Thanks in advance!
You could use mat-tooltip for this case.
https://material.angular.io/components/tooltip/overview
It has built in matTooltipPosition directive so you wouldnt need to add any class to it.
1) Import the appropriate module in app.module.ts
import {MatTooltipModule} from '#angular/material/tooltip';
2) Use the mat-tooltip selector and the matTooltipPosition input property
<button mat-raised-button
matTooltip="Info about the action"
[matTooltipPosition]='where you want it to be'
aria-label="Button that displays a tooltip when focused or hovered over">
Action
</button>
more examples:
https://material.angular.io/components/tooltip/examples

Include component from parent app in component contained in node_modules directory

I am working on Vue app that incorporates Vue Bootstrap Calendar, and I would like to be able to override the content of the day cell (handled by the Day.vue component) to add my own custom content inside. My thought was initially to modify the Day component to include <slot></slot> tags and pass in the custom content that way.
The problem has to do with accessing the Day component. To include the calendar in your app, you include the Calendar.vue component, which includes Week.vue, which in turn includes Day.vue. As I understand slots, I have to have the child component (Day.vue in this case) included in the component where I'm passing the data, which means it would need to be included in my own component.
If this is not possible, my other thought is to perhaps modify the library by adding another configuration prop (something like dayCustomContent) to the Calendar.vue that indicates that the Day cell content is custom content, pass that in to Calendar.vue, and then down to Day.vue, and then in the Day.vue template, have a v-if conditional based on this prop that either displays the custom content or the default cell content, something like:
<template>
<div class="day-cell" v-if="dayCustomContent">
...my custom content here...
</div>
<div class="day-cell" v-else>
...default events from my.events goes here...
</div>
</template>
I would probably then need to define a custom component to render whatever custom content I want to display, and somehow include that component within Day.vue.
So to sum up, my questions are these:
1) Is there a way to do what I need with slots?
2) For my second option, am I going down the right path? I'm open to suggestions.
UPDATE: I was able to get this done by adding a boolean customDayContent prop in Calendar.vue like so and passing it down to Week.vue and then to Day.vue:
<template>
...
<div class="dates" ref="dates">
<Week
v-for="(week, index) in Weeks"
:firstDay="firstDay"
:key="week + index"
:week="week"
:canAddEvent="canAddEvent"
:canDeleteEvent="canDeleteEvent"
:customDayContent="customDayContent"
:displayWeekNumber="displayWeekNumber"
#eventAdded="eventAdded"
#eventDeleted="eventDeleted"
></Week>
</div>
...
</template>
<script>
export default {
...
props: {
...
customDayContent: {
type: Boolean,
default: false
}
},
}
</script>
and then in Day.vue, do like I had suggested with v-if:
<template>
<div class="day-cell" v-if="customDayContent">
<custom-day></custom-day>
</div>
<div
class="day-cell"
:class="{'today' : day.isToday, 'current-month' : day.isCurrentMonth, 'weekend': day.isWeekEnd, 'selected-day':isDaySelected}"
#click="showDayOptions"
v-else
>
... existing code goes here...
</div>
</template>
The last part is referencing the CustomDay.vue component referenced in my v-if block. I want the user to be able to define the content of their own custom CustomDay.vue template in their own parent app. However, I'm having trouble trying to figure out how to do that. Following the pattern of including components already in this component, I added this in the components section of Day.vue:
CustomDay: require("../../../../src/Components/CustomDay.vue").default
? require("../../../../src/Components/CustomDay.vue").default
: require("../../../../src/Components/CustomDay.vue")
However, no matter what I try along these lines, I get an error that the relative module was not found. On top of that, I need to add it to the componentsarray only if customDayContent is true. What is the best way to do that? In a watcher or computer property, perhaps? Or another way?

Why the scoped style in vue is useless? The parent element style still affect the child element

The Parent element style:
.container {
margin: 20px;
border:1px solid #f1f1f1;
font-size:14px;
font-weight:normal;
The child element style:
.container{}
But the child element style should be rendered like this:
why there are two data-v-*** in the child element and use the parent container style?
I know it's been ages, but I am going to add something here to help future people.
I encountered the same thing. Basically, I was nesting components within components, and being all fancy with scoped so that each component had a class called .container ... well to my surprise when rendering the styles started conflicting. I thought scoped was meant to fix this...
But apparently by design, that's not the case:
https://vue-loader.vuejs.org/guide/scoped-css.html#mixing-local-and-global-styles
With scoped, the parent component's styles will not leak into child components. However, a child component's root node will be affected by both the parent's scoped CSS and the child's scoped CSS. This is by design so that the parent can style the child root element for layout purposes.
So for instance, I have two components nested, I end up with this:
I have a view loading in two components:
<template>
<div>
<login-splash />
<login-form />
</div>
</template>
The two included are like this:
<template>
<div class="container">
<div>
<h1 class="big">Title</h1>
<h2 class="small">Subtitle</h2>
</div>
</div>
</template>
<template>
<div class="container">
<form class="form">
<label class="label">Username
<input class="input" type="input" name="username">
</label>
<label class="label">Password
<input class="input" type="password" name="password">
</label>
Forgot Password
</form>
<button-submit />
</div>
</template>
The issue is with button-submit which looks like this:
<template>
<div class="container">
<button class="button">Button</button>
</div>
</template>
Each of these files has scoped SCSS and it ends up producing the issue stated above.
This all ladders back to https://v2.vuejs.org/v2/style-guide/#Component-style-scoping-essential
Basically the solution is "use a class naming based solution like bem"... which isn't what anyone wants to hear when they see and use scoped and think it's a silver bullet... I know... but as with all web development, you gotta do what you gotta do.
If you are developing a large project, working with other developers, or sometimes include 3rd-party HTML/CSS (e.g. from Auth0), consistent scoping will ensure that your styles only apply to the components they are meant for.
Beyond the scoped attribute, using unique class names can help ensure that 3rd-party CSS does not apply to your own HTML. For example, many projects use the button, btn, or icon class names, so even if not using a strategy such as BEM, adding an app-specific and/or component-specific prefix (e.g. ButtonClose-icon) can provide some protection.
An alternative is to use CSS Modules, as stated in this answer:
https://stackoverflow.com/a/45900067/1034494
This ends up producing something like this:
There are two data-v attributes because you are specifying a CSS selector in the child component styles. The fact that it's empty does not change that. As long as you don't scope both components' styles, they will of course influence each other, especially if you choose identical class names.

Categories

Resources