Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2024-12-30 12:13:30 +01:00
parent ee6454ef3c
commit eb16a03768
16 changed files with 131 additions and 32 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="640" height="640" viewBox="0 0 640 640" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M370.766 153.765C377.563 166.716 371.236 182.114 359.357 190.647C323.005 216.758 299.326 259.411 299.326 307.597C299.326 365.997 334.107 416.27 384.077 438.817C395.235 443.852 403.478 454.368 403.478 466.609V640H382.864C224.433 640 96 511.517 96 353.025L96 20.6143C96 9.22934 105.229 0 116.614 0V0C226.982 3.14552e-06 322.792 62.3523 370.766 153.765Z" fill="black"/>
<path d="M438.772 411.19C496.335 411.19 543 364.454 543 306.803C543 249.152 496.335 202.417 438.772 202.417C381.208 202.417 334.543 249.152 334.543 306.803C334.543 364.454 381.208 411.19 438.772 411.19Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 702 B

@@ -13,23 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { Icon } from '@backstage/canon';
import type { IconNames } from '@backstage/canon';
import { defaultIcons } from '../../../src/components/Icon/icons';
import { Text } from '../Text/Text';
import { icons, Text } from '@backstage/canon';
import styles from './styles.module.css';
export const IconLibrary = () => {
const icons = Object.keys(defaultIcons);
const list = Object.keys(icons);
return (
<div className="icon-library">
{icons.map(icon => (
<div key={icon} className="icon-library-item">
<div className="icon-library-item-icon">
<div className={styles.library}>
{list.map(icon => (
<div key={icon} className={styles.item}>
<div className={styles.icon}>
<Icon name={icon as IconNames} />
</div>
<Text>{icon}</Text>
<span>{icon}</span>
</div>
))}
</div>
@@ -1,17 +1,17 @@
.icon-library {
.library {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 1rem;
}
.icon-library-item {
.item {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.icon-library-item-icon {
.icon {
display: flex;
width: 100%;
justify-content: center;
@@ -19,4 +19,10 @@
height: 80px;
border: 1px solid #d3d3d3;
border-radius: 0.5rem;
background-color: var(--canon-background);
transition: background-color 0.2s ease-in-out;
&:hover {
background-color: var(--canon-surface-1);
}
}
+16
View File
@@ -0,0 +1,16 @@
import { CodeBlock } from '@/components/CodeBlock';
import { IconLibrary } from '@/components/IconLibrary';
# Iconography
All our default icons are provided by [Remix Icon](https://remixicon.com/). We
don't import all icons to reduce the bundle size but we cherry pick a nice
selection for you to use in your application. The list of names is set down
below. To use an icon, you can use the `Icon` component and pass the name of
the icon you want to use.
<CodeBlock title="Icon component" code={`<Icon name="heart" />`} />
## Icon library
<IconLibrary />
-10
View File
@@ -32,16 +32,6 @@ provide are the ones coming from the theme.
`}
/>
```tsx
<Stack direction="column" gap="md">
<Box>Hello World</Box>
<Inline gap="sm">
<Box>Project 1</Box>
<Box>Project 2</Box>
</Inline>
</Stack>
```
<LayoutComponents />
## Layout Helpers
+26 -3
View File
@@ -1501,8 +1501,8 @@ __metadata:
linkType: hard
"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6":
version: 1.23.7
resolution: "es-abstract@npm:1.23.7"
version: 1.23.8
resolution: "es-abstract@npm:1.23.8"
dependencies:
array-buffer-byte-length: ^1.0.2
arraybuffer.prototype.slice: ^1.0.4
@@ -1539,8 +1539,10 @@ __metadata:
object-inspect: ^1.13.3
object-keys: ^1.1.1
object.assign: ^4.1.7
own-keys: ^1.0.0
regexp.prototype.flags: ^1.5.3
safe-array-concat: ^1.1.3
safe-push-apply: ^1.0.0
safe-regex-test: ^1.1.0
string.prototype.trim: ^1.2.10
string.prototype.trimend: ^1.0.9
@@ -1551,7 +1553,7 @@ __metadata:
typed-array-length: ^1.0.7
unbox-primitive: ^1.1.0
which-typed-array: ^1.1.18
checksum: 030f09ff2d7db69cd6c6da5b1ccb88aee986e23cf82149135f78b5b9675f1cd79a0e64de2d7e393ae40b98de76369292d87bf31db69b5b9151370f7948ee7c59
checksum: b91916702b8147bf3f2ed35c83a7c3f19ba09641364ebce8351d60358fa49ac66da353fe4a991de72502bb4853f52e51e3f2f93920c7c8d5dc01ab2b30d77b17
languageName: node
linkType: hard
@@ -3605,6 +3607,17 @@ __metadata:
languageName: node
linkType: hard
"own-keys@npm:^1.0.0":
version: 1.0.1
resolution: "own-keys@npm:1.0.1"
dependencies:
get-intrinsic: ^1.2.6
object-keys: ^1.1.1
safe-push-apply: ^1.0.0
checksum: cc9dd7d85c4ccfbe8109fce307d581ac7ede7b26de892b537873fbce2dc6a206d89aea0630dbb98e47ce0873517cefeaa7be15fcf94aaf4764a3b34b474a5b61
languageName: node
linkType: hard
"p-limit@npm:^3.0.2":
version: 3.1.0
resolution: "p-limit@npm:3.1.0"
@@ -4014,6 +4027,16 @@ __metadata:
languageName: node
linkType: hard
"safe-push-apply@npm:^1.0.0":
version: 1.0.0
resolution: "safe-push-apply@npm:1.0.0"
dependencies:
es-errors: ^1.3.0
isarray: ^2.0.5
checksum: 8c11cbee6dc8ff5cc0f3d95eef7052e43494591384015902e4292aef4ae9e539908288520ed97179cee17d6ffb450fe5f05a46ce7a1749685f7524fd568ab5db
languageName: node
linkType: hard
"safe-regex-test@npm:^1.0.3, safe-regex-test@npm:^1.1.0":
version: 1.1.0
resolution: "safe-regex-test@npm:1.1.0"
+51
View File
@@ -224,6 +224,33 @@ export interface GridProps extends SpaceProps {
style?: React.CSSProperties;
}
// @public (undocumented)
export const Heading: React_2.ForwardRefExoticComponent<
HeadingProps & React_2.RefAttributes<HTMLHeadingElement>
>;
// @public (undocumented)
export interface HeadingProps {
// (undocumented)
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
// (undocumented)
children: React.ReactNode;
// (undocumented)
variant?:
| 'display'
| 'title1'
| 'title2'
| 'title3'
| 'title4'
| 'title5'
| Partial<
Record<
Breakpoint,
'display' | 'title1' | 'title2' | 'title3' | 'title4' | 'title5'
>
>;
}
// @public (undocumented)
export const Icon: (props: IconProps) => React_2.JSX.Element;
@@ -258,6 +285,9 @@ export type IconProps = {
size?: number;
};
// @public (undocumented)
export const icons: IconMap;
// @public (undocumented)
export const Inline: ForwardRefExoticComponent<
InlineProps & RefAttributes<HTMLElement>
@@ -400,6 +430,27 @@ export const TableRow: React_3.ForwardRefExoticComponent<
React_3.RefAttributes<HTMLTableRowElement>
>;
// @public (undocumented)
const Text_2: React_2.ForwardRefExoticComponent<
TextProps & React_2.RefAttributes<HTMLParagraphElement>
>;
export { Text_2 as Text };
// @public (undocumented)
export interface TextProps {
// (undocumented)
children: React.ReactNode;
// (undocumented)
variant?:
| 'subtitle'
| 'body'
| 'caption'
| 'label'
| Partial<Record<Breakpoint, 'subtitle' | 'body' | 'caption' | 'label'>>;
// (undocumented)
weight?: 'regular' | 'bold' | Partial<Record<Breakpoint, 'regular' | 'bold'>>;
}
// @public (undocumented)
export const useCanon: () => CanonContextProps;
@@ -18,6 +18,7 @@ import React, { forwardRef } from 'react';
import { HeadingProps } from './types';
import { useCanon } from '../../contexts/canon';
/** @public */
export const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(
(props, ref) => {
const { children, variant = 'title1', as = 'h1', ...restProps } = props;
@@ -18,7 +18,7 @@ import React from 'react';
import { Meta, StoryObj } from '@storybook/react';
import { Icon } from './Icon';
import { CanonProvider } from '../../contexts/canon';
import { defaultIcons } from './icons';
import { icons } from './icons';
const meta = {
title: 'Components/Icon',
@@ -29,7 +29,7 @@ const meta = {
argTypes: {
name: {
control: 'select',
options: Object.keys(defaultIcons),
options: Object.keys(icons),
},
},
args: {
+2 -2
View File
@@ -39,8 +39,8 @@ import {
RiSunLine,
} from '@remixicon/react';
// List of default icons
export const defaultIcons: IconMap = {
/** @public */
export const icons: IconMap = {
arrowDown: RiArrowDownFill,
arrowLeft: RiArrowLeftFill,
arrowRight: RiArrowRightFill,
@@ -15,4 +15,5 @@
*/
export * from './Icon';
export * from './icons';
export type * from './types';
@@ -1,3 +1,5 @@
'use client';
/*
* Copyright 2024 The Backstage Authors
*
@@ -18,6 +20,7 @@ import React, { forwardRef } from 'react';
import { TextProps } from './types';
import { useCanon } from '../../contexts/canon';
/** @public */
export const Text = forwardRef<HTMLParagraphElement, TextProps>(
(props, ref) => {
const {
+2 -1
View File
@@ -14,11 +14,12 @@
* limitations under the License.
*/
import type { ReactNode } from 'react';
import type { Breakpoint } from '../../types';
/** @public */
export interface TextProps {
children: React.ReactNode;
children: ReactNode;
variant?:
| 'subtitle'
| 'body'
+3 -3
View File
@@ -18,7 +18,7 @@
import React, { createContext, useContext, ReactNode } from 'react';
import { IconMap, IconNames } from '../components/Icon/types';
import { defaultIcons } from '../components/Icon/icons';
import { icons } from '../components/Icon/icons';
import { useMediaQuery } from '../hooks/useMediaQuery';
import type { Breakpoint } from '../types';
@@ -32,7 +32,7 @@ export interface CanonContextProps {
}
const CanonContext = createContext<CanonContextProps>({
icons: defaultIcons,
icons,
breakpoint: 'md',
getResponsiveValue: () => '',
});
@@ -48,7 +48,7 @@ export const CanonProvider = (props: CanonProviderProps) => {
const { children, overrides } = props;
// Merge provided overrides with default icons
const combinedIcons = { ...defaultIcons, ...overrides };
const combinedIcons = { ...icons, ...overrides };
const isBreakpointSm = useMediaQuery(`(min-width: 640px)`);
const isBreakpointMd = useMediaQuery(`(min-width: 768px)`);
+2
View File
@@ -29,6 +29,8 @@ export * from './components/Grid';
export * from './components/Stack';
export * from './components/Inline';
export * from './components/Container';
export * from './components/Text';
export * from './components/Heading';
// UI components
export * from './components/Button';