Tailwind: How to create a loading: modifier/variant? - tailwind-css

I'm trying to create a modifier for a button for when it's in a loading state.
Based on the documentation here, I added the following in my tailwind.config.js
// I assume this is included in tailwindcss
// and doesn't need to be installed separately
const plugin = require('tailwindcss/plugin')
module.exports = {
// ...
plugins: [
plugin(function({ addVariant }) {
addVariant('loading', '&:loading')
})
],
};
I assume this allows me to add a string of loading in the class such that it will apply those styles. This doesn't seem to work though, what am I doing wrong?
<!-- I assume this should be blue-600 -->
<button className="bg-blue-600 loading:bg-blue-100">
This is a normal button
</button>
<!-- I assume this should be blue-100 since it has className, "loading" -->
<button className="loading bg-blue-600 loading:bg-blue-100">
This is a loading button
</button>

& sign points to an element with THIS variant applied, so it should be translated in CSS as "this element with class .loading". In your example :loading will be translated as loading state which is not valid
So it should be addVariant('loading', '&.loading') not addVariant('loading', '&:loading')
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addVariant }) {
addVariant('loading', '&.loading') // here
})
],
};

Related

How I can apply styling to active slide in react-image-gallery?

I want to add custom styling to the slides and gallery control buttons in react-image-gallery But I am confused how to do this. I have searched the assets on google and tried to do it on my own but I am unable to apply custom styling on it.
This is the code which I have applied till now:
import 'react-image-gallery/styles/css/image-gallery.css';
import ImageGallery from 'react-image-gallery';
const GalleryComponent = (props)=>{
const properties = {
thumbnailPosition: 'left',
showFullscreenButton: false,
useBrowserFullscreen: false,
showPlayButton: false,
items: [
{
original: "https://placeimg.com/640/480/any/1",
thumbnail: "https://placeimg.com/250/150/any/1"
},
{
original: "https://placeimg.com/640/480/any/2",
thumbnail: "https://placeimg.com/250/150/any/2"
},
{
original: "https://placeimg.com/640/480/any/3",
thumbnail: "https://placeimg.com/250/150/any/3"
}
]
};
return (
<ImageGallery {...properties} />
)
}
Currently achived this :
Slider i wanted in actual:
So kindly tell me a way to target the required components in react-image-gallery to add styling to them.
Thanks!

JSX styles are not working for Storybook after an upgrade

I upgraded my project from NextJS 10 to NextJS 12. Everything is working except for Storybook, which has no styles now.
I am using styled-jsx library to generate embedded css, using it as:
const SearchResult = ({ onClick, vehicle }: SearchResultProps): JSX.Element => {
return (
<div className="search-result" data-testid="search-result" onClick={onClick}>
<style jsx>{styles}</style>
...
</div>
);
};
It generates styles like class="jsx-2615582530 search-result". Before the update, it would also embed a style search-result.jsx-2615582530 into the generated storybook. Now, the jsx style names are there, yet the styles are gone.
I upgraded styled-jsx from 3.3.1 to 5.0.0 and NextJS to 12.0.3. Did not change any loaders or anything. My guess, webpack might have easily gotten upgraded.
My config:
const webpack = require('webpack');
module.exports = ({ config }) => {
// Fill in process.env on the client
config.plugins.push(
new webpack.DefinePlugin({
'process.serializedEnv': {},
})
);
// Sentry requires different packages for front and back end,
// but in storybook we know it's always client side
config.resolve.alias = {
'sentry-alias': '#sentry/browser',
'#/remoteConfig': './standardRemoteConfig',
};
config.module.rules.push({
test: /\.md$/,
loader: "raw-loader",
}),
config.externals = [...(config.externals || []), 'fs', 'net'];
config.resolve.extensions.push('.md');
config.resolve.fallback = {
"https": false,
"stream": false,
};
return config;
};
and main
module.exports = {
core: {
builder: 'webpack5',
},
stories: ['../stories/**/*.stories.tsx'],
addons: [
'#storybook/addon-actions',
'#storybook/addon-links',
'#storybook/addon-backgrounds',
'#storybook/addon-knobs',
'#storybook/addon-viewport',
'#storybook/addon-a11y',
'storybook-addon-paddings',
],
};
Further, if I include styles as <style>{styles}</style> without the jsx prop, they are included in the produced storybook.
Only, the text is displayed weird:
When jsx is there, <style /> is missing from the resulting markup, altogether.
Suggestions?
Newer styled-jsx required the following:
+import { StyleRegistry } from 'styled-jsx';
and
-export const decorators = [withPaddings, withRedux(), (story: Function) => <I18nextProvider i18n={i18n}>{story()}</I18nextProvider>]
+export const decorators = [(Story) => (
+ <StyleRegistry>
+ <Story />
+ </StyleRegistry>
+), withPaddings, withRedux(), (story: Function) => <I18nextProvider i18n={i18n}>{story()}</I18nextProvider>]
This yet again makes embedded jsx styles present.

JIT tailwindcss using variable in bg-[] not rendering color

when passing my color as props like this <List text="something" color="#84AB86" /> and using in the code className={'bg-[${color}] '} it does not render properly.
when looking at chrome dev tools color are added correctly like this bg-[#84AB86]
while putting the color manually without taking it from props, it does work correctly
after more testing it seems not possible either to do it like this
const color = "#84CC79"
className={`bg-[${color}]`}
any idea why
To use dynamic classes with JIT tailwind you either need to use safelist config key or create stub file where you list all your dynamic classes that you will use.
Config example:
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
],
safelist: [
'bg-red-500',
'text-3xl',
'lg:text-4xl',
]
// ...
}
Or make safelist.txt in your src folder, then add classes there just like so:
bg-[#84AB86]
bg-[#fffeee]
// etc..
And don't forget to include this safelist.txt file to your config content so tailwind could watch it.
Explanation from tailwind docs
If you are not using JIT, then you can use safelist option for PurgeCSS:
// tailwind.config.js
module.exports = {
purge: {
// Configure as you need
content: ['./src/**/*.html'],
// These options are passed through directly to PurgeCSS
options: {
// List your classes here, or you can even use RegExp
safelist: ['bg-red-500', 'px-4', /^text-/],
blocklist: [/^debug-/],
keyframes: true,
fontFace: true,
},
},
// ...
}
From the Tailwindcss documentation
Dynamic values Note that you still need to write purgeable HTML when
using arbitrary values, and your classes need to exist as complete
strings for Tailwind to detect them correctly.
Don't use string concatenation to create class names --> <div className={mt-[${size === 'lg' ? '22px' : '17px' }]}></div>
Do dynamically select a complete class name --> <div className={ size === 'lg' ? 'mt-[22px]' : 'mt-[17px]' }></div>
Tailwind doesn’t include any sort of client-side runtime, so class
names need to be statically extractable at build-time, and can’t
depend on any sort of arbitrary dynamic values that change on the
client. Use inline styles for these situations, or combine Tailwind
with a CSS-in-JS library like Emotion if it makes sense for your
project.
As mentioned above tailwind engine In order to render a custom class dynamicaly:
Does not like:
className={`bg-[${custom-color}]-100`}
It expects:
const customBgColorLight = 'bg-custom-color-100';
className={`${customBgColorLight} .....`}
For this to work properly you have to include the name of the class in the safelist:[] in your tailwind.config.js.
For tailwind v.3
/** #type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
safelist: [
'bg-custom-color-500', // your-custom-css-class
'text-custom-color-500',
'border-custom-color-500',
..... // other classes
'hover:bg-custom-color-500', // *** also include it with the selector if needed ***
.... // other classes
],
theme: {
extend: {
colors: {
'custom-color': { // you have to use quotes if key is not in camelCase format
100: '#d6d6d6',
500: '#5E8EA2',
..... //other variants
},
...... // other colors
So you can use it:
// if you want store the values to an object
const yourClassObj = {
customBgColor: 'bg-custom-color-500',
customBrdColor: 'border-custom-color-500',
customTxtColor: 'text-custom-color-500',
};
const { customBgColor, customBrdColor, customTxtColor } = yourClassObj;
<YourComponent
className={`mb-2 font-semibold py-2 px-4 rounded-lg
${ conditionGoesHere ? `${customBgColor} text-white cursor-default`
: `${customTxtColor} border ${customBrdColor}
bg-transparent hover:border-transparent
hover:${customBgColor} hover:text-white`
}`}
/>
An easy solution is to use the built in style property.
For example in React:
Dont Use:
className={`bg-[${color}]`}
Use Instead:
style={{
backgroundColor: color,
}}

Hide Docs tab in Storybook

I want to create stories using both Typescript and MDX, therefore I have in my main.js:
module.exports = {
stories: ['../src/**/*.stories.(mdx|ts)'],
addons: ['#storybook/addon-docs', 'storybook-addon-preview']
};
However I don't want to have "Docs" tab next to "Canvas". How do I remove it? Without '#storybook/addon-docs' MDX story is not displayed.
Put this in preview.js:
export const parameters = {
previewTabs: {
'storybook/docs/panel': {
hidden: true
}
}
};
Used in Storybook version 6.0.x
I am currently using #storybook/angular#6.0.21 and the previous answer unfortunately did not work for me. I was able to find a solution in the storybook DocsPage documentation.
The relevant section:
You can replace DocsPage at any level by overriding the docs.page parameter:
- With null to remove docs
- With MDX docs
- With a custom React component
I was able to completely remove the DocsPage for a single story like this:
export const myStory = () => ({
moduleMetadata: MODULE_METADATA,
component: MyComponent,
});
myStory.parameters = {
docs: { page: null },
};

How to render activeClassName style for a react-router-dom NavLink rendered within a material-ui button in a typescript environment?

I am learning react and trying to set the style of a react-router-dom NavLink encapsulated inside a material-ui Button. I am using React with Typescript and a custom Webpack build.
The documentation states that this can be achieved by setting the activeClassName property.
In the code listing below I try setting the activeClassName on the button containing the NavLink component.
import * as navbar from './NavBar.css';
const NavBarLinks = () => (
<>
<Button
color="inherit"
component={NavLink}
activeClassName={navbar.highlighted}
to="/about"
>
About
</Button>
</>
);
The highlighted css class is as follows:
.highlighted {
border-bottom: 3px solid rgb(174, 185, 28);
}
However, no bottom border is rendered. How do I get the activeClassName style to render for a react-router-dom NavLink rendered within a material-ui Button within a Typescript environment?
My build environment is configured as follows.
I have created a type declaration file for the stylesheet
and saved this in a folder referenced in tsconfig.json.
export const active: string;
export const horizmenu: string;
export const highlighted: string;
My tsconfig.json includes the typesRoot configuration. This references the types folder where my css type declaration file is stored:
"typeRoots": ["node_modules/#types", "src/types"]
My webpack development configuration is using css-loader to bundle css files under src/app/*/
{
// link css modules
test: /\.css$/,
include: path.resolve(constants.dir.SRC, 'app'),
use: [
{ loader: require.resolve('style-loader') },
{
loader: require.resolve('css-loader'),
options: {
modules: {
localIdentName: '[path][name]__[local]___[hash:base64:5]',
},
importLoaders: 1,
sourceMap: true,
},
},
],
},
...
When I perform a Webpack development build I can see that the NavBar.css contents are picked up by the css-loader and embedded as a string in the bundle file.
What you have should work, but you are passing a class name, not a style, so I think you just need to make your activeClassName prop equal to "highlighted".
<Button
color="inherit"
component={NavLink}
activeClassName="highlighted"
to="/about"
>
About
</Button>
You'll also need to add !important to you style so it overrides the CSS of the Material UI button.
Working codesandbox link

Resources