@headless-tree/react 0.0.14 → 1.0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @headless-tree/react
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [9e5027b]
8
+ - @headless-tree/core@1.0.0
9
+
10
+ ## 0.0.15
11
+
12
+ ### Patch Changes
13
+
14
+ - 617faea: Support for keyboard-controlled drag-and-drop events
15
+ - Updated dependencies [2af5668]
16
+ - Updated dependencies [617faea]
17
+ - @headless-tree/core@0.0.15
18
+
3
19
  ## 0.0.14
4
20
 
5
21
  ### Patch Changes
@@ -0,0 +1,8 @@
1
+ import React, { HTMLProps } from "react";
2
+ import { AssistiveDndState, DndState, HotkeysConfig, TreeInstance } from "@headless-tree/core";
3
+ declare const getDefaultLabel: <T>(dnd: DndState<T> | null | undefined, assistiveState: AssistiveDndState, hotkeys: HotkeysConfig<T>) => string;
4
+ export declare const AssistiveTreeDescription: <T>({ tree, getLabel, ...props }: {
5
+ tree: TreeInstance<T>;
6
+ getLabel?: typeof getDefaultLabel;
7
+ } & HTMLProps<HTMLSpanElement>) => React.JSX.Element;
8
+ export {};
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.AssistiveTreeDescription = void 0;
18
+ const react_1 = __importDefault(require("react"));
19
+ const core_1 = require("@headless-tree/core");
20
+ // https://medium.com/salesforce-ux/4-major-patterns-for-accessible-drag-and-drop-1d43f64ebf09
21
+ const styles = {
22
+ position: "absolute",
23
+ margin: "-1px",
24
+ width: "1px",
25
+ height: "1px",
26
+ overflow: "hidden",
27
+ clip: "rect(0 0 0 0)",
28
+ };
29
+ const getDefaultLabel = (dnd, assistiveState, hotkeys) => {
30
+ var _a, _b;
31
+ const itemNames = (_b = (_a = dnd === null || dnd === void 0 ? void 0 : dnd.draggedItems) === null || _a === void 0 ? void 0 : _a.map((item) => item.getItemName()).join(", ")) !== null && _b !== void 0 ? _b : "";
32
+ const position = !(dnd === null || dnd === void 0 ? void 0 : dnd.dragTarget)
33
+ ? "None"
34
+ : "childIndex" in dnd.dragTarget
35
+ ? `${dnd.dragTarget.childIndex} of ${dnd.dragTarget.item.getChildren().length} in ${dnd.dragTarget.item.getItemName()}`
36
+ : `in ${dnd.dragTarget.item.getItemName()}`;
37
+ const navGuide = `Press ${hotkeys.dragUp.hotkey} and ${hotkeys.dragDown.hotkey} to move up or down, ` +
38
+ `${hotkeys.completeDrag.hotkey} to drop, ${hotkeys.cancelDrag.hotkey} to abort.`;
39
+ switch (assistiveState) {
40
+ case core_1.AssistiveDndState.Started:
41
+ return itemNames
42
+ ? `Dragging ${itemNames}. Current position: ${position}. ${navGuide}`
43
+ : `Current position: ${position}. ${navGuide}`;
44
+ case core_1.AssistiveDndState.Dragging:
45
+ return itemNames ? `${itemNames}, ${position}` : position;
46
+ case core_1.AssistiveDndState.Completed:
47
+ return `Drag completed. Press ${hotkeys.startDrag.hotkey} to move selected items`;
48
+ case core_1.AssistiveDndState.Aborted:
49
+ return `Drag cancelled. Press ${hotkeys.startDrag.hotkey} to move selected items`;
50
+ case core_1.AssistiveDndState.None:
51
+ default:
52
+ return `Press ${hotkeys.startDrag.hotkey} to move selected items`;
53
+ }
54
+ };
55
+ const AssistiveTreeDescription = (_a) => {
56
+ var _b;
57
+ var { tree, getLabel = getDefaultLabel } = _a, props = __rest(_a, ["tree", "getLabel"]);
58
+ const state = tree.getState();
59
+ return (react_1.default.createElement("span", Object.assign({ "aria-live": "assertive" }, props, { style: Object.assign(Object.assign({}, styles), props.style) }), getLabel(state.dnd, (_b = state.assistiveDndState) !== null && _b !== void 0 ? _b : core_1.AssistiveDndState.None, tree.getHotkeyPresets())));
60
+ };
61
+ exports.AssistiveTreeDescription = AssistiveTreeDescription;
@@ -1,2 +1,2 @@
1
- import { TreeConfig } from "@headless-tree/core";
2
- export declare const useTree: <T>(config: TreeConfig<T>) => import("@headless-tree/core").TreeInstance<T>;
1
+ export * from "./assistive-tree-description";
2
+ export * from "./use-tree";
package/lib/cjs/index.js CHANGED
@@ -1,16 +1,18 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useTree = void 0;
4
- const react_1 = require("react");
5
- const core_1 = require("@headless-tree/core");
6
- const useTree = (config) => {
7
- const [tree] = (0, react_1.useState)(() => ({ current: (0, core_1.createTree)(config) }));
8
- const [state, setState] = (0, react_1.useState)(() => tree.current.getState());
9
- tree.current.setConfig((prev) => (Object.assign(Object.assign(Object.assign({}, prev), config), { state: Object.assign(Object.assign({}, state), config.state), setState: (state) => {
10
- var _a;
11
- setState(state);
12
- (_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state);
13
- } })));
14
- return tree.current;
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
- exports.useTree = useTree;
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./assistive-tree-description"), exports);
18
+ __exportStar(require("./use-tree"), exports);
@@ -0,0 +1,2 @@
1
+ import { TreeConfig } from "@headless-tree/core";
2
+ export declare const useTree: <T>(config: TreeConfig<T>) => import("@headless-tree/core").TreeInstance<T>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useTree = void 0;
4
+ const react_1 = require("react");
5
+ const core_1 = require("@headless-tree/core");
6
+ const useTree = (config) => {
7
+ const [tree] = (0, react_1.useState)(() => ({ current: (0, core_1.createTree)(config) }));
8
+ const [state, setState] = (0, react_1.useState)(() => tree.current.getState());
9
+ tree.current.setConfig((prev) => (Object.assign(Object.assign(Object.assign({}, prev), config), { state: Object.assign(Object.assign({}, state), config.state), setState: (state) => {
10
+ var _a;
11
+ setState(state);
12
+ (_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state);
13
+ } })));
14
+ return tree.current;
15
+ };
16
+ exports.useTree = useTree;
@@ -0,0 +1,8 @@
1
+ import React, { HTMLProps } from "react";
2
+ import { AssistiveDndState, DndState, HotkeysConfig, TreeInstance } from "@headless-tree/core";
3
+ declare const getDefaultLabel: <T>(dnd: DndState<T> | null | undefined, assistiveState: AssistiveDndState, hotkeys: HotkeysConfig<T>) => string;
4
+ export declare const AssistiveTreeDescription: <T>({ tree, getLabel, ...props }: {
5
+ tree: TreeInstance<T>;
6
+ getLabel?: typeof getDefaultLabel;
7
+ } & HTMLProps<HTMLSpanElement>) => React.JSX.Element;
8
+ export {};
@@ -0,0 +1,54 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React from "react";
13
+ import { AssistiveDndState, } from "@headless-tree/core";
14
+ // https://medium.com/salesforce-ux/4-major-patterns-for-accessible-drag-and-drop-1d43f64ebf09
15
+ const styles = {
16
+ position: "absolute",
17
+ margin: "-1px",
18
+ width: "1px",
19
+ height: "1px",
20
+ overflow: "hidden",
21
+ clip: "rect(0 0 0 0)",
22
+ };
23
+ const getDefaultLabel = (dnd, assistiveState, hotkeys) => {
24
+ var _a, _b;
25
+ const itemNames = (_b = (_a = dnd === null || dnd === void 0 ? void 0 : dnd.draggedItems) === null || _a === void 0 ? void 0 : _a.map((item) => item.getItemName()).join(", ")) !== null && _b !== void 0 ? _b : "";
26
+ const position = !(dnd === null || dnd === void 0 ? void 0 : dnd.dragTarget)
27
+ ? "None"
28
+ : "childIndex" in dnd.dragTarget
29
+ ? `${dnd.dragTarget.childIndex} of ${dnd.dragTarget.item.getChildren().length} in ${dnd.dragTarget.item.getItemName()}`
30
+ : `in ${dnd.dragTarget.item.getItemName()}`;
31
+ const navGuide = `Press ${hotkeys.dragUp.hotkey} and ${hotkeys.dragDown.hotkey} to move up or down, ` +
32
+ `${hotkeys.completeDrag.hotkey} to drop, ${hotkeys.cancelDrag.hotkey} to abort.`;
33
+ switch (assistiveState) {
34
+ case AssistiveDndState.Started:
35
+ return itemNames
36
+ ? `Dragging ${itemNames}. Current position: ${position}. ${navGuide}`
37
+ : `Current position: ${position}. ${navGuide}`;
38
+ case AssistiveDndState.Dragging:
39
+ return itemNames ? `${itemNames}, ${position}` : position;
40
+ case AssistiveDndState.Completed:
41
+ return `Drag completed. Press ${hotkeys.startDrag.hotkey} to move selected items`;
42
+ case AssistiveDndState.Aborted:
43
+ return `Drag cancelled. Press ${hotkeys.startDrag.hotkey} to move selected items`;
44
+ case AssistiveDndState.None:
45
+ default:
46
+ return `Press ${hotkeys.startDrag.hotkey} to move selected items`;
47
+ }
48
+ };
49
+ export const AssistiveTreeDescription = (_a) => {
50
+ var _b;
51
+ var { tree, getLabel = getDefaultLabel } = _a, props = __rest(_a, ["tree", "getLabel"]);
52
+ const state = tree.getState();
53
+ return (React.createElement("span", Object.assign({ "aria-live": "assertive" }, props, { style: Object.assign(Object.assign({}, styles), props.style) }), getLabel(state.dnd, (_b = state.assistiveDndState) !== null && _b !== void 0 ? _b : AssistiveDndState.None, tree.getHotkeyPresets())));
54
+ };
@@ -1,2 +1,2 @@
1
- import { TreeConfig } from "@headless-tree/core";
2
- export declare const useTree: <T>(config: TreeConfig<T>) => import("@headless-tree/core").TreeInstance<T>;
1
+ export * from "./assistive-tree-description";
2
+ export * from "./use-tree";
package/lib/esm/index.js CHANGED
@@ -1,12 +1,2 @@
1
- import { useState } from "react";
2
- import { createTree } from "@headless-tree/core";
3
- export const useTree = (config) => {
4
- const [tree] = useState(() => ({ current: createTree(config) }));
5
- const [state, setState] = useState(() => tree.current.getState());
6
- tree.current.setConfig((prev) => (Object.assign(Object.assign(Object.assign({}, prev), config), { state: Object.assign(Object.assign({}, state), config.state), setState: (state) => {
7
- var _a;
8
- setState(state);
9
- (_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state);
10
- } })));
11
- return tree.current;
12
- };
1
+ export * from "./assistive-tree-description";
2
+ export * from "./use-tree";
@@ -0,0 +1,2 @@
1
+ import { TreeConfig } from "@headless-tree/core";
2
+ export declare const useTree: <T>(config: TreeConfig<T>) => import("@headless-tree/core").TreeInstance<T>;
@@ -0,0 +1,12 @@
1
+ import { useState } from "react";
2
+ import { createTree } from "@headless-tree/core";
3
+ export const useTree = (config) => {
4
+ const [tree] = useState(() => ({ current: createTree(config) }));
5
+ const [state, setState] = useState(() => tree.current.getState());
6
+ tree.current.setConfig((prev) => (Object.assign(Object.assign(Object.assign({}, prev), config), { state: Object.assign(Object.assign({}, state), config.state), setState: (state) => {
7
+ var _a;
8
+ setState(state);
9
+ (_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state);
10
+ } })));
11
+ return tree.current;
12
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headless-tree/react",
3
- "version": "0.0.14",
3
+ "version": "1.0.0",
4
4
  "main": "lib/cjs/index.js",
5
5
  "module": "lib/esm/index.js",
6
6
  "types": "lib/esm/index.d.ts",
@@ -25,7 +25,7 @@
25
25
  "prop-types": "15.8.1",
26
26
  "react": "^18.2.0",
27
27
  "react-dom": "^18.2.0",
28
- "typescript": "^5.7.3"
28
+ "typescript": "^5.7.2"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@headless-tree/core": "*",
@@ -0,0 +1,77 @@
1
+ import React, { HTMLProps } from "react";
2
+ import {
3
+ AssistiveDndState,
4
+ DndState,
5
+ HotkeysConfig,
6
+ TreeInstance,
7
+ } from "@headless-tree/core";
8
+
9
+ // https://medium.com/salesforce-ux/4-major-patterns-for-accessible-drag-and-drop-1d43f64ebf09
10
+
11
+ const styles = {
12
+ position: "absolute",
13
+ margin: "-1px",
14
+ width: "1px",
15
+ height: "1px",
16
+ overflow: "hidden",
17
+ clip: "rect(0 0 0 0)",
18
+ } as const;
19
+
20
+ const getDefaultLabel = <T,>(
21
+ dnd: DndState<T> | null | undefined,
22
+ assistiveState: AssistiveDndState,
23
+ hotkeys: HotkeysConfig<T>,
24
+ ) => {
25
+ const itemNames =
26
+ dnd?.draggedItems?.map((item) => item.getItemName()).join(", ") ?? "";
27
+ const position = !dnd?.dragTarget
28
+ ? "None"
29
+ : "childIndex" in dnd.dragTarget
30
+ ? `${dnd.dragTarget.childIndex} of ${dnd.dragTarget.item.getChildren().length} in ${dnd.dragTarget.item.getItemName()}`
31
+ : `in ${dnd.dragTarget.item.getItemName()}`;
32
+ const navGuide =
33
+ `Press ${hotkeys.dragUp.hotkey} and ${hotkeys.dragDown.hotkey} to move up or down, ` +
34
+ `${hotkeys.completeDrag.hotkey} to drop, ${hotkeys.cancelDrag.hotkey} to abort.`;
35
+ switch (assistiveState) {
36
+ case AssistiveDndState.Started:
37
+ return itemNames
38
+ ? `Dragging ${itemNames}. Current position: ${position}. ${navGuide}`
39
+ : `Current position: ${position}. ${navGuide}`;
40
+ case AssistiveDndState.Dragging:
41
+ return itemNames ? `${itemNames}, ${position}` : position;
42
+ case AssistiveDndState.Completed:
43
+ return `Drag completed. Press ${hotkeys.startDrag.hotkey} to move selected items`;
44
+ case AssistiveDndState.Aborted:
45
+ return `Drag cancelled. Press ${hotkeys.startDrag.hotkey} to move selected items`;
46
+ case AssistiveDndState.None:
47
+ default:
48
+ return `Press ${hotkeys.startDrag.hotkey} to move selected items`;
49
+ }
50
+ };
51
+
52
+ export const AssistiveTreeDescription = <T,>({
53
+ tree,
54
+ getLabel = getDefaultLabel,
55
+ ...props
56
+ }: {
57
+ tree: TreeInstance<T>;
58
+ getLabel?: typeof getDefaultLabel;
59
+ } & HTMLProps<HTMLSpanElement>) => {
60
+ const state = tree.getState();
61
+ return (
62
+ <span
63
+ aria-live="assertive"
64
+ {...props}
65
+ style={{
66
+ ...styles,
67
+ ...props.style,
68
+ }}
69
+ >
70
+ {getLabel(
71
+ state.dnd,
72
+ state.assistiveDndState ?? AssistiveDndState.None,
73
+ tree.getHotkeyPresets(),
74
+ )}
75
+ </span>
76
+ );
77
+ };
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./assistive-tree-description";
2
+ export * from "./use-tree";
package/typedoc.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "extends": ["../../typedoc.base.json"],
3
- "entryPoints": ["src/index.tsx"]
3
+ "entryPoints": ["src/index.ts"]
4
4
  }
File without changes