Skip to content

Commit

Permalink
Merge branch 'main' into dialog-subtitle
Browse files Browse the repository at this point in the history
  • Loading branch information
liamsms authored Jul 22, 2024
2 parents 16a2372 + 0008528 commit 6d8785e
Show file tree
Hide file tree
Showing 24 changed files with 711 additions and 1 deletion.
13 changes: 13 additions & 0 deletions .changeset/added-system-status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@salt-ds/lab": minor
---

Added `SystemStatus`, `SystemStatusContent`, `SystemStatusActions` component to lab.

```tsx
<SystemStatus>
<SystemStatusContent>
<Text color="inherit">New feature updates are available</Text>
</SystemStatusContent>
</SystemStatus>
```
6 changes: 5 additions & 1 deletion .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
"packageRules": [
{
"groupName": "Mosaic",
"packagePatterns": ["^@jpmorganchase/mosaic"]
"matchPackagePrefixes": ["@jpmorganchase/mosaic"]
},
{
"groupName": "AG Grid",
"matchPackagePrefixes": ["@ag-grid"]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { SystemStatus, SystemStatusContent } from "@salt-ds/lab";
import * as systemStatusStories from "@stories/system-status/system-status.stories";
import { composeStories } from "@storybook/react";
import { checkAccessibility } from "../../../../../../cypress/tests/checkAccessibility";

const composedStories = composeStories(systemStatusStories);
// biome-ignore lint/suspicious/noShadowRestrictedNames: <explanation>
const { Info, Success, Error, Warning } = composedStories;

describe("GIVEN a System status", () => {
checkAccessibility(composedStories);

it('should render an info status when `status="info"`', () => {
cy.mount(<Info />);

cy.findByTestId("InfoSolidIcon").should("exist");
});
it('should render a success status when `status="success"`', () => {
cy.mount(<Success />);

cy.findByTestId("SuccessTickIcon").should("exist");
});
it('should render a warning status when `status="warning"`', () => {
cy.mount(<Warning />);

cy.findByTestId("WarningSolidIcon").should("exist");
});
it('should render an error status when `status="error"`', () => {
cy.mount(<Error />);

cy.findByTestId("ErrorSolidIcon").should("exist");
});

it('should have a default role of "status"', () => {
const message = "example announcement";
cy.mount(
<SystemStatus>
<SystemStatusContent>{message}</SystemStatusContent>
</SystemStatus>,
);

cy.findByRole("status").should("have.text", message);
});
});
1 change: 1 addition & 0 deletions packages/lab/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export * from "./skip-link";
export * from "./slider";
export * from "./stepped-tracker";
export * from "./stepper-input";
export * from "./system-status";
export * from "./tabs";
export * from "./tabs-next";
export * from "./toast-group";
Expand Down
48 changes: 48 additions & 0 deletions packages/lab/src/system-status/SystemStatus.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* Styles applied to root component */
.saltSystemStatus {
--saltIcon-color: var(--salt-content-bold-foreground);

background: var(--saltSystemStatus-background, var(--systemStatus-background));
border-color: var(--saltSystemStatus-borderColor, var(--systemStatus-borderColor));
border-width: var(--saltSystemStatus-borderWidth, var(--salt-size-border));
border-style: var(--saltSystemStatus-borderStyle, var(--salt-container-borderStyle));
box-sizing: border-box;
display: flex;
gap: var(--salt-spacing-75);
padding: var(--saltSystemStatus-padding, var(--salt-spacing-50) var(--salt-spacing-100));
width: 100%;
min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));
font-family: var(--salt-text-fontFamily);
font-size: var(--salt-text-fontSize);
font-weight: var(--salt-text-fontWeight);
line-height: var(--salt-text-lineHeight);
}

/* Styles applied to icon */
.saltSystemStatus-icon.saltIcon {
min-height: var(--salt-size-base);
}

/* Styles applied when state = "info" */
.saltSystemStatus-info {
--systemStatus-borderColor: var(--salt-status-info-bold-background);
--systemStatus-background: var(--salt-status-info-bold-background);
}

/* Styles applied when state = "error" */
.saltSystemStatus-error {
--systemStatus-borderColor: var(--salt-status-error-bold-background);
--systemStatus-background: var(--salt-status-error-bold-background);
}

/* Styles applied when state = "warning" */
.saltSystemStatus-warning {
--systemStatus-borderColor: var(--salt-status-warning-bold-background);
--systemStatus-background: var(--salt-status-warning-bold-background);
}

/* Styles applied when state = "success" */
.saltSystemStatus-success {
--systemStatus-borderColor: var(--salt-status-success-bold-background);
--systemStatus-background: var(--salt-status-success-bold-background);
}
47 changes: 47 additions & 0 deletions packages/lab/src/system-status/SystemStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {
StatusIndicator,
type ValidationStatus,
makePrefixer,
} from "@salt-ds/core";
import { clsx } from "clsx";
import { type HTMLAttributes, forwardRef } from "react";

import { useComponentCssInjection } from "@salt-ds/styles";
import { useWindow } from "@salt-ds/window";

import systemStatusCss from "./SystemStatus.css";

export interface SystemStatusProps extends HTMLAttributes<HTMLDivElement> {
/**
* A string to determine the current state of the SystemStatus. Defaults to `info`.
*/
status?: ValidationStatus;
}

const withBaseName = makePrefixer("saltSystemStatus");

export const SystemStatus = forwardRef<HTMLDivElement, SystemStatusProps>(
function SystemStatus(
{ children, className, status = "info", ...rest },
ref,
) {
const targetWindow = useWindow();
useComponentCssInjection({
testId: "salt-system-status",
css: systemStatusCss,
window: targetWindow,
});

return (
<div
className={clsx(withBaseName(), withBaseName(status), className)}
ref={ref}
role="status"
{...rest}
>
<StatusIndicator status={status} className={withBaseName("icon")} />
{children}
</div>
);
},
);
5 changes: 5 additions & 0 deletions packages/lab/src/system-status/SystemStatusActions.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.saltSystemStatusActions {
margin-bottom: auto;
display: flex;
gap: var(--salt-spacing-100);
}
38 changes: 38 additions & 0 deletions packages/lab/src/system-status/SystemStatusActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { makePrefixer } from "@salt-ds/core";
import { clsx } from "clsx";
import {
type ComponentPropsWithoutRef,
type ReactNode,
forwardRef,
} from "react";

import { useComponentCssInjection } from "@salt-ds/styles";
import { useWindow } from "@salt-ds/window";
import systemStatusActionsCss from "./SystemStatusActions.css";

const withBaseName = makePrefixer("saltSystemStatusActions");

interface SystemStatusActionsProps extends ComponentPropsWithoutRef<"div"> {
/**
* The content of SystemStatusActions
*/
children: ReactNode;
}

export const SystemStatusActions = forwardRef<
HTMLDivElement,
SystemStatusActionsProps
>(function SystemStatusActions(props, ref) {
const { className, ...rest } = props;

const targetWindow = useWindow();
useComponentCssInjection({
testId: "salt-system-status-actions",
css: systemStatusActionsCss,
window: targetWindow,
});

return (
<div className={clsx(withBaseName(), className)} {...rest} ref={ref} />
);
});
6 changes: 6 additions & 0 deletions packages/lab/src/system-status/SystemStatusContent.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* Styles applied to SystemStatusContent */
.saltSystemStatusContent {
flex: 1 0;
margin: var(--salt-spacing-75) 0;
color: var(--salt-content-bold-foreground);
}
38 changes: 38 additions & 0 deletions packages/lab/src/system-status/SystemStatusContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { makePrefixer } from "@salt-ds/core";
import { clsx } from "clsx";
import {
type ComponentPropsWithoutRef,
type ReactNode,
forwardRef,
} from "react";

import { useComponentCssInjection } from "@salt-ds/styles";
import { useWindow } from "@salt-ds/window";
import systemStatusContentCss from "./SystemStatusContent.css";

const withBaseName = makePrefixer("saltSystemStatusContent");

interface SystemStatusContentProps extends ComponentPropsWithoutRef<"div"> {
/**
* The content of SystemStatusContent
*/
children: ReactNode;
}

export const SystemStatusContent = forwardRef<
HTMLDivElement,
SystemStatusContentProps
>(function SystemStatusContent(props, ref) {
const { className, ...rest } = props;

const targetWindow = useWindow();
useComponentCssInjection({
testId: "salt-system-status-content",
css: systemStatusContentCss,
window: targetWindow,
});

return (
<div className={clsx(withBaseName(), className)} {...rest} ref={ref} />
);
});
3 changes: 3 additions & 0 deletions packages/lab/src/system-status/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./SystemStatus";
export * from "./SystemStatusContent";
export * from "./SystemStatusActions";
64 changes: 64 additions & 0 deletions packages/lab/stories/system-status/system-status.qa.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { StackLayout, Text } from "@salt-ds/core";
import {
SystemStatus,
SystemStatusContent,
type SystemStatusProps,
} from "@salt-ds/lab";
import type { Meta, StoryFn } from "@storybook/react";
import { QAContainer } from "docs/components";
import type { FC } from "react";

export default {
title: "Lab/System Status/System Status QA",
component: SystemStatus,
} as Meta<typeof SystemStatus>;

const BasicSystemStatusExample: FC<SystemStatusProps> = ({ status }) => {
return (
<SystemStatus status={status}>
<SystemStatusContent>
<StackLayout gap={0.5}>
<Text color="inherit">
<strong>Title</strong>
</Text>
<Text color="inherit">Example custom renderer</Text>
</StackLayout>
</SystemStatusContent>
</SystemStatus>
);
};

const InfoSystemStatus = () => <BasicSystemStatusExample status={"info"} />;
const ErrorSystemStatus = () => <BasicSystemStatusExample status={"error"} />;
const WarningSystemStatus = () => (
<BasicSystemStatusExample status={"warning"} />
);
const SuccessSystemStatus = () => (
<BasicSystemStatusExample status={"success"} />
);

export const ExamplesGrid: StoryFn = (props) => (
<QAContainer cols={1} itemPadding={10} height={600} width={1000} {...props}>
<InfoSystemStatus />
<ErrorSystemStatus />
<WarningSystemStatus />
<SuccessSystemStatus />
</QAContainer>
);

ExamplesGrid.parameters = {
chromatic: {
disableSnapshot: false,
modes: {
theme: {
themeNext: "disabled",
},
themeNext: {
themeNext: "enable",
corner: "rounded",
accent: "teal",
// Ignore headingFont given font is not loaded
},
},
},
};
Loading

0 comments on commit 6d8785e

Please sign in to comment.