Remove ScrollArea from BUI

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2025-10-13 23:41:57 +01:00
parent de53c65aeb
commit 0c5351760e
9 changed files with 5 additions and 305 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/ui': minor
---
**BREAKING** The ScrollArea component has been removed from Backstage UI because it did not meet our accessibility standards.
-29
View File
@@ -34,7 +34,6 @@ import { ReactNode } from 'react';
import { RefAttributes } from 'react';
import type { RemixiconComponentType } from '@remixicon/react';
import { RowProps } from 'react-aria-components';
import { ScrollArea as ScrollArea_2 } from '@base-ui-components/react/scroll-area';
import type { SearchFieldProps as SearchFieldProps_2 } from 'react-aria-components';
import type { SelectProps as SelectProps_2 } from 'react-aria-components';
import type { SeparatorProps } from 'react-aria-components';
@@ -624,14 +623,6 @@ export const componentDefinitions: {
readonly radio: 'bui-Radio';
};
};
readonly ScrollArea: {
readonly classNames: {
readonly root: 'bui-ScrollAreaRoot';
readonly viewport: 'bui-ScrollAreaViewport';
readonly scrollbar: 'bui-ScrollAreaScrollbar';
readonly thumb: 'bui-ScrollAreaThumb';
};
};
readonly SearchField: {
readonly classNames: {
readonly root: 'bui-SearchField';
@@ -1265,26 +1256,6 @@ export type Responsive<T> = T | Partial<Record<Breakpoint, T>>;
// @public (undocumented)
export function Row<T extends object>(props: RowProps<T>): JSX_2.Element;
// @public (undocumented)
export const ScrollArea: {
Root: ForwardRefExoticComponent<
Omit<ScrollArea_2.Root.Props & RefAttributes<HTMLDivElement>, 'ref'> &
RefAttributes<HTMLDivElement>
>;
Viewport: ForwardRefExoticComponent<
Omit<ScrollArea_2.Viewport.Props & RefAttributes<HTMLDivElement>, 'ref'> &
RefAttributes<HTMLDivElement>
>;
Scrollbar: ForwardRefExoticComponent<
Omit<ScrollArea_2.Scrollbar.Props & RefAttributes<HTMLDivElement>, 'ref'> &
RefAttributes<HTMLDivElement>
>;
Thumb: ForwardRefExoticComponent<
Omit<ScrollArea_2.Thumb.Props & RefAttributes<HTMLDivElement>, 'ref'> &
RefAttributes<HTMLDivElement>
>;
};
// @public (undocumented)
export const SearchField: ForwardRefExoticComponent<
SearchFieldProps & RefAttributes<HTMLDivElement>
@@ -62,21 +62,6 @@
padding-block: var(--bui-space-1);
}
/* Ensure ScrollArea works properly within MenuRA popover */
.bui-MenuPopover .bui-ScrollAreaRoot {
/* Take full height of popover */
height: 100%;
min-height: 0;
flex: 1;
/* Ensure the root container has proper height constraints */
display: flex;
flex-direction: column;
}
.bui-MenuPopover .bui-ScrollAreaScrollbar {
margin-inline: var(--bui-space-1_5);
}
.bui-MenuItem {
padding-inline: var(--bui-space-1);
display: block;
@@ -1,67 +0,0 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@layer components {
.bui-ScrollAreaRoot {
box-sizing: border-box;
width: 100%;
}
.bui-ScrollAreaViewport {
height: 100%;
overscroll-behavior: contain;
}
.bui-ScrollAreaContent {
display: flex;
flex-direction: column;
gap: 1rem;
padding-block: 0.75rem;
padding-left: 1rem;
padding-right: 1.5rem;
}
.bui-ScrollAreaScrollbar {
display: flex;
justify-content: center;
background-color: var(--bui-scrollbar);
width: 0.25rem;
border-radius: 0.375rem;
margin: 0.5rem;
opacity: 0;
transition: opacity 150ms 300ms;
&[data-hovering],
&[data-scrolling] {
opacity: 1;
transition-duration: 75ms;
transition-delay: 0ms;
}
&::before {
content: '';
position: absolute;
width: 1.25rem;
height: 100%;
}
}
.bui-ScrollAreaThumb {
width: 100%;
border-radius: inherit;
background-color: var(--bui-scrollbar-thumb);
}
}
@@ -1,67 +0,0 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Meta, StoryObj } from '@storybook/react-vite';
import { ScrollArea } from './ScrollArea';
import { Text } from '../Text/Text';
const meta = {
title: 'Backstage UI/ScrollArea',
component: ScrollArea.Root,
} satisfies Meta<typeof ScrollArea.Root>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
render: () => (
<ScrollArea.Root style={{ width: '24rem', height: '8.5rem' }}>
<ScrollArea.Viewport
style={{ border: '1px solid var(--bui-border)', borderRadius: '4px' }}
>
<div style={{ padding: '0.75rem', paddingRight: '1.5rem' }}>
<Text style={{ paddingBottom: '1rem' }}>
Vernacular architecture is building done outside any academic
tradition, and without professional guidance. It is not a particular
architectural movement or style, but rather a broad category,
encompassing a wide range and variety of building types, with
differing methods of construction, from around the world, both
historical and extant and classical and modern. Vernacular
architecture constitutes 95% of the world's built environment, as
estimated in 1995 by Amos Rapoport, as measured against the small
percentage of new buildings every year designed by architects and
built by engineers.
</Text>
<Text>
This type of architecture usually serves immediate, local needs, is
constrained by the materials available in its particular region and
reflects local traditions and cultural practices. The study of
vernacular architecture does not examine formally schooled
architects, but instead that of the design skills and tradition of
local builders, who were rarely given any attribution for the work.
More recently, vernacular architecture has been examined by
designers and the building industry in an effort to be more energy
conscious with contemporary design and constructionpart of a
broader interest in sustainable design.
</Text>
</div>
</ScrollArea.Viewport>
<ScrollArea.Scrollbar orientation="vertical">
<ScrollArea.Thumb />
</ScrollArea.Scrollbar>
</ScrollArea.Root>
),
};
@@ -1,101 +0,0 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { forwardRef } from 'react';
import { ScrollArea as ScrollAreaPrimitive } from '@base-ui-components/react/scroll-area';
import clsx from 'clsx';
import { useStyles } from '../../hooks/useStyles';
import styles from './ScrollArea.module.css';
const ScrollAreaRoot = forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
>(({ className, ...props }, ref) => {
const { classNames } = useStyles('ScrollArea');
return (
<ScrollAreaPrimitive.Root
ref={ref}
className={clsx(classNames.root, styles[classNames.root], className)}
{...props}
/>
);
});
ScrollAreaRoot.displayName = ScrollAreaPrimitive.Root.displayName;
const ScrollAreaViewport = forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Viewport>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Viewport>
>(({ className, ...props }, ref) => {
const { classNames } = useStyles('ScrollArea');
return (
<ScrollAreaPrimitive.Viewport
ref={ref}
className={clsx(
classNames.viewport,
styles[classNames.viewport],
className,
)}
{...props}
/>
);
});
ScrollAreaViewport.displayName = ScrollAreaPrimitive.Viewport.displayName;
const ScrollAreaScrollbar = forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Scrollbar>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Scrollbar>
>(({ className, ...props }, ref) => {
const { classNames } = useStyles('ScrollArea');
return (
<ScrollAreaPrimitive.Scrollbar
ref={ref}
className={clsx(
classNames.scrollbar,
styles[classNames.scrollbar],
className,
)}
{...props}
/>
);
});
ScrollAreaScrollbar.displayName = ScrollAreaPrimitive.Scrollbar.displayName;
const ScrollAreaThumb = forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Thumb>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Thumb>
>(({ className, ...props }, ref) => {
const { classNames } = useStyles('ScrollArea');
return (
<ScrollAreaPrimitive.Thumb
ref={ref}
className={clsx(classNames.thumb, styles[classNames.thumb], className)}
{...props}
/>
);
});
ScrollAreaThumb.displayName = ScrollAreaPrimitive.Thumb.displayName;
/** @public */
export const ScrollArea = {
Root: ScrollAreaRoot,
Viewport: ScrollAreaViewport,
Scrollbar: ScrollAreaScrollbar,
Thumb: ScrollAreaThumb,
};
@@ -1,17 +0,0 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './ScrollArea';
-1
View File
@@ -51,7 +51,6 @@ export * from './components/Text';
export * from './components/TextField';
export * from './components/Tooltip';
export * from './components/Menu';
export * from './components/ScrollArea';
export * from './components/SearchField';
export * from './components/Link';
export * from './components/Select';
@@ -279,14 +279,6 @@ export const componentDefinitions = {
radio: 'bui-Radio',
},
},
ScrollArea: {
classNames: {
root: 'bui-ScrollAreaRoot',
viewport: 'bui-ScrollAreaViewport',
scrollbar: 'bui-ScrollAreaScrollbar',
thumb: 'bui-ScrollAreaThumb',
},
},
SearchField: {
classNames: {
root: 'bui-SearchField',