@featherk/composables 0.10.9 → 0.11.0

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.
@@ -1,4 +1,4 @@
1
1
  export { useGridA11y } from "./useGridA11y";
2
2
  export { useGridActiveFilter } from "./useGridActiveFilter";
3
3
  export { useGridRowAction } from "./useGridRowAction";
4
- export type { UseGridRowActionOptions, UseGridRowActionReturn, RowActionContext, } from "./useGridRowAction";
4
+ export type { UseGridRowActionOptions, UseGridRowActionReturn, RowActionContext, RowActionCoordinates, } from "./useGridRowAction";
@@ -13,6 +13,14 @@
13
13
  */
14
14
  import type { Ref } from "vue";
15
15
  import type { GridRowClickEvent } from "../types/kendo";
16
+ export interface RowActionCoordinates {
17
+ clientX: number;
18
+ clientY: number;
19
+ pageX: number;
20
+ pageY: number;
21
+ screenX: number;
22
+ screenY: number;
23
+ }
16
24
  export interface RowActionContext<T = any> {
17
25
  /**
18
26
  * Data item associated with the activated row.
@@ -41,6 +49,12 @@ export interface RowActionContext<T = any> {
41
49
  shiftKey: boolean;
42
50
  metaKey: boolean;
43
51
  altKey: boolean;
52
+ /**
53
+ * Pointer coordinates of the activation. Derived from the native mouse event
54
+ * for clicks, or from the focused row's bounding box for keyboard activation.
55
+ * `undefined` when neither source is available.
56
+ */
57
+ coordinates?: RowActionCoordinates;
44
58
  }
45
59
  export interface UseGridRowActionOptions<T = any> {
46
60
  /**
@@ -1,6 +1,7 @@
1
1
  import { type ComponentPublicInstance, type Ref } from "vue";
2
2
  /** A template ref that may point to an element or a Vue/Kendo component. */
3
3
  export type PopupMenuElementRef = Ref<HTMLElement | ComponentPublicInstance | null>;
4
+ export type PopupMenuTriggerMode = "button" | "row";
4
5
  /** Why the popup was closed, including the focus policy for mouse paths. */
5
6
  export type PopupMenuCloseReason = "keyboard" | "mouse-selection" | "outside-click" | "trigger-click" | null;
6
7
  export type PopupMenuCloseTrigger = Exclude<PopupMenuCloseReason, null>;
@@ -40,11 +41,10 @@ export type UsePopupMenuOptions = {
40
41
  * Defaults to `".k-menu-item:not(.k-disabled)"` for Kendo Menu.
41
42
  */
42
43
  menuItemSelector?: string;
43
- /**
44
- * Keeps `aria-expanded` on the trigger in sync with `isOpen`.
45
- * Applies only to button-like triggers. Defaults to `true`.
46
- */
47
- manageAriaExpanded?: boolean;
44
+ /** Keeps menu-trigger ARIA attributes in sync with `isOpen`. Defaults to `true`. */
45
+ manageMenuTriggerAria?: boolean;
46
+ /** Allows a table row to own the menu trigger semantics without adding button behavior. */
47
+ triggerMode?: PopupMenuTriggerMode;
48
48
  };
49
49
  /** Functions returned by {@link usePopupMenu} for the action menu. */
50
50
  export type UsePopupMenuReturn = {
@@ -10,7 +10,7 @@ Composable that provides safe, accessible row click and keyboard activation hand
10
10
  - **Text Selection Protection**: Automatically suppresses row actions when the user is highlighting/selecting text inside a cell within the row.
11
11
  - **Primary Mouse Button**: Restricts click activation to primary (left) mouse clicks.
12
12
  - **Keyboard Accessibility**: Supports keyboard row activation (`Enter` / `Space`) when focus is on a data row.
13
- - **Action Decoupled**: Provides normalized row event context (`dataItem`, `rowIndex`, `field`, `triggerType`, modifier keys) while leaving action logic (dialog, route navigation, context menu) to the consumer.
13
+ - **Action Decoupled**: Provides normalized row event context (`dataItem`, `rowIndex`, `field`, `triggerType`, modifier keys, and optional coordinates) while leaving action logic (dialog, route navigation, context menu) to the consumer.
14
14
  - **Composable Combination**: Integrates seamlessly with `useGridA11y` for combined row navigation and row action handling.
15
15
 
16
16
  ## Prerequisites
@@ -125,40 +125,67 @@ onMounted(() => {
125
125
 
126
126
  `useGridRowAction(options: UseGridRowActionOptions<T>)` accepts the following configuration:
127
127
 
128
- | Option | Type | Default | Description |
129
- | :--- | :--- | :--- | :--- |
130
- | `onRowAction` | `(dataItem: T, context: RowActionContext<T>) => void` | **Required** | Callback executed when a valid row click or keyboard activation occurs. |
131
- | `dataItems` | `Ref<T[]> \| T[]` | `undefined` | Grid data array or ref used to resolve the `dataItem` on grid-level `@keydown` activation. |
132
- | `gridRef` | `Ref<any>` | `undefined` | Optional ref to Kendo Grid instance as an alternative `dataItem` lookup source. |
133
- | `ignoreSelectors` | `string[]` | `[]` | Additional CSS selectors inside row cells that should prevent triggering row actions. |
134
- | `shouldIgnoreTarget` | `(target: HTMLElement, event: Event) => boolean` | `undefined` | Custom predicate function for advanced target element filtering. |
135
- | `enableKeyboardAction` | `boolean` | `true` | Whether to enable `Enter`/`Space` key activation on focused rows. |
128
+ | Option | Type | Default | Description |
129
+ | :--------------------- | :---------------------------------------------------- | :----------- | :----------------------------------------------------------------------------------------- |
130
+ | `onRowAction` | `(dataItem: T, context: RowActionContext<T>) => void` | **Required** | Callback executed when a valid row click or keyboard activation occurs. |
131
+ | `dataItems` | `Ref<T[]> \| T[]` | `undefined` | Grid data array or ref used to resolve the `dataItem` on grid-level `@keydown` activation. |
132
+ | `gridRef` | `Ref<any>` | `undefined` | Optional ref to Kendo Grid instance as an alternative `dataItem` lookup source. |
133
+ | `ignoreSelectors` | `string[]` | `[]` | Additional CSS selectors inside row cells that should prevent triggering row actions. |
134
+ | `shouldIgnoreTarget` | `(target: HTMLElement, event: Event) => boolean` | `undefined` | Custom predicate function for advanced target element filtering. |
135
+ | `enableKeyboardAction` | `boolean` | `true` | Whether to enable `Enter`/`Space` key activation on focused rows. |
136
136
 
137
137
  ## Returns Reference
138
138
 
139
139
  `useGridRowAction` returns an object containing:
140
140
 
141
- | Property | Type | Description |
142
- | :--- | :--- | :--- |
143
- | `handleRowClick` | `(event: GridRowClickEvent) => void` | Primary click handler to bind to Kendo Grid's `@rowclick`. |
141
+ | Property | Type | Description |
142
+ | :----------------- | :----------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------- |
143
+ | `handleRowClick` | `(event: GridRowClickEvent) => void` | Primary click handler to bind to Kendo Grid's `@rowclick`. |
144
144
  | `handleRowKeyDown` | `(event: KeyboardEvent, explicitDataItem?: T) => void` | Primary keyboard handler to bind to Kendo Grid's `@keydown`. Accepts optional `explicitDataItem` if bound at slot/row level. |
145
- | `isIgnoredTarget` | `(target: HTMLElement, event?: Event) => boolean` | Utility function to test if a given DOM element matches default or custom ignore selectors. |
145
+ | `isIgnoredTarget` | `(target: HTMLElement, event?: Event) => boolean` | Utility function to test if a given DOM element matches default or custom ignore selectors. |
146
146
 
147
147
  ## Callback Context Reference
148
148
 
149
149
  The `onRowAction` callback receives `(dataItem, context)` where `context` contains:
150
150
 
151
- | Property | Type | Description |
152
- | :--- | :--- | :--- |
153
- | `dataItem` | `T` | The row's data item. |
154
- | `rowIndex` | `number \| undefined` | Row index in the grid data. |
155
- | `field` | `string \| undefined` | Column field name if clicked on a specific cell. |
156
- | `event` | `Event` | Original native browser DOM event. |
157
- | `triggerType` | `'click' \| 'keyboard'` | Interaction source that triggered the action (`click` or `keyboard`). |
158
- | `ctrlKey` | `boolean` | `true` if Ctrl key was held down during activation. |
159
- | `shiftKey` | `boolean` | `true` if Shift key was held down during activation. |
160
- | `metaKey` | `boolean` | `true` if Cmd / Meta key was held down during activation. |
161
- | `altKey` | `boolean` | `true` if Alt key was held down during activation. |
151
+ | Property | Type | Description |
152
+ | :------------ | :---------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- |
153
+ | `dataItem` | `T` | The row's data item. |
154
+ | `rowIndex` | `number \| undefined` | Row index in the grid data. |
155
+ | `field` | `string \| undefined` | Column field name if clicked on a specific cell. |
156
+ | `event` | `Event` | Original native browser DOM event. |
157
+ | `triggerType` | `'click' \| 'keyboard'` | Interaction source that triggered the action (`click` or `keyboard`). |
158
+ | `ctrlKey` | `boolean` | `true` if Ctrl key was held down during activation. |
159
+ | `shiftKey` | `boolean` | `true` if Shift key was held down during activation. |
160
+ | `metaKey` | `boolean` | `true` if Cmd / Meta key was held down during activation. |
161
+ | `altKey` | `boolean` | `true` if Alt key was held down during activation. |
162
+ | `coordinates` | `RowActionCoordinates \| undefined` | Activation coordinates when available. Mouse clicks use native pointer coordinates; keyboard activation uses the focused row's bounding box. |
163
+
164
+ ### Row Action Coordinates
165
+
166
+ `RowActionCoordinates` is exported from `@featherk/composables` and contains the following values:
167
+
168
+ | Property | Description |
169
+ | :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
170
+ | `clientX`, `clientY` | Coordinates relative to the browser viewport. |
171
+ | `pageX`, `pageY` | Coordinates relative to the full document, including scroll offset. |
172
+ | `screenX`, `screenY` | Coordinates relative to the physical screen for pointer activation. For keyboard activation, these are approximated from the row's viewport coordinates. |
173
+
174
+ The coordinates can be used to position a context menu, popover, tooltip, or other contextual UI near the activated row:
175
+
176
+ ```ts
177
+ onRowAction: (dataItem, context) => {
178
+ if (context.coordinates) {
179
+ openContextMenu({
180
+ dataItem,
181
+ left: context.coordinates.clientX,
182
+ top: context.coordinates.clientY,
183
+ });
184
+ }
185
+ },
186
+ ```
187
+
188
+ For mouse activation, the values come from the native mouse or pointer event. For keyboard activation, there is no actual pointer location, so the composable derives the values from the focused row's bounding box using its left edge and bottom edge. The `coordinates` property is therefore optional.
162
189
 
163
190
  ## Default Ignored Selectors
164
191
 
@@ -19,7 +19,7 @@ Composable for accessible Kendo UI for Vue `Popup` + `Menu` action menus. It man
19
19
  <button
20
20
  ref="triggerRef"
21
21
  type="button"
22
- aria-haspopup="true"
22
+ aria-haspopup="menu"
23
23
  @click="menu.handleActionButtonClick"
24
24
  @keydown="menu.handleActionButtonKeydown"
25
25
  >
@@ -141,7 +141,8 @@ const onSelect = (event: KendoMenuSelectEvent) => {
141
141
  - `focusTargetRef?: PopupMenuElementRef`: Optional element/component to focus after a keyboard-driven close.
142
142
  - `resolveFocusTarget?: () => HTMLElement | null`: Dynamic focus-target resolver. It takes precedence over `focusTargetRef` and is useful for virtualized grid rows.
143
143
  - `menuItemSelector?: string`: Selector for the first enabled item. Defaults to `.k-menu-item:not(.k-disabled)`.
144
- - `manageAriaExpanded?: boolean`: Keeps `aria-expanded` on a button-like trigger in sync with `isOpen`. Defaults to `true`; set to `false` to bind the attribute yourself.
144
+ - `manageMenuTriggerAria?: boolean`: Keeps `aria-haspopup="menu"` and `aria-expanded` in sync with `isOpen` on the resolved `triggerRef` element. Defaults to `true`; while enabled, the composable owns both attributes and removes them when the trigger is replaced or the component unmounts. Set to `false` to own both attributes yourself.
145
+ - `triggerMode?: "button" | "row"`: Selects the trigger semantics. Defaults to `"button"`; use `"row"` only when a `tr.k-table-row` owns the menu trigger. Row mode manages ARIA attributes but does not add `role`, `tabindex`, or keyboard behavior.
145
146
 
146
147
  `PopupMenuElementRef` accepts a normal `HTMLElement` ref or a Vue/Kendo component ref that exposes `$el`.
147
148
 
@@ -172,7 +173,9 @@ export type KendoMenuSelectEvent = {
172
173
  ## Behavior
173
174
 
174
175
  - Pointer click, `Enter`, and `Space` toggle the menu.
175
- - `aria-expanded` is written to the trigger whenever it is a `<button>`, has `role="button"`, or declares `aria-haspopup`.
176
+ - `aria-haspopup="menu"` and `aria-expanded` are written to every resolved `triggerRef` element, including native buttons and Vue/Kendo component refs resolved through `$el`.
177
+ - A `tr.k-table-row` is managed only with `triggerMode: "row"`; rows are never automatically made keyboard buttons.
178
+ - Trigger replacement and virtualization are handled by re-resolving the ref. Managed attributes are removed from the previous trigger and on unmount. Set `manageMenuTriggerAria` to `false` when the consumer owns the attributes.
176
179
  - Opening focuses the first enabled Kendo Menu item after Vue renders it.
177
180
  - Outside clicks close the menu, while the trigger is ignored to prevent a close/reopen race.
178
181
  - Menu selection records keyboard or mouse modality from the selection event type.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@featherk/composables",
3
- "version": "0.10.9",
3
+ "version": "0.11.0",
4
4
  "main": "dist/featherk-composables.umd.js",
5
5
  "module": "dist/featherk-composables.es.js",
6
6
  "types": "dist/index.d.ts",