@dxos/react-ui-attention 0.8.4-main.c85a9c8dae → 0.8.4-main.d05539e30a

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 (82) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/chunk-D2BLVJ6Z.mjs +421 -0
  3. package/dist/lib/browser/chunk-D2BLVJ6Z.mjs.map +7 -0
  4. package/dist/lib/browser/chunk-I4VO2RQM.mjs +255 -0
  5. package/dist/lib/browser/chunk-I4VO2RQM.mjs.map +7 -0
  6. package/dist/lib/browser/index.mjs +22 -23
  7. package/dist/lib/browser/index.mjs.map +4 -4
  8. package/dist/lib/browser/meta.json +1 -1
  9. package/dist/lib/browser/testing/index.mjs +4 -3
  10. package/dist/lib/browser/testing/index.mjs.map +2 -2
  11. package/dist/lib/browser/types/index.mjs +29 -0
  12. package/dist/lib/node-esm/chunk-6INLBC62.mjs +423 -0
  13. package/dist/lib/node-esm/chunk-6INLBC62.mjs.map +7 -0
  14. package/dist/lib/node-esm/chunk-ZTUVSH4P.mjs +256 -0
  15. package/dist/lib/node-esm/chunk-ZTUVSH4P.mjs.map +7 -0
  16. package/dist/lib/node-esm/index.mjs +22 -23
  17. package/dist/lib/node-esm/index.mjs.map +4 -4
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/lib/node-esm/testing/index.mjs +4 -3
  20. package/dist/lib/node-esm/testing/index.mjs.map +2 -2
  21. package/dist/lib/node-esm/types/index.mjs +30 -0
  22. package/dist/types/src/attention.d.ts +46 -11
  23. package/dist/types/src/attention.d.ts.map +1 -1
  24. package/dist/types/src/components/AttentionGlyph/AttentionGlyph.d.ts.map +1 -0
  25. package/dist/types/src/components/AttentionGlyph/AttentionGlyph.stories.d.ts.map +1 -0
  26. package/dist/types/src/components/AttentionGlyph/index.d.ts +2 -0
  27. package/dist/types/src/components/AttentionGlyph/index.d.ts.map +1 -0
  28. package/dist/types/src/components/AttentionProvider/AttentionProvider.d.ts +34 -0
  29. package/dist/types/src/components/AttentionProvider/AttentionProvider.d.ts.map +1 -0
  30. package/dist/types/src/components/AttentionProvider/AttentionProvider.stories.d.ts.map +1 -0
  31. package/dist/types/src/components/AttentionProvider/index.d.ts +2 -0
  32. package/dist/types/src/components/AttentionProvider/index.d.ts.map +1 -0
  33. package/dist/types/src/components/{SelectionProvider.d.ts → SelectionProvider/SelectionProvider.d.ts} +3 -3
  34. package/dist/types/src/components/SelectionProvider/SelectionProvider.d.ts.map +1 -0
  35. package/dist/types/src/components/SelectionProvider/index.d.ts +2 -0
  36. package/dist/types/src/components/SelectionProvider/index.d.ts.map +1 -0
  37. package/dist/types/src/index.d.ts +0 -1
  38. package/dist/types/src/index.d.ts.map +1 -1
  39. package/dist/types/src/selection.d.ts.map +1 -1
  40. package/dist/types/src/testing/decorators/withAttention.d.ts.map +1 -1
  41. package/dist/types/src/types/index.d.ts +3 -0
  42. package/dist/types/src/types/index.d.ts.map +1 -0
  43. package/dist/types/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +22 -32
  45. package/src/attention.test.ts +179 -23
  46. package/src/attention.ts +136 -54
  47. package/src/components/{AttentionGlyph.tsx → AttentionGlyph/AttentionGlyph.tsx} +5 -5
  48. package/src/components/AttentionGlyph/index.ts +5 -0
  49. package/src/components/{AttentionProvider.stories.tsx → AttentionProvider/AttentionProvider.stories.tsx} +1 -2
  50. package/src/components/{AttentionProvider.tsx → AttentionProvider/AttentionProvider.tsx} +47 -79
  51. package/src/components/AttentionProvider/index.ts +5 -0
  52. package/src/components/{SelectionProvider.tsx → SelectionProvider/SelectionProvider.tsx} +15 -8
  53. package/src/components/SelectionProvider/index.ts +5 -0
  54. package/src/index.ts +0 -1
  55. package/src/selection.ts +10 -8
  56. package/src/testing/decorators/withAttention.ts +1 -0
  57. package/src/types/index.ts +9 -0
  58. package/dist/lib/browser/chunk-PAZBZOO2.mjs +0 -7
  59. package/dist/lib/browser/chunk-PAZBZOO2.mjs.map +0 -7
  60. package/dist/lib/browser/chunk-TAZUDNJI.mjs +0 -705
  61. package/dist/lib/browser/chunk-TAZUDNJI.mjs.map +0 -7
  62. package/dist/lib/browser/types.mjs +0 -7
  63. package/dist/lib/node-esm/chunk-FT553KKP.mjs +0 -706
  64. package/dist/lib/node-esm/chunk-FT553KKP.mjs.map +0 -7
  65. package/dist/lib/node-esm/chunk-PMGNPL4M.mjs +0 -9
  66. package/dist/lib/node-esm/chunk-PMGNPL4M.mjs.map +0 -7
  67. package/dist/lib/node-esm/types.mjs +0 -8
  68. package/dist/types/src/components/AttentionGlyph.d.ts.map +0 -1
  69. package/dist/types/src/components/AttentionGlyph.stories.d.ts.map +0 -1
  70. package/dist/types/src/components/AttentionProvider.d.ts +0 -39
  71. package/dist/types/src/components/AttentionProvider.d.ts.map +0 -1
  72. package/dist/types/src/components/AttentionProvider.stories.d.ts.map +0 -1
  73. package/dist/types/src/components/SelectionProvider.d.ts.map +0 -1
  74. package/dist/types/src/types.d.ts +0 -10
  75. package/dist/types/src/types.d.ts.map +0 -1
  76. package/src/types.ts +0 -16
  77. /package/dist/lib/browser/{types.mjs.map → types/index.mjs.map} +0 -0
  78. /package/dist/lib/node-esm/{types.mjs.map → types/index.mjs.map} +0 -0
  79. /package/dist/types/src/components/{AttentionGlyph.d.ts → AttentionGlyph/AttentionGlyph.d.ts} +0 -0
  80. /package/dist/types/src/components/{AttentionGlyph.stories.d.ts → AttentionGlyph/AttentionGlyph.stories.d.ts} +0 -0
  81. /package/dist/types/src/components/{AttentionProvider.stories.d.ts → AttentionProvider/AttentionProvider.stories.d.ts} +0 -0
  82. /package/src/components/{AttentionGlyph.stories.tsx → AttentionGlyph/AttentionGlyph.stories.tsx} +0 -0
@@ -11,6 +11,7 @@ import React, {
11
11
  type FocusEvent,
12
12
  type PropsWithChildren,
13
13
  forwardRef,
14
+ useCallback,
14
15
  useContext,
15
16
  useEffect,
16
17
  useMemo,
@@ -22,8 +23,7 @@ import { useDefaultValue } from '@dxos/react-hooks';
22
23
  import { type ThemedClassName } from '@dxos/react-ui';
23
24
  import { mx } from '@dxos/ui-theme';
24
25
 
25
- import { AttentionManager, getAttendables } from '../attention';
26
- import { ATTENDABLE_PATH_SEPARATOR, type Attention } from '../types';
26
+ import { type Attention, AttentionManager, getAttendables } from '../../attention';
27
27
 
28
28
  const ATTENTION_NAME = 'Attention';
29
29
  const ATTENDABLE_ATTRIBUTE = 'data-attendable-id';
@@ -31,41 +31,34 @@ const ATTENTION_SOURCE_ATTRIBUTE = 'data-w-attention-source';
31
31
 
32
32
  type AttentionContextValue = {
33
33
  attention: AttentionManager;
34
- path: string[];
35
34
  };
36
35
 
37
36
  const [AttentionContextProvider, useAttentionContext] = createContext<AttentionContextValue>(ATTENTION_NAME, {
38
37
  attention: undefined as unknown as AttentionManager,
39
- path: [],
40
38
  });
41
39
 
42
40
  const UNKNOWN_ATTENDABLE = { hasAttention: false, isAncestor: false, isRelated: false } as Attention;
43
41
 
42
+ /**
43
+ * Subscribe to the attention state for a qualified graph ID.
44
+ */
45
+ // TODO(burdon): Unify with seleciton and change to contextId?
44
46
  const useAttention = (attendableId?: string): Attention => {
45
- const { attention, path } = useAttentionContext(ATTENTION_NAME);
47
+ const { attention } = useAttentionContext(ATTENTION_NAME);
46
48
  const [state, setState] = useState<Attention>(UNKNOWN_ATTENDABLE);
47
-
48
- const key = useMemo(() => {
49
- if (!attendableId) {
50
- return undefined;
51
- }
52
- return [...attendableId.split(ATTENDABLE_PATH_SEPARATOR), ...path];
53
- }, [attendableId, path]);
54
-
55
49
  useEffect(() => {
56
- if (!key || !attention) {
50
+ if (!attendableId || !attention) {
57
51
  setState(UNKNOWN_ATTENDABLE);
58
52
  return;
59
53
  }
60
54
 
61
- // Set initial state.
62
- setState(attention.get(key));
55
+ const currentState = attention.get(attendableId);
56
+ setState(currentState);
63
57
 
64
- // Subscribe to changes.
65
- return attention.subscribe(key, (newState) => {
58
+ return attention.subscribe(attendableId, (newState) => {
66
59
  setState(newState);
67
60
  });
68
- }, [attention, key]);
61
+ }, [attention, attendableId]);
69
62
 
70
63
  return state;
71
64
  };
@@ -73,16 +66,13 @@ const useAttention = (attendableId?: string): Attention => {
73
66
  const useAttended = () => {
74
67
  const { attention } = useAttentionContext(ATTENTION_NAME);
75
68
  const [current, setCurrent] = useState<readonly string[]>([]);
76
-
77
69
  useEffect(() => {
78
70
  if (!attention) {
79
71
  return;
80
72
  }
81
73
 
82
- // Set initial state.
83
74
  setCurrent(attention.getCurrent());
84
75
 
85
- // Subscribe to changes.
86
76
  return attention.subscribeCurrent((newCurrent) => {
87
77
  setCurrent(newCurrent);
88
78
  });
@@ -93,7 +83,6 @@ const useAttended = () => {
93
83
 
94
84
  /**
95
85
  * Computes HTML element attributes to apply so the attention system can detect changes.
96
- * @param attendableId
97
86
  */
98
87
  const useAttentionAttributes = (attendableId?: string) => {
99
88
  const { hasAttention } = useAttention(attendableId);
@@ -107,73 +96,57 @@ const useAttentionAttributes = (attendableId?: string) => {
107
96
  }, [attendableId, hasAttention]);
108
97
  };
109
98
 
110
- const useAttentionPath = () => {
111
- const { path } = useAttentionContext(ATTENTION_NAME);
112
- return path;
113
- };
99
+ type RootAttentionProviderProps = PropsWithChildren<{
100
+ attention?: AttentionManager;
101
+ onChange?: (nextAttended: string[]) => void;
102
+ }>;
114
103
 
115
- const RootAttentionProvider = ({
116
- children,
117
- attention: propsAttention,
118
- onChange,
119
- }: PropsWithChildren<
120
- Partial<{
121
- attention: AttentionManager;
122
- onChange: (nextAttended: string[]) => void;
123
- }>
124
- >) => {
104
+ const RootAttentionProvider = ({ children, attention: propsAttention, onChange }: RootAttentionProviderProps) => {
125
105
  const registry = useContext(RegistryContext);
126
106
  const attention = useDefaultValue(propsAttention, () => new AttentionManager(registry));
127
107
 
128
- const handleFocus = (event: FocusEvent) => {
129
- // NOTE(thure): Use the following to debug focus movement across the app:
130
- log('focus', { related: event.relatedTarget, target: event.target });
131
-
132
- const selector = [
133
- '[data-attendable-id]',
134
- ...Array.from(document.querySelectorAll('[aria-controls]')).map(
135
- (el) => `[id="${el.getAttribute('aria-controls')}"]`,
136
- ),
137
- ].join(',');
138
- const prev = attention.getCurrent();
139
- const next = getAttendables(selector, event.target);
140
- // TODO(wittjosiah): Not allowing empty state means that the attended item is not strictly guaranteed to be in the DOM.
141
- // Currently this depends on the deck in order to ensure that when the attended item is removed something else is attended.
142
- // Only update state if the result is different and not empty.
143
- if (next.length > 0 && (prev.length !== next.length || !!prev.find((id, index) => next[index] !== id))) {
144
- attention.update(next);
145
- onChange?.(next);
146
- }
147
- };
108
+ const handleFocus = useCallback(
109
+ (event: FocusEvent) => {
110
+ // NOTE(thure): Use the following to debug focus movement across the app:
111
+ log('focus', { related: event.relatedTarget, target: event.target });
112
+
113
+ const selector = [
114
+ '[data-attendable-id]',
115
+ ...Array.from(document.querySelectorAll('[aria-controls]')).map(
116
+ (el) => `[id="${el.getAttribute('aria-controls')}"]`,
117
+ ),
118
+ ].join(',');
119
+ const prev = attention.getCurrent();
120
+ const next = getAttendables(selector, event.target);
121
+ // TODO(wittjosiah): Not allowing empty state means that the attended item is not strictly guaranteed to be in the DOM.
122
+ // Currently this depends on the deck in order to ensure that when the attended item is removed something else is attended.
123
+ // Only update state if the result is different and not empty.
124
+ if (next.length > 0 && (prev.length !== next.length || !!prev.find((id, index) => next[index] !== id))) {
125
+ attention.update(next);
126
+ onChange?.(next);
127
+ }
128
+ },
129
+ [attention, onChange],
130
+ );
148
131
 
149
132
  return (
150
- <AttentionContextProvider attention={attention} path={[]}>
151
- <div role='none' className='contents' onFocusCapture={handleFocus}>
133
+ <AttentionContextProvider attention={attention}>
134
+ <div className='contents' onFocusCapture={handleFocus}>
152
135
  {children}
153
136
  </div>
154
137
  </AttentionContextProvider>
155
138
  );
156
139
  };
157
140
 
158
- const AttentionProvider = ({ id, children }: PropsWithChildren<{ id: string }>) => {
159
- const { attention, path } = useAttentionContext(ATTENTION_NAME);
160
- const nextPath = useMemo(() => [id, ...path], [id, path]);
161
-
162
- return (
163
- <AttentionContextProvider attention={attention} path={nextPath}>
164
- {children}
165
- </AttentionContextProvider>
166
- );
167
- };
168
-
169
141
  export type AttendableContainerProps = ThemedClassName<
170
142
  ComponentPropsWithRef<'div'> & { id: string; asChild?: boolean }
171
143
  >;
172
144
 
173
145
  /**
174
- * Note that DeckPlugin and StackPlugin both handle attention on their own, and when rendering content in those cases it
175
- * is not necessary to also render an `AttendableContainer`. This component is primarily for Storybook stories and other
176
- * testing scenarios, or the rare cases where an attendable entity is rendered outside of either of those plugins.
146
+ * Note that DeckPlugin and StackPlugin both handle attention on their own,
147
+ * and when rendering content in those cases it is not necessary to also render an `AttendableContainer`.
148
+ * This component is primarily for Storybook stories and other testing scenarios,
149
+ * or the rare cases where an attendable entity is rendered outside of either of those plugins.
177
150
  */
178
151
  const AttendableContainer = forwardRef<HTMLDivElement, AttendableContainerProps>(
179
152
  ({ id, classNames, children, asChild, ...props }, forwardedRef) => {
@@ -182,8 +155,8 @@ const AttendableContainer = forwardRef<HTMLDivElement, AttendableContainerProps>
182
155
  return (
183
156
  <Comp
184
157
  role='none'
185
- {...attentionAttrs}
186
158
  {...props}
159
+ {...attentionAttrs}
187
160
  className={mx('dx-attention-surface', props.tabIndex === 0 && 'dx-focus-ring-inset-over-all', classNames)}
188
161
  ref={forwardedRef}
189
162
  >
@@ -195,14 +168,9 @@ const AttendableContainer = forwardRef<HTMLDivElement, AttendableContainerProps>
195
168
 
196
169
  export {
197
170
  RootAttentionProvider,
198
- AttentionProvider,
199
171
  AttendableContainer,
200
172
  useAttentionContext,
201
173
  useAttention,
202
174
  useAttended,
203
175
  useAttentionAttributes,
204
- useAttentionPath,
205
- ATTENTION_NAME,
206
- ATTENDABLE_ATTRIBUTE,
207
- ATTENTION_SOURCE_ATTRIBUTE,
208
176
  };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './AttentionProvider';
@@ -15,7 +15,7 @@ import {
15
15
  type SelectionMode,
16
16
  type SelectionResult,
17
17
  defaultSelection,
18
- } from '../selection';
18
+ } from '../../selection';
19
19
 
20
20
  const SELECTION_NAME = 'Selection';
21
21
 
@@ -23,6 +23,11 @@ type SelectionContextValue = {
23
23
  selection: SelectionManager;
24
24
  };
25
25
 
26
+ // Default value lets consumers like `useSelected` render outside a
27
+ // `SelectionProvider` (e.g. isolated stories) without throwing —
28
+ // `selection` reads as `undefined` and the hook falls back to the
29
+ // per-mode default result. Without this default, Radix `createContext`
30
+ // throws "Selection must be used within Selection" on every consumer.
26
31
  const [SelectionContextProvider, useSelectionContext] = createContext<SelectionContextValue>(SELECTION_NAME, {
27
32
  selection: undefined as unknown as SelectionManager,
28
33
  });
@@ -30,20 +35,20 @@ const [SelectionContextProvider, useSelectionContext] = createContext<SelectionC
30
35
  /**
31
36
  * Manages selection state across the app for multiple contexts.
32
37
  */
33
- // TODO(burdon): When is the selection removed?
34
38
  export const SelectionProvider = ({
35
39
  children,
36
- selection: propsSelection,
40
+ selection: selectionProp,
37
41
  }: PropsWithChildren<{ selection?: SelectionManager }>) => {
38
42
  const registry = useContext(RegistryContext);
39
- const selection = useDefaultValue(propsSelection, () => new SelectionManager(registry));
43
+ const selection = useDefaultValue(selectionProp, () => new SelectionManager(registry));
44
+
40
45
  return <SelectionContextProvider selection={selection}>{children}</SelectionContextProvider>;
41
46
  };
42
47
 
43
48
  /**
44
49
  * Get the selection contexts.
45
50
  */
46
- export const useSelectionManager = () => {
51
+ export const useSelectionManager = (): SelectionManager => {
47
52
  const { selection } = useSelectionContext(SELECTION_NAME);
48
53
  return selection;
49
54
  };
@@ -101,11 +106,13 @@ export type UseSelectionActions = {
101
106
  /**
102
107
  * Provides functions to manage the selection state for multiple contexts.
103
108
  */
104
- // TODO(burdon): Mode not used.
105
- export const useSelectionActions = (contextIds: string[], mode: SelectionMode = 'multi'): UseSelectionActions => {
106
- const stableContextIds = useMemo(() => contextIds, [JSON.stringify(contextIds)]); // TODO(burdon): Avoid stringify.
109
+ export const useSelectionActions = (contextIds: string[]): UseSelectionActions => {
110
+ const stableContextIds = useMemo(() => contextIds, [JSON.stringify(contextIds)]);
107
111
  const { selection } = useSelectionContext(SELECTION_NAME);
108
112
 
113
+ // No-op when rendered outside a `SelectionProvider` (e.g. an isolated
114
+ // story or a test harness) — `selection` is `undefined` from the
115
+ // context default value. Matches the pre-co-locate behaviour.
109
116
  const singleSelect = useCallback(
110
117
  (id: string) => {
111
118
  if (!selection) {
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './SelectionProvider';
package/src/index.ts CHANGED
@@ -5,4 +5,3 @@
5
5
  export * from './attention';
6
6
  export * from './components';
7
7
  export * from './selection';
8
- export * from './types';
package/src/selection.ts CHANGED
@@ -8,15 +8,17 @@ import * as Schema from 'effect/Schema';
8
8
 
9
9
  import { invariant } from '@dxos/invariant';
10
10
 
11
- // TODO(burdon): Reconcile with @dxos/graph.
12
-
13
11
  export type SelectionMode = 'single' | 'multi' | 'range' | 'multi-range';
14
12
 
15
13
  export const SelectionSchema = Schema.Union(
16
- Schema.Struct({ mode: Schema.Literal('single'), id: Schema.optional(Schema.String) }).pipe(Schema.mutable),
17
- Schema.Struct({ mode: Schema.Literal('multi'), ids: Schema.Array(Schema.String).pipe(Schema.mutable) }).pipe(
18
- Schema.mutable,
19
- ),
14
+ Schema.Struct({
15
+ mode: Schema.Literal('single'),
16
+ id: Schema.optional(Schema.String),
17
+ }).pipe(Schema.mutable),
18
+ Schema.Struct({
19
+ mode: Schema.Literal('multi'),
20
+ ids: Schema.Array(Schema.String).pipe(Schema.mutable),
21
+ }).pipe(Schema.mutable),
20
22
  Schema.Struct({
21
23
  mode: Schema.Literal('range'),
22
24
  from: Schema.optional(Schema.String),
@@ -49,7 +51,6 @@ export type SelectionResult<T extends SelectionMode> = T extends 'single'
49
51
  ? { from: string; to: string }[]
50
52
  : never;
51
53
 
52
- // TODO(burdon): Refactor.
53
54
  export const getSelectionSet = (selectionManager: SelectionManager, contextId?: string) => {
54
55
  const ids = new Set<string>(contextId ? [contextId] : []);
55
56
  for (const context of selectionManager.getSelectionContexts()) {
@@ -125,13 +126,14 @@ export class SelectionManager {
125
126
  this._registry.update(this._state, (state) => ({
126
127
  selections: { ...state.selections, [contextId]: newSelection },
127
128
  }));
129
+
128
130
  return newSelection;
129
131
  }
130
132
 
131
- // TODO(burdon): Disambiguate with getSelection?
132
133
  getSelected<T extends SelectionMode>(contextId: string, mode: T = 'multi' as T): SelectionResult<T> {
133
134
  const selection = this.getSelection(contextId, mode);
134
135
  invariant(selection?.mode === mode, 'Selection mode mismatch');
136
+
135
137
  // Cast required because TypeScript can't infer the relationship between T and the matched result.
136
138
  return Match.type<Selection>().pipe(
137
139
  Match.when({ mode: 'single' }, (s) => s.id),
@@ -20,6 +20,7 @@ export const withAttention = (initialAttendedId?: string): Decorator => {
20
20
  () => (initialAttendedId ? new AttentionManager(registry, [initialAttendedId]) : undefined),
21
21
  [registry],
22
22
  );
23
+
23
24
  return createElement(
24
25
  RegistryContext.Provider,
25
26
  { value: registry },
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ // UI-free re-exports of @dxos/react-ui-attention. Importing from here does not
6
+ // pull in React components, so it is safe to use from operations, schemas, and
7
+ // other non-DOM code that only needs the data model and pure helpers.
8
+ export * from '../attention';
9
+ export * from '../selection';
@@ -1,7 +0,0 @@
1
- // src/types.ts
2
- var ATTENDABLE_PATH_SEPARATOR = "~";
3
-
4
- export {
5
- ATTENDABLE_PATH_SEPARATOR
6
- };
7
- //# sourceMappingURL=chunk-PAZBZOO2.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/types.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\n// NOTE: Chosen from RFC 1738's `safe` characters: http://www.faqs.org/rfcs/rfc1738.html\nexport const ATTENDABLE_PATH_SEPARATOR = '~';\n\nexport type Attention = {\n hasAttention: boolean;\n isAncestor: boolean;\n isRelated: boolean;\n};\n\nexport type CurrentState = {\n current: string[];\n};\n"],
5
- "mappings": ";AAKO,IAAMA,4BAA4B;",
6
- "names": ["ATTENDABLE_PATH_SEPARATOR"]
7
- }