Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
14 changes: 12 additions & 2 deletions apps/shade/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,18 @@ const preview: Preview = {
storySort: {
method: 'alphabetical',
order: [
'Introduction', 'Principles', 'Architecture', 'Tokens', 'Contributing',
'Components', 'Layout', 'Experimental'],
'Primitives',
'Components',
'Layout',
'Features',
'Experimental',
'Introduction',
'Principles',
'Architecture',
'Tokens',
'Contributing',
'*'
],
},
},
docs: {
Expand Down
37 changes: 37 additions & 0 deletions apps/shade/src/components/primitives/box.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type {Meta, StoryObj} from '@storybook/react-vite';
import {Box} from './box';

const meta = {
title: 'Primitives / Box',
component: Box,
tags: ['autodocs'],
parameters: {
docs: {
description: {
component: 'Framing primitive for padding and radius without implicit layout behavior.'
}
}
}
} satisfies Meta<typeof Box>;

export default meta;
type Story = StoryObj<typeof Box>;

export const Default: Story = {
args: {
padding: 'lg',
radius: 'lg',
className: 'border border-border-default bg-surface-panel',
children: 'Framed content'
}
};

export const AxisPadding: Story = {
args: {
paddingX: 'xl',
paddingY: 'sm',
radius: 'md',
className: 'border border-border-default bg-surface-panel',
children: 'Independent horizontal and vertical spacing'
}
};
45 changes: 45 additions & 0 deletions apps/shade/src/components/primitives/box.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {cn} from '@/lib/utils';
import {PADDING_CLASSES, PADDING_X_CLASSES, PADDING_Y_CLASSES, SpaceStep} from './types';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use the @ alias for internal primitive imports.

Line 2 should use the project alias instead of a relative internal import.

Suggested change
-import {PADDING_CLASSES, PADDING_X_CLASSES, PADDING_Y_CLASSES, SpaceStep} from './types';
+import {PADDING_CLASSES, PADDING_X_CLASSES, PADDING_Y_CLASSES, SpaceStep} from '@/components/primitives/types';

As per coding guidelines: apps/shade/src/**/*.{ts,tsx,js}: Use the @ alias for internal imports (e.g. @/lib/utils).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import {PADDING_CLASSES, PADDING_X_CLASSES, PADDING_Y_CLASSES, SpaceStep} from './types';
import {PADDING_CLASSES, PADDING_X_CLASSES, PADDING_Y_CLASSES, SpaceStep} from '@/components/primitives/types';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/shade/src/components/primitives/box.tsx` at line 2, Replace the relative
import in box.tsx with the project alias: change the import of PADDING_CLASSES,
PADDING_X_CLASSES, PADDING_Y_CLASSES, SpaceStep from './types' to the @ alias
pointing at the same module (e.g. import {PADDING_CLASSES, PADDING_X_CLASSES,
PADDING_Y_CLASSES, SpaceStep} from '@/components/primitives/types'), so the file
uses the mandated "@/..." internal import style instead of a relative path.

import React from 'react';

type BoxRadius = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';

const RADIUS_CLASSES: Record<BoxRadius, string> = {
none: 'rounded-none',
sm: 'rounded-sm',
md: 'rounded-md',
lg: 'rounded-lg',
xl: 'rounded-xl',
full: 'rounded-full'
};

export interface BoxProps extends React.HTMLAttributes<HTMLDivElement> {
padding?: SpaceStep;
paddingX?: SpaceStep;
paddingY?: SpaceStep;
radius?: BoxRadius;
}

function Box({
className,
padding,
paddingX,
paddingY,
radius,
...props
}: BoxProps) {

Check warning on line 30 in apps/shade/src/components/primitives/box.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Mark the props of the component as read-only.

See more on https://sonarcloud.io/project/issues?id=TryGhost_Ghost&issues=AZ1jUMnq6XBGhgATRziR&open=AZ1jUMnq6XBGhgATRziR&pullRequest=27180
return (
<div
className={cn(
padding && PADDING_CLASSES[padding],
paddingX && PADDING_X_CLASSES[paddingX],
paddingY && PADDING_Y_CLASSES[paddingY],
radius && RADIUS_CLASSES[radius],
className
)}
{...props}
/>
);
}

export {Box};
53 changes: 53 additions & 0 deletions apps/shade/src/components/primitives/container.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type {Meta, StoryObj} from '@storybook/react-vite';
import {Container} from './container';

const meta = {
title: 'Primitives / Container',
component: Container,
tags: ['autodocs'],
parameters: {
layout: 'fullscreen',
docs: {
description: {
component: 'Width-constrained primitive for page and region containers.'
}
}
}
} satisfies Meta<typeof Container>;

export default meta;
type Story = StoryObj<typeof Container>;

export const PageWidth: Story = {
args: {
size: 'page',
paddingX: 'lg',
children: (
<div className="rounded-md border border-border-default bg-surface-panel p-4">
Page-width container content
</div>
)
},
render: args => (
<div className="w-full bg-accent py-6">
<Container {...args} />
</div>
)
};

export const ProseWidth: Story = {
args: {
size: 'prose',
centered: true,
children: (
<div className="rounded-md border border-border-default bg-surface-panel p-4 text-sm">
A narrower, readable content width intended for copy-heavy regions.
</div>
)
},
render: args => (
<div className="w-full bg-accent py-6">
<Container {...args} />
</div>
)
};
69 changes: 69 additions & 0 deletions apps/shade/src/components/primitives/container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {cn} from '@/lib/utils';
import {PADDING_X_CLASSES, SpaceStep} from './types';
import React from 'react';

export type ContainerSize =
| 'xs'
| 'sm'
| 'md'
| 'lg'
| 'xl'
| '2xl'
| '3xl'
| '4xl'
| '5xl'
| '6xl'
| '7xl'
| '8xl'
| '9xl'
| 'prose'
| 'page'
| 'page-with-sidebar';

const MAX_WIDTH_CLASSES: Record<ContainerSize, string> = {
xs: 'max-w-xs',
sm: 'max-w-sm',
md: 'max-w-md',
lg: 'max-w-lg',
xl: 'max-w-xl',
'2xl': 'max-w-2xl',
'3xl': 'max-w-3xl',
'4xl': 'max-w-4xl',
'5xl': 'max-w-5xl',
'6xl': 'max-w-6xl',
'7xl': 'max-w-7xl',
'8xl': 'max-w-8xl',
'9xl': 'max-w-9xl',
prose: 'max-w-prose',
page: 'max-w-page',
'page-with-sidebar': 'max-w-pageminsidebar'
};

export interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {
size?: ContainerSize;
centered?: boolean;
paddingX?: SpaceStep;
}

function Container({
className,
size = 'page',
centered = true,
paddingX,
...props
}: ContainerProps) {

Check warning on line 54 in apps/shade/src/components/primitives/container.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Mark the props of the component as read-only.

See more on https://sonarcloud.io/project/issues?id=TryGhost_Ghost&issues=AZ1jUMnY6XBGhgATRziP&open=AZ1jUMnY6XBGhgATRziP&pullRequest=27180
return (
<div
className={cn(
'w-full',
MAX_WIDTH_CLASSES[size],
centered && 'mx-auto',
paddingX && PADDING_X_CLASSES[paddingX],
className
)}
{...props}
/>
);
}

export {Container};
56 changes: 56 additions & 0 deletions apps/shade/src/components/primitives/grid.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type {Meta, StoryObj} from '@storybook/react-vite';
import {Grid} from './grid';

const meta = {
title: 'Primitives / Grid',
component: Grid,
tags: ['autodocs'],
parameters: {
docs: {
description: {
component: 'Two-dimensional layout primitive for explicit columns and spacing.'
}
}
}
} satisfies Meta<typeof Grid>;

export default meta;
type Story = StoryObj<typeof Grid>;

const renderCell = (label: string) => (
<div className="rounded-md border border-border-default bg-surface-panel p-3 text-sm">
{label}
</div>
);

export const TwoColumns: Story = {
args: {
columns: 2,
gap: 'md',
children: (
<>
{renderCell('Card 1')}
{renderCell('Card 2')}
{renderCell('Card 3')}
{renderCell('Card 4')}
</>
)
}
};

export const ThreeColumns: Story = {
args: {
columns: 3,
gap: 'lg',
children: (
<>
{renderCell('A')}
{renderCell('B')}
{renderCell('C')}
{renderCell('D')}
{renderCell('E')}
{renderCell('F')}
</>
)
}
};
54 changes: 54 additions & 0 deletions apps/shade/src/components/primitives/grid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {cn} from '@/lib/utils';
import {
ALIGN_ITEMS_CLASSES,
GAP_CLASSES,
JUSTIFY_CONTENT_CLASSES,
Align,
Justify,
SpaceStep
} from './types';
import React from 'react';

type GridColumns = 1 | 2 | 3 | 4 | 5 | 6 | 12;

const GRID_COLUMNS_CLASSES: Record<GridColumns, string> = {
1: 'grid-cols-1',
2: 'grid-cols-2',
3: 'grid-cols-3',
4: 'grid-cols-4',
5: 'grid-cols-5',
6: 'grid-cols-6',
12: 'grid-cols-12'
};

export interface GridProps extends React.HTMLAttributes<HTMLDivElement> {
columns?: GridColumns;
gap?: SpaceStep;
align?: Align;
justify?: Justify;
}

function Grid({
className,
columns = 1,
gap = 'md',
align = 'stretch',
justify = 'start',
...props
}: GridProps) {

Check warning on line 38 in apps/shade/src/components/primitives/grid.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Mark the props of the component as read-only.

See more on https://sonarcloud.io/project/issues?id=TryGhost_Ghost&issues=AZ1jUMn06XBGhgATRziS&open=AZ1jUMn06XBGhgATRziS&pullRequest=27180
return (
<div
className={cn(
'grid',
GRID_COLUMNS_CLASSES[columns],
GAP_CLASSES[gap],
ALIGN_ITEMS_CLASSES[align],
JUSTIFY_CONTENT_CLASSES[justify],
className
)}
{...props}
/>
);
}

export {Grid};
15 changes: 15 additions & 0 deletions apps/shade/src/components/primitives/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export {Box} from './box';
export {Container} from './container';
export type {ContainerSize} from './container';
export {Grid} from './grid';
export {Inline} from './inline';
export {Stack} from './stack';
export {Text} from './text';
export type {
TextElement,
TextLeading,
TextSize,
TextTone,
TextWeight
} from './text';
export type {Align, Justify, SpaceStep} from './types';
Loading
Loading