Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/silver-crabs-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@adaptive-web/adaptive-ui-designer-core": patch
"@adaptive-web/adaptive-ui": patch
---

AUI: Added support for generating default cursor styles
9 changes: 9 additions & 0 deletions packages/adaptive-ui/docs/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export type ColorRecipeParams = {
export interface ComponentAnatomy<TConditions extends ComponentConditions, TParts extends ComponentParts> {
conditions: TConditions;
context?: string;
cursor?: CursorDefinition | false;
focus?: FocusDefinition<TParts>;
interactivity?: InteractivityDefinition;
name?: string;
Expand Down Expand Up @@ -246,6 +247,12 @@ export function createTokenSwatch(name: string, intendedFor?: StyleProperty | St
// @public
export const createTyped: typeof TypedCSSDesignToken.createTyped;

// @public
export interface CursorDefinition {
cursorType?: string;
part?: string;
}

// @public
export function deltaSwatch(palette: Palette, reference: Paint, delta: number, direction?: PaletteDirection): Color;

Expand Down Expand Up @@ -599,6 +606,8 @@ export interface SerializableAnatomy {
// (undocumented)
context: string;
// (undocumented)
cursor?: CursorDefinition | false;
// (undocumented)
focus?: FocusDefinition<any>;
// (undocumented)
interactivity?: InteractivityDefinition;
Expand Down
5 changes: 5 additions & 0 deletions packages/adaptive-ui/src/bin/aui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ function jsonToAUIStyleSheet(obj: SerializableAnatomy): AUIStyleSheet {
parts: obj.parts,
interactivity: obj.interactivity,
focus: obj.focus,
cursor: obj.cursor,
},
rules: obj.styleRules.map(style => {
const styles = style.styles?.map(name => {
Expand Down Expand Up @@ -396,6 +397,10 @@ function jsonToAUIStyleSheet(obj: SerializableAnatomy): AUIStyleSheet {
}
}

if (sheet.anatomy.cursor && typeof sheet.anatomy.cursor === "object") {
sheet.anatomy.cursor.part = resolvePart(obj, sheet.anatomy.cursor.part);
}

return sheet;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,35 @@ export class ElementStylesRenderer {
);
}

// Apply interactive cursor styles (skip if explicitly disabled)
if (anatomy.interactivity?.interactive !== undefined && anatomy.cursor !== false) {
// Determine which part gets the cursor (already resolved to selector by aui.ts)
let cursorPart: string | undefined;
let cursorType = "pointer";

if (anatomy.cursor && typeof anatomy.cursor === "object") {
// Explicit cursor definition (part already resolved to selector)
cursorPart = anatomy.cursor.part ?? anatomy.focus?.focusTarget.part;
cursorType = anatomy.cursor.cursorType ?? "pointer";
} else if (anatomy.focus) {
// Default: use focus target part (already resolved to selector)
cursorPart = anatomy.focus.focusTarget.part;
}

// Only apply if we determined a cursor target or want to apply to root
if (cursorPart !== undefined || anatomy.focus) {
globalStyleRules.push(
{
target: {
contextCondition: anatomy.interactivity.interactive,
part: cursorPart,
},
styles: Styles.fromProperties({ cursor: cursorType }),
},
);
}
}

// If this component can get focus, apply the focus indicator styles.
if (anatomy.focus) {
if (ElementStylesRenderer._focusResetStylesAdjusted && anatomy.focus?.resetTarget) {
Expand Down
27 changes: 27 additions & 0 deletions packages/adaptive-ui/src/core/modules/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ export interface ComponentAnatomy<TConditions extends ComponentConditions, TPart
* Description of the focus structure of the component.
*/
focus?: FocusDefinition<TParts>;

/**
* Description of cursor behavior for interactive elements.
* If not provided, defaults to using focus.focusTarget.part with cursor: pointer.
* Set to false to explicitly disable automatic cursor generation.
*/
cursor?: CursorDefinition | false;
}

/**
Expand Down Expand Up @@ -285,6 +292,25 @@ export const Focus = {
},
} as const;

/**
* Defines cursor behavior for interactive elements.
*
* @public
*/
export interface CursorDefinition {
/**
* The part that should receive the cursor style when interactive.
* If undefined, uses the same part as focus.focusTarget.part.
*/
part?: string;

/**
* The cursor type to apply (defaults to "pointer").
* Common values: "pointer", "text", "move", "grab", "default".
*/
cursorType?: string;
}

/**
* Parameters used to evaluate style modules for a component.
*
Expand Down Expand Up @@ -525,6 +551,7 @@ export interface SerializableAnatomy {
parts: Record<string, string>,
interactivity?: InteractivityDefinition,
focus?: FocusDefinition<any>,
cursor?: CursorDefinition | false,
styleRules: SerializableStyleRule[]
}

Expand Down
14 changes: 14 additions & 0 deletions packages/adaptive-ui/src/reference/modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1708,6 +1708,20 @@ export const disabledStyles: Styles = Styles.fromProperties(
"styles.disabled",
);

/**
* Style module for the interactive cursor.
*
* By default, sets the cursor to "pointer".
*
* @public
*/
export const interactiveCursorStyles: Styles = Styles.fromProperties(
{
cursor: "pointer",
},
"styles.interactiveCursor",
);

/**
* @public
*/
Expand Down
Loading