@dxos/react-ui-attention 0.8.3 → 0.8.4-main.f9ba587
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.
- package/dist/lib/browser/{chunk-PL2OIVDU.mjs → chunk-QPEFFJ4E.mjs} +7 -7
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +2 -2
- package/dist/lib/node-esm/{chunk-FJBSBKQ5.mjs → chunk-F2JRKDYV.mjs} +7 -7
- package/dist/lib/node-esm/index.mjs +1 -1
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +2 -2
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -15
- package/dist/lib/node/chunk-UHRK5BJW.cjs +0 -661
- package/dist/lib/node/chunk-UHRK5BJW.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -75
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/testing/index.cjs +0 -35
- package/dist/lib/node/testing/index.cjs.map +0 -7
- /package/dist/lib/browser/{chunk-PL2OIVDU.mjs.map → chunk-QPEFFJ4E.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-FJBSBKQ5.mjs.map → chunk-F2JRKDYV.mjs.map} +0 -0
|
@@ -1,661 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
var chunk_UHRK5BJW_exports = {};
|
|
30
|
-
__export(chunk_UHRK5BJW_exports, {
|
|
31
|
-
ATTENABLE_ATTRIBUTE: () => ATTENABLE_ATTRIBUTE,
|
|
32
|
-
ATTENDABLE_PATH_SEPARATOR: () => ATTENDABLE_PATH_SEPARATOR,
|
|
33
|
-
ATTENTION_NAME: () => ATTENTION_NAME,
|
|
34
|
-
ATTENTION_SOURCE_ATTRIBUTE: () => ATTENTION_SOURCE_ATTRIBUTE,
|
|
35
|
-
AttendableContainer: () => AttendableContainer,
|
|
36
|
-
AttentionGlyph: () => AttentionGlyph,
|
|
37
|
-
AttentionManager: () => AttentionManager,
|
|
38
|
-
AttentionProvider: () => AttentionProvider,
|
|
39
|
-
AttentionSchema: () => AttentionSchema,
|
|
40
|
-
RootAttentionProvider: () => RootAttentionProvider,
|
|
41
|
-
SelectionManager: () => SelectionManager,
|
|
42
|
-
SelectionProvider: () => SelectionProvider,
|
|
43
|
-
Syncing: () => Syncing,
|
|
44
|
-
defaultSelection: () => defaultSelection,
|
|
45
|
-
getAttendables: () => getAttendables,
|
|
46
|
-
getSelectionSet: () => getSelectionSet,
|
|
47
|
-
useAttended: () => useAttended,
|
|
48
|
-
useAttention: () => useAttention,
|
|
49
|
-
useAttentionAttributes: () => useAttentionAttributes,
|
|
50
|
-
useAttentionContext: () => useAttentionContext,
|
|
51
|
-
useAttentionPath: () => useAttentionPath,
|
|
52
|
-
useSelected: () => useSelected,
|
|
53
|
-
useSelectionActions: () => useSelectionActions,
|
|
54
|
-
useSelectionManager: () => useSelectionManager
|
|
55
|
-
});
|
|
56
|
-
module.exports = __toCommonJS(chunk_UHRK5BJW_exports);
|
|
57
|
-
var import_signals_core = require("@preact/signals-core");
|
|
58
|
-
var import_effect = require("effect");
|
|
59
|
-
var import_live_object = require("@dxos/live-object");
|
|
60
|
-
var import_util = require("@dxos/util");
|
|
61
|
-
var import_tracking = require("@preact-signals/safe-react/tracking");
|
|
62
|
-
var import_react = __toESM(require("react"));
|
|
63
|
-
var import_react_ui = require("@dxos/react-ui");
|
|
64
|
-
var import_react_ui_theme = require("@dxos/react-ui-theme");
|
|
65
|
-
var import_tracking2 = require("@preact-signals/safe-react/tracking");
|
|
66
|
-
var import_react_context = require("@radix-ui/react-context");
|
|
67
|
-
var import_react_primitive = require("@radix-ui/react-primitive");
|
|
68
|
-
var import_react_slot = require("@radix-ui/react-slot");
|
|
69
|
-
var import_react2 = __toESM(require("react"));
|
|
70
|
-
var import_react_ui2 = require("@dxos/react-ui");
|
|
71
|
-
var import_react_ui_theme2 = require("@dxos/react-ui-theme");
|
|
72
|
-
var import_signals_core2 = require("@preact/signals-core");
|
|
73
|
-
var import_effect2 = require("effect");
|
|
74
|
-
var import_invariant = require("@dxos/invariant");
|
|
75
|
-
var import_live_object2 = require("@dxos/live-object");
|
|
76
|
-
var import_tracking3 = require("@preact-signals/safe-react/tracking");
|
|
77
|
-
var import_react_context2 = require("@radix-ui/react-context");
|
|
78
|
-
var import_effect3 = require("effect");
|
|
79
|
-
var import_react3 = __toESM(require("react"));
|
|
80
|
-
var import_react_ui3 = require("@dxos/react-ui");
|
|
81
|
-
var ATTENDABLE_PATH_SEPARATOR = "~";
|
|
82
|
-
var AttentionSchema = import_effect.Schema.mutable(import_effect.Schema.Struct({
|
|
83
|
-
hasAttention: import_effect.Schema.Boolean,
|
|
84
|
-
isAncestor: import_effect.Schema.Boolean,
|
|
85
|
-
isRelated: import_effect.Schema.Boolean
|
|
86
|
-
}));
|
|
87
|
-
var stringKey = (key) => key.join(",");
|
|
88
|
-
var AttentionManager = class {
|
|
89
|
-
constructor(initial = []) {
|
|
90
|
-
this._map = new import_util.ComplexMap(stringKey);
|
|
91
|
-
this._state = (0, import_live_object.live)({
|
|
92
|
-
current: []
|
|
93
|
-
});
|
|
94
|
-
if (initial.length > 0) {
|
|
95
|
-
this.update(initial);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Currently attended element.
|
|
100
|
-
*
|
|
101
|
-
* @reactive
|
|
102
|
-
*/
|
|
103
|
-
get current() {
|
|
104
|
-
return this._state.current;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* All attention paths.
|
|
108
|
-
*/
|
|
109
|
-
keys() {
|
|
110
|
-
return Array.from(this._map.keys());
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Get the attention state for a given path.
|
|
114
|
-
*/
|
|
115
|
-
get(key) {
|
|
116
|
-
const object = this._map.get(key);
|
|
117
|
-
if (object) {
|
|
118
|
-
return object;
|
|
119
|
-
}
|
|
120
|
-
const newObject = (0, import_live_object.live)(AttentionSchema, {
|
|
121
|
-
hasAttention: false,
|
|
122
|
-
isAncestor: false,
|
|
123
|
-
isRelated: false
|
|
124
|
-
});
|
|
125
|
-
this._map.set(key, newObject);
|
|
126
|
-
return newObject;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Update the currently attended element.
|
|
130
|
-
*
|
|
131
|
-
* @internal
|
|
132
|
-
*/
|
|
133
|
-
update(nextKey) {
|
|
134
|
-
const currentKey = (0, import_signals_core.untracked)(() => this.current);
|
|
135
|
-
const currentRelatedTo = currentKey[0];
|
|
136
|
-
const nextRelatedTo = nextKey[0];
|
|
137
|
-
this.get([
|
|
138
|
-
nextRelatedTo
|
|
139
|
-
]);
|
|
140
|
-
const currentRelatedKeys = this.keys().filter((key) => key[0] === currentRelatedTo);
|
|
141
|
-
const nextRelatedKeys = this.keys().filter((key) => key[0] === nextRelatedTo && stringKey(key) !== stringKey(nextKey));
|
|
142
|
-
const prevRelatedKeys = currentRelatedKeys.filter((curr) => !nextRelatedKeys.find((next) => stringKey(curr) === stringKey(next)));
|
|
143
|
-
const currentAncestorKeys = currentKey.slice(1).map((_, i) => currentKey.slice(i + 1, currentKey.length));
|
|
144
|
-
const nextAncestorKeys = nextKey.slice(1).map((_, i) => nextKey.slice(i + 1, nextKey.length));
|
|
145
|
-
const prevAncestorKeys = currentAncestorKeys.filter((curr) => !nextAncestorKeys.find((next) => stringKey(curr) === stringKey(next)));
|
|
146
|
-
this._state.current = nextKey;
|
|
147
|
-
prevRelatedKeys.forEach((key) => this._set(key, {}));
|
|
148
|
-
prevAncestorKeys.forEach((key) => this._set(key, {}));
|
|
149
|
-
nextRelatedKeys.forEach((key) => this._set(key, {
|
|
150
|
-
isRelated: true
|
|
151
|
-
}));
|
|
152
|
-
nextAncestorKeys.forEach((key) => this._set(key, {
|
|
153
|
-
isAncestor: true
|
|
154
|
-
}));
|
|
155
|
-
this._set(nextKey, {
|
|
156
|
-
hasAttention: true
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
_set(key, attention) {
|
|
160
|
-
const object = this.get(key);
|
|
161
|
-
object.hasAttention = attention.hasAttention ?? false;
|
|
162
|
-
object.isAncestor = attention.isAncestor ?? false;
|
|
163
|
-
object.isRelated = attention.isRelated ?? false;
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
var getAttendables = (selector, cursor, acc = []) => {
|
|
167
|
-
const closestAttendable = cursor.closest(selector);
|
|
168
|
-
if (closestAttendable) {
|
|
169
|
-
const attendableId = closestAttendable.getAttribute("data-attendable-id");
|
|
170
|
-
if (!attendableId) {
|
|
171
|
-
const trigger = document.querySelector(`[aria-controls="${closestAttendable.getAttribute("id")}"]`);
|
|
172
|
-
if (!trigger) {
|
|
173
|
-
return acc;
|
|
174
|
-
} else {
|
|
175
|
-
return getAttendables(selector, trigger, acc);
|
|
176
|
-
}
|
|
177
|
-
} else {
|
|
178
|
-
acc.push(...attendableId.split(ATTENDABLE_PATH_SEPARATOR));
|
|
179
|
-
return !closestAttendable.parentElement ? acc : getAttendables(selector, closestAttendable.parentElement, acc);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return [
|
|
183
|
-
...new Set(acc)
|
|
184
|
-
];
|
|
185
|
-
};
|
|
186
|
-
var attentionGlyphStyles = "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-accentSurfaceText [[aria-current][data-attention=true]_&]:bg-accentSurface [[aria-current][data-attention=true]_&]:text-accentSurfaceText";
|
|
187
|
-
var presenceIconStyles = "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";
|
|
188
|
-
var PresenceOne = () => {
|
|
189
|
-
var _effect = (0, import_tracking.useSignals)();
|
|
190
|
-
try {
|
|
191
|
-
return /* @__PURE__ */ import_react.default.createElement("svg", {
|
|
192
|
-
width: "12",
|
|
193
|
-
height: "12",
|
|
194
|
-
viewBox: "0 0 12 12",
|
|
195
|
-
className: presenceIconStyles,
|
|
196
|
-
fill: "none",
|
|
197
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
198
|
-
}, /* @__PURE__ */ import_react.default.createElement("circle", {
|
|
199
|
-
cx: "6",
|
|
200
|
-
cy: "6",
|
|
201
|
-
r: "2.5",
|
|
202
|
-
fill: "currentColor"
|
|
203
|
-
}));
|
|
204
|
-
} finally {
|
|
205
|
-
_effect.f();
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
var PresenceMany = () => {
|
|
209
|
-
var _effect = (0, import_tracking.useSignals)();
|
|
210
|
-
try {
|
|
211
|
-
return /* @__PURE__ */ import_react.default.createElement("svg", {
|
|
212
|
-
width: "12",
|
|
213
|
-
height: "12",
|
|
214
|
-
viewBox: "0 0 12 12",
|
|
215
|
-
className: presenceIconStyles,
|
|
216
|
-
fill: "none",
|
|
217
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
218
|
-
}, /* @__PURE__ */ import_react.default.createElement("path", {
|
|
219
|
-
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",
|
|
220
|
-
fill: "currentColor"
|
|
221
|
-
}), /* @__PURE__ */ import_react.default.createElement("circle", {
|
|
222
|
-
cx: "4.25",
|
|
223
|
-
cy: "6",
|
|
224
|
-
r: "2.5",
|
|
225
|
-
fill: "currentColor"
|
|
226
|
-
}));
|
|
227
|
-
} finally {
|
|
228
|
-
_effect.f();
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
var Syncing = () => {
|
|
232
|
-
var _effect = (0, import_tracking.useSignals)();
|
|
233
|
-
try {
|
|
234
|
-
const animationProps = (0, import_react.useMemo)(() => ({
|
|
235
|
-
// Synchronize animations.
|
|
236
|
-
animationDelay: `-${Date.now() % 2e3}ms`
|
|
237
|
-
}), []);
|
|
238
|
-
return /* @__PURE__ */ import_react.default.createElement("div", {
|
|
239
|
-
role: "status",
|
|
240
|
-
className: "flex items-center"
|
|
241
|
-
}, /* @__PURE__ */ import_react.default.createElement(import_react_ui.Icon, {
|
|
242
|
-
icon: "ph--circle-notch--bold",
|
|
243
|
-
size: 3,
|
|
244
|
-
style: animationProps,
|
|
245
|
-
classNames: "text-subdued animate-[spin_2s_linear_infinite]"
|
|
246
|
-
}));
|
|
247
|
-
} finally {
|
|
248
|
-
_effect.f();
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
var AttentionGlyph = /* @__PURE__ */ (0, import_react.forwardRef)(({ presence, attended, syncing, containsAttended, classNames, ...props }, forwardedRef) => {
|
|
252
|
-
var _effect = (0, import_tracking.useSignals)();
|
|
253
|
-
try {
|
|
254
|
-
const icon = syncing ? /* @__PURE__ */ import_react.default.createElement(Syncing, null) : presence === "many" ? /* @__PURE__ */ import_react.default.createElement(PresenceMany, null) : presence === "one" ? /* @__PURE__ */ import_react.default.createElement(PresenceOne, null) : null;
|
|
255
|
-
return /* @__PURE__ */ import_react.default.createElement("div", {
|
|
256
|
-
role: "none",
|
|
257
|
-
className: "flex",
|
|
258
|
-
"data-attention": attended,
|
|
259
|
-
"data-contains-attended": containsAttended
|
|
260
|
-
}, /* @__PURE__ */ import_react.default.createElement("span", {
|
|
261
|
-
role: "none",
|
|
262
|
-
...props,
|
|
263
|
-
className: (0, import_react_ui_theme.mx)(attentionGlyphStyles, classNames),
|
|
264
|
-
ref: forwardedRef
|
|
265
|
-
}, icon));
|
|
266
|
-
} finally {
|
|
267
|
-
_effect.f();
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
var ATTENTION_NAME = "Attention";
|
|
271
|
-
var ATTENABLE_ATTRIBUTE = "data-attendable-id";
|
|
272
|
-
var ATTENTION_SOURCE_ATTRIBUTE = "data-is-attention-source";
|
|
273
|
-
var [AttentionContextProvider, useAttentionContext] = (0, import_react_context.createContext)(ATTENTION_NAME, {
|
|
274
|
-
attention: new AttentionManager(),
|
|
275
|
-
path: []
|
|
276
|
-
});
|
|
277
|
-
var UNKNOWN_ATTENDABLE = {
|
|
278
|
-
hasAttention: false,
|
|
279
|
-
isAncestor: false,
|
|
280
|
-
isRelated: false
|
|
281
|
-
};
|
|
282
|
-
var useAttention = (attendableId) => {
|
|
283
|
-
const { attention, path } = useAttentionContext(ATTENTION_NAME);
|
|
284
|
-
if (!attendableId) {
|
|
285
|
-
return UNKNOWN_ATTENDABLE;
|
|
286
|
-
}
|
|
287
|
-
const current = [
|
|
288
|
-
...attendableId.split(ATTENDABLE_PATH_SEPARATOR),
|
|
289
|
-
...path
|
|
290
|
-
];
|
|
291
|
-
return attention.get(current);
|
|
292
|
-
};
|
|
293
|
-
var useAttended = () => {
|
|
294
|
-
const { attention } = useAttentionContext(ATTENTION_NAME);
|
|
295
|
-
return attention.current;
|
|
296
|
-
};
|
|
297
|
-
var useAttentionAttributes = (attendableId) => {
|
|
298
|
-
const { hasAttention } = useAttention(attendableId);
|
|
299
|
-
return (0, import_react2.useMemo)(() => {
|
|
300
|
-
const attributes = {
|
|
301
|
-
[ATTENABLE_ATTRIBUTE]: attendableId
|
|
302
|
-
};
|
|
303
|
-
if (hasAttention) {
|
|
304
|
-
attributes[ATTENTION_SOURCE_ATTRIBUTE] = "true";
|
|
305
|
-
}
|
|
306
|
-
return attributes;
|
|
307
|
-
}, [
|
|
308
|
-
attendableId,
|
|
309
|
-
hasAttention
|
|
310
|
-
]);
|
|
311
|
-
};
|
|
312
|
-
var useAttentionPath = () => {
|
|
313
|
-
const { path } = useAttentionContext(ATTENTION_NAME);
|
|
314
|
-
return path;
|
|
315
|
-
};
|
|
316
|
-
var RootAttentionProvider = ({ children, attention: propsAttention, onChange }) => {
|
|
317
|
-
var _effect = (0, import_tracking2.useSignals)();
|
|
318
|
-
try {
|
|
319
|
-
const attention = (0, import_react_ui2.useDefaultValue)(propsAttention, () => new AttentionManager());
|
|
320
|
-
const handleFocus = (event) => {
|
|
321
|
-
const selector = [
|
|
322
|
-
"[data-attendable-id]",
|
|
323
|
-
...Array.from(document.querySelectorAll("[aria-controls]")).map((el) => `[id="${el.getAttribute("aria-controls")}"]`)
|
|
324
|
-
].join(",");
|
|
325
|
-
const prev = attention.current;
|
|
326
|
-
const next = getAttendables(selector, event.target);
|
|
327
|
-
if (next.length > 0 && (prev.length !== next.length || !!prev.find((id, index) => next[index] !== id))) {
|
|
328
|
-
attention.update(next);
|
|
329
|
-
onChange?.(next);
|
|
330
|
-
}
|
|
331
|
-
};
|
|
332
|
-
return /* @__PURE__ */ import_react2.default.createElement(AttentionContextProvider, {
|
|
333
|
-
attention,
|
|
334
|
-
path: []
|
|
335
|
-
}, /* @__PURE__ */ import_react2.default.createElement("div", {
|
|
336
|
-
role: "none",
|
|
337
|
-
className: "contents",
|
|
338
|
-
onFocusCapture: handleFocus
|
|
339
|
-
}, children));
|
|
340
|
-
} finally {
|
|
341
|
-
_effect.f();
|
|
342
|
-
}
|
|
343
|
-
};
|
|
344
|
-
var AttentionProvider = ({ id, children }) => {
|
|
345
|
-
var _effect = (0, import_tracking2.useSignals)();
|
|
346
|
-
try {
|
|
347
|
-
const { attention, path } = useAttentionContext(ATTENTION_NAME);
|
|
348
|
-
const nextPath = (0, import_react2.useMemo)(() => [
|
|
349
|
-
id,
|
|
350
|
-
...path
|
|
351
|
-
], [
|
|
352
|
-
id,
|
|
353
|
-
path
|
|
354
|
-
]);
|
|
355
|
-
return /* @__PURE__ */ import_react2.default.createElement(AttentionContextProvider, {
|
|
356
|
-
attention,
|
|
357
|
-
path: nextPath
|
|
358
|
-
}, children);
|
|
359
|
-
} finally {
|
|
360
|
-
_effect.f();
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
var AttendableContainer = /* @__PURE__ */ (0, import_react2.forwardRef)(({ id, classNames, children, asChild, ...props }, forwardedRef) => {
|
|
364
|
-
var _effect = (0, import_tracking2.useSignals)();
|
|
365
|
-
try {
|
|
366
|
-
const attentionAttrs = useAttentionAttributes(id);
|
|
367
|
-
const Root = asChild ? import_react_slot.Slot : import_react_primitive.Primitive.div;
|
|
368
|
-
return /* @__PURE__ */ import_react2.default.createElement(Root, {
|
|
369
|
-
role: "none",
|
|
370
|
-
...attentionAttrs,
|
|
371
|
-
...props,
|
|
372
|
-
className: (0, import_react_ui_theme2.mx)("attention-surface", props.tabIndex === 0 && "dx-focus-ring-inset-over-all", classNames),
|
|
373
|
-
ref: forwardedRef
|
|
374
|
-
}, children);
|
|
375
|
-
} finally {
|
|
376
|
-
_effect.f();
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-attention/src/selection.ts";
|
|
380
|
-
var defaultSelection = import_effect2.Match.type().pipe(import_effect2.Match.when("single", () => ({
|
|
381
|
-
mode: "single"
|
|
382
|
-
})), import_effect2.Match.when("multi", () => ({
|
|
383
|
-
mode: "multi",
|
|
384
|
-
ids: []
|
|
385
|
-
})), import_effect2.Match.when("range", () => ({
|
|
386
|
-
mode: "range"
|
|
387
|
-
})), import_effect2.Match.when("multi-range", () => ({
|
|
388
|
-
mode: "multi-range",
|
|
389
|
-
ranges: []
|
|
390
|
-
})), import_effect2.Match.exhaustive);
|
|
391
|
-
var getSelectionSet = (selectionManager, contextId) => {
|
|
392
|
-
const ids = new Set(contextId ? [
|
|
393
|
-
contextId
|
|
394
|
-
] : []);
|
|
395
|
-
for (const context of selectionManager.getSelectionContexts()) {
|
|
396
|
-
const selection = selectionManager.getSelection(context);
|
|
397
|
-
if (selection?.mode === "multi") {
|
|
398
|
-
for (const id of selection.ids) {
|
|
399
|
-
ids.add(id);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
return ids;
|
|
404
|
-
};
|
|
405
|
-
var SelectionManager = class {
|
|
406
|
-
constructor(initial = {}) {
|
|
407
|
-
this._state = (0, import_live_object2.live)({
|
|
408
|
-
selections: {}
|
|
409
|
-
});
|
|
410
|
-
if (Object.keys(initial).length > 0) {
|
|
411
|
-
(0, import_signals_core2.untracked)(() => {
|
|
412
|
-
this._state.selections = initial;
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
getSelectionContexts() {
|
|
417
|
-
return Object.keys(this._state.selections);
|
|
418
|
-
}
|
|
419
|
-
getSelection(contextId, mode = void 0) {
|
|
420
|
-
const selection = (0, import_signals_core2.untracked)(() => this._state.selections[contextId]);
|
|
421
|
-
if (!mode || selection) {
|
|
422
|
-
return selection;
|
|
423
|
-
}
|
|
424
|
-
return (0, import_signals_core2.untracked)(() => {
|
|
425
|
-
this._state.selections[contextId] = defaultSelection(mode);
|
|
426
|
-
return this._state.selections[contextId];
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
// TODO(burdon): Disambiguate with getSelection?
|
|
430
|
-
getSelected(contextId, mode = "multi") {
|
|
431
|
-
const selection = this.getSelection(contextId, mode);
|
|
432
|
-
(0, import_invariant.invariant)(selection?.mode === mode, "Selection mode mismatch", {
|
|
433
|
-
F: __dxlog_file,
|
|
434
|
-
L: 91,
|
|
435
|
-
S: this,
|
|
436
|
-
A: [
|
|
437
|
-
"selection?.mode === mode",
|
|
438
|
-
"'Selection mode mismatch'"
|
|
439
|
-
]
|
|
440
|
-
});
|
|
441
|
-
return import_effect2.Match.type().pipe(import_effect2.Match.when({
|
|
442
|
-
mode: "single"
|
|
443
|
-
}, (s) => s.id), import_effect2.Match.when({
|
|
444
|
-
mode: "multi"
|
|
445
|
-
}, (s) => s.ids), import_effect2.Match.when({
|
|
446
|
-
mode: "range"
|
|
447
|
-
}, (s) => s.from && s.to ? {
|
|
448
|
-
from: s.from,
|
|
449
|
-
to: s.to
|
|
450
|
-
} : void 0), import_effect2.Match.when({
|
|
451
|
-
mode: "multi-range"
|
|
452
|
-
}, (s) => s.ranges), import_effect2.Match.exhaustive)(selection);
|
|
453
|
-
}
|
|
454
|
-
updateSingle(contextId, id) {
|
|
455
|
-
(0, import_signals_core2.untracked)(() => {
|
|
456
|
-
const selection = this.getSelection(contextId, "single");
|
|
457
|
-
(0, import_invariant.invariant)(selection?.mode === "single", "Selection mode is not single", {
|
|
458
|
-
F: __dxlog_file,
|
|
459
|
-
L: 104,
|
|
460
|
-
S: this,
|
|
461
|
-
A: [
|
|
462
|
-
"selection?.mode === 'single'",
|
|
463
|
-
"'Selection mode is not single'"
|
|
464
|
-
]
|
|
465
|
-
});
|
|
466
|
-
selection.id = id;
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
updateMulti(contextId, ids) {
|
|
470
|
-
(0, import_signals_core2.untracked)(() => {
|
|
471
|
-
const selection = this.getSelection(contextId, "multi");
|
|
472
|
-
(0, import_invariant.invariant)(selection?.mode === "multi", "Selection mode is not multi", {
|
|
473
|
-
F: __dxlog_file,
|
|
474
|
-
L: 112,
|
|
475
|
-
S: this,
|
|
476
|
-
A: [
|
|
477
|
-
"selection?.mode === 'multi'",
|
|
478
|
-
"'Selection mode is not multi'"
|
|
479
|
-
]
|
|
480
|
-
});
|
|
481
|
-
selection.ids = ids;
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
updateRange(contextId, from, to) {
|
|
485
|
-
(0, import_signals_core2.untracked)(() => {
|
|
486
|
-
const selection = this.getSelection(contextId, "range");
|
|
487
|
-
(0, import_invariant.invariant)(selection?.mode === "range", "Selection mode is not range", {
|
|
488
|
-
F: __dxlog_file,
|
|
489
|
-
L: 120,
|
|
490
|
-
S: this,
|
|
491
|
-
A: [
|
|
492
|
-
"selection?.mode === 'range'",
|
|
493
|
-
"'Selection mode is not range'"
|
|
494
|
-
]
|
|
495
|
-
});
|
|
496
|
-
selection.from = from;
|
|
497
|
-
selection.to = to;
|
|
498
|
-
});
|
|
499
|
-
}
|
|
500
|
-
updateMultiRange(contextId, ranges) {
|
|
501
|
-
(0, import_signals_core2.untracked)(() => {
|
|
502
|
-
const selection = this.getSelection(contextId, "multi-range");
|
|
503
|
-
(0, import_invariant.invariant)(selection?.mode === "multi-range", "Selection mode is not multi-range", {
|
|
504
|
-
F: __dxlog_file,
|
|
505
|
-
L: 129,
|
|
506
|
-
S: this,
|
|
507
|
-
A: [
|
|
508
|
-
"selection?.mode === 'multi-range'",
|
|
509
|
-
"'Selection mode is not multi-range'"
|
|
510
|
-
]
|
|
511
|
-
});
|
|
512
|
-
selection.ranges = ranges;
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
clearSelection(contextId) {
|
|
516
|
-
(0, import_signals_core2.untracked)(() => {
|
|
517
|
-
const selection = this.getSelection(contextId);
|
|
518
|
-
if (selection) {
|
|
519
|
-
this._state.selections[contextId] = defaultSelection(selection.mode);
|
|
520
|
-
}
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
toggleSelection(contextId, id) {
|
|
524
|
-
(0, import_signals_core2.untracked)(() => {
|
|
525
|
-
const selection = this.getSelection(contextId, "multi");
|
|
526
|
-
(0, import_invariant.invariant)(selection?.mode === "multi", "Selection mode is not multi", {
|
|
527
|
-
F: __dxlog_file,
|
|
528
|
-
L: 146,
|
|
529
|
-
S: this,
|
|
530
|
-
A: [
|
|
531
|
-
"selection?.mode === 'multi'",
|
|
532
|
-
"'Selection mode is not multi'"
|
|
533
|
-
]
|
|
534
|
-
});
|
|
535
|
-
if (selection.ids.includes(id)) {
|
|
536
|
-
const index = selection.ids.indexOf(id);
|
|
537
|
-
selection.ids.splice(index, 1);
|
|
538
|
-
} else {
|
|
539
|
-
selection.ids.push(id);
|
|
540
|
-
}
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
};
|
|
544
|
-
var SELECTION_NAME = "Selection";
|
|
545
|
-
var [SelectionContextProvider, useSelectionContext] = (0, import_react_context2.createContext)(SELECTION_NAME, {
|
|
546
|
-
selection: new SelectionManager()
|
|
547
|
-
});
|
|
548
|
-
var SelectionProvider = ({ children, selection: propsSelection }) => {
|
|
549
|
-
var _effect = (0, import_tracking3.useSignals)();
|
|
550
|
-
try {
|
|
551
|
-
const selection = (0, import_react_ui3.useDefaultValue)(propsSelection, () => new SelectionManager());
|
|
552
|
-
return /* @__PURE__ */ import_react3.default.createElement(SelectionContextProvider, {
|
|
553
|
-
selection
|
|
554
|
-
}, children);
|
|
555
|
-
} finally {
|
|
556
|
-
_effect.f();
|
|
557
|
-
}
|
|
558
|
-
};
|
|
559
|
-
var useSelectionManager = () => {
|
|
560
|
-
const { selection } = useSelectionContext(SELECTION_NAME);
|
|
561
|
-
return selection;
|
|
562
|
-
};
|
|
563
|
-
var useSelected = (contextId, mode = "multi") => {
|
|
564
|
-
const { selection } = useSelectionContext(SELECTION_NAME);
|
|
565
|
-
if (contextId) {
|
|
566
|
-
return selection.getSelected(contextId, mode);
|
|
567
|
-
}
|
|
568
|
-
return import_effect3.Match.type().pipe(import_effect3.Match.when({
|
|
569
|
-
mode: "single"
|
|
570
|
-
}, (s) => s.id), import_effect3.Match.when({
|
|
571
|
-
mode: "multi"
|
|
572
|
-
}, (s) => s.ids), import_effect3.Match.when({
|
|
573
|
-
mode: "range"
|
|
574
|
-
}, (s) => s.from && s.to ? {
|
|
575
|
-
from: s.from,
|
|
576
|
-
to: s.to
|
|
577
|
-
} : void 0), import_effect3.Match.when({
|
|
578
|
-
mode: "multi-range"
|
|
579
|
-
}, (s) => s.ranges), import_effect3.Match.exhaustive)(defaultSelection(mode));
|
|
580
|
-
};
|
|
581
|
-
var useSelectionActions = (contextIds, mode = "multi") => {
|
|
582
|
-
const stableContextIds = (0, import_react3.useMemo)(() => contextIds, [
|
|
583
|
-
JSON.stringify(contextIds)
|
|
584
|
-
]);
|
|
585
|
-
const { selection } = useSelectionContext(SELECTION_NAME);
|
|
586
|
-
const singleSelect = (0, import_react3.useCallback)((id) => {
|
|
587
|
-
for (const contextId of stableContextIds) {
|
|
588
|
-
selection.updateSingle(contextId, id);
|
|
589
|
-
}
|
|
590
|
-
}, [
|
|
591
|
-
selection,
|
|
592
|
-
stableContextIds
|
|
593
|
-
]);
|
|
594
|
-
const multiSelect = (0, import_react3.useCallback)((ids) => {
|
|
595
|
-
for (const contextId of stableContextIds) {
|
|
596
|
-
selection.updateMulti(contextId, ids);
|
|
597
|
-
}
|
|
598
|
-
}, [
|
|
599
|
-
selection,
|
|
600
|
-
stableContextIds
|
|
601
|
-
]);
|
|
602
|
-
const rangeSelect = (0, import_react3.useCallback)((from, to) => {
|
|
603
|
-
for (const contextId of stableContextIds) {
|
|
604
|
-
selection.updateRange(contextId, from, to);
|
|
605
|
-
}
|
|
606
|
-
}, [
|
|
607
|
-
selection,
|
|
608
|
-
stableContextIds
|
|
609
|
-
]);
|
|
610
|
-
const toggle = (0, import_react3.useCallback)((id) => {
|
|
611
|
-
for (const contextId of stableContextIds) {
|
|
612
|
-
selection.toggleSelection(contextId, id);
|
|
613
|
-
}
|
|
614
|
-
}, [
|
|
615
|
-
selection,
|
|
616
|
-
stableContextIds
|
|
617
|
-
]);
|
|
618
|
-
const clear = (0, import_react3.useCallback)(() => {
|
|
619
|
-
for (const contextId of stableContextIds) {
|
|
620
|
-
selection.clearSelection(contextId);
|
|
621
|
-
}
|
|
622
|
-
}, [
|
|
623
|
-
selection,
|
|
624
|
-
stableContextIds
|
|
625
|
-
]);
|
|
626
|
-
return {
|
|
627
|
-
singleSelect,
|
|
628
|
-
multiSelect,
|
|
629
|
-
rangeSelect,
|
|
630
|
-
toggle,
|
|
631
|
-
clear
|
|
632
|
-
};
|
|
633
|
-
};
|
|
634
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
635
|
-
0 && (module.exports = {
|
|
636
|
-
ATTENABLE_ATTRIBUTE,
|
|
637
|
-
ATTENDABLE_PATH_SEPARATOR,
|
|
638
|
-
ATTENTION_NAME,
|
|
639
|
-
ATTENTION_SOURCE_ATTRIBUTE,
|
|
640
|
-
AttendableContainer,
|
|
641
|
-
AttentionGlyph,
|
|
642
|
-
AttentionManager,
|
|
643
|
-
AttentionProvider,
|
|
644
|
-
AttentionSchema,
|
|
645
|
-
RootAttentionProvider,
|
|
646
|
-
SelectionManager,
|
|
647
|
-
SelectionProvider,
|
|
648
|
-
Syncing,
|
|
649
|
-
defaultSelection,
|
|
650
|
-
getAttendables,
|
|
651
|
-
getSelectionSet,
|
|
652
|
-
useAttended,
|
|
653
|
-
useAttention,
|
|
654
|
-
useAttentionAttributes,
|
|
655
|
-
useAttentionContext,
|
|
656
|
-
useAttentionPath,
|
|
657
|
-
useSelected,
|
|
658
|
-
useSelectionActions,
|
|
659
|
-
useSelectionManager
|
|
660
|
-
});
|
|
661
|
-
//# sourceMappingURL=chunk-UHRK5BJW.cjs.map
|