@window-splitter/react 0.8.0

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.
Files changed (81) hide show
  1. package/.storybook/main.ts +17 -0
  2. package/.storybook/preview.ts +14 -0
  3. package/.tshy/build.json +8 -0
  4. package/.tshy/commonjs.json +19 -0
  5. package/.tshy/esm.json +18 -0
  6. package/.turbo/turbo-build.log +5 -0
  7. package/.turbo/turbo-lint.log +5 -0
  8. package/CHANGELOG.md +606 -0
  9. package/README.md +53 -0
  10. package/dist/commonjs/ReactWindowSplitter.d.ts +19 -0
  11. package/dist/commonjs/ReactWindowSplitter.d.ts.map +1 -0
  12. package/dist/commonjs/ReactWindowSplitter.js +558 -0
  13. package/dist/commonjs/ReactWindowSplitter.js.map +1 -0
  14. package/dist/commonjs/ReactWindowSplitter.stories.d.ts +47 -0
  15. package/dist/commonjs/ReactWindowSplitter.stories.d.ts.map +1 -0
  16. package/dist/commonjs/ReactWindowSplitter.stories.js +330 -0
  17. package/dist/commonjs/ReactWindowSplitter.stories.js.map +1 -0
  18. package/dist/commonjs/ReactWindowSplitter.test.d.ts +2 -0
  19. package/dist/commonjs/ReactWindowSplitter.test.d.ts.map +1 -0
  20. package/dist/commonjs/ReactWindowSplitter.test.js +219 -0
  21. package/dist/commonjs/ReactWindowSplitter.test.js.map +1 -0
  22. package/dist/commonjs/bundle.size.d.ts +2 -0
  23. package/dist/commonjs/bundle.size.d.ts.map +1 -0
  24. package/dist/commonjs/bundle.size.js +29 -0
  25. package/dist/commonjs/bundle.size.js.map +1 -0
  26. package/dist/commonjs/index.d.ts +3 -0
  27. package/dist/commonjs/index.d.ts.map +1 -0
  28. package/dist/commonjs/index.js +18 -0
  29. package/dist/commonjs/index.js.map +1 -0
  30. package/dist/commonjs/package.json +3 -0
  31. package/dist/commonjs/useIndexedChildren.d.ts +8 -0
  32. package/dist/commonjs/useIndexedChildren.d.ts.map +1 -0
  33. package/dist/commonjs/useIndexedChildren.js +81 -0
  34. package/dist/commonjs/useIndexedChildren.js.map +1 -0
  35. package/dist/commonjs/useMove.d.ts +8 -0
  36. package/dist/commonjs/useMove.d.ts.map +1 -0
  37. package/dist/commonjs/useMove.js +19 -0
  38. package/dist/commonjs/useMove.js.map +1 -0
  39. package/dist/esm/ReactWindowSplitter.d.ts +19 -0
  40. package/dist/esm/ReactWindowSplitter.d.ts.map +1 -0
  41. package/dist/esm/ReactWindowSplitter.js +532 -0
  42. package/dist/esm/ReactWindowSplitter.js.map +1 -0
  43. package/dist/esm/ReactWindowSplitter.stories.d.ts +47 -0
  44. package/dist/esm/ReactWindowSplitter.stories.d.ts.map +1 -0
  45. package/dist/esm/ReactWindowSplitter.stories.js +286 -0
  46. package/dist/esm/ReactWindowSplitter.stories.js.map +1 -0
  47. package/dist/esm/ReactWindowSplitter.test.d.ts +2 -0
  48. package/dist/esm/ReactWindowSplitter.test.d.ts.map +1 -0
  49. package/dist/esm/ReactWindowSplitter.test.js +191 -0
  50. package/dist/esm/ReactWindowSplitter.test.js.map +1 -0
  51. package/dist/esm/bundle.size.d.ts +2 -0
  52. package/dist/esm/bundle.size.d.ts.map +1 -0
  53. package/dist/esm/bundle.size.js +4 -0
  54. package/dist/esm/bundle.size.js.map +1 -0
  55. package/dist/esm/index.d.ts +3 -0
  56. package/dist/esm/index.d.ts.map +1 -0
  57. package/dist/esm/index.js +2 -0
  58. package/dist/esm/index.js.map +1 -0
  59. package/dist/esm/package.json +3 -0
  60. package/dist/esm/useIndexedChildren.d.ts +8 -0
  61. package/dist/esm/useIndexedChildren.d.ts.map +1 -0
  62. package/dist/esm/useIndexedChildren.js +54 -0
  63. package/dist/esm/useIndexedChildren.js.map +1 -0
  64. package/dist/esm/useMove.d.ts +8 -0
  65. package/dist/esm/useMove.d.ts.map +1 -0
  66. package/dist/esm/useMove.js +16 -0
  67. package/dist/esm/useMove.js.map +1 -0
  68. package/eslint.config.js +3 -0
  69. package/package.json +108 -0
  70. package/rsbuild.config.js +25 -0
  71. package/src/ReactWindowSplitter.stories.tsx +705 -0
  72. package/src/ReactWindowSplitter.test.tsx +384 -0
  73. package/src/ReactWindowSplitter.tsx +884 -0
  74. package/src/__snapshots__/ReactWindowSplitter.test.tsx.snap +58 -0
  75. package/src/bundle.size.ts +4 -0
  76. package/src/index.ts +2 -0
  77. package/src/useIndexedChildren.tsx +79 -0
  78. package/src/useMove.ts +22 -0
  79. package/tsconfig.json +6 -0
  80. package/vitest.config.ts +20 -0
  81. package/vitest.setup.ts +7 -0
@@ -0,0 +1,58 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`Autosave > cookie 1`] = `"autosave-cookie-example=%7B%22size%22%3A%7B%22x%22%3A0%2C%22y%22%3A0%2C%22width%22%3A500%2C%22height%22%3A200%2C%22top%22%3A0%2C%22right%22%3A500%2C%22bottom%22%3A200%2C%22left%22%3A0%7D%2C%22items%22%3A%5B%7B%22type%22%3A%22panel%22%2C%22min%22%3A%7B%22type%22%3A%22pixel%22%2C%22value%22%3A%220%22%7D%2C%22max%22%3A%221fr%22%2C%22collapsible%22%3Afalse%2C%22collapsedSize%22%3A%7B%22type%22%3A%22pixel%22%2C%22value%22%3A%220%22%7D%2C%22onCollapseChange%22%3A%7B%7D%2C%22onResize%22%3A%7B%7D%2C%22collapseIsControlled%22%3Afalse%2C%22id%22%3A%22panel1%22%2C%22currentValue%22%3A%7B%22type%22%3A%22percent%22%2C%22value%22%3A%220.7%22%7D%7D%2C%7B%22type%22%3A%22handle%22%2C%22size%22%3A%7B%22type%22%3A%22pixel%22%2C%22value%22%3A%2210%22%7D%2C%22id%22%3A%22resizer1%22%7D%2C%7B%22type%22%3A%22panel%22%2C%22min%22%3A%7B%22type%22%3A%22pixel%22%2C%22value%22%3A%220%22%7D%2C%22max%22%3A%221fr%22%2C%22collapsible%22%3Afalse%2C%22collapsedSize%22%3A%7B%22type%22%3A%22pixel%22%2C%22value%22%3A%220%22%7D%2C%22onCollapseChange%22%3A%7B%7D%2C%22onResize%22%3A%7B%7D%2C%22collapseIsControlled%22%3Afalse%2C%22id%22%3A%22panel2%22%2C%22currentValue%22%3A%7B%22type%22%3A%22percent%22%2C%22value%22%3A%220.3%22%7D%7D%5D%2C%22orientation%22%3A%22horizontal%22%2C%22dragOvershoot%22%3A%220%22%2C%22groupId%22%3A%22autosave-cookie-example%22%2C%22autosaveStrategy%22%3A%22cookie%22%7D"`;
4
+
5
+ exports[`Autosave > localStorage 1`] = `
6
+ [
7
+ {
8
+ "collapseIsControlled": false,
9
+ "collapsedSize": {
10
+ "type": "pixel",
11
+ "value": "0",
12
+ },
13
+ "collapsible": false,
14
+ "currentValue": {
15
+ "type": "percent",
16
+ "value": "0.70081967213114754098",
17
+ },
18
+ "id": "1",
19
+ "max": "1fr",
20
+ "min": {
21
+ "type": "pixel",
22
+ "value": "0",
23
+ },
24
+ "onCollapseChange": {},
25
+ "onResize": {},
26
+ "type": "panel",
27
+ },
28
+ {
29
+ "id": "resizer",
30
+ "size": {
31
+ "type": "pixel",
32
+ "value": "10",
33
+ },
34
+ "type": "handle",
35
+ },
36
+ {
37
+ "collapseIsControlled": false,
38
+ "collapsedSize": {
39
+ "type": "pixel",
40
+ "value": "0",
41
+ },
42
+ "collapsible": false,
43
+ "currentValue": {
44
+ "type": "percent",
45
+ "value": "0.29918032786885245902",
46
+ },
47
+ "id": "2",
48
+ "max": "1fr",
49
+ "min": {
50
+ "type": "pixel",
51
+ "value": "0",
52
+ },
53
+ "onCollapseChange": {},
54
+ "onResize": {},
55
+ "type": "panel",
56
+ },
57
+ ]
58
+ `;
@@ -0,0 +1,4 @@
1
+ import * as windowSplitter from "./ReactWindowSplitter.js";
2
+
3
+ // eslint-disable-next-line no-console
4
+ console.log(windowSplitter);
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./ReactWindowSplitter.js";
2
+ export { PanelHandle, PanelGroupHandle } from "@window-splitter/interface";
@@ -0,0 +1,79 @@
1
+ // File largely copied from https://github.com/souporserious/reforest
2
+
3
+ import * as React from "react";
4
+
5
+ const IndexContext = React.createContext<string | null>(null);
6
+
7
+ /**
8
+ * Parses a numerical dot-separated string as an index path.
9
+ *
10
+ * @example
11
+ * parseIndexPath('0.10.2') -> [0, 10, 2]
12
+ */
13
+ function parseIndexPath(indexPathString: string) {
14
+ return indexPathString.split(".").map((index) => parseInt(index, 10));
15
+ }
16
+
17
+ /** Returns the index path data based on the closest useIndexedChildren. */
18
+ export function useIndex() {
19
+ const indexPathString = React.useContext(IndexContext);
20
+
21
+ return React.useMemo(() => {
22
+ if (indexPathString === null) {
23
+ throw new Error("Panels/PanelResizers must be used within a PanelGroup");
24
+ }
25
+
26
+ const indexPath = parseIndexPath(indexPathString);
27
+ return { index: indexPath[indexPath.length - 1]! };
28
+ }, [indexPathString]);
29
+ }
30
+
31
+ function flattenChildren(children: React.ReactNode[]): React.ReactNode[] {
32
+ const flattenedChildren = children.flatMap((child) => {
33
+ // For fragments we want to get rid of those so the children are flat
34
+ if (React.isValidElement(child) && child.type === React.Fragment) {
35
+ return flattenChildren(child.props.children);
36
+ }
37
+
38
+ return child;
39
+ });
40
+
41
+ return flattenedChildren.map((child, index) => {
42
+ if (!React.isValidElement(child)) return child;
43
+
44
+ // We then correct the keys for the order of the children
45
+ // eslint-disable-next-line @eslint-react/no-clone-element
46
+ return React.cloneElement(child, {
47
+ // eslint-disable-next-line @eslint-react/no-array-index-key
48
+ key: `.${index}`,
49
+ });
50
+ });
51
+ }
52
+
53
+ /** Provides the current index path for each child. */
54
+ export function useIndexedChildren(childrenProp: React.ReactNode) {
55
+ const indexPathString = React.useContext(IndexContext);
56
+
57
+ return (
58
+ <>
59
+ {/* eslint-disable-next-line @eslint-react/no-children-to-array */}
60
+ {flattenChildren(React.Children.toArray(childrenProp)).map(
61
+ (child, index) => {
62
+ if (!React.isValidElement(child)) return child;
63
+ return (
64
+ <IndexContext.Provider
65
+ key={child.key}
66
+ value={
67
+ indexPathString
68
+ ? `${indexPathString}.${index.toString()}`
69
+ : index.toString()
70
+ }
71
+ >
72
+ {child}
73
+ </IndexContext.Provider>
74
+ );
75
+ }
76
+ )}
77
+ </>
78
+ );
79
+ }
package/src/useMove.ts ADDED
@@ -0,0 +1,22 @@
1
+ import { useEffectEvent } from "@react-aria/utils";
2
+ import { move, MoveEvents } from "@window-splitter/interface";
3
+ import { useMemo } from "react";
4
+
5
+ export function useMove({ onMoveStart, onMove, onMoveEnd }: MoveEvents) {
6
+ const onMoveStartEvent = useEffectEvent(onMoveStart);
7
+ const onMoveEvent = useEffectEvent(onMove);
8
+ const onMoveEndEvent = useEffectEvent(onMoveEnd);
9
+
10
+ return useMemo(() => {
11
+ return move({
12
+ onMoveStart: onMoveStartEvent,
13
+ onMove: onMoveEvent,
14
+ onMoveEnd: onMoveEndEvent,
15
+ }) as unknown as {
16
+ moveProps: {
17
+ onPointerDown: (e: React.PointerEvent) => void;
18
+ onKeyDown: (e: React.KeyboardEvent) => void;
19
+ };
20
+ };
21
+ }, [onMoveStartEvent, onMoveEvent, onMoveEndEvent]);
22
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["@testing-library/jest-dom"]
5
+ }
6
+ }
@@ -0,0 +1,20 @@
1
+ import { defineConfig } from "vitest/config";
2
+ import react from "@vitejs/plugin-react";
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ test: {
7
+ setupFiles: ["./vitest.setup.ts"],
8
+ coverage: {
9
+ provider: "istanbul",
10
+ include: ["**/*.tsx", "!**/*.stories.tsx", "!**/*.test.tsx"],
11
+ reporter: ["text", "html", "json-summary", "json"],
12
+ reportOnFailure: true,
13
+ },
14
+ browser: {
15
+ enabled: true,
16
+ provider: "playwright",
17
+ instances: [{ browser: "chromium" }],
18
+ },
19
+ },
20
+ });
@@ -0,0 +1,7 @@
1
+ import "@testing-library/jest-dom/vitest";
2
+ import { cleanup } from "@testing-library/react";
3
+ import { afterEach } from "vitest";
4
+
5
+ afterEach(() => {
6
+ cleanup();
7
+ });