diff --git a/packages/canon/.storybook/main.ts b/packages/canon/.storybook/main.ts
index 2e369475d6..cf7921268e 100644
--- a/packages/canon/.storybook/main.ts
+++ b/packages/canon/.storybook/main.ts
@@ -10,6 +10,7 @@ function getAbsolutePath(value: string): any {
}
const config: StorybookConfig = {
stories: [
+ '../docs/**/*.mdx',
'../src/components/**/*.mdx',
'../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)',
],
diff --git a/packages/canon/.storybook/preview-head.html b/packages/canon/.storybook/preview-head.html
deleted file mode 100644
index e1c9e51552..0000000000
--- a/packages/canon/.storybook/preview-head.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/packages/canon/.storybook/preview.tsx b/packages/canon/.storybook/preview.tsx
index 867461818b..1ac53acd86 100644
--- a/packages/canon/.storybook/preview.tsx
+++ b/packages/canon/.storybook/preview.tsx
@@ -2,6 +2,9 @@ import React from 'react';
import type { Preview, ReactRenderer } from '@storybook/react';
import { withThemeByDataAttribute } from '@storybook/addon-themes';
+// Storybook specific styles
+import '../docs/components/styles.css';
+
// Canon specific styles
import '../src/css/core.css';
import '../src/css/components.css';
diff --git a/packages/canon/docs/Home.mdx b/packages/canon/docs/Home.mdx
new file mode 100644
index 0000000000..5b85ab15ad
--- /dev/null
+++ b/packages/canon/docs/Home.mdx
@@ -0,0 +1,91 @@
+import { Unstyled } from '@storybook/blocks';
+import {
+ Columns,
+ Text,
+ ComponentStatus,
+ Banner,
+ Title,
+ Roadmap,
+} from './components';
+import { list } from './components/Roadmap/list';
+
+
+
+
+
+
+ Welcome to the Canon, the new design library for Backstage plugins. This
+ project is still under active development but we will make sure to document
+ the API as we go. We are aiming to improve the general UI of Backstage and
+ plugins across Backstage. This new library will take time to build but we are
+ building it incrementally with not conflict with the existing theming system.
+
+
+
+ This library is still under heavy construction. Please be aware that the API
+ will change until we reach a stable release.
+
+
+
+ Component Status
+
+
+ We are still in the process of documenting the API and building the
+ components. You can use the statuses below to see what is ready and what is
+ coming soon. If there is a component missing that you need, please let us know
+ by opening an issue on GitHub.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Roadmap
+
+
+
+
+
diff --git a/packages/canon/docs/Iconography.mdx b/packages/canon/docs/Iconography.mdx
new file mode 100644
index 0000000000..83d181af12
--- /dev/null
+++ b/packages/canon/docs/Iconography.mdx
@@ -0,0 +1,22 @@
+import { Unstyled, Source, Meta } from '@storybook/blocks';
+import { Title, Text, IconLibrary } from './components';
+
+
+
+
+
+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.
+
+
+`} language="tsx" dark />
+
+
+
+
diff --git a/packages/canon/docs/Layout.mdx b/packages/canon/docs/Layout.mdx
new file mode 100644
index 0000000000..9145f71aed
--- /dev/null
+++ b/packages/canon/docs/Layout.mdx
@@ -0,0 +1,54 @@
+import { Unstyled, Source, Meta } from '@storybook/blocks';
+import { Title, Text, LayoutComponents } from './components';
+import * as Table from './components/Table';
+
+
+
+
+
+Layout
+
+ Canon is made for extensibility. We built this library to make it easy for any
+ Backstage plugin creator to be able to build their ideas at speed ensuring
+ consistency across the rest of your ecosystem. Each component is designed to
+ be editable to match your need but sometimes you want to have more control
+ over the layout of your page. To help you with that, we created a set of
+ layout components that you can use to build your own layouts. All of these
+ components are built to extend on our theming system, making it easy for you
+ to build your own layouts. Sometimes these components are not enough so we
+ created a set of helpers to be used with any CSS-in-JS library.
+
+
+Layout Components
+
+
+ We built a couple of layout components to help you build responsive elements
+ that will be consistent with the rest of your Backstage instance. These
+ components are opinionated and use TypeScript to ensure that the props you
+ provide are the ones coming from the theme.
+
+
+
+ Hello World
+
+ Project 1
+ Project 2
+
+`}
+ language="tsx"
+ dark
+/>
+
+
+
+Layout Helpers
+
+
+ Sometimes you want to use global tokens dynamically outside of React
+ components. To help you with that we would like to provide a set of helpers
+ that you can use in your code. These helpers are not available just yet but we
+ are working on it.
+
+
+
diff --git a/packages/canon/docs/Responsive.mdx b/packages/canon/docs/Responsive.mdx
new file mode 100644
index 0000000000..85292ee555
--- /dev/null
+++ b/packages/canon/docs/Responsive.mdx
@@ -0,0 +1,150 @@
+import { Unstyled, Meta, Canvas, Source } from '@storybook/blocks';
+import {
+ Columns,
+ Text,
+ ComponentStatus,
+ Banner,
+ Title,
+ Roadmap,
+} from './components';
+import { list } from './components/Roadmap/list';
+import * as HeadingStories from '../src/components/Heading/Heading.stories';
+import * as TextStories from '../src/components/Text/Text.stories';
+import * as Table from './components/Table';
+import { Chip } from './components/Chip';
+
+
+
+
+
+Responsive
+
+ Canon is built on a responsive design system, meaning that the components are
+ designed to adapt to different screen sizes. By default we offer a set of
+ breakpoints that you can use to create responsive components.
+
+
+
+ Breakpoints
+
+
+
+
+
+ Breakpoint prefix
+ Minimum width
+ CSS
+
+
+
+
+
+ xs
+
+
+ 0px
+
+
+ {`{ ... }`}
+
+
+
+
+ sm
+
+
+ 640px
+
+
+ {`@media (min-width: 640px) { ... }`}
+
+
+
+
+ md
+
+
+ 768px
+
+
+ {`@media (min-width: 768px) { ... }`}
+
+
+
+
+ lg
+
+
+ 1024px
+
+
+ {`@media (min-width: 1024px) { ... }`}
+
+
+
+
+ xl
+
+
+ 1280px
+
+
+ {`@media (min-width: 1280px) { ... }`}
+
+
+
+
+ 2xl
+
+
+ 1536px
+
+
+ {`@media (min-width: 1536px) { ... }`}
+
+
+
+
+
+Responsive components
+
+
+ Canon components are designed to be responsive, meaning that they will adapt
+ to different screen sizes. Not every component is responsive, but the ones
+ that are will have a prop to control the responsive behavior.
+
+
+
+ The behaviour is the same for each component. For each prop, instead of adding
+ the value, you add an object with the value and the breakpoint prefix.
+
+
+Button
+
+// Responsive value
+
+`} dark />
+
+How to update breakpoints
+
+
+ The set of keys are not to be changed, but you can update the minimum width of
+ each breakpoint in the theme provider.
+
+
+`}
+ dark
+/>
+
+
diff --git a/packages/canon/docs/Theme.mdx b/packages/canon/docs/Theme.mdx
new file mode 100644
index 0000000000..1ea7c5c4c6
--- /dev/null
+++ b/packages/canon/docs/Theme.mdx
@@ -0,0 +1,231 @@
+import { Unstyled, Source, Meta } from '@storybook/blocks';
+import { Title, Text, Chip } from './components';
+import * as Table from './components/Table';
+
+{' '}
+
+
+
+Theming
+
+ Backstage ships with a default theme with a light and dark mode variant. The
+ themes are provided as a part of the `@backstage/canon` package, which also
+ includes utilities for customizing the default theme, or creating completely
+ new themes.
+
+
+Light & Dark modes
+
+ By default we are supporting both light and dark modes. Each user can opt to
+ choose what theme they want to use or to use their system decide what theme to
+ use. If you want to create your own theme, you will have to set both light and
+ dark themes following the instructions below. If you only set one of them, the
+ other mode will fallback to the default theme.
+
+
+How to create your own theme
+
+ To create your own theme, you will have to define the variables below. To do
+ that, create a theme.css file and import it in your application. Here's an
+ example below on how to set your light and dark mode.
+
+
+
+Colors
+
+ We provide a set of generic colours tokens that we use across Canon. By
+ changing these colours you can easily change the look and feel of your
+ application to match your brand.
+
+
+
+
+ Prop
+ Description
+
+
+
+
+
+ --canon-accent
+
+ The accent color for the theme.
+
+
+
+ --canon-bg
+
+ The background color for the theme.
+
+
+
+ --canon-surface-1
+
+ The first surface color for the theme.
+
+
+
+ --canon-surface-2
+
+ The second surface color for the theme.
+
+
+
+ --canon-outline
+
+ The outline color for the theme.
+
+
+
+ --canon-outline-focus
+
+ The outline focus color for the theme.
+
+
+
+ --canon-text-primary
+
+ The primary text color for the theme.
+
+
+
+ --canon-text-secondary
+
+ The secondary text color for the theme.
+
+
+
+
+Typography
+
+ 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
+ monospace font that we use for code blocks and tables.
+
+
+
+
+
+ Prop
+ Description
+
+
+
+
+
+ --canon-font-regular
+
+ The sans-serif font for the theme.
+
+
+
+ --canon-font-mono
+
+ The monospace font for the theme.
+
+
+
+
+Spacing
+
+ Our default spacing system is made to work in most scenarios. We have 7 scale
+ values from `xxs` to `xxl`. We use the values on padding and margin in our
+ layout components mostly. If you prefer to use a different spacing system, you
+ can do that by changing the values below.
+
+
+
+
+
+ Prop
+ Description
+
+
+
+
+
+ --canon-space-unit
+
+
+ The base unit for the spacing system. Default value is `1em`
+
+
+
+
+ --canon-space-xxs
+
+ Default value is `0.25 x space unit`
+
+
+
+ --canon-space-xs
+
+ Default value is `0.5 x space unit`
+
+
+
+ --canon-space-sm
+
+ Default value is `0.75 x space unit`
+
+
+
+ --canon-space-md
+
+ Default value is `1.25 x space unit`
+
+
+
+ --canon-space-lg
+
+ Default value is `2 x space unit`
+
+
+
+ --canon-space-xl
+
+ Default value is `3.25 x space unit`
+
+
+
+ --canon-space-xxl
+
+ Default value is `5.25 x space unit`
+
+
+
+
+
diff --git a/packages/canon/docs/Typography.mdx b/packages/canon/docs/Typography.mdx
new file mode 100644
index 0000000000..802b9881be
--- /dev/null
+++ b/packages/canon/docs/Typography.mdx
@@ -0,0 +1,48 @@
+import { Unstyled, Meta, Canvas } from '@storybook/blocks';
+import {
+ Columns,
+ Text,
+ ComponentStatus,
+ Banner,
+ Title,
+ Roadmap,
+} from './components';
+import { list } from './components/Roadmap/list';
+import * as HeadingStories from '../src/components/Heading/Heading.stories';
+import * as TextStories from '../src/components/Text/Text.stories';
+
+
+
+
+
+Typography
+
+ Canon offers a suite of typography components designed to seamlessly align
+ with the rest of your Backstage instance. While you can customize their
+ appearance to match your brand, the underlying API remains consistent and
+ unchanged. Each component is built on a responsive structure, allowing you to
+ define different typography values for various breakpoints.
+
+
+Heading
+
+ Headings are used to structure the content of your page. They are used to
+ create a hierarchy of information and to make the content more readable. The
+ best way to use add these headings to your page is to import the [Heading
+ component](?path=/docs/components-heading--docs).
+
+
+
+
+Text
+
+ Canon provides four distinct text variants, each offering different font sizes
+ carefully designed to cover the majority of use cases. These variants are
+ versatile and can be paired with regular and bold of font weights. You can use
+ the [Text component](?path=/docs/components-text--docs) to add text to your
+ page.
+
+
+
+
+
diff --git a/packages/canon/docs/components/Banner/Banner.tsx b/packages/canon/docs/components/Banner/Banner.tsx
new file mode 100644
index 0000000000..3199e65bc0
--- /dev/null
+++ b/packages/canon/docs/components/Banner/Banner.tsx
@@ -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 React from 'react';
+
+export const Banner = ({
+ children,
+ variant = 'info',
+}: {
+ children: React.ReactNode;
+ variant?: 'info' | 'warning';
+}) => {
+ return (
+
+
+
+
+ {children}
+
+ );
+};
diff --git a/packages/canon/docs/components/Banner/index.ts b/packages/canon/docs/components/Banner/index.ts
new file mode 100644
index 0000000000..31f4aa88b0
--- /dev/null
+++ b/packages/canon/docs/components/Banner/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { Banner } from './Banner';
diff --git a/packages/canon/docs/components/Banner/styles.css b/packages/canon/docs/components/Banner/styles.css
new file mode 100644
index 0000000000..d20e14ce0b
--- /dev/null
+++ b/packages/canon/docs/components/Banner/styles.css
@@ -0,0 +1,37 @@
+.banner {
+ display: flex;
+ align-items: center;
+ font-size: 16px;
+ line-height: 28px;
+ padding: 16px;
+ border-radius: 6px;
+ margin-bottom: 16px;
+ border: 1px solid #e0e0e0;
+
+ & > p {
+ margin: 0;
+ }
+
+ &.info {
+ background-color: #f2f2f2;
+ border-color: #cdcdcd;
+ color: #888888;
+ }
+
+ &.warning {
+ background-color: #fff2b9;
+ border-color: #ffd000;
+ color: #d79927;
+ }
+
+ & .icon {
+ width: 32px;
+ height: 32px;
+ background-color: rgba(215, 153, 39, 0.2);
+ border-radius: 6px;
+ margin-right: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+}
diff --git a/packages/canon/docs/components/Chip/Chip.tsx b/packages/canon/docs/components/Chip/Chip.tsx
new file mode 100644
index 0000000000..e6e1d1b1c4
--- /dev/null
+++ b/packages/canon/docs/components/Chip/Chip.tsx
@@ -0,0 +1,27 @@
+/*
+ * 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 React from 'react';
+
+export const Chip = ({
+ children,
+ head = false,
+}: {
+ children: React.ReactNode;
+ head?: boolean;
+}) => {
+ return {children};
+};
diff --git a/packages/canon/docs/components/Chip/index.ts b/packages/canon/docs/components/Chip/index.ts
new file mode 100644
index 0000000000..ff9e4794c5
--- /dev/null
+++ b/packages/canon/docs/components/Chip/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { Chip } from './Chip';
diff --git a/packages/canon/docs/components/Chip/styles.css b/packages/canon/docs/components/Chip/styles.css
new file mode 100644
index 0000000000..95cf7cef34
--- /dev/null
+++ b/packages/canon/docs/components/Chip/styles.css
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+.chip {
+ display: inline-flex;
+ align-items: center;
+ font-family: monospace;
+ font-size: 13px;
+ border-radius: 6px;
+ padding: 0px 8px;
+ height: 24px;
+ margin-right: 4px;
+ background-color: #f0f0f0;
+ color: #5d5d5d;
+
+ &.head {
+ background-color: #eaf2fd;
+ color: #2563eb;
+ }
+}
diff --git a/packages/canon/docs/components/Columns/Columns.tsx b/packages/canon/docs/components/Columns/Columns.tsx
new file mode 100644
index 0000000000..115ec50010
--- /dev/null
+++ b/packages/canon/docs/components/Columns/Columns.tsx
@@ -0,0 +1,31 @@
+/*
+ * 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 React from 'react';
+
+export const Columns = ({
+ children,
+ style,
+}: {
+ children: React.ReactNode;
+ style?: React.CSSProperties;
+}) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/packages/canon/docs/components/Columns/index.ts b/packages/canon/docs/components/Columns/index.ts
new file mode 100644
index 0000000000..05de0850be
--- /dev/null
+++ b/packages/canon/docs/components/Columns/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { Columns } from './Columns';
diff --git a/packages/canon/docs/components/Columns/styles.css b/packages/canon/docs/components/Columns/styles.css
new file mode 100644
index 0000000000..c34acfc406
--- /dev/null
+++ b/packages/canon/docs/components/Columns/styles.css
@@ -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.
+ */
+
+.columns {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ row-gap: 20px;
+ column-gap: 80px;
+}
diff --git a/packages/canon/docs/components/ComponentStatus/ComponentStatus.tsx b/packages/canon/docs/components/ComponentStatus/ComponentStatus.tsx
new file mode 100644
index 0000000000..0159e27b32
--- /dev/null
+++ b/packages/canon/docs/components/ComponentStatus/ComponentStatus.tsx
@@ -0,0 +1,48 @@
+/*
+ * 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 React from 'react';
+
+export const ComponentStatus = ({
+ name,
+ status = 'notStarted',
+ style,
+ link,
+}: {
+ name: string;
+ status: 'notStarted' | 'inProgress' | 'alpha' | 'beta' | 'stable';
+ style?: React.CSSProperties;
+ link?: string;
+}) => {
+ return (
+
+ );
+};
diff --git a/packages/canon/docs/components/ComponentStatus/index.ts b/packages/canon/docs/components/ComponentStatus/index.ts
new file mode 100644
index 0000000000..238c001289
--- /dev/null
+++ b/packages/canon/docs/components/ComponentStatus/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { ComponentStatus } from './ComponentStatus';
diff --git a/packages/canon/docs/components/ComponentStatus/styles.css b/packages/canon/docs/components/ComponentStatus/styles.css
new file mode 100644
index 0000000000..6ef02ccf3f
--- /dev/null
+++ b/packages/canon/docs/components/ComponentStatus/styles.css
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+.component-status {
+ display: flex;
+ justify-content: space-between;
+
+ & .title {
+ color: #3b59ff;
+ font-size: 16px;
+ font-weight: 400;
+ text-decoration: none;
+ }
+
+ & .pill {
+ display: inline-flex;
+ align-items: center;
+ color: #000;
+ border-radius: 40px;
+ padding: 0px 8px;
+ height: 24px;
+ font-size: 12px;
+ font-weight: 600;
+ border-style: solid;
+ border-width: 1px;
+ margin-left: 8px;
+
+ &.notStarted {
+ background-color: #f2f2f2;
+ border-color: #cdcdcd;
+ color: #888888;
+ }
+
+ &.inProgress {
+ background-color: #fff2b9;
+ border-color: #ffd000;
+ color: #d79927;
+ }
+
+ &.alpha {
+ background-color: #d7f9d7;
+ border-color: #4ed14a;
+ color: #3a9837;
+ }
+
+ &.beta {
+ background-color: #d7f9d7;
+ border-color: #4ed14a;
+ color: #3a9837;
+ }
+
+ &.stable {
+ background-color: #d7f9d7;
+ border-color: #4ed14a;
+ color: #3a9837;
+ }
+ }
+}
diff --git a/packages/canon/docs/components/IconLibrary/IconLibrary.tsx b/packages/canon/docs/components/IconLibrary/IconLibrary.tsx
new file mode 100644
index 0000000000..e32f4c08a4
--- /dev/null
+++ b/packages/canon/docs/components/IconLibrary/IconLibrary.tsx
@@ -0,0 +1,37 @@
+/*
+ * 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 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';
+
+export const IconLibrary = () => {
+ const icons = Object.keys(defaultIcons);
+
+ return (
+
+ {icons.map(icon => (
+
+
+
+
+ {icon}
+
+ ))}
+
+ );
+};
diff --git a/packages/canon/docs/components/IconLibrary/index.ts b/packages/canon/docs/components/IconLibrary/index.ts
new file mode 100644
index 0000000000..071c80db85
--- /dev/null
+++ b/packages/canon/docs/components/IconLibrary/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { IconLibrary } from './IconLibrary';
diff --git a/packages/canon/docs/components/IconLibrary/styles.css b/packages/canon/docs/components/IconLibrary/styles.css
new file mode 100644
index 0000000000..1a6f63ca79
--- /dev/null
+++ b/packages/canon/docs/components/IconLibrary/styles.css
@@ -0,0 +1,22 @@
+.icon-library {
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 1rem;
+}
+
+.icon-library-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+}
+
+.icon-library-item-icon {
+ display: flex;
+ width: 100%;
+ justify-content: center;
+ align-items: center;
+ height: 80px;
+ border: 1px solid #d3d3d3;
+ border-radius: 0.5rem;
+}
diff --git a/packages/canon/docs/components/LayoutComponents/LayoutComponents.tsx b/packages/canon/docs/components/LayoutComponents/LayoutComponents.tsx
new file mode 100644
index 0000000000..56f389a389
--- /dev/null
+++ b/packages/canon/docs/components/LayoutComponents/LayoutComponents.tsx
@@ -0,0 +1,64 @@
+/*
+ * 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 React from 'react';
+import { BoxSvg } from './svgs/box';
+import { StackSvg } from './svgs/stack';
+import { GridSvg } from './svgs/grid';
+import { InlineSvg } from './svgs/inline';
+import { ContainerSvg } from './svgs/container';
+
+export const LayoutComponents = () => {
+ return (
+
+ );
+};
diff --git a/packages/canon/docs/components/LayoutComponents/index.ts b/packages/canon/docs/components/LayoutComponents/index.ts
new file mode 100644
index 0000000000..55cc9f25ef
--- /dev/null
+++ b/packages/canon/docs/components/LayoutComponents/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { LayoutComponents } from './LayoutComponents';
diff --git a/packages/canon/docs/components/LayoutComponents/styles.css b/packages/canon/docs/components/LayoutComponents/styles.css
new file mode 100644
index 0000000000..9319121224
--- /dev/null
+++ b/packages/canon/docs/components/LayoutComponents/styles.css
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+.layout-components {
+ display: flex;
+ justify-content: flex-start;
+ gap: 1rem;
+ flex-wrap: wrap;
+
+ & .box {
+ display: flex;
+ flex-direction: column;
+ width: calc(33.33% - 0.67rem);
+ margin-bottom: 1rem;
+ align-items: flex-start;
+ }
+
+ & .content {
+ flex: none;
+ background: linear-gradient(180deg, #f3f3f3 0%, #fff 100%);
+ border-radius: 4px;
+ width: 100%;
+ height: 180px;
+ transition: all 0.2s ease-in-out;
+ margin-bottom: 0.75rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ &:hover {
+ transform: translateY(-4px);
+ }
+ }
+
+ & .title {
+ font-size: 16px;
+ transition: color 0.2s ease-in-out;
+ margin-bottom: 0.25rem;
+ }
+
+ & .description {
+ font-size: 16px;
+ color: #9e9e9e;
+ }
+}
diff --git a/packages/canon/docs/components/LayoutComponents/svgs/box.tsx b/packages/canon/docs/components/LayoutComponents/svgs/box.tsx
new file mode 100644
index 0000000000..1749b38c6f
--- /dev/null
+++ b/packages/canon/docs/components/LayoutComponents/svgs/box.tsx
@@ -0,0 +1,54 @@
+/*
+ * 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 React from 'react';
+
+export const BoxSvg = () => {
+ return (
+
+ );
+};
diff --git a/packages/canon/docs/components/LayoutComponents/svgs/container.tsx b/packages/canon/docs/components/LayoutComponents/svgs/container.tsx
new file mode 100644
index 0000000000..62fe4ce266
--- /dev/null
+++ b/packages/canon/docs/components/LayoutComponents/svgs/container.tsx
@@ -0,0 +1,373 @@
+/*
+ * 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 React from 'react';
+
+export const ContainerSvg = () => {
+ return (
+
+ );
+};
diff --git a/packages/canon/docs/components/LayoutComponents/svgs/grid.tsx b/packages/canon/docs/components/LayoutComponents/svgs/grid.tsx
new file mode 100644
index 0000000000..5527d1f3e2
--- /dev/null
+++ b/packages/canon/docs/components/LayoutComponents/svgs/grid.tsx
@@ -0,0 +1,91 @@
+/*
+ * 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 React from 'react';
+
+export const GridSvg = () => {
+ return (
+
+ );
+};
diff --git a/packages/canon/docs/components/LayoutComponents/svgs/inline.tsx b/packages/canon/docs/components/LayoutComponents/svgs/inline.tsx
new file mode 100644
index 0000000000..fadb9bfc1b
--- /dev/null
+++ b/packages/canon/docs/components/LayoutComponents/svgs/inline.tsx
@@ -0,0 +1,92 @@
+/*
+ * 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 React from 'react';
+
+export const InlineSvg = () => {
+ return (
+
+ );
+};
diff --git a/packages/canon/docs/components/LayoutComponents/svgs/stack.tsx b/packages/canon/docs/components/LayoutComponents/svgs/stack.tsx
new file mode 100644
index 0000000000..aeda998d2e
--- /dev/null
+++ b/packages/canon/docs/components/LayoutComponents/svgs/stack.tsx
@@ -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 React from 'react';
+
+export const StackSvg = () => {
+ return (
+
+ );
+};
diff --git a/packages/canon/docs/components/PropsTable/PropsTable.tsx b/packages/canon/docs/components/PropsTable/PropsTable.tsx
new file mode 100644
index 0000000000..a3dc9e271c
--- /dev/null
+++ b/packages/canon/docs/components/PropsTable/PropsTable.tsx
@@ -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.
+ */
+
+import React from 'react';
+import * as Table from '..';
+import { Chip } from '..';
+
+// Modify the PropsTable component to accept a generic type
+export const PropsTable = >({
+ data,
+}: {
+ data: T;
+}) => {
+ return (
+
+
+
+ Prop
+ Type
+ Responsive
+
+
+
+ {Object.keys(data).map(n => (
+
+
+ {n}
+
+
+ {Array.isArray(data[n].type) ? (
+ data[n].type.map((t: any) => {t})
+ ) : (
+ {data[n].type}
+ )}
+
+
+ {data[n].responsive ? 'Yes' : 'No'}
+
+
+ ))}
+
+
+ );
+};
diff --git a/packages/canon/docs/components/PropsTable/getProps.ts b/packages/canon/docs/components/PropsTable/getProps.ts
new file mode 100644
index 0000000000..5773eaeb27
--- /dev/null
+++ b/packages/canon/docs/components/PropsTable/getProps.ts
@@ -0,0 +1,43 @@
+/*
+ * 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 function getProps(styles: Record) {
+ return Object.keys(styles).reduce(
+ (acc: Record, n) => {
+ const style = styles[n];
+
+ let values: string[] = [];
+
+ if (style.values) {
+ // If values exist, use them
+ values = Object.keys(style.values);
+ } else if (style.mappings && style.mappings.length > 0) {
+ // If mappings exist, use the first mapping's values
+ const firstMapping = style.mappings[0];
+ values = Object.keys(styles[firstMapping].values);
+ } else {
+ // Default to an empty array if neither values nor mappings exist
+ values = [];
+ }
+
+ acc[n] = {
+ type: values,
+ responsive: true,
+ };
+ return acc;
+ },
+ {} as Record,
+ );
+}
diff --git a/packages/canon/docs/components/PropsTable/index.ts b/packages/canon/docs/components/PropsTable/index.ts
new file mode 100644
index 0000000000..181933f0f8
--- /dev/null
+++ b/packages/canon/docs/components/PropsTable/index.ts
@@ -0,0 +1,17 @@
+/*
+ * 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 { PropsTable } from './PropsTable';
+export { getProps } from './getProps';
diff --git a/packages/canon/docs/components/Roadmap/Roadmap.tsx b/packages/canon/docs/components/Roadmap/Roadmap.tsx
new file mode 100644
index 0000000000..2177ea558f
--- /dev/null
+++ b/packages/canon/docs/components/Roadmap/Roadmap.tsx
@@ -0,0 +1,53 @@
+/*
+ * 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 React from 'react';
+import { RoadmapItem } from './list';
+
+export const Roadmap = ({ list }: { list: RoadmapItem[] }) => {
+ const orderList = ['inProgress', 'notStarted', 'completed'];
+ return (
+
;
+};
diff --git a/packages/canon/docs/components/Table/index.ts b/packages/canon/docs/components/Table/index.ts
new file mode 100644
index 0000000000..7419aa83a8
--- /dev/null
+++ b/packages/canon/docs/components/Table/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { Root, Header, Body, Row, Cell, HeaderRow, HeaderCell } from './Table';
diff --git a/packages/canon/docs/components/Table/styles.css b/packages/canon/docs/components/Table/styles.css
new file mode 100644
index 0000000000..ed56774a85
--- /dev/null
+++ b/packages/canon/docs/components/Table/styles.css
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+.sb-table-wrapper {
+ border: 1px solid #e7e7e7;
+ border-radius: 4px;
+ overflow: hidden;
+
+ & .sb-table {
+ width: 100%;
+ margin: 0 !important;
+ padding: 0 !important;
+ border-spacing: 0px;
+ border-collapse: collapse;
+ }
+
+ & .sb-table-cell {
+ padding: 12px 16px !important;
+ border: none !important;
+ text-align: left;
+ background-color: white !important;
+ font-size: 16px;
+
+ & p {
+ margin: 0;
+ }
+ }
+
+ & .sb-table-header-cell {
+ background-color: #f5f5f5 !important;
+ border-bottom: 1px solid #e7e7e7 !important;
+ font-weight: 500;
+ font-size: 14px;
+ }
+
+ & .sb-table-row {
+ border: none;
+ border-bottom: 1px solid #e7e7e7;
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+
+ & .sb-table-chip {
+ display: inline-block;
+ font-size: 14px !important;
+ border: 1px solid #e7e7e7;
+ border-radius: 6px;
+ padding: 0px 6px;
+ height: 24px;
+ }
+
+ & .sb-table-type {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ gap: 8px;
+ }
+}
diff --git a/packages/canon/docs/components/Text/Text.tsx b/packages/canon/docs/components/Text/Text.tsx
new file mode 100644
index 0000000000..90804b7da7
--- /dev/null
+++ b/packages/canon/docs/components/Text/Text.tsx
@@ -0,0 +1,31 @@
+/*
+ * 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 React from 'react';
+
+export const Text = ({
+ children,
+ style,
+}: {
+ children: React.ReactNode;
+ style?: React.CSSProperties;
+}) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/packages/canon/docs/components/Text/index.ts b/packages/canon/docs/components/Text/index.ts
new file mode 100644
index 0000000000..873fca2c76
--- /dev/null
+++ b/packages/canon/docs/components/Text/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { Text } from './Text';
diff --git a/packages/canon/docs/components/Text/styles.css b/packages/canon/docs/components/Text/styles.css
new file mode 100644
index 0000000000..b1bc40a1ac
--- /dev/null
+++ b/packages/canon/docs/components/Text/styles.css
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+.sb-text {
+ font-size: 16px;
+ line-height: 28px;
+ margin: 0;
+ margin-bottom: 16px;
+ color: #4f4f4f;
+
+ & p {
+ font-size: 16px;
+ line-height: 28px;
+ margin: 0;
+ }
+
+ & code {
+ font-size: 13px;
+ color: #215cff;
+ background-color: #f1f3fc;
+ padding: 4px 4px;
+ border-radius: 4px;
+ }
+
+ & a {
+ color: #215cff;
+ text-decoration: none;
+ border-bottom: 1px solid #215cff;
+ }
+}
diff --git a/packages/canon/docs/components/Title/Title.tsx b/packages/canon/docs/components/Title/Title.tsx
new file mode 100644
index 0000000000..59fefad8f9
--- /dev/null
+++ b/packages/canon/docs/components/Title/Title.tsx
@@ -0,0 +1,38 @@
+/*
+ * 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 React from 'react';
+
+export const Title = ({
+ children,
+ style,
+ type = 'h1',
+}: {
+ children: React.ReactNode;
+ style?: React.CSSProperties;
+ type?: 'h1' | 'h2' | 'h3';
+}) => {
+ let Component = 'h1';
+ if (type === 'h1') Component = 'h1';
+ if (type === 'h2') Component = 'h2';
+ if (type === 'h3') Component = 'h3';
+
+ return React.createElement(Component, {
+ className: `sb-title ${type}`,
+ style,
+ children,
+ });
+};
diff --git a/packages/canon/docs/components/Title/index.ts b/packages/canon/docs/components/Title/index.ts
new file mode 100644
index 0000000000..998dc81882
--- /dev/null
+++ b/packages/canon/docs/components/Title/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { Title } from './Title';
diff --git a/packages/canon/docs/components/Title/styles.css b/packages/canon/docs/components/Title/styles.css
new file mode 100644
index 0000000000..61e99e20b3
--- /dev/null
+++ b/packages/canon/docs/components/Title/styles.css
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+.sb-title {
+ margin: 0;
+ font-weight: 500;
+ border: none;
+
+ &.h1 {
+ font-size: 36px;
+ line-height: 44px;
+ margin-bottom: 24px;
+ margin-top: 0px;
+ }
+
+ &.h2 {
+ font-size: 24px;
+ line-height: 32px;
+ margin-bottom: 12px;
+ margin-top: 52px;
+ }
+
+ &.h3 {
+ font-size: 20px;
+ line-height: 28px;
+ margin-bottom: 12px;
+ margin-top: 40px;
+ }
+}
diff --git a/packages/canon/docs/components/index.ts b/packages/canon/docs/components/index.ts
new file mode 100644
index 0000000000..0e5ff2e325
--- /dev/null
+++ b/packages/canon/docs/components/index.ts
@@ -0,0 +1,27 @@
+/*
+ * 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 './Banner';
+export * from './Chip';
+export * from './Columns';
+export * from './ComponentStatus';
+export * from './IconLibrary';
+export * from './LayoutComponents';
+export * from './PropsTable';
+export * from './Roadmap';
+export * from './Table';
+export * from './Text';
+export * from './Title';
diff --git a/packages/canon/docs/components/styles.css b/packages/canon/docs/components/styles.css
new file mode 100644
index 0000000000..706b1626b3
--- /dev/null
+++ b/packages/canon/docs/components/styles.css
@@ -0,0 +1,15 @@
+.sbdocs-content {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
+ Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
+}
+
+@import './Banner/styles.css';
+@import './Chip/styles.css';
+@import './Columns/styles.css';
+@import './ComponentStatus/styles.css';
+@import './IconLibrary/styles.css';
+@import './LayoutComponents/styles.css';
+@import './Roadmap/styles.css';
+@import './Table/styles.css';
+@import './Text/styles.css';
+@import './Title/styles.css';
diff --git a/packages/canon/docs/spaceProps.ts b/packages/canon/docs/spaceProps.ts
new file mode 100644
index 0000000000..3eb6961bc1
--- /dev/null
+++ b/packages/canon/docs/spaceProps.ts
@@ -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.
+ */
+
+export const spacePropsList = [
+ 'margin',
+ 'marginBottom',
+ 'marginLeft',
+ 'marginRight',
+ 'marginTop',
+ 'marginX',
+ 'marginY',
+ 'padding',
+ 'paddingBottom',
+ 'paddingLeft',
+ 'paddingRight',
+ 'paddingTop',
+ 'paddingX',
+ 'paddingY',
+].reduce(
+ (acc: { [key: string]: { type: string[]; responsive: boolean } }, prop) => {
+ acc[prop] = {
+ type: ['2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl'],
+ responsive: true,
+ };
+ return acc;
+ },
+ {},
+);