How to add Bootstrap 5 padding uniformly across sides? - css

I am trying to experiment with Bootstrap 5 within React, but somehow fail to understand the padding and margin. Consider the following code:
const Breadcrumbs = (props) => {
return (
<div className={"bg-dark rounded-start"}>
<Breadcrumb>
<Breadcrumb.Item href="#">Home</Breadcrumb.Item>
<Breadcrumb.Item href="https://somelink.com">
Library
</Breadcrumb.Item>
<Breadcrumb.Item active>Data</Breadcrumb.Item>
</Breadcrumb>
</div>
)
}
Its a Component which is later on shown in a Container. I chose a dark background to better show the issue. With this code, the Breadcrumbs render like this:
Now I want them to have some padding within the surrounding box, lets say only in vertical direction. According to the Spacing documentation I should be adding modifier classes, for example py-2 which should add a Padding to both top and bottom to $spacer * .5. When applying the additional class like this:
const Breadcrumbs = (props) => {
return (
<div className={"bg-dark py-2 rounded-start"}>
<Breadcrumb>
<Breadcrumb.Item href="#">Home</Breadcrumb.Item>
<Breadcrumb.Item href="https://somelink.com">
Library
</Breadcrumb.Item>
<Breadcrumb.Item active>Data</Breadcrumb.Item>
</Breadcrumb>
</div>
)
}
It now looks like this:
My question now is: how can I add padding that keeps the Breacrumbs vertically centered within the surrounding div?
//Edit: I think I found something. The <ol> element created by Breadcrumb has a margin-bottom set. How can I remove that?

Related

Why is my nested web component adding vertical space in Lit?

I have a weird issue where when I add padding-left: 32px to an element, vertical space gets added. If the CSS says 0, and I add the space manually in Chrome debugger, the vertical space isn't there. This is only happening with nested components. I'm not sure if I'm misusing something or if I have found a bug.
I have code like this:
<cai-setting-row class="itemGroupMiddle doubleIndent" data-type="A"
>Not Nested A</cai-setting-row
><cai-setting-row class="itemGroupMiddle doubleIndent" data-type="A"
>Not Nested B</cai-setting-row
>
<cai-setting-row-account></cai-setting-row-account>
The render of cai-setting-row-account is just the same markup:
render() {
return html`<cai-setting-row
class="itemGroupMiddle doubleIndent"
data-type="A"
>Nested A</cai-setting-row
><cai-setting-row class="itemGroupMiddle doubleIndent" data-type="A"
>Nested B</cai-setting-row
>`;
}
It renders like this:
The "Not Nested" elements look right. The "Nested" ones have extra space and you can see a weird border on top that is the distance of the padding.
I have a functioning sandbox here:
https://studio.webcomponents.dev/edit/8u0cg76BNEiSoHXQT8by/
I misunderstood how class is used on a custom component. Doing <my-component class="foo"> adds foo to the :host. My code in sandbox needed to change the magic of const parentClass = this.getAttribute('class') ?? ''; to const parentClass = this.getAttribute('itemClass') ?? '';, such that I wouldn't accidentally be applying classes to the :host and the intended element.

Tooltip on absolute element in React JS

I am using this library https://tvkhoa.github.io/testlib/ to make some nice tooltip in my React App.
I use that code in my own component which look like this
const Tooltip = ({className, children, text, placement = 'bottom', isDisabled = false}) => {
return (
<ReactTippyTooltip className={className} html={<span>{text}</span>}
theme="dark" position={placement} arrow={true} arrowSize="regular"
animation="shift" hideDelay={300}>
{children}
</ReactTippyTooltip>
);
};
On basic elements such as simple images or buttons, everything works fine. But in some cases, I need to have a tooltip on an absolute element. For example on an InfoButton which overlaps an image.
<div className="relative"> <!-- container -->
<img />
<Tooltip> <!-- tooltip container -->
<InfoButton className="absolute top-0 left-0">
</Tooltip>
</div>
But I noticed that the tooltip appears bellow the image, instead of bellow the InfoButton.
If I have a look with the devtool, I can see that my InfoButton is inside a div that represents ReactTippyTooltip, and that div is 0*0 and is positionned bellow the image in the DOM. This is because only its content (InfoButton) is absolute and positionned inside the image. It can be summarized by the following image
I put a className to ReactTippyTooltip as a workaround and I made it absolute as well. Like this my tooltip is at the right place, but I feel like there is something wrong with what I am my doing.
Has anyone encountered some issues with tooltip on absolute elements ?
Can I do some better code with the library I am using ?
Does it exist some react tooltip library that use reference of the element to display the tooltip ?

cdkDragPreview and cdkDragPlaceholder not working as expected with horizontal elements

I'm using display-inline in my elements as I want them to lay out horizontally instead of vertically as they do in most of the Angular examples. That said, the CSS behaves very weird. I'm specifically having two issues.
When I click an element to drag it, it grows (shrinks back to regular size after dropped). I'm not sure exactly why this happens but it is definitely not desired. I've tried numerous things to fix this via both css and adding a cdkDragPreview element with matchSize present (this seems to be the method Angular recommends). All of those efforts failed. I came across the following bug report that seems similar to my issue: https://github.com/angular/components/issues/19060. I noted that the bug was closed, so I don't know if that means it has been fixed.
When I start to drag an element from the bottom drop list, the remaining items move around sporadically while that element is still in the drop list (when it goes out of the bottom drop list they behave as I would expect them to). I created a hide style for the cdkDragPlaceholder as this seems to be how Angular provides control of this but it only helped with the top drop lists and seemed to have no effect on the bottom.
Here is a link that illustrates both issues on StackBlitz: https://stackblitz.com/edit/spuzzler. I'm guessing that my issue can be fixed with CSS, but I can't figure out how.
Create a cdkDropList for each word. My idea is to have an outer div and an inner div that is really the element that is dragged. More over, I fixed the size of the outer div. So, when you drag, there's no re-order of the words (simply leaves an empty space instead of the word you drag)
You can see the result in this stackblitz
<div #contenedor class="categories" cdkDropListGroup>
<ng-container *ngFor="let item of items;let i=index">
<div class="categories-item" cdkDropList
cdkDropListOrientation="horizontal"
[cdkDropListData]="{item:item,index:i}" (cdkDropListDropped)="drop($event)" >
<div class="inner" cdkDrag>
<div *cdkDragPlaceholder></div>
<div class="categories-item-drag" *cdkDragPreview matchSize="true" >
<div class="inner">{{item}}</div>
</div>
{{item}}
</div>
</div>
</ng-container>
</div>
I use an observable that returns an array or words. In subscribe I equal to item and, using a setTimeout() add the size to the outter div
export class AppComponent implements OnInit {
#ViewChildren(CdkDropList, { read: ElementRef }) pills: QueryList<ElementRef>;
constructor(private renderer: Renderer2) {}
items: any[];
positions: any[];
ngOnInit() {
this.getParragraf().subscribe(res => {
this.items = res;
setTimeout(() => {
this.pills.forEach(x => {
this.renderer.setStyle(
x.nativeElement,
"width",
x.nativeElement.getBoundingClientRect().width + "px"
);
});
});
});
}
drop(event: CdkDragDrop<any>) {
this.items.splice(event.previousContainer.data.index, 1);
this.items.splice(event.container.data.index,0,event.previousContainer.data.item)
/* if we want to interchange the words, replace the two lines by*/
//this.items[event.previousContainer.data.index]=event.container.data.item
//this.items[event.container.data.index]=event.previousContainer.data.item
//event.currentIndex=0;
}
getParragraf() {
return of(
"Let him who walks in the dark, who has no light, trust in the name of the Lord and rely on his God.".split(
" "
)
);
}
}
Updated Really you needn't make a cdkDropListGroup, you can take advantage of [cdkDropListConnectedTo]. For this, you have two arrays: words and items
if res is an array of strings, you can have
this.items = res.map((x,index)=>({value:x,ok:false,id:'id'+index}));
this.words=res.map(x=>({o:Math.random(),value:x}))
.sort((a,b)=>a.o-b.o)
.map(x=>(
{value:x.value,
connected:this.items.filter(w=>x.value==w.value).map(x=>x.id)
}))
and use item.value,item.id and word.value,word.connected
See a new stackblitz

What is the correct way to style canvas area is storybook

In storybook, all stories are sitting tight agains the top left corner of the container.
This is causing problems when displaying items that have visual appearance outside the relative container e.g. a box-shadow.
So I am wondering what is the best way to add margin to the surrounding container. I had a look in the theming docs of storybook, but could not find anything related?
In .storybook/preview.js, you can just add the following:
addDecorator(storyFn => (
<>
<div style={{ margin: '1rem' }}>{storyFn()}</div>
</>
))
This way all the stories will appear with a margin of 1rem.
Adding to my preview.js:
export const decorators = [
(Story) => (
<div style={{ margin: '3em'}}>
<Story />
</div>
)
]
solved the problem for me
It's better to add padding on each component because not all components needs margins.
For example, in your .stories.tsx file
const Template: ComponentStory<typeof IconButton> = (args) => (
<div style="padding: 20px"><YourComponent {...args} /></div>
)
You can even use layout parameter to center all stories in the UI globally.
See Story layout for more details.
<!-- Checkbox.stories.mdx -->
import { Meta } from '#storybook/addon-docs';
import { Checkbox } from './Checkbox';
<Meta
title="Checkbox"
parameters={{
layout: 'centered',
}}
component={Checkbox}
/>

Angular 6: Update NG Style with function

I'm here today because I'm wondering something about the NG Style with Angular (my version being the 6). How can i update [ngStyle] when I use a function to return a value.
As always, here is a simplified example of my problem:
I generate div from an array of objects.
For each section, there are two div: one on the left and one on the right.
The size of the left div changes depending on the content, so it can do both 50px and 125px.
I want the right div to fit the size of the one on his left, always half that size (2 in getLeftDivHeight).
Obviously, this will be done in each section (Container).
How can I make the ngStyle update when the div's height to the left changes (due to resizing, adding content, or page display time)? )
Here is the code:
HTML
<section class = "Container" *ngFor="let oneContent of allContent">
<div id = "{{oneContent.id}}" style="float: left">
<p> {{oneContent.Content}} </ p>
</div>
<div style="float: right" [ngStyle]="height: getLeftDivHeight(oneContent.id, 2)">
</div>
</div>
Typescript (only the related function)
getLeftDivHeight(id: string, divisionNumber: number): string {
height = document.GetElementById(id).getBoundingClientRect().height /
divisionNumber;
return height + 'px';
}
Note that I am not looking for an HTML solution, but an Angular one, the code above is just an example to explain my problem.
Thank you in advance
You could return the whole style string, for example height: 100px, from the getLeftDivHeight method
getLeftDivHeight(id: string, divisionNumber: number): string {
height = document.GetElementById(id).getBoundingClientRect().height / divisionNumber;
return `height: ${height}px`;
}
or you could use the below syntax in the template
[style.height.px]="getLeftDivHeight(parameters)"
return only numerical height value from the method.
So, I finally manage to do it, using a directive.
I used ElementRef to access the HTML Object of my right div.
import {ElementRef,Renderer} from '#angular/core';
constructor(private el: ElementRef,public renderer: Renderer) {}
Then, I used Dom to access the left div height
this.el.nativeElement.parentElement.childElement[0].clientHeight;
Then I use this.renderer.setElementStyle() to apply style
I also learn that use offscrollheight to do the math is not a good idea !

Resources