@openfin/workspace-platform 45.2.1 → 45.2.3

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.
@@ -0,0 +1,2 @@
1
+ import { LanguageStorageController } from '../../../../client-api-platform/src/api/controllers/language-storage-controller';
2
+ export declare const getLanguageStorageController: () => LanguageStorageController;
@@ -0,0 +1,25 @@
1
+ import { WorkspaceStorageProxyStore } from '../../../../client-api-platform/src/api/controllers/workspace-storage-proxy-store';
2
+ import { Locale } from '../../../../client-api-platform/src/shapes';
3
+ /**
4
+ * Stores the configured and user-selected languages on the platform origin and
5
+ * mirrors the effective preference into the Workspace UI origin.
6
+ *
7
+ * Twin of `ThemeStorageController`: `SelectedLanguage` is the user's explicit choice
8
+ * (Language menu), `DefaultLanguage` is the platform's init-time configuration, and
9
+ * resolution is `Selected ?? Default ?? en-US`.
10
+ */
11
+ export declare class LanguageStorageController {
12
+ private providerStorage;
13
+ private workspaceStorageProxyStore;
14
+ constructor(providerStorage: Pick<Storage, 'getItem' | 'setItem'>, workspaceStorageProxyStore?: WorkspaceStorageProxyStore);
15
+ setSelectedLanguage(locale: Locale): void;
16
+ setDefaultLanguage(locale: Locale): void;
17
+ getSelectedLanguage(): Locale | undefined;
18
+ getDefaultLanguage(): Locale;
19
+ getLanguage(): Locale;
20
+ /**
21
+ * Mirrors the language preference into Workspace UI storage so every UI document on
22
+ * that origin can read it before first paint and react to `storage` events.
23
+ */
24
+ synchronizeWorkspaceStorage: () => Promise<void>;
25
+ }
@@ -1,3 +1,4 @@
1
+ import { WorkspaceStorageProxyStore } from '../../../../client-api-platform/src/api/controllers/workspace-storage-proxy-store';
1
2
  import { StorageProxy } from '../../../../client-api-platform/src/api/utils';
2
3
  import { ColorSchemeOptionType, CustomPaletteSet } from '../../../../client-api-platform/src/shapes';
3
4
  /**
@@ -36,15 +37,13 @@ export declare const generateLegacyCSSVars: (palettes: LegacyPalettes, isWindows
36
37
  dark: string;
37
38
  };
38
39
  export declare class ThemeStorageController {
39
- #private;
40
40
  private providerStorage;
41
+ private workspaceStorageProxyStore;
41
42
  private darkPaletteVars?;
42
43
  private lightPaletteVars?;
43
44
  private themePaletteSheet?;
44
- private workspaceStorage?;
45
- private storageFactory?;
46
45
  private isLegacySinglePaletteTheme;
47
- constructor(providerStorage: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>);
46
+ constructor(providerStorage: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>, workspaceStorageProxyStore?: WorkspaceStorageProxyStore);
48
47
  /**
49
48
  * Sets the storage factory. This can only be done once, and will throw for subsequent calls.
50
49
  *
@@ -0,0 +1,13 @@
1
+ import { StorageProxy } from '../../../../client-api-platform/src/api/utils';
2
+ /**
3
+ * Owns the storage proxy shared by platform features that need to synchronize
4
+ * state into the Workspace UI origin.
5
+ */
6
+ export declare class WorkspaceStorageProxyStore {
7
+ private storageProxy?;
8
+ private storageFactory?;
9
+ setStorageFactory: (factory: () => StorageProxy) => void;
10
+ getOrCreateStorageProxy: () => Promise<StorageProxy>;
11
+ destroyStorageProxy: () => Promise<void>;
12
+ }
13
+ export declare const workspaceStorageProxyStore: WorkspaceStorageProxyStore;
@@ -1,3 +1,86 @@
1
+ export declare const viewTabColors: {
2
+ backgroundColor: {
3
+ default: string;
4
+ hover: string;
5
+ active: string;
6
+ focus: string;
7
+ };
8
+ fontColor: {
9
+ default: string;
10
+ active: string;
11
+ };
12
+ };
13
+ /** `viewTab` stays on `workspacePlatform`; only its siblings move into `_internalWorkspaceData`. */
14
+ export declare const mockSnapshotWithViewTab: {
15
+ windows: {
16
+ layout: {
17
+ content: {
18
+ type: string;
19
+ content: {
20
+ type: string;
21
+ componentName: string;
22
+ componentState: {
23
+ _internalWorkspaceData: {
24
+ viewIdentifier: string;
25
+ };
26
+ workspacePlatform: {
27
+ browserNavigationButtons: {
28
+ reload: boolean;
29
+ };
30
+ viewTab: {
31
+ backgroundColor: {
32
+ default: string;
33
+ hover: string;
34
+ active: string;
35
+ focus: string;
36
+ };
37
+ fontColor: {
38
+ default: string;
39
+ active: string;
40
+ };
41
+ };
42
+ };
43
+ };
44
+ }[];
45
+ }[];
46
+ };
47
+ }[];
48
+ };
49
+ export declare const mockSnapshotWithViewTabMapped: {
50
+ windows: {
51
+ layout: {
52
+ content: {
53
+ type: string;
54
+ content: {
55
+ type: string;
56
+ componentName: string;
57
+ componentState: {
58
+ _internalWorkspaceData: {
59
+ viewIdentifier: string;
60
+ browserNavigationButtons: {
61
+ reload: boolean;
62
+ };
63
+ };
64
+ workspacePlatform: {
65
+ viewTab: {
66
+ backgroundColor: {
67
+ default: string;
68
+ hover: string;
69
+ active: string;
70
+ focus: string;
71
+ };
72
+ fontColor: {
73
+ default: string;
74
+ active: string;
75
+ };
76
+ };
77
+ };
78
+ };
79
+ }[];
80
+ }[];
81
+ };
82
+ }[];
83
+ };
1
84
  export declare const mockSnapshotWithInternalData1: {
2
85
  windows: {
3
86
  layout: {
@@ -1,10 +1,21 @@
1
1
  import type OpenFin from '@openfin/core';
2
2
  import { BrowserCreateViewRequest, BrowserViewState, BrowserWorkspacePlatformViewOptions } from '../../../../client-api-platform/src/shapes';
3
+ /**
4
+ * Strips unusable `viewTab` colors instead of rejecting the request. A tab color is decoration, and this runs
5
+ * inside `createView`, so throwing here would abort view creation and leave the surrounding window
6
+ * half-built over a cosmetic typo. Discarded states fall back to their theme default in the stylesheet.
7
+ */
8
+ export declare const sanitizeViewWorkspacePlatform: (opts: BrowserCreateViewRequest) => BrowserCreateViewRequest;
3
9
  export declare function preserveInteropIfManifestConflict(opts: Partial<OpenFin.ViewOptions>, fetchManifest: ({ manifestUrl }: {
4
10
  manifestUrl: string;
5
11
  }, callerIdentity: OpenFin.Identity) => any, callerIdentity: OpenFin.Identity): Promise<any>;
6
12
  type ViewStateBase = Pick<BrowserViewState, '_internalWorkspaceData' | 'workspacePlatform'>;
7
13
  export declare const mapInternalWorkspaceDataToWorkspacePlatform: <T extends ViewStateBase>(viewState: T) => T;
14
+ /**
15
+ * Moves legacy workspace platform view options into `_internalWorkspaceData`, which Core round-trips through layout
16
+ * componentState. `viewTab` and newer options are exempt — Core now persists `workspacePlatform` on view options directly,
17
+ * so they stay put and the runtime becomes the single source of truth.
18
+ */
8
19
  export declare const mapWorkspacePlatformToInternalWorkspaceData: <T extends ViewStateBase>(viewState: T) => T;
9
20
  export declare const setHotkeysIfNavigationButtonsEnabled: (options: BrowserCreateViewRequest) => Promise<BrowserCreateViewRequest>;
10
21
  export declare const registerHotkeyListenersIfEnabled: (viewIdentity: OpenFin.Identity, buttonOptions?: BrowserWorkspacePlatformViewOptions["browserNavigationButtons"]) => void;
@@ -5,6 +5,7 @@ import type { AnalyticsEvent } from '../../common/src/utils/usage-register';
5
5
  import type { CustomActionSpecifier, CustomButtonConfig } from '../../common/src/api/action';
6
6
  import type { AddDefaultPagePayload, AttachedPage, BookmarkNode, CopyPagePayload, HandlePagesAndWindowClosePayload, HandlePagesAndWindowCloseResult, HandleSaveModalOnPageClosePayload, Page, PageLayoutsWithSelectedViews, PageWithUpdatableRuntimeAttribs, SaveModalOnPageCloseResult, SetActivePageForWindowPayload, ShouldPageClosePayload, ShouldPageCloseResult, ViewsPreventingUnloadPayload } from '../../common/src/api/pages/shapes';
7
7
  import type { NotificationsCustomManifestOptions } from '../../common/src/api/shapes/notifications';
8
+ import type { ViewTabAppearanceOptions } from '../../common/src/api/shapes/view-tab';
8
9
  import type { CustomThemes, GeneratedPalettes } from '../../common/src/api/theming';
9
10
  import type { App, DockProviderConfigWithIdentity, StoreButtonConfig } from '../../client-api/src/shapes';
10
11
  import type { WorkflowIntegration } from '../../client-api/src/shapes/integrations';
@@ -15,6 +16,7 @@ export type { App, AppIntent, Image } from '../../client-api/src/shapes';
15
16
  export type { CustomActionSpecifier, CustomButtonConfig } from '../../common/src/api/action';
16
17
  export type { AttachedPage, Page, PagePinnedState, PageLayout, PageLayoutDetails, PageWithUpdatableRuntimeAttribs, PanelConfigHorizontal, PanelConfigVertical, PanelConfig, ExtendedPanelConfig, CopyPagePayload, HandleSaveModalOnPageClosePayload, SaveModalOnPageCloseResult, SetActivePageForWindowPayload, ShouldPageClosePayload, ShouldPageCloseResult, ViewsPreventingUnloadPayload } from '../../common/src/api/pages/shapes';
17
18
  export { PanelPosition } from '../../common/src/api/pages/shapes';
19
+ export type { ThemedIcon, ViewTabAppearanceOptions, ViewTabColorRole, ViewTabControl, ViewTabControlPosition, ViewTabStateColorOptions } from '../../common/src/api/shapes/view-tab';
18
20
  export type { CustomThemes, CustomThemeOptions, ThemeOptions, CustomThemeOptionsWithScheme, CustomPaletteSet, BaseThemeOptions, ThemeExtension, WorkspaceThemeSet, NotificationIndicatorColorsSet, NotificationIndicatorColorsSetDarkScheme, NotificationIndicatorColorsSetLightScheme, NotificationIndicatorColorsWithScheme } from '../../common/src/api/theming';
19
21
  export type { AnalyticsEvent } from '../../common/src/utils/usage-register';
20
22
  export type { WorkflowIntegration } from '../../client-api/src/shapes/integrations';
@@ -232,7 +234,7 @@ export type ViewTabContextMenuTemplate = OpenFin.MenuItemTemplate<ViewTabMenuDat
232
234
  /**
233
235
  * UI elements within a view tab that can be navigated to via keyboard.
234
236
  */
235
- export type ViewTabElements = 'inactive-tab' | 'active-tab' | 'inactive-tab-close-button' | 'active-tab-close-button' | 'add-tab-button';
237
+ export type ViewTabElements = 'inactive-tab' | 'active-tab' | 'inactive-tab-close-button' | 'active-tab-close-button' | 'inactive-tab-custom-control' | 'active-tab-custom-control' | 'add-tab-button';
236
238
  /**
237
239
  * Configuration options for view tab keyboard navigation behavior.
238
240
  */
@@ -242,7 +244,7 @@ export interface ViewTabOptions {
242
244
  * arrow keys when an element in the view is selected.
243
245
  * The order of the items in the array have no impact.
244
246
  * Note: these are not mutually exclusive and can overlap.
245
- * Default (when undefined): ["inactive-tab","active-tab","active-tab-close-button","inactive-tab-close-button","add-tab-button"]
247
+ * Default (when undefined): ["inactive-tab","active-tab","active-tab-close-button","inactive-tab-close-button","active-tab-custom-control","inactive-tab-custom-control","add-tab-button"]
246
248
  */
247
249
  arrowNavigation?: ViewTabElements[];
248
250
  /**
@@ -369,6 +371,19 @@ export interface ViewTabCustomActionPayload {
369
371
  windowIdentity: OpenFin.Identity;
370
372
  selectedViews: OpenFin.Identity[];
371
373
  }
374
+ export interface ViewTabControlActionPayload {
375
+ callerType: CustomActionCallerType.ViewTabControl;
376
+ /** Identity of the Browser window containing the view tab. */
377
+ windowIdentity: OpenFin.Identity;
378
+ /** Identity of the view represented by the tab. */
379
+ viewIdentity: OpenFin.Identity;
380
+ /** Any data necessary for the functioning of the specified custom action. */
381
+ customData?: any;
382
+ /** Client x-coordinate where the control was invoked. */
383
+ x: number;
384
+ /** Client y-coordinate where the control was invoked. */
385
+ y: number;
386
+ }
372
387
  /**
373
388
  * Payload received by the openViewTabContextMenu provider override.
374
389
  */
@@ -608,12 +623,16 @@ export declare enum WindowType {
608
623
  Browser = "browser",
609
624
  Platform = "platform"
610
625
  }
626
+ /** How view tab widths are calculated. `'uniform'` is today's equal-width behavior. */
627
+ export type ViewTabWidthMode = 'uniform' | 'content';
611
628
  export interface BrowserWorkspacePlatformViewOptions {
612
629
  browserNavigationButtons?: RequireAtLeastOne<{
613
630
  back?: boolean;
614
631
  forward?: boolean;
615
632
  reload?: boolean;
616
633
  }>;
634
+ /** Per-view tab appearance options. */
635
+ viewTab?: ViewTabAppearanceOptions;
617
636
  }
618
637
  type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
619
638
  [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
@@ -690,16 +709,36 @@ export interface BrowserWorkspacePlatformWindowOptions {
690
709
  minWidth?: string;
691
710
  maxWidth?: string;
692
711
  };
693
- /** Specifies the min and max sizes for view tabs in a layout.
712
+ /**
713
+ * Specifies the min and max sizes for view tabs in a layout, and how those widths are calculated.
694
714
  * View tabs will expand to take all available space up to the specified maximum size.
695
715
  * Similarly, they will collapse down to the specified minimum size.
696
716
  * When there is not enough room to fit the tabs, the tabstrip will become scrollable.
697
717
  * Sizes can be specified as pixels (e.g. "100px") or as percentage of tab strip width (e.g. "20%").
698
- * The default value for both min and max is "120px". To maintain usability, minimum values below 28px will be ignored and 28px will be used as the minimum.
718
+ * Defaults depend on the width mode: `'uniform'` uses "120px" for both bounds, while `'content'` sizes a
719
+ * tab to its own chrome and so applies no minimum and a "200px" maximum.
720
+ * To maintain usability, minimum values below 28px will be ignored and 28px will be used as the minimum.
721
+ *
722
+ * @example
723
+ * ```ts
724
+ * workspacePlatform: {
725
+ * viewTabDimensions: {
726
+ * widthMode: 'content',
727
+ * minWidth: '50px',
728
+ * maxWidth: '200px'
729
+ * }
730
+ * }
731
+ * ```
699
732
  */
700
733
  viewTabDimensions?: {
701
734
  minWidth?: string;
702
735
  maxWidth?: string;
736
+ /**
737
+ * Controls how view tab widths are calculated.
738
+ * - `'uniform'` (default): current equal-width tab behavior.
739
+ * - `'content'`: tab width is driven by tab chrome (label, favicon, spinner, controls) within min/max bounds.
740
+ */
741
+ widthMode?: ViewTabWidthMode;
703
742
  };
704
743
  /**
705
744
  * Controls whether tab-search chevron buttons are shown for page tabs and view tabs.
@@ -1989,6 +2028,7 @@ export declare enum CustomActionCallerType {
1989
2028
  StoreCustomButton = "StoreCustomButton",
1990
2029
  CustomDropdownItem = "CustomDropdownItem",
1991
2030
  GlobalContextMenu = "GlobalContextMenu",
2031
+ ViewTabControl = "ViewTabControl",
1992
2032
  ViewTabContextMenu = "ViewTabContextMenu",
1993
2033
  PageTabContextMenu = "PageTabContextMenu",
1994
2034
  SaveButtonContextMenu = "SaveButtonContextMenu",
@@ -1999,7 +2039,7 @@ export declare enum CustomActionCallerType {
1999
2039
  * When `callerType == CustomActionCallerType.API`, the payload is defined by the code directly invoking the action.*/
2000
2040
  export type CustomActionPayload = {
2001
2041
  callerType: CustomActionCallerType.API;
2002
- } | CustomButtonActionPayload | StoreCustomButtonActionPayload | CustomDropdownItemActionPayload | GlobalContextMenuOptionActionPayload | ViewTabCustomActionPayload | PageTabContextMenuOptionActionPayload | OpenSaveContextMenuOptionActionPayload;
2042
+ } | CustomButtonActionPayload | StoreCustomButtonActionPayload | CustomDropdownItemActionPayload | GlobalContextMenuOptionActionPayload | ViewTabControlActionPayload | ViewTabCustomActionPayload | PageTabContextMenuOptionActionPayload | OpenSaveContextMenuOptionActionPayload;
2003
2043
  export interface GetCurrentWorkspaceOptions {
2004
2044
  skipSnapshotUpdate?: boolean;
2005
2045
  }
@@ -0,0 +1,86 @@
1
+ import type { CustomButtonConfig } from '../../../../common/src/api/action';
2
+ /**
3
+ * A CSS color value per view tab state. Any omitted state keeps its theme default, so a partial
4
+ * object overrides only the states it names.
5
+ *
6
+ * An empty string means inherit — that state is unset and falls back to its theme default. This is the only
7
+ * way to remove a color from a view that already has one: `updateOptions` merges, so omitting a state leaves
8
+ * its current color in place, and an empty `viewTab` object is treated as no change at all.
9
+ */
10
+ export interface ViewTabStateColorOptions {
11
+ /** Color when the tab is inactive. */
12
+ default?: string;
13
+ /** Color when the tab is hovered (and not active). */
14
+ hover?: string;
15
+ /** Color when the tab is active. */
16
+ active?: string;
17
+ /** Color when the tab is active and its view is focused. */
18
+ focus?: string;
19
+ }
20
+ export type ViewTabControlPosition = {
21
+ /** Tab element used as the placement anchor. */
22
+ relativeTo: 'title' | 'favicon';
23
+ /** Side of the anchor on which the control is placed. */
24
+ placement: 'before' | 'after';
25
+ };
26
+ export type ThemedIcon = {
27
+ dark: string;
28
+ light: string;
29
+ };
30
+ export interface ViewTabControl extends Omit<CustomButtonConfig, 'iconUrl' | 'parentHover'> {
31
+ /** Icon URL, or URLs selected according to the current color scheme. */
32
+ iconUrl?: string | ThemedIcon;
33
+ /** Defaults to before the tab title. */
34
+ position?: ViewTabControlPosition;
35
+ }
36
+ export type ViewTabColorRole = 'backgroundColor' | 'fontColor';
37
+ /**
38
+ * Per-view view-tab appearance settings, nested under `workspacePlatform.viewTab` on view options.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * import * as WorkspacePlatform from '@openfin/workspace-platform';
43
+ *
44
+ * const platform = WorkspacePlatform.getCurrentSync();
45
+ * await platform.Browser.createView({
46
+ * url: 'https://example.com',
47
+ * workspacePlatform: {
48
+ * viewTab: {
49
+ * backgroundColor: { default: '#1e3a5f', active: '#356aa3' },
50
+ * fontColor: { default: '#c9d8ea', active: '#ffffff' }
51
+ * }
52
+ * }
53
+ * });
54
+ * ```
55
+ *
56
+ * @example
57
+ * Returning a view to its theme defaults, naming every state that should be unset:
58
+ * ```ts
59
+ * await view.updateOptions({
60
+ * workspacePlatform: {
61
+ * viewTab: {
62
+ * backgroundColor: { default: '', hover: '', active: '', focus: '' },
63
+ * fontColor: { default: '', hover: '', active: '', focus: '' }
64
+ * }
65
+ * }
66
+ * });
67
+ * ```
68
+ */
69
+ export interface ViewTabAppearanceOptions {
70
+ /** Tab background color per state. */
71
+ backgroundColor?: ViewTabStateColorOptions;
72
+ /** Tab title text color per state. Does not affect the close or lock icons. */
73
+ fontColor?: ViewTabStateColorOptions;
74
+ /**
75
+ * Snapshot-safe controls rendered in this view's tab.
76
+ *
77
+ * Rendering requires the GoldenLayout 2 engine with scrolling tab overflow, which is how the
78
+ * Core UI Browser creates its layouts (`experimental.layoutEngine: 'v2'`, the Browser default).
79
+ * Windows that opt back in to the v1 engine render their tabs without custom controls, and this
80
+ * option is ignored rather than rejected.
81
+ *
82
+ * Controls render at a fixed size, so the right-most ones are clipped on tabs that are too
83
+ * narrow to fit them.
84
+ */
85
+ controls?: ViewTabControl[];
86
+ }
@@ -1,5 +1,15 @@
1
1
  export declare const mockLogger: {
2
2
  debug: jest.Mock<any, any, any>;
3
+ info: jest.Mock<any, any, any>;
3
4
  warn: jest.Mock<any, any, any>;
4
5
  error: jest.Mock<any, any, any>;
5
6
  };
7
+ export declare const mockPerformanceLogger: {
8
+ debug: jest.Mock<any, any, any>;
9
+ info: jest.Mock<any, any, any>;
10
+ warn: jest.Mock<any, any, any>;
11
+ error: jest.Mock<any, any, any>;
12
+ startTimer: jest.Mock<any, any, any>;
13
+ endTimer: jest.Mock<any, any, any>;
14
+ clearTimer: jest.Mock<any, any, any>;
15
+ };
@@ -7,6 +7,7 @@ declare enum LocalStorageKey {
7
7
  DockPosition = "DockPosition",
8
8
  SelectedColorScheme = "SelectedColorScheme",
9
9
  SelectedLanguage = "SelectedLanguage",
10
+ DefaultLanguage = "DefaultLanguage",
10
11
  ThemePaletteSheet = "ThemePaletteSheet",
11
12
  HasMovedStore = "HasMovedStore",
12
13
  PageDragState = "BrowserPageDragState",
@@ -0,0 +1,20 @@
1
+ import type OpenFin from '@openfin/core';
2
+ export type ViewOptionsConsumer = 'appearance' | 'controls' | 'shared';
3
+ /**
4
+ * Reads view options for the custom view-tab feature, optionally instrumented in debug builds.
5
+ *
6
+ * Collection is active only when the build-time `LOG_DEBUG` constant is true — set via
7
+ * `OF__WORKSPACE_LOG_DEBUG=true` at build time (including PR preview builds where that env is enabled).
8
+ * Tests may also enable collection with `globalThis.LOG_DEBUG = true` when the build constant is undefined.
9
+ * Production builds call `view.getOptions()` directly with no marks or logs.
10
+ *
11
+ * Baseline comparison before de-duplication should primarily use IPC / measure count: expect two `getOptions`
12
+ * calls and two Performance Timeline entries per view (appearance + controls). The de-duplicated path emits one
13
+ * entry with the `shared` consumer. Per-call baseline durations are secondary because two reads can overlap.
14
+ *
15
+ * Inspect entries in DevTools by filtering measures named `of-workspace-view-tab-get-options-*`. The Performance
16
+ * Timeline duration is authoritative; structured logs are the human-readable companion.
17
+ *
18
+ * Each debug invocation calls `view.getOptions()` exactly once — no caching or de-duplication on this branch.
19
+ */
20
+ export declare const getViewOptions: (view: OpenFin.View, consumer: ViewOptionsConsumer) => Promise<OpenFin.ViewOptions>;
@@ -0,0 +1,51 @@
1
+ import type OpenFin from '@openfin/core';
2
+ import type { ViewTabAppearanceOptions, ViewTabColorRole } from '../../../common/src/api/shapes/view-tab';
3
+ export declare const VIEW_TAB_STATES: readonly ["default", "hover", "active", "focus"];
4
+ export type ViewTabState = (typeof VIEW_TAB_STATES)[number];
5
+ /** A color that was discarded during sanitization, for the caller to log. */
6
+ export interface RejectedViewTabColor {
7
+ role: ViewTabColorRole;
8
+ /** Absent when the whole role was malformed rather than one of its states. */
9
+ state?: ViewTabState;
10
+ value: unknown;
11
+ }
12
+ /**
13
+ * Drops every state whose value is not a supported CSS color, returning what survived alongside what was
14
+ * discarded. Tab color is decoration, so a malformed value degrades that state to its theme default instead
15
+ * of failing the operation that carried it.
16
+ *
17
+ * Only the two color roles are validated. Every other `viewTab` option — `controls`, and whatever follows it
18
+ * — is carried through untouched, so a bad color cannot take an unrelated tab option down with it. Appearance
19
+ * is omitted only when nothing at all is left, which keeps a wholly-invalid object out of persistence.
20
+ */
21
+ export declare const sanitizeViewTabAppearance: (viewTab: unknown) => {
22
+ appearance?: ViewTabAppearanceOptions;
23
+ rejected: RejectedViewTabColor[];
24
+ };
25
+ /** Formats a rejected color for a log line, e.g. `viewTab.fontColor.default "##EDE8D0"`. */
26
+ export declare const describeRejectedViewTabColor: ({ role, state, value }: RejectedViewTabColor) => string;
27
+ type ViewOptionsWithWorkspacePlatform = {
28
+ workspacePlatform?: {
29
+ viewTab?: ViewTabAppearanceOptions;
30
+ };
31
+ };
32
+ /**
33
+ * True when this `view-options-changed` diff touched `workspacePlatform.viewTab`, so that unrelated view
34
+ * option changes do not repaint tabs.
35
+ *
36
+ * `oldVal` is checked as well as `newVal` because clearing `viewTab` drops it from `newVal` entirely —
37
+ * that case only shows up on the old side, and it still needs a repaint.
38
+ */
39
+ export declare const hasViewTabDiff: (diff: unknown) => boolean;
40
+ export declare const getViewTabAppearanceFromViewOptions: (options: ViewOptionsWithWorkspacePlatform) => ViewTabAppearanceOptions | undefined;
41
+ /**
42
+ * Reads view tab appearance from the view. Core persists `workspacePlatform` on view options across create,
43
+ * `updateOptions`, snapshot, and `getOptions`, so `getOptions` is the single source of truth.
44
+ */
45
+ export declare const getViewTabAppearanceFromView: (view: OpenFin.View) => Promise<ViewTabAppearanceOptions | undefined>;
46
+ /**
47
+ * Writes the per-state custom properties for a single tab element. Values are set inline so that sibling tabs
48
+ * in the same tab strip are unaffected.
49
+ */
50
+ export declare const applyViewTabAppearance: (tab: HTMLElement, appearance?: ViewTabAppearanceOptions) => void;
51
+ export {};
@@ -13,14 +13,6 @@
13
13
  "issuer": "common/src/utils/layout.ts"
14
14
  }
15
15
  ],
16
- "lodash.clonedeep": [
17
- {
18
- "type": "explicit",
19
- "version": "4.5.0",
20
- "packageName": "common/package.json",
21
- "issuer": "common/src/utils/layout.ts"
22
- }
23
- ],
24
16
  "react-i18next": [
25
17
  {
26
18
  "type": "explicit",
@@ -45,19 +37,27 @@
45
37
  "issuer": "common/src/api/i18next.ts"
46
38
  }
47
39
  ],
48
- "dexie": [
40
+ "lodash.clonedeep": [
49
41
  {
50
42
  "type": "explicit",
51
- "version": "^4.0.11",
43
+ "version": "4.5.0",
52
44
  "packageName": "common/package.json",
53
- "issuer": "common/src/api/pages/idb.ts"
54
- },
45
+ "issuer": "common/src/utils/layout.ts"
46
+ }
47
+ ],
48
+ "dexie": [
55
49
  {
56
50
  "type": "root-implicit",
57
51
  "version": "^4.0.11",
58
52
  "packageName": "dock3/package.json",
59
53
  "issuer": "dock3/src/api/idb.ts"
60
54
  },
55
+ {
56
+ "type": "explicit",
57
+ "version": "^4.0.11",
58
+ "packageName": "common/package.json",
59
+ "issuer": "common/src/api/pages/idb.ts"
60
+ },
61
61
  {
62
62
  "type": "explicit",
63
63
  "version": "^4.0.11",