Refactored components to avoid synchronous setState calls in effects
by using proper React patterns:
- TableOfContents: Use requestAnimationFrame to defer setState calls
and useLayoutEffect for DOM measurements
- CustomTheme: Use lazy state initialization for isClient and defer
theme loading with requestAnimationFrame
- PlaygroundContext: Use lazy initialization for localStorage hydration
These changes maintain functionality while satisfying the strict
react-hooks/set-state-in-effect ESLint rule.
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
Next.js 16 requires ESLint 9 for proper flat config support. This commit:
- Upgrades eslint from ^8 to ^9
- Migrates from .eslintrc.json to eslint.config.mjs (flat config)
- Updates lint script to use eslint directly (next lint removed in Next.js 16)
- Adds tsconfig.json includes for Next.js 16 dev types
- Fixes layout.tsx to use proper theme CSS link tags
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
After upgrading to Next.js 16.1.6, the build failed with CSS Module
purity errors in Popover and Tooltip components. Next.js 16 with
Turbopack enforces stricter validation requiring global selectors
like [data-theme='dark'] to be combined with local classes.
Changed nested selector structure:
[data-theme='dark'] { .bui-Popover { ... } }
To flattened structure:
[data-theme='dark'] .bui-Popover { ... }
This matches the pattern used in Dialog.module.css and satisfies
Turbopack's CSS Module purity requirements.
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
Added a `danger` variant for destructive actions like delete or remove.
Uses solid red background with white text in both light and dark modes.
- Added CSS styles with custom properties for future token migration
- Updated Storybook stories to include danger variant examples
- Updated docs-ui documentation to reflect the new variant
Signed-off-by: Johan Persson <johanopersson@gmail.com>
When no className prop was passed to a component using useDefinition,
the hook would add a literal "undefined" string as a CSS class. This
happened because clsx treats object keys as class names, and
`{ [undefined]: true }` creates an "undefined" key.
Fixed by using conditional expressions instead of object syntax,
which clsx correctly ignores when falsy.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Add proper visual feedback for disabled Switch component by
applying `not-allowed` cursor and disabled text color.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Improves documentation quality and consistency across all UI components.
Props documentation:
- Added descriptions to all props across all components
- Fixed prop types to match source implementations
- Added missing props (onAction, isInvalid, aria-label, etc.)
- Corrected default values and removed non-existent props
- Converted props-definition files to .tsx for Chip component usage
Examples and snippets:
- Added side-by-side layout option to Snippet component
- Fixed snippet/preview mismatches
- Improved example code indentation and formatting
- Added live previews to Container, Box, Grid examples
- Wrapped Skeleton examples in themed Box for visibility
API reference:
- Added ReactAriaLinks to all components
- Updated React Aria URLs to react-aria.adobe.com format
- Cleaned up verbose prose and standardized descriptions
Other:
- Updated PageTitle descriptions to 5-12 word format
- Varied example intro phrasing for consistency
Signed-off-by: Johan Persson <johanopersson@gmail.com>
When navigating to a URL that doesn't match any tab href, the Tabs
component would pass `selectedKey={null}` to React Aria's Tabs,
which triggers an infinite render loop.
This fix uses an empty string instead of null to indicate no
selection, which React Aria handles correctly.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
This includes the group count, user count, tenant ID, and operational
duration of the synchronization process. With this, the JSON log output
can be ingested to track metrics on the functionality.
Signed-off-by: tomislacker <tomislacker@users.noreply.github.com>