stylesheet styling not applying to one specific - html

I'm working within a React app and have a component that renders numerous span tags. The tags all have different class names and receive all their styling from the linked stylesheet. Except for one class, which is shown below as actions. For some reason, I cannot figure out how to update this one class via the stylesheet.
If I go into Chrome Dev tools and change the styling to the actions, the changes will render. If I create a customStyle object in the component and apply actions with a style attribute pointing to that object, the class will then style as expected.
However, if I add an ID to the actions span tag and try to style from the linked stylesheet, the issue comes back and none of my custom styling is applied to actions. I've tried removing all the styling for the actions class and only rendering a background-color of red, but even that won't take.
Is there some reason I may be missing that allows all other classes in this component to be styled via the stylesheet, but actions cannot?
Thanks in advance for any responses, and please let me know if there's any more additional info I can provide.
Below is component code:
import React from 'react';
const ListHeaderComponent = (props) => {
return (
<span className='header'>
<span className='subheader'}>
<span className='content'>
Hello
</span>
</span>
<span className='subcontent'>
This is where the content goes
</span>
<span className='actions' id="what">
This is where the actions go
</span>
</span>
);
};
export default SplitViewListHeader;
I have gone through the stylesheet thoroughly and the class is only referenced once. Below is a sample of code that won't take that I've tried with the class that doesn't update:
.actions {
background-color: red;
}

CSS scripts when pointed towards an element id is very particular about it. It will only point to that very element and have no effect on the nested sequence. That is why they are only used to point towards very specific elements that have standalone functions; or just use a name. I think that is the reason why id won't work.

What happens if you use class="" instead of className=""?

Related

*ngIf causing custom directive to not work properly

A custom directive applied to both components(1/2)-in-spotlight is not working properly when using *ngIf. The issue resolves when I remove the *ngIf and one of the components that would not show in the current situation/"mode".
In the HTML file using the component (original):
<div>
<div>
<div>
<div>
<component1-in-spotlight *ngIf="mode===OptionOne"></component1-in-spotlight>
<component2-in-spotlight *ngIf="mode===OptionTwo"></component2-in-spotlight>
</div>
</div>
</div>
</div>
I found 2 solutions but both aren't effective or proper.
Duplicating the surrounding parent/grandparent components (placing the second case in an <ng-template #elseBlock>) and applying ngIf-else to the top most component (in the oversimplified example, a div) works. But, I'd have a lot of duplicate code and is a terrible solution.
Option 1 (to illustrate since it might be a bit confusing for some). In the HTML file using the component:
<div *ngIf="mode===OptionOne"; else myElseBlock">
<div>
<div>
<div>
<component1-in-spotlight></component1-in-spotlight>
</div>
</div>
</div>
</div>
</ng-template #myElseBlock>
<div>
<div>
<div>
<div>
<component2-in-spotlight></component2-in-spotlight>
</div>
</div>
</div>
</div>
</ng-template>
Using [hidden] on the 2 components instead of *ngIf seems fine. But there is never a case where the hidden component will be toggled to visible, it's decided upon creation and stays using either of the 2 components until it's destroyed. So, it should just only have one of the 2 components in DOM. Not just hiding it. Plus, that means flipping the logic--[hidden]="mode!==OptionOne". For now, it's just 2 options and seems unlikely more would be added, but I can't guarantee that.
--
It may seem like these 2 components are the same, so why not just have 1 component and pass in the mode and let the logic decide within the TS file of that component? Well, they both have different services that are injected into the constructor for the component. I was trying that before finding out and remembering that I can't use this before calling super() to decide which service to send up to the base class the component is extending.
Merging the 2 components and using #Input to get the "mode":
In the HTML file using the component:
<div>
<div>
<div>
<div>
<component-in-spotlight-merged [inputMode]="mode"></component-in-spotlight-merged>
</div>
</div>
</div>
</div>
In the component-in-spotlight-merged TS file--what I tried to do:
export class ComponentInSpotlightMergedComponent extends MyComponentBaseComponent {
#Input() inputMode: MyEnumType;
//...
constructor(
myService1: MyService1,
myService2: MyService2,
){
if(this.inputMode === Option1){
super(myService1);
}
else{
super(myService2);
}
}
//...
}
Using [hidden] can be for a quick fix, but is there a proper way to fix this?
Edit:
Not working meaning: It's a custom directive for tabbing focus between elements and the hotkey logic is binded here. Somehow the hotkey works but the focus is not working as it expected and none of my console.log() are outputted.
Angular 9+
You can use Angular NgSwitch directive as shown below.
<div [ngSwitch]="mode">
<!-- the same view can be shown in more than one case -->
<component1-in-spotlight *ngSwitchCase="option1">...</component1-in-spotlight>
<component2-in-spotlight *ngSwitchCase="option2">...</component2-in-spotlight>
<!--default case when there are no matches -->
<some-element *ngSwitchDefault>...</some-element>
</div>
The fix was to use setTimeout(() => myCallbackFn(), 0); (on my hotkey bind function that is called in ngAfterViewInit in a component class down the line--a view grandchild?).
I was in a rabbit hole of reading other stackoverflow questions and found How do I combine a template reference variable with ngIf? where a comment mentioned that ngIf takes a tick of time to evaluate. I eventually searched and found How to check whether ngIf has taken effect.

How to add button role to a custom element in angular to make it accessible by screen reader?

I have a custom component in angular that handles images. I have alt text as an input to the element and the screen reader picks it up to utter it out. But whenever I tab to the image, it says 'Trash' group. I want the screen reader to read it out as 'Trash' button. How can I achieve this? The following is my current implementation:
Icn component:
<img [ngClass]="class" [file]="file" [alt]="alt">
Usage:
<icn class="del-icon" [file]="'trash'" [alt]="Trash"></icn>
I tried role="button" but that didn't work.
I don't know Angular so you may need to do some digging on how to structure this but your approach is making things difficult.
Instead make the button a <button>. This way you get all the native accessibility built in (e.g. accessible via tab by default, accepts focus, has hover and focus states etc.)and you will also get the correct announcements in screen readers.
Then place the icon inside the <button> and just style it appropriately.
<button> <!--add whatever directives angular requires here-->
<img [ngClass]="class" [file]="file" [alt]="alt">
</button>
Also you may consider using inline SVGs for your icons as they offer styling options and can change colour according to user preferences. It is also one less resource to download so will help with performance.
I figured out the solution to this problem by experimenting more with the roles.
The image tag doesn't take the role="button" as an attribute. Instead, the role needs to be assigned to the parent element of the image tag i.e., in my case the component icn like follows:
<icn class="del-icon" role="button" [file]="'trash'" [alt]="Trash"></icn>
Now, the screen reader software reads out as the 'Trash button' and gives further more instructions on how to interact with the button. And also if the above doesn't work, just by encapsulating the custom component in a span tag and assigning the role="button" to the span tag works like a charm.
<span class="del-btn-container" role="button">
<icn class="del-icon" [file]="'trash'" [alt]="Trash"></icn>
</span>
Note: Button role examples

Easiest way to add html to a React component

Say I have the following component in my web app:
class About extends React.Component {
render() {
return (
<div className="about">
/* place html here. */
</div>
)
}
}
I'm currently practicing my understanding of raw html/css. So ideally, I want to be able to write up this about section somewhere else. E.G., an about.html and an about.css, an about.html with some inline css, or a <style> tag. Or most ideally, lower down in the same file that defines this component.
The idea is I want to separate my practicing of hmtl/css from the React specific / JSX code.
Is this possible? and if so what is the least friction route assuming that this is not a very mission critical project and I'm fine with taking a less secure or more hacky approach?
If you want, you can declare a variable elsewhere or write a different component separate from this block and bring it in. But at the end of the day, you're still going to be writing JSX. You can still use .css to style your JSX the same as you would html, there's really no difference.

Why doesn't individual styling of a react component instance work?

I'm using the following instance of a react component in a view:
<Jumbotron>
Lot's of important content
</Jumbotron>
I want an individual style (i.e. a different background image for this instance. So this doesn't work:
<Jumbotron className="individual">
Lot's of important content
</Jumbotron>
Wrapping the instance in a div also doesn't work. How can I do this with simple markup and CSS so that I can simply style the individual class in CSS? AFAIK properties won't help to customize instances...
You can either pass in the style attribute or you can pass through the className attribute in the same way
<Jumbotron className="background--black">
And have your component like this -
const Jumbotron = ({className}) => {
<div className={className}>
Here is the jumbotron
</div>
}
export default Jumbotron
And import a css file that has that class in, if you're using className. But I would probably recommend just using style attribute if it's a one off.

Angular2 Templates: How to bind keydown.arrow to whole div instead of only control elements?

I have a simple navigator component with some buttons and a date-picker subcomponent. Now the idea is, that I can bind keydown.arrowleft etc. for the whole div (which has css style of 100% height and width). It's template looks like this:
<div id="ck-navigator" (keydown.arrowleft)="decrementDate();
$event.preventDefault()" (keydown.arrowright)="incrementDate();
$event.preventDefault()">
<button (click)="decrementDate()" class="fa fa-2x fa-chevron-left">
</button>
<ck-date-picker [date]="date" (dateChange)="changeDate($event)">
</ck-date-picker>
<button (click)="incrementDate()" class="fa fa-2x fa-chevron-right"></button>
</div>
I don't show the component code, it does not matter for this question (afaik).
This is working, but only if I actively select a button or the date-picker in advance (aka a control element). Is there a possibility to extend the keybinding to the whole div (i.e. if I just click somewhere on the site). Sorry for my lack of understanding the DOM and thanks for any push in the right direction.
The problem is that your div is not focusable so it isn't reacting to your keybindings. Try adding the attribute tabindex="0" to the div.
If what you want is to detect key events on the whole page what you need is probably to add #HostListener to your component. It is gona let you manage events in the whole page/window.
Seeing an example.
import { Component, HostListener } from '#angular/core';
[your #Component stuff ..... ]
#HostListener("window:keydown", ['$event'])
onKeyDown(event:KeyboardEvent) {
console.log(`Pressed ${event.key}!`);
}
Furthermore could help you to know that when you want to refer specific items you can use ElementRef class and ViewChild by importing them from angular/core. Then manage DOM components as:
#ViewChild('DOM_Id') element: ElementRef;
Maybe it helps. Peace