afformative 0.7.0-beta.3 → 0.7.0-beta.5

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 CHANGED
@@ -38,6 +38,8 @@ npm i afformative
38
38
 
39
39
  ## Quick Start
40
40
 
41
+ Afformative is framework-agnostic, but this section will assume usage with React.
42
+
41
43
  A formatter is an object with `format`, `stringify`, and `compare` methods. Formatters must be created using the `createFormatter` function.
42
44
 
43
45
  `createFormatter` accepts a single object parameter. `format` is the only required property, but specifying `stringify` is recommended in most cases.
@@ -49,6 +51,7 @@ import { ReactNode } from "react"
49
51
  const dateFormatter = createFormatter<Date, ReactNode>({
50
52
  format: value => <time dateTime={value.toISOString()}>{value.toLocaleDateString()}</time>,
51
53
  stringify: value => value.toLocaleDateString(),
54
+ compare: value => value.valueOf(),
52
55
  })
53
56
 
54
57
  dateFormatter.format(new Date()) // <time dateTime="2026-05-30T09:17:26.263Z">30/05/2026</time>
@@ -75,11 +78,36 @@ const List = <TItem extends unknown>({ formatter, items }: ListProps<TItem>) =>
75
78
  )
76
79
  ```
77
80
 
78
- The `stringify` method is useful when you need a plain string representation of a value. For example, a combobox component can use it to match items against the user's typed input.
81
+ The `stringify` method is useful when you need a plain string representation of a value. For example, a combobox component can use it to match items against the user's typed input. The default implementation of `stringify` is simply `String(format(value))`.
82
+
83
+ ## Accessing State
84
+
85
+ Create formatters inside hooks to access React context.
86
+
87
+ ```tsx
88
+ const useEnumFormatter = (enumType: string): Formatter<string, ReactNode> => {
89
+ const enumTranslationKeys = useSelector(selectEnumTranslationKeys(enumType))
90
+ const intl = useIntl()
91
+
92
+ return useMemo(
93
+ () =>
94
+ createFormatter<string, ReactNode>({
95
+ format: value => (
96
+ <FormattedMessage defaultMessage={value} id={enumTranslationKeys[value]} />
97
+ ),
98
+ stringify: value =>
99
+ intl.formatMessage({ defaultMessage: value, id: enumTranslationKeys[value] }),
100
+ }),
101
+ [intl, enumTranslationKeys],
102
+ )
103
+ }
104
+ ```
105
+
106
+ ## Comparing Values
79
107
 
80
- ## Compare
108
+ Every formatter exposes a `compare` method which can be directly passed to `Array.prototype.sort`. The default implementation compares the return values of `stringify` via `localeCompare`.
81
109
 
82
- Every formatter exposes a `compare` method, which can be used to sort values. The default implementation compares the return values of `stringify` via `localeCompare`. In the following example, `Amount` objects are sorted first by currency, then by value.
110
+ In the following example, `Amount` objects are sorted first by currency, then by value.
83
111
 
84
112
  ```tsx
85
113
  import { createFormatter } from "afformative"
@@ -109,22 +137,22 @@ amounts.sort(amountFormatter.compare)
109
137
  // [{ EUR, 1 }, { EUR, 5 }, { USD, 2 }, { USD, 3 }]
110
138
  ```
111
139
 
112
- ## Usage Context
140
+ ## Formatter Context
113
141
 
114
- You can pass an optional usage context object to all formatter methods. Let's use a dummy table component as an example.
142
+ You can pass context to all formatter methods. Let's use a dummy table component as an example.
115
143
 
116
144
  ```tsx
117
145
  import { Formatter } from "afformative"
118
146
  import { ReactNode } from "react"
119
147
 
120
- interface TableFormatterUsageContext {
148
+ interface TableFormatterContext {
121
149
  row: number[]
122
150
  cellIndex: number
123
151
  }
124
152
 
125
153
  interface TableProps {
126
154
  rows: number[][]
127
- formatter: Formatter<number, ReactNode, TableFormatterUsageContext>
155
+ formatter: Formatter<number, ReactNode, TableFormatterContext>
128
156
  }
129
157
 
130
158
  const Table = ({ rows, formatter }: TableProps) => (
@@ -140,17 +168,19 @@ const Table = ({ rows, formatter }: TableProps) => (
140
168
  )
141
169
  ```
142
170
 
143
- Usage context allows the users of this table component to write purpose-built formatters, making it possible to take other values in the same row into account. For example, the following formatter would change the color of the cell value based on the previous value in the same row.
171
+ Context allows the users of this table component to write purpose-built formatters, making it possible to take other values in the same row into account.
172
+
173
+ For example, the following formatter would change the color of the cell value based on the previous value in the same row.
144
174
 
145
175
  ```tsx
146
176
  import { createFormatter } from "afformative"
147
177
  import { ReactNode } from "react"
148
178
 
149
- import { TableFormatterUsageContext } from "./Table"
179
+ import { TableFormatterContext } from "./Table"
150
180
 
151
- const rowTrendFormatter = createFormatter<number, ReactNode, TableFormatterUsageContext>({
152
- format: (value, { row, cellIndex }) => {
153
- if (cellIndex === 0) {
181
+ const rowTrendFormatter = createFormatter<number, ReactNode, TableFormatterContext>({
182
+ format: (value, { row, cellIndex } = {}) => {
183
+ if (!cellIndex || !row) {
154
184
  return <span>{value}</span>
155
185
  }
156
186
 
@@ -163,28 +193,33 @@ const rowTrendFormatter = createFormatter<number, ReactNode, TableFormatterUsage
163
193
 
164
194
  This formatter only makes sense in the context of our table component.
165
195
 
166
- Because `row` and `cellIndex` are passed as the usage context, the formatter still receives only the cell value as its first parameter. This means generic formatters (e.g. a currency formatter) can be passed to the table component without any changes.
196
+ Because `row` and `cellIndex` are passed as context, the formatter still receives only the cell value as its first parameter. This means generic formatters (e.g. a currency formatter) can be passed to the table component without any changes.
197
+
198
+ ## Formatter Meta
167
199
 
168
- ## Accessing React Context
200
+ As explained above, context can be used to pass information from the consumer to the formatter. The `meta` property can be used to pass information from the formatter to the consumer instead. The base `FormatterMeta` interface is extensible via declaration merging.
169
201
 
170
- Create formatters inside custom hooks to access React context values such as translations or application state.
202
+ For example, formatters can explicily mark themselves as print-friendly. Consumers may then decide to use `stringify` instead of `format` based on this flag.
171
203
 
172
204
  ```tsx
173
- const useEnumFormatter = (enumType: string): Formatter<string, ReactNode> => {
174
- const enumTranslationKeys = useSelector(selectEnumTranslationKeys(enumType))
175
- const intl = useIntl()
205
+ declare module "afformative" {
206
+ interface FormatterMeta<TInput, TOutput, TContext> {
207
+ isPrintFriendly?: boolean
208
+ }
209
+ }
176
210
 
177
- return useMemo(
178
- () =>
179
- createFormatter<string, ReactNode>({
180
- format: value => (
181
- <FormattedMessage defaultMessage={value} id={enumTranslationKeys[value]} />
182
- ),
183
- stringify: value =>
184
- intl.formatMessage({ defaultMessage: value, id: enumTranslationKeys[value] }),
185
- }),
186
- [intl, enumTranslationKeys],
187
- )
211
+ const colorfulFormatter = createFormatter<string, ReactNode>({
212
+ format: value => <Colorful>{value}</Colorful>,
213
+ stringify: value => value,
214
+ })
215
+
216
+ interface PrinterProps {
217
+ content: string
218
+ formatter: Formatter<string, ReactNode>
219
+ }
220
+
221
+ const Printer = ({ content, formatter }: PrinterProps) => {
222
+ return formatter.meta?.isPrintFriendly ? formatter.format(content) : formatter.stringify(content)
188
223
  }
189
224
  ```
190
225
 
package/dist/index.cjs CHANGED
@@ -1,14 +1,13 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/createFormatter.ts
3
3
  const createFormatter = (param) => {
4
- const { format: formatParam, stringify: stringifyParam, compare: compareParam, ...rest } = param;
5
- const format = (value, usageContext) => formatParam(value, usageContext ?? {});
6
- const stringify = stringifyParam ? (value, usageContext) => stringifyParam(value, usageContext ?? {}) : (value, usageContext) => String(format(value, usageContext ?? {}));
4
+ const { compare: compareParam, format, meta, stringify: stringifyParam } = param;
5
+ const stringify = stringifyParam ?? ((value, ctx) => String(format(value, ctx)));
7
6
  return {
8
- compare: compareParam ? (a, b, usageContext) => compareParam(a, b, usageContext ?? {}) : (a, b, usageContext) => stringify(a, usageContext ?? {}).localeCompare(stringify(b, usageContext ?? {})),
7
+ compare: compareParam ?? ((a, b, ctx) => stringify(a, ctx).localeCompare(stringify(b, ctx))),
9
8
  format,
10
- stringify,
11
- ...rest
9
+ meta,
10
+ stringify
12
11
  };
13
12
  };
14
13
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/createFormatter.ts"],"sourcesContent":["export interface FormatterFormatDefinition<TInput, TOutput, TUsageContext extends object = object> {\n (value: TInput, usageContext: Partial<TUsageContext>): TOutput\n}\n\nexport interface FormatterFormat<TInput, TOutput, TUsageContext extends object = object> {\n (value: TInput, usageContext?: Partial<TUsageContext>): TOutput\n}\n\nexport interface FormatterStringifyDefinition<TInput, TUsageContext extends object = object> {\n (value: TInput, usageContext: Partial<TUsageContext>): string\n}\n\nexport interface FormatterStringify<TInput, TUsageContext extends object = object> {\n (value: TInput, usageContext?: Partial<TUsageContext>): string\n}\n\nexport interface FormatterCompareDefinition<TInput, TUsageContext extends object = object> {\n (a: TInput, b: TInput, usageContext: Partial<TUsageContext>): number\n}\n\nexport interface FormatterCompare<TInput, TUsageContext extends object = object> {\n (a: TInput, b: TInput, usageContext?: Partial<TUsageContext>): number\n}\n\nexport interface Formatter<TInput, TOutput, TUsageContext extends object = object> {\n compare: FormatterCompare<TInput, TUsageContext>\n format: FormatterFormat<TInput, TOutput, TUsageContext>\n stringify: FormatterStringify<TInput, TUsageContext>\n name?: string\n}\n\nexport interface CreateFormatterParam<TInput, TOutput, TUsageContext extends object = object> {\n compare?: FormatterCompareDefinition<TInput, TUsageContext>\n format: FormatterFormatDefinition<TInput, TOutput, TUsageContext>\n stringify?: FormatterStringifyDefinition<TInput, TUsageContext>\n}\n\nexport const createFormatter = <TInput, TOutput, TUsageContext extends object = object>(\n param: CreateFormatterParam<TInput, TOutput, TUsageContext>,\n): Formatter<TInput, TOutput, TUsageContext> => {\n const { format: formatParam, stringify: stringifyParam, compare: compareParam, ...rest } = param\n\n const format: FormatterFormat<TInput, TOutput, TUsageContext> = (value, usageContext) =>\n formatParam(value, usageContext ?? {})\n\n const stringify: FormatterStringify<TInput, TUsageContext> = stringifyParam\n ? (value, usageContext) => stringifyParam(value, usageContext ?? {})\n : (value, usageContext) => String(format(value, usageContext ?? {}))\n\n const compare: FormatterCompare<TInput, TUsageContext> = compareParam\n ? (a, b, usageContext) => compareParam(a, b, usageContext ?? {})\n : (a, b, usageContext) =>\n stringify(a, usageContext ?? {}).localeCompare(stringify(b, usageContext ?? {}))\n\n return {\n compare,\n format,\n stringify,\n ...rest,\n }\n}\n"],"mappings":";;AAqCA,MAAa,mBACX,UAC8C;CAC9C,MAAM,EAAE,QAAQ,aAAa,WAAW,gBAAgB,SAAS,cAAc,GAAG,SAAS;CAE3F,MAAM,UAA2D,OAAO,iBACtE,YAAY,OAAO,gBAAgB,CAAC,CAAC;CAEvC,MAAM,YAAuD,kBACxD,OAAO,iBAAiB,eAAe,OAAO,gBAAgB,CAAC,CAAC,KAChE,OAAO,iBAAiB,OAAO,OAAO,OAAO,gBAAgB,CAAC,CAAC,CAAC;CAOrE,OAAO;EACL,SANuD,gBACpD,GAAG,GAAG,iBAAiB,aAAa,GAAG,GAAG,gBAAgB,CAAC,CAAC,KAC5D,GAAG,GAAG,iBACL,UAAU,GAAG,gBAAgB,CAAC,CAAC,EAAE,cAAc,UAAU,GAAG,gBAAgB,CAAC,CAAC,CAAC;EAInF;EACA;EACA,GAAG;CACL;AACF"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/createFormatter.ts"],"sourcesContent":["export interface FormatterFormat<TInput, TOutput, TContext = unknown> {\n (value: TInput, ctx?: TContext): TOutput\n}\n\nexport interface FormatterStringify<TInput, TContext = unknown> {\n (value: TInput, ctx?: TContext): string\n}\n\nexport interface FormatterCompare<TInput, TContext = unknown> {\n (a: TInput, b: TInput, ctx?: TContext): number\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/no-unused-vars\nexport interface FormatterMeta<TInput, TOutput, TContext = unknown> {}\n\nexport interface Formatter<TInput, TOutput, TContext = unknown> {\n compare: FormatterCompare<TInput, TContext>\n format: FormatterFormat<TInput, TOutput, TContext>\n meta?: FormatterMeta<TInput, TOutput, TContext>\n stringify: FormatterStringify<TInput, TContext>\n}\n\nexport interface CreateFormatterParam<TInput, TOutput, TContext = unknown> {\n compare?: FormatterCompare<TInput, TContext>\n format: FormatterFormat<TInput, TOutput, TContext>\n meta?: FormatterMeta<TInput, TOutput, TContext>\n stringify?: FormatterStringify<TInput, TContext>\n}\n\nexport const createFormatter = <TInput, TOutput, TContext = unknown>(\n param: CreateFormatterParam<TInput, TOutput, TContext>,\n): Formatter<TInput, TOutput, TContext> => {\n const { compare: compareParam, format, meta, stringify: stringifyParam } = param\n\n const stringify: FormatterStringify<TInput, TContext> =\n stringifyParam ?? ((value, ctx) => String(format(value, ctx)))\n\n const compare: FormatterCompare<TInput, TContext> =\n compareParam ?? ((a, b, ctx) => stringify(a, ctx).localeCompare(stringify(b, ctx)))\n\n return {\n compare,\n format,\n meta,\n stringify,\n }\n}\n"],"mappings":";;AA6BA,MAAa,mBACX,UACyC;CACzC,MAAM,EAAE,SAAS,cAAc,QAAQ,MAAM,WAAW,mBAAmB;CAE3E,MAAM,YACJ,oBAAoB,OAAO,QAAQ,OAAO,OAAO,OAAO,GAAG,CAAC;CAK9D,OAAO;EACL,SAHA,kBAAkB,GAAG,GAAG,QAAQ,UAAU,GAAG,GAAG,EAAE,cAAc,UAAU,GAAG,GAAG,CAAC;EAIjF;EACA;EACA;CACF;AACF"}
package/dist/index.d.cts CHANGED
@@ -1,34 +1,27 @@
1
1
  //#region src/createFormatter.d.ts
2
- interface FormatterFormatDefinition<TInput, TOutput, TUsageContext extends object = object> {
3
- (value: TInput, usageContext: Partial<TUsageContext>): TOutput;
2
+ interface FormatterFormat<TInput, TOutput, TContext = unknown> {
3
+ (value: TInput, ctx?: TContext): TOutput;
4
4
  }
5
- interface FormatterFormat<TInput, TOutput, TUsageContext extends object = object> {
6
- (value: TInput, usageContext?: Partial<TUsageContext>): TOutput;
5
+ interface FormatterStringify<TInput, TContext = unknown> {
6
+ (value: TInput, ctx?: TContext): string;
7
7
  }
8
- interface FormatterStringifyDefinition<TInput, TUsageContext extends object = object> {
9
- (value: TInput, usageContext: Partial<TUsageContext>): string;
8
+ interface FormatterCompare<TInput, TContext = unknown> {
9
+ (a: TInput, b: TInput, ctx?: TContext): number;
10
10
  }
11
- interface FormatterStringify<TInput, TUsageContext extends object = object> {
12
- (value: TInput, usageContext?: Partial<TUsageContext>): string;
11
+ interface FormatterMeta<TInput, TOutput, TContext = unknown> {}
12
+ interface Formatter<TInput, TOutput, TContext = unknown> {
13
+ compare: FormatterCompare<TInput, TContext>;
14
+ format: FormatterFormat<TInput, TOutput, TContext>;
15
+ meta?: FormatterMeta<TInput, TOutput, TContext>;
16
+ stringify: FormatterStringify<TInput, TContext>;
13
17
  }
14
- interface FormatterCompareDefinition<TInput, TUsageContext extends object = object> {
15
- (a: TInput, b: TInput, usageContext: Partial<TUsageContext>): number;
18
+ interface CreateFormatterParam<TInput, TOutput, TContext = unknown> {
19
+ compare?: FormatterCompare<TInput, TContext>;
20
+ format: FormatterFormat<TInput, TOutput, TContext>;
21
+ meta?: FormatterMeta<TInput, TOutput, TContext>;
22
+ stringify?: FormatterStringify<TInput, TContext>;
16
23
  }
17
- interface FormatterCompare<TInput, TUsageContext extends object = object> {
18
- (a: TInput, b: TInput, usageContext?: Partial<TUsageContext>): number;
19
- }
20
- interface Formatter<TInput, TOutput, TUsageContext extends object = object> {
21
- compare: FormatterCompare<TInput, TUsageContext>;
22
- format: FormatterFormat<TInput, TOutput, TUsageContext>;
23
- stringify: FormatterStringify<TInput, TUsageContext>;
24
- name?: string;
25
- }
26
- interface CreateFormatterParam<TInput, TOutput, TUsageContext extends object = object> {
27
- compare?: FormatterCompareDefinition<TInput, TUsageContext>;
28
- format: FormatterFormatDefinition<TInput, TOutput, TUsageContext>;
29
- stringify?: FormatterStringifyDefinition<TInput, TUsageContext>;
30
- }
31
- declare const createFormatter: <TInput, TOutput, TUsageContext extends object = object>(param: CreateFormatterParam<TInput, TOutput, TUsageContext>) => Formatter<TInput, TOutput, TUsageContext>;
24
+ declare const createFormatter: <TInput, TOutput, TContext = unknown>(param: CreateFormatterParam<TInput, TOutput, TContext>) => Formatter<TInput, TOutput, TContext>;
32
25
  //#endregion
33
- export { CreateFormatterParam, Formatter, FormatterCompare, FormatterCompareDefinition, FormatterFormat, FormatterFormatDefinition, FormatterStringify, FormatterStringifyDefinition, createFormatter };
26
+ export { CreateFormatterParam, Formatter, FormatterCompare, FormatterFormat, FormatterMeta, FormatterStringify, createFormatter };
34
27
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.ts CHANGED
@@ -1,34 +1,27 @@
1
1
  //#region src/createFormatter.d.ts
2
- interface FormatterFormatDefinition<TInput, TOutput, TUsageContext extends object = object> {
3
- (value: TInput, usageContext: Partial<TUsageContext>): TOutput;
2
+ interface FormatterFormat<TInput, TOutput, TContext = unknown> {
3
+ (value: TInput, ctx?: TContext): TOutput;
4
4
  }
5
- interface FormatterFormat<TInput, TOutput, TUsageContext extends object = object> {
6
- (value: TInput, usageContext?: Partial<TUsageContext>): TOutput;
5
+ interface FormatterStringify<TInput, TContext = unknown> {
6
+ (value: TInput, ctx?: TContext): string;
7
7
  }
8
- interface FormatterStringifyDefinition<TInput, TUsageContext extends object = object> {
9
- (value: TInput, usageContext: Partial<TUsageContext>): string;
8
+ interface FormatterCompare<TInput, TContext = unknown> {
9
+ (a: TInput, b: TInput, ctx?: TContext): number;
10
10
  }
11
- interface FormatterStringify<TInput, TUsageContext extends object = object> {
12
- (value: TInput, usageContext?: Partial<TUsageContext>): string;
11
+ interface FormatterMeta<TInput, TOutput, TContext = unknown> {}
12
+ interface Formatter<TInput, TOutput, TContext = unknown> {
13
+ compare: FormatterCompare<TInput, TContext>;
14
+ format: FormatterFormat<TInput, TOutput, TContext>;
15
+ meta?: FormatterMeta<TInput, TOutput, TContext>;
16
+ stringify: FormatterStringify<TInput, TContext>;
13
17
  }
14
- interface FormatterCompareDefinition<TInput, TUsageContext extends object = object> {
15
- (a: TInput, b: TInput, usageContext: Partial<TUsageContext>): number;
18
+ interface CreateFormatterParam<TInput, TOutput, TContext = unknown> {
19
+ compare?: FormatterCompare<TInput, TContext>;
20
+ format: FormatterFormat<TInput, TOutput, TContext>;
21
+ meta?: FormatterMeta<TInput, TOutput, TContext>;
22
+ stringify?: FormatterStringify<TInput, TContext>;
16
23
  }
17
- interface FormatterCompare<TInput, TUsageContext extends object = object> {
18
- (a: TInput, b: TInput, usageContext?: Partial<TUsageContext>): number;
19
- }
20
- interface Formatter<TInput, TOutput, TUsageContext extends object = object> {
21
- compare: FormatterCompare<TInput, TUsageContext>;
22
- format: FormatterFormat<TInput, TOutput, TUsageContext>;
23
- stringify: FormatterStringify<TInput, TUsageContext>;
24
- name?: string;
25
- }
26
- interface CreateFormatterParam<TInput, TOutput, TUsageContext extends object = object> {
27
- compare?: FormatterCompareDefinition<TInput, TUsageContext>;
28
- format: FormatterFormatDefinition<TInput, TOutput, TUsageContext>;
29
- stringify?: FormatterStringifyDefinition<TInput, TUsageContext>;
30
- }
31
- declare const createFormatter: <TInput, TOutput, TUsageContext extends object = object>(param: CreateFormatterParam<TInput, TOutput, TUsageContext>) => Formatter<TInput, TOutput, TUsageContext>;
24
+ declare const createFormatter: <TInput, TOutput, TContext = unknown>(param: CreateFormatterParam<TInput, TOutput, TContext>) => Formatter<TInput, TOutput, TContext>;
32
25
  //#endregion
33
- export { CreateFormatterParam, Formatter, FormatterCompare, FormatterCompareDefinition, FormatterFormat, FormatterFormatDefinition, FormatterStringify, FormatterStringifyDefinition, createFormatter };
26
+ export { CreateFormatterParam, Formatter, FormatterCompare, FormatterFormat, FormatterMeta, FormatterStringify, createFormatter };
34
27
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,13 +1,12 @@
1
1
  //#region src/createFormatter.ts
2
2
  const createFormatter = (param) => {
3
- const { format: formatParam, stringify: stringifyParam, compare: compareParam, ...rest } = param;
4
- const format = (value, usageContext) => formatParam(value, usageContext ?? {});
5
- const stringify = stringifyParam ? (value, usageContext) => stringifyParam(value, usageContext ?? {}) : (value, usageContext) => String(format(value, usageContext ?? {}));
3
+ const { compare: compareParam, format, meta, stringify: stringifyParam } = param;
4
+ const stringify = stringifyParam ?? ((value, ctx) => String(format(value, ctx)));
6
5
  return {
7
- compare: compareParam ? (a, b, usageContext) => compareParam(a, b, usageContext ?? {}) : (a, b, usageContext) => stringify(a, usageContext ?? {}).localeCompare(stringify(b, usageContext ?? {})),
6
+ compare: compareParam ?? ((a, b, ctx) => stringify(a, ctx).localeCompare(stringify(b, ctx))),
8
7
  format,
9
- stringify,
10
- ...rest
8
+ meta,
9
+ stringify
11
10
  };
12
11
  };
13
12
  //#endregion
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/createFormatter.ts"],"sourcesContent":["export interface FormatterFormatDefinition<TInput, TOutput, TUsageContext extends object = object> {\n (value: TInput, usageContext: Partial<TUsageContext>): TOutput\n}\n\nexport interface FormatterFormat<TInput, TOutput, TUsageContext extends object = object> {\n (value: TInput, usageContext?: Partial<TUsageContext>): TOutput\n}\n\nexport interface FormatterStringifyDefinition<TInput, TUsageContext extends object = object> {\n (value: TInput, usageContext: Partial<TUsageContext>): string\n}\n\nexport interface FormatterStringify<TInput, TUsageContext extends object = object> {\n (value: TInput, usageContext?: Partial<TUsageContext>): string\n}\n\nexport interface FormatterCompareDefinition<TInput, TUsageContext extends object = object> {\n (a: TInput, b: TInput, usageContext: Partial<TUsageContext>): number\n}\n\nexport interface FormatterCompare<TInput, TUsageContext extends object = object> {\n (a: TInput, b: TInput, usageContext?: Partial<TUsageContext>): number\n}\n\nexport interface Formatter<TInput, TOutput, TUsageContext extends object = object> {\n compare: FormatterCompare<TInput, TUsageContext>\n format: FormatterFormat<TInput, TOutput, TUsageContext>\n stringify: FormatterStringify<TInput, TUsageContext>\n name?: string\n}\n\nexport interface CreateFormatterParam<TInput, TOutput, TUsageContext extends object = object> {\n compare?: FormatterCompareDefinition<TInput, TUsageContext>\n format: FormatterFormatDefinition<TInput, TOutput, TUsageContext>\n stringify?: FormatterStringifyDefinition<TInput, TUsageContext>\n}\n\nexport const createFormatter = <TInput, TOutput, TUsageContext extends object = object>(\n param: CreateFormatterParam<TInput, TOutput, TUsageContext>,\n): Formatter<TInput, TOutput, TUsageContext> => {\n const { format: formatParam, stringify: stringifyParam, compare: compareParam, ...rest } = param\n\n const format: FormatterFormat<TInput, TOutput, TUsageContext> = (value, usageContext) =>\n formatParam(value, usageContext ?? {})\n\n const stringify: FormatterStringify<TInput, TUsageContext> = stringifyParam\n ? (value, usageContext) => stringifyParam(value, usageContext ?? {})\n : (value, usageContext) => String(format(value, usageContext ?? {}))\n\n const compare: FormatterCompare<TInput, TUsageContext> = compareParam\n ? (a, b, usageContext) => compareParam(a, b, usageContext ?? {})\n : (a, b, usageContext) =>\n stringify(a, usageContext ?? {}).localeCompare(stringify(b, usageContext ?? {}))\n\n return {\n compare,\n format,\n stringify,\n ...rest,\n }\n}\n"],"mappings":";AAqCA,MAAa,mBACX,UAC8C;CAC9C,MAAM,EAAE,QAAQ,aAAa,WAAW,gBAAgB,SAAS,cAAc,GAAG,SAAS;CAE3F,MAAM,UAA2D,OAAO,iBACtE,YAAY,OAAO,gBAAgB,CAAC,CAAC;CAEvC,MAAM,YAAuD,kBACxD,OAAO,iBAAiB,eAAe,OAAO,gBAAgB,CAAC,CAAC,KAChE,OAAO,iBAAiB,OAAO,OAAO,OAAO,gBAAgB,CAAC,CAAC,CAAC;CAOrE,OAAO;EACL,SANuD,gBACpD,GAAG,GAAG,iBAAiB,aAAa,GAAG,GAAG,gBAAgB,CAAC,CAAC,KAC5D,GAAG,GAAG,iBACL,UAAU,GAAG,gBAAgB,CAAC,CAAC,EAAE,cAAc,UAAU,GAAG,gBAAgB,CAAC,CAAC,CAAC;EAInF;EACA;EACA,GAAG;CACL;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/createFormatter.ts"],"sourcesContent":["export interface FormatterFormat<TInput, TOutput, TContext = unknown> {\n (value: TInput, ctx?: TContext): TOutput\n}\n\nexport interface FormatterStringify<TInput, TContext = unknown> {\n (value: TInput, ctx?: TContext): string\n}\n\nexport interface FormatterCompare<TInput, TContext = unknown> {\n (a: TInput, b: TInput, ctx?: TContext): number\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/no-unused-vars\nexport interface FormatterMeta<TInput, TOutput, TContext = unknown> {}\n\nexport interface Formatter<TInput, TOutput, TContext = unknown> {\n compare: FormatterCompare<TInput, TContext>\n format: FormatterFormat<TInput, TOutput, TContext>\n meta?: FormatterMeta<TInput, TOutput, TContext>\n stringify: FormatterStringify<TInput, TContext>\n}\n\nexport interface CreateFormatterParam<TInput, TOutput, TContext = unknown> {\n compare?: FormatterCompare<TInput, TContext>\n format: FormatterFormat<TInput, TOutput, TContext>\n meta?: FormatterMeta<TInput, TOutput, TContext>\n stringify?: FormatterStringify<TInput, TContext>\n}\n\nexport const createFormatter = <TInput, TOutput, TContext = unknown>(\n param: CreateFormatterParam<TInput, TOutput, TContext>,\n): Formatter<TInput, TOutput, TContext> => {\n const { compare: compareParam, format, meta, stringify: stringifyParam } = param\n\n const stringify: FormatterStringify<TInput, TContext> =\n stringifyParam ?? ((value, ctx) => String(format(value, ctx)))\n\n const compare: FormatterCompare<TInput, TContext> =\n compareParam ?? ((a, b, ctx) => stringify(a, ctx).localeCompare(stringify(b, ctx)))\n\n return {\n compare,\n format,\n meta,\n stringify,\n }\n}\n"],"mappings":";AA6BA,MAAa,mBACX,UACyC;CACzC,MAAM,EAAE,SAAS,cAAc,QAAQ,MAAM,WAAW,mBAAmB;CAE3E,MAAM,YACJ,oBAAoB,OAAO,QAAQ,OAAO,OAAO,OAAO,GAAG,CAAC;CAK9D,OAAO;EACL,SAHA,kBAAkB,GAAG,GAAG,QAAQ,UAAU,GAAG,GAAG,EAAE,cAAc,UAAU,GAAG,GAAG,CAAC;EAIjF;EACA;EACA;CACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "afformative",
3
- "version": "0.7.0-beta.3",
3
+ "version": "0.7.0-beta.5",
4
4
  "description": "A standardized way to format values in your React components.",
5
5
  "keywords": [
6
6
  "react",
@@ -46,7 +46,7 @@
46
46
  "test:eslint": "eslint src",
47
47
  "test:prettier": "prettier --check src",
48
48
  "test:typescript": "tsc --noEmit",
49
- "test:vitest": "vitest run"
49
+ "test:vitest": "vitest run --typecheck"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@eslint/js": "^10.0.1",