diff --git a/docs/Spacing.mdx b/docs/Spacing.mdx
new file mode 100644
index 00000000..4df678f4
--- /dev/null
+++ b/docs/Spacing.mdx
@@ -0,0 +1,54 @@
+import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks';
+import * as SpacingStories from './Spacing.stories';
+
+
+
+# Spacing
+
+Spacing tokens are used to maintain consistent layout and whitespace throughout the application. They follow a scale that provides a range of sizes for various layout needs. It follows the [Tailwind CSS spacing](https://tailwindcss.com/docs/customizing-spacing#default-spacing-scale).
+
+
+
+## Usage
+
+Spacing tokens can be used in both CSS and CSS-in-JS contexts. The table below shows the name, size in rem, pixels, and how to access each spacing token in JS and CSS.
+
+| Name | Size | Pixels | JS | CSS |
+| ---- | -------- | ------ | -------------- | -------------------- |
+| 0 | 0px | 0px | `spacing[0]` | `var(--spacing-0)` |
+| px | 1px | 1px | `spacing.px` | `var(--spacing-px)` |
+| 0.5 | 0.125rem | 2px | `spacing[0.5]` | `var(--spacing-0-5)` |
+| 1 | 0.25rem | 4px | `spacing[1]` | `var(--spacing-1)` |
+| 1.5 | 0.375rem | 6px | `spacing[1.5]` | `var(--spacing-1-5)` |
+| 2 | 0.5rem | 8px | `spacing[2]` | `var(--spacing-2)` |
+| 2.5 | 0.625rem | 10px | `spacing[2.5]` | `var(--spacing-2-5)` |
+| 3 | 0.75rem | 12px | `spacing[3]` | `var(--spacing-3)` |
+| 3.5 | 0.875rem | 14px | `spacing[3.5]` | `var(--spacing-3-5)` |
+| 4 | 1rem | 16px | `spacing[4]` | `var(--spacing-4)` |
+| 5 | 1.25rem | 20px | `spacing[5]` | `var(--spacing-5)` |
+| 6 | 1.5rem | 24px | `spacing[6]` | `var(--spacing-6)` |
+| 7 | 1.75rem | 28px | `spacing[7]` | `var(--spacing-7)` |
+| 8 | 2rem | 32px | `spacing[8]` | `var(--spacing-8)` |
+| 9 | 2.25rem | 36px | `spacing[9]` | `var(--spacing-9)` |
+| 10 | 2.5rem | 40px | `spacing[10]` | `var(--spacing-10)` |
+| 11 | 2.75rem | 44px | `spacing[11]` | `var(--spacing-11)` |
+| 12 | 3rem | 48px | `spacing[12]` | `var(--spacing-12)` |
+| 14 | 3.5rem | 56px | `spacing[14]` | `var(--spacing-14)` |
+| 16 | 4rem | 64px | `spacing[16]` | `var(--spacing-16)` |
+| 20 | 5rem | 80px | `spacing[20]` | `var(--spacing-20)` |
+| 24 | 6rem | 96px | `spacing[24]` | `var(--spacing-24)` |
+| 28 | 7rem | 112px | `spacing[28]` | `var(--spacing-28)` |
+| 32 | 8rem | 128px | `spacing[32]` | `var(--spacing-32)` |
+| 36 | 9rem | 144px | `spacing[36]` | `var(--spacing-36)` |
+| 40 | 10rem | 160px | `spacing[40]` | `var(--spacing-40)` |
+| 44 | 11rem | 176px | `spacing[44]` | `var(--spacing-44)` |
+| 48 | 12rem | 192px | `spacing[48]` | `var(--spacing-48)` |
+| 52 | 13rem | 208px | `spacing[52]` | `var(--spacing-52)` |
+| 56 | 14rem | 224px | `spacing[56]` | `var(--spacing-56)` |
+| 60 | 15rem | 240px | `spacing[60]` | `var(--spacing-60)` |
+| 64 | 16rem | 256px | `spacing[64]` | `var(--spacing-64)` |
+| 72 | 18rem | 288px | `spacing[72]` | `var(--spacing-72)` |
+| 80 | 20rem | 320px | `spacing[80]` | `var(--spacing-80)` |
+| 96 | 24rem | 384px | `spacing[96]` | `var(--spacing-96)` |
diff --git a/docs/Spacing.stories.tsx b/docs/Spacing.stories.tsx
new file mode 100644
index 00000000..522a32c9
--- /dev/null
+++ b/docs/Spacing.stories.tsx
@@ -0,0 +1,73 @@
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import { SpacingSwatch, Text } from './components';
+import { spacing } from '../src/js/spacing/spacing';
+import README from './Spacing.mdx';
+
+const meta: Meta = {
+ title: 'Spacing/Spacing',
+ parameters: {
+ docs: {
+ page: README,
+ },
+ },
+};
+
+export default meta;
+
+const spacingData = [
+ { name: '0', size: '0px', pixels: '0px', value: spacing['0'] },
+ { name: 'px', size: '1px', pixels: '1px', value: spacing.px },
+ { name: '0.5', size: '0.125rem', pixels: '2px', value: spacing['0.5'] },
+ { name: '1', size: '0.25rem', pixels: '4px', value: spacing['1'] },
+ { name: '1.5', size: '0.375rem', pixels: '6px', value: spacing['1.5'] },
+ { name: '2', size: '0.5rem', pixels: '8px', value: spacing['2'] },
+ { name: '2.5', size: '0.625rem', pixels: '10px', value: spacing['2.5'] },
+ { name: '3', size: '0.75rem', pixels: '12px', value: spacing['3'] },
+ { name: '3.5', size: '0.875rem', pixels: '14px', value: spacing['3.5'] },
+ { name: '4', size: '1rem', pixels: '16px', value: spacing['4'] },
+ { name: '5', size: '1.25rem', pixels: '20px', value: spacing['5'] },
+ { name: '6', size: '1.5rem', pixels: '24px', value: spacing['6'] },
+ { name: '7', size: '1.75rem', pixels: '28px', value: spacing['7'] },
+ { name: '8', size: '2rem', pixels: '32px', value: spacing['8'] },
+ { name: '9', size: '2.25rem', pixels: '36px', value: spacing['9'] },
+ { name: '10', size: '2.5rem', pixels: '40px', value: spacing['10'] },
+ { name: '11', size: '2.75rem', pixels: '44px', value: spacing['11'] },
+ { name: '12', size: '3rem', pixels: '48px', value: spacing['12'] },
+ { name: '14', size: '3.5rem', pixels: '56px', value: spacing['14'] },
+ { name: '16', size: '4rem', pixels: '64px', value: spacing['16'] },
+ { name: '20', size: '5rem', pixels: '80px', value: spacing['20'] },
+ { name: '24', size: '6rem', pixels: '96px', value: spacing['24'] },
+ { name: '28', size: '7rem', pixels: '112px', value: spacing['28'] },
+ { name: '32', size: '8rem', pixels: '128px', value: spacing['32'] },
+ { name: '36', size: '9rem', pixels: '144px', value: spacing['36'] },
+ { name: '40', size: '10rem', pixels: '160px', value: spacing['40'] },
+ { name: '44', size: '11rem', pixels: '176px', value: spacing['44'] },
+ { name: '48', size: '12rem', pixels: '192px', value: spacing['48'] },
+ { name: '52', size: '13rem', pixels: '208px', value: spacing['52'] },
+ { name: '56', size: '14rem', pixels: '224px', value: spacing['56'] },
+ { name: '60', size: '15rem', pixels: '240px', value: spacing['60'] },
+ { name: '64', size: '16rem', pixels: '256px', value: spacing['64'] },
+ { name: '72', size: '18rem', pixels: '288px', value: spacing['72'] },
+ { name: '80', size: '20rem', pixels: '320px', value: spacing['80'] },
+ { name: '96', size: '24rem', pixels: '384px', value: spacing['96'] },
+];
+
+export const Default: StoryObj = {
+ render: () => (
+
+
+ Name | Size | Pixels
+
+ {spacingData.map((item) => (
+
+ ))}
+
+ ),
+};
diff --git a/docs/components/SpacingSwatch/SpacingSwatch.stories.tsx b/docs/components/SpacingSwatch/SpacingSwatch.stories.tsx
new file mode 100644
index 00000000..04f54ecc
--- /dev/null
+++ b/docs/components/SpacingSwatch/SpacingSwatch.stories.tsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import { SpacingSwatch } from './SpacingSwatch';
+
+const meta: Meta = {
+ title: 'Documentation Components/SpacingSwatch',
+ component: SpacingSwatch,
+ argTypes: {
+ name: { control: 'text' },
+ size: { control: 'text' },
+ pixels: { control: 'text' },
+ value: { control: 'text' },
+ },
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ name: '4',
+ size: '1rem',
+ pixels: '16px',
+ value: '1rem',
+ },
+};
diff --git a/docs/components/SpacingSwatch/SpacingSwatch.tsx b/docs/components/SpacingSwatch/SpacingSwatch.tsx
new file mode 100644
index 00000000..78f00b53
--- /dev/null
+++ b/docs/components/SpacingSwatch/SpacingSwatch.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import { Text } from '../Text';
+
+interface SpacingSwatchProps {
+ name: string;
+ size: string;
+ pixels: string;
+ value: string;
+}
+
+export const SpacingSwatch: React.FC = ({
+ name,
+ size,
+ pixels,
+ value,
+}) => (
+
+
+ {name} |{' '}
+ {size} | {pixels}
+
+
+
+);
diff --git a/docs/components/SpacingSwatch/index.tsx b/docs/components/SpacingSwatch/index.tsx
new file mode 100644
index 00000000..60b4c942
--- /dev/null
+++ b/docs/components/SpacingSwatch/index.tsx
@@ -0,0 +1 @@
+export { SpacingSwatch } from './SpacingSwatch';
diff --git a/docs/components/index.tsx b/docs/components/index.tsx
index 9868799e..bf055aa2 100644
--- a/docs/components/index.tsx
+++ b/docs/components/index.tsx
@@ -1,3 +1,4 @@
export { ColorSwatch } from './ColorSwatch';
export { ColorSwatchGroup } from './ColorSwatchGroup';
+export { SpacingSwatch } from './SpacingSwatch';
export { Text } from './Text';
diff --git a/src/css/spacing.css b/src/css/spacing.css
new file mode 100644
index 00000000..8ed01335
--- /dev/null
+++ b/src/css/spacing.css
@@ -0,0 +1,42 @@
+/*
+ * This spacing system follows Tailwind CSS default spacing scale.
+ * For more information, see: https://tailwindcss.com/docs/customizing-spacing#default-spacing-scale
+ */
+
+:root {
+ --spacing-0: 0px;
+ --spacing-px: 1px;
+ --spacing-0-5: 0.125rem;
+ --spacing-1: 0.25rem;
+ --spacing-1-5: 0.375rem;
+ --spacing-2: 0.5rem;
+ --spacing-2-5: 0.625rem;
+ --spacing-3: 0.75rem;
+ --spacing-3-5: 0.875rem;
+ --spacing-4: 1rem;
+ --spacing-5: 1.25rem;
+ --spacing-6: 1.5rem;
+ --spacing-7: 1.75rem;
+ --spacing-8: 2rem;
+ --spacing-9: 2.25rem;
+ --spacing-10: 2.5rem;
+ --spacing-11: 2.75rem;
+ --spacing-12: 3rem;
+ --spacing-14: 3.5rem;
+ --spacing-16: 4rem;
+ --spacing-20: 5rem;
+ --spacing-24: 6rem;
+ --spacing-28: 7rem;
+ --spacing-32: 8rem;
+ --spacing-36: 9rem;
+ --spacing-40: 10rem;
+ --spacing-44: 11rem;
+ --spacing-48: 12rem;
+ --spacing-52: 13rem;
+ --spacing-56: 14rem;
+ --spacing-60: 15rem;
+ --spacing-64: 16rem;
+ --spacing-72: 18rem;
+ --spacing-80: 20rem;
+ --spacing-96: 24rem;
+}
diff --git a/src/figma/spacing.json b/src/figma/spacing.json
new file mode 100644
index 00000000..f19aca85
--- /dev/null
+++ b/src/figma/spacing.json
@@ -0,0 +1,144 @@
+{
+ "spacing": {
+ "0": {
+ "value": "0px",
+ "type": "spacing"
+ },
+ "px": {
+ "value": "1px",
+ "type": "spacing"
+ },
+ "0.5": {
+ "value": "2px",
+ "type": "spacing"
+ },
+ "1": {
+ "value": "4px",
+ "type": "spacing"
+ },
+ "1.5": {
+ "value": "6px",
+ "type": "spacing"
+ },
+ "2": {
+ "value": "8px",
+ "type": "spacing"
+ },
+ "2.5": {
+ "value": "10px",
+ "type": "spacing"
+ },
+ "3": {
+ "value": "12px",
+ "type": "spacing"
+ },
+ "3.5": {
+ "value": "14px",
+ "type": "spacing"
+ },
+ "4": {
+ "value": "16px",
+ "type": "spacing"
+ },
+ "5": {
+ "value": "20px",
+ "type": "spacing"
+ },
+ "6": {
+ "value": "24px",
+ "type": "spacing"
+ },
+ "7": {
+ "value": "28px",
+ "type": "spacing"
+ },
+ "8": {
+ "value": "32px",
+ "type": "spacing"
+ },
+ "9": {
+ "value": "36px",
+ "type": "spacing"
+ },
+ "10": {
+ "value": "40px",
+ "type": "spacing"
+ },
+ "11": {
+ "value": "44px",
+ "type": "spacing"
+ },
+ "12": {
+ "value": "48px",
+ "type": "spacing"
+ },
+ "14": {
+ "value": "56px",
+ "type": "spacing"
+ },
+ "16": {
+ "value": "64px",
+ "type": "spacing"
+ },
+ "20": {
+ "value": "80px",
+ "type": "spacing"
+ },
+ "24": {
+ "value": "96px",
+ "type": "spacing"
+ },
+ "28": {
+ "value": "112px",
+ "type": "spacing"
+ },
+ "32": {
+ "value": "128px",
+ "type": "spacing"
+ },
+ "36": {
+ "value": "144px",
+ "type": "spacing"
+ },
+ "40": {
+ "value": "160px",
+ "type": "spacing"
+ },
+ "44": {
+ "value": "176px",
+ "type": "spacing"
+ },
+ "48": {
+ "value": "192px",
+ "type": "spacing"
+ },
+ "52": {
+ "value": "208px",
+ "type": "spacing"
+ },
+ "56": {
+ "value": "224px",
+ "type": "spacing"
+ },
+ "60": {
+ "value": "240px",
+ "type": "spacing"
+ },
+ "64": {
+ "value": "256px",
+ "type": "spacing"
+ },
+ "72": {
+ "value": "288px",
+ "type": "spacing"
+ },
+ "80": {
+ "value": "320px",
+ "type": "spacing"
+ },
+ "96": {
+ "value": "384px",
+ "type": "spacing"
+ }
+ }
+}
diff --git a/src/js/spacing/spacing.test.ts b/src/js/spacing/spacing.test.ts
new file mode 100644
index 00000000..2a63bed9
--- /dev/null
+++ b/src/js/spacing/spacing.test.ts
@@ -0,0 +1,98 @@
+import { spacing } from './spacing';
+
+/**
+ * Get a spacing value by key.
+ * @param key - The spacing key.
+ * @returns The spacing value or undefined if not found.
+ */
+function getSpacing(key: string): string | undefined {
+ return spacing[key];
+}
+
+describe('spacing tokens', () => {
+ it('spacing object contains all expected keys', () => {
+ const expectedKeys = [
+ 'px',
+ '0',
+ '0.5',
+ '1',
+ '1.5',
+ '2',
+ '2.5',
+ '3',
+ '3.5',
+ '4',
+ '5',
+ '6',
+ '7',
+ '8',
+ '9',
+ '10',
+ '11',
+ '12',
+ '14',
+ '16',
+ '20',
+ '24',
+ '28',
+ '32',
+ '36',
+ '40',
+ '44',
+ '48',
+ '52',
+ '56',
+ '60',
+ '64',
+ '72',
+ '80',
+ '96',
+ ];
+
+ expectedKeys.forEach((key) => {
+ expect(spacing[key as keyof typeof spacing]).toBeDefined();
+ });
+ });
+
+ it('spacing values are correct', () => {
+ expect(spacing['0']).toBe('0px');
+ expect(spacing.px).toBe('1px');
+ expect(spacing['0.5']).toBe('0.125rem');
+ expect(spacing['1']).toBe('0.25rem');
+ expect(spacing['1.5']).toBe('0.375rem');
+ expect(spacing['2']).toBe('0.5rem');
+ expect(spacing['4']).toBe('1rem');
+ expect(spacing['16']).toBe('4rem');
+ expect(spacing['96']).toBe('24rem');
+ });
+
+ it('getSpacing function returns correct values', () => {
+ expect(getSpacing('0')).toBe('0px');
+ expect(getSpacing('px')).toBe('1px');
+ expect(getSpacing('0.5')).toBe('0.125rem');
+ expect(getSpacing('1')).toBe('0.25rem');
+ expect(getSpacing('4')).toBe('1rem');
+ expect(getSpacing('96')).toBe('24rem');
+ });
+
+ it('getSpacing function returns undefined for non-existent keys', () => {
+ expect(getSpacing('nonexistent')).toBeUndefined();
+ expect(getSpacing('100')).toBeUndefined();
+ });
+
+ it('spacing object has the correct number of entries', () => {
+ expect(Object.keys(spacing)).toHaveLength(35);
+ });
+
+ it('all spacing values are strings', () => {
+ Object.values(spacing).forEach((value) => {
+ expect(typeof value).toBe('string');
+ });
+ });
+
+ it('all spacing values end with either px or rem', () => {
+ Object.values(spacing).forEach((value) => {
+ expect(value.endsWith('px') || value.endsWith('rem')).toBe(true);
+ });
+ });
+});
diff --git a/src/js/spacing/spacing.ts b/src/js/spacing/spacing.ts
new file mode 100644
index 00000000..9c63611a
--- /dev/null
+++ b/src/js/spacing/spacing.ts
@@ -0,0 +1,41 @@
+/**
+ * This spacing system follows Tailwind CSS default spacing scale.
+ * For more information, see: https://tailwindcss.com/docs/customizing-spacing#default-spacing-scale
+ */
+export const spacing: { [key: string]: string } = {
+ px: '1px',
+ 0: '0px',
+ 0.5: '0.125rem',
+ 1: '0.25rem',
+ 1.5: '0.375rem',
+ 2: '0.5rem',
+ 2.5: '0.625rem',
+ 3: '0.75rem',
+ 3.5: '0.875rem',
+ 4: '1rem',
+ 5: '1.25rem',
+ 6: '1.5rem',
+ 7: '1.75rem',
+ 8: '2rem',
+ 9: '2.25rem',
+ 10: '2.5rem',
+ 11: '2.75rem',
+ 12: '3rem',
+ 14: '3.5rem',
+ 16: '4rem',
+ 20: '5rem',
+ 24: '6rem',
+ 28: '7rem',
+ 32: '8rem',
+ 36: '9rem',
+ 40: '10rem',
+ 44: '11rem',
+ 48: '12rem',
+ 52: '13rem',
+ 56: '14rem',
+ 60: '15rem',
+ 64: '16rem',
+ 72: '18rem',
+ 80: '20rem',
+ 96: '24rem',
+};