dsh-quick-actions 0.1.0 → 0.2.0-rc.2
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/README.en.md +43 -19
- package/README.md +43 -19
- package/lib/client.js +297 -147
- package/lib/client.js.map +1 -1
- package/lib/index.js +192 -140
- package/lib/types/client/controller.d.ts +61 -39
- package/lib/types/client/dsh.d.ts +8 -4
- package/lib/types/client/index.d.ts +4 -4
- package/lib/types/client/surfaces/layout.d.ts +7 -0
- package/lib/types/host/index.d.ts +19 -22
- package/lib/types/host/settings.d.ts +63 -48
- package/lib/types/index.d.ts +16 -14
- package/lib/types/model/catalog.d.ts +3 -18
- package/lib/types/model/index.d.ts +1 -0
- package/lib/types/{host → model}/presets.d.ts +5 -0
- package/lib/types/model/settings.d.ts +11 -7
- package/lib/types/styles/index.d.ts +17 -13
- package/package.json +18 -13
|
@@ -25,6 +25,8 @@ export type SurfaceDensity = 'wide' | 'narrow';
|
|
|
25
25
|
*/
|
|
26
26
|
export declare const NARROW_SURFACE_WIDTH = 480;
|
|
27
27
|
export declare function densityFor(width: number): SurfaceDensity;
|
|
28
|
+
/** How far, in CSS px, a control may overrun the bar row and still count as fitting. */
|
|
29
|
+
export declare const FIT_TOLERANCE = 0.5;
|
|
28
30
|
/** One measured row of the `bar` layout. */
|
|
29
31
|
export interface BarFitInput {
|
|
30
32
|
/** Usable inner width of the action row. */
|
|
@@ -45,5 +47,10 @@ export interface BarFitInput {
|
|
|
45
47
|
* no layout — every width reads as zero. That answers "all of them": showing the
|
|
46
48
|
* full row and letting the browser's own overflow handle it for one frame is
|
|
47
49
|
* better than flashing a "more" button that the next frame withdraws.
|
|
50
|
+
*
|
|
51
|
+
* A control fits when it overruns the row by less than `FIT_TOLERANCE`. Whenever
|
|
52
|
+
* the bar is content-sized (spec 22.9) the row it measures is exactly as wide as
|
|
53
|
+
* the controls it shows, and fractional layout can report that a hair short;
|
|
54
|
+
* folding a face over the difference would narrow the row and start a cascade.
|
|
48
55
|
*/
|
|
49
56
|
export declare function fitActionCount(input: BarFitInput): number;
|
|
@@ -1,38 +1,35 @@
|
|
|
1
1
|
import type { CanonicalRewriteOutcome, SettingsRewriteProvider } from './settings.js';
|
|
2
2
|
import type { PresetCatalog } from '../model/index.js';
|
|
3
3
|
/**
|
|
4
|
-
* The read-only catalog projection
|
|
5
|
-
* the
|
|
6
|
-
*
|
|
4
|
+
* The read-only catalog projection (spec 6.2). It is the catalog itself under
|
|
5
|
+
* the name the spec gives it — one shape, so the Host cannot publish something
|
|
6
|
+
* the model never validated.
|
|
7
7
|
*/
|
|
8
8
|
export type CatalogSnapshot = PresetCatalog;
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
* the fenced write face. Declared structurally so the Host is testable against a
|
|
12
|
-
* controlled fake; the real `SettingsProvider` satisfies it.
|
|
13
|
-
*/
|
|
14
|
-
export interface QuickActionsSettingsProvider extends SettingsRewriteProvider {
|
|
15
|
-
register(ns: string, schema: unknown, options?: unknown): unknown;
|
|
16
|
-
}
|
|
9
|
+
/** The Host settings provider as this plugin uses it; the real `SettingsForms` satisfies it. */
|
|
10
|
+
export type QuickActionsSettingsProvider = SettingsRewriteProvider;
|
|
17
11
|
/** The running Host, owned by the fiber that started it. */
|
|
18
12
|
export interface QuickActionsHost {
|
|
19
|
-
/** Settles when the startup canonical rewrite has been attempted. */
|
|
20
|
-
readonly ready: Promise<CanonicalRewriteOutcome>;
|
|
21
13
|
/**
|
|
22
|
-
* The
|
|
23
|
-
*
|
|
24
|
-
*
|
|
14
|
+
* The authoritative catalog as lossless JSON. Each call hands back a detached
|
|
15
|
+
* copy, so a consumer cannot reach the authoritative catalog through the value
|
|
16
|
+
* it was given.
|
|
25
17
|
*/
|
|
26
18
|
describeCatalog(): Promise<CatalogSnapshot>;
|
|
19
|
+
/**
|
|
20
|
+
* Canonicalize the stored section against this catalog (spec 6.3). Only
|
|
21
|
+
* meaningful once the entry is active: before that the provider does not
|
|
22
|
+
* serve the form, and the answer is `unregistered`.
|
|
23
|
+
*/
|
|
24
|
+
canonicalize(settings: QuickActionsSettingsProvider): Promise<CanonicalRewriteOutcome>;
|
|
27
25
|
}
|
|
28
26
|
/**
|
|
29
|
-
* Load
|
|
27
|
+
* Load and validate the catalog.
|
|
30
28
|
*
|
|
31
|
-
* An invalid preset configuration throws
|
|
32
|
-
*
|
|
33
|
-
*
|
|
29
|
+
* An invalid preset configuration throws: the catalog is author-owned, so a
|
|
30
|
+
* mistake fails plugin loading rather than silently shipping a partial catalog
|
|
31
|
+
* (spec 5.1).
|
|
34
32
|
*
|
|
35
|
-
* @param settings - the Host settings provider.
|
|
36
33
|
* @param config - the Host composition entry's config.
|
|
37
34
|
*/
|
|
38
|
-
export declare function startQuickActionsHost(
|
|
35
|
+
export declare function startQuickActionsHost(config: unknown): QuickActionsHost;
|
|
@@ -1,67 +1,82 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
3
|
-
* (spec 4.2, 6.1, 6.3).
|
|
2
|
+
* The plugin's Config — which since DSH 0.1.7 *is* its Settings form — and the
|
|
3
|
+
* Host's canonical rewrite (spec 4.2, 6.1, 6.3, 22).
|
|
4
4
|
*
|
|
5
|
-
* The Host is the sole validation and migration authority, so the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* The Host is the sole validation and migration authority, so the schema is
|
|
6
|
+
* deliberately permissive: it fixes the shape of the section and its defaults,
|
|
7
|
+
* and nothing else. A strict schema would refuse a section a higher version
|
|
8
|
+
* wrote — which is exactly the data spec 5.3 requires to survive a downgrade
|
|
9
|
+
* untouched. The shared model decodes and normalizes what the schema lets
|
|
10
|
+
* through, and it never rewrites content it cannot render.
|
|
11
11
|
*/
|
|
12
12
|
import Schema from '@deepseek-ai/schemastery';
|
|
13
13
|
import type { PresetCatalog, QuickActionSettingsV1 } from '../model/index.js';
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
layout: Schema<string, string>;
|
|
29
|
-
userActionsById: Schema<any, any>;
|
|
30
|
-
actionOrder: Schema<any, any>;
|
|
31
|
-
presetStateById: Schema<any, any>;
|
|
32
|
-
}>>;
|
|
33
|
-
/**
|
|
34
|
-
* Shape of the catalog namespace. Its authoritative content is the composition
|
|
35
|
-
* `base` layer the Host declares; a user layer is never written and, if one were
|
|
36
|
-
* hand-written into the document, Clients would still read `base` (spec 17.2).
|
|
15
|
+
* The plugin Config (spec 22.2). Every field is `volatile`, because DSH lets a
|
|
16
|
+
* Settings form — and so the Client — reach volatile fields only.
|
|
17
|
+
*
|
|
18
|
+
* - The five user-state fields are top-level on purpose: the DSH legacy import
|
|
19
|
+
* moves an old `settings.yaml` section into the entry of the same id key by
|
|
20
|
+
* key, and refuses the whole section when any top-level key is not a volatile
|
|
21
|
+
* field. This exact shape is what lets that one-shot import land.
|
|
22
|
+
* - `presets` is the author's list merged behind the built-ins (spec 5.1). It
|
|
23
|
+
* is volatile only so the Client can read it — a non-volatile field never
|
|
24
|
+
* reaches the browser — and nothing in this plugin ever writes it.
|
|
25
|
+
*
|
|
26
|
+
* The collections stay unconstrained: a stricter schema would refuse a section
|
|
27
|
+
* this release cannot render, and refusing it is how stored data gets lost.
|
|
37
28
|
*/
|
|
38
|
-
export declare const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
29
|
+
export declare const Config: Schema<Schemastery.ObjectS<NoInfer<{
|
|
30
|
+
presets: Schema<any, any, "volatile-defined">;
|
|
31
|
+
schemaVersion: Schema<number, number, "volatile-defined">;
|
|
32
|
+
layout: Schema<string, string, "volatile-defined">;
|
|
33
|
+
userActionsById: Schema<any, any, "volatile-defined">;
|
|
34
|
+
actionOrder: Schema<any, any, "volatile-defined">;
|
|
35
|
+
presetStateById: Schema<any, any, "volatile-defined">;
|
|
36
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
37
|
+
presets: Schema<any, any, "volatile-defined">;
|
|
38
|
+
schemaVersion: Schema<number, number, "volatile-defined">;
|
|
39
|
+
layout: Schema<string, string, "volatile-defined">;
|
|
40
|
+
userActionsById: Schema<any, any, "volatile-defined">;
|
|
41
|
+
actionOrder: Schema<any, any, "volatile-defined">;
|
|
42
|
+
presetStateById: Schema<any, any, "volatile-defined">;
|
|
43
|
+
}>>, "plain">;
|
|
44
|
+
/** One path-addressed field write, as the settings provider takes it. */
|
|
45
|
+
export interface SettingsSetOp {
|
|
46
|
+
readonly op: 'set';
|
|
47
|
+
readonly path: readonly string[];
|
|
48
|
+
readonly value: unknown;
|
|
49
|
+
}
|
|
50
|
+
/** One form as the provider describes it. */
|
|
48
51
|
export interface SettingsDescriptorLike {
|
|
49
52
|
readonly ns: string;
|
|
50
|
-
/** Monotonic revision of the raw
|
|
53
|
+
/** Monotonic revision of the raw entry configuration; send it back to fence a write. */
|
|
51
54
|
readonly revision: number;
|
|
52
|
-
/** The
|
|
55
|
+
/** The form fields the active profile patch sets. */
|
|
53
56
|
readonly user?: unknown;
|
|
54
57
|
}
|
|
55
58
|
/**
|
|
56
59
|
* The part of the Host settings provider the canonical rewrite reads and writes
|
|
57
60
|
* through. Declared structurally so the rewrite is testable against a controlled
|
|
58
|
-
* fake — the real `
|
|
61
|
+
* fake — the real `SettingsForms` satisfies it as-is.
|
|
59
62
|
*/
|
|
60
63
|
export interface SettingsRewriteProvider {
|
|
61
64
|
readonly writable: boolean;
|
|
62
65
|
describe(): readonly SettingsDescriptorLike[];
|
|
63
|
-
|
|
66
|
+
mutate(ns: string, ops: readonly SettingsSetOp[], expectedRevision?: number): Promise<void>;
|
|
64
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* One write per user-state field, never touching `presets`: the author's list
|
|
70
|
+
* shares the entry's config, and a write that restated it would pin whatever it
|
|
71
|
+
* read into the profile layer.
|
|
72
|
+
*/
|
|
73
|
+
export declare function stateOps(section: QuickActionSettingsV1): readonly SettingsSetOp[];
|
|
74
|
+
/**
|
|
75
|
+
* The user-state fields the profile layer actually sets, or `undefined` when it
|
|
76
|
+
* sets none. The same layer may carry the author's `presets`; those are Config,
|
|
77
|
+
* not stored state, so a profile holding only presets has nothing stored.
|
|
78
|
+
*/
|
|
79
|
+
export declare function storedState(user: unknown): Readonly<Record<string, unknown>> | undefined;
|
|
65
80
|
export type CanonicalRewriteOutcome =
|
|
66
81
|
/** The stored section already was canonical; nothing was written. */
|
|
67
82
|
{
|
|
@@ -90,7 +105,7 @@ export type CanonicalRewriteOutcome =
|
|
|
90
105
|
} | {
|
|
91
106
|
readonly status: 'read-only';
|
|
92
107
|
}
|
|
93
|
-
/** The
|
|
108
|
+
/** The form is not served — the entry is not active — so there is nothing to fence a write to. */
|
|
94
109
|
| {
|
|
95
110
|
readonly status: 'unregistered';
|
|
96
111
|
};
|
|
@@ -99,9 +114,9 @@ export type CanonicalRewriteOutcome =
|
|
|
99
114
|
* persist it behind the revision it was read at (spec 6.3).
|
|
100
115
|
*
|
|
101
116
|
* Nothing is written when nothing is stored: materializing the defaults into the
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
117
|
+
* profile layer would shadow every layer below it for good. Nothing is written
|
|
118
|
+
* for a higher `schemaVersion` either — that data belongs to the version that
|
|
119
|
+
* wrote it.
|
|
105
120
|
*
|
|
106
121
|
* A conflict means another writer won the race, so the rewrite refreshes the
|
|
107
122
|
* authoritative snapshot and recomputes rather than replaying its own stale
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Host composition entry for Composer Quick Actions.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* missing one — the stored section is left untouched and the surfaces go
|
|
9
|
-
* read-only (spec 10).
|
|
4
|
+
* Since DSH 0.1.7 the stored section is this entry's own Config (spec 22): the
|
|
5
|
+
* exported `Config` declares it, the Loader hands it over, and DSH Settings
|
|
6
|
+
* reads and writes it through the active profile. There is no namespace to
|
|
7
|
+
* register and no second namespace for the catalog.
|
|
10
8
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* `settings` is therefore an optional dependency, as for every first-party
|
|
10
|
+
* plugin: the Quick Actions run without it, and while it is present this entry
|
|
11
|
+
* opts out of an auto-generated Settings page — the plugin ships its own
|
|
12
|
+
* management panel — and canonicalizes the stored section once every entry of
|
|
13
|
+
* the profile has settled.
|
|
14
|
+
*
|
|
15
|
+
* Everything this entry installs is owned by this fiber and withdrawn when it
|
|
16
|
+
* unloads. The user's stored section deliberately survives unload, so
|
|
17
|
+
* reinstalling restores the user's actions.
|
|
15
18
|
*
|
|
16
19
|
* The public surface is the plugin contract only. The shared model, the
|
|
17
20
|
* Settings rewrite and the catalog assembly stay internal to the package
|
|
18
|
-
* (spec 11.2)
|
|
19
|
-
* to the release-surface decision.
|
|
21
|
+
* (spec 11.2).
|
|
20
22
|
*/
|
|
21
23
|
import type { Context } from '@deepseek-ai/cordis';
|
|
22
24
|
import type { QuickActionsHost } from './host/index.js';
|
|
23
25
|
export declare const name = "composer-quick-actions";
|
|
24
|
-
export
|
|
26
|
+
export { Config } from './host/settings.js';
|
|
25
27
|
export type { ComposerQuickActionsConfig } from './host/config.js';
|
|
26
28
|
export type { CatalogSnapshot, QuickActionsHost } from './host/index.js';
|
|
27
29
|
/**
|
|
28
|
-
* Load the Preset Catalog,
|
|
30
|
+
* Load the Preset Catalog and, while Settings is present, canonicalize the
|
|
29
31
|
* stored section. An invalid preset configuration throws here, failing plugin
|
|
30
32
|
* loading loudly rather than shipping a partial catalog (spec 5.1).
|
|
31
33
|
*
|
|
@@ -3,11 +3,11 @@ import type { PresetQuickAction, QuickActionField, QuickActionIssueReason } from
|
|
|
3
3
|
export declare const QUICK_ACTION_CATALOG_LIMIT = 50;
|
|
4
4
|
/** Where a catalog entry was declared. */
|
|
5
5
|
export type PresetSource = 'builtin' | 'config';
|
|
6
|
-
/** What
|
|
6
|
+
/** What either face feeds the model: raw JSON, validated here rather than upstream. */
|
|
7
7
|
export interface PresetCatalogInput {
|
|
8
8
|
/** The package's built-in manifest, in declaration order. */
|
|
9
9
|
readonly builtins: readonly unknown[];
|
|
10
|
-
/** `
|
|
10
|
+
/** The `presets` Config field, in declaration order. */
|
|
11
11
|
readonly configured: readonly unknown[];
|
|
12
12
|
}
|
|
13
13
|
/** One reason the plugin config must fail to load. */
|
|
@@ -25,7 +25,7 @@ export type PresetCatalogIssue = {
|
|
|
25
25
|
readonly count: number;
|
|
26
26
|
readonly limit: number;
|
|
27
27
|
};
|
|
28
|
-
/** The authoritative, read-only
|
|
28
|
+
/** The authoritative, read-only Preset Catalog (spec 6.2): what the Host validates and the Client rebuilds (spec 22.3). */
|
|
29
29
|
export interface PresetCatalog {
|
|
30
30
|
readonly schemaVersion: 1;
|
|
31
31
|
/** Determined by the catalog projection; any change to it changes this value. */
|
|
@@ -46,18 +46,3 @@ export type PresetCatalogResult = {
|
|
|
46
46
|
* author got wrong, so the mistake surfaces at startup rather than at send time.
|
|
47
47
|
*/
|
|
48
48
|
export declare function buildPresetCatalog(input: PresetCatalogInput): PresetCatalogResult;
|
|
49
|
-
/**
|
|
50
|
-
* Read one published catalog snapshot back (spec 17.2). The Host is the catalog's
|
|
51
|
-
* single validation authority, so this is a defensive decode of an already
|
|
52
|
-
* confirmed snapshot rather than a second authority — but it is a decode, not a
|
|
53
|
-
* cast: a snapshot this release cannot read in full yields no catalog at all.
|
|
54
|
-
*
|
|
55
|
-
* All-or-nothing on purpose. Dropping the entries it cannot read would show the
|
|
56
|
-
* user a silently truncated action list, which is exactly what spec 5.1 forbids
|
|
57
|
-
* the Host to do; the consumer reports a catalog error instead (spec 10).
|
|
58
|
-
*
|
|
59
|
-
* The Host's `revision` is carried through rather than recomputed. It is the
|
|
60
|
-
* catalog's published identity, and a Client that recomputed it would be
|
|
61
|
-
* asserting an authority it does not have.
|
|
62
|
-
*/
|
|
63
|
-
export declare function decodeCatalogSnapshot(raw: unknown): PresetCatalog | undefined;
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
* Preset Catalog (spec 5.1), declared ahead of the Host composition's
|
|
4
4
|
* `Config.presets`.
|
|
5
5
|
*
|
|
6
|
+
* It lives in the shared model because both faces merge it: the Host validates
|
|
7
|
+
* the catalog at load, and the Client rebuilds the same catalog from this list
|
|
8
|
+
* plus the `presets` form field it reads (spec 22.3). One list, so the two can
|
|
9
|
+
* never disagree about what the built-ins are.
|
|
10
|
+
*
|
|
6
11
|
* These are author-facing product copy in one language; changing a label or a
|
|
7
12
|
* text is a product decision, not an implementation one.
|
|
8
13
|
*
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import type { CustomQuickActionValue, PresetQuickActionState, QuickActionSettingsV1, QuickActionTombstone, StoredQuickActionValue } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* The one namespace holding user data (spec 4.2); renaming it orphans every
|
|
4
|
-
* stored section.
|
|
5
|
-
* the
|
|
3
|
+
* The one namespace holding user data (spec 4.2, 22); renaming it orphans every
|
|
4
|
+
* stored section. Since DSH 0.1.7 a Settings namespace *is* a profile entry id,
|
|
5
|
+
* so this is also the Cordis loader entry id the bundle patch inserts — the two
|
|
6
|
+
* can no longer drift apart. It lives in the shared model because both faces
|
|
7
|
+
* address it: the Host describes and fences its canonical rewrite against it,
|
|
8
|
+
* the Client reads and writes the same form.
|
|
6
9
|
*/
|
|
7
10
|
export declare const QUICK_ACTIONS_SETTINGS_NAMESPACE = "composer-quick-actions";
|
|
8
11
|
/**
|
|
9
|
-
* The
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
+
* The top-level fields of the stored section, in canonical order (spec 4.2).
|
|
13
|
+
* Each is a separate volatile Config field (spec 22.2): the DSH legacy import
|
|
14
|
+
* addresses a section by these exact top-level keys, and every write sets them
|
|
15
|
+
* field by field so a write never reaches the author's `presets`.
|
|
12
16
|
*/
|
|
13
|
-
export declare const
|
|
17
|
+
export declare const QUICK_ACTION_STATE_FIELDS: readonly ["schemaVersion", "layout", "userActionsById", "actionOrder", "presetStateById"];
|
|
14
18
|
/** The state a fresh install starts from (spec 4.2). */
|
|
15
19
|
export declare const DEFAULT_QUICK_ACTION_SETTINGS: QuickActionSettingsV1;
|
|
16
20
|
/**
|
|
@@ -11,22 +11,26 @@
|
|
|
11
11
|
* Colours are DSH alias theme tokens only — nothing here defines a palette, and
|
|
12
12
|
* nothing overrides a global theme (spec 8.4).
|
|
13
13
|
*
|
|
14
|
-
* ## The width rule (spec 8.2)
|
|
14
|
+
* ## The width rule (spec 8.2, 22.9)
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* `.dsh-cqa-ribbon` (and the launcher, in the same box) renders in the composer
|
|
17
|
+
* stack, outside the InputBar, which is the element that owns
|
|
18
|
+
* `--dsh-composer-side-clearance` as padding. It therefore subtracts that
|
|
19
|
+
* clearance from both sides itself, is capped at `--dsh-composer-card-max-width`
|
|
20
|
+
* — the same cap the composer card uses — and is centred, so its left and right
|
|
21
|
+
* edges coincide with the input box exactly rather than approximately.
|
|
18
22
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
23
|
+
* `.dsh-cqa-bar` makes no such claim. Since DSH 0.1.6-alpha.2 the composer dock is
|
|
24
|
+
* a row under the card that DSH centres and sizes to its content, shared with
|
|
25
|
+
* DSH's own stats pills and context meter, so the bar is a content-sized member of
|
|
26
|
+
* that row (spec 22.9). It only has to stay inside it: `min-width: 0` lets it
|
|
27
|
+
* shrink when the row reaches the composer's width, which is what hands the
|
|
28
|
+
* overflow split a smaller region to fold into "more". Once it folds it claims
|
|
29
|
+
* the card's width (`[data-quick-actions-overflow]`), capped by the row's own
|
|
30
|
+
* `max-width: 100%`: content-sized, the region the split measures would only be
|
|
31
|
+
* as wide as what it already shows, and a wider window could never unfold it.
|
|
28
32
|
*/
|
|
29
|
-
export declare const QUICK_ACTIONS_CSS = "\n.dsh-cqa-ribbon,\n.dsh-cqa-launcher {\n box-sizing: border-box;\n width: calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance));\n max-width: var(--dsh-composer-card-max-width);\n margin: 0 auto;\n}\n.dsh-cqa-bar {\n box-sizing: border-box;\n width: 100%;\n max-width: var(--dsh-composer-card-max-width);\n margin: 0 auto;\n}\n\n.dsh-cqa-row {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n padding: 2px 0;\n}\n.dsh-cqa-row[data-density='narrow'] {\n gap: 6px;\n}\n\n.dsh-cqa-title {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n white-space: nowrap;\n}\n\n/* The ribbon overflows horizontally; the management entry never scrolls away. */\n.dsh-cqa-scroll {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1 1 auto;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: thin;\n}\n.dsh-cqa-fit {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n}\n.dsh-cqa-trailing {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: none;\n margin-left: auto;\n}\n\n/*\n * The capsule itself \u2014 height, radius, padding, colours, hover and \":disabled\"\n * \u2014 belongs to the official \"Button\". What is left here is what a shared\n * control cannot know (how it behaves inside these rows) plus what the\n * primitive does not supply. Nothing below may restate a Button property,\n * because the plugin class is applied after the primitive's and would win on\n * equal specificity.\n *\n * The focus ring is one of the things it does not supply: \"Button.module.css\"\n * and \"Pill.module.css\" carry no \":focus\" rule at all \u2014 the library leaves the\n * ring to each component that wants one (\"Input.module.css\" has\n * \":focus-within\", \"HoverCard\" and \"JsonTree\" their own). Spec 8.4 makes a\n * clear focus ring a hard gate, so it stays here for every control this plugin\n * renders.\n */\n.dsh-cqa-action,\n.dsh-cqa-entry {\n /* No global border-box reset exists in this stylesheet, and Button pads\n itself, so the cap has to count that padding to mean 240px on screen. */\n box-sizing: border-box;\n flex: none;\n /* Long labels truncate rather than pushing the row's other controls out. */\n max-width: 240px;\n}\n.dsh-cqa-action:focus-visible,\n.dsh-cqa-entry:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n/* \"aria-disabled\" is not \":disabled\": a control kept focusable while a write is\n in flight still has to read as inert, and no primitive expresses that. */\n.dsh-cqa-entry[aria-disabled='true'] {\n opacity: 0.5;\n cursor: default;\n}\n/* The searchable panel's rows stay native \u2014 a full-width, left-aligned list row\n is not a capsule \u2014 so they still need a focus ring of their own. */\n.dsh-cqa-panel-item:focus-visible,\n.dsh-cqa-link:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n.dsh-cqa-label {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-cqa-icon {\n flex: none;\n}\n/* The chip look is \"Pill\"'s; only its behaviour in a flex row is ours. */\n.dsh-cqa-badge,\n.dsh-cqa-tag {\n flex: none;\n}\n\n.dsh-cqa-note {\n box-sizing: border-box;\n width: 100%;\n margin: 4px 0 0;\n padding: 4px 8px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 18px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-cqa-note-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n.dsh-cqa-link {\n flex: none;\n border: 0;\n background: none;\n padding: 0;\n color: var(--dsw-alias-state-business-primary);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n text-decoration: underline;\n}\n\n/* Anchored surfaces: the popover list and the confirmation panel. */\n.dsh-cqa-anchor {\n position: relative;\n}\n.dsh-cqa-backdrop {\n position: fixed;\n z-index: 19;\n inset: 0;\n}\n.dsh-cqa-panel {\n position: absolute;\n z-index: 20;\n bottom: calc(100% + 6px);\n left: 0;\n box-sizing: border-box;\n max-width: min(100%, 360px);\n min-width: 220px;\n max-height: 260px;\n overflow-y: auto;\n padding: 6px;\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: 12px;\n background: var(--dsw-specific-tip);\n box-shadow: var(--dsw-elevation-soft);\n}\n.dsh-cqa-panel-head {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-cqa-panel-head .dsh-cqa-panel-title {\n flex: 1 1 auto;\n min-width: 0;\n}\n.dsh-cqa-panel-title {\n padding: 4px 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n.dsh-cqa-panel-item {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 6px 8px;\n border: 0;\n border-radius: 8px;\n background: none;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 13px;\n line-height: 20px;\n text-align: left;\n cursor: pointer;\n}\n.dsh-cqa-panel-item:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-cqa-panel-item:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n.dsh-cqa-confirm-text {\n margin: 6px 0;\n padding: 8px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n font-family: var(--ds-font-family-code);\n font-size: 12px;\n line-height: 18px;\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 160px;\n overflow-y: auto;\n}\n.dsh-cqa-confirm-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n\n/* ------------------------------------------------------------------------- */\n/* Fields, shared by the search box and the Custom Quick Action form */\n/* ------------------------------------------------------------------------- */\n\n.dsh-cqa-field {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 4px 0;\n}\n.dsh-cqa-field-label {\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 18px;\n}\n.dsh-cqa-field-hint {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n line-height: 16px;\n}\n.dsh-cqa-field-error {\n color: var(--dsw-alias-state-danger-primary, var(--dsw-alias-label-primary));\n font-size: 11px;\n line-height: 16px;\n font-weight: 500;\n}\n\n.dsh-cqa-input,\n.dsh-cqa-textarea {\n box-sizing: border-box;\n width: 100%;\n padding: 4px 8px;\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 13px;\n line-height: 20px;\n}\n.dsh-cqa-textarea {\n resize: vertical;\n min-height: 72px;\n font-family: var(--ds-font-family-code);\n white-space: pre-wrap;\n}\n.dsh-cqa-input:focus-visible,\n.dsh-cqa-textarea:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n.dsh-cqa-input:disabled,\n.dsh-cqa-textarea:disabled {\n opacity: 0.5;\n}\n\n.dsh-cqa-switch {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 0;\n cursor: pointer;\n}\n\n/* ------------------------------------------------------------------------- */\n/* The centralized management overlay */\n/* ------------------------------------------------------------------------- */\n\n/*\n * The overlay and its click-catching backdrop. Neither paints: only DSH alias\n * theme tokens may be used here, and this release has no token to spend on a\n * modal scrim (spec 8.4).\n *\n * These two numbers rank the overlay against its own backdrop, and nothing\n * else. Since ticket 26 the overlay is portaled to the document body, so it and\n * the anchored popovers (19 and 20, still rendered in the input dock) sit in\n * different stacking contexts: which of them paints on top follows from where\n * the dock's own ancestors land in the root context, not from comparing 31\n * against 20. Raising these would not change that.\n */\n.dsh-cqa-manager-backdrop {\n z-index: 30;\n}\n.dsh-cqa-manager {\n position: fixed;\n z-index: 31;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n width: min(560px, calc(100vw - 24px));\n max-height: min(80vh, 680px);\n overflow-y: auto;\n padding: 12px;\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: 12px;\n background: var(--dsw-specific-tip);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-elevation-soft);\n}\n\n.dsh-cqa-manager-head {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-cqa-manager-title {\n flex: 1 1 auto;\n min-width: 0;\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 14px;\n font-weight: 600;\n line-height: 20px;\n}\n\n.dsh-cqa-section {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 6px 0;\n border-top: 0.5px solid var(--dsw-alias-border-l1);\n}\n.dsh-cqa-section-head {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n.dsh-cqa-section-head .dsh-cqa-section-title {\n flex: 1 1 auto;\n}\n.dsh-cqa-section-title {\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n}\n.dsh-cqa-group {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n.dsh-cqa-entry[aria-pressed='true'] {\n background: var(--dsw-alias-state-business-tertiary);\n color: var(--dsw-alias-label-primary-bluish);\n opacity: 1;\n}\n\n.dsh-cqa-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.dsh-cqa-list-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 6px 8px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover);\n}\n/* A hidden or disabled action stays legible: it is managed here, not removed. */\n.dsh-cqa-list-item[data-quick-action-hidden] .dsh-cqa-list-head,\n.dsh-cqa-list-item[data-quick-action-hidden] .dsh-cqa-list-text {\n opacity: 0.6;\n}\n.dsh-cqa-list-head {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n min-width: 0;\n font-size: 13px;\n line-height: 20px;\n}\n.dsh-cqa-list-text {\n min-width: 0;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font-family: var(--ds-font-family-code);\n font-size: 11px;\n line-height: 16px;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.dsh-cqa-list-controls {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.dsh-cqa-form {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 6px 0 0;\n border-top: 0.5px solid var(--dsw-alias-border-l1);\n}\n.dsh-cqa-form-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding-top: 6px;\n}\n";
|
|
33
|
+
export declare const QUICK_ACTIONS_CSS = "\n.dsh-cqa-ribbon,\n.dsh-cqa-launcher {\n box-sizing: border-box;\n width: calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance));\n max-width: var(--dsh-composer-card-max-width);\n margin: 0 auto;\n}\n.dsh-cqa-bar {\n box-sizing: border-box;\n min-width: 0;\n max-width: var(--dsh-composer-card-max-width);\n}\n/* Folding: claim the card's width, for the dock row's own max-width to cap. */\n.dsh-cqa-bar[data-quick-actions-overflow] {\n width: var(--dsh-composer-card-max-width);\n}\n\n.dsh-cqa-row {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n padding: 2px 0;\n}\n.dsh-cqa-row[data-density='narrow'] {\n gap: 6px;\n}\n\n.dsh-cqa-title {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n white-space: nowrap;\n}\n\n/* The ribbon overflows horizontally; the management entry never scrolls away. */\n.dsh-cqa-scroll {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1 1 auto;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: thin;\n}\n.dsh-cqa-fit {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n}\n.dsh-cqa-trailing {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: none;\n margin-left: auto;\n}\n\n/*\n * The capsule itself \u2014 height, radius, padding, colours, hover and \":disabled\"\n * \u2014 belongs to the official \"Button\". What is left here is what a shared\n * control cannot know (how it behaves inside these rows) plus what the\n * primitive does not supply. Nothing below may restate a Button property,\n * because the plugin class is applied after the primitive's and would win on\n * equal specificity.\n *\n * The focus ring is one of the things it does not supply: \"Button.module.css\"\n * and \"Pill.module.css\" carry no \":focus\" rule at all \u2014 the library leaves the\n * ring to each component that wants one (\"Input.module.css\" has\n * \":focus-within\", \"HoverCard\" and \"JsonTree\" their own). Spec 8.4 makes a\n * clear focus ring a hard gate, so it stays here for every control this plugin\n * renders.\n */\n.dsh-cqa-action,\n.dsh-cqa-entry {\n /* No global border-box reset exists in this stylesheet, and Button pads\n itself, so the cap has to count that padding to mean 240px on screen. */\n box-sizing: border-box;\n flex: none;\n /* Long labels truncate rather than pushing the row's other controls out. */\n max-width: 240px;\n}\n.dsh-cqa-action:focus-visible,\n.dsh-cqa-entry:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n/* \"aria-disabled\" is not \":disabled\": a control kept focusable while a write is\n in flight still has to read as inert, and no primitive expresses that. */\n.dsh-cqa-entry[aria-disabled='true'] {\n opacity: 0.5;\n cursor: default;\n}\n/* The searchable panel's rows stay native \u2014 a full-width, left-aligned list row\n is not a capsule \u2014 so they still need a focus ring of their own. */\n.dsh-cqa-panel-item:focus-visible,\n.dsh-cqa-link:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n.dsh-cqa-label {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dsh-cqa-icon {\n flex: none;\n}\n/* The chip look is \"Pill\"'s; only its behaviour in a flex row is ours. */\n.dsh-cqa-badge,\n.dsh-cqa-tag {\n flex: none;\n}\n\n.dsh-cqa-note {\n box-sizing: border-box;\n width: 100%;\n margin: 4px 0 0;\n padding: 4px 8px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 18px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-cqa-note-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n.dsh-cqa-link {\n flex: none;\n border: 0;\n background: none;\n padding: 0;\n color: var(--dsw-alias-state-business-primary);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n text-decoration: underline;\n}\n\n/* Anchored surfaces: the popover list and the confirmation panel. */\n.dsh-cqa-anchor {\n position: relative;\n}\n.dsh-cqa-backdrop {\n position: fixed;\n z-index: 19;\n inset: 0;\n}\n.dsh-cqa-panel {\n position: absolute;\n z-index: 20;\n bottom: calc(100% + 6px);\n left: 0;\n box-sizing: border-box;\n max-width: min(100%, 360px);\n min-width: 220px;\n max-height: 260px;\n overflow-y: auto;\n padding: 6px;\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: 12px;\n background: var(--dsw-specific-tip);\n box-shadow: var(--dsw-elevation-soft);\n}\n.dsh-cqa-panel-head {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-cqa-panel-head .dsh-cqa-panel-title {\n flex: 1 1 auto;\n min-width: 0;\n}\n.dsh-cqa-panel-title {\n padding: 4px 8px;\n color: var(--dsw-alias-label-tertiary);\n font-size: 12px;\n line-height: 18px;\n}\n.dsh-cqa-panel-item {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 6px 8px;\n border: 0;\n border-radius: 8px;\n background: none;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 13px;\n line-height: 20px;\n text-align: left;\n cursor: pointer;\n}\n.dsh-cqa-panel-item:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-cqa-panel-item:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n.dsh-cqa-confirm-text {\n margin: 6px 0;\n padding: 8px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-primary);\n font-family: var(--ds-font-family-code);\n font-size: 12px;\n line-height: 18px;\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 160px;\n overflow-y: auto;\n}\n.dsh-cqa-confirm-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n\n/* ------------------------------------------------------------------------- */\n/* Fields, shared by the search box and the Custom Quick Action form */\n/* ------------------------------------------------------------------------- */\n\n.dsh-cqa-field {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 4px 0;\n}\n.dsh-cqa-field-label {\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 18px;\n}\n.dsh-cqa-field-hint {\n color: var(--dsw-alias-label-tertiary);\n font-size: 11px;\n line-height: 16px;\n}\n.dsh-cqa-field-error {\n color: var(--dsw-alias-state-danger-primary, var(--dsw-alias-label-primary));\n font-size: 11px;\n line-height: 16px;\n font-weight: 500;\n}\n\n.dsh-cqa-input,\n.dsh-cqa-textarea {\n box-sizing: border-box;\n width: 100%;\n padding: 4px 8px;\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 13px;\n line-height: 20px;\n}\n.dsh-cqa-textarea {\n resize: vertical;\n min-height: 72px;\n font-family: var(--ds-font-family-code);\n white-space: pre-wrap;\n}\n.dsh-cqa-input:focus-visible,\n.dsh-cqa-textarea:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n.dsh-cqa-input:disabled,\n.dsh-cqa-textarea:disabled {\n opacity: 0.5;\n}\n\n.dsh-cqa-switch {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 0;\n cursor: pointer;\n}\n\n/* ------------------------------------------------------------------------- */\n/* The centralized management overlay */\n/* ------------------------------------------------------------------------- */\n\n/*\n * The overlay and its click-catching backdrop. Neither paints: only DSH alias\n * theme tokens may be used here, and this release has no token to spend on a\n * modal scrim (spec 8.4).\n *\n * These two numbers rank the overlay against its own backdrop, and nothing\n * else. Since ticket 26 the overlay is portaled to the document body, so it and\n * the anchored popovers (19 and 20, still rendered in the input dock) sit in\n * different stacking contexts: which of them paints on top follows from where\n * the dock's own ancestors land in the root context, not from comparing 31\n * against 20. Raising these would not change that.\n */\n.dsh-cqa-manager-backdrop {\n z-index: 30;\n}\n.dsh-cqa-manager {\n position: fixed;\n z-index: 31;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n width: min(560px, calc(100vw - 24px));\n max-height: min(80vh, 680px);\n overflow-y: auto;\n padding: 12px;\n border: 0.5px solid var(--dsw-alias-border-l1);\n border-radius: 12px;\n background: var(--dsw-specific-tip);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-elevation-soft);\n}\n\n.dsh-cqa-manager-head {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-cqa-manager-title {\n flex: 1 1 auto;\n min-width: 0;\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 14px;\n font-weight: 600;\n line-height: 20px;\n}\n\n.dsh-cqa-section {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 6px 0;\n border-top: 0.5px solid var(--dsw-alias-border-l1);\n}\n.dsh-cqa-section-head {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n.dsh-cqa-section-head .dsh-cqa-section-title {\n flex: 1 1 auto;\n}\n.dsh-cqa-section-title {\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n}\n.dsh-cqa-group {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n.dsh-cqa-entry[aria-pressed='true'] {\n background: var(--dsw-alias-state-business-tertiary);\n color: var(--dsw-alias-label-primary-bluish);\n opacity: 1;\n}\n\n.dsh-cqa-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.dsh-cqa-list-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 6px 8px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover);\n}\n/* A hidden or disabled action stays legible: it is managed here, not removed. */\n.dsh-cqa-list-item[data-quick-action-hidden] .dsh-cqa-list-head,\n.dsh-cqa-list-item[data-quick-action-hidden] .dsh-cqa-list-text {\n opacity: 0.6;\n}\n.dsh-cqa-list-head {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n min-width: 0;\n font-size: 13px;\n line-height: 20px;\n}\n.dsh-cqa-list-text {\n min-width: 0;\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font-family: var(--ds-font-family-code);\n font-size: 11px;\n line-height: 16px;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.dsh-cqa-list-controls {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.dsh-cqa-form {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 6px 0 0;\n border-top: 0.5px solid var(--dsw-alias-border-l1);\n}\n.dsh-cqa-form-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding-top: 6px;\n}\n";
|
|
30
34
|
/**
|
|
31
35
|
* Install the stylesheet once per document and return its disposer, so the
|
|
32
36
|
* Client fiber owns it like every other registration (spec 7.3).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-quick-actions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-rc.2",
|
|
4
4
|
"description": "Persistent Quick Actions for the DSH message composer",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -60,23 +60,28 @@
|
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
64
|
-
"@deepseek-ai/dsh-client-connection": ">=0.1.
|
|
65
|
-
"@deepseek-ai/dsh-client-locale": ">=0.1.
|
|
66
|
-
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.
|
|
67
|
-
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.
|
|
68
|
-
"@deepseek-ai/dsh-client-ui-renderer": ">=0.1.
|
|
69
|
-
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.
|
|
70
|
-
"@deepseek-ai/dsh-settings": ">=0.1.
|
|
71
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
63
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
64
|
+
"@deepseek-ai/dsh-client-connection": ">=0.1.7-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.7-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.7-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.7-alpha.2",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-renderer": ">=0.1.7-alpha.2",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.7-alpha.2",
|
|
70
|
+
"@deepseek-ai/dsh-settings": ">=0.1.7-alpha.2",
|
|
71
|
+
"@deepseek-ai/schemastery": "^3.18.4",
|
|
72
72
|
"react": "^18.3.1",
|
|
73
73
|
"react-dom": "^18.3.1"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
76
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
77
|
+
"@deepseek-ai/dsh-client-connection": "0.1.7-rc.1",
|
|
78
|
+
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.1",
|
|
79
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.1",
|
|
77
80
|
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
|
|
78
|
-
"@deepseek-ai/dsh-
|
|
79
|
-
"@deepseek-ai/
|
|
81
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-settings": "0.1.7-rc.1",
|
|
84
|
+
"@deepseek-ai/schemastery": "^3.18.4",
|
|
80
85
|
"@types/react": "~18.3.31",
|
|
81
86
|
"@types/react-dom": "~18.3.7",
|
|
82
87
|
"react": "^18.3.1",
|