reshaped 3.7.0-canary.1 → 3.7.0-canary.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -96,7 +96,7 @@ const View = (props) => {
96
96
  const renderItem = ({ className, child, index }) => {
97
97
  const isItem = child.type === ViewItem;
98
98
  const isView = child.type === View;
99
- const key = child.key || index;
99
+ const key = child.key;
100
100
  const dividerElement = !!index && divided && renderDivider({ className, key });
101
101
  let itemElement;
102
102
  if (isItem) {
@@ -120,7 +120,7 @@ const View = (props) => {
120
120
  }
121
121
  if (isItem && child.props?.gap === "auto")
122
122
  nowrap = true;
123
- return (_jsxs(React.Fragment, { children: [dividerElement, itemElement] }, `${key}-fragment`));
123
+ return (_jsxs(React.Fragment, { children: [dividerElement, itemElement] }, key ? `${key}-fragment` : undefined));
124
124
  };
125
125
  // Using any in favor of resolving the props in runtime where we don't know their props definitions
126
126
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -121,6 +121,10 @@ export declare const hiddenItem: {
121
121
  name: string;
122
122
  render: () => React.JSX.Element;
123
123
  };
124
+ export declare const keys: {
125
+ name: string;
126
+ render: () => React.JSX.Element;
127
+ };
124
128
  export declare const nestedGaps: {
125
129
  name: string;
126
130
  render: () => React.JSX.Element;
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { useEffect, useState } from "react";
2
2
  import { Placeholder, Example } from "../../../utilities/storybook/index.js";
3
3
  import View from "../index.js";
4
4
  import Hidden from "../../Hidden/index.js";
@@ -8,6 +8,7 @@ import Avatar from "../../Avatar/index.js";
8
8
  import MenuItem from "../../MenuItem/index.js";
9
9
  import Button from "../../Button/index.js";
10
10
  import IconPlus from "../../../icons/Plus.js";
11
+ import useToggle from "../../../hooks/useToggle.js";
11
12
  export default {
12
13
  title: "Utility components/View",
13
14
  component: View,
@@ -1067,6 +1068,28 @@ export const hiddenItem = {
1067
1068
  </Example.Item>
1068
1069
  </Example>),
1069
1070
  };
1071
+ const KeyItem = (props) => {
1072
+ const [timer, setTimer] = useState(0);
1073
+ useEffect(() => {
1074
+ const t = setInterval(() => setTimer((t) => t + 1), 500);
1075
+ return () => clearInterval(t);
1076
+ }, []);
1077
+ return (<div>
1078
+ {props.children}, timer: {timer}
1079
+ </div>);
1080
+ };
1081
+ export const keys = {
1082
+ name: "item, key",
1083
+ render: () => {
1084
+ const toggle = useToggle();
1085
+ return (<View gap={2}>
1086
+ <Button onClick={() => toggle.toggle()}>Toggle</Button>
1087
+ <View.Item>Item 1</View.Item>
1088
+ {toggle.active && <KeyItem>Item 2</KeyItem>}
1089
+ <KeyItem>Item 3</KeyItem>
1090
+ </View>);
1091
+ },
1092
+ };
1070
1093
  export const nestedGaps = {
1071
1094
  name: "composition, nested gap",
1072
1095
  render: () => (<Example>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reshaped",
3
3
  "description": "Professionally crafted design system in React & Figma for building products of any scale and complexity",
4
- "version": "3.7.0-canary.1",
4
+ "version": "3.7.0-canary.3",
5
5
  "license": "MIT",
6
6
  "email": "hello@reshaped.so",
7
7
  "homepage": "https://reshaped.so",
@@ -1,27 +0,0 @@
1
- import { StoryObj } from "@storybook/react-vite";
2
- import { fn } from "storybook/test";
3
- declare const _default: {
4
- title: string;
5
- component: import("react").FC<import("./..").TabsProps> & {
6
- Item: import("react").ForwardRefExoticComponent<import("./..").TabsItemProps & import("react").RefAttributes<import("../../Actionable").ActionableRef>>;
7
- List: import("react").FC<import("../Tabs.types").ListProps>;
8
- Panel: import("react").FC<import("../Tabs.types").PanelProps>;
9
- };
10
- parameters: {
11
- iframe: {
12
- url: string;
13
- };
14
- chromatic: {
15
- disableSnapshot: boolean;
16
- };
17
- };
18
- };
19
- export default _default;
20
- export declare const base: StoryObj;
21
- export declare const defaultValue: StoryObj<{
22
- handleChange: ReturnType<typeof fn>;
23
- }>;
24
- export declare const value: StoryObj<{
25
- handleChange: ReturnType<typeof fn>;
26
- }>;
27
- export declare const className: StoryObj;
@@ -1,128 +0,0 @@
1
- import { expect, within, userEvent, waitFor, fn } from "storybook/test";
2
- import Tabs from "../index.js";
3
- export default {
4
- title: "Components/Tabs/tests",
5
- component: Tabs,
6
- parameters: {
7
- iframe: {
8
- url: "https://reshaped.so/docs/components/tabs",
9
- },
10
- chromatic: { disableSnapshot: true },
11
- },
12
- };
13
- export const base = {
14
- name: "base",
15
- render: () => (<Tabs>
16
- <Tabs.List>
17
- <Tabs.Item value="1">Item 1</Tabs.Item>
18
- <Tabs.Item value="2">Item 2</Tabs.Item>
19
- </Tabs.List>
20
-
21
- <Tabs.Panel value="1">Content 1</Tabs.Panel>
22
- <Tabs.Panel value="2">Content 2</Tabs.Panel>
23
- </Tabs>),
24
- play: async ({ canvas }) => {
25
- const list = canvas.getByRole("tablist");
26
- const items = canvas.getAllByRole("tab");
27
- const panels = canvas.getAllByRole("tabpanel", { hidden: true });
28
- expect(list).toBeInTheDocument();
29
- expect(items).toHaveLength(2);
30
- expect(panels).toHaveLength(2);
31
- expect(panels[0]).toBeVisible();
32
- expect(panels[1]).not.toBeVisible();
33
- const selectedItem = items[0];
34
- const selectedPanel = panels[0];
35
- expect(selectedItem).toHaveAttribute("aria-selected", "true");
36
- expect(selectedItem.getAttribute("aria-controls")).toBe(selectedPanel.getAttribute("id"));
37
- const unselectedItem = items[1];
38
- const unselectedPanel = panels[1];
39
- expect(unselectedItem).toHaveAttribute("aria-selected", "false");
40
- expect(unselectedItem.getAttribute("aria-controls")).toBe(unselectedPanel.getAttribute("id"));
41
- await userEvent.tab();
42
- expect(document.activeElement).toBe(items[0]);
43
- await userEvent.tab();
44
- waitFor(() => {
45
- expect(document.activeElement).toBe(panels[0]);
46
- });
47
- },
48
- };
49
- export const defaultValue = {
50
- name: "defaultValue, uncontrolled",
51
- args: {
52
- handleChange: fn(),
53
- },
54
- render: (args) => (<Tabs defaultValue="2" onChange={args.handleChange}>
55
- <Tabs.List>
56
- <Tabs.Item value="1">Item 1</Tabs.Item>
57
- <Tabs.Item value="2">Item 2</Tabs.Item>
58
- </Tabs.List>
59
-
60
- <Tabs.Panel value="1">Content 1</Tabs.Panel>
61
- <Tabs.Panel value="2">Content 2</Tabs.Panel>
62
- </Tabs>),
63
- play: async ({ canvas, args }) => {
64
- const items = canvas.getAllByRole("tab");
65
- expect(items[1]).toHaveAttribute("aria-selected", "true");
66
- expect(items[1]).toHaveAttribute("tabindex", "0");
67
- expect(items[0]).toHaveAttribute("tabindex", "-1");
68
- await userEvent.click(items[0]);
69
- expect(args.handleChange).toHaveBeenCalledTimes(1);
70
- expect(args.handleChange).toHaveBeenCalledWith({ value: "1" });
71
- expect(document.activeElement).toBe(items[0]);
72
- expect(items[0]).toHaveAttribute("aria-selected", "true");
73
- expect(items[0]).toHaveAttribute("tabindex", "0");
74
- expect(items[1]).toHaveAttribute("tabindex", "-1");
75
- },
76
- };
77
- export const value = {
78
- name: "value, controlled",
79
- args: {
80
- handleChange: fn(),
81
- },
82
- render: (args) => (<Tabs value="2" onChange={args.handleChange}>
83
- <Tabs.List>
84
- <Tabs.Item value="1">Item 1</Tabs.Item>
85
- <Tabs.Item value="2">Item 2</Tabs.Item>
86
- </Tabs.List>
87
-
88
- <Tabs.Panel value="1">Content 1</Tabs.Panel>
89
- <Tabs.Panel value="2">Content 2</Tabs.Panel>
90
- </Tabs>),
91
- play: async ({ canvas, args }) => {
92
- const items = canvas.getAllByRole("tab");
93
- expect(items[1]).toHaveAttribute("aria-selected", "true");
94
- expect(items[1]).toHaveAttribute("tabindex", "0");
95
- expect(items[0]).toHaveAttribute("tabindex", "-1");
96
- await userEvent.click(items[0]);
97
- expect(args.handleChange).toHaveBeenCalledTimes(1);
98
- expect(args.handleChange).toHaveBeenCalledWith({ value: "1" });
99
- expect(document.activeElement).toBe(items[0]);
100
- expect(items[1]).toHaveAttribute("aria-selected", "true");
101
- expect(items[1]).toHaveAttribute("tabindex", "0");
102
- expect(items[0]).toHaveAttribute("tabindex", "-1");
103
- },
104
- };
105
- export const className = {
106
- name: "className, attributes",
107
- render: () => (<div data-testid="root">
108
- <Tabs>
109
- <Tabs.List attributes={{ id: "test-list-id" }} className="test-list-classname">
110
- <Tabs.Item attributes={{ id: "test-item-id" }} value="1">
111
- Item
112
- </Tabs.Item>
113
- </Tabs.List>
114
-
115
- <Tabs.Panel attributes={{ "data-testid": "test-panel-id" }} className="test-panel-classname" value="1"/>
116
- </Tabs>
117
- </div>),
118
- play: async ({ canvas }) => {
119
- const list = canvas.getByTestId("root").firstChild;
120
- const item = within(list).getByRole("presentation");
121
- const panel = canvas.getByRole("tabpanel");
122
- expect(list).toHaveClass("test-list-classname");
123
- expect(list).toHaveAttribute("id", "test-list-id");
124
- expect(item).toHaveAttribute("id", "test-item-id");
125
- expect(panel).toHaveClass("test-panel-classname");
126
- expect(panel).toHaveAttribute("data-testid", "test-panel-id");
127
- },
128
- };