@enact/core
Advanced tools
Comparing version 3.3.0-alpha.10 to 3.3.0-alpha.11
@@ -5,2 +5,8 @@ # Change Log | ||
## [3.3.0-alpha.11] - 2020-06-08 | ||
### Added | ||
- `core/handle.forwardCustom` handler to simplify forwarding custom events from components | ||
## [3.3.0-alpha.10] - 2020-05-26 | ||
@@ -7,0 +13,0 @@ |
@@ -7,10 +7,6 @@ // Type definitions for core/handle | ||
/** | ||
* The signature for event handling functions supported by `handle` and related functions | ||
* The signature for event handlers | ||
*/ | ||
export interface HandlerFunction { | ||
( | ||
event: any, | ||
props: { [key: string]: any }, | ||
context: { [key: string]: any } | ||
): void; | ||
export interface EventHandler { | ||
(event: any): void; | ||
} | ||
@@ -28,6 +24,10 @@ /** | ||
/** | ||
* The signature for event handlers | ||
* The signature for event handling functions supported by `handle` and related functions | ||
*/ | ||
export interface EventHandler { | ||
(event: any): void; | ||
export interface HandlerFunction { | ||
( | ||
event: any, | ||
props: { [key: string]: any }, | ||
context: { [key: string]: any } | ||
): void; | ||
} | ||
@@ -579,2 +579,28 @@ /** | ||
/** | ||
* Creates a handler that will forward the event to a function at `name` on `props` . | ||
* | ||
* If `adapter` is not specified, a new event payload will be generated with a `type` member with | ||
the `name` of the custom event. If `adapter` is specified, the `type` member is added to the | ||
value returned by `adapter` . | ||
* | ||
* The `adapter` function receives the same arguments as any handler. The value returned from | ||
`adapter` is passed as the first argument to `handler` with the remaining arguments kept the | ||
same. This is often useful to generate a custom event payload before forwarding on to a callback. | ||
* | ||
* Example: | ||
* ``` | ||
import {forwardCustom} from '@enact/core/handle'; | ||
// calls the onChange callback with the event: {type: 'onChange'} | ||
const forwardChange = forwardCustom('onChange'); | ||
// calls the onChange callback with the event: {type: 'onChange', index} | ||
const forwardChangeWithIndex = forwardCustom('onChange', (ev, {index}) => ({index})); | ||
``` | ||
*/ | ||
export function forwardCustom( | ||
name: string, | ||
adapter?: EventAdapter | ||
): HandlerFunction; | ||
/** | ||
* Accepts a handler and returns the logical complement of the value returned from the handler. | ||
@@ -581,0 +607,0 @@ * |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.stopImmediate = exports.stop = exports.returnsTrue = exports.preventDefault = exports.oneOf = exports.not = exports.log = exports.handle = exports.forProp = exports.forKeyCode = exports.forKey = exports.forEventProp = exports.forwardWithPrevent = exports.forward = exports.callOnEvent = exports.call = exports.adaptEvent = exports["default"] = void 0; | ||
exports.stopImmediate = exports.stop = exports.returnsTrue = exports.preventDefault = exports.oneOf = exports.not = exports.log = exports.handle = exports.forProp = exports.forKeyCode = exports.forKey = exports.forEventProp = exports.forwardWithPrevent = exports.forwardCustom = exports.forward = exports.callOnEvent = exports.call = exports.adaptEvent = exports["default"] = void 0; | ||
@@ -17,80 +17,3 @@ var _cond = _interopRequireDefault(require("ramda/src/cond")); | ||
/** | ||
* `core/handle` provides a set of utilities to support handling events for `kind()`s and | ||
* `React.Component`s. The default export, `handle()`, generates an event handler function from a | ||
* set of input functions. The input functions either process or filter the event. If an input | ||
* function returns `true`, `handle()` will continue processing the event by calling the next input | ||
* function in the chain. If it returns `false` (or any falsy value like `null` or `undefined`), | ||
* the event handling chain stops at that input function. | ||
* | ||
* Example: | ||
* ``` | ||
* import {forKey, forward, handle, preventDefault} from '@enact/core/handle'; | ||
* | ||
* // logEnter will contain a function that accepts an event, a props object, and a context object | ||
* const logEnter = handle( | ||
* forward('onKeyDown'), // forwards the event to the function passed in the onKeyDown prop | ||
* forKey('enter'), // if the event.keyCode maps to the enter key, allows event processing to continue | ||
* preventDefault, // calls event.preventDefault() to prevent the `keypress` event | ||
* (ev, props) => { // custom event handler -- in this case, logging some text | ||
* // since it doesn't return `true`, no further input functions would be called after this one | ||
* console.log('The Enter key was pressed down'); | ||
* } | ||
* ).finally(() => { | ||
* console.log('This will log at the end no matter what happens within the handler above') | ||
* }); | ||
* ``` | ||
* | ||
* `handle()` can also be bound to a component instance which allows it to access the instance | ||
* `props` and `context`. This allows you to write consistent event handlers for components created | ||
* either with `kind()` or ES6 classes without worrying about from where the props are sourced. | ||
* | ||
* Handlers can either be bound directly using the native `bind()` method or using the `bindAs()` | ||
* utility method that is appended to the handler. | ||
* | ||
* Example: | ||
* ``` | ||
* import {forKey, forward, handle, preventDefault} from '@enact/core/handle'; | ||
* import React from 'react'; | ||
* | ||
* class MyComponent extends React.Component { | ||
* // bind handle() to the instance | ||
* constructor () { | ||
* super(); | ||
* | ||
* // logEnter will be bound to `this` and set as this.handleKeyDown | ||
* // | ||
* // Equivalent to the following with the advantage of set the function name to be displayed in | ||
* // development tool call stacks | ||
* // | ||
* // this.handleKeyDown = logEnter.bind(this) | ||
* logEnter.bindAs(this, 'handleKeyDown'); | ||
* } | ||
* | ||
* render () { | ||
* return ( | ||
* <div onKeyDown={this.handleKeyDown} /> | ||
* ); | ||
* } | ||
* } | ||
* ``` | ||
* | ||
* @module core/handle | ||
* @exports adaptEvent | ||
* @exports call | ||
* @exports callOnEvent | ||
* @exports forward | ||
* @exports forwardWithPrevent | ||
* @exports forEventProp | ||
* @exports forKey | ||
* @exports forKeyCode | ||
* @exports forProp | ||
* @exports handle | ||
* @exports log | ||
* @exports oneOf | ||
* @exports preventDefault | ||
* @exports returnsTrue | ||
* @exports stop | ||
* @exports stopImmediate | ||
*/ | ||
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } | ||
@@ -764,2 +687,50 @@ /** | ||
/** | ||
* Creates a handler that will forward the event to a function at `name` on `props`. | ||
* | ||
* If `adapter` is not specified, a new event payload will be generated with a `type` member with | ||
* the `name` of the custom event. If `adapter` is specified, the `type` member is added to the | ||
* value returned by `adapter`. | ||
* | ||
* The `adapter` function receives the same arguments as any handler. The value returned from | ||
* `adapter` is passed as the first argument to `handler` with the remaining arguments kept the | ||
* same. This is often useful to generate a custom event payload before forwarding on to a callback. | ||
* | ||
* Example: | ||
* ``` | ||
* import {forwardCustom} from '@enact/core/handle'; | ||
* | ||
* // calls the onChange callback with the event: {type: 'onChange'} | ||
* const forwardChange = forwardCustom('onChange'); | ||
* | ||
* // calls the onChange callback with the event: {type: 'onChange', index} | ||
* const forwardChangeWithIndex = forwardCustom('onChange', (ev, {index}) => ({index})); | ||
* ``` | ||
* | ||
* @method forwardCustom | ||
* @param {String} name Name of method on the `props` | ||
* @param {EventAdapter} [adapter] Function to adapt the event payload | ||
* | ||
* @returns {HandlerFunction} Returns an [event handler]{@link core/handle.EventHandler} | ||
* (suitable for passing to handle or used directly within | ||
* `handlers` in [kind]{@link core/kind}) that will forward the | ||
* custom event. | ||
* @memberof core/handle | ||
* @public | ||
*/ | ||
exports.adaptEvent = adaptEvent; | ||
var forwardCustom = handle.forwardCustom = function (name, adapter) { | ||
return handle(adaptEvent(function () { | ||
var ev = adapter ? adapter.apply(void 0, arguments) : null; // Handle either no adapter or a non-object return from the adapter | ||
if (!ev || _typeof(ev) !== 'object') { | ||
ev = {}; | ||
} | ||
ev.type = name; | ||
return ev; | ||
}, forward(name))).named('forwardCustom'); | ||
}; | ||
/** | ||
* Accepts a handler and returns the logical complement of the value returned from the handler. | ||
@@ -790,4 +761,5 @@ * | ||
exports.adaptEvent = adaptEvent; | ||
exports.forwardCustom = forwardCustom; | ||
var not = handle.not = function (handler) { | ||
@@ -794,0 +766,0 @@ return function () { |
@@ -417,2 +417,61 @@ "use strict"; | ||
}); | ||
describe('#forwardCustom', function () { | ||
test('should pass an object with `type` when no adapter is provided', function () { | ||
var handler = jest.fn(); | ||
(0, _handle.forwardCustom)('onCustomEvent')(null, { | ||
onCustomEvent: handler | ||
}); | ||
var expected = { | ||
type: 'onCustomEvent' | ||
}; | ||
var actual = handler.mock.calls[0][0]; | ||
expect(actual).toEqual(expected); | ||
}); | ||
test('should add `type` to object returned by adapter', function () { | ||
var handler = jest.fn(); | ||
var adapter = function adapter() { | ||
return { | ||
index: 0 | ||
}; | ||
}; | ||
(0, _handle.forwardCustom)('onCustomEvent', adapter)(null, { | ||
onCustomEvent: handler | ||
}); | ||
var expected = { | ||
type: 'onCustomEvent', | ||
index: 0 | ||
}; | ||
var actual = handler.mock.calls[0][0]; | ||
expect(actual).toEqual(expected); | ||
}); | ||
test('should create an event payload if the adapter returns nothing', function () { | ||
var handler = jest.fn(); | ||
var adapter = function adapter() { | ||
return null; | ||
}; | ||
(0, _handle.forwardCustom)('onCustomEvent', adapter)(null, { | ||
onCustomEvent: handler | ||
}); | ||
var expected = { | ||
type: 'onCustomEvent' | ||
}; | ||
var actual = handler.mock.calls[0][0]; | ||
expect(actual).toEqual(expected); | ||
}); | ||
test('should pass event, props, and context args to adapter', function () { | ||
var adapter = jest.fn(); | ||
var args = [1, // ev, | ||
2, // props, | ||
3 // context | ||
]; | ||
(0, _handle.forwardCustom)('onCustomEvent', adapter).apply(void 0, args); | ||
var expected = args; | ||
var actual = adapter.mock.calls[0]; | ||
expect(actual).toEqual(expected); | ||
}); | ||
}); | ||
}); |
{ | ||
"name": "@enact/core", | ||
"version": "3.3.0-alpha.10", | ||
"version": "3.3.0-alpha.11", | ||
"description": "Enact is an open source JavaScript framework containing everything you need to create a fast, scalable mobile or web application.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
218117
5556