Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ module.exports = function config(api) {
api.cache(true);

return {
plugins: [
[
'babel-plugin-react-compiler',
{
target: '18', // should be the minimal supported version from peerDependencies
},
],
[
'babel-plugin-transform-define',
{
SUPPORTED_BROWSERS: browserslist(),
},
],
],
presets: [
[
'@jetbrains/babel-preset-jetbrains',
Expand All @@ -17,14 +31,6 @@ module.exports = function config(api) {
},
],
],
plugins: [
[
'babel-plugin-transform-define',
{
SUPPORTED_BROWSERS: browserslist(),
},
],
],
env: {
test: {
plugins: ['require-context-hook'],
Expand Down
2 changes: 2 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import unicorn from 'eslint-plugin-unicorn';
import {FlatCompat} from '@eslint/eslintrc';
import eslint from '@eslint/js';
import tsEslint from 'typescript-eslint';
import reactHooks from 'eslint-plugin-react-hooks';

// eslint-disable-next-line no-underscore-dangle
const __filename = fileURLToPath(import.meta.url);
Expand Down Expand Up @@ -62,6 +63,7 @@ export default defineConfig([
importPlugin.flatConfigs.recommended,
prettierConfig,
...jetbrainsConfigRules,
reactHooks.configs.flat['recommended-latest'],

// Base configuration for all files
{
Expand Down
96 changes: 68 additions & 28 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
"@vitejs/plugin-react": "^5.0.4",
"@vitest/eslint-plugin": "^1.3.23",
"acorn": "^8.15.0",
"babel-plugin-react-compiler": "^1.0.0",
"babel-plugin-require-context-hook": "^1.0.0",
"caniuse-lite": "^1.0.30001751",
"chai-as-promised": "^8.0.2",
Expand All @@ -142,7 +143,7 @@
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.0",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-storybook": "^9.1.13",
"eslint-plugin-unicorn": "^61.0.2",
"events": "^3.3.0",
Expand Down Expand Up @@ -236,6 +237,7 @@
"postcss-loader": "^8.2.0",
"postcss-modules-values-replace": "^4.2.2",
"postcss-preset-env": "^10.4.0",
"react-compiler-runtime": "^1.0.0",
"react-movable": "^3.4.1",
"react-virtualized": "^9.22.6",
"react-waypoint": "^10.3.0",
Expand Down
45 changes: 14 additions & 31 deletions src/collapse/collapse-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,17 @@ export const CollapseContent: React.FC<PropsWithChildren<Props>> = ({
const {collapsed, duration, id, disableAnimation} = useContext(CollapseContext);
const containerRef = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement | null>(null);
const initialContentHeight = useRef<number>(minHeight);
const contentHeight = useRef<number>(DEFAULT_HEIGHT);
const [initialContentHeight] = useState<number>(minHeight);
const [contentHeight, setContentHeight] = useState<number>(DEFAULT_HEIGHT);

const [dimensions, setDimensions] = useState({width: 0, height: 0});
const [height, setHeight] = useState<string>(toPx(minHeight));
const [showFade, setShowFade] = useState<boolean>(collapsed);
const nextHeight = collapsed ? initialContentHeight : contentHeight;
const height = toPx(nextHeight);

const [shouldHideContent, setShouldHideContent] = useState<boolean>(collapsed && minHeight <= DEFAULT_HEIGHT);

useEffect(() => {
function onTransitionEnd() {
if (initialContentHeight.current <= DEFAULT_HEIGHT) {
if (initialContentHeight <= DEFAULT_HEIGHT) {
setShouldHideContent(collapsed);
}
}
Expand All @@ -54,48 +53,32 @@ export const CollapseContent: React.FC<PropsWithChildren<Props>> = ({
return () => {
container?.removeEventListener('transitionend', onTransitionEnd);
};
}, [collapsed]);
}, [collapsed, initialContentHeight]);

useEffect(() => {
setShowFade(collapsed);
if (!collapsed) setShouldHideContent(false);
}, [collapsed]);

useEffect(() => {
if (contentRef.current) {
contentHeight.current = getRect(contentRef.current).height;
}
}, [minHeight, dimensions.height]);

useEffect(() => {
const nextHeight = collapsed ? initialContentHeight.current : contentHeight.current;
setHeight(toPx(nextHeight));
}, [collapsed, dimensions.height]);
if (!collapsed && shouldHideContent) {
setShouldHideContent(false);
}

useEffect(() => {
if (contentRef.current) {
const observer = new ResizeObserver(([entry]) => {
if (entry && entry.borderBoxSize) {
const {inlineSize, blockSize} = entry.borderBoxSize[0];

setDimensions({width: inlineSize, height: blockSize});
}
const observer = new ResizeObserver(() => {
setContentHeight(getRect(contentRef.current).height);
});

observer.observe(contentRef.current);
}
}, []);

const style = useMemo(() => {
const calculatedDuration = duration + contentHeight.current * DURATION_FACTOR;
const calculatedDuration = duration + contentHeight * DURATION_FACTOR;
return {
'--duration': `${calculatedDuration}ms`,
height,
opacity: collapsed && !minHeight ? HIDDEN : VISIBLE,
};
}, [duration, height, collapsed, minHeight]);
}, [duration, contentHeight, height, collapsed, minHeight]);

const fadeShouldBeVisible = useMemo(() => Boolean(minHeight && showFade), [minHeight, showFade]);
const fadeShouldBeVisible = useMemo(() => Boolean(minHeight && collapsed), [minHeight, collapsed]);

const shouldRenderContent = disableAnimation ? !collapsed : !shouldHideContent;

Expand Down
12 changes: 9 additions & 3 deletions src/heading/heading.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {memo, type HTMLAttributes, type ComponentType} from 'react';
import {memo, type HTMLAttributes, type ComponentType, useEffect} from 'react';
import classNames from 'classnames';
import deprecate from 'util-deprecate';

Expand All @@ -15,7 +15,7 @@ export enum Levels {
H4 = 4,
}

const fallbackHeading = deprecate(() => 'h3', 'Headings of level 5 and higher are replaced with h3');
const warnFallbackHeading = deprecate(() => {}, 'Headings of level 5 and higher are replaced with h3');

export interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
level?: Levels | undefined;
Expand All @@ -29,7 +29,13 @@ const HeadingMemo: ComponentType<HeadingProps> = memo(function Heading({
}: HeadingProps) {
const classes = classNames(styles.heading, className);

const Tag: 'h1' | 'h2' | 'h3' | 'h4' = level <= Levels.H4 ? `h${level}` : fallbackHeading();
const isSupportedLevel = level <= Levels.H4;
useEffect(() => {
if (!isSupportedLevel) {
warnFallbackHeading();
}
}, [isSupportedLevel]);
const Tag: 'h1' | 'h2' | 'h3' | 'h4' = isSupportedLevel ? `h${level}` : 'h3';

return (
<Tag {...restProps} className={classes}>
Expand Down
Loading