@dxos/react-ui-stack 0.7.5-main.9d26e3a → 0.7.5-main.b19bfc8
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.
- package/dist/lib/browser/index.mjs +173 -176
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +201 -203
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +173 -176
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/MenuSignifier.d.ts +2 -3
- package/dist/types/src/components/MenuSignifier.d.ts.map +1 -1
- package/dist/types/src/components/Stack.d.ts +6 -1
- package/dist/types/src/components/Stack.d.ts.map +1 -1
- package/dist/types/src/components/Stack.stories.d.ts +1 -2
- package/dist/types/src/components/Stack.stories.d.ts.map +1 -1
- package/dist/types/src/components/StackContext.d.ts +2 -1
- package/dist/types/src/components/StackContext.d.ts.map +1 -1
- package/dist/types/src/components/StackItem.d.ts +13 -5
- package/dist/types/src/components/StackItem.d.ts.map +1 -1
- package/dist/types/src/components/StackItemContent.d.ts +35 -2
- package/dist/types/src/components/StackItemContent.d.ts.map +1 -1
- package/dist/types/src/components/StackItemDragHandle.d.ts +2 -2
- package/dist/types/src/components/StackItemDragHandle.d.ts.map +1 -1
- package/dist/types/src/components/StackItemHeading.d.ts +1 -1
- package/dist/types/src/components/StackItemHeading.d.ts.map +1 -1
- package/dist/types/src/components/StackItemResizeHandle.d.ts +1 -2
- package/dist/types/src/components/StackItemResizeHandle.d.ts.map +1 -1
- package/dist/types/src/components/StackItemSigil.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useStackDropForElements.d.ts +15 -0
- package/dist/types/src/hooks/useStackDropForElements.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -27
- package/src/components/Stack.stories.tsx +1 -1
- package/src/components/Stack.tsx +44 -57
- package/src/components/StackContext.tsx +3 -1
- package/src/components/StackItem.tsx +45 -14
- package/src/components/StackItemContent.tsx +48 -28
- package/src/components/StackItemHeading.tsx +2 -2
- package/src/components/StackItemResizeHandle.tsx +12 -98
- package/src/components/StackItemSigil.tsx +90 -103
- package/src/hooks/index.ts +5 -0
- package/src/hooks/useStackDropForElements.ts +73 -0
- package/dist/types/src/playwright/playwright.config.d.ts +0 -3
- package/dist/types/src/playwright/playwright.config.d.ts.map +0 -1
- package/dist/types/src/testing/EditorContent.d.ts +0 -8
- package/dist/types/src/testing/EditorContent.d.ts.map +0 -1
- package/src/testing/EditorContent.tsx +0 -60
- /package/src/playwright/{playwright.config.ts → playwright.config.cts} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type ComponentPropsWithoutRef } from 'react';
|
|
2
2
|
export type StackItemDragHandleProps = ComponentPropsWithoutRef<'button'> & {
|
|
3
3
|
asChild: boolean;
|
|
4
4
|
};
|
|
5
|
-
export declare const StackItemDragHandle: ({ asChild, children }: StackItemDragHandleProps) =>
|
|
5
|
+
export declare const StackItemDragHandle: ({ asChild, children }: StackItemDragHandleProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
//# sourceMappingURL=StackItemDragHandle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackItemDragHandle.d.ts","sourceRoot":"","sources":["../../../../src/components/StackItemDragHandle.tsx"],"names":[],"mappings":"AAKA,
|
|
1
|
+
{"version":3,"file":"StackItemDragHandle.d.ts","sourceRoot":"","sources":["../../../../src/components/StackItemDragHandle.tsx"],"names":[],"mappings":"AAKA,OAAc,EAAE,KAAK,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAI7D,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAAC,QAAQ,CAAC,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAEjG,eAAO,MAAM,mBAAmB,0BAA2B,wBAAwB,4CAUlF,CAAC"}
|
|
@@ -2,7 +2,7 @@ import React, { type ComponentPropsWithoutRef, type ComponentPropsWithRef } from
|
|
|
2
2
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
3
3
|
import { type AttendableId, type Related } from '@dxos/react-ui-attention';
|
|
4
4
|
export type StackItemHeadingProps = ThemedClassName<ComponentPropsWithoutRef<'div'>>;
|
|
5
|
-
export declare const StackItemHeading: ({ children, classNames, ...props }: StackItemHeadingProps) =>
|
|
5
|
+
export declare const StackItemHeading: ({ children, classNames, ...props }: StackItemHeadingProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export type StackItemHeadingLabelProps = ThemedClassName<ComponentPropsWithRef<'h1'>> & AttendableId & Related;
|
|
7
7
|
export declare const StackItemHeadingLabel: React.ForwardRefExoticComponent<Omit<StackItemHeadingLabelProps, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
|
|
8
8
|
//# sourceMappingURL=StackItemHeading.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackItemHeading.d.ts","sourceRoot":"","sources":["../../../../src/components/StackItemHeading.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,KAAK,wBAAwB,EAAE,KAAK,qBAAqB,EAAc,MAAM,OAAO,CAAC;AAErG,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAgB,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAKzF,MAAM,MAAM,qBAAqB,GAAG,eAAe,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;AAErF,eAAO,MAAM,gBAAgB,uCAAwC,qBAAqB,
|
|
1
|
+
{"version":3,"file":"StackItemHeading.d.ts","sourceRoot":"","sources":["../../../../src/components/StackItemHeading.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,KAAK,wBAAwB,EAAE,KAAK,qBAAqB,EAAc,MAAM,OAAO,CAAC;AAErG,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAgB,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAKzF,MAAM,MAAM,qBAAqB,GAAG,eAAe,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;AAErF,eAAO,MAAM,gBAAgB,uCAAwC,qBAAqB,4CAkBzF,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,eAAe,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,GAAG,OAAO,CAAC;AAE/G,eAAO,MAAM,qBAAqB,oHAejC,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
export type StackItemResizeHandleProps = {};
|
|
3
|
-
export declare const StackItemResizeHandle: () =>
|
|
2
|
+
export declare const StackItemResizeHandle: () => import("react/jsx-runtime").JSX.Element;
|
|
4
3
|
//# sourceMappingURL=StackItemResizeHandle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackItemResizeHandle.d.ts","sourceRoot":"","sources":["../../../../src/components/StackItemResizeHandle.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StackItemResizeHandle.d.ts","sourceRoot":"","sources":["../../../../src/components/StackItemResizeHandle.tsx"],"names":[],"mappings":"AAcA,MAAM,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAE5C,eAAO,MAAM,qBAAqB,+CAajC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackItemSigil.d.ts","sourceRoot":"","sources":["../../../../src/components/StackItemSigil.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAY,KAAK,iBAAiB,EAAgC,MAAM,OAAO,CAAC;AAE9F,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,
|
|
1
|
+
{"version":3,"file":"StackItemSigil.d.ts","sourceRoot":"","sources":["../../../../src/components/StackItemSigil.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAY,KAAK,iBAAiB,EAAgC,MAAM,OAAO,CAAC;AAE9F,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAU,KAAK,WAAW,EAAyD,MAAM,gBAAgB,CAAC;AACjH,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,OAAO,EAAgB,MAAM,0BAA0B,CAAC;AAOzF,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,YAAY,GAAG,MAAM,CAAC,CAAC;AAElF,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,GAAG,YAAY,GAAG,OAAO,CAAC;AAE9F,eAAO,MAAM,oBAAoB,kHAgBhC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CACjD;IACE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,oBAAoB,EAAE,EAAE,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACnD,GAAG,OAAO,CACZ,CAAC;AAEF,eAAO,MAAM,cAAc;mBARR,MAAM;kBACP,MAAM;cACV,oBAAoB,EAAE,EAAE;UAC5B,MAAM;eACD,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI;;;2CAwGpD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Orientation } from '../components/Stack';
|
|
2
|
+
import { type StackItemRearrangeHandler } from '../components/StackContext';
|
|
3
|
+
/**
|
|
4
|
+
* Hook to handle drag and drop functionality for Stack components.
|
|
5
|
+
*/
|
|
6
|
+
export declare const useStackDropForElements: ({ element, selfDroppable, orientation, id, onRearrange, }: {
|
|
7
|
+
element: HTMLDivElement | null;
|
|
8
|
+
selfDroppable: boolean;
|
|
9
|
+
orientation: Orientation;
|
|
10
|
+
id?: string;
|
|
11
|
+
onRearrange?: StackItemRearrangeHandler;
|
|
12
|
+
}) => {
|
|
13
|
+
dropping: boolean;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useStackDropForElements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStackDropForElements.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useStackDropForElements.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,KAAK,yBAAyB,EAAsB,MAAM,4BAA4B,CAAC;AAEhG;;GAEG;AACH,eAAO,MAAM,uBAAuB,8DAMjC;IACD,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,yBAAyB,CAAC;CACzC;;CA4CA,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"5.7.
|
|
1
|
+
{"version":"5.7.3"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-stack",
|
|
3
|
-
"version": "0.7.5-main.
|
|
3
|
+
"version": "0.7.5-main.b19bfc8",
|
|
4
4
|
"description": "A stack component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": "DXOS.org",
|
|
9
9
|
"sideEffects": true,
|
|
10
|
+
"type": "module",
|
|
10
11
|
"exports": {
|
|
11
12
|
".": {
|
|
12
13
|
"types": "./dist/types/src/index.d.ts",
|
|
@@ -36,22 +37,23 @@
|
|
|
36
37
|
],
|
|
37
38
|
"dependencies": {
|
|
38
39
|
"@atlaskit/pragmatic-drag-and-drop": "^1.4.0",
|
|
40
|
+
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.0",
|
|
39
41
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
|
|
40
42
|
"@effect/schema": "^0.75.5",
|
|
41
|
-
"@fluentui/react-tabster": "
|
|
42
|
-
"@radix-ui/primitive": "
|
|
43
|
-
"@radix-ui/react-compose-refs": "
|
|
44
|
-
"@radix-ui/react-context": "
|
|
45
|
-
"@radix-ui/react-menu": "
|
|
46
|
-
"@radix-ui/react-slot": "
|
|
47
|
-
"@radix-ui/react-use-controllable-state": "
|
|
43
|
+
"@fluentui/react-tabster": "9.23.3",
|
|
44
|
+
"@radix-ui/primitive": "1.1.1",
|
|
45
|
+
"@radix-ui/react-compose-refs": "1.1.1",
|
|
46
|
+
"@radix-ui/react-context": "1.1.1",
|
|
47
|
+
"@radix-ui/react-menu": "2.1.6",
|
|
48
|
+
"@radix-ui/react-slot": "1.1.2",
|
|
49
|
+
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
48
50
|
"react-resize-detector": "^11.0.1",
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/live-object": "0.7.5-main.
|
|
52
|
-
"@dxos/react-ui-
|
|
53
|
-
"@dxos/react-ui-
|
|
54
|
-
"@dxos/util": "0.7.5-main.
|
|
51
|
+
"@dxos/keyboard": "0.7.5-main.b19bfc8",
|
|
52
|
+
"@dxos/echo-schema": "0.7.5-main.b19bfc8",
|
|
53
|
+
"@dxos/live-object": "0.7.5-main.b19bfc8",
|
|
54
|
+
"@dxos/react-ui-attention": "0.7.5-main.b19bfc8",
|
|
55
|
+
"@dxos/react-ui-dnd": "0.7.5-main.b19bfc8",
|
|
56
|
+
"@dxos/util": "0.7.5-main.b19bfc8"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
59
|
"@phosphor-icons/react": "^2.1.5",
|
|
@@ -60,24 +62,24 @@
|
|
|
60
62
|
"react": "~18.2.0",
|
|
61
63
|
"react-dom": "~18.2.0",
|
|
62
64
|
"vite": "5.4.7",
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/
|
|
65
|
-
"@dxos/
|
|
66
|
-
"@dxos/
|
|
67
|
-
"@dxos/react-ui": "0.7.5-main.
|
|
68
|
-
"@dxos/react-ui-editor": "0.7.5-main.
|
|
69
|
-
"@dxos/react-ui-theme": "0.7.5-main.
|
|
70
|
-
"@dxos/storybook-utils": "0.7.5-main.
|
|
71
|
-
"@dxos/test-utils": "0.7.5-main.
|
|
65
|
+
"@dxos/client": "0.7.5-main.b19bfc8",
|
|
66
|
+
"@dxos/app-graph": "0.7.5-main.b19bfc8",
|
|
67
|
+
"@dxos/echo-schema": "0.7.5-main.b19bfc8",
|
|
68
|
+
"@dxos/random": "0.7.5-main.b19bfc8",
|
|
69
|
+
"@dxos/react-ui": "0.7.5-main.b19bfc8",
|
|
70
|
+
"@dxos/react-ui-editor": "0.7.5-main.b19bfc8",
|
|
71
|
+
"@dxos/react-ui-theme": "0.7.5-main.b19bfc8",
|
|
72
|
+
"@dxos/storybook-utils": "0.7.5-main.b19bfc8",
|
|
73
|
+
"@dxos/test-utils": "0.7.5-main.b19bfc8"
|
|
72
74
|
},
|
|
73
75
|
"peerDependencies": {
|
|
74
76
|
"@phosphor-icons/react": "^2.1.5",
|
|
75
77
|
"react": "~18.2.0",
|
|
76
78
|
"react-dom": "~18.2.0",
|
|
77
|
-
"@dxos/
|
|
78
|
-
"@dxos/
|
|
79
|
-
"@dxos/
|
|
80
|
-
"@dxos/
|
|
79
|
+
"@dxos/client": "0.7.5-main.b19bfc8",
|
|
80
|
+
"@dxos/react-ui": "0.7.5-main.b19bfc8",
|
|
81
|
+
"@dxos/random": "0.7.5-main.b19bfc8",
|
|
82
|
+
"@dxos/react-ui-theme": "0.7.5-main.b19bfc8"
|
|
81
83
|
},
|
|
82
84
|
"publishConfig": {
|
|
83
85
|
"access": "public"
|
|
@@ -126,7 +126,7 @@ export const Default: Story = {
|
|
|
126
126
|
};
|
|
127
127
|
|
|
128
128
|
const meta: Meta<typeof StorybookStack> = {
|
|
129
|
-
title: 'ui/react-ui-stack
|
|
129
|
+
title: 'ui/react-ui-stack/Stack',
|
|
130
130
|
component: StorybookStack,
|
|
131
131
|
decorators: [withTheme],
|
|
132
132
|
argTypes: { orientation: { control: 'radio', options: ['horizontal', 'vertical'] } },
|
package/src/components/Stack.tsx
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
//
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
|
-
|
|
5
|
-
import { attachClosestEdge, extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
4
|
+
|
|
6
5
|
import { useArrowNavigationGroup } from '@fluentui/react-tabster';
|
|
7
6
|
import { composeRefs } from '@radix-ui/react-compose-refs';
|
|
8
|
-
import React, {
|
|
9
|
-
Children,
|
|
10
|
-
type CSSProperties,
|
|
11
|
-
type ComponentPropsWithRef,
|
|
12
|
-
forwardRef,
|
|
13
|
-
useLayoutEffect,
|
|
14
|
-
useState,
|
|
15
|
-
} from 'react';
|
|
7
|
+
import React, { Children, type CSSProperties, type ComponentPropsWithRef, forwardRef, useState, useMemo } from 'react';
|
|
16
8
|
|
|
17
9
|
import { type ThemedClassName, ListItem } from '@dxos/react-ui';
|
|
18
10
|
import { mx } from '@dxos/react-ui-theme';
|
|
19
11
|
|
|
20
|
-
import { type StackContextValue, StackContext
|
|
12
|
+
import { type StackContextValue, StackContext } from './StackContext';
|
|
13
|
+
import { useStackDropForElements } from '../hooks';
|
|
21
14
|
|
|
22
15
|
export type Orientation = 'horizontal' | 'vertical';
|
|
23
|
-
export type Size = 'intrinsic' | 'contain';
|
|
16
|
+
export type Size = 'intrinsic' | 'contain' | 'contain-fit-content';
|
|
24
17
|
|
|
25
18
|
export type StackProps = Omit<ThemedClassName<ComponentPropsWithRef<'div'>>, 'aria-orientation'> &
|
|
26
19
|
Partial<StackContextValue> & { itemsCount?: number };
|
|
27
20
|
|
|
28
21
|
export const railGridHorizontal = 'grid-rows-[[rail-start]_var(--rail-size)_[content-start]_1fr_[content-end]]';
|
|
29
|
-
|
|
30
22
|
export const railGridVertical = 'grid-cols-[[rail-start]_var(--rail-size)_[content-start]_1fr_[content-end]]';
|
|
31
23
|
|
|
24
|
+
// TODO(ZaymonFC): Magic 2px to stop overflow (tabster dummies... ask @thure).
|
|
25
|
+
export const railGridHorizontalContainFitContent =
|
|
26
|
+
'grid-rows-[[rail-start]_var(--rail-size)_[content-start]_fit-content(calc(100%-var(--rail-size)*2+2px))_[content-end]]';
|
|
27
|
+
export const railGridVerticalContainFitContent =
|
|
28
|
+
'grid-cols-[[rail-start]_var(--rail-size)_[content-start]_fit-content(calc(100%-var(--rail-size)*2+2px))_[content-end]]';
|
|
29
|
+
|
|
30
|
+
export const autoScrollRootAttributes = { 'data-drag-autoscroll': 'idle' };
|
|
31
|
+
|
|
32
32
|
export const Stack = forwardRef<HTMLDivElement, StackProps>(
|
|
33
33
|
(
|
|
34
34
|
{
|
|
@@ -46,49 +46,34 @@ export const Stack = forwardRef<HTMLDivElement, StackProps>(
|
|
|
46
46
|
) => {
|
|
47
47
|
const [stackElement, stackRef] = useState<HTMLDivElement | null>(null);
|
|
48
48
|
const composedItemRef = composeRefs<HTMLDivElement>(stackRef, forwardedRef);
|
|
49
|
-
const [dropping, setDropping] = useState(false);
|
|
50
|
-
|
|
51
49
|
const arrowNavigationGroup = useArrowNavigationGroup({ axis: orientation });
|
|
52
50
|
|
|
53
51
|
const styles: CSSProperties = {
|
|
54
|
-
[orientation === 'horizontal' ? 'gridTemplateColumns' : 'gridTemplateRows']:
|
|
52
|
+
[orientation === 'horizontal' ? 'gridTemplateColumns' : 'gridTemplateRows']:
|
|
53
|
+
`repeat(${itemsCount}, min-content) [tabster-dummies] 0`,
|
|
55
54
|
...style,
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
const selfDroppable = !!(itemsCount < 1 && onRearrange && props.id);
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
const { dropping } = useStackDropForElements({
|
|
60
|
+
id: props.id,
|
|
61
|
+
element: stackElement,
|
|
62
|
+
selfDroppable,
|
|
63
|
+
orientation,
|
|
64
|
+
onRearrange,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const gridClasses = useMemo(() => {
|
|
68
|
+
if (!rail) {
|
|
69
|
+
return orientation === 'horizontal' ? 'grid-rows-1 pli-1' : 'grid-cols-1 plb-1';
|
|
63
70
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
{ input, element, allowedEdges: [orientation === 'horizontal' ? 'left' : 'top'] },
|
|
71
|
-
);
|
|
72
|
-
},
|
|
73
|
-
onDragEnter: ({ source }) => {
|
|
74
|
-
if (source.data.type === acceptSourceType) {
|
|
75
|
-
setDropping(true);
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
onDrag: ({ source }) => {
|
|
79
|
-
if (source.data.type === acceptSourceType) {
|
|
80
|
-
setDropping(true);
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
onDragLeave: () => setDropping(false),
|
|
84
|
-
onDrop: ({ self, source }) => {
|
|
85
|
-
setDropping(false);
|
|
86
|
-
if (source.data.type === acceptSourceType && selfDroppable) {
|
|
87
|
-
onRearrange(source.data as StackItemData, self.data as StackItemData, extractClosestEdge(self.data));
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
}, [stackElement, selfDroppable]);
|
|
71
|
+
if (orientation === 'horizontal') {
|
|
72
|
+
return size === 'contain-fit-content' ? railGridHorizontalContainFitContent : railGridHorizontal;
|
|
73
|
+
} else {
|
|
74
|
+
return size === 'contain-fit-content' ? railGridVerticalContainFitContent : railGridVertical;
|
|
75
|
+
}
|
|
76
|
+
}, [rail, orientation, size]);
|
|
92
77
|
|
|
93
78
|
return (
|
|
94
79
|
<StackContext.Provider value={{ orientation, rail, size, onRearrange }}>
|
|
@@ -97,25 +82,27 @@ export const Stack = forwardRef<HTMLDivElement, StackProps>(
|
|
|
97
82
|
{...arrowNavigationGroup}
|
|
98
83
|
className={mx(
|
|
99
84
|
'grid relative',
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
? railGridHorizontal
|
|
103
|
-
: railGridVertical
|
|
104
|
-
: orientation === 'horizontal'
|
|
105
|
-
? 'grid-rows-1'
|
|
106
|
-
: 'grid-cols-1',
|
|
107
|
-
size === 'contain' &&
|
|
85
|
+
gridClasses,
|
|
86
|
+
(size === 'contain' || size === 'contain-fit-content') &&
|
|
108
87
|
(orientation === 'horizontal'
|
|
109
88
|
? 'overflow-x-auto min-bs-0 bs-full max-bs-full'
|
|
110
89
|
: 'overflow-y-auto min-is-0 is-full max-is-full'),
|
|
111
90
|
classNames,
|
|
112
91
|
)}
|
|
92
|
+
data-rail={rail}
|
|
113
93
|
aria-orientation={orientation}
|
|
114
94
|
style={styles}
|
|
115
95
|
ref={composedItemRef}
|
|
116
96
|
>
|
|
117
97
|
{children}
|
|
118
|
-
{selfDroppable && dropping &&
|
|
98
|
+
{selfDroppable && dropping && (
|
|
99
|
+
<ListItem.DropIndicator
|
|
100
|
+
lineInset={8}
|
|
101
|
+
terminalInset={-8}
|
|
102
|
+
gap={-8}
|
|
103
|
+
edge={orientation === 'horizontal' ? 'left' : 'top'}
|
|
104
|
+
/>
|
|
105
|
+
)}
|
|
119
106
|
</div>
|
|
120
107
|
</StackContext.Provider>
|
|
121
108
|
);
|
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
import type { Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
6
6
|
import { createContext, useContext } from 'react';
|
|
7
7
|
|
|
8
|
+
import { type Size as DndSize } from '@dxos/react-ui-dnd';
|
|
9
|
+
|
|
8
10
|
import { type Orientation, type Size } from './Stack';
|
|
9
11
|
|
|
10
|
-
export type StackItemSize =
|
|
12
|
+
export type StackItemSize = DndSize;
|
|
11
13
|
|
|
12
14
|
export type StackItemData = { id: string; type: 'column' | 'card' };
|
|
13
15
|
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
|
6
6
|
import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';
|
|
8
|
+
import { scrollJustEnoughIntoView } from '@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view';
|
|
9
9
|
import {
|
|
10
10
|
attachClosestEdge,
|
|
11
11
|
extractClosestEdge,
|
|
@@ -16,6 +16,7 @@ import { composeRefs } from '@radix-ui/react-compose-refs';
|
|
|
16
16
|
import React, { forwardRef, useLayoutEffect, useState, type ComponentPropsWithRef, useCallback } from 'react';
|
|
17
17
|
|
|
18
18
|
import { type ThemedClassName, ListItem } from '@dxos/react-ui';
|
|
19
|
+
import { resizeAttributes, sizeStyle } from '@dxos/react-ui-dnd';
|
|
19
20
|
import { mx } from '@dxos/react-ui-theme';
|
|
20
21
|
|
|
21
22
|
import { useStack, StackItemContext, type StackItemSize, type StackItemData } from './StackContext';
|
|
@@ -46,10 +47,27 @@ export type StackItemRootProps = ThemedClassName<ComponentPropsWithRef<'div'>> &
|
|
|
46
47
|
size?: StackItemSize;
|
|
47
48
|
onSizeChange?: (nextSize: StackItemSize) => void;
|
|
48
49
|
role?: 'article' | 'section';
|
|
50
|
+
disableRearrange?: boolean;
|
|
51
|
+
focusIndicatorVariant?: 'over-all' | 'group';
|
|
49
52
|
};
|
|
50
53
|
|
|
51
54
|
const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
52
|
-
(
|
|
55
|
+
(
|
|
56
|
+
{
|
|
57
|
+
item,
|
|
58
|
+
children,
|
|
59
|
+
classNames,
|
|
60
|
+
size: propsSize,
|
|
61
|
+
onSizeChange,
|
|
62
|
+
role,
|
|
63
|
+
order,
|
|
64
|
+
style,
|
|
65
|
+
disableRearrange,
|
|
66
|
+
focusIndicatorVariant = 'over-all',
|
|
67
|
+
...props
|
|
68
|
+
},
|
|
69
|
+
forwardedRef,
|
|
70
|
+
) => {
|
|
53
71
|
const [itemElement, itemRef] = useState<HTMLDivElement | null>(null);
|
|
54
72
|
const [selfDragHandleElement, selfDragHandleRef] = useState<HTMLDivElement | null>(null);
|
|
55
73
|
const [closestEdge, setEdge] = useState<Edge | null>(null);
|
|
@@ -74,7 +92,7 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
|
74
92
|
const type = orientation === 'horizontal' ? 'column' : 'card';
|
|
75
93
|
|
|
76
94
|
useLayoutEffect(() => {
|
|
77
|
-
if (!itemElement || !onRearrange) {
|
|
95
|
+
if (!itemElement || !onRearrange || disableRearrange) {
|
|
78
96
|
return;
|
|
79
97
|
}
|
|
80
98
|
return combine(
|
|
@@ -82,10 +100,20 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
|
82
100
|
element: itemElement,
|
|
83
101
|
...(selfDragHandleElement && { dragHandle: selfDragHandleElement }),
|
|
84
102
|
getInitialData: () => ({ id: item.id, type }),
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
103
|
+
onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
|
|
104
|
+
document.body.setAttribute('data-drag-preview', 'true');
|
|
105
|
+
scrollJustEnoughIntoView({ element: source.element });
|
|
106
|
+
const { x, y } = preserveOffsetOnSource({ element: source.element, input: location.current.input })({
|
|
107
|
+
container: (source.element.offsetParent ?? document.body) as HTMLElement,
|
|
108
|
+
});
|
|
109
|
+
nativeSetDragImage?.(source.element, x, y);
|
|
110
|
+
},
|
|
111
|
+
onDragStart: () => {
|
|
112
|
+
document.body.removeAttribute('data-drag-preview');
|
|
113
|
+
itemElement?.closest('[data-drag-autoscroll]')?.setAttribute('data-drag-autoscroll', 'active');
|
|
114
|
+
},
|
|
115
|
+
onDrop: () => {
|
|
116
|
+
itemElement?.closest('[data-drag-autoscroll]')?.setAttribute('data-drag-autoscroll', 'idle');
|
|
89
117
|
},
|
|
90
118
|
}),
|
|
91
119
|
dropTargetForElements({
|
|
@@ -126,17 +154,20 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
|
126
154
|
tabIndex={0}
|
|
127
155
|
{...focusGroupAttrs}
|
|
128
156
|
className={mx(
|
|
129
|
-
'group/stack-item grid relative
|
|
130
|
-
|
|
157
|
+
'group/stack-item grid relative',
|
|
158
|
+
focusIndicatorVariant === 'over-all'
|
|
159
|
+
? 'dx-focus-ring-inset-over-all'
|
|
160
|
+
: orientation === 'horizontal'
|
|
161
|
+
? 'dx-focus-ring-group-x'
|
|
162
|
+
: 'dx-focus-ring-group-y',
|
|
131
163
|
orientation === 'horizontal' ? 'grid-rows-subgrid' : 'grid-cols-subgrid',
|
|
132
164
|
rail && (orientation === 'horizontal' ? 'row-span-2' : 'col-span-2'),
|
|
133
165
|
classNames,
|
|
134
166
|
)}
|
|
135
167
|
data-dx-stack-item
|
|
168
|
+
{...resizeAttributes}
|
|
136
169
|
style={{
|
|
137
|
-
...(size
|
|
138
|
-
[orientation === 'horizontal' ? 'inlineSize' : 'blockSize']: `${size}rem`,
|
|
139
|
-
}),
|
|
170
|
+
...sizeStyle(size, orientation),
|
|
140
171
|
...(Number.isFinite(order) && {
|
|
141
172
|
[orientation === 'horizontal' ? 'gridColumn' : 'gridRow']: `${order}`,
|
|
142
173
|
}),
|
|
@@ -145,7 +176,7 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
|
145
176
|
ref={composedItemRef}
|
|
146
177
|
>
|
|
147
178
|
{children}
|
|
148
|
-
{closestEdge && <ListItem.DropIndicator edge={closestEdge} />}
|
|
179
|
+
{closestEdge && <ListItem.DropIndicator lineInset={8} terminalInset={-8} edge={closestEdge} />}
|
|
149
180
|
</Root>
|
|
150
181
|
</StackItemContext.Provider>
|
|
151
182
|
);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { type ComponentPropsWithoutRef } from 'react';
|
|
5
|
+
import React, { type ComponentPropsWithoutRef, forwardRef } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
8
8
|
import { mx } from '@dxos/react-ui-theme';
|
|
@@ -10,33 +10,53 @@ import { mx } from '@dxos/react-ui-theme';
|
|
|
10
10
|
import { useStack } from './StackContext';
|
|
11
11
|
|
|
12
12
|
export type StackItemContentProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & {
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* This flag is required in order to clarify a developer experience that seemed like it needed extra boilerplate
|
|
15
|
+
* (`row-span-2`) or was buggy. See the description of the StackItem.Content component itself for more information.
|
|
16
|
+
*/
|
|
17
|
+
toolbar: boolean;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Whether to provide for the layout of a statusbar after the content.
|
|
21
|
+
*/
|
|
14
22
|
statusbar?: boolean;
|
|
15
|
-
};
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
...props
|
|
23
|
-
}: StackItemContentProps) => {
|
|
24
|
-
const { size } = useStack();
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div
|
|
28
|
-
role='none'
|
|
29
|
-
{...props}
|
|
30
|
-
className={mx('group grid grid-cols-[100%]', size === 'contain' && 'min-bs-0 overflow-hidden', classNames)}
|
|
31
|
-
style={{
|
|
32
|
-
gridTemplateRows: [
|
|
33
|
-
...(toolbar ? ['var(--rail-action)'] : []),
|
|
34
|
-
'1fr',
|
|
35
|
-
...(statusbar ? ['var(--statusbar-size)'] : []),
|
|
36
|
-
].join(' '),
|
|
37
|
-
}}
|
|
38
|
-
>
|
|
39
|
-
{children}
|
|
40
|
-
</div>
|
|
41
|
-
);
|
|
24
|
+
/**
|
|
25
|
+
* Whether to set a certain aspect ratio on the content, including the toolbar and statusbar. This is provided for
|
|
26
|
+
* convenience and consistency; it can instead be specified by the `classNames` or `style` props as needed.
|
|
27
|
+
*/
|
|
28
|
+
size?: 'intrinsic' | 'video' | 'square';
|
|
42
29
|
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* This component should be used by plugins for rendering content within a stack item, a.k.a. a “plank” or “section”.
|
|
33
|
+
* The `toolbar` flag must be provided since this component provides for the layout of content with the toolbar.
|
|
34
|
+
*/
|
|
35
|
+
export const StackItemContent = forwardRef<HTMLDivElement, StackItemContentProps>(
|
|
36
|
+
({ children, toolbar, statusbar, classNames, size = 'intrinsic', ...props }, forwardedRef) => {
|
|
37
|
+
const { size: stackItemSize } = useStack();
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
role='none'
|
|
42
|
+
{...props}
|
|
43
|
+
className={mx(
|
|
44
|
+
'group grid grid-cols-[100%]',
|
|
45
|
+
stackItemSize === 'contain' && 'min-bs-0 overflow-hidden',
|
|
46
|
+
size === 'video' ? 'aspect-video' : size === 'square' && 'aspect-square',
|
|
47
|
+
classNames,
|
|
48
|
+
)}
|
|
49
|
+
style={{
|
|
50
|
+
gridTemplateRows: [
|
|
51
|
+
...(toolbar ? ['var(--rail-action)'] : []),
|
|
52
|
+
'1fr',
|
|
53
|
+
...(statusbar ? ['var(--statusbar-size)'] : []),
|
|
54
|
+
].join(' '),
|
|
55
|
+
}}
|
|
56
|
+
ref={forwardedRef}
|
|
57
|
+
>
|
|
58
|
+
{children}
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
},
|
|
62
|
+
);
|
|
@@ -23,7 +23,7 @@ export const StackItemHeading = ({ children, classNames, ...props }: StackItemHe
|
|
|
23
23
|
tabIndex={0}
|
|
24
24
|
{...focusableGroupAttrs}
|
|
25
25
|
className={mx(
|
|
26
|
-
'flex items-center
|
|
26
|
+
'flex items-center dx-focus-ring-inset-over-all relative !border-is-0',
|
|
27
27
|
orientation === 'horizontal' ? 'bs-[--rail-size]' : 'is-[--rail-size] flex-col',
|
|
28
28
|
classNames,
|
|
29
29
|
)}
|
|
@@ -43,7 +43,7 @@ export const StackItemHeadingLabel = forwardRef<HTMLHeadingElement, StackItemHea
|
|
|
43
43
|
{...props}
|
|
44
44
|
data-attention={((related && isRelated) || hasAttention || isAncestor).toString()}
|
|
45
45
|
className={mx(
|
|
46
|
-
'pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText',
|
|
46
|
+
'pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText self-center',
|
|
47
47
|
classNames,
|
|
48
48
|
)}
|
|
49
49
|
ref={forwardedRef}
|