diff --git a/.storybook/styles.css b/.storybook/styles.css
index bdba9fb..ae35084 100644
--- a/.storybook/styles.css
+++ b/.storybook/styles.css
@@ -1,7 +1,3 @@
.docblock-argstable-body label {
min-height: auto;
}
-
-.sbdocs p {
- max-width: 30rem;
-}
diff --git a/components/composition/Grid/Grid.css b/components/composition/Grid/Grid.css
index cc97422..58e02e7 100644
--- a/components/composition/Grid/Grid.css
+++ b/components/composition/Grid/Grid.css
@@ -85,6 +85,10 @@ diamond-grid {
--diamond-grid-gap: 0;
}
+ &[gap='xs'] {
+ --diamond-grid-gap: var(--diamond-spacing-xs);
+ }
+
&[gap='sm'] {
--diamond-grid-gap: var(--diamond-spacing-sm);
}
diff --git a/components/content/Icon/Icon.css b/components/content/Icon/Icon.css
new file mode 100644
index 0000000..5325a20
--- /dev/null
+++ b/components/content/Icon/Icon.css
@@ -0,0 +1,42 @@
+diamond-icon {
+ align-items: baseline;
+ color: var(--diamond-theme-icon-color);
+ display: inline-flex;
+
+ &::part(icon) {
+ align-items: center;
+ display: flex;
+ height: 1em;
+ justify-content: center;
+ position: relative;
+ top: var(--diamond-icon-baseline-adjust);
+ width: var(--diamond-icon-size);
+ }
+
+ svg {
+ aspect-ratio: 1 / 1;
+ display: block;
+ flex: 0 0 var(--diamond-icon-size);
+ height: var(--diamond-icon-size);
+ min-width: var(--diamond-icon-size);
+ width: var(--diamond-icon-size);
+ }
+
+ &[variant='circle'] {
+ &::part(icon)::before {
+ background-color: var(--diamond-theme-icon-color);
+ border-radius: 100%;
+ content: '';
+ display: block;
+ height: var(--diamond-icon-size);
+ position: absolute;
+ width: var(--diamond-icon-size);
+ }
+
+ svg {
+ color: var(--diamond-theme-background);
+ transform: scale(0.75);
+ z-index: 1;
+ }
+ }
+}
diff --git a/components/content/Icon/Icon.stories.ts b/components/content/Icon/Icon.stories.ts
new file mode 100644
index 0000000..765b2ee
--- /dev/null
+++ b/components/content/Icon/Icon.stories.ts
@@ -0,0 +1,286 @@
+import { StoryObj } from '@storybook/web-components';
+import { html } from 'lit';
+
+import './Icon';
+
+const description = `
+Wraps an svg icon to provide alignment and sizing.
+
+Icons must have the appropriate fill or stroke set to currentColor.
+
+Icons are hidden from screen readers by default and should be accompanied by text. If an icon is used on its own in a button or link, add a label prop to the component.
+`;
+
+export default {
+ component: 'diamond-icon',
+ parameters: {
+ docs: {
+ description: {
+ component: description,
+ },
+ },
+ },
+ argTypes: {
+ variant: {
+ control: {
+ type: 'radio',
+ },
+ options: ['default', 'circle'],
+ },
+ label: {
+ control: {
+ type: 'text',
+ },
+ description: 'Aria label for the icon, if used without text.',
+ },
+ },
+};
+
+export const Icon: StoryObj = {
+ render: (args) => html`
+
+
+
+ This is some text next to the icon
+ `,
+};
+
+Icon.args = {
+ variant: 'default',
+};
+
+const sizes = ['h1', 'h2', 'h3', 'h4', 'md', 'default', 'sm', 'xs'];
+
+export const Sizes: StoryObj = {
+ render: () => html`
+ ${sizes.map(
+ (size) => html`
+
+
+
+
+ The quick brown fox jumps over the lazy dog.
+
+ `,
+ )}
+ `,
+};
+
+Sizes.parameters = {
+ docs: {
+ description: {
+ story:
+ 'Icons inherit their size from the current text size or can be sized using text size classes.',
+ },
+ },
+};
+
+export const IconInAGrid: StoryObj = {
+ render: () => html`
+
+
+
+
+
+
+
+
Title text
+
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
+ vulputate vel magna id varius. Donec non auctor magna, id auctor
+ lacus. Vestibulum vitae ex id tortor varius fringilla. Cras in ligula
+ vulputate, lacinia metus vitae, suscipit purus. Nunc lacinia porta
+ urna eget accumsan. Pellentesque quis condimentum est. Aliquam leo
+ risus, blandit vel volutpat et, accumsan eget purus.
+
+
+
+ `,
+};
+
+IconInAGrid.parameters = {
+ docs: {
+ description: {
+ story:
+ 'Icons in a grid can be aligned to the text with the baseline alignment.',
+ },
+ },
+};
+
+const themes = ['light', 'medium', 'dark'];
+
+export const IconColors: StoryObj = {
+ render: () => html`
+ ${themes.map(
+ (theme) => html`
+
+
+
+
+ `,
+};
+
+Unstyled.args = {
+ variant: 'unstyled',
+};
+
+const unstyledDescription = `
+Removes the list styles. This is useful for semantic lists that we don't want to see visually.
+
+**Note**: Safari does not recognize ordered or unordered lists as lists in the accessibility tree if they have a list-style value of none, unless the list is nested within the