Merge pull request #30874 from backstage/bui-header-page
BUI - Update breacrumb on HeaderPage
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/ui': minor
|
||||
---
|
||||
|
||||
Backstage UI - HeaderPage - We are updating the breadcrumb to be more visible and accessible.
|
||||
File diff suppressed because one or more lines are too long
@@ -9,7 +9,8 @@ import {
|
||||
defaultSnippet,
|
||||
withTabs,
|
||||
withBreadcrumbs,
|
||||
withHeaderPage,
|
||||
withCustomActions,
|
||||
withMenuItems,
|
||||
} from './header-page.props';
|
||||
import { PageTitle } from '@/components/PageTitle';
|
||||
import { Theming } from '@/components/Theming';
|
||||
@@ -35,6 +36,52 @@ import { ChangelogComponent } from '@/components/ChangelogComponent';
|
||||
|
||||
<PropsTable data={propDefs} />
|
||||
|
||||
<Theming component="Header" />
|
||||
## Examples
|
||||
|
||||
### With Breadcrumbs
|
||||
|
||||
You can add breadcrumbs to the header page to help users navigate to the previous page. The `breadcrumbs`
|
||||
prop is an array of objects with a `label` and `href` property. By default we truncate the breadcrumb label to 240px.
|
||||
|
||||
<Snippet
|
||||
open
|
||||
preview={<HeaderPageSnippet story="WithLongBreadcrumbs" />}
|
||||
code={withBreadcrumbs}
|
||||
/>
|
||||
|
||||
### With Tabs
|
||||
|
||||
You can add tabs to the header page to help users navigate to the different sections of the page. The `tabs`
|
||||
prop is an array of objects with a `label` and `href` property.
|
||||
|
||||
<Snippet
|
||||
open
|
||||
preview={<HeaderPageSnippet story="WithTabs" />}
|
||||
code={withTabs}
|
||||
/>
|
||||
|
||||
### With Custom Actions
|
||||
|
||||
You can add custom actions to the header page to help users navigate to the different sections of the page. The `customActions`
|
||||
prop is a React node.
|
||||
|
||||
<Snippet
|
||||
open
|
||||
preview={<HeaderPageSnippet story="WithCustomActions" />}
|
||||
code={withCustomActions}
|
||||
/>
|
||||
|
||||
### With Menu Items
|
||||
|
||||
You can add menu items to the header page to help users navigate to the different sections of the page. The `menuItems`
|
||||
prop is an array of objects with a `label`, `value` and `onClick` property.
|
||||
|
||||
<Snippet
|
||||
open
|
||||
preview={<HeaderPageSnippet story="WithMenuItems" />}
|
||||
code={withMenuItems}
|
||||
/>
|
||||
|
||||
<Theming component="HeaderPage" />
|
||||
|
||||
<ChangelogComponent component="Header" />
|
||||
|
||||
@@ -93,7 +93,7 @@ export const usage = `import { HeaderPage } from '@backstage/ui';
|
||||
<HeaderPage />`;
|
||||
|
||||
export const defaultSnippet = `<HeaderPage
|
||||
title="My plugin"
|
||||
title="Page Title"
|
||||
tabs={[
|
||||
{ id: 'overview', label: 'Overview' },
|
||||
{ id: 'checks', label: 'Checks' },
|
||||
@@ -107,3 +107,35 @@ export const defaultSnippet = `<HeaderPage
|
||||
]}
|
||||
customActions={<Button>Custom action</Button>}
|
||||
/>`;
|
||||
|
||||
export const withBreadcrumbs = `<HeaderPage
|
||||
title="Page Title"
|
||||
breadcrumbs={[
|
||||
{ label: 'Home', href: '/' },
|
||||
{ label: 'Long Breadcrumb Name', href: '/long-breadcrumb' },
|
||||
]}
|
||||
/>`;
|
||||
|
||||
export const withTabs = `<HeaderPage
|
||||
title="Page Title"
|
||||
tabs={[
|
||||
{ id: 'overview', label: 'Overview', href: '/overview' },
|
||||
{ id: 'checks', label: 'Checks', href: '/checks' },
|
||||
{ id: 'tracks', label: 'Tracks', href: '/tracks' },
|
||||
{ id: 'campaigns', label: 'Campaigns', href: '/campaigns' },
|
||||
{ id: 'integrations', label: 'Integrations', href: '/integrations' },
|
||||
]}
|
||||
/>`;
|
||||
|
||||
export const withCustomActions = `<HeaderPage
|
||||
title="Page Title"
|
||||
customActions={<Button>Custom action</Button>}
|
||||
/>`;
|
||||
|
||||
export const withMenuItems = `<HeaderPage
|
||||
title="Page Title"
|
||||
menuItems={[
|
||||
{ label: 'Settings', value: 'settings', onClick: () => {} },
|
||||
{ label: 'Invite new members', value: 'invite-new-members', onClick: () => {} },
|
||||
]}
|
||||
/>`;
|
||||
|
||||
@@ -9659,66 +9659,13 @@
|
||||
margin-left: -8px;
|
||||
}
|
||||
|
||||
.bui-HeaderPageControls {
|
||||
.bui-HeaderPageControls, .bui-HeaderPageBreadcrumbs {
|
||||
align-items: center;
|
||||
gap: var(--bui-space-2);
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.bui-HeaderPageSticky {
|
||||
z-index: -1;
|
||||
height: 0;
|
||||
color: var(--bui-fg-primary);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.bui-HeaderPageStickyWrapper {
|
||||
background-color: var(--bui-bg-surface-1);
|
||||
border-bottom: 1px solid var(--bui-border);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.bui-HeaderPageStickyContent {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.bui-HeaderPageBreadcrumbs {
|
||||
align-items: center;
|
||||
gap: var(--bui-space-2);
|
||||
font-size: var(--bui-font-size-3);
|
||||
font-weight: var(--bui-font-weight-regular);
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.bui-HeaderPageBreadcrumb {
|
||||
align-items: center;
|
||||
gap: var(--bui-space-2);
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.bui-HeaderPageBreadcrumbLink {
|
||||
color: var(--bui-fg-secondary);
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
||||
&[data-active="true"] {
|
||||
color: var(--bui-fg-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.bui-HeaderPageBreadcrumbSeparator {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: var(--bui-fg-secondary);
|
||||
}
|
||||
|
||||
.bui-Icon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
|
||||
@@ -42,11 +42,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@base-ui-components/react": "1.0.0-alpha.7",
|
||||
"@gsap/react": "^2.1.2",
|
||||
"@remixicon/react": "^4.6.0",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"clsx": "^2.1.1",
|
||||
"gsap": "^3.13.0",
|
||||
"react-aria-components": "^1.10.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -437,10 +437,6 @@ export const componentDefinitions: {
|
||||
readonly toolbarControls: 'bui-HeaderToolbarControls';
|
||||
readonly toolbarIcon: 'bui-HeaderToolbarIcon';
|
||||
readonly toolbarName: 'bui-HeaderToolbarName';
|
||||
readonly breadcrumbs: 'bui-HeaderBreadcrumbs';
|
||||
readonly breadcrumb: 'bui-HeaderBreadcrumb';
|
||||
readonly breadcrumbLink: 'bui-HeaderBreadcrumbLink';
|
||||
readonly breadcrumbSeparator: 'bui-HeaderBreadcrumbSeparator';
|
||||
readonly tabsWrapper: 'bui-HeaderTabsWrapper';
|
||||
};
|
||||
};
|
||||
@@ -448,15 +444,9 @@ export const componentDefinitions: {
|
||||
readonly classNames: {
|
||||
readonly root: 'bui-HeaderPage';
|
||||
readonly content: 'bui-HeaderPageContent';
|
||||
readonly breadcrumbs: 'bui-HeaderPageBreadcrumbs';
|
||||
readonly tabsWrapper: 'bui-HeaderPageTabsWrapper';
|
||||
readonly controls: 'bui-HeaderPageControls';
|
||||
readonly sticky: 'bui-HeaderPageSticky';
|
||||
readonly stickyWrapper: 'bui-HeaderPageStickyWrapper';
|
||||
readonly stickyContent: 'bui-HeaderPageStickyContent';
|
||||
readonly breadcrumbs: 'bui-HeaderPageBreadcrumbs';
|
||||
readonly breadcrumb: 'bui-HeaderPageBreadcrumb';
|
||||
readonly breadcrumbLink: 'bui-HeaderPageBreadcrumbLink';
|
||||
readonly breadcrumbSeparator: 'bui-HeaderPageBreadcrumbSeparator';
|
||||
};
|
||||
};
|
||||
readonly Heading: {
|
||||
|
||||
@@ -23,10 +23,6 @@ import { ButtonIcon } from '../ButtonIcon';
|
||||
import { Menu } from '../Menu';
|
||||
import { Text } from '../Text';
|
||||
import { useNavigate, useHref } from 'react-router-dom';
|
||||
import { gsap } from 'gsap';
|
||||
import { ScrollTrigger } from 'gsap/ScrollTrigger';
|
||||
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
|
||||
/**
|
||||
* A component that renders a toolbar.
|
||||
|
||||
@@ -111,7 +111,7 @@ const layoutDecorator = [
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
title: 'Header Page',
|
||||
title: 'Page Title',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -134,12 +134,30 @@ export const WithCustomActions: Story = {
|
||||
render: () => (
|
||||
<HeaderPage
|
||||
{...Default.args}
|
||||
menuItems={menuItems}
|
||||
customActions={<Button>Custom action</Button>}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
export const WithBreadcrumbs: Story = {
|
||||
decorators: [withRouter],
|
||||
args: {
|
||||
...Default.args,
|
||||
breadcrumbs: [{ label: 'Home', href: '/' }],
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLongBreadcrumbs: Story = {
|
||||
decorators: [withRouter],
|
||||
args: {
|
||||
...Default.args,
|
||||
breadcrumbs: [
|
||||
{ label: 'Home', href: '/' },
|
||||
{ label: 'Long Breadcrumb Name', href: '/long-breadcrumb' },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const WithEverything: Story = {
|
||||
decorators: [withRouter],
|
||||
render: () => (
|
||||
@@ -148,6 +166,7 @@ export const WithEverything: Story = {
|
||||
menuItems={menuItems}
|
||||
tabs={tabs}
|
||||
customActions={<Button>Custom action</Button>}
|
||||
breadcrumbs={[{ label: 'Home', href: '/' }]}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -39,55 +39,9 @@
|
||||
gap: var(--bui-space-2);
|
||||
}
|
||||
|
||||
.bui-HeaderPageSticky {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
height: 0;
|
||||
color: var(--bui-fg-primary);
|
||||
}
|
||||
|
||||
.bui-HeaderPageStickyWrapper {
|
||||
background-color: var(--bui-bg-surface-1);
|
||||
border-bottom: 1px solid var(--bui-border);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.bui-HeaderPageStickyContent {
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.bui-HeaderPageBreadcrumbs {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: var(--bui-space-2);
|
||||
font-size: var(--bui-font-size-3);
|
||||
font-weight: var(--bui-font-weight-regular);
|
||||
}
|
||||
|
||||
.bui-HeaderPageBreadcrumb {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: var(--bui-space-2);
|
||||
}
|
||||
|
||||
.bui-HeaderPageBreadcrumbLink {
|
||||
color: var(--bui-fg-secondary);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
&[data-active='true'] {
|
||||
color: var(--bui-fg-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.bui-HeaderPageBreadcrumbSeparator {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: var(--bui-fg-secondary);
|
||||
}
|
||||
|
||||
@@ -21,14 +21,9 @@ import { ButtonIcon } from '../ButtonIcon';
|
||||
import { RiArrowRightSLine, RiMore2Line } from '@remixicon/react';
|
||||
import { Tabs, TabList, Tab } from '../Tabs';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
import { useRef } from 'react';
|
||||
import { useGSAP } from '@gsap/react';
|
||||
import { gsap } from 'gsap';
|
||||
import { ScrollTrigger } from 'gsap/ScrollTrigger';
|
||||
import { Container } from '../Container';
|
||||
import { Link } from '../Link';
|
||||
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
import { Fragment } from 'react/jsx-runtime';
|
||||
|
||||
/**
|
||||
* A component that renders a header page.
|
||||
@@ -38,126 +33,81 @@ gsap.registerPlugin(ScrollTrigger);
|
||||
export const HeaderPage = (props: HeaderPageProps) => {
|
||||
const { title, menuItems, tabs, customActions, breadcrumbs } = props;
|
||||
const { classNames } = useStyles('HeaderPage');
|
||||
const stickyRef = useRef<HTMLDivElement>(null);
|
||||
const stickyContentRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useGSAP(() => {
|
||||
const tl = gsap.timeline({
|
||||
scrollTrigger: {
|
||||
trigger: stickyRef.current,
|
||||
start: 'top top',
|
||||
end: '120px top',
|
||||
scrub: true,
|
||||
},
|
||||
});
|
||||
|
||||
tl.to(stickyContentRef.current, {
|
||||
opacity: 1,
|
||||
ease: 'power2.inOut',
|
||||
}).to(
|
||||
stickyRef.current,
|
||||
{
|
||||
zIndex: 10,
|
||||
ease: 'none',
|
||||
},
|
||||
'<',
|
||||
);
|
||||
});
|
||||
|
||||
const controls = (
|
||||
<div className={classNames.controls}>
|
||||
{customActions}
|
||||
{menuItems && (
|
||||
<Menu.Root>
|
||||
<Menu.Trigger
|
||||
render={props => (
|
||||
<ButtonIcon
|
||||
{...props}
|
||||
size="small"
|
||||
icon={<RiMore2Line />}
|
||||
variant="tertiary"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner sideOffset={4} align="end">
|
||||
<Menu.Popup>
|
||||
{menuItems.map(menuItem => (
|
||||
<Menu.Item
|
||||
key={menuItem.value}
|
||||
onClick={() => menuItem.onClick?.()}
|
||||
>
|
||||
{menuItem.label}
|
||||
</Menu.Item>
|
||||
))}
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Container className={classNames.root}>
|
||||
<div className={classNames.content}>
|
||||
<Container className={classNames.root}>
|
||||
<div className={classNames.content}>
|
||||
<div className={classNames.breadcrumbs}>
|
||||
{breadcrumbs &&
|
||||
breadcrumbs.map(breadcrumb => (
|
||||
<Fragment key={breadcrumb.label}>
|
||||
<Link
|
||||
href={breadcrumb.href}
|
||||
variant="title-small"
|
||||
weight="bold"
|
||||
color="secondary"
|
||||
truncate
|
||||
style={{ maxWidth: '240px' }}
|
||||
>
|
||||
{breadcrumb.label}
|
||||
</Link>
|
||||
<RiArrowRightSLine size={16} color="var(--bui-fg-secondary)" />
|
||||
</Fragment>
|
||||
))}
|
||||
<Text variant="title-small" weight="bold" as="h2">
|
||||
{title}
|
||||
</Text>
|
||||
{controls}
|
||||
</div>
|
||||
{tabs && (
|
||||
<div className={classNames.tabsWrapper}>
|
||||
<Tabs>
|
||||
<TabList>
|
||||
{tabs.map(tab => (
|
||||
<Tab
|
||||
key={tab.id}
|
||||
id={tab.id}
|
||||
href={tab.href}
|
||||
matchStrategy={tab.matchStrategy}
|
||||
>
|
||||
{tab.label}
|
||||
</Tab>
|
||||
))}
|
||||
</TabList>
|
||||
</Tabs>
|
||||
</div>
|
||||
)}
|
||||
</Container>
|
||||
<div className={classNames.sticky} ref={stickyRef}>
|
||||
<div className={classNames.stickyWrapper} ref={stickyContentRef}>
|
||||
<Container className={classNames.stickyContent}>
|
||||
{breadcrumbs ? (
|
||||
<div className={classNames.breadcrumbs}>
|
||||
{breadcrumbs.map((breadcrumb, index) => (
|
||||
<div key={breadcrumb.label} className={classNames.breadcrumb}>
|
||||
<Link
|
||||
href={breadcrumb.href}
|
||||
className={classNames.breadcrumbLink}
|
||||
data-active={index === breadcrumbs.length - 1}
|
||||
>
|
||||
{breadcrumb.label}
|
||||
</Link>
|
||||
{index < breadcrumbs.length - 1 && (
|
||||
<RiArrowRightSLine
|
||||
size={16}
|
||||
className={classNames.breadcrumbSeparator}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<Text variant="body-medium" as="p">
|
||||
{title}
|
||||
</Text>
|
||||
)}
|
||||
{controls}
|
||||
</Container>
|
||||
<div className={classNames.controls}>
|
||||
{customActions}
|
||||
{menuItems && (
|
||||
<Menu.Root>
|
||||
<Menu.Trigger
|
||||
render={props => (
|
||||
<ButtonIcon
|
||||
{...props}
|
||||
size="small"
|
||||
icon={<RiMore2Line />}
|
||||
variant="tertiary"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner sideOffset={4} align="end">
|
||||
<Menu.Popup>
|
||||
{menuItems.map(menuItem => (
|
||||
<Menu.Item
|
||||
key={menuItem.value}
|
||||
onClick={() => menuItem.onClick?.()}
|
||||
>
|
||||
{menuItem.label}
|
||||
</Menu.Item>
|
||||
))}
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
{tabs && (
|
||||
<div className={classNames.tabsWrapper}>
|
||||
<Tabs>
|
||||
<TabList>
|
||||
{tabs.map(tab => (
|
||||
<Tab
|
||||
key={tab.id}
|
||||
id={tab.id}
|
||||
href={tab.href}
|
||||
matchStrategy={tab.matchStrategy}
|
||||
>
|
||||
{tab.label}
|
||||
</Tab>
|
||||
))}
|
||||
</TabList>
|
||||
</Tabs>
|
||||
</div>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
useTable,
|
||||
} from '.';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { data as data1 } from './mocked-data1';
|
||||
import { data as data1Raw } from './mocked-data1';
|
||||
import { data as data2 } from './mocked-data2';
|
||||
import { data as data3 } from './mocked-data3';
|
||||
import { data as data4 } from './mocked-data4';
|
||||
@@ -45,6 +45,10 @@ const meta = {
|
||||
],
|
||||
} satisfies Meta;
|
||||
|
||||
// Added this fix to fix Chromatic timeout error. This bug is due to rerendering the table with too many rows.
|
||||
// Work in progress to fix it here - https://github.com/backstage/backstage/pull/30687
|
||||
const data1 = data1Raw.slice(0, 25);
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
|
||||
@@ -112,10 +112,6 @@ export const componentDefinitions = {
|
||||
toolbarControls: 'bui-HeaderToolbarControls',
|
||||
toolbarIcon: 'bui-HeaderToolbarIcon',
|
||||
toolbarName: 'bui-HeaderToolbarName',
|
||||
breadcrumbs: 'bui-HeaderBreadcrumbs',
|
||||
breadcrumb: 'bui-HeaderBreadcrumb',
|
||||
breadcrumbLink: 'bui-HeaderBreadcrumbLink',
|
||||
breadcrumbSeparator: 'bui-HeaderBreadcrumbSeparator',
|
||||
tabsWrapper: 'bui-HeaderTabsWrapper',
|
||||
},
|
||||
},
|
||||
@@ -123,15 +119,9 @@ export const componentDefinitions = {
|
||||
classNames: {
|
||||
root: 'bui-HeaderPage',
|
||||
content: 'bui-HeaderPageContent',
|
||||
breadcrumbs: 'bui-HeaderPageBreadcrumbs',
|
||||
tabsWrapper: 'bui-HeaderPageTabsWrapper',
|
||||
controls: 'bui-HeaderPageControls',
|
||||
sticky: 'bui-HeaderPageSticky',
|
||||
stickyWrapper: 'bui-HeaderPageStickyWrapper',
|
||||
stickyContent: 'bui-HeaderPageStickyContent',
|
||||
breadcrumbs: 'bui-HeaderPageBreadcrumbs',
|
||||
breadcrumb: 'bui-HeaderPageBreadcrumb',
|
||||
breadcrumbLink: 'bui-HeaderPageBreadcrumbLink',
|
||||
breadcrumbSeparator: 'bui-HeaderPageBreadcrumbSeparator',
|
||||
},
|
||||
},
|
||||
Heading: {
|
||||
|
||||
@@ -7473,7 +7473,6 @@ __metadata:
|
||||
dependencies:
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@base-ui-components/react": "npm:1.0.0-alpha.7"
|
||||
"@gsap/react": "npm:^2.1.2"
|
||||
"@remixicon/react": "npm:^4.6.0"
|
||||
"@storybook/addon-essentials": "npm:^8.6.12"
|
||||
"@storybook/addon-interactions": "npm:^8.6.12"
|
||||
@@ -7492,7 +7491,6 @@ __metadata:
|
||||
eslint-plugin-storybook: "npm:^0.12.0"
|
||||
glob: "npm:^11.0.1"
|
||||
globals: "npm:^15.11.0"
|
||||
gsap: "npm:^3.13.0"
|
||||
lightningcss: "npm:^1.29.1"
|
||||
mini-css-extract-plugin: "npm:^2.9.2"
|
||||
react: "npm:^18.0.2"
|
||||
@@ -9367,16 +9365,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@gsap/react@npm:^2.1.2":
|
||||
version: 2.1.2
|
||||
resolution: "@gsap/react@npm:2.1.2"
|
||||
peerDependencies:
|
||||
gsap: ^3.12.5
|
||||
react: ">=17"
|
||||
checksum: 10/48e78bbb31a4ec5a75aab6ea69ec3f4df0bb7cff0c8ebfcdc14553cb8e35f54b7fcf94f933e2aa65fd977135aaac87b855007d376504f1bb93a74328ba1dc0cb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@headlessui/react@npm:^1.7.15":
|
||||
version: 1.7.17
|
||||
resolution: "@headlessui/react@npm:1.7.17"
|
||||
@@ -32336,13 +32324,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"gsap@npm:^3.13.0":
|
||||
version: 3.13.0
|
||||
resolution: "gsap@npm:3.13.0"
|
||||
checksum: 10/1908d51cbdf8f0bec8a69919af352d743a06529639a89f750f1c02e9a165d3ea816f867569df222ee7bfc14e23e268ebeb51dc5df0687fa7918ddd5d3b3efaec
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"gtoken@npm:^7.0.0":
|
||||
version: 7.0.1
|
||||
resolution: "gtoken@npm:7.0.1"
|
||||
|
||||
Reference in New Issue
Block a user