Use different profile image sizes in Microsoft Graph Toolkit - reactjs

In my MGT React SharePoint WebPart, I would like to have some of the profile images displayed with large size (48px), while other images displayed with medium size (36px).
I know the property avatarSize can be used, but this only supports Small, Large or Auto. And in the mgt-person css class, I can specify --avatar-size: 36px. But since this css class affects all person components on the page, all profile images are now sized 36px. And there is no support for specifying a css class on the person component itself.
Do you know if this can be achieved another way?
UPDATE:
I managed to solve this myself with the help from this article:
https://developer.microsoft.com/en-us/graph/blogs/a-lap-around-microsoft-graph-toolkit-day-4-customizing-components/
Using the following definitions in my scss file, it can adjust the avatar size based on for example a WebPart property:
.personsmall mgt-person {
--avatar-size: 24px;
}
.personmedium mgt-person {
--avatar-size: 36px;
}
.personlarge mgt-person {
--avatar-size: 48px;
}
And in my tsx file, it looks like this:
public render(): React.ReactElement<IRolesProps> {
let cf: CommonFunctions = new CommonFunctions();
return (
<div className={this._getAvatarSizeClass(this.props.roleSize)}>
{this.props.roles && this.props.roles.map((val) => {
return (
<Stack className={styles.roleSpacing}>
<Text className={styles.roleHeader} variant="xLarge">{val.role}</Text>
<Person userId={val.person} view=PersonViewType.twolines fetchImage={true} showPresence={true}
personCardInteraction={PersonCardInteraction.hover} line2Property="mail"></Person>
</Stack>);
})}
</div>
);
}
private _getAvatarSizeClass(avatarSize: AvatarSize): any {
if (avatarSize) {
switch (avatarSize) {
case AvatarSize.Small:
return styles.personsmall;
case AvatarSize.Medium:
return styles.personmedium;
case AvatarSize.Large:
return styles.personlarge;
default:
break;
}
}
}
Hope this helps someone else struggling with this.

There is a styling guide: MGT Styling guide
You can simply create a CSS rule and call the desired component. Example from the styling guide
mgt-person {
--avatar-size: 34px;
}
Thus you should be able to combine this with a CSS class such as:
mgt-person.my-avatar-size {
--avatar-size:42px;
}
Since all React components expose a className attribute this should work:
<Person className='my-avatar-size'></Person>
UPDATE
Since, for some reason, there is no className attribute available, why don't you use a data- attribute instead:
mgt-person[data-cssclass='my-avatar-size']{
--avatar-size:42px;
}
<Person data-cssclass='my-avatar-size'></Person>
Hacky, but should work. Also, you might want to look at the actual generated HTML and use this.

Related

How to use a dynamic background image URL with Tailwind CSS and React

In React, I'm unable to use a URL string in my Tailwind background image class:
1: Not working, getting error "can't resolve ${link}"
const link = "https://cdn.test.net/test.jpg";
<div className={`px-4 py-1 h-[22rem] lg:h-[28vw] bg-cover bg-center bg-[url('${link}')]`}></div
2: Working, but I need to use a variable inside my bg- class.
const link = "bg-[url('https://cdn.test.net/test.jpg')]";
<div className={`px-4 py-1 h-[22rem] lg:h-[28vw] bg-cover bg-center ${link}`}></div>
I still need to be able to use ${link} inside bg-[url('${link}')].
Here is how it looks for me
The given example should be working fine.
Working fine for me.
The CSS file generated by Tailwind will only include classes that it recognizes when it scans your code, which means that dynamically generated classes (e.g. bg-[url('${link}')]) will not be included.
If you only have a few different background images, you could add them to your tailwind.config.js and switch between them:
module.exports = {
theme: {
extend: {
backgroundImage: {
'first': "url('/img/first.jpg')",
'second': "url('/img/second.jpg')",
}
}
}
}
<div className={`bg-cover bg-center ${useFirst ? 'bg-first' : 'bg-second'}`}></div>
This would work, as long as you use the full utility class name, e.g. bg-first, in the code for Tailwind to find and include in the generated CSS.
If you need to reference completely arbitrary URL values, you can always use a style attribute instead of Tailwind classes. For example:
<div className="bg-cover bg-center" style={{backgroundImage: `url('${link}')`}}></div>

How can i dynamically change images as Background in TailwindCSS?

I want to make a carousel, where the background is changing, i don't want to use the <img/> tag! I set the value as described in the documentation: https://tailwindcss.com/docs/background-image#arbitrary-values
My Code:
import React from 'react';
type CarouselProps = {
img: string;
};
const Carousel = ({ img }: CarouselProps) => {
return (
<div
className={`col-span-full bg-[url(${img})] bg-cover grid grid-cols-12 gap-6`}
> ...
</div>
);
};
When i set the String i pass to the Component hardcoded it works but when i use curly Braces and $ it doesn't. In addition i don't want to define my Background-Images in the tailwind.conf.js
The Error:
ERROR in ./src/index.css (./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5]
.use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[2]!
./node_modules/source-map-loader/dist/cjs.js!./src/index.css) 9:36-70
i don't want to define my Background-Images in the tailwind.conf.js
Well you have to. What you're trying to do isn't supported.
The way Tailwind scans your source code for classes is intentionally
very simple — we don’t actually parse or execute any of your code in
the language it’s written in, we just use regular expressions to
extract every string that could possibly be a class name.
so tailwind has no idea what your React code actually means. So it's simply not going to work.
Tailwind does not support dynamic class names:
Don't construct class names dynamically
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
you should customise your theme to include the image url:
You can add your own background images by editing the
theme.backgroundImage section of your tailwind.config.js file:
tailwind.config.js
module.exports = {
theme: {
extend: {
backgroundImage: {
'hero-pattern': "url('/img/hero-pattern.svg')",
'footer-texture': "url('/img/footer-texture.png')",
}
}
}
}
The solution is to use the style attribute. Thanks for helping :)
<div
className="col-span-full bg- bg-cover grid grid-cols-12 gap-6"
style={{
backgroundImage: `url(${img})`,
}}
>

Is there a way to easily add className to all tags in JSX?

I've been told that I shouldn't use HTML tags to style it in the CSS but rather use classes. Okay, not a problem I'll just add className to the tags. However there are quite a few of them in the code, so I was just wondering if there was a better way than just copy pasting the className into each tag or if there's a way to say for example all p tags should have class "text".
if all p tags should have a particular style then you should highly consider styling all the p tags directly via CSS
p {
font-size: 16px;
/* Your Styles here */
}
p.specific {
font-size: 24px;
/* Override styles for specific elements here */
}
Now answering the actual question. This can be done via JavaScript but once again I don't recommend this as this will have serious performance issues if there are a lot of nodes on the page.
document.getElementsByTagName("p").forEach(p => p.classList.add("text"));
Since you have tagged this as react, you can also extract the paragraph into its own component
const P = ({ children }) => {
return <p className="text">{children}</p>;
};
You can either add class to all elements like Mailk suggested.
document.querySelectorAll("p").forEach(p => p.classList.add("text"));
or you can simply find and replace all the p tags using the text editor.
find: <p
replace to: <p className="text"

how to use common less variable with styled component?

Say I have a styled component, in index.jsx
import './index.less';
class Input extends React.Component {
...
}
and my index.less files looks:
.input{
color: #whiteColor;
}
This index.less has to work with the mixin.less that imported in the root project.
So my question is, even though I imported the mixin.less, it prompts variable #whiteColor not found. Any idea to solve this?
I have felt the same pain, why isn't my styled component resolving less variables?
The syntax is simple JavaScript, just do:
.input{
color: ${props => props.whiteColor};
// or
color: ${props => props.theme.whiteColor};
}
But, at my company, we had thousands of less components, and we really thought that the less syntax was cleaner and definitely faster to write. We developed Styless.
It is a babel plugin that parses less and generates javascript code. Add it to your .babelrc file.
{
"plugins": ["babel-plugin-styless"]
}
Then, we can do!!
const Input = styled.input`
#highlight: blue; // can be overwritten by theme or props
background: darken(#highlight, 5%); // make green darken by 5%
`;
Check here to see how to use the theme provider and load variable from your index.less!
You can try import the mixin.less in index.less
I have been trying the same than you.
But then I thought.. it is that what I really want? Because styled-components propose a different approach to having a modular structure for your styles.
https://www.styled-components.com/docs/advanced Check theming, is amazing powerful.
Because in styled components you define the variables with javascript.
And if you want color manipulation like less, sass, you can check https://github.com/erikras/styled-components-theme
Its like forgetting about less, and sass and moving it to a new style modules.
Still, if you want to keep your defined style classes, you can do that:
class MyComponent extends React.Component {
render() {
// Attach the passed-in className to the DOM node
return <div className={`some-global-class ${this.props.className}`} />;
}
}
Check the existing CSS usage from docs:
https://www.styled-components.com/docs/advanced#existing-css

Change css style of Angular Material Data Table

I'm using mdDataTable to display data retrieved form Server. Is there a possibility to change the css class of mdt-row? If I try to add a class, mdDatatable overwrites it
in your own css file, you can override the css by explicitly targetting the angular md classes, like this:
.mdt-row {
{overridesettingname}: {newsetting};
}
But I'd be careful because that overrides site-wide. You can override just a single page by targeting a parent element on the page, like:
.{mypageclassname} .mdt-row {
{overridesettingname}: {newsetting};
}
Another note, make sure YOUR css file is loaded AFTER the angular css file(s).
You can explore the classes and ids for the element in the developer tool, It is easy to add style for all elements, Here I've added sample styles you can keep added as you wish. Hope it helps.
.mat-table {
overflow: auto;
max-height: 700px;
}
.mat-header-cell .mat-sort-header-sorted {
color: #0A0A0A;
}
md-pagination-wrapper {
width:auto !important;
}
md-row:nth-child(even){
background-color:#EDF1F5;
}
md-row:nth-child(odd){
background-color:#FDFDFB;
}

Resources