svelte-cartesian
Advanced tools
Comparing version
{ | ||
"name": "svelte-cartesian", | ||
"version": "1.1.2", | ||
"version": "1.1.3", | ||
"description": "A single component that helps render prop combinations (the \"Cartesian Product\") for visual regression testing.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
216
README.md
# Svelte Cartesian | ||
A single component that helps render prop combinations (the "Cartesian | ||
Product") for visual regression testing. | ||
A single component that helps render prop combinations. It can be used with visual regression test software such as [Playwright](https://playwright.dev/) | ||
or [Storybook](https://storybook.js.org/) (see [examples](#examples)). | ||
Its name comes from "Cartesian Product" in which an intersection of two | ||
or more arrays form a matrix, such as: | ||
``` | ||
[a, b] * [x, y] --> [[a, x], [a, y], [b, x], [b, y]] | ||
``` | ||
<img src="https://raw.githubusercontent.com/theetrain/svelte-cartesian/main/demo.jpg" alt="Cartesian demonstration featuring a 4 x 3 x 2 combination." /> | ||
@@ -11,13 +18,13 @@ | ||
- [After using `svelte-cartesian`](#after-using-svelte-cartesian) | ||
- [Svelte 4 usage](#svelte-4-usage) | ||
- [Basic usage (Svelte 4)](#basic-usage-svelte-4) | ||
- [Usage with slots (Svelte 4)](#usage-with-slots-svelte-4) | ||
- [Adding labels (Svelte 4)](#adding-labels-svelte-4) | ||
- [Styling `<Cartesian>` (Svelte 4)](#styling-cartesian-svelte-4) | ||
- [`<Cartesian>` props (Svelte 4)](#cartesian-props-svelte-4) | ||
- [`<Cartesian>` slots (Svelte 4)](#cartesian-slots-svelte-4) | ||
- [Examples (Svelte 4)](#examples-svelte-4) | ||
- [Setup](#setup) | ||
- [Basic usage](#basic-usage) | ||
- [Usage with slots](#usage-with-slots) | ||
- [Available slots](#available-slots) | ||
- [Adding labels](#adding-labels) | ||
- [Styling `<Cartesian>`](#styling-cartesian) | ||
- [`<Cartesian>` props](#cartesian-props) | ||
- [Examples](#examples) | ||
- [Usage with Playwright](#usage-with-playwright) | ||
- [Usage with Storybook](#usage-with-storybook) | ||
- [Svelte 5 usage (experimental)](#svelte-5-usage-experimental) | ||
- [Styling `<CartesianWithRunes>` (Svelte 5)](#styling-cartesianwithrunes-svelte-5) | ||
- [`<CartesianWithRunes>` props (Svelte 5)](#cartesianwithrunes-props-svelte-5) | ||
- [Project roadmap](#project-roadmap) | ||
@@ -48,10 +55,8 @@ - [Goals](#goals) | ||
<details> | ||
<summary>Before and after using <code>svelte-cartesian</code></summary> | ||
### Before using `svelte-cartesian` | ||
<!-- prettier-ignore-start --> | ||
```html | ||
<script> | ||
import { Button } from './Button.svelte' | ||
import { Button } from "./Button.svelte" | ||
</script> | ||
@@ -63,5 +68,5 @@ | ||
{#each ['main', 'common', 'ghost'] as prominence} | ||
<Button {size} {variant} {prominence}> | ||
<button {size} {variant} {prominence}> | ||
Dispense popcorn | ||
</Button> | ||
</button> | ||
{/each} | ||
@@ -71,2 +76,3 @@ {/each} | ||
``` | ||
<!-- prettier-ignore-end --> | ||
@@ -93,19 +99,17 @@ ### After using `svelte-cartesian` | ||
</details> | ||
## Setup | ||
## Svelte 4 usage | ||
1. Install package | ||
```bash | ||
npm install -D svelte-cartesian | ||
``` | ||
```bash | ||
npm install -D svelte-cartesian | ||
``` | ||
2. Add component to your page. | ||
```html | ||
<script> | ||
import { Cartesian } from 'svelte-cartesian' | ||
</script> | ||
``` | ||
```html | ||
<script> | ||
import { Cartesian } from "svelte-cartesian" | ||
</script> | ||
``` | ||
@@ -115,3 +119,3 @@ 3. Pass props with array of potential values, including an explicit `undefined` | ||
### Basic usage (Svelte 4) | ||
## Basic usage | ||
@@ -139,3 +143,3 @@ - Pass a component to the `Component` prop. | ||
### Usage with slots (Svelte 4) | ||
## Usage with slots | ||
@@ -150,4 +154,4 @@ - Pass your component into the default slot. | ||
<script> | ||
import Button from './Button.svelte' | ||
import { Cartesian } from 'svelte-cartesian' | ||
import Button from "./Button.svelte" | ||
import { Cartesian } from "svelte-cartesian" | ||
@@ -157,5 +161,5 @@ const props = { | ||
props: { | ||
variant: ['primary', 'secondary'], | ||
size: ['medium', 'large'] | ||
} | ||
variant: ["primary", "secondary"], | ||
size: ["medium", "large"], | ||
}, | ||
} | ||
@@ -166,8 +170,6 @@ </script> | ||
<Cartesian {...props} let:innerProps> | ||
<Button {...innerProps}> | ||
<svelte:fragment slot="left"> | ||
Left contents | ||
</svelte:fragment> | ||
<button {...innerProps}> | ||
<svelte:fragment slot="left"> Left contents </svelte:fragment> | ||
Click me | ||
</Button> | ||
</button> | ||
</Cartesian> | ||
@@ -177,17 +179,19 @@ | ||
<Cartesian {...props} let:innerProps> | ||
<Button {...innerProps}> | ||
Click me | ||
</Button> | ||
<button {...innerProps}>Click me</button> | ||
</Cartesian> | ||
``` | ||
### Adding labels (Svelte 4) | ||
### Available slots | ||
| slot name | slot props | description | | ||
| --------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| _default_ | `let:innerProps` | Default slot. Contents get passed to provided `Component`. When `asChild` is set to `true`, contents **MAY** contain provided `Component` and its respective slots; see [usage with slots](#usage-with-slots-svelte-4) for more details. | | ||
| `label` | `let:label`, `let:innerProps` | Provide your own label, styles, and logic instead of the default provided label. | | ||
## Adding labels | ||
Use the `labels` prop to generate labels next to every component instance. | ||
```html | ||
<Cartesian | ||
props={props} | ||
Component={Component} | ||
labels /> | ||
<Cartesian props="{props}" Component="{Component}" labels /> | ||
<!-- ^^^^^^ implied as `true` --> | ||
@@ -207,7 +211,3 @@ ``` | ||
<!-- Using `label` slot prop --> | ||
<Cartesian | ||
props={props} | ||
Component={Component} | ||
labels | ||
> | ||
<Cartesian props="{props}" Component="{Component}" labels> | ||
<div class="label-container" slot="label" let:label> | ||
@@ -225,6 +225,3 @@ <span class="label">Props</span> | ||
--> | ||
<Cartesian | ||
props={props} | ||
Component={Component} | ||
> | ||
<Cartesian props="{props}" Component="{Component}"> | ||
<div class="label-container" slot="label" let:innerProps> | ||
@@ -237,3 +234,3 @@ <span class="label">Props</span> | ||
### Styling `<Cartesian>` (Svelte 4) | ||
## Styling `<Cartesian>` | ||
@@ -278,3 +275,3 @@ `<Cartesian>` has these default CSS behaviours: | ||
### `<Cartesian>` props (Svelte 4) | ||
## `<Cartesian>` props | ||
@@ -289,68 +286,69 @@ | prop | type | description | | ||
| `divAttributes` | `?SvelteHTMLElements["div"]={}` | Attributes to be spread onto the wrapping `<div>` element. | | ||
| `let:innerProps` | `Record<string, any>` | Provides a single combination of props at every iteration to the *default* slot. Use this alongside `asChild` to spread `innerProps` to your nested component. | | ||
| `let:innerProps` | `Record<string, any>` | Provides a single combination of props at every iteration to the _default_ slot. Use this alongside `asChild` to spread `innerProps` to your nested component. | | ||
| `let:label` | `string` | Generated label for a given instance. This is provided to the `label` slot. See [adding labels](#adding-labels-svelte-4) for more details. | | ||
### `<Cartesian>` slots (Svelte 4) | ||
## Examples | ||
| slot name | slot props | description | | ||
| --------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| *default* | `let:innerProps` | Default slot. Contents get passed to provided `Component`. When `asChild` is set to `true`, contents **MAY** contain provided `Component` and its respective slots; see [usage with slots](#usage-with-slots-svelte-4) for more details. | | ||
| `label` | `let:label`, `let:innerProps` | Provide your own label, styles, and logic instead of the default provided label. | | ||
### Usage with Playwright | ||
### Examples (Svelte 4) | ||
1. Create a page using `<Cartesian />` | ||
2. Set up a test to take a screenshot of your page. | ||
See more examples in [end to end tests](./e2e/svelte-4/src/routes/). | ||
```js | ||
test("default slot", async ({ page }) => { | ||
await page.goto("localhost:4173/") | ||
await expect(page).toHaveScreenshot() | ||
}) | ||
``` | ||
## Svelte 5 usage (experimental) | ||
See complete Playwright examples in [end to end | ||
tests](./e2e/svelte-4/src/routes/). | ||
>[!WARNING] | ||
>This component is based on the release candidate of Svelte 5 and is considered | ||
>unstable. Any breaking changes will not be properly indicated in | ||
>`svelte-cartesian` releases at this time, but there are no planned changes. | ||
### Usage with Storybook | ||
1. Install package | ||
1. Set up a component story. | ||
2. Import `<Cartesian />` to render prop combinations: | ||
```bash | ||
npm install -D svelte-cartesian | ||
``` | ||
```html | ||
<script context="module"> | ||
import { Story, Template } from "@storybook/addon-svelte-csf" | ||
import { Cartesian } from "svelte-cartesian" | ||
import Switch from "./Switch.svelte" | ||
2. Add component to your page. | ||
export const meta = { | ||
title: "Switch", | ||
component: Switch, | ||
tags: ["autodocs"], | ||
} | ||
const props = { | ||
label: ["Active profile"], | ||
size: ["sm", "md"], | ||
toggle: ["on", "off"], | ||
buttonAttributes: [{ disabled: true }, { disabled: false }], | ||
} | ||
</script> | ||
```html | ||
<script> | ||
import Button from './Button.svelte' | ||
import { CartesianWithRunes as Cartesian } from 'svelte-cartesian' | ||
</script> | ||
<!-- Basic Cartesian usage --> | ||
<template> | ||
<Cartesian {props} Component="{Switch}" /> | ||
</template> | ||
{#snippet children()} | ||
Click me | ||
{/snippet} | ||
<Story name="Switches" /> | ||
<Cartesian | ||
Component={Button} | ||
props={{ | ||
variant: ['primary', 'secondary'], | ||
size: ['medium', 'large'], | ||
children: [children] | ||
}} | ||
/> | ||
``` | ||
<!-- | ||
Optional, but recommended to test states | ||
--> | ||
<Story name="Switches Pressed" parameters={{ pseudo: { active: true } }} /> | ||
<Story name="Switches Focused" parameters={{ pseudo: { focusVisible: true } }} | ||
/> | ||
``` | ||
3. Pass props with array of potential values, including an explicit `undefined` | ||
where applicable. Ensure snippets are passed in as props and defined within | ||
the markup of the page using `<CartesianWithRunes>`. | ||
See | ||
[storybook-addon-pseudo-states](https://github.com/chromaui/storybook-addon-pseudo-states) | ||
for more inspiration. | ||
### Styling `<CartesianWithRunes>` (Svelte 5) | ||
## Svelte 5 usage (experimental) | ||
Styling `<CartesianWithRunes>` is done in the exact same way as with [`<Cartesian>`](#styling-cartesian-svelte-4). | ||
See [Svelte 5 README](./README-svelte-5.md). | ||
### `<CartesianWithRunes>` props (Svelte 5) | ||
| prop | type | description | | ||
| --------------- | ------------------------------- | ------------------------------------------------------------------------------- | | ||
| `Component` | `ComponentType` | **Required**: A Svelte component. | | ||
| `props` | `Record<string, any[]>` | **Required**: An object containing prop names and an array of potential values. | | ||
| `unstyled` | `?boolean=false` | Disable built-in CSS. | | ||
| `divAttributes` | `?SvelteHTMLElements["div"]={}` | Attributes to be spread onto the wrapping `<div>` element. | | ||
## Project roadmap | ||
@@ -357,0 +355,0 @@ |
24095
-3.1%355
-0.56%