Add new TableCellProfile
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
Add new TableCellProfile component for Table and DataTable in Canon.
|
||||
@@ -246,6 +246,48 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-TableCellProfile {
|
||||
gap: var(--canon-space-2);
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-TableCellProfileAvatar {
|
||||
vertical-align: middle;
|
||||
user-select: none;
|
||||
color: var(--canon-fg-primary);
|
||||
background-color: var(--canon-bg-surface-2);
|
||||
border-radius: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
display: inline-flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.canon-TableCellProfileAvatarImage {
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.canon-TableCellProfileAvatarFallback {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
border-radius: var(--canon-radius-full);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Text {
|
||||
font-family: var(--canon-font-regular);
|
||||
margin: 0;
|
||||
|
||||
@@ -9470,6 +9470,48 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-TableCellProfile {
|
||||
gap: var(--canon-space-2);
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-TableCellProfileAvatar {
|
||||
vertical-align: middle;
|
||||
user-select: none;
|
||||
color: var(--canon-fg-primary);
|
||||
background-color: var(--canon-bg-surface-2);
|
||||
border-radius: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
display: inline-flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.canon-TableCellProfileAvatarImage {
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.canon-TableCellProfileAvatarFallback {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
border-radius: var(--canon-radius-full);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.canon-Text {
|
||||
font-family: var(--canon-font-regular);
|
||||
margin: 0;
|
||||
|
||||
@@ -260,6 +260,9 @@ export const DataTable: {
|
||||
TableCellLink: ForwardRefExoticComponent<
|
||||
TableCellLinkProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
TableCellProfile: ForwardRefExoticComponent<
|
||||
TableCellProfileProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
TableHead: ForwardRefExoticComponent<
|
||||
ThHTMLAttributes<HTMLTableCellElement> & RefAttributes<HTMLTableCellElement>
|
||||
>;
|
||||
@@ -1116,6 +1119,9 @@ export const Table: {
|
||||
CellLink: ForwardRefExoticComponent<
|
||||
TableCellLinkProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
CellProfile: ForwardRefExoticComponent<
|
||||
TableCellProfileProps & RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
Caption: ForwardRefExoticComponent<
|
||||
HTMLAttributes<HTMLTableCaptionElement> &
|
||||
RefAttributes<HTMLTableCaptionElement>
|
||||
@@ -1124,7 +1130,7 @@ export const Table: {
|
||||
|
||||
// @public (undocumented)
|
||||
export interface TableCellLinkProps
|
||||
extends React.TdHTMLAttributes<HTMLTableCellElement> {
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
// (undocumented)
|
||||
description?: string;
|
||||
// (undocumented)
|
||||
@@ -1135,9 +1141,22 @@ export interface TableCellLinkProps
|
||||
title: string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface TableCellProfileProps
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
// (undocumented)
|
||||
name?: string;
|
||||
// (undocumented)
|
||||
src?: string;
|
||||
// (undocumented)
|
||||
to?: string;
|
||||
// (undocumented)
|
||||
withImage?: boolean;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface TableCellTextProps
|
||||
extends React.TdHTMLAttributes<HTMLTableCellElement> {
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
// (undocumented)
|
||||
description?: string;
|
||||
// (undocumented)
|
||||
|
||||
@@ -46,5 +46,6 @@ export const DataTable = {
|
||||
TableCell: Table.Cell,
|
||||
TableCellText: Table.CellText,
|
||||
TableCellLink: Table.CellLink,
|
||||
TableCellProfile: Table.CellProfile,
|
||||
TableHead: Table.Head,
|
||||
};
|
||||
|
||||
@@ -58,7 +58,7 @@ export const columns: ColumnDef<DataProps>[] = [
|
||||
accessorKey: 'owner',
|
||||
header: 'Owner',
|
||||
cell: ({ row }) => (
|
||||
<DataTable.TableCellText title={row.getValue('owner')} />
|
||||
<DataTable.TableCellProfile name={row.getValue('owner')} />
|
||||
),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ import clsx from 'clsx';
|
||||
import { TableCell } from './TableCell/TableCell';
|
||||
import { TableCellText } from './TableCellText/TableCellText';
|
||||
import { TableCellLink } from './TableCellLink/TableCellLink';
|
||||
import { TableCellProfile } from './TableCellProfile/TableCellProfile';
|
||||
|
||||
const TableRoot = forwardRef<
|
||||
HTMLTableElement,
|
||||
@@ -91,5 +92,6 @@ export const Table = {
|
||||
Cell: TableCell,
|
||||
CellText: TableCellText,
|
||||
CellLink: TableCellLink,
|
||||
CellProfile: TableCellProfile,
|
||||
Caption: TableCaption,
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ import type { useRender } from '@base-ui-components/react/use-render';
|
||||
|
||||
/** @public */
|
||||
export interface TableCellLinkProps
|
||||
extends React.TdHTMLAttributes<HTMLTableCellElement> {
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
title: string;
|
||||
description?: string;
|
||||
href: string;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 { TableCellProfile } from './TableCellProfile';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Table/TableCellProfile',
|
||||
component: TableCellProfile,
|
||||
} satisfies Meta<typeof TableCellProfile>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
src: 'https://avatars.githubusercontent.com/u/1540635?v=4',
|
||||
name: 'Charles de Dreuille',
|
||||
},
|
||||
};
|
||||
|
||||
export const Fallback: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
src: 'https://avatars.githubusercontent.com/u/15406AAAAAAAAA',
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLink: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
to: 'https://www.google.com',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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-TableCellProfile {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: var(--canon-space-2);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.canon-TableCellProfileAvatar {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
vertical-align: middle;
|
||||
border-radius: 100%;
|
||||
user-select: none;
|
||||
font-weight: 500;
|
||||
color: var(--canon-fg-primary);
|
||||
background-color: var(--canon-bg-surface-2);
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
overflow: hidden;
|
||||
height: 1.25rem;
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
.canon-TableCellProfileAvatarImage {
|
||||
object-fit: cover;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.canon-TableCellProfileAvatarFallback {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
font-size: var(--canon-font-size-2);
|
||||
font-weight: var(--canon-font-weight-regular);
|
||||
box-shadow: inset 0 0 0 1px var(--canon-border);
|
||||
border-radius: var(--canon-radius-full);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 { TableCellProfileProps } from './types';
|
||||
import { Text } from '../../Text/Text';
|
||||
import { Link } from '../../Link/Link';
|
||||
import { Avatar } from '@base-ui-components/react/avatar';
|
||||
|
||||
/** @public */
|
||||
const TableCellProfile = forwardRef<HTMLDivElement, TableCellProfileProps>(
|
||||
({ className, src, name, to, withImage = true, ...rest }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx('canon-TableCellProfile', className)}
|
||||
{...rest}
|
||||
>
|
||||
{withImage && (
|
||||
<Avatar.Root className="canon-TableCellProfileAvatar">
|
||||
<Avatar.Image
|
||||
src={src}
|
||||
width="20"
|
||||
height="20"
|
||||
className="canon-TableCellProfileAvatarImage"
|
||||
/>
|
||||
<Avatar.Fallback className="canon-TableCellProfileAvatarFallback">
|
||||
{(name || '')
|
||||
.split(' ')
|
||||
.map(word => word[0])
|
||||
.join('')
|
||||
.toLocaleUpperCase('en-US')
|
||||
.slice(0, 1)}
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
)}
|
||||
{name && to ? (
|
||||
<Link to={to}>{name}</Link>
|
||||
) : (
|
||||
<Text variant="body">{name}</Text>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
);
|
||||
TableCellProfile.displayName = 'TableCellProfile';
|
||||
|
||||
export { TableCellProfile };
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 TableCellProfileProps
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
src?: string;
|
||||
name?: string;
|
||||
to?: string;
|
||||
withImage?: boolean;
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/** @public */
|
||||
export interface TableCellTextProps
|
||||
extends React.TdHTMLAttributes<HTMLTableCellElement> {
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
title: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
@@ -17,3 +17,4 @@
|
||||
export * from './Table';
|
||||
export * from './TableCellText/types';
|
||||
export * from './TableCellLink/types';
|
||||
export * from './TableCellProfile/types';
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
@import '../components/Table/TableCell/TableCell.styles.css';
|
||||
@import '../components/Table/TableCellText/TableCellText.styles.css';
|
||||
@import '../components/Table/TableCellLink/TableCellLink.styles.css';
|
||||
@import '../components/Table/TableCellProfile/TableCellProfile.styles.css';
|
||||
@import '../components/Text/styles.css';
|
||||
@import '../components/Heading/styles.css';
|
||||
@import '../components/IconButton/styles.css';
|
||||
|
||||
Reference in New Issue
Block a user