@dxos/react-ui-list 0.8.4-main.ead640a → 0.8.4-main.ef1bc66f44

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 (39) hide show
  1. package/dist/lib/browser/index.mjs +638 -711
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +638 -711
  5. package/dist/lib/node-esm/index.mjs.map +3 -3
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/List/List.d.ts +2 -2
  8. package/dist/types/src/components/List/List.d.ts.map +1 -1
  9. package/dist/types/src/components/List/List.stories.d.ts +2 -2
  10. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/List/ListRoot.d.ts +2 -2
  12. package/dist/types/src/components/List/ListRoot.d.ts.map +1 -1
  13. package/dist/types/src/components/Tree/Tree.d.ts +7 -4
  14. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  15. package/dist/types/src/components/Tree/Tree.stories.d.ts +9 -28
  16. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Tree/TreeContext.d.ts +5 -3
  18. package/dist/types/src/components/Tree/TreeContext.d.ts.map +1 -1
  19. package/dist/types/src/components/Tree/TreeItem.d.ts +12 -3
  20. package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
  21. package/dist/types/src/components/Tree/TreeItemHeading.d.ts +1 -1
  22. package/dist/types/src/components/Tree/TreeItemHeading.d.ts.map +1 -1
  23. package/dist/types/src/components/Tree/testing.d.ts +2 -2
  24. package/dist/types/src/components/Tree/testing.d.ts.map +1 -1
  25. package/dist/types/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +29 -27
  27. package/src/components/Accordion/Accordion.stories.tsx +3 -3
  28. package/src/components/Accordion/AccordionItem.tsx +2 -2
  29. package/src/components/Accordion/AccordionRoot.tsx +1 -1
  30. package/src/components/List/List.stories.tsx +29 -17
  31. package/src/components/List/ListItem.tsx +3 -3
  32. package/src/components/List/ListRoot.tsx +2 -2
  33. package/src/components/List/testing.ts +2 -2
  34. package/src/components/Tree/Tree.stories.tsx +74 -60
  35. package/src/components/Tree/Tree.tsx +17 -9
  36. package/src/components/Tree/TreeContext.tsx +5 -3
  37. package/src/components/Tree/TreeItem.tsx +19 -16
  38. package/src/components/Tree/TreeItemHeading.tsx +5 -3
  39. package/src/components/Tree/testing.ts +4 -3
@@ -13,7 +13,6 @@ import {
13
13
  import * as Schema from 'effect/Schema';
14
14
  import React, { type FC, type KeyboardEvent, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
15
15
 
16
- import { type HasId } from '@dxos/echo/internal';
17
16
  import { invariant } from '@dxos/invariant';
18
17
  import { TreeItem as NaturalTreeItem, Treegrid } from '@dxos/react-ui';
19
18
  import {
@@ -22,7 +21,7 @@ import {
22
21
  hoverableControls,
23
22
  hoverableFocusedKeyboardControls,
24
23
  hoverableFocusedWithinControls,
25
- } from '@dxos/react-ui-theme';
24
+ } from '@dxos/ui-theme';
26
25
 
27
26
  import { DEFAULT_INDENTATION, paddingIndentation } from './helpers';
28
27
  import { useTree } from './TreeContext';
@@ -43,7 +42,7 @@ export const TreeDataSchema = Schema.Struct({
43
42
  export type TreeData = Schema.Schema.Type<typeof TreeDataSchema>;
44
43
  export const isTreeData = (data: unknown): data is TreeData => Schema.is(TreeDataSchema)(data);
45
44
 
46
- export type ColumnRenderer<T extends HasId = any> = FC<{
45
+ export type ColumnRenderer<T extends { id: string } = any> = FC<{
47
46
  item: T;
48
47
  path: string[];
49
48
  open: boolean;
@@ -51,26 +50,28 @@ export type ColumnRenderer<T extends HasId = any> = FC<{
51
50
  setMenuOpen: (open: boolean) => void;
52
51
  }>;
53
52
 
54
- export type TreeItemProps<T extends HasId = any> = {
53
+ export type TreeItemProps<T extends { id: string } = any> = {
55
54
  item: T;
56
55
  path: string[];
57
56
  levelOffset?: number;
58
57
  last: boolean;
59
58
  draggable?: boolean;
60
59
  renderColumns?: ColumnRenderer<T>;
60
+ blockInstruction?: (params: { instruction: Instruction; source: TreeData; target: TreeData }) => boolean;
61
61
  canDrop?: (params: { source: TreeData; target: TreeData }) => boolean;
62
62
  canSelect?: (params: { item: T; path: string[] }) => boolean;
63
63
  onOpenChange?: (params: { item: T; path: string[]; open: boolean }) => void;
64
64
  onSelect?: (params: { item: T; path: string[]; current: boolean; option: boolean }) => void;
65
65
  };
66
66
 
67
- const RawTreeItem = <T extends HasId = any>({
67
+ const RawTreeItem = <T extends { id: string } = any>({
68
68
  item,
69
69
  path: _path,
70
70
  levelOffset = 2,
71
71
  last,
72
72
  draggable: _draggable,
73
73
  renderColumns: Columns,
74
+ blockInstruction,
74
75
  canDrop,
75
76
  canSelect,
76
77
  onOpenChange,
@@ -84,15 +85,12 @@ const RawTreeItem = <T extends HasId = any>({
84
85
  const [instruction, setInstruction] = useState<Instruction | null>(null);
85
86
  const [menuOpen, setMenuOpen] = useState(false);
86
87
 
87
- const { useItems, getProps, isOpen, isCurrent } = useTree();
88
+ const { useItems, getProps, useIsOpen, useIsCurrent } = useTree();
88
89
  const items = useItems(item);
89
- const { id, parentOf, label, className, headingClassName, icon, iconClassName, disabled, testId } = getProps(
90
- item,
91
- _path,
92
- );
90
+ const { id, parentOf, label, className, headingClassName, icon, iconHue, disabled, testId } = getProps(item, _path);
93
91
  const path = useMemo(() => [..._path, id], [_path, id]);
94
- const open = isOpen(path, item);
95
- const current = isCurrent(path, item);
92
+ const open = useIsOpen(path, item);
93
+ const current = useIsCurrent(path, item);
96
94
  const level = path.length - levelOffset;
97
95
  const isBranch = !!parentOf;
98
96
  const mode: ItemMode = last ? 'last-in-group' : open ? 'expanded' : 'standard';
@@ -152,7 +150,11 @@ const RawTreeItem = <T extends HasId = any>({
152
150
  },
153
151
  getIsSticky: () => true,
154
152
  onDrag: ({ self, source }) => {
155
- const instruction = extractInstruction(self.data);
153
+ const desired = extractInstruction(self.data);
154
+ const block =
155
+ desired && blockInstruction?.({ instruction: desired, source: source.data as TreeData, target: data });
156
+ const instruction: Instruction | null =
157
+ block && desired.type !== 'instruction-blocked' ? { type: 'instruction-blocked', desired } : desired;
156
158
 
157
159
  if (source.data.id !== id) {
158
160
  if (instruction?.type === 'make-child' && isBranch && !open && !cancelExpandRef.current) {
@@ -183,7 +185,7 @@ const RawTreeItem = <T extends HasId = any>({
183
185
  },
184
186
  }),
185
187
  );
186
- }, [_draggable, item, id, mode, path, open, canDrop]);
188
+ }, [_draggable, item, id, mode, path, open, blockInstruction, canDrop]);
187
189
 
188
190
  // Cancel expand on unmount.
189
191
  useEffect(() => () => cancelExpand(), [cancelExpand]);
@@ -239,7 +241,7 @@ const RawTreeItem = <T extends HasId = any>({
239
241
  ghostFocusWithin,
240
242
  className,
241
243
  ]}
242
- data-itemid={id}
244
+ data-object-id={id}
243
245
  data-testid={testId}
244
246
  // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
245
247
  // without alerting the user (except for in the correct link element). See also:
@@ -264,7 +266,7 @@ const RawTreeItem = <T extends HasId = any>({
264
266
  label={label}
265
267
  className={headingClassName}
266
268
  icon={icon}
267
- iconClassName={iconClassName}
269
+ iconHue={iconHue}
268
270
  onSelect={handleSelect}
269
271
  ref={buttonRef}
270
272
  />
@@ -282,6 +284,7 @@ const RawTreeItem = <T extends HasId = any>({
282
284
  last={index === items.length - 1}
283
285
  draggable={_draggable}
284
286
  renderColumns={Columns}
287
+ blockInstruction={blockInstruction}
285
288
  canDrop={canDrop}
286
289
  canSelect={canSelect}
287
290
  onOpenChange={onOpenChange}
@@ -6,6 +6,7 @@ import React, { type KeyboardEvent, type MouseEvent, forwardRef, memo, useCallba
6
6
 
7
7
  import { Button, Icon, type Label, toLocalizedString, useTranslation } from '@dxos/react-ui';
8
8
  import { TextTooltip } from '@dxos/react-ui-text-tooltip';
9
+ import { getStyles } from '@dxos/ui-theme';
9
10
 
10
11
  // TODO(wittjosiah): Consider whether there should be a separate disabled prop which was visually distinct
11
12
  // rather than just making the item unselectable.
@@ -13,7 +14,7 @@ export type TreeItemHeadingProps = {
13
14
  label: Label;
14
15
  className?: string;
15
16
  icon?: string;
16
- iconClassName?: string;
17
+ iconHue?: string;
17
18
  disabled?: boolean;
18
19
  current?: boolean;
19
20
  onSelect?: (option: boolean) => void;
@@ -21,8 +22,9 @@ export type TreeItemHeadingProps = {
21
22
 
22
23
  export const TreeItemHeading = memo(
23
24
  forwardRef<HTMLButtonElement, TreeItemHeadingProps>(
24
- ({ label, className, icon, iconClassName, disabled, current, onSelect }, forwardedRef) => {
25
+ ({ label, className, icon, iconHue, disabled, current, onSelect }, forwardedRef) => {
25
26
  const { t } = useTranslation();
27
+ const styles = iconHue ? getStyles(iconHue) : undefined;
26
28
 
27
29
  const handleSelect = useCallback(
28
30
  (event: MouseEvent) => {
@@ -65,7 +67,7 @@ export const TreeItemHeading = memo(
65
67
  onKeyDown={handleButtonKeydown}
66
68
  {...(current && { 'aria-current': 'location' })}
67
69
  >
68
- {icon && <Icon icon={icon ?? 'ph--placeholder--regular'} size={5} classNames={['mlb-1', iconClassName]} />}
70
+ {icon && <Icon icon={icon ?? 'ph--placeholder--regular'} size={5} classNames={['mlb-1', styles?.icon]} />}
69
71
  <span className='flex-1 is-0 truncate text-start text-sm font-normal' data-tooltip>
70
72
  {toLocalizedString(label, t)}
71
73
  </span>
@@ -5,20 +5,21 @@
5
5
  import { type Instruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
6
6
  import * as Schema from 'effect/Schema';
7
7
 
8
- import { type HasId, ObjectId } from '@dxos/echo/internal';
8
+ import { Obj } from '@dxos/echo';
9
9
  import { log } from '@dxos/log';
10
10
  import { faker } from '@dxos/random';
11
11
 
12
12
  import { type TreeData } from './TreeItem';
13
13
 
14
- export type TestItem = HasId & {
14
+ export type TestItem = {
15
+ id: string;
15
16
  name: string;
16
17
  icon?: string;
17
18
  items: TestItem[];
18
19
  };
19
20
 
20
21
  export const TestItemSchema = Schema.Struct({
21
- id: ObjectId,
22
+ id: Obj.ID,
22
23
  name: Schema.String,
23
24
  icon: Schema.optional(Schema.String),
24
25
  items: Schema.mutable(Schema.Array(Schema.suspend((): Schema.Schema<TestItem> => TestItemSchema))),