Add mouse support - #8131
Conversation
27361fb to
9e86d33
Compare
|
/snapit |
|
🫰✨ Thanks @gonzaloriestra! Your snapshot has been published to npm. Test the snapshot by installing your package globally: pnpm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260720151107Caution After installing, validate the version by running |
9e86d33 to
65f7aff
Compare
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
65f7aff to
692317a
Compare
0427849 to
603e207
Compare
692317a to
12c1559
Compare
603e207 to
f022390
Compare
12c1559 to
4533b4c
Compare
f022390 to
aed6ae1
Compare
4533b4c to
ad56e66
Compare
ad56e66 to
8ca325d
Compare
250576c to
65e2599
Compare
8282535 to
3def2e5
Compare
65e2599 to
4990f80
Compare
4990f80 to
f8326f2
Compare
3def2e5 to
a2925a4
Compare
f8326f2 to
853bb21
Compare
779debb to
b462d6d
Compare
f4834c1 to
0c72475
Compare
b462d6d to
4c46ebf
Compare
0c72475 to
f9bd5d4
Compare
4c46ebf to
f20d04f
Compare
f9bd5d4 to
5325d2d
Compare
f20d04f to
d0e96b4
Compare
5325d2d to
be36637
Compare
d0e96b4 to
77de5a9
Compare
be36637 to
a610c01
Compare
77de5a9 to
3e16126
Compare
a610c01 to
91a8307
Compare
fa36048 to
ffbcb1f
Compare
91a8307 to
355a0e0
Compare
ffbcb1f to
a115868
Compare
355a0e0 to
d8c60f1
Compare
Differences in type declarationsWe detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:
New type declarationspackages/cli-kit/dist/public/node/mouse.d.tsimport { getMouseEnabled, setMouseEnabled } from '../../private/node/conf-store.js';
export { getMouseEnabled, setMouseEnabled };
packages/cli-kit/dist/private/node/ui/components/Mouse.d.tsimport React from 'react';
import { type ClickHandler, type ElementRef, type MouseEnterHandler } from '@ink-tools/ink-mouse';
interface MouseProviderProps extends React.PropsWithChildren {
allowTerminalScrolling?: boolean;
trackMouseMovement?: boolean;
}
export declare function removeTerminalInputResponses(input: string): string;
export declare function MouseProvider({ children, ...mouseProviderProps }: MouseProviderProps): React.ReactElement;
export declare function useOnClick(ref: ElementRef, handler: ClickHandler | null | undefined): void;
export declare function useOnMouseEnter(ref: ElementRef, handler: MouseEnterHandler | null | undefined): void;
export {};
Existing type declarationspackages/cli-kit/dist/private/node/conf-store.d.ts@@ -25,6 +25,7 @@ export interface ConfSchema {
currentDevSessionId?: string;
cache?: Cache;
autoUpgradeEnabled?: boolean;
+ mouseEnabled?: boolean;
}
/**
* Get session.
@@ -139,6 +140,19 @@ export declare function getAutoUpgradeEnabled(config?: LocalStorage<ConfSchema>)
* @param enabled - Whether auto-upgrade should be enabled.
*/
export declare function setAutoUpgradeEnabled(enabled: boolean, config?: LocalStorage<ConfSchema>): void;
+/**
+ * Get mouse interaction preference.
+ * Defaults to true if the preference has never been explicitly set.
+ *
+ * @returns Whether mouse interactions are enabled.
+ */
+export declare function getMouseEnabled(config?: LocalStorage<ConfSchema>): boolean;
+/**
+ * Set mouse interaction preference.
+ *
+ * @param enabled - Whether mouse interactions should be enabled.
+ */
+export declare function setMouseEnabled(enabled: boolean, config?: LocalStorage<ConfSchema>): void;
export declare function getConfigStoreForPartnerStatus(): LocalStorage<Record<string, {
status: true;
checkedAt: string;
packages/cli-kit/dist/private/node/otel-metrics.d.ts@@ -2,7 +2,7 @@ import { OtelService } from '../../public/node/vendor/otel-js/service/types.js';
import { DefaultOtelServiceOptions } from '../../public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.js';
type MetricRecorder = 'console' | {
type: 'otel';
- otel: Pick<OtelService, 'record'>;
+ otel: Pick<OtelService, 'getMeterProvider' | 'record'>;
};
interface Timing {
active: number;
packages/cli-kit/dist/private/node/ui.d.ts@@ -28,6 +28,7 @@ export declare class Stdout extends EventEmitter {
columns: number;
rows: number;
readonly frames: string[];
+ readonly controlSequences: string[];
private _lastFrame?;
constructor(options: {
columns?: number;
packages/cli-kit/dist/public/node/analytics.d.ts@@ -6,6 +6,7 @@ interface ReportAnalyticsEventOptions {
errorMessage?: string;
exitMode: CommandExitMode;
}
+export declare function sendAnalyticsEventFromStdin(): Promise<void>;
/**
* Report an analytics event, sending it off to Monorail -- Shopify's internal analytics service.
*
packages/cli-kit/dist/public/node/base-command.d.ts@@ -10,6 +10,7 @@ export interface NonTTYFlagRequirement {
}
declare abstract class BaseCommand extends Command {
static baseFlags: FlagInput<{}>;
+ static get requiresSyncAnalytics(): boolean;
static nonTTYFlagRequirements(_flags: FlagOutput): NonTTYFlagRequirement[];
static descriptionWithoutMarkdown(): string | undefined;
static analyticsNameOverride(): string | undefined;
packages/cli-kit/dist/public/node/ink.d.ts@@ -1 +1,3 @@
-export { Box, Text, Static, useInput, useStdin, useStdout, measureElement } from 'ink';
\ No newline at end of file
+export { Box, Text, Static, useInput, useStdin, useStdout, measureElement } from 'ink';
+export type { DOMElement } from 'ink';
+export { MouseProvider, useOnClick, useOnMouseEnter } from '../../private/node/ui/components/Mouse.js';
\ No newline at end of file
packages/cli-kit/dist/public/node/metadata.d.ts@@ -42,6 +42,7 @@ declare const coreData: RuntimeMetadataManager<CmdFieldsFromMonorail, {
startCommand: string;
startTopic?: string;
startArgs: string[];
+ requiresSyncAnalytics?: boolean;
};
} & {
environmentFlags: string;
@@ -63,6 +64,7 @@ export declare const getAllPublicMetadata: () => Partial<CmdFieldsFromMonorail>,
startCommand: string;
startTopic?: string;
startArgs: string[];
+ requiresSyncAnalytics?: boolean;
};
} & {
environmentFlags: string;
@@ -83,6 +85,7 @@ export declare const getAllPublicMetadata: () => Partial<CmdFieldsFromMonorail>,
startCommand: string;
startTopic?: string;
startArgs: string[];
+ requiresSyncAnalytics?: boolean;
};
} & {
environmentFlags: string;
packages/cli-kit/dist/public/node/ui.d.ts@@ -220,7 +220,8 @@ export interface RenderSelectPromptOptions<T> extends Omit<SelectPromptProps<T>,
* seventh
* tenth
*
- * Press ↑↓ arrows to select, enter to confirm.
+ * Press ↑↓ arrows to select, enter to confirm, or click an
+ * option.
*
*/
export declare function renderSelectPrompt<T>({ renderOptions, isConfirmationPrompt, ...props }: RenderSelectPromptOptions<T>, uiDebugOptions?: UIDebugOptions): Promise<T>;
@@ -245,8 +246,8 @@ export interface RenderConfirmationPromptOptions extends Pick<SelectPromptProps<
* > (y) Yes, confirm changes
* (n) Cancel
*
- * Press ↑↓ arrows to select, enter or a shortcut to
- * confirm.
+ * Use ↑↓ to select; press enter, use a shortcut, or click
+ * an option.
*
*/
export declare function renderConfirmationPrompt({ message, infoTable, confirmationMessage, cancellationMessage, renderOptions, defaultValue, abortSignal, infoMessage, }: RenderConfirmationPromptOptions): Promise<boolean>;
@@ -288,7 +289,8 @@ export interface RenderAutocompleteOptions<T> extends PartialBy<Omit<Autocomplet
* twenty-fourth
* twenty-fifth
*
- * Press ↑↓ arrows to select, enter to confirm.
+ * Press ↑↓ arrows to select, enter to confirm, or click an
+ * option.
*
*/
export declare function renderAutocompletePrompt<T>({ renderOptions, ...props }: RenderAutocompleteOptions<T>, uiDebugOptions?: UIDebugOptions): Promise<T>;
packages/cli-kit/dist/private/node/testing/ui.d.ts@@ -9,13 +9,16 @@ declare class Stderr extends EventEmitter {
}
export declare class Stdin extends EventEmitter {
isTTY: boolean;
+ isRaw: boolean;
data: string | null;
constructor(options?: {
isTTY?: boolean;
});
write: (data: string) => void;
setEncoding(): void;
- setRawMode(): void;
+ setRawMode(isRaw: boolean): void;
+ pause(): void;
+ resume(): void;
ref(): void;
unref(): void;
read: () => string | null;
@@ -35,6 +38,7 @@ interface RenderOptions {
stdout?: EventEmitter;
stderr?: EventEmitter;
stdin?: EventEmitter;
+ stdoutIsTTY?: boolean;
}
export declare const render: (tree: ReactElement, options?: RenderOptions) => Instance;
/**
packages/cli-kit/dist/public/node/vendor/otel-js/service/types.d.ts@@ -1,5 +1,5 @@
-import type { Counter, Histogram, MeterProvider, MetricAttributes, MetricOptions, UpDownCounter } from '@opentelemetry/api';
-import type { ViewOptions } from '@opentelemetry/sdk-metrics';
+import type { Counter, Histogram, MetricAttributes, MetricOptions, UpDownCounter } from '@opentelemetry/api';
+import type { MeterProvider, ViewOptions } from '@opentelemetry/sdk-metrics';
export type CustomMetricLabels<TLabels extends Record<TKeys, MetricAttributes>, TKeys extends string = keyof TLabels & string> = {
[P in TKeys]: TLabels[P] extends MetricAttributes ? TLabels[P] : never;
};
|
a115868 to
3b08977
Compare

WHY are these changes introduced?
HackDays project: https://vault.shopify.io/hackdays/154/projects/24279-Shopify-CLI-UX-improvements
Shopify CLI prompts and app dev tabs are keyboard-only, making common interactions less direct.
WHAT is this pull request doing?
Adds shared mouse handling for prompts and app dev tabs, including terminal scrolling support and
shopify config mouse on|offcontrols.demo.mp4
How to test your changes?
pnpm i -g @shopify/cli@0.0.0-snapshot-20260811121607shopify app initshopify app devChecklist
patchfor bug fixes ·minorfor new features ·majorfor breaking changes) and added a changeset withpnpm changeset add