Merge branch 'backstage:master' into feature/catalog-backend-module-bitbucket-server_-_revert-of-27850
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
Add new breakpoint helpers up(), down() and current breakpoint to help you use our breakpoints in your React components.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': minor
|
||||
---
|
||||
|
||||
Improve class name structure using data attributes instead of class names.
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"mode": "pre",
|
||||
"mode": "exit",
|
||||
"tag": "next",
|
||||
"initialVersions": {
|
||||
"example-app": "0.2.107",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
Add new DataTable component and update Table component styles.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/repo-tools': patch
|
||||
---
|
||||
|
||||
Checking up the files where `createRouter` has been declared and check if `@deprecated` tag exists. If it does not exist then only the message will appear.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': minor
|
||||
---
|
||||
|
||||
Internal update to move the `new` and `create-github-app` to their own module.
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
with:
|
||||
context: './example-app'
|
||||
file: ./example-app/packages/backend/Dockerfile
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
run: |
|
||||
mkdir -p ./pr
|
||||
echo $PR_NUMBER > ./pr/pr_number
|
||||
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: pr_number-${{ github.event.pull_request.number }}
|
||||
path: pr/
|
||||
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: 'Upload artifact'
|
||||
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
@@ -0,0 +1,84 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import {
|
||||
MenuSnippet,
|
||||
ButtonSnippet,
|
||||
LinkSnippet,
|
||||
} from '@/snippets/stories-snippets';
|
||||
import { linkPropDefs } from './props';
|
||||
|
||||
# Link
|
||||
|
||||
A link component that renders a `<a>` element.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<LinkSnippet story="Default" />}
|
||||
code={`<Link href="https://backstage.io">Sign up for Backstage</Link>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Link } from '@backstage/canon';
|
||||
|
||||
<Link href="https://backstage.io">Sign up for Backstage</Link>`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
- `canon-Link`
|
||||
- `canon-Link[data-variant='body']`
|
||||
- `canon-Link[data-variant='subtitle']`
|
||||
- `canon-Link[data-variant='caption']`
|
||||
- `canon-Link[data-variant='label']`
|
||||
- `canon-Link[data-weight='regular']`
|
||||
- `canon-Link[data-weight='bold']`
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={linkPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
|
||||
Here's a view when links have different variants.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<LinkSnippet story="AllVariants" />}
|
||||
code={`<Flex gap="4" direction="column">
|
||||
<Link href="https://canon.backstage.io" variant="subtitle" />
|
||||
<Link href="https://canon.backstage.io" variant="body" />
|
||||
<Link href="https://canon.backstage.io" variant="caption" />
|
||||
<Link href="https://canon.backstage.io" variant="label" />
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Weights
|
||||
|
||||
Here's a view when links have different weights.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<LinkSnippet story="AllWeights" />}
|
||||
code={`<Flex gap="4" direction="column">
|
||||
<Link href="https://canon.backstage.io" weight="regular" />
|
||||
<Link href="https://canon.backstage.io" weight="bold" />
|
||||
</Flex>`}
|
||||
/>
|
||||
@@ -0,0 +1,22 @@
|
||||
import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs';
|
||||
import type { PropDef } from '@/utils/propDefs';
|
||||
|
||||
export const linkPropDefs: Record<string, PropDef> = {
|
||||
to: {
|
||||
type: 'string',
|
||||
},
|
||||
variant: {
|
||||
type: 'enum',
|
||||
values: ['subtitle', 'body', 'caption', 'label'],
|
||||
default: 'body',
|
||||
responsive: true,
|
||||
},
|
||||
weight: {
|
||||
type: 'enum',
|
||||
values: ['regular', 'bold'],
|
||||
default: 'regular',
|
||||
responsive: true,
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -0,0 +1,157 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { MenuSnippet } from '@/snippets/stories-snippets';
|
||||
import { BaseUI } from '@/components/HeadlessBanners/BaseUI';
|
||||
import {
|
||||
menuRootPropDefs,
|
||||
menuTriggerPropDefs,
|
||||
menuPositionerPropDefs,
|
||||
menuItemPropDefs,
|
||||
} from './props';
|
||||
|
||||
# Menu
|
||||
|
||||
A list of actions in a dropdown, enhanced with keyboard navigation.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<MenuSnippet story="Default" />}
|
||||
code={`<Menu.Root>
|
||||
<Menu.Trigger
|
||||
render={props => (
|
||||
<Button
|
||||
{...props}
|
||||
size="medium"
|
||||
variant="secondary"
|
||||
iconEnd="chevron-down"
|
||||
>
|
||||
Menu
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner sideOffset={8} align="start">
|
||||
<Menu.Popup>
|
||||
<Menu.Item>Settings</Menu.Item>
|
||||
<Menu.Item>Invite new members</Menu.Item>
|
||||
<Menu.Item>Download app</Menu.Item>
|
||||
<Menu.Item>Log out</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Menu } from '@backstage/canon';
|
||||
|
||||
<Menu.Root>
|
||||
<Menu.Trigger />
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner>
|
||||
<Menu.Popup>
|
||||
<Menu.Item />
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
- `canon-MenuTrigger`
|
||||
- `canon-MenuBackdrop`
|
||||
- `canon-MenuPositioner`
|
||||
- `canon-MenuPopup`
|
||||
- `canon-MenuArrow`
|
||||
- `canon-MenuItem`
|
||||
- `canon-MenuGroup`
|
||||
- `canon-MenuGroupLabel`
|
||||
- `canon-MenuRadioGroup`
|
||||
- `canon-MenuRadioItem`
|
||||
- `canon-MenuRadioItemIndicator`
|
||||
- `canon-MenuCheckboxItem`
|
||||
- `canon-MenuCheckboxItemIndicator`
|
||||
- `canon-MenuSubmenuTrigger`
|
||||
- `canon-MenuSeparator`
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<BaseUI href="https://base-ui.com/react/components/menu" />
|
||||
|
||||
### Menu.Root
|
||||
|
||||
Groups all parts of the menu. Doesn't render its own HTML element.
|
||||
|
||||
<PropsTable data={menuRootPropDefs} />
|
||||
|
||||
### Menu.Trigger
|
||||
|
||||
The trigger by default render a simple unstyled button. Because menus can be rendered in different ways, we recommend
|
||||
using the `render` prop to render a custom trigger.
|
||||
|
||||
<CodeBlock code={`<Menu.Trigger render={props => <Button {...props} />} />`} />
|
||||
|
||||
<PropsTable data={menuTriggerPropDefs} />
|
||||
|
||||
### Menu.Positioner
|
||||
|
||||
Positions the menu popup against the trigger. Renders a `<div>` element.
|
||||
|
||||
<PropsTable data={menuPositionerPropDefs} />
|
||||
|
||||
### Menu.Item
|
||||
|
||||
An individual interactive item in the menu. Renders a `<div>` element.
|
||||
|
||||
<PropsTable data={menuItemPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Open on hover
|
||||
|
||||
To create a menu that opens on hover, add the `openOnHover` prop to the Root part.
|
||||
You can additionally configure how quickly the menu opens on hover using the `delay` prop.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<MenuSnippet story="OpenOnHover" />}
|
||||
code={`<Menu.Root openOnHover delay={100}>
|
||||
<Menu.Trigger
|
||||
render={props => (
|
||||
<Button
|
||||
{...props}
|
||||
size="medium"
|
||||
variant="secondary"
|
||||
iconEnd="chevron-down"
|
||||
>
|
||||
Menu
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner sideOffset={8} align="start">
|
||||
<Menu.Popup>
|
||||
<Menu.Item>Settings</Menu.Item>
|
||||
<Menu.Item>Invite new members</Menu.Item>
|
||||
<Menu.Item>Download app</Menu.Item>
|
||||
<Menu.Item>Log out</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>`}
|
||||
/>
|
||||
@@ -0,0 +1,142 @@
|
||||
import {
|
||||
classNamePropDefs,
|
||||
stylePropDefs,
|
||||
renderPropDefs,
|
||||
} from '@/utils/propDefs';
|
||||
import type { PropDef } from '@/utils/propDefs';
|
||||
|
||||
export const menuRootPropDefs: Record<string, PropDef> = {
|
||||
defaultOpen: {
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
},
|
||||
open: {
|
||||
type: 'boolean',
|
||||
},
|
||||
onOpenChange: {
|
||||
type: 'enum',
|
||||
values: ['(open, event) => void'],
|
||||
},
|
||||
closeParentOnEsc: {
|
||||
type: 'boolean',
|
||||
default: 'true',
|
||||
},
|
||||
modal: {
|
||||
type: 'boolean',
|
||||
default: 'true',
|
||||
},
|
||||
onOpenChangeComplete: {
|
||||
type: 'enum',
|
||||
values: ['(open) => void'],
|
||||
},
|
||||
disabled: {
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
},
|
||||
openOnHover: {
|
||||
type: 'boolean',
|
||||
},
|
||||
delay: {
|
||||
type: 'number',
|
||||
default: '100',
|
||||
},
|
||||
loop: {
|
||||
type: 'boolean',
|
||||
default: 'true',
|
||||
},
|
||||
orientation: {
|
||||
type: 'enum',
|
||||
values: ['horizontal', 'vertical'],
|
||||
default: 'vertical',
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
|
||||
export const menuTriggerPropDefs: Record<string, PropDef> = {
|
||||
...renderPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
|
||||
export const menuPositionerPropDefs: Record<string, PropDef> = {
|
||||
align: {
|
||||
type: 'enum',
|
||||
values: ['start', 'center', 'end'],
|
||||
default: 'center',
|
||||
},
|
||||
alignOffset: {
|
||||
type: 'enum',
|
||||
values: ['number', '(data) => number'],
|
||||
default: '0',
|
||||
},
|
||||
side: {
|
||||
type: 'enum',
|
||||
values: ['bottom', 'inline-end', 'inline-start', 'left', 'right', 'top'],
|
||||
default: 'bottom',
|
||||
},
|
||||
sideOffset: {
|
||||
type: 'enum',
|
||||
values: ['number', '(data) => number'],
|
||||
default: '0',
|
||||
},
|
||||
arrowPadding: {
|
||||
type: 'number',
|
||||
default: '5',
|
||||
},
|
||||
anchor: {
|
||||
type: 'enum',
|
||||
values: [
|
||||
'React.Ref',
|
||||
'Element',
|
||||
'VirtualElement',
|
||||
'(() => Element | VirtualElement | null)',
|
||||
'null',
|
||||
],
|
||||
},
|
||||
collisionBoundary: {
|
||||
type: 'enum',
|
||||
values: ['clipping-ancestors', 'Element', 'Element[]', 'Rect'],
|
||||
default: 'clipping-ancestors',
|
||||
},
|
||||
collisionPadding: {
|
||||
type: 'enum',
|
||||
values: ['number', 'Rect'],
|
||||
default: '5',
|
||||
},
|
||||
sticky: {
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
},
|
||||
positionMethod: {
|
||||
type: 'enum',
|
||||
values: ['absolute', 'fixed'],
|
||||
default: 'absolute',
|
||||
},
|
||||
trackAnchor: {
|
||||
type: 'boolean',
|
||||
default: 'true',
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
|
||||
export const menuItemPropDefs: Record<string, PropDef> = {
|
||||
label: {
|
||||
type: 'string',
|
||||
},
|
||||
onClick: {
|
||||
type: 'enum',
|
||||
values: ['(event) => void'],
|
||||
},
|
||||
closeOnClick: {
|
||||
type: 'boolean',
|
||||
default: 'true',
|
||||
},
|
||||
disabled: {
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -29,8 +29,100 @@ Here's an example of how your theme.css file should look like:
|
||||
|
||||
<CodeBlock lang="css" code={customTheme} />
|
||||
|
||||
## CSS class name structure
|
||||
|
||||
All Canon components come with a set of CSS classes that you can use to style them. To make it
|
||||
easier to identify the class name you can use, we use a specific structure for the class names.
|
||||
|
||||
<img
|
||||
src="/css-classname-structure.png"
|
||||
style={{ width: '100%', marginBottom: '32px', marginTop: '16px' }}
|
||||
/>
|
||||
|
||||
Every component has a unique prefix `.canon-` followed by the component name. Component props
|
||||
are represented using the `data-` attribute. That way, class names are easily identifiable.
|
||||
|
||||
## Available CSS variables
|
||||
|
||||
### Base colors
|
||||
|
||||
These colors are used for special purposes like ring, scrollbar, ...
|
||||
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
<Table.HeaderRow>
|
||||
<Table.HeaderCell>Prop</Table.HeaderCell>
|
||||
<Table.HeaderCell>Description</Table.HeaderCell>
|
||||
</Table.HeaderRow>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-black</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Pure black color. This one should be the same in light and dark themes.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-white</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Pure white color. This one should be the same in light and dark themes.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-gray-1</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-gray-2</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-gray-3</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-gray-4</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-gray-5</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-gray-6</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-gray-7</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-gray-8</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>You can use these mostly for backgrounds colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
### Core background colors
|
||||
|
||||
These colors are used for the background of your application. We are mostly using for now a
|
||||
@@ -57,98 +149,60 @@ color of your app.
|
||||
</Table.Cell>
|
||||
<Table.Cell>Use for any panels or elevated surfaces.</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
### Component background colors
|
||||
|
||||
These colors are meants for interactive components like buttons, callout avatar, chips, ...
|
||||
We have two main level of background you can customise. The accent one is mostly used as a primary option
|
||||
for interactive components. The tint one is used for secondary components like callouts, avatars, ...
|
||||
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
<Table.HeaderRow>
|
||||
<Table.HeaderCell>Prop</Table.HeaderCell>
|
||||
<Table.HeaderCell>Description</Table.HeaderCell>
|
||||
</Table.HeaderRow>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-bg-accent</Chip>
|
||||
<Chip head>--canon-bg-surface-2</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used mostly for primary interactive components.</Table.Cell>
|
||||
<Table.Cell>Use for any panels or elevated surfaces.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-bg-accent-hover</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Used for interactive components when they are hovered.
|
||||
<Chip head>--canon-bg-solid</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used for solid background colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-bg-accent-focus</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Used for interactive components when they are in focus.
|
||||
<Chip head>--canon-bg-solid-hover</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used for solid background colors when hovered.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-bg-accent-disabled</Chip>
|
||||
<Chip head>--canon-bg-solid-pressed</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used for solid background colors when pressed.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
Used for interactive components when they are disabled.
|
||||
<Chip head>--canon-bg-solid-disabled</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used for solid background colors when disabled.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-bg-tint</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used for secondary interactive components.</Table.Cell>
|
||||
<Table.Cell>Used for tint background colors.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-bg-tint-hover</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Used for interactive components when they are hovered.
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used for tint background colors when hovered.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-bg-tint-focus</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Used for interactive components when they are active.
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used for tint background colors when active.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-bg-tint-disabled</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Used for interactive components when they are disabled.
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used for tint background colors when disabled.</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
### Status background colors
|
||||
|
||||
These backgrounds are intended for non-interactive elements to visually convey a specific state.
|
||||
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
<Table.HeaderRow>
|
||||
<Table.HeaderCell>Prop</Table.HeaderCell>
|
||||
<Table.HeaderCell>Description</Table.HeaderCell>
|
||||
</Table.HeaderRow>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-bg-danger</Chip>
|
||||
@@ -189,7 +243,7 @@ are prefixed with `fg` to make it easier to identify.
|
||||
<Chip head>--canon-fg-primary</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of `--canon-bg-app` or `--canon-bg-surface-1`.
|
||||
It should be used on top of main background surfaces.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
@@ -197,7 +251,7 @@ are prefixed with `fg` to make it easier to identify.
|
||||
<Chip head>--canon-fg-secondary</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of `--canon-bg-app` or `--canon-bg-surface-1`.
|
||||
It should be used on top of main background surfaces.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
@@ -205,7 +259,7 @@ are prefixed with `fg` to make it easier to identify.
|
||||
<Chip head>--canon-fg-link</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of `--canon-bg-app` or `--canon-bg-surface-1`.
|
||||
It should be used on top of main background surfaces.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
@@ -213,38 +267,64 @@ are prefixed with `fg` to make it easier to identify.
|
||||
<Chip head>--canon-fg-link-hover</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of `--canon-bg-app` or `--canon-bg-surface-1`.
|
||||
It should be used on top of main background surfaces.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-fg-accent</Chip>
|
||||
<Chip head>--canon-fg-disabled</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of main background surfaces.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-fg-solid</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of solid background colors.
|
||||
</Table.Cell>
|
||||
<Table.Cell>It should be used on top of `--canon-bg-accent`.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-fg-tint</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>It should be used on top of `--canon-bg-tint`.</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of tint background colors.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-fg-tint-disabled</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of tint background colors when disabled.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-fg-danger</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>It should be used on top of `--canon-bg-danger`.</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of danger background colors.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-fg-warning</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>It should be used on top of `--canon-bg-warning`.</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of warning background colors.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-fg-success</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>It should be used on top of `--canon-bg-success`.</Table.Cell>
|
||||
<Table.Cell>
|
||||
It should be used on top of success background colors.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
@@ -288,21 +368,9 @@ low contrast to help as a separator with the different background colors.
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-border-tint</Chip>
|
||||
<Chip head>--canon-border-disabled</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>It should be used on top of `--canon-bg-tint`.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-border-tint-hover</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used when the component is hovered.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-border-tint-focus</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>Used when the component is in focus.</Table.Cell>
|
||||
<Table.Cell>Used when the component is disabled.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
@@ -325,7 +393,40 @@ low contrast to help as a separator with the different background colors.
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
## Font families
|
||||
### Special colors
|
||||
|
||||
These colors are used for special purposes like ring, scrollbar, ...
|
||||
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
<Table.HeaderRow>
|
||||
<Table.HeaderCell>Prop</Table.HeaderCell>
|
||||
<Table.HeaderCell>Description</Table.HeaderCell>
|
||||
</Table.HeaderRow>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-ring</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>The color of the ring.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-scrollbar</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>The color of the scrollbar.</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-scrollbar-thumb</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>The color of the scrollbar thumb.</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
### Font families
|
||||
|
||||
We have two fonts that we use across Canon. The first one is the sans-serif
|
||||
font that we use for the body of the application. The second one is the
|
||||
@@ -354,9 +455,9 @@ monospace font that we use for code blocks and tables.
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
## Font weights
|
||||
### Font weights
|
||||
|
||||
We have two font weights that we use across Canon. Regular or Bold
|
||||
We have two font weights that we use across Canon. Regular or Bold.
|
||||
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
@@ -381,7 +482,7 @@ We have two font weights that we use across Canon. Regular or Bold
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
## Spacing
|
||||
### Spacing
|
||||
|
||||
We built a spacing system based on a single value `--canon-space`. This value is
|
||||
used to calculate the spacing for all the components. By default if you would like to
|
||||
@@ -520,18 +621,9 @@ tokens for pretty much each spacing properties like padding, margin, gaps, ...
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
### Radius (Work in progress)
|
||||
### Radius
|
||||
|
||||
Our radius system is a little bit different from spacing as we use a factor to calculate the radius values.
|
||||
Under the hood different components uses different radius values. For example, button can be set to have full radius
|
||||
while a checkbox will have to remain a square.
|
||||
|
||||
Here are the different radius factor we recommend to use
|
||||
|
||||
- None: `0`
|
||||
- Small: `0.75`
|
||||
- Medium: `1`
|
||||
- Large: `1.5`
|
||||
We use a radius system to make sure that the components have a consistent look and feel.
|
||||
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
@@ -543,9 +635,59 @@ Here are the different radius factor we recommend to use
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-radius-factor</Chip>
|
||||
<Chip head>--canon-radius-1</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The radius of the component. Default value is `0.125rem`.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-radius-2</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The radius of the component. Default value is `0.25rem`.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-radius-3</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The radius of the component. Default value is `0.5rem`.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-radius-4</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The radius of the component. Default value is `0.75rem`.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-radius-5</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The radius of the component. Default value is `1rem`.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-radius-6</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The radius of the component. Default value is `1.25rem`.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Chip head>--canon-radius-full</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The radius of the component. Default value is `9999px`.
|
||||
</Table.Cell>
|
||||
<Table.Cell>By default the value is set to medium `1`.</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
|
||||
@@ -13,6 +13,8 @@ import * as TextFieldStories from '../../../packages/canon/src/components/TextFi
|
||||
import * as TextStories from '../../../packages/canon/src/components/Text/Text.stories';
|
||||
import * as FlexStories from '../../../packages/canon/src/components/Flex/Flex.stories';
|
||||
import * as SelectStories from '../../../packages/canon/src/components/Select/Select.stories';
|
||||
import * as MenuStories from '../../../packages/canon/src/components/Menu/Menu.stories';
|
||||
import * as LinkStories from '../../../packages/canon/src/components/Link/Link.stories';
|
||||
|
||||
export const BoxSnippet = ({ story }: { story: keyof typeof BoxStories }) => {
|
||||
const stories = composeStories(BoxStories);
|
||||
@@ -125,3 +127,17 @@ export const SelectSnippet = ({
|
||||
|
||||
return StoryComponent ? <StoryComponent /> : null;
|
||||
};
|
||||
|
||||
export const MenuSnippet = ({ story }: { story: keyof typeof MenuStories }) => {
|
||||
const stories = composeStories(MenuStories);
|
||||
const StoryComponent = stories[story as keyof typeof stories];
|
||||
|
||||
return StoryComponent ? <StoryComponent /> : null;
|
||||
};
|
||||
|
||||
export const LinkSnippet = ({ story }: { story: keyof typeof LinkStories }) => {
|
||||
const stories = composeStories(LinkStories);
|
||||
const StoryComponent = stories[story as keyof typeof stories];
|
||||
|
||||
return StoryComponent ? <StoryComponent /> : null;
|
||||
};
|
||||
|
||||
@@ -91,6 +91,16 @@ export const components: Page[] = [
|
||||
slug: 'icon-button',
|
||||
status: 'alpha',
|
||||
},
|
||||
{
|
||||
title: 'Link',
|
||||
slug: 'link',
|
||||
status: 'alpha',
|
||||
},
|
||||
{
|
||||
title: 'Menu',
|
||||
slug: 'menu',
|
||||
status: 'alpha',
|
||||
},
|
||||
{
|
||||
title: 'Select',
|
||||
slug: 'select',
|
||||
|
||||
@@ -203,3 +203,11 @@ export const childrenPropDefs: Record<string, PropDef> = {
|
||||
responsive: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const renderPropDefs: Record<string, PropDef> = {
|
||||
render: {
|
||||
type: 'enum',
|
||||
values: ['React.ReactElement', '(props, state) => React.ReactElement'],
|
||||
responsive: false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -916,11 +916,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^20":
|
||||
version: 20.17.24
|
||||
resolution: "@types/node@npm:20.17.24"
|
||||
version: 20.17.30
|
||||
resolution: "@types/node@npm:20.17.30"
|
||||
dependencies:
|
||||
undici-types: "npm:~6.19.2"
|
||||
checksum: 10/0c5fe294b003656b0f95ffce295c08e7ed3fa814ba9bf891e146dced90322d186e63837db9d9bb14d4f294fbe1a6fa1c89ced0b173380c8aaeb90de6c3eddb3b
|
||||
checksum: 10/69fd3b177417be77b459e8f1dd4e78c85c686167086920fbf35a9fda301709bbeee6a87ad2591fb1ddd96c65e725ec6bb527a06496626a1c94367d1361048f8d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5410,22 +5410,22 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"typescript@npm:^5":
|
||||
version: 5.8.2
|
||||
resolution: "typescript@npm:5.8.2"
|
||||
version: 5.8.3
|
||||
resolution: "typescript@npm:5.8.3"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 10/dbc2168a55d56771f4d581997be52bab5cbc09734fec976cfbaabd787e61fb4c6cf9125fd48c6f98054ce549c77ecedefc7f64252a830dd8e9c3381f61fbeb78
|
||||
checksum: 10/65c40944c51b513b0172c6710ee62e951b70af6f75d5a5da745cb7fab132c09ae27ffdf7838996e3ed603bb015dadd099006658046941bd0ba30340cc563ae92
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@npm%3A^5#optional!builtin<compat/typescript>":
|
||||
version: 5.8.2
|
||||
resolution: "typescript@patch:typescript@npm%3A5.8.2#optional!builtin<compat/typescript>::version=5.8.2&hash=5786d5"
|
||||
version: 5.8.3
|
||||
resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin<compat/typescript>::version=5.8.3&hash=5786d5"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 10/97920a082ffc57583b1cb6bc4faa502acc156358e03f54c7fc7fdf0b61c439a717f4c9070c449ee9ee683d4cfc3bb203127c2b9794b2950f66d9d307a4ff262c
|
||||
checksum: 10/b9b1e73dabac5dc730c041325dbd9c99467c1b0d239f1b74ec3b90d831384af3e2ba973946232df670519147eb51a2c20f6f96163cea2b359f03de1e2091cc4f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
+52
-52
@@ -2961,94 +2961,94 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-darwin-arm64@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-darwin-arm64@npm:1.11.10"
|
||||
"@swc/core-darwin-arm64@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-darwin-arm64@npm:1.11.21"
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-darwin-x64@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-darwin-x64@npm:1.11.10"
|
||||
"@swc/core-darwin-x64@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-darwin-x64@npm:1.11.21"
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-arm-gnueabihf@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-linux-arm-gnueabihf@npm:1.11.10"
|
||||
"@swc/core-linux-arm-gnueabihf@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-linux-arm-gnueabihf@npm:1.11.21"
|
||||
conditions: os=linux & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-arm64-gnu@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-linux-arm64-gnu@npm:1.11.10"
|
||||
"@swc/core-linux-arm64-gnu@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-linux-arm64-gnu@npm:1.11.21"
|
||||
conditions: os=linux & cpu=arm64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-arm64-musl@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-linux-arm64-musl@npm:1.11.10"
|
||||
"@swc/core-linux-arm64-musl@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-linux-arm64-musl@npm:1.11.21"
|
||||
conditions: os=linux & cpu=arm64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-x64-gnu@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-linux-x64-gnu@npm:1.11.10"
|
||||
"@swc/core-linux-x64-gnu@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-linux-x64-gnu@npm:1.11.21"
|
||||
conditions: os=linux & cpu=x64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-x64-musl@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-linux-x64-musl@npm:1.11.10"
|
||||
"@swc/core-linux-x64-musl@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-linux-x64-musl@npm:1.11.21"
|
||||
conditions: os=linux & cpu=x64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-win32-arm64-msvc@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-win32-arm64-msvc@npm:1.11.10"
|
||||
"@swc/core-win32-arm64-msvc@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-win32-arm64-msvc@npm:1.11.21"
|
||||
conditions: os=win32 & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-win32-ia32-msvc@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-win32-ia32-msvc@npm:1.11.10"
|
||||
"@swc/core-win32-ia32-msvc@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-win32-ia32-msvc@npm:1.11.21"
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-win32-x64-msvc@npm:1.11.10":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core-win32-x64-msvc@npm:1.11.10"
|
||||
"@swc/core-win32-x64-msvc@npm:1.11.21":
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core-win32-x64-msvc@npm:1.11.21"
|
||||
conditions: os=win32 & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core@npm:^1.3.46":
|
||||
version: 1.11.10
|
||||
resolution: "@swc/core@npm:1.11.10"
|
||||
version: 1.11.21
|
||||
resolution: "@swc/core@npm:1.11.21"
|
||||
dependencies:
|
||||
"@swc/core-darwin-arm64": "npm:1.11.10"
|
||||
"@swc/core-darwin-x64": "npm:1.11.10"
|
||||
"@swc/core-linux-arm-gnueabihf": "npm:1.11.10"
|
||||
"@swc/core-linux-arm64-gnu": "npm:1.11.10"
|
||||
"@swc/core-linux-arm64-musl": "npm:1.11.10"
|
||||
"@swc/core-linux-x64-gnu": "npm:1.11.10"
|
||||
"@swc/core-linux-x64-musl": "npm:1.11.10"
|
||||
"@swc/core-win32-arm64-msvc": "npm:1.11.10"
|
||||
"@swc/core-win32-ia32-msvc": "npm:1.11.10"
|
||||
"@swc/core-win32-x64-msvc": "npm:1.11.10"
|
||||
"@swc/core-darwin-arm64": "npm:1.11.21"
|
||||
"@swc/core-darwin-x64": "npm:1.11.21"
|
||||
"@swc/core-linux-arm-gnueabihf": "npm:1.11.21"
|
||||
"@swc/core-linux-arm64-gnu": "npm:1.11.21"
|
||||
"@swc/core-linux-arm64-musl": "npm:1.11.21"
|
||||
"@swc/core-linux-x64-gnu": "npm:1.11.21"
|
||||
"@swc/core-linux-x64-musl": "npm:1.11.21"
|
||||
"@swc/core-win32-arm64-msvc": "npm:1.11.21"
|
||||
"@swc/core-win32-ia32-msvc": "npm:1.11.21"
|
||||
"@swc/core-win32-x64-msvc": "npm:1.11.21"
|
||||
"@swc/counter": "npm:^0.1.3"
|
||||
"@swc/types": "npm:^0.1.19"
|
||||
"@swc/types": "npm:^0.1.21"
|
||||
peerDependencies:
|
||||
"@swc/helpers": "*"
|
||||
"@swc/helpers": ">=0.5.17"
|
||||
dependenciesMeta:
|
||||
"@swc/core-darwin-arm64":
|
||||
optional: true
|
||||
@@ -3073,7 +3073,7 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
"@swc/helpers":
|
||||
optional: true
|
||||
checksum: 10/4fcda5222fe4311dd6fe07586c72458f86a3a7ccee09cc7115ff3308f12d84a019d0b6996bcc778014f30f9a683de2d94a21498f69f8ed53941912c851716572
|
||||
checksum: 10/98a0f201a0a4aa026b0b07c61c8da49d94d4ac3b059b466416c90b9b2cb4f457d836ae55ccfe90b0a89c7bdde36526ba5b7747c4e616c0d556c733e3728e9dd4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -3084,12 +3084,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/types@npm:^0.1.19":
|
||||
version: 0.1.19
|
||||
resolution: "@swc/types@npm:0.1.19"
|
||||
"@swc/types@npm:^0.1.21":
|
||||
version: 0.1.21
|
||||
resolution: "@swc/types@npm:0.1.21"
|
||||
dependencies:
|
||||
"@swc/counter": "npm:^0.1.3"
|
||||
checksum: 10/693147cc9b23147164ddff9cb89477c369fbeb103319584779352a9ff1c72e0a70b97a89dfd97629040db8956d668d7b7a8fed328ffea46a3e8c18577e396994
|
||||
checksum: 10/6554bf5c78519f49099a2ba448d170191a14b1c7a35df848f10ee4d6c03ecd681e5213884905187de1d1d221589ec8b5cb77f477d099dc1627c3ec9d7f2fcdb0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5942,11 +5942,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"docusaurus-pushfeedback@npm:^1.0.0":
|
||||
version: 1.0.1
|
||||
resolution: "docusaurus-pushfeedback@npm:1.0.1"
|
||||
version: 1.0.3
|
||||
resolution: "docusaurus-pushfeedback@npm:1.0.3"
|
||||
peerDependencies:
|
||||
"@docusaurus/core": 3.x
|
||||
checksum: 10/5160e33eded0c4bec51fba986561c33b69eee46799d69051188990d66353e43e49d826f5e44c9f73a67d0df36aa03ee7a3679b6d0cd6b0d9fed5f0f78fe4a1a3
|
||||
checksum: 10/ee80ae0c1fc079b2c317cab86d83ba50cce18938a6ce0ac647aad25dc68fc0ad659e55c11e93d0e7c23270c503c3cb300111dfbdd04785ef7aaf6fb123b57eae
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--variant-primary {
|
||||
.canon-Button[data-variant="primary"] {
|
||||
background-color: var(--canon-bg-solid);
|
||||
color: var(--canon-fg-solid);
|
||||
transition: background-color .15s, box-shadow .15s;
|
||||
@@ -40,7 +40,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--variant-secondary {
|
||||
.canon-Button[data-variant="secondary"] {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
color: var(--canon-fg-primary);
|
||||
@@ -66,24 +66,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--size-medium {
|
||||
.canon-Button[data-size="medium"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
padding: 0 var(--canon-space-3);
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.canon-Button--size-small {
|
||||
.canon-Button[data-size="small"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
padding: 0 var(--canon-space-2);
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.canon-Button--size-small .canon-Button--icon {
|
||||
.canon-Button[data-size="small"] .canon-ButtonIcon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.canon-Button--size-medium .canon-Button--icon {
|
||||
.canon-Button[data-size="medium"] .canon-ButtonIcon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
+123
-116
@@ -22,7 +22,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--variant-primary {
|
||||
.canon-Button[data-variant="primary"] {
|
||||
background-color: var(--canon-bg-solid);
|
||||
color: var(--canon-fg-solid);
|
||||
transition: background-color .15s, box-shadow .15s;
|
||||
@@ -46,7 +46,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--variant-secondary {
|
||||
.canon-Button[data-variant="secondary"] {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
color: var(--canon-fg-primary);
|
||||
@@ -72,28 +72,58 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--size-medium {
|
||||
.canon-Button[data-size="medium"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
padding: 0 var(--canon-space-3);
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.canon-Button--size-small {
|
||||
.canon-Button[data-size="small"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
padding: 0 var(--canon-space-2);
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.canon-Button--size-small .canon-Button--icon {
|
||||
.canon-Button[data-size="small"] .canon-ButtonIcon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.canon-Button--size-medium .canon-Button--icon {
|
||||
.canon-Button[data-size="medium"] .canon-ButtonIcon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.canon-DataTableRoot {
|
||||
gap: var(--canon-space-3);
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination {
|
||||
padding-top: var(--canon-space-5);
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--left {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--right {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--canon-space-2);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--select {
|
||||
min-width: 10.5rem;
|
||||
}
|
||||
|
||||
.canon-Flex {
|
||||
display: flex;
|
||||
}
|
||||
@@ -179,117 +209,94 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.table {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
border-radius: var(--canon-radius-2);
|
||||
.canon-TableRoot {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
padding-bottom: var(--canon-space-0_5);
|
||||
padding-top: var(--canon-space-0_5);
|
||||
font-size: var(--canon-font-size-3);
|
||||
font-family: var(--canon-font-regular);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
|
||||
& table {
|
||||
caption-side: bottom;
|
||||
width: 100%;
|
||||
font-size: var(--canon-font-size-sm);
|
||||
border-collapse: collapse;
|
||||
}
|
||||
}
|
||||
|
||||
.table-head {
|
||||
.canon-TableHead {
|
||||
text-align: left;
|
||||
padding: var(--canon-space-3);
|
||||
font-size: var(--canon-font-size-3);
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.table-body {
|
||||
& tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.canon-TableBody {
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.table-row {
|
||||
.canon-TableRow {
|
||||
border-bottom: 1px solid var(--canon-border);
|
||||
transition: color .2s ease-in-out;
|
||||
|
||||
&:hover td {
|
||||
background-color: var(--canon-bg-tint);
|
||||
}
|
||||
|
||||
& .table-cell:first-child {
|
||||
border-top-left-radius: var(--canon-radius-2);
|
||||
border-bottom-left-radius: var(--canon-radius-2);
|
||||
box-shadow: inset 4px 2px 0 0 var(--canon-bg-surface-1), inset 4px -2px 0 0 var(--canon-bg-surface-1);
|
||||
padding-left: var(--canon-space-3);
|
||||
}
|
||||
|
||||
& .table-cell:last-child {
|
||||
border-top-right-radius: var(--canon-radius-2);
|
||||
border-bottom-right-radius: var(--canon-radius-2);
|
||||
box-shadow: inset -4px 2px 0 0 var(--canon-bg-surface-1), inset -4px -2px 0 0 var(--canon-bg-surface-1);
|
||||
padding-right: var(--canon-space-3);
|
||||
}
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
.canon-TableBody .canon-TableRow:hover {
|
||||
background-color: var(--canon-gray-2);
|
||||
}
|
||||
|
||||
.canon-TableCell {
|
||||
padding: var(--canon-space-3);
|
||||
background-color: var(--canon-bg);
|
||||
box-shadow: inset 0px 2px 0 0 var(--canon-bg-surface-1), inset 0px -2px 0 0 var(--canon-bg-surface-1);
|
||||
font-size: var(--canon-font-size-3);
|
||||
}
|
||||
|
||||
.canon-TableCellText, .canon-TableCellLink {
|
||||
gap: var(--canon-space-0_5);
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Text {
|
||||
font-family: var(--canon-font-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.canon-Text--variant-body {
|
||||
.canon-Text[data-variant="body"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-subtitle {
|
||||
.canon-Text[data-variant="subtitle"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-caption {
|
||||
.canon-Text[data-variant="caption"] {
|
||||
font-size: var(--canon-font-size-2);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-label {
|
||||
.canon-Text[data-variant="label"] {
|
||||
font-size: var(--canon-font-size-1);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--weight-regular {
|
||||
.canon-Text[data-weight="regular"] {
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
}
|
||||
|
||||
.canon-Text--weight-bold {
|
||||
.canon-Text[data-weight="bold"] {
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Text--color-primary {
|
||||
.canon-Text[data-color="primary"] {
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.canon-Text--color-secondary {
|
||||
.canon-Text[data-color="secondary"] {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-Text--color-danger {
|
||||
.canon-Text[data-color="danger"] {
|
||||
color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-Text--color-warning {
|
||||
.canon-Text[data-color="warning"] {
|
||||
color: var(--canon-fg-warning);
|
||||
}
|
||||
|
||||
.canon-Text--color-success {
|
||||
.canon-Text[data-color="success"] {
|
||||
color: var(--canon-fg-success);
|
||||
}
|
||||
|
||||
@@ -301,32 +308,32 @@
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.canon-Heading--variant-display {
|
||||
.canon-Heading[data-variant="display"] {
|
||||
font-size: var(--canon-font-size-10);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title1 {
|
||||
.canon-Heading[data-variant="title1"] {
|
||||
font-size: var(--canon-font-size-9);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title2 {
|
||||
.canon-Heading[data-variant="title2"] {
|
||||
font-size: var(--canon-font-size-8);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title3 {
|
||||
.canon-Heading[data-variant="title3"] {
|
||||
font-size: var(--canon-font-size-7);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title4 {
|
||||
.canon-Heading[data-variant="title4"] {
|
||||
font-size: var(--canon-font-size-title4);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title5 {
|
||||
.canon-Heading[data-variant="title5"] {
|
||||
font-size: var(--canon-font-size-5);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
@@ -349,7 +356,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--variant-primary {
|
||||
.canon-IconButton[data-variant="primary"] {
|
||||
background-color: var(--canon-bg-solid);
|
||||
color: var(--canon-fg-solid);
|
||||
transition: background-color .15s, box-shadow .15s;
|
||||
@@ -373,7 +380,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--variant-secondary {
|
||||
.canon-IconButton[data-variant="secondary"] {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
color: var(--canon-fg-primary);
|
||||
@@ -399,24 +406,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--size-medium {
|
||||
.canon-IconButton[data-size="medium"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-small {
|
||||
.canon-IconButton[data-size="small"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-small .canon-IconButton--icon {
|
||||
.canon-IconButton[data-size="small"] .canon-IconButtonIcon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-medium .canon-IconButton--icon {
|
||||
.canon-IconButton[data-size="medium"] .canon-IconButtonIcon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
@@ -428,14 +435,14 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-TextField--label {
|
||||
.canon-TextFieldLabel {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-TextField--description {
|
||||
.canon-TextFieldDescription {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -443,7 +450,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-TextField--error {
|
||||
.canon-TextFieldError {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -451,7 +458,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-TextField--input {
|
||||
.canon-TextFieldInput {
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
padding: 0 var(--canon-space-4);
|
||||
@@ -464,39 +471,39 @@
|
||||
transition: border-color .2s ease-in-out, outline-color .2s ease-in-out;
|
||||
}
|
||||
|
||||
.canon-TextField--input::placeholder {
|
||||
.canon-TextFieldInput::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-TextField--input:hover {
|
||||
.canon-TextFieldInput:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-TextField--input:focus-visible {
|
||||
.canon-TextFieldInput:focus-visible {
|
||||
outline-color: var(--canon-border-pressed);
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
.canon-TextField--input[data-invalid] {
|
||||
.canon-TextFieldInput[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-TextField--input[data-disabled] {
|
||||
.canon-TextFieldInput[data-disabled] {
|
||||
opacity: .5;
|
||||
cursor: not-allowed;
|
||||
border: 1px solid var(--canon-border-disabled);
|
||||
}
|
||||
|
||||
.canon-TextField--input-size-small {
|
||||
.canon-TextFieldInput[data-size="small"] {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-TextField--input-size-medium {
|
||||
.canon-TextFieldInput[data-size="medium"] {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.canon-TextField--required {
|
||||
.canon-TextFieldRequired {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
@@ -573,31 +580,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Link--variant-body {
|
||||
.canon-Link[data-variant="body"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-subtitle {
|
||||
.canon-Link[data-variant="subtitle"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-caption {
|
||||
.canon-Link[data-variant="caption"] {
|
||||
font-size: var(--canon-font-size-2);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-label {
|
||||
.canon-Link[data-variant="label"] {
|
||||
font-size: var(--canon-font-size-1);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--weight-regular {
|
||||
.canon-Link[data-weight="regular"] {
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
}
|
||||
|
||||
.canon-Link--weight-bold {
|
||||
.canon-Link[data-weight="bold"] {
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
@@ -721,14 +728,14 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--label {
|
||||
.canon-SelectLabel {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-Select--description {
|
||||
.canon-SelectDescription {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -736,7 +743,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-Select--error {
|
||||
.canon-SelectError {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -744,7 +751,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-Select--trigger {
|
||||
.canon-SelectTrigger {
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
@@ -763,38 +770,38 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--trigger::placeholder {
|
||||
.canon-SelectTrigger::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-Select--trigger:hover {
|
||||
.canon-SelectTrigger:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-Select--trigger:focus-visible {
|
||||
.canon-SelectTrigger:focus-visible {
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-invalid] {
|
||||
.canon-SelectTrigger[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-invalid]:hover, .canon-Select--trigger[data-invalid]:focus-visible {
|
||||
.canon-SelectTrigger[data-invalid]:hover, .canon-SelectTrigger[data-invalid]:focus-visible {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-disabled] {
|
||||
.canon-SelectTrigger[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--canon-border-disabled);
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-Select--trigger-size-small {
|
||||
.canon-SelectTrigger[data-size="small"] {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-Select--trigger-size-medium {
|
||||
.canon-SelectTrigger[data-size="medium"] {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
@@ -803,11 +810,11 @@
|
||||
transition: transform .2s;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-popup-open] .canon-SelectIcon {
|
||||
.canon-SelectTrigger[data-popup-open] .canon-SelectIcon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.canon-Select--popup {
|
||||
.canon-SelectPopup {
|
||||
box-sizing: border-box;
|
||||
max-height: var(--available-height);
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
@@ -822,12 +829,12 @@
|
||||
box-shadow: 0 4px 12px #0003;
|
||||
}
|
||||
|
||||
.canon-Select--popup[data-starting-style], .canon-Select--popup[data-ending-style] {
|
||||
.canon-SelectPopup[data-starting-style], .canon-SelectPopup[data-ending-style] {
|
||||
opacity: 0;
|
||||
transform: scale(.9);
|
||||
}
|
||||
|
||||
.canon-Select--item {
|
||||
.canon-SelectItem {
|
||||
width: var(--anchor-width);
|
||||
padding-block: var(--canon-space-2);
|
||||
padding-inline: var(--canon-space-4);
|
||||
@@ -845,13 +852,13 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-highlighted] {
|
||||
.canon-SelectItem[data-highlighted] {
|
||||
z-index: 0;
|
||||
color: var(--canon-fg-primary);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-highlighted]:before {
|
||||
.canon-SelectItem[data-highlighted]:before {
|
||||
content: "";
|
||||
z-index: -1;
|
||||
background-color: var(--canon-bg-tint-hover);
|
||||
@@ -861,37 +868,37 @@
|
||||
inset-inline: .25rem;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-disabled] {
|
||||
.canon-SelectItem[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-Select--item-indicator {
|
||||
.canon-SelectItemIndicator {
|
||||
grid-area: icon;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--item-text {
|
||||
.canon-SelectItemText {
|
||||
flex: 1;
|
||||
grid-area: text;
|
||||
}
|
||||
|
||||
.canon-Select--required {
|
||||
.canon-SelectRequired {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
margin-left: var(--canon-space-1);
|
||||
}
|
||||
|
||||
.canon-Select--icon {
|
||||
.canon-SelectIcon {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--value {
|
||||
.canon-SelectValue {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
.canon-DataTablePagination {
|
||||
padding-top: var(--canon-space-5);
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--left {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--right {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--canon-space-2);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--select {
|
||||
min-width: 10.5rem;
|
||||
}
|
||||
@@ -6,32 +6,32 @@
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.canon-Heading--variant-display {
|
||||
.canon-Heading[data-variant="display"] {
|
||||
font-size: var(--canon-font-size-10);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title1 {
|
||||
.canon-Heading[data-variant="title1"] {
|
||||
font-size: var(--canon-font-size-9);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title2 {
|
||||
.canon-Heading[data-variant="title2"] {
|
||||
font-size: var(--canon-font-size-8);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title3 {
|
||||
.canon-Heading[data-variant="title3"] {
|
||||
font-size: var(--canon-font-size-7);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title4 {
|
||||
.canon-Heading[data-variant="title4"] {
|
||||
font-size: var(--canon-font-size-title4);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title5 {
|
||||
.canon-Heading[data-variant="title5"] {
|
||||
font-size: var(--canon-font-size-5);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--variant-primary {
|
||||
.canon-IconButton[data-variant="primary"] {
|
||||
background-color: var(--canon-bg-solid);
|
||||
color: var(--canon-fg-solid);
|
||||
transition: background-color .15s, box-shadow .15s;
|
||||
@@ -40,7 +40,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--variant-secondary {
|
||||
.canon-IconButton[data-variant="secondary"] {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
color: var(--canon-fg-primary);
|
||||
@@ -66,24 +66,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--size-medium {
|
||||
.canon-IconButton[data-size="medium"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-small {
|
||||
.canon-IconButton[data-size="small"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-small .canon-IconButton--icon {
|
||||
.canon-IconButton[data-size="small"] .canon-IconButtonIcon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-medium .canon-IconButton--icon {
|
||||
.canon-IconButton[data-size="medium"] .canon-IconButtonIcon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
@@ -16,30 +16,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Link--variant-body {
|
||||
.canon-Link[data-variant="body"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-subtitle {
|
||||
.canon-Link[data-variant="subtitle"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-caption {
|
||||
.canon-Link[data-variant="caption"] {
|
||||
font-size: var(--canon-font-size-2);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-label {
|
||||
.canon-Link[data-variant="label"] {
|
||||
font-size: var(--canon-font-size-1);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--weight-regular {
|
||||
.canon-Link[data-weight="regular"] {
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
}
|
||||
|
||||
.canon-Link--weight-bold {
|
||||
.canon-Link[data-weight="bold"] {
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--label {
|
||||
.canon-SelectLabel {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-Select--description {
|
||||
.canon-SelectDescription {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -20,7 +20,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-Select--error {
|
||||
.canon-SelectError {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -28,7 +28,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-Select--trigger {
|
||||
.canon-SelectTrigger {
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
@@ -47,38 +47,38 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--trigger::placeholder {
|
||||
.canon-SelectTrigger::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-Select--trigger:hover {
|
||||
.canon-SelectTrigger:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-Select--trigger:focus-visible {
|
||||
.canon-SelectTrigger:focus-visible {
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-invalid] {
|
||||
.canon-SelectTrigger[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-invalid]:hover, .canon-Select--trigger[data-invalid]:focus-visible {
|
||||
.canon-SelectTrigger[data-invalid]:hover, .canon-SelectTrigger[data-invalid]:focus-visible {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-disabled] {
|
||||
.canon-SelectTrigger[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--canon-border-disabled);
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-Select--trigger-size-small {
|
||||
.canon-SelectTrigger[data-size="small"] {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-Select--trigger-size-medium {
|
||||
.canon-SelectTrigger[data-size="medium"] {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
@@ -87,11 +87,11 @@
|
||||
transition: transform .2s;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-popup-open] .canon-SelectIcon {
|
||||
.canon-SelectTrigger[data-popup-open] .canon-SelectIcon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.canon-Select--popup {
|
||||
.canon-SelectPopup {
|
||||
box-sizing: border-box;
|
||||
max-height: var(--available-height);
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
@@ -106,12 +106,12 @@
|
||||
box-shadow: 0 4px 12px #0003;
|
||||
}
|
||||
|
||||
.canon-Select--popup[data-starting-style], .canon-Select--popup[data-ending-style] {
|
||||
.canon-SelectPopup[data-starting-style], .canon-SelectPopup[data-ending-style] {
|
||||
opacity: 0;
|
||||
transform: scale(.9);
|
||||
}
|
||||
|
||||
.canon-Select--item {
|
||||
.canon-SelectItem {
|
||||
width: var(--anchor-width);
|
||||
padding-block: var(--canon-space-2);
|
||||
padding-inline: var(--canon-space-4);
|
||||
@@ -129,13 +129,13 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-highlighted] {
|
||||
.canon-SelectItem[data-highlighted] {
|
||||
z-index: 0;
|
||||
color: var(--canon-fg-primary);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-highlighted]:before {
|
||||
.canon-SelectItem[data-highlighted]:before {
|
||||
content: "";
|
||||
z-index: -1;
|
||||
background-color: var(--canon-bg-tint-hover);
|
||||
@@ -145,37 +145,37 @@
|
||||
inset-inline: .25rem;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-disabled] {
|
||||
.canon-SelectItem[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-Select--item-indicator {
|
||||
.canon-SelectItemIndicator {
|
||||
grid-area: icon;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--item-text {
|
||||
.canon-SelectItemText {
|
||||
flex: 1;
|
||||
grid-area: text;
|
||||
}
|
||||
|
||||
.canon-Select--required {
|
||||
.canon-SelectRequired {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
margin-left: var(--canon-space-1);
|
||||
}
|
||||
|
||||
.canon-Select--icon {
|
||||
.canon-SelectIcon {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--value {
|
||||
.canon-SelectValue {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
|
||||
+123
-116
@@ -9246,7 +9246,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--variant-primary {
|
||||
.canon-Button[data-variant="primary"] {
|
||||
background-color: var(--canon-bg-solid);
|
||||
color: var(--canon-fg-solid);
|
||||
transition: background-color .15s, box-shadow .15s;
|
||||
@@ -9270,7 +9270,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--variant-secondary {
|
||||
.canon-Button[data-variant="secondary"] {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
color: var(--canon-fg-primary);
|
||||
@@ -9296,28 +9296,58 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--size-medium {
|
||||
.canon-Button[data-size="medium"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
padding: 0 var(--canon-space-3);
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.canon-Button--size-small {
|
||||
.canon-Button[data-size="small"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
padding: 0 var(--canon-space-2);
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.canon-Button--size-small .canon-Button--icon {
|
||||
.canon-Button[data-size="small"] .canon-ButtonIcon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.canon-Button--size-medium .canon-Button--icon {
|
||||
.canon-Button[data-size="medium"] .canon-ButtonIcon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.canon-DataTableRoot {
|
||||
gap: var(--canon-space-3);
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination {
|
||||
padding-top: var(--canon-space-5);
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--left {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--right {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--canon-space-2);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--select {
|
||||
min-width: 10.5rem;
|
||||
}
|
||||
|
||||
.canon-Flex {
|
||||
display: flex;
|
||||
}
|
||||
@@ -9403,117 +9433,94 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.table {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
border-radius: var(--canon-radius-2);
|
||||
.canon-TableRoot {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
padding-bottom: var(--canon-space-0_5);
|
||||
padding-top: var(--canon-space-0_5);
|
||||
font-size: var(--canon-font-size-3);
|
||||
font-family: var(--canon-font-regular);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
|
||||
& table {
|
||||
caption-side: bottom;
|
||||
width: 100%;
|
||||
font-size: var(--canon-font-size-sm);
|
||||
border-collapse: collapse;
|
||||
}
|
||||
}
|
||||
|
||||
.table-head {
|
||||
.canon-TableHead {
|
||||
text-align: left;
|
||||
padding: var(--canon-space-3);
|
||||
font-size: var(--canon-font-size-3);
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.table-body {
|
||||
& tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.canon-TableBody {
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.table-row {
|
||||
.canon-TableRow {
|
||||
border-bottom: 1px solid var(--canon-border);
|
||||
transition: color .2s ease-in-out;
|
||||
|
||||
&:hover td {
|
||||
background-color: var(--canon-bg-tint);
|
||||
}
|
||||
|
||||
& .table-cell:first-child {
|
||||
border-top-left-radius: var(--canon-radius-2);
|
||||
border-bottom-left-radius: var(--canon-radius-2);
|
||||
box-shadow: inset 4px 2px 0 0 var(--canon-bg-surface-1), inset 4px -2px 0 0 var(--canon-bg-surface-1);
|
||||
padding-left: var(--canon-space-3);
|
||||
}
|
||||
|
||||
& .table-cell:last-child {
|
||||
border-top-right-radius: var(--canon-radius-2);
|
||||
border-bottom-right-radius: var(--canon-radius-2);
|
||||
box-shadow: inset -4px 2px 0 0 var(--canon-bg-surface-1), inset -4px -2px 0 0 var(--canon-bg-surface-1);
|
||||
padding-right: var(--canon-space-3);
|
||||
}
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
.canon-TableBody .canon-TableRow:hover {
|
||||
background-color: var(--canon-gray-2);
|
||||
}
|
||||
|
||||
.canon-TableCell {
|
||||
padding: var(--canon-space-3);
|
||||
background-color: var(--canon-bg);
|
||||
box-shadow: inset 0px 2px 0 0 var(--canon-bg-surface-1), inset 0px -2px 0 0 var(--canon-bg-surface-1);
|
||||
font-size: var(--canon-font-size-3);
|
||||
}
|
||||
|
||||
.canon-TableCellText, .canon-TableCellLink {
|
||||
gap: var(--canon-space-0_5);
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Text {
|
||||
font-family: var(--canon-font-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.canon-Text--variant-body {
|
||||
.canon-Text[data-variant="body"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-subtitle {
|
||||
.canon-Text[data-variant="subtitle"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-caption {
|
||||
.canon-Text[data-variant="caption"] {
|
||||
font-size: var(--canon-font-size-2);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-label {
|
||||
.canon-Text[data-variant="label"] {
|
||||
font-size: var(--canon-font-size-1);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--weight-regular {
|
||||
.canon-Text[data-weight="regular"] {
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
}
|
||||
|
||||
.canon-Text--weight-bold {
|
||||
.canon-Text[data-weight="bold"] {
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Text--color-primary {
|
||||
.canon-Text[data-color="primary"] {
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.canon-Text--color-secondary {
|
||||
.canon-Text[data-color="secondary"] {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-Text--color-danger {
|
||||
.canon-Text[data-color="danger"] {
|
||||
color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-Text--color-warning {
|
||||
.canon-Text[data-color="warning"] {
|
||||
color: var(--canon-fg-warning);
|
||||
}
|
||||
|
||||
.canon-Text--color-success {
|
||||
.canon-Text[data-color="success"] {
|
||||
color: var(--canon-fg-success);
|
||||
}
|
||||
|
||||
@@ -9525,32 +9532,32 @@
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.canon-Heading--variant-display {
|
||||
.canon-Heading[data-variant="display"] {
|
||||
font-size: var(--canon-font-size-10);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title1 {
|
||||
.canon-Heading[data-variant="title1"] {
|
||||
font-size: var(--canon-font-size-9);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title2 {
|
||||
.canon-Heading[data-variant="title2"] {
|
||||
font-size: var(--canon-font-size-8);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title3 {
|
||||
.canon-Heading[data-variant="title3"] {
|
||||
font-size: var(--canon-font-size-7);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title4 {
|
||||
.canon-Heading[data-variant="title4"] {
|
||||
font-size: var(--canon-font-size-title4);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title5 {
|
||||
.canon-Heading[data-variant="title5"] {
|
||||
font-size: var(--canon-font-size-5);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
@@ -9573,7 +9580,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--variant-primary {
|
||||
.canon-IconButton[data-variant="primary"] {
|
||||
background-color: var(--canon-bg-solid);
|
||||
color: var(--canon-fg-solid);
|
||||
transition: background-color .15s, box-shadow .15s;
|
||||
@@ -9597,7 +9604,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--variant-secondary {
|
||||
.canon-IconButton[data-variant="secondary"] {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
color: var(--canon-fg-primary);
|
||||
@@ -9623,24 +9630,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--size-medium {
|
||||
.canon-IconButton[data-size="medium"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-small {
|
||||
.canon-IconButton[data-size="small"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-small .canon-IconButton--icon {
|
||||
.canon-IconButton[data-size="small"] .canon-IconButtonIcon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-medium .canon-IconButton--icon {
|
||||
.canon-IconButton[data-size="medium"] .canon-IconButtonIcon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
@@ -9652,14 +9659,14 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-TextField--label {
|
||||
.canon-TextFieldLabel {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-TextField--description {
|
||||
.canon-TextFieldDescription {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -9667,7 +9674,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-TextField--error {
|
||||
.canon-TextFieldError {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -9675,7 +9682,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-TextField--input {
|
||||
.canon-TextFieldInput {
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
padding: 0 var(--canon-space-4);
|
||||
@@ -9688,39 +9695,39 @@
|
||||
transition: border-color .2s ease-in-out, outline-color .2s ease-in-out;
|
||||
}
|
||||
|
||||
.canon-TextField--input::placeholder {
|
||||
.canon-TextFieldInput::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-TextField--input:hover {
|
||||
.canon-TextFieldInput:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-TextField--input:focus-visible {
|
||||
.canon-TextFieldInput:focus-visible {
|
||||
outline-color: var(--canon-border-pressed);
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
.canon-TextField--input[data-invalid] {
|
||||
.canon-TextFieldInput[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-TextField--input[data-disabled] {
|
||||
.canon-TextFieldInput[data-disabled] {
|
||||
opacity: .5;
|
||||
cursor: not-allowed;
|
||||
border: 1px solid var(--canon-border-disabled);
|
||||
}
|
||||
|
||||
.canon-TextField--input-size-small {
|
||||
.canon-TextFieldInput[data-size="small"] {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-TextField--input-size-medium {
|
||||
.canon-TextFieldInput[data-size="medium"] {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.canon-TextField--required {
|
||||
.canon-TextFieldRequired {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
@@ -9797,31 +9804,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Link--variant-body {
|
||||
.canon-Link[data-variant="body"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-subtitle {
|
||||
.canon-Link[data-variant="subtitle"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-caption {
|
||||
.canon-Link[data-variant="caption"] {
|
||||
font-size: var(--canon-font-size-2);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-label {
|
||||
.canon-Link[data-variant="label"] {
|
||||
font-size: var(--canon-font-size-1);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--weight-regular {
|
||||
.canon-Link[data-weight="regular"] {
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
}
|
||||
|
||||
.canon-Link--weight-bold {
|
||||
.canon-Link[data-weight="bold"] {
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
@@ -9945,14 +9952,14 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--label {
|
||||
.canon-SelectLabel {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-Select--description {
|
||||
.canon-SelectDescription {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -9960,7 +9967,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-Select--error {
|
||||
.canon-SelectError {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -9968,7 +9975,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-Select--trigger {
|
||||
.canon-SelectTrigger {
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
@@ -9987,38 +9994,38 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--trigger::placeholder {
|
||||
.canon-SelectTrigger::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-Select--trigger:hover {
|
||||
.canon-SelectTrigger:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-Select--trigger:focus-visible {
|
||||
.canon-SelectTrigger:focus-visible {
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-invalid] {
|
||||
.canon-SelectTrigger[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-invalid]:hover, .canon-Select--trigger[data-invalid]:focus-visible {
|
||||
.canon-SelectTrigger[data-invalid]:hover, .canon-SelectTrigger[data-invalid]:focus-visible {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-disabled] {
|
||||
.canon-SelectTrigger[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--canon-border-disabled);
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-Select--trigger-size-small {
|
||||
.canon-SelectTrigger[data-size="small"] {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-Select--trigger-size-medium {
|
||||
.canon-SelectTrigger[data-size="medium"] {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
@@ -10027,11 +10034,11 @@
|
||||
transition: transform .2s;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-popup-open] .canon-SelectIcon {
|
||||
.canon-SelectTrigger[data-popup-open] .canon-SelectIcon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.canon-Select--popup {
|
||||
.canon-SelectPopup {
|
||||
box-sizing: border-box;
|
||||
max-height: var(--available-height);
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
@@ -10046,12 +10053,12 @@
|
||||
box-shadow: 0 4px 12px #0003;
|
||||
}
|
||||
|
||||
.canon-Select--popup[data-starting-style], .canon-Select--popup[data-ending-style] {
|
||||
.canon-SelectPopup[data-starting-style], .canon-SelectPopup[data-ending-style] {
|
||||
opacity: 0;
|
||||
transform: scale(.9);
|
||||
}
|
||||
|
||||
.canon-Select--item {
|
||||
.canon-SelectItem {
|
||||
width: var(--anchor-width);
|
||||
padding-block: var(--canon-space-2);
|
||||
padding-inline: var(--canon-space-4);
|
||||
@@ -10069,13 +10076,13 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-highlighted] {
|
||||
.canon-SelectItem[data-highlighted] {
|
||||
z-index: 0;
|
||||
color: var(--canon-fg-primary);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-highlighted]:before {
|
||||
.canon-SelectItem[data-highlighted]:before {
|
||||
content: "";
|
||||
z-index: -1;
|
||||
background-color: var(--canon-bg-tint-hover);
|
||||
@@ -10085,37 +10092,37 @@
|
||||
inset-inline: .25rem;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-disabled] {
|
||||
.canon-SelectItem[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-Select--item-indicator {
|
||||
.canon-SelectItemIndicator {
|
||||
grid-area: icon;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--item-text {
|
||||
.canon-SelectItemText {
|
||||
flex: 1;
|
||||
grid-area: text;
|
||||
}
|
||||
|
||||
.canon-Select--required {
|
||||
.canon-SelectRequired {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
margin-left: var(--canon-space-1);
|
||||
}
|
||||
|
||||
.canon-Select--icon {
|
||||
.canon-SelectIcon {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Select--value {
|
||||
.canon-SelectValue {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
|
||||
@@ -1,58 +1,4 @@
|
||||
.table {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
border-radius: var(--canon-radius-2);
|
||||
width: 100%;
|
||||
padding-bottom: var(--canon-space-0_5);
|
||||
padding-top: var(--canon-space-0_5);
|
||||
.canon-TableCell {
|
||||
padding: var(--canon-space-3);
|
||||
font-size: var(--canon-font-size-3);
|
||||
font-family: var(--canon-font-regular);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
|
||||
& table {
|
||||
caption-side: bottom;
|
||||
width: 100%;
|
||||
font-size: var(--canon-font-size-sm);
|
||||
border-collapse: collapse;
|
||||
}
|
||||
}
|
||||
|
||||
.table-head {
|
||||
text-align: left;
|
||||
padding: var(--canon-space-3);
|
||||
}
|
||||
|
||||
.table-body {
|
||||
& tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.table-row {
|
||||
transition: color .2s ease-in-out;
|
||||
|
||||
&:hover td {
|
||||
background-color: var(--canon-bg-tint);
|
||||
}
|
||||
|
||||
& .table-cell:first-child {
|
||||
border-top-left-radius: var(--canon-radius-2);
|
||||
border-bottom-left-radius: var(--canon-radius-2);
|
||||
box-shadow: inset 4px 2px 0 0 var(--canon-bg-surface-1), inset 4px -2px 0 0 var(--canon-bg-surface-1);
|
||||
padding-left: var(--canon-space-3);
|
||||
}
|
||||
|
||||
& .table-cell:last-child {
|
||||
border-top-right-radius: var(--canon-radius-2);
|
||||
border-bottom-right-radius: var(--canon-radius-2);
|
||||
box-shadow: inset -4px 2px 0 0 var(--canon-bg-surface-1), inset -4px -2px 0 0 var(--canon-bg-surface-1);
|
||||
padding-right: var(--canon-space-3);
|
||||
}
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
padding: var(--canon-space-3);
|
||||
background-color: var(--canon-bg);
|
||||
box-shadow: inset 0px 2px 0 0 var(--canon-bg-surface-1), inset 0px -2px 0 0 var(--canon-bg-surface-1);
|
||||
}
|
||||
|
||||
+11
-12
@@ -1,54 +1,53 @@
|
||||
.canon-Text {
|
||||
font-family: var(--canon-font-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.canon-Text--variant-body {
|
||||
.canon-Text[data-variant="body"] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-subtitle {
|
||||
.canon-Text[data-variant="subtitle"] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-caption {
|
||||
.canon-Text[data-variant="caption"] {
|
||||
font-size: var(--canon-font-size-2);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-label {
|
||||
.canon-Text[data-variant="label"] {
|
||||
font-size: var(--canon-font-size-1);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--weight-regular {
|
||||
.canon-Text[data-weight="regular"] {
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
}
|
||||
|
||||
.canon-Text--weight-bold {
|
||||
.canon-Text[data-weight="bold"] {
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Text--color-primary {
|
||||
.canon-Text[data-color="primary"] {
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.canon-Text--color-secondary {
|
||||
.canon-Text[data-color="secondary"] {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-Text--color-danger {
|
||||
.canon-Text[data-color="danger"] {
|
||||
color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-Text--color-warning {
|
||||
.canon-Text[data-color="warning"] {
|
||||
color: var(--canon-fg-warning);
|
||||
}
|
||||
|
||||
.canon-Text--color-success {
|
||||
.canon-Text[data-color="success"] {
|
||||
color: var(--canon-fg-success);
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-TextField--label {
|
||||
.canon-TextFieldLabel {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-TextField--description {
|
||||
.canon-TextFieldDescription {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -20,7 +20,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-TextField--error {
|
||||
.canon-TextFieldError {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -28,7 +28,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-TextField--input {
|
||||
.canon-TextFieldInput {
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
padding: 0 var(--canon-space-4);
|
||||
@@ -41,39 +41,39 @@
|
||||
transition: border-color .2s ease-in-out, outline-color .2s ease-in-out;
|
||||
}
|
||||
|
||||
.canon-TextField--input::placeholder {
|
||||
.canon-TextFieldInput::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-TextField--input:hover {
|
||||
.canon-TextFieldInput:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-TextField--input:focus-visible {
|
||||
.canon-TextFieldInput:focus-visible {
|
||||
outline-color: var(--canon-border-pressed);
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
.canon-TextField--input[data-invalid] {
|
||||
.canon-TextFieldInput[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-TextField--input[data-disabled] {
|
||||
.canon-TextFieldInput[data-disabled] {
|
||||
opacity: .5;
|
||||
cursor: not-allowed;
|
||||
border: 1px solid var(--canon-border-disabled);
|
||||
}
|
||||
|
||||
.canon-TextField--input-size-small {
|
||||
.canon-TextFieldInput[data-size="small"] {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-TextField--input-size-medium {
|
||||
.canon-TextFieldInput[data-size="medium"] {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.canon-TextField--required {
|
||||
.canon-TextFieldRequired {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"@storybook/react": "^8.6.8",
|
||||
"@storybook/react-webpack5": "^8.6.8",
|
||||
"@storybook/test": "^8.6.8",
|
||||
"@tanstack/react-table": "^8.21.2",
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"chalk": "^5.4.1",
|
||||
|
||||
+118
-33
@@ -17,6 +17,7 @@ import { ReactNode } from 'react';
|
||||
import { RefAttributes } from 'react';
|
||||
import type { RemixiconComponentType } from '@remixicon/react';
|
||||
import { ScrollArea as ScrollArea_2 } from '@base-ui-components/react/scroll-area';
|
||||
import { Table as Table_2 } from '@tanstack/react-table';
|
||||
import { TdHTMLAttributes } from 'react';
|
||||
import { ThHTMLAttributes } from 'react';
|
||||
import { Tooltip as Tooltip_2 } from '@base-ui-components/react/tooltip';
|
||||
@@ -219,6 +220,65 @@ export interface ContainerProps {
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
// @public
|
||||
export const DataTable: {
|
||||
Root: <TData>(
|
||||
props: {
|
||||
table: Table_2<TData>;
|
||||
} & React.HTMLAttributes<HTMLDivElement>,
|
||||
) => JSX.Element;
|
||||
Pagination: ForwardRefExoticComponent<
|
||||
DataTablePaginationProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
Table: ForwardRefExoticComponent<
|
||||
DataTableTableProps & RefAttributes<HTMLTableElement>
|
||||
>;
|
||||
TableRoot: ForwardRefExoticComponent<
|
||||
Omit<
|
||||
HTMLAttributes<HTMLTableElement> & RefAttributes<HTMLTableElement>,
|
||||
'ref'
|
||||
> &
|
||||
RefAttributes<HTMLTableElement>
|
||||
>;
|
||||
TableHeader: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableSectionElement> &
|
||||
RefAttributes<HTMLTableSectionElement>
|
||||
>;
|
||||
TableBody: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableSectionElement> &
|
||||
RefAttributes<HTMLTableSectionElement>
|
||||
>;
|
||||
TableRow: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableRowElement> & RefAttributes<HTMLTableRowElement>
|
||||
>;
|
||||
TableCell: ForwardRefExoticComponent<
|
||||
TdHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
|
||||
>;
|
||||
TableCellText: ForwardRefExoticComponent<
|
||||
TableCellTextProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
TableCellLink: ForwardRefExoticComponent<
|
||||
TableCellLinkProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
TableHead: ForwardRefExoticComponent<
|
||||
ThHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
|
||||
>;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export interface DataTablePaginationProps
|
||||
extends React.HTMLAttributes<HTMLDivElement> {}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface DataTableRootProps<TData>
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
table: Table_2<TData>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface DataTableTableProps
|
||||
extends React.HTMLAttributes<HTMLTableElement> {}
|
||||
|
||||
// @public (undocumented)
|
||||
export type Display = 'none' | 'flex' | 'block' | 'inline';
|
||||
|
||||
@@ -1028,43 +1088,61 @@ export type StylingPropDef = {
|
||||
parseValue?: (value: string) => string | undefined;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const Table: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableElement> & RefAttributes<HTMLTableElement>
|
||||
>;
|
||||
// @public
|
||||
export const Table: {
|
||||
Root: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableElement> & RefAttributes<HTMLTableElement>
|
||||
>;
|
||||
Header: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableSectionElement> &
|
||||
RefAttributes<HTMLTableSectionElement>
|
||||
>;
|
||||
Body: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableSectionElement> &
|
||||
RefAttributes<HTMLTableSectionElement>
|
||||
>;
|
||||
Head: ForwardRefExoticComponent<
|
||||
ThHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
|
||||
>;
|
||||
Row: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableRowElement> & RefAttributes<HTMLTableRowElement>
|
||||
>;
|
||||
Cell: ForwardRefExoticComponent<
|
||||
TdHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
|
||||
>;
|
||||
CellText: ForwardRefExoticComponent<
|
||||
TableCellTextProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
CellLink: ForwardRefExoticComponent<
|
||||
TableCellLinkProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
Caption: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableCaptionElement> &
|
||||
RefAttributes<HTMLTableCaptionElement>
|
||||
>;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const TableBody: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableSectionElement> &
|
||||
RefAttributes<HTMLTableSectionElement>
|
||||
>;
|
||||
export interface TableCellLinkProps
|
||||
extends React.TdHTMLAttributes<HTMLTableCellElement> {
|
||||
// (undocumented)
|
||||
description?: string;
|
||||
// (undocumented)
|
||||
href: string;
|
||||
// (undocumented)
|
||||
render?: useRender.ComponentProps<'a'>['render'];
|
||||
// (undocumented)
|
||||
title: string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const TableCell: ForwardRefExoticComponent<
|
||||
TdHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const TableFooter: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableSectionElement> &
|
||||
RefAttributes<HTMLTableSectionElement>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const TableHead: ForwardRefExoticComponent<
|
||||
ThHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const TableHeader: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableSectionElement> &
|
||||
RefAttributes<HTMLTableSectionElement>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const TableRow: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableRowElement> & RefAttributes<HTMLTableRowElement>
|
||||
>;
|
||||
export interface TableCellTextProps
|
||||
extends React.TdHTMLAttributes<HTMLTableCellElement> {
|
||||
// (undocumented)
|
||||
description?: string;
|
||||
// (undocumented)
|
||||
title: string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
const Text_2: ForwardRefExoticComponent<
|
||||
@@ -1143,6 +1221,13 @@ export const Tooltip: {
|
||||
>;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const useBreakpoint: () => {
|
||||
breakpoint: Breakpoint;
|
||||
up: (key: Breakpoint) => boolean;
|
||||
down: (key: Breakpoint) => boolean;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const useIcons: () => IconContextProps;
|
||||
|
||||
|
||||
@@ -44,18 +44,15 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
<button
|
||||
ref={ref}
|
||||
disabled={disabled}
|
||||
className={clsx(
|
||||
'canon-Button',
|
||||
`canon-Button--size-${responsiveSize}`,
|
||||
`canon-Button--variant-${responsiveVariant}`,
|
||||
className,
|
||||
)}
|
||||
className={clsx('canon-Button', className)}
|
||||
data-size={responsiveSize}
|
||||
data-variant={responsiveVariant}
|
||||
style={style}
|
||||
{...rest}
|
||||
>
|
||||
{iconStart && <Icon name={iconStart} className="canon-Button--icon" />}
|
||||
{iconStart && <Icon name={iconStart} className="canon-ButtonIcon" />}
|
||||
{children}
|
||||
{iconEnd && <Icon name={iconEnd} className="canon-Button--icon" />}
|
||||
{iconEnd && <Icon name={iconEnd} className="canon-ButtonIcon" />}
|
||||
</button>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--variant-primary {
|
||||
.canon-Button[data-variant='primary'] {
|
||||
background-color: var(--canon-bg-solid);
|
||||
color: var(--canon-fg-solid);
|
||||
transition: background-color 150ms ease, box-shadow 150ms ease;
|
||||
@@ -56,7 +56,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--variant-secondary {
|
||||
.canon-Button[data-variant='secondary'] {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
color: var(--canon-fg-primary);
|
||||
@@ -82,24 +82,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Button--size-medium {
|
||||
.canon-Button[data-size='medium'] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
padding: 0 var(--canon-space-3);
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.canon-Button--size-small {
|
||||
.canon-Button[data-size='small'] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
padding: 0 var(--canon-space-2);
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.canon-Button--size-small .canon-Button--icon {
|
||||
.canon-Button[data-size='small'] .canon-ButtonIcon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.canon-Button--size-medium .canon-Button--icon {
|
||||
.canon-Button[data-size='medium'] .canon-ButtonIcon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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';
|
||||
import { DataTable } from '.';
|
||||
import { data, DataProps } from './mocked-components';
|
||||
import { columns } from './mocked-columns';
|
||||
import {
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getPaginationRowModel,
|
||||
useReactTable,
|
||||
PaginationState,
|
||||
} from '@tanstack/react-table';
|
||||
import { useState } from 'react';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/DataTable',
|
||||
} satisfies Meta;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Uncontrolled: Story = {
|
||||
render: () => {
|
||||
const table = useReactTable<DataProps>({
|
||||
data,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
});
|
||||
|
||||
return (
|
||||
<DataTable.Root table={table}>
|
||||
<DataTable.Table />
|
||||
<DataTable.Pagination />
|
||||
</DataTable.Root>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const Controlled: Story = {
|
||||
render: () => {
|
||||
const [pagination, setPagination] = useState<PaginationState>({
|
||||
pageIndex: 4,
|
||||
pageSize: 5,
|
||||
});
|
||||
|
||||
const table = useReactTable<DataProps>({
|
||||
data,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
state: {
|
||||
pagination,
|
||||
},
|
||||
onPaginationChange: setPagination,
|
||||
});
|
||||
|
||||
return (
|
||||
<DataTable.Root table={table}>
|
||||
<DataTable.Table />
|
||||
<DataTable.Pagination />
|
||||
</DataTable.Root>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const WithCustomTable: Story = {
|
||||
render: () => {
|
||||
const table = useReactTable<DataProps>({
|
||||
data,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
});
|
||||
|
||||
return (
|
||||
<DataTable.Root table={table}>
|
||||
<DataTable.TableRoot>
|
||||
<DataTable.TableHeader>
|
||||
{table.getHeaderGroups().map(headerGroup => (
|
||||
<DataTable.TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map(header => {
|
||||
return (
|
||||
<DataTable.TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
</DataTable.TableHead>
|
||||
);
|
||||
})}
|
||||
</DataTable.TableRow>
|
||||
))}
|
||||
</DataTable.TableHeader>
|
||||
<DataTable.TableBody>
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map(row => (
|
||||
<DataTable.TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && 'selected'}
|
||||
>
|
||||
{row.getVisibleCells().map(cell => (
|
||||
<DataTable.TableCell key={cell.id}>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext(),
|
||||
)}
|
||||
</DataTable.TableCell>
|
||||
))}
|
||||
</DataTable.TableRow>
|
||||
))
|
||||
) : (
|
||||
<DataTable.TableRow>
|
||||
<DataTable.TableCell
|
||||
colSpan={columns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
No results.
|
||||
</DataTable.TableCell>
|
||||
</DataTable.TableRow>
|
||||
)}
|
||||
</DataTable.TableBody>
|
||||
</DataTable.TableRoot>
|
||||
<DataTable.Pagination />
|
||||
</DataTable.Root>
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 { Table } from '../Table';
|
||||
import { DataTableRoot } from './Root/DataTableRoot';
|
||||
import { DataTablePagination } from './Pagination/DataTablePagination';
|
||||
import { Table as TanstackTable } from '@tanstack/react-table';
|
||||
import { DataTableTable } from './Table/DataTableTable';
|
||||
|
||||
const TableRoot = forwardRef<
|
||||
React.ElementRef<typeof Table.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof Table.Root>
|
||||
>(({ className, ...props }, ref) => <Table.Root ref={ref} {...props} />);
|
||||
TableRoot.displayName = Table.Root.displayName;
|
||||
|
||||
/**
|
||||
* DataTable component for displaying tabular data with pagination
|
||||
* @public
|
||||
*/
|
||||
export const DataTable = {
|
||||
Root: DataTableRoot as <TData>(
|
||||
props: {
|
||||
table: TanstackTable<TData>;
|
||||
} & React.HTMLAttributes<HTMLDivElement>,
|
||||
) => JSX.Element,
|
||||
Pagination: DataTablePagination,
|
||||
Table: DataTableTable,
|
||||
TableRoot: TableRoot,
|
||||
TableHeader: Table.Header,
|
||||
TableBody: Table.Body,
|
||||
TableRow: Table.Row,
|
||||
TableCell: Table.Cell,
|
||||
TableCellText: Table.CellText,
|
||||
TableCellLink: Table.CellLink,
|
||||
TableHead: Table.Head,
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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';
|
||||
import { DataTablePagination } from './DataTablePagination';
|
||||
import {
|
||||
getCoreRowModel,
|
||||
getFilteredRowModel,
|
||||
getPaginationRowModel,
|
||||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from '@tanstack/react-table';
|
||||
import { data, DataProps } from '../mocked-components';
|
||||
import { columns } from '../mocked-columns';
|
||||
import { DataTable } from '../DataTable';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/DataTable/Pagination',
|
||||
component: DataTablePagination,
|
||||
} satisfies Meta<typeof DataTablePagination>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {
|
||||
render: () => {
|
||||
const table = useReactTable<DataProps>({
|
||||
data,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
getFilteredRowModel: getFilteredRowModel(),
|
||||
});
|
||||
|
||||
return (
|
||||
<DataTable.Root table={table}>
|
||||
<DataTable.Pagination />
|
||||
</DataTable.Root>
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
.canon-DataTablePagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-top: var(--canon-space-5);
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--canon-space-2);
|
||||
}
|
||||
|
||||
.canon-DataTablePagination--select {
|
||||
min-width: 10.5rem;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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 { Text } from '../../Text';
|
||||
import { DataTablePaginationProps } from './types';
|
||||
import { IconButton } from '../../IconButton';
|
||||
import clsx from 'clsx';
|
||||
import { Select } from '../../Select';
|
||||
import { useDataTable } from '../Root/DataTableRoot';
|
||||
|
||||
/** @public */
|
||||
const DataTablePagination = forwardRef(
|
||||
(
|
||||
props: DataTablePaginationProps,
|
||||
ref: React.ForwardedRef<HTMLDivElement>,
|
||||
) => {
|
||||
const { className, ...rest } = props;
|
||||
const { table } = useDataTable();
|
||||
const pageIndex = table?.getState().pagination.pageIndex;
|
||||
const pageSize = table?.getState().pagination.pageSize;
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx('canon-DataTablePagination', className)}
|
||||
{...rest}
|
||||
>
|
||||
<div className="canon-DataTablePagination--left">
|
||||
{!table.options.manualPagination && (
|
||||
<Select
|
||||
name="pageSize"
|
||||
size="small"
|
||||
placeholder="Show 10 results"
|
||||
options={[
|
||||
{ label: 'Show 5 results', value: '5' },
|
||||
{ label: 'Show 10 results', value: '10' },
|
||||
{ label: 'Show 20 results', value: '20' },
|
||||
{ label: 'Show 30 results', value: '30' },
|
||||
{ label: 'Show 40 results', value: '40' },
|
||||
{ label: 'Show 50 results', value: '50' },
|
||||
]}
|
||||
value={pageSize?.toString()}
|
||||
onValueChange={value => {
|
||||
table?.setPageSize(Number(value));
|
||||
}}
|
||||
className="canon-DataTablePagination--select"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="canon-DataTablePagination--right">
|
||||
<Text variant="body">{`${(pageIndex ?? 0) * (pageSize ?? 10) + 1} - ${
|
||||
((pageIndex ?? 0) + 1) * (pageSize ?? 10)
|
||||
} of ${table?.getRowCount()}`}</Text>
|
||||
<IconButton
|
||||
variant="secondary"
|
||||
size="small"
|
||||
onClick={() => table?.previousPage()}
|
||||
disabled={!table?.getCanPreviousPage()}
|
||||
icon="chevron-left"
|
||||
/>
|
||||
<IconButton
|
||||
variant="secondary"
|
||||
size="small"
|
||||
onClick={() => table?.nextPage()}
|
||||
disabled={!table?.getCanNextPage()}
|
||||
icon="chevron-right"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
DataTablePagination.displayName = 'DataTablePagination';
|
||||
|
||||
export { DataTablePagination };
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** @public */
|
||||
export interface DataTablePaginationProps
|
||||
extends React.HTMLAttributes<HTMLDivElement> {}
|
||||
@@ -0,0 +1,5 @@
|
||||
.canon-DataTableRoot {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--canon-space-3);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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, createContext, useContext } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { DataTableRootProps } from './types';
|
||||
import { Table } from '@tanstack/react-table';
|
||||
|
||||
type DataTableContextType<TData> = {
|
||||
table: Table<TData>;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const DataTableContext = createContext<DataTableContextType<any> | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
/** @public */
|
||||
const DataTableRoot = forwardRef(
|
||||
<TData,>(
|
||||
props: DataTableRootProps<TData>,
|
||||
ref: React.ForwardedRef<HTMLDivElement>,
|
||||
) => {
|
||||
const { className, table, ...rest } = props;
|
||||
|
||||
return (
|
||||
<DataTableContext.Provider value={{ table }}>
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx('canon-DataTable', className)}
|
||||
{...rest}
|
||||
/>
|
||||
</DataTableContext.Provider>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
DataTableRoot.displayName = 'DataTableRoot';
|
||||
|
||||
export { DataTableRoot };
|
||||
|
||||
/** @public */
|
||||
export function useDataTable<TData>() {
|
||||
const context = useContext(DataTableContext);
|
||||
if (!context) {
|
||||
throw new Error('useDataTable must be used within a DataTableRoot');
|
||||
}
|
||||
return context as DataTableContextType<TData>;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { Table } from '@tanstack/react-table';
|
||||
|
||||
/** @public */
|
||||
export interface DataTableRootProps<TData>
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* The table instance.
|
||||
*/
|
||||
table: Table<TData>;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 clsx from 'clsx';
|
||||
import { DataTableTableProps } from './types';
|
||||
import { Table } from '../../Table';
|
||||
import { useDataTable } from '../Root/DataTableRoot';
|
||||
import { flexRender } from '@tanstack/react-table';
|
||||
|
||||
/** @public */
|
||||
const DataTableTable = forwardRef(
|
||||
(props: DataTableTableProps, ref: React.ForwardedRef<HTMLTableElement>) => {
|
||||
const { className, ...rest } = props;
|
||||
const { table } = useDataTable();
|
||||
|
||||
return (
|
||||
<Table.Root ref={ref} className={clsx(className)} {...rest}>
|
||||
<Table.Header>
|
||||
{table.getHeaderGroups().map(headerGroup => (
|
||||
<Table.Row key={headerGroup.id}>
|
||||
{headerGroup.headers.map(header => {
|
||||
return (
|
||||
<Table.Head key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
</Table.Head>
|
||||
);
|
||||
})}
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map(row => (
|
||||
<Table.Row
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && 'selected'}
|
||||
>
|
||||
{row.getVisibleCells().map(cell => (
|
||||
<Table.Cell key={cell.id}>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</Table.Cell>
|
||||
))}
|
||||
</Table.Row>
|
||||
))
|
||||
) : (
|
||||
<Table.Row>
|
||||
<Table.Cell
|
||||
colSpan={table.getAllColumns().length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
No results.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)}
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
DataTableTable.displayName = 'DataTableRoot';
|
||||
|
||||
export { DataTableTable };
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** @public */
|
||||
export interface DataTableTableProps
|
||||
extends React.HTMLAttributes<HTMLTableElement> {}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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 './DataTable';
|
||||
export * from './Root/types';
|
||||
export * from './Pagination/types';
|
||||
export * from './Table/types';
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
import { DataProps } from './mocked-components';
|
||||
import { Checkbox } from '../Checkbox';
|
||||
import { DataTable } from './DataTable';
|
||||
|
||||
export const columns: ColumnDef<DataProps>[] = [
|
||||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => (
|
||||
<Checkbox
|
||||
checked={table.getIsAllPageRowsSelected()}
|
||||
onChange={(checked: boolean) =>
|
||||
table.toggleAllPageRowsSelected(checked)
|
||||
}
|
||||
aria-label="Select all"
|
||||
/>
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<td>
|
||||
<Checkbox
|
||||
checked={row.getIsSelected()}
|
||||
onChange={(checked: boolean) => row.toggleSelected(checked)}
|
||||
aria-label="Select row"
|
||||
/>
|
||||
</td>
|
||||
),
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
},
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: 'Name',
|
||||
cell: ({ row }) => (
|
||||
<DataTable.TableCellLink
|
||||
title={row.getValue('name')}
|
||||
description={row.original.description}
|
||||
href="/"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'owner',
|
||||
header: 'Owner',
|
||||
cell: ({ row }) => (
|
||||
<DataTable.TableCellText title={row.getValue('owner')} />
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'type',
|
||||
header: 'Type',
|
||||
cell: ({ row }) => <DataTable.TableCellText title={row.getValue('type')} />,
|
||||
},
|
||||
{
|
||||
accessorKey: 'tags',
|
||||
header: 'Tags',
|
||||
cell: ({ row }) => <DataTable.TableCellText title={row.getValue('tags')} />,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,818 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
export interface DataProps {
|
||||
name: string;
|
||||
owner: string;
|
||||
type: 'documentation' | 'library' | 'service' | 'website' | 'other';
|
||||
description?: string;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
export const data: DataProps[] = [
|
||||
{
|
||||
name: 'authentication-and-authorization-service',
|
||||
owner: 'security-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'A comprehensive service handling user authentication and role-based access control across all applications.',
|
||||
tags: ['security', 'authentication', 'authorization'],
|
||||
},
|
||||
{
|
||||
name: 'user-interface-dashboard-and-analytics-platform',
|
||||
owner: 'frontend-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Interactive dashboard providing real-time analytics and data visualization for business metrics.',
|
||||
tags: ['analytics', 'visualization', 'dashboard'],
|
||||
},
|
||||
{
|
||||
name: 'payment-gateway',
|
||||
owner: 'finance-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Secure payment processing system supporting multiple payment methods and currencies.',
|
||||
tags: ['payments', 'security', 'finance'],
|
||||
},
|
||||
{
|
||||
name: 'real-time-analytics-processing-and-visualization-engine',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'High-performance engine for processing and visualizing streaming data analytics.',
|
||||
tags: ['analytics', 'real-time', 'data-processing'],
|
||||
},
|
||||
{
|
||||
name: 'notification-center',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Centralized system for managing and delivering notifications across multiple channels.',
|
||||
tags: ['notifications', 'messaging'],
|
||||
},
|
||||
{
|
||||
name: 'administrative-control-panel-and-user-management-interface',
|
||||
owner: 'frontend-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Admin interface for managing users, permissions, and system configurations.',
|
||||
tags: ['admin', 'user-management', 'configuration'],
|
||||
},
|
||||
{
|
||||
name: 'search-indexer',
|
||||
owner: 'search-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service responsible for indexing and updating searchable content across the platform.',
|
||||
tags: ['search', 'indexing'],
|
||||
},
|
||||
{
|
||||
name: 'cross-platform-mobile-application-framework',
|
||||
owner: 'mobile-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Framework enabling development of cross-platform mobile applications with shared codebase.',
|
||||
tags: ['mobile', 'framework', 'cross-platform'],
|
||||
},
|
||||
{
|
||||
name: 'database-migration',
|
||||
owner: 'devops-team',
|
||||
type: 'other',
|
||||
description:
|
||||
'Tools and scripts for managing database schema migrations and data transformations.',
|
||||
tags: ['database', 'migration', 'devops'],
|
||||
},
|
||||
{
|
||||
name: 'api-gateway',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Central entry point for all API requests, handling routing, authentication, and rate limiting.',
|
||||
tags: ['api', 'gateway', 'security', 'routing'],
|
||||
},
|
||||
{
|
||||
name: 'content-management',
|
||||
owner: 'content-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'System for managing and delivering digital content across multiple channels.',
|
||||
tags: ['content', 'management', 'delivery'],
|
||||
},
|
||||
{
|
||||
name: 'enterprise-reporting-and-analytics-dashboard',
|
||||
owner: 'analytics-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Comprehensive business intelligence platform for enterprise-wide reporting and analytics.',
|
||||
tags: ['analytics', 'reporting', 'business-intelligence'],
|
||||
},
|
||||
{
|
||||
name: 'image-processing-and-optimization-service',
|
||||
owner: 'media-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for processing, optimizing, and delivering images across different devices and networks.',
|
||||
tags: ['media', 'optimization', 'processing'],
|
||||
},
|
||||
{
|
||||
name: 'customer-portal',
|
||||
owner: 'frontend-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Self-service portal for customers to manage their accounts and access services.',
|
||||
tags: ['customer', 'self-service'],
|
||||
},
|
||||
{
|
||||
name: 'log-aggregator',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Centralized logging system for collecting, processing, and analyzing application logs.',
|
||||
tags: ['logging', 'monitoring', 'devops'],
|
||||
},
|
||||
{
|
||||
name: 'identity-provider',
|
||||
owner: 'security-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service managing user identities and authentication across the organization.',
|
||||
tags: ['identity', 'security', 'authentication'],
|
||||
},
|
||||
{
|
||||
name: 'document-storage',
|
||||
owner: 'storage-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Secure and scalable document storage system with version control and access management.',
|
||||
tags: ['storage', 'documents', 'version-control'],
|
||||
},
|
||||
{
|
||||
name: 'workflow-engine',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Engine for defining and executing business processes and workflows.',
|
||||
tags: ['workflow', 'automation'],
|
||||
},
|
||||
{
|
||||
name: 'mobile-backend',
|
||||
owner: 'mobile-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Backend services supporting mobile applications with optimized APIs and data synchronization.',
|
||||
tags: ['mobile', 'backend', 'api'],
|
||||
},
|
||||
{
|
||||
name: 'system-monitoring-and-alerting-dashboard',
|
||||
owner: 'devops-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Real-time monitoring and alerting system for infrastructure and application health.',
|
||||
tags: ['monitoring', 'alerting', 'devops', 'infrastructure'],
|
||||
},
|
||||
{
|
||||
name: 'email-service',
|
||||
owner: 'communication-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Reliable email delivery service with templates and tracking capabilities.',
|
||||
tags: ['email', 'communication'],
|
||||
},
|
||||
{
|
||||
name: 'data-pipeline',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'ETL pipeline for processing and transforming large volumes of data.',
|
||||
tags: ['data', 'etl', 'pipeline'],
|
||||
},
|
||||
{
|
||||
name: 'configuration-manager',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Centralized system for managing application configurations across environments.',
|
||||
tags: ['configuration', 'management'],
|
||||
},
|
||||
{
|
||||
name: 'testing-framework',
|
||||
owner: 'qa-team',
|
||||
type: 'library',
|
||||
description:
|
||||
'Comprehensive testing framework supporting various types of automated tests.',
|
||||
tags: ['testing', 'automation', 'qa'],
|
||||
},
|
||||
{
|
||||
name: 'cache-service',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Distributed caching service for improving application performance.',
|
||||
tags: ['caching', 'performance'],
|
||||
},
|
||||
{
|
||||
name: 'billing-system',
|
||||
owner: 'finance-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'System for managing customer billing, invoicing, and payment processing.',
|
||||
tags: ['billing', 'finance', 'payments'],
|
||||
},
|
||||
{
|
||||
name: 'comprehensive-product-documentation-and-api-reference',
|
||||
owner: 'docs-team',
|
||||
type: 'documentation',
|
||||
description:
|
||||
'Complete documentation covering product features, APIs, and integration guides.',
|
||||
tags: ['documentation', 'api', 'reference'],
|
||||
},
|
||||
{
|
||||
name: 'queue-manager',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Message queue system for asynchronous processing and event handling.',
|
||||
tags: ['queue', 'messaging', 'async'],
|
||||
},
|
||||
{
|
||||
name: 'security-scanner',
|
||||
owner: 'security-team',
|
||||
type: 'other',
|
||||
description:
|
||||
'Automated security scanning tool for identifying vulnerabilities in code and infrastructure.',
|
||||
tags: ['security', 'scanning', 'vulnerability'],
|
||||
},
|
||||
{
|
||||
name: 'user-profile',
|
||||
owner: 'frontend-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'User profile management interface with personalization features.',
|
||||
tags: ['user', 'profile', 'personalization'],
|
||||
},
|
||||
{
|
||||
name: 'data-warehouse',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Centralized data repository for business intelligence and analytics.',
|
||||
tags: ['data', 'warehouse', 'analytics'],
|
||||
},
|
||||
{
|
||||
name: 'deployment-automation',
|
||||
owner: 'devops-team',
|
||||
type: 'other',
|
||||
description:
|
||||
'Automated deployment pipeline for continuous integration and delivery.',
|
||||
tags: ['deployment', 'automation', 'ci-cd', 'devops'],
|
||||
},
|
||||
{
|
||||
name: 'chat-service',
|
||||
owner: 'communication-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Real-time chat service supporting text, file sharing, and group conversations.',
|
||||
tags: ['chat', 'communication', 'real-time'],
|
||||
},
|
||||
{
|
||||
name: 'analytics-dashboard',
|
||||
owner: 'analytics-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Interactive dashboard for visualizing and analyzing business metrics.',
|
||||
tags: ['analytics', 'dashboard', 'visualization'],
|
||||
},
|
||||
{
|
||||
name: 'file-uploader',
|
||||
owner: 'storage-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for handling secure file uploads with progress tracking and validation.',
|
||||
tags: ['storage', 'upload', 'files'],
|
||||
},
|
||||
{
|
||||
name: 'search-service',
|
||||
owner: 'search-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Full-text search service with advanced filtering and ranking capabilities.',
|
||||
tags: ['search', 'full-text'],
|
||||
},
|
||||
{
|
||||
name: 'mobile-sdk',
|
||||
owner: 'mobile-team',
|
||||
type: 'library',
|
||||
description:
|
||||
'Software development kit for building mobile applications with native features.',
|
||||
tags: ['mobile', 'sdk', 'development'],
|
||||
},
|
||||
{
|
||||
name: 'performance-monitor',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'System for monitoring and analyzing application performance metrics.',
|
||||
tags: ['performance', 'monitoring', 'metrics'],
|
||||
},
|
||||
{
|
||||
name: 'content-delivery',
|
||||
owner: 'media-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'CDN service for optimized content delivery across global networks.',
|
||||
tags: ['cdn', 'content', 'delivery'],
|
||||
},
|
||||
{
|
||||
name: 'user-authentication',
|
||||
owner: 'security-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service handling user login, session management, and authentication flows.',
|
||||
tags: ['authentication', 'security', 'user'],
|
||||
},
|
||||
{
|
||||
name: 'data-export',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for exporting data in various formats with scheduling capabilities.',
|
||||
tags: ['data', 'export', 'scheduling'],
|
||||
},
|
||||
{
|
||||
name: 'admin-api',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'API endpoints for administrative functions and system management.',
|
||||
tags: ['api', 'admin', 'management'],
|
||||
},
|
||||
{
|
||||
name: 'testing-dashboard',
|
||||
owner: 'qa-team',
|
||||
type: 'website',
|
||||
description: 'Dashboard for monitoring test results and quality metrics.',
|
||||
tags: ['testing', 'dashboard', 'qa'],
|
||||
},
|
||||
{
|
||||
name: 'message-broker',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Message broker service for reliable event-driven communication between services.',
|
||||
tags: ['messaging', 'broker', 'event-driven'],
|
||||
},
|
||||
{
|
||||
name: 'payment-processor',
|
||||
owner: 'finance-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for processing financial transactions and payment methods.',
|
||||
tags: ['payments', 'finance', 'processing'],
|
||||
},
|
||||
{
|
||||
name: 'document-viewer',
|
||||
owner: 'frontend-team',
|
||||
type: 'website',
|
||||
description: 'Web-based document viewer supporting multiple file formats.',
|
||||
tags: ['documents', 'viewer'],
|
||||
},
|
||||
{
|
||||
name: 'load-balancer',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for distributing network traffic across multiple servers.',
|
||||
tags: ['load-balancing', 'networking', 'infrastructure'],
|
||||
},
|
||||
{
|
||||
name: 'security-audit',
|
||||
owner: 'security-team',
|
||||
type: 'other',
|
||||
description:
|
||||
'Tools and processes for conducting security audits and compliance checks.',
|
||||
tags: ['security', 'audit', 'compliance'],
|
||||
},
|
||||
{
|
||||
name: 'user-settings',
|
||||
owner: 'frontend-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Interface for users to manage their preferences and account settings.',
|
||||
tags: ['user', 'settings', 'preferences'],
|
||||
},
|
||||
{
|
||||
name: 'data-import',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for importing and validating data from external sources.',
|
||||
tags: ['data', 'import', 'validation'],
|
||||
},
|
||||
{
|
||||
name: 'infrastructure-monitor',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Monitoring system for infrastructure components and resources.',
|
||||
tags: ['monitoring', 'infrastructure', 'devops'],
|
||||
},
|
||||
{
|
||||
name: 'notification-manager',
|
||||
owner: 'communication-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for managing and delivering notifications across multiple channels.',
|
||||
tags: ['notifications', 'management'],
|
||||
},
|
||||
{
|
||||
name: 'analytics-processor',
|
||||
owner: 'analytics-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for processing and analyzing business data and metrics.',
|
||||
tags: ['analytics', 'processing', 'metrics'],
|
||||
},
|
||||
{
|
||||
name: 'file-manager',
|
||||
owner: 'storage-team',
|
||||
type: 'website',
|
||||
description: 'Web interface for managing files and storage resources.',
|
||||
tags: ['files', 'storage', 'management'],
|
||||
},
|
||||
{
|
||||
name: 'search-index',
|
||||
owner: 'search-team',
|
||||
type: 'service',
|
||||
description: 'Service for maintaining and updating search indices.',
|
||||
tags: ['search', 'indexing'],
|
||||
},
|
||||
{
|
||||
name: 'mobile-authentication',
|
||||
owner: 'mobile-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Authentication service specifically designed for mobile applications.',
|
||||
tags: ['mobile', 'authentication', 'security'],
|
||||
},
|
||||
{
|
||||
name: 'system-monitor',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Monitoring service for system health and performance metrics.',
|
||||
tags: ['monitoring', 'system', 'metrics'],
|
||||
},
|
||||
{
|
||||
name: 'media-processor',
|
||||
owner: 'media-team',
|
||||
type: 'service',
|
||||
description: 'Service for processing and optimizing media files.',
|
||||
tags: ['media', 'processing', 'optimization'],
|
||||
},
|
||||
{
|
||||
name: 'user-management',
|
||||
owner: 'security-team',
|
||||
type: 'service',
|
||||
description: 'Service for managing user accounts and permissions.',
|
||||
tags: ['user', 'management', 'security'],
|
||||
},
|
||||
{
|
||||
name: 'data-transformer',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for transforming data between different formats and structures.',
|
||||
tags: ['data', 'transformation'],
|
||||
},
|
||||
{
|
||||
name: 'admin-dashboard',
|
||||
owner: 'platform-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Administrative interface for system management and monitoring.',
|
||||
tags: ['admin', 'dashboard', 'management'],
|
||||
},
|
||||
{
|
||||
name: 'test-automation',
|
||||
owner: 'qa-team',
|
||||
type: 'other',
|
||||
description: 'Tools and frameworks for automating testing processes.',
|
||||
tags: ['testing', 'automation', 'qa'],
|
||||
},
|
||||
{
|
||||
name: 'event-bus',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description: 'Event-driven communication system between services.',
|
||||
tags: ['events', 'messaging', 'communication'],
|
||||
},
|
||||
{
|
||||
name: 'invoice-generator',
|
||||
owner: 'finance-team',
|
||||
type: 'service',
|
||||
description: 'Service for generating and managing invoices.',
|
||||
tags: ['invoices', 'finance'],
|
||||
},
|
||||
{
|
||||
name: 'document-editor',
|
||||
owner: 'frontend-team',
|
||||
type: 'website',
|
||||
description: 'Web-based document editing interface.',
|
||||
tags: ['documents', 'editor'],
|
||||
},
|
||||
{
|
||||
name: 'service-discovery',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description: 'Service for discovering and registering available services.',
|
||||
tags: ['discovery', 'services', 'devops'],
|
||||
},
|
||||
{
|
||||
name: 'security-monitor',
|
||||
owner: 'security-team',
|
||||
type: 'service',
|
||||
description: 'Service for monitoring security events and threats.',
|
||||
tags: ['security', 'monitoring', 'threats'],
|
||||
},
|
||||
{
|
||||
name: 'user-preferences',
|
||||
owner: 'frontend-team',
|
||||
type: 'website',
|
||||
description: 'Interface for managing user preferences and settings.',
|
||||
tags: ['user', 'preferences'],
|
||||
},
|
||||
{
|
||||
name: 'data-validator',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description: 'Service for validating data integrity and format.',
|
||||
tags: ['data', 'validation'],
|
||||
},
|
||||
{
|
||||
name: 'infrastructure-automation',
|
||||
owner: 'devops-team',
|
||||
type: 'other',
|
||||
description:
|
||||
'Tools for automating infrastructure provisioning and management.',
|
||||
tags: ['infrastructure', 'automation', 'devops'],
|
||||
},
|
||||
{
|
||||
name: 'notification-dispatcher',
|
||||
owner: 'communication-team',
|
||||
type: 'service',
|
||||
description:
|
||||
'Service for dispatching notifications to appropriate channels.',
|
||||
tags: ['notifications', 'dispatch'],
|
||||
},
|
||||
{
|
||||
name: 'analytics-collector',
|
||||
owner: 'analytics-team',
|
||||
type: 'service',
|
||||
description: 'Service for collecting and aggregating analytics data.',
|
||||
tags: ['analytics', 'collection', 'aggregation'],
|
||||
},
|
||||
{
|
||||
name: 'file-processor',
|
||||
owner: 'storage-team',
|
||||
type: 'service',
|
||||
description: 'Service for processing and managing files.',
|
||||
tags: ['files', 'processing'],
|
||||
},
|
||||
{
|
||||
name: 'search-analyzer',
|
||||
owner: 'search-team',
|
||||
type: 'service',
|
||||
description: 'Service for analyzing search queries and results.',
|
||||
tags: ['search', 'analysis'],
|
||||
},
|
||||
{
|
||||
name: 'mobile-notifications',
|
||||
owner: 'mobile-team',
|
||||
type: 'service',
|
||||
description: 'Service for sending notifications to mobile devices.',
|
||||
tags: ['mobile', 'notifications'],
|
||||
},
|
||||
{
|
||||
name: 'system-alerts',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description: 'Service for managing and dispatching system alerts.',
|
||||
tags: ['alerts', 'system', 'monitoring'],
|
||||
},
|
||||
{
|
||||
name: 'media-encoder',
|
||||
owner: 'media-team',
|
||||
type: 'service',
|
||||
description: 'Service for encoding and processing media files.',
|
||||
tags: ['media', 'encoding'],
|
||||
},
|
||||
{
|
||||
name: 'user-authorization',
|
||||
owner: 'security-team',
|
||||
type: 'service',
|
||||
description: 'Service for managing user permissions and access control.',
|
||||
tags: ['authorization', 'security', 'user'],
|
||||
},
|
||||
{
|
||||
name: 'data-aggregator',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description: 'Service for aggregating data from multiple sources.',
|
||||
tags: ['data', 'aggregation'],
|
||||
},
|
||||
{
|
||||
name: 'admin-authentication',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description: 'Authentication service for administrative access.',
|
||||
tags: ['admin', 'authentication', 'security'],
|
||||
},
|
||||
{
|
||||
name: 'test-coverage',
|
||||
owner: 'qa-team',
|
||||
type: 'other',
|
||||
description: 'Tools for measuring and reporting test coverage.',
|
||||
tags: ['testing', 'coverage', 'qa'],
|
||||
},
|
||||
{
|
||||
name: 'event-processor',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description: 'Service for processing and handling events.',
|
||||
tags: ['events', 'processing'],
|
||||
},
|
||||
{
|
||||
name: 'payment-validator',
|
||||
owner: 'finance-team',
|
||||
type: 'service',
|
||||
description: 'Service for validating payment transactions.',
|
||||
tags: ['payments', 'validation', 'finance'],
|
||||
},
|
||||
{
|
||||
name: 'document-converter',
|
||||
owner: 'frontend-team',
|
||||
type: 'service',
|
||||
description: 'Service for converting documents between different formats.',
|
||||
tags: ['documents', 'conversion'],
|
||||
},
|
||||
{
|
||||
name: 'service-health',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description: 'Service for monitoring and reporting service health status.',
|
||||
tags: ['health', 'monitoring', 'services'],
|
||||
},
|
||||
{
|
||||
name: 'security-logger',
|
||||
owner: 'security-team',
|
||||
type: 'service',
|
||||
description: 'Service for logging security-related events and activities.',
|
||||
tags: ['security', 'logging'],
|
||||
},
|
||||
{
|
||||
name: 'user-analytics',
|
||||
owner: 'frontend-team',
|
||||
type: 'website',
|
||||
description:
|
||||
'Analytics dashboard for user behavior and engagement metrics.',
|
||||
tags: ['analytics', 'user', 'metrics'],
|
||||
},
|
||||
{
|
||||
name: 'data-cleaner',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description: 'Service for cleaning and standardizing data.',
|
||||
tags: ['data', 'cleaning'],
|
||||
},
|
||||
{
|
||||
name: 'infrastructure-deployer',
|
||||
owner: 'devops-team',
|
||||
type: 'other',
|
||||
description: 'Tools for deploying and managing infrastructure resources.',
|
||||
tags: ['infrastructure', 'deployment', 'devops'],
|
||||
},
|
||||
{
|
||||
name: 'notification-queue',
|
||||
owner: 'communication-team',
|
||||
type: 'service',
|
||||
description: 'Queue system for managing notification delivery.',
|
||||
tags: ['notifications', 'queue'],
|
||||
},
|
||||
{
|
||||
name: 'analytics-exporter',
|
||||
owner: 'analytics-team',
|
||||
type: 'service',
|
||||
description: 'Service for exporting analytics data in various formats.',
|
||||
tags: ['analytics', 'export'],
|
||||
},
|
||||
{
|
||||
name: 'file-validator',
|
||||
owner: 'storage-team',
|
||||
type: 'service',
|
||||
description: 'Service for validating file integrity and format.',
|
||||
tags: ['files', 'validation'],
|
||||
},
|
||||
{
|
||||
name: 'search-optimizer',
|
||||
owner: 'search-team',
|
||||
type: 'service',
|
||||
description: 'Service for optimizing search performance and relevance.',
|
||||
tags: ['search', 'optimization'],
|
||||
},
|
||||
{
|
||||
name: 'mobile-analytics',
|
||||
owner: 'mobile-team',
|
||||
type: 'service',
|
||||
description: 'Analytics service specifically for mobile applications.',
|
||||
tags: ['mobile', 'analytics'],
|
||||
},
|
||||
{
|
||||
name: 'system-logger',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description: 'Service for logging system events and activities.',
|
||||
tags: ['logging', 'system'],
|
||||
},
|
||||
{
|
||||
name: 'media-validator',
|
||||
owner: 'media-team',
|
||||
type: 'service',
|
||||
description: 'Service for validating media files and formats.',
|
||||
tags: ['media', 'validation'],
|
||||
},
|
||||
{
|
||||
name: 'user-audit',
|
||||
owner: 'security-team',
|
||||
type: 'service',
|
||||
description: 'Service for auditing user activities and access.',
|
||||
tags: ['audit', 'user', 'security'],
|
||||
},
|
||||
{
|
||||
name: 'data-normalizer',
|
||||
owner: 'data-team',
|
||||
type: 'service',
|
||||
description: 'Service for normalizing data formats and structures.',
|
||||
tags: ['data', 'normalization'],
|
||||
},
|
||||
{
|
||||
name: 'admin-authorization',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description: 'Authorization service for administrative functions.',
|
||||
tags: ['admin', 'authorization', 'security'],
|
||||
},
|
||||
{
|
||||
name: 'test-reporting',
|
||||
owner: 'qa-team',
|
||||
type: 'other',
|
||||
description: 'Tools for generating and managing test reports.',
|
||||
tags: ['testing', 'reporting', 'qa'],
|
||||
},
|
||||
{
|
||||
name: 'event-aggregator',
|
||||
owner: 'platform-team',
|
||||
type: 'service',
|
||||
description: 'Service for aggregating and processing events.',
|
||||
tags: ['events', 'aggregation'],
|
||||
},
|
||||
{
|
||||
name: 'payment-reconciler',
|
||||
owner: 'finance-team',
|
||||
type: 'service',
|
||||
description: 'Service for reconciling payment transactions.',
|
||||
tags: ['payments', 'reconciliation', 'finance'],
|
||||
},
|
||||
{
|
||||
name: 'document-validator',
|
||||
owner: 'frontend-team',
|
||||
type: 'service',
|
||||
description: 'Service for validating document formats and content.',
|
||||
tags: ['documents', 'validation'],
|
||||
},
|
||||
{
|
||||
name: 'service-monitor',
|
||||
owner: 'devops-team',
|
||||
type: 'service',
|
||||
description: 'Service for monitoring service health and performance.',
|
||||
tags: ['monitoring', 'services', 'health'],
|
||||
},
|
||||
{
|
||||
name: 'security-validator',
|
||||
owner: 'security-team',
|
||||
type: 'service',
|
||||
description: 'Service for validating security configurations and policies.',
|
||||
tags: ['security', 'validation'],
|
||||
},
|
||||
];
|
||||
@@ -45,11 +45,8 @@ export const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(
|
||||
return (
|
||||
<Component
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
'canon-Heading',
|
||||
responsiveVariant && `canon-Heading--variant-${responsiveVariant}`,
|
||||
className,
|
||||
)}
|
||||
className={clsx('canon-Heading', className)}
|
||||
data-variant={responsiveVariant}
|
||||
{...restProps}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -22,32 +22,32 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-Heading--variant-display {
|
||||
.canon-Heading[data-variant='display'] {
|
||||
font-size: var(--canon-font-size-10);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title1 {
|
||||
.canon-Heading[data-variant='title1'] {
|
||||
font-size: var(--canon-font-size-9);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title2 {
|
||||
.canon-Heading[data-variant='title2'] {
|
||||
font-size: var(--canon-font-size-8);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title3 {
|
||||
.canon-Heading[data-variant='title3'] {
|
||||
font-size: var(--canon-font-size-7);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title4 {
|
||||
.canon-Heading[data-variant='title4'] {
|
||||
font-size: var(--canon-font-size-title4);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Heading--variant-title5 {
|
||||
.canon-Heading[data-variant='title5'] {
|
||||
font-size: var(--canon-font-size-5);
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
@@ -39,16 +39,13 @@ export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
'canon-IconButton',
|
||||
`canon-IconButton--size-${responsiveSize}`,
|
||||
`canon-IconButton--variant-${responsiveVariant}`,
|
||||
className,
|
||||
)}
|
||||
className={clsx('canon-IconButton', className)}
|
||||
data-size={responsiveSize}
|
||||
data-variant={responsiveVariant}
|
||||
style={style}
|
||||
{...rest}
|
||||
>
|
||||
<Icon name={icon} className="canon-IconButton--icon" />
|
||||
<Icon name={icon} className="canon-IconButtonIcon" />
|
||||
</button>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--variant-primary {
|
||||
.canon-IconButton[data-variant='primary'] {
|
||||
background-color: var(--canon-bg-solid);
|
||||
color: var(--canon-fg-solid);
|
||||
transition: background-color 150ms ease, box-shadow 150ms ease;
|
||||
@@ -56,7 +56,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--variant-secondary {
|
||||
.canon-IconButton[data-variant='secondary'] {
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
color: var(--canon-fg-primary);
|
||||
@@ -82,24 +82,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-IconButton--size-medium {
|
||||
.canon-IconButton[data-size='medium'] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-small {
|
||||
.canon-IconButton[data-size='small'] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-small .canon-IconButton--icon {
|
||||
.canon-IconButton[data-size='small'] .canon-IconButtonIcon {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.canon-IconButton--size-medium .canon-IconButton--icon {
|
||||
.canon-IconButton[data-size='medium'] .canon-IconButtonIcon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
@@ -38,14 +38,9 @@ export const Link = forwardRef<HTMLElement, LinkProps>((props, ref) => {
|
||||
const { renderElement } = useRender({
|
||||
render,
|
||||
props: {
|
||||
className: clsx(
|
||||
'canon-Link',
|
||||
responsiveVariant && `canon-Link--variant-${responsiveVariant}`,
|
||||
responsiveWeight && `canon-Link--weight-${responsiveWeight}`,
|
||||
className,
|
||||
),
|
||||
responsiveVariant,
|
||||
responsiveWeight,
|
||||
className: clsx('canon-Link', className),
|
||||
['data-variant']: responsiveVariant,
|
||||
['data-weight']: responsiveWeight,
|
||||
...restProps,
|
||||
},
|
||||
refs: [ref, internalRef],
|
||||
|
||||
@@ -36,30 +36,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
.canon-Link--variant-body {
|
||||
.canon-Link[data-variant='body'] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-subtitle {
|
||||
.canon-Link[data-variant='subtitle'] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-caption {
|
||||
.canon-Link[data-variant='caption'] {
|
||||
font-size: var(--canon-font-size-2);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--variant-label {
|
||||
.canon-Link[data-variant='label'] {
|
||||
font-size: var(--canon-font-size-1);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Link--weight-regular {
|
||||
.canon-Link[data-weight='regular'] {
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
}
|
||||
|
||||
.canon-Link--weight-bold {
|
||||
.canon-Link[data-weight='bold'] {
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,12 @@ export const Default: Story = {
|
||||
<>
|
||||
<Menu.Trigger
|
||||
render={props => (
|
||||
<Button {...props} size="small">
|
||||
<Button
|
||||
{...props}
|
||||
size="medium"
|
||||
variant="secondary"
|
||||
iconEnd="chevron-down"
|
||||
>
|
||||
Menu
|
||||
</Button>
|
||||
)}
|
||||
@@ -40,9 +45,10 @@ export const Default: Story = {
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner sideOffset={8} align="start">
|
||||
<Menu.Popup>
|
||||
<Menu.Item>Item 1</Menu.Item>
|
||||
<Menu.Item>Item 2</Menu.Item>
|
||||
<Menu.Item>Item 3</Menu.Item>
|
||||
<Menu.Item>Settings</Menu.Item>
|
||||
<Menu.Item>Invite new members</Menu.Item>
|
||||
<Menu.Item>Download app</Menu.Item>
|
||||
<Menu.Item>Log out</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
@@ -57,3 +63,10 @@ export const Open: Story = {
|
||||
open: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const OpenOnHover: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
openOnHover: true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.canon-Select--label {
|
||||
.canon-SelectLabel {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-Select--description {
|
||||
.canon-SelectDescription {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -36,7 +36,7 @@
|
||||
padding-top: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-Select--error {
|
||||
.canon-SelectError {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -44,7 +44,7 @@
|
||||
padding-top: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-Select--trigger {
|
||||
.canon-SelectTrigger {
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
@@ -63,41 +63,41 @@
|
||||
gap: var(--canon-space-2);
|
||||
}
|
||||
|
||||
.canon-Select--trigger::placeholder {
|
||||
.canon-SelectTrigger::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-Select--trigger:hover {
|
||||
.canon-SelectTrigger:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-Select--trigger:focus-visible {
|
||||
.canon-SelectTrigger:focus-visible {
|
||||
border-color: var(--canon-border-pressed);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-invalid] {
|
||||
.canon-SelectTrigger[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
.canon-Select--trigger[data-invalid]:hover {
|
||||
.canon-SelectTrigger[data-invalid]:hover {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-invalid]:focus-visible {
|
||||
.canon-SelectTrigger[data-invalid]:focus-visible {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-disabled] {
|
||||
.canon-SelectTrigger[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--canon-border-disabled);
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-Select--trigger-size-small {
|
||||
.canon-SelectTrigger[data-size='small'] {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-Select--trigger-size-medium {
|
||||
.canon-SelectTrigger[data-size='medium'] {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
@@ -106,11 +106,11 @@
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.canon-Select--trigger[data-popup-open] .canon-SelectIcon {
|
||||
.canon-SelectTrigger[data-popup-open] .canon-SelectIcon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.canon-Select--popup {
|
||||
.canon-SelectPopup {
|
||||
box-sizing: border-box;
|
||||
max-height: var(--available-height);
|
||||
overflow-y: auto;
|
||||
@@ -125,13 +125,13 @@
|
||||
transition: transform 150ms, opacity 150ms;
|
||||
}
|
||||
|
||||
.canon-Select--popup[data-starting-style],
|
||||
.canon-Select--popup[data-ending-style] {
|
||||
.canon-SelectPopup[data-starting-style],
|
||||
.canon-SelectPopup[data-ending-style] {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.canon-Select--item {
|
||||
.canon-SelectItem {
|
||||
position: relative;
|
||||
width: var(--anchor-width);
|
||||
display: grid;
|
||||
@@ -149,13 +149,13 @@
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.canon-Select--item[data-highlighted] {
|
||||
.canon-SelectItem[data-highlighted] {
|
||||
z-index: 0;
|
||||
position: relative;
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.canon-Select--item[data-highlighted]::before {
|
||||
.canon-SelectItem[data-highlighted]::before {
|
||||
content: '';
|
||||
z-index: -1;
|
||||
position: absolute;
|
||||
@@ -165,37 +165,37 @@
|
||||
background-color: var(--canon-bg-tint-hover);
|
||||
}
|
||||
|
||||
.canon-Select--item[data-disabled] {
|
||||
.canon-SelectItem[data-disabled] {
|
||||
cursor: not-allowed;
|
||||
color: var(--canon-fg-disabled);
|
||||
}
|
||||
|
||||
.canon-Select--item-indicator {
|
||||
.canon-SelectItemIndicator {
|
||||
grid-area: icon;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.canon-Select--item-text {
|
||||
.canon-SelectItemText {
|
||||
flex: 1;
|
||||
grid-area: text;
|
||||
}
|
||||
|
||||
.canon-Select--required {
|
||||
.canon-SelectRequired {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
margin-left: var(--canon-space-1);
|
||||
}
|
||||
|
||||
.canon-Select--icon {
|
||||
.canon-SelectIcon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.canon-Select--value {
|
||||
.canon-SelectValue {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -48,10 +48,10 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
|
||||
return (
|
||||
<div className={clsx('canon-Select', className)} style={style} ref={ref}>
|
||||
{label && (
|
||||
<label className="canon-Select--label" htmlFor={selectId}>
|
||||
<label className="canon-SelectLabel" htmlFor={selectId}>
|
||||
{label}
|
||||
{required && (
|
||||
<span aria-hidden="true" className="canon-Select--required">
|
||||
<span aria-hidden="true" className="canon-SelectRequired">
|
||||
(Required)
|
||||
</span>
|
||||
)}
|
||||
@@ -60,35 +60,33 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
|
||||
<SelectPrimitive.Root {...rest}>
|
||||
<SelectPrimitive.Trigger
|
||||
id={selectId}
|
||||
className={clsx('canon-Select--trigger', {
|
||||
'canon-Select--trigger-size-small': responsiveSize === 'small',
|
||||
'canon-Select--trigger-size-medium': responsiveSize === 'medium',
|
||||
})}
|
||||
className="canon-SelectTrigger"
|
||||
data-size={responsiveSize}
|
||||
data-invalid={error}
|
||||
>
|
||||
<SelectPrimitive.Value
|
||||
className="canon-Select--value"
|
||||
className="canon-SelectValue"
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
<SelectPrimitive.Icon className="canon-Select--icon">
|
||||
<SelectPrimitive.Icon className="canon-SelectIcon">
|
||||
<Icon name="chevron-down" />
|
||||
</SelectPrimitive.Icon>
|
||||
</SelectPrimitive.Trigger>
|
||||
<SelectPrimitive.Portal>
|
||||
<SelectPrimitive.Backdrop />
|
||||
<SelectPrimitive.Positioner>
|
||||
<SelectPrimitive.Popup className="canon-Select--popup">
|
||||
<SelectPrimitive.Popup className="canon-SelectPopup">
|
||||
{options?.map(option => (
|
||||
<SelectPrimitive.Item
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
disabled={option.disabled}
|
||||
className="canon-Select--item"
|
||||
className="canon-SelectItem"
|
||||
>
|
||||
<SelectPrimitive.ItemIndicator className="canon-Select--item-indicator">
|
||||
<SelectPrimitive.ItemIndicator className="canon-SelectItemIndicator">
|
||||
<Icon name="check" />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
<SelectPrimitive.ItemText className="canon-Select--item-text">
|
||||
<SelectPrimitive.ItemText className="canon-SelectItemText">
|
||||
{option.label}
|
||||
</SelectPrimitive.ItemText>
|
||||
</SelectPrimitive.Item>
|
||||
@@ -98,12 +96,12 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
|
||||
</SelectPrimitive.Portal>
|
||||
</SelectPrimitive.Root>
|
||||
{description && (
|
||||
<p className="canon-Select--description" id={descriptionId}>
|
||||
<p className="canon-SelectDescription" id={descriptionId}>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{error && (
|
||||
<p className="canon-Select--error" id={errorId} role="alert">
|
||||
<p className="canon-SelectError" id={errorId} role="alert">
|
||||
{error}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ComponentType } from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Table } from '../Table';
|
||||
|
||||
const invoices = [
|
||||
{
|
||||
invoice: 'INV001',
|
||||
@@ -59,28 +63,15 @@ const invoices = [
|
||||
},
|
||||
];
|
||||
|
||||
import { ComponentType } from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableFooter,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '../Table';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Table',
|
||||
component: Table,
|
||||
component: Table.Root,
|
||||
subcomponents: {
|
||||
TableBody: TableBody as ComponentType<unknown>,
|
||||
TableCell: TableCell as ComponentType<unknown>,
|
||||
TableFooter: TableFooter as ComponentType<unknown>,
|
||||
TableHead: TableHead as ComponentType<unknown>,
|
||||
TableHeader: TableHeader as ComponentType<unknown>,
|
||||
TableRow: TableRow as ComponentType<unknown>,
|
||||
Body: Table.Body as ComponentType<unknown>,
|
||||
Cell: Table.Cell as ComponentType<unknown>,
|
||||
Head: Table.Head as ComponentType<unknown>,
|
||||
Header: Table.Header as ComponentType<unknown>,
|
||||
Row: Table.Row as ComponentType<unknown>,
|
||||
},
|
||||
} satisfies Meta<typeof Table>;
|
||||
|
||||
@@ -89,31 +80,27 @@ type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {
|
||||
render: () => (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[100px]">Invoice</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Method</TableHead>
|
||||
<TableHead className="text-right">Amount</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.Head className="w-[100px]">Invoice</Table.Head>
|
||||
<Table.Head>Status</Table.Head>
|
||||
<Table.Head>Method</Table.Head>
|
||||
<Table.Head className="text-right">Amount</Table.Head>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{invoices.map(invoice => (
|
||||
<TableRow key={invoice.invoice}>
|
||||
<TableCell className="font-medium">{invoice.invoice}</TableCell>
|
||||
<TableCell>{invoice.paymentStatus}</TableCell>
|
||||
<TableCell>{invoice.paymentMethod}</TableCell>
|
||||
<TableCell className="text-right">{invoice.totalAmount}</TableCell>
|
||||
</TableRow>
|
||||
<Table.Row key={invoice.invoice}>
|
||||
<Table.Cell className="font-medium">{invoice.invoice}</Table.Cell>
|
||||
<Table.Cell>{invoice.paymentStatus}</Table.Cell>
|
||||
<Table.Cell>{invoice.paymentMethod}</Table.Cell>
|
||||
<Table.Cell className="text-right">
|
||||
{invoice.totalAmount}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</TableBody>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
<TableCell colSpan={3}>Total</TableCell>
|
||||
<TableCell className="text-right">$2,500.00</TableCell>
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
</Table>
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -13,103 +13,83 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
/** @public */
|
||||
const Table = forwardRef<
|
||||
import { forwardRef } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { TableCell } from './TableCell/TableCell';
|
||||
import { TableCellText } from './TableCellText/TableCellText';
|
||||
import { TableCellLink } from './TableCellLink/TableCellLink';
|
||||
|
||||
const TableRoot = forwardRef<
|
||||
HTMLTableElement,
|
||||
React.HTMLAttributes<HTMLTableElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div className="table">
|
||||
<table ref={ref} className={className} {...props} />
|
||||
</div>
|
||||
<table ref={ref} className={clsx('canon-TableRoot', className)} {...props} />
|
||||
));
|
||||
Table.displayName = 'Table';
|
||||
TableRoot.displayName = 'TableRoot';
|
||||
|
||||
/** @public */
|
||||
const TableHeader = forwardRef<
|
||||
HTMLTableSectionElement,
|
||||
React.HTMLAttributes<HTMLTableSectionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<thead
|
||||
ref={ref}
|
||||
className={['table-header', className].join(' ')}
|
||||
className={clsx('canon-TableHeader', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TableHeader.displayName = 'TableHeader';
|
||||
|
||||
/** @public */
|
||||
const TableBody = forwardRef<
|
||||
HTMLTableSectionElement,
|
||||
React.HTMLAttributes<HTMLTableSectionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tbody ref={ref} className={['table-body', className].join(' ')} {...props} />
|
||||
<tbody ref={ref} className={clsx('canon-TableBody', className)} {...props} />
|
||||
));
|
||||
TableBody.displayName = 'TableBody';
|
||||
|
||||
/** @public */
|
||||
const TableFooter = forwardRef<
|
||||
HTMLTableSectionElement,
|
||||
React.HTMLAttributes<HTMLTableSectionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tfoot
|
||||
ref={ref}
|
||||
className={['table-footer', className].join(' ')}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TableFooter.displayName = 'TableFooter';
|
||||
|
||||
/** @public */
|
||||
const TableRow = forwardRef<
|
||||
HTMLTableRowElement,
|
||||
React.HTMLAttributes<HTMLTableRowElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tr ref={ref} className={['table-row', className].join(' ')} {...props}>
|
||||
<tr ref={ref} className={clsx('canon-TableRow', className)} {...props}>
|
||||
{props.children}
|
||||
</tr>
|
||||
));
|
||||
TableRow.displayName = 'TableRow';
|
||||
|
||||
/** @public */
|
||||
const TableHead = forwardRef<
|
||||
HTMLTableCellElement,
|
||||
React.ThHTMLAttributes<HTMLTableCellElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<th ref={ref} className={['table-head', className].join(' ')} {...props} />
|
||||
<th ref={ref} className={clsx('canon-TableHead', className)} {...props} />
|
||||
));
|
||||
TableHead.displayName = 'TableHead';
|
||||
|
||||
/** @public */
|
||||
const TableCell = forwardRef<
|
||||
HTMLTableCellElement,
|
||||
React.TdHTMLAttributes<HTMLTableCellElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<td ref={ref} className={['table-cell', className].join(' ')} {...props} />
|
||||
));
|
||||
TableCell.displayName = 'TableCell';
|
||||
|
||||
/** @public */
|
||||
const TableCaption = forwardRef<
|
||||
HTMLTableCaptionElement,
|
||||
React.HTMLAttributes<HTMLTableCaptionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<caption
|
||||
ref={ref}
|
||||
className={['table-caption', className].join(' ')}
|
||||
className={clsx('canon-TableCaption', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TableCaption.displayName = 'TableCaption';
|
||||
|
||||
export {
|
||||
Table,
|
||||
TableHeader,
|
||||
TableBody,
|
||||
TableFooter,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TableCell,
|
||||
TableCaption,
|
||||
/**
|
||||
* Table component for displaying tabular data
|
||||
* @public
|
||||
*/
|
||||
export const Table = {
|
||||
Root: TableRoot,
|
||||
Header: TableHeader,
|
||||
Body: TableBody,
|
||||
Head: TableHead,
|
||||
Row: TableRow,
|
||||
Cell: TableCell,
|
||||
CellText: TableCellText,
|
||||
CellLink: TableCellLink,
|
||||
Caption: TableCaption,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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';
|
||||
import { TableCell } from './TableCell';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Table/TableCell',
|
||||
component: TableCell,
|
||||
} satisfies Meta<typeof TableCell>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
children: 'Hello world',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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-TableCell {
|
||||
padding: var(--canon-space-3);
|
||||
font-size: var(--canon-font-size-3);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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 clsx from 'clsx';
|
||||
|
||||
/** @public */
|
||||
const TableCell = forwardRef<
|
||||
HTMLTableCellElement,
|
||||
React.TdHTMLAttributes<HTMLTableCellElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<td ref={ref} className={clsx('canon-TableCell', className)} {...props} />
|
||||
));
|
||||
TableCell.displayName = 'TableCell';
|
||||
|
||||
export { TableCell };
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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';
|
||||
import { TableCellLink } from './TableCellLink';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Table/TableCellLink',
|
||||
component: TableCellLink,
|
||||
} satisfies Meta<typeof TableCellLink>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
title: 'I am a link',
|
||||
href: 'https://canon.backstage.io',
|
||||
},
|
||||
};
|
||||
|
||||
export const WithDescription: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
description: 'This is a description',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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-TableCellLink {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--canon-space-0_5);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 clsx from 'clsx';
|
||||
import { TableCellLinkProps } from './types';
|
||||
import { Text } from '../../Text/Text';
|
||||
import { Link } from '../../Link/Link';
|
||||
|
||||
/** @public */
|
||||
const TableCellLink = forwardRef<HTMLDivElement, TableCellLinkProps>(
|
||||
({ className, title, description, href, render, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx('canon-TableCellLink', className)}
|
||||
{...props}
|
||||
>
|
||||
{title && (
|
||||
<Link href={href} render={render}>
|
||||
{title}
|
||||
</Link>
|
||||
)}
|
||||
{description && (
|
||||
<Text variant="body" color="secondary">
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
);
|
||||
TableCellLink.displayName = 'TableCellLink';
|
||||
|
||||
export { TableCellLink };
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 { useRender } from '@base-ui-components/react/use-render';
|
||||
|
||||
/** @public */
|
||||
export interface TableCellLinkProps
|
||||
extends React.TdHTMLAttributes<HTMLTableCellElement> {
|
||||
title: string;
|
||||
description?: string;
|
||||
href: string;
|
||||
render?: useRender.ComponentProps<'a'>['render'];
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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';
|
||||
import { TableCellText } from './TableCellText';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Table/TableCellText',
|
||||
component: TableCellText,
|
||||
} satisfies Meta<typeof TableCellText>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
title: 'Hello world',
|
||||
},
|
||||
};
|
||||
|
||||
export const WithDescription: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
description: 'This is a description',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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-TableCellText {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--canon-space-0_5);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 clsx from 'clsx';
|
||||
import { TableCellTextProps } from './types';
|
||||
import { Text } from '../../Text/Text';
|
||||
|
||||
/** @public */
|
||||
const TableCellText = forwardRef<HTMLDivElement, TableCellTextProps>(
|
||||
({ className, title, description, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx('canon-TableCellText', className)}
|
||||
{...props}
|
||||
>
|
||||
{title && <Text variant="body">{title}</Text>}
|
||||
{description && (
|
||||
<Text variant="body" color="secondary">
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
);
|
||||
TableCellText.displayName = 'TableCellText';
|
||||
|
||||
export { TableCellText };
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** @public */
|
||||
export interface TableCellTextProps
|
||||
extends React.TdHTMLAttributes<HTMLTableCellElement> {
|
||||
title: string;
|
||||
description?: string;
|
||||
}
|
||||
@@ -13,12 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export {
|
||||
Table,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TableHeader,
|
||||
TableCell,
|
||||
TableBody,
|
||||
TableFooter,
|
||||
} from './Table';
|
||||
|
||||
export * from './Table';
|
||||
export * from './TableCellText/types';
|
||||
export * from './TableCellLink/types';
|
||||
|
||||
@@ -1,61 +1,25 @@
|
||||
.table {
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
.canon-TableRoot {
|
||||
width: 100%;
|
||||
background-color: var(--canon-bg-surface-1);
|
||||
border-radius: var(--canon-radius-2);
|
||||
padding-bottom: var(--canon-space-0_5);
|
||||
padding-top: var(--canon-space-0_5);
|
||||
font-size: var(--canon-font-size-3);
|
||||
font-family: var(--canon-font-regular);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
caption-side: bottom;
|
||||
font-size: var(--canon-font-size-sm);
|
||||
border-collapse: collapse;
|
||||
}
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.table-head {
|
||||
.canon-TableHead {
|
||||
text-align: left;
|
||||
padding: var(--canon-space-3);
|
||||
font-size: var(--canon-font-size-3);
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.table-body {
|
||||
tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.canon-TableBody {
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.table-row {
|
||||
.canon-TableRow {
|
||||
border-bottom: 1px solid var(--canon-border);
|
||||
transition: color 0.2s ease-in-out;
|
||||
|
||||
&:hover td {
|
||||
background-color: var(--canon-bg-tint);
|
||||
}
|
||||
|
||||
& .table-cell:first-child {
|
||||
border-top-left-radius: var(--canon-radius-2);
|
||||
border-bottom-left-radius: var(--canon-radius-2);
|
||||
box-shadow: inset 4px 2px 0 0 var(--canon-bg-surface-1),
|
||||
inset 4px -2px 0 0 var(--canon-bg-surface-1);
|
||||
padding-left: var(--canon-space-3);
|
||||
}
|
||||
|
||||
& .table-cell:last-child {
|
||||
border-top-right-radius: var(--canon-radius-2);
|
||||
border-bottom-right-radius: var(--canon-radius-2);
|
||||
box-shadow: inset -4px 2px 0 0 var(--canon-bg-surface-1),
|
||||
inset -4px -2px 0 0 var(--canon-bg-surface-1);
|
||||
padding-right: var(--canon-space-3);
|
||||
}
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
padding: var(--canon-space-3);
|
||||
background-color: var(--canon-bg);
|
||||
box-shadow: inset 0px 2px 0 0 var(--canon-bg-surface-1),
|
||||
inset 0px -2px 0 0 var(--canon-bg-surface-1);
|
||||
.canon-TableBody .canon-TableRow:hover {
|
||||
background-color: var(--canon-gray-2);
|
||||
}
|
||||
|
||||
@@ -41,13 +41,10 @@ export const Text = forwardRef<HTMLParagraphElement, TextProps>(
|
||||
return (
|
||||
<p
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
'canon-Text',
|
||||
responsiveVariant && `canon-Text--variant-${responsiveVariant}`,
|
||||
responsiveWeight && `canon-Text--weight-${responsiveWeight}`,
|
||||
responsiveColor && `canon-Text--color-${responsiveColor}`,
|
||||
className,
|
||||
)}
|
||||
className={clsx('canon-Text', className)}
|
||||
data-variant={responsiveVariant}
|
||||
data-weight={responsiveWeight}
|
||||
data-color={responsiveColor}
|
||||
style={style}
|
||||
{...restProps}
|
||||
>
|
||||
|
||||
@@ -16,55 +16,54 @@
|
||||
|
||||
.canon-Text {
|
||||
font-family: var(--canon-font-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canon-Text--variant-body {
|
||||
.canon-Text[data-variant='body'] {
|
||||
font-size: var(--canon-font-size-3);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-subtitle {
|
||||
.canon-Text[data-variant='subtitle'] {
|
||||
font-size: var(--canon-font-size-4);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-caption {
|
||||
.canon-Text[data-variant='caption'] {
|
||||
font-size: var(--canon-font-size-2);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--variant-label {
|
||||
.canon-Text[data-variant='label'] {
|
||||
font-size: var(--canon-font-size-1);
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.canon-Text--weight-regular {
|
||||
.canon-Text[data-weight='regular'] {
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
}
|
||||
|
||||
.canon-Text--weight-bold {
|
||||
.canon-Text[data-weight='bold'] {
|
||||
font-weight: var(--canon-font-weight-bold);
|
||||
}
|
||||
|
||||
.canon-Text--color-primary {
|
||||
.canon-Text[data-color='primary'] {
|
||||
color: var(--canon-fg-primary);
|
||||
}
|
||||
|
||||
.canon-Text--color-secondary {
|
||||
.canon-Text[data-color='secondary'] {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-Text--color-danger {
|
||||
.canon-Text[data-color='danger'] {
|
||||
color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-Text--color-warning {
|
||||
.canon-Text[data-color='warning'] {
|
||||
color: var(--canon-fg-warning);
|
||||
}
|
||||
|
||||
.canon-Text--color-success {
|
||||
.canon-Text[data-color='success'] {
|
||||
color: var(--canon-fg-success);
|
||||
}
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.canon-TextField--label {
|
||||
.canon-TextFieldLabel {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-primary);
|
||||
margin-bottom: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-TextField--description {
|
||||
.canon-TextFieldDescription {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-secondary);
|
||||
@@ -36,7 +36,7 @@
|
||||
padding-top: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-TextField--error {
|
||||
.canon-TextFieldError {
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
color: var(--canon-fg-danger);
|
||||
@@ -44,7 +44,7 @@
|
||||
padding-top: var(--canon-space-1_5);
|
||||
}
|
||||
|
||||
.canon-TextField--input {
|
||||
.canon-TextFieldInput {
|
||||
border-radius: var(--canon-radius-3);
|
||||
border: 1px solid var(--canon-border);
|
||||
padding: 0 var(--canon-space-4);
|
||||
@@ -57,39 +57,39 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.canon-TextField--input::placeholder {
|
||||
.canon-TextFieldInput::placeholder {
|
||||
color: var(--canon-fg-secondary);
|
||||
}
|
||||
|
||||
.canon-TextField--input:hover {
|
||||
.canon-TextFieldInput:hover {
|
||||
border-color: var(--canon-border-hover);
|
||||
}
|
||||
|
||||
.canon-TextField--input:focus-visible {
|
||||
.canon-TextFieldInput:focus-visible {
|
||||
outline-color: var(--canon-border-pressed);
|
||||
outline-width: 0px;
|
||||
border-color: var(--canon-border-pressed);
|
||||
}
|
||||
|
||||
.canon-TextField--input[data-invalid] {
|
||||
.canon-TextFieldInput[data-invalid] {
|
||||
border-color: var(--canon-fg-danger);
|
||||
}
|
||||
|
||||
.canon-TextField--input[data-disabled] {
|
||||
.canon-TextFieldInput[data-disabled] {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
border: 1px solid var(--canon-border-disabled);
|
||||
}
|
||||
|
||||
.canon-TextField--input-size-small {
|
||||
.canon-TextFieldInput[data-size='small'] {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.canon-TextField--input-size-medium {
|
||||
.canon-TextFieldInput[data-size='medium'] {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.canon-TextField--required {
|
||||
.canon-TextFieldRequired {
|
||||
color: var(--canon-fg-secondary);
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
|
||||
@@ -50,10 +50,10 @@ export const TextField = forwardRef<HTMLDivElement, TextFieldProps>(
|
||||
ref={ref}
|
||||
>
|
||||
{label && (
|
||||
<label className="canon-TextField--label" htmlFor={inputId}>
|
||||
<label className="canon-TextFieldLabel" htmlFor={inputId}>
|
||||
{label}
|
||||
{required && (
|
||||
<span aria-hidden="true" className="canon-TextField--required">
|
||||
<span aria-hidden="true" className="canon-TextFieldRequired">
|
||||
(Required)
|
||||
</span>
|
||||
)}
|
||||
@@ -61,10 +61,8 @@ export const TextField = forwardRef<HTMLDivElement, TextFieldProps>(
|
||||
)}
|
||||
<Input
|
||||
id={inputId}
|
||||
className={clsx('canon-TextField--input', {
|
||||
'canon-TextField--input-size-small': responsiveSize === 'small',
|
||||
'canon-TextField--input-size-medium': responsiveSize === 'medium',
|
||||
})}
|
||||
className="canon-TextFieldInput"
|
||||
data-size={responsiveSize}
|
||||
aria-labelledby={label ? inputId : undefined}
|
||||
aria-describedby={clsx({
|
||||
[descriptionId]: description,
|
||||
@@ -75,12 +73,12 @@ export const TextField = forwardRef<HTMLDivElement, TextFieldProps>(
|
||||
{...rest}
|
||||
/>
|
||||
{description && (
|
||||
<p className="canon-TextField--description" id={descriptionId}>
|
||||
<p className="canon-TextFieldDescription" id={descriptionId}>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{error && (
|
||||
<p className="canon-TextField--error" id={errorId} role="alert">
|
||||
<p className="canon-TextFieldError" id={errorId} role="alert">
|
||||
{error}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -16,12 +16,17 @@
|
||||
|
||||
@import '../components/Box/styles.css';
|
||||
@import '../components/Button/styles.css';
|
||||
@import '../components/DataTable/Root/DataTableRoot.styles.css';
|
||||
@import '../components/DataTable/Pagination/DataTablePagination.styles.css';
|
||||
@import '../components/Flex/styles.css';
|
||||
@import '../components/Grid/styles.css';
|
||||
@import '../components/Container/styles.css';
|
||||
@import '../components/Icon/styles.css';
|
||||
@import '../components/Checkbox/styles.css';
|
||||
@import '../components/Table/styles.css';
|
||||
@import '../components/Table/TableCell/TableCell.styles.css';
|
||||
@import '../components/Table/TableCellText/TableCellText.styles.css';
|
||||
@import '../components/Table/TableCellLink/TableCellLink.styles.css';
|
||||
@import '../components/Text/styles.css';
|
||||
@import '../components/Heading/styles.css';
|
||||
@import '../components/IconButton/styles.css';
|
||||
|
||||
@@ -25,18 +25,40 @@ export const breakpoints: { name: string; id: Breakpoint; value: number }[] = [
|
||||
{ name: 'Extra Large', id: 'xl', value: 1536 },
|
||||
];
|
||||
|
||||
export const useBreakpoint = (): Breakpoint => {
|
||||
// TODO: Perhaps refactor for useMediaQuery to accept an array of queries
|
||||
/** @public */
|
||||
export const useBreakpoint = () => {
|
||||
// Call all media queries at the top level
|
||||
const matches = breakpoints.map(breakpoint => {
|
||||
const match = useMediaQuery(`(min-width: ${breakpoint.value}px)`);
|
||||
return match;
|
||||
return useMediaQuery(`(min-width: ${breakpoint.value}px)`);
|
||||
});
|
||||
|
||||
// Pre-calculate all the up/down values we need
|
||||
const upMatches = new Map(
|
||||
breakpoints.map(bp => [bp.id, useMediaQuery(`(min-width: ${bp.value}px)`)]),
|
||||
);
|
||||
|
||||
const downMatches = new Map(
|
||||
breakpoints.map(bp => [
|
||||
bp.id,
|
||||
useMediaQuery(`(max-width: ${bp.value - 1}px)`),
|
||||
]),
|
||||
);
|
||||
|
||||
let breakpoint: Breakpoint = breakpoints[0].id;
|
||||
for (let i = matches.length - 1; i >= 0; i--) {
|
||||
if (matches[i]) {
|
||||
return breakpoints[i].id;
|
||||
breakpoint = breakpoints[i].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return breakpoints[0].id;
|
||||
return {
|
||||
breakpoint,
|
||||
up: (key: Breakpoint): boolean => {
|
||||
return upMatches.get(key) ?? false;
|
||||
},
|
||||
down: (key: Breakpoint): boolean => {
|
||||
return downMatches.get(key) ?? false;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -20,12 +20,10 @@ import { useBreakpoint, breakpoints } from './useBreakpoint';
|
||||
type ResponsiveValue = string | Partial<Record<Breakpoint, string>>;
|
||||
|
||||
export const useResponsiveValue = (value: ResponsiveValue) => {
|
||||
const currentBreakpoint = useBreakpoint();
|
||||
const { breakpoint } = useBreakpoint();
|
||||
|
||||
if (typeof value === 'object') {
|
||||
const index = breakpoints.findIndex(
|
||||
breakpoint => breakpoint.id === currentBreakpoint,
|
||||
);
|
||||
const index = breakpoints.findIndex(b => b.id === breakpoint);
|
||||
|
||||
for (let i = index; i >= 0; i--) {
|
||||
if (value[breakpoints[i].id]) {
|
||||
|
||||
@@ -33,6 +33,7 @@ export * from './components/Heading';
|
||||
|
||||
// UI components
|
||||
export * from './components/Button';
|
||||
export * from './components/DataTable';
|
||||
export * from './components/Icon';
|
||||
export * from './components/IconButton';
|
||||
export * from './components/Checkbox';
|
||||
@@ -47,3 +48,6 @@ export * from './components/Select';
|
||||
// Types
|
||||
export * from './types';
|
||||
export * from './props';
|
||||
|
||||
// Hooks
|
||||
export { useBreakpoint } from './hooks/useBreakpoint';
|
||||
|
||||
@@ -18,9 +18,11 @@ Commands:
|
||||
config:docs
|
||||
config:print
|
||||
config:schema
|
||||
create-github-app
|
||||
help [command]
|
||||
info
|
||||
migrate [command]
|
||||
new
|
||||
package [command]
|
||||
repo [command]
|
||||
versions:bump
|
||||
@@ -132,6 +134,15 @@ Options:
|
||||
--version
|
||||
```
|
||||
|
||||
### `backstage-cli-alpha create-github-app`
|
||||
|
||||
```
|
||||
Usage: program [options] <github-org>
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
```
|
||||
|
||||
### `backstage-cli-alpha info`
|
||||
|
||||
```
|
||||
@@ -204,6 +215,23 @@ Options:
|
||||
-h, --help
|
||||
```
|
||||
|
||||
### `backstage-cli-alpha new`
|
||||
|
||||
```
|
||||
Usage: program [options]
|
||||
|
||||
Options:
|
||||
--baseVersion <version>
|
||||
--license <license>
|
||||
--no-private
|
||||
--npm-registry <URL>
|
||||
--option <name>=<value>
|
||||
--scope <scope>
|
||||
--select <name>
|
||||
--skip-install
|
||||
-h, --help
|
||||
```
|
||||
|
||||
### `backstage-cli-alpha package`
|
||||
|
||||
```
|
||||
|
||||
@@ -25,6 +25,8 @@ import chalk from 'chalk';
|
||||
),
|
||||
);
|
||||
const initializer = new CliInitializer();
|
||||
initializer.add(import('./modules/new/alpha'));
|
||||
initializer.add(import('./modules/create-github-app/alpha'));
|
||||
initializer.add(import('./modules/info/alpha'));
|
||||
initializer.add(import('./modules/config/alpha'));
|
||||
initializer.add(import('./modules/build/alpha'));
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import { Command } from 'commander';
|
||||
import { lazy } from '../lib/lazy';
|
||||
import { registerCommands as registerConfigCommands } from '../modules/config';
|
||||
import {
|
||||
registerPackageCommands as registerPackageBuildCommands,
|
||||
@@ -40,6 +39,9 @@ import {
|
||||
registerPackageCommands as registerMaintenancePackageCommands,
|
||||
registerRepoCommands as registerMaintenanceRepoCommands,
|
||||
} from '../modules/maintenance';
|
||||
import { removed } from '../lib/removed';
|
||||
import { registerCommands as registerNewCommands } from '../modules/new';
|
||||
import { registerCommands as registerCreateGithubAppCommands } from '../modules/create-github-app';
|
||||
|
||||
export function registerRepoCommand(program: Command) {
|
||||
const command = program
|
||||
@@ -66,62 +68,16 @@ export function registerScriptCommand(program: Command) {
|
||||
}
|
||||
|
||||
export function registerCommands(program: Command) {
|
||||
program
|
||||
.command('new')
|
||||
.storeOptionsAsProperties(false)
|
||||
.description(
|
||||
'Open up an interactive guide to creating new things in your app',
|
||||
)
|
||||
.option(
|
||||
'--select <name>',
|
||||
'Select the thing you want to be creating upfront',
|
||||
)
|
||||
.option(
|
||||
'--option <name>=<value>',
|
||||
'Pre-fill options for the creation process',
|
||||
(opt, arr: string[]) => [...arr, opt],
|
||||
[],
|
||||
)
|
||||
.option(
|
||||
'--skip-install',
|
||||
`Skips running 'yarn install' and 'yarn lint --fix'`,
|
||||
)
|
||||
.option('--scope <scope>', 'The scope to use for new packages')
|
||||
.option(
|
||||
'--npm-registry <URL>',
|
||||
'The package registry to use for new packages',
|
||||
)
|
||||
.option(
|
||||
'--baseVersion <version>',
|
||||
'The version to use for any new packages (default: 0.1.0)',
|
||||
)
|
||||
.option(
|
||||
'--license <license>',
|
||||
'The license to use for any new packages (default: Apache-2.0)',
|
||||
)
|
||||
.option('--no-private', 'Do not mark new packages as private')
|
||||
.action(lazy(() => import('./new/new'), 'default'));
|
||||
|
||||
registerConfigCommands(program);
|
||||
registerRepoCommand(program);
|
||||
registerScriptCommand(program);
|
||||
registerMigrateCommand(program);
|
||||
registerBuildCommands(program);
|
||||
registerInfoCommands(program);
|
||||
program
|
||||
.command('create-github-app <github-org>')
|
||||
.description('Create new GitHub App in your organization.')
|
||||
.action(lazy(() => import('./create-github-app'), 'default'));
|
||||
|
||||
registerNewCommands(program);
|
||||
registerCreateGithubAppCommands(program);
|
||||
// Notifications for removed commands
|
||||
program
|
||||
.command('create')
|
||||
.allowUnknownOption(true)
|
||||
.action(removed("use 'backstage-cli new' instead"));
|
||||
program
|
||||
.command('create-plugin')
|
||||
.allowUnknownOption(true)
|
||||
.action(removed("use 'backstage-cli new' instead"));
|
||||
|
||||
program
|
||||
.command('plugin:diff')
|
||||
.allowUnknownOption(true)
|
||||
@@ -145,14 +101,3 @@ export function registerCommands(program: Command) {
|
||||
program.command('install').allowUnknownOption(true).action(removed());
|
||||
program.command('onboard').allowUnknownOption(true).action(removed());
|
||||
}
|
||||
|
||||
function removed(message?: string) {
|
||||
return () => {
|
||||
console.error(
|
||||
message
|
||||
? `This command has been removed, ${message}`
|
||||
: 'This command has been removed',
|
||||
);
|
||||
process.exit(1);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
export function removed(message?: string) {
|
||||
return () => {
|
||||
console.error(
|
||||
message
|
||||
? `This command has been removed, ${message}`
|
||||
: 'This command has been removed',
|
||||
);
|
||||
process.exit(1);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
import { createCliPlugin } from '../../wiring/factory';
|
||||
import { Command } from 'commander';
|
||||
import { lazy } from '../../lib/lazy';
|
||||
|
||||
export default createCliPlugin({
|
||||
pluginId: 'new',
|
||||
init: async reg => {
|
||||
reg.addCommand({
|
||||
path: ['create-github-app'],
|
||||
description: 'Create new GitHub App in your organization.',
|
||||
execute: async ({ args }) => {
|
||||
const command = new Command();
|
||||
const defaultCommand = command
|
||||
.argument('<github-org>')
|
||||
.action(
|
||||
lazy(() => import('./commands/create-github-app'), 'default'),
|
||||
);
|
||||
|
||||
await defaultCommand.parseAsync(args, { from: 'user' });
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
+1
-1
@@ -18,7 +18,7 @@ import fs from 'fs-extra';
|
||||
import chalk from 'chalk';
|
||||
import { stringify as stringifyYaml } from 'yaml';
|
||||
import inquirer, { Question, Answers } from 'inquirer';
|
||||
import { paths } from '../../lib/paths';
|
||||
import { paths } from '../../../../lib/paths';
|
||||
import { GithubCreateAppServer } from './GithubCreateAppServer';
|
||||
import openBrowser from 'react-dev-utils/openBrowser';
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
import { Command } from 'commander';
|
||||
import { lazy } from '../../lib/lazy';
|
||||
|
||||
export function registerCommands(program: Command) {
|
||||
program
|
||||
.command('create-github-app <github-org>')
|
||||
.description('Create new GitHub App in your organization.')
|
||||
.action(
|
||||
lazy(
|
||||
() => import('../create-github-app/commands/create-github-app'),
|
||||
'default',
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
import { createCliPlugin } from '../../wiring/factory';
|
||||
import { Command } from 'commander';
|
||||
import { lazy } from '../../lib/lazy';
|
||||
import { removed } from '../../lib/removed';
|
||||
|
||||
export default createCliPlugin({
|
||||
pluginId: 'new',
|
||||
init: async reg => {
|
||||
reg.addCommand({
|
||||
path: ['new'],
|
||||
description:
|
||||
'Open up an interactive guide to creating new things in your app',
|
||||
execute: async ({ args }) => {
|
||||
const command = new Command();
|
||||
const defaultCommand = command
|
||||
.storeOptionsAsProperties(false)
|
||||
.description(
|
||||
'Open up an interactive guide to creating new things in your app',
|
||||
)
|
||||
.option(
|
||||
'--select <name>',
|
||||
'Select the thing you want to be creating upfront',
|
||||
)
|
||||
.option(
|
||||
'--option <name>=<value>',
|
||||
'Pre-fill options for the creation process',
|
||||
(opt, arr: string[]) => [...arr, opt],
|
||||
[],
|
||||
)
|
||||
.option(
|
||||
'--skip-install',
|
||||
`Skips running 'yarn install' and 'yarn lint --fix'`,
|
||||
)
|
||||
.option('--scope <scope>', 'The scope to use for new packages')
|
||||
.option(
|
||||
'--npm-registry <URL>',
|
||||
'The package registry to use for new packages',
|
||||
)
|
||||
.option(
|
||||
'--baseVersion <version>',
|
||||
'The version to use for any new packages (default: 0.1.0)',
|
||||
)
|
||||
.option(
|
||||
'--license <license>',
|
||||
'The license to use for any new packages (default: Apache-2.0)',
|
||||
)
|
||||
.option('--no-private', 'Do not mark new packages as private')
|
||||
.action(lazy(() => import('./commands/new'), 'default'));
|
||||
|
||||
await defaultCommand.parseAsync(args, { from: 'user' });
|
||||
},
|
||||
});
|
||||
|
||||
reg.addCommand({
|
||||
path: ['create'],
|
||||
description: 'Create a new Backstage app',
|
||||
deprecated: true,
|
||||
execute: async () => {
|
||||
removed("use 'backstage-cli new' instead")();
|
||||
},
|
||||
});
|
||||
reg.addCommand({
|
||||
path: ['create-plugin'],
|
||||
description: 'Create a new Backstage plugin',
|
||||
deprecated: true,
|
||||
execute: async () => {
|
||||
removed("use 'backstage-cli new' instead")();
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
+2
-2
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createNewPackage } from '../../lib/new/createNewPackage';
|
||||
import { createNewPackage } from '../lib/createNewPackage';
|
||||
import { default as newCommand } from './new';
|
||||
|
||||
jest.mock('../../lib/new/createNewPackage');
|
||||
jest.mock('../lib/createNewPackage');
|
||||
|
||||
describe.each([
|
||||
[undefined, undefined, undefined],
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createNewPackage } from '../../lib/new/createNewPackage';
|
||||
import { createNewPackage } from '../lib/createNewPackage';
|
||||
|
||||
type ArgOptions = {
|
||||
option: string[];
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
import { Command } from 'commander';
|
||||
import { lazy } from '../../lib/lazy';
|
||||
import { removed } from '../../lib/removed';
|
||||
|
||||
export function registerCommands(program: Command) {
|
||||
program
|
||||
.command('new')
|
||||
.storeOptionsAsProperties(false)
|
||||
.description(
|
||||
'Open up an interactive guide to creating new things in your app',
|
||||
)
|
||||
.option(
|
||||
'--select <name>',
|
||||
'Select the thing you want to be creating upfront',
|
||||
)
|
||||
.option(
|
||||
'--option <name>=<value>',
|
||||
'Pre-fill options for the creation process',
|
||||
(opt, arr: string[]) => [...arr, opt],
|
||||
[],
|
||||
)
|
||||
.option(
|
||||
'--skip-install',
|
||||
`Skips running 'yarn install' and 'yarn lint --fix'`,
|
||||
)
|
||||
.option('--scope <scope>', 'The scope to use for new packages')
|
||||
.option(
|
||||
'--npm-registry <URL>',
|
||||
'The package registry to use for new packages',
|
||||
)
|
||||
.option(
|
||||
'--baseVersion <version>',
|
||||
'The version to use for any new packages (default: 0.1.0)',
|
||||
)
|
||||
.option(
|
||||
'--license <license>',
|
||||
'The license to use for any new packages (default: Apache-2.0)',
|
||||
)
|
||||
.option('--no-private', 'Do not mark new packages as private')
|
||||
.action(lazy(() => import('./commands/new'), 'default'));
|
||||
|
||||
program
|
||||
.command('create')
|
||||
.allowUnknownOption(true)
|
||||
.action(removed("use 'backstage-cli new' instead"));
|
||||
program
|
||||
.command('create-plugin')
|
||||
.allowUnknownOption(true)
|
||||
.action(removed("use 'backstage-cli new' instead"));
|
||||
}
|
||||
+3
-3
@@ -24,9 +24,9 @@ import startCase from 'lodash/startCase';
|
||||
import upperCase from 'lodash/upperCase';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import lowerFirst from 'lodash/lowerFirst';
|
||||
import { Lockfile } from '../../versioning';
|
||||
import { paths } from '../../paths';
|
||||
import { createPackageVersionProvider } from '../../version';
|
||||
import { Lockfile } from '../../../../lib/versioning';
|
||||
import { paths } from '../../../../lib/paths';
|
||||
import { createPackageVersionProvider } from '../../../../lib/version';
|
||||
|
||||
const builtInHelpers = {
|
||||
camelCase,
|
||||
+2
-2
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
|
||||
import { assertError } from '@backstage/errors';
|
||||
import { addCodeownersEntry } from '../../codeowners';
|
||||
import { Task } from '../../tasks';
|
||||
import { addCodeownersEntry } from '../../../../lib/codeowners';
|
||||
import { Task } from '../../../../lib/tasks';
|
||||
import {
|
||||
PortableTemplate,
|
||||
PortableTemplateConfig,
|
||||
+2
-2
@@ -16,8 +16,8 @@
|
||||
import fs from 'fs-extra';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import camelCase from 'lodash/camelCase';
|
||||
import { paths } from '../../paths';
|
||||
import { Task } from '../../tasks';
|
||||
import { paths } from '../../../../lib/paths';
|
||||
import { Task } from '../../../../lib/tasks';
|
||||
import { PortableTemplateInput } from '../types';
|
||||
|
||||
export async function installNewPackage(input: PortableTemplateInput) {
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
import { relative as relativePath } from 'node:path';
|
||||
import { writeTemplateContents } from './writeTemplateContents';
|
||||
import { createMockDirectory } from '@backstage/backend-test-utils';
|
||||
import { paths } from '../../paths';
|
||||
import { paths } from '../../../../lib/paths';
|
||||
|
||||
const baseConfig = {
|
||||
version: '0.1.0',
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user