@tailwind base;
@tailwind components;
@tailwind utilities;
.tw-pointer-events-all {
pointer-events: all;
}
With the 1.10.0 release of AdminWeb, we upgraded the Tailwind dependency to v3 along with a few other enhancements. These require a few changes to AdminStarter.
Update Admin Components, Styles, and Tailwindcss modules
yarn install @broadleaf/admin-components@1.10.0-rc1.0 @broadleaf/admin-style@1.10.0-rc1.0 @broadleaf/admin-tailwindcss@1.10.0-rc1.0
Update Tailwind, PostCSS, and Autoprefixer
yarn install -D tailwindcss@latest postcss@latest autoprefixer@latest
Tailwind v3 requires PostSS v8.
Remove the global.css
stylesheet from being imported by index.html
Remove the purgecss comments in App.jsx
as they are no longer needed
Change the purge
property in tailwind.config.js
to content
as well as defaultConfig.purge
to defaultConfig.content
Add a new file: styles/base.css
The import order that should be use for tailwind vs the base Broadleaf styles has changed.
@tailwind base;
@tailwind components;
@tailwind utilities;
.tw-pointer-events-all {
pointer-events: all;
}
In styles/index.css
Remove all tailwind imports, base, components, and utilities
Import the new base.css
before the broadleaf style imports
Remove the /* purgecss start ignore */
comment at the top of the file, it is no longer needed
After the existing broadleaf style imports, add a new one @import '@broadleaf/admin-components/styles/components/form-control.css';
Remove the .tw-pointer-events-all
style as it is in base.css
now
Add new style override:
.sub-menu-open > .DropdownMenu > div > ul > li {
@apply tw-cursor-default tw-bg-gray-800 tw-text-gray-700 tw-transition-colors;
}
Remove the /* purgecss end ignore */
comment
That covers the essentials for upgrading to AdminWeb 1.10.0. Please also review Tailwind’s upgrade guide if you have additional style customizations.
We noticed that properties defined in a .env
at the root of the project are not always able to override the default properties defined in the @broadleaf/admin-components
library.
Create a buildTimePropertyResolver.js
in the src/
directory
import { has, get } from 'lodash';
import { utils } from '@broadleaf/admin-components';
/**
* Resolve properties from Vite at build time.
* This overrides the default build-time properties resolver, but is still
* subsequent to the runtime resolver.
*/
function buildTimeResolver(propertyName) {
if (has(import.meta.env, propertyName)) {
return get(import.meta.env, propertyName);
}
// handle the case where we are evaluating this in Vite, which requires prefixing VITE_
if (has(import.meta.env, `VITE_${propertyName}`)) {
return get(import.meta.env, `VITE_${propertyName}`);
}
return undefined;
}
utils.Environment.registerResolver(buildTimeResolver, 2000);
Import into src/index.tsx
// ...
import * as serviceWorker from './serviceWorker';
import './loadLocaleData';
import './componentRegistration';
import './buildTimePropertyResolver'; // <-- add like this
import '../styles/index.css';
//...
This script will scan for any <component>.messages.js|ts
files that contain react-intl message descriptors and generate a <local-code>.json
file for each locale you intend to translate admin text into as well as a composite index.json
.
The index.json
can be loaded into your app to override any out-of-box translations from the Broadleaf components library as well as include translations for new components.
Note
|
This is the same process used by the Next.js Starter. |
Tip
|
The <local-code>.json for the default language (e.g., en.json ) can be sent to professional translation services to provide the contents for other languages, e.g., to create an fr.json .
|
Add a few new dev-dependencies to facilitate the script
yarn add -D colorette extract-react-intl-messages glob pretty-ms
Create a scripts/build-langs.js
const fs = require('fs');
const colorette = require('colorette');
const { sync: globSync } = require('glob');
const extractMessages = require('extract-react-intl-messages');
const last = require('lodash/last');
const ms = require('pretty-ms');
const MESSAGES_PATTERN = 'src/**/*?(.)messages.{js,ts}';
const DEFAULT_LOCALE = 'en';
const TRANSLATED_LOCALES = []; // e.g., ['fr', 'es']
const LANG_DIR = 'messages/';
const LANG_PATTERN = `${LANG_DIR}*.json`;
async function buildLangs() {
const start = Date.now();
const mainFile = `${LANG_DIR}index.json`;
console.log(
colorette.cyan(
`\n${colorette.bold(MESSAGES_PATTERN)} → ${colorette.bold(
`${mainFile}`
)}...`
)
);
// extract the default messages that from our components messages files
await extractMessages(
[DEFAULT_LOCALE, ...TRANSLATED_LOCALES],
MESSAGES_PATTERN,
LANG_DIR,
{ defaultLocale: DEFAULT_LOCALE }
);
// merge the existing translated json files (e.g. es.json, fr.json, etc) into
// one object so they can be aggregated
const allMessages = globSync(LANG_PATTERN)
.filter(filename => !filename.endsWith('index.json'))
.map(filename => {
const locale = last(filename.split('/')).split('.json')[0];
return { [locale]: JSON.parse(fs.readFileSync(filename, 'utf8')) };
})
.reduce((acc, localeObject) => {
return { ...acc, ...localeObject };
}, {});
// write the index.json aggregated json file with all of the messages
fs.writeFileSync(mainFile, JSON.stringify({ ...allMessages }, null, 2));
console.log(
colorette.green(
`created ${colorette.bold(`${mainFile}`)} in ${colorette.bold(
ms(Date.now() - start)
)}`
)
);
}
buildLangs();
Modify DEFAULT_LOCAL
and TRANSLATED_LOCALES
as desired for your project
Use the build-langs
script in your package.json
{
"scripts": {
"build:langs": "node scripts/build-langs.js"
}
}
Run yarn build:langs
This will generate a (likely) empty messages/en.json
and messages/index.json
Import the new messages into your App.jsx
Merge with the base Broadleaf messages
Pass to <AdminProvider>
import merge from 'lodash/merge'; // optionally using lodash for ease of merging
import messages from '@broadleaf/admin-components/messages';
import customMessages from '../messages';
const combinedMessages = merge({}, messages, customMessages);
// ...
<AdminProvider messages={combinedMessages}>