Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Heading and Text components #510

Merged
merged 22 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/react-components/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
RadioGroupPage,
SelectPage,
TagGroupPage,
TextPage,
TextAreaPage,
TextFieldPage,
SwitchPage,
Expand Down Expand Up @@ -169,6 +170,7 @@ function App() {
<TooltipPage />
<TextAreaPage />
<TextFieldPage />
<TextPage />
</main>
<Footer />
<Footer
Expand Down
44 changes: 44 additions & 0 deletions packages/react-components/src/components/Heading/Heading.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* Headings */
h1.bcds-react-aria-Heading {
font: var(--typography-bold-h1);
}

h2.bcds-react-aria-Heading {
font: var(--typography-bold-h2);
}

h3.bcds-react-aria-Heading {
font: var(--typography-bold-h3);
}

h4.bcds-react-aria-Heading {
font: var(--typography-bold-h4);
}

h5.bcds-react-aria-Heading {
font: var(--typography-bold-h5);
}

h6.bcds-react-aria-Heading {
font: var(--typography-bold-h6);
}

/* Text colour */
.bcds-react-aria-Heading.primary {
color: var(--typography-color-primary);
}
.bcds-react-aria-Heading.primaryInvert {
color: var(--typography-color-primary-invert);
}
.bcds-react-aria-Heading.secondary {
color: var(--typography-color-secondary);
}
.bcds-react-aria-Heading.secondaryInvert {
color: var(--typography-color-secondary-invert);
}
.bcds-react-aria-Heading.disabled {
color: var(--typography-color-disabled);
}
.bcds-react-aria-Heading.danger {
color: var(--typography-color-danger);
}
32 changes: 32 additions & 0 deletions packages/react-components/src/components/Heading/Heading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
Heading as ReactAriaHeading,
HeadingProps as ReactAriaHeadingProps,
} from "react-aria-components";

import "./Heading.css";

export interface HeadingProps extends ReactAriaHeadingProps {
/* Sets text color, defaults to primary */
color?:
| "primary"
| "primaryInvert"
| "secondary"
| "secondaryInvert"
| "disabled"
| "danger";
/* If true, renders component without CSS class */
isUnstyled?: boolean;
}

export default function Heading({
color = "primary",
isUnstyled = false,
...props
}: HeadingProps) {
return (
<ReactAriaHeading
className={isUnstyled ? undefined : `bcds-react-aria-Heading ${color}`}
{...props}
/>
);
}
2 changes: 2 additions & 0 deletions packages/react-components/src/components/Heading/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from "./Heading";
export type { HeadingProps } from "./Heading";
64 changes: 64 additions & 0 deletions packages/react-components/src/components/Text/Text.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* Medium size (default) */
.bcds-react-aria-Text.medium {
font: var(--typography-regular-body);
}

.bcds-react-aria-Text.medium b,
.bcds-react-aria-Text.medium strong {
font: var(--typography-bold-body);
}

.bcds-react-aria-Text.medium i,
.bcds-react-aria-Text.medium em {
font: var(--typography-italic-body);
}

/* Small size */
.bcds-react-aria-Text.small {
font: var(--typography-regular-small-body);
}

.bcds-react-aria-Text.small b,
.bcds-react-aria-Text.small strong {
font: var(--typography-bold-small-body);
}

.bcds-react-aria-Text.small i,
.bcds-react-aria-Text.small em {
font: var(--typography-italic-small-body);
}

/* Large size */
.bcds-react-aria-Text.large {
font: var(--typography-regular-large-body);
}

.bcds-react-aria-Text.large b,
.bcds-react-aria-Text.large strong {
font: var(--typography-bold-large-body);
}

.bcds-react-aria-Text.large i,
.bcds-react-aria-Text.large em {
font: var(--typography-italic-large-body);
}

/* Text color */
.bcds-react-aria-Text.primary {
color: var(--typography-color-primary);
}
.bcds-react-aria-Text.primaryInvert {
color: var(--typography-color-primary-invert);
}
.bcds-react-aria-Text.secondary {
color: var(--typography-color-secondary);
}
.bcds-react-aria-Text.secondaryInvert {
color: var(--typography-color-secondary-invert);
}
.bcds-react-aria-Text.disabled {
color: var(--typography-color-disabled);
}
.bcds-react-aria-Text.danger {
color: var(--typography-color-danger);
}
41 changes: 41 additions & 0 deletions packages/react-components/src/components/Text/Text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
Text as ReactAriaText,
TextProps as ReactAriaTextProps,
} from "react-aria-components";

import "./Text.css";

export interface TextProps extends ReactAriaTextProps {
/* Sets text size, defaults to medium */
size?: "small" | "medium" | "large";
/* Sets text color, defaults to primary */
color?:
| "primary"
| "primaryInvert"
| "secondary"
| "secondaryInvert"
| "disabled"
| "danger";
/* If true, renders component without CSS class */
isUnstyled?: boolean;
}

export default function Text({
elementType = "span",
size = "medium",
color = "primary",
isUnstyled = false,
...props
}: TextProps) {
return (
<ReactAriaText
elementType={elementType}
className={
isUnstyled ? undefined : `bcds-react-aria-Text ${size} ${color}`
}
{...props}
>
{props.children}
</ReactAriaText>
);
}
2 changes: 2 additions & 0 deletions packages/react-components/src/components/Text/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from "./Text";
export type { TextProps } from "./Text";
2 changes: 2 additions & 0 deletions packages/react-components/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export { default as Dialog, DialogTrigger } from "./Dialog";
export { default as Footer, FooterLinks } from "./Footer";
export { default as Form } from "./Form";
export { default as Header } from "./Header";
export { default as Heading } from "./Heading";
export { default as InlineAlert } from "./InlineAlert";
export { default as Modal } from "./Modal";
export { default as Radio } from "./Radio";
Expand All @@ -34,6 +35,7 @@ export { default as SvgTooltipArrowUp } from "./Icons/SvgTooltipArrowUp";
export { default as Tag } from "./Tag";
export { default as TagGroup } from "./TagGroup";
export { default as TagList } from "./TagList";
export { default as Text } from "./Text";
export { default as TextArea } from "./TextArea";
export { default as TextField } from "./TextField";
export { default as Switch } from "./Switch";
Expand Down
55 changes: 55 additions & 0 deletions packages/react-components/src/pages/TextPage/TextPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Heading, Text } from "@/components";

export default function TextPage() {
return (
<>
<Heading level={2}>Headings and text</Heading>
<Text>
The Heading and Text components provide an easy way to populate sections
of content. They implement the B.C. Design System's typescale.
</Text>
<Heading level={3}>Headings</Heading>
<Text>
The Heading component supports standard HTML heading levels (H1 to H6).
</Text>
<Heading level={3}>Text size</Heading>
<Text>The text component supports 3 different sizes: </Text>
<ul>
<li>
<Text size="large">Large</Text>
</li>
<li>
<Text size="medium">Medium (default)</Text>
</li>
<li>
<Text size="small">Small</Text>
</li>
</ul>
<Heading level={4}>Text styling</Heading>
<Text>
The text component also supports standard text styling, like <b>bold</b>{" "}
and <i>italic</i>.
</Text>
<Heading level={4}>Text colour</Heading>
<Text>You can modify the colour of text via prop:</Text>
<ul>
<li>
<Text color="primary">Primary (default)</Text>
</li>
<li>
<Text color="secondary">Secondary</Text>
</li>
<li>
<Text color="disabled">Disabled</Text>
</li>
<li>
<Text color="danger">Danger</Text>
</li>
</ul>
<Text>
Inverted versions of the primary and secondary colours for use on dark
backgrounds are also supported.
</Text>
</>
);
}
3 changes: 3 additions & 0 deletions packages/react-components/src/pages/TextPage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import TextPage from "./TextPage";

export default TextPage;
2 changes: 2 additions & 0 deletions packages/react-components/src/pages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ModalDialogPage from "./ModalDialog";
import RadioGroupPage from "./RadioGroup";
import SelectPage from "./Select";
import TagGroupPage from "./TagGroup";
import TextPage from "./TextPage";
import TextAreaPage from "./TextArea";
import TextFieldPage from "./TextField";
import SwitchPage from "./Switch";
Expand All @@ -26,6 +27,7 @@ export {
RadioGroupPage,
SelectPage,
TagGroupPage,
TextPage,
TextAreaPage,
TextFieldPage,
SwitchPage,
Expand Down
61 changes: 61 additions & 0 deletions packages/react-components/src/stories/Heading.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{/* Heading.mdx */}

import {
Canvas,
Controls,
Meta,
Primary,
Source,
Story,
Subtitle,
} from "@storybook/blocks";

import * as HeadingStories from "./Heading.stories";

<Meta of={HeadingStories} />

# Headings

<Subtitle>Utility content for creating section headings</Subtitle>

<Source
code={`import { Heading } from "@bcgov/design-system-react-components";`}
language="typescript"
/>

## Usage and resources

Heading is a utility component that creates a text heading for a section of content. It renders a standard heading element (`<h1>` to `<h6>`), styled to align with the [B.C. Design System typescale](https://www2.gov.bc.ca/gov/content?id=72C2CD6E05494C84B9A072DD9C6A5342).

## Controls

<Canvas of={HeadingStories.HeadingTemplate} />
<Controls of={HeadingStories.HeadingTemplate} />

## Configuration

Heading text is populated via the `children` slot.

### Styling headings

You can override the default styling of a heading by either:

- Passing a `className` to apply your own CSS class
- Setting the `isUnstyled` prop to render a heading without any additional CSS, allowing it to inherit its styles from its parent element

<Canvas of={HeadingStories.UnstyledHeading} />

Use the `color` prop to set the text colour, from the options defined in the design system colour palette:

<Canvas of={HeadingStories.PrimaryInvert} />

### Heading level

Use the `level` prop to set the heading level. `level` expects a number from 1 to 6:

<Canvas of={HeadingStories.Heading1} />
<Canvas of={HeadingStories.Heading2} />
<Canvas of={HeadingStories.Heading3} />
<Canvas of={HeadingStories.Heading4} />
<Canvas of={HeadingStories.Heading5} />
<Canvas of={HeadingStories.Heading6} />
Loading