@dxos/react-ui-attention 0.7.5-main.9d2a38b → 0.7.5-main.e94eead

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 (38) hide show
  1. package/dist/lib/browser/{chunk-24QUHUNM.mjs → chunk-CRGQHPBS.mjs} +109 -3
  2. package/dist/lib/browser/{chunk-24QUHUNM.mjs.map → chunk-CRGQHPBS.mjs.map} +4 -4
  3. package/dist/lib/browser/index.mjs +11 -3
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +1 -1
  6. package/dist/lib/node/{chunk-QOTK2MG6.cjs → chunk-P7OLU2DK.cjs} +113 -7
  7. package/dist/lib/node/chunk-P7OLU2DK.cjs.map +7 -0
  8. package/dist/lib/node/index.cjs +26 -18
  9. package/dist/lib/node/index.cjs.map +2 -2
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/testing/index.cjs +2 -2
  12. package/dist/lib/node-esm/{chunk-JV4EAWON.mjs → chunk-2RO7IZV4.mjs} +109 -3
  13. package/dist/lib/node-esm/{chunk-JV4EAWON.mjs.map → chunk-2RO7IZV4.mjs.map} +4 -4
  14. package/dist/lib/node-esm/index.mjs +11 -3
  15. package/dist/lib/node-esm/meta.json +1 -1
  16. package/dist/lib/node-esm/testing/index.mjs +1 -1
  17. package/dist/types/src/components/AttentionGlyph.d.ts +1 -1
  18. package/dist/types/src/components/AttentionGlyph.d.ts.map +1 -1
  19. package/dist/types/src/components/AttentionGlyph.stories.d.ts +3 -3
  20. package/dist/types/src/components/AttentionProvider.d.ts +2 -2
  21. package/dist/types/src/components/AttentionProvider.d.ts.map +1 -1
  22. package/dist/types/src/components/AttentionProvider.stories.d.ts +2 -3
  23. package/dist/types/src/components/AttentionProvider.stories.d.ts.map +1 -1
  24. package/dist/types/src/components/SelectionProvider.d.ts +18 -0
  25. package/dist/types/src/components/SelectionProvider.d.ts.map +1 -0
  26. package/dist/types/src/components/index.d.ts +1 -0
  27. package/dist/types/src/components/index.d.ts.map +1 -1
  28. package/dist/types/src/index.d.ts +1 -0
  29. package/dist/types/src/index.d.ts.map +1 -1
  30. package/dist/types/src/selection.d.ts +15 -0
  31. package/dist/types/src/selection.d.ts.map +1 -0
  32. package/package.json +19 -18
  33. package/src/components/AttentionProvider.tsx +42 -2
  34. package/src/components/SelectionProvider.tsx +75 -0
  35. package/src/components/index.ts +1 -0
  36. package/src/index.ts +1 -0
  37. package/src/selection.ts +60 -0
  38. package/dist/lib/node/chunk-QOTK2MG6.cjs.map +0 -7
@@ -276,11 +276,113 @@ var AttendableContainer = /* @__PURE__ */ forwardRef2(({ id, classNames, childre
276
276
  role: "none",
277
277
  ...attendableAttrs,
278
278
  ...props,
279
- className: mx2("attention-surface", props.tabIndex === 0 && "ch-focus-ring-inset-over-all", classNames),
279
+ className: mx2("attention-surface", props.tabIndex === 0 && "dx-focus-ring-inset-over-all", classNames),
280
280
  ref: forwardedRef
281
281
  }, children);
282
282
  });
283
283
 
284
+ // packages/ui/react-ui-attention/src/selection.ts
285
+ import { untracked as untracked2 } from "@preact/signals-core";
286
+ import { create as create2 } from "@dxos/live-object";
287
+ var SelectionManager = class {
288
+ constructor(initial = {}) {
289
+ this._state = create2({
290
+ selections: {}
291
+ });
292
+ if (Object.keys(initial).length > 0) {
293
+ untracked2(() => {
294
+ this._state.selections = initial;
295
+ });
296
+ }
297
+ }
298
+ get selections() {
299
+ return this._state.selections;
300
+ }
301
+ getSelection(contextId) {
302
+ if (!this.selections[contextId]) {
303
+ untracked2(() => {
304
+ this._state.selections[contextId] = /* @__PURE__ */ new Set();
305
+ });
306
+ }
307
+ return this.selections[contextId];
308
+ }
309
+ updateSelection(contextId, selectedIds) {
310
+ untracked2(() => {
311
+ this._state.selections[contextId] = selectedIds instanceof Set ? selectedIds : new Set(selectedIds);
312
+ });
313
+ }
314
+ clearSelection(contextId) {
315
+ untracked2(() => {
316
+ this._state.selections[contextId] = /* @__PURE__ */ new Set();
317
+ });
318
+ }
319
+ toggleSelection(contextId, id) {
320
+ untracked2(() => {
321
+ const current = this.getSelection(contextId);
322
+ if (current.has(id)) {
323
+ current.delete(id);
324
+ } else {
325
+ current.add(id);
326
+ }
327
+ });
328
+ }
329
+ };
330
+
331
+ // packages/ui/react-ui-attention/src/components/SelectionProvider.tsx
332
+ import { createContext as createContext2 } from "@radix-ui/react-context";
333
+ import React3, { useCallback, useMemo as useMemo3 } from "react";
334
+ import { useDefaultValue as useDefaultValue2 } from "@dxos/react-ui";
335
+ var SELECTION_NAME = "Selection";
336
+ var [SelectionContextProvider, useSelectionContext] = createContext2(SELECTION_NAME, {
337
+ selection: new SelectionManager()
338
+ });
339
+ var SelectionProvider = ({ children, selection: propsSelection }) => {
340
+ const selection = useDefaultValue2(propsSelection, () => new SelectionManager());
341
+ return /* @__PURE__ */ React3.createElement(SelectionContextProvider, {
342
+ selection
343
+ }, children);
344
+ };
345
+ var emptySet = /* @__PURE__ */ new Set();
346
+ var useSelectedItems = (contextId) => {
347
+ const { selection } = useSelectionContext(SELECTION_NAME);
348
+ return contextId ? selection.getSelection(contextId) : emptySet;
349
+ };
350
+ var useSelectionActions = (contextIds) => {
351
+ const stableContextIds = useMemo3(() => contextIds, [
352
+ JSON.stringify(contextIds)
353
+ ]);
354
+ const { selection } = useSelectionContext(SELECTION_NAME);
355
+ const select = useCallback((ids) => {
356
+ for (const contextId of stableContextIds) {
357
+ selection.updateSelection(contextId, ids);
358
+ }
359
+ }, [
360
+ selection,
361
+ stableContextIds
362
+ ]);
363
+ const toggle = useCallback((id) => {
364
+ for (const contextId of stableContextIds) {
365
+ selection.toggleSelection(contextId, id);
366
+ }
367
+ }, [
368
+ selection,
369
+ stableContextIds
370
+ ]);
371
+ const clear = useCallback(() => {
372
+ for (const contextId of stableContextIds) {
373
+ selection.clearSelection(contextId);
374
+ }
375
+ }, [
376
+ selection,
377
+ stableContextIds
378
+ ]);
379
+ return {
380
+ select,
381
+ toggle,
382
+ clear
383
+ };
384
+ };
385
+
284
386
  export {
285
387
  AttentionSchema,
286
388
  AttentionManager,
@@ -297,6 +399,10 @@ export {
297
399
  useAttentionPath,
298
400
  RootAttentionProvider,
299
401
  AttentionProvider,
300
- AttendableContainer
402
+ AttendableContainer,
403
+ SelectionManager,
404
+ SelectionProvider,
405
+ useSelectedItems,
406
+ useSelectionActions
301
407
  };
302
- //# sourceMappingURL=chunk-24QUHUNM.mjs.map
408
+ //# sourceMappingURL=chunk-CRGQHPBS.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/attention.ts", "../../../src/components/AttentionGlyph.tsx", "../../../src/components/AttentionProvider.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { untracked } from '@preact/signals-core';\n\nimport { S } from '@dxos/echo-schema';\nimport { create, type ReactiveObject } from '@dxos/live-object';\nimport { ComplexMap } from '@dxos/util';\n\nexport const AttentionSchema = S.mutable(\n S.Struct({\n hasAttention: S.Boolean,\n isAncestor: S.Boolean,\n isRelated: S.Boolean,\n }),\n);\n\nexport type Attention = S.Schema.Type<typeof AttentionSchema>;\n\n// TODO(wittjosiah): Use mosaic path utility?\nconst stringKey = (key: string[]) => key.join(',');\n\n/**\n * Manages attention state for an application.\n */\n// TODO(wittjosiah): Write unit tests.\nexport class AttentionManager {\n // Each attention path is associated with an attention object.\n // The lookup is not a reactive object to ensure that attention for each path is subscribable independently.\n private readonly _map = new ComplexMap<string[], ReactiveObject<Attention>>(stringKey);\n private readonly _state = create<{ current: string[] }>({ current: [] });\n\n constructor(initial: string[] = []) {\n if (initial.length > 0) {\n this.update(initial);\n }\n }\n\n /**\n * Currently attended element.\n *\n * @reactive\n */\n get current(): ReactiveObject<readonly string[]> {\n return this._state.current;\n }\n\n /**\n * All attention paths.\n */\n keys(): string[][] {\n return Array.from(this._map.keys());\n }\n\n /**\n * Get the attention state for a given path.\n */\n get(key: string[]): ReactiveObject<Attention> {\n const object = this._map.get(key);\n if (object) {\n return object;\n }\n\n const newObject = create(AttentionSchema, { hasAttention: false, isAncestor: false, isRelated: false });\n this._map.set(key, newObject);\n return newObject;\n }\n\n /**\n * Update the currently attended element.\n *\n * @internal\n */\n update(nextKey: string[]) {\n const currentKey = untracked(() => this.current);\n const currentRelatedTo = currentKey[0];\n const nextRelatedTo = nextKey[0];\n\n // Ensure related attention object is initialized.\n this.get([nextRelatedTo]);\n\n const currentRelatedKeys = this.keys().filter((key) => key[0] === currentRelatedTo);\n const nextRelatedKeys = this.keys().filter(\n (key) => key[0] === nextRelatedTo && stringKey(key) !== stringKey(nextKey),\n );\n const prevRelatedKeys = currentRelatedKeys.filter(\n (curr) => !nextRelatedKeys.find((next) => stringKey(curr) === stringKey(next)),\n );\n\n const currentAncestorKeys = currentKey.slice(1).map((_, i) => currentKey.slice(i + 1, currentKey.length));\n const nextAncestorKeys = nextKey.slice(1).map((_, i) => nextKey.slice(i + 1, nextKey.length));\n const prevAncestorKeys = currentAncestorKeys.filter(\n (curr) => !nextAncestorKeys.find((next) => stringKey(curr) === stringKey(next)),\n );\n\n this._state.current = nextKey;\n prevRelatedKeys.forEach((key) => this._set(key, {}));\n prevAncestorKeys.forEach((key) => this._set(key, {}));\n nextRelatedKeys.forEach((key) => this._set(key, { isRelated: true }));\n nextAncestorKeys.forEach((key) => this._set(key, { isAncestor: true }));\n this._set(nextKey, { hasAttention: true });\n }\n\n private _set(key: string[], attention: Partial<Attention>) {\n const object = this.get(key);\n object.hasAttention = attention.hasAttention ?? false;\n object.isAncestor = attention.isAncestor ?? false;\n object.isRelated = attention.isRelated ?? false;\n }\n}\n\n/**\n * Accumulates all attendable id’s between the element provided and the root, inclusive.\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 // (attempt tail recursion)\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// Copyright 2024 DXOS.org\n//\n\nimport { type Primitive } from '@radix-ui/react-primitive';\nimport React, { type ComponentPropsWithRef, type CSSProperties, forwardRef, useMemo } from 'react';\n\nimport { Icon, type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nconst attentionGlyphStyles =\n 'inline-block rounded-sm is-3 bs-3 bg-transparent text-accentText transition-colors [[data-contains-attended=true]_&]:bg-attentionRelated [[data-attention=true]_&]:bg-accentSurface [[data-attention=true]_&]:text-inverse [[aria-current][data-attention=true]_&]:bg-accentSurface [[aria-current][data-attention=true]_&]:text-inverse';\n\nconst presenceIconStyles =\n 'is-3 bs-3 group-[[aria-current]_&:hover]/attentionGlyphButton:hidden group-[[aria-current]_&:focus]/attentionGlyphButton:hidden group-[[data-attention=true]_&:hover]/attentionGlyphButton:hidden group-[[data-attention=true]_&:focus]/attentionGlyphButton:hidden group-[[aria-current][data-attention=true]_&:hover]/attentionGlyphButton:hidden group-[[aria-current][data-attention=true]_&:focus]/attentionGlyphButton:hidden';\n\nconst PresenceOne = () => {\n return (\n <svg\n width='12'\n height='12'\n viewBox='0 0 12 12'\n className={presenceIconStyles}\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <circle cx='6' cy='6' r='2.5' fill='currentColor' />\n </svg>\n );\n};\n\nconst PresenceMany = () => {\n return (\n <svg\n width='12'\n height='12'\n viewBox='0 0 12 12'\n className={presenceIconStyles}\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M6.75 8.27311C7.38815 7.72296 7.79212 6.90866 7.79212 6C7.79212 5.09134 7.38815 4.27704 6.75 3.72689C7.06722 3.58122 7.42019 3.5 7.79212 3.5C9.17283 3.5 10.2921 4.61929 10.2921 6C10.2921 7.38071 9.17283 8.5 7.79212 8.5C7.42019 8.5 7.06723 8.41878 6.75 8.27311Z'\n fill='currentColor'\n />\n <circle cx='4.25' cy='6' r='2.5' fill='currentColor' />\n </svg>\n );\n};\n\nexport const Syncing = () => {\n const animationProps = useMemo<CSSProperties>(\n () => ({\n // Synchronize animations.\n animationDelay: `-${Date.now() % 2_000}ms`,\n }),\n [],\n );\n\n return (\n <div role='status' className='flex items-center'>\n <Icon\n icon='ph--circle-notch--regular'\n size={3}\n style={animationProps}\n classNames='text-subdued animate-[spin_2s_linear_infinite]'\n />\n </div>\n );\n};\n\nexport type AttentionGlyphProps = {\n attended?: boolean;\n containsAttended?: boolean;\n syncing?: boolean;\n presence?: 'none' | 'one' | 'many';\n} & ThemedClassName<Omit<ComponentPropsWithRef<typeof Primitive.span>, 'children'>>;\n\nexport const AttentionGlyph = forwardRef<HTMLSpanElement, AttentionGlyphProps>(\n ({ presence, attended, syncing, containsAttended, classNames, ...props }, forwardedRef) => {\n const icon = syncing ? (\n <Syncing />\n ) : presence === 'many' ? (\n <PresenceMany />\n ) : presence === 'one' ? (\n <PresenceOne />\n ) : null;\n\n return (\n <div role='none' className='flex' data-attention={attended} data-contains-attended={containsAttended}>\n <span role='none' {...props} className={mx(attentionGlyphStyles, classNames)} ref={forwardedRef}>\n {icon}\n </span>\n </div>\n );\n },\n);\n", "//\n// Copyright 2024 DXOS.org\n//\n\n// NOTE(thure): The following unused imports quell TS2742 (“likely not portable”).\n\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport { createContext, type Scope, type CreateScope } from '@radix-ui/react-context';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { Slot } from '@radix-ui/react-slot';\nimport React, { useMemo, type FocusEvent, type PropsWithChildren, type ComponentPropsWithRef, forwardRef } from 'react';\n\nimport { useDefaultValue, type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { type Attention, AttentionManager, getAttendables } from '../attention';\n\nconst ATTENTION_NAME = 'Attention';\nconst ATTENABLE_ATTRIBUTE = 'data-attendable-id';\nconst ATTENTION_SOURCE_ATTRIBUTE = 'data-is-attention-source';\n\ntype AttentionContextValue = {\n attention: AttentionManager;\n path: string[];\n};\n\nconst [AttentionContextProvider, useAttentionContext] = createContext<AttentionContextValue>(ATTENTION_NAME, {\n attention: new AttentionManager(),\n path: [],\n});\n\nconst UNKNOWN_ATTENDABLE = { hasAttention: false, isAncestor: false, isRelated: false };\n\nconst useAttention = (attendableId?: string): Attention => {\n const { attention, path } = useAttentionContext(ATTENTION_NAME);\n if (!attendableId) {\n return UNKNOWN_ATTENDABLE;\n }\n\n const current = [attendableId, ...path];\n return attention.get(current);\n};\n\nconst useAttended = () => {\n const { attention } = useAttentionContext(ATTENTION_NAME);\n return attention.current;\n};\n\n/**\n * Computes HTML element attributes to apply so the attention system can detect changes\n * @param attendableId\n */\nconst useAttendableAttributes = (attendableId?: string) => {\n const { hasAttention } = useAttention(attendableId);\n return useMemo(() => {\n const attributes: Record<string, string | undefined> = { [ATTENABLE_ATTRIBUTE]: attendableId };\n if (hasAttention) {\n attributes[ATTENTION_SOURCE_ATTRIBUTE] = 'true';\n }\n\n return attributes;\n }, [attendableId, hasAttention]);\n};\n\nconst useAttentionPath = () => {\n const { path } = useAttentionContext(ATTENTION_NAME);\n return path;\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 attention = useDefaultValue(propsAttention, () => new AttentionManager());\n const handleFocus = (event: FocusEvent) => {\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.current;\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} path={[]}>\n <div role='none' className='contents' onFocusCapture={handleFocus}>\n {children}\n </div>\n </AttentionContextProvider>\n );\n};\n\nconst AttentionProvider = ({ id, children }: PropsWithChildren<{ id: string }>) => {\n const { attention, path } = useAttentionContext(ATTENTION_NAME);\n const nextPath = useMemo(() => [id, ...path], [id, path]);\n\n return (\n <AttentionContextProvider attention={attention} path={nextPath}>\n {children}\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, and when rendering content in those cases it\n * is not necessary to also render an `AttendableContainer`. This component is primarily for Storybook stories and other\n * testing scenarios, 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 attendableAttrs = useAttendableAttributes(id);\n const Root = asChild ? Slot : Primitive.div;\n return (\n <Root\n role='none'\n {...attendableAttrs}\n {...props}\n className={mx('attention-surface', props.tabIndex === 0 && 'ch-focus-ring-inset-over-all', classNames)}\n ref={forwardedRef}\n >\n {children}\n </Root>\n );\n },\n);\n\nexport {\n RootAttentionProvider,\n AttentionProvider,\n AttendableContainer,\n useAttentionContext,\n useAttention,\n useAttended,\n useAttendableAttributes,\n useAttentionPath,\n ATTENTION_NAME,\n ATTENABLE_ATTRIBUTE,\n ATTENTION_SOURCE_ATTRIBUTE,\n};\n"],
5
- "mappings": "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",
6
- "names": ["untracked", "S", "create", "ComplexMap", "AttentionSchema", "S", "mutable", "Struct", "hasAttention", "Boolean", "isAncestor", "isRelated", "stringKey", "key", "join", "AttentionManager", "constructor", "initial", "_map", "ComplexMap", "_state", "create", "current", "length", "update", "keys", "Array", "from", "get", "object", "newObject", "set", "nextKey", "currentKey", "untracked", "currentRelatedTo", "nextRelatedTo", "currentRelatedKeys", "filter", "nextRelatedKeys", "prevRelatedKeys", "curr", "find", "next", "currentAncestorKeys", "slice", "map", "_", "i", "nextAncestorKeys", "prevAncestorKeys", "forEach", "_set", "attention", "getAttendables", "selector", "cursor", "acc", "closestAttendable", "closest", "attendableId", "getAttribute", "trigger", "document", "querySelector", "push", "parentElement", "Set", "React", "forwardRef", "useMemo", "Icon", "mx", "attentionGlyphStyles", "presenceIconStyles", "PresenceOne", "svg", "width", "height", "viewBox", "className", "fill", "xmlns", "circle", "cx", "cy", "r", "PresenceMany", "path", "d", "Syncing", "animationProps", "useMemo", "animationDelay", "Date", "now", "div", "role", "Icon", "icon", "size", "style", "classNames", "AttentionGlyph", "forwardRef", "presence", "attended", "syncing", "containsAttended", "props", "forwardedRef", "data-attention", "data-contains-attended", "span", "mx", "ref", "createContext", "Primitive", "Slot", "React", "useMemo", "forwardRef", "useDefaultValue", "mx", "ATTENTION_NAME", "ATTENABLE_ATTRIBUTE", "ATTENTION_SOURCE_ATTRIBUTE", "AttentionContextProvider", "useAttentionContext", "createContext", "attention", "AttentionManager", "path", "UNKNOWN_ATTENDABLE", "hasAttention", "isAncestor", "isRelated", "useAttention", "attendableId", "current", "get", "useAttended", "useAttendableAttributes", "useMemo", "attributes", "useAttentionPath", "RootAttentionProvider", "children", "propsAttention", "onChange", "useDefaultValue", "handleFocus", "event", "selector", "Array", "from", "document", "querySelectorAll", "map", "el", "getAttribute", "join", "prev", "next", "getAttendables", "target", "length", "find", "id", "index", "update", "React", "div", "role", "className", "onFocusCapture", "AttentionProvider", "nextPath", "AttendableContainer", "forwardRef", "classNames", "asChild", "props", "forwardedRef", "attendableAttrs", "Root", "Slot", "Primitive", "mx", "tabIndex", "ref"]
3
+ "sources": ["../../../src/attention.ts", "../../../src/components/AttentionGlyph.tsx", "../../../src/components/AttentionProvider.tsx", "../../../src/selection.ts", "../../../src/components/SelectionProvider.tsx"],
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { untracked } from '@preact/signals-core';\n\nimport { S } from '@dxos/echo-schema';\nimport { create, type ReactiveObject } from '@dxos/live-object';\nimport { ComplexMap } from '@dxos/util';\n\nexport const AttentionSchema = S.mutable(\n S.Struct({\n hasAttention: S.Boolean,\n isAncestor: S.Boolean,\n isRelated: S.Boolean,\n }),\n);\n\nexport type Attention = S.Schema.Type<typeof AttentionSchema>;\n\n// TODO(wittjosiah): Use mosaic path utility?\nconst stringKey = (key: string[]) => key.join(',');\n\n/**\n * Manages attention state for an application.\n */\n// TODO(wittjosiah): Write unit tests.\nexport class AttentionManager {\n // Each attention path is associated with an attention object.\n // The lookup is not a reactive object to ensure that attention for each path is subscribable independently.\n private readonly _map = new ComplexMap<string[], ReactiveObject<Attention>>(stringKey);\n private readonly _state = create<{ current: string[] }>({ current: [] });\n\n constructor(initial: string[] = []) {\n if (initial.length > 0) {\n this.update(initial);\n }\n }\n\n /**\n * Currently attended element.\n *\n * @reactive\n */\n get current(): ReactiveObject<readonly string[]> {\n return this._state.current;\n }\n\n /**\n * All attention paths.\n */\n keys(): string[][] {\n return Array.from(this._map.keys());\n }\n\n /**\n * Get the attention state for a given path.\n */\n get(key: string[]): ReactiveObject<Attention> {\n const object = this._map.get(key);\n if (object) {\n return object;\n }\n\n const newObject = create(AttentionSchema, { hasAttention: false, isAncestor: false, isRelated: false });\n this._map.set(key, newObject);\n return newObject;\n }\n\n /**\n * Update the currently attended element.\n *\n * @internal\n */\n update(nextKey: string[]) {\n const currentKey = untracked(() => this.current);\n const currentRelatedTo = currentKey[0];\n const nextRelatedTo = nextKey[0];\n\n // Ensure related attention object is initialized.\n this.get([nextRelatedTo]);\n\n const currentRelatedKeys = this.keys().filter((key) => key[0] === currentRelatedTo);\n const nextRelatedKeys = this.keys().filter(\n (key) => key[0] === nextRelatedTo && stringKey(key) !== stringKey(nextKey),\n );\n const prevRelatedKeys = currentRelatedKeys.filter(\n (curr) => !nextRelatedKeys.find((next) => stringKey(curr) === stringKey(next)),\n );\n\n const currentAncestorKeys = currentKey.slice(1).map((_, i) => currentKey.slice(i + 1, currentKey.length));\n const nextAncestorKeys = nextKey.slice(1).map((_, i) => nextKey.slice(i + 1, nextKey.length));\n const prevAncestorKeys = currentAncestorKeys.filter(\n (curr) => !nextAncestorKeys.find((next) => stringKey(curr) === stringKey(next)),\n );\n\n this._state.current = nextKey;\n prevRelatedKeys.forEach((key) => this._set(key, {}));\n prevAncestorKeys.forEach((key) => this._set(key, {}));\n nextRelatedKeys.forEach((key) => this._set(key, { isRelated: true }));\n nextAncestorKeys.forEach((key) => this._set(key, { isAncestor: true }));\n this._set(nextKey, { hasAttention: true });\n }\n\n private _set(key: string[], attention: Partial<Attention>) {\n const object = this.get(key);\n object.hasAttention = attention.hasAttention ?? false;\n object.isAncestor = attention.isAncestor ?? false;\n object.isRelated = attention.isRelated ?? false;\n }\n}\n\n/**\n * Accumulates all attendable id’s between the element provided and the root, inclusive.\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 // (attempt tail recursion)\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// Copyright 2024 DXOS.org\n//\n\nimport { type Primitive } from '@radix-ui/react-primitive';\nimport React, { type ComponentPropsWithRef, type CSSProperties, forwardRef, useMemo } from 'react';\n\nimport { Icon, type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nconst attentionGlyphStyles =\n 'inline-block rounded-sm is-3 bs-3 bg-transparent text-accentText transition-colors [[data-contains-attended=true]_&]:bg-attentionRelated [[data-attention=true]_&]:bg-accentSurface [[data-attention=true]_&]:text-inverse [[aria-current][data-attention=true]_&]:bg-accentSurface [[aria-current][data-attention=true]_&]:text-inverse';\n\nconst presenceIconStyles =\n 'is-3 bs-3 group-[[aria-current]_&:hover]/attentionGlyphButton:hidden group-[[aria-current]_&:focus]/attentionGlyphButton:hidden group-[[data-attention=true]_&:hover]/attentionGlyphButton:hidden group-[[data-attention=true]_&:focus]/attentionGlyphButton:hidden group-[[aria-current][data-attention=true]_&:hover]/attentionGlyphButton:hidden group-[[aria-current][data-attention=true]_&:focus]/attentionGlyphButton:hidden';\n\nconst PresenceOne = () => {\n return (\n <svg\n width='12'\n height='12'\n viewBox='0 0 12 12'\n className={presenceIconStyles}\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <circle cx='6' cy='6' r='2.5' fill='currentColor' />\n </svg>\n );\n};\n\nconst PresenceMany = () => {\n return (\n <svg\n width='12'\n height='12'\n viewBox='0 0 12 12'\n className={presenceIconStyles}\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M6.75 8.27311C7.38815 7.72296 7.79212 6.90866 7.79212 6C7.79212 5.09134 7.38815 4.27704 6.75 3.72689C7.06722 3.58122 7.42019 3.5 7.79212 3.5C9.17283 3.5 10.2921 4.61929 10.2921 6C10.2921 7.38071 9.17283 8.5 7.79212 8.5C7.42019 8.5 7.06723 8.41878 6.75 8.27311Z'\n fill='currentColor'\n />\n <circle cx='4.25' cy='6' r='2.5' fill='currentColor' />\n </svg>\n );\n};\n\nexport const Syncing = () => {\n const animationProps = useMemo<CSSProperties>(\n () => ({\n // Synchronize animations.\n animationDelay: `-${Date.now() % 2_000}ms`,\n }),\n [],\n );\n\n return (\n <div role='status' className='flex items-center'>\n <Icon\n icon='ph--circle-notch--regular'\n size={3}\n style={animationProps}\n classNames='text-subdued animate-[spin_2s_linear_infinite]'\n />\n </div>\n );\n};\n\nexport type AttentionGlyphProps = {\n attended?: boolean;\n containsAttended?: boolean;\n syncing?: boolean;\n presence?: 'none' | 'one' | 'many';\n} & ThemedClassName<Omit<ComponentPropsWithRef<typeof Primitive.span>, 'children'>>;\n\nexport const AttentionGlyph = forwardRef<HTMLSpanElement, AttentionGlyphProps>(\n ({ presence, attended, syncing, containsAttended, classNames, ...props }, forwardedRef) => {\n const icon = syncing ? (\n <Syncing />\n ) : presence === 'many' ? (\n <PresenceMany />\n ) : presence === 'one' ? (\n <PresenceOne />\n ) : null;\n\n return (\n <div role='none' className='flex' data-attention={attended} data-contains-attended={containsAttended}>\n <span role='none' {...props} className={mx(attentionGlyphStyles, classNames)} ref={forwardedRef}>\n {icon}\n </span>\n </div>\n );\n },\n);\n", "//\n// Copyright 2024 DXOS.org\n//\n\n// NOTE(thure): The following unused imports quell TS2742 (“likely not portable”).\n\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport { createContext, type Scope, type CreateScope } from '@radix-ui/react-context';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { Slot } from '@radix-ui/react-slot';\nimport React, { useMemo, type FocusEvent, type PropsWithChildren, type ComponentPropsWithRef, forwardRef } from 'react';\n\nimport { useDefaultValue, type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { type Attention, AttentionManager, getAttendables } from '../attention';\n\nconst ATTENTION_NAME = 'Attention';\nconst ATTENABLE_ATTRIBUTE = 'data-attendable-id';\nconst ATTENTION_SOURCE_ATTRIBUTE = 'data-is-attention-source';\n\ntype AttentionContextValue = {\n attention: AttentionManager;\n path: string[];\n};\n\nconst [AttentionContextProvider, useAttentionContext] = createContext<AttentionContextValue>(ATTENTION_NAME, {\n attention: new AttentionManager(),\n path: [],\n});\n\nconst UNKNOWN_ATTENDABLE = { hasAttention: false, isAncestor: false, isRelated: false };\n\nconst useAttention = (attendableId?: string): Attention => {\n const { attention, path } = useAttentionContext(ATTENTION_NAME);\n if (!attendableId) {\n return UNKNOWN_ATTENDABLE;\n }\n\n const current = [attendableId, ...path];\n return attention.get(current);\n};\n\nconst useAttended = () => {\n const { attention } = useAttentionContext(ATTENTION_NAME);\n return attention.current;\n};\n\n/**\n * Computes HTML element attributes to apply so the attention system can detect changes\n * @param attendableId\n */\nconst useAttendableAttributes = (attendableId?: string) => {\n const { hasAttention } = useAttention(attendableId);\n return useMemo(() => {\n const attributes: Record<string, string | undefined> = { [ATTENABLE_ATTRIBUTE]: attendableId };\n if (hasAttention) {\n attributes[ATTENTION_SOURCE_ATTRIBUTE] = 'true';\n }\n\n return attributes;\n }, [attendableId, hasAttention]);\n};\n\nconst useAttentionPath = () => {\n const { path } = useAttentionContext(ATTENTION_NAME);\n return path;\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 attention = useDefaultValue(propsAttention, () => new AttentionManager());\n const handleFocus = (event: FocusEvent) => {\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.current;\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 // NOTE(thure): Use the following to debug the macOS package issue #8540\n\n // const [startEl, setStartEl] = useState<HTMLElement | null>(null);\n // const [endEl, setEndEl] = useState<HTMLElement | null>(null);\n //\n // const handleEventDebug = useCallback((event: any) => {\n // console.log(`[${event.type}]`, event.target, event.currentTarget, [event.clientX, event.clientY]);\n // }, []);\n //\n // const handleStartDebug = useCallback(\n // (event: any) => {\n // setStartEl(event.target);\n // handleEventDebug(event);\n // },\n // [handleEventDebug],\n // );\n //\n // const handleEndDebug = useCallback(\n // (event: any) => {\n // setEndEl(event.target);\n // handleEventDebug(event);\n // },\n // [handleEventDebug],\n // );\n //\n // const handleClickDebug = useCallback(\n // (event: any) => {\n // console.log('[click compare]', startEl, endEl, startEl === endEl);\n // handleEventDebug(event);\n // },\n // [startEl, endEl, handleEventDebug],\n // );\n\n return (\n <AttentionContextProvider attention={attention} path={[]}>\n <div\n role='none'\n className='contents'\n onFocusCapture={handleFocus}\n // onClick={handleClickDebug}\n // onMouseDown={handleStartDebug}\n // onMouseUp={handleEndDebug}\n >\n {children}\n </div>\n </AttentionContextProvider>\n );\n};\n\nconst AttentionProvider = ({ id, children }: PropsWithChildren<{ id: string }>) => {\n const { attention, path } = useAttentionContext(ATTENTION_NAME);\n const nextPath = useMemo(() => [id, ...path], [id, path]);\n\n return (\n <AttentionContextProvider attention={attention} path={nextPath}>\n {children}\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, and when rendering content in those cases it\n * is not necessary to also render an `AttendableContainer`. This component is primarily for Storybook stories and other\n * testing scenarios, 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 attendableAttrs = useAttendableAttributes(id);\n const Root = asChild ? Slot : Primitive.div;\n return (\n <Root\n role='none'\n {...attendableAttrs}\n {...props}\n className={mx('attention-surface', props.tabIndex === 0 && 'dx-focus-ring-inset-over-all', classNames)}\n ref={forwardedRef}\n >\n {children}\n </Root>\n );\n },\n);\n\nexport {\n RootAttentionProvider,\n AttentionProvider,\n AttendableContainer,\n useAttentionContext,\n useAttention,\n useAttended,\n useAttendableAttributes,\n useAttentionPath,\n ATTENTION_NAME,\n ATTENABLE_ATTRIBUTE,\n ATTENTION_SOURCE_ATTRIBUTE,\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { untracked } from '@preact/signals-core';\n\nimport { create, type ReactiveObject } from '@dxos/live-object';\n\n/**\n * Manages selection state for different contexts.\n * Each context maintains its own list of selected IDs.\n */\n// TODO(burdon): Review/remove this abstraction. Selection should be managed by specific components.\nexport class SelectionManager {\n private readonly _state = create<{ selections: Record<string, Set<string>> }>({ selections: {} });\n\n constructor(initial: Record<string, Set<string>> = {}) {\n if (Object.keys(initial).length > 0) {\n untracked(() => {\n this._state.selections = initial;\n });\n }\n }\n\n get selections(): ReactiveObject<Record<string, Set<string>>> {\n return this._state.selections;\n }\n\n getSelection(contextId: string): Set<string> {\n if (!this.selections[contextId]) {\n untracked(() => {\n this._state.selections[contextId] = new Set();\n });\n }\n return this.selections[contextId];\n }\n\n updateSelection(contextId: string, selectedIds: Set<string> | string[]) {\n untracked(() => {\n this._state.selections[contextId] = selectedIds instanceof Set ? selectedIds : new Set(selectedIds);\n });\n }\n\n clearSelection(contextId: string) {\n untracked(() => {\n this._state.selections[contextId] = new Set();\n });\n }\n\n toggleSelection(contextId: string, id: string) {\n untracked(() => {\n const current = this.getSelection(contextId);\n if (current.has(id)) {\n current.delete(id);\n } else {\n current.add(id);\n }\n });\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContext } from '@radix-ui/react-context';\nimport React, { useCallback, useMemo, type PropsWithChildren } from 'react';\n\nimport { useDefaultValue } from '@dxos/react-ui';\n\nimport { SelectionManager } from '../selection';\n\nconst SELECTION_NAME = 'Selection';\n\ntype SelectionContextValue = {\n selection: SelectionManager;\n};\n\nconst [SelectionContextProvider, useSelectionContext] = createContext<SelectionContextValue>(SELECTION_NAME, {\n selection: new SelectionManager(),\n});\n\n/**\n * Manages selection state across the app for multiple contexts.\n */\n// TODO(burdon): Review/remove this.\n// TODO(burdon): When is the selection removed?\nexport const SelectionProvider = ({\n children,\n selection: propsSelection,\n}: PropsWithChildren<{ selection?: SelectionManager }>) => {\n const selection = useDefaultValue(propsSelection, () => new SelectionManager());\n return <SelectionContextProvider selection={selection}>{children}</SelectionContextProvider>;\n};\n\nconst emptySet = new Set<string>();\n\n// TODO(burdon): Return array?\nexport const useSelectedItems = (contextId?: string): Set<string> => {\n const { selection } = useSelectionContext(SELECTION_NAME);\n return contextId ? selection.getSelection(contextId) : emptySet;\n};\n\n/**\n * Provides functions to manage the selection state for multiple contexts.\n */\nexport const useSelectionActions = (contextIds: string[]) => {\n const stableContextIds = useMemo(() => contextIds, [JSON.stringify(contextIds)]);\n const { selection } = useSelectionContext(SELECTION_NAME);\n\n const select = useCallback(\n (ids: string[]) => {\n for (const contextId of stableContextIds) {\n selection.updateSelection(contextId, ids);\n }\n },\n [selection, stableContextIds],\n );\n\n const toggle = useCallback(\n (id: string) => {\n for (const contextId of stableContextIds) {\n selection.toggleSelection(contextId, id);\n }\n },\n [selection, stableContextIds],\n );\n\n const clear = useCallback(() => {\n for (const contextId of stableContextIds) {\n selection.clearSelection(contextId);\n }\n }, [selection, stableContextIds]);\n\n return { select, toggle, clear };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["untracked", "S", "create", "ComplexMap", "AttentionSchema", "S", "mutable", "Struct", "hasAttention", "Boolean", "isAncestor", "isRelated", "stringKey", "key", "join", "AttentionManager", "constructor", "initial", "_map", "ComplexMap", "_state", "create", "current", "length", "update", "keys", "Array", "from", "get", "object", "newObject", "set", "nextKey", "currentKey", "untracked", "currentRelatedTo", "nextRelatedTo", "currentRelatedKeys", "filter", "nextRelatedKeys", "prevRelatedKeys", "curr", "find", "next", "currentAncestorKeys", "slice", "map", "_", "i", "nextAncestorKeys", "prevAncestorKeys", "forEach", "_set", "attention", "getAttendables", "selector", "cursor", "acc", "closestAttendable", "closest", "attendableId", "getAttribute", "trigger", "document", "querySelector", "push", "parentElement", "Set", "React", "forwardRef", "useMemo", "Icon", "mx", "attentionGlyphStyles", "presenceIconStyles", "PresenceOne", "svg", "width", "height", "viewBox", "className", "fill", "xmlns", "circle", "cx", "cy", "r", "PresenceMany", "path", "d", "Syncing", "animationProps", "useMemo", "animationDelay", "Date", "now", "div", "role", "Icon", "icon", "size", "style", "classNames", "AttentionGlyph", "forwardRef", "presence", "attended", "syncing", "containsAttended", "props", "forwardedRef", "data-attention", "data-contains-attended", "span", "mx", "ref", "createContext", "Primitive", "Slot", "React", "useMemo", "forwardRef", "useDefaultValue", "mx", "ATTENTION_NAME", "ATTENABLE_ATTRIBUTE", "ATTENTION_SOURCE_ATTRIBUTE", "AttentionContextProvider", "useAttentionContext", "createContext", "attention", "AttentionManager", "path", "UNKNOWN_ATTENDABLE", "hasAttention", "isAncestor", "isRelated", "useAttention", "attendableId", "current", "get", "useAttended", "useAttendableAttributes", "useMemo", "attributes", "useAttentionPath", "RootAttentionProvider", "children", "propsAttention", "onChange", "useDefaultValue", "handleFocus", "event", "selector", "Array", "from", "document", "querySelectorAll", "map", "el", "getAttribute", "join", "prev", "next", "getAttendables", "target", "length", "find", "id", "index", "update", "React", "div", "role", "className", "onFocusCapture", "AttentionProvider", "nextPath", "AttendableContainer", "forwardRef", "classNames", "asChild", "props", "forwardedRef", "attendableAttrs", "Root", "Slot", "Primitive", "mx", "tabIndex", "ref", "untracked", "create", "SelectionManager", "constructor", "initial", "_state", "create", "selections", "Object", "keys", "length", "untracked", "getSelection", "contextId", "Set", "updateSelection", "selectedIds", "clearSelection", "toggleSelection", "id", "current", "has", "delete", "add", "createContext", "React", "useCallback", "useMemo", "useDefaultValue", "SELECTION_NAME", "SelectionContextProvider", "useSelectionContext", "createContext", "selection", "SelectionManager", "SelectionProvider", "children", "propsSelection", "useDefaultValue", "React", "emptySet", "Set", "useSelectedItems", "contextId", "getSelection", "useSelectionActions", "contextIds", "stableContextIds", "useMemo", "JSON", "stringify", "select", "useCallback", "ids", "updateSelection", "toggle", "id", "toggleSelection", "clear", "clearSelection"]
7
7
  }
@@ -8,14 +8,18 @@ import {
8
8
  AttentionProvider,
9
9
  AttentionSchema,
10
10
  RootAttentionProvider,
11
+ SelectionManager,
12
+ SelectionProvider,
11
13
  Syncing,
12
14
  getAttendables,
13
15
  useAttendableAttributes,
14
16
  useAttended,
15
17
  useAttention,
16
18
  useAttentionContext,
17
- useAttentionPath
18
- } from "./chunk-24QUHUNM.mjs";
19
+ useAttentionPath,
20
+ useSelectedItems,
21
+ useSelectionActions
22
+ } from "./chunk-CRGQHPBS.mjs";
19
23
  export {
20
24
  ATTENABLE_ATTRIBUTE,
21
25
  ATTENTION_NAME,
@@ -26,12 +30,16 @@ export {
26
30
  AttentionProvider,
27
31
  AttentionSchema,
28
32
  RootAttentionProvider,
33
+ SelectionManager,
34
+ SelectionProvider,
29
35
  Syncing,
30
36
  getAttendables,
31
37
  useAttendableAttributes,
32
38
  useAttended,
33
39
  useAttention,
34
40
  useAttentionContext,
35
- useAttentionPath
41
+ useAttentionPath,
42
+ useSelectedItems,
43
+ useSelectionActions
36
44
  };
37
45
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"inputs":{"packages/ui/react-ui-attention/src/attention.ts":{"bytes":16177,"imports":[{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/live-object","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-attention/src/components/AttentionGlyph.tsx":{"bytes":10623,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-attention/src/components/AttentionProvider.tsx":{"bytes":16925,"imports":[{"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/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-attention/src/attention.ts","kind":"import-statement","original":"../attention"}],"format":"esm"},"packages/ui/react-ui-attention/src/components/index.ts":{"bytes":644,"imports":[{"path":"packages/ui/react-ui-attention/src/components/AttentionGlyph.tsx","kind":"import-statement","original":"./AttentionGlyph"},{"path":"packages/ui/react-ui-attention/src/components/AttentionProvider.tsx","kind":"import-statement","original":"./AttentionProvider"}],"format":"esm"},"packages/ui/react-ui-attention/src/index.ts":{"bytes":597,"imports":[{"path":"packages/ui/react-ui-attention/src/attention.ts","kind":"import-statement","original":"./attention"},{"path":"packages/ui/react-ui-attention/src/components/index.ts","kind":"import-statement","original":"./components"}],"format":"esm"},"packages/ui/react-ui-attention/src/testing/decorators/withAttention.ts":{"bytes":1386,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-attention/src/components/index.ts","kind":"import-statement","original":"../../components"}],"format":"esm"},"packages/ui/react-ui-attention/src/testing/decorators/index.ts":{"bytes":534,"imports":[{"path":"packages/ui/react-ui-attention/src/testing/decorators/withAttention.ts","kind":"import-statement","original":"./withAttention"}],"format":"esm"},"packages/ui/react-ui-attention/src/testing/index.ts":{"bytes":516,"imports":[{"path":"packages/ui/react-ui-attention/src/testing/decorators/index.ts","kind":"import-statement","original":"./decorators"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-attention/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"packages/ui/react-ui-attention/dist/lib/browser/index.mjs":{"imports":[{"path":"packages/ui/react-ui-attention/dist/lib/browser/chunk-24QUHUNM.mjs","kind":"import-statement"}],"exports":["ATTENABLE_ATTRIBUTE","ATTENTION_NAME","ATTENTION_SOURCE_ATTRIBUTE","AttendableContainer","AttentionGlyph","AttentionManager","AttentionProvider","AttentionSchema","RootAttentionProvider","Syncing","getAttendables","useAttendableAttributes","useAttended","useAttention","useAttentionContext","useAttentionPath"],"entryPoint":"packages/ui/react-ui-attention/src/index.ts","inputs":{"packages/ui/react-ui-attention/src/index.ts":{"bytesInOutput":0}},"bytes":739},"packages/ui/react-ui-attention/dist/lib/browser/testing/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":697},"packages/ui/react-ui-attention/dist/lib/browser/testing/index.mjs":{"imports":[{"path":"packages/ui/react-ui-attention/dist/lib/browser/chunk-24QUHUNM.mjs","kind":"import-statement"},{"path":"react","kind":"import-statement","external":true}],"exports":["withAttention"],"entryPoint":"packages/ui/react-ui-attention/src/testing/index.ts","inputs":{"packages/ui/react-ui-attention/src/testing/decorators/withAttention.ts":{"bytesInOutput":164},"packages/ui/react-ui-attention/src/testing/decorators/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-attention/src/testing/index.ts":{"bytesInOutput":0}},"bytes":367},"packages/ui/react-ui-attention/dist/lib/browser/chunk-24QUHUNM.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":22154},"packages/ui/react-ui-attention/dist/lib/browser/chunk-24QUHUNM.mjs":{"imports":[{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/live-object","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","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/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"exports":["ATTENABLE_ATTRIBUTE","ATTENTION_NAME","ATTENTION_SOURCE_ATTRIBUTE","AttendableContainer","AttentionGlyph","AttentionManager","AttentionProvider","AttentionSchema","RootAttentionProvider","Syncing","getAttendables","useAttendableAttributes","useAttended","useAttention","useAttentionContext","useAttentionPath"],"inputs":{"packages/ui/react-ui-attention/src/attention.ts":{"bytesInOutput":3558},"packages/ui/react-ui-attention/src/components/AttentionGlyph.tsx":{"bytesInOutput":3212},"packages/ui/react-ui-attention/src/components/AttentionProvider.tsx":{"bytesInOutput":3282},"packages/ui/react-ui-attention/src/components/index.ts":{"bytesInOutput":0}},"bytes":10627}}}
1
+ {"inputs":{"packages/ui/react-ui-attention/src/attention.ts":{"bytes":16177,"imports":[{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/live-object","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-attention/src/components/AttentionGlyph.tsx":{"bytes":10623,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-attention/src/components/AttentionProvider.tsx":{"bytes":20134,"imports":[{"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/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-attention/src/attention.ts","kind":"import-statement","original":"../attention"}],"format":"esm"},"packages/ui/react-ui-attention/src/selection.ts":{"bytes":5816,"imports":[{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"@dxos/live-object","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-attention/src/components/SelectionProvider.tsx":{"bytes":7671,"imports":[{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-attention/src/selection.ts","kind":"import-statement","original":"../selection"}],"format":"esm"},"packages/ui/react-ui-attention/src/components/index.ts":{"bytes":757,"imports":[{"path":"packages/ui/react-ui-attention/src/components/AttentionGlyph.tsx","kind":"import-statement","original":"./AttentionGlyph"},{"path":"packages/ui/react-ui-attention/src/components/AttentionProvider.tsx","kind":"import-statement","original":"./AttentionProvider"},{"path":"packages/ui/react-ui-attention/src/components/SelectionProvider.tsx","kind":"import-statement","original":"./SelectionProvider"}],"format":"esm"},"packages/ui/react-ui-attention/src/index.ts":{"bytes":690,"imports":[{"path":"packages/ui/react-ui-attention/src/attention.ts","kind":"import-statement","original":"./attention"},{"path":"packages/ui/react-ui-attention/src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"packages/ui/react-ui-attention/src/selection.ts","kind":"import-statement","original":"./selection"}],"format":"esm"},"packages/ui/react-ui-attention/src/testing/decorators/withAttention.ts":{"bytes":1386,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-attention/src/components/index.ts","kind":"import-statement","original":"../../components"}],"format":"esm"},"packages/ui/react-ui-attention/src/testing/decorators/index.ts":{"bytes":534,"imports":[{"path":"packages/ui/react-ui-attention/src/testing/decorators/withAttention.ts","kind":"import-statement","original":"./withAttention"}],"format":"esm"},"packages/ui/react-ui-attention/src/testing/index.ts":{"bytes":516,"imports":[{"path":"packages/ui/react-ui-attention/src/testing/decorators/index.ts","kind":"import-statement","original":"./decorators"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-attention/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"packages/ui/react-ui-attention/dist/lib/browser/index.mjs":{"imports":[{"path":"packages/ui/react-ui-attention/dist/lib/browser/chunk-CRGQHPBS.mjs","kind":"import-statement"}],"exports":["ATTENABLE_ATTRIBUTE","ATTENTION_NAME","ATTENTION_SOURCE_ATTRIBUTE","AttendableContainer","AttentionGlyph","AttentionManager","AttentionProvider","AttentionSchema","RootAttentionProvider","SelectionManager","SelectionProvider","Syncing","getAttendables","useAttendableAttributes","useAttended","useAttention","useAttentionContext","useAttentionPath","useSelectedItems","useSelectionActions"],"entryPoint":"packages/ui/react-ui-attention/src/index.ts","inputs":{"packages/ui/react-ui-attention/src/index.ts":{"bytesInOutput":0}},"bytes":907},"packages/ui/react-ui-attention/dist/lib/browser/testing/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":697},"packages/ui/react-ui-attention/dist/lib/browser/testing/index.mjs":{"imports":[{"path":"packages/ui/react-ui-attention/dist/lib/browser/chunk-CRGQHPBS.mjs","kind":"import-statement"},{"path":"react","kind":"import-statement","external":true}],"exports":["withAttention"],"entryPoint":"packages/ui/react-ui-attention/src/testing/index.ts","inputs":{"packages/ui/react-ui-attention/src/testing/decorators/withAttention.ts":{"bytesInOutput":164},"packages/ui/react-ui-attention/src/testing/decorators/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-attention/src/testing/index.ts":{"bytesInOutput":0}},"bytes":367},"packages/ui/react-ui-attention/dist/lib/browser/chunk-CRGQHPBS.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30221},"packages/ui/react-ui-attention/dist/lib/browser/chunk-CRGQHPBS.mjs":{"imports":[{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/live-object","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","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/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"@dxos/live-object","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true}],"exports":["ATTENABLE_ATTRIBUTE","ATTENTION_NAME","ATTENTION_SOURCE_ATTRIBUTE","AttendableContainer","AttentionGlyph","AttentionManager","AttentionProvider","AttentionSchema","RootAttentionProvider","SelectionManager","SelectionProvider","Syncing","getAttendables","useAttendableAttributes","useAttended","useAttention","useAttentionContext","useAttentionPath","useSelectedItems","useSelectionActions"],"inputs":{"packages/ui/react-ui-attention/src/attention.ts":{"bytesInOutput":3558},"packages/ui/react-ui-attention/src/components/AttentionGlyph.tsx":{"bytesInOutput":3212},"packages/ui/react-ui-attention/src/components/AttentionProvider.tsx":{"bytesInOutput":3282},"packages/ui/react-ui-attention/src/selection.ts":{"bytesInOutput":1199},"packages/ui/react-ui-attention/src/components/SelectionProvider.tsx":{"bytesInOutput":1662},"packages/ui/react-ui-attention/src/components/index.ts":{"bytesInOutput":0}},"bytes":13696}}}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RootAttentionProvider
3
- } from "../chunk-24QUHUNM.mjs";
3
+ } from "../chunk-CRGQHPBS.mjs";
4
4
 
5
5
  // packages/ui/react-ui-attention/src/testing/decorators/withAttention.ts
6
6
  import { createElement } from "react";
@@ -26,8 +26,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var chunk_QOTK2MG6_exports = {};
30
- __export(chunk_QOTK2MG6_exports, {
29
+ var chunk_P7OLU2DK_exports = {};
30
+ __export(chunk_P7OLU2DK_exports, {
31
31
  ATTENABLE_ATTRIBUTE: () => ATTENABLE_ATTRIBUTE,
32
32
  ATTENTION_NAME: () => ATTENTION_NAME,
33
33
  ATTENTION_SOURCE_ATTRIBUTE: () => ATTENTION_SOURCE_ATTRIBUTE,
@@ -37,15 +37,19 @@ __export(chunk_QOTK2MG6_exports, {
37
37
  AttentionProvider: () => AttentionProvider,
38
38
  AttentionSchema: () => AttentionSchema,
39
39
  RootAttentionProvider: () => RootAttentionProvider,
40
+ SelectionManager: () => SelectionManager,
41
+ SelectionProvider: () => SelectionProvider,
40
42
  Syncing: () => Syncing,
41
43
  getAttendables: () => getAttendables,
42
44
  useAttendableAttributes: () => useAttendableAttributes,
43
45
  useAttended: () => useAttended,
44
46
  useAttention: () => useAttention,
45
47
  useAttentionContext: () => useAttentionContext,
46
- useAttentionPath: () => useAttentionPath
48
+ useAttentionPath: () => useAttentionPath,
49
+ useSelectedItems: () => useSelectedItems,
50
+ useSelectionActions: () => useSelectionActions
47
51
  });
48
- module.exports = __toCommonJS(chunk_QOTK2MG6_exports);
52
+ module.exports = __toCommonJS(chunk_P7OLU2DK_exports);
49
53
  var import_signals_core = require("@preact/signals-core");
50
54
  var import_echo_schema = require("@dxos/echo-schema");
51
55
  var import_live_object = require("@dxos/live-object");
@@ -59,6 +63,11 @@ var import_react_slot = require("@radix-ui/react-slot");
59
63
  var import_react2 = __toESM(require("react"));
60
64
  var import_react_ui2 = require("@dxos/react-ui");
61
65
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
66
+ var import_signals_core2 = require("@preact/signals-core");
67
+ var import_live_object2 = require("@dxos/live-object");
68
+ var import_react_context2 = require("@radix-ui/react-context");
69
+ var import_react3 = __toESM(require("react"));
70
+ var import_react_ui3 = require("@dxos/react-ui");
62
71
  var AttentionSchema = import_echo_schema.S.mutable(import_echo_schema.S.Struct({
63
72
  hasAttention: import_echo_schema.S.Boolean,
64
73
  isAncestor: import_echo_schema.S.Boolean,
@@ -317,10 +326,103 @@ var AttendableContainer = /* @__PURE__ */ (0, import_react2.forwardRef)(({ id, c
317
326
  role: "none",
318
327
  ...attendableAttrs,
319
328
  ...props,
320
- className: (0, import_react_ui_theme2.mx)("attention-surface", props.tabIndex === 0 && "ch-focus-ring-inset-over-all", classNames),
329
+ className: (0, import_react_ui_theme2.mx)("attention-surface", props.tabIndex === 0 && "dx-focus-ring-inset-over-all", classNames),
321
330
  ref: forwardedRef
322
331
  }, children);
323
332
  });
333
+ var SelectionManager = class {
334
+ constructor(initial = {}) {
335
+ this._state = (0, import_live_object2.create)({
336
+ selections: {}
337
+ });
338
+ if (Object.keys(initial).length > 0) {
339
+ (0, import_signals_core2.untracked)(() => {
340
+ this._state.selections = initial;
341
+ });
342
+ }
343
+ }
344
+ get selections() {
345
+ return this._state.selections;
346
+ }
347
+ getSelection(contextId) {
348
+ if (!this.selections[contextId]) {
349
+ (0, import_signals_core2.untracked)(() => {
350
+ this._state.selections[contextId] = /* @__PURE__ */ new Set();
351
+ });
352
+ }
353
+ return this.selections[contextId];
354
+ }
355
+ updateSelection(contextId, selectedIds) {
356
+ (0, import_signals_core2.untracked)(() => {
357
+ this._state.selections[contextId] = selectedIds instanceof Set ? selectedIds : new Set(selectedIds);
358
+ });
359
+ }
360
+ clearSelection(contextId) {
361
+ (0, import_signals_core2.untracked)(() => {
362
+ this._state.selections[contextId] = /* @__PURE__ */ new Set();
363
+ });
364
+ }
365
+ toggleSelection(contextId, id) {
366
+ (0, import_signals_core2.untracked)(() => {
367
+ const current = this.getSelection(contextId);
368
+ if (current.has(id)) {
369
+ current.delete(id);
370
+ } else {
371
+ current.add(id);
372
+ }
373
+ });
374
+ }
375
+ };
376
+ var SELECTION_NAME = "Selection";
377
+ var [SelectionContextProvider, useSelectionContext] = (0, import_react_context2.createContext)(SELECTION_NAME, {
378
+ selection: new SelectionManager()
379
+ });
380
+ var SelectionProvider = ({ children, selection: propsSelection }) => {
381
+ const selection = (0, import_react_ui3.useDefaultValue)(propsSelection, () => new SelectionManager());
382
+ return /* @__PURE__ */ import_react3.default.createElement(SelectionContextProvider, {
383
+ selection
384
+ }, children);
385
+ };
386
+ var emptySet = /* @__PURE__ */ new Set();
387
+ var useSelectedItems = (contextId) => {
388
+ const { selection } = useSelectionContext(SELECTION_NAME);
389
+ return contextId ? selection.getSelection(contextId) : emptySet;
390
+ };
391
+ var useSelectionActions = (contextIds) => {
392
+ const stableContextIds = (0, import_react3.useMemo)(() => contextIds, [
393
+ JSON.stringify(contextIds)
394
+ ]);
395
+ const { selection } = useSelectionContext(SELECTION_NAME);
396
+ const select = (0, import_react3.useCallback)((ids) => {
397
+ for (const contextId of stableContextIds) {
398
+ selection.updateSelection(contextId, ids);
399
+ }
400
+ }, [
401
+ selection,
402
+ stableContextIds
403
+ ]);
404
+ const toggle = (0, import_react3.useCallback)((id) => {
405
+ for (const contextId of stableContextIds) {
406
+ selection.toggleSelection(contextId, id);
407
+ }
408
+ }, [
409
+ selection,
410
+ stableContextIds
411
+ ]);
412
+ const clear = (0, import_react3.useCallback)(() => {
413
+ for (const contextId of stableContextIds) {
414
+ selection.clearSelection(contextId);
415
+ }
416
+ }, [
417
+ selection,
418
+ stableContextIds
419
+ ]);
420
+ return {
421
+ select,
422
+ toggle,
423
+ clear
424
+ };
425
+ };
324
426
  // Annotate the CommonJS export names for ESM import in node:
325
427
  0 && (module.exports = {
326
428
  ATTENABLE_ATTRIBUTE,
@@ -332,12 +434,16 @@ var AttendableContainer = /* @__PURE__ */ (0, import_react2.forwardRef)(({ id, c
332
434
  AttentionProvider,
333
435
  AttentionSchema,
334
436
  RootAttentionProvider,
437
+ SelectionManager,
438
+ SelectionProvider,
335
439
  Syncing,
336
440
  getAttendables,
337
441
  useAttendableAttributes,
338
442
  useAttended,
339
443
  useAttention,
340
444
  useAttentionContext,
341
- useAttentionPath
445
+ useAttentionPath,
446
+ useSelectedItems,
447
+ useSelectionActions
342
448
  });
343
- //# sourceMappingURL=chunk-QOTK2MG6.cjs.map
449
+ //# sourceMappingURL=chunk-P7OLU2DK.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/attention.ts", "../../../src/components/AttentionGlyph.tsx", "../../../src/components/AttentionProvider.tsx", "../../../src/selection.ts", "../../../src/components/SelectionProvider.tsx"],
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { untracked } from '@preact/signals-core';\n\nimport { S } from '@dxos/echo-schema';\nimport { create, type ReactiveObject } from '@dxos/live-object';\nimport { ComplexMap } from '@dxos/util';\n\nexport const AttentionSchema = S.mutable(\n S.Struct({\n hasAttention: S.Boolean,\n isAncestor: S.Boolean,\n isRelated: S.Boolean,\n }),\n);\n\nexport type Attention = S.Schema.Type<typeof AttentionSchema>;\n\n// TODO(wittjosiah): Use mosaic path utility?\nconst stringKey = (key: string[]) => key.join(',');\n\n/**\n * Manages attention state for an application.\n */\n// TODO(wittjosiah): Write unit tests.\nexport class AttentionManager {\n // Each attention path is associated with an attention object.\n // The lookup is not a reactive object to ensure that attention for each path is subscribable independently.\n private readonly _map = new ComplexMap<string[], ReactiveObject<Attention>>(stringKey);\n private readonly _state = create<{ current: string[] }>({ current: [] });\n\n constructor(initial: string[] = []) {\n if (initial.length > 0) {\n this.update(initial);\n }\n }\n\n /**\n * Currently attended element.\n *\n * @reactive\n */\n get current(): ReactiveObject<readonly string[]> {\n return this._state.current;\n }\n\n /**\n * All attention paths.\n */\n keys(): string[][] {\n return Array.from(this._map.keys());\n }\n\n /**\n * Get the attention state for a given path.\n */\n get(key: string[]): ReactiveObject<Attention> {\n const object = this._map.get(key);\n if (object) {\n return object;\n }\n\n const newObject = create(AttentionSchema, { hasAttention: false, isAncestor: false, isRelated: false });\n this._map.set(key, newObject);\n return newObject;\n }\n\n /**\n * Update the currently attended element.\n *\n * @internal\n */\n update(nextKey: string[]) {\n const currentKey = untracked(() => this.current);\n const currentRelatedTo = currentKey[0];\n const nextRelatedTo = nextKey[0];\n\n // Ensure related attention object is initialized.\n this.get([nextRelatedTo]);\n\n const currentRelatedKeys = this.keys().filter((key) => key[0] === currentRelatedTo);\n const nextRelatedKeys = this.keys().filter(\n (key) => key[0] === nextRelatedTo && stringKey(key) !== stringKey(nextKey),\n );\n const prevRelatedKeys = currentRelatedKeys.filter(\n (curr) => !nextRelatedKeys.find((next) => stringKey(curr) === stringKey(next)),\n );\n\n const currentAncestorKeys = currentKey.slice(1).map((_, i) => currentKey.slice(i + 1, currentKey.length));\n const nextAncestorKeys = nextKey.slice(1).map((_, i) => nextKey.slice(i + 1, nextKey.length));\n const prevAncestorKeys = currentAncestorKeys.filter(\n (curr) => !nextAncestorKeys.find((next) => stringKey(curr) === stringKey(next)),\n );\n\n this._state.current = nextKey;\n prevRelatedKeys.forEach((key) => this._set(key, {}));\n prevAncestorKeys.forEach((key) => this._set(key, {}));\n nextRelatedKeys.forEach((key) => this._set(key, { isRelated: true }));\n nextAncestorKeys.forEach((key) => this._set(key, { isAncestor: true }));\n this._set(nextKey, { hasAttention: true });\n }\n\n private _set(key: string[], attention: Partial<Attention>) {\n const object = this.get(key);\n object.hasAttention = attention.hasAttention ?? false;\n object.isAncestor = attention.isAncestor ?? false;\n object.isRelated = attention.isRelated ?? false;\n }\n}\n\n/**\n * Accumulates all attendable id’s between the element provided and the root, inclusive.\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 // (attempt tail recursion)\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// Copyright 2024 DXOS.org\n//\n\nimport { type Primitive } from '@radix-ui/react-primitive';\nimport React, { type ComponentPropsWithRef, type CSSProperties, forwardRef, useMemo } from 'react';\n\nimport { Icon, type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nconst attentionGlyphStyles =\n 'inline-block rounded-sm is-3 bs-3 bg-transparent text-accentText transition-colors [[data-contains-attended=true]_&]:bg-attentionRelated [[data-attention=true]_&]:bg-accentSurface [[data-attention=true]_&]:text-inverse [[aria-current][data-attention=true]_&]:bg-accentSurface [[aria-current][data-attention=true]_&]:text-inverse';\n\nconst presenceIconStyles =\n 'is-3 bs-3 group-[[aria-current]_&:hover]/attentionGlyphButton:hidden group-[[aria-current]_&:focus]/attentionGlyphButton:hidden group-[[data-attention=true]_&:hover]/attentionGlyphButton:hidden group-[[data-attention=true]_&:focus]/attentionGlyphButton:hidden group-[[aria-current][data-attention=true]_&:hover]/attentionGlyphButton:hidden group-[[aria-current][data-attention=true]_&:focus]/attentionGlyphButton:hidden';\n\nconst PresenceOne = () => {\n return (\n <svg\n width='12'\n height='12'\n viewBox='0 0 12 12'\n className={presenceIconStyles}\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <circle cx='6' cy='6' r='2.5' fill='currentColor' />\n </svg>\n );\n};\n\nconst PresenceMany = () => {\n return (\n <svg\n width='12'\n height='12'\n viewBox='0 0 12 12'\n className={presenceIconStyles}\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M6.75 8.27311C7.38815 7.72296 7.79212 6.90866 7.79212 6C7.79212 5.09134 7.38815 4.27704 6.75 3.72689C7.06722 3.58122 7.42019 3.5 7.79212 3.5C9.17283 3.5 10.2921 4.61929 10.2921 6C10.2921 7.38071 9.17283 8.5 7.79212 8.5C7.42019 8.5 7.06723 8.41878 6.75 8.27311Z'\n fill='currentColor'\n />\n <circle cx='4.25' cy='6' r='2.5' fill='currentColor' />\n </svg>\n );\n};\n\nexport const Syncing = () => {\n const animationProps = useMemo<CSSProperties>(\n () => ({\n // Synchronize animations.\n animationDelay: `-${Date.now() % 2_000}ms`,\n }),\n [],\n );\n\n return (\n <div role='status' className='flex items-center'>\n <Icon\n icon='ph--circle-notch--regular'\n size={3}\n style={animationProps}\n classNames='text-subdued animate-[spin_2s_linear_infinite]'\n />\n </div>\n );\n};\n\nexport type AttentionGlyphProps = {\n attended?: boolean;\n containsAttended?: boolean;\n syncing?: boolean;\n presence?: 'none' | 'one' | 'many';\n} & ThemedClassName<Omit<ComponentPropsWithRef<typeof Primitive.span>, 'children'>>;\n\nexport const AttentionGlyph = forwardRef<HTMLSpanElement, AttentionGlyphProps>(\n ({ presence, attended, syncing, containsAttended, classNames, ...props }, forwardedRef) => {\n const icon = syncing ? (\n <Syncing />\n ) : presence === 'many' ? (\n <PresenceMany />\n ) : presence === 'one' ? (\n <PresenceOne />\n ) : null;\n\n return (\n <div role='none' className='flex' data-attention={attended} data-contains-attended={containsAttended}>\n <span role='none' {...props} className={mx(attentionGlyphStyles, classNames)} ref={forwardedRef}>\n {icon}\n </span>\n </div>\n );\n },\n);\n", "//\n// Copyright 2024 DXOS.org\n//\n\n// NOTE(thure): The following unused imports quell TS2742 (“likely not portable”).\n\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport { createContext, type Scope, type CreateScope } from '@radix-ui/react-context';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { Slot } from '@radix-ui/react-slot';\nimport React, { useMemo, type FocusEvent, type PropsWithChildren, type ComponentPropsWithRef, forwardRef } from 'react';\n\nimport { useDefaultValue, type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { type Attention, AttentionManager, getAttendables } from '../attention';\n\nconst ATTENTION_NAME = 'Attention';\nconst ATTENABLE_ATTRIBUTE = 'data-attendable-id';\nconst ATTENTION_SOURCE_ATTRIBUTE = 'data-is-attention-source';\n\ntype AttentionContextValue = {\n attention: AttentionManager;\n path: string[];\n};\n\nconst [AttentionContextProvider, useAttentionContext] = createContext<AttentionContextValue>(ATTENTION_NAME, {\n attention: new AttentionManager(),\n path: [],\n});\n\nconst UNKNOWN_ATTENDABLE = { hasAttention: false, isAncestor: false, isRelated: false };\n\nconst useAttention = (attendableId?: string): Attention => {\n const { attention, path } = useAttentionContext(ATTENTION_NAME);\n if (!attendableId) {\n return UNKNOWN_ATTENDABLE;\n }\n\n const current = [attendableId, ...path];\n return attention.get(current);\n};\n\nconst useAttended = () => {\n const { attention } = useAttentionContext(ATTENTION_NAME);\n return attention.current;\n};\n\n/**\n * Computes HTML element attributes to apply so the attention system can detect changes\n * @param attendableId\n */\nconst useAttendableAttributes = (attendableId?: string) => {\n const { hasAttention } = useAttention(attendableId);\n return useMemo(() => {\n const attributes: Record<string, string | undefined> = { [ATTENABLE_ATTRIBUTE]: attendableId };\n if (hasAttention) {\n attributes[ATTENTION_SOURCE_ATTRIBUTE] = 'true';\n }\n\n return attributes;\n }, [attendableId, hasAttention]);\n};\n\nconst useAttentionPath = () => {\n const { path } = useAttentionContext(ATTENTION_NAME);\n return path;\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 attention = useDefaultValue(propsAttention, () => new AttentionManager());\n const handleFocus = (event: FocusEvent) => {\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.current;\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 // NOTE(thure): Use the following to debug the macOS package issue #8540\n\n // const [startEl, setStartEl] = useState<HTMLElement | null>(null);\n // const [endEl, setEndEl] = useState<HTMLElement | null>(null);\n //\n // const handleEventDebug = useCallback((event: any) => {\n // console.log(`[${event.type}]`, event.target, event.currentTarget, [event.clientX, event.clientY]);\n // }, []);\n //\n // const handleStartDebug = useCallback(\n // (event: any) => {\n // setStartEl(event.target);\n // handleEventDebug(event);\n // },\n // [handleEventDebug],\n // );\n //\n // const handleEndDebug = useCallback(\n // (event: any) => {\n // setEndEl(event.target);\n // handleEventDebug(event);\n // },\n // [handleEventDebug],\n // );\n //\n // const handleClickDebug = useCallback(\n // (event: any) => {\n // console.log('[click compare]', startEl, endEl, startEl === endEl);\n // handleEventDebug(event);\n // },\n // [startEl, endEl, handleEventDebug],\n // );\n\n return (\n <AttentionContextProvider attention={attention} path={[]}>\n <div\n role='none'\n className='contents'\n onFocusCapture={handleFocus}\n // onClick={handleClickDebug}\n // onMouseDown={handleStartDebug}\n // onMouseUp={handleEndDebug}\n >\n {children}\n </div>\n </AttentionContextProvider>\n );\n};\n\nconst AttentionProvider = ({ id, children }: PropsWithChildren<{ id: string }>) => {\n const { attention, path } = useAttentionContext(ATTENTION_NAME);\n const nextPath = useMemo(() => [id, ...path], [id, path]);\n\n return (\n <AttentionContextProvider attention={attention} path={nextPath}>\n {children}\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, and when rendering content in those cases it\n * is not necessary to also render an `AttendableContainer`. This component is primarily for Storybook stories and other\n * testing scenarios, 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 attendableAttrs = useAttendableAttributes(id);\n const Root = asChild ? Slot : Primitive.div;\n return (\n <Root\n role='none'\n {...attendableAttrs}\n {...props}\n className={mx('attention-surface', props.tabIndex === 0 && 'dx-focus-ring-inset-over-all', classNames)}\n ref={forwardedRef}\n >\n {children}\n </Root>\n );\n },\n);\n\nexport {\n RootAttentionProvider,\n AttentionProvider,\n AttendableContainer,\n useAttentionContext,\n useAttention,\n useAttended,\n useAttendableAttributes,\n useAttentionPath,\n ATTENTION_NAME,\n ATTENABLE_ATTRIBUTE,\n ATTENTION_SOURCE_ATTRIBUTE,\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { untracked } from '@preact/signals-core';\n\nimport { create, type ReactiveObject } from '@dxos/live-object';\n\n/**\n * Manages selection state for different contexts.\n * Each context maintains its own list of selected IDs.\n */\n// TODO(burdon): Review/remove this abstraction. Selection should be managed by specific components.\nexport class SelectionManager {\n private readonly _state = create<{ selections: Record<string, Set<string>> }>({ selections: {} });\n\n constructor(initial: Record<string, Set<string>> = {}) {\n if (Object.keys(initial).length > 0) {\n untracked(() => {\n this._state.selections = initial;\n });\n }\n }\n\n get selections(): ReactiveObject<Record<string, Set<string>>> {\n return this._state.selections;\n }\n\n getSelection(contextId: string): Set<string> {\n if (!this.selections[contextId]) {\n untracked(() => {\n this._state.selections[contextId] = new Set();\n });\n }\n return this.selections[contextId];\n }\n\n updateSelection(contextId: string, selectedIds: Set<string> | string[]) {\n untracked(() => {\n this._state.selections[contextId] = selectedIds instanceof Set ? selectedIds : new Set(selectedIds);\n });\n }\n\n clearSelection(contextId: string) {\n untracked(() => {\n this._state.selections[contextId] = new Set();\n });\n }\n\n toggleSelection(contextId: string, id: string) {\n untracked(() => {\n const current = this.getSelection(contextId);\n if (current.has(id)) {\n current.delete(id);\n } else {\n current.add(id);\n }\n });\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContext } from '@radix-ui/react-context';\nimport React, { useCallback, useMemo, type PropsWithChildren } from 'react';\n\nimport { useDefaultValue } from '@dxos/react-ui';\n\nimport { SelectionManager } from '../selection';\n\nconst SELECTION_NAME = 'Selection';\n\ntype SelectionContextValue = {\n selection: SelectionManager;\n};\n\nconst [SelectionContextProvider, useSelectionContext] = createContext<SelectionContextValue>(SELECTION_NAME, {\n selection: new SelectionManager(),\n});\n\n/**\n * Manages selection state across the app for multiple contexts.\n */\n// TODO(burdon): Review/remove this.\n// TODO(burdon): When is the selection removed?\nexport const SelectionProvider = ({\n children,\n selection: propsSelection,\n}: PropsWithChildren<{ selection?: SelectionManager }>) => {\n const selection = useDefaultValue(propsSelection, () => new SelectionManager());\n return <SelectionContextProvider selection={selection}>{children}</SelectionContextProvider>;\n};\n\nconst emptySet = new Set<string>();\n\n// TODO(burdon): Return array?\nexport const useSelectedItems = (contextId?: string): Set<string> => {\n const { selection } = useSelectionContext(SELECTION_NAME);\n return contextId ? selection.getSelection(contextId) : emptySet;\n};\n\n/**\n * Provides functions to manage the selection state for multiple contexts.\n */\nexport const useSelectionActions = (contextIds: string[]) => {\n const stableContextIds = useMemo(() => contextIds, [JSON.stringify(contextIds)]);\n const { selection } = useSelectionContext(SELECTION_NAME);\n\n const select = useCallback(\n (ids: string[]) => {\n for (const contextId of stableContextIds) {\n selection.updateSelection(contextId, ids);\n }\n },\n [selection, stableContextIds],\n );\n\n const toggle = useCallback(\n (id: string) => {\n for (const contextId of stableContextIds) {\n selection.toggleSelection(contextId, id);\n }\n },\n [selection, stableContextIds],\n );\n\n const clear = useCallback(() => {\n for (const contextId of stableContextIds) {\n selection.clearSelection(contextId);\n }\n }, [selection, stableContextIds]);\n\n return { select, toggle, clear };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["import_react", "import_react_ui", "import_react_ui_theme", "import_signals_core", "import_live_object", "import_react_context", "AttentionSchema", "S", "mutable", "Struct", "hasAttention", "Boolean", "isAncestor", "isRelated", "stringKey", "key", "join", "AttentionManager", "constructor", "initial", "ComplexMap", "_state", "create", "current", "length", "update", "keys", "Array", "from", "_map", "get", "object", "newObject", "set", "nextKey", "currentKey", "untracked", "currentRelatedTo", "nextRelatedTo", "currentRelatedKeys", "filter", "nextRelatedKeys", "prevRelatedKeys", "curr", "find", "next", "currentAncestorKeys", "slice", "map", "_", "i", "nextAncestorKeys", "prevAncestorKeys", "forEach", "_set", "attention", "getAttendables", "selector", "cursor", "acc", "closestAttendable", "closest", "attendableId", "getAttribute", "trigger", "document", "querySelector", "push", "parentElement", "Set", "attentionGlyphStyles", "presenceIconStyles", "PresenceOne", "React", "svg", "width", "height", "viewBox", "className", "fill", "xmlns", "circle", "cx", "cy", "r", "PresenceMany", "path", "d", "Syncing", "animationProps", "useMemo", "animationDelay", "Date", "now", "div", "role", "Icon", "icon", "size", "style", "classNames", "AttentionGlyph", "forwardRef", "presence", "attended", "syncing", "containsAttended", "props", "forwardedRef", "data-attention", "data-contains-attended", "span", "mx", "ref", "ATTENTION_NAME", "ATTENABLE_ATTRIBUTE", "ATTENTION_SOURCE_ATTRIBUTE", "AttentionContextProvider", "useAttentionContext", "createContext", "UNKNOWN_ATTENDABLE", "useAttention", "useAttended", "useAttendableAttributes", "attributes", "useAttentionPath", "RootAttentionProvider", "children", "propsAttention", "onChange", "useDefaultValue", "handleFocus", "event", "querySelectorAll", "el", "prev", "target", "id", "index", "onFocusCapture", "AttentionProvider", "nextPath", "AttendableContainer", "asChild", "attendableAttrs", "Root", "Slot", "Primitive", "tabIndex", "SelectionManager", "selections", "Object", "getSelection", "contextId", "updateSelection", "selectedIds", "clearSelection", "toggleSelection", "has", "delete", "add", "SELECTION_NAME", "SelectionContextProvider", "useSelectionContext", "selection", "SelectionProvider", "propsSelection", "emptySet", "useSelectedItems", "useSelectionActions", "contextIds", "stableContextIds", "JSON", "stringify", "select", "useCallback", "ids", "toggle", "clear"]
7
+ }