I am having a problem with ngStyle after updating to angular 7. In angular 5 its working fine.
Using ngStyle I am dynamically applying style with Css grid.
but dont know why 'grid-column': '1 / span 2' is not working.
here is my code
<div class="widthHeight100"
[ngStyle]="getStyleForGroup(group)">
<div *ngFor="let subGroup of group?.childs"
[ngStyle]="getStyleForSubGroup(subGroup)">
In typescript
Grid container:
getStyleForGroup(mdg: MdgSimple) {
let style: any = {
'width': '100%',
'height': '100%'
};
if (!isNullOrUndefined(mdg)) {
if (!isNullOrUndefined(mdg.childs)) {
if (mdg.childs.length > 0) {
style = {
'display': 'grid',
'grid-template-rows': this.getGridTemplateCount(mdg.childs, true),
'grid-template-columns': this.getGridTemplateCount(mdg.childs, false),
'grid-column-gap': '4px',
'grid-row-gap': '4px',
'justify-items': 'start',
'align-items': 'start',
'padding': '5px'
};
}
}
}
return style;
}
Childs:
getStyleForSubGroup(mdsg: MdsgSimple) {
let style: any = {
'width': '100%',
'height': '100%'
};
if (!isNullOrUndefined(mdsg) && !isNullOrUndefined(mdsg.layout)) {
style = {
'grid-row': this.getCssRowInfo(mdsg),
'grid-column': this.getCssColumnInfo(mdsg),
'height': this.getHeight(mdsg),
'width': this.getWidth(mdsg),
'min-width': this.getMinWidth(mdsg),
'max-width': this.getMaxWidth(mdsg),
'min-height': this.getMinHeight(mdsg),
'max-height': this.getMaxHeight(mdsg),
};
}
return style;
}
But controls are overlapping each other. I have checked using chrome css element inspector grid area showing unsafe.
But its all working fine in angular 5 version.
example 1 / span 2 also not working
here is screen shot for error.
Any suggestion please ?
I have the exact same issue. ngStyle is replacing this:
{
'grid-column': (width > 1 ? column + ' / ' + (column + width) : column + ''),
'grid-row': '' + row
}
with this:
style="grid-area: 1 / unsafe / auto / unsafe
when width > 1
HTML
<p [ngStyle]="myStyles">
Hello World!
</p>
TS
myStyles = {
'color': 'red',
'font-size': '20px',
'font-weight': 'bold'
}
I just write very basic code, Try this I hope it'll help you out. Thanks
Related
I'm trying to create a "collapsible text" react component that allows a user-determined number of lines to be displayed. I'm using the line-clamp CSS property to do this, for the most part. On the JavaScript side of things, I want to selectively render a button that toggles the effect based on whether the content to be shown is greater in height than the number of lines to be shown multiplied by their line height. This is working fairly well in Firefox and Chrome. I can get the line height of the element after it's rendered, and I can multiply that by the number of lines that the user wants shown to approximate the height of the content. I can use that to set a min-height CSS property, and I can compare that value against the scroll height of the content. The problem is, I'm getting the same value for the scroll height of the content in Firefox and Chrome, but NOT in Safari.
const CollapsibleText = ({
text,
linesToShow,
markdown = false,
containerStyles,
textStyles,
buttonStyles,
handleScroll,
}) => {
const [isActive, setIsActive] = useState(false)
const contentRef = useRef(null)
const [displayButton, setDisplayButton] = useState(false)
const [contentMinimumHeight, setContentMinimumHeight] = useState(null)
const windowSize = useWindowSize()
const linesShown = windowSize.mobile
? parseInt(linesToShow[0])
: parseInt(linesToShow[1])
const handleToggleIsActive = () => {
if (isActive && handleScroll) {
handleScroll()
}
setIsActive(!isActive)
}
useEffect(() => {
const contentLineHeight = parseInt(
window
.getComputedStyle(contentRef.current, null)
.getPropertyValue('line-height')
)
const contentHeight = contentRef.current.scrollHeight
// Adding 5 here to offset rounding that seems to occur in actual pixel values of rendered output, value of 5 is arbitrary.
const linesToShowHeight = contentLineHeight * linesShown + 5
setContentMinimumHeight(linesToShowHeight)
console.log('Content height: ', contentHeight)
console.log('Lines to show height: ', linesToShowHeight)
if (contentHeight > linesToShowHeight) {
setDisplayButton(true)
}
if (contentHeight < linesToShowHeight) {
setDisplayButton(false)
}
}, [windowSize])
return (
<div sx={{ ...containerStyles }}>
<div
sx={{
display: '-webkit-box',
'-webkit-line-clamp': !isActive ? linesToShow : 'none',
lineClamp: !isActive ? linesToShow : 'none',
'-webkit-box-orient': 'vertical',
overflow: 'hidden',
outline: '2px solid red',
textOverflow: 'ellipsis',
minHeight: contentMinimumHeight,
'&:first-child': {
marginTop: '0px',
},
}}
>
{markdown ? (
<div
ref={contentRef}
sx={{
...textStyles,
'& *:first-child': {
marginTop: '0px',
// marginBottom: '0px',
},
}}
dangerouslySetInnerHTML={{
__html: text,
}}
/>
) : (
<p
ref={contentRef}
sx={{
whiteSpace: 'pre-wrap',
...textStyles,
}}
>
{text}{' '}
</p>
)}
</div>
{displayButton && (
<Button
variant="viewMore"
sx={{ marginTop: '20px', ...buttonStyles }}
onClick={handleToggleIsActive}
>
{!isActive ? 'Read more' : 'Read Less'}{' '}
<ChevronDown
styles={{ transform: !isActive ? 'none' : 'rotate(180deg)' }}
/>
</Button>
)}
</div>
)
}
export default CollapsibleText
To determine the content height, I'm using a ref and grabbing the scroll height of the element in question. I get the same value in Chrome and Firefox, but a larger value in Safari, which breaks my ability to selectively render the "toggle" button I'm trying to implement.
I'm comparing the "line height" (with my admittedly very simplistic algorithm) against the content height to determine whether or not to render the button. I get the same measurement in all three browsers, so as far as I can tell Safari is just measuring the scroll height of the content differently than in Chrome and Firefox.
I seemingly have to use a min height because the line-clamp property causes the content to collapse to zero in Safari. Setting the min height allows things to work more or less as predicted where the content is more than the user-defined lines to show prop given to the component.
Screenshots of the console logs for the SAME content in each browser:
Firefox:
Chrome:
Safari:
I am trying to show a basic tooltip when the user clicks on an event in the calendar with a few event details but the tooltip gets covered by the next row.
Currently, I'm trying to use the slotPropGetter prop to change the style of a cell to include z-index: -1 and inline-styling the tooltip with z-index: 1000 but to no avail.
Here's my current component:
export default() =>{
const eventStyleGetter = ({ color }) => {
const style = {
backgroundColor: color,
opacity: 0.8,
zindex: "6",
position:"relative",
};
return {
style: style,
};
};
const slotStyleGetter = () =>{
const style = {
position: "relative",
zindex:0,
height:"100px",
}
return{
style: style
}
}
const CalendarElement = (
<Calendar
localizer={localizer}
defaultDate={new Date()}
events={events}
style={{ height: 500 }}
eventPropGetter={(event) => eventStyleGetter(event)}
slotPropGetter={(slot) => slotStyleGetter(slot)}
onSelectSlot={(e) => handleSlotSelect(e)}
selectable
popup
components={{
event: EventPopover,
}}
/>
);
return(
{CalendarElement}
)
}
The issue isn't the cell z-index, but that of your tooltip. What are you using to render your tooltip? Under the hood, RBC has react-bootstrap#^0.32.4, which uses react-overlay#^0.8.0. If you use react-overlay to create your tooltips, you can portal them, which should automatically handle your z-index issue.
The way to correctly implement this is to use Reactstrap/Bootstrap Popover (based on Popperjs) rather than plain CSS. It worked in this case.
I'm creating a skills chart in a React component, where each bar starts with a short width and then it expands to a specified width after 0.5 second. The width is related to the skill level, defined in the following array:
const skills = [
{ skillName: 'JavaScript', level: 10, color: 'bca538' },
{ skillName: 'HTML', level: 9, color: 'af4336' },
{ skillName: 'CSS', level: 9, color: '2f81b7' },
]
The chart is represented in the following code:
<div className="chart__bars">
{skills.map((skill, index) => {
const { skillName, level, color } = skill
const { scale } = this.state
return (
<div
className={'chart__bars__item'}
key={skillName}
style={{
background: `#${color}`,
height: `${(100 / skills.length) * (index + 1)}%`,
width: `${scale ? level * 10 : 30}%`,
zIndex: skills.length - index,
}}
>
<h4
style={{
opacity: `${scale ? 1 : 0}`,
}}
>
{skillName}
</h4>
</div>
)
})}
</div>
After the component is mounted, it triggers a state change after 0.5 second, which should then expand each bar (logic for this is inside the style property in the code above). Here's the initial state:
state = {
scale: false,
}
And here's where I change it:
componentDidMount() {
setInterval(() => {
this.setState({ scale: true })
}, 500)
}
It works fine on the browser, but not on mobile. Using the devtools I can see the width being updated, but it won't expand. If I uncheck the tick box for the width, and then check it again, then the width expands (which should happen automatically).
The working example is on my website: https://marcelcruz.io.
Any thoughts would be much appreciated!
Thanks.
I have done a lot of looking but there is suprisingly little documentation in regard to reactstrap carousel image responsiveness.
My ReactStrap carousel resizes responsively but the images do not.
Options I have researched/tried:
CSS via className in the carousel component itself? This is the one I thought might be best, but I haven't found a combination of background-size, height, and max-width that resizes the image properly.
srcset ? I'm not sure how to implement this or any other inline attribute, given that the carousel is a component
Perhaps some place in the carousel component itself?
Or is there a better way for me to modify the images?
Or is #media the answer via css?
`
const items = [
{
src: 'img1.png',
altText: '',
caption: ''
},
{
src: 'img2.png',
altText: '',
caption: 'Freedom Isn\'t Free'
},
{
src: 'img3.png',
altText: '',
caption: ''
}
];
class HomeCarousel extends Component {
constructor(props) {
super(props);
this.state = { activeIndex: 0 };
this.next = this.next.bind(this);
this.previous = this.previous.bind(this);
this.goToIndex = this.goToIndex.bind(this);
this.onExiting = this.onExiting.bind(this);
this.onExited = this.onExited.bind(this);
}
onExiting() {
this.animating = true;
}
onExited() {
this.animating = false;
}
next() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === items.length - 1 ? 0 : this.state.activeIndex + 1;
this.setState({ activeIndex: nextIndex });
}
previous() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === 0 ? items.length - 1 : this.state.activeIndex - 1;
this.setState({ activeIndex: nextIndex });
}
goToIndex(newIndex) {
if (this.animating) return;
this.setState({ activeIndex: newIndex });
}
render() {
const { activeIndex } = this.state;
const slides = items.map((item) => {
return (
<CarouselItem
className="carouselImg"
onExiting={this.onExiting}
onExited={this.onExited}
key={item.src}
>
<img src={item.src} alt={item.altText} />
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
);
});
return (
<Carousel
activeIndex={activeIndex}
next={this.next}
previous={this.previous}
>
<CarouselIndicators items={items} activeIndex={activeIndex} onClickHandler={this.goToIndex} />
{slides}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={this.previous} />
<CarouselControl direction="next" directionText="Next" onClickHandler={this.next} />
</Carousel>
);
}
}
export default HomeCarousel;
`
Good day and Hello,
I already tried this reactstrap with the Carousel component in my reactjs app.
I solved this by adding bootstrap 4 classess "d-block w-100".
I created this in my reactstrap Carousel component and in this element
from this:
<img src={item.src} alt={item.altText} />
I changed to:
<img className="d-block w-100" src={item.src} alt={item.altText} />
I just copied these classes (d-block w-100) from bootstrap 4 documentation
https://getbootstrap.com/docs/4.0/components/carousel/
This is my example that I used Reactstrap Carousel with Dynamic data from my WordPress Rest API data.
https://github.com/jun20/React-JS-and-WP-Rest-API/tree/home-carousel-final
.carousel-item > img {
width: 100%;
}
... will fix your problem.
And it has nothing to do with Reactstrap. That's probably why you didn't find much. Has to do with the TwBs Carousel alone. I personally don't see any reason why that rule is not part of TwBs carousel CSS, because everyone expects that <img> to have a width of 100% of its parent.
If you want to limit it to a particular carousel, modify the selector accordingly.
Another frequently requested TwBs carousel mod is:
.carousel-control-prev,.carousel-control-next {
cursor:pointer;
}
Given bootstrap uses flexbox, you can make the reactstrap carousel images responsive by adding this to your css:
.carousel-item, .carousel-item.active {
align-items:center;
}
This seems to prevent the image height from stretching. Worked for me!
Based on the reactstrap Carousel example 1 on this page https://reactstrap.github.io/components/carousel/
Here's how I got it to be responsive in my use case:
<CarouselItem
onExiting={() => setAnimating(true)}
onExited={() => setAnimating(false)}
key={item.src}
>
<img src={item.src} alt={item.altText} style={{ width: "100%"}}/>
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
So, passing in style={{ width: "100%"}} to the img tag, made my oversized images fit the screen perfectly and may work for others coming here.
I am trying to build a SPFx webpart containing a ChoiceGroup. When I set the css style to ms-sm12 the choices are aligned vertical:
Show assigned to:
o anyone
* me
o nobody
I like them to align horizontal in one row:
Show assigned to: o anyone * me o nobody
When I set the style to ms-sm6, it aligns them "mixed":
The Slider and Toggle are set to ms-sm3
Show assigned to: o anyone
* me
o nobody
With ms-sm4 it looks like:
With ms-sm3, ms-sm2, ms-sm1 it looks like (the title getting more and more squashed and all options in one column:
How can I force / encourage the options to be rendered horizontal?
Follow the steps given below :
1) Create New .scss file
ex: fabric.scss and paste this class in it.
.inlineflex .ms-ChoiceField{
display: inline-block;
}
2) In your component give refernece like:
import './fabric.scss';
3) Add component and apply class.
<ChoiceGroup
className="inlineflex"
label='Pick one icon'
options={ [
{
key: 'day',
text: 'Day'
},
{
key: 'week',
text: 'Week'
},
{
key: 'month',
text: 'Month'
}
] }
/>
Another option that doesn't require adding a CSS is to apply the style directly to the control:
set the flexContainer style to display:flex.
you will notice a space might be needed at the end of the options, I added a non-breaking space as \u00A0
<ChoiceGroup selectedKey={valueType}
styles={{ flexContainer: { display: "flex" } }} options={[
{ key: 'specific', text: 'selected\u00A0\u00A0' },
{ key: 'relative', text: 'relative' }]} />
done!
add styles property to ChoiceGroup styles={{ flexContainer: { display: "flex" } }}
add styles property to options styles: { choiceFieldWrapper: { display: 'inline-block', margin: '0 0 0 10px' }}
done!
const options: IChoiceGroupOption[] = [
{ key: 'conforme', text: 'Conforme'},
{ key: 'noConforme', text: 'No conforme', styles:{field: { marginLeft: "15px"}}}
];
<ChoiceGroup styles={{ flexContainer: { display: "flex" } }} options={options} />