Skip to content

Commit b74a178

Browse files
authored
AUI: Added support for generating default cursor styles (#297)
1 parent 7d6fd23 commit b74a178

6 files changed

Lines changed: 90 additions & 0 deletions

File tree

.changeset/silver-crabs-flash.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@adaptive-web/adaptive-ui-designer-core": patch
3+
"@adaptive-web/adaptive-ui": patch
4+
---
5+
6+
AUI: Added support for generating default cursor styles

packages/adaptive-ui/docs/api-report.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export type ColorRecipeParams = {
116116
export interface ComponentAnatomy<TConditions extends ComponentConditions, TParts extends ComponentParts> {
117117
conditions: TConditions;
118118
context?: string;
119+
cursor?: CursorDefinition | false;
119120
focus?: FocusDefinition<TParts>;
120121
interactivity?: InteractivityDefinition;
121122
name?: string;
@@ -246,6 +247,12 @@ export function createTokenSwatch(name: string, intendedFor?: StyleProperty | St
246247
// @public
247248
export const createTyped: typeof TypedCSSDesignToken.createTyped;
248249

250+
// @public
251+
export interface CursorDefinition {
252+
cursorType?: string;
253+
part?: string;
254+
}
255+
249256
// @public
250257
export function deltaSwatch(palette: Palette, reference: Paint, delta: number, direction?: PaletteDirection): Color;
251258

@@ -599,6 +606,8 @@ export interface SerializableAnatomy {
599606
// (undocumented)
600607
context: string;
601608
// (undocumented)
609+
cursor?: CursorDefinition | false;
610+
// (undocumented)
602611
focus?: FocusDefinition<any>;
603612
// (undocumented)
604613
interactivity?: InteractivityDefinition;

packages/adaptive-ui/src/bin/aui.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ function jsonToAUIStyleSheet(obj: SerializableAnatomy): AUIStyleSheet {
347347
parts: obj.parts,
348348
interactivity: obj.interactivity,
349349
focus: obj.focus,
350+
cursor: obj.cursor,
350351
},
351352
rules: obj.styleRules.map(style => {
352353
const styles = style.styles?.map(name => {
@@ -396,6 +397,10 @@ function jsonToAUIStyleSheet(obj: SerializableAnatomy): AUIStyleSheet {
396397
}
397398
}
398399

400+
if (sheet.anatomy.cursor && typeof sheet.anatomy.cursor === "object") {
401+
sheet.anatomy.cursor.part = resolvePart(obj, sheet.anatomy.cursor.part);
402+
}
403+
399404
return sheet;
400405
}
401406

packages/adaptive-ui/src/core/modules/element-styles-renderer.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,35 @@ export class ElementStylesRenderer {
278278
);
279279
}
280280

281+
// Apply interactive cursor styles (skip if explicitly disabled)
282+
if (anatomy.interactivity?.interactive !== undefined && anatomy.cursor !== false) {
283+
// Determine which part gets the cursor (already resolved to selector by aui.ts)
284+
let cursorPart: string | undefined;
285+
let cursorType = "pointer";
286+
287+
if (anatomy.cursor && typeof anatomy.cursor === "object") {
288+
// Explicit cursor definition (part already resolved to selector)
289+
cursorPart = anatomy.cursor.part ?? anatomy.focus?.focusTarget.part;
290+
cursorType = anatomy.cursor.cursorType ?? "pointer";
291+
} else if (anatomy.focus) {
292+
// Default: use focus target part (already resolved to selector)
293+
cursorPart = anatomy.focus.focusTarget.part;
294+
}
295+
296+
// Only apply if we determined a cursor target or want to apply to root
297+
if (cursorPart !== undefined || anatomy.focus) {
298+
globalStyleRules.push(
299+
{
300+
target: {
301+
contextCondition: anatomy.interactivity.interactive,
302+
part: cursorPart,
303+
},
304+
styles: Styles.fromProperties({ cursor: cursorType }),
305+
},
306+
);
307+
}
308+
}
309+
281310
// If this component can get focus, apply the focus indicator styles.
282311
if (anatomy.focus) {
283312
if (ElementStylesRenderer._focusResetStylesAdjusted && anatomy.focus?.resetTarget) {

packages/adaptive-ui/src/core/modules/types.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ export interface ComponentAnatomy<TConditions extends ComponentConditions, TPart
7272
* Description of the focus structure of the component.
7373
*/
7474
focus?: FocusDefinition<TParts>;
75+
76+
/**
77+
* Description of cursor behavior for interactive elements.
78+
* If not provided, defaults to using focus.focusTarget.part with cursor: pointer.
79+
* Set to false to explicitly disable automatic cursor generation.
80+
*/
81+
cursor?: CursorDefinition | false;
7582
}
7683

7784
/**
@@ -285,6 +292,25 @@ export const Focus = {
285292
},
286293
} as const;
287294

295+
/**
296+
* Defines cursor behavior for interactive elements.
297+
*
298+
* @public
299+
*/
300+
export interface CursorDefinition {
301+
/**
302+
* The part that should receive the cursor style when interactive.
303+
* If undefined, uses the same part as focus.focusTarget.part.
304+
*/
305+
part?: string;
306+
307+
/**
308+
* The cursor type to apply (defaults to "pointer").
309+
* Common values: "pointer", "text", "move", "grab", "default".
310+
*/
311+
cursorType?: string;
312+
}
313+
288314
/**
289315
* Parameters used to evaluate style modules for a component.
290316
*
@@ -525,6 +551,7 @@ export interface SerializableAnatomy {
525551
parts: Record<string, string>,
526552
interactivity?: InteractivityDefinition,
527553
focus?: FocusDefinition<any>,
554+
cursor?: CursorDefinition | false,
528555
styleRules: SerializableStyleRule[]
529556
}
530557

packages/adaptive-ui/src/reference/modules.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,20 @@ export const disabledStyles: Styles = Styles.fromProperties(
17081708
"styles.disabled",
17091709
);
17101710

1711+
/**
1712+
* Style module for the interactive cursor.
1713+
*
1714+
* By default, sets the cursor to "pointer".
1715+
*
1716+
* @public
1717+
*/
1718+
export const interactiveCursorStyles: Styles = Styles.fromProperties(
1719+
{
1720+
cursor: "pointer",
1721+
},
1722+
"styles.interactiveCursor",
1723+
);
1724+
17111725
/**
17121726
* @public
17131727
*/

0 commit comments

Comments
 (0)