@dxos/react-ui-attention 0.8.4-main.40e3dcdf1b → 0.8.4-main.422d1c7879

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 (35) hide show
  1. package/dist/lib/browser/{chunk-Q5SLNQ4B.mjs → chunk-4SEURHOL.mjs} +16 -12
  2. package/dist/lib/browser/chunk-4SEURHOL.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-GMKHOVJ5.mjs +1 -0
  4. package/dist/lib/browser/chunk-GMKHOVJ5.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +8 -7
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/testing/index.mjs +1 -2
  8. package/dist/lib/browser/testing/index.mjs.map +1 -1
  9. package/dist/lib/browser/types.mjs +1 -6
  10. package/dist/lib/node-esm/{chunk-LSWTWT3W.mjs → chunk-6PQ4P7AL.mjs} +16 -11
  11. package/dist/lib/node-esm/chunk-6PQ4P7AL.mjs.map +7 -0
  12. package/dist/lib/node-esm/chunk-UHVMYYIB.mjs +2 -0
  13. package/dist/lib/node-esm/chunk-UHVMYYIB.mjs.map +7 -0
  14. package/dist/lib/node-esm/index.mjs +8 -7
  15. package/dist/lib/node-esm/meta.json +1 -1
  16. package/dist/lib/node-esm/testing/index.mjs +1 -2
  17. package/dist/lib/node-esm/testing/index.mjs.map +1 -1
  18. package/dist/lib/node-esm/types.mjs +1 -6
  19. package/dist/types/src/attention.d.ts +14 -2
  20. package/dist/types/src/attention.d.ts.map +1 -1
  21. package/dist/types/src/components/AttentionProvider.stories.d.ts.map +1 -1
  22. package/dist/types/src/types.d.ts +0 -1
  23. package/dist/types/src/types.d.ts.map +1 -1
  24. package/dist/types/tsconfig.tsbuildinfo +1 -1
  25. package/package.json +14 -24
  26. package/src/attention.test.ts +37 -10
  27. package/src/attention.ts +31 -8
  28. package/src/components/AttentionProvider.stories.tsx +0 -1
  29. package/src/types.ts +0 -3
  30. package/dist/lib/browser/chunk-PAZBZOO2.mjs +0 -7
  31. package/dist/lib/browser/chunk-PAZBZOO2.mjs.map +0 -7
  32. package/dist/lib/browser/chunk-Q5SLNQ4B.mjs.map +0 -7
  33. package/dist/lib/node-esm/chunk-LSWTWT3W.mjs.map +0 -7
  34. package/dist/lib/node-esm/chunk-PMGNPL4M.mjs +0 -9
  35. package/dist/lib/node-esm/chunk-PMGNPL4M.mjs.map +0 -7
@@ -1,7 +1,3 @@
1
- import {
2
- ATTENDABLE_PATH_SEPARATOR
3
- } from "./chunk-PAZBZOO2.mjs";
4
-
5
1
  // src/attention.ts
6
2
  import { Atom } from "@effect-atom/atom-react";
7
3
  var AttentionManager = class {
@@ -77,8 +73,8 @@ var AttentionManager = class {
77
73
  * Takes the array of qualified IDs collected from the DOM; the first element is the primary attended item.
78
74
  * Ancestry is derived from the progressive prefixes of the primary ID.
79
75
  * Relatedness is derived from the segment ID: any tracked key whose last `/` segment matches the
80
- * attended ID's segment ID is marked `isRelated`. Additionally, if the primary ID has a
81
- * separator-prefixed last segment (starts with `~`), its immediate parent gets `isRelated` alongside `isAncestor`.
76
+ * attended ID's segment ID is marked `isRelated`. Additionally, if the primary ID is a linked segment
77
+ * (starts with `~`), its immediate parent gets `isRelated` alongside `isAncestor`.
82
78
  *
83
79
  * @internal
84
80
  */
@@ -104,13 +100,13 @@ var AttentionManager = class {
104
100
  this._registry.set(this._currentAtom, nextIds);
105
101
  const prefixes = expandAttendableId(primaryId);
106
102
  const prefixSet = new Set(prefixes);
107
- const separatedParent = isSeparatorPrefixed(primaryId) ? getParentId(primaryId) : void 0;
103
+ const linkedParent = isLinkedSegment(primaryId) ? getParentId(primaryId) : void 0;
108
104
  for (const prefix of prefixes) {
109
105
  if (prefix === primaryId) {
110
106
  this._set(prefix, {
111
107
  hasAttention: true
112
108
  });
113
- } else if (prefix === separatedParent) {
109
+ } else if (prefix === linkedParent) {
114
110
  this._set(prefix, {
115
111
  isAncestor: true,
116
112
  isRelated: true
@@ -159,13 +155,19 @@ var getAttendables = (selector, cursor, acc = []) => {
159
155
  ...new Set(acc)
160
156
  ];
161
157
  };
158
+ var LINKED_PREFIX = "~";
162
159
  var expandAttendableId = (qualifiedId) => {
163
160
  const segments = qualifiedId.split("/");
164
161
  return segments.map((_, index) => segments.slice(0, index + 1).join("/"));
165
162
  };
166
- var isSeparatorPrefixed = (qualifiedId) => {
163
+ var isLinkedSegment = (qualifiedId) => {
164
+ const lastSegment = qualifiedId.split("/").pop() ?? "";
165
+ return lastSegment.startsWith(LINKED_PREFIX);
166
+ };
167
+ var linkedSegment = (variant) => `${LINKED_PREFIX}${variant}`;
168
+ var getLinkedVariant = (qualifiedId) => {
167
169
  const lastSegment = qualifiedId.split("/").pop() ?? "";
168
- return lastSegment.startsWith(ATTENDABLE_PATH_SEPARATOR);
170
+ return lastSegment.startsWith(LINKED_PREFIX) ? lastSegment.slice(LINKED_PREFIX.length) : lastSegment;
169
171
  };
170
172
  var getParentId = (qualifiedId) => {
171
173
  if (!qualifiedId) {
@@ -693,7 +695,9 @@ export {
693
695
  AttentionManager,
694
696
  getAttendables,
695
697
  expandAttendableId,
696
- isSeparatorPrefixed,
698
+ isLinkedSegment,
699
+ linkedSegment,
700
+ getLinkedVariant,
697
701
  getParentId,
698
702
  getSegmentId,
699
703
  ATTENTION_NAME,
@@ -714,4 +718,4 @@ export {
714
718
  useSelected,
715
719
  useSelectionActions
716
720
  };
717
- //# sourceMappingURL=chunk-Q5SLNQ4B.mjs.map
721
+ //# sourceMappingURL=chunk-4SEURHOL.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/attention.ts", "../../../src/components/AttentionProvider.tsx", "../../../src/selection.ts", "../../../src/components/SelectionProvider.tsx"],
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { Atom, type Registry } from '@effect-atom/atom-react';\n\nimport { type Attention } from './types';\n\n/**\n * Manages attention state for an application.\n * Attention keys are slash-qualified graph IDs; ancestry is derived from progressive prefixes.\n */\nexport class AttentionManager {\n private readonly _map = new Map<string, Atom.Writable<Attention>>();\n private readonly _currentAtom: Atom.Writable<string[]>;\n\n constructor(\n private readonly _registry: Registry.Registry,\n initial: string[] = [],\n ) {\n this._currentAtom = Atom.make<string[]>([]).pipe(Atom.keepAlive);\n if (initial.length > 0) {\n this.update(initial);\n }\n }\n\n /**\n * Atom for the currently attended element IDs.\n */\n get current(): Atom.Atom<string[]> {\n return this._currentAtom;\n }\n\n /**\n * Gets the currently attended element IDs.\n */\n getCurrent(): readonly string[] {\n return this._registry.get(this._currentAtom);\n }\n\n /**\n * Subscribe to changes in the current attention IDs.\n */\n subscribeCurrent(cb: (current: readonly string[]) => void): () => void {\n this._registry.get(this._currentAtom);\n return this._registry.subscribe(this._currentAtom, () => {\n cb(this._registry.get(this._currentAtom));\n });\n }\n\n /**\n * All tracked qualified IDs.\n */\n keys(): string[] {\n return Array.from(this._map.keys());\n }\n\n /**\n * Get the attention state for a given qualified ID.\n */\n get(id: string): Attention {\n const atom = this._getAtom(id);\n return this._registry.get(atom);\n }\n\n /**\n * Subscribe to changes in the attention state for a given qualified ID.\n */\n subscribe(id: string, cb: (attention: Attention) => void): () => void {\n const atom = this._getAtom(id);\n this._registry.get(atom);\n return this._registry.subscribe(atom, () => {\n cb(this._registry.get(atom));\n });\n }\n\n private _getAtom(id: string): Atom.Writable<Attention> {\n const existing = this._map.get(id);\n if (existing) {\n return existing;\n }\n\n const newAtom = Atom.make<Attention>({ hasAttention: false, isAncestor: false, isRelated: false }).pipe(\n Atom.keepAlive,\n );\n this._map.set(id, newAtom);\n return newAtom;\n }\n\n /**\n * Update the currently attended element.\n * Takes the array of qualified IDs collected from the DOM; the first element is the primary attended item.\n * Ancestry is derived from the progressive prefixes of the primary ID.\n * Relatedness is derived from the segment ID: any tracked key whose last `/` segment matches the\n * attended ID's segment ID is marked `isRelated`. Additionally, if the primary ID is a linked segment\n * (starts with `~`), its immediate parent gets `isRelated` alongside `isAncestor`.\n *\n * @internal\n */\n update(nextIds: string[]): void {\n const primaryId = nextIds[0];\n if (!primaryId) {\n return;\n }\n\n const currentIds = this.getCurrent();\n const prevPrimaryId = currentIds[0];\n // Clear previous attention state: ancestors, primary, and related keys.\n if (prevPrimaryId) {\n const prevPrefixes = expandAttendableId(prevPrimaryId);\n for (const prefix of prevPrefixes) {\n this._set(prefix, {});\n }\n const prevSegmentId = getSegmentId(prevPrimaryId);\n for (const key of this.keys()) {\n if (getSegmentId(key) === prevSegmentId) {\n this._set(key, {});\n }\n }\n }\n\n this._registry.set(this._currentAtom, nextIds);\n\n // Set ancestors and primary.\n const prefixes = expandAttendableId(primaryId);\n const prefixSet = new Set(prefixes);\n const linkedParent = isLinkedSegment(primaryId) ? getParentId(primaryId) : undefined;\n\n for (const prefix of prefixes) {\n if (prefix === primaryId) {\n this._set(prefix, { hasAttention: true });\n } else if (prefix === linkedParent) {\n this._set(prefix, { isAncestor: true, isRelated: true });\n } else {\n this._set(prefix, { isAncestor: true });\n }\n }\n\n // Set related keys: any tracked key sharing the same segment ID.\n const segmentId = getSegmentId(primaryId);\n for (const key of this.keys()) {\n if (!prefixSet.has(key) && getSegmentId(key) === segmentId) {\n this._set(key, { isRelated: true });\n }\n }\n }\n\n private _set(id: string, attention: Partial<Attention>): void {\n const atom = this._getAtom(id);\n this._registry.set(atom, {\n hasAttention: attention.hasAttention ?? false,\n isAncestor: attention.isAncestor ?? false,\n isRelated: attention.isRelated ?? false,\n });\n }\n}\n\n/**\n * Accumulates all attendable IDs between the element provided and the root, inclusive.\n * Each `data-attendable-id` value is treated as a single qualified ID (no splitting).\n */\nexport const getAttendables = (selector: string, cursor: Element, acc: string[] = []): string[] => {\n // Find the closest element with `data-attendable-id`, if any; start from cursor and move up the DOM tree.\n const closestAttendable = cursor.closest(selector);\n if (closestAttendable) {\n const attendableId = closestAttendable.getAttribute('data-attendable-id');\n if (!attendableId) {\n // This has an id of an aria-controls elsewhere on the page, move cursor to that trigger.\n const trigger = document.querySelector(`[aria-controls=\"${closestAttendable.getAttribute('id')}\"]`);\n if (!trigger) {\n return acc;\n } else {\n return getAttendables(selector, trigger, acc);\n }\n } else {\n acc.push(attendableId);\n return !closestAttendable.parentElement ? acc : getAttendables(selector, closestAttendable.parentElement, acc);\n }\n }\n\n return [...new Set(acc)];\n};\n\nexport type AttendableId = { attendableId?: string };\n\nexport type Related = { related?: boolean };\n\n/**\n * Prefix for linked segments. A linked segment's attention state is shared with its parent:\n * when a linked node has attention, the parent is marked as both ancestor and related.\n */\nconst LINKED_PREFIX = '~';\n\n/**\n * Decompose a qualified graph ID into progressive prefixes for ancestry tracking.\n * e.g. `root/a/b/c` yields `['root', 'root/a', 'root/a/b', 'root/a/b/c']`.\n */\nexport const expandAttendableId = (qualifiedId: string): string[] => {\n const segments = qualifiedId.split('/');\n return segments.map((_, index) => segments.slice(0, index + 1).join('/'));\n};\n\n/**\n * Whether the last segment of a qualified ID is a linked segment (starts with `~`).\n * Linked segments share their attention state with the parent node.\n */\nexport const isLinkedSegment = (qualifiedId: string): boolean => {\n const lastSegment = qualifiedId.split('/').pop() ?? '';\n return lastSegment.startsWith(LINKED_PREFIX);\n};\n\n/**\n * Build a linked segment ID from a variant name (e.g., `'settings'` -> `'~settings'`).\n * Nodes identified by linked segments share their attention state with the parent node.\n */\nexport const linkedSegment = (variant: string): string => `${LINKED_PREFIX}${variant}`;\n\n/**\n * Extract the variant name from the last segment of a qualified ID, stripping the linked prefix.\n * e.g. `'root/space/obj/~settings'` -> `'settings'`.\n * If the segment is not linked (no `~` prefix), returns the segment as-is.\n */\nexport const getLinkedVariant = (qualifiedId: string): string => {\n const lastSegment = qualifiedId.split('/').pop() ?? '';\n return lastSegment.startsWith(LINKED_PREFIX) ? lastSegment.slice(LINKED_PREFIX.length) : lastSegment;\n};\n\n/**\n * Get the parent qualified ID (everything before the last `/` segment).\n */\nexport const getParentId = (qualifiedId: string | undefined): string | undefined => {\n if (!qualifiedId) {\n return undefined;\n }\n\n const lastSlash = qualifiedId.lastIndexOf('/');\n return lastSlash > 0 ? qualifiedId.slice(0, lastSlash) : undefined;\n};\n\n/**\n * Extract the segment ID (last segment) of a qualified ID.\n */\nexport const getSegmentId = (qualifiedId: string): string => {\n return qualifiedId.split('/').pop() ?? qualifiedId;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { RegistryContext } from '@effect-atom/atom-react';\nimport { createContext } from '@radix-ui/react-context';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { Slot } from '@radix-ui/react-slot';\nimport React, {\n type ComponentPropsWithRef,\n type FocusEvent,\n type PropsWithChildren,\n forwardRef,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\nimport { log } from '@dxos/log';\nimport { useDefaultValue } from '@dxos/react-hooks';\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/ui-theme';\n\nimport { AttentionManager, getAttendables } from '../attention';\nimport { type Attention } from '../types';\n\nconst ATTENTION_NAME = 'Attention';\nconst ATTENDABLE_ATTRIBUTE = 'data-attendable-id';\nconst ATTENTION_SOURCE_ATTRIBUTE = 'data-w-attention-source';\n\ntype AttentionContextValue = {\n attention: AttentionManager;\n};\n\nconst [AttentionContextProvider, useAttentionContext] = createContext<AttentionContextValue>(ATTENTION_NAME, {\n attention: undefined as unknown as AttentionManager,\n});\n\nconst UNKNOWN_ATTENDABLE = { hasAttention: false, isAncestor: false, isRelated: false } as Attention;\n\n/**\n * Subscribe to the attention state for a qualified graph ID.\n */\nconst useAttention = (attendableId?: string): Attention => {\n const { attention } = useAttentionContext(ATTENTION_NAME);\n const [state, setState] = useState<Attention>(UNKNOWN_ATTENDABLE);\n\n useEffect(() => {\n if (!attendableId || !attention) {\n setState(UNKNOWN_ATTENDABLE);\n return;\n }\n\n const currentState = attention.get(attendableId);\n setState(currentState);\n\n return attention.subscribe(attendableId, (newState) => {\n setState(newState);\n });\n }, [attention, attendableId]);\n\n return state;\n};\n\nconst useAttended = () => {\n const { attention } = useAttentionContext(ATTENTION_NAME);\n const [current, setCurrent] = useState<readonly string[]>([]);\n\n useEffect(() => {\n if (!attention) {\n return;\n }\n\n setCurrent(attention.getCurrent());\n\n return attention.subscribeCurrent((newCurrent) => {\n setCurrent(newCurrent);\n });\n }, [attention]);\n\n return current;\n};\n\n/**\n * Computes HTML element attributes to apply so the attention system can detect changes.\n */\nconst useAttentionAttributes = (attendableId?: string) => {\n const { hasAttention } = useAttention(attendableId);\n return useMemo(() => {\n const attributes: Record<string, string | undefined> = { [ATTENDABLE_ATTRIBUTE]: attendableId };\n if (hasAttention) {\n attributes[ATTENTION_SOURCE_ATTRIBUTE] = 'true';\n }\n\n return attributes;\n }, [attendableId, hasAttention]);\n};\n\nconst RootAttentionProvider = ({\n children,\n attention: propsAttention,\n onChange,\n}: PropsWithChildren<\n Partial<{\n attention: AttentionManager;\n onChange: (nextAttended: string[]) => void;\n }>\n>) => {\n const registry = useContext(RegistryContext);\n const attention = useDefaultValue(propsAttention, () => new AttentionManager(registry));\n\n const handleFocus = (event: FocusEvent) => {\n // NOTE(thure): Use the following to debug focus movement across the app:\n log('focus', { related: event.relatedTarget, target: event.target });\n\n const selector = [\n '[data-attendable-id]',\n ...Array.from(document.querySelectorAll('[aria-controls]')).map(\n (el) => `[id=\"${el.getAttribute('aria-controls')}\"]`,\n ),\n ].join(',');\n const prev = attention.getCurrent();\n const next = getAttendables(selector, event.target);\n // TODO(wittjosiah): Not allowing empty state means that the attended item is not strictly guaranteed to be in the DOM.\n // Currently this depends on the deck in order to ensure that when the attended item is removed something else is attended.\n // Only update state if the result is different and not empty.\n if (next.length > 0 && (prev.length !== next.length || !!prev.find((id, index) => next[index] !== id))) {\n attention.update(next);\n onChange?.(next);\n }\n };\n\n return (\n <AttentionContextProvider attention={attention}>\n <div role='none' className='contents' onFocusCapture={handleFocus}>\n {children}\n </div>\n </AttentionContextProvider>\n );\n};\n\nexport type AttendableContainerProps = ThemedClassName<\n ComponentPropsWithRef<'div'> & { id: string; asChild?: boolean }\n>;\n\n/**\n * Note that DeckPlugin and StackPlugin both handle attention on their own,\n * and when rendering content in those cases it is not necessary to also render an `AttendableContainer`.\n * This component is primarily for Storybook stories and other testing scenarios,\n * or the rare cases where an attendable entity is rendered outside of either of those plugins.\n */\nconst AttendableContainer = forwardRef<HTMLDivElement, AttendableContainerProps>(\n ({ id, classNames, children, asChild, ...props }, forwardedRef) => {\n const attentionAttrs = useAttentionAttributes(id);\n const Comp = asChild ? Slot : Primitive.div;\n return (\n <Comp\n role='none'\n {...props}\n {...attentionAttrs}\n className={mx('dx-attention-surface', props.tabIndex === 0 && 'dx-focus-ring-inset-over-all', classNames)}\n ref={forwardedRef}\n >\n {children}\n </Comp>\n );\n },\n);\n\nexport {\n RootAttentionProvider,\n AttendableContainer,\n useAttentionContext,\n useAttention,\n useAttended,\n useAttentionAttributes,\n ATTENTION_NAME,\n ATTENDABLE_ATTRIBUTE,\n ATTENTION_SOURCE_ATTRIBUTE,\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { Atom, type Registry } from '@effect-atom/atom-react';\nimport * as Match from 'effect/Match';\nimport * as Schema from 'effect/Schema';\n\nimport { invariant } from '@dxos/invariant';\n\n// TODO(burdon): Reconcile with @dxos/graph.\n\nexport type SelectionMode = 'single' | 'multi' | 'range' | 'multi-range';\n\nexport const SelectionSchema = Schema.Union(\n Schema.Struct({ mode: Schema.Literal('single'), id: Schema.optional(Schema.String) }).pipe(Schema.mutable),\n Schema.Struct({ mode: Schema.Literal('multi'), ids: Schema.Array(Schema.String).pipe(Schema.mutable) }).pipe(\n Schema.mutable,\n ),\n Schema.Struct({\n mode: Schema.Literal('range'),\n from: Schema.optional(Schema.String),\n to: Schema.optional(Schema.String),\n }).pipe(Schema.mutable),\n Schema.Struct({\n mode: Schema.Literal('multi-range'),\n ranges: Schema.Array(Schema.Struct({ from: Schema.String, to: Schema.String })).pipe(Schema.mutable),\n }).pipe(Schema.mutable),\n).pipe(Schema.mutable);\n\nexport type Selection = Schema.Schema.Type<typeof SelectionSchema>;\n\nexport const defaultSelection = Match.type<SelectionMode>().pipe(\n Match.withReturnType<Selection>(),\n Match.when('single', () => ({ mode: 'single' })),\n Match.when('multi', () => ({ mode: 'multi', ids: [] })),\n Match.when('range', () => ({ mode: 'range' })),\n Match.when('multi-range', () => ({ mode: 'multi-range', ranges: [] })),\n Match.exhaustive,\n);\n\nexport type SelectionResult<T extends SelectionMode> = T extends 'single'\n ? string | undefined\n : T extends 'multi'\n ? string[]\n : T extends 'range'\n ? { from: string; to: string } | undefined\n : T extends 'multi-range'\n ? { from: string; to: string }[]\n : never;\n\n// TODO(burdon): Refactor.\nexport const getSelectionSet = (selectionManager: SelectionManager, contextId?: string) => {\n const ids = new Set<string>(contextId ? [contextId] : []);\n for (const context of selectionManager.getSelectionContexts()) {\n const selection = selectionManager.getSelection(context);\n if (selection?.mode === 'multi') {\n for (const id of selection.ids) {\n ids.add(id);\n }\n }\n }\n\n return ids;\n};\n\n/**\n * Manages selection state for different contexts.\n * Each context maintains its own selection mode and state.\n */\nexport class SelectionManager {\n private readonly _state: Atom.Writable<{ selections: Record<string, Selection> }>;\n\n constructor(\n private readonly _registry: Registry.Registry,\n initial: Record<string, Selection> = {},\n ) {\n this._state = Atom.make<{ selections: Record<string, Selection> }>({\n selections: { ...initial },\n });\n }\n\n /**\n * Get the state atom for reactive access in the graph system.\n */\n get state(): Atom.Atom<{ selections: Record<string, Selection> }> {\n return this._state;\n }\n\n /**\n * Gets the current state.\n */\n getState(): { selections: Record<string, Selection> } {\n return this._registry.get(this._state);\n }\n\n /**\n * Subscribe to changes in the selection state.\n */\n subscribe(cb: (state: { selections: Record<string, Selection> }) => void): () => void {\n this._registry.get(this._state);\n return this._registry.subscribe(this._state, () => {\n cb(this._registry.get(this._state));\n });\n }\n\n getSelectionContexts(): string[] {\n return Object.keys(this._registry.get(this._state).selections);\n }\n\n getSelection(contextId: string): Selection | undefined;\n getSelection<T extends SelectionMode>(contextId: string, mode: T): Selection;\n getSelection<T extends SelectionMode | undefined>(\n contextId: string,\n mode: T = undefined as T,\n ): Selection | undefined {\n const state = this._registry.get(this._state);\n const selection = state.selections[contextId];\n if (!mode || selection) {\n return selection;\n }\n\n // Create new selection for the context.\n const newSelection = defaultSelection(mode);\n this._registry.update(this._state, (state) => ({\n selections: { ...state.selections, [contextId]: newSelection },\n }));\n return newSelection;\n }\n\n // TODO(burdon): Disambiguate with getSelection?\n getSelected<T extends SelectionMode>(contextId: string, mode: T = 'multi' as T): SelectionResult<T> {\n const selection = this.getSelection(contextId, mode);\n invariant(selection?.mode === mode, 'Selection mode mismatch');\n // Cast required because TypeScript can't infer the relationship between T and the matched result.\n return Match.type<Selection>().pipe(\n Match.when({ mode: 'single' }, (s) => s.id),\n Match.when({ mode: 'multi' }, (s) => s.ids),\n Match.when({ mode: 'range' }, (s) => (s.from && s.to ? { from: s.from, to: s.to } : undefined)),\n Match.when({ mode: 'multi-range' }, (s) => s.ranges),\n Match.exhaustive,\n )(selection) as SelectionResult<T>;\n }\n\n updateSingle(contextId: string, id: string): void {\n const selection = this.getSelection(contextId, 'single');\n invariant(selection?.mode === 'single', 'Selection mode is not single');\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, id },\n },\n }));\n }\n\n updateMulti(contextId: string, ids: string[]) {\n const selection = this.getSelection(contextId, 'multi');\n invariant(selection?.mode === 'multi', 'Selection mode is not multi');\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, ids: [...ids] },\n },\n }));\n }\n\n updateRange(contextId: string, from: string, to: string) {\n const selection = this.getSelection(contextId, 'range');\n invariant(selection?.mode === 'range', 'Selection mode is not range');\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, from, to },\n },\n }));\n }\n\n updateMultiRange(contextId: string, ranges: { from: string; to: string }[]) {\n const selection = this.getSelection(contextId, 'multi-range');\n invariant(selection?.mode === 'multi-range', 'Selection mode is not multi-range');\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, ranges: [...ranges] },\n },\n }));\n }\n\n clearSelection(contextId: string): void {\n const selection = this.getSelection(contextId);\n if (!selection) {\n return;\n }\n\n const clearedSelection = Match.type<Selection>().pipe(\n Match.when({ mode: 'single' }, (s) => ({ ...s, id: undefined })),\n Match.when({ mode: 'multi' }, (s) => ({ ...s, ids: [] })),\n Match.when({ mode: 'range' }, (s) => ({ ...s, from: undefined, to: undefined })),\n Match.when({ mode: 'multi-range' }, (s) => ({ ...s, ranges: [] })),\n Match.exhaustive,\n )(selection);\n\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: clearedSelection,\n },\n }));\n }\n\n toggleSelection(contextId: string, id: string): void {\n const selection = this.getSelection(contextId, 'multi');\n invariant(selection?.mode === 'multi', 'Selection mode is not multi');\n\n const newIds = selection.ids.includes(id)\n ? selection.ids.filter((existingId) => existingId !== id)\n : [...selection.ids, id];\n\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, ids: newIds },\n },\n }));\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect-atom/atom-react';\nimport { createContext } from '@radix-ui/react-context';\nimport * as Match from 'effect/Match';\nimport React, { type PropsWithChildren, useCallback, useContext, useEffect, useMemo, useState } from 'react';\n\nimport { useDefaultValue } from '@dxos/react-hooks';\n\nimport {\n type Selection,\n SelectionManager,\n type SelectionMode,\n type SelectionResult,\n defaultSelection,\n} from '../selection';\n\nconst SELECTION_NAME = 'Selection';\n\ntype SelectionContextValue = {\n selection: SelectionManager;\n};\n\nconst [SelectionContextProvider, useSelectionContext] = createContext<SelectionContextValue>(SELECTION_NAME, {\n selection: undefined as unknown as SelectionManager,\n});\n\n/**\n * Manages selection state across the app for multiple contexts.\n */\n// TODO(burdon): When is the selection removed?\nexport const SelectionProvider = ({\n children,\n selection: propsSelection,\n}: PropsWithChildren<{ selection?: SelectionManager }>) => {\n const registry = useContext(RegistryContext);\n const selection = useDefaultValue(propsSelection, () => new SelectionManager(registry));\n return <SelectionContextProvider selection={selection}>{children}</SelectionContextProvider>;\n};\n\n/**\n * Get the selection contexts.\n */\nexport const useSelectionManager = () => {\n const { selection } = useSelectionContext(SELECTION_NAME);\n return selection;\n};\n\nconst getDefaultResult = <T extends SelectionMode>(mode: T): SelectionResult<T> => {\n return Match.type<Selection>().pipe(\n Match.when({ mode: 'single' }, (selection) => selection.id),\n Match.when({ mode: 'multi' }, (selection) => selection.ids),\n Match.when({ mode: 'range' }, (selection) =>\n selection.from && selection.to ? { from: selection.from, to: selection.to } : undefined,\n ),\n Match.when({ mode: 'multi-range' }, (selection) => selection.ranges),\n Match.exhaustive,\n )(defaultSelection(mode)) as SelectionResult<T>;\n};\n\n/**\n * Get the selected objects for a given context.\n */\nexport const useSelected = <T extends SelectionMode>(\n contextId?: string,\n mode: T = 'multi' as T,\n): SelectionResult<T> => {\n const { selection } = useSelectionContext(SELECTION_NAME);\n const [state, setState] = useState<SelectionResult<T>>(() =>\n contextId && selection ? selection.getSelected(contextId, mode) : getDefaultResult(mode),\n );\n\n useEffect(() => {\n if (!contextId || !selection) {\n setState(getDefaultResult(mode));\n return;\n }\n\n // Set initial state.\n setState(selection.getSelected(contextId, mode));\n\n // Subscribe to changes.\n return selection.subscribe(() => {\n setState(selection.getSelected(contextId, mode));\n });\n }, [selection, contextId, mode]);\n\n return state;\n};\n\nexport type UseSelectionActions = {\n singleSelect: (id: string) => void;\n multiSelect: (ids: string[]) => void;\n rangeSelect: (from: string, to: string) => void;\n toggle: (id: string) => void;\n clear: () => void;\n};\n\n/**\n * Provides functions to manage the selection state for multiple contexts.\n */\n// TODO(burdon): Mode not used.\nexport const useSelectionActions = (contextIds: string[], mode: SelectionMode = 'multi'): UseSelectionActions => {\n const stableContextIds = useMemo(() => contextIds, [JSON.stringify(contextIds)]); // TODO(burdon): Avoid stringify.\n const { selection } = useSelectionContext(SELECTION_NAME);\n\n const singleSelect = useCallback(\n (id: string) => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.updateSingle(contextId, id);\n }\n },\n [selection, stableContextIds],\n );\n\n const multiSelect = useCallback(\n (ids: string[]) => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.updateMulti(contextId, ids);\n }\n },\n [selection, stableContextIds],\n );\n\n const rangeSelect = useCallback(\n (from: string, to: string) => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.updateRange(contextId, from, to);\n }\n },\n [selection, stableContextIds],\n );\n\n const toggle = useCallback(\n (id: string) => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.toggleSelection(contextId, id);\n }\n },\n [selection, stableContextIds],\n );\n\n const clear = useCallback(() => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.clearSelection(contextId);\n }\n }, [selection, stableContextIds]);\n\n return { singleSelect, multiSelect, rangeSelect, toggle, clear };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["Atom", "AttentionManager", "_map", "Map", "_currentAtom", "_registry", "initial", "Atom", "make", "pipe", "keepAlive", "length", "update", "current", "getCurrent", "get", "subscribeCurrent", "cb", "subscribe", "keys", "Array", "from", "id", "atom", "_getAtom", "existing", "newAtom", "hasAttention", "isAncestor", "isRelated", "set", "nextIds", "primaryId", "currentIds", "prevPrimaryId", "prevPrefixes", "expandAttendableId", "prefix", "_set", "prevSegmentId", "getSegmentId", "key", "prefixes", "prefixSet", "Set", "linkedParent", "isLinkedSegment", "getParentId", "undefined", "segmentId", "has", "attention", "getAttendables", "selector", "cursor", "acc", "closestAttendable", "closest", "attendableId", "getAttribute", "trigger", "document", "querySelector", "push", "parentElement", "LINKED_PREFIX", "qualifiedId", "segments", "split", "map", "_", "index", "slice", "join", "lastSegment", "pop", "startsWith", "linkedSegment", "variant", "getLinkedVariant", "lastSlash", "lastIndexOf", "RegistryContext", "createContext", "Primitive", "Slot", "React", "forwardRef", "useContext", "useEffect", "useMemo", "useState", "log", "useDefaultValue", "mx", "ATTENTION_NAME", "ATTENDABLE_ATTRIBUTE", "ATTENTION_SOURCE_ATTRIBUTE", "AttentionContextProvider", "useAttentionContext", "createContext", "attention", "undefined", "UNKNOWN_ATTENDABLE", "hasAttention", "isAncestor", "isRelated", "useAttention", "attendableId", "state", "setState", "useState", "useEffect", "currentState", "get", "subscribe", "newState", "useAttended", "current", "setCurrent", "getCurrent", "subscribeCurrent", "newCurrent", "useAttentionAttributes", "useMemo", "attributes", "RootAttentionProvider", "children", "propsAttention", "onChange", "registry", "useContext", "RegistryContext", "useDefaultValue", "AttentionManager", "handleFocus", "event", "log", "related", "relatedTarget", "target", "selector", "Array", "from", "document", "querySelectorAll", "map", "el", "getAttribute", "join", "prev", "next", "getAttendables", "length", "find", "id", "index", "update", "div", "role", "className", "onFocusCapture", "AttendableContainer", "forwardRef", "classNames", "asChild", "props", "forwardedRef", "attentionAttrs", "Comp", "Slot", "Primitive", "mx", "tabIndex", "ref", "Atom", "Match", "Schema", "invariant", "SelectionSchema", "Union", "Struct", "mode", "Literal", "id", "optional", "String", "pipe", "mutable", "ids", "Array", "from", "to", "ranges", "defaultSelection", "type", "withReturnType", "when", "exhaustive", "getSelectionSet", "selectionManager", "contextId", "Set", "context", "getSelectionContexts", "selection", "getSelection", "add", "SelectionManager", "_state", "_registry", "initial", "make", "selections", "state", "getState", "get", "subscribe", "cb", "Object", "keys", "undefined", "newSelection", "update", "getSelected", "s", "updateSingle", "updateMulti", "updateRange", "updateMultiRange", "clearSelection", "clearedSelection", "toggleSelection", "newIds", "includes", "filter", "existingId", "RegistryContext", "createContext", "Match", "React", "useCallback", "useContext", "useEffect", "useMemo", "useState", "useDefaultValue", "SELECTION_NAME", "SelectionContextProvider", "useSelectionContext", "createContext", "selection", "undefined", "SelectionProvider", "children", "propsSelection", "registry", "useContext", "RegistryContext", "useDefaultValue", "SelectionManager", "React", "useSelectionManager", "getDefaultResult", "mode", "type", "pipe", "when", "id", "ids", "from", "to", "ranges", "exhaustive", "defaultSelection", "useSelected", "contextId", "state", "setState", "useState", "getSelected", "useEffect", "subscribe", "useSelectionActions", "contextIds", "stableContextIds", "useMemo", "JSON", "stringify", "singleSelect", "useCallback", "updateSingle", "multiSelect", "updateMulti", "rangeSelect", "updateRange", "toggle", "toggleSelection", "clear", "clearSelection"]
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-GMKHOVJ5.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1,3 +1,4 @@
1
+ import "./chunk-GMKHOVJ5.mjs";
1
2
  import {
2
3
  ATTENDABLE_ATTRIBUTE,
3
4
  ATTENTION_NAME,
@@ -11,10 +12,12 @@ import {
11
12
  defaultSelection,
12
13
  expandAttendableId,
13
14
  getAttendables,
15
+ getLinkedVariant,
14
16
  getParentId,
15
17
  getSegmentId,
16
18
  getSelectionSet,
17
- isSeparatorPrefixed,
19
+ isLinkedSegment,
20
+ linkedSegment,
18
21
  useAttended,
19
22
  useAttention,
20
23
  useAttentionAttributes,
@@ -22,10 +25,7 @@ import {
22
25
  useSelected,
23
26
  useSelectionActions,
24
27
  useSelectionManager
25
- } from "./chunk-Q5SLNQ4B.mjs";
26
- import {
27
- ATTENDABLE_PATH_SEPARATOR
28
- } from "./chunk-PAZBZOO2.mjs";
28
+ } from "./chunk-4SEURHOL.mjs";
29
29
 
30
30
  // src/components/AttentionGlyph.tsx
31
31
  import React, { forwardRef, useMemo } from "react";
@@ -97,7 +97,6 @@ var AttentionGlyph = /* @__PURE__ */ forwardRef(({ presence, attended, syncing,
97
97
  });
98
98
  export {
99
99
  ATTENDABLE_ATTRIBUTE,
100
- ATTENDABLE_PATH_SEPARATOR,
101
100
  ATTENTION_NAME,
102
101
  ATTENTION_SOURCE_ATTRIBUTE,
103
102
  AttendableContainer,
@@ -111,10 +110,12 @@ export {
111
110
  defaultSelection,
112
111
  expandAttendableId,
113
112
  getAttendables,
113
+ getLinkedVariant,
114
114
  getParentId,
115
115
  getSegmentId,
116
116
  getSelectionSet,
117
- isSeparatorPrefixed,
117
+ isLinkedSegment,
118
+ linkedSegment,
118
119
  useAttended,
119
120
  useAttention,
120
121
  useAttentionAttributes,
@@ -1 +1 @@
1
- {"inputs":{"src/types.ts":{"bytes":1000,"imports":[],"format":"esm"},"src/attention.ts":{"bytes":23381,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"src/types.ts","kind":"import-statement","original":"./types"}],"format":"esm"},"src/components/AttentionGlyph.tsx":{"bytes":10090,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true}],"format":"esm"},"src/components/AttentionProvider.tsx":{"bytes":18018,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-primitive","kind":"import-statement","external":true},{"path":"@radix-ui/react-slot","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/react-hooks","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"src/attention.ts","kind":"import-statement","original":"../attention"}],"format":"esm"},"src/selection.ts":{"bytes":28228,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"effect/Match","kind":"import-statement","external":true},{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"src/components/SelectionProvider.tsx":{"bytes":15632,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"effect/Match","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-hooks","kind":"import-statement","external":true},{"path":"src/selection.ts","kind":"import-statement","original":"../selection"}],"format":"esm"},"src/components/index.ts":{"bytes":708,"imports":[{"path":"src/components/AttentionGlyph.tsx","kind":"import-statement","original":"./AttentionGlyph"},{"path":"src/components/AttentionProvider.tsx","kind":"import-statement","original":"./AttentionProvider"},{"path":"src/components/SelectionProvider.tsx","kind":"import-statement","original":"./SelectionProvider"}],"format":"esm"},"src/index.ts":{"bytes":726,"imports":[{"path":"src/attention.ts","kind":"import-statement","original":"./attention"},{"path":"src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"src/selection.ts","kind":"import-statement","original":"./selection"},{"path":"src/types.ts","kind":"import-statement","original":"./types"}],"format":"esm"},"src/testing/decorators/withAttention.ts":{"bytes":3609,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/attention.ts","kind":"import-statement","original":"../../attention"},{"path":"src/components/index.ts","kind":"import-statement","original":"../../components"}],"format":"esm"},"src/testing/decorators/index.ts":{"bytes":493,"imports":[{"path":"src/testing/decorators/withAttention.ts","kind":"import-statement","original":"./withAttention"}],"format":"esm"},"src/testing/index.ts":{"bytes":471,"imports":[{"path":"src/testing/decorators/index.ts","kind":"import-statement","original":"./decorators"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":5234},"dist/lib/browser/index.mjs":{"imports":[{"path":"dist/lib/browser/chunk-Q5SLNQ4B.mjs","kind":"import-statement"},{"path":"dist/lib/browser/chunk-PAZBZOO2.mjs","kind":"import-statement"},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true}],"exports":["ATTENDABLE_ATTRIBUTE","ATTENDABLE_PATH_SEPARATOR","ATTENTION_NAME","ATTENTION_SOURCE_ATTRIBUTE","AttendableContainer","AttentionGlyph","AttentionManager","RootAttentionProvider","SelectionManager","SelectionProvider","SelectionSchema","Syncing","defaultSelection","expandAttendableId","getAttendables","getParentId","getSegmentId","getSelectionSet","isSeparatorPrefixed","useAttended","useAttention","useAttentionAttributes","useAttentionContext","useSelected","useSelectionActions","useSelectionManager"],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0},"src/components/AttentionGlyph.tsx":{"bytesInOutput":2992}},"bytes":4189},"dist/lib/browser/types.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"dist/lib/browser/types.mjs":{"imports":[{"path":"dist/lib/browser/chunk-PAZBZOO2.mjs","kind":"import-statement"}],"exports":["ATTENDABLE_PATH_SEPARATOR"],"entryPoint":"src/types.ts","inputs":{},"bytes":143},"dist/lib/browser/testing/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":1872},"dist/lib/browser/testing/index.mjs":{"imports":[{"path":"dist/lib/browser/chunk-Q5SLNQ4B.mjs","kind":"import-statement"},{"path":"dist/lib/browser/chunk-PAZBZOO2.mjs","kind":"import-statement"},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["withAttention"],"entryPoint":"src/testing/index.ts","inputs":{"src/testing/decorators/withAttention.ts":{"bytesInOutput":610},"src/testing/index.ts":{"bytesInOutput":0}},"bytes":855},"dist/lib/browser/chunk-Q5SLNQ4B.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":42438},"dist/lib/browser/chunk-Q5SLNQ4B.mjs":{"imports":[{"path":"dist/lib/browser/chunk-PAZBZOO2.mjs","kind":"import-statement"},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-primitive","kind":"import-statement","external":true},{"path":"@radix-ui/react-slot","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/react-hooks","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"effect/Match","kind":"import-statement","external":true},{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"effect/Match","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-hooks","kind":"import-statement","external":true}],"exports":["ATTENDABLE_ATTRIBUTE","ATTENTION_NAME","ATTENTION_SOURCE_ATTRIBUTE","AttendableContainer","AttentionManager","RootAttentionProvider","SelectionManager","SelectionProvider","SelectionSchema","defaultSelection","expandAttendableId","getAttendables","getParentId","getSegmentId","getSelectionSet","isSeparatorPrefixed","useAttended","useAttention","useAttentionAttributes","useAttentionContext","useSelected","useSelectionActions","useSelectionManager"],"inputs":{"src/attention.ts":{"bytesInOutput":5182},"src/components/AttentionProvider.tsx":{"bytesInOutput":3752},"src/selection.ts":{"bytesInOutput":7192},"src/components/SelectionProvider.tsx":{"bytesInOutput":3533}},"bytes":20381},"dist/lib/browser/chunk-PAZBZOO2.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":503},"dist/lib/browser/chunk-PAZBZOO2.mjs":{"imports":[],"exports":["ATTENDABLE_PATH_SEPARATOR"],"inputs":{"src/types.ts":{"bytesInOutput":37}},"bytes":138}}}
1
+ {"inputs":{"src/attention.ts":{"bytes":25938,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true}],"format":"esm"},"src/components/AttentionGlyph.tsx":{"bytes":10090,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true}],"format":"esm"},"src/components/AttentionProvider.tsx":{"bytes":18018,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-primitive","kind":"import-statement","external":true},{"path":"@radix-ui/react-slot","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/react-hooks","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"src/attention.ts","kind":"import-statement","original":"../attention"}],"format":"esm"},"src/selection.ts":{"bytes":28228,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"effect/Match","kind":"import-statement","external":true},{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"src/components/SelectionProvider.tsx":{"bytes":15632,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"effect/Match","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-hooks","kind":"import-statement","external":true},{"path":"src/selection.ts","kind":"import-statement","original":"../selection"}],"format":"esm"},"src/components/index.ts":{"bytes":708,"imports":[{"path":"src/components/AttentionGlyph.tsx","kind":"import-statement","original":"./AttentionGlyph"},{"path":"src/components/AttentionProvider.tsx","kind":"import-statement","original":"./AttentionProvider"},{"path":"src/components/SelectionProvider.tsx","kind":"import-statement","original":"./SelectionProvider"}],"format":"esm"},"src/types.ts":{"bytes":613,"imports":[],"format":"esm"},"src/index.ts":{"bytes":726,"imports":[{"path":"src/attention.ts","kind":"import-statement","original":"./attention"},{"path":"src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"src/selection.ts","kind":"import-statement","original":"./selection"},{"path":"src/types.ts","kind":"import-statement","original":"./types"}],"format":"esm"},"src/testing/decorators/withAttention.ts":{"bytes":3609,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/attention.ts","kind":"import-statement","original":"../../attention"},{"path":"src/components/index.ts","kind":"import-statement","original":"../../components"}],"format":"esm"},"src/testing/decorators/index.ts":{"bytes":493,"imports":[{"path":"src/testing/decorators/withAttention.ts","kind":"import-statement","original":"./withAttention"}],"format":"esm"},"src/testing/index.ts":{"bytes":471,"imports":[{"path":"src/testing/decorators/index.ts","kind":"import-statement","original":"./decorators"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":5234},"dist/lib/browser/index.mjs":{"imports":[{"path":"dist/lib/browser/chunk-GMKHOVJ5.mjs","kind":"import-statement"},{"path":"dist/lib/browser/chunk-4SEURHOL.mjs","kind":"import-statement"},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true}],"exports":["ATTENDABLE_ATTRIBUTE","ATTENTION_NAME","ATTENTION_SOURCE_ATTRIBUTE","AttendableContainer","AttentionGlyph","AttentionManager","RootAttentionProvider","SelectionManager","SelectionProvider","SelectionSchema","Syncing","defaultSelection","expandAttendableId","getAttendables","getLinkedVariant","getParentId","getSegmentId","getSelectionSet","isLinkedSegment","linkedSegment","useAttended","useAttention","useAttentionAttributes","useAttentionContext","useSelected","useSelectionActions","useSelectionManager"],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0},"src/components/AttentionGlyph.tsx":{"bytesInOutput":2992}},"bytes":4189},"dist/lib/browser/types.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"dist/lib/browser/types.mjs":{"imports":[{"path":"dist/lib/browser/chunk-GMKHOVJ5.mjs","kind":"import-statement"}],"exports":[],"entryPoint":"src/types.ts","inputs":{},"bytes":66},"dist/lib/browser/chunk-GMKHOVJ5.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"dist/lib/browser/chunk-GMKHOVJ5.mjs":{"imports":[],"exports":[],"inputs":{"src/types.ts":{"bytesInOutput":0}},"bytes":44},"dist/lib/browser/testing/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":1871},"dist/lib/browser/testing/index.mjs":{"imports":[{"path":"dist/lib/browser/chunk-4SEURHOL.mjs","kind":"import-statement"},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["withAttention"],"entryPoint":"src/testing/index.ts","inputs":{"src/testing/decorators/withAttention.ts":{"bytesInOutput":610},"src/testing/index.ts":{"bytesInOutput":0}},"bytes":823},"dist/lib/browser/chunk-4SEURHOL.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":43665},"dist/lib/browser/chunk-4SEURHOL.mjs":{"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-primitive","kind":"import-statement","external":true},{"path":"@radix-ui/react-slot","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/react-hooks","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"effect/Match","kind":"import-statement","external":true},{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"effect/Match","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-hooks","kind":"import-statement","external":true}],"exports":["ATTENDABLE_ATTRIBUTE","ATTENTION_NAME","ATTENTION_SOURCE_ATTRIBUTE","AttendableContainer","AttentionManager","RootAttentionProvider","SelectionManager","SelectionProvider","SelectionSchema","defaultSelection","expandAttendableId","getAttendables","getLinkedVariant","getParentId","getSegmentId","getSelectionSet","isLinkedSegment","linkedSegment","useAttended","useAttention","useAttentionAttributes","useAttentionContext","useSelected","useSelectionActions","useSelectionManager"],"inputs":{"src/attention.ts":{"bytesInOutput":5433},"src/components/AttentionProvider.tsx":{"bytesInOutput":3752},"src/selection.ts":{"bytesInOutput":7192},"src/components/SelectionProvider.tsx":{"bytesInOutput":3533}},"bytes":20596}}}
@@ -2,8 +2,7 @@ import {
2
2
  AttentionManager,
3
3
  RootAttentionProvider,
4
4
  SelectionProvider
5
- } from "../chunk-Q5SLNQ4B.mjs";
6
- import "../chunk-PAZBZOO2.mjs";
5
+ } from "../chunk-4SEURHOL.mjs";
7
6
 
8
7
  // src/testing/decorators/withAttention.ts
9
8
  import { Registry, RegistryContext } from "@effect-atom/atom-react";
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/testing/decorators/withAttention.ts"],
4
4
  "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { Registry, RegistryContext } from '@effect-atom/atom-react';\nimport { type Decorator } from '@storybook/react';\nimport { createElement, useMemo } from 'react';\n\nimport { AttentionManager } from '../../attention';\nimport { RootAttentionProvider, SelectionProvider } from '../../components';\n\n/**\n * Storybook decorator that provides attention context.\n * @param initialAttendedId Optional ID to set as initially attended.\n */\nexport const withAttention = (initialAttendedId?: string): Decorator => {\n return (Story) => {\n const registry = useMemo(() => Registry.make(), []);\n const attention = useMemo(\n () => (initialAttendedId ? new AttentionManager(registry, [initialAttendedId]) : undefined),\n [registry],\n );\n return createElement(\n RegistryContext.Provider,\n { value: registry },\n createElement(RootAttentionProvider, { attention }, createElement(SelectionProvider, {}, createElement(Story))),\n );\n };\n};\n"],
5
- "mappings": ";;;;;;;;AAIA,SAASA,UAAUC,uBAAuB;AAE1C,SAASC,eAAeC,eAAe;AAShC,IAAMC,gBAAgB,CAACC,sBAAAA;AAC5B,SAAO,CAACC,UAAAA;AACN,UAAMC,WAAWC,QAAQ,MAAMC,SAASC,KAAI,GAAI,CAAA,CAAE;AAClD,UAAMC,YAAYH,QAChB,MAAOH,oBAAoB,IAAIO,iBAAiBL,UAAU;MAACF;KAAkB,IAAIQ,QACjF;MAACN;KAAS;AAEZ,WAAOO,cACLC,gBAAgBC,UAChB;MAAEC,OAAOV;IAAS,GAClBO,cAAcI,uBAAuB;MAAEP;IAAU,GAAGG,cAAcK,mBAAmB,CAAC,GAAGL,cAAcR,KAAAA,CAAAA,CAAAA,CAAAA;EAE3G;AACF;",
5
+ "mappings": ";;;;;;;AAIA,SAASA,UAAUC,uBAAuB;AAE1C,SAASC,eAAeC,eAAe;AAShC,IAAMC,gBAAgB,CAACC,sBAAAA;AAC5B,SAAO,CAACC,UAAAA;AACN,UAAMC,WAAWC,QAAQ,MAAMC,SAASC,KAAI,GAAI,CAAA,CAAE;AAClD,UAAMC,YAAYH,QAChB,MAAOH,oBAAoB,IAAIO,iBAAiBL,UAAU;MAACF;KAAkB,IAAIQ,QACjF;MAACN;KAAS;AAEZ,WAAOO,cACLC,gBAAgBC,UAChB;MAAEC,OAAOV;IAAS,GAClBO,cAAcI,uBAAuB;MAAEP;IAAU,GAAGG,cAAcK,mBAAmB,CAAC,GAAGL,cAAcR,KAAAA,CAAAA,CAAAA,CAAAA;EAE3G;AACF;",
6
6
  "names": ["Registry", "RegistryContext", "createElement", "useMemo", "withAttention", "initialAttendedId", "Story", "registry", "useMemo", "Registry", "make", "attention", "AttentionManager", "undefined", "createElement", "RegistryContext", "Provider", "value", "RootAttentionProvider", "SelectionProvider"]
7
7
  }
@@ -1,7 +1,2 @@
1
- import {
2
- ATTENDABLE_PATH_SEPARATOR
3
- } from "./chunk-PAZBZOO2.mjs";
4
- export {
5
- ATTENDABLE_PATH_SEPARATOR
6
- };
1
+ import "./chunk-GMKHOVJ5.mjs";
7
2
  //# sourceMappingURL=types.mjs.map
@@ -1,7 +1,4 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import {
3
- ATTENDABLE_PATH_SEPARATOR
4
- } from "./chunk-PMGNPL4M.mjs";
5
2
 
6
3
  // src/attention.ts
7
4
  import { Atom } from "@effect-atom/atom-react";
@@ -78,8 +75,8 @@ var AttentionManager = class {
78
75
  * Takes the array of qualified IDs collected from the DOM; the first element is the primary attended item.
79
76
  * Ancestry is derived from the progressive prefixes of the primary ID.
80
77
  * Relatedness is derived from the segment ID: any tracked key whose last `/` segment matches the
81
- * attended ID's segment ID is marked `isRelated`. Additionally, if the primary ID has a
82
- * separator-prefixed last segment (starts with `~`), its immediate parent gets `isRelated` alongside `isAncestor`.
78
+ * attended ID's segment ID is marked `isRelated`. Additionally, if the primary ID is a linked segment
79
+ * (starts with `~`), its immediate parent gets `isRelated` alongside `isAncestor`.
83
80
  *
84
81
  * @internal
85
82
  */
@@ -105,13 +102,13 @@ var AttentionManager = class {
105
102
  this._registry.set(this._currentAtom, nextIds);
106
103
  const prefixes = expandAttendableId(primaryId);
107
104
  const prefixSet = new Set(prefixes);
108
- const separatedParent = isSeparatorPrefixed(primaryId) ? getParentId(primaryId) : void 0;
105
+ const linkedParent = isLinkedSegment(primaryId) ? getParentId(primaryId) : void 0;
109
106
  for (const prefix of prefixes) {
110
107
  if (prefix === primaryId) {
111
108
  this._set(prefix, {
112
109
  hasAttention: true
113
110
  });
114
- } else if (prefix === separatedParent) {
111
+ } else if (prefix === linkedParent) {
115
112
  this._set(prefix, {
116
113
  isAncestor: true,
117
114
  isRelated: true
@@ -160,13 +157,19 @@ var getAttendables = (selector, cursor, acc = []) => {
160
157
  ...new Set(acc)
161
158
  ];
162
159
  };
160
+ var LINKED_PREFIX = "~";
163
161
  var expandAttendableId = (qualifiedId) => {
164
162
  const segments = qualifiedId.split("/");
165
163
  return segments.map((_, index) => segments.slice(0, index + 1).join("/"));
166
164
  };
167
- var isSeparatorPrefixed = (qualifiedId) => {
165
+ var isLinkedSegment = (qualifiedId) => {
168
166
  const lastSegment = qualifiedId.split("/").pop() ?? "";
169
- return lastSegment.startsWith(ATTENDABLE_PATH_SEPARATOR);
167
+ return lastSegment.startsWith(LINKED_PREFIX);
168
+ };
169
+ var linkedSegment = (variant) => `${LINKED_PREFIX}${variant}`;
170
+ var getLinkedVariant = (qualifiedId) => {
171
+ const lastSegment = qualifiedId.split("/").pop() ?? "";
172
+ return lastSegment.startsWith(LINKED_PREFIX) ? lastSegment.slice(LINKED_PREFIX.length) : lastSegment;
170
173
  };
171
174
  var getParentId = (qualifiedId) => {
172
175
  if (!qualifiedId) {
@@ -694,7 +697,9 @@ export {
694
697
  AttentionManager,
695
698
  getAttendables,
696
699
  expandAttendableId,
697
- isSeparatorPrefixed,
700
+ isLinkedSegment,
701
+ linkedSegment,
702
+ getLinkedVariant,
698
703
  getParentId,
699
704
  getSegmentId,
700
705
  ATTENTION_NAME,
@@ -715,4 +720,4 @@ export {
715
720
  useSelected,
716
721
  useSelectionActions
717
722
  };
718
- //# sourceMappingURL=chunk-LSWTWT3W.mjs.map
723
+ //# sourceMappingURL=chunk-6PQ4P7AL.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/attention.ts", "../../../src/components/AttentionProvider.tsx", "../../../src/selection.ts", "../../../src/components/SelectionProvider.tsx"],
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { Atom, type Registry } from '@effect-atom/atom-react';\n\nimport { type Attention } from './types';\n\n/**\n * Manages attention state for an application.\n * Attention keys are slash-qualified graph IDs; ancestry is derived from progressive prefixes.\n */\nexport class AttentionManager {\n private readonly _map = new Map<string, Atom.Writable<Attention>>();\n private readonly _currentAtom: Atom.Writable<string[]>;\n\n constructor(\n private readonly _registry: Registry.Registry,\n initial: string[] = [],\n ) {\n this._currentAtom = Atom.make<string[]>([]).pipe(Atom.keepAlive);\n if (initial.length > 0) {\n this.update(initial);\n }\n }\n\n /**\n * Atom for the currently attended element IDs.\n */\n get current(): Atom.Atom<string[]> {\n return this._currentAtom;\n }\n\n /**\n * Gets the currently attended element IDs.\n */\n getCurrent(): readonly string[] {\n return this._registry.get(this._currentAtom);\n }\n\n /**\n * Subscribe to changes in the current attention IDs.\n */\n subscribeCurrent(cb: (current: readonly string[]) => void): () => void {\n this._registry.get(this._currentAtom);\n return this._registry.subscribe(this._currentAtom, () => {\n cb(this._registry.get(this._currentAtom));\n });\n }\n\n /**\n * All tracked qualified IDs.\n */\n keys(): string[] {\n return Array.from(this._map.keys());\n }\n\n /**\n * Get the attention state for a given qualified ID.\n */\n get(id: string): Attention {\n const atom = this._getAtom(id);\n return this._registry.get(atom);\n }\n\n /**\n * Subscribe to changes in the attention state for a given qualified ID.\n */\n subscribe(id: string, cb: (attention: Attention) => void): () => void {\n const atom = this._getAtom(id);\n this._registry.get(atom);\n return this._registry.subscribe(atom, () => {\n cb(this._registry.get(atom));\n });\n }\n\n private _getAtom(id: string): Atom.Writable<Attention> {\n const existing = this._map.get(id);\n if (existing) {\n return existing;\n }\n\n const newAtom = Atom.make<Attention>({ hasAttention: false, isAncestor: false, isRelated: false }).pipe(\n Atom.keepAlive,\n );\n this._map.set(id, newAtom);\n return newAtom;\n }\n\n /**\n * Update the currently attended element.\n * Takes the array of qualified IDs collected from the DOM; the first element is the primary attended item.\n * Ancestry is derived from the progressive prefixes of the primary ID.\n * Relatedness is derived from the segment ID: any tracked key whose last `/` segment matches the\n * attended ID's segment ID is marked `isRelated`. Additionally, if the primary ID is a linked segment\n * (starts with `~`), its immediate parent gets `isRelated` alongside `isAncestor`.\n *\n * @internal\n */\n update(nextIds: string[]): void {\n const primaryId = nextIds[0];\n if (!primaryId) {\n return;\n }\n\n const currentIds = this.getCurrent();\n const prevPrimaryId = currentIds[0];\n // Clear previous attention state: ancestors, primary, and related keys.\n if (prevPrimaryId) {\n const prevPrefixes = expandAttendableId(prevPrimaryId);\n for (const prefix of prevPrefixes) {\n this._set(prefix, {});\n }\n const prevSegmentId = getSegmentId(prevPrimaryId);\n for (const key of this.keys()) {\n if (getSegmentId(key) === prevSegmentId) {\n this._set(key, {});\n }\n }\n }\n\n this._registry.set(this._currentAtom, nextIds);\n\n // Set ancestors and primary.\n const prefixes = expandAttendableId(primaryId);\n const prefixSet = new Set(prefixes);\n const linkedParent = isLinkedSegment(primaryId) ? getParentId(primaryId) : undefined;\n\n for (const prefix of prefixes) {\n if (prefix === primaryId) {\n this._set(prefix, { hasAttention: true });\n } else if (prefix === linkedParent) {\n this._set(prefix, { isAncestor: true, isRelated: true });\n } else {\n this._set(prefix, { isAncestor: true });\n }\n }\n\n // Set related keys: any tracked key sharing the same segment ID.\n const segmentId = getSegmentId(primaryId);\n for (const key of this.keys()) {\n if (!prefixSet.has(key) && getSegmentId(key) === segmentId) {\n this._set(key, { isRelated: true });\n }\n }\n }\n\n private _set(id: string, attention: Partial<Attention>): void {\n const atom = this._getAtom(id);\n this._registry.set(atom, {\n hasAttention: attention.hasAttention ?? false,\n isAncestor: attention.isAncestor ?? false,\n isRelated: attention.isRelated ?? false,\n });\n }\n}\n\n/**\n * Accumulates all attendable IDs between the element provided and the root, inclusive.\n * Each `data-attendable-id` value is treated as a single qualified ID (no splitting).\n */\nexport const getAttendables = (selector: string, cursor: Element, acc: string[] = []): string[] => {\n // Find the closest element with `data-attendable-id`, if any; start from cursor and move up the DOM tree.\n const closestAttendable = cursor.closest(selector);\n if (closestAttendable) {\n const attendableId = closestAttendable.getAttribute('data-attendable-id');\n if (!attendableId) {\n // This has an id of an aria-controls elsewhere on the page, move cursor to that trigger.\n const trigger = document.querySelector(`[aria-controls=\"${closestAttendable.getAttribute('id')}\"]`);\n if (!trigger) {\n return acc;\n } else {\n return getAttendables(selector, trigger, acc);\n }\n } else {\n acc.push(attendableId);\n return !closestAttendable.parentElement ? acc : getAttendables(selector, closestAttendable.parentElement, acc);\n }\n }\n\n return [...new Set(acc)];\n};\n\nexport type AttendableId = { attendableId?: string };\n\nexport type Related = { related?: boolean };\n\n/**\n * Prefix for linked segments. A linked segment's attention state is shared with its parent:\n * when a linked node has attention, the parent is marked as both ancestor and related.\n */\nconst LINKED_PREFIX = '~';\n\n/**\n * Decompose a qualified graph ID into progressive prefixes for ancestry tracking.\n * e.g. `root/a/b/c` yields `['root', 'root/a', 'root/a/b', 'root/a/b/c']`.\n */\nexport const expandAttendableId = (qualifiedId: string): string[] => {\n const segments = qualifiedId.split('/');\n return segments.map((_, index) => segments.slice(0, index + 1).join('/'));\n};\n\n/**\n * Whether the last segment of a qualified ID is a linked segment (starts with `~`).\n * Linked segments share their attention state with the parent node.\n */\nexport const isLinkedSegment = (qualifiedId: string): boolean => {\n const lastSegment = qualifiedId.split('/').pop() ?? '';\n return lastSegment.startsWith(LINKED_PREFIX);\n};\n\n/**\n * Build a linked segment ID from a variant name (e.g., `'settings'` -> `'~settings'`).\n * Nodes identified by linked segments share their attention state with the parent node.\n */\nexport const linkedSegment = (variant: string): string => `${LINKED_PREFIX}${variant}`;\n\n/**\n * Extract the variant name from the last segment of a qualified ID, stripping the linked prefix.\n * e.g. `'root/space/obj/~settings'` -> `'settings'`.\n * If the segment is not linked (no `~` prefix), returns the segment as-is.\n */\nexport const getLinkedVariant = (qualifiedId: string): string => {\n const lastSegment = qualifiedId.split('/').pop() ?? '';\n return lastSegment.startsWith(LINKED_PREFIX) ? lastSegment.slice(LINKED_PREFIX.length) : lastSegment;\n};\n\n/**\n * Get the parent qualified ID (everything before the last `/` segment).\n */\nexport const getParentId = (qualifiedId: string | undefined): string | undefined => {\n if (!qualifiedId) {\n return undefined;\n }\n\n const lastSlash = qualifiedId.lastIndexOf('/');\n return lastSlash > 0 ? qualifiedId.slice(0, lastSlash) : undefined;\n};\n\n/**\n * Extract the segment ID (last segment) of a qualified ID.\n */\nexport const getSegmentId = (qualifiedId: string): string => {\n return qualifiedId.split('/').pop() ?? qualifiedId;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { RegistryContext } from '@effect-atom/atom-react';\nimport { createContext } from '@radix-ui/react-context';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { Slot } from '@radix-ui/react-slot';\nimport React, {\n type ComponentPropsWithRef,\n type FocusEvent,\n type PropsWithChildren,\n forwardRef,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\nimport { log } from '@dxos/log';\nimport { useDefaultValue } from '@dxos/react-hooks';\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/ui-theme';\n\nimport { AttentionManager, getAttendables } from '../attention';\nimport { type Attention } from '../types';\n\nconst ATTENTION_NAME = 'Attention';\nconst ATTENDABLE_ATTRIBUTE = 'data-attendable-id';\nconst ATTENTION_SOURCE_ATTRIBUTE = 'data-w-attention-source';\n\ntype AttentionContextValue = {\n attention: AttentionManager;\n};\n\nconst [AttentionContextProvider, useAttentionContext] = createContext<AttentionContextValue>(ATTENTION_NAME, {\n attention: undefined as unknown as AttentionManager,\n});\n\nconst UNKNOWN_ATTENDABLE = { hasAttention: false, isAncestor: false, isRelated: false } as Attention;\n\n/**\n * Subscribe to the attention state for a qualified graph ID.\n */\nconst useAttention = (attendableId?: string): Attention => {\n const { attention } = useAttentionContext(ATTENTION_NAME);\n const [state, setState] = useState<Attention>(UNKNOWN_ATTENDABLE);\n\n useEffect(() => {\n if (!attendableId || !attention) {\n setState(UNKNOWN_ATTENDABLE);\n return;\n }\n\n const currentState = attention.get(attendableId);\n setState(currentState);\n\n return attention.subscribe(attendableId, (newState) => {\n setState(newState);\n });\n }, [attention, attendableId]);\n\n return state;\n};\n\nconst useAttended = () => {\n const { attention } = useAttentionContext(ATTENTION_NAME);\n const [current, setCurrent] = useState<readonly string[]>([]);\n\n useEffect(() => {\n if (!attention) {\n return;\n }\n\n setCurrent(attention.getCurrent());\n\n return attention.subscribeCurrent((newCurrent) => {\n setCurrent(newCurrent);\n });\n }, [attention]);\n\n return current;\n};\n\n/**\n * Computes HTML element attributes to apply so the attention system can detect changes.\n */\nconst useAttentionAttributes = (attendableId?: string) => {\n const { hasAttention } = useAttention(attendableId);\n return useMemo(() => {\n const attributes: Record<string, string | undefined> = { [ATTENDABLE_ATTRIBUTE]: attendableId };\n if (hasAttention) {\n attributes[ATTENTION_SOURCE_ATTRIBUTE] = 'true';\n }\n\n return attributes;\n }, [attendableId, hasAttention]);\n};\n\nconst RootAttentionProvider = ({\n children,\n attention: propsAttention,\n onChange,\n}: PropsWithChildren<\n Partial<{\n attention: AttentionManager;\n onChange: (nextAttended: string[]) => void;\n }>\n>) => {\n const registry = useContext(RegistryContext);\n const attention = useDefaultValue(propsAttention, () => new AttentionManager(registry));\n\n const handleFocus = (event: FocusEvent) => {\n // NOTE(thure): Use the following to debug focus movement across the app:\n log('focus', { related: event.relatedTarget, target: event.target });\n\n const selector = [\n '[data-attendable-id]',\n ...Array.from(document.querySelectorAll('[aria-controls]')).map(\n (el) => `[id=\"${el.getAttribute('aria-controls')}\"]`,\n ),\n ].join(',');\n const prev = attention.getCurrent();\n const next = getAttendables(selector, event.target);\n // TODO(wittjosiah): Not allowing empty state means that the attended item is not strictly guaranteed to be in the DOM.\n // Currently this depends on the deck in order to ensure that when the attended item is removed something else is attended.\n // Only update state if the result is different and not empty.\n if (next.length > 0 && (prev.length !== next.length || !!prev.find((id, index) => next[index] !== id))) {\n attention.update(next);\n onChange?.(next);\n }\n };\n\n return (\n <AttentionContextProvider attention={attention}>\n <div role='none' className='contents' onFocusCapture={handleFocus}>\n {children}\n </div>\n </AttentionContextProvider>\n );\n};\n\nexport type AttendableContainerProps = ThemedClassName<\n ComponentPropsWithRef<'div'> & { id: string; asChild?: boolean }\n>;\n\n/**\n * Note that DeckPlugin and StackPlugin both handle attention on their own,\n * and when rendering content in those cases it is not necessary to also render an `AttendableContainer`.\n * This component is primarily for Storybook stories and other testing scenarios,\n * or the rare cases where an attendable entity is rendered outside of either of those plugins.\n */\nconst AttendableContainer = forwardRef<HTMLDivElement, AttendableContainerProps>(\n ({ id, classNames, children, asChild, ...props }, forwardedRef) => {\n const attentionAttrs = useAttentionAttributes(id);\n const Comp = asChild ? Slot : Primitive.div;\n return (\n <Comp\n role='none'\n {...props}\n {...attentionAttrs}\n className={mx('dx-attention-surface', props.tabIndex === 0 && 'dx-focus-ring-inset-over-all', classNames)}\n ref={forwardedRef}\n >\n {children}\n </Comp>\n );\n },\n);\n\nexport {\n RootAttentionProvider,\n AttendableContainer,\n useAttentionContext,\n useAttention,\n useAttended,\n useAttentionAttributes,\n ATTENTION_NAME,\n ATTENDABLE_ATTRIBUTE,\n ATTENTION_SOURCE_ATTRIBUTE,\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { Atom, type Registry } from '@effect-atom/atom-react';\nimport * as Match from 'effect/Match';\nimport * as Schema from 'effect/Schema';\n\nimport { invariant } from '@dxos/invariant';\n\n// TODO(burdon): Reconcile with @dxos/graph.\n\nexport type SelectionMode = 'single' | 'multi' | 'range' | 'multi-range';\n\nexport const SelectionSchema = Schema.Union(\n Schema.Struct({ mode: Schema.Literal('single'), id: Schema.optional(Schema.String) }).pipe(Schema.mutable),\n Schema.Struct({ mode: Schema.Literal('multi'), ids: Schema.Array(Schema.String).pipe(Schema.mutable) }).pipe(\n Schema.mutable,\n ),\n Schema.Struct({\n mode: Schema.Literal('range'),\n from: Schema.optional(Schema.String),\n to: Schema.optional(Schema.String),\n }).pipe(Schema.mutable),\n Schema.Struct({\n mode: Schema.Literal('multi-range'),\n ranges: Schema.Array(Schema.Struct({ from: Schema.String, to: Schema.String })).pipe(Schema.mutable),\n }).pipe(Schema.mutable),\n).pipe(Schema.mutable);\n\nexport type Selection = Schema.Schema.Type<typeof SelectionSchema>;\n\nexport const defaultSelection = Match.type<SelectionMode>().pipe(\n Match.withReturnType<Selection>(),\n Match.when('single', () => ({ mode: 'single' })),\n Match.when('multi', () => ({ mode: 'multi', ids: [] })),\n Match.when('range', () => ({ mode: 'range' })),\n Match.when('multi-range', () => ({ mode: 'multi-range', ranges: [] })),\n Match.exhaustive,\n);\n\nexport type SelectionResult<T extends SelectionMode> = T extends 'single'\n ? string | undefined\n : T extends 'multi'\n ? string[]\n : T extends 'range'\n ? { from: string; to: string } | undefined\n : T extends 'multi-range'\n ? { from: string; to: string }[]\n : never;\n\n// TODO(burdon): Refactor.\nexport const getSelectionSet = (selectionManager: SelectionManager, contextId?: string) => {\n const ids = new Set<string>(contextId ? [contextId] : []);\n for (const context of selectionManager.getSelectionContexts()) {\n const selection = selectionManager.getSelection(context);\n if (selection?.mode === 'multi') {\n for (const id of selection.ids) {\n ids.add(id);\n }\n }\n }\n\n return ids;\n};\n\n/**\n * Manages selection state for different contexts.\n * Each context maintains its own selection mode and state.\n */\nexport class SelectionManager {\n private readonly _state: Atom.Writable<{ selections: Record<string, Selection> }>;\n\n constructor(\n private readonly _registry: Registry.Registry,\n initial: Record<string, Selection> = {},\n ) {\n this._state = Atom.make<{ selections: Record<string, Selection> }>({\n selections: { ...initial },\n });\n }\n\n /**\n * Get the state atom for reactive access in the graph system.\n */\n get state(): Atom.Atom<{ selections: Record<string, Selection> }> {\n return this._state;\n }\n\n /**\n * Gets the current state.\n */\n getState(): { selections: Record<string, Selection> } {\n return this._registry.get(this._state);\n }\n\n /**\n * Subscribe to changes in the selection state.\n */\n subscribe(cb: (state: { selections: Record<string, Selection> }) => void): () => void {\n this._registry.get(this._state);\n return this._registry.subscribe(this._state, () => {\n cb(this._registry.get(this._state));\n });\n }\n\n getSelectionContexts(): string[] {\n return Object.keys(this._registry.get(this._state).selections);\n }\n\n getSelection(contextId: string): Selection | undefined;\n getSelection<T extends SelectionMode>(contextId: string, mode: T): Selection;\n getSelection<T extends SelectionMode | undefined>(\n contextId: string,\n mode: T = undefined as T,\n ): Selection | undefined {\n const state = this._registry.get(this._state);\n const selection = state.selections[contextId];\n if (!mode || selection) {\n return selection;\n }\n\n // Create new selection for the context.\n const newSelection = defaultSelection(mode);\n this._registry.update(this._state, (state) => ({\n selections: { ...state.selections, [contextId]: newSelection },\n }));\n return newSelection;\n }\n\n // TODO(burdon): Disambiguate with getSelection?\n getSelected<T extends SelectionMode>(contextId: string, mode: T = 'multi' as T): SelectionResult<T> {\n const selection = this.getSelection(contextId, mode);\n invariant(selection?.mode === mode, 'Selection mode mismatch');\n // Cast required because TypeScript can't infer the relationship between T and the matched result.\n return Match.type<Selection>().pipe(\n Match.when({ mode: 'single' }, (s) => s.id),\n Match.when({ mode: 'multi' }, (s) => s.ids),\n Match.when({ mode: 'range' }, (s) => (s.from && s.to ? { from: s.from, to: s.to } : undefined)),\n Match.when({ mode: 'multi-range' }, (s) => s.ranges),\n Match.exhaustive,\n )(selection) as SelectionResult<T>;\n }\n\n updateSingle(contextId: string, id: string): void {\n const selection = this.getSelection(contextId, 'single');\n invariant(selection?.mode === 'single', 'Selection mode is not single');\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, id },\n },\n }));\n }\n\n updateMulti(contextId: string, ids: string[]) {\n const selection = this.getSelection(contextId, 'multi');\n invariant(selection?.mode === 'multi', 'Selection mode is not multi');\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, ids: [...ids] },\n },\n }));\n }\n\n updateRange(contextId: string, from: string, to: string) {\n const selection = this.getSelection(contextId, 'range');\n invariant(selection?.mode === 'range', 'Selection mode is not range');\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, from, to },\n },\n }));\n }\n\n updateMultiRange(contextId: string, ranges: { from: string; to: string }[]) {\n const selection = this.getSelection(contextId, 'multi-range');\n invariant(selection?.mode === 'multi-range', 'Selection mode is not multi-range');\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, ranges: [...ranges] },\n },\n }));\n }\n\n clearSelection(contextId: string): void {\n const selection = this.getSelection(contextId);\n if (!selection) {\n return;\n }\n\n const clearedSelection = Match.type<Selection>().pipe(\n Match.when({ mode: 'single' }, (s) => ({ ...s, id: undefined })),\n Match.when({ mode: 'multi' }, (s) => ({ ...s, ids: [] })),\n Match.when({ mode: 'range' }, (s) => ({ ...s, from: undefined, to: undefined })),\n Match.when({ mode: 'multi-range' }, (s) => ({ ...s, ranges: [] })),\n Match.exhaustive,\n )(selection);\n\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: clearedSelection,\n },\n }));\n }\n\n toggleSelection(contextId: string, id: string): void {\n const selection = this.getSelection(contextId, 'multi');\n invariant(selection?.mode === 'multi', 'Selection mode is not multi');\n\n const newIds = selection.ids.includes(id)\n ? selection.ids.filter((existingId) => existingId !== id)\n : [...selection.ids, id];\n\n this._registry.update(this._state, (state) => ({\n selections: {\n ...state.selections,\n [contextId]: { ...selection, ids: newIds },\n },\n }));\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect-atom/atom-react';\nimport { createContext } from '@radix-ui/react-context';\nimport * as Match from 'effect/Match';\nimport React, { type PropsWithChildren, useCallback, useContext, useEffect, useMemo, useState } from 'react';\n\nimport { useDefaultValue } from '@dxos/react-hooks';\n\nimport {\n type Selection,\n SelectionManager,\n type SelectionMode,\n type SelectionResult,\n defaultSelection,\n} from '../selection';\n\nconst SELECTION_NAME = 'Selection';\n\ntype SelectionContextValue = {\n selection: SelectionManager;\n};\n\nconst [SelectionContextProvider, useSelectionContext] = createContext<SelectionContextValue>(SELECTION_NAME, {\n selection: undefined as unknown as SelectionManager,\n});\n\n/**\n * Manages selection state across the app for multiple contexts.\n */\n// TODO(burdon): When is the selection removed?\nexport const SelectionProvider = ({\n children,\n selection: propsSelection,\n}: PropsWithChildren<{ selection?: SelectionManager }>) => {\n const registry = useContext(RegistryContext);\n const selection = useDefaultValue(propsSelection, () => new SelectionManager(registry));\n return <SelectionContextProvider selection={selection}>{children}</SelectionContextProvider>;\n};\n\n/**\n * Get the selection contexts.\n */\nexport const useSelectionManager = () => {\n const { selection } = useSelectionContext(SELECTION_NAME);\n return selection;\n};\n\nconst getDefaultResult = <T extends SelectionMode>(mode: T): SelectionResult<T> => {\n return Match.type<Selection>().pipe(\n Match.when({ mode: 'single' }, (selection) => selection.id),\n Match.when({ mode: 'multi' }, (selection) => selection.ids),\n Match.when({ mode: 'range' }, (selection) =>\n selection.from && selection.to ? { from: selection.from, to: selection.to } : undefined,\n ),\n Match.when({ mode: 'multi-range' }, (selection) => selection.ranges),\n Match.exhaustive,\n )(defaultSelection(mode)) as SelectionResult<T>;\n};\n\n/**\n * Get the selected objects for a given context.\n */\nexport const useSelected = <T extends SelectionMode>(\n contextId?: string,\n mode: T = 'multi' as T,\n): SelectionResult<T> => {\n const { selection } = useSelectionContext(SELECTION_NAME);\n const [state, setState] = useState<SelectionResult<T>>(() =>\n contextId && selection ? selection.getSelected(contextId, mode) : getDefaultResult(mode),\n );\n\n useEffect(() => {\n if (!contextId || !selection) {\n setState(getDefaultResult(mode));\n return;\n }\n\n // Set initial state.\n setState(selection.getSelected(contextId, mode));\n\n // Subscribe to changes.\n return selection.subscribe(() => {\n setState(selection.getSelected(contextId, mode));\n });\n }, [selection, contextId, mode]);\n\n return state;\n};\n\nexport type UseSelectionActions = {\n singleSelect: (id: string) => void;\n multiSelect: (ids: string[]) => void;\n rangeSelect: (from: string, to: string) => void;\n toggle: (id: string) => void;\n clear: () => void;\n};\n\n/**\n * Provides functions to manage the selection state for multiple contexts.\n */\n// TODO(burdon): Mode not used.\nexport const useSelectionActions = (contextIds: string[], mode: SelectionMode = 'multi'): UseSelectionActions => {\n const stableContextIds = useMemo(() => contextIds, [JSON.stringify(contextIds)]); // TODO(burdon): Avoid stringify.\n const { selection } = useSelectionContext(SELECTION_NAME);\n\n const singleSelect = useCallback(\n (id: string) => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.updateSingle(contextId, id);\n }\n },\n [selection, stableContextIds],\n );\n\n const multiSelect = useCallback(\n (ids: string[]) => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.updateMulti(contextId, ids);\n }\n },\n [selection, stableContextIds],\n );\n\n const rangeSelect = useCallback(\n (from: string, to: string) => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.updateRange(contextId, from, to);\n }\n },\n [selection, stableContextIds],\n );\n\n const toggle = useCallback(\n (id: string) => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.toggleSelection(contextId, id);\n }\n },\n [selection, stableContextIds],\n );\n\n const clear = useCallback(() => {\n if (!selection) {\n return;\n }\n for (const contextId of stableContextIds) {\n selection.clearSelection(contextId);\n }\n }, [selection, stableContextIds]);\n\n return { singleSelect, multiSelect, rangeSelect, toggle, clear };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["Atom", "AttentionManager", "_map", "Map", "_currentAtom", "_registry", "initial", "Atom", "make", "pipe", "keepAlive", "length", "update", "current", "getCurrent", "get", "subscribeCurrent", "cb", "subscribe", "keys", "Array", "from", "id", "atom", "_getAtom", "existing", "newAtom", "hasAttention", "isAncestor", "isRelated", "set", "nextIds", "primaryId", "currentIds", "prevPrimaryId", "prevPrefixes", "expandAttendableId", "prefix", "_set", "prevSegmentId", "getSegmentId", "key", "prefixes", "prefixSet", "Set", "linkedParent", "isLinkedSegment", "getParentId", "undefined", "segmentId", "has", "attention", "getAttendables", "selector", "cursor", "acc", "closestAttendable", "closest", "attendableId", "getAttribute", "trigger", "document", "querySelector", "push", "parentElement", "LINKED_PREFIX", "qualifiedId", "segments", "split", "map", "_", "index", "slice", "join", "lastSegment", "pop", "startsWith", "linkedSegment", "variant", "getLinkedVariant", "lastSlash", "lastIndexOf", "RegistryContext", "createContext", "Primitive", "Slot", "React", "forwardRef", "useContext", "useEffect", "useMemo", "useState", "log", "useDefaultValue", "mx", "ATTENTION_NAME", "ATTENDABLE_ATTRIBUTE", "ATTENTION_SOURCE_ATTRIBUTE", "AttentionContextProvider", "useAttentionContext", "createContext", "attention", "undefined", "UNKNOWN_ATTENDABLE", "hasAttention", "isAncestor", "isRelated", "useAttention", "attendableId", "state", "setState", "useState", "useEffect", "currentState", "get", "subscribe", "newState", "useAttended", "current", "setCurrent", "getCurrent", "subscribeCurrent", "newCurrent", "useAttentionAttributes", "useMemo", "attributes", "RootAttentionProvider", "children", "propsAttention", "onChange", "registry", "useContext", "RegistryContext", "useDefaultValue", "AttentionManager", "handleFocus", "event", "log", "related", "relatedTarget", "target", "selector", "Array", "from", "document", "querySelectorAll", "map", "el", "getAttribute", "join", "prev", "next", "getAttendables", "length", "find", "id", "index", "update", "div", "role", "className", "onFocusCapture", "AttendableContainer", "forwardRef", "classNames", "asChild", "props", "forwardedRef", "attentionAttrs", "Comp", "Slot", "Primitive", "mx", "tabIndex", "ref", "Atom", "Match", "Schema", "invariant", "SelectionSchema", "Union", "Struct", "mode", "Literal", "id", "optional", "String", "pipe", "mutable", "ids", "Array", "from", "to", "ranges", "defaultSelection", "type", "withReturnType", "when", "exhaustive", "getSelectionSet", "selectionManager", "contextId", "Set", "context", "getSelectionContexts", "selection", "getSelection", "add", "SelectionManager", "_state", "_registry", "initial", "make", "selections", "state", "getState", "get", "subscribe", "cb", "Object", "keys", "undefined", "newSelection", "update", "getSelected", "s", "updateSingle", "updateMulti", "updateRange", "updateMultiRange", "clearSelection", "clearedSelection", "toggleSelection", "newIds", "includes", "filter", "existingId", "RegistryContext", "createContext", "Match", "React", "useCallback", "useContext", "useEffect", "useMemo", "useState", "useDefaultValue", "SELECTION_NAME", "SelectionContextProvider", "useSelectionContext", "createContext", "selection", "undefined", "SelectionProvider", "children", "propsSelection", "registry", "useContext", "RegistryContext", "useDefaultValue", "SelectionManager", "React", "useSelectionManager", "getDefaultResult", "mode", "type", "pipe", "when", "id", "ids", "from", "to", "ranges", "exhaustive", "defaultSelection", "useSelected", "contextId", "state", "setState", "useState", "getSelected", "useEffect", "subscribe", "useSelectionActions", "contextIds", "stableContextIds", "useMemo", "JSON", "stringify", "singleSelect", "useCallback", "updateSingle", "multiSelect", "updateMulti", "rangeSelect", "updateRange", "toggle", "toggleSelection", "clear", "clearSelection"]
7
+ }
@@ -0,0 +1,2 @@
1
+ import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+ //# sourceMappingURL=chunk-UHVMYYIB.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1,4 +1,5 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+ import "./chunk-UHVMYYIB.mjs";
2
3
  import {
3
4
  ATTENDABLE_ATTRIBUTE,
4
5
  ATTENTION_NAME,
@@ -12,10 +13,12 @@ import {
12
13
  defaultSelection,
13
14
  expandAttendableId,
14
15
  getAttendables,
16
+ getLinkedVariant,
15
17
  getParentId,
16
18
  getSegmentId,
17
19
  getSelectionSet,
18
- isSeparatorPrefixed,
20
+ isLinkedSegment,
21
+ linkedSegment,
19
22
  useAttended,
20
23
  useAttention,
21
24
  useAttentionAttributes,
@@ -23,10 +26,7 @@ import {
23
26
  useSelected,
24
27
  useSelectionActions,
25
28
  useSelectionManager
26
- } from "./chunk-LSWTWT3W.mjs";
27
- import {
28
- ATTENDABLE_PATH_SEPARATOR
29
- } from "./chunk-PMGNPL4M.mjs";
29
+ } from "./chunk-6PQ4P7AL.mjs";
30
30
 
31
31
  // src/components/AttentionGlyph.tsx
32
32
  import React, { forwardRef, useMemo } from "react";
@@ -98,7 +98,6 @@ var AttentionGlyph = /* @__PURE__ */ forwardRef(({ presence, attended, syncing,
98
98
  });
99
99
  export {
100
100
  ATTENDABLE_ATTRIBUTE,
101
- ATTENDABLE_PATH_SEPARATOR,
102
101
  ATTENTION_NAME,
103
102
  ATTENTION_SOURCE_ATTRIBUTE,
104
103
  AttendableContainer,
@@ -112,10 +111,12 @@ export {
112
111
  defaultSelection,
113
112
  expandAttendableId,
114
113
  getAttendables,
114
+ getLinkedVariant,
115
115
  getParentId,
116
116
  getSegmentId,
117
117
  getSelectionSet,
118
- isSeparatorPrefixed,
118
+ isLinkedSegment,
119
+ linkedSegment,
119
120
  useAttended,
120
121
  useAttention,
121
122
  useAttentionAttributes,