@bccampus/ui-components 0.4.0 → 0.4.2

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 (37) hide show
  1. package/dist/AbstractFocusProvider-CxvlcEki.js +29 -0
  2. package/dist/AbstractSelectionProvider-BtaROstC.js +30 -0
  3. package/dist/CompositeDataItem-DuHOHCWy.js +158 -0
  4. package/dist/ListboxFocusProvider.d.ts +149 -0
  5. package/dist/ListboxFocusProvider.js +53 -0
  6. package/dist/MultipleSelectionProvider.d.ts +141 -0
  7. package/dist/MultipleSelectionProvider.js +19 -0
  8. package/dist/SingleSelectionProvider.d.ts +141 -0
  9. package/dist/SingleSelectionProvider.js +23 -0
  10. package/dist/composite-component-DSUbd1XS.js +122 -0
  11. package/dist/composite.d.ts +108 -51
  12. package/dist/composite.js +57 -447
  13. package/dist/icon-generator-tuhuqdpL.js +76 -0
  14. package/dist/icon-generator.d.ts +11 -4
  15. package/dist/icon-generator.js +4 -74
  16. package/dist/listbox.d.ts +171 -0
  17. package/dist/listbox.js +76 -0
  18. package/dist/masked-image-generator.js +7 -7
  19. package/dist/ui-components.js +5 -5
  20. package/package.json +5 -1
  21. package/src/components/ui/composite/CompositeData.ts +22 -114
  22. package/src/components/ui/composite/FocusProvider/AbstractFocusProvider.ts +83 -0
  23. package/src/components/ui/composite/FocusProvider/ListboxFocusProvider.ts +74 -0
  24. package/src/components/ui/composite/SelectionProvider/AbstractSelectionProvider.ts +45 -0
  25. package/src/components/ui/composite/SelectionProvider/MultipleSelectionProvider.ts +28 -0
  26. package/src/components/ui/composite/SelectionProvider/SingleSelectionProvider.ts +37 -0
  27. package/src/components/ui/composite/composite-component-item.tsx +12 -10
  28. package/src/components/ui/composite/composite-component.tsx +39 -68
  29. package/src/components/ui/composite/index.ts +4 -1
  30. package/src/components/ui/composite/listbox.tsx +61 -0
  31. package/src/components/ui/composite/types.ts +51 -30
  32. package/src/components/ui/icon-generator/index.ts +2 -0
  33. package/src/hooks/use-keyboard-event.ts +31 -42
  34. package/vite.config.ts +6 -2
  35. package/src/components/ui/composite/composite-data-context.tsx +0 -31
  36. /package/dist/{igenerate-tiles.d.ts → generate-tiles.d.ts} +0 -0
  37. /package/dist/{igenerate-tiles.js → generate-tiles.js} +0 -0
@@ -0,0 +1,74 @@
1
+
2
+ import type { CompositeDataItem } from "../CompositeDataItem";
3
+ import { AbstractFocusProvider } from "./AbstractFocusProvider";
4
+
5
+ export class ListboxFocusProvider<T extends object> extends AbstractFocusProvider<T> {
6
+ setFocusPointers() {
7
+ let first: CompositeDataItem<T> | null = null;
8
+ let last: CompositeDataItem<T> | null = null
9
+
10
+ const lookupData = [...this.data.lookup];
11
+ for (let index = 0; index < lookupData.length; index++) {
12
+ const [key, item] = lookupData[index];
13
+
14
+ if (!this.isFocusable(item)) continue;
15
+ if (!first) first = item;
16
+ last = item;
17
+
18
+ if (index < lookupData.length - 1) {
19
+ let newIndex = index === lookupData.length - 1 ? 0 : index + 1;
20
+ while (newIndex < lookupData.length && !this.isFocusable(lookupData[newIndex][1])) {
21
+ newIndex = (newIndex + 1) % lookupData.length;
22
+ }
23
+
24
+ item.pointers.down = lookupData[newIndex][0];
25
+ lookupData[newIndex][1].pointers.up = key;
26
+ }
27
+ }
28
+
29
+ return [first, last] as const;
30
+ }
31
+
32
+ focusUp(): void {
33
+ if (this.focusedItem.get()?.pointers.up) {
34
+ this.focus(this.focusedItem.get()!.pointers.up!);
35
+ }
36
+ }
37
+ focusDown(): void {
38
+ if (this.focusedItem.get()?.pointers.down) {
39
+ this.focus(this.focusedItem.get()!.pointers.down!);
40
+ }
41
+ }
42
+ focusLeft(): void {
43
+ throw new Error("Method not implemented.");
44
+ }
45
+ focusRight(): void {
46
+ throw new Error("Method not implemented.");
47
+ }
48
+ focusPageUp(): void {
49
+ throw new Error("Method not implemented.");
50
+ }
51
+ focesPageDown(): void {
52
+ throw new Error("Method not implemented.");
53
+ }
54
+ focusToFirst(): void {
55
+ if (this.firstFocusableItem) {
56
+ this.focus(this.firstFocusableItem);
57
+ }
58
+ }
59
+ focusToLast(): void {
60
+ if (this.lastFocusableItem) {
61
+ this.focus(this.lastFocusableItem);
62
+ }
63
+ }
64
+ focusToFirstInRow(): void {
65
+ throw new Error("Method not implemented.");
66
+ }
67
+ focusToLastInRow(): void {
68
+ throw new Error("Method not implemented.");
69
+ }
70
+ focusToTypeAheadMatch(): void {
71
+ throw new Error("Method not implemented.");
72
+ }
73
+
74
+ }
@@ -0,0 +1,45 @@
1
+ import { atom, type PreinitializedWritableAtom } from 'nanostores';
2
+ import type { CompositeData } from '../CompositeData';
3
+ import { CompositeDataItem } from '../CompositeDataItem';
4
+ import type { CompositeDataOptions, CompositeItemKey } from '../types';
5
+
6
+ export interface SelectionProvider {
7
+ select(itemKey?: CompositeItemKey, recursive?: boolean): void;
8
+ deselect(itemKey?: CompositeItemKey, recursive?: boolean): void;
9
+ toggleSelect(itemKey?: CompositeItemKey, recursive?: boolean): void;
10
+ }
11
+
12
+ export abstract class AbstractSelectionProvider<T extends object> {
13
+ protected data!: CompositeData<T>;
14
+ protected dataOptions!: CompositeDataOptions<T>;
15
+
16
+ selectedKeys: PreinitializedWritableAtom<Set<CompositeItemKey>> = atom(new Set());
17
+
18
+ init(data: CompositeData<T>, dataOptions: CompositeDataOptions<T>) {
19
+ this.data = data;
20
+ this.dataOptions = dataOptions;
21
+
22
+ // Set initially selected items : SelectionProvider
23
+ this.dataOptions.selectedKeys.forEach(selectedKey => this.select(selectedKey));
24
+
25
+ }
26
+
27
+ abstract select(itemKey?: CompositeItemKey, recursive?: boolean): void;
28
+ abstract select(item: CompositeDataItem<T>, recursive?: boolean): void;
29
+ abstract select(item?: CompositeDataItem<T> | CompositeItemKey, recursive?: boolean): void;
30
+
31
+
32
+ abstract deselect(itemKey?: CompositeItemKey, recursive?: boolean): void;
33
+ abstract deselect(item: CompositeDataItem<T>, recursive?: boolean): void;
34
+ abstract deselect(item?: CompositeDataItem<T> | CompositeItemKey, recursive?: boolean): void;
35
+
36
+ toggleSelect(itemKey?: CompositeItemKey, recursive?: boolean): void;
37
+ toggleSelect(item: CompositeDataItem<T>, recursive?: boolean): void;
38
+ toggleSelect(item?: CompositeDataItem<T> | CompositeItemKey, recursive: boolean = false) {
39
+ const _item = item ? item instanceof CompositeDataItem ? item : this.data.lookup.get(item) : this.data.focusProvider.focusedItem.get();
40
+ if (!_item) return;
41
+
42
+ if (_item.state.get().selected) this.deselect(_item, recursive);
43
+ else this.select(_item, recursive);
44
+ }
45
+ }
@@ -0,0 +1,28 @@
1
+ import { CompositeDataItem } from '../CompositeDataItem';
2
+ import type { CompositeItemKey } from '../types';
3
+ import { AbstractSelectionProvider } from './AbstractSelectionProvider';
4
+ import { difference, union } from "@/lib/set-operations";
5
+
6
+ export class SingleSelectionProvider<T extends object> extends AbstractSelectionProvider<T> {
7
+
8
+
9
+ select(itemKey: CompositeItemKey, recursive?: boolean): void;
10
+ select(item: CompositeDataItem<T>, recursive?: boolean): void;
11
+ select(item: CompositeDataItem<T> | CompositeItemKey, recursive: boolean = false) {
12
+ const _item = item instanceof CompositeDataItem ? item : this.data.lookup.get(item);
13
+ if (!_item) return;
14
+
15
+ const selectedKeys = _item.select(recursive);
16
+ this.selectedKeys.set(union(this.selectedKeys.get(), selectedKeys));
17
+ }
18
+
19
+ deselect(itemKey: CompositeItemKey, recursive?: boolean): void;
20
+ deselect(item: CompositeDataItem<T>, recursive?: boolean): void;
21
+ deselect(item: CompositeDataItem<T> | CompositeItemKey, recursive: boolean = false) {
22
+ const _item = item instanceof CompositeDataItem ? item : this.data.lookup.get(item);
23
+ if (!_item) return;
24
+
25
+ const deselectedKeys = _item.deselect(recursive);
26
+ this.selectedKeys.set(difference(this.selectedKeys.get(), deselectedKeys));
27
+ }
28
+ }
@@ -0,0 +1,37 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+
3
+ import { CompositeDataItem } from '../CompositeDataItem';
4
+ import type { CompositeItemKey } from '../types';
5
+ import { AbstractSelectionProvider } from './AbstractSelectionProvider';
6
+ import { difference } from "@/lib/set-operations";
7
+
8
+ export class SingleSelectionProvider<T extends object> extends AbstractSelectionProvider<T> {
9
+
10
+ select(itemKey?: CompositeItemKey, recursive?: boolean): void;
11
+ select(item: CompositeDataItem<T>, recursive?: boolean): void;
12
+ select(item?: CompositeDataItem<T> | CompositeItemKey, _recursive: boolean = false) {
13
+ const _item = item ? item instanceof CompositeDataItem ? item : this.data.lookup.get(item) : this.data.focusProvider.focusedItem.get();
14
+ if (!_item) return;
15
+
16
+ this.selectedKeys.get().forEach(selectedKey => {
17
+ const _item = this.data.lookup.get(selectedKey);
18
+ if (!_item) return;
19
+
20
+ _item.deselect(false);
21
+ });
22
+
23
+ const selectedKeys = _item.select(false);
24
+
25
+ this.selectedKeys.set(new Set(selectedKeys));
26
+ }
27
+
28
+ deselect(itemKey?: CompositeItemKey, recursive?: boolean): void;
29
+ deselect(item: CompositeDataItem<T>, recursive?: boolean): void;
30
+ deselect(item?: CompositeDataItem<T> | CompositeItemKey, _recursive: boolean = false) {
31
+ const _item = item ? item instanceof CompositeDataItem ? item : this.data.lookup.get(item) : this.data.focusProvider.focusedItem.get();
32
+ if (!_item) return;
33
+
34
+ const deselectedKeys = _item.deselect(false);
35
+ this.selectedKeys.set(difference(this.selectedKeys.get(), deselectedKeys));
36
+ }
37
+ }
@@ -1,31 +1,32 @@
1
1
  import { useMemo } from "react";
2
- import type { CompositeItemEventHandlers, CompositeItemProps } from "./types";
2
+ import type { CompositeEventHandlers, CompositeItemProps } from "./types";
3
3
  import { useStore } from "@nanostores/react";
4
4
 
5
5
  export function CompositeComponentItem<T extends object>({
6
6
  id,
7
7
  className,
8
8
  item,
9
- mouseEventHandler,
10
- keyboardEventHandler,
9
+ role,
10
+ itemMouseEventHandler,
11
+ itemKeyboardEventHandler,
11
12
  render,
12
13
  }: CompositeItemProps<T>) {
13
14
  const data = useStore(item.data);
14
15
  const state = useStore(item.state);
15
16
 
16
- const handlers: CompositeItemEventHandlers = useMemo(() => {
17
+ const handlers: CompositeEventHandlers = useMemo(() => {
17
18
  if (state.disabled) return {};
18
19
 
19
20
  return {
20
- mouseEventHandler: () => mouseEventHandler?.(item),
21
- keyboardEventHandler: () => keyboardEventHandler?.(item),
21
+ mouseEventHandler: () => itemMouseEventHandler?.(item),
22
+ keyboardEventHandler: () => itemKeyboardEventHandler?.(item),
22
23
  };
23
- }, [state.disabled, item, keyboardEventHandler, mouseEventHandler]);
24
+ }, [state.disabled, item, itemKeyboardEventHandler, itemMouseEventHandler]);
24
25
 
25
26
  return (
26
27
  <div
27
28
  id={id}
28
- role="option"
29
+ role={role}
29
30
  aria-disabled={state.disabled}
30
31
  data-key={item.key}
31
32
  tabIndex={!state.disabled ? (state.focused ? 0 : -1) : undefined}
@@ -37,12 +38,13 @@ export function CompositeComponentItem<T extends object>({
37
38
  [...item.children].map((child) => (
38
39
  <CompositeComponentItem
39
40
  id={`${id}-${item.key}`}
41
+ role={role}
40
42
  item={child}
41
43
  key={child.key}
42
44
  render={render}
43
45
  className={className}
44
- mouseEventHandler={mouseEventHandler}
45
- keyboardEventHandler={keyboardEventHandler}
46
+ itemMouseEventHandler={itemMouseEventHandler}
47
+ itemKeyboardEventHandler={itemKeyboardEventHandler}
46
48
  />
47
49
  ))}
48
50
  </div>
@@ -1,98 +1,69 @@
1
- import { useCallback, useImperativeHandle, useRef } from "react";
2
- import { CompositeDataItem } from "./CompositeDataItem";
3
- import type { CompositeItemKey, CompositeProps } from "./types";
4
- import { useKeyboardEvent } from "@/hooks/use-keyboard-event";
5
- import { useCompositeContext } from "./composite-data-context";
1
+ import { useImperativeHandle, useMemo } from "react";
2
+ import type { CompositeProps } from "./types";
6
3
  import { CompositeComponentItem } from "./composite-component-item";
7
4
  import { useId } from "@/hooks/use-id";
8
5
 
6
+ const defaultRoles = {
7
+ listbox: {
8
+ rootRole: "listbox",
9
+ groupRole: "group",
10
+ itemRole: "option",
11
+ },
12
+ grid: {
13
+ rootRole: "grid",
14
+ groupRole: "rowgroup",
15
+ itemRole: "row",
16
+ },
17
+ custom: undefined,
18
+ };
19
+
9
20
  export function CompositeComponent<T extends object>({
21
+ data,
22
+ variant,
23
+ rootRole,
24
+ itemRole,
25
+ groupRole,
10
26
  renderItem,
11
27
  className,
12
28
  itemClassName,
13
29
  ref,
30
+ handleRef,
14
31
  id,
32
+ itemMouseEventHandler,
33
+ itemKeyboardEventHandler,
15
34
  ...props
16
35
  }: CompositeProps<T>) {
17
- const compositeData = useCompositeContext<T>();
18
- const compositeRef = useRef<HTMLDivElement>(null);
19
36
  const compositeId = useId(id);
20
37
 
21
- const focus = useCallback(
22
- (itemKey: CompositeItemKey) => {
23
- compositeData.focus(itemKey);
24
- // const focusedItemEl = compositeRef.current?.querySelector<HTMLDivElement>(`[data-key="${itemKey}"]`);
25
- // if (focusedItemEl) focusedItemEl.focus();
26
- },
27
- [compositeData]
28
- );
29
-
30
- const focusDown = useCallback(() => {
31
- if (compositeData.focusedItem.get()?.pointers.down) {
32
- focus(compositeData.focusedItem.get()!.pointers.down!);
33
- }
34
- }, [compositeData, focus]);
35
-
36
- const focusUp = useCallback(() => {
37
- if (compositeData.focusedItem.get()?.pointers.up) {
38
- focus(compositeData.focusedItem.get()!.pointers.up!);
39
- }
40
- }, [compositeData, focus]);
41
-
42
- const handleKeyDown = useKeyboardEvent({
43
- ArrowUp: focusUp,
44
- ArrowLeft: focusUp,
45
- ArrowDown: focusDown,
46
- ArrowRight: focusDown,
47
- Space: () => {
48
- if (compositeData.focusedItem.get()) compositeData.toggleSelect(compositeData.focusedItem.get()!);
49
- },
50
- });
51
-
52
- const handleItemMouseEvent = useCallback(
53
- (item: CompositeDataItem<T>) => {
54
- focus(item.key);
55
- compositeData.toggleSelect(item);
56
- },
57
- [compositeData, focus]
58
- );
59
-
60
38
  useImperativeHandle(
61
- ref,
39
+ handleRef,
62
40
  () => {
63
41
  return {
64
- focusDown() {
65
- focusDown();
66
- },
67
- focusUp() {
68
- focusUp();
69
- },
70
- select() {
71
- if (compositeData.focusedItem.get()) compositeData.toggleSelect(compositeData.focusedItem.get()!);
72
- },
42
+ focusProvider: data.focusProvider,
43
+ selectionProvider: data.selectionProvider,
73
44
  };
74
45
  },
75
- [compositeData, focusDown, focusUp]
46
+ [data]
47
+ );
48
+
49
+ const roles = useMemo(
50
+ () => defaultRoles[variant] ?? { rootRole, groupRole, itemRole },
51
+ [groupRole, itemRole, rootRole, variant]
76
52
  );
77
53
 
78
54
  return (
79
- <div
80
- ref={compositeRef}
81
- id={compositeId}
82
- className={className}
83
- tabIndex={-1}
84
- role="listbox"
85
- onKeyDown={handleKeyDown}
86
- {...props}
87
- >
88
- {[...compositeData].map((item) => (
55
+ <div ref={ref} id={compositeId} className={className} tabIndex={-1} role={roles.rootRole} {...props}>
56
+ {[...data].map((item) => (
89
57
  <CompositeComponentItem
90
58
  className={itemClassName}
91
59
  id={`${compositeId}-${item.key}`}
60
+ role={roles.itemRole}
61
+ groupRole={roles.groupRole}
92
62
  item={item}
93
63
  key={item.key}
94
64
  render={renderItem}
95
- mouseEventHandler={handleItemMouseEvent}
65
+ itemMouseEventHandler={itemMouseEventHandler}
66
+ itemKeyboardEventHandler={itemKeyboardEventHandler}
96
67
  />
97
68
  ))}
98
69
  </div>
@@ -1,4 +1,7 @@
1
1
  export * from './composite-component.tsx'
2
2
  export * from './composite-component-item.tsx'
3
- export * from './composite-data-context.tsx'
3
+ export * from './CompositeData.ts'
4
+ export * from './CompositeDataItem.ts'
5
+ export * from './FocusProvider/AbstractFocusProvider.ts'
6
+ export * from './SelectionProvider/AbstractSelectionProvider.ts'
4
7
  export * from './types.ts'
@@ -0,0 +1,61 @@
1
+ import { CompositeComponent } from "./composite-component";
2
+ import { useCallback, useRef } from "react";
3
+ import { CompositeDataItem } from "./CompositeDataItem";
4
+ import type { BaseCompositeProps } from "./types";
5
+ import { useKeyboardEvent } from "@/hooks/use-keyboard-event";
6
+
7
+ export function Listbox<T extends object>({ data, ...props }: BaseCompositeProps<T>) {
8
+ const compositeRef = useRef<HTMLDivElement>(null);
9
+
10
+ const focusElement = useCallback(() => {
11
+ const itemKey = data.focusProvider.focusedItem.get()?.key;
12
+
13
+ if (itemKey && compositeRef.current) {
14
+ const focusedItemEl = compositeRef.current.querySelector<HTMLDivElement>(`[data-key="${itemKey}"]`);
15
+ if (focusedItemEl) focusedItemEl.focus();
16
+ }
17
+ }, [data]);
18
+
19
+ const handleKeyboardEvent = useKeyboardEvent({
20
+ ArrowUp: () => {
21
+ data.focusProvider.focusUp();
22
+ focusElement();
23
+ },
24
+ ArrowDown: () => {
25
+ data.focusProvider.focusDown();
26
+ focusElement();
27
+ },
28
+ Home: () => {
29
+ data.focusProvider.focusToFirst();
30
+ focusElement();
31
+ },
32
+ End: () => {
33
+ data.focusProvider.focusToLast();
34
+ focusElement();
35
+ },
36
+ Space: () => {
37
+ data.selectionProvider?.toggleSelect();
38
+ focusElement();
39
+ },
40
+ });
41
+
42
+ const handleItemMouseEvent = useCallback(
43
+ (item: CompositeDataItem<T>) => {
44
+ data.focusProvider.focus(item.key);
45
+ data.selectionProvider?.toggleSelect(item);
46
+ focusElement();
47
+ },
48
+ [data.focusProvider, data.selectionProvider, focusElement]
49
+ );
50
+
51
+ return (
52
+ <CompositeComponent
53
+ ref={compositeRef}
54
+ variant="listbox"
55
+ data={data}
56
+ onKeyDown={handleKeyboardEvent}
57
+ itemMouseEventHandler={handleItemMouseEvent}
58
+ {...props}
59
+ />
60
+ );
61
+ }
@@ -1,8 +1,29 @@
1
- import type { KeyboardEventHandler, MouseEventHandler, ReactNode } from "react";
1
+ import type { AriaRole, KeyboardEventHandler, MouseEventHandler, ReactNode } from "react";
2
2
  import type { CompositeDataItem } from "./CompositeDataItem";
3
+ import type { AbstractFocusProvider, FocusProvider } from "./FocusProvider/AbstractFocusProvider";
4
+ import type { AbstractSelectionProvider, SelectionProvider } from "./SelectionProvider/AbstractSelectionProvider";
5
+ import type { CompositeData } from "./CompositeData";
3
6
 
4
7
  export type CompositeItemKey = string | number;
5
8
 
9
+ ;
10
+ export type CompositeRoles = {
11
+ variant: 'listbox'
12
+ rootRole?: never
13
+ itemRole?: never
14
+ groupRole?: never
15
+ } | {
16
+ variant: 'grid'
17
+ rootRole?: never
18
+ itemRole?: never
19
+ groupRole?: never
20
+ } | {
21
+ variant: 'custom'
22
+ rootRole: AriaRole
23
+ itemRole: AriaRole
24
+ groupRole: AriaRole
25
+ };
26
+
6
27
  export interface CompositeOptions {
7
28
  disabledKeys?: CompositeItemKey[];
8
29
  selectedKeys?: CompositeItemKey[];
@@ -16,6 +37,11 @@ interface CompositeDataPropGetters<T> {
16
37
  getItemChildren: (item: T) => T[] | undefined;
17
38
  }
18
39
 
40
+ export interface CompositeProviderOptions<T extends object> {
41
+ focusProvider: AbstractFocusProvider<T>;
42
+ selectionProvider?: AbstractSelectionProvider<T>;
43
+ }
44
+
19
45
  export type CompositeDataOptions<T> = Required<CompositeOptions> & CompositeDataPropGetters<T>;
20
46
 
21
47
  export type CompositeDataItemOptions<T> = CompositeDataPropGetters<T> & {
@@ -29,53 +55,48 @@ export interface CompositeDataItemState {
29
55
  disabled: boolean;
30
56
  }
31
57
 
32
- export interface CompositeProps<T extends object> extends React.ComponentPropsWithoutRef<"div"> {
33
- renderItem: CompositeItemRenderFn<T>;
58
+ export interface CompositeEventHandlers {
59
+ mouseEventHandler?: MouseEventHandler<HTMLElement>;
60
+ keyboardEventHandler?: KeyboardEventHandler<HTMLElement>;
61
+ }
62
+
63
+ export interface CompositeItemEventHandlerFunctions<T extends object> {
64
+ itemMouseEventHandler?: (itemAtom: CompositeDataItem<T>) => void;
65
+ itemKeyboardEventHandler?: (itemAtom: CompositeDataItem<T>) => void;
66
+ }
67
+
68
+ export interface BaseCompositeProps<T extends object> extends React.ComponentPropsWithoutRef<"div"> {
69
+ data: CompositeData<T>;
34
70
  className?: string;
71
+ ref?: React.Ref<HTMLDivElement>
72
+ handleRef?: React.Ref<CompositeHandle>
73
+
74
+ renderItem: CompositeItemRenderFn<T>;
35
75
  itemClassName?: string;
36
- ref?: React.Ref<CompositeHandle>
76
+
37
77
  }
38
78
 
79
+ export type CompositeProps<T extends object> = BaseCompositeProps<T> & CompositeItemEventHandlerFunctions<T> & CompositeRoles;
39
80
 
40
81
  export interface CompositeHandle {
41
- focusUp: () => void;
42
- focusDown: () => void;
43
- select: () => void;
44
- }
45
-
46
- export interface CompositeItemEventHandlers {
47
- mouseEventHandler?: MouseEventHandler<HTMLElement>;
48
- keyboardEventHandler?: KeyboardEventHandler<HTMLElement>;
82
+ focusProvider: FocusProvider;
83
+ selectionProvider?: SelectionProvider;
49
84
  }
50
85
 
51
86
  export type CompositeItemRenderFn<T extends object> = (
52
87
  item: { data: T; level: number; key: CompositeItemKey },
53
88
  state: CompositeDataItemState,
54
- eventHandlers: CompositeItemEventHandlers
89
+ eventHandlers: CompositeEventHandlers
55
90
  ) => ReactNode;
56
91
 
57
- export interface CompositeItemProps<T extends object> {
92
+ export interface CompositeItemProps<T extends object> extends CompositeItemEventHandlerFunctions<T> {
58
93
  id: string;
59
94
  className?: string;
95
+ role?: AriaRole;
96
+ groupRole?: AriaRole;
60
97
 
61
98
  item: CompositeDataItem<T>;
62
99
 
63
- mouseEventHandler?: (itemAtom: CompositeDataItem<T>) => void;
64
- keyboardEventHandler?: (itemAtom: CompositeDataItem<T>) => void;
65
-
66
100
  remove?: () => void;
67
101
  render: CompositeItemRenderFn<T>;
68
102
  }
69
-
70
- export interface CompositeFocusProvider {
71
- setPointers: () => void;
72
-
73
- goFirst: () => void;
74
- goLast: () => void;
75
-
76
- goUp: () => void;
77
- goDown: () => void;
78
- goLeft: () => void;
79
- goRight: () => void;
80
-
81
- }
@@ -0,0 +1,2 @@
1
+ export * from "./icon-generator.tsx"
2
+ export * from "./types"