diff --git a/microsite-canon/app/favicon.ico b/microsite-canon/app/favicon.ico deleted file mode 100644 index 718d6fea48..0000000000 Binary files a/microsite-canon/app/favicon.ico and /dev/null differ diff --git a/microsite-canon/app/icon.svg b/microsite-canon/app/icon.svg new file mode 100644 index 0000000000..12cad81e95 --- /dev/null +++ b/microsite-canon/app/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/microsite-canon/components/IconLibrary/IconLibrary.tsx b/microsite-canon/components/IconLibrary/IconLibrary.tsx index e32f4c08a4..2b5c06aa5e 100644 --- a/microsite-canon/components/IconLibrary/IconLibrary.tsx +++ b/microsite-canon/components/IconLibrary/IconLibrary.tsx @@ -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 ( -
- {icons.map(icon => ( -
-
+
+ {list.map(icon => ( +
+
- {icon} + {icon}
))}
diff --git a/microsite-canon/components/IconLibrary/styles.css b/microsite-canon/components/IconLibrary/styles.module.css similarity index 62% rename from microsite-canon/components/IconLibrary/styles.css rename to microsite-canon/components/IconLibrary/styles.module.css index 1a6f63ca79..40b177ced0 100644 --- a/microsite-canon/components/IconLibrary/styles.css +++ b/microsite-canon/components/IconLibrary/styles.module.css @@ -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); + } } diff --git a/microsite-canon/content/iconography.mdx b/microsite-canon/content/iconography.mdx new file mode 100644 index 0000000000..9083c93389 --- /dev/null +++ b/microsite-canon/content/iconography.mdx @@ -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. + +`} /> + +## Icon library + + diff --git a/microsite-canon/content/layout.mdx b/microsite-canon/content/layout.mdx index 4b0622d92e..dc3a5d4585 100644 --- a/microsite-canon/content/layout.mdx +++ b/microsite-canon/content/layout.mdx @@ -32,16 +32,6 @@ provide are the ones coming from the theme. `} /> -```tsx - - Hello World - - Project 1 - Project 2 - - -``` - ## Layout Helpers diff --git a/microsite-canon/yarn.lock b/microsite-canon/yarn.lock index 25272cdc9e..3751b33bc2 100644 --- a/microsite-canon/yarn.lock +++ b/microsite-canon/yarn.lock @@ -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" diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index cc193e1180..f2e88fd367 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -224,6 +224,33 @@ export interface GridProps extends SpaceProps { style?: React.CSSProperties; } +// @public (undocumented) +export const Heading: React_2.ForwardRefExoticComponent< + HeadingProps & React_2.RefAttributes +>; + +// @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 @@ -400,6 +430,27 @@ export const TableRow: React_3.ForwardRefExoticComponent< React_3.RefAttributes >; +// @public (undocumented) +const Text_2: React_2.ForwardRefExoticComponent< + TextProps & React_2.RefAttributes +>; +export { Text_2 as Text }; + +// @public (undocumented) +export interface TextProps { + // (undocumented) + children: React.ReactNode; + // (undocumented) + variant?: + | 'subtitle' + | 'body' + | 'caption' + | 'label' + | Partial>; + // (undocumented) + weight?: 'regular' | 'bold' | Partial>; +} + // @public (undocumented) export const useCanon: () => CanonContextProps; diff --git a/packages/canon/src/components/Heading/Heading.tsx b/packages/canon/src/components/Heading/Heading.tsx index 04ce6bcdfa..612c871ebb 100644 --- a/packages/canon/src/components/Heading/Heading.tsx +++ b/packages/canon/src/components/Heading/Heading.tsx @@ -18,6 +18,7 @@ import React, { forwardRef } from 'react'; import { HeadingProps } from './types'; import { useCanon } from '../../contexts/canon'; +/** @public */ export const Heading = forwardRef( (props, ref) => { const { children, variant = 'title1', as = 'h1', ...restProps } = props; diff --git a/packages/canon/src/components/Icon/Icon.stories.tsx b/packages/canon/src/components/Icon/Icon.stories.tsx index a5cf0ae56a..ad9d6d01dd 100644 --- a/packages/canon/src/components/Icon/Icon.stories.tsx +++ b/packages/canon/src/components/Icon/Icon.stories.tsx @@ -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: { diff --git a/packages/canon/src/components/Icon/icons.ts b/packages/canon/src/components/Icon/icons.ts index 29808cf0c8..de005cf63d 100644 --- a/packages/canon/src/components/Icon/icons.ts +++ b/packages/canon/src/components/Icon/icons.ts @@ -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, diff --git a/packages/canon/src/components/Icon/index.tsx b/packages/canon/src/components/Icon/index.tsx index 3e7564c77e..0fa2eac35b 100644 --- a/packages/canon/src/components/Icon/index.tsx +++ b/packages/canon/src/components/Icon/index.tsx @@ -15,4 +15,5 @@ */ export * from './Icon'; +export * from './icons'; export type * from './types'; diff --git a/packages/canon/src/components/Text/Text.tsx b/packages/canon/src/components/Text/Text.tsx index 3af01f92f9..762832c97d 100644 --- a/packages/canon/src/components/Text/Text.tsx +++ b/packages/canon/src/components/Text/Text.tsx @@ -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( (props, ref) => { const { diff --git a/packages/canon/src/components/Text/types.ts b/packages/canon/src/components/Text/types.ts index d3232e1d67..129087e7d5 100644 --- a/packages/canon/src/components/Text/types.ts +++ b/packages/canon/src/components/Text/types.ts @@ -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' diff --git a/packages/canon/src/contexts/canon.tsx b/packages/canon/src/contexts/canon.tsx index da0b9b420b..92b36ce396 100644 --- a/packages/canon/src/contexts/canon.tsx +++ b/packages/canon/src/contexts/canon.tsx @@ -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({ - 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)`); diff --git a/packages/canon/src/index.ts b/packages/canon/src/index.ts index ce589b8c53..f6cca4bed6 100644 --- a/packages/canon/src/index.ts +++ b/packages/canon/src/index.ts @@ -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';