@omerdlw/base-framework 1.0.3 → 1.0.5
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/index.js +5415 -5319
- package/dist/index.js.map +1 -1
- package/dist/kernel/compose.d.ts.map +1 -1
- package/dist/kernel/handlers.d.ts.map +1 -1
- package/dist/kernel/hooks.d.ts.map +1 -1
- package/dist/kernel/index.js.map +1 -1
- package/dist/kernel/operations.d.ts.map +1 -1
- package/dist/kernel/schema.d.ts +0 -2
- package/dist/kernel/schema.d.ts.map +1 -1
- package/dist/kernel/store.d.ts.map +1 -1
- package/dist/kernel/types.d.ts.map +1 -1
- package/dist/kernel/utils.d.ts +0 -2
- package/dist/kernel/utils.d.ts.map +1 -1
- package/dist/modules/ambient/color.d.ts +16 -0
- package/dist/modules/ambient/color.d.ts.map +1 -0
- package/dist/modules/ambient/constants.d.ts +0 -17
- package/dist/modules/ambient/constants.d.ts.map +1 -1
- package/dist/modules/ambient/context.d.ts +1 -7
- package/dist/modules/ambient/context.d.ts.map +1 -1
- package/dist/modules/ambient/dom.d.ts +19 -0
- package/dist/modules/ambient/dom.d.ts.map +1 -0
- package/dist/modules/ambient/extractor.d.ts +5 -0
- package/dist/modules/ambient/extractor.d.ts.map +1 -0
- package/dist/modules/ambient/hooks.d.ts +9 -0
- package/dist/modules/ambient/hooks.d.ts.map +1 -0
- package/dist/modules/ambient/index.d.ts +7 -4
- package/dist/modules/ambient/index.d.ts.map +1 -1
- package/dist/modules/ambient/index.js +66 -60
- package/dist/modules/ambient/index.js.map +1 -1
- package/dist/modules/ambient/module.d.ts +5 -1
- package/dist/modules/ambient/module.d.ts.map +1 -1
- package/dist/modules/background/constants.d.ts +1 -10
- package/dist/modules/background/constants.d.ts.map +1 -1
- package/dist/modules/background/context.d.ts +1 -13
- package/dist/modules/background/context.d.ts.map +1 -1
- package/dist/modules/background/hooks.d.ts +13 -118
- package/dist/modules/background/hooks.d.ts.map +1 -1
- package/dist/modules/background/index.d.ts +8 -3
- package/dist/modules/background/index.d.ts.map +1 -1
- package/dist/modules/background/index.js +975 -991
- package/dist/modules/background/index.js.map +1 -1
- package/dist/modules/background/module.d.ts +1 -0
- package/dist/modules/background/module.d.ts.map +1 -1
- package/dist/modules/background/overlay.d.ts +93 -2
- package/dist/modules/background/overlay.d.ts.map +1 -1
- package/dist/modules/background/playback.d.ts +10 -0
- package/dist/modules/background/playback.d.ts.map +1 -0
- package/dist/modules/background/state.d.ts +9 -0
- package/dist/modules/background/state.d.ts.map +1 -0
- package/dist/modules/background/{utils.d.ts → visual.d.ts} +6 -14
- package/dist/modules/background/visual.d.ts.map +1 -0
- package/dist/modules/background/youtube/player.d.ts +28 -0
- package/dist/modules/background/youtube/player.d.ts.map +1 -0
- package/dist/modules/context-menu/context.d.ts +1 -10
- package/dist/modules/context-menu/context.d.ts.map +1 -1
- package/dist/modules/context-menu/dom.d.ts +8 -0
- package/dist/modules/context-menu/dom.d.ts.map +1 -0
- package/dist/modules/context-menu/hooks.d.ts +11 -11
- package/dist/modules/context-menu/hooks.d.ts.map +1 -1
- package/dist/modules/context-menu/index.d.ts +8 -3
- package/dist/modules/context-menu/index.d.ts.map +1 -1
- package/dist/modules/context-menu/index.js +97 -101
- package/dist/modules/context-menu/index.js.map +1 -1
- package/dist/modules/context-menu/{utils.d.ts → items.d.ts} +2 -9
- package/dist/modules/context-menu/items.d.ts.map +1 -0
- package/dist/modules/context-menu/module.d.ts.map +1 -1
- package/dist/modules/context-menu/overlay.d.ts +13 -1
- package/dist/modules/context-menu/overlay.d.ts.map +1 -1
- package/dist/modules/context-menu/state.d.ts +1 -0
- package/dist/modules/context-menu/state.d.ts.map +1 -1
- package/dist/modules/controls/{utils.d.ts → entries.d.ts} +6 -5
- package/dist/modules/controls/entries.d.ts.map +1 -0
- package/dist/modules/controls/hooks.d.ts +0 -7
- package/dist/modules/controls/hooks.d.ts.map +1 -1
- package/dist/modules/controls/index.d.ts +5 -3
- package/dist/modules/controls/index.d.ts.map +1 -1
- package/dist/modules/controls/index.js +66 -61
- package/dist/modules/controls/index.js.map +1 -1
- package/dist/modules/controls/layout.d.ts +7 -0
- package/dist/modules/controls/layout.d.ts.map +1 -0
- package/dist/modules/controls/overlay.d.ts +9 -0
- package/dist/modules/controls/overlay.d.ts.map +1 -1
- package/dist/modules/dock/cards.d.ts.map +1 -1
- package/dist/modules/dock/dom.d.ts +24 -0
- package/dist/modules/dock/dom.d.ts.map +1 -0
- package/dist/modules/dock/helpers.d.ts +25 -0
- package/dist/modules/dock/helpers.d.ts.map +1 -0
- package/dist/modules/dock/hooks.d.ts +3 -918
- package/dist/modules/dock/hooks.d.ts.map +1 -1
- package/dist/modules/dock/index.d.ts +3 -2
- package/dist/modules/dock/index.d.ts.map +1 -1
- package/dist/modules/dock/index.js +2372 -2330
- package/dist/modules/dock/index.js.map +1 -1
- package/dist/modules/dock/layout.d.ts +26 -0
- package/dist/modules/dock/layout.d.ts.map +1 -0
- package/dist/modules/dock/module.d.ts.map +1 -1
- package/dist/modules/dock/overlay.d.ts.map +1 -1
- package/dist/modules/dock/paths.d.ts +10 -0
- package/dist/modules/dock/paths.d.ts.map +1 -0
- package/dist/modules/dock/provider.d.ts.map +1 -1
- package/dist/modules/dock/runtime/display.d.ts.map +1 -1
- package/dist/modules/dock/runtime/dock.d.ts.map +1 -1
- package/dist/modules/dock/runtime/pipeline.d.ts +32 -0
- package/dist/modules/dock/runtime/pipeline.d.ts.map +1 -0
- package/dist/modules/dock/status/events.d.ts.map +1 -1
- package/dist/modules/dock/styles.d.ts +900 -0
- package/dist/modules/dock/styles.d.ts.map +1 -0
- package/dist/modules/dock/surface/context.d.ts +1 -2
- package/dist/modules/dock/surface/context.d.ts.map +1 -1
- package/dist/modules/dock/surface/definition.d.ts.map +1 -1
- package/dist/modules/dock/surface/helpers.d.ts +7 -0
- package/dist/modules/dock/surface/helpers.d.ts.map +1 -0
- package/dist/modules/dock/surface/hooks.d.ts.map +1 -1
- package/dist/modules/dock/surface/machine.d.ts.map +1 -1
- package/dist/modules/dock/surface/stack.d.ts.map +1 -1
- package/dist/modules/dock/surface/view-model.d.ts.map +1 -1
- package/dist/modules/dock/types.d.ts.map +1 -1
- package/dist/modules/index.js +5010 -4916
- package/dist/modules/index.js.map +1 -1
- package/dist/modules/loading/context.d.ts +2 -13
- package/dist/modules/loading/context.d.ts.map +1 -1
- package/dist/modules/loading/hooks.d.ts +15 -2
- package/dist/modules/loading/hooks.d.ts.map +1 -1
- package/dist/modules/loading/index.d.ts +3 -2
- package/dist/modules/loading/index.d.ts.map +1 -1
- package/dist/modules/loading/index.js +38 -34
- package/dist/modules/loading/index.js.map +1 -1
- package/dist/modules/loading/module.d.ts.map +1 -1
- package/dist/modules/loading/state.d.ts +6 -0
- package/dist/modules/loading/state.d.ts.map +1 -0
- package/dist/modules/media/constants.d.ts +0 -1
- package/dist/modules/media/constants.d.ts.map +1 -1
- package/dist/modules/media/context.d.ts +2 -6
- package/dist/modules/media/context.d.ts.map +1 -1
- package/dist/modules/media/hooks.d.ts +6 -1
- package/dist/modules/media/hooks.d.ts.map +1 -1
- package/dist/modules/media/index.d.ts +4 -3
- package/dist/modules/media/index.d.ts.map +1 -1
- package/dist/modules/media/index.js +100 -98
- package/dist/modules/media/index.js.map +1 -1
- package/dist/modules/media/module.d.ts.map +1 -1
- package/dist/modules/media/overlay.d.ts +0 -5
- package/dist/modules/media/overlay.d.ts.map +1 -1
- package/dist/modules/media/playback.d.ts +5 -0
- package/dist/modules/media/playback.d.ts.map +1 -0
- package/dist/modules/media/session.d.ts +8 -0
- package/dist/modules/media/session.d.ts.map +1 -0
- package/dist/modules/media/types.d.ts +0 -1
- package/dist/modules/media/types.d.ts.map +1 -1
- package/dist/modules/modal/context.d.ts +1 -12
- package/dist/modules/modal/context.d.ts.map +1 -1
- package/dist/modules/modal/dom.d.ts +4 -0
- package/dist/modules/modal/dom.d.ts.map +1 -0
- package/dist/modules/modal/header.d.ts +7 -0
- package/dist/modules/modal/header.d.ts.map +1 -0
- package/dist/modules/modal/hooks.d.ts +12 -1
- package/dist/modules/modal/hooks.d.ts.map +1 -1
- package/dist/modules/modal/identity.d.ts +7 -0
- package/dist/modules/modal/identity.d.ts.map +1 -0
- package/dist/modules/modal/index.d.ts +9 -4
- package/dist/modules/modal/index.d.ts.map +1 -1
- package/dist/modules/modal/index.js +118 -86
- package/dist/modules/modal/index.js.map +1 -1
- package/dist/modules/modal/layout.d.ts +13 -0
- package/dist/modules/modal/layout.d.ts.map +1 -0
- package/dist/modules/modal/module.d.ts.map +1 -1
- package/dist/modules/modal/overlay.d.ts.map +1 -1
- package/dist/modules/modal/types.d.ts.map +1 -1
- package/dist/modules/notification/context.d.ts +2 -8
- package/dist/modules/notification/context.d.ts.map +1 -1
- package/dist/modules/notification/hooks.d.ts +8 -1
- package/dist/modules/notification/hooks.d.ts.map +1 -1
- package/dist/modules/notification/index.d.ts +4 -3
- package/dist/modules/notification/index.d.ts.map +1 -1
- package/dist/modules/notification/index.js +56 -46
- package/dist/modules/notification/index.js.map +1 -1
- package/dist/modules/notification/state.d.ts +17 -0
- package/dist/modules/notification/state.d.ts.map +1 -0
- package/dist/provider.js.map +1 -1
- package/docs/modules/ambient.md +12 -8
- package/docs/modules/background.md +15 -13
- package/docs/modules/context-menu.md +13 -13
- package/docs/modules/controls.md +4 -3
- package/docs/modules/dock.md +8 -2
- package/docs/modules/loading.md +11 -11
- package/docs/modules/media.md +8 -7
- package/docs/modules/modal.md +4 -1
- package/docs/modules/notification.md +4 -4
- package/package.json +4 -4
- package/dist/modules/ambient/utils.d.ts +0 -18
- package/dist/modules/ambient/utils.d.ts.map +0 -1
- package/dist/modules/background/utils.d.ts.map +0 -1
- package/dist/modules/context-menu/utils.d.ts.map +0 -1
- package/dist/modules/controls/utils.d.ts.map +0 -1
- package/dist/modules/dock/utils.d.ts +0 -93
- package/dist/modules/dock/utils.d.ts.map +0 -1
- package/dist/modules/loading/utils.d.ts +0 -4
- package/dist/modules/loading/utils.d.ts.map +0 -1
- package/dist/modules/media/utils.d.ts +0 -17
- package/dist/modules/media/utils.d.ts.map +0 -1
- package/dist/modules/modal/utils.d.ts +0 -31
- package/dist/modules/modal/utils.d.ts.map +0 -1
- package/dist/modules/notification/utils.d.ts +0 -9
- package/dist/modules/notification/utils.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import React, { createContext, memo, createElement, isValidElement, cloneElement, Suspense, useEffect, useState, useCallback, useMemo, use, useSyncExternalStore, useRef, useContext, useLayoutEffect, lazy, useId, useReducer,
|
|
2
|
+
import React, { createContext, memo, createElement, isValidElement, cloneElement, Suspense, useEffect, useState, useCallback, useMemo, use, useSyncExternalStore, useRef, useContext, useLayoutEffect, lazy, useId, useReducer, Children } from 'react';
|
|
3
3
|
import { motion, AnimatePresence, useMotionValue, useSpring, useTransform, useDragControls, MotionConfig } from 'motion/react';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -423,1585 +423,1392 @@ function Button({
|
|
|
423
423
|
);
|
|
424
424
|
}
|
|
425
425
|
Button.displayName = "Button";
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
DYNAMIC: "dynamic",
|
|
432
|
-
USER: "user"
|
|
433
|
-
});
|
|
434
|
-
var REGISTRY_LIFECYCLES = Object.freeze({
|
|
435
|
-
IMMEDIATE: "immediate",
|
|
436
|
-
GRACEFUL: "graceful",
|
|
437
|
-
PERSISTENT: "persistent",
|
|
438
|
-
ROUTE: "route"
|
|
439
|
-
});
|
|
440
|
-
var REGISTRY_VALIDATION_MODES = Object.freeze({
|
|
441
|
-
WARN: "warn",
|
|
442
|
-
STRICT: "strict"
|
|
443
|
-
});
|
|
444
|
-
var REGISTRY_METADATA_KEYS = Object.freeze([
|
|
445
|
-
"cleanup",
|
|
446
|
-
"cleanupDelayMs",
|
|
447
|
-
"instanceId",
|
|
448
|
-
"lifecycle",
|
|
449
|
-
"priority",
|
|
450
|
-
"source",
|
|
451
|
-
"scope",
|
|
452
|
-
"validation"
|
|
453
|
-
]);
|
|
454
|
-
Object.freeze({
|
|
455
|
-
[REGISTRY_SOURCES.STATIC]: 100,
|
|
456
|
-
[REGISTRY_SOURCES.DYNAMIC]: 200,
|
|
457
|
-
[REGISTRY_SOURCES.USER]: 300
|
|
458
|
-
});
|
|
459
|
-
Object.freeze({
|
|
460
|
-
[REGISTRY_SOURCES.STATIC]: 10,
|
|
461
|
-
[REGISTRY_SOURCES.DYNAMIC]: 20,
|
|
462
|
-
[REGISTRY_SOURCES.USER]: 30
|
|
463
|
-
});
|
|
464
|
-
var REGISTRY_LIFECYCLE_VALUES = new Set(
|
|
465
|
-
Object.values(REGISTRY_LIFECYCLES)
|
|
466
|
-
);
|
|
467
|
-
var REGISTRY_METADATA_KEY_SET = new Set(
|
|
468
|
-
REGISTRY_METADATA_KEYS
|
|
469
|
-
);
|
|
470
|
-
var REGISTRY_SCOPE_KINDS = Object.freeze({
|
|
471
|
-
APP: "app",
|
|
472
|
-
SESSION: "session",
|
|
473
|
-
ROUTE: "route",
|
|
474
|
-
INSTANCE: "instance",
|
|
475
|
-
WORKSPACE: "workspace"
|
|
476
|
-
});
|
|
477
|
-
REGISTRY_SCOPE_KINDS.APP;
|
|
478
|
-
function getOrCreateGlobalContext(name, defaultValue) {
|
|
479
|
-
const sym = /* @__PURE__ */ Symbol.for(`@omerdlw/base-framework/context/${name}`);
|
|
480
|
-
const store = globalThis;
|
|
481
|
-
if (!store[sym]) {
|
|
482
|
-
store[sym] = createContext(defaultValue);
|
|
483
|
-
}
|
|
484
|
-
return store[sym];
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// src/kernel/utils.ts
|
|
488
|
-
function parseFiniteNumber(value) {
|
|
489
|
-
const parsed = Number(value);
|
|
490
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
426
|
+
function isValidComponentType(type) {
|
|
427
|
+
if (typeof type === "function") return true;
|
|
428
|
+
return Boolean(
|
|
429
|
+
type != null && typeof type === "object" && !isValidElement(type) && "$$typeof" in type
|
|
430
|
+
);
|
|
491
431
|
}
|
|
492
|
-
function
|
|
493
|
-
return
|
|
432
|
+
function resolveComponentType(...candidates) {
|
|
433
|
+
return candidates.find(isValidComponentType) ?? null;
|
|
494
434
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
return lifecycle && REGISTRY_LIFECYCLE_VALUES.has(lifecycle) ? lifecycle : fallback;
|
|
435
|
+
function resolveRenderableContent(...candidates) {
|
|
436
|
+
return candidates.find(
|
|
437
|
+
(candidate) => candidate !== null && candidate !== void 0
|
|
438
|
+
) ?? null;
|
|
500
439
|
}
|
|
501
|
-
function
|
|
502
|
-
if (
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
return { issues: ["registry metadata must be an object"], valid: false };
|
|
506
|
-
const issues = [];
|
|
507
|
-
Object.keys(metadata).forEach((key) => {
|
|
508
|
-
if (!REGISTRY_METADATA_KEY_SET.has(key))
|
|
509
|
-
issues.push(`unknown registry metadata field: ${key}`);
|
|
510
|
-
});
|
|
511
|
-
if (metadata.source !== void 0 && !getValidString(metadata.source))
|
|
512
|
-
issues.push("source must be a non-empty string");
|
|
513
|
-
if (metadata.instanceId !== void 0 && !getValidString(metadata.instanceId))
|
|
514
|
-
issues.push("instanceId must be a non-empty string");
|
|
515
|
-
if (metadata.scope !== void 0 && !getValidString(metadata.scope))
|
|
516
|
-
issues.push("scope must be a non-empty string");
|
|
517
|
-
if (metadata.priority !== void 0 && parseFiniteNumber(metadata.priority) === null)
|
|
518
|
-
issues.push("priority must be a finite number");
|
|
519
|
-
if (metadata.cleanupDelayMs !== void 0) {
|
|
520
|
-
const delay = parseFiniteNumber(metadata.cleanupDelayMs);
|
|
521
|
-
if (delay === null || delay < 0)
|
|
522
|
-
issues.push("cleanupDelayMs must be a non-negative finite number");
|
|
440
|
+
function collectSearchableText(value, visitedObjects) {
|
|
441
|
+
if (typeof value === "string") return value;
|
|
442
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
443
|
+
return String(value);
|
|
523
444
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
);
|
|
445
|
+
if (Array.isArray(value)) {
|
|
446
|
+
if (visitedObjects.has(value)) return "";
|
|
447
|
+
visitedObjects.add(value);
|
|
448
|
+
const text = value.map((entry) => collectSearchableText(entry, visitedObjects)).join(" ");
|
|
449
|
+
visitedObjects.delete(value);
|
|
450
|
+
return text;
|
|
529
451
|
}
|
|
530
|
-
if (
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
452
|
+
if (isValidElement(value)) {
|
|
453
|
+
if (visitedObjects.has(value)) return "";
|
|
454
|
+
visitedObjects.add(value);
|
|
455
|
+
const text = collectSearchableText(
|
|
456
|
+
value.props?.children,
|
|
457
|
+
visitedObjects
|
|
535
458
|
);
|
|
459
|
+
visitedObjects.delete(value);
|
|
460
|
+
return text;
|
|
536
461
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
defaultLifecycle = null,
|
|
542
|
-
defaultSource = DEFAULT_SOURCE
|
|
543
|
-
} = {}) {
|
|
544
|
-
const registryMeta = isObject(metadata) ? metadata : {};
|
|
545
|
-
const normalizedDefaultDelay = parseFiniteNumber(defaultCleanupDelayMs);
|
|
546
|
-
const fallbackCleanupDelayMs = normalizedDefaultDelay !== null && normalizedDefaultDelay >= 0 ? normalizedDefaultDelay : null;
|
|
547
|
-
const fallbackLifecycle = defaultLifecycle && REGISTRY_LIFECYCLE_VALUES.has(defaultLifecycle) ? defaultLifecycle : null;
|
|
548
|
-
const source = getValidString(registryMeta.source) || getValidString(defaultSource, DEFAULT_SOURCE) || DEFAULT_SOURCE;
|
|
549
|
-
const scope = getValidString(registryMeta.scope);
|
|
550
|
-
const priority = parseFiniteNumber(registryMeta.priority);
|
|
551
|
-
const lifecycle = resolveLifecycle(registryMeta, fallbackLifecycle);
|
|
552
|
-
const validation = isValidationMode(registryMeta.validation) ? registryMeta.validation : null;
|
|
553
|
-
const cleanupDelayCandidate = parseFiniteNumber(registryMeta.cleanupDelayMs);
|
|
554
|
-
let cleanupDelayMs = cleanupDelayCandidate !== null && cleanupDelayCandidate >= 0 ? cleanupDelayCandidate : fallbackCleanupDelayMs;
|
|
555
|
-
if (lifecycle === REGISTRY_LIFECYCLES.IMMEDIATE) {
|
|
556
|
-
cleanupDelayMs = 0;
|
|
557
|
-
} else if ((lifecycle === REGISTRY_LIFECYCLES.GRACEFUL || lifecycle === REGISTRY_LIFECYCLES.ROUTE) && cleanupDelayMs === null) {
|
|
558
|
-
cleanupDelayMs = fallbackCleanupDelayMs;
|
|
462
|
+
if (value && typeof value === "object") {
|
|
463
|
+
if (visitedObjects.has(value)) return "";
|
|
464
|
+
visitedObjects.add(value);
|
|
465
|
+
return Object.values(value).map((entry) => collectSearchableText(entry, visitedObjects)).join(" ");
|
|
559
466
|
}
|
|
560
|
-
return
|
|
561
|
-
cleanupDelayMs,
|
|
562
|
-
lifecycle,
|
|
563
|
-
priority,
|
|
564
|
-
registerOptions: {
|
|
565
|
-
...priority !== null && { priority },
|
|
566
|
-
...validation === REGISTRY_VALIDATION_MODES.STRICT && { validation },
|
|
567
|
-
...scope && { scope }
|
|
568
|
-
},
|
|
569
|
-
source,
|
|
570
|
-
...scope && { scope },
|
|
571
|
-
...validation && { validation }
|
|
572
|
-
};
|
|
467
|
+
return "";
|
|
573
468
|
}
|
|
574
|
-
function
|
|
575
|
-
return
|
|
469
|
+
function toSearchableText(value) {
|
|
470
|
+
return collectSearchableText(value, /* @__PURE__ */ new WeakSet());
|
|
576
471
|
}
|
|
577
|
-
function
|
|
578
|
-
|
|
579
|
-
return Object.fromEntries(
|
|
580
|
-
REGISTRY_METADATA_KEYS.filter((key) => options[key] !== void 0).map(
|
|
581
|
-
(key) => [key, options[key]]
|
|
582
|
-
)
|
|
583
|
-
);
|
|
472
|
+
function normalizeUpper(value) {
|
|
473
|
+
return String(value || "").trim().toUpperCase();
|
|
584
474
|
}
|
|
585
|
-
function
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
}
|
|
590
|
-
return value;
|
|
475
|
+
function formatMediaTime(seconds = 0) {
|
|
476
|
+
const sec = Math.max(0, Math.floor(Number(seconds) || 0));
|
|
477
|
+
const m = Math.floor(sec / 60);
|
|
478
|
+
const s = sec % 60;
|
|
479
|
+
return `${m}:${s < 10 ? "0" : ""}${s}`;
|
|
591
480
|
}
|
|
592
|
-
function
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
481
|
+
function isHudDescriptor(value) {
|
|
482
|
+
return isObject(value) && !isValidElement(value) && ("component" in value || "content" in value || "node" in value || "element" in value || "isActive" in value || "id" in value);
|
|
483
|
+
}
|
|
484
|
+
function createDockScheduler(options = {}) {
|
|
485
|
+
return createScheduler({
|
|
486
|
+
defaultLabel: "dock-task",
|
|
487
|
+
...options
|
|
598
488
|
});
|
|
599
|
-
const getSelectedSnapshot = useCallback(() => {
|
|
600
|
-
const snapshot = store.getSnapshot();
|
|
601
|
-
const cache = cacheRef.current;
|
|
602
|
-
if (cache.snapshot === snapshot && cache.selector === selector && cache.isEqual === isEqual) {
|
|
603
|
-
return cache.selected;
|
|
604
|
-
}
|
|
605
|
-
const selected = selector(snapshot);
|
|
606
|
-
if (cache.snapshot !== null && cache.isEqual === isEqual && isEqual(cache.selected, selected)) {
|
|
607
|
-
cache.snapshot = snapshot;
|
|
608
|
-
cache.selector = selector;
|
|
609
|
-
return cache.selected;
|
|
610
|
-
}
|
|
611
|
-
cacheRef.current = {
|
|
612
|
-
isEqual,
|
|
613
|
-
selected,
|
|
614
|
-
selector,
|
|
615
|
-
snapshot
|
|
616
|
-
};
|
|
617
|
-
return selected;
|
|
618
|
-
}, [isEqual, selector, store]);
|
|
619
|
-
return useSyncExternalStore(
|
|
620
|
-
store.subscribe,
|
|
621
|
-
getSelectedSnapshot,
|
|
622
|
-
getSelectedSnapshot
|
|
623
|
-
);
|
|
624
489
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
[callback, ref]
|
|
490
|
+
|
|
491
|
+
// src/modules/dock/paths.ts
|
|
492
|
+
function isSamePath(left, right) {
|
|
493
|
+
const normalizedLeft = normalizePath(left);
|
|
494
|
+
const normalizedRight = normalizePath(right);
|
|
495
|
+
return Boolean(
|
|
496
|
+
normalizedLeft && normalizedRight && normalizedLeft === normalizedRight
|
|
633
497
|
);
|
|
634
|
-
useEffect(() => {
|
|
635
|
-
document.addEventListener("pointerdown", handlePointer);
|
|
636
|
-
return () => document.removeEventListener("pointerdown", handlePointer);
|
|
637
|
-
}, [handlePointer]);
|
|
638
498
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
APP_ERROR: "APP_ERROR"
|
|
647
|
-
});
|
|
648
|
-
var EventEmitter = class {
|
|
649
|
-
events = /* @__PURE__ */ new Map();
|
|
650
|
-
debounceTimers = /* @__PURE__ */ new Map();
|
|
651
|
-
subscribe(event, callback) {
|
|
652
|
-
if (typeof event !== "string" || !event || typeof callback !== "function") {
|
|
653
|
-
return () => {
|
|
654
|
-
};
|
|
655
|
-
}
|
|
656
|
-
const listeners2 = this.events.get(event) || /* @__PURE__ */ new Set();
|
|
657
|
-
listeners2.add(callback);
|
|
658
|
-
this.events.set(event, listeners2);
|
|
659
|
-
return () => {
|
|
660
|
-
listeners2.delete(callback);
|
|
661
|
-
if (listeners2.size === 0) this.events.delete(event);
|
|
662
|
-
};
|
|
663
|
-
}
|
|
664
|
-
emit(event, payload) {
|
|
665
|
-
const listeners2 = this.events.get(event);
|
|
666
|
-
if (!listeners2 || listeners2.size === 0) return;
|
|
667
|
-
const snapshot = Array.from(listeners2);
|
|
668
|
-
for (const callback of snapshot) {
|
|
669
|
-
try {
|
|
670
|
-
callback(payload);
|
|
671
|
-
} catch (error) {
|
|
672
|
-
report(`Event listener (${String(event)})`, error);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
emitDebounced(event, payload, waitMs = 100) {
|
|
677
|
-
const existing = this.debounceTimers.get(event);
|
|
678
|
-
if (existing) clearTimeout(existing);
|
|
679
|
-
const timer = setTimeout(() => {
|
|
680
|
-
this.debounceTimers.delete(event);
|
|
681
|
-
this.emit(event, payload);
|
|
682
|
-
}, waitMs);
|
|
683
|
-
this.debounceTimers.set(event, timer);
|
|
684
|
-
}
|
|
685
|
-
cancelDebounced(event) {
|
|
686
|
-
if (event) {
|
|
687
|
-
const timer = this.debounceTimers.get(event);
|
|
688
|
-
if (timer) {
|
|
689
|
-
clearTimeout(timer);
|
|
690
|
-
this.debounceTimers.delete(event);
|
|
691
|
-
}
|
|
692
|
-
} else {
|
|
693
|
-
for (const timer of this.debounceTimers.values()) {
|
|
694
|
-
clearTimeout(timer);
|
|
695
|
-
}
|
|
696
|
-
this.debounceTimers.clear();
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
unsubscribeAll(event) {
|
|
700
|
-
this.cancelDebounced(event);
|
|
701
|
-
if (event) this.events.delete(event);
|
|
702
|
-
else this.events.clear();
|
|
703
|
-
}
|
|
704
|
-
hasListeners(event) {
|
|
705
|
-
return Boolean(this.events.get(event)?.size);
|
|
706
|
-
}
|
|
707
|
-
getListenerCount(event) {
|
|
708
|
-
return this.events.get(event)?.size || 0;
|
|
709
|
-
}
|
|
710
|
-
getAllEvents() {
|
|
711
|
-
return [...this.events.keys()];
|
|
712
|
-
}
|
|
713
|
-
};
|
|
714
|
-
var GLOBAL_EVENTS_KEY = /* @__PURE__ */ Symbol.for("__base_framework_global_events__");
|
|
715
|
-
var _global = globalThis;
|
|
716
|
-
var globalEvents = _global[GLOBAL_EVENTS_KEY] ?? (_global[GLOBAL_EVENTS_KEY] = new EventEmitter());
|
|
717
|
-
|
|
718
|
-
// src/hooks/use-global-event.ts
|
|
719
|
-
function useGlobalEvent(event, callback, options) {
|
|
720
|
-
const callbackRef = useRef(callback);
|
|
721
|
-
const debounceTimerRef = useRef(null);
|
|
722
|
-
useRef(0);
|
|
723
|
-
const throttleTimerRef = useRef(null);
|
|
724
|
-
useIsomorphicLayoutEffect(() => {
|
|
725
|
-
callbackRef.current = callback;
|
|
726
|
-
});
|
|
727
|
-
const debounceMs = options?.debounceMs;
|
|
728
|
-
const throttleMs = options?.throttleMs;
|
|
729
|
-
useEffect(() => {
|
|
730
|
-
if (!event) return;
|
|
731
|
-
const events = Array.isArray(event) ? event.filter(Boolean) : [event];
|
|
732
|
-
if (events.length === 0) return;
|
|
733
|
-
const handler = (payload) => {
|
|
734
|
-
callbackRef.current?.(payload);
|
|
735
|
-
};
|
|
736
|
-
const unsubs = events.map((ev) => globalEvents.subscribe(ev, handler));
|
|
737
|
-
return () => {
|
|
738
|
-
unsubs.forEach((unsub) => unsub());
|
|
739
|
-
if (debounceTimerRef.current !== null) {
|
|
740
|
-
clearTimeout(debounceTimerRef.current);
|
|
741
|
-
debounceTimerRef.current = null;
|
|
742
|
-
}
|
|
743
|
-
if (throttleTimerRef.current !== null) {
|
|
744
|
-
clearTimeout(throttleTimerRef.current);
|
|
745
|
-
throttleTimerRef.current = null;
|
|
746
|
-
}
|
|
747
|
-
};
|
|
748
|
-
}, [event, debounceMs, throttleMs]);
|
|
499
|
+
function isPathPrefix(candidatePath, pathname) {
|
|
500
|
+
const normalizedCandidate = normalizePath(candidatePath);
|
|
501
|
+
const normalizedPathname = normalizePath(pathname);
|
|
502
|
+
if (!normalizedCandidate || !normalizedPathname) return false;
|
|
503
|
+
if (normalizedCandidate === normalizedPathname) return true;
|
|
504
|
+
if (normalizedCandidate === "/") return normalizedPathname.startsWith("/");
|
|
505
|
+
return normalizedPathname.startsWith(`${normalizedCandidate}/`);
|
|
749
506
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
var ACTIVE_FULLSCREEN_ROOT_SELECTOR = '[data-fullscreen-state-root="true"][data-affect-global-state="true"]';
|
|
753
|
-
var domObserver = null;
|
|
754
|
-
var lastSnapshot = false;
|
|
755
|
-
function getDomSnapshot() {
|
|
756
|
-
if (typeof document === "undefined") {
|
|
757
|
-
return activeFullscreenStateIds.size > 0;
|
|
758
|
-
}
|
|
759
|
-
return document.querySelector(ACTIVE_FULLSCREEN_ROOT_SELECTOR) !== null;
|
|
507
|
+
function isInlineActionPathMatch(path, pathname) {
|
|
508
|
+
return isSamePath(path, pathname) || path !== "/" && isPathPrefix(path, pathname);
|
|
760
509
|
}
|
|
761
|
-
function
|
|
762
|
-
|
|
510
|
+
function isSafeInternalHref(value) {
|
|
511
|
+
const href = typeof value === "string" ? value.trim() : "";
|
|
512
|
+
return href.startsWith("/") && !href.startsWith("//");
|
|
763
513
|
}
|
|
764
|
-
function
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
514
|
+
function getDockLocationKey({
|
|
515
|
+
hash = "",
|
|
516
|
+
pathname = "/",
|
|
517
|
+
search = ""
|
|
518
|
+
} = {}) {
|
|
519
|
+
const normalizedPathname = String(pathname || "/").trim() || "/";
|
|
520
|
+
const normalizedSearch = String(search || "").trim();
|
|
521
|
+
const normalizedHash = String(hash || "").trim();
|
|
522
|
+
const query = normalizedSearch ? normalizedSearch.startsWith("?") ? normalizedSearch : `?${normalizedSearch}` : "";
|
|
523
|
+
const fragment = normalizedHash ? normalizedHash.startsWith("#") ? normalizedHash : `#${normalizedHash}` : "";
|
|
524
|
+
return `${normalizedPathname}${query}${fragment}`;
|
|
771
525
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
domObserver = new MutationObserver(() => {
|
|
777
|
-
emitIfSnapshotChanged();
|
|
778
|
-
});
|
|
779
|
-
domObserver.observe(document.documentElement, {
|
|
780
|
-
attributes: true,
|
|
781
|
-
childList: true,
|
|
782
|
-
subtree: true,
|
|
783
|
-
attributeFilter: [
|
|
784
|
-
"data-fullscreen-state",
|
|
785
|
-
"data-fullscreen-state-root",
|
|
786
|
-
"data-affect-global-state"
|
|
787
|
-
]
|
|
788
|
-
});
|
|
526
|
+
|
|
527
|
+
// src/modules/dock/surface/helpers.ts
|
|
528
|
+
function isSurfaceDescriptor(value) {
|
|
529
|
+
return value != null && typeof value === "object" && !Array.isArray(value) && !isValidElement(value);
|
|
789
530
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
531
|
+
var generatedExtensionId = 0;
|
|
532
|
+
function normalizeSurfaceExtension(input) {
|
|
533
|
+
if (!input) return null;
|
|
534
|
+
if (isValidElement(input)) {
|
|
535
|
+
return {
|
|
536
|
+
align: "left",
|
|
537
|
+
className: "",
|
|
538
|
+
component: null,
|
|
539
|
+
content: input,
|
|
540
|
+
id: `ext-${++generatedExtensionId}`,
|
|
541
|
+
order: 0,
|
|
542
|
+
props: {},
|
|
543
|
+
unstyled: false
|
|
544
|
+
};
|
|
793
545
|
}
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
546
|
+
if (typeof input !== "object") return null;
|
|
547
|
+
const extension = input;
|
|
548
|
+
const component = isValidComponentType(extension.component) ? extension.component : null;
|
|
549
|
+
const content = isValidElement(extension.content) || typeof extension.content === "string" || typeof extension.content === "number" ? extension.content : null;
|
|
550
|
+
if (!component && content == null) return null;
|
|
551
|
+
const align = extension.align === "right" || extension.align === "end" ? "right" : extension.align === "center" ? "center" : "left";
|
|
552
|
+
return {
|
|
553
|
+
align,
|
|
554
|
+
className: typeof extension.className === "string" ? extension.className : "",
|
|
555
|
+
component,
|
|
556
|
+
content,
|
|
557
|
+
id: String(
|
|
558
|
+
extension.id || extension.key || `ext-${++generatedExtensionId}`
|
|
559
|
+
),
|
|
560
|
+
order: Number.isFinite(Number(extension.order)) ? Number(extension.order) : 0,
|
|
561
|
+
props: isPlainObject(extension.props) ? extension.props : {},
|
|
562
|
+
unstyled: Boolean(extension.unstyled)
|
|
804
563
|
};
|
|
805
564
|
}
|
|
806
|
-
function
|
|
807
|
-
|
|
565
|
+
function normalizeSurfaceFlowSnapshot(value) {
|
|
566
|
+
if (!isPlainObject(value)) return null;
|
|
567
|
+
return { ...value };
|
|
808
568
|
}
|
|
809
|
-
function
|
|
810
|
-
|
|
569
|
+
function createSurfaceReturnHandshake(input) {
|
|
570
|
+
const source = typeof input === "string" ? { pathname: input } : input;
|
|
571
|
+
const pathname = typeof source?.pathname === "string" ? source.pathname.trim() : "";
|
|
572
|
+
if (!isSafeInternalHref(pathname)) return null;
|
|
573
|
+
return {
|
|
574
|
+
focusKey: typeof source?.focusKey === "string" && source.focusKey.trim() ? source.focusKey.trim() : null,
|
|
575
|
+
pathname,
|
|
576
|
+
restoreScroll: source?.restoreScroll !== false,
|
|
577
|
+
returnOnCancel: source?.returnOnCancel === true
|
|
578
|
+
};
|
|
811
579
|
}
|
|
812
|
-
|
|
813
|
-
"
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
)
|
|
580
|
+
function resolveSurfaceFlowReturnHandshake(definition, input) {
|
|
581
|
+
const flowInput = input && typeof input === "object" ? input : null;
|
|
582
|
+
const inputHandshake = flowInput?.returnHandshake ?? (flowInput?.returnTo ? {
|
|
583
|
+
focusKey: flowInput.returnFocusKey,
|
|
584
|
+
pathname: flowInput.returnTo,
|
|
585
|
+
restoreScroll: flowInput.restoreReturnScroll,
|
|
586
|
+
returnOnCancel: flowInput.returnOnCancel
|
|
587
|
+
} : null);
|
|
588
|
+
const baseHandshake = definition?.returnHandshake;
|
|
589
|
+
if (!baseHandshake && !inputHandshake) return null;
|
|
590
|
+
return createSurfaceReturnHandshake({ ...baseHandshake, ...inputHandshake });
|
|
822
591
|
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
592
|
+
|
|
593
|
+
// src/modules/dock/surface/context.tsx
|
|
594
|
+
var SurfaceExtensionsContext = createContext(null);
|
|
595
|
+
var SurfaceItemContext = createContext({
|
|
596
|
+
id: null,
|
|
597
|
+
width: null
|
|
598
|
+
});
|
|
599
|
+
function useSurfaceDimensions() {
|
|
600
|
+
const { width } = use(SurfaceItemContext);
|
|
601
|
+
return useMemo(() => ({ width }), [width]);
|
|
829
602
|
}
|
|
830
|
-
function
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
);
|
|
836
|
-
|
|
837
|
-
() =>
|
|
838
|
-
|
|
603
|
+
function useSurfaceId() {
|
|
604
|
+
return use(SurfaceItemContext).id;
|
|
605
|
+
}
|
|
606
|
+
function useSurfaceHeader() {
|
|
607
|
+
const store = use(SurfaceExtensionsContext)?.headerActions ?? null;
|
|
608
|
+
const surfaceId = useSurfaceId();
|
|
609
|
+
return useCallback(
|
|
610
|
+
(patch) => {
|
|
611
|
+
if (!store) return;
|
|
612
|
+
const data = typeof patch === "function" ? patch({}) : patch;
|
|
613
|
+
if (data?.headerAction !== void 0)
|
|
614
|
+
store.setAction(surfaceId, data.headerAction);
|
|
615
|
+
},
|
|
616
|
+
[store, surfaceId]
|
|
839
617
|
);
|
|
840
|
-
return useSyncExternalStore(subscribeToType, getEntries, getEntries);
|
|
841
618
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
619
|
+
function useSurfaceAction(action) {
|
|
620
|
+
const store = use(SurfaceExtensionsContext)?.headerActions ?? null;
|
|
621
|
+
const surfaceId = useSurfaceId();
|
|
622
|
+
useEffect(() => {
|
|
623
|
+
if (!store || action === void 0) return;
|
|
624
|
+
store.setAction(surfaceId, action);
|
|
625
|
+
return () => store.removeAction(surfaceId);
|
|
626
|
+
}, [store, surfaceId, action]);
|
|
847
627
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
payload[coreModule.id] = slice;
|
|
856
|
-
hasSlices = true;
|
|
628
|
+
var SurfaceHeaderActionStore = class {
|
|
629
|
+
store = createStore({
|
|
630
|
+
actionsBySurface: {},
|
|
631
|
+
version: 0
|
|
632
|
+
});
|
|
633
|
+
get version() {
|
|
634
|
+
return this.store.getSnapshot().version;
|
|
857
635
|
}
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
...isObject(config.registry) ? config.registry : {}
|
|
864
|
-
}
|
|
636
|
+
subscribe = (listener) => this.store.subscribe(listener);
|
|
637
|
+
getAction = (surfaceId) => {
|
|
638
|
+
const sId = surfaceId != null ? String(surfaceId) : "active";
|
|
639
|
+
const { actionsBySurface } = this.store.getSnapshot();
|
|
640
|
+
return actionsBySurface[sId] ?? actionsBySurface.active ?? actionsBySurface.global ?? null;
|
|
865
641
|
};
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
}
|
|
878
|
-
function createEntryCleanupKey(type, key, source, instanceId, scope) {
|
|
879
|
-
return JSON.stringify([
|
|
880
|
-
"entry",
|
|
881
|
-
type,
|
|
882
|
-
key,
|
|
883
|
-
scope ?? null,
|
|
884
|
-
source,
|
|
885
|
-
instanceId
|
|
886
|
-
]);
|
|
887
|
-
}
|
|
888
|
-
function getCleanupScope(context) {
|
|
889
|
-
return context?.cleanupScope || /* @__PURE__ */ new Map();
|
|
890
|
-
}
|
|
891
|
-
function clearCleanupTimer(scope, cleanupKey) {
|
|
892
|
-
const lifecycle = scope.get(cleanupKey);
|
|
893
|
-
if (!lifecycle) return;
|
|
894
|
-
lifecycle.cancelled = true;
|
|
895
|
-
if (lifecycle.timerId !== null) clearTimeout(lifecycle.timerId);
|
|
896
|
-
scope.delete(cleanupKey);
|
|
897
|
-
}
|
|
898
|
-
function scheduleCleanup(scope, cleanupKey, callback, delayMs) {
|
|
899
|
-
clearCleanupTimer(scope, cleanupKey);
|
|
900
|
-
const lifecycle = {
|
|
901
|
-
cancelled: false,
|
|
902
|
-
timerId: null
|
|
642
|
+
setAction = (surfaceId, action) => {
|
|
643
|
+
const sId = surfaceId != null ? String(surfaceId) : "active";
|
|
644
|
+
const current = this.store.getSnapshot();
|
|
645
|
+
if (current.actionsBySurface[sId] === action) return;
|
|
646
|
+
this.store.setState({
|
|
647
|
+
actionsBySurface: {
|
|
648
|
+
...current.actionsBySurface,
|
|
649
|
+
[sId]: action
|
|
650
|
+
},
|
|
651
|
+
version: current.version + 1
|
|
652
|
+
});
|
|
903
653
|
};
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
const definition = coreModule.registry;
|
|
913
|
-
const toEntries = coreModule.page?.entries;
|
|
914
|
-
if (!definition || !toEntries || slice == null || slice === false) return [];
|
|
915
|
-
const type = coreModule.id;
|
|
916
|
-
const items = Array.isArray(slice) ? slice : [slice];
|
|
917
|
-
const registrations = [];
|
|
918
|
-
for (const item of items) {
|
|
919
|
-
if (item == null || item === false) continue;
|
|
920
|
-
const itemMetadata = isObject(item) && isObject(item.registry) ? item.registry : {};
|
|
921
|
-
const metadata = { ...pageMetadata, ...itemMetadata };
|
|
922
|
-
if (metadata.validation === "strict" && !validateRegistryMetadata(metadata).valid) {
|
|
923
|
-
continue;
|
|
924
|
-
}
|
|
925
|
-
const payload = isObject(item) ? Object.fromEntries(
|
|
926
|
-
Object.entries(item).filter(([key]) => key !== "registry")
|
|
927
|
-
) : item;
|
|
928
|
-
const { cleanupDelayMs, lifecycle, registerOptions, scope, source } = normalizeRegistryMetadata(metadata, {
|
|
929
|
-
defaultCleanupDelayMs: definition.cleanupDelayMs ?? null,
|
|
930
|
-
defaultLifecycle: definition.lifecycle,
|
|
931
|
-
defaultSource: DEFAULT_SOURCE
|
|
654
|
+
removeAction = (surfaceId) => {
|
|
655
|
+
const sId = surfaceId != null ? String(surfaceId) : "active";
|
|
656
|
+
const current = this.store.getSnapshot();
|
|
657
|
+
if (!(sId in current.actionsBySurface)) return;
|
|
658
|
+
const { [sId]: _, ...nextActions } = current.actionsBySurface;
|
|
659
|
+
this.store.setState({
|
|
660
|
+
actionsBySurface: nextActions,
|
|
661
|
+
version: current.version + 1
|
|
932
662
|
});
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
663
|
+
};
|
|
664
|
+
clearSurface = (surfaceId) => this.removeAction(surfaceId);
|
|
665
|
+
};
|
|
666
|
+
var SurfaceExtensionsStore = class {
|
|
667
|
+
extensionsBySurface = /* @__PURE__ */ new Map();
|
|
668
|
+
cachedListBySurface = /* @__PURE__ */ new Map();
|
|
669
|
+
store = createStore({ version: 0 });
|
|
670
|
+
get version() {
|
|
671
|
+
return this.store.getSnapshot().version;
|
|
672
|
+
}
|
|
673
|
+
subscribe = (listener) => this.store.subscribe(listener);
|
|
674
|
+
notify = () => {
|
|
675
|
+
this.cachedListBySurface.clear();
|
|
676
|
+
this.store.setState((prev) => ({ version: prev.version + 1 }));
|
|
677
|
+
};
|
|
678
|
+
getExtensionsForSurface = (surfaceId) => {
|
|
679
|
+
const sId = surfaceId != null ? String(surfaceId) : "active";
|
|
680
|
+
if (this.cachedListBySurface.has(sId))
|
|
681
|
+
return this.cachedListBySurface.get(sId);
|
|
682
|
+
const globalExts = this.extensionsBySurface.get("global");
|
|
683
|
+
const activeExts = this.extensionsBySurface.get("active");
|
|
684
|
+
const surfaceExts = sId !== "global" && sId !== "active" ? this.extensionsBySurface.get(sId) : void 0;
|
|
685
|
+
let fallbackExts;
|
|
686
|
+
if (!globalExts && !activeExts && !surfaceExts && this.extensionsBySurface.size > 0) {
|
|
687
|
+
for (const map of this.extensionsBySurface.values()) {
|
|
688
|
+
if (map.size > 0) {
|
|
689
|
+
fallbackExts = map;
|
|
690
|
+
break;
|
|
691
|
+
}
|
|
938
692
|
}
|
|
939
|
-
registrations.push({
|
|
940
|
-
cleanupDelayMs,
|
|
941
|
-
cleanupKey: createEntryCleanupKey(
|
|
942
|
-
type,
|
|
943
|
-
key,
|
|
944
|
-
source,
|
|
945
|
-
context.instanceId,
|
|
946
|
-
scope
|
|
947
|
-
),
|
|
948
|
-
key,
|
|
949
|
-
lifecycle,
|
|
950
|
-
registerOptions,
|
|
951
|
-
scope,
|
|
952
|
-
source,
|
|
953
|
-
type,
|
|
954
|
-
value
|
|
955
|
-
});
|
|
956
693
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
};
|
|
962
|
-
function applyRegistryConfig(config, context) {
|
|
963
|
-
const modules = context.modules ?? [];
|
|
964
|
-
if (!config || modules.length === 0) return NO_CLEANUP;
|
|
965
|
-
const pageMetadata = isObject(config.registry) ? config.registry : {};
|
|
966
|
-
const slices = config;
|
|
967
|
-
const registrations = modules.flatMap((coreModule) => {
|
|
968
|
-
try {
|
|
969
|
-
return collectModuleRegistrations(
|
|
970
|
-
coreModule,
|
|
971
|
-
slices[coreModule.id],
|
|
972
|
-
pageMetadata,
|
|
973
|
-
context
|
|
974
|
-
);
|
|
975
|
-
} catch (error) {
|
|
976
|
-
report(`Registry apply (${coreModule.id})`, error);
|
|
977
|
-
return [];
|
|
694
|
+
if (!globalExts && !activeExts && !surfaceExts && !fallbackExts) {
|
|
695
|
+
const empty = [];
|
|
696
|
+
this.cachedListBySurface.set(sId, empty);
|
|
697
|
+
return empty;
|
|
978
698
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
runRegistrationBatch(context, (queue) => {
|
|
988
|
-
registrations.forEach(
|
|
989
|
-
({ cleanupKey, key, registerOptions, source, type, value }) => {
|
|
990
|
-
clearCleanupTimer(cleanupScope, cleanupKey);
|
|
991
|
-
queue.register(type, key, value, source, registerOptions);
|
|
992
|
-
}
|
|
699
|
+
const merged = new Map([
|
|
700
|
+
...globalExts || [],
|
|
701
|
+
...activeExts || [],
|
|
702
|
+
...surfaceExts || [],
|
|
703
|
+
...fallbackExts || []
|
|
704
|
+
]);
|
|
705
|
+
const result = Array.from(merged.values()).sort(
|
|
706
|
+
(a, b) => a.order - b.order
|
|
993
707
|
);
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
const immediate = [];
|
|
997
|
-
registrations.forEach((registration) => {
|
|
998
|
-
if (isPersistentLifecycle(registration.lifecycle)) return;
|
|
999
|
-
const { cleanupDelayMs, cleanupKey, key, type } = registration;
|
|
1000
|
-
if (typeof cleanupDelayMs === "number" && cleanupDelayMs > 0) {
|
|
1001
|
-
scheduleCleanup(
|
|
1002
|
-
cleanupScope,
|
|
1003
|
-
cleanupKey,
|
|
1004
|
-
() => context.unregister(type, key, owner(registration)),
|
|
1005
|
-
cleanupDelayMs
|
|
1006
|
-
);
|
|
1007
|
-
} else {
|
|
1008
|
-
immediate.push(registration);
|
|
1009
|
-
}
|
|
1010
|
-
});
|
|
1011
|
-
if (immediate.length === 0) return;
|
|
1012
|
-
runRegistrationBatch(context, (queue) => {
|
|
1013
|
-
immediate.forEach(
|
|
1014
|
-
(registration) => queue.unregister(
|
|
1015
|
-
registration.type,
|
|
1016
|
-
registration.key,
|
|
1017
|
-
owner(registration)
|
|
1018
|
-
)
|
|
1019
|
-
);
|
|
1020
|
-
});
|
|
708
|
+
this.cachedListBySurface.set(sId, result);
|
|
709
|
+
return result;
|
|
1021
710
|
};
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
}
|
|
1032
|
-
if (isObject(sourceOrOptions)) {
|
|
1033
|
-
return {
|
|
1034
|
-
optionsArg,
|
|
1035
|
-
sourceOrOptions: { ...sourceOrOptions, instanceId }
|
|
1036
|
-
};
|
|
1037
|
-
}
|
|
1038
|
-
return {
|
|
1039
|
-
optionsArg: void 0,
|
|
1040
|
-
sourceOrOptions: {
|
|
1041
|
-
...isObject(optionsArg) ? optionsArg : {},
|
|
1042
|
-
instanceId
|
|
711
|
+
setExtension = (surfaceId, extension) => {
|
|
712
|
+
if (!extension) return;
|
|
713
|
+
const normalized = normalizeSurfaceExtension(extension);
|
|
714
|
+
if (!normalized) return;
|
|
715
|
+
const sId = surfaceId != null ? String(surfaceId) : "active";
|
|
716
|
+
let surfaceMap = this.extensionsBySurface.get(sId);
|
|
717
|
+
if (!surfaceMap) {
|
|
718
|
+
surfaceMap = /* @__PURE__ */ new Map();
|
|
719
|
+
this.extensionsBySurface.set(sId, surfaceMap);
|
|
1043
720
|
}
|
|
721
|
+
const prev = surfaceMap.get(normalized.id);
|
|
722
|
+
if (prev && prev.content === normalized.content && prev.align === normalized.align && prev.order === normalized.order && prev.className === normalized.className && prev.unstyled === normalized.unstyled && prev.component === normalized.component && prev.props === normalized.props)
|
|
723
|
+
return;
|
|
724
|
+
surfaceMap.set(normalized.id, normalized);
|
|
725
|
+
this.notify();
|
|
1044
726
|
};
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
return [input.sourceOrOptions, input.optionsArg];
|
|
1058
|
-
}
|
|
1059
|
-
var MAX_STABILIZATION_DEPTH = 64;
|
|
1060
|
-
function createStableFunctionEntry(fn) {
|
|
1061
|
-
const entry = {
|
|
1062
|
-
current: fn,
|
|
1063
|
-
stable(...args) {
|
|
1064
|
-
return entry.current?.apply(this, args);
|
|
727
|
+
removeExtension = (surfaceId, extensionId) => {
|
|
728
|
+
if (!extensionId) return;
|
|
729
|
+
const sId = surfaceId != null ? String(surfaceId) : "active";
|
|
730
|
+
let removed = false;
|
|
731
|
+
for (const [key, map] of this.extensionsBySurface.entries()) {
|
|
732
|
+
if (key === sId || key === "active" || key === "global") {
|
|
733
|
+
if (map.has(extensionId)) {
|
|
734
|
+
map.delete(extensionId);
|
|
735
|
+
if (map.size === 0) this.extensionsBySurface.delete(key);
|
|
736
|
+
removed = true;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
1065
739
|
}
|
|
740
|
+
if (removed) this.notify();
|
|
1066
741
|
};
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
742
|
+
clearSurface = (surfaceId) => {
|
|
743
|
+
const sId = surfaceId != null ? String(surfaceId) : "active";
|
|
744
|
+
this.extensionsBySurface.delete(sId);
|
|
745
|
+
this.extensionsBySurface.delete("active");
|
|
746
|
+
this.notify();
|
|
747
|
+
};
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
// src/kernel/constants.ts
|
|
751
|
+
var DEFAULT_SOURCE = "dynamic";
|
|
752
|
+
var REGISTRY_SOURCES = Object.freeze({
|
|
753
|
+
STATIC: "static",
|
|
754
|
+
DYNAMIC: "dynamic",
|
|
755
|
+
USER: "user"
|
|
756
|
+
});
|
|
757
|
+
var REGISTRY_LIFECYCLES = Object.freeze({
|
|
758
|
+
IMMEDIATE: "immediate",
|
|
759
|
+
GRACEFUL: "graceful",
|
|
760
|
+
PERSISTENT: "persistent",
|
|
761
|
+
ROUTE: "route"
|
|
762
|
+
});
|
|
763
|
+
var REGISTRY_VALIDATION_MODES = Object.freeze({
|
|
764
|
+
WARN: "warn",
|
|
765
|
+
STRICT: "strict"
|
|
766
|
+
});
|
|
767
|
+
var REGISTRY_METADATA_KEYS = Object.freeze([
|
|
768
|
+
"cleanup",
|
|
769
|
+
"cleanupDelayMs",
|
|
770
|
+
"instanceId",
|
|
771
|
+
"lifecycle",
|
|
772
|
+
"priority",
|
|
773
|
+
"source",
|
|
774
|
+
"scope",
|
|
775
|
+
"validation"
|
|
776
|
+
]);
|
|
777
|
+
Object.freeze({
|
|
778
|
+
[REGISTRY_SOURCES.STATIC]: 100,
|
|
779
|
+
[REGISTRY_SOURCES.DYNAMIC]: 200,
|
|
780
|
+
[REGISTRY_SOURCES.USER]: 300
|
|
781
|
+
});
|
|
782
|
+
Object.freeze({
|
|
783
|
+
[REGISTRY_SOURCES.STATIC]: 10,
|
|
784
|
+
[REGISTRY_SOURCES.DYNAMIC]: 20,
|
|
785
|
+
[REGISTRY_SOURCES.USER]: 30
|
|
786
|
+
});
|
|
787
|
+
var REGISTRY_LIFECYCLE_VALUES = new Set(
|
|
788
|
+
Object.values(REGISTRY_LIFECYCLES)
|
|
789
|
+
);
|
|
790
|
+
var REGISTRY_METADATA_KEY_SET = new Set(
|
|
791
|
+
REGISTRY_METADATA_KEYS
|
|
792
|
+
);
|
|
793
|
+
var REGISTRY_SCOPE_KINDS = Object.freeze({
|
|
794
|
+
APP: "app",
|
|
795
|
+
SESSION: "session",
|
|
796
|
+
ROUTE: "route",
|
|
797
|
+
INSTANCE: "instance",
|
|
798
|
+
WORKSPACE: "workspace"
|
|
799
|
+
});
|
|
800
|
+
REGISTRY_SCOPE_KINDS.APP;
|
|
801
|
+
function getOrCreateGlobalContext(name, defaultValue) {
|
|
802
|
+
const sym = /* @__PURE__ */ Symbol.for(`@omerdlw/base-framework/context/${name}`);
|
|
803
|
+
const store = globalThis;
|
|
804
|
+
if (!store[sym]) {
|
|
805
|
+
store[sym] = createContext(defaultValue);
|
|
806
|
+
}
|
|
807
|
+
return store[sym];
|
|
1072
808
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
809
|
+
|
|
810
|
+
// src/kernel/utils.ts
|
|
811
|
+
function parseFiniteNumber(value) {
|
|
812
|
+
const parsed = Number(value);
|
|
813
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
1075
814
|
}
|
|
1076
|
-
function
|
|
1077
|
-
return
|
|
815
|
+
function getValidString(value, fallback = null) {
|
|
816
|
+
return trimToNull(value) ?? fallback;
|
|
1078
817
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
const nextKeys = Object.keys(nextValue);
|
|
1085
|
-
if (previousKeys.length !== nextKeys.length) return false;
|
|
1086
|
-
return nextKeys.every(
|
|
1087
|
-
(key) => Object.prototype.hasOwnProperty.call(previousValue, key)
|
|
1088
|
-
);
|
|
818
|
+
|
|
819
|
+
// src/kernel/schema.ts
|
|
820
|
+
function resolveLifecycle(metadata, fallback) {
|
|
821
|
+
const lifecycle = metadata?.lifecycle ?? metadata?.cleanup;
|
|
822
|
+
return lifecycle && REGISTRY_LIFECYCLE_VALUES.has(lifecycle) ? lifecycle : fallback;
|
|
1089
823
|
}
|
|
1090
|
-
function
|
|
1091
|
-
if (
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
824
|
+
function validateRegistryMetadata(metadata) {
|
|
825
|
+
if (metadata === void 0 || metadata === null)
|
|
826
|
+
return { issues: [], valid: true };
|
|
827
|
+
if (!isObject(metadata))
|
|
828
|
+
return { issues: ["registry metadata must be an object"], valid: false };
|
|
829
|
+
const issues = [];
|
|
830
|
+
Object.keys(metadata).forEach((key) => {
|
|
831
|
+
if (!REGISTRY_METADATA_KEY_SET.has(key))
|
|
832
|
+
issues.push(`unknown registry metadata field: ${key}`);
|
|
833
|
+
});
|
|
834
|
+
if (metadata.source !== void 0 && !getValidString(metadata.source))
|
|
835
|
+
issues.push("source must be a non-empty string");
|
|
836
|
+
if (metadata.instanceId !== void 0 && !getValidString(metadata.instanceId))
|
|
837
|
+
issues.push("instanceId must be a non-empty string");
|
|
838
|
+
if (metadata.scope !== void 0 && !getValidString(metadata.scope))
|
|
839
|
+
issues.push("scope must be a non-empty string");
|
|
840
|
+
if (metadata.priority !== void 0 && parseFiniteNumber(metadata.priority) === null)
|
|
841
|
+
issues.push("priority must be a finite number");
|
|
842
|
+
if (metadata.cleanupDelayMs !== void 0) {
|
|
843
|
+
const delay = parseFiniteNumber(metadata.cleanupDelayMs);
|
|
844
|
+
if (delay === null || delay < 0)
|
|
845
|
+
issues.push("cleanupDelayMs must be a non-negative finite number");
|
|
1110
846
|
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
scope,
|
|
1116
|
-
isValidElement(previousValue) ? previousValue.props : void 0,
|
|
1117
|
-
seen,
|
|
1118
|
-
depth + 1
|
|
847
|
+
const lifecycle = metadata.lifecycle ?? metadata.cleanup;
|
|
848
|
+
if (lifecycle !== void 0 && !REGISTRY_LIFECYCLE_VALUES.has(String(lifecycle))) {
|
|
849
|
+
issues.push(
|
|
850
|
+
`lifecycle must be one of: ${[...REGISTRY_LIFECYCLE_VALUES].join(", ")}`
|
|
1119
851
|
);
|
|
1120
|
-
if (isValidElement(previousValue) && previousValue.type === value.type && previousValue.key === value.key && previousValue.props === nextProps) {
|
|
1121
|
-
return previousValue;
|
|
1122
|
-
}
|
|
1123
|
-
return cloneElement(value, nextProps);
|
|
1124
|
-
}
|
|
1125
|
-
if (Array.isArray(value)) {
|
|
1126
|
-
const nextValue = value.every(isReactNodeLike) ? Children.toArray(value) : value;
|
|
1127
|
-
const previousArray = Array.isArray(previousValue) ? previousValue : null;
|
|
1128
|
-
let hasChanged2 = !previousArray || previousArray.length !== nextValue.length;
|
|
1129
|
-
const stabilizedValue2 = nextValue.map((item, index) => {
|
|
1130
|
-
const nextItem = stabilizeRegistryValue(
|
|
1131
|
-
item,
|
|
1132
|
-
`${path}[${index}]`,
|
|
1133
|
-
scope,
|
|
1134
|
-
previousArray?.[index],
|
|
1135
|
-
seen,
|
|
1136
|
-
depth + 1
|
|
1137
|
-
);
|
|
1138
|
-
if (!previousArray || nextItem !== previousArray[index]) {
|
|
1139
|
-
hasChanged2 = true;
|
|
1140
|
-
}
|
|
1141
|
-
return nextItem;
|
|
1142
|
-
});
|
|
1143
|
-
return !hasChanged2 ? previousArray : stabilizedValue2;
|
|
1144
852
|
}
|
|
1145
|
-
if (
|
|
1146
|
-
|
|
853
|
+
if (metadata.validation !== void 0 && !Object.values(REGISTRY_VALIDATION_MODES).includes(
|
|
854
|
+
metadata.validation
|
|
855
|
+
)) {
|
|
856
|
+
issues.push(
|
|
857
|
+
`validation must be one of: ${Object.values(REGISTRY_VALIDATION_MODES).join(", ")}`
|
|
858
|
+
);
|
|
1147
859
|
}
|
|
1148
|
-
|
|
1149
|
-
const previousRecord = previousValue;
|
|
1150
|
-
const stabilizedValue = {};
|
|
1151
|
-
const canReusePrevious = hasSameObjectKeys(previousValue, value);
|
|
1152
|
-
let hasChanged = !canReusePrevious;
|
|
1153
|
-
Object.keys(source).forEach((key) => {
|
|
1154
|
-
const nextValue = stabilizeRegistryValue(
|
|
1155
|
-
source[key],
|
|
1156
|
-
`${path}.${key}`,
|
|
1157
|
-
scope,
|
|
1158
|
-
previousRecord?.[key],
|
|
1159
|
-
seen,
|
|
1160
|
-
depth + 1
|
|
1161
|
-
);
|
|
1162
|
-
stabilizedValue[key] = nextValue;
|
|
1163
|
-
if (!canReusePrevious || nextValue !== previousRecord?.[key]) {
|
|
1164
|
-
hasChanged = true;
|
|
1165
|
-
}
|
|
1166
|
-
});
|
|
1167
|
-
return !hasChanged ? previousValue : stabilizedValue;
|
|
1168
|
-
}
|
|
1169
|
-
function useAppliedRegistryConfig(payload, context, componentSlices) {
|
|
1170
|
-
const functionEntriesRef = useRef(/* @__PURE__ */ new Map());
|
|
1171
|
-
const appliedRef = useRef(null);
|
|
1172
|
-
useIsomorphicLayoutEffect(() => {
|
|
1173
|
-
const previous = appliedRef.current;
|
|
1174
|
-
if (previous && previous.payload === payload && previous.context === context) {
|
|
1175
|
-
return;
|
|
1176
|
-
}
|
|
1177
|
-
const functionEntries = functionEntriesRef.current;
|
|
1178
|
-
const usedPaths = /* @__PURE__ */ new Set();
|
|
1179
|
-
const config = stabilizeRegistryValue(
|
|
1180
|
-
payload,
|
|
1181
|
-
"config",
|
|
1182
|
-
{ componentSlices, functionEntries, usedPaths },
|
|
1183
|
-
previous?.config
|
|
1184
|
-
);
|
|
1185
|
-
functionEntries.forEach((_entry, path) => {
|
|
1186
|
-
if (!usedPaths.has(path)) functionEntries.delete(path);
|
|
1187
|
-
});
|
|
1188
|
-
if (previous && previous.config === config && previous.context === context) {
|
|
1189
|
-
previous.payload = payload;
|
|
1190
|
-
return;
|
|
1191
|
-
}
|
|
1192
|
-
previous?.cleanup();
|
|
1193
|
-
appliedRef.current = {
|
|
1194
|
-
cleanup: applyRegistryConfig(config, context),
|
|
1195
|
-
config,
|
|
1196
|
-
context,
|
|
1197
|
-
payload
|
|
1198
|
-
};
|
|
1199
|
-
});
|
|
1200
|
-
useIsomorphicLayoutEffect(
|
|
1201
|
-
() => () => {
|
|
1202
|
-
appliedRef.current?.cleanup();
|
|
1203
|
-
appliedRef.current = null;
|
|
1204
|
-
},
|
|
1205
|
-
[]
|
|
1206
|
-
);
|
|
860
|
+
return { issues, valid: issues.length === 0 };
|
|
1207
861
|
}
|
|
1208
|
-
function
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
const
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
)
|
|
1230
|
-
});
|
|
862
|
+
function normalizeRegistryMetadata(metadata, {
|
|
863
|
+
defaultCleanupDelayMs = null,
|
|
864
|
+
defaultLifecycle = null,
|
|
865
|
+
defaultSource = DEFAULT_SOURCE
|
|
866
|
+
} = {}) {
|
|
867
|
+
const registryMeta = isObject(metadata) ? metadata : {};
|
|
868
|
+
const normalizedDefaultDelay = parseFiniteNumber(defaultCleanupDelayMs);
|
|
869
|
+
const fallbackCleanupDelayMs = normalizedDefaultDelay !== null && normalizedDefaultDelay >= 0 ? normalizedDefaultDelay : null;
|
|
870
|
+
const fallbackLifecycle = defaultLifecycle && REGISTRY_LIFECYCLE_VALUES.has(defaultLifecycle) ? defaultLifecycle : null;
|
|
871
|
+
const source = getValidString(registryMeta.source) || getValidString(defaultSource, DEFAULT_SOURCE) || DEFAULT_SOURCE;
|
|
872
|
+
const scope = getValidString(registryMeta.scope);
|
|
873
|
+
const priority = parseFiniteNumber(registryMeta.priority);
|
|
874
|
+
const lifecycle = resolveLifecycle(registryMeta, fallbackLifecycle);
|
|
875
|
+
const validation = isValidationMode(registryMeta.validation) ? registryMeta.validation : null;
|
|
876
|
+
const cleanupDelayCandidate = parseFiniteNumber(registryMeta.cleanupDelayMs);
|
|
877
|
+
let cleanupDelayMs = cleanupDelayCandidate !== null && cleanupDelayCandidate >= 0 ? cleanupDelayCandidate : fallbackCleanupDelayMs;
|
|
878
|
+
if (lifecycle === REGISTRY_LIFECYCLES.IMMEDIATE) {
|
|
879
|
+
cleanupDelayMs = 0;
|
|
880
|
+
} else if ((lifecycle === REGISTRY_LIFECYCLES.GRACEFUL || lifecycle === REGISTRY_LIFECYCLES.ROUTE) && cleanupDelayMs === null) {
|
|
881
|
+
cleanupDelayMs = fallbackCleanupDelayMs;
|
|
882
|
+
}
|
|
1231
883
|
return {
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
884
|
+
cleanupDelayMs,
|
|
885
|
+
lifecycle,
|
|
886
|
+
priority,
|
|
887
|
+
registerOptions: {
|
|
888
|
+
...priority !== null && { priority },
|
|
889
|
+
...validation === REGISTRY_VALIDATION_MODES.STRICT && { validation },
|
|
890
|
+
...scope && { scope }
|
|
891
|
+
},
|
|
892
|
+
source,
|
|
893
|
+
...scope && { scope },
|
|
894
|
+
...validation && { validation }
|
|
1238
895
|
};
|
|
1239
896
|
}
|
|
1240
|
-
function
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
() =>
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
() => createRegistryApplyContext(
|
|
1250
|
-
{ batch, register, unregister },
|
|
1251
|
-
{
|
|
1252
|
-
cleanupScope,
|
|
1253
|
-
instanceId,
|
|
1254
|
-
modules,
|
|
1255
|
-
pathname
|
|
1256
|
-
}
|
|
1257
|
-
),
|
|
1258
|
-
[batch, cleanupScope, instanceId, modules, pathname, register, unregister]
|
|
1259
|
-
);
|
|
1260
|
-
const payload = useMemo(
|
|
1261
|
-
() => config ? createModulePayload(modules, config, metadata) : null,
|
|
1262
|
-
[config, metadata, modules]
|
|
1263
|
-
);
|
|
1264
|
-
const componentSlices = useMemo(
|
|
1265
|
-
() => new Set(
|
|
1266
|
-
modules.filter(
|
|
1267
|
-
(coreModule) => coreModule.registry?.valueKind === "component"
|
|
1268
|
-
).map((coreModule) => coreModule.id)
|
|
1269
|
-
),
|
|
1270
|
-
[modules]
|
|
897
|
+
function isValidationMode(value) {
|
|
898
|
+
return Object.values(REGISTRY_VALIDATION_MODES).includes(value);
|
|
899
|
+
}
|
|
900
|
+
function pickRegistryMetadata(options) {
|
|
901
|
+
if (!isObject(options)) return {};
|
|
902
|
+
return Object.fromEntries(
|
|
903
|
+
REGISTRY_METADATA_KEYS.filter((key) => options[key] !== void 0).map(
|
|
904
|
+
(key) => [key, options[key]]
|
|
905
|
+
)
|
|
1271
906
|
);
|
|
1272
|
-
useAppliedRegistryConfig(payload, context, componentSlices);
|
|
1273
907
|
}
|
|
1274
|
-
function
|
|
1275
|
-
|
|
908
|
+
function useRequiredContext(context, hookName, providerName) {
|
|
909
|
+
const value = use(context);
|
|
910
|
+
if (value === null) {
|
|
911
|
+
throw new Error(`${hookName} must be used within ${providerName}`);
|
|
912
|
+
}
|
|
913
|
+
return value;
|
|
1276
914
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
915
|
+
function useStore(store, selector = (state) => state, isEqual = Object.is) {
|
|
916
|
+
const cacheRef = useRef({
|
|
917
|
+
isEqual: null,
|
|
918
|
+
selected: void 0,
|
|
919
|
+
selector: null,
|
|
920
|
+
snapshot: null
|
|
921
|
+
});
|
|
922
|
+
const getSelectedSnapshot = useCallback(() => {
|
|
923
|
+
const snapshot = store.getSnapshot();
|
|
924
|
+
const cache = cacheRef.current;
|
|
925
|
+
if (cache.snapshot === snapshot && cache.selector === selector && cache.isEqual === isEqual) {
|
|
926
|
+
return cache.selected;
|
|
927
|
+
}
|
|
928
|
+
const selected = selector(snapshot);
|
|
929
|
+
if (cache.snapshot !== null && cache.isEqual === isEqual && isEqual(cache.selected, selected)) {
|
|
930
|
+
cache.snapshot = snapshot;
|
|
931
|
+
cache.selector = selector;
|
|
932
|
+
return cache.selected;
|
|
933
|
+
}
|
|
934
|
+
cacheRef.current = {
|
|
935
|
+
isEqual,
|
|
936
|
+
selected,
|
|
937
|
+
selector,
|
|
938
|
+
snapshot
|
|
939
|
+
};
|
|
940
|
+
return selected;
|
|
941
|
+
}, [isEqual, selector, store]);
|
|
942
|
+
return useSyncExternalStore(
|
|
943
|
+
store.subscribe,
|
|
944
|
+
getSelectedSnapshot,
|
|
945
|
+
getSelectedSnapshot
|
|
1283
946
|
);
|
|
1284
|
-
const config = coreModule && options?.enabled !== false && value != null ? { [id]: value } : null;
|
|
1285
|
-
useRegistry(config, pickRegistryMetadata(options));
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
// src/theme.tsx
|
|
1289
|
-
function defineThemeSpec(id) {
|
|
1290
|
-
return Object.freeze({ id });
|
|
1291
947
|
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
};
|
|
948
|
+
function useClickOutside(ref, callback) {
|
|
949
|
+
const handlePointer = useCallback(
|
|
950
|
+
(event) => {
|
|
951
|
+
if (ref?.current && !ref.current.contains(event.target)) {
|
|
952
|
+
callback?.(event);
|
|
953
|
+
}
|
|
954
|
+
},
|
|
955
|
+
[callback, ref]
|
|
956
|
+
);
|
|
957
|
+
useEffect(() => {
|
|
958
|
+
document.addEventListener("pointerdown", handlePointer);
|
|
959
|
+
return () => document.removeEventListener("pointerdown", handlePointer);
|
|
960
|
+
}, [handlePointer]);
|
|
1305
961
|
}
|
|
962
|
+
var useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect;
|
|
1306
963
|
|
|
1307
|
-
// src/
|
|
1308
|
-
var
|
|
1309
|
-
"
|
|
1310
|
-
"
|
|
1311
|
-
"
|
|
1312
|
-
"
|
|
1313
|
-
]);
|
|
1314
|
-
var DOCK_EVENTS = Object.freeze({
|
|
1315
|
-
NAVIGATE_START: "DOCK_NAVIGATE_START",
|
|
1316
|
-
NAVIGATE_END: "DOCK_NAVIGATE_END",
|
|
1317
|
-
UPDATE_BADGE: "DOCK_UPDATE_BADGE",
|
|
1318
|
-
NAVIGATE: "DOCK_NAVIGATE",
|
|
1319
|
-
GUARD: "DOCK_GUARD",
|
|
1320
|
-
NOT_FOUND: "DOCK_NOT_FOUND",
|
|
1321
|
-
STATUS_SET: "DOCK_STATUS_SET",
|
|
1322
|
-
STATUS_CLEAR: "DOCK_STATUS_CLEAR"
|
|
1323
|
-
});
|
|
1324
|
-
var DOCK_HUD_RENDER_MODE = Object.freeze({
|
|
1325
|
-
COMPONENT: "component",
|
|
1326
|
-
NODE: "node"
|
|
1327
|
-
});
|
|
1328
|
-
var DOCK_HUD_VARIANT = Object.freeze({
|
|
1329
|
-
EXPANDED: "expanded",
|
|
1330
|
-
PROGRESS: "progress",
|
|
1331
|
-
CUSTOM: "custom"
|
|
1332
|
-
});
|
|
1333
|
-
var DOCK_HUD_PRIORITY = Object.freeze({
|
|
1334
|
-
TASK_PROGRESS: 30,
|
|
1335
|
-
CONTEXTUAL: 10,
|
|
1336
|
-
SELECTION: 20,
|
|
1337
|
-
CRITICAL: 50,
|
|
1338
|
-
DEFAULT: 0,
|
|
1339
|
-
MEDIA: 15
|
|
1340
|
-
});
|
|
1341
|
-
var DOCK_ATTENTION_KIND = Object.freeze({
|
|
1342
|
-
SURFACE: "surface",
|
|
1343
|
-
OPERATION: "operation",
|
|
1344
|
-
LOADING: "loading",
|
|
1345
|
-
STATUS: "status",
|
|
1346
|
-
ROUTE: "route",
|
|
1347
|
-
HUD: "hud"
|
|
1348
|
-
});
|
|
1349
|
-
var DOCK_ATTENTION_PRIORITY = Object.freeze({
|
|
1350
|
-
STATUS_OVERLAY: 300,
|
|
1351
|
-
SURFACE: 400,
|
|
1352
|
-
OPERATION: 250,
|
|
1353
|
-
LOADING: 100,
|
|
1354
|
-
STATUS: 75,
|
|
1355
|
-
ROUTE: 0,
|
|
1356
|
-
HUD: 200
|
|
1357
|
-
});
|
|
1358
|
-
var DOCK_ATTENTION_PRIORITY_OFFSET_MAX = 99;
|
|
1359
|
-
var DOCK_SURFACE_RENDER_MODE = Object.freeze({
|
|
1360
|
-
COMPONENT: "component",
|
|
1361
|
-
NODE: "node"
|
|
1362
|
-
});
|
|
1363
|
-
var DOCK_SURFACE_FLOW_STATUS = Object.freeze({
|
|
1364
|
-
OPEN: "open",
|
|
1365
|
-
COMPLETED: "completed",
|
|
1366
|
-
CANCELLED: "cancelled"
|
|
1367
|
-
});
|
|
1368
|
-
var DOCK_SURFACE_PHASE = Object.freeze({
|
|
1369
|
-
IDLE: "idle",
|
|
1370
|
-
DISMISSING_ACTION: "dismissing_action",
|
|
1371
|
-
EXPANDING_BODY: "expanding_body",
|
|
1372
|
-
OPEN: "open",
|
|
1373
|
-
CLOSING_ANTICIPATION: "closing_anticipation",
|
|
1374
|
-
COLLAPSING_BODY: "collapsing_body",
|
|
1375
|
-
RESTORING_HEADER: "restoring_header"
|
|
1376
|
-
});
|
|
1377
|
-
var VIEWPORT_MARGIN = 24;
|
|
1378
|
-
var DOCK_CARD_DIMENSIONS = Object.freeze({
|
|
1379
|
-
expandedY: -72,
|
|
1380
|
-
chromeHeight: 20,
|
|
1381
|
-
collapsedY: -10,
|
|
1382
|
-
extensionShelfY: -42,
|
|
1383
|
-
extensionShelfScale: 0.94,
|
|
1384
|
-
extensionShelfHeight: 45,
|
|
1385
|
-
hudHeight: 52,
|
|
1386
|
-
actionGap: 10,
|
|
1387
|
-
height: 68
|
|
1388
|
-
});
|
|
1389
|
-
var DOCK_CARD_LAYOUT = Object.freeze({
|
|
1390
|
-
collapsed: Object.freeze({
|
|
1391
|
-
offsetY: DOCK_CARD_DIMENSIONS.collapsedY,
|
|
1392
|
-
scale: 0.88
|
|
1393
|
-
}),
|
|
1394
|
-
expanded: Object.freeze({
|
|
1395
|
-
offsetY: DOCK_CARD_DIMENSIONS.expandedY,
|
|
1396
|
-
scale: 1
|
|
1397
|
-
}),
|
|
1398
|
-
extensionShelfY: DOCK_CARD_DIMENSIONS.extensionShelfY,
|
|
1399
|
-
extensionShelfScale: DOCK_CARD_DIMENSIONS.extensionShelfScale,
|
|
1400
|
-
extensionShelfHeight: DOCK_CARD_DIMENSIONS.extensionShelfHeight,
|
|
1401
|
-
chromeHeight: DOCK_CARD_DIMENSIONS.chromeHeight,
|
|
1402
|
-
hudHeight: DOCK_CARD_DIMENSIONS.hudHeight,
|
|
1403
|
-
actionGap: DOCK_CARD_DIMENSIONS.actionGap,
|
|
1404
|
-
baseHeight: DOCK_CARD_DIMENSIONS.height
|
|
1405
|
-
});
|
|
1406
|
-
var DOCK_TRANSACTION_EVENTS = Object.freeze({
|
|
1407
|
-
START: "START",
|
|
1408
|
-
COMPLETE: "COMPLETE",
|
|
1409
|
-
CANCEL: "CANCEL",
|
|
1410
|
-
FAIL: "FAIL",
|
|
1411
|
-
TIME_OUT: "TIME_OUT"
|
|
1412
|
-
});
|
|
1413
|
-
var DOCK_TRANSACTION_STATUS = Object.freeze({
|
|
1414
|
-
PENDING: "pending",
|
|
1415
|
-
COMPLETED: "completed",
|
|
1416
|
-
CANCELLED: "cancelled",
|
|
1417
|
-
FAILED: "failed",
|
|
1418
|
-
TIMED_OUT: "timed-out"
|
|
1419
|
-
});
|
|
1420
|
-
var DOCK_TRANSACTION_REASON = Object.freeze({
|
|
1421
|
-
GUARD: "guard",
|
|
1422
|
-
SUPERSEDED: "superseded",
|
|
1423
|
-
TIME_OUT: "time-out"
|
|
1424
|
-
});
|
|
1425
|
-
var DOCK_TRANSACTION_TIMEOUT_MS = 15e3;
|
|
1426
|
-
var DOCK_PREFETCH_INTENT_DELAY_MS = 90;
|
|
1427
|
-
var DOCK_CONTINUITY_EVENTS = Object.freeze({
|
|
1428
|
-
CLEAR: "CLEAR",
|
|
1429
|
-
CONSUME_RETURN: "CONSUME_RETURN",
|
|
1430
|
-
DELIVER_RETURN: "DELIVER_RETURN",
|
|
1431
|
-
RECORD: "RECORD",
|
|
1432
|
-
REMOVE: "REMOVE"
|
|
1433
|
-
});
|
|
1434
|
-
var DOCK_CONTINUITY_MAX_ENTRIES = 32;
|
|
1435
|
-
var DOCK_SURFACE_RETURN_MAX_ENTRIES = 16;
|
|
1436
|
-
var DOCK_OPERATION_EVENTS = Object.freeze({
|
|
1437
|
-
CANCEL: "CANCEL",
|
|
1438
|
-
CLEAR: "CLEAR",
|
|
1439
|
-
COMPLETE: "COMPLETE",
|
|
1440
|
-
START: "START",
|
|
1441
|
-
UPDATE: "UPDATE"
|
|
1442
|
-
});
|
|
1443
|
-
var DOCK_OPERATION_STATUS = Object.freeze({
|
|
1444
|
-
CANCELLED: "cancelled",
|
|
1445
|
-
COMPLETED: "completed",
|
|
1446
|
-
PENDING: "pending"
|
|
1447
|
-
});
|
|
1448
|
-
var DOCK_OPERATION_MAX_ENTRIES = 24;
|
|
1449
|
-
var DOCK_FOCUSABLE_SELECTOR = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
1450
|
-
var DOCK_FOCUS_RESTORE_BLOCKED_REASONS = Object.freeze([
|
|
1451
|
-
"browser-back",
|
|
1452
|
-
"dock",
|
|
1453
|
-
"unmount"
|
|
1454
|
-
]);
|
|
1455
|
-
var DOCK_LIFECYCLE = Object.freeze({
|
|
1456
|
-
CLOSING: "closing",
|
|
1457
|
-
OPENING: "opening",
|
|
1458
|
-
IDLE: "idle",
|
|
1459
|
-
OPEN: "open"
|
|
1460
|
-
});
|
|
1461
|
-
var PLAYBACK_RATES = Object.freeze([1, 1.25, 1.5, 2]);
|
|
1462
|
-
var STATUS_PRIORITY = Object.freeze({
|
|
1463
|
-
GUARD: 120,
|
|
1464
|
-
ACCOUNT_DELETE: 115,
|
|
1465
|
-
APP_ERROR: 100,
|
|
1466
|
-
API_ERROR: 95,
|
|
1467
|
-
NOT_FOUND: 97,
|
|
1468
|
-
OFFLINE: 90,
|
|
1469
|
-
LOGOUT: 110,
|
|
1470
|
-
SIGNUP: 110,
|
|
1471
|
-
LOGIN: 110,
|
|
1472
|
-
ONLINE: 10
|
|
964
|
+
// src/events.ts
|
|
965
|
+
var EVENT_TYPES = Object.freeze({
|
|
966
|
+
API_UNAUTHORIZED: "API_UNAUTHORIZED",
|
|
967
|
+
STATE_CHANGE: "STATE_CHANGE",
|
|
968
|
+
API_ERROR: "API_ERROR",
|
|
969
|
+
APP_ERROR: "APP_ERROR"
|
|
1473
970
|
});
|
|
1474
|
-
var
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
// src/modules/dock/utils.ts
|
|
1491
|
-
function isSamePath(left, right) {
|
|
1492
|
-
const normalizedLeft = normalizePath(left);
|
|
1493
|
-
const normalizedRight = normalizePath(right);
|
|
1494
|
-
return Boolean(
|
|
1495
|
-
normalizedLeft && normalizedRight && normalizedLeft === normalizedRight
|
|
1496
|
-
);
|
|
1497
|
-
}
|
|
1498
|
-
function isPathPrefix(candidatePath, pathname) {
|
|
1499
|
-
const normalizedCandidate = normalizePath(candidatePath);
|
|
1500
|
-
const normalizedPathname = normalizePath(pathname);
|
|
1501
|
-
if (!normalizedCandidate || !normalizedPathname) return false;
|
|
1502
|
-
if (normalizedCandidate === normalizedPathname) return true;
|
|
1503
|
-
if (normalizedCandidate === "/") return normalizedPathname.startsWith("/");
|
|
1504
|
-
return normalizedPathname.startsWith(`${normalizedCandidate}/`);
|
|
1505
|
-
}
|
|
1506
|
-
function isInlineActionPathMatch(path, pathname) {
|
|
1507
|
-
return isSamePath(path, pathname) || path !== "/" && isPathPrefix(path, pathname);
|
|
1508
|
-
}
|
|
1509
|
-
function isSafeInternalHref(value) {
|
|
1510
|
-
const href = typeof value === "string" ? value.trim() : "";
|
|
1511
|
-
return href.startsWith("/") && !href.startsWith("//");
|
|
1512
|
-
}
|
|
1513
|
-
function getDockLocationKey({
|
|
1514
|
-
hash = "",
|
|
1515
|
-
pathname = "/",
|
|
1516
|
-
search = ""
|
|
1517
|
-
} = {}) {
|
|
1518
|
-
const normalizedPathname = String(pathname || "/").trim() || "/";
|
|
1519
|
-
const normalizedSearch = String(search || "").trim();
|
|
1520
|
-
const normalizedHash = String(hash || "").trim();
|
|
1521
|
-
const query = normalizedSearch ? normalizedSearch.startsWith("?") ? normalizedSearch : `?${normalizedSearch}` : "";
|
|
1522
|
-
const fragment = normalizedHash ? normalizedHash.startsWith("#") ? normalizedHash : `#${normalizedHash}` : "";
|
|
1523
|
-
return `${normalizedPathname}${query}${fragment}`;
|
|
1524
|
-
}
|
|
1525
|
-
function formatMediaTime(seconds = 0) {
|
|
1526
|
-
const sec = Math.max(0, Math.floor(Number(seconds) || 0));
|
|
1527
|
-
const m = Math.floor(sec / 60);
|
|
1528
|
-
const s = sec % 60;
|
|
1529
|
-
return `${m}:${s < 10 ? "0" : ""}${s}`;
|
|
1530
|
-
}
|
|
1531
|
-
function isValidBannerUrl(banner) {
|
|
1532
|
-
const value = trimToNull(banner);
|
|
1533
|
-
if (!value) return false;
|
|
1534
|
-
return /^(https?:\/\/|\/|data:image\/)/.test(value);
|
|
1535
|
-
}
|
|
1536
|
-
function toObject(value) {
|
|
1537
|
-
return isObject(value) ? value : {};
|
|
1538
|
-
}
|
|
1539
|
-
function isValidComponentType(type) {
|
|
1540
|
-
if (typeof type === "function") return true;
|
|
1541
|
-
return Boolean(
|
|
1542
|
-
type != null && typeof type === "object" && !isValidElement(type) && "$$typeof" in type
|
|
1543
|
-
);
|
|
1544
|
-
}
|
|
1545
|
-
function resolveComponentType(...candidates) {
|
|
1546
|
-
return candidates.find(isValidComponentType) ?? null;
|
|
1547
|
-
}
|
|
1548
|
-
function resolveRenderableContent(...candidates) {
|
|
1549
|
-
return candidates.find(
|
|
1550
|
-
(candidate) => candidate !== null && candidate !== void 0
|
|
1551
|
-
) ?? null;
|
|
1552
|
-
}
|
|
1553
|
-
function collectSearchableText(value, visitedObjects) {
|
|
1554
|
-
if (typeof value === "string") return value;
|
|
1555
|
-
if (typeof value === "number" || typeof value === "boolean")
|
|
1556
|
-
return String(value);
|
|
1557
|
-
if (Array.isArray(value)) {
|
|
1558
|
-
if (visitedObjects.has(value)) return "";
|
|
1559
|
-
visitedObjects.add(value);
|
|
1560
|
-
const text = value.map((entry) => collectSearchableText(entry, visitedObjects)).join(" ");
|
|
1561
|
-
visitedObjects.delete(value);
|
|
1562
|
-
return text;
|
|
971
|
+
var EventEmitter = class {
|
|
972
|
+
events = /* @__PURE__ */ new Map();
|
|
973
|
+
debounceTimers = /* @__PURE__ */ new Map();
|
|
974
|
+
subscribe(event, callback) {
|
|
975
|
+
if (typeof event !== "string" || !event || typeof callback !== "function") {
|
|
976
|
+
return () => {
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
const listeners2 = this.events.get(event) || /* @__PURE__ */ new Set();
|
|
980
|
+
listeners2.add(callback);
|
|
981
|
+
this.events.set(event, listeners2);
|
|
982
|
+
return () => {
|
|
983
|
+
listeners2.delete(callback);
|
|
984
|
+
if (listeners2.size === 0) this.events.delete(event);
|
|
985
|
+
};
|
|
1563
986
|
}
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
const
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
987
|
+
emit(event, payload) {
|
|
988
|
+
const listeners2 = this.events.get(event);
|
|
989
|
+
if (!listeners2 || listeners2.size === 0) return;
|
|
990
|
+
const snapshot = Array.from(listeners2);
|
|
991
|
+
for (const callback of snapshot) {
|
|
992
|
+
try {
|
|
993
|
+
callback(payload);
|
|
994
|
+
} catch (error) {
|
|
995
|
+
report(`Event listener (${String(event)})`, error);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
1573
998
|
}
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
999
|
+
emitDebounced(event, payload, waitMs = 100) {
|
|
1000
|
+
const existing = this.debounceTimers.get(event);
|
|
1001
|
+
if (existing) clearTimeout(existing);
|
|
1002
|
+
const timer = setTimeout(() => {
|
|
1003
|
+
this.debounceTimers.delete(event);
|
|
1004
|
+
this.emit(event, payload);
|
|
1005
|
+
}, waitMs);
|
|
1006
|
+
this.debounceTimers.set(event, timer);
|
|
1578
1007
|
}
|
|
1579
|
-
|
|
1008
|
+
cancelDebounced(event) {
|
|
1009
|
+
if (event) {
|
|
1010
|
+
const timer = this.debounceTimers.get(event);
|
|
1011
|
+
if (timer) {
|
|
1012
|
+
clearTimeout(timer);
|
|
1013
|
+
this.debounceTimers.delete(event);
|
|
1014
|
+
}
|
|
1015
|
+
} else {
|
|
1016
|
+
for (const timer of this.debounceTimers.values()) {
|
|
1017
|
+
clearTimeout(timer);
|
|
1018
|
+
}
|
|
1019
|
+
this.debounceTimers.clear();
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
unsubscribeAll(event) {
|
|
1023
|
+
this.cancelDebounced(event);
|
|
1024
|
+
if (event) this.events.delete(event);
|
|
1025
|
+
else this.events.clear();
|
|
1026
|
+
}
|
|
1027
|
+
hasListeners(event) {
|
|
1028
|
+
return Boolean(this.events.get(event)?.size);
|
|
1029
|
+
}
|
|
1030
|
+
getListenerCount(event) {
|
|
1031
|
+
return this.events.get(event)?.size || 0;
|
|
1032
|
+
}
|
|
1033
|
+
getAllEvents() {
|
|
1034
|
+
return [...this.events.keys()];
|
|
1035
|
+
}
|
|
1036
|
+
};
|
|
1037
|
+
var GLOBAL_EVENTS_KEY = /* @__PURE__ */ Symbol.for("__base_framework_global_events__");
|
|
1038
|
+
var _global = globalThis;
|
|
1039
|
+
var globalEvents = _global[GLOBAL_EVENTS_KEY] ?? (_global[GLOBAL_EVENTS_KEY] = new EventEmitter());
|
|
1040
|
+
|
|
1041
|
+
// src/hooks/use-global-event.ts
|
|
1042
|
+
function useGlobalEvent(event, callback, options) {
|
|
1043
|
+
const callbackRef = useRef(callback);
|
|
1044
|
+
const debounceTimerRef = useRef(null);
|
|
1045
|
+
useRef(0);
|
|
1046
|
+
const throttleTimerRef = useRef(null);
|
|
1047
|
+
useIsomorphicLayoutEffect(() => {
|
|
1048
|
+
callbackRef.current = callback;
|
|
1049
|
+
});
|
|
1050
|
+
const debounceMs = options?.debounceMs;
|
|
1051
|
+
const throttleMs = options?.throttleMs;
|
|
1052
|
+
useEffect(() => {
|
|
1053
|
+
if (!event) return;
|
|
1054
|
+
const events = Array.isArray(event) ? event.filter(Boolean) : [event];
|
|
1055
|
+
if (events.length === 0) return;
|
|
1056
|
+
const handler = (payload) => {
|
|
1057
|
+
callbackRef.current?.(payload);
|
|
1058
|
+
};
|
|
1059
|
+
const unsubs = events.map((ev) => globalEvents.subscribe(ev, handler));
|
|
1060
|
+
return () => {
|
|
1061
|
+
unsubs.forEach((unsub) => unsub());
|
|
1062
|
+
if (debounceTimerRef.current !== null) {
|
|
1063
|
+
clearTimeout(debounceTimerRef.current);
|
|
1064
|
+
debounceTimerRef.current = null;
|
|
1065
|
+
}
|
|
1066
|
+
if (throttleTimerRef.current !== null) {
|
|
1067
|
+
clearTimeout(throttleTimerRef.current);
|
|
1068
|
+
throttleTimerRef.current = null;
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
}, [event, debounceMs, throttleMs]);
|
|
1580
1072
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1073
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
1074
|
+
var activeFullscreenStateIds = /* @__PURE__ */ new Set();
|
|
1075
|
+
var ACTIVE_FULLSCREEN_ROOT_SELECTOR = '[data-fullscreen-state-root="true"][data-affect-global-state="true"]';
|
|
1076
|
+
var domObserver = null;
|
|
1077
|
+
var lastSnapshot = false;
|
|
1078
|
+
function getDomSnapshot() {
|
|
1079
|
+
if (typeof document === "undefined") {
|
|
1080
|
+
return activeFullscreenStateIds.size > 0;
|
|
1081
|
+
}
|
|
1082
|
+
return document.querySelector(ACTIVE_FULLSCREEN_ROOT_SELECTOR) !== null;
|
|
1583
1083
|
}
|
|
1584
|
-
function
|
|
1585
|
-
|
|
1084
|
+
function emitChange() {
|
|
1085
|
+
listeners.forEach((listener) => listener());
|
|
1586
1086
|
}
|
|
1587
|
-
function
|
|
1588
|
-
const
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1087
|
+
function emitIfSnapshotChanged() {
|
|
1088
|
+
const nextSnapshot = getDomSnapshot();
|
|
1089
|
+
if (nextSnapshot === lastSnapshot) {
|
|
1090
|
+
return;
|
|
1091
|
+
}
|
|
1092
|
+
lastSnapshot = nextSnapshot;
|
|
1093
|
+
emitChange();
|
|
1593
1094
|
}
|
|
1594
|
-
function
|
|
1595
|
-
if (
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1095
|
+
function ensureDomObserver() {
|
|
1096
|
+
if (typeof document === "undefined" || domObserver || listeners.size === 0) {
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
domObserver = new MutationObserver(() => {
|
|
1100
|
+
emitIfSnapshotChanged();
|
|
1101
|
+
});
|
|
1102
|
+
domObserver.observe(document.documentElement, {
|
|
1103
|
+
attributes: true,
|
|
1104
|
+
childList: true,
|
|
1105
|
+
subtree: true,
|
|
1106
|
+
attributeFilter: [
|
|
1107
|
+
"data-fullscreen-state",
|
|
1108
|
+
"data-fullscreen-state-root",
|
|
1109
|
+
"data-affect-global-state"
|
|
1110
|
+
]
|
|
1111
|
+
});
|
|
1603
1112
|
}
|
|
1604
|
-
function
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
}
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
return {
|
|
1611
|
-
...nextStyle,
|
|
1612
|
-
backgroundImage: `url(${icon})`
|
|
1613
|
-
};
|
|
1113
|
+
function releaseDomObserver() {
|
|
1114
|
+
if (listeners.size > 0 || !domObserver) {
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
domObserver.disconnect();
|
|
1118
|
+
domObserver = null;
|
|
1614
1119
|
}
|
|
1615
|
-
function
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
cn: classNamesFn
|
|
1623
|
-
} = {}) {
|
|
1624
|
-
const resolve = classNamesFn || cn;
|
|
1625
|
-
const toneClasses = {
|
|
1626
|
-
muted: slots.actionMuted,
|
|
1627
|
-
active: slots.actionActive
|
|
1120
|
+
function subscribe(listener) {
|
|
1121
|
+
listeners.add(listener);
|
|
1122
|
+
ensureDomObserver();
|
|
1123
|
+
emitIfSnapshotChanged();
|
|
1124
|
+
return () => {
|
|
1125
|
+
listeners.delete(listener);
|
|
1126
|
+
releaseDomObserver();
|
|
1628
1127
|
};
|
|
1629
|
-
if (button && !className && base === void 0) {
|
|
1630
|
-
if (tone) {
|
|
1631
|
-
const toneClass = toneClasses[tone] || slots.actionSurface || slots.actionMuted;
|
|
1632
|
-
return resolve(button, toneClass);
|
|
1633
|
-
}
|
|
1634
|
-
const stateToken = isActive ? slots.actionActive : slots.actionMuted;
|
|
1635
|
-
return resolve(button, stateToken);
|
|
1636
|
-
}
|
|
1637
|
-
const elementClass = className || button;
|
|
1638
|
-
const resolvedBase = base !== void 0 ? base : slots.action;
|
|
1639
|
-
const stateClass = variant || tone && (toneClasses[tone] || slots.actionSurface) || (isActive ? slots.actionActive : slots.actionMuted);
|
|
1640
|
-
return resolve(stateClass, resolvedBase, elementClass);
|
|
1641
1128
|
}
|
|
1642
|
-
function
|
|
1643
|
-
|
|
1644
|
-
const activeElement = document.activeElement;
|
|
1645
|
-
if (activeElement && typeof activeElement.blur === "function") {
|
|
1646
|
-
activeElement.blur();
|
|
1647
|
-
}
|
|
1129
|
+
function getSnapshot() {
|
|
1130
|
+
return getDomSnapshot();
|
|
1648
1131
|
}
|
|
1649
|
-
function
|
|
1650
|
-
|
|
1651
|
-
return Boolean(
|
|
1652
|
-
element && typeof element.closest === "function" && element.closest(selector)
|
|
1653
|
-
);
|
|
1132
|
+
function useIsFullscreenStateActive() {
|
|
1133
|
+
return useSyncExternalStore(subscribe, getSnapshot, () => false);
|
|
1654
1134
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1135
|
+
var RegistryContext = getOrCreateGlobalContext(
|
|
1136
|
+
"RegistryContext",
|
|
1137
|
+
null
|
|
1138
|
+
);
|
|
1139
|
+
function useRegistryActions() {
|
|
1140
|
+
return useRequiredContext(
|
|
1141
|
+
RegistryContext,
|
|
1142
|
+
"useRegistryActions",
|
|
1143
|
+
"RegistryProvider"
|
|
1144
|
+
).actions;
|
|
1660
1145
|
}
|
|
1661
|
-
function
|
|
1662
|
-
return
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1146
|
+
function useRegistrySubscription() {
|
|
1147
|
+
return useRequiredContext(
|
|
1148
|
+
RegistryContext,
|
|
1149
|
+
"useRegistrySubscription",
|
|
1150
|
+
"RegistryProvider"
|
|
1151
|
+
).subscription;
|
|
1666
1152
|
}
|
|
1667
|
-
function
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1153
|
+
function useRegistryEntries(type) {
|
|
1154
|
+
const { getEntriesSnapshot, subscribe: subscribe2 } = useRegistrySubscription();
|
|
1155
|
+
const subscribeToType = useCallback(
|
|
1156
|
+
(listener) => subscribe2(type, null, listener),
|
|
1157
|
+
[subscribe2, type]
|
|
1158
|
+
);
|
|
1159
|
+
const getEntries = useCallback(
|
|
1160
|
+
() => getEntriesSnapshot(type),
|
|
1161
|
+
[getEntriesSnapshot, type]
|
|
1162
|
+
);
|
|
1163
|
+
return useSyncExternalStore(subscribeToType, getEntries, getEntries);
|
|
1677
1164
|
}
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1165
|
+
var EMPTY_MODULES = Object.freeze([]);
|
|
1166
|
+
var ModuleHostContext = getOrCreateGlobalContext("ModuleHostContext", null);
|
|
1167
|
+
function selectModuleSlice(coreModule, config) {
|
|
1168
|
+
const slice = coreModule.page?.select ? coreModule.page.select(config) : config[coreModule.id];
|
|
1169
|
+
return slice ?? null;
|
|
1170
|
+
}
|
|
1171
|
+
function createModulePayload(modules, config, metadata = {}) {
|
|
1172
|
+
const payload = {};
|
|
1173
|
+
let hasSlices = false;
|
|
1174
|
+
for (const coreModule of modules) {
|
|
1175
|
+
if (!coreModule.page?.entries) continue;
|
|
1176
|
+
const slice = selectModuleSlice(coreModule, config);
|
|
1177
|
+
if (slice === null) continue;
|
|
1178
|
+
payload[coreModule.id] = slice;
|
|
1179
|
+
hasSlices = true;
|
|
1685
1180
|
}
|
|
1181
|
+
if (!hasSlices) return null;
|
|
1182
|
+
return {
|
|
1183
|
+
...payload,
|
|
1184
|
+
registry: {
|
|
1185
|
+
...metadata,
|
|
1186
|
+
...isObject(config.registry) ? config.registry : {}
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1686
1189
|
}
|
|
1687
|
-
function
|
|
1688
|
-
|
|
1689
|
-
return !result || !DOCK_FOCUS_RESTORE_BLOCKED_REASONS.includes(
|
|
1690
|
-
blockedReason
|
|
1691
|
-
);
|
|
1190
|
+
function useInstalledModules() {
|
|
1191
|
+
return use(ModuleHostContext)?.modules ?? EMPTY_MODULES;
|
|
1692
1192
|
}
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1193
|
+
|
|
1194
|
+
// src/kernel/handlers.ts
|
|
1195
|
+
function isPersistentLifecycle(lifecycle) {
|
|
1196
|
+
return lifecycle === REGISTRY_LIFECYCLES.PERSISTENT;
|
|
1697
1197
|
}
|
|
1698
|
-
|
|
1699
|
-
function
|
|
1700
|
-
const identity = link?.id ?? link?.path ?? link?.name ?? link?.type;
|
|
1701
|
-
return `dock-card:${identity == null ? `slot-${index}` : String(identity)}`;
|
|
1198
|
+
function runRegistrationBatch(context, executor) {
|
|
1199
|
+
return typeof context.batch === "function" ? context.batch(executor) : executor(context);
|
|
1702
1200
|
}
|
|
1703
|
-
function
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1201
|
+
function createEntryCleanupKey(type, key, source, instanceId, scope) {
|
|
1202
|
+
return JSON.stringify([
|
|
1203
|
+
"entry",
|
|
1204
|
+
type,
|
|
1205
|
+
key,
|
|
1206
|
+
scope ?? null,
|
|
1207
|
+
source,
|
|
1208
|
+
instanceId
|
|
1209
|
+
]);
|
|
1710
1210
|
}
|
|
1711
|
-
function
|
|
1712
|
-
return
|
|
1211
|
+
function getCleanupScope(context) {
|
|
1212
|
+
return context?.cleanupScope || /* @__PURE__ */ new Map();
|
|
1713
1213
|
}
|
|
1714
|
-
function
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
const identityPart = link?.path || link?.name || link?.id || "item";
|
|
1721
|
-
const titlePart = link?.title || link?.name || "";
|
|
1722
|
-
const descPart = description || "";
|
|
1723
|
-
const iconPart = showVideoIcon ? "video" : link?.icon || "no-icon";
|
|
1724
|
-
return `${statusPart}:${identityPart}:${iconPart}:${titlePart}:${descPart}`;
|
|
1214
|
+
function clearCleanupTimer(scope, cleanupKey) {
|
|
1215
|
+
const lifecycle = scope.get(cleanupKey);
|
|
1216
|
+
if (!lifecycle) return;
|
|
1217
|
+
lifecycle.cancelled = true;
|
|
1218
|
+
if (lifecycle.timerId !== null) clearTimeout(lifecycle.timerId);
|
|
1219
|
+
scope.delete(cleanupKey);
|
|
1725
1220
|
}
|
|
1726
|
-
function
|
|
1727
|
-
|
|
1728
|
-
const
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
);
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
return dockItems.findIndex(
|
|
1739
|
-
(item) => isSamePath(item.path, normalizedPathname) || item.targetPath && isSamePath(item.targetPath, normalizedPathname)
|
|
1740
|
-
);
|
|
1221
|
+
function scheduleCleanup(scope, cleanupKey, callback, delayMs) {
|
|
1222
|
+
clearCleanupTimer(scope, cleanupKey);
|
|
1223
|
+
const lifecycle = {
|
|
1224
|
+
cancelled: false,
|
|
1225
|
+
timerId: null
|
|
1226
|
+
};
|
|
1227
|
+
lifecycle.timerId = setTimeout(() => {
|
|
1228
|
+
if (lifecycle.cancelled || scope.get(cleanupKey) !== lifecycle) return;
|
|
1229
|
+
scope.delete(cleanupKey);
|
|
1230
|
+
callback();
|
|
1231
|
+
}, delayMs);
|
|
1232
|
+
scope.set(cleanupKey, lifecycle);
|
|
1741
1233
|
}
|
|
1742
|
-
function
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1234
|
+
function collectModuleRegistrations(coreModule, slice, pageMetadata, context) {
|
|
1235
|
+
const definition = coreModule.registry;
|
|
1236
|
+
const toEntries = coreModule.page?.entries;
|
|
1237
|
+
if (!definition || !toEntries || slice == null || slice === false) return [];
|
|
1238
|
+
const type = coreModule.id;
|
|
1239
|
+
const items = Array.isArray(slice) ? slice : [slice];
|
|
1240
|
+
const registrations = [];
|
|
1241
|
+
for (const item of items) {
|
|
1242
|
+
if (item == null || item === false) continue;
|
|
1243
|
+
const itemMetadata = isObject(item) && isObject(item.registry) ? item.registry : {};
|
|
1244
|
+
const metadata = { ...pageMetadata, ...itemMetadata };
|
|
1245
|
+
if (metadata.validation === "strict" && !validateRegistryMetadata(metadata).valid) {
|
|
1246
|
+
continue;
|
|
1247
|
+
}
|
|
1248
|
+
const payload = isObject(item) ? Object.fromEntries(
|
|
1249
|
+
Object.entries(item).filter(([key]) => key !== "registry")
|
|
1250
|
+
) : item;
|
|
1251
|
+
const { cleanupDelayMs, lifecycle, registerOptions, scope, source } = normalizeRegistryMetadata(metadata, {
|
|
1252
|
+
defaultCleanupDelayMs: definition.cleanupDelayMs ?? null,
|
|
1253
|
+
defaultLifecycle: definition.lifecycle,
|
|
1254
|
+
defaultSource: DEFAULT_SOURCE
|
|
1255
|
+
});
|
|
1256
|
+
for (const { key, value } of toEntries(payload, context) ?? []) {
|
|
1257
|
+
const validation = definition.validate?.(value);
|
|
1258
|
+
if (validation && !validation.valid) {
|
|
1259
|
+
report(`Registry ${type} config is invalid`, validation.issues, "warn");
|
|
1260
|
+
continue;
|
|
1261
|
+
}
|
|
1262
|
+
registrations.push({
|
|
1263
|
+
cleanupDelayMs,
|
|
1264
|
+
cleanupKey: createEntryCleanupKey(
|
|
1265
|
+
type,
|
|
1266
|
+
key,
|
|
1267
|
+
source,
|
|
1268
|
+
context.instanceId,
|
|
1269
|
+
scope
|
|
1270
|
+
),
|
|
1271
|
+
key,
|
|
1272
|
+
lifecycle,
|
|
1273
|
+
registerOptions,
|
|
1274
|
+
scope,
|
|
1275
|
+
source,
|
|
1276
|
+
type,
|
|
1277
|
+
value
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
return registrations;
|
|
1748
1282
|
}
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1283
|
+
var NO_CLEANUP = () => {
|
|
1284
|
+
};
|
|
1285
|
+
function applyRegistryConfig(config, context) {
|
|
1286
|
+
const modules = context.modules ?? [];
|
|
1287
|
+
if (!config || modules.length === 0) return NO_CLEANUP;
|
|
1288
|
+
const pageMetadata = isObject(config.registry) ? config.registry : {};
|
|
1289
|
+
const slices = config;
|
|
1290
|
+
const registrations = modules.flatMap((coreModule) => {
|
|
1752
1291
|
try {
|
|
1753
|
-
return
|
|
1754
|
-
|
|
1755
|
-
|
|
1292
|
+
return collectModuleRegistrations(
|
|
1293
|
+
coreModule,
|
|
1294
|
+
slices[coreModule.id],
|
|
1295
|
+
pageMetadata,
|
|
1296
|
+
context
|
|
1297
|
+
);
|
|
1298
|
+
} catch (error) {
|
|
1299
|
+
report(`Registry apply (${coreModule.id})`, error);
|
|
1300
|
+
return [];
|
|
1756
1301
|
}
|
|
1302
|
+
});
|
|
1303
|
+
if (registrations.length === 0) return NO_CLEANUP;
|
|
1304
|
+
const cleanupScope = getCleanupScope(context);
|
|
1305
|
+
const owner = (registration) => ({
|
|
1306
|
+
instanceId: context.instanceId,
|
|
1307
|
+
scope: registration.scope,
|
|
1308
|
+
source: registration.source
|
|
1309
|
+
});
|
|
1310
|
+
runRegistrationBatch(context, (queue) => {
|
|
1311
|
+
registrations.forEach(
|
|
1312
|
+
({ cleanupKey, key, registerOptions, source, type, value }) => {
|
|
1313
|
+
clearCleanupTimer(cleanupScope, cleanupKey);
|
|
1314
|
+
queue.register(type, key, value, source, registerOptions);
|
|
1315
|
+
}
|
|
1316
|
+
);
|
|
1317
|
+
});
|
|
1318
|
+
return () => {
|
|
1319
|
+
const immediate = [];
|
|
1320
|
+
registrations.forEach((registration) => {
|
|
1321
|
+
if (isPersistentLifecycle(registration.lifecycle)) return;
|
|
1322
|
+
const { cleanupDelayMs, cleanupKey, key, type } = registration;
|
|
1323
|
+
if (typeof cleanupDelayMs === "number" && cleanupDelayMs > 0) {
|
|
1324
|
+
scheduleCleanup(
|
|
1325
|
+
cleanupScope,
|
|
1326
|
+
cleanupKey,
|
|
1327
|
+
() => context.unregister(type, key, owner(registration)),
|
|
1328
|
+
cleanupDelayMs
|
|
1329
|
+
);
|
|
1330
|
+
} else {
|
|
1331
|
+
immediate.push(registration);
|
|
1332
|
+
}
|
|
1333
|
+
});
|
|
1334
|
+
if (immediate.length === 0) return;
|
|
1335
|
+
runRegistrationBatch(context, (queue) => {
|
|
1336
|
+
immediate.forEach(
|
|
1337
|
+
(registration) => queue.unregister(
|
|
1338
|
+
registration.type,
|
|
1339
|
+
registration.key,
|
|
1340
|
+
owner(registration)
|
|
1341
|
+
)
|
|
1342
|
+
);
|
|
1343
|
+
});
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
// src/kernel/hooks.ts
|
|
1348
|
+
function withInstanceId(instanceId, sourceOrOptions, optionsArg) {
|
|
1349
|
+
if (typeof sourceOrOptions === "string") {
|
|
1350
|
+
return {
|
|
1351
|
+
optionsArg: { ...isObject(optionsArg) ? optionsArg : {}, instanceId },
|
|
1352
|
+
sourceOrOptions
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
if (isObject(sourceOrOptions)) {
|
|
1356
|
+
return {
|
|
1357
|
+
optionsArg,
|
|
1358
|
+
sourceOrOptions: { ...sourceOrOptions, instanceId }
|
|
1359
|
+
};
|
|
1757
1360
|
}
|
|
1758
|
-
return
|
|
1361
|
+
return {
|
|
1362
|
+
optionsArg: void 0,
|
|
1363
|
+
sourceOrOptions: {
|
|
1364
|
+
...isObject(optionsArg) ? optionsArg : {},
|
|
1365
|
+
instanceId
|
|
1366
|
+
}
|
|
1367
|
+
};
|
|
1759
1368
|
}
|
|
1760
|
-
function
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1369
|
+
function withInstanceIdForUnregister(instanceId, sourceOrOptions) {
|
|
1370
|
+
if (typeof sourceOrOptions === "string") {
|
|
1371
|
+
return { instanceId, source: sourceOrOptions };
|
|
1372
|
+
}
|
|
1373
|
+
if (isObject(sourceOrOptions)) {
|
|
1374
|
+
return { ...sourceOrOptions, instanceId };
|
|
1375
|
+
}
|
|
1376
|
+
return { instanceId };
|
|
1765
1377
|
}
|
|
1766
|
-
function
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
if (!activePath) return items;
|
|
1770
|
-
return items.filter(
|
|
1771
|
-
(item, index) => index === 0 || !isAncestorPath(item, activePath)
|
|
1772
|
-
);
|
|
1378
|
+
function resolveRegisterArgsWithInstance(instanceId, sourceOrOptions, optionsArg) {
|
|
1379
|
+
const input = withInstanceId(instanceId, sourceOrOptions, optionsArg);
|
|
1380
|
+
return [input.sourceOrOptions, input.optionsArg];
|
|
1773
1381
|
}
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
const
|
|
1777
|
-
|
|
1778
|
-
|
|
1382
|
+
var MAX_STABILIZATION_DEPTH = 64;
|
|
1383
|
+
function createStableFunctionEntry(fn) {
|
|
1384
|
+
const entry = {
|
|
1385
|
+
current: fn,
|
|
1386
|
+
stable(...args) {
|
|
1387
|
+
return entry.current?.apply(this, args);
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
return entry;
|
|
1779
1391
|
}
|
|
1780
|
-
function
|
|
1781
|
-
|
|
1782
|
-
return
|
|
1783
|
-
(item) => !item?.isLoading || isSameItem(item, activeItem)
|
|
1784
|
-
);
|
|
1392
|
+
function isDirectRegistryComponentPath(path, componentSlices) {
|
|
1393
|
+
const match = /^config\.([^.[]+)\.[^.[]+$/.exec(path);
|
|
1394
|
+
return Boolean(match && componentSlices.has(match[1]));
|
|
1785
1395
|
}
|
|
1786
|
-
function
|
|
1787
|
-
|
|
1788
|
-
const active = items[activeIndex];
|
|
1789
|
-
const rest = [
|
|
1790
|
-
...items.slice(0, activeIndex),
|
|
1791
|
-
...items.slice(activeIndex + 1)
|
|
1792
|
-
];
|
|
1793
|
-
rest.sort((a, b) => a.path === "/" ? 1 : b.path === "/" ? -1 : 0);
|
|
1794
|
-
return [active, ...rest];
|
|
1396
|
+
function isReactNodeLike(value) {
|
|
1397
|
+
return value === null || value === void 0 || typeof value === "boolean" || typeof value === "string" || typeof value === "number" || isValidElement(value);
|
|
1795
1398
|
}
|
|
1796
|
-
function
|
|
1797
|
-
return
|
|
1399
|
+
function isStabilizableObject(value) {
|
|
1400
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && !isValidElement(value);
|
|
1798
1401
|
}
|
|
1799
|
-
function
|
|
1800
|
-
|
|
1402
|
+
function hasSameObjectKeys(previousValue, nextValue) {
|
|
1403
|
+
if (!isStabilizableObject(previousValue) || !isStabilizableObject(nextValue)) {
|
|
1404
|
+
return false;
|
|
1405
|
+
}
|
|
1406
|
+
const previousKeys = Object.keys(previousValue);
|
|
1407
|
+
const nextKeys = Object.keys(nextValue);
|
|
1408
|
+
if (previousKeys.length !== nextKeys.length) return false;
|
|
1409
|
+
return nextKeys.every(
|
|
1410
|
+
(key) => Object.prototype.hasOwnProperty.call(previousValue, key)
|
|
1411
|
+
);
|
|
1801
1412
|
}
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
if (
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1413
|
+
function stabilizeRegistryValue(value, path, scope, previousValue, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
|
|
1414
|
+
if (depth > MAX_STABILIZATION_DEPTH) return value;
|
|
1415
|
+
if (typeof value === "function") {
|
|
1416
|
+
const isComponent = value.name && /^[A-Z]/.test(value.name);
|
|
1417
|
+
if (isComponent || isDirectRegistryComponentPath(path, scope.componentSlices)) {
|
|
1418
|
+
return value;
|
|
1419
|
+
}
|
|
1420
|
+
scope.usedPaths.add(path);
|
|
1421
|
+
let entry = scope.functionEntries.get(path);
|
|
1422
|
+
if (!entry) {
|
|
1423
|
+
entry = createStableFunctionEntry(value);
|
|
1424
|
+
scope.functionEntries.set(path, entry);
|
|
1425
|
+
} else {
|
|
1426
|
+
entry.current = value;
|
|
1427
|
+
}
|
|
1428
|
+
return entry.stable;
|
|
1816
1429
|
}
|
|
1817
|
-
if (typeof
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
if (
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
)
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
}
|
|
1430
|
+
if (value && typeof value === "object") {
|
|
1431
|
+
if (seen.has(value)) return value;
|
|
1432
|
+
seen.add(value);
|
|
1433
|
+
}
|
|
1434
|
+
if (isValidElement(value)) {
|
|
1435
|
+
const nextProps = stabilizeRegistryValue(
|
|
1436
|
+
value.props,
|
|
1437
|
+
`${path}.props`,
|
|
1438
|
+
scope,
|
|
1439
|
+
isValidElement(previousValue) ? previousValue.props : void 0,
|
|
1440
|
+
seen,
|
|
1441
|
+
depth + 1
|
|
1442
|
+
);
|
|
1443
|
+
if (isValidElement(previousValue) && previousValue.type === value.type && previousValue.key === value.key && previousValue.props === nextProps) {
|
|
1444
|
+
return previousValue;
|
|
1445
|
+
}
|
|
1446
|
+
return cloneElement(value, nextProps);
|
|
1447
|
+
}
|
|
1448
|
+
if (Array.isArray(value)) {
|
|
1449
|
+
const nextValue = value.every(isReactNodeLike) ? Children.toArray(value) : value;
|
|
1450
|
+
const previousArray = Array.isArray(previousValue) ? previousValue : null;
|
|
1451
|
+
let hasChanged2 = !previousArray || previousArray.length !== nextValue.length;
|
|
1452
|
+
const stabilizedValue2 = nextValue.map((item, index) => {
|
|
1453
|
+
const nextItem = stabilizeRegistryValue(
|
|
1454
|
+
item,
|
|
1455
|
+
`${path}[${index}]`,
|
|
1456
|
+
scope,
|
|
1457
|
+
previousArray?.[index],
|
|
1458
|
+
seen,
|
|
1459
|
+
depth + 1
|
|
1460
|
+
);
|
|
1461
|
+
if (!previousArray || nextItem !== previousArray[index]) {
|
|
1462
|
+
hasChanged2 = true;
|
|
1463
|
+
}
|
|
1464
|
+
return nextItem;
|
|
1465
|
+
});
|
|
1466
|
+
return !hasChanged2 ? previousArray : stabilizedValue2;
|
|
1467
|
+
}
|
|
1468
|
+
if (typeof value !== "object" || value === null) {
|
|
1469
|
+
return value;
|
|
1470
|
+
}
|
|
1471
|
+
const source = value;
|
|
1472
|
+
const previousRecord = previousValue;
|
|
1473
|
+
const stabilizedValue = {};
|
|
1474
|
+
const canReusePrevious = hasSameObjectKeys(previousValue, value);
|
|
1475
|
+
let hasChanged = !canReusePrevious;
|
|
1476
|
+
Object.keys(source).forEach((key) => {
|
|
1477
|
+
const nextValue = stabilizeRegistryValue(
|
|
1478
|
+
source[key],
|
|
1479
|
+
`${path}.${key}`,
|
|
1480
|
+
scope,
|
|
1481
|
+
previousRecord?.[key],
|
|
1482
|
+
seen,
|
|
1483
|
+
depth + 1
|
|
1484
|
+
);
|
|
1485
|
+
stabilizedValue[key] = nextValue;
|
|
1486
|
+
if (!canReusePrevious || nextValue !== previousRecord?.[key]) {
|
|
1487
|
+
hasChanged = true;
|
|
1488
|
+
}
|
|
1489
|
+
});
|
|
1490
|
+
return !hasChanged ? previousValue : stabilizedValue;
|
|
1835
1491
|
}
|
|
1836
|
-
function
|
|
1837
|
-
|
|
1838
|
-
|
|
1492
|
+
function useAppliedRegistryConfig(payload, context, componentSlices) {
|
|
1493
|
+
const functionEntriesRef = useRef(/* @__PURE__ */ new Map());
|
|
1494
|
+
const appliedRef = useRef(null);
|
|
1495
|
+
useIsomorphicLayoutEffect(() => {
|
|
1496
|
+
const previous = appliedRef.current;
|
|
1497
|
+
if (previous && previous.payload === payload && previous.context === context) {
|
|
1498
|
+
return;
|
|
1499
|
+
}
|
|
1500
|
+
const functionEntries = functionEntriesRef.current;
|
|
1501
|
+
const usedPaths = /* @__PURE__ */ new Set();
|
|
1502
|
+
const config = stabilizeRegistryValue(
|
|
1503
|
+
payload,
|
|
1504
|
+
"config",
|
|
1505
|
+
{ componentSlices, functionEntries, usedPaths },
|
|
1506
|
+
previous?.config
|
|
1507
|
+
);
|
|
1508
|
+
functionEntries.forEach((_entry, path) => {
|
|
1509
|
+
if (!usedPaths.has(path)) functionEntries.delete(path);
|
|
1510
|
+
});
|
|
1511
|
+
if (previous && previous.config === config && previous.context === context) {
|
|
1512
|
+
previous.payload = payload;
|
|
1513
|
+
return;
|
|
1514
|
+
}
|
|
1515
|
+
previous?.cleanup();
|
|
1516
|
+
appliedRef.current = {
|
|
1517
|
+
cleanup: applyRegistryConfig(config, context),
|
|
1518
|
+
config,
|
|
1519
|
+
context,
|
|
1520
|
+
payload
|
|
1521
|
+
};
|
|
1522
|
+
});
|
|
1523
|
+
useIsomorphicLayoutEffect(
|
|
1524
|
+
() => () => {
|
|
1525
|
+
appliedRef.current?.cleanup();
|
|
1526
|
+
appliedRef.current = null;
|
|
1527
|
+
},
|
|
1528
|
+
[]
|
|
1529
|
+
);
|
|
1839
1530
|
}
|
|
1840
|
-
function
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1531
|
+
function createRegistryApplyContext(actions, {
|
|
1532
|
+
cleanupScope = /* @__PURE__ */ new Map(),
|
|
1533
|
+
instanceId,
|
|
1534
|
+
modules = [],
|
|
1535
|
+
pathname
|
|
1536
|
+
}) {
|
|
1537
|
+
const stamp = (queue) => ({
|
|
1538
|
+
register: (type, key, item, sourceOrOptions, optionsArg) => queue.register(
|
|
1539
|
+
type,
|
|
1540
|
+
key,
|
|
1541
|
+
item,
|
|
1542
|
+
...resolveRegisterArgsWithInstance(
|
|
1543
|
+
instanceId,
|
|
1544
|
+
sourceOrOptions,
|
|
1545
|
+
optionsArg
|
|
1546
|
+
)
|
|
1547
|
+
),
|
|
1548
|
+
unregister: (type, key, sourceOrOptions) => queue.unregister(
|
|
1549
|
+
type,
|
|
1550
|
+
key,
|
|
1551
|
+
withInstanceIdForUnregister(instanceId, sourceOrOptions)
|
|
1552
|
+
)
|
|
1553
|
+
});
|
|
1844
1554
|
return {
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1555
|
+
...stamp(actions),
|
|
1556
|
+
batch: (executor) => typeof executor === "function" ? actions.batch((queue) => executor(stamp(queue))) : 0,
|
|
1557
|
+
cleanupScope,
|
|
1558
|
+
instanceId,
|
|
1559
|
+
modules,
|
|
1560
|
+
pathname
|
|
1849
1561
|
};
|
|
1850
1562
|
}
|
|
1851
|
-
function
|
|
1852
|
-
const
|
|
1853
|
-
const
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
const
|
|
1860
|
-
|
|
1861
|
-
|
|
1563
|
+
function useRegistry(config, metadata) {
|
|
1564
|
+
const { batch, register, unregister } = useRegistryActions();
|
|
1565
|
+
const pathname = usePathname();
|
|
1566
|
+
const modules = useInstalledModules();
|
|
1567
|
+
const instanceId = `registry-instance-${useId()}`;
|
|
1568
|
+
const [cleanupScope] = useState(
|
|
1569
|
+
() => /* @__PURE__ */ new Map()
|
|
1570
|
+
);
|
|
1571
|
+
const context = useMemo(
|
|
1572
|
+
() => createRegistryApplyContext(
|
|
1573
|
+
{ batch, register, unregister },
|
|
1574
|
+
{
|
|
1575
|
+
cleanupScope,
|
|
1576
|
+
instanceId,
|
|
1577
|
+
modules,
|
|
1578
|
+
pathname
|
|
1579
|
+
}
|
|
1580
|
+
),
|
|
1581
|
+
[batch, cleanupScope, instanceId, modules, pathname, register, unregister]
|
|
1582
|
+
);
|
|
1583
|
+
const payload = useMemo(
|
|
1584
|
+
() => config ? createModulePayload(modules, config, metadata) : null,
|
|
1585
|
+
[config, metadata, modules]
|
|
1586
|
+
);
|
|
1587
|
+
const componentSlices = useMemo(
|
|
1588
|
+
() => new Set(
|
|
1589
|
+
modules.filter(
|
|
1590
|
+
(coreModule) => coreModule.registry?.valueKind === "component"
|
|
1591
|
+
).map((coreModule) => coreModule.id)
|
|
1592
|
+
),
|
|
1593
|
+
[modules]
|
|
1594
|
+
);
|
|
1595
|
+
useAppliedRegistryConfig(payload, context, componentSlices);
|
|
1862
1596
|
}
|
|
1863
|
-
function
|
|
1864
|
-
return
|
|
1865
|
-
defaultLabel: "dock-task",
|
|
1866
|
-
...options
|
|
1867
|
-
});
|
|
1597
|
+
function defineModule(coreModule) {
|
|
1598
|
+
return Object.freeze({ ...coreModule });
|
|
1868
1599
|
}
|
|
1600
|
+
createStore(void 0);
|
|
1869
1601
|
|
|
1870
|
-
// src/
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
width: null
|
|
1875
|
-
});
|
|
1876
|
-
function useSurfaceDimensions() {
|
|
1877
|
-
const { width } = use(SurfaceItemContext);
|
|
1878
|
-
return useMemo(() => ({ width }), [width]);
|
|
1879
|
-
}
|
|
1880
|
-
function useSurfaceId() {
|
|
1881
|
-
return use(SurfaceItemContext).id;
|
|
1882
|
-
}
|
|
1883
|
-
function useSurfaceHeader() {
|
|
1884
|
-
const store = use(SurfaceExtensionsContext)?.headerActions ?? null;
|
|
1885
|
-
const surfaceId = useSurfaceId();
|
|
1886
|
-
return useCallback(
|
|
1887
|
-
(patch) => {
|
|
1888
|
-
if (!store) return;
|
|
1889
|
-
const data = typeof patch === "function" ? patch({}) : patch;
|
|
1890
|
-
if (data?.headerAction !== void 0)
|
|
1891
|
-
store.setAction(surfaceId, data.headerAction);
|
|
1892
|
-
},
|
|
1893
|
-
[store, surfaceId]
|
|
1602
|
+
// src/kernel/adapters.ts
|
|
1603
|
+
function useModuleRegistration(id, value, options) {
|
|
1604
|
+
const coreModule = useInstalledModules().find(
|
|
1605
|
+
(candidate) => candidate.id === id
|
|
1894
1606
|
);
|
|
1607
|
+
const config = coreModule && options?.enabled !== false && value != null ? { [id]: value } : null;
|
|
1608
|
+
useRegistry(config, pickRegistryMetadata(options));
|
|
1895
1609
|
}
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
if (!store || action === void 0) return;
|
|
1901
|
-
store.setAction(surfaceId, action);
|
|
1902
|
-
return () => store.removeAction(surfaceId);
|
|
1903
|
-
}, [store, surfaceId, action]);
|
|
1610
|
+
|
|
1611
|
+
// src/theme.tsx
|
|
1612
|
+
function defineThemeSpec(id) {
|
|
1613
|
+
return Object.freeze({ id });
|
|
1904
1614
|
}
|
|
1905
|
-
var
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
}
|
|
1913
|
-
subscribe = (listener) => this.store.subscribe(listener);
|
|
1914
|
-
getAction = (surfaceId) => {
|
|
1915
|
-
const sId = surfaceId != null ? String(surfaceId) : "global";
|
|
1916
|
-
const { actionsBySurface } = this.store.getSnapshot();
|
|
1917
|
-
return actionsBySurface[sId] ?? actionsBySurface.global ?? null;
|
|
1918
|
-
};
|
|
1919
|
-
setAction = (surfaceId, action) => {
|
|
1920
|
-
const sId = surfaceId != null ? String(surfaceId) : "global";
|
|
1921
|
-
const current = this.store.getSnapshot();
|
|
1922
|
-
if (current.actionsBySurface[sId] === action) return;
|
|
1923
|
-
this.store.setState({
|
|
1924
|
-
actionsBySurface: {
|
|
1925
|
-
...current.actionsBySurface,
|
|
1926
|
-
[sId]: action
|
|
1927
|
-
},
|
|
1928
|
-
version: current.version + 1
|
|
1929
|
-
});
|
|
1930
|
-
};
|
|
1931
|
-
removeAction = (surfaceId) => {
|
|
1932
|
-
const sId = surfaceId != null ? String(surfaceId) : "global";
|
|
1933
|
-
const current = this.store.getSnapshot();
|
|
1934
|
-
if (!(sId in current.actionsBySurface)) return;
|
|
1935
|
-
const { [sId]: _, ...nextActions } = current.actionsBySurface;
|
|
1936
|
-
this.store.setState({
|
|
1937
|
-
actionsBySurface: nextActions,
|
|
1938
|
-
version: current.version + 1
|
|
1939
|
-
});
|
|
1940
|
-
};
|
|
1941
|
-
clearSurface = (surfaceId) => this.removeAction(surfaceId);
|
|
1942
|
-
};
|
|
1943
|
-
var SurfaceExtensionsStore = class {
|
|
1944
|
-
extensionsBySurface = /* @__PURE__ */ new Map();
|
|
1945
|
-
cachedListBySurface = /* @__PURE__ */ new Map();
|
|
1946
|
-
store = createStore({ version: 0 });
|
|
1947
|
-
get version() {
|
|
1948
|
-
return this.store.getSnapshot().version;
|
|
1949
|
-
}
|
|
1950
|
-
subscribe = (listener) => this.store.subscribe(listener);
|
|
1951
|
-
notify = () => {
|
|
1952
|
-
this.cachedListBySurface.clear();
|
|
1953
|
-
this.store.setState((prev) => ({ version: prev.version + 1 }));
|
|
1954
|
-
};
|
|
1955
|
-
getExtensionsForSurface = (surfaceId) => {
|
|
1956
|
-
const sId = surfaceId != null ? String(surfaceId) : "global";
|
|
1957
|
-
if (this.cachedListBySurface.has(sId))
|
|
1958
|
-
return this.cachedListBySurface.get(sId);
|
|
1959
|
-
const globalExts = this.extensionsBySurface.get("global");
|
|
1960
|
-
const surfaceExts = this.extensionsBySurface.get(sId);
|
|
1961
|
-
if (!globalExts && !surfaceExts) {
|
|
1962
|
-
const empty = [];
|
|
1963
|
-
this.cachedListBySurface.set(sId, empty);
|
|
1964
|
-
return empty;
|
|
1965
|
-
}
|
|
1966
|
-
const merged = new Map([...globalExts || [], ...surfaceExts || []]);
|
|
1967
|
-
const result = Array.from(merged.values()).sort(
|
|
1968
|
-
(a, b) => a.order - b.order
|
|
1615
|
+
var EMPTY = /* @__PURE__ */ new Map();
|
|
1616
|
+
var ThemeContext = getOrCreateGlobalContext("ThemeContext", EMPTY);
|
|
1617
|
+
function useTheme(spec) {
|
|
1618
|
+
const config = useContext(ThemeContext).get(spec.id);
|
|
1619
|
+
if (!config) {
|
|
1620
|
+
throw new Error(
|
|
1621
|
+
`Theme "${spec.id}" is missing. Ensure its theme configuration is provided to <ThemeProvider themes={[...]}> (e.g. in src/config/ or your theme setup).`
|
|
1969
1622
|
);
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
if (!extension) return;
|
|
1975
|
-
const normalized = normalizeSurfaceExtension(extension);
|
|
1976
|
-
if (!normalized) return;
|
|
1977
|
-
const sId = surfaceId != null ? String(surfaceId) : "global";
|
|
1978
|
-
let surfaceMap = this.extensionsBySurface.get(sId);
|
|
1979
|
-
if (!surfaceMap) {
|
|
1980
|
-
surfaceMap = /* @__PURE__ */ new Map();
|
|
1981
|
-
this.extensionsBySurface.set(sId, surfaceMap);
|
|
1982
|
-
}
|
|
1983
|
-
const prev = surfaceMap.get(normalized.id);
|
|
1984
|
-
if (prev && prev.content === normalized.content && prev.align === normalized.align && prev.order === normalized.order && prev.className === normalized.className && prev.unstyled === normalized.unstyled && prev.component === normalized.component && prev.props === normalized.props)
|
|
1985
|
-
return;
|
|
1986
|
-
surfaceMap.set(normalized.id, normalized);
|
|
1987
|
-
this.notify();
|
|
1988
|
-
};
|
|
1989
|
-
removeExtension = (surfaceId, extensionId) => {
|
|
1990
|
-
if (!extensionId) return;
|
|
1991
|
-
const sId = surfaceId != null ? String(surfaceId) : "global";
|
|
1992
|
-
const surfaceMap = this.extensionsBySurface.get(sId);
|
|
1993
|
-
if (!surfaceMap || !surfaceMap.has(extensionId)) return;
|
|
1994
|
-
surfaceMap.delete(extensionId);
|
|
1995
|
-
if (surfaceMap.size === 0) this.extensionsBySurface.delete(sId);
|
|
1996
|
-
this.notify();
|
|
1997
|
-
};
|
|
1998
|
-
clearSurface = (surfaceId) => {
|
|
1999
|
-
const sId = surfaceId != null ? String(surfaceId) : "global";
|
|
2000
|
-
if (!this.extensionsBySurface.has(sId)) return;
|
|
2001
|
-
this.extensionsBySurface.delete(sId);
|
|
2002
|
-
this.notify();
|
|
1623
|
+
}
|
|
1624
|
+
return {
|
|
1625
|
+
slots: config.slots,
|
|
1626
|
+
styles: config.styles ?? {}
|
|
2003
1627
|
};
|
|
2004
|
-
}
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
// src/modules/dock/constants.ts
|
|
1631
|
+
var DOCK_STYLE_SECTIONS = Object.freeze([
|
|
1632
|
+
"card",
|
|
1633
|
+
"icon",
|
|
1634
|
+
"title",
|
|
1635
|
+
"description"
|
|
1636
|
+
]);
|
|
1637
|
+
var DOCK_EVENTS = Object.freeze({
|
|
1638
|
+
NAVIGATE_START: "DOCK_NAVIGATE_START",
|
|
1639
|
+
NAVIGATE_END: "DOCK_NAVIGATE_END",
|
|
1640
|
+
UPDATE_BADGE: "DOCK_UPDATE_BADGE",
|
|
1641
|
+
NAVIGATE: "DOCK_NAVIGATE",
|
|
1642
|
+
GUARD: "DOCK_GUARD",
|
|
1643
|
+
NOT_FOUND: "DOCK_NOT_FOUND",
|
|
1644
|
+
STATUS_SET: "DOCK_STATUS_SET",
|
|
1645
|
+
STATUS_CLEAR: "DOCK_STATUS_CLEAR"
|
|
1646
|
+
});
|
|
1647
|
+
var DOCK_HUD_RENDER_MODE = Object.freeze({
|
|
1648
|
+
COMPONENT: "component",
|
|
1649
|
+
NODE: "node"
|
|
1650
|
+
});
|
|
1651
|
+
var DOCK_HUD_VARIANT = Object.freeze({
|
|
1652
|
+
EXPANDED: "expanded",
|
|
1653
|
+
PROGRESS: "progress",
|
|
1654
|
+
CUSTOM: "custom"
|
|
1655
|
+
});
|
|
1656
|
+
var DOCK_HUD_PRIORITY = Object.freeze({
|
|
1657
|
+
TASK_PROGRESS: 30,
|
|
1658
|
+
CONTEXTUAL: 10,
|
|
1659
|
+
SELECTION: 20,
|
|
1660
|
+
CRITICAL: 50,
|
|
1661
|
+
DEFAULT: 0,
|
|
1662
|
+
MEDIA: 15
|
|
1663
|
+
});
|
|
1664
|
+
var DOCK_ATTENTION_KIND = Object.freeze({
|
|
1665
|
+
SURFACE: "surface",
|
|
1666
|
+
OPERATION: "operation",
|
|
1667
|
+
LOADING: "loading",
|
|
1668
|
+
STATUS: "status",
|
|
1669
|
+
ROUTE: "route",
|
|
1670
|
+
HUD: "hud"
|
|
1671
|
+
});
|
|
1672
|
+
var DOCK_ATTENTION_PRIORITY = Object.freeze({
|
|
1673
|
+
STATUS_OVERLAY: 300,
|
|
1674
|
+
SURFACE: 400,
|
|
1675
|
+
OPERATION: 250,
|
|
1676
|
+
LOADING: 100,
|
|
1677
|
+
STATUS: 75,
|
|
1678
|
+
ROUTE: 0,
|
|
1679
|
+
HUD: 200
|
|
1680
|
+
});
|
|
1681
|
+
var DOCK_ATTENTION_PRIORITY_OFFSET_MAX = 99;
|
|
1682
|
+
var DOCK_SURFACE_RENDER_MODE = Object.freeze({
|
|
1683
|
+
COMPONENT: "component",
|
|
1684
|
+
NODE: "node"
|
|
1685
|
+
});
|
|
1686
|
+
var DOCK_SURFACE_FLOW_STATUS = Object.freeze({
|
|
1687
|
+
OPEN: "open",
|
|
1688
|
+
COMPLETED: "completed",
|
|
1689
|
+
CANCELLED: "cancelled"
|
|
1690
|
+
});
|
|
1691
|
+
var DOCK_SURFACE_PHASE = Object.freeze({
|
|
1692
|
+
IDLE: "idle",
|
|
1693
|
+
DISMISSING_ACTION: "dismissing_action",
|
|
1694
|
+
EXPANDING_BODY: "expanding_body",
|
|
1695
|
+
OPEN: "open",
|
|
1696
|
+
CLOSING_ANTICIPATION: "closing_anticipation",
|
|
1697
|
+
COLLAPSING_BODY: "collapsing_body",
|
|
1698
|
+
RESTORING_HEADER: "restoring_header"
|
|
1699
|
+
});
|
|
1700
|
+
var VIEWPORT_MARGIN = 24;
|
|
1701
|
+
var DOCK_CARD_DIMENSIONS = Object.freeze({
|
|
1702
|
+
expandedY: -72,
|
|
1703
|
+
chromeHeight: 20,
|
|
1704
|
+
collapsedY: -10,
|
|
1705
|
+
extensionShelfY: -42,
|
|
1706
|
+
extensionShelfScale: 0.94,
|
|
1707
|
+
extensionShelfHeight: 45,
|
|
1708
|
+
hudHeight: 52,
|
|
1709
|
+
actionGap: 10,
|
|
1710
|
+
height: 68
|
|
1711
|
+
});
|
|
1712
|
+
var DOCK_CARD_LAYOUT = Object.freeze({
|
|
1713
|
+
collapsed: Object.freeze({
|
|
1714
|
+
offsetY: DOCK_CARD_DIMENSIONS.collapsedY,
|
|
1715
|
+
scale: 0.88
|
|
1716
|
+
}),
|
|
1717
|
+
expanded: Object.freeze({
|
|
1718
|
+
offsetY: DOCK_CARD_DIMENSIONS.expandedY,
|
|
1719
|
+
scale: 1
|
|
1720
|
+
}),
|
|
1721
|
+
extensionShelfY: DOCK_CARD_DIMENSIONS.extensionShelfY,
|
|
1722
|
+
extensionShelfScale: DOCK_CARD_DIMENSIONS.extensionShelfScale,
|
|
1723
|
+
extensionShelfHeight: DOCK_CARD_DIMENSIONS.extensionShelfHeight,
|
|
1724
|
+
chromeHeight: DOCK_CARD_DIMENSIONS.chromeHeight,
|
|
1725
|
+
hudHeight: DOCK_CARD_DIMENSIONS.hudHeight,
|
|
1726
|
+
actionGap: DOCK_CARD_DIMENSIONS.actionGap,
|
|
1727
|
+
baseHeight: DOCK_CARD_DIMENSIONS.height
|
|
1728
|
+
});
|
|
1729
|
+
var DOCK_TRANSACTION_EVENTS = Object.freeze({
|
|
1730
|
+
START: "START",
|
|
1731
|
+
COMPLETE: "COMPLETE",
|
|
1732
|
+
CANCEL: "CANCEL",
|
|
1733
|
+
FAIL: "FAIL",
|
|
1734
|
+
TIME_OUT: "TIME_OUT"
|
|
1735
|
+
});
|
|
1736
|
+
var DOCK_TRANSACTION_STATUS = Object.freeze({
|
|
1737
|
+
PENDING: "pending",
|
|
1738
|
+
COMPLETED: "completed",
|
|
1739
|
+
CANCELLED: "cancelled",
|
|
1740
|
+
FAILED: "failed",
|
|
1741
|
+
TIMED_OUT: "timed-out"
|
|
1742
|
+
});
|
|
1743
|
+
var DOCK_TRANSACTION_REASON = Object.freeze({
|
|
1744
|
+
GUARD: "guard",
|
|
1745
|
+
SUPERSEDED: "superseded",
|
|
1746
|
+
TIME_OUT: "time-out"
|
|
1747
|
+
});
|
|
1748
|
+
var DOCK_TRANSACTION_TIMEOUT_MS = 15e3;
|
|
1749
|
+
var DOCK_PREFETCH_INTENT_DELAY_MS = 90;
|
|
1750
|
+
var DOCK_CONTINUITY_EVENTS = Object.freeze({
|
|
1751
|
+
CLEAR: "CLEAR",
|
|
1752
|
+
CONSUME_RETURN: "CONSUME_RETURN",
|
|
1753
|
+
DELIVER_RETURN: "DELIVER_RETURN",
|
|
1754
|
+
RECORD: "RECORD",
|
|
1755
|
+
REMOVE: "REMOVE"
|
|
1756
|
+
});
|
|
1757
|
+
var DOCK_CONTINUITY_MAX_ENTRIES = 32;
|
|
1758
|
+
var DOCK_SURFACE_RETURN_MAX_ENTRIES = 16;
|
|
1759
|
+
var DOCK_OPERATION_EVENTS = Object.freeze({
|
|
1760
|
+
CANCEL: "CANCEL",
|
|
1761
|
+
CLEAR: "CLEAR",
|
|
1762
|
+
COMPLETE: "COMPLETE",
|
|
1763
|
+
START: "START",
|
|
1764
|
+
UPDATE: "UPDATE"
|
|
1765
|
+
});
|
|
1766
|
+
var DOCK_OPERATION_STATUS = Object.freeze({
|
|
1767
|
+
CANCELLED: "cancelled",
|
|
1768
|
+
COMPLETED: "completed",
|
|
1769
|
+
PENDING: "pending"
|
|
1770
|
+
});
|
|
1771
|
+
var DOCK_OPERATION_MAX_ENTRIES = 24;
|
|
1772
|
+
var DOCK_FOCUSABLE_SELECTOR = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
1773
|
+
var DOCK_FOCUS_RESTORE_BLOCKED_REASONS = Object.freeze([
|
|
1774
|
+
"browser-back",
|
|
1775
|
+
"dock",
|
|
1776
|
+
"unmount"
|
|
1777
|
+
]);
|
|
1778
|
+
var DOCK_LIFECYCLE = Object.freeze({
|
|
1779
|
+
CLOSING: "closing",
|
|
1780
|
+
OPENING: "opening",
|
|
1781
|
+
IDLE: "idle",
|
|
1782
|
+
OPEN: "open"
|
|
1783
|
+
});
|
|
1784
|
+
var PLAYBACK_RATES = Object.freeze([1, 1.25, 1.5, 2]);
|
|
1785
|
+
var STATUS_PRIORITY = Object.freeze({
|
|
1786
|
+
GUARD: 120,
|
|
1787
|
+
ACCOUNT_DELETE: 115,
|
|
1788
|
+
APP_ERROR: 100,
|
|
1789
|
+
API_ERROR: 95,
|
|
1790
|
+
NOT_FOUND: 97,
|
|
1791
|
+
OFFLINE: 90,
|
|
1792
|
+
LOGOUT: 110,
|
|
1793
|
+
SIGNUP: 110,
|
|
1794
|
+
LOGIN: 110,
|
|
1795
|
+
ONLINE: 10
|
|
1796
|
+
});
|
|
1797
|
+
var ERROR_STATUS_TYPES = /* @__PURE__ */ new Set([
|
|
1798
|
+
"GUARD",
|
|
1799
|
+
"ACCOUNT_DELETE",
|
|
1800
|
+
"APP_ERROR",
|
|
1801
|
+
"API_ERROR",
|
|
1802
|
+
"NOT_FOUND"
|
|
1803
|
+
]);
|
|
1804
|
+
var OVERLAY_STATUS_STORAGE_KEY = "dock_overlay_status";
|
|
1805
|
+
var OVERLAY_STATUS_CLEAR_DURATION = 3e3;
|
|
1806
|
+
var STATUS_CLEAR_DURATION = 4500;
|
|
1807
|
+
var API_ERROR_BATCH_DELAY = 300;
|
|
1808
|
+
var DOCK_HEIGHT_BUFFER = 16;
|
|
1809
|
+
var HEIGHT_EPSILON = 0.5;
|
|
1810
|
+
var MAX_VISIBLE_STACKED_CARDS = 3;
|
|
1811
|
+
var dockTheme = defineThemeSpec("dock");
|
|
2005
1812
|
|
|
2006
1813
|
// src/modules/media/constants.ts
|
|
2007
1814
|
var DEFAULT_MEDIA_STATE = Object.freeze({
|
|
@@ -2070,6 +1877,8 @@ var LoadingContext = getOrCreateGlobalContext("LoadingContext", null);
|
|
|
2070
1877
|
var NOOP_LOADING_STORE = createStore(
|
|
2071
1878
|
DEFAULT_LOADING_STATE_WITH_PAGE
|
|
2072
1879
|
);
|
|
1880
|
+
|
|
1881
|
+
// src/modules/loading/hooks.ts
|
|
2073
1882
|
function useOptionalLoadingState(selector, isEqual) {
|
|
2074
1883
|
const ctx = useContext(LoadingContext);
|
|
2075
1884
|
return useStore(
|
|
@@ -4073,126 +3882,55 @@ function runSurfaceTransition({
|
|
|
4073
3882
|
}
|
|
4074
3883
|
});
|
|
4075
3884
|
}
|
|
4076
|
-
function
|
|
4077
|
-
|
|
3885
|
+
function blurActiveElement() {
|
|
3886
|
+
if (typeof document === "undefined") return;
|
|
3887
|
+
const activeElement = document.activeElement;
|
|
3888
|
+
if (activeElement && typeof activeElement.blur === "function") {
|
|
3889
|
+
activeElement.blur();
|
|
3890
|
+
}
|
|
4078
3891
|
}
|
|
4079
|
-
function
|
|
4080
|
-
const
|
|
4081
|
-
return
|
|
4082
|
-
|
|
4083
|
-
[slots]
|
|
3892
|
+
function closestMatches(target, selector) {
|
|
3893
|
+
const element = target;
|
|
3894
|
+
return Boolean(
|
|
3895
|
+
element && typeof element.closest === "function" && element.closest(selector)
|
|
4084
3896
|
);
|
|
4085
3897
|
}
|
|
4086
|
-
function
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
const position = options?.position;
|
|
4091
|
-
const size = options?.size;
|
|
4092
|
-
const opacity = options?.opacity;
|
|
4093
|
-
const repeat = options?.repeat;
|
|
4094
|
-
const targetPath = options?.path;
|
|
4095
|
-
const config = useMemo(() => {
|
|
4096
|
-
if (!banner) return null;
|
|
4097
|
-
if (typeof banner === "string") {
|
|
4098
|
-
return {
|
|
4099
|
-
bannerUrl: banner,
|
|
4100
|
-
...position ? { bannerPosition: position } : {},
|
|
4101
|
-
...size ? { bannerSize: size } : {},
|
|
4102
|
-
...opacity !== void 0 ? { bannerOpacity: opacity } : {},
|
|
4103
|
-
...repeat ? { bannerRepeat: repeat } : {},
|
|
4104
|
-
...targetPath ? { path: targetPath } : {}
|
|
4105
|
-
};
|
|
4106
|
-
}
|
|
4107
|
-
if (typeof banner === "object") {
|
|
4108
|
-
return {
|
|
4109
|
-
bannerUrl: banner.url || banner.bannerUrl,
|
|
4110
|
-
bannerPosition: banner.position || banner.bannerPosition || position,
|
|
4111
|
-
bannerSize: banner.size || banner.bannerSize || size,
|
|
4112
|
-
bannerOpacity: banner.opacity ?? banner.bannerOpacity ?? opacity,
|
|
4113
|
-
bannerRepeat: banner.repeat || banner.bannerRepeat || repeat,
|
|
4114
|
-
...targetPath ? { path: targetPath } : {}
|
|
4115
|
-
};
|
|
4116
|
-
}
|
|
4117
|
-
return null;
|
|
4118
|
-
}, [banner, position, size, opacity, repeat, targetPath]);
|
|
4119
|
-
useDockRegistration(config, options);
|
|
4120
|
-
}
|
|
4121
|
-
var EMPTY_DOCK_STATE_STORE = createStore(EMPTY_DOCK_STATE);
|
|
4122
|
-
function selectDockConfigState(state) {
|
|
4123
|
-
return {
|
|
4124
|
-
activeItem: state.activeItem,
|
|
4125
|
-
dockHeight: state.dockHeight,
|
|
4126
|
-
expanded: state.expanded,
|
|
4127
|
-
pathname: state.pathname
|
|
4128
|
-
};
|
|
4129
|
-
}
|
|
4130
|
-
function useDockConfig(configOrTitle, options) {
|
|
4131
|
-
const normalizedConfig = useMemo(() => {
|
|
4132
|
-
if (!configOrTitle) return null;
|
|
4133
|
-
if (typeof configOrTitle === "string") return { title: configOrTitle };
|
|
4134
|
-
return configOrTitle;
|
|
4135
|
-
}, [configOrTitle]);
|
|
4136
|
-
useDockRegistration(normalizedConfig, options);
|
|
4137
|
-
const dockContext = use(DockContext);
|
|
4138
|
-
const actions = dockContext?.actions;
|
|
4139
|
-
const state = useStore(
|
|
4140
|
-
dockContext?.store ?? EMPTY_DOCK_STATE_STORE,
|
|
4141
|
-
selectDockConfigState,
|
|
4142
|
-
shallowEqual
|
|
4143
|
-
);
|
|
4144
|
-
return useMemo(
|
|
4145
|
-
() => ({
|
|
4146
|
-
activeItem: state.activeItem,
|
|
4147
|
-
clearHud: actions?.clearHud ?? (() => {
|
|
4148
|
-
}),
|
|
4149
|
-
closeAllSurfaces: actions?.closeAllSurfaces ?? (() => {
|
|
4150
|
-
}),
|
|
4151
|
-
closeSurface: actions?.closeSurface ?? (() => {
|
|
4152
|
-
}),
|
|
4153
|
-
expanded: state.expanded,
|
|
4154
|
-
dockHeight: state.dockHeight,
|
|
4155
|
-
navigate: actions?.navigate ?? (async () => false),
|
|
4156
|
-
openSurface: actions?.openSurface ?? (() => void 0),
|
|
4157
|
-
pathname: state.pathname,
|
|
4158
|
-
setExpanded: actions?.setExpanded ?? (() => {
|
|
4159
|
-
}),
|
|
4160
|
-
setHud: actions?.setHud ?? (() => {
|
|
4161
|
-
}),
|
|
4162
|
-
setSearchQuery: actions?.setSearchQuery ?? (() => {
|
|
4163
|
-
})
|
|
4164
|
-
}),
|
|
4165
|
-
[actions, state]
|
|
3898
|
+
function isInteractiveTarget(target) {
|
|
3899
|
+
return closestMatches(
|
|
3900
|
+
target,
|
|
3901
|
+
'button, a, input, textarea, select, [role="button"], [tabindex]:not([tabindex="-1"])'
|
|
4166
3902
|
);
|
|
4167
3903
|
}
|
|
4168
|
-
function
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
height: dockHeight,
|
|
4173
|
-
width: activeItem?.width ?? null,
|
|
4174
|
-
isSurface: Boolean(activeItem?.isSurface)
|
|
4175
|
-
};
|
|
4176
|
-
}
|
|
4177
|
-
function useSurfaceReturn() {
|
|
4178
|
-
const pathname = usePathname();
|
|
4179
|
-
const { continuity } = useDockActions();
|
|
4180
|
-
const dockReturnHandoffs = useDockSelector(
|
|
4181
|
-
(state) => state.dockReturnHandoffs
|
|
4182
|
-
);
|
|
4183
|
-
const entries = useMemo(
|
|
4184
|
-
() => (dockReturnHandoffs || []).filter(
|
|
4185
|
-
(handoff) => isSamePath(handoff.path, pathname)
|
|
4186
|
-
),
|
|
4187
|
-
[dockReturnHandoffs, pathname]
|
|
4188
|
-
);
|
|
4189
|
-
const consume = useCallback(
|
|
4190
|
-
(handoffId = null) => continuity.consumeReturn(pathname, handoffId),
|
|
4191
|
-
[continuity, pathname]
|
|
3904
|
+
function isEditableDockTarget(target) {
|
|
3905
|
+
return closestMatches(
|
|
3906
|
+
target,
|
|
3907
|
+
'input, textarea, select, [contenteditable="true"]'
|
|
4192
3908
|
);
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
3909
|
+
}
|
|
3910
|
+
function getDockFocusableElements(container) {
|
|
3911
|
+
if (!container || typeof container.querySelectorAll !== "function") return [];
|
|
3912
|
+
return Array.from(
|
|
3913
|
+
container.querySelectorAll(DOCK_FOCUSABLE_SELECTOR)
|
|
3914
|
+
).filter((element) => {
|
|
3915
|
+
if (!element || element.getAttribute("aria-hidden") === "true")
|
|
3916
|
+
return false;
|
|
3917
|
+
const style = typeof window !== "undefined" ? window.getComputedStyle(element) : null;
|
|
3918
|
+
return style?.display !== "none" && style?.visibility !== "hidden" && style?.pointerEvents !== "none";
|
|
3919
|
+
});
|
|
3920
|
+
}
|
|
3921
|
+
function focusDockElement(element) {
|
|
3922
|
+
if (!element || typeof element.focus !== "function") return false;
|
|
3923
|
+
try {
|
|
3924
|
+
element.focus({ preventScroll: true });
|
|
3925
|
+
return document.activeElement === element;
|
|
3926
|
+
} catch {
|
|
3927
|
+
return false;
|
|
3928
|
+
}
|
|
3929
|
+
}
|
|
3930
|
+
function shouldRestoreDockFocus(result) {
|
|
3931
|
+
const blockedReason = result?.blockedReason;
|
|
3932
|
+
return !result || !DOCK_FOCUS_RESTORE_BLOCKED_REASONS.includes(
|
|
3933
|
+
blockedReason
|
|
4196
3934
|
);
|
|
4197
3935
|
}
|
|
4198
3936
|
function useDockFocusTrap({
|
|
@@ -4269,8 +4007,9 @@ function useDockKeyboard({
|
|
|
4269
4007
|
}) {
|
|
4270
4008
|
const handleKeyDown = useCallback(
|
|
4271
4009
|
(event) => {
|
|
4272
|
-
if (isEditableDockTarget(event.target) || isInteractiveTarget(event.target))
|
|
4010
|
+
if (isEditableDockTarget(event.target) || isInteractiveTarget(event.target)) {
|
|
4273
4011
|
return;
|
|
4012
|
+
}
|
|
4274
4013
|
if (isOverlayActive || !expanded) return;
|
|
4275
4014
|
const { key } = event;
|
|
4276
4015
|
if (key === "Escape") {
|
|
@@ -4281,8 +4020,9 @@ function useDockKeyboard({
|
|
|
4281
4020
|
if (key === "Enter" && focusedIndex !== -1) {
|
|
4282
4021
|
event.preventDefault();
|
|
4283
4022
|
const focusedItem = dockItems[focusedIndex];
|
|
4284
|
-
if (focusedItem?.path)
|
|
4023
|
+
if (focusedItem?.path) {
|
|
4285
4024
|
navigate(focusedItem.path, { item: focusedItem });
|
|
4025
|
+
}
|
|
4286
4026
|
return;
|
|
4287
4027
|
}
|
|
4288
4028
|
if (dockItems.length === 0) return;
|
|
@@ -4310,814 +4050,1119 @@ function useDockKeyboard({
|
|
|
4310
4050
|
setFocusedIndex
|
|
4311
4051
|
]
|
|
4312
4052
|
);
|
|
4313
|
-
useEffect(() => {
|
|
4314
|
-
if (!expanded) return;
|
|
4315
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
4316
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
4317
|
-
}, [expanded, handleKeyDown]);
|
|
4053
|
+
useEffect(() => {
|
|
4054
|
+
if (!expanded) return;
|
|
4055
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
4056
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
4057
|
+
}, [expanded, handleKeyDown]);
|
|
4058
|
+
}
|
|
4059
|
+
function useDockRouteReset(pathname, onRouteChange) {
|
|
4060
|
+
const previousPathRef = useRef(pathname);
|
|
4061
|
+
useEffect(() => {
|
|
4062
|
+
if (previousPathRef.current === pathname) return;
|
|
4063
|
+
previousPathRef.current = pathname;
|
|
4064
|
+
onRouteChange?.(pathname);
|
|
4065
|
+
}, [onRouteChange, pathname]);
|
|
4066
|
+
}
|
|
4067
|
+
function useSurfaceFlows({
|
|
4068
|
+
closeSurface,
|
|
4069
|
+
openSurface,
|
|
4070
|
+
refs,
|
|
4071
|
+
syncSurfaceStack
|
|
4072
|
+
}) {
|
|
4073
|
+
const updateSurfaceFlow = useCallback(
|
|
4074
|
+
(flowId, snapshot) => {
|
|
4075
|
+
const surfaceId = refs.flowIndex.get(flowId);
|
|
4076
|
+
if (!surfaceId) return false;
|
|
4077
|
+
const record = refs.records.get(surfaceId);
|
|
4078
|
+
if (!record?.flow) return false;
|
|
4079
|
+
const nextSession = updateSurfaceFlowSession(record.flow, snapshot);
|
|
4080
|
+
if (!nextSession) return false;
|
|
4081
|
+
const nextSurfaceEntry = {
|
|
4082
|
+
...record.entry,
|
|
4083
|
+
flow: toSurfaceFlowState(nextSession)
|
|
4084
|
+
};
|
|
4085
|
+
record.flow = nextSession;
|
|
4086
|
+
record.entry = nextSurfaceEntry;
|
|
4087
|
+
syncSurfaceFlowUrlState(nextSurfaceEntry, record.urlState);
|
|
4088
|
+
syncSurfaceStack(
|
|
4089
|
+
updateSurfaceStackEntry(
|
|
4090
|
+
refs.stackRef.current,
|
|
4091
|
+
surfaceId,
|
|
4092
|
+
() => nextSurfaceEntry
|
|
4093
|
+
)
|
|
4094
|
+
);
|
|
4095
|
+
return true;
|
|
4096
|
+
},
|
|
4097
|
+
[syncSurfaceStack, refs]
|
|
4098
|
+
);
|
|
4099
|
+
const completeSurfaceFlow = useCallback(
|
|
4100
|
+
(flowId, data = null) => {
|
|
4101
|
+
const surfaceId = refs.flowIndex.get(flowId);
|
|
4102
|
+
if (!surfaceId) return false;
|
|
4103
|
+
const record = refs.records.get(surfaceId);
|
|
4104
|
+
if (record?.flow)
|
|
4105
|
+
record.flow = {
|
|
4106
|
+
...record.flow,
|
|
4107
|
+
status: DOCK_SURFACE_FLOW_STATUS.COMPLETED
|
|
4108
|
+
};
|
|
4109
|
+
closeSurface({ data, success: true }, surfaceId);
|
|
4110
|
+
return true;
|
|
4111
|
+
},
|
|
4112
|
+
[closeSurface, refs]
|
|
4113
|
+
);
|
|
4114
|
+
const cancelSurfaceFlow = useCallback(
|
|
4115
|
+
(flowId, data = null) => {
|
|
4116
|
+
const surfaceId = refs.flowIndex.get(flowId);
|
|
4117
|
+
if (!surfaceId) return false;
|
|
4118
|
+
const record = refs.records.get(surfaceId);
|
|
4119
|
+
if (record?.flow)
|
|
4120
|
+
record.flow = {
|
|
4121
|
+
...record.flow,
|
|
4122
|
+
status: DOCK_SURFACE_FLOW_STATUS.CANCELLED
|
|
4123
|
+
};
|
|
4124
|
+
closeSurface(
|
|
4125
|
+
{ cancelled: true, data, reason: "flow-cancelled", success: false },
|
|
4126
|
+
surfaceId
|
|
4127
|
+
);
|
|
4128
|
+
return true;
|
|
4129
|
+
},
|
|
4130
|
+
[closeSurface, refs]
|
|
4131
|
+
);
|
|
4132
|
+
const getSurfaceFlow = useCallback(
|
|
4133
|
+
(flowId) => {
|
|
4134
|
+
const surfaceId = refs.flowIndex.get(flowId);
|
|
4135
|
+
const session = surfaceId ? refs.records.get(surfaceId)?.flow : null;
|
|
4136
|
+
if (!session) return null;
|
|
4137
|
+
return {
|
|
4138
|
+
cancel: (data = null) => cancelSurfaceFlow(flowId, data),
|
|
4139
|
+
complete: (data = null) => completeSurfaceFlow(flowId, data),
|
|
4140
|
+
flowId,
|
|
4141
|
+
isOpen: session.status === DOCK_SURFACE_FLOW_STATUS.OPEN,
|
|
4142
|
+
snapshot: session.snapshot,
|
|
4143
|
+
status: session.status,
|
|
4144
|
+
update: (snapshot) => updateSurfaceFlow(flowId, snapshot)
|
|
4145
|
+
};
|
|
4146
|
+
},
|
|
4147
|
+
[cancelSurfaceFlow, completeSurfaceFlow, updateSurfaceFlow, refs]
|
|
4148
|
+
);
|
|
4149
|
+
const openSurfaceFlow = useCallback(
|
|
4150
|
+
(input, flowInput = null, {
|
|
4151
|
+
preserveUrl = false,
|
|
4152
|
+
snapshot
|
|
4153
|
+
} = {}) => {
|
|
4154
|
+
const definition = createSurfaceFlowDefinition(input);
|
|
4155
|
+
if (!definition) {
|
|
4156
|
+
const error = createSurfaceError(
|
|
4157
|
+
"DOCK_SURFACE_FLOW_INVALID_DEFINITION",
|
|
4158
|
+
"Dock surface flow definition is invalid"
|
|
4159
|
+
);
|
|
4160
|
+
report("Dock surface flow definition", error);
|
|
4161
|
+
return Promise.resolve({ success: false, error });
|
|
4162
|
+
}
|
|
4163
|
+
const existingSurfaceId = refs.flowIndex.get(definition.id);
|
|
4164
|
+
if (definition.singleton && existingSurfaceId) {
|
|
4165
|
+
return refs.records.get(existingSurfaceId)?.promise ?? Promise.resolve({
|
|
4166
|
+
success: false,
|
|
4167
|
+
error: createSurfaceError(
|
|
4168
|
+
"DOCK_SURFACE_FLOW_ORPHANED",
|
|
4169
|
+
"Dock surface flow is orphaned"
|
|
4170
|
+
)
|
|
4171
|
+
});
|
|
4172
|
+
}
|
|
4173
|
+
const flowSession = createSurfaceFlowSession(definition, {
|
|
4174
|
+
input: flowInput,
|
|
4175
|
+
snapshot
|
|
4176
|
+
});
|
|
4177
|
+
try {
|
|
4178
|
+
const surfaceInput = definition.createSurface({
|
|
4179
|
+
flowId: definition.id,
|
|
4180
|
+
input: flowInput,
|
|
4181
|
+
snapshot: flowSession?.snapshot
|
|
4182
|
+
});
|
|
4183
|
+
return openSurface(surfaceInput, { flowSession, preserveUrl });
|
|
4184
|
+
} catch (error) {
|
|
4185
|
+
report("Dock surface flow factory", error);
|
|
4186
|
+
return Promise.resolve({ success: false, error });
|
|
4187
|
+
}
|
|
4188
|
+
},
|
|
4189
|
+
[openSurface, refs]
|
|
4190
|
+
);
|
|
4191
|
+
const restoreSurfaceFlow = useCallback(
|
|
4192
|
+
(input) => {
|
|
4193
|
+
const definition = createSurfaceFlowDefinition(input);
|
|
4194
|
+
const snapshot = getRestorableSurfaceFlowSnapshot(definition);
|
|
4195
|
+
if (!definition || snapshot === void 0) return Promise.resolve(null);
|
|
4196
|
+
return openSurfaceFlow(definition, null, { preserveUrl: true, snapshot });
|
|
4197
|
+
},
|
|
4198
|
+
[openSurfaceFlow]
|
|
4199
|
+
);
|
|
4200
|
+
return {
|
|
4201
|
+
cancelSurfaceFlow,
|
|
4202
|
+
completeSurfaceFlow,
|
|
4203
|
+
getSurfaceFlow,
|
|
4204
|
+
openSurfaceFlow,
|
|
4205
|
+
restoreSurfaceFlow,
|
|
4206
|
+
updateSurfaceFlow
|
|
4207
|
+
};
|
|
4208
|
+
}
|
|
4209
|
+
function useSurfaceLifecycleEffects({
|
|
4210
|
+
clearChoreographyTimers,
|
|
4211
|
+
closeAllSurfaces,
|
|
4212
|
+
focusRestoreFrameRef,
|
|
4213
|
+
refs,
|
|
4214
|
+
runtimeScheduler
|
|
4215
|
+
}) {
|
|
4216
|
+
useEffect(() => {
|
|
4217
|
+
if (!IS_BROWSER) return;
|
|
4218
|
+
const handlePopState = () => {
|
|
4219
|
+
const activeEntry = refs.stackRef.current[refs.stackRef.current.length - 1];
|
|
4220
|
+
if (!activeEntry?.syncWithUrl && !activeEntry?.urlKey) return;
|
|
4221
|
+
if (new URL(window.location.href).searchParams.get("surface") === getSurfaceUrlValue(activeEntry))
|
|
4222
|
+
return;
|
|
4223
|
+
closeAllSurfaces({
|
|
4224
|
+
success: false,
|
|
4225
|
+
cancelled: true,
|
|
4226
|
+
reason: "browser-back"
|
|
4227
|
+
});
|
|
4228
|
+
};
|
|
4229
|
+
window.addEventListener("popstate", handlePopState);
|
|
4230
|
+
return () => window.removeEventListener("popstate", handlePopState);
|
|
4231
|
+
}, [closeAllSurfaces, refs]);
|
|
4232
|
+
useEffect(() => {
|
|
4233
|
+
return () => {
|
|
4234
|
+
clearChoreographyTimers();
|
|
4235
|
+
if (focusRestoreFrameRef.current !== null) {
|
|
4236
|
+
runtimeScheduler.cancel(focusRestoreFrameRef.current);
|
|
4237
|
+
focusRestoreFrameRef.current = null;
|
|
4238
|
+
}
|
|
4239
|
+
const result = { cancelled: true, reason: "unmount", success: false };
|
|
4240
|
+
refs.stackRef.current.forEach(
|
|
4241
|
+
({ id }) => releaseSurfaceResources({ refs, result, surfaceId: id })
|
|
4242
|
+
);
|
|
4243
|
+
refs.stackRef.current = [];
|
|
4244
|
+
refs.payloads.clear();
|
|
4245
|
+
refs.records.clear();
|
|
4246
|
+
refs.flowIndex.clear();
|
|
4247
|
+
};
|
|
4248
|
+
}, [clearChoreographyTimers, focusRestoreFrameRef, refs, runtimeScheduler]);
|
|
4249
|
+
}
|
|
4250
|
+
var SurfaceFlowContext = createContext(null);
|
|
4251
|
+
function SurfaceFlowProvider({
|
|
4252
|
+
children,
|
|
4253
|
+
value
|
|
4254
|
+
}) {
|
|
4255
|
+
return /* @__PURE__ */ jsx(SurfaceFlowContext, { value, children });
|
|
4256
|
+
}
|
|
4257
|
+
function useSurfaceFlow(input) {
|
|
4258
|
+
const context = use(SurfaceFlowContext);
|
|
4259
|
+
const definition = useMemo(() => createSurfaceFlowDefinition(input), [input]);
|
|
4260
|
+
const restoredFlowIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
4261
|
+
const flowId = definition?.id ?? null;
|
|
4262
|
+
const activeFlow = useMemo(() => {
|
|
4263
|
+
if (!flowId) return null;
|
|
4264
|
+
return context?.surfaceState?.surfaceStack?.map((s) => s.flow).find((f) => f?.flowId === flowId) ?? null;
|
|
4265
|
+
}, [context?.surfaceState?.surfaceStack, flowId]);
|
|
4266
|
+
useEffect(() => {
|
|
4267
|
+
if (!definition || !context?.restoreSurfaceFlow || restoredFlowIdsRef.current.has(definition.id))
|
|
4268
|
+
return;
|
|
4269
|
+
restoredFlowIdsRef.current.add(definition.id);
|
|
4270
|
+
void context.restoreSurfaceFlow(definition);
|
|
4271
|
+
}, [context, definition]);
|
|
4272
|
+
const open = useCallback(
|
|
4273
|
+
(flowInput = null) => {
|
|
4274
|
+
if (!definition || !context?.openSurfaceFlow) {
|
|
4275
|
+
return Promise.resolve({
|
|
4276
|
+
success: false,
|
|
4277
|
+
error: createSurfaceError(
|
|
4278
|
+
"DOCK_SURFACE_FLOW_UNAVAILABLE",
|
|
4279
|
+
"Dock surface flow is unavailable"
|
|
4280
|
+
)
|
|
4281
|
+
});
|
|
4282
|
+
}
|
|
4283
|
+
return context.openSurfaceFlow(definition, flowInput);
|
|
4284
|
+
},
|
|
4285
|
+
[context, definition]
|
|
4286
|
+
);
|
|
4287
|
+
return useMemo(
|
|
4288
|
+
() => ({
|
|
4289
|
+
activeFlow,
|
|
4290
|
+
cancel: (result = null) => flowId ? context?.cancelSurfaceFlow?.(flowId, result) : void 0,
|
|
4291
|
+
complete: (result = null) => flowId ? context?.completeSurfaceFlow?.(flowId, result) : void 0,
|
|
4292
|
+
flowId,
|
|
4293
|
+
isOpen: activeFlow?.status === DOCK_SURFACE_FLOW_STATUS.OPEN,
|
|
4294
|
+
open,
|
|
4295
|
+
snapshot: activeFlow?.snapshot ?? definition?.initialSnapshot ?? null,
|
|
4296
|
+
update: (snapshot) => flowId ? context?.updateSurfaceFlow?.(flowId, snapshot) : void 0
|
|
4297
|
+
}),
|
|
4298
|
+
[activeFlow, context, definition?.initialSnapshot, flowId, open]
|
|
4299
|
+
);
|
|
4318
4300
|
}
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4301
|
+
var DockSurfaceHeaderRadiusContext = createContext(
|
|
4302
|
+
null
|
|
4303
|
+
);
|
|
4304
|
+
function useDockSurfaceHeaderButtonModel({
|
|
4305
|
+
children,
|
|
4306
|
+
className = "",
|
|
4307
|
+
disabled = false,
|
|
4308
|
+
onClick,
|
|
4309
|
+
ariaLabel,
|
|
4310
|
+
icon = null
|
|
4311
|
+
}) {
|
|
4312
|
+
const contextRadius = use(DockSurfaceHeaderRadiusContext);
|
|
4313
|
+
return { contextRadius };
|
|
4326
4314
|
}
|
|
4327
|
-
function
|
|
4328
|
-
|
|
4329
|
-
cardStyle,
|
|
4330
|
-
expanded,
|
|
4315
|
+
function useDockSurfaceControlsModel({
|
|
4316
|
+
activeItem = null,
|
|
4331
4317
|
hasExtensions = false,
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4318
|
+
onClose = null,
|
|
4319
|
+
onBack = null,
|
|
4320
|
+
closeLabel = null,
|
|
4321
|
+
backLabel = null,
|
|
4322
|
+
className = "",
|
|
4323
|
+
surfacePhase: propSurfacePhase
|
|
4336
4324
|
}) {
|
|
4337
|
-
const
|
|
4338
|
-
const
|
|
4339
|
-
const
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
const isShelf = !expanded && position === 1 && hasExtensions;
|
|
4344
|
-
const isHeavyBlur = position < visibleCount || expanded || isShelf;
|
|
4345
|
-
const collapsedScaleValue = collapsedScale ** position;
|
|
4346
|
-
const y = expanded ? position * expandedOffsetY : isShelf ? DOCK_CARD_LAYOUT.extensionShelfY : position * collapsedOffsetY;
|
|
4347
|
-
const shelfScale = DOCK_CARD_LAYOUT.extensionShelfScale ?? 0.94;
|
|
4348
|
-
const scale = expanded ? cardScale || 1 : isShelf ? shelfScale : collapsedScaleValue;
|
|
4349
|
-
const collapsedOpacity = Math.max(0.1, +(1 - position * 0.2).toFixed(2));
|
|
4350
|
-
const opacity = expanded || isShelf ? 1 : position < visibleCount ? collapsedOpacity : 0;
|
|
4351
|
-
return {
|
|
4352
|
-
className: cn(theme.slots.card, cardStyle?.className),
|
|
4353
|
-
data: {
|
|
4354
|
-
"data-anchored": isAnchoredToBottom,
|
|
4355
|
-
"data-blur": isHeavyBlur ? "heavy" : "light",
|
|
4356
|
-
"data-placement": isTop ? "top" : isAnchoredToBottom ? "bottom" : "float",
|
|
4357
|
-
"data-shelf": isShelf
|
|
4358
|
-
},
|
|
4359
|
-
style: {
|
|
4360
|
-
...theme.styles.card,
|
|
4361
|
-
...safeCardStyle,
|
|
4362
|
-
willChange: "transform, opacity",
|
|
4363
|
-
transformOrigin: isAnchoredToBottom ? "bottom center" : "top center",
|
|
4364
|
-
zIndex: Z_INDEX.DOCK_CARD_STACK_BASE - position,
|
|
4365
|
-
WebkitPerspective: 1e3,
|
|
4366
|
-
perspective: 1e3,
|
|
4367
|
-
WebkitBackfaceVisibility: "hidden",
|
|
4368
|
-
backfaceVisibility: "hidden",
|
|
4369
|
-
WebkitFontSmoothing: "antialiased",
|
|
4370
|
-
transform: "translateZ(0)",
|
|
4371
|
-
...isTop ? { height: "100%" } : {},
|
|
4372
|
-
pointerEvents: expanded || position < visibleCount ? void 0 : "none"
|
|
4325
|
+
const phase = propSurfacePhase ?? activeItem?.surfacePhase;
|
|
4326
|
+
const isBodyVisible = phase ? phase === DOCK_SURFACE_PHASE.EXPANDING_BODY || phase === DOCK_SURFACE_PHASE.OPEN : true;
|
|
4327
|
+
const actionStore = use(SurfaceExtensionsContext)?.headerActions ?? null;
|
|
4328
|
+
const surfaceId = activeItem?.surfaceId || "active";
|
|
4329
|
+
const subscribeAction = useCallback(
|
|
4330
|
+
(onStoreChange) => actionStore ? actionStore.subscribe(onStoreChange) : () => {
|
|
4373
4331
|
},
|
|
4374
|
-
|
|
4375
|
-
};
|
|
4376
|
-
}
|
|
4377
|
-
function getViewportMaxHeight() {
|
|
4378
|
-
if (typeof window === "undefined") return Infinity;
|
|
4379
|
-
return window.innerHeight - VIEWPORT_MARGIN;
|
|
4380
|
-
}
|
|
4381
|
-
function getContainerHeight({
|
|
4382
|
-
cardContentHeight,
|
|
4383
|
-
isHud = false
|
|
4384
|
-
}) {
|
|
4385
|
-
const chromeHeight = DOCK_CARD_LAYOUT.chromeHeight;
|
|
4386
|
-
const minCardHeight = isHud ? DOCK_CARD_LAYOUT.hudHeight : DOCK_CARD_LAYOUT.baseHeight;
|
|
4387
|
-
const numericContentHeight = Number(cardContentHeight);
|
|
4388
|
-
const nextCardHeight = Math.max(
|
|
4389
|
-
minCardHeight,
|
|
4390
|
-
(Number.isFinite(numericContentHeight) ? numericContentHeight : 0) + chromeHeight
|
|
4332
|
+
[actionStore]
|
|
4391
4333
|
);
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
return Math.min(
|
|
4403
|
-
targetWidth,
|
|
4404
|
-
Math.max(windowWidth - (isDesktop ? 32 : 16), 0)
|
|
4405
|
-
);
|
|
4406
|
-
}
|
|
4407
|
-
return Math.min(460, Math.max(windowWidth - 16, 0));
|
|
4408
|
-
}
|
|
4409
|
-
function getObservedHeight(entry, element) {
|
|
4410
|
-
const rawBorderBoxSize = entry?.borderBoxSize;
|
|
4411
|
-
const borderBoxSize = Array.isArray(rawBorderBoxSize) ? rawBorderBoxSize[0] : rawBorderBoxSize;
|
|
4412
|
-
if (borderBoxSize?.blockSize != null)
|
|
4413
|
-
return Math.round(borderBoxSize.blockSize);
|
|
4414
|
-
if (entry?.contentRect?.height != null)
|
|
4415
|
-
return Math.round(entry.contentRect.height);
|
|
4416
|
-
return Math.round(element?.offsetHeight || 0);
|
|
4334
|
+
const getActionSnapshot = useCallback(
|
|
4335
|
+
() => actionStore ? actionStore.getAction(surfaceId) : null,
|
|
4336
|
+
[actionStore, surfaceId]
|
|
4337
|
+
);
|
|
4338
|
+
const dynamicAction = useSyncExternalStore(
|
|
4339
|
+
subscribeAction,
|
|
4340
|
+
getActionSnapshot,
|
|
4341
|
+
() => null
|
|
4342
|
+
);
|
|
4343
|
+
return { isBodyVisible, dynamicAction };
|
|
4417
4344
|
}
|
|
4418
|
-
function
|
|
4419
|
-
|
|
4345
|
+
function SurfaceExtensionsProvider({
|
|
4346
|
+
children
|
|
4347
|
+
}) {
|
|
4348
|
+
const [value] = useState(() => ({
|
|
4349
|
+
extensions: new SurfaceExtensionsStore(),
|
|
4350
|
+
headerActions: new SurfaceHeaderActionStore()
|
|
4351
|
+
}));
|
|
4352
|
+
return /* @__PURE__ */ jsx(SurfaceExtensionsContext, { value, children });
|
|
4420
4353
|
}
|
|
4421
|
-
function
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4354
|
+
function useDockSurfaceExtension({
|
|
4355
|
+
align = "left",
|
|
4356
|
+
children,
|
|
4357
|
+
className = "",
|
|
4358
|
+
id,
|
|
4359
|
+
order = 0,
|
|
4360
|
+
unstyled = false
|
|
4361
|
+
}) {
|
|
4362
|
+
const store = use(SurfaceExtensionsContext)?.extensions ?? null;
|
|
4363
|
+
const surfaceId = useSurfaceId();
|
|
4364
|
+
const generatedId = useId();
|
|
4365
|
+
const effectiveId = id || `dock-surface-ext-${generatedId}`;
|
|
4428
4366
|
useIsomorphicLayoutEffect(() => {
|
|
4429
|
-
if (
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
lastHeightRef.current = 0;
|
|
4438
|
-
callbackRef.current(0);
|
|
4439
|
-
}
|
|
4440
|
-
return;
|
|
4441
|
-
}
|
|
4442
|
-
const element = elementRef?.current;
|
|
4443
|
-
if (!element) return;
|
|
4444
|
-
function publishHeight(nextHeight) {
|
|
4445
|
-
if (!hasMeaningfulHeightChange(lastHeightRef.current, nextHeight)) return;
|
|
4446
|
-
lastHeightRef.current = nextHeight;
|
|
4447
|
-
callbackRef.current?.(nextHeight);
|
|
4448
|
-
}
|
|
4449
|
-
let pendingHeight = null;
|
|
4450
|
-
function flushPendingHeight() {
|
|
4451
|
-
rafRef.current = null;
|
|
4452
|
-
if (pendingHeight == null) return;
|
|
4453
|
-
const heightToPublish = pendingHeight;
|
|
4454
|
-
pendingHeight = null;
|
|
4455
|
-
publishHeight(heightToPublish);
|
|
4456
|
-
}
|
|
4457
|
-
function scheduleMeasurement(nextHeight) {
|
|
4458
|
-
pendingHeight = nextHeight;
|
|
4459
|
-
if (rafRef.current !== null) return;
|
|
4460
|
-
rafRef.current = requestAnimationFrame(flushPendingHeight);
|
|
4461
|
-
}
|
|
4462
|
-
publishHeight(element.offsetHeight || 0);
|
|
4463
|
-
const observer = new ResizeObserver((entries) => {
|
|
4464
|
-
for (const entry of entries) {
|
|
4465
|
-
scheduleMeasurement(getObservedHeight(entry, element));
|
|
4466
|
-
}
|
|
4467
|
-
});
|
|
4468
|
-
observer.observe(element);
|
|
4469
|
-
const handlePageShow = () => scheduleMeasurement(element.offsetHeight || 0);
|
|
4470
|
-
const handleVisibilityChange = () => {
|
|
4471
|
-
if (document.visibilityState === "visible") handlePageShow();
|
|
4367
|
+
if (!store) return;
|
|
4368
|
+
const extension = {
|
|
4369
|
+
align,
|
|
4370
|
+
className,
|
|
4371
|
+
content: children,
|
|
4372
|
+
id: effectiveId,
|
|
4373
|
+
order,
|
|
4374
|
+
unstyled
|
|
4472
4375
|
};
|
|
4473
|
-
|
|
4474
|
-
|
|
4376
|
+
store.setExtension(surfaceId, extension);
|
|
4377
|
+
if (surfaceId && surfaceId !== "active") {
|
|
4378
|
+
store.setExtension("active", extension);
|
|
4379
|
+
}
|
|
4380
|
+
});
|
|
4381
|
+
useEffect(() => {
|
|
4475
4382
|
return () => {
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
rafRef.current = null;
|
|
4383
|
+
if (store) {
|
|
4384
|
+
store.removeExtension(surfaceId, effectiveId);
|
|
4385
|
+
if (surfaceId && surfaceId !== "active") {
|
|
4386
|
+
store.removeExtension("active", effectiveId);
|
|
4387
|
+
}
|
|
4482
4388
|
}
|
|
4483
4389
|
};
|
|
4484
|
-
}, [
|
|
4390
|
+
}, [store, surfaceId, effectiveId]);
|
|
4485
4391
|
}
|
|
4486
|
-
function
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4392
|
+
function useIsSurfaceExtensionsVisible(activeItem) {
|
|
4393
|
+
const store = use(SurfaceExtensionsContext)?.extensions ?? null;
|
|
4394
|
+
const surfaceId = activeItem?.surfaceId || "active";
|
|
4395
|
+
const isSurface = Boolean(activeItem?.isSurface);
|
|
4396
|
+
const phase = activeItem?.surfacePhase;
|
|
4397
|
+
const isBodyVisible = phase === DOCK_SURFACE_PHASE.EXPANDING_BODY || phase === DOCK_SURFACE_PHASE.OPEN;
|
|
4398
|
+
const subscribe2 = useCallback(
|
|
4399
|
+
(onStoreChange) => store ? store.subscribe(onStoreChange) : () => {
|
|
4400
|
+
},
|
|
4401
|
+
[store]
|
|
4402
|
+
);
|
|
4403
|
+
const getSnapshot2 = useCallback(
|
|
4404
|
+
() => store ? store.getExtensionsForSurface(surfaceId).length : 0,
|
|
4405
|
+
[store, surfaceId]
|
|
4406
|
+
);
|
|
4407
|
+
const dynamicCount = useSyncExternalStore(subscribe2, getSnapshot2, () => 0);
|
|
4408
|
+
const descriptorCount = useMemo(() => {
|
|
4409
|
+
const raw = activeItem?.surfaceExtensions || activeItem?.extensions || [];
|
|
4410
|
+
return Array.isArray(raw) ? raw.length : 0;
|
|
4411
|
+
}, [activeItem?.surfaceExtensions, activeItem?.extensions]);
|
|
4412
|
+
return Boolean(
|
|
4413
|
+
isSurface && isBodyVisible && (dynamicCount > 0 || descriptorCount > 0)
|
|
4491
4414
|
);
|
|
4492
4415
|
}
|
|
4493
|
-
function
|
|
4494
|
-
|
|
4495
|
-
isHud = false,
|
|
4496
|
-
setDockHeight,
|
|
4497
|
-
surfacePhase = DOCK_SURFACE_PHASE.IDLE
|
|
4416
|
+
function useDockSurfaceExtensionsBarModel({
|
|
4417
|
+
activeItem
|
|
4498
4418
|
}) {
|
|
4499
|
-
const
|
|
4500
|
-
|
|
4419
|
+
const store = use(SurfaceExtensionsContext)?.extensions ?? null;
|
|
4420
|
+
const surfaceId = activeItem?.surfaceId || "active";
|
|
4421
|
+
const subscribe2 = useCallback(
|
|
4422
|
+
(onStoreChange) => store ? store.subscribe(onStoreChange) : () => {
|
|
4423
|
+
},
|
|
4424
|
+
[store]
|
|
4501
4425
|
);
|
|
4502
|
-
const
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
const surfacePhaseRef = useRef(surfacePhase);
|
|
4506
|
-
const lastAppliedContainerHeightRef = useRef(
|
|
4507
|
-
isHud ? DOCK_CARD_LAYOUT.hudHeight : DOCK_CARD_LAYOUT.baseHeight
|
|
4426
|
+
const getSnapshot2 = useCallback(
|
|
4427
|
+
() => store ? store.getExtensionsForSurface(surfaceId) : [],
|
|
4428
|
+
[store, surfaceId]
|
|
4508
4429
|
);
|
|
4509
|
-
const
|
|
4510
|
-
|
|
4430
|
+
const dynamicExtensions = useSyncExternalStore(
|
|
4431
|
+
subscribe2,
|
|
4432
|
+
getSnapshot2,
|
|
4433
|
+
() => []
|
|
4511
4434
|
);
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
}, [
|
|
4516
|
-
const
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4435
|
+
const descriptorExtensions = useMemo(() => {
|
|
4436
|
+
const raw = activeItem?.surfaceExtensions || activeItem?.extensions || [];
|
|
4437
|
+
return Array.isArray(raw) ? raw.map(normalizeSurfaceExtension).filter((ext) => ext !== null) : [];
|
|
4438
|
+
}, [activeItem?.surfaceExtensions, activeItem?.extensions]);
|
|
4439
|
+
const allExtensions = useMemo(() => {
|
|
4440
|
+
const map = /* @__PURE__ */ new Map();
|
|
4441
|
+
descriptorExtensions.forEach((ext) => map.set(ext.id, ext));
|
|
4442
|
+
dynamicExtensions.forEach((ext) => map.set(ext.id, ext));
|
|
4443
|
+
return Array.from(map.values()).sort((a, b) => a.order - b.order);
|
|
4444
|
+
}, [descriptorExtensions, dynamicExtensions]);
|
|
4445
|
+
return { allExtensions };
|
|
4446
|
+
}
|
|
4447
|
+
var DRAG_RANGE = [...DOCK_SURFACE_DRAG_INTERPOLATION.DRAG_RANGE];
|
|
4448
|
+
var OPACITY_RANGE = [...DOCK_SURFACE_DRAG_INTERPOLATION.OPACITY_RANGE];
|
|
4449
|
+
var SCALE_RANGE = [...DOCK_SURFACE_DRAG_INTERPOLATION.SCALE_RANGE];
|
|
4450
|
+
function useDockSurfaceShellModel({
|
|
4451
|
+
ref,
|
|
4452
|
+
title = "",
|
|
4453
|
+
onClose = null,
|
|
4454
|
+
onBack = null,
|
|
4455
|
+
allowSwipeDismiss = true,
|
|
4456
|
+
closeLabel = "Close surface",
|
|
4457
|
+
backLabel = "Previous step",
|
|
4458
|
+
showControls = false,
|
|
4459
|
+
className = "",
|
|
4460
|
+
contentClassName = "",
|
|
4461
|
+
children,
|
|
4462
|
+
onAnimationComplete = null,
|
|
4463
|
+
isActive = true,
|
|
4464
|
+
surfaceId = null,
|
|
4465
|
+
surfacePhase = DOCK_SURFACE_PHASE.OPEN,
|
|
4466
|
+
surfaceWidth = null
|
|
4467
|
+
}) {
|
|
4468
|
+
const surfaceElementRef = useRef(null);
|
|
4469
|
+
const setSurfaceElementRef = useCallback(
|
|
4470
|
+
(node) => {
|
|
4471
|
+
surfaceElementRef.current = node;
|
|
4472
|
+
if (typeof ref === "function") ref(node);
|
|
4473
|
+
else if (ref) ref.current = node;
|
|
4474
|
+
},
|
|
4475
|
+
[ref]
|
|
4476
|
+
);
|
|
4477
|
+
const isFullyOpen = surfacePhase === DOCK_SURFACE_PHASE.OPEN;
|
|
4478
|
+
const titleId = surfaceId == null ? void 0 : `dock-surface-title-${surfaceId}`;
|
|
4479
|
+
const dragY = useMotionValue(0);
|
|
4480
|
+
const dragOpacity = useTransform(dragY, DRAG_RANGE, OPACITY_RANGE);
|
|
4481
|
+
const dragScale = useTransform(dragY, DRAG_RANGE, SCALE_RANGE);
|
|
4482
|
+
useDockFocusTrap({
|
|
4483
|
+
containerRef: surfaceElementRef,
|
|
4484
|
+
enabled: isActive && isFullyOpen,
|
|
4485
|
+
onDismiss: typeof onClose === "function" ? onClose : null
|
|
4486
|
+
});
|
|
4487
|
+
const handleDragEnd = (_event, info) => {
|
|
4488
|
+
if (!isActive || !allowSwipeDismiss || typeof onClose !== "function" || !isFullyOpen)
|
|
4489
|
+
return;
|
|
4490
|
+
if (info.offset.y > DOCK_SURFACE_DRAG_THRESHOLDS.DISMISS_OFFSET_Y || info.velocity.y > DOCK_SURFACE_DRAG_THRESHOLDS.DISMISS_VELOCITY_Y) {
|
|
4491
|
+
onClose();
|
|
4538
4492
|
}
|
|
4539
|
-
}
|
|
4540
|
-
const
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4493
|
+
};
|
|
4494
|
+
const dragControls = useDragControls();
|
|
4495
|
+
const canDragDismiss = Boolean(
|
|
4496
|
+
isActive && allowSwipeDismiss && typeof onClose === "function" && isFullyOpen
|
|
4497
|
+
);
|
|
4498
|
+
const handleSurfacePointerDown = useCallback(
|
|
4499
|
+
(event) => {
|
|
4500
|
+
if (!canDragDismiss) return;
|
|
4501
|
+
const target = event.target;
|
|
4502
|
+
if (target?.closest?.(
|
|
4503
|
+
'input, textarea, select, [role="slider"], [data-no-surface-drag], [data-lenis-prevent]'
|
|
4504
|
+
)) {
|
|
4505
|
+
return;
|
|
4506
|
+
}
|
|
4507
|
+
dragControls.start(event);
|
|
4545
4508
|
},
|
|
4546
|
-
[
|
|
4509
|
+
[canDragDismiss, dragControls]
|
|
4547
4510
|
);
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
}
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4511
|
+
const isBodyVisible = surfacePhase === DOCK_SURFACE_PHASE.EXPANDING_BODY || surfacePhase === DOCK_SURFACE_PHASE.OPEN;
|
|
4512
|
+
const resolvedSurfaceId = surfaceId || "active";
|
|
4513
|
+
const bodyVariants = useMemo(
|
|
4514
|
+
() => ({
|
|
4515
|
+
hidden: dockSurfaceBodyRole.hidden,
|
|
4516
|
+
visible: {
|
|
4517
|
+
...dockSurfaceBodyRole.visible,
|
|
4518
|
+
transition: surfacePhase === DOCK_SURFACE_PHASE.EXPANDING_BODY ? DOCK_SURFACE_BODY_ENTER_TRANSITION : DOCK_SURFACE_BODY_STEP_TRANSITION
|
|
4519
|
+
},
|
|
4520
|
+
exit: {
|
|
4521
|
+
...dockSurfaceBodyRole.exit,
|
|
4522
|
+
transition: DOCK_SURFACE_BODY_EXIT_TRANSITION
|
|
4523
|
+
}
|
|
4524
|
+
}),
|
|
4525
|
+
[surfacePhase]
|
|
4526
|
+
);
|
|
4527
|
+
const surfaceItemValue = useMemo(
|
|
4528
|
+
() => ({ id: resolvedSurfaceId, width: surfaceWidth }),
|
|
4529
|
+
[resolvedSurfaceId, surfaceWidth]
|
|
4530
|
+
);
|
|
4531
|
+
return {
|
|
4532
|
+
setSurfaceElementRef,
|
|
4533
|
+
titleId,
|
|
4534
|
+
dragY,
|
|
4535
|
+
dragOpacity,
|
|
4536
|
+
dragScale,
|
|
4537
|
+
handleDragEnd,
|
|
4538
|
+
dragControls,
|
|
4539
|
+
canDragDismiss,
|
|
4540
|
+
handleSurfacePointerDown,
|
|
4541
|
+
isBodyVisible,
|
|
4542
|
+
bodyVariants,
|
|
4543
|
+
surfaceItemValue
|
|
4544
|
+
};
|
|
4565
4545
|
}
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
const
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
if (typeof document !== "undefined") setPortalTarget(document.body);
|
|
4573
|
-
}, []);
|
|
4574
|
-
useEffect(() => {
|
|
4575
|
-
if (typeof window === "undefined") return void 0;
|
|
4576
|
-
let resizeFrameId = null;
|
|
4577
|
-
const handleResize = () => {
|
|
4578
|
-
if (resizeFrameId !== null) return;
|
|
4579
|
-
resizeFrameId = window.requestAnimationFrame(() => {
|
|
4580
|
-
resizeFrameId = null;
|
|
4581
|
-
setViewportRevision((revision) => revision + 1);
|
|
4582
|
-
});
|
|
4583
|
-
};
|
|
4584
|
-
window.addEventListener("resize", handleResize, { passive: true });
|
|
4585
|
-
return () => {
|
|
4586
|
-
window.removeEventListener("resize", handleResize);
|
|
4587
|
-
if (resizeFrameId !== null) window.cancelAnimationFrame(resizeFrameId);
|
|
4588
|
-
};
|
|
4589
|
-
}, []);
|
|
4590
|
-
return { portalTarget, stackWidth };
|
|
4546
|
+
|
|
4547
|
+
// src/modules/dock/styles.ts
|
|
4548
|
+
function isValidBannerUrl(banner) {
|
|
4549
|
+
const value = trimToNull(banner);
|
|
4550
|
+
if (!value) return false;
|
|
4551
|
+
return /^(https?:\/\/|\/|data:image\/)/.test(value);
|
|
4591
4552
|
}
|
|
4592
|
-
function
|
|
4593
|
-
const
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4553
|
+
function splitStyle(style = {}) {
|
|
4554
|
+
const { className, ...inlineStyle } = style;
|
|
4555
|
+
return {
|
|
4556
|
+
className,
|
|
4557
|
+
inlineStyle
|
|
4558
|
+
};
|
|
4598
4559
|
}
|
|
4599
|
-
function
|
|
4600
|
-
|
|
4560
|
+
function getLineClampStyle(maxLines, style) {
|
|
4561
|
+
if (Number(maxLines) <= 1) return style;
|
|
4562
|
+
return {
|
|
4563
|
+
WebkitBoxOrient: "vertical",
|
|
4564
|
+
WebkitLineClamp: maxLines,
|
|
4565
|
+
display: "-webkit-box",
|
|
4566
|
+
overflow: "hidden",
|
|
4567
|
+
...style
|
|
4568
|
+
};
|
|
4601
4569
|
}
|
|
4602
|
-
function
|
|
4570
|
+
function getImageIconStyle(style, icon) {
|
|
4571
|
+
const nextStyle = {
|
|
4572
|
+
...style
|
|
4573
|
+
};
|
|
4574
|
+
delete nextStyle.background;
|
|
4575
|
+
delete nextStyle.backgroundImage;
|
|
4603
4576
|
return {
|
|
4604
|
-
...
|
|
4605
|
-
|
|
4606
|
-
...toObject(hoverStyle?.[section])
|
|
4577
|
+
...nextStyle,
|
|
4578
|
+
backgroundImage: `url(${icon})`
|
|
4607
4579
|
};
|
|
4608
4580
|
}
|
|
4609
|
-
function
|
|
4581
|
+
function resolveDockActionClass(slots, {
|
|
4582
|
+
className = "",
|
|
4583
|
+
button = "",
|
|
4610
4584
|
isActive = false,
|
|
4611
|
-
|
|
4585
|
+
variant = "",
|
|
4586
|
+
tone = "",
|
|
4587
|
+
base,
|
|
4588
|
+
cn: classNamesFn
|
|
4612
4589
|
} = {}) {
|
|
4613
|
-
const
|
|
4614
|
-
const
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
card: {},
|
|
4618
|
-
icon: {},
|
|
4619
|
-
title: {},
|
|
4620
|
-
description: {}
|
|
4590
|
+
const resolve = classNamesFn || cn;
|
|
4591
|
+
const toneClasses = {
|
|
4592
|
+
muted: slots.actionMuted,
|
|
4593
|
+
active: slots.actionActive
|
|
4621
4594
|
};
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
);
|
|
4595
|
+
if (button && !className && base === void 0) {
|
|
4596
|
+
if (tone) {
|
|
4597
|
+
const toneClass = toneClasses[tone] || slots.actionSurface || slots.actionMuted;
|
|
4598
|
+
return resolve(button, toneClass);
|
|
4599
|
+
}
|
|
4600
|
+
const stateToken = isActive ? slots.actionActive : slots.actionMuted;
|
|
4601
|
+
return resolve(button, stateToken);
|
|
4629
4602
|
}
|
|
4630
|
-
|
|
4603
|
+
const elementClass = className || button;
|
|
4604
|
+
const resolvedBase = base !== void 0 ? base : slots.action;
|
|
4605
|
+
const stateClass = variant || tone && (toneClasses[tone] || slots.actionSurface) || (isActive ? slots.actionActive : slots.actionMuted);
|
|
4606
|
+
return resolve(stateClass, resolvedBase, elementClass);
|
|
4607
|
+
}
|
|
4608
|
+
function getDockItemCardProps({
|
|
4609
|
+
cardScale,
|
|
4610
|
+
cardStyle,
|
|
4611
|
+
expanded,
|
|
4612
|
+
hasExtensions = false,
|
|
4613
|
+
isAnchoredToBottom,
|
|
4614
|
+
position,
|
|
4615
|
+
theme,
|
|
4616
|
+
visibleCount = 3
|
|
4617
|
+
}) {
|
|
4618
|
+
const { offsetY: collapsedOffsetY, scale: collapsedScale } = DOCK_CARD_LAYOUT.collapsed;
|
|
4619
|
+
const { offsetY: expandedOffsetY } = DOCK_CARD_LAYOUT.expanded;
|
|
4620
|
+
const safeCardStyle = { ...cardStyle };
|
|
4621
|
+
delete safeCardStyle.scale;
|
|
4622
|
+
delete safeCardStyle.className;
|
|
4623
|
+
const isTop = position === 0;
|
|
4624
|
+
const isShelf = !expanded && position === 1 && hasExtensions;
|
|
4625
|
+
const isHeavyBlur = position < visibleCount || expanded || isShelf;
|
|
4626
|
+
const collapsedScaleValue = collapsedScale ** position;
|
|
4627
|
+
const y = expanded ? position * expandedOffsetY : isShelf ? DOCK_CARD_LAYOUT.extensionShelfY : position * collapsedOffsetY;
|
|
4628
|
+
const shelfScale = DOCK_CARD_LAYOUT.extensionShelfScale ?? 0.94;
|
|
4629
|
+
const scale = expanded ? cardScale || 1 : isShelf ? shelfScale : collapsedScaleValue;
|
|
4630
|
+
const collapsedOpacity = Math.max(0.1, +(1 - position * 0.2).toFixed(2));
|
|
4631
|
+
const opacity = expanded || isShelf ? 1 : position < visibleCount ? collapsedOpacity : 0;
|
|
4631
4632
|
return {
|
|
4632
|
-
|
|
4633
|
-
|
|
4633
|
+
className: cn(theme.slots.card, cardStyle?.className),
|
|
4634
|
+
data: {
|
|
4635
|
+
"data-anchored": isAnchoredToBottom,
|
|
4636
|
+
"data-blur": isHeavyBlur ? "heavy" : "light",
|
|
4637
|
+
"data-placement": isTop ? "top" : isAnchoredToBottom ? "bottom" : "float",
|
|
4638
|
+
"data-shelf": isShelf
|
|
4639
|
+
},
|
|
4640
|
+
style: {
|
|
4641
|
+
...theme.styles.card,
|
|
4642
|
+
...safeCardStyle,
|
|
4643
|
+
willChange: "transform, opacity",
|
|
4644
|
+
transformOrigin: isAnchoredToBottom ? "bottom center" : "top center",
|
|
4645
|
+
zIndex: Z_INDEX.DOCK_CARD_STACK_BASE - position,
|
|
4646
|
+
WebkitPerspective: 1e3,
|
|
4647
|
+
perspective: 1e3,
|
|
4648
|
+
WebkitBackfaceVisibility: "hidden",
|
|
4649
|
+
backfaceVisibility: "hidden",
|
|
4650
|
+
WebkitFontSmoothing: "antialiased",
|
|
4651
|
+
transform: "translateZ(0)",
|
|
4652
|
+
...isTop ? { height: "100%" } : {},
|
|
4653
|
+
pointerEvents: expanded || position < visibleCount ? void 0 : "none"
|
|
4654
|
+
},
|
|
4655
|
+
motionValues: { y, scale, opacity }
|
|
4634
4656
|
};
|
|
4635
4657
|
}
|
|
4636
|
-
function
|
|
4637
|
-
|
|
4638
|
-
isLoading,
|
|
4639
|
-
isOverlay,
|
|
4640
|
-
path
|
|
4641
|
-
}, pathname) {
|
|
4642
|
-
return Boolean(action) && !isLoading && (isOverlay || !path || isInlineActionPathMatch(path, pathname));
|
|
4658
|
+
function toObject(value) {
|
|
4659
|
+
return isObject(value) ? value : {};
|
|
4643
4660
|
}
|
|
4644
|
-
function
|
|
4645
|
-
|
|
4646
|
-
if (
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
return Boolean(link.name && activeItem.name && link.name === activeItem.name);
|
|
4661
|
+
function pickCardSurfaceStyle(style) {
|
|
4662
|
+
const cardSurfaceStyle = {};
|
|
4663
|
+
if (style?.background != null) cardSurfaceStyle.background = style.background;
|
|
4664
|
+
if (style?.borderColor != null)
|
|
4665
|
+
cardSurfaceStyle.borderColor = style.borderColor;
|
|
4666
|
+
return cardSurfaceStyle;
|
|
4651
4667
|
}
|
|
4652
|
-
function
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
syncSurfaceStack
|
|
4657
|
-
}) {
|
|
4658
|
-
const updateSurfaceFlow = useCallback(
|
|
4659
|
-
(flowId, snapshot) => {
|
|
4660
|
-
const surfaceId = refs.flowIndex.get(flowId);
|
|
4661
|
-
if (!surfaceId) return false;
|
|
4662
|
-
const record = refs.records.get(surfaceId);
|
|
4663
|
-
if (!record?.flow) return false;
|
|
4664
|
-
const nextSession = updateSurfaceFlowSession(record.flow, snapshot);
|
|
4665
|
-
if (!nextSession) return false;
|
|
4666
|
-
const nextSurfaceEntry = {
|
|
4667
|
-
...record.entry,
|
|
4668
|
-
flow: toSurfaceFlowState(nextSession)
|
|
4669
|
-
};
|
|
4670
|
-
record.flow = nextSession;
|
|
4671
|
-
record.entry = nextSurfaceEntry;
|
|
4672
|
-
syncSurfaceFlowUrlState(nextSurfaceEntry, record.urlState);
|
|
4673
|
-
syncSurfaceStack(
|
|
4674
|
-
updateSurfaceStackEntry(
|
|
4675
|
-
refs.stackRef.current,
|
|
4676
|
-
surfaceId,
|
|
4677
|
-
() => nextSurfaceEntry
|
|
4678
|
-
)
|
|
4679
|
-
);
|
|
4680
|
-
return true;
|
|
4681
|
-
},
|
|
4682
|
-
[syncSurfaceStack, refs]
|
|
4683
|
-
);
|
|
4684
|
-
const completeSurfaceFlow = useCallback(
|
|
4685
|
-
(flowId, data = null) => {
|
|
4686
|
-
const surfaceId = refs.flowIndex.get(flowId);
|
|
4687
|
-
if (!surfaceId) return false;
|
|
4688
|
-
const record = refs.records.get(surfaceId);
|
|
4689
|
-
if (record?.flow)
|
|
4690
|
-
record.flow = {
|
|
4691
|
-
...record.flow,
|
|
4692
|
-
status: DOCK_SURFACE_FLOW_STATUS.COMPLETED
|
|
4693
|
-
};
|
|
4694
|
-
closeSurface({ data, success: true }, surfaceId);
|
|
4695
|
-
return true;
|
|
4696
|
-
},
|
|
4697
|
-
[closeSurface, refs]
|
|
4698
|
-
);
|
|
4699
|
-
const cancelSurfaceFlow = useCallback(
|
|
4700
|
-
(flowId, data = null) => {
|
|
4701
|
-
const surfaceId = refs.flowIndex.get(flowId);
|
|
4702
|
-
if (!surfaceId) return false;
|
|
4703
|
-
const record = refs.records.get(surfaceId);
|
|
4704
|
-
if (record?.flow)
|
|
4705
|
-
record.flow = {
|
|
4706
|
-
...record.flow,
|
|
4707
|
-
status: DOCK_SURFACE_FLOW_STATUS.CANCELLED
|
|
4708
|
-
};
|
|
4709
|
-
closeSurface(
|
|
4710
|
-
{ cancelled: true, data, reason: "flow-cancelled", success: false },
|
|
4711
|
-
surfaceId
|
|
4712
|
-
);
|
|
4713
|
-
return true;
|
|
4714
|
-
},
|
|
4715
|
-
[closeSurface, refs]
|
|
4716
|
-
);
|
|
4717
|
-
const getSurfaceFlow = useCallback(
|
|
4718
|
-
(flowId) => {
|
|
4719
|
-
const surfaceId = refs.flowIndex.get(flowId);
|
|
4720
|
-
const session = surfaceId ? refs.records.get(surfaceId)?.flow : null;
|
|
4721
|
-
if (!session) return null;
|
|
4722
|
-
return {
|
|
4723
|
-
cancel: (data = null) => cancelSurfaceFlow(flowId, data),
|
|
4724
|
-
complete: (data = null) => completeSurfaceFlow(flowId, data),
|
|
4725
|
-
flowId,
|
|
4726
|
-
isOpen: session.status === DOCK_SURFACE_FLOW_STATUS.OPEN,
|
|
4727
|
-
snapshot: session.snapshot,
|
|
4728
|
-
status: session.status,
|
|
4729
|
-
update: (snapshot) => updateSurfaceFlow(flowId, snapshot)
|
|
4730
|
-
};
|
|
4731
|
-
},
|
|
4732
|
-
[cancelSurfaceFlow, completeSurfaceFlow, updateSurfaceFlow, refs]
|
|
4733
|
-
);
|
|
4734
|
-
const openSurfaceFlow = useCallback(
|
|
4735
|
-
(input, flowInput = null, {
|
|
4736
|
-
preserveUrl = false,
|
|
4737
|
-
snapshot
|
|
4738
|
-
} = {}) => {
|
|
4739
|
-
const definition = createSurfaceFlowDefinition(input);
|
|
4740
|
-
if (!definition) {
|
|
4741
|
-
const error = createSurfaceError(
|
|
4742
|
-
"DOCK_SURFACE_FLOW_INVALID_DEFINITION",
|
|
4743
|
-
"Dock surface flow definition is invalid"
|
|
4744
|
-
);
|
|
4745
|
-
report("Dock surface flow definition", error);
|
|
4746
|
-
return Promise.resolve({ success: false, error });
|
|
4747
|
-
}
|
|
4748
|
-
const existingSurfaceId = refs.flowIndex.get(definition.id);
|
|
4749
|
-
if (definition.singleton && existingSurfaceId) {
|
|
4750
|
-
return refs.records.get(existingSurfaceId)?.promise ?? Promise.resolve({
|
|
4751
|
-
success: false,
|
|
4752
|
-
error: createSurfaceError(
|
|
4753
|
-
"DOCK_SURFACE_FLOW_ORPHANED",
|
|
4754
|
-
"Dock surface flow is orphaned"
|
|
4755
|
-
)
|
|
4756
|
-
});
|
|
4757
|
-
}
|
|
4758
|
-
const flowSession = createSurfaceFlowSession(definition, {
|
|
4759
|
-
input: flowInput,
|
|
4760
|
-
snapshot
|
|
4761
|
-
});
|
|
4762
|
-
try {
|
|
4763
|
-
const surfaceInput = definition.createSurface({
|
|
4764
|
-
flowId: definition.id,
|
|
4765
|
-
input: flowInput,
|
|
4766
|
-
snapshot: flowSession?.snapshot
|
|
4767
|
-
});
|
|
4768
|
-
return openSurface(surfaceInput, { flowSession, preserveUrl });
|
|
4769
|
-
} catch (error) {
|
|
4770
|
-
report("Dock surface flow factory", error);
|
|
4771
|
-
return Promise.resolve({ success: false, error });
|
|
4772
|
-
}
|
|
4773
|
-
},
|
|
4774
|
-
[openSurface, refs]
|
|
4775
|
-
);
|
|
4776
|
-
const restoreSurfaceFlow = useCallback(
|
|
4777
|
-
(input) => {
|
|
4778
|
-
const definition = createSurfaceFlowDefinition(input);
|
|
4779
|
-
const snapshot = getRestorableSurfaceFlowSnapshot(definition);
|
|
4780
|
-
if (!definition || snapshot === void 0) return Promise.resolve(null);
|
|
4781
|
-
return openSurfaceFlow(definition, null, { preserveUrl: true, snapshot });
|
|
4782
|
-
},
|
|
4783
|
-
[openSurfaceFlow]
|
|
4784
|
-
);
|
|
4668
|
+
function toStyleSections(value) {
|
|
4669
|
+
return toObject(value);
|
|
4670
|
+
}
|
|
4671
|
+
function mergeStyleSection(baseStyle, stateStyle, hoverStyle, section) {
|
|
4785
4672
|
return {
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
openSurfaceFlow,
|
|
4790
|
-
restoreSurfaceFlow,
|
|
4791
|
-
updateSurfaceFlow
|
|
4673
|
+
...toObject(baseStyle?.[section]),
|
|
4674
|
+
...toObject(stateStyle?.[section]),
|
|
4675
|
+
...toObject(hoverStyle?.[section])
|
|
4792
4676
|
};
|
|
4793
4677
|
}
|
|
4794
|
-
function
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
if (focusRestoreFrameRef.current !== null) {
|
|
4821
|
-
runtimeScheduler.cancel(focusRestoreFrameRef.current);
|
|
4822
|
-
focusRestoreFrameRef.current = null;
|
|
4823
|
-
}
|
|
4824
|
-
const result = { cancelled: true, reason: "unmount", success: false };
|
|
4825
|
-
refs.stackRef.current.forEach(
|
|
4826
|
-
({ id }) => releaseSurfaceResources({ refs, result, surfaceId: id })
|
|
4827
|
-
);
|
|
4828
|
-
refs.stackRef.current = [];
|
|
4829
|
-
refs.payloads.clear();
|
|
4830
|
-
refs.records.clear();
|
|
4831
|
-
refs.flowIndex.clear();
|
|
4832
|
-
};
|
|
4833
|
-
}, [clearChoreographyTimers, focusRestoreFrameRef, refs, runtimeScheduler]);
|
|
4678
|
+
function resolveDockVisualStyle(style, {
|
|
4679
|
+
isActive = false,
|
|
4680
|
+
isHovered = false
|
|
4681
|
+
} = {}) {
|
|
4682
|
+
const baseStyle = toObject(style);
|
|
4683
|
+
const stateStyle = isActive ? toStyleSections(baseStyle.active) : toStyleSections(baseStyle.inactive);
|
|
4684
|
+
const hoverStyle = isHovered ? toStyleSections(baseStyle.hover) : {};
|
|
4685
|
+
const sections = {
|
|
4686
|
+
card: {},
|
|
4687
|
+
icon: {},
|
|
4688
|
+
title: {},
|
|
4689
|
+
description: {}
|
|
4690
|
+
};
|
|
4691
|
+
for (const section of DOCK_STYLE_SECTIONS) {
|
|
4692
|
+
sections[section] = mergeStyleSection(
|
|
4693
|
+
baseStyle,
|
|
4694
|
+
stateStyle,
|
|
4695
|
+
hoverStyle,
|
|
4696
|
+
section
|
|
4697
|
+
);
|
|
4698
|
+
}
|
|
4699
|
+
sections.card = { ...pickCardSurfaceStyle(baseStyle), ...sections.card };
|
|
4700
|
+
return {
|
|
4701
|
+
...sections,
|
|
4702
|
+
scale: hoverStyle?.card?.scale ?? stateStyle?.card?.scale ?? baseStyle?.scale
|
|
4703
|
+
};
|
|
4834
4704
|
}
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
children,
|
|
4838
|
-
value
|
|
4839
|
-
}) {
|
|
4840
|
-
return /* @__PURE__ */ jsx(SurfaceFlowContext, { value, children });
|
|
4705
|
+
function useDockTheme() {
|
|
4706
|
+
return useTheme(dockTheme);
|
|
4841
4707
|
}
|
|
4842
|
-
function
|
|
4843
|
-
const
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
const
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
}
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
}
|
|
4870
|
-
|
|
4708
|
+
function useDockActionClass() {
|
|
4709
|
+
const { slots } = useDockTheme();
|
|
4710
|
+
return useCallback(
|
|
4711
|
+
(options) => resolveDockActionClass(slots, options),
|
|
4712
|
+
[slots]
|
|
4713
|
+
);
|
|
4714
|
+
}
|
|
4715
|
+
function useDockRegistration(config, options) {
|
|
4716
|
+
useModuleRegistration("dock", config, options);
|
|
4717
|
+
}
|
|
4718
|
+
function useDockBanner(banner, options) {
|
|
4719
|
+
const position = options?.position;
|
|
4720
|
+
const size = options?.size;
|
|
4721
|
+
const opacity = options?.opacity;
|
|
4722
|
+
const repeat = options?.repeat;
|
|
4723
|
+
const targetPath = options?.path;
|
|
4724
|
+
const config = useMemo(() => {
|
|
4725
|
+
if (!banner) return null;
|
|
4726
|
+
if (typeof banner === "string") {
|
|
4727
|
+
return {
|
|
4728
|
+
bannerUrl: banner,
|
|
4729
|
+
...position ? { bannerPosition: position } : {},
|
|
4730
|
+
...size ? { bannerSize: size } : {},
|
|
4731
|
+
...opacity !== void 0 ? { bannerOpacity: opacity } : {},
|
|
4732
|
+
...repeat ? { bannerRepeat: repeat } : {},
|
|
4733
|
+
...targetPath ? { path: targetPath } : {}
|
|
4734
|
+
};
|
|
4735
|
+
}
|
|
4736
|
+
if (typeof banner === "object") {
|
|
4737
|
+
return {
|
|
4738
|
+
bannerUrl: banner.url || banner.bannerUrl,
|
|
4739
|
+
bannerPosition: banner.position || banner.bannerPosition || position,
|
|
4740
|
+
bannerSize: banner.size || banner.bannerSize || size,
|
|
4741
|
+
bannerOpacity: banner.opacity ?? banner.bannerOpacity ?? opacity,
|
|
4742
|
+
bannerRepeat: banner.repeat || banner.bannerRepeat || repeat,
|
|
4743
|
+
...targetPath ? { path: targetPath } : {}
|
|
4744
|
+
};
|
|
4745
|
+
}
|
|
4746
|
+
return null;
|
|
4747
|
+
}, [banner, position, size, opacity, repeat, targetPath]);
|
|
4748
|
+
useDockRegistration(config, options);
|
|
4749
|
+
}
|
|
4750
|
+
var EMPTY_DOCK_STATE_STORE = createStore(EMPTY_DOCK_STATE);
|
|
4751
|
+
function selectDockConfigState(state) {
|
|
4752
|
+
return {
|
|
4753
|
+
activeItem: state.activeItem,
|
|
4754
|
+
dockHeight: state.dockHeight,
|
|
4755
|
+
expanded: state.expanded,
|
|
4756
|
+
pathname: state.pathname
|
|
4757
|
+
};
|
|
4758
|
+
}
|
|
4759
|
+
function useDockConfig(configOrTitle, options) {
|
|
4760
|
+
const normalizedConfig = useMemo(() => {
|
|
4761
|
+
if (!configOrTitle) return null;
|
|
4762
|
+
if (typeof configOrTitle === "string") return { title: configOrTitle };
|
|
4763
|
+
return configOrTitle;
|
|
4764
|
+
}, [configOrTitle]);
|
|
4765
|
+
useDockRegistration(normalizedConfig, options);
|
|
4766
|
+
const dockContext = use(DockContext);
|
|
4767
|
+
const actions = dockContext?.actions;
|
|
4768
|
+
const state = useStore(
|
|
4769
|
+
dockContext?.store ?? EMPTY_DOCK_STATE_STORE,
|
|
4770
|
+
selectDockConfigState,
|
|
4771
|
+
shallowEqual
|
|
4871
4772
|
);
|
|
4872
4773
|
return useMemo(
|
|
4873
4774
|
() => ({
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4775
|
+
activeItem: state.activeItem,
|
|
4776
|
+
clearHud: actions?.clearHud ?? (() => {
|
|
4777
|
+
}),
|
|
4778
|
+
closeAllSurfaces: actions?.closeAllSurfaces ?? (() => {
|
|
4779
|
+
}),
|
|
4780
|
+
closeSurface: actions?.closeSurface ?? (() => {
|
|
4781
|
+
}),
|
|
4782
|
+
expanded: state.expanded,
|
|
4783
|
+
dockHeight: state.dockHeight,
|
|
4784
|
+
navigate: actions?.navigate ?? (async () => false),
|
|
4785
|
+
openSurface: actions?.openSurface ?? (() => void 0),
|
|
4786
|
+
pathname: state.pathname,
|
|
4787
|
+
setExpanded: actions?.setExpanded ?? (() => {
|
|
4788
|
+
}),
|
|
4789
|
+
setHud: actions?.setHud ?? (() => {
|
|
4790
|
+
}),
|
|
4791
|
+
setSearchQuery: actions?.setSearchQuery ?? (() => {
|
|
4792
|
+
})
|
|
4882
4793
|
}),
|
|
4883
|
-
[
|
|
4794
|
+
[actions, state]
|
|
4795
|
+
);
|
|
4796
|
+
}
|
|
4797
|
+
function useDockDimensions() {
|
|
4798
|
+
const { dockHeight } = useDockHeight();
|
|
4799
|
+
const activeItem = useDockSelector((state) => state.activeItem);
|
|
4800
|
+
return {
|
|
4801
|
+
height: dockHeight,
|
|
4802
|
+
width: activeItem?.width ?? null,
|
|
4803
|
+
isSurface: Boolean(activeItem?.isSurface)
|
|
4804
|
+
};
|
|
4805
|
+
}
|
|
4806
|
+
function useSurfaceReturn() {
|
|
4807
|
+
const pathname = usePathname();
|
|
4808
|
+
const { continuity } = useDockActions();
|
|
4809
|
+
const dockReturnHandoffs = useDockSelector(
|
|
4810
|
+
(state) => state.dockReturnHandoffs
|
|
4811
|
+
);
|
|
4812
|
+
const entries = useMemo(
|
|
4813
|
+
() => (dockReturnHandoffs || []).filter(
|
|
4814
|
+
(handoff) => isSamePath(handoff.path, pathname)
|
|
4815
|
+
),
|
|
4816
|
+
[dockReturnHandoffs, pathname]
|
|
4817
|
+
);
|
|
4818
|
+
const consume = useCallback(
|
|
4819
|
+
(handoffId = null) => continuity.consumeReturn(pathname, handoffId),
|
|
4820
|
+
[continuity, pathname]
|
|
4821
|
+
);
|
|
4822
|
+
return useMemo(
|
|
4823
|
+
() => ({ consume, entries, peek: () => entries[0] || null }),
|
|
4824
|
+
[consume, entries]
|
|
4825
|
+
);
|
|
4826
|
+
}
|
|
4827
|
+
|
|
4828
|
+
// src/modules/dock/runtime/pipeline.ts
|
|
4829
|
+
function isSameDockItem(item, candidate) {
|
|
4830
|
+
return Boolean(
|
|
4831
|
+
item?.path && item.path === candidate?.path || item?.name && item.name === candidate?.name
|
|
4832
|
+
);
|
|
4833
|
+
}
|
|
4834
|
+
var isSameItem = isSameDockItem;
|
|
4835
|
+
function getItemKey(link, index = 0) {
|
|
4836
|
+
const identity = link?.id ?? link?.path ?? link?.name ?? link?.type;
|
|
4837
|
+
return `dock-card:${identity == null ? `slot-${index}` : String(identity)}`;
|
|
4838
|
+
}
|
|
4839
|
+
function resolveDockHeaderKey({
|
|
4840
|
+
link,
|
|
4841
|
+
description = "",
|
|
4842
|
+
showVideoIcon = false
|
|
4843
|
+
}) {
|
|
4844
|
+
const statusPart = link?.isStatus ? `status:${link.statusType || link.type || "status"}` : "standard";
|
|
4845
|
+
const identityPart = link?.path || link?.name || link?.id || "item";
|
|
4846
|
+
const titlePart = link?.title || link?.name || "";
|
|
4847
|
+
const descPart = description || "";
|
|
4848
|
+
const iconPart = showVideoIcon ? "video" : link?.icon || "no-icon";
|
|
4849
|
+
return `${statusPart}:${identityPart}:${iconPart}:${titlePart}:${descPart}`;
|
|
4850
|
+
}
|
|
4851
|
+
function findDockItemIndex(dockItems, activeItem, pathname) {
|
|
4852
|
+
const normalizedPathname = normalizePath(pathname);
|
|
4853
|
+
const selectedDataSourceIndex = dockItems.findIndex(
|
|
4854
|
+
(item) => item.isDataSource && item.isSelected
|
|
4855
|
+
);
|
|
4856
|
+
if (selectedDataSourceIndex !== -1) return selectedDataSourceIndex;
|
|
4857
|
+
if (activeItem) {
|
|
4858
|
+
const matchedActiveIndex = dockItems.findIndex(
|
|
4859
|
+
(item) => item.path && isSamePath(item.path, activeItem.path) || item.name && item.name === activeItem.name
|
|
4860
|
+
);
|
|
4861
|
+
if (matchedActiveIndex !== -1) return matchedActiveIndex;
|
|
4862
|
+
}
|
|
4863
|
+
return dockItems.findIndex(
|
|
4864
|
+
(item) => isSamePath(item.path, normalizedPathname) || item.targetPath && isSamePath(item.targetPath, normalizedPathname)
|
|
4884
4865
|
);
|
|
4885
4866
|
}
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
children,
|
|
4891
|
-
className = "",
|
|
4892
|
-
disabled = false,
|
|
4893
|
-
onClick,
|
|
4894
|
-
ariaLabel,
|
|
4895
|
-
icon = null
|
|
4867
|
+
function resolveActiveIndex({
|
|
4868
|
+
dockItems,
|
|
4869
|
+
activeItem,
|
|
4870
|
+
pathname
|
|
4896
4871
|
}) {
|
|
4897
|
-
|
|
4898
|
-
return { contextRadius };
|
|
4872
|
+
return Math.max(0, findDockItemIndex(dockItems, activeItem, pathname));
|
|
4899
4873
|
}
|
|
4900
|
-
function
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
const
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4874
|
+
function shouldKeepAncestorItem(item, activePath) {
|
|
4875
|
+
const policy = item?.keepWhenDescendant;
|
|
4876
|
+
if (typeof policy === "function") {
|
|
4877
|
+
try {
|
|
4878
|
+
return Boolean(policy(activePath, item));
|
|
4879
|
+
} catch {
|
|
4880
|
+
return false;
|
|
4881
|
+
}
|
|
4882
|
+
}
|
|
4883
|
+
return policy === true;
|
|
4884
|
+
}
|
|
4885
|
+
function isAncestorPath(item, activePath) {
|
|
4886
|
+
const candidatePath = item?.path;
|
|
4887
|
+
if (!candidatePath || candidatePath === "/" || candidatePath === activePath) {
|
|
4888
|
+
return false;
|
|
4889
|
+
}
|
|
4890
|
+
return isPathPrefix(candidatePath, activePath) && !shouldKeepAncestorItem(item, activePath);
|
|
4891
|
+
}
|
|
4892
|
+
function removeAncestorDuplicates(items = []) {
|
|
4893
|
+
if (!Array.isArray(items) || items.length <= 1) return items;
|
|
4894
|
+
const activePath = items[0]?.path;
|
|
4895
|
+
if (!activePath) return items;
|
|
4896
|
+
return items.filter(
|
|
4897
|
+
(item, index) => index === 0 || !isAncestorPath(item, activePath)
|
|
4922
4898
|
);
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4899
|
+
}
|
|
4900
|
+
function replaceActiveItem(items, activeIndex, activeItem) {
|
|
4901
|
+
if (activeIndex === -1 || !activeItem) return items;
|
|
4902
|
+
const nextItems = [...items];
|
|
4903
|
+
nextItems[activeIndex] = activeItem;
|
|
4904
|
+
return nextItems;
|
|
4905
|
+
}
|
|
4906
|
+
function removeInactiveLoadingItems(items = [], activeItem = null) {
|
|
4907
|
+
if (!Array.isArray(items) || items.length === 0) return items;
|
|
4908
|
+
return items.filter(
|
|
4909
|
+
(item) => !item?.isLoading || isSameItem(item, activeItem)
|
|
4927
4910
|
);
|
|
4928
|
-
return { isBodyVisible, dynamicAction };
|
|
4929
4911
|
}
|
|
4930
|
-
function
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
const
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4912
|
+
function reorderItemsWithActiveFirst(items, activeIndex) {
|
|
4913
|
+
if (activeIndex === -1) return items;
|
|
4914
|
+
const active = items[activeIndex];
|
|
4915
|
+
const rest = [
|
|
4916
|
+
...items.slice(0, activeIndex),
|
|
4917
|
+
...items.slice(activeIndex + 1)
|
|
4918
|
+
];
|
|
4919
|
+
rest.sort((a, b) => a.path === "/" ? 1 : b.path === "/" ? -1 : 0);
|
|
4920
|
+
return [active, ...rest];
|
|
4938
4921
|
}
|
|
4939
|
-
function
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4922
|
+
function shouldRenderInlineAction({
|
|
4923
|
+
action,
|
|
4924
|
+
isLoading,
|
|
4925
|
+
isOverlay,
|
|
4926
|
+
path
|
|
4927
|
+
}, pathname) {
|
|
4928
|
+
return Boolean(action) && !isLoading && (isOverlay || !path || isInlineActionPathMatch(path, pathname));
|
|
4929
|
+
}
|
|
4930
|
+
function getIsItemActive(link, activeItem) {
|
|
4931
|
+
if (!link || !activeItem) return false;
|
|
4932
|
+
if (link.path && activeItem.path && isSamePath(link.path, activeItem.path))
|
|
4933
|
+
return true;
|
|
4934
|
+
if (link.targetPath && activeItem.targetPath && isSamePath(link.targetPath, activeItem.targetPath))
|
|
4935
|
+
return true;
|
|
4936
|
+
return Boolean(link.name && activeItem.name && link.name === activeItem.name);
|
|
4937
|
+
}
|
|
4938
|
+
function getViewportMaxHeight() {
|
|
4939
|
+
if (typeof window === "undefined") return Infinity;
|
|
4940
|
+
return window.innerHeight - VIEWPORT_MARGIN;
|
|
4941
|
+
}
|
|
4942
|
+
function getContainerHeight({
|
|
4943
|
+
cardContentHeight,
|
|
4944
|
+
isHud = false
|
|
4946
4945
|
}) {
|
|
4947
|
-
const
|
|
4948
|
-
const
|
|
4949
|
-
const
|
|
4950
|
-
const
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4946
|
+
const chromeHeight = DOCK_CARD_LAYOUT.chromeHeight;
|
|
4947
|
+
const minCardHeight = isHud ? DOCK_CARD_LAYOUT.hudHeight : DOCK_CARD_LAYOUT.baseHeight;
|
|
4948
|
+
const numericContentHeight = Number(cardContentHeight);
|
|
4949
|
+
const nextCardHeight = Math.max(
|
|
4950
|
+
minCardHeight,
|
|
4951
|
+
(Number.isFinite(numericContentHeight) ? numericContentHeight : 0) + chromeHeight
|
|
4952
|
+
);
|
|
4953
|
+
return Math.min(nextCardHeight, getViewportMaxHeight());
|
|
4954
|
+
}
|
|
4955
|
+
function getDockCardWidth({
|
|
4956
|
+
width
|
|
4957
|
+
} = {}) {
|
|
4958
|
+
if (typeof window === "undefined") return width ? Number(width) || 460 : 460;
|
|
4959
|
+
const windowWidth = window.innerWidth;
|
|
4960
|
+
const isDesktop = windowWidth >= 640;
|
|
4961
|
+
const targetWidth = Number(width);
|
|
4962
|
+
if (Number.isFinite(targetWidth) && targetWidth > 0) {
|
|
4963
|
+
return Math.min(
|
|
4964
|
+
targetWidth,
|
|
4965
|
+
Math.max(windowWidth - (isDesktop ? 32 : 16), 0)
|
|
4966
|
+
);
|
|
4967
|
+
}
|
|
4968
|
+
return Math.min(460, Math.max(windowWidth - 16, 0));
|
|
4969
|
+
}
|
|
4970
|
+
function getObservedHeight(entry, element) {
|
|
4971
|
+
const rawBorderBoxSize = entry?.borderBoxSize;
|
|
4972
|
+
const borderBoxSize = Array.isArray(rawBorderBoxSize) ? rawBorderBoxSize[0] : rawBorderBoxSize;
|
|
4973
|
+
if (borderBoxSize?.blockSize != null) {
|
|
4974
|
+
return Math.round(borderBoxSize.blockSize);
|
|
4975
|
+
}
|
|
4976
|
+
if (entry?.contentRect?.height != null) {
|
|
4977
|
+
return Math.round(entry.contentRect.height);
|
|
4978
|
+
}
|
|
4979
|
+
return Math.round(element?.offsetHeight || 0);
|
|
4980
|
+
}
|
|
4981
|
+
function hasMeaningfulHeightChange(previousHeight, nextHeight) {
|
|
4982
|
+
return Math.abs(Math.round(nextHeight) - Math.round(previousHeight)) > HEIGHT_EPSILON;
|
|
4983
|
+
}
|
|
4984
|
+
function useElementHeight(onHeightChange, elementRef, shouldMeasure, dependencyKey = null) {
|
|
4985
|
+
const lastHeightRef = useRef(0);
|
|
4986
|
+
const rafRef = useRef(null);
|
|
4987
|
+
const callbackRef = useRef(onHeightChange);
|
|
4988
|
+
useIsomorphicLayoutEffect(() => {
|
|
4989
|
+
callbackRef.current = onHeightChange;
|
|
4990
|
+
}, [onHeightChange]);
|
|
4991
|
+
useIsomorphicLayoutEffect(() => {
|
|
4992
|
+
if (rafRef.current !== null) {
|
|
4993
|
+
cancelAnimationFrame(rafRef.current);
|
|
4994
|
+
rafRef.current = null;
|
|
4995
|
+
}
|
|
4996
|
+
lastHeightRef.current = -1;
|
|
4997
|
+
if (!callbackRef.current) return;
|
|
4998
|
+
if (!shouldMeasure) {
|
|
4999
|
+
if (hasMeaningfulHeightChange(lastHeightRef.current, 0)) {
|
|
5000
|
+
lastHeightRef.current = 0;
|
|
5001
|
+
callbackRef.current(0);
|
|
5002
|
+
}
|
|
5003
|
+
return;
|
|
5004
|
+
}
|
|
5005
|
+
const element = elementRef?.current;
|
|
5006
|
+
if (!element) return;
|
|
5007
|
+
function publishHeight(nextHeight) {
|
|
5008
|
+
if (!hasMeaningfulHeightChange(lastHeightRef.current, nextHeight)) return;
|
|
5009
|
+
lastHeightRef.current = nextHeight;
|
|
5010
|
+
callbackRef.current?.(nextHeight);
|
|
5011
|
+
}
|
|
5012
|
+
let pendingHeight = null;
|
|
5013
|
+
function flushPendingHeight() {
|
|
5014
|
+
rafRef.current = null;
|
|
5015
|
+
if (pendingHeight == null) return;
|
|
5016
|
+
const heightToPublish = pendingHeight;
|
|
5017
|
+
pendingHeight = null;
|
|
5018
|
+
publishHeight(heightToPublish);
|
|
5019
|
+
}
|
|
5020
|
+
function scheduleMeasurement(nextHeight) {
|
|
5021
|
+
pendingHeight = nextHeight;
|
|
5022
|
+
if (rafRef.current !== null) return;
|
|
5023
|
+
rafRef.current = requestAnimationFrame(flushPendingHeight);
|
|
5024
|
+
}
|
|
5025
|
+
publishHeight(element.offsetHeight || 0);
|
|
5026
|
+
const observer = new ResizeObserver((entries) => {
|
|
5027
|
+
for (const entry of entries) {
|
|
5028
|
+
scheduleMeasurement(getObservedHeight(entry, element));
|
|
5029
|
+
}
|
|
4960
5030
|
});
|
|
4961
|
-
|
|
4962
|
-
|
|
5031
|
+
observer.observe(element);
|
|
5032
|
+
const handlePageShow = () => scheduleMeasurement(element.offsetHeight || 0);
|
|
5033
|
+
const handleVisibilityChange = () => {
|
|
5034
|
+
if (document.visibilityState === "visible") handlePageShow();
|
|
5035
|
+
};
|
|
5036
|
+
window.addEventListener("pageshow", handlePageShow);
|
|
5037
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
4963
5038
|
return () => {
|
|
4964
|
-
|
|
5039
|
+
observer.disconnect();
|
|
5040
|
+
window.removeEventListener("pageshow", handlePageShow);
|
|
5041
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
5042
|
+
if (rafRef.current !== null) {
|
|
5043
|
+
cancelAnimationFrame(rafRef.current);
|
|
5044
|
+
rafRef.current = null;
|
|
5045
|
+
}
|
|
4965
5046
|
};
|
|
4966
|
-
}, [
|
|
5047
|
+
}, [dependencyKey, elementRef, shouldMeasure]);
|
|
4967
5048
|
}
|
|
4968
|
-
function
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
const isBodyVisible = phase === DOCK_SURFACE_PHASE.EXPANDING_BODY || phase === DOCK_SURFACE_PHASE.OPEN;
|
|
4974
|
-
const subscribe2 = useCallback(
|
|
4975
|
-
(onStoreChange) => store ? store.subscribe(onStoreChange) : () => {
|
|
4976
|
-
},
|
|
4977
|
-
[store]
|
|
4978
|
-
);
|
|
4979
|
-
const getSnapshot2 = useCallback(
|
|
4980
|
-
() => store ? store.getExtensionsForSurface(surfaceId).length : 0,
|
|
4981
|
-
[store, surfaceId]
|
|
4982
|
-
);
|
|
4983
|
-
const dynamicCount = useSyncExternalStore(subscribe2, getSnapshot2, () => 0);
|
|
4984
|
-
const descriptorCount = useMemo(() => {
|
|
4985
|
-
const raw = activeItem?.surfaceExtensions || activeItem?.extensions || [];
|
|
4986
|
-
return Array.isArray(raw) ? raw.length : 0;
|
|
4987
|
-
}, [activeItem?.surfaceExtensions, activeItem?.extensions]);
|
|
4988
|
-
return Boolean(
|
|
4989
|
-
isSurface && isBodyVisible && (dynamicCount > 0 || descriptorCount > 0)
|
|
5049
|
+
function publishDockHeightCssVar(heightPx) {
|
|
5050
|
+
if (typeof document === "undefined") return;
|
|
5051
|
+
document.documentElement.style.setProperty(
|
|
5052
|
+
"--dock-h",
|
|
5053
|
+
`${Math.round(heightPx)}px`
|
|
4990
5054
|
);
|
|
4991
5055
|
}
|
|
4992
|
-
function
|
|
4993
|
-
|
|
5056
|
+
function useDockHeightController({
|
|
5057
|
+
contentKey = null,
|
|
5058
|
+
isHud = false,
|
|
5059
|
+
setDockHeight,
|
|
5060
|
+
surfacePhase = DOCK_SURFACE_PHASE.IDLE
|
|
4994
5061
|
}) {
|
|
4995
|
-
const
|
|
4996
|
-
|
|
4997
|
-
const subscribe2 = useCallback(
|
|
4998
|
-
(onStoreChange) => store ? store.subscribe(onStoreChange) : () => {
|
|
4999
|
-
},
|
|
5000
|
-
[store]
|
|
5001
|
-
);
|
|
5002
|
-
const getSnapshot2 = useCallback(
|
|
5003
|
-
() => store ? store.getExtensionsForSurface(surfaceId) : [],
|
|
5004
|
-
[store, surfaceId]
|
|
5062
|
+
const [containerHeight, setContainerHeight] = useState(
|
|
5063
|
+
isHud ? DOCK_CARD_LAYOUT.hudHeight : DOCK_CARD_LAYOUT.baseHeight
|
|
5005
5064
|
);
|
|
5006
|
-
const
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5065
|
+
const heightRef = useRef({ content: 0 });
|
|
5066
|
+
const rafRef = useRef(null);
|
|
5067
|
+
const isHudRef = useRef(isHud);
|
|
5068
|
+
const surfacePhaseRef = useRef(surfacePhase);
|
|
5069
|
+
const lastAppliedContainerHeightRef = useRef(
|
|
5070
|
+
isHud ? DOCK_CARD_LAYOUT.hudHeight : DOCK_CARD_LAYOUT.baseHeight
|
|
5010
5071
|
);
|
|
5011
|
-
const
|
|
5012
|
-
|
|
5013
|
-
return Array.isArray(raw) ? raw.map(normalizeSurfaceExtension).filter((ext) => ext !== null) : [];
|
|
5014
|
-
}, [activeItem?.surfaceExtensions, activeItem?.extensions]);
|
|
5015
|
-
const allExtensions = useMemo(() => {
|
|
5016
|
-
const map = /* @__PURE__ */ new Map();
|
|
5017
|
-
descriptorExtensions.forEach((ext) => map.set(ext.id, ext));
|
|
5018
|
-
dynamicExtensions.forEach((ext) => map.set(ext.id, ext));
|
|
5019
|
-
return Array.from(map.values()).sort((a, b) => a.order - b.order);
|
|
5020
|
-
}, [descriptorExtensions, dynamicExtensions]);
|
|
5021
|
-
return { allExtensions };
|
|
5022
|
-
}
|
|
5023
|
-
var DRAG_RANGE = [...DOCK_SURFACE_DRAG_INTERPOLATION.DRAG_RANGE];
|
|
5024
|
-
var OPACITY_RANGE = [...DOCK_SURFACE_DRAG_INTERPOLATION.OPACITY_RANGE];
|
|
5025
|
-
var SCALE_RANGE = [...DOCK_SURFACE_DRAG_INTERPOLATION.SCALE_RANGE];
|
|
5026
|
-
function useDockSurfaceShellModel({
|
|
5027
|
-
ref,
|
|
5028
|
-
title = "",
|
|
5029
|
-
onClose = null,
|
|
5030
|
-
onBack = null,
|
|
5031
|
-
allowSwipeDismiss = true,
|
|
5032
|
-
closeLabel = "Close surface",
|
|
5033
|
-
backLabel = "Previous step",
|
|
5034
|
-
showControls = false,
|
|
5035
|
-
className = "",
|
|
5036
|
-
contentClassName = "",
|
|
5037
|
-
children,
|
|
5038
|
-
onAnimationComplete = null,
|
|
5039
|
-
isActive = true,
|
|
5040
|
-
surfaceId = null,
|
|
5041
|
-
surfacePhase = DOCK_SURFACE_PHASE.OPEN,
|
|
5042
|
-
surfaceWidth = null
|
|
5043
|
-
}) {
|
|
5044
|
-
const surfaceElementRef = useRef(null);
|
|
5045
|
-
const setSurfaceElementRef = useCallback(
|
|
5046
|
-
(node) => {
|
|
5047
|
-
surfaceElementRef.current = node;
|
|
5048
|
-
if (typeof ref === "function") ref(node);
|
|
5049
|
-
else if (ref) ref.current = node;
|
|
5050
|
-
},
|
|
5051
|
-
[ref]
|
|
5072
|
+
const lastAppliedSpacerHeightRef = useRef(
|
|
5073
|
+
(isHud ? DOCK_CARD_LAYOUT.hudHeight : DOCK_CARD_LAYOUT.baseHeight) + DOCK_HEIGHT_BUFFER
|
|
5052
5074
|
);
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
const
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
onDismiss: typeof onClose === "function" ? onClose : null
|
|
5062
|
-
});
|
|
5063
|
-
const handleDragEnd = (_event, info) => {
|
|
5064
|
-
if (!isActive || !allowSwipeDismiss || typeof onClose !== "function" || !isFullyOpen)
|
|
5065
|
-
return;
|
|
5066
|
-
if (info.offset.y > DOCK_SURFACE_DRAG_THRESHOLDS.DISMISS_OFFSET_Y || info.velocity.y > DOCK_SURFACE_DRAG_THRESHOLDS.DISMISS_VELOCITY_Y) {
|
|
5067
|
-
onClose();
|
|
5075
|
+
useIsomorphicLayoutEffect(() => {
|
|
5076
|
+
isHudRef.current = isHud;
|
|
5077
|
+
surfacePhaseRef.current = surfacePhase;
|
|
5078
|
+
}, [isHud, surfacePhase]);
|
|
5079
|
+
const applyHeight = useCallback(() => {
|
|
5080
|
+
if (rafRef.current !== null) {
|
|
5081
|
+
cancelAnimationFrame(rafRef.current);
|
|
5082
|
+
rafRef.current = null;
|
|
5068
5083
|
}
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
)
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
+
const { content } = heightRef.current;
|
|
5085
|
+
const currentPhase = surfacePhaseRef.current;
|
|
5086
|
+
const isLockedToBaseHeight = currentPhase === DOCK_SURFACE_PHASE.DISMISSING_ACTION || currentPhase === DOCK_SURFACE_PHASE.COLLAPSING_BODY || currentPhase === DOCK_SURFACE_PHASE.RESTORING_HEADER;
|
|
5087
|
+
const computedContentHeight = isLockedToBaseHeight ? 0 : content;
|
|
5088
|
+
const height = getContainerHeight({
|
|
5089
|
+
cardContentHeight: computedContentHeight,
|
|
5090
|
+
isHud: isHudRef.current
|
|
5091
|
+
});
|
|
5092
|
+
const totalSpacerHeight = height + DOCK_HEIGHT_BUFFER;
|
|
5093
|
+
if (Math.abs(height - lastAppliedContainerHeightRef.current) > 0.5) {
|
|
5094
|
+
lastAppliedContainerHeightRef.current = height;
|
|
5095
|
+
setContainerHeight(height);
|
|
5096
|
+
}
|
|
5097
|
+
if (Math.abs(totalSpacerHeight - lastAppliedSpacerHeightRef.current) > 0.5) {
|
|
5098
|
+
lastAppliedSpacerHeightRef.current = totalSpacerHeight;
|
|
5099
|
+
publishDockHeightCssVar(totalSpacerHeight);
|
|
5100
|
+
setDockHeight(totalSpacerHeight);
|
|
5101
|
+
}
|
|
5102
|
+
}, [setDockHeight]);
|
|
5103
|
+
const handleContentHeightChange = useCallback(
|
|
5104
|
+
(height) => {
|
|
5105
|
+
const numericHeight = Number(height);
|
|
5106
|
+
heightRef.current.content = Number.isFinite(numericHeight) ? Math.max(0, numericHeight) : 0;
|
|
5107
|
+
applyHeight();
|
|
5084
5108
|
},
|
|
5085
|
-
[
|
|
5086
|
-
);
|
|
5087
|
-
const isBodyVisible = surfacePhase === DOCK_SURFACE_PHASE.EXPANDING_BODY || surfacePhase === DOCK_SURFACE_PHASE.OPEN;
|
|
5088
|
-
const resolvedSurfaceId = surfaceId || "active";
|
|
5089
|
-
const bodyVariants = useMemo(
|
|
5090
|
-
() => ({
|
|
5091
|
-
hidden: dockSurfaceBodyRole.hidden,
|
|
5092
|
-
visible: {
|
|
5093
|
-
...dockSurfaceBodyRole.visible,
|
|
5094
|
-
transition: surfacePhase === DOCK_SURFACE_PHASE.EXPANDING_BODY ? DOCK_SURFACE_BODY_ENTER_TRANSITION : DOCK_SURFACE_BODY_STEP_TRANSITION
|
|
5095
|
-
},
|
|
5096
|
-
exit: {
|
|
5097
|
-
...dockSurfaceBodyRole.exit,
|
|
5098
|
-
transition: DOCK_SURFACE_BODY_EXIT_TRANSITION
|
|
5099
|
-
}
|
|
5100
|
-
}),
|
|
5101
|
-
[surfacePhase]
|
|
5102
|
-
);
|
|
5103
|
-
const surfaceItemValue = useMemo(
|
|
5104
|
-
() => ({ id: resolvedSurfaceId, width: surfaceWidth }),
|
|
5105
|
-
[resolvedSurfaceId, surfaceWidth]
|
|
5109
|
+
[applyHeight]
|
|
5106
5110
|
);
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5111
|
+
useEffect(() => {
|
|
5112
|
+
return () => {
|
|
5113
|
+
if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
|
|
5114
|
+
};
|
|
5115
|
+
}, []);
|
|
5116
|
+
useIsomorphicLayoutEffect(() => applyHeight(), [applyHeight, contentKey]);
|
|
5117
|
+
useIsomorphicLayoutEffect(() => applyHeight(), [applyHeight, surfacePhase]);
|
|
5118
|
+
useIsomorphicLayoutEffect(() => applyHeight(), [applyHeight, isHud]);
|
|
5119
|
+
return { containerHeight, handleContentHeightChange };
|
|
5120
|
+
}
|
|
5121
|
+
function isSurfaceShapePhase(phase) {
|
|
5122
|
+
return phase === DOCK_SURFACE_PHASE.EXPANDING_BODY || phase === DOCK_SURFACE_PHASE.OPEN || phase === DOCK_SURFACE_PHASE.CLOSING_ANTICIPATION;
|
|
5123
|
+
}
|
|
5124
|
+
function getTargetItemWidth(activeItem) {
|
|
5125
|
+
if (!activeItem?.isSurface || isSurfaceShapePhase(activeItem.surfacePhase)) {
|
|
5126
|
+
return activeItem?.width;
|
|
5127
|
+
}
|
|
5128
|
+
return activeItem.restingWidth;
|
|
5129
|
+
}
|
|
5130
|
+
function useDockViewport(activeItem = null) {
|
|
5131
|
+
const targetWidth = getTargetItemWidth(activeItem);
|
|
5132
|
+
const [, setViewportRevision] = useState(0);
|
|
5133
|
+
const [portalTarget, setPortalTarget] = useState(null);
|
|
5134
|
+
const stackWidth = getDockCardWidth({ width: targetWidth });
|
|
5135
|
+
useIsomorphicLayoutEffect(() => {
|
|
5136
|
+
if (typeof document !== "undefined") setPortalTarget(document.body);
|
|
5137
|
+
}, []);
|
|
5138
|
+
useEffect(() => {
|
|
5139
|
+
if (typeof window === "undefined") return void 0;
|
|
5140
|
+
let resizeFrameId = null;
|
|
5141
|
+
const handleResize = () => {
|
|
5142
|
+
if (resizeFrameId !== null) return;
|
|
5143
|
+
resizeFrameId = window.requestAnimationFrame(() => {
|
|
5144
|
+
resizeFrameId = null;
|
|
5145
|
+
setViewportRevision((revision) => revision + 1);
|
|
5146
|
+
});
|
|
5147
|
+
};
|
|
5148
|
+
window.addEventListener("resize", handleResize, { passive: true });
|
|
5149
|
+
return () => {
|
|
5150
|
+
window.removeEventListener("resize", handleResize);
|
|
5151
|
+
if (resizeFrameId !== null) window.cancelAnimationFrame(resizeFrameId);
|
|
5152
|
+
};
|
|
5153
|
+
}, []);
|
|
5154
|
+
return { portalTarget, stackWidth };
|
|
5155
|
+
}
|
|
5156
|
+
function getItemMeasurementKey({
|
|
5157
|
+
link,
|
|
5158
|
+
expanded,
|
|
5159
|
+
isHud = false
|
|
5160
|
+
}) {
|
|
5161
|
+
const state = isHud ? "hud" : link.isLoading ? "loading" : link.isSurface ? `surface-${link.surfacePhase ?? "open"}` : "standard";
|
|
5162
|
+
return `${link.path || link.name || "item"}:${state}:${expanded ? "expanded" : "collapsed"}`;
|
|
5163
|
+
}
|
|
5164
|
+
function getRouteMeasurementKey(pathname, key) {
|
|
5165
|
+
return `${pathname || ""}:${key}`;
|
|
5121
5166
|
}
|
|
5122
5167
|
function createDockGuardRegistry() {
|
|
5123
5168
|
const guards = /* @__PURE__ */ new Map();
|
|
@@ -8687,7 +8732,7 @@ function useDockOperationState() {
|
|
|
8687
8732
|
);
|
|
8688
8733
|
const operationIdRef = useRef(0);
|
|
8689
8734
|
const operationStateRef = useRef(operationState);
|
|
8690
|
-
|
|
8735
|
+
useIsomorphicLayoutEffect(() => {
|
|
8691
8736
|
operationStateRef.current = operationState;
|
|
8692
8737
|
}, [operationState]);
|
|
8693
8738
|
const start = useCallback((input = {}) => {
|
|
@@ -8752,13 +8797,10 @@ function useDockOperationState() {
|
|
|
8752
8797
|
[operationState.entries]
|
|
8753
8798
|
);
|
|
8754
8799
|
const operationHud = useMemo(
|
|
8755
|
-
() => (
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8759
|
-
pendingCount
|
|
8760
|
-
})
|
|
8761
|
-
),
|
|
8800
|
+
() => createDockOperationHud(activeOperation, {
|
|
8801
|
+
onCancel: cancel,
|
|
8802
|
+
pendingCount
|
|
8803
|
+
}),
|
|
8762
8804
|
[activeOperation, cancel, pendingCount]
|
|
8763
8805
|
);
|
|
8764
8806
|
return { activeOperation, operationActions, operationHud, operationState };
|
|
@@ -11149,7 +11191,7 @@ function useSurfaceStack({
|
|
|
11149
11191
|
const surfacePhaseRef = useRef(DOCK_SURFACE_PHASE.IDLE);
|
|
11150
11192
|
const transitionRunnerRef = useRef(null);
|
|
11151
11193
|
const onSurfaceFlowSettledRef = useRef(onSurfaceFlowSettled);
|
|
11152
|
-
|
|
11194
|
+
useIsomorphicLayoutEffect(() => {
|
|
11153
11195
|
onSurfaceFlowSettledRef.current = onSurfaceFlowSettled;
|
|
11154
11196
|
}, [onSurfaceFlowSettled]);
|
|
11155
11197
|
const clearChoreographyTimers = useCallback(() => {
|
|
@@ -12045,7 +12087,7 @@ function useDockPage(slice, page) {
|
|
|
12045
12087
|
useDockGuard(slice?.guard ?? NO_GUARD);
|
|
12046
12088
|
useDockContextActions(slice?.actions ?? NO_ACTIONS);
|
|
12047
12089
|
const surfacesRef = useRef(slice?.surfaces);
|
|
12048
|
-
|
|
12090
|
+
useIsomorphicLayoutEffect(() => {
|
|
12049
12091
|
surfacesRef.current = slice?.surfaces;
|
|
12050
12092
|
}, [slice?.surfaces]);
|
|
12051
12093
|
return useMemo(
|
|
@@ -12086,6 +12128,6 @@ var dockModule = defineModule({
|
|
|
12086
12128
|
}
|
|
12087
12129
|
});
|
|
12088
12130
|
|
|
12089
|
-
export { DOCK_EVENTS, DOCK_FADE_TRANSITION, DOCK_HUD_PRIORITY, DOCK_HUD_RENDER_MODE, DOCK_HUD_VARIANT, Dock, DockCardBanner, DockCardHeader, DockDescription, DockIcon, DockProvider, DockSurfaceAction, DockSurfaceExtension, DockSurfaceHeaderButton, DockTitle, ErrorActions, GuardActions, createDockGuardRegistry, createErrorStatus, createGuardStatus, createInlineSurfaceEntry, createSurfaceEntryDefinition, createSurfaceFlowBuilder, defineBreadcrumb, defineDockAction, defineHud, defineStepSurface, defineSurface, dockFadeVariants, dockListItemVariants, dockModule, dockTheme, isValidBannerUrl, textCrossfadeVariants, useDock, useDockActionClass, useDockActions, useDockBanner, useDockConfig, useDockContextActions, useDockDimensions, useDockGuard, useDockHeight, useDockHud, useDockRegistration, useDockSelector, useDockState, useHud, useOptionalDockActions, useOptionalDockState, useSurface, useSurfaceAction, useSurfaceDimensions, useSurfaceFlow, useSurfaceHeader, useSurfaceId, useSurfaceReturn, useSurfaceStep };
|
|
12131
|
+
export { DOCK_EVENTS, DOCK_FADE_TRANSITION, DOCK_HUD_PRIORITY, DOCK_HUD_RENDER_MODE, DOCK_HUD_VARIANT, Dock, DockCardBanner, DockCardHeader, DockDescription, DockIcon, DockProvider, DockSurfaceAction, DockSurfaceExtension, DockSurfaceHeaderButton, DockTitle, ErrorActions, GuardActions, createDockGuardRegistry, createErrorStatus, createGuardStatus, createInlineSurfaceEntry, createSurfaceEntryDefinition, createSurfaceFlowBuilder, defineBreadcrumb, defineDockAction, defineHud, defineStepSurface, defineSurface, dockFadeVariants, dockListItemVariants, dockModule, dockTheme, isValidBannerUrl, textCrossfadeVariants, useDock, useDockActionClass, useDockActions, useDockBanner, useDockConfig, useDockContextActions, useDockDimensions, useDockGuard, useDockHeight, useDockHud, useDockRegistration, useDockSelector, useDockState, useDockTheme, useHud, useOptionalDockActions, useOptionalDockState, useSurface, useSurfaceAction, useSurfaceDimensions, useSurfaceFlow, useSurfaceHeader, useSurfaceId, useSurfaceReturn, useSurfaceStep };
|
|
12090
12132
|
//# sourceMappingURL=index.js.map
|
|
12091
12133
|
//# sourceMappingURL=index.js.map
|