Configuration
ConfigProvider is bestax-bulma's extension point for app-wide choices that Bulma itself can't express in React: a class-prefix namespace for the Bulma CSS classes your components emit, a default icon library every Icon should fall back to, and where portaled content such as a Popover panel renders. It works through React context, so any setting you provide applies to every descendant component, with no prop drilling.
Overview
ConfigProvider takes these settings:
classPrefix— prefix applied to every Bulma class name the library renders (pair it with the matching prefixed bestax CSS bundle,@allxsmith/bestax-bulma/versions/bestax-prefixed.css, forclassPrefix="bestax-").iconLibrary— the default icon library ('fa','mdi','ion','material-icons','material-symbols') thatIconcomponents resolve to when nolibraryprop is set.portalContainer: where portaled content goes when it has no target of its own, such asPopover'sappendToBodypanel, aModalwithportal, or aPortalwith nocontainer.
Each is optional; without a ConfigProvider the library uses unprefixed Bulma classes and Font Awesome icons, and portals into document.body.
CSS Class Prefixing
Class prefixing adds a namespace to every Bulma class the library renders:
buttonbecomesbestax-buttonboxbecomesbestax-boxtitlebecomesbestax-title
The goal is to avoid collisions between Bulma's generic class names (.button, .card, .title, .menu, .notification, …) and the class names used by your own application's CSS. Teams that have their own hand-written stylesheets — design tokens, layout utilities, component classes — often already use some of those names; prefixing every Bulma class lets both sets coexist cleanly.
Class prefixing is about namespacing Bulma's class names, not about running bestax alongside another CSS framework like Bootstrap or Tailwind Preflight. Bulma's base-element rules (in bulma/sass/base/minireset.scss and generic.scss) target raw HTML tags — body, p, h1–h6, ul, img, table, … — and apply globally regardless of any class prefix. Stacking Bulma on top of another framework's reset is not a supported setup; pick one framework for the base layer.
Basic Usage
Standard Configuration
import { ConfigProvider, Button, Box, Title } from '@allxsmith/bestax-bulma';
import '@allxsmith/bestax-bulma/versions/bestax-prefixed.css';
function App() {
return (
<ConfigProvider classPrefix="bestax-">
<Box p="4">
<Title size="4">Prefixed Components</Title>
<Button color="primary">Prefixed Button</Button>
</Box>
</ConfigProvider>
);
}
This renders HTML with prefixed CSS classes:
<div class="bestax-box p-4">
<h4 class="bestax-title is-4">Prefixed Components</h4>
<button class="bestax-button is-primary">Prefixed Button</button>
</div>
Avoiding Conflicts With Your Own Stylesheets
If your application already ships its own CSS — a home-grown design system, marketing-page styles, vendored legacy stylesheets — odds are some of your selectors clash with Bulma's (.button, .card, .title, .menu, .notification, .content…). Prefixing every Bulma class keeps the two worlds distinct:
import { ConfigProvider, Button, Box, Title } from '@allxsmith/bestax-bulma';
import '@allxsmith/bestax-bulma/versions/bestax-prefixed.css';
import './styles/app.css'; // your own CSS, free to define its own .button, .card, etc.
function App() {
return (
<ConfigProvider classPrefix="bestax-">
{/* bestax renders .bestax-button, .bestax-box, etc.
Your app's own .button / .card rules are untouched. */}
<Box p="4">
<Title size="4">App section</Title>
<Button color="primary">Action</Button>
</Box>
</ConfigProvider>
);
}
Default Icon Library
Every Icon component can resolve to a different icon library — Font Awesome, Material Design Icons, Ionicons, Material Icons, or Material Symbols. Setting iconLibrary on ConfigProvider lets the whole tree default to one library; individual Icon components can still override per-use.
import { ConfigProvider, Icon, Button } from '@allxsmith/bestax-bulma';
import '@mdi/font/css/materialdesignicons.min.css';
function App() {
return (
<ConfigProvider iconLibrary="mdi">
<Button color="primary">
<Icon name="rocket-launch" aria-hidden="true" />
<span>Launch</span>
</Button>
</ConfigProvider>
);
}
Valid values are 'fa' (Font Awesome), 'mdi' (Material Design Icons), 'ion' (Ionicons), 'material-icons', and 'material-symbols'. This is the same choice pnpm create bestax@latest prompts for during project setup.
Where Portaled Content Goes
Content a component portals, such as the panel Popover renders with appendToBody, a Modal with portal, or a Toast, goes to document.body unless portalContainer names an element or a selector to use instead. Set it when that content has to stay inside something document.body is outside of: a scoped Theme, whose variables sit on its own wrapper, or a shadow root, whose styles stay inside it. The element must not sit under an ancestor with a transform, filter, backdrop-filter, perspective, will-change: transform, or a contain that includes paint or layout, because the overlays it receives are position: fixed and would be placed against that ancestor instead of the viewport. The ConfigProvider reference has the rest of what to check, and a worked example.
Combining Prefix and Icon Library
Both settings are independent and compose. Set whichever you need:
<ConfigProvider classPrefix="bestax-" iconLibrary="mdi">
<App />
</ConfigProvider>
Prefixed bestax CSS bundle
bestax ships a prebuilt, bestax--prefixed bundle (Bulma and the bestax extras, all prefixed together) that pairs with classPrefix="bestax-". Import it directly:
// Prefixed bestax bundle (Bulma + extras, all "bestax-" prefixed)
import '@allxsmith/bestax-bulma/versions/bestax-prefixed.css';
function App() {
return (
<ConfigProvider classPrefix="bestax-">
<Button color="primary">Uses bestax-button class</Button>
</ConfigProvider>
);
}
Custom Prefix Builds
For teams building custom Bulma CSS with their own prefixes:
1. Install Dependencies
- pnpm
- npm
- yarn
- bun
pnpm add bulma sass
npm install bulma sass
yarn add bulma sass
bun add bulma sass
If pnpm stops on a build script here, see When pnpm blocks a build script.
2. Create Custom Sass File
@use 'bulma/sass' with (
$class-prefix: 'mycompany-'
);
3. Configure Your Application
import { ConfigProvider, Button, Box } from '@allxsmith/bestax-bulma';
import './styles/mycompany-bulma.scss';
function App() {
return (
<ConfigProvider classPrefix="mycompany-">
<Box>
<Button color="primary">Custom Prefixed Button</Button>
</Box>
</ConfigProvider>
);
}
Advanced Configuration
Nested Providers
ConfigProviders can be nested. An inner provider replaces the outer one's settings rather than adding to them, so inside it any setting it leaves out is back to its default:
function NestedConfiguration() {
return (
<ConfigProvider classPrefix="outer-">
<Box p="4">
<Title>Outer Prefix (outer-)</Title>
<ConfigProvider classPrefix="inner-">
<Box p="4" mt="3">
<Title>Inner Prefix (inner-)</Title>
<Button color="primary">Inner Button</Button>
</Box>
</ConfigProvider>
<Button color="info" mt="3">
Outer Button
</Button>
</Box>
</ConfigProvider>
);
}
Using Configuration in Custom Components
Your own components can participate in the same prefix/icon conventions as bestax's built-ins:
import { usePrefixedClass } from '@allxsmith/bestax-bulma';
function CustomComponent() {
const prefixed = usePrefixedClass();
return <div className={prefixed('custom-component')}>Custom content</div>;
}
Configuration Hooks
These hooks expose the active configuration so your own components can honor the same settings as bestax's built-ins.
useConfig
Returns the full configuration object:
import { useConfig } from '@allxsmith/bestax-bulma';
function MyComponent() {
const { classPrefix, iconLibrary } = useConfig();
// ...
}
useClassPrefix
Convenience hook that returns just the class prefix as a string (empty string if none):
import { useClassPrefix } from '@allxsmith/bestax-bulma';
function MyComponent() {
const classPrefix = useClassPrefix();
}
usePrefixedClass
Returns a function that applies the configured prefix to a class name — handy when building custom components that need to stay in sync with a prefixed Bulma build:
import { usePrefixedClass } from '@allxsmith/bestax-bulma';
function CustomBanner() {
const prefixed = usePrefixedClass();
// Renders "bestax-notification" under ConfigProvider classPrefix="bestax-",
// or plain "notification" without a prefix.
return <div className={prefixed('notification')}>Hello</div>;
}
useIconLibrary
Returns the configured icon library (or undefined):
import { useIconLibrary } from '@allxsmith/bestax-bulma';
function MyIcon({ name }) {
const library = useIconLibrary() ?? 'fa';
// Render an icon using the configured library
}
Use Cases
Multi-tenant Applications
Different tenants can have different styling namespaces:
function TenantApp({ tenantName }) {
return (
<ConfigProvider classPrefix={`${tenantName}-`}>
<App />
</ConfigProvider>
);
}
Component Library Wrapping
When building your own component library on top of bestax, give its Bulma classes a distinct namespace so they can't clash with anything a consumer adds:
function MyLibraryProvider({ children }) {
return <ConfigProvider classPrefix="mylib-">{children}</ConfigProvider>;
}
Best Practices
- Set at the root level — apply
ConfigProvideronce near the top of your tree; nest only when a subtree genuinely needs different settings. - Match CSS and React — if you set
classPrefix="bestax-", import the matching prefixed bestax bundle@allxsmith/bestax-bulma/versions/bestax-prefixed.css(or your own Sass build with the same prefix). Using the bestax bundle — rather than stockbulma/css/...plus a separateextras.css— keeps the bestax extra components (Notification, Tooltip, etc.) prefixed too. - Match icon font and setting — if you set
iconLibrary="mdi", make sure the MDI font package is imported somewhere in your app. - Trust one source — the
create-bestaxinstaller wires all of this up in a consistent way; reach for a customConfigProvideronly when the defaults don't fit.
Integration with Other Features
ConfigProvider works seamlessly with other library features:
function CompleteSetup() {
return (
<ConfigProvider classPrefix="bestax-">
<Theme primaryH="270" primaryS="100%" primaryL="50%" isRoot>
<App />
</Theme>
</ConfigProvider>
);
}
For detailed API documentation and more examples, see the ConfigProvider API reference.