What's the react inline style for an anchor link? - reactjs

I'm trying to set the standard properties of this anchor tag but I'm not sure of the syntax. How do I set the link color, visited color, hover, active etc}
const linkStyle = {
???
}
linkFormatter = cell => <a style={linkStyle} href='' role="link" onClick={() => { this.clickToGoToList(cell); }} >{cell} </a>;

So the short answer is that you cannot access selectors/pseudo-selectors with inline style objects. Possible solutions:
1) Style them with css in a stylesheet (though this feels pretty hacky)
2) Use a styling library. Glamorous is my preference but Bootstrap also has a React library. These libraries actually create React components to style elements and allow you access to pseudo-selectors like :active, :hover, and the like.

Related

React Native Components Override styles "leaking"

I'm trying to build my own component library specific to my React Native app using the Atomic Design Methodology, so I have small components like Paragraph, Title, Wrap, Button, Subtitle etc. in a single file called "Atoms". I can import them in my other components like so:
import { Paragraph, Title, Wrap, Button, Subtitle } from "../Atoms";
I'm building them using tailwind-react-native-classnames. It's a great package using Tailwind CSS with lots of useful features like platform prefixes and dark mode support.
Now, sometimes I need unique style changes on these components, so I have a style prop to mix the style Object to one, it works like this:
<Subtitle style={tw`pt-20`}>Some Text</Subtitle>
And in the component:
const Subtitle = ({ style, children }) => (
<Text style={Object.assign(tw`text-xl mb-3 text-octonary dark:text-white`, style)}>
{children}
</Text>
);
This works well, any style can be overwritten, it's intuitive to work with and gives me lots of freedom. But here's the problem, the changes (inconsistently, and not every component) seems to effect the same components on other Screens. So in the above example the tw`pt-20` translates to paddingTop: 5rem and applies it to other places, other Screens, with the same component, that shouldn't even have this style applied to it.
Why is this happening? Is it cashed somehow? And how can I fix it?
Thanks in advance for any help/suggestions.
I found a solution, thanks to #Abe I experimented using tw.style(). So instead of this:
const Subtitle = ({ style, children }) => (
<Text
style={Object.assign(tw`text-xl mb-3 text-octonary dark:text-white`, style)}
>
{children}
</Text>
);
I did this:
const Subtitle = ({ style, children }) => (
<Text
style={tw.style(
"text-xl",
"mb-3",
"text-octonary",
"dark:text-white",
style
)}
>
{children}
</Text>
);
It's not as close to normal Tailwind CSS since every class needs separate quotes and also be separated by commas, but it works! But then I went even further and did this:
const Subtitle = ({ style, children }) => {
const s = tw`text-xl mb-3 text-octonary dark:text-white`;
return <Text style={tw.style(s, style)}>{children}</Text>;
};
It's more compact, I can code vanilla tailwind and no "leaking". So win-win-win!

Can you pass props to a layout in sveltekit

I am working on a site with SvelteKit and I want to have a layout with a navbar for each page. The navbar has links with the active link being the page you are on. Is there a way I can pass a prop from each page to the template that changes which link is active?
Thanks!
I think I know what you're looking for. SvelteKit comes with the default page store. $page.url.pathname subscribes to that store and returns the current pathname. There are several ways you could apply this.
The following example creates a component Navlink.svelte, which
Imports the default Svelte store page
Creates a reactive boolean active and sets it to true when $page.url.pathname equals href. The $: make it reactive, meaning that Svelte reruns the code whenever either $page.url.pathname or href changes.
In the a element, we pass href as a prop. Whenever you use the Navlink component, you pass it href like you would a regular a element. That is also why we use export let href.
We also add class:active. This is the Svelte way of applying classes conditionally. Note that this is actually shorthand for class:active={active}, meaning we apply the class active when the variable active (after the equal sign) is true. When the variable and the class share the same name, we can use class:active. (docs on this subject)
Style the .active class however you like.
<script>
import { page } from "$app/stores"
export let href
$: active = $page.url.pathname === href
</script>
<a {href} class:active>
<slot />
</a>
<style>
a.active {
color: red;
}
</style>
You can also use a Tailwind class combined with some inline logic:
<a class:text-primary={$page.url.pathname === '/about'} href="/about">About</a>
Or use traditional CSS combined with a ternary operator:
<a href="/about" class="{($page.url.pathname === '/about')? active : inactive}"

Material UI - Overriding styles using Root & using ClassName

I'm new to material UI. While learning, I came to know out that styles of a material UI can be overridden with the rule name of the classes.
If I have an element - MenuItem where I just need to change the default styling of the text (such as fontFamily, fontWeight, fontSize)
According to the documentation available here https://material-ui.com/api/menu-item/ I used makeStyles hook and have overridden some properties of the root element of Menu-Item
Sample code
const useStyles = makeStyles((theme) => ({
menuItem: {
fontFamily: "Raleway",
}
}));
JSX code: <MenuItem onClick={handleClose} component={Link} to="/services" classes={{root: classes.menuItem}}>Services</MenuItem>
In one more tutorial, I found another way of overriding - with className like
const useStyles = makeStyles((theme) => ({
menuItem: {
fontFamily: "Raleway",
}
}));
JSX code: <MenuItem onClick={handleClose} component={Link} to="/services" className={classes.menuItem}>Services</MenuItem>
My question lies in this part className={classes.menuItem} and classes={{root: classes.menuItem}}
On using root -> I see the css properties getting added to the root element but on using className={classes.menuItem} I see a new class is added to the DOM. But Is there any difference with respect to the behaviour of the app between these 2 methods or is it just another way of doing it?
Thanks
From what I can tell having worked with Material UI, the difference is with what you're trying to do.
className={classes.menuItem} and classes={{root: classes.menuItem}} will both get you the results that you're expecting, as you've already discovered.
The distinctions are important when you start building custom themes, because Material UI allows you to apply classes to the components as a whole, meaning potentially comprised of other components, or pass along styles to the root elements if you need a higher specificity.
For example, consider the Stepper component.
classes={{root: classes.menuItem}} will override the root in the component, applying your styles.
className={classes.menuItem} will add an additional class to the component, leaving the underlying styles intact.

How to correctly use Reach Router Links with a Fluent UI Nav

Is there a way to make the Fluent UI (formerly Office Fabric UI) Nav component correctly work replacing it's <a> element links with a custom link such as <Link> from Reach Router?
Fluent UI Nav provides an onRenderLink props but that only changes the inner content innermost <a> element. It leaves the outer wrapping element with a traditional <a> which causes full page re-renders when the user uses it.
It also provides the linkAs prop but that changes the entire content of the "Group Header" and takes a way all of the nice CSS styling advantages of using the Nav in the first place.
Is there a way to actually get this working?
I did a little more googling and found this codepen which uses LinkAs :
(props) => {
return <Link className={props.className} style={{color: 'inherit', boxSizing: 'border-box'}} to={props.href}>
<span style={{display: 'flex'}}>
{ !!props.iconProps && <Icon style={{margin: '0 4px'}} {...props.iconProps} /> }
{props.children}
</span>
</Link> ;
}
A little bit disappointing that you basically have to reverse engineer their CSS and render it yourself in order to get this working.

How to pass padding/margin as props in React-Bootstrap components

I am trying to apply margins and paddings with React-Bootstrap as props.
I passed the docs through but haven't found any mention adding padding or margin in there as it is in official bootstrap docs (3th and 4th). I know it doesn't support well Bootstrap 4, so tried with both.
I tried to pass params as p={1}, paddingxs={5} or mt='1' but it doesn't recognize any of them. More over tried to find any Spacing element in React-Bootstrap folder, but failed.
Paddings and margins work as classnames. But I feel there must be a way to it without Bootstrap classes. There must be a kind of property.
First include bootstrap CSS in your src/index.js or App.js
import 'bootstrap/dist/css/bootstrap.min.css';
Then you can style your component by passing desired bootstrap CSS class name as className prop in React, for example:
import React from "react"
import Container from "react-bootstrap/Container";
function MyComponent() {
return (
<Container fluid className="p-0">
<SomeOtherComponent />
</Container>
);
}
export default MyComponent
Above code will add p-0 CSS class to Container.
Reference
React - How do I add CSS classes to components?
React-Bootstrap - Stylesheets
You can add margin and padding by using default React's style:
const divStyle = {
marginLeft: '10px',
};
function HelloWorldComponent() {
return <div style={divStyle}>Hello World!</div>;
}
Refrenced from here
The answer is: there is no props from React Bootstrap to use margins/paddings.
You can use props for col class, but no for margins.
Example:
<Col className="col-6 col-md-3 mb-3 pt-2">
// there you have a Col component from React-Bootstrap 4
// it has some grid system classes, that you can use as props like this:
https://react-bootstrap.github.io/layout/grid/
<Col xs={6} md={3} className="mb-3 pt-2">
// but as you can see, the native classes of Bootstrap 4 like
// mt, mb, pt, pb etc, they have not a props use with
// React-Bootstrap, you have to use them like regular classes
// inside "className"
You'll want to add className="p-5" to the element. This isn't documented in react-bootstrap but it's in the original Bootstrap 4 documentation here: https://getbootstrap.com/docs/4.4/utilities/spacing/#examples
Usually, I'm able to add custom styles to React Bootstrap components by just adding them to the style param. I've put together a short example below, hope this helps.
import React from 'react';
import { Button } from 'react-bootstrap';
const styles = {
myCoolButton: {
paddingTop: "10vh",
paddingBottom: "10vh",
paddingRight: "10vw",
paddingLeft: "10vw"
}
}
const ReactButton = (props) => {
return (
<Button style={styles.myCoolButton} onClick={()=> {
console.log("Do something here!")
}}>Click Me!</Button>
);
}
export default ReactButton
You can also pass custom components (including those from react-bootstrap) into the styled-components constructor if you prefer to do it that way.
None of the jQuery-free implementations of Bootstrap (React Bootstrap, BootstrapVue or ngBootstrap) have implemented utility directives for spacing (margin/padding), simply because Bootstrap have made it unnecessary in the vast majority of cases, by providing a very intuitive set of Spacing utility classes.
All you need to do is apply the desired class.
To apply utility classes selectively, based on responsiveness interval (media queries), you could use a useMedia hook, as demoed here.
In a nutshell:
const interval = useMedia([
"(min-width: 1200px)",
"(min-width: 992px)",
"(min-width: 768px)",
"(min-width: 576px)"
],
["xl", "lg", "md", "sm"],
"xs"
);
(Based on useMedia from useHooks/useMedia).
You can now reuse this hook throughout your app to add media interval based logic.
Example usages:
// interval === 'sm' ? a : b
// ['xs', 'sm'].includes(interval) ? a : b
// negations of the above, etc...
Important: this particular implementation returns the first matching media query in the list.
If you need to map various media queries, to an object/map with true/false values, you'll need to modify getValue fn to return the entire list, along these lines:
const getValue = () => {
const matches = mediaQueryLists.map(mql => mql.matches);
return values.reduce((o, k, i) => ({...o, [k]: matches[i]}), {})
};
Working example here.
Obviously, you could expand on it and add/remove queries. However, be warned each query adds a separate listener so it could impact performance.
In most cases, the return of the first matching query (first example) is enough.
Note: if the above useMedia hook is not enough for your use case, a more robust and heavily tested solution for media-query listeners in JS is enquire.js. It's easy to use, incredibly light and thoroughly tested cross-browser/cross-device. I have no affiliation with it, but I have used it in various projects over the course of more than a decade. In short, I couldn't recommend it more.
Back to Bootstrap 4: in order to customize the $spacer sizes, follow the guide provided under Bootstrap's theming as it's actually about more than what we typically call theming (changing colors), it's about overriding default values of Bootstrap's SASS defaults, including responsivenss breakpoints, spacers, number of columns and many, many others. The one you're interested in is $spacer.
Simply write the overrides into an .scss file and import it in your root component. Example.
Note: a (simpler and more intuitive) option to customize Bootstrap is to do it visually, using bootstrap.build but it's typically a few minor versions behind (i.e. Bootstrap is now at v4.4.1 and the build tool is at v4.3.0).
The build customizer provides intuitive controls and real time visualization.
It allows export as .css or .scss.
Just try this out once according to your input and still if face any issue you can reach out.In below we have increased the .col padding with .px-md-5 and then countered then with .mx-md-n5 on the parent .row.
JSX:
import React from 'react'
import { MDBContainer, MDBRow, MDBCol } from 'mdbreact';
const SpacingPage = () => {
return (
<MDBContainer>
<MDBRow className="mx-md-n5">
<MDBCol size="6" className="py-3 px-md-5">Custom column padding</MDBCol>
<MDBCol size="6" className="py-3 px-md-5">Custom column padding</MDBCol>
</MDBRow>
</MDBContainer>
)
}
export default SpacingPage;
If you still have any kind of doubt on this then feel free to ask .

Resources