Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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: 14 additions & 0 deletions .gemini/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"mcpServers": {
"figma": {
"type": "http",
"url": "https://mcp.figma.com/mcp"
},
"sem": {
"args": [
"mcp"
],
"command": "sem"
}
}
}
15 changes: 15 additions & 0 deletions packages/react/ds-global/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,20 @@
/* For debug */
--baseline-grid-color: orange;
/* Temporary, waiting for a better understanding */

--mockup-stack-background: #edb3b340;
--mockup-stack-navigation: #c9595950;
--mockup-stack-content: #edb3b360;
/* --mockup-stack-content:#FFFFFF80; */
--baseline-shift: 1px;
--min-column-width: 65px;

--gap: 1rem;
}

html,
body,
#root,
#storybook-root {
height: 100%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import { renderToString } from "react-dom/server";
import { describe, expect, it } from "vitest";
import { ApplicationLayout } from "./ApplicationLayout.js";

describe("ApplicationLayout SSR", () => {
it("renders without hydration errors", () => {
const html = renderToString(
<ApplicationLayout>Test content</ApplicationLayout>,
);
expect(html).toContain("Test content");
expect(html).toContain("application-layout");
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import type { Meta, StoryObj } from "@storybook/react-vite";
import * as testComponents from "../../storybook/testComponents.js";
import { ViewContentLayout } from "../ViewContentLayout/ViewContentLayout.js";
import { ViewLayout } from "../ViewLayout/ViewLayout.js";
import { ApplicationLayout } from "./ApplicationLayout.js";

const meta: Meta<typeof ApplicationLayout> = {
title: "Layouts/ApplicationLayout",
component: ApplicationLayout,
tags: ["autodocs"],
parameters: {
layout: "fullscreen",
},
};

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

export const Default: Story = {
args: {
children: [
<testComponents.Sidebar key="sidebar" />,
<ViewLayout key="view">
<ViewContentLayout key="content">
{[...Array(10)].map((_, index) => (
// biome-ignore lint/suspicious/noArrayIndexKey: only for testing purposes
<testComponents.Card key={`test_${index}`} />
))}
</ViewContentLayout>
<testComponents.Sidebar key="sidebar" />,
</ViewLayout>,
],
},
};

export const WithCustomClass: Story = {
args: {
children: "Custom styled",
className: "custom-class",
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { ApplicationLayout } from "./ApplicationLayout.js";

describe("ApplicationLayout", () => {
it("renders children", () => {
render(<ApplicationLayout>Test content</ApplicationLayout>);
expect(screen.getByText("Test content")).toBeInTheDocument();
});

it("applies custom className", () => {
render(
<ApplicationLayout className="custom-class">Content</ApplicationLayout>,
);
const element = screen.getByText("Content");
expect(element).toHaveClass("application-layout");
expect(element).toHaveClass("custom-class");
});

it("passes through additional props", () => {
render(
<ApplicationLayout data-testid="test-component">
Content
</ApplicationLayout>,
);
expect(screen.getByTestId("test-component")).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import type React from "react";
import type { ApplicationLayoutProps } from "./types.js";
import "./styles.css";

/**
* ApplicationLayout component
*/
export const ApplicationLayout = ({
className,
children,
...props
}: ApplicationLayoutProps): React.ReactElement => {
return (
<div
className={`ds application-layout${className ? ` ${className}` : ""}`}
{...props}
>
{children}
</div>
);
};
5 changes: 5 additions & 0 deletions packages/react/ds-global/src/lib/ApplicationLayout/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

export { ApplicationLayout } from "./ApplicationLayout.js";
export type { ApplicationLayoutProps } from "./types.js";
11 changes: 11 additions & 0 deletions packages/react/ds-global/src/lib/ApplicationLayout/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* Generated by component/react v0.1.0 */
/* Generated by @canonical/summon:component-react v0.1.0 */

.ds.application-layout {
/* Component styles */
background: var(--mockup-stack-background); /* For demo purposes only */
height: 100%;
display: grid;
gap: var(--gap);
grid-template-columns: min-content 1fr;
}
9 changes: 9 additions & 0 deletions packages/react/ds-global/src/lib/ApplicationLayout/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import type { HTMLAttributes, ReactNode } from "react";

export interface ApplicationLayoutProps extends HTMLAttributes<HTMLDivElement> {
/** Content to render inside the component */
children?: ReactNode;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import { renderToString } from "react-dom/server";
import { describe, expect, it } from "vitest";
import { ViewContentLayout } from "./ViewContentLayout.js";

describe("ViewContentLayout SSR", () => {
it("renders without hydration errors", () => {
const html = renderToString(
<ViewContentLayout>Test content</ViewContentLayout>,
);
expect(html).toContain("Test content");
expect(html).toContain("view-content-layout");
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import type { Meta, StoryObj } from "@storybook/react-vite";
import { ViewContentLayout } from "./ViewContentLayout.js";

const meta: Meta<typeof ViewContentLayout> = {
title: "Layouts/ViewContentLayout",
component: ViewContentLayout,
tags: ["autodocs"],
parameters: {
layout: "fullscreen",
},
};

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

const ExampleCard = () => (
<div
style={{
border: "1px solid #ccc",
minHeight: "300px",
backgroundColor: "#f9f9f9",
}}
>
This is an example card inside the ViewLayout.
</div>
);

export const Default: Story = {
args: {
// children: "Hello, ViewContentLayout!",
// biome-ignore lint/suspicious/noArrayIndexKey: only for testing purposes
children: [...Array(3)].map((_, index) => <ExampleCard key={index} />),
},
// decorators: [decorators.threeColumnGrid()],
};

export const Fluid: Story = {
args: {
// biome-ignore lint/suspicious/noArrayIndexKey: only for testing purposes
children: [...Array(8)].map((_, index) => <ExampleCard key={index} />),
},
// decorators: [decorators.fluidGrid()],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { ViewContentLayout } from "./ViewContentLayout.js";

describe("ViewContentLayout", () => {
it("renders children", () => {
render(<ViewContentLayout>Test content</ViewContentLayout>);
expect(screen.getByText("Test content")).toBeInTheDocument();
});

it("applies custom className", () => {
render(
<ViewContentLayout className="custom-class">Content</ViewContentLayout>,
);
const element = screen.getByText("Content");
expect(element).toHaveClass("view-content-layout");
expect(element).toHaveClass("custom-class");
});

it("passes through additional props", () => {
render(
<ViewContentLayout data-testid="test-component">
Content
</ViewContentLayout>,
);
expect(screen.getByTestId("test-component")).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import type React from "react";
import type { ViewContentLayoutProps } from "./types.js";
import "./styles.css";

/**
* ViewContentLayout component
*/
export const ViewContentLayout = ({
className,
children,
...props
}: ViewContentLayoutProps): React.ReactElement => {
return (
<div
className={`ds view-content-layout${className ? ` ${className}` : ""}`}
{...props}
>
{children}
</div>
);
};
5 changes: 5 additions & 0 deletions packages/react/ds-global/src/lib/ViewContentLayout/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

export type { ViewContentLayoutProps } from "./types.js";
export { ViewContentLayout } from "./ViewContentLayout.js";
17 changes: 17 additions & 0 deletions packages/react/ds-global/src/lib/ViewContentLayout/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* Generated by component/react v0.1.0 */
/* Generated by @canonical/summon:component-react v0.1.0 */

.ds.view-content-layout {
background: var(--mockup-stack-background); /* For demo purposes only */
grid-column: 1 / -2;
display: grid;
/* grid-template-columns: subgrid; */
grid-template-columns: repeat(
auto-fill,
minmax(var(--min-column-width), 1fr) minmax(var(--min-column-width), 1fr)
minmax(var(--min-column-width), 1fr)
minmax(var(--min-column-width), 1fr)
);
gap: var(--gap);
height: 100%;
}
9 changes: 9 additions & 0 deletions packages/react/ds-global/src/lib/ViewContentLayout/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import type { HTMLAttributes, ReactNode } from "react";

export interface ViewContentLayoutProps extends HTMLAttributes<HTMLDivElement> {
/** Content to render inside the component */
children?: ReactNode;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import { renderToString } from "react-dom/server";
import { describe, expect, it } from "vitest";
import { ViewLayout } from "./ViewLayout.js";

describe("ViewLayout SSR", () => {
it("renders without hydration errors", () => {
const html = renderToString(<ViewLayout>Test content</ViewLayout>);
expect(html).toContain("Test content");
expect(html).toContain("view-layout");
});
});
40 changes: 40 additions & 0 deletions packages/react/ds-global/src/lib/ViewLayout/ViewLayout.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Generated by component/react v0.1.0
// Generated by @canonical/summon:component-react v0.1.0

import type { Meta, StoryObj } from "@storybook/react-vite";
import * as testComponents from "../../storybook/testComponents.js";
import { ViewContentLayout } from "../ViewContentLayout/ViewContentLayout.js";
import { ViewLayout } from "./ViewLayout.js";

const meta: Meta<typeof ViewLayout> = {
title: "Layouts/ViewLayout",
component: ViewLayout,
tags: ["autodocs"],
parameters: {
layout: "fullscreen",
},
};

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

export const Default: Story = {
args: {
children: [
<ViewContentLayout key="content">
{[...Array(10)].map((_, index) => (
// biome-ignore lint/suspicious/noArrayIndexKey: only for testing purposes
<testComponents.Card key={`test_${index}`} />
))}
</ViewContentLayout>,
<testComponents.Sidebar key="sidebar" />,
],
},
};

export const WithCustomClass: Story = {
args: {
children: "Custom styled",
className: "custom-class",
},
};
Loading