afformative 0.6.0 → 0.6.3
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.
- package/README.md +3 -3
- package/dist/afformative.cjs.js +26 -57
- package/dist/afformative.esm.js +23 -58
- package/dist/afformative.umd.js +57 -59
- package/dist/afformative.umd.min.js +1 -1
- package/dist/types/makeFormatter.d.ts +34 -33
- package/dist/types/makeFormatter.d.ts.map +1 -1
- package/package.json +5 -2
- package/src/makeFormatter.test.ts +179 -73
- package/src/makeFormatter.ts +110 -79
package/README.md
CHANGED
|
@@ -81,13 +81,13 @@ Although formatters can render icons or custom translation components, we often
|
|
|
81
81
|
|
|
82
82
|
> Lexicographic sorting of items based on translations is a typical real world example, especially when you are using a custom React component for visualising the translation keys alongside the actual translations.
|
|
83
83
|
|
|
84
|
-
This is where usage suggestions
|
|
84
|
+
This is where usage suggestions come into play. Suggestions can be used to tell formatters that a value needs to be rendered with some special care. For example, pass `"primitive"` to tell a formatter that it should return a primitive value, such as a string.
|
|
85
85
|
|
|
86
86
|
```js
|
|
87
87
|
import { makeFormatter } from "afformative"
|
|
88
88
|
|
|
89
|
-
const booleanFormatter = makeFormatter((value,
|
|
90
|
-
if (
|
|
89
|
+
const booleanFormatter = makeFormatter((value, suggestions) => {
|
|
90
|
+
if (suggestions.includes("primitive")) {
|
|
91
91
|
return value ? "True" : "False"
|
|
92
92
|
}
|
|
93
93
|
|
package/dist/afformative.cjs.js
CHANGED
|
@@ -2,33 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
if (source == null) return {};
|
|
7
|
-
var target = {};
|
|
8
|
-
var sourceKeys = Object.keys(source);
|
|
9
|
-
var key, i;
|
|
5
|
+
var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
key = sourceKeys[i];
|
|
13
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
14
|
-
target[key] = source[key];
|
|
15
|
-
}
|
|
7
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
16
8
|
|
|
17
|
-
|
|
18
|
-
}
|
|
9
|
+
var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
|
|
19
10
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// value: TInput,
|
|
28
|
-
// usageSuggestions: TSuggestion[],
|
|
29
|
-
// dataContext: DataContext,
|
|
30
|
-
// ): PrimitiveSuggestion extends TSuggestion ? TPrimitiveOutput : TOutput
|
|
31
|
-
// }
|
|
11
|
+
var ensureFormatSuggestionIntegrity = function ensureFormatSuggestionIntegrity(suggestions) {
|
|
12
|
+
return suggestions.includes("primitive") || !suggestions.includes("comparable") ? suggestions : ["primitive"].concat(_toConsumableArray__default["default"](suggestions));
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
var ensureFormatAsPrimitiveSuggestionIntegrity = function ensureFormatAsPrimitiveSuggestionIntegrity(suggestions) {
|
|
16
|
+
return suggestions.includes("primitive") ? suggestions : ["primitive"].concat(_toConsumableArray__default["default"](suggestions));
|
|
17
|
+
};
|
|
32
18
|
|
|
33
19
|
/**
|
|
34
20
|
* Creates a new formatter.
|
|
@@ -37,50 +23,33 @@ function _objectWithoutPropertiesLoose(source, excluded) {
|
|
|
37
23
|
* @param formatterOptions Additional options for the formatter.
|
|
38
24
|
*/
|
|
39
25
|
var makeFormatter = function makeFormatter(format, formatterOptions) {
|
|
40
|
-
var formatter = function formatter(
|
|
41
|
-
var _format;
|
|
42
|
-
|
|
43
|
-
var children = _ref.children,
|
|
44
|
-
_ref$suggestions = _ref.suggestions,
|
|
45
|
-
suggestions = _ref$suggestions === void 0 ? [] : _ref$suggestions,
|
|
46
|
-
dataContext = _objectWithoutPropertiesLoose(_ref, ["children", "suggestions"]);
|
|
26
|
+
var formatter = function formatter(props) {
|
|
27
|
+
var _format, _props$suggestions;
|
|
47
28
|
|
|
48
|
-
return (_format = format(children, suggestions,
|
|
29
|
+
return (_format = format(props.children, (_props$suggestions = props.suggestions) !== null && _props$suggestions !== void 0 ? _props$suggestions : [], props)) !== null && _format !== void 0 ? _format : null;
|
|
49
30
|
};
|
|
50
31
|
|
|
51
|
-
formatter.displayName = formatterOptions
|
|
32
|
+
formatter.displayName = formatterOptions === null || formatterOptions === void 0 ? void 0 : formatterOptions.displayName;
|
|
52
33
|
|
|
53
|
-
formatter.format = function (value
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (dataContext === void 0) {
|
|
59
|
-
dataContext = {};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return format(value, usageSuggestions, dataContext);
|
|
34
|
+
formatter.format = function (value) {
|
|
35
|
+
var suggestions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
36
|
+
var dataContext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
37
|
+
return format(value, ensureFormatSuggestionIntegrity(suggestions), dataContext);
|
|
63
38
|
};
|
|
64
39
|
|
|
65
|
-
formatter.formatAsPrimitive = function (value
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (dataContext === void 0) {
|
|
71
|
-
dataContext = {};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return format(value, ["primitive"].concat(usageSuggestions), dataContext);
|
|
40
|
+
formatter.formatAsPrimitive = function (value) {
|
|
41
|
+
var suggestions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
42
|
+
var dataContext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
43
|
+
return format(value, ensureFormatAsPrimitiveSuggestionIntegrity(suggestions), dataContext);
|
|
75
44
|
};
|
|
76
45
|
|
|
77
46
|
formatter.wrap = function (nextFormat, nextFormatterOptions) {
|
|
78
|
-
var nextFormatter = makeFormatter(function (value,
|
|
79
|
-
var delegate = function delegate(delegatedValue,
|
|
80
|
-
return formatter.format(delegatedValue,
|
|
47
|
+
var nextFormatter = makeFormatter(function (value, suggestions, dataContext) {
|
|
48
|
+
var delegate = function delegate(delegatedValue, delegatedSuggestions, delegatedDataContext) {
|
|
49
|
+
return formatter.format(delegatedValue, delegatedSuggestions !== null && delegatedSuggestions !== void 0 ? delegatedSuggestions : suggestions, delegatedDataContext !== null && delegatedDataContext !== void 0 ? delegatedDataContext : dataContext);
|
|
81
50
|
};
|
|
82
51
|
|
|
83
|
-
return nextFormat(delegate, value,
|
|
52
|
+
return nextFormat(delegate, value, suggestions, dataContext);
|
|
84
53
|
}, nextFormatterOptions !== null && nextFormatterOptions !== void 0 ? nextFormatterOptions : formatterOptions);
|
|
85
54
|
nextFormatter.innerFormatter = formatter;
|
|
86
55
|
return nextFormatter;
|
package/dist/afformative.esm.js
CHANGED
|
@@ -1,30 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
if (source == null) return {};
|
|
3
|
-
var target = {};
|
|
4
|
-
var sourceKeys = Object.keys(source);
|
|
5
|
-
var key, i;
|
|
1
|
+
import _toConsumableArray from '@babel/runtime/helpers/esm/toConsumableArray';
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
target[key] = source[key];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return target;
|
|
14
|
-
}
|
|
3
|
+
var ensureFormatSuggestionIntegrity = function ensureFormatSuggestionIntegrity(suggestions) {
|
|
4
|
+
return suggestions.includes("primitive") || !suggestions.includes("comparable") ? suggestions : ["primitive"].concat(_toConsumableArray(suggestions));
|
|
5
|
+
};
|
|
15
6
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// which is, of course, nonsense. Same applies to `FormatChainDefinition`.
|
|
20
|
-
//
|
|
21
|
-
// interface FormatDefinition<TInput, TOutput, TPrimitiveOutput> {
|
|
22
|
-
// <TSuggestion extends Suggestion>(
|
|
23
|
-
// value: TInput,
|
|
24
|
-
// usageSuggestions: TSuggestion[],
|
|
25
|
-
// dataContext: DataContext,
|
|
26
|
-
// ): PrimitiveSuggestion extends TSuggestion ? TPrimitiveOutput : TOutput
|
|
27
|
-
// }
|
|
7
|
+
var ensureFormatAsPrimitiveSuggestionIntegrity = function ensureFormatAsPrimitiveSuggestionIntegrity(suggestions) {
|
|
8
|
+
return suggestions.includes("primitive") ? suggestions : ["primitive"].concat(_toConsumableArray(suggestions));
|
|
9
|
+
};
|
|
28
10
|
|
|
29
11
|
/**
|
|
30
12
|
* Creates a new formatter.
|
|
@@ -33,50 +15,33 @@ function _objectWithoutPropertiesLoose(source, excluded) {
|
|
|
33
15
|
* @param formatterOptions Additional options for the formatter.
|
|
34
16
|
*/
|
|
35
17
|
var makeFormatter = function makeFormatter(format, formatterOptions) {
|
|
36
|
-
var formatter = function formatter(
|
|
37
|
-
var _format;
|
|
38
|
-
|
|
39
|
-
var children = _ref.children,
|
|
40
|
-
_ref$suggestions = _ref.suggestions,
|
|
41
|
-
suggestions = _ref$suggestions === void 0 ? [] : _ref$suggestions,
|
|
42
|
-
dataContext = _objectWithoutPropertiesLoose(_ref, ["children", "suggestions"]);
|
|
18
|
+
var formatter = function formatter(props) {
|
|
19
|
+
var _format, _props$suggestions;
|
|
43
20
|
|
|
44
|
-
return (_format = format(children, suggestions,
|
|
21
|
+
return (_format = format(props.children, (_props$suggestions = props.suggestions) !== null && _props$suggestions !== void 0 ? _props$suggestions : [], props)) !== null && _format !== void 0 ? _format : null;
|
|
45
22
|
};
|
|
46
23
|
|
|
47
|
-
formatter.displayName = formatterOptions
|
|
24
|
+
formatter.displayName = formatterOptions === null || formatterOptions === void 0 ? void 0 : formatterOptions.displayName;
|
|
48
25
|
|
|
49
|
-
formatter.format = function (value
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (dataContext === void 0) {
|
|
55
|
-
dataContext = {};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return format(value, usageSuggestions, dataContext);
|
|
26
|
+
formatter.format = function (value) {
|
|
27
|
+
var suggestions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
28
|
+
var dataContext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
29
|
+
return format(value, ensureFormatSuggestionIntegrity(suggestions), dataContext);
|
|
59
30
|
};
|
|
60
31
|
|
|
61
|
-
formatter.formatAsPrimitive = function (value
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (dataContext === void 0) {
|
|
67
|
-
dataContext = {};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return format(value, ["primitive"].concat(usageSuggestions), dataContext);
|
|
32
|
+
formatter.formatAsPrimitive = function (value) {
|
|
33
|
+
var suggestions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
34
|
+
var dataContext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
35
|
+
return format(value, ensureFormatAsPrimitiveSuggestionIntegrity(suggestions), dataContext);
|
|
71
36
|
};
|
|
72
37
|
|
|
73
38
|
formatter.wrap = function (nextFormat, nextFormatterOptions) {
|
|
74
|
-
var nextFormatter = makeFormatter(function (value,
|
|
75
|
-
var delegate = function delegate(delegatedValue,
|
|
76
|
-
return formatter.format(delegatedValue,
|
|
39
|
+
var nextFormatter = makeFormatter(function (value, suggestions, dataContext) {
|
|
40
|
+
var delegate = function delegate(delegatedValue, delegatedSuggestions, delegatedDataContext) {
|
|
41
|
+
return formatter.format(delegatedValue, delegatedSuggestions !== null && delegatedSuggestions !== void 0 ? delegatedSuggestions : suggestions, delegatedDataContext !== null && delegatedDataContext !== void 0 ? delegatedDataContext : dataContext);
|
|
77
42
|
};
|
|
78
43
|
|
|
79
|
-
return nextFormat(delegate, value,
|
|
44
|
+
return nextFormat(delegate, value, suggestions, dataContext);
|
|
80
45
|
}, nextFormatterOptions !== null && nextFormatterOptions !== void 0 ? nextFormatterOptions : formatterOptions);
|
|
81
46
|
nextFormatter.innerFormatter = formatter;
|
|
82
47
|
return nextFormatter;
|
package/dist/afformative.umd.js
CHANGED
|
@@ -2,35 +2,50 @@
|
|
|
2
2
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
3
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Afformative = {}));
|
|
5
|
-
}(this, (function (exports) { 'use strict';
|
|
6
|
-
|
|
7
|
-
function
|
|
8
|
-
if (
|
|
9
|
-
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
for (i = 0; i < sourceKeys.length; i++) {
|
|
14
|
-
key = sourceKeys[i];
|
|
15
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
16
|
-
target[key] = source[key];
|
|
5
|
+
})(this, (function (exports) { 'use strict';
|
|
6
|
+
|
|
7
|
+
function _arrayLikeToArray(arr, len) {
|
|
8
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
9
|
+
|
|
10
|
+
for (var i = 0, arr2 = new Array(len); i < len; i++) {
|
|
11
|
+
arr2[i] = arr[i];
|
|
17
12
|
}
|
|
18
13
|
|
|
19
|
-
return
|
|
14
|
+
return arr2;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function _arrayWithoutHoles(arr) {
|
|
18
|
+
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function _iterableToArray(iter) {
|
|
22
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function _unsupportedIterableToArray(o, minLen) {
|
|
26
|
+
if (!o) return;
|
|
27
|
+
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
28
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
29
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
30
|
+
if (n === "Map" || n === "Set") return Array.from(o);
|
|
31
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function _nonIterableSpread() {
|
|
35
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
20
36
|
}
|
|
21
37
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// }
|
|
38
|
+
function _toConsumableArray(arr) {
|
|
39
|
+
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var ensureFormatSuggestionIntegrity = function ensureFormatSuggestionIntegrity(suggestions) {
|
|
43
|
+
return suggestions.includes("primitive") || !suggestions.includes("comparable") ? suggestions : ["primitive"].concat(_toConsumableArray(suggestions));
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
var ensureFormatAsPrimitiveSuggestionIntegrity = function ensureFormatAsPrimitiveSuggestionIntegrity(suggestions) {
|
|
47
|
+
return suggestions.includes("primitive") ? suggestions : ["primitive"].concat(_toConsumableArray(suggestions));
|
|
48
|
+
};
|
|
34
49
|
|
|
35
50
|
/**
|
|
36
51
|
* Creates a new formatter.
|
|
@@ -39,50 +54,33 @@ function _objectWithoutPropertiesLoose(source, excluded) {
|
|
|
39
54
|
* @param formatterOptions Additional options for the formatter.
|
|
40
55
|
*/
|
|
41
56
|
var makeFormatter = function makeFormatter(format, formatterOptions) {
|
|
42
|
-
var formatter = function formatter(
|
|
43
|
-
var _format;
|
|
57
|
+
var formatter = function formatter(props) {
|
|
58
|
+
var _format, _props$suggestions;
|
|
44
59
|
|
|
45
|
-
|
|
46
|
-
_ref$suggestions = _ref.suggestions,
|
|
47
|
-
suggestions = _ref$suggestions === void 0 ? [] : _ref$suggestions,
|
|
48
|
-
dataContext = _objectWithoutPropertiesLoose(_ref, ["children", "suggestions"]);
|
|
49
|
-
|
|
50
|
-
return (_format = format(children, suggestions, dataContext)) !== null && _format !== void 0 ? _format : null;
|
|
60
|
+
return (_format = format(props.children, (_props$suggestions = props.suggestions) !== null && _props$suggestions !== void 0 ? _props$suggestions : [], props)) !== null && _format !== void 0 ? _format : null;
|
|
51
61
|
};
|
|
52
62
|
|
|
53
|
-
formatter.displayName = formatterOptions
|
|
54
|
-
|
|
55
|
-
formatter.format = function (value, usageSuggestions, dataContext) {
|
|
56
|
-
if (usageSuggestions === void 0) {
|
|
57
|
-
usageSuggestions = [];
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (dataContext === void 0) {
|
|
61
|
-
dataContext = {};
|
|
62
|
-
}
|
|
63
|
+
formatter.displayName = formatterOptions === null || formatterOptions === void 0 ? void 0 : formatterOptions.displayName;
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
formatter.format = function (value) {
|
|
66
|
+
var suggestions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
67
|
+
var dataContext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
68
|
+
return format(value, ensureFormatSuggestionIntegrity(suggestions), dataContext);
|
|
65
69
|
};
|
|
66
70
|
|
|
67
|
-
formatter.formatAsPrimitive = function (value
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (dataContext === void 0) {
|
|
73
|
-
dataContext = {};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return format(value, ["primitive"].concat(usageSuggestions), dataContext);
|
|
71
|
+
formatter.formatAsPrimitive = function (value) {
|
|
72
|
+
var suggestions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
73
|
+
var dataContext = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
74
|
+
return format(value, ensureFormatAsPrimitiveSuggestionIntegrity(suggestions), dataContext);
|
|
77
75
|
};
|
|
78
76
|
|
|
79
77
|
formatter.wrap = function (nextFormat, nextFormatterOptions) {
|
|
80
|
-
var nextFormatter = makeFormatter(function (value,
|
|
81
|
-
var delegate = function delegate(delegatedValue,
|
|
82
|
-
return formatter.format(delegatedValue,
|
|
78
|
+
var nextFormatter = makeFormatter(function (value, suggestions, dataContext) {
|
|
79
|
+
var delegate = function delegate(delegatedValue, delegatedSuggestions, delegatedDataContext) {
|
|
80
|
+
return formatter.format(delegatedValue, delegatedSuggestions !== null && delegatedSuggestions !== void 0 ? delegatedSuggestions : suggestions, delegatedDataContext !== null && delegatedDataContext !== void 0 ? delegatedDataContext : dataContext);
|
|
83
81
|
};
|
|
84
82
|
|
|
85
|
-
return nextFormat(delegate, value,
|
|
83
|
+
return nextFormat(delegate, value, suggestions, dataContext);
|
|
86
84
|
}, nextFormatterOptions !== null && nextFormatterOptions !== void 0 ? nextFormatterOptions : formatterOptions);
|
|
87
85
|
nextFormatter.innerFormatter = formatter;
|
|
88
86
|
return nextFormatter;
|
|
@@ -95,4 +93,4 @@ exports.makeFormatter = makeFormatter;
|
|
|
95
93
|
|
|
96
94
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
97
95
|
|
|
98
|
-
}))
|
|
96
|
+
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(n
|
|
1
|
+
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).Afformative={})}(this,(function(t){"use strict";function n(t,n){(null==n||n>t.length)&&(n=t.length);for(var r=0,e=Array(n);n>r;r++)e[r]=t[r];return e}function r(t){return function(t){if(Array.isArray(t))return n(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,r){if(t){if("string"==typeof t)return n(t,r);var e=Object.prototype.toString.call(t).slice(8,-1);return"Object"===e&&t.constructor&&(e=t.constructor.name),"Map"===e||"Set"===e?Array.from(t):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?n(t,r):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}var e=function(t){return t.includes("primitive")||!t.includes("comparable")?t:["primitive"].concat(r(t))},i=function(t){return t.includes("primitive")?t:["primitive"].concat(r(t))};t.makeFormatter=function t(n,r){var o=function(t){var r,e;return null!==(r=n(t.children,null!==(e=t.suggestions)&&void 0!==e?e:[],t))&&void 0!==r?r:null};return o.displayName=null==r?void 0:r.displayName,o.format=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n(t,e(r),i)},o.formatAsPrimitive=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n(t,i(r),e)},o.wrap=function(n,e){var i=t((function(t,r,e){return n((function(t,n,i){return o.format(t,null!=n?n:r,null!=i?i:e)}),t,r,e)}),null!=e?e:r);return i.innerFormatter=o,i},o},Object.defineProperty(t,"__esModule",{value:!0})}));
|
|
@@ -1,89 +1,90 @@
|
|
|
1
|
-
declare type PrimitiveSuggestion = "primitive";
|
|
2
|
-
declare type
|
|
3
|
-
|
|
1
|
+
declare type PrimitiveSuggestion = "primitive" | "comparable";
|
|
2
|
+
declare type Suggestion = PrimitiveSuggestion | "abbreviated" | "as-icon"
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Since v0.6.3. Use `"as-icon"` or `"with-icon"` instead.
|
|
5
|
+
*/
|
|
6
|
+
| "icon" | "verbose" | "with-icon";
|
|
7
|
+
declare type DataContext = Record<string, any>;
|
|
4
8
|
interface FormatterOptions {
|
|
5
9
|
/** Formatter name, useful for debugging or advanced pattern matching. */
|
|
6
10
|
displayName?: string;
|
|
7
11
|
}
|
|
8
|
-
|
|
9
|
-
interface FormatDefinition<TInput, TOutput, TPrimitiveOutput> {
|
|
12
|
+
interface FormatDefinition<TInput, TOutput, TPrimitiveOutput, TDataContext extends DataContext> {
|
|
10
13
|
(
|
|
11
14
|
/** Value to format. */
|
|
12
15
|
value: TInput,
|
|
13
16
|
/** Suggestions passed by the consumer of a formatter. */
|
|
14
|
-
|
|
17
|
+
suggestions: Suggestion[],
|
|
15
18
|
/** Additional data context to be used by the formatter. */
|
|
16
|
-
dataContext:
|
|
19
|
+
dataContext: Partial<TDataContext>): TOutput | TPrimitiveOutput;
|
|
17
20
|
}
|
|
18
|
-
interface FormatMethod<TInput, TOutput, TPrimitiveOutput> {
|
|
19
|
-
|
|
21
|
+
interface FormatMethod<TInput, TOutput, TPrimitiveOutput, TDataContext extends DataContext> {
|
|
22
|
+
(
|
|
20
23
|
/** Value to format. */
|
|
21
24
|
value: TInput,
|
|
22
25
|
/** Suggestions the formatter should take note of. */
|
|
23
|
-
|
|
26
|
+
suggestions?: Suggestion[],
|
|
24
27
|
/** Additional data context the formatter might find useful. */
|
|
25
|
-
dataContext?:
|
|
28
|
+
dataContext?: Partial<TDataContext>): TOutput | TPrimitiveOutput;
|
|
26
29
|
}
|
|
27
|
-
interface FormatAsPrimitiveMethod<TInput, TPrimitiveOutput> {
|
|
30
|
+
interface FormatAsPrimitiveMethod<TInput, TPrimitiveOutput, TDataContext extends DataContext> {
|
|
28
31
|
(
|
|
29
32
|
/** Value to format. */
|
|
30
33
|
value: TInput,
|
|
31
34
|
/** Suggestions the formatter should take note of in addition to `primitive`. */
|
|
32
|
-
|
|
35
|
+
suggestions?: Suggestion[],
|
|
33
36
|
/** Additional data context the formatter might find useful. */
|
|
34
|
-
dataContext?:
|
|
37
|
+
dataContext?: Partial<TDataContext>): TPrimitiveOutput;
|
|
35
38
|
}
|
|
36
|
-
interface FormatChainDefinition<TInnerInput, TInnerOutput, TInnerPrimitiveInput, TOuterInput, TOuterOutput, TOuterPrimitiveOutput> {
|
|
39
|
+
interface FormatChainDefinition<TInnerInput, TInnerOutput, TInnerPrimitiveInput, TInnerDataContext extends DataContext, TOuterInput, TOuterOutput, TOuterPrimitiveOutput, TOuterDataContext extends DataContext> {
|
|
37
40
|
(
|
|
38
41
|
/**
|
|
39
42
|
* The `formatter.format` method which can be used to delegate the formatting
|
|
40
43
|
* to the wrapped formatter. Delegation is simplified so if no suggestions or contextual
|
|
41
44
|
* props are passed, the original ones are used instead.
|
|
42
45
|
*/
|
|
43
|
-
delegate: FormatMethod<TInnerInput, TInnerOutput, TInnerPrimitiveInput>,
|
|
46
|
+
delegate: FormatMethod<TInnerInput, TInnerOutput, TInnerPrimitiveInput, TInnerDataContext>,
|
|
44
47
|
/** Value to format. */
|
|
45
48
|
value: TOuterInput,
|
|
46
49
|
/** Suggestions the formatter should take note of. */
|
|
47
|
-
|
|
50
|
+
suggestions: Suggestion[],
|
|
48
51
|
/** Additional data context the formatter might find useful. */
|
|
49
|
-
dataContext:
|
|
52
|
+
dataContext: Partial<TOuterDataContext>): TOuterOutput | TOuterPrimitiveOutput;
|
|
50
53
|
}
|
|
51
|
-
|
|
54
|
+
declare type FormatterProps<TInput, TDataContext extends DataContext> = {
|
|
52
55
|
/** Value to format. */
|
|
53
56
|
children: TInput;
|
|
54
57
|
/** Suggestions the formatter should take note of. */
|
|
55
58
|
suggestions?: Suggestion[];
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
export interface Formatter<TInput, TOutput, TPrimitiveOutput = TOutput> {
|
|
59
|
+
} & Partial<TDataContext>;
|
|
60
|
+
export interface Formatter<TInput, TOutput, TPrimitiveOutput = TOutput, TDataContext extends DataContext = DataContext> {
|
|
60
61
|
/** Formatter name, useful for debugging or advanced pattern matching. */
|
|
61
62
|
displayName?: string;
|
|
62
63
|
/** Formats a value. */
|
|
63
|
-
format: FormatMethod<TInput, TOutput, TPrimitiveOutput>;
|
|
64
|
+
format: FormatMethod<TInput, TOutput, TPrimitiveOutput, TDataContext>;
|
|
64
65
|
/** Formats a value with the `primitive` suggestion. */
|
|
65
|
-
formatAsPrimitive: FormatAsPrimitiveMethod<TInput, TPrimitiveOutput>;
|
|
66
|
-
/** The callee of the
|
|
67
|
-
innerFormatter?: Formatter<any, any, any>;
|
|
66
|
+
formatAsPrimitive: FormatAsPrimitiveMethod<TInput, TPrimitiveOutput, TDataContext>;
|
|
67
|
+
/** The callee of the `wrap` method used to produce this formatter. */
|
|
68
|
+
innerFormatter?: Formatter<any, any, any, any>;
|
|
68
69
|
/**
|
|
69
70
|
* Creates a new formatter from an existing one. Allows overriding of formatter behaviour
|
|
70
71
|
* for certain values.
|
|
71
72
|
*/
|
|
72
|
-
wrap: <TNextInput = TInput, TNextOutput = TOutput, TNextPrimitiveOutput = TPrimitiveOutput>(
|
|
73
|
+
wrap: <TNextInput = TInput, TNextOutput = TOutput, TNextPrimitiveOutput = TPrimitiveOutput, TNextDataContext extends TDataContext = TDataContext>(
|
|
73
74
|
/**
|
|
74
75
|
* Function used to format the value. Has the same signature as the one passed
|
|
75
76
|
* to `makeFormatter`, except a `delegate` function is passed in the first position.
|
|
76
77
|
* This function can be used to delegate formatting to the original (inner) formatter.
|
|
77
78
|
*/
|
|
78
|
-
nextFormat: FormatChainDefinition<TInput, TOutput, TPrimitiveOutput, TNextInput, TNextOutput, TNextPrimitiveOutput>,
|
|
79
|
+
nextFormat: FormatChainDefinition<TInput, TOutput, TPrimitiveOutput, TDataContext, TNextInput, TNextOutput, TNextPrimitiveOutput, TNextDataContext>,
|
|
79
80
|
/** New formatter options, replacing the original ones. */
|
|
80
|
-
nextFormatterOptions?: FormatterOptions) => Formatter<TNextInput, TNextOutput, TNextPrimitiveOutput>;
|
|
81
|
+
nextFormatterOptions?: FormatterOptions) => Formatter<TNextInput, TNextOutput, TNextPrimitiveOutput, TNextDataContext>;
|
|
81
82
|
/**
|
|
82
83
|
* Backwards-compatible way to use the formatter as a React component.
|
|
83
84
|
*
|
|
84
|
-
* @deprecated Since v0.6.0. Prefer using the `
|
|
85
|
+
* @deprecated Since v0.6.0. Prefer using the `format` method instead.
|
|
85
86
|
*/
|
|
86
|
-
(props: FormatterProps<TInput>): TOutput | TPrimitiveOutput | null;
|
|
87
|
+
(props: FormatterProps<TInput, TDataContext>): TOutput | TPrimitiveOutput | null;
|
|
87
88
|
}
|
|
88
89
|
/**
|
|
89
90
|
* Creates a new formatter.
|
|
@@ -91,6 +92,6 @@ export interface Formatter<TInput, TOutput, TPrimitiveOutput = TOutput> {
|
|
|
91
92
|
* @param format Function used to format the value.
|
|
92
93
|
* @param formatterOptions Additional options for the formatter.
|
|
93
94
|
*/
|
|
94
|
-
export declare const makeFormatter: <TInput, TOutput, TPrimitiveOutput = TOutput>(format: FormatDefinition<TInput, TOutput, TPrimitiveOutput>, formatterOptions?: FormatterOptions | undefined) => Formatter<TInput, TOutput, TPrimitiveOutput>;
|
|
95
|
+
export declare const makeFormatter: <TInput, TOutput, TPrimitiveOutput = TOutput, TDataContext extends DataContext = DataContext>(format: FormatDefinition<TInput, TOutput, TPrimitiveOutput, TDataContext>, formatterOptions?: FormatterOptions | undefined) => Formatter<TInput, TOutput, TPrimitiveOutput, TDataContext>;
|
|
95
96
|
export {};
|
|
96
97
|
//# sourceMappingURL=makeFormatter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeFormatter.d.ts","sourceRoot":"","sources":["../../src/makeFormatter.ts"],"names":[],"mappings":"AAAA,aAAK,mBAAmB,GAAG,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"makeFormatter.d.ts","sourceRoot":"","sources":["../../src/makeFormatter.ts"],"names":[],"mappings":"AAAA,aAAK,mBAAmB,GAAG,WAAW,GAAG,YAAY,CAAA;AAErD,aAAK,UAAU,GACX,mBAAmB,GACnB,aAAa,GACb,SAAS;AACX;;GAEG;GACD,MAAM,GACN,SAAS,GACT,WAAW,CAAA;AAUf,aAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAEtC,UAAU,gBAAgB;IACxB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,UAAU,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,YAAY,SAAS,WAAW;IAC5F;IACE,uBAAuB;IACvB,KAAK,EAAE,MAAM;IACb,yDAAyD;IACzD,WAAW,EAAE,UAAU,EAAE;IACzB,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC,GACjC,OAAO,GAAG,gBAAgB,CAAA;CAC9B;AAED,UAAU,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,YAAY,SAAS,WAAW;IACxF;IACE,uBAAuB;IACvB,KAAK,EAAE,MAAM;IACb,qDAAqD;IACrD,WAAW,CAAC,EAAE,UAAU,EAAE;IAC1B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAClC,OAAO,GAAG,gBAAgB,CAAA;CAC9B;AAED,UAAU,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,EAAE,YAAY,SAAS,WAAW;IAC1F;IACE,uBAAuB;IACvB,KAAK,EAAE,MAAM;IACb,gFAAgF;IAChF,WAAW,CAAC,EAAE,UAAU,EAAE;IAC1B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAClC,gBAAgB,CAAA;CACpB;AAED,UAAU,qBAAqB,CAC7B,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,SAAS,WAAW,EACrC,WAAW,EACX,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,SAAS,WAAW;IAErC;IACE;;;;OAIG;IACH,QAAQ,EAAE,YAAY,CAAC,WAAW,EAAE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,CAAC;IAC1F,uBAAuB;IACvB,KAAK,EAAE,WAAW;IAClB,qDAAqD;IACrD,WAAW,EAAE,UAAU,EAAE;IACzB,+DAA+D;IAC/D,WAAW,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACtC,YAAY,GAAG,qBAAqB,CAAA;CACxC;AAED,aAAK,cAAc,CAAC,MAAM,EAAE,YAAY,SAAS,WAAW,IAAI;IAC9D,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,qDAAqD;IACrD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAA;CAC3B,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;AAEzB,MAAM,WAAW,SAAS,CACxB,MAAM,EACN,OAAO,EACP,gBAAgB,GAAG,OAAO,EAC1B,YAAY,SAAS,WAAW,GAAG,WAAW;IAE9C,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uBAAuB;IACvB,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,YAAY,CAAC,CAAA;IACrE,uDAAuD;IACvD,iBAAiB,EAAE,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,EAAE,YAAY,CAAC,CAAA;IAClF,sEAAsE;IACtE,cAAc,CAAC,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IAC9C;;;OAGG;IACH,IAAI,EAAE,CACJ,UAAU,GAAG,MAAM,EACnB,WAAW,GAAG,OAAO,EACrB,oBAAoB,GAAG,gBAAgB,EACvC,gBAAgB,SAAS,YAAY,GAAG,YAAY;IAEpD;;;;OAIG;IACH,UAAU,EAAE,qBAAqB,CAC/B,MAAM,EACN,OAAO,EACP,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,gBAAgB,CACjB;IACD,0DAA0D;IAC1D,oBAAoB,CAAC,EAAE,gBAAgB,KACpC,SAAS,CAAC,UAAU,EAAE,WAAW,EAAE,oBAAoB,EAAE,gBAAgB,CAAC,CAAA;IAC/E;;;;OAIG;IACH,CAAC,KAAK,EAAE,cAAc,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,OAAO,GAAG,gBAAgB,GAAG,IAAI,CAAA;CACjF;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,yRAoEzB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "afformative",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/afformative.cjs.js",
|
|
6
6
|
"module": "dist/afformative.esm.js",
|
|
@@ -27,9 +27,12 @@
|
|
|
27
27
|
"contributors": [
|
|
28
28
|
"Vaclav Jancarik <vaclav.janc@gmail.com>"
|
|
29
29
|
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@babel/runtime": "^7.12.1"
|
|
32
|
+
},
|
|
30
33
|
"publishConfig": {
|
|
31
34
|
"access": "public"
|
|
32
35
|
},
|
|
33
36
|
"sideEffects": false,
|
|
34
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "ddc8c8682e2777c730108466792b7670d8a43f06"
|
|
35
38
|
}
|
|
@@ -2,111 +2,217 @@ import { makeFormatter } from "./makeFormatter"
|
|
|
2
2
|
|
|
3
3
|
const toUpperCase = (string: string) => string.toUpperCase()
|
|
4
4
|
|
|
5
|
+
const upperCaseFormatter = makeFormatter<string, string>(toUpperCase)
|
|
6
|
+
|
|
7
|
+
interface ValueRecord {
|
|
8
|
+
value: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const valueRecordUpperCaseFormatter = makeFormatter<ValueRecord, ValueRecord, string>(
|
|
12
|
+
({ value }, suggestions) => {
|
|
13
|
+
if (suggestions.includes("primitive")) {
|
|
14
|
+
return toUpperCase(value)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return { value: toUpperCase(value) }
|
|
18
|
+
},
|
|
19
|
+
)
|
|
20
|
+
|
|
5
21
|
describe("makeFormatter", () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
22
|
+
const format = jest.fn()
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
jest.clearAllMocks()
|
|
9
26
|
})
|
|
10
27
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
28
|
+
describe("displayName", () => {
|
|
29
|
+
it("accepts a `displayName` option", () => {
|
|
30
|
+
const displayName = "upperCaseFormatter"
|
|
31
|
+
const formatter = makeFormatter<string, string>(toUpperCase, { displayName })
|
|
32
|
+
expect(formatter.displayName).toBe(displayName)
|
|
33
|
+
})
|
|
14
34
|
})
|
|
15
35
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
36
|
+
describe("format", () => {
|
|
37
|
+
it("handles trivial formatting", () => {
|
|
38
|
+
expect(upperCaseFormatter.format("foo")).toBe("FOO")
|
|
39
|
+
})
|
|
21
40
|
|
|
22
|
-
|
|
41
|
+
it("passes through non-empty suggestions", () => {
|
|
42
|
+
const formatter = makeFormatter<string, string>(format)
|
|
43
|
+
formatter.format("foo", ["abbreviated"])
|
|
44
|
+
expect(format.mock.calls[0][1]).toEqual(["abbreviated"])
|
|
23
45
|
})
|
|
24
46
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
47
|
+
it("passes through empty suggestions", () => {
|
|
48
|
+
const formatter = makeFormatter<string, string>(format)
|
|
49
|
+
formatter.format("foo", [])
|
|
50
|
+
expect(format.mock.calls[0][1]).toEqual([])
|
|
51
|
+
})
|
|
29
52
|
|
|
30
|
-
|
|
31
|
-
|
|
53
|
+
it("defaults suggestions to an empty array", () => {
|
|
54
|
+
const formatter = makeFormatter<string, string>(format)
|
|
55
|
+
formatter.format("foo")
|
|
56
|
+
expect(format.mock.calls[0][1]).toEqual([])
|
|
57
|
+
})
|
|
32
58
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
59
|
+
it("passes through the `primitive` suggestion", () => {
|
|
60
|
+
const formatter = makeFormatter<string, string>(format)
|
|
61
|
+
formatter.format("foo", ["primitive"])
|
|
62
|
+
expect(format.mock.calls[0][1]).toEqual(["primitive"])
|
|
63
|
+
})
|
|
37
64
|
|
|
38
|
-
|
|
65
|
+
it("passes the `primitive` suggestion alongside `comparable` when missing", () => {
|
|
66
|
+
const formatter = makeFormatter<string, string>(format)
|
|
67
|
+
formatter.format("foo", ["comparable"])
|
|
68
|
+
expect(format.mock.calls[0][1]).toEqual(["primitive", "comparable"])
|
|
39
69
|
})
|
|
40
70
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
71
|
+
it("does not pass the `primitive` suggestion alongside other suggestions when missing", () => {
|
|
72
|
+
const formatter = makeFormatter<string, string>(format)
|
|
73
|
+
formatter.format("foo", ["abbreviated", "verbose"])
|
|
74
|
+
expect(format.mock.calls[0][1]).toEqual(["abbreviated", "verbose"])
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it("supports data context", () => {
|
|
78
|
+
const formatter = makeFormatter<string, string>(format)
|
|
79
|
+
formatter.format("foo", [], { foo: "bar" })
|
|
80
|
+
expect(format.mock.calls[0][2]).toEqual({ foo: "bar" })
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it("defaults data context to an empty object", () => {
|
|
84
|
+
const formatter = makeFormatter<string, string>(format)
|
|
85
|
+
formatter.format("foo")
|
|
86
|
+
expect(format.mock.calls[0][2]).toEqual({})
|
|
87
|
+
})
|
|
44
88
|
})
|
|
45
89
|
|
|
46
|
-
|
|
47
|
-
|
|
90
|
+
describe("formatAsPrimitive", () => {
|
|
91
|
+
it("handles trivial formatting", () => {
|
|
92
|
+
expect(upperCaseFormatter.formatAsPrimitive("foo")).toBe("FOO")
|
|
93
|
+
})
|
|
48
94
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
95
|
+
it("passes the `primitive` suggestion when no suggestions are passed", () => {
|
|
96
|
+
const formatter = makeFormatter<string, string>(format)
|
|
97
|
+
formatter.formatAsPrimitive("foo")
|
|
98
|
+
expect(format.mock.calls[0][1]).toEqual(["primitive"])
|
|
99
|
+
})
|
|
52
100
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
101
|
+
it("passes the `primitive` suggestion when empty suggestions are passed", () => {
|
|
102
|
+
const formatter = makeFormatter<string, string>(format)
|
|
103
|
+
formatter.formatAsPrimitive("foo", [])
|
|
104
|
+
expect(format.mock.calls[0][1]).toEqual(["primitive"])
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it("passes the `primitive` suggestion when a different suggestion is passed", () => {
|
|
108
|
+
const formatter = makeFormatter<string, string>(format)
|
|
109
|
+
formatter.formatAsPrimitive("foo", ["abbreviated"])
|
|
110
|
+
expect(format.mock.calls[0][1]).toEqual(["primitive", "abbreviated"])
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it("passes through the `primitive` suggestion", () => {
|
|
114
|
+
const formatter = makeFormatter<string, string>(format)
|
|
115
|
+
formatter.formatAsPrimitive("foo", ["primitive"])
|
|
116
|
+
expect(format.mock.calls[0][1]).toEqual(["primitive"])
|
|
117
|
+
})
|
|
56
118
|
|
|
57
|
-
|
|
58
|
-
|
|
119
|
+
it("passes the `primitive` suggestion alongside `comparable`", () => {
|
|
120
|
+
const formatter = makeFormatter<string, string>(format)
|
|
121
|
+
formatter.formatAsPrimitive("foo", ["comparable"])
|
|
122
|
+
expect(format.mock.calls[0][1]).toEqual(["primitive", "comparable"])
|
|
123
|
+
})
|
|
59
124
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
125
|
+
it("supports data context", () => {
|
|
126
|
+
const formatter = makeFormatter<string, string>(format)
|
|
127
|
+
formatter.formatAsPrimitive("foo", [], { foo: "bar" })
|
|
128
|
+
expect(format.mock.calls[0][2]).toEqual({ foo: "bar" })
|
|
129
|
+
})
|
|
63
130
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
131
|
+
it("defaults data context to an empty object", () => {
|
|
132
|
+
const formatter = makeFormatter<string, string>(format)
|
|
133
|
+
formatter.formatAsPrimitive("foo")
|
|
134
|
+
expect(format.mock.calls[0][2]).toEqual({})
|
|
135
|
+
})
|
|
67
136
|
})
|
|
68
137
|
|
|
69
|
-
|
|
70
|
-
|
|
138
|
+
describe("wrap", () => {
|
|
139
|
+
it("handles trivial wrapping", () => {
|
|
140
|
+
const formatter = makeFormatter<string, string>(format).wrap(() => "bar")
|
|
141
|
+
expect(formatter.format("foo")).toBe("bar")
|
|
142
|
+
})
|
|
71
143
|
|
|
72
|
-
|
|
144
|
+
it("handles single-value mapping", () => {
|
|
145
|
+
const formatter = makeFormatter<string, string>(format).wrap((delegate, value) =>
|
|
146
|
+
value === "ping" ? "pong" : delegate(value),
|
|
147
|
+
)
|
|
73
148
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
)
|
|
149
|
+
expect(formatter.format("ping")).toBe("pong")
|
|
150
|
+
})
|
|
77
151
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
152
|
+
it("handles delegation to the original formatter", () => {
|
|
153
|
+
const formatter = upperCaseFormatter.wrap((delegate, value) =>
|
|
154
|
+
value === "ping" ? "pong" : delegate(value),
|
|
155
|
+
)
|
|
82
156
|
|
|
83
|
-
|
|
84
|
-
|
|
157
|
+
expect(formatter.format("foo")).toBe("FOO")
|
|
158
|
+
})
|
|
85
159
|
|
|
86
|
-
|
|
87
|
-
(delegate, value
|
|
88
|
-
|
|
160
|
+
it("sets the `innerFormatter` property", () => {
|
|
161
|
+
const wrappedFormatter = upperCaseFormatter.wrap((delegate, value) => delegate(value))
|
|
162
|
+
expect(wrappedFormatter.innerFormatter).toBe(upperCaseFormatter)
|
|
163
|
+
})
|
|
89
164
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
165
|
+
it("passes the `primitive` suggestion to `delegate` when using `formatAsPrimitive`", () => {
|
|
166
|
+
const formatter = valueRecordUpperCaseFormatter.wrap((delegate, value) => delegate(value))
|
|
167
|
+
expect(formatter.formatAsPrimitive({ value: "foo" })).toBe("FOO")
|
|
168
|
+
})
|
|
93
169
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
170
|
+
it("passes suggestions through to `delegate` when not overriden", () => {
|
|
171
|
+
const formatter = valueRecordUpperCaseFormatter.wrap((delegate, value) => delegate(value))
|
|
172
|
+
expect(formatter.format({ value: "foo" }, ["primitive"])).toBe("FOO")
|
|
173
|
+
})
|
|
99
174
|
|
|
100
|
-
|
|
175
|
+
it("supports overriding of suggestions for `delegate`", () => {
|
|
176
|
+
const formatter = valueRecordUpperCaseFormatter.wrap((delegate, value) => delegate(value, []))
|
|
177
|
+
expect(formatter.format({ value: "foo" }, ["primitive"])).toEqual({ value: "FOO" })
|
|
101
178
|
})
|
|
102
179
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
180
|
+
it("supports modifying the input structure", () => {
|
|
181
|
+
const formatter = upperCaseFormatter.wrap<ValueRecord>((delegate, { value }) =>
|
|
182
|
+
delegate(value),
|
|
183
|
+
)
|
|
106
184
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
185
|
+
expect(formatter.format({ value: "foo" })).toBe("FOO")
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it("supports modifying the output structure", () => {
|
|
189
|
+
const formatter = upperCaseFormatter.wrap<ValueRecord, ValueRecord>(
|
|
190
|
+
(delegate, { value }) => ({ value: delegate(value) }),
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
expect(formatter.format({ value: "foo" })).toEqual({ value: "FOO" })
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
it("supports modifying the data context structure", () => {
|
|
197
|
+
interface ListContext {
|
|
198
|
+
row: string
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const listFormatter = upperCaseFormatter.wrap<string, string, string, ListContext>(
|
|
202
|
+
(delegate, value, suggestions, { row }) => `${row}: ${delegate(value)}`,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
interface GridContext extends ListContext {
|
|
206
|
+
column: string
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
expect(listFormatter.format("foo", [], { row: "A" })).toBe("A: FOO")
|
|
210
|
+
|
|
211
|
+
const gridFormatter = listFormatter.wrap<string, string, string, GridContext>(
|
|
212
|
+
(delegate, value, suggestions, { column }) => delegate(value).replace(":", `${column}:`),
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
expect(gridFormatter.format("foo", [], { row: "B", column: "1" })).toBe("B1: FOO")
|
|
216
|
+
})
|
|
111
217
|
})
|
|
112
218
|
})
|
package/src/makeFormatter.ts
CHANGED
|
@@ -1,57 +1,61 @@
|
|
|
1
|
-
type PrimitiveSuggestion = "primitive"
|
|
2
|
-
|
|
3
|
-
type Suggestion =
|
|
1
|
+
type PrimitiveSuggestion = "primitive" | "comparable"
|
|
2
|
+
|
|
3
|
+
type Suggestion =
|
|
4
|
+
| PrimitiveSuggestion
|
|
5
|
+
| "abbreviated"
|
|
6
|
+
| "as-icon"
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Since v0.6.3. Use `"as-icon"` or `"with-icon"` instead.
|
|
9
|
+
*/
|
|
10
|
+
| "icon"
|
|
11
|
+
| "verbose"
|
|
12
|
+
| "with-icon"
|
|
13
|
+
|
|
14
|
+
const ensureFormatSuggestionIntegrity = (suggestions: Suggestion[]): Suggestion[] =>
|
|
15
|
+
suggestions.includes("primitive") || !suggestions.includes("comparable")
|
|
16
|
+
? suggestions
|
|
17
|
+
: ["primitive", ...suggestions]
|
|
18
|
+
|
|
19
|
+
const ensureFormatAsPrimitiveSuggestionIntegrity = (suggestions: Suggestion[]): Suggestion[] =>
|
|
20
|
+
suggestions.includes("primitive") ? suggestions : ["primitive", ...suggestions]
|
|
21
|
+
|
|
22
|
+
type DataContext = Record<string, any>
|
|
4
23
|
|
|
5
24
|
interface FormatterOptions {
|
|
6
25
|
/** Formatter name, useful for debugging or advanced pattern matching. */
|
|
7
26
|
displayName?: string
|
|
8
27
|
}
|
|
9
28
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// TODO: Update `FormatDefinition` type based on this snippet. Sadly, TypeScript cannot correctly
|
|
13
|
-
// verify the return type of the format definition based on the suggestions, printing errors such
|
|
14
|
-
// as `Type 'string' is not assignable to type '"primitive" extends TSuggestion ? string : string'`
|
|
15
|
-
// which is, of course, nonsense. Same applies to `FormatChainDefinition`.
|
|
16
|
-
//
|
|
17
|
-
// interface FormatDefinition<TInput, TOutput, TPrimitiveOutput> {
|
|
18
|
-
// <TSuggestion extends Suggestion>(
|
|
19
|
-
// value: TInput,
|
|
20
|
-
// usageSuggestions: TSuggestion[],
|
|
21
|
-
// dataContext: DataContext,
|
|
22
|
-
// ): PrimitiveSuggestion extends TSuggestion ? TPrimitiveOutput : TOutput
|
|
23
|
-
// }
|
|
24
|
-
|
|
25
|
-
interface FormatDefinition<TInput, TOutput, TPrimitiveOutput> {
|
|
29
|
+
interface FormatDefinition<TInput, TOutput, TPrimitiveOutput, TDataContext extends DataContext> {
|
|
26
30
|
(
|
|
27
31
|
/** Value to format. */
|
|
28
32
|
value: TInput,
|
|
29
33
|
/** Suggestions passed by the consumer of a formatter. */
|
|
30
|
-
|
|
34
|
+
suggestions: Suggestion[],
|
|
31
35
|
/** Additional data context to be used by the formatter. */
|
|
32
|
-
dataContext:
|
|
36
|
+
dataContext: Partial<TDataContext>,
|
|
33
37
|
): TOutput | TPrimitiveOutput
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
interface FormatMethod<TInput, TOutput, TPrimitiveOutput> {
|
|
37
|
-
|
|
40
|
+
interface FormatMethod<TInput, TOutput, TPrimitiveOutput, TDataContext extends DataContext> {
|
|
41
|
+
(
|
|
38
42
|
/** Value to format. */
|
|
39
43
|
value: TInput,
|
|
40
44
|
/** Suggestions the formatter should take note of. */
|
|
41
|
-
|
|
45
|
+
suggestions?: Suggestion[],
|
|
42
46
|
/** Additional data context the formatter might find useful. */
|
|
43
|
-
dataContext?:
|
|
44
|
-
):
|
|
47
|
+
dataContext?: Partial<TDataContext>,
|
|
48
|
+
): TOutput | TPrimitiveOutput
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
interface FormatAsPrimitiveMethod<TInput, TPrimitiveOutput> {
|
|
51
|
+
interface FormatAsPrimitiveMethod<TInput, TPrimitiveOutput, TDataContext extends DataContext> {
|
|
48
52
|
(
|
|
49
53
|
/** Value to format. */
|
|
50
54
|
value: TInput,
|
|
51
55
|
/** Suggestions the formatter should take note of in addition to `primitive`. */
|
|
52
|
-
|
|
56
|
+
suggestions?: Suggestion[],
|
|
53
57
|
/** Additional data context the formatter might find useful. */
|
|
54
|
-
dataContext?:
|
|
58
|
+
dataContext?: Partial<TDataContext>,
|
|
55
59
|
): TPrimitiveOutput
|
|
56
60
|
}
|
|
57
61
|
|
|
@@ -59,9 +63,11 @@ interface FormatChainDefinition<
|
|
|
59
63
|
TInnerInput,
|
|
60
64
|
TInnerOutput,
|
|
61
65
|
TInnerPrimitiveInput,
|
|
66
|
+
TInnerDataContext extends DataContext,
|
|
62
67
|
TOuterInput,
|
|
63
68
|
TOuterOutput,
|
|
64
|
-
TOuterPrimitiveOutput
|
|
69
|
+
TOuterPrimitiveOutput,
|
|
70
|
+
TOuterDataContext extends DataContext
|
|
65
71
|
> {
|
|
66
72
|
(
|
|
67
73
|
/**
|
|
@@ -69,39 +75,47 @@ interface FormatChainDefinition<
|
|
|
69
75
|
* to the wrapped formatter. Delegation is simplified so if no suggestions or contextual
|
|
70
76
|
* props are passed, the original ones are used instead.
|
|
71
77
|
*/
|
|
72
|
-
delegate: FormatMethod<TInnerInput, TInnerOutput, TInnerPrimitiveInput>,
|
|
78
|
+
delegate: FormatMethod<TInnerInput, TInnerOutput, TInnerPrimitiveInput, TInnerDataContext>,
|
|
73
79
|
/** Value to format. */
|
|
74
80
|
value: TOuterInput,
|
|
75
81
|
/** Suggestions the formatter should take note of. */
|
|
76
|
-
|
|
82
|
+
suggestions: Suggestion[],
|
|
77
83
|
/** Additional data context the formatter might find useful. */
|
|
78
|
-
dataContext:
|
|
84
|
+
dataContext: Partial<TOuterDataContext>,
|
|
79
85
|
): TOuterOutput | TOuterPrimitiveOutput
|
|
80
86
|
}
|
|
81
87
|
|
|
82
|
-
|
|
88
|
+
type FormatterProps<TInput, TDataContext extends DataContext> = {
|
|
83
89
|
/** Value to format. */
|
|
84
90
|
children: TInput
|
|
85
91
|
/** Suggestions the formatter should take note of. */
|
|
86
92
|
suggestions?: Suggestion[]
|
|
87
|
-
|
|
88
|
-
[dataContextPropName: string]: any
|
|
89
|
-
}
|
|
93
|
+
} & Partial<TDataContext>
|
|
90
94
|
|
|
91
|
-
export interface Formatter<
|
|
95
|
+
export interface Formatter<
|
|
96
|
+
TInput,
|
|
97
|
+
TOutput,
|
|
98
|
+
TPrimitiveOutput = TOutput,
|
|
99
|
+
TDataContext extends DataContext = DataContext
|
|
100
|
+
> {
|
|
92
101
|
/** Formatter name, useful for debugging or advanced pattern matching. */
|
|
93
102
|
displayName?: string
|
|
94
103
|
/** Formats a value. */
|
|
95
|
-
format: FormatMethod<TInput, TOutput, TPrimitiveOutput>
|
|
104
|
+
format: FormatMethod<TInput, TOutput, TPrimitiveOutput, TDataContext>
|
|
96
105
|
/** Formats a value with the `primitive` suggestion. */
|
|
97
|
-
formatAsPrimitive: FormatAsPrimitiveMethod<TInput, TPrimitiveOutput>
|
|
98
|
-
/** The callee of the
|
|
99
|
-
innerFormatter?: Formatter<any, any, any>
|
|
106
|
+
formatAsPrimitive: FormatAsPrimitiveMethod<TInput, TPrimitiveOutput, TDataContext>
|
|
107
|
+
/** The callee of the `wrap` method used to produce this formatter. */
|
|
108
|
+
innerFormatter?: Formatter<any, any, any, any>
|
|
100
109
|
/**
|
|
101
110
|
* Creates a new formatter from an existing one. Allows overriding of formatter behaviour
|
|
102
111
|
* for certain values.
|
|
103
112
|
*/
|
|
104
|
-
wrap: <
|
|
113
|
+
wrap: <
|
|
114
|
+
TNextInput = TInput,
|
|
115
|
+
TNextOutput = TOutput,
|
|
116
|
+
TNextPrimitiveOutput = TPrimitiveOutput,
|
|
117
|
+
TNextDataContext extends TDataContext = TDataContext
|
|
118
|
+
>(
|
|
105
119
|
/**
|
|
106
120
|
* Function used to format the value. Has the same signature as the one passed
|
|
107
121
|
* to `makeFormatter`, except a `delegate` function is passed in the first position.
|
|
@@ -111,19 +125,21 @@ export interface Formatter<TInput, TOutput, TPrimitiveOutput = TOutput> {
|
|
|
111
125
|
TInput,
|
|
112
126
|
TOutput,
|
|
113
127
|
TPrimitiveOutput,
|
|
128
|
+
TDataContext,
|
|
114
129
|
TNextInput,
|
|
115
130
|
TNextOutput,
|
|
116
|
-
TNextPrimitiveOutput
|
|
131
|
+
TNextPrimitiveOutput,
|
|
132
|
+
TNextDataContext
|
|
117
133
|
>,
|
|
118
134
|
/** New formatter options, replacing the original ones. */
|
|
119
135
|
nextFormatterOptions?: FormatterOptions,
|
|
120
|
-
) => Formatter<TNextInput, TNextOutput, TNextPrimitiveOutput>
|
|
136
|
+
) => Formatter<TNextInput, TNextOutput, TNextPrimitiveOutput, TNextDataContext>
|
|
121
137
|
/**
|
|
122
138
|
* Backwards-compatible way to use the formatter as a React component.
|
|
123
139
|
*
|
|
124
|
-
* @deprecated Since v0.6.0. Prefer using the `
|
|
140
|
+
* @deprecated Since v0.6.0. Prefer using the `format` method instead.
|
|
125
141
|
*/
|
|
126
|
-
(props: FormatterProps<TInput>): TOutput | TPrimitiveOutput | null
|
|
142
|
+
(props: FormatterProps<TInput, TDataContext>): TOutput | TPrimitiveOutput | null
|
|
127
143
|
}
|
|
128
144
|
|
|
129
145
|
/**
|
|
@@ -132,52 +148,67 @@ export interface Formatter<TInput, TOutput, TPrimitiveOutput = TOutput> {
|
|
|
132
148
|
* @param format Function used to format the value.
|
|
133
149
|
* @param formatterOptions Additional options for the formatter.
|
|
134
150
|
*/
|
|
135
|
-
export const makeFormatter = <
|
|
136
|
-
|
|
151
|
+
export const makeFormatter = <
|
|
152
|
+
TInput,
|
|
153
|
+
TOutput,
|
|
154
|
+
TPrimitiveOutput = TOutput,
|
|
155
|
+
TDataContext extends DataContext = DataContext
|
|
156
|
+
>(
|
|
157
|
+
format: FormatDefinition<TInput, TOutput, TPrimitiveOutput, TDataContext>,
|
|
137
158
|
formatterOptions?: FormatterOptions,
|
|
138
|
-
): Formatter<TInput, TOutput, TPrimitiveOutput> => {
|
|
139
|
-
const formatter: Formatter<TInput, TOutput, TPrimitiveOutput> =
|
|
140
|
-
children,
|
|
141
|
-
suggestions = [],
|
|
142
|
-
...dataContext
|
|
143
|
-
}) => format(children, suggestions, dataContext) ?? null
|
|
159
|
+
): Formatter<TInput, TOutput, TPrimitiveOutput, TDataContext> => {
|
|
160
|
+
const formatter: Formatter<TInput, TOutput, TPrimitiveOutput, TDataContext> = props =>
|
|
161
|
+
format(props.children, props.suggestions ?? [], props) ?? null
|
|
144
162
|
|
|
145
163
|
formatter.displayName = formatterOptions?.displayName
|
|
146
164
|
|
|
147
|
-
formatter.format = (value,
|
|
148
|
-
format(value,
|
|
149
|
-
|
|
150
|
-
formatter.formatAsPrimitive = (value,
|
|
151
|
-
format(
|
|
152
|
-
|
|
153
|
-
|
|
165
|
+
formatter.format = (value, suggestions = [], dataContext = {}) =>
|
|
166
|
+
format(value, ensureFormatSuggestionIntegrity(suggestions), dataContext)
|
|
167
|
+
|
|
168
|
+
formatter.formatAsPrimitive = (value, suggestions = [], dataContext = {}) =>
|
|
169
|
+
format(
|
|
170
|
+
value,
|
|
171
|
+
ensureFormatAsPrimitiveSuggestionIntegrity(suggestions),
|
|
172
|
+
dataContext,
|
|
173
|
+
) as TPrimitiveOutput
|
|
174
|
+
|
|
175
|
+
formatter.wrap = <
|
|
176
|
+
TNextInput,
|
|
177
|
+
TNextOutput,
|
|
178
|
+
TNextPrimitiveOutput,
|
|
179
|
+
TNextDataContext extends TDataContext
|
|
180
|
+
>(
|
|
154
181
|
nextFormat: FormatChainDefinition<
|
|
155
182
|
TInput,
|
|
156
183
|
TOutput,
|
|
157
184
|
TPrimitiveOutput,
|
|
185
|
+
TDataContext,
|
|
158
186
|
TNextInput,
|
|
159
187
|
TNextOutput,
|
|
160
|
-
TNextPrimitiveOutput
|
|
188
|
+
TNextPrimitiveOutput,
|
|
189
|
+
TNextDataContext
|
|
161
190
|
>,
|
|
162
191
|
nextFormatterOptions?: FormatterOptions,
|
|
163
192
|
) => {
|
|
164
|
-
const nextFormatter
|
|
165
|
-
|
|
166
|
-
|
|
193
|
+
const nextFormatter = makeFormatter<
|
|
194
|
+
TNextInput,
|
|
195
|
+
TNextOutput,
|
|
196
|
+
TNextPrimitiveOutput,
|
|
197
|
+
TNextDataContext
|
|
198
|
+
>((value, suggestions, dataContext) => {
|
|
199
|
+
const delegate: FormatMethod<TInput, TOutput, TPrimitiveOutput, TDataContext> = (
|
|
200
|
+
delegatedValue,
|
|
201
|
+
delegatedSuggestions,
|
|
202
|
+
delegatedDataContext,
|
|
203
|
+
) =>
|
|
204
|
+
formatter.format(
|
|
167
205
|
delegatedValue,
|
|
168
|
-
|
|
169
|
-
delegatedDataContext,
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
delegatedDataContext ?? dataContext,
|
|
175
|
-
) as any
|
|
176
|
-
|
|
177
|
-
return nextFormat(delegate, value, usageSuggestions, dataContext) as any
|
|
178
|
-
},
|
|
179
|
-
nextFormatterOptions ?? formatterOptions,
|
|
180
|
-
)
|
|
206
|
+
delegatedSuggestions ?? suggestions,
|
|
207
|
+
delegatedDataContext ?? dataContext,
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
return nextFormat(delegate, value, suggestions, dataContext)
|
|
211
|
+
}, nextFormatterOptions ?? formatterOptions)
|
|
181
212
|
|
|
182
213
|
nextFormatter.innerFormatter = formatter
|
|
183
214
|
|