diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index 4f4a52ffd3..ceb099f683 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -12,6 +12,7 @@ import { default as React_2 } from 'react'; import * as React_3 from 'react'; import { ReactNode } from 'react'; import { RefAttributes } from 'react'; +import { ScrollArea as ScrollArea_2 } from '@base-ui-components/react/scroll-area'; // @public (undocumented) export type AlignItems = 'stretch' | 'start' | 'center' | 'end'; @@ -827,6 +828,38 @@ export type ResponsivePropDef = RegularPropDef & { responsive: true; }; +// @public (undocumented) +export const ScrollArea: { + Root: React_2.ForwardRefExoticComponent< + Omit< + ScrollArea_2.Root.Props & React_2.RefAttributes, + 'ref' + > & + React_2.RefAttributes + >; + Viewport: React_2.ForwardRefExoticComponent< + Omit< + ScrollArea_2.Viewport.Props & React_2.RefAttributes, + 'ref' + > & + React_2.RefAttributes + >; + Scrollbar: React_2.ForwardRefExoticComponent< + Omit< + ScrollArea_2.Scrollbar.Props & React_2.RefAttributes, + 'ref' + > & + React_2.RefAttributes + >; + Thumb: React_2.ForwardRefExoticComponent< + Omit< + ScrollArea_2.Thumb.Props & React_2.RefAttributes, + 'ref' + > & + React_2.RefAttributes + >; +}; + // @public (undocumented) export type Space = | '0.5' diff --git a/packages/canon/src/components/ScrollArea/ScrollArea.stories.tsx b/packages/canon/src/components/ScrollArea/ScrollArea.stories.tsx new file mode 100644 index 0000000000..3caf39a29e --- /dev/null +++ b/packages/canon/src/components/ScrollArea/ScrollArea.stories.tsx @@ -0,0 +1,68 @@ +/* + * 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 React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { ScrollArea } from './ScrollArea'; +import { Text } from '../Text/Text'; + +const meta = { + title: 'Components/ScrollArea', + component: ScrollArea.Root, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: () => ( + + +
+ + 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. + + + 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 construction—part of a + broader interest in sustainable design. + +
+
+ + + +
+ ), +}; diff --git a/packages/canon/src/components/ScrollArea/ScrollArea.styles.css b/packages/canon/src/components/ScrollArea/ScrollArea.styles.css new file mode 100644 index 0000000000..1d1c25e9d0 --- /dev/null +++ b/packages/canon/src/components/ScrollArea/ScrollArea.styles.css @@ -0,0 +1,67 @@ +/* + * 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. + */ + +.canon-ScrollAreaRoot { + box-sizing: border-box; + width: 24rem; + height: 8.5rem; + max-width: calc(100vw - 8rem); +} + +.canon-ScrollAreaViewport { + height: 100%; + overscroll-behavior: contain; +} + +.canon-ScrollAreaContent { + display: flex; + flex-direction: column; + gap: 1rem; + padding-block: 0.75rem; + padding-left: 1rem; + padding-right: 1.5rem; +} + +.canon-ScrollAreaScrollbar { + display: flex; + justify-content: center; + background-color: var(--canon-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%; + } +} + +.canon-ScrollAreaThumb { + width: 100%; + border-radius: inherit; + background-color: var(--canon-scrollbar-thumb); +} diff --git a/packages/canon/src/components/ScrollArea/ScrollArea.tsx b/packages/canon/src/components/ScrollArea/ScrollArea.tsx new file mode 100644 index 0000000000..1c0036d005 --- /dev/null +++ b/packages/canon/src/components/ScrollArea/ScrollArea.tsx @@ -0,0 +1,75 @@ +/* + * 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 React from 'react'; +import { ScrollArea as ScrollAreaPrimitive } from '@base-ui-components/react/scroll-area'; +import clsx from 'clsx'; + +const ScrollAreaRoot = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +ScrollAreaRoot.displayName = ScrollAreaPrimitive.Root.displayName; + +const ScrollAreaViewport = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +ScrollAreaViewport.displayName = ScrollAreaPrimitive.Viewport.displayName; + +const ScrollAreaScrollbar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +ScrollAreaScrollbar.displayName = ScrollAreaPrimitive.Scrollbar.displayName; + +const ScrollAreaThumb = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +ScrollAreaThumb.displayName = ScrollAreaPrimitive.Thumb.displayName; + +/** @public */ +export const ScrollArea = { + Root: ScrollAreaRoot, + Viewport: ScrollAreaViewport, + Scrollbar: ScrollAreaScrollbar, + Thumb: ScrollAreaThumb, +}; diff --git a/packages/canon/src/components/ScrollArea/index.ts b/packages/canon/src/components/ScrollArea/index.ts new file mode 100644 index 0000000000..20dab2d8ec --- /dev/null +++ b/packages/canon/src/components/ScrollArea/index.ts @@ -0,0 +1,17 @@ +/* + * 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'; diff --git a/packages/canon/src/css/components.css b/packages/canon/src/css/components.css index d7d99bbe91..e077a065f3 100644 --- a/packages/canon/src/css/components.css +++ b/packages/canon/src/css/components.css @@ -27,3 +27,4 @@ @import '../components/Input/Input.styles.css'; @import '../components/Field/Field.styles.css'; @import '../components/Link/styles.css'; +@import '../components/ScrollArea/ScrollArea.styles.css'; diff --git a/packages/canon/src/css/core.css b/packages/canon/src/css/core.css index 8c7863953a..8efb066b70 100644 --- a/packages/canon/src/css/core.css +++ b/packages/canon/src/css/core.css @@ -109,8 +109,10 @@ --canon-border-warning: #e36d05; --canon-border-success: #53db83; - /* Ring Colors */ + /* Special Colors */ --canon-ring: #1f5493; + --canon-scrollbar: #a0a0a03b; + --canon-scrollbar-thumb: #a0a0a0; } /* Dark theme tokens */ @@ -153,4 +155,9 @@ --canon-border-danger: #f87a7a; --canon-border-warning: #e36d05; --canon-border-success: #53db83; + + /* Special Colors */ + --canon-ring: #1f5493; + --canon-scrollbar: #3636363a; + --canon-scrollbar-thumb: #575757; } diff --git a/packages/canon/src/index.ts b/packages/canon/src/index.ts index 18dad55e89..7c359e2d9b 100644 --- a/packages/canon/src/index.ts +++ b/packages/canon/src/index.ts @@ -38,6 +38,7 @@ export * from './components/Checkbox'; export * from './components/Table'; export * from './components/Input'; export * from './components/Field'; +export * from './components/ScrollArea'; // Types export * from './types';