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

chore(ui): migrate Grid, GridColumn and GridRow components to Typescript #595

Merged
merged 6 commits into from
Nov 7, 2024
Merged
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
5 changes: 5 additions & 0 deletions .changeset/bright-adults-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudoperators/juno-ui-components": minor
---

Migrate Grid, GridColumn and GridRow components to TypeScript
37 changes: 0 additions & 37 deletions packages/ui-components/src/components/Grid/Grid.component.js

This file was deleted.

44 changes: 44 additions & 0 deletions packages/ui-components/src/components/Grid/Grid.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from "react"

// Styles to apply when the 'auto' prop is true, overriding default grid column properties
const autoStyles = {
"--grid-column-flex-grow": "1",
"--grid-column-flex-shrink": "0",
"--grid-column-flex-basis": "0",
"--grid-column-default-width": "auto",
}

export interface GridProps extends React.HTMLAttributes<HTMLDivElement> {
andypf marked this conversation as resolved.
Show resolved Hide resolved
/**
* Controls whether columns should auto-size.
* If true, this will override the default 12-column grid layout.
*/
auto?: boolean
/**
* Elements to be rendered within the grid.
*/
children?: React.ReactNode
/**
* Additional CSS classes to apply to the grid for custom styling.
*/
className?: string
}

/**
* A general-use grid component.
* Used in conjunction with GridColumn and GridRow components to create a flexible grid layout.
*/
export const Grid: React.FC<GridProps> = ({ auto = false, children = null, className = "", ...props }) => {
const gridStyles = auto ? autoStyles : {}

return (
<div className={`juno-grid ${className}`} style={gridStyles} {...props}>
{children}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,30 @@
*/

import React from "react"
import { Grid } from "./index.js"
import { GridRow } from "../GridRow/GridRow.component.js"
import { GridColumn } from "../GridColumn/GridColumn.component.js"
import { StoryFn, Meta } from "@storybook/react"
import { Grid } from "./Grid.component"
import { GridRow } from "../GridRow/GridRow.component"
import { GridColumn } from "../GridColumn/GridColumn.component"

export default {
title: "Layout/Grid/Grid",
component: Grid,
argTypes: {
children: {
control: false,
},
children: { control: false },
},
decorators: [(Story) => <Story className="jn-bg-juno-blue-3 jn-text-juno-grey-blue" />],
}
decorators: [
(Story) => (
<div className="jn-bg-juno-blue-3 jn-text-juno-grey-blue">
<Story />
</div>
),
],
} as Meta<typeof Grid>

// for the decorator to work like this (passing props to the story) we have to access the passed props from the decorator
// from the context. This might be storybook 6.x-specific. Double check when we upgrade to storybook 7.x
const Template = (args, context) => <Grid {...args} className={context.className}></Grid>
const Template: StoryFn<typeof Grid> = (args) => <Grid {...args} />

export const Default = {
render: Template,

parameters: {
docs: {
description: {
Expand All @@ -34,7 +36,6 @@ export const Default = {
},
},
},

args: {
children: [
<GridRow key="1">
Expand All @@ -54,7 +55,7 @@ export const Default = {
<GridRow key="2">
<GridColumn>Column</GridColumn>
<GridColumn cols={3}>Column cols-3</GridColumn>
<GridColumn cols={5}>Column cols-6</GridColumn>
andypf marked this conversation as resolved.
Show resolved Hide resolved
<GridColumn cols={5}>Column cols-5</GridColumn>
<GridColumn cols={2}>Column cols-2</GridColumn>
</GridRow>,
],
Expand All @@ -63,7 +64,6 @@ export const Default = {

export const Auto = {
render: Template,

parameters: {
docs: {
description: {
Expand All @@ -72,7 +72,6 @@ export const Auto = {
},
},
},

args: {
auto: true,
children: [
Expand All @@ -97,15 +96,13 @@ export const Auto = {
<GridColumn>Column</GridColumn>
<GridColumn>Column</GridColumn>
<GridColumn>Column</GridColumn>
<GridColumn>Column</GridColumn>
</GridRow>,
],
},
}

export const MixedGrid = {
render: Template,

args: {
children: (
<GridRow>
Expand All @@ -120,7 +117,6 @@ export const MixedGrid = {

export const MixedAutoGrid = {
render: Template,

args: {
auto: true,
children: (
Expand All @@ -136,7 +132,6 @@ export const MixedAutoGrid = {

export const NestedGrid = {
render: Template,

args: {
children: (
<GridRow>
Expand Down
28 changes: 0 additions & 28 deletions packages/ui-components/src/components/Grid/Grid.test.js

This file was deleted.

90 changes: 90 additions & 0 deletions packages/ui-components/src/components/Grid/Grid.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors
* SPDX-License-Identifier: Apache-2.0
*/

import * as React from "react"
import { render, screen } from "@testing-library/react"
import { describe, expect, test } from "vitest"

import { Grid } from "./Grid.component"

describe("Grid Component", () => {
describe("Basic Rendering", () => {
test("renders a Grid container", () => {
render(<Grid data-testid="my-grid" />)
expect(screen.getByTestId("my-grid")).toBeInTheDocument()
})

test("renders children elements correctly", () => {
render(
<Grid data-testid="my-grid">
<div data-testid="child1">Child 1</div>
<div data-testid="child2">Child 2</div>
</Grid>
)

expect(screen.getByTestId("child1")).toBeInTheDocument()
expect(screen.getByTestId("child2")).toBeInTheDocument()
})
})

describe("Class Names", () => {
test("renders a custom className", () => {
render(<Grid data-testid="my-grid" className="my-grid-class" />)
expect(screen.getByTestId("my-grid")).toHaveClass("my-grid-class")
})

test("applies default className when no custom className is provided", () => {
render(<Grid data-testid="my-default-grid" />)
expect(screen.getByTestId("my-default-grid")).toHaveClass("juno-grid")
})
})

describe("Inline Styles and Auto Prop", () => {
test("has modified CSS variables in a style tag for auto grids", () => {
render(<Grid data-testid="my-auto-grid" auto />)
const gridElement = screen.getByTestId("my-auto-grid")

// Ensure element is in the document before accessing style
expect(gridElement).toBeInTheDocument()

// Cast element style as CSSStyleDeclaration to ensure type safety
const style = gridElement.style

expect(style.getPropertyValue("--grid-column-flex-grow")).toBe("1")
expect(style.getPropertyValue("--grid-column-flex-shrink")).toBe("0")
expect(style.getPropertyValue("--grid-column-flex-basis")).toBe("0")
})

test("does not apply auto styles when 'auto' prop is false", () => {
render(<Grid data-testid="my-standard-grid" />)
const gridElement = screen.getByTestId("my-standard-grid")

const style = gridElement.style

// Ensure auto grid styles are not applied
expect(style.getPropertyValue("--grid-column-flex-grow")).toBe("")
expect(style.getPropertyValue("--grid-column-flex-shrink")).toBe("")
expect(style.getPropertyValue("--grid-column-flex-basis")).toBe("")
})

test("applies custom styles", () => {
render(<Grid data-testid="my-grid" style={{ backgroundColor: "red" }} />)
const gridElement = screen.getByTestId("my-grid")
const style = gridElement.style

expect(style.backgroundColor).toBe("red")
})

test("applies no styles when neither auto nor style prop is provided", () => {
render(<Grid data-testid="my-no-styles-grid" />)
const gridElement = screen.getByTestId("my-no-styles-grid")
const style = gridElement.style

expect(style.flexGrow).toBe("")
expect(style.flexShrink).toBe("")
expect(style.flexBasis).toBe("")
})
})
})
Loading
Loading