I would like to add translate-z-[] utility class to my tailwindcss classes so I could use parallax scrolling effects with perspective and translateZ, is there a way to generate these classes (add something like --tw-translate-z variable at the end on tailwinds transform class)?
Yes, you can create plugins for custom utilities
You config should have something like this
const plugin = require('tailwindcss/plugin');
module.exports = {
theme: {},
plugins: [
plugin(function({ matchUtilities, theme }) {
matchUtilities(
{
'translate-z': (value) => ({
'--tw-translate-z': value,
transform: ` translate3d(var(--tw-translate-x), var(--tw-translate-y), var(--tw-translate-z)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))`,
}), // this is actual CSS
},
{ values: theme('translate'), supportsNegativeValues: true }
)
})
],
}
DEMO
Related
I am writing plugin to add custom styles in TailwindCSS, but I am a bit confused with values of theme(). I don't know how to see all the theme values to apply my base styles. How do I know where it is?
module.exports = {
// ...
plugins: [
plugin(function ({ addBase, addComponents, addUtilities, theme }) {
addBase({
'h1': {
fontSize: theme('fontSize.2xl'), // need to see more fontSize and properties, where I can see it?
},
'h2': {
fontSize: theme('fontSize.xl'),
},
})
}
]
}
I´ve been researching a lot about Vuetify + Storybook integration.
I installed Vuetify using Vite and then installed the storybook/vue3 plugin using:
npx sb init --builder storybook-builder-vite
The problem is that every component that I created is not using the Vuetify styles. I read here that I need to extend the Storybook app so my preview.js looks like:
// .storybook/preview.js
import { app } from '#storybook/vue3';
import vuetify from '../src/plugins/vuetify'
app.use(vuetify);
export const decorators = [
(story) => ({
components: { story },
template: '<v-app><story /></v-app>',
}),
];
But this doesn't seem to work. It doesn't throw any errors in the terminal and not in the browser but the vuetify styles and components do not work. My components are being render normally with Vuetify if I try to run the app itself.
Any ideas? I´m totally lost. Maybe there´s no support since Vuetify 3 is on alpha? Or this is a storybook issue?
Here´s my repo if you want to check it out https://github.com/heyimnowi/vue-ui-library
OMG I cannot believe I solve it by just doing this:
const path = require('path')
const vuetify = require('#vuetify/vite-plugin'); // THIS
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials"
],
"framework": "#storybook/vue3",
"core": {
"builder": "storybook-builder-vite"
},
async viteFinal(config, { configType }) {
config.resolve.alias['~storybook'] = path.resolve(__dirname)
config.resolve.alias['#'] = path.resolve(__dirname, '..', 'src')
config.css = {
preprocessorOptions: {
scss: { additionalData: `#import "src/styles/application.scss";` },
},
};
config.plugins = [
...config.plugins,
vuetify() // THIS
];
return config;
}
}
I'm trying to add a new variant called not-first to the Tailwind toolbelt, but when I try to use it, it doesn't work.
tailwind.config.js:
const plugin = require('tailwindcss/plugin');
module.exports = {
mode: 'jit',
purge: ['./src/**/*.{js,jsx}', './public/index.html'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [
plugin(({ addVariant, e }) => {
addVariant('not-first', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
const element = e(`not-first${separator}${className}`);
return `.${element} > :not(:first-child)`;
});
});
}),
],
}
Usage:
<li className={`not-first:bg-blue`}>{item.name}</li>
What am I doing wrong?
It looks like you're applying the :not(:first-child) to the child of the element you're targeting with the not-first: pseudo-class.
:first-child should be applied to the child element itself (see: https://developer.mozilla.org/en-US/docs/Web/CSS/:first-child).
To fix this, you could try changing
return `.${element} > :not(:first-child)`;
to
return `.${element}:not(:first-child)`;
I have a few SCSS theme files I want to extract to CSS files and later load them into the page. I want to be able to use contenthash for long term caching.
Since I'm using Webpack 4, I am also using mini-css-extract-plugin. I started down the path of creating a splitChunks in my webpack config.
// webpack.config.js
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].[contenthash].css",
chunkFilename: "[id].[contenthash].css"
})
],
optimization: {
splitChunks: {
cacheGroups: {
'vendor': {
// custom commons chunk for js
},
'theme-a': {
test: /theme-a.\scss/,
},
'theme-b': {
test: /theme-b.\scss/,
},
// more themes
}
}
}
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader"
]
}
]
}
}
I've then tried dynamically importing the css in my app:
// app.js
class App extends React.Component {
// constructor
login(themeName) {
import(/* webpackChunkName: "`${themeName}`" */ `./path/to/${themeName}.scss`).then(theme => {
// do something with `theme`
}
}
// other stuff
}
I need to be able to load that css file dynamically in login() and I'm just not sure how to reference it when it has a generated [contenthash].
TLDR: Is there a good way to both extract css and import the referenced CSS bundle to lazy load later? I'm not tied to mini-css-extract-plugin.
Edit: Created a mini-css-extract-plugin issue here.
My solution ended up using extract-text-webpack-plugin. My config now looks like this:
// webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ExtractThemeA = new ExtractTextPlugin({ filename: 'themeA.[hash].css', allChunks: true});
module.exports = {
plugins: [
ExtractThemeA,
// more plugins for other css files
],
optimization: {
splitChunks: {
cacheGroups: {
// Note: No changes to splitChunks
'vendor': {
// custom commons chunk for js
}
}
}
module: {
rules: [
{
test: /theme-a\.scss$/,
use: ExtractThemeA.extract([ 'css-loader', 'sass-loader' ])
},
// more module rules for each css file needed
]
}
}
Then, these chunks are available by file name in my HtmlWebpackPlugin:
<!-- HtmlWebpackPlugin Template -->
<script>
// provides me with an array of file name strings
var themesManifest = <%= htmlWebpackPlugin.files.css %>
</script>
Sorry for my miss understanding,
You could probably just make two different scss-files and import them as needed. theme.scss admin.scss or like so
This is how I am doing scss in React right now
In App.js
import styles from '../../stylesheet/main.scss'
// could be as well
import styles1 from '../../stylesheet/theme.scss' // some file
import styles2 from '../../stylesheet/admin.scss' // some other file
const App = () => {
<div className={styles.action_feed} >{ content }</div>
}
In main.scss
.action_feed {
position: fixed;
width: 350px;
height: auto;
max-height: 100%;
max-width: 100%;
top: 0;
left: 0;
z-index: 9999;
}
I think you could just as well do it like so
const themeName = 'main'
import(`./stylesheet/${themeName}.scss`, (css) => {
// meaby set this to state? not quite sure how should properly handle
// dynamically imported css
this.setState({ css: css.action_feed })
// or possible this way. I have done some non-React dom manipulation
// this way before
document.querySelector('body').classList.add(css.action_feed)
})
<div className={this.state.css}>{ content }</div>
You should probably check out React's new Refs API as well. It might give you some nice flexibility for giving className-attr to required element.
Having set to splitChunks.chunks to all works though i think in this case anyway
I have a component:
import React from 'react';
import * as styles from './RedComponent.css';
class RedComponent extends React.Component {
render () {
return <div className={ styles.red }></div>;
}
}
This is the test case:
describe('Test suite', () => {
test('RedComponent tests', () => {
const wrapper = shallow(<RedComponent />);
});
console.log(wrapper.debug());
gives
<div className={[undefined]}></div>
instead of
<div className="RedComponent__red"></div>
If I console the imported styles I get
console.log(styles); // {default: {}}
This is only in Jest test cases. Style is not undefined when the app renders in browser.
My jest config:
{
"moduleFileExtensions": [
"js"
],
"moduleDirectories": [
"node_modules"
],
"moduleNameMapper": {
"\\.(css|less)$": "identity-obj-proxy"
},
"setupFiles": [
"./test-setup.js"
],
"collectCoverageFrom": [
"src/**/*.{js}",
"!**/node_modules/**"
],
"testEnvironment": "node",
"transform": {
"^.+\\.js$": "babel-jest",
"\\.(md|ttf|txt|eot|ico|otf|svg|png|gif|woff2|woff|jpeg)$": "./file-transformer.js"
}
}
Using jest v21.2.1, identity-obj-proxy v3.0.0 and React v16.0.0.
You have to change this line
import * as styles from './RedComponent.css';
to this:
import styles from './RedComponent.css';
I assume that you are using css-loader or similar and this is just how the loader works.
Maybe worths to check the example:
https://github.com/keyanzhang/jest-css-modules-example/
I think your moduleNameMapper should be like this:
"^.+\\.(css|less)$": "identity-obj-proxy"
Create a jest/identity-obj-proxy-esm.js file with the following content:
// This works around the fact we use ES named exports for styles, e.g.:
// import * as styles from './styles.scss'.
// https://github.com/keyanzhang/identity-obj-proxy/issues/8
module.exports = new Proxy(
{},
{
get: function getter(target, key) {
if (key === '__esModule') {
// True instead of false to pretend we're an ES module.
return true;
}
return key;
},
},
);
Edit jest.config.js:
// jest.config.js
module.exports = {
...
moduleNameMapper: {
...
'\\.(css|scss)$': '<rootDir>/jest/identity-obj-proxy-esm.js',
}
};
🏆 João Vieira and https://github.com/keyz/identity-obj-proxy/issues/8#issuecomment-430241345