simple-merge-class-names 2.0.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,7 +11,11 @@ A straightforward utility for merging CSS class names in `React + Tailwind` and
11
11
  - [Workflow To Minimize Typing Strain](#workflow-to-minimize-typing-strain)
12
12
 
13
13
  - [Argument Handling](#argument-handling)
14
+
14
15
  - [Breaking Changes From Version 1.X.X](#breaking-changes-from-version-1xx)
16
+
17
+ - [Console Warning for Invalid Arguments](#console-warning-for-invalid-arguments)
18
+
15
19
  - [Testing](#testing)
16
20
  - [Source Code](#source-code)
17
21
  - [Misc.](#misc)
@@ -103,6 +107,18 @@ function MyComponent() {
103
107
 
104
108
  In pervious versions, arguments that were not strings were implicitly converted to strings by the JavaScript engine.
105
109
 
110
+ ### Console Warning for Invalid Arguments
111
+
112
+ Invalid arguments are not silently ignored, as they may indicate a deeper issue. A single warning is logged to the developer console whenever these arguments are passed and ignored.
113
+
114
+ Example output:
115
+
116
+ ```plaintext
117
+ [mergeClassNames] Warning: invalid arguments were provided and were ignored:
118
+ - Expected all arguments to be strings, but got 4 non-string values: [(1/4): (undefined) of type "undefined", (2/4): (test) of type "object", (3/4): ([object Object]) of type "object", (4/4): (null) of type "object"].
119
+ - Expected 0 empty strings, but got 2.
120
+ ```
121
+
106
122
  ## Testing
107
123
 
108
124
  This project uses `Vitest` as the test runner for fast, modern testing.
@@ -1 +1 @@
1
- export declare const mergeClassNames: (...args: unknown[]) => string;
1
+ export declare const mergeClassNames: (...args: string[]) => string;
@@ -39,17 +39,65 @@
39
39
 
40
40
  const isTypeString = (val) => typeof val === "string";
41
41
 
42
- const isNotEmptyString = (val) => val !== "";
42
+ const isNonEmptyString = (val) => val !== "";
43
+
44
+ const partition = (array, keepPredicate) => {
45
+ const keep = [];
46
+ const ignore = [];
47
+ for (const element of array) {
48
+ (keepPredicate(element) ? keep : ignore).push(element);
49
+ }
50
+ return [keep, ignore];
51
+ };
43
52
 
44
53
  export const mergeClassNames = (...args) => {
45
- const space = "\x20"; // " "; ASCII code for single space character;
54
+ const space = "\x20"; // ASCII code for a single space character (" "), decimal 32
55
+
56
+ const [strings, nonStrings] = partition(args, isTypeString);
57
+
58
+ const trimmed = strings.map((val) => val.trim());
59
+
60
+ const [nonEmptyStrings, emptyStrings] = partition(
61
+ trimmed,
62
+ isNonEmptyString
63
+ );
64
+
65
+ const className = nonEmptyStrings.join(space);
66
+
67
+ /* Don't silently ignore invalid input, explicitly disclose them as it indicate a bigger problem */
68
+ const warn = [];
69
+
70
+ /* "Expected all arguments to be strings ..." */
71
+ if (nonStrings.length > 0) {
72
+ const join = ", ";
73
+ const count = nonStrings.length;
74
+ const formatGotArray = (element, index) =>
75
+ `(${index + 1}/${count}): (${element}) of type "${typeof element}"`;
76
+ const message = nonStrings.map(formatGotArray).join(join);
77
+
78
+ warn.push(
79
+ `Expected all arguments to be strings, but got ${count} non-string values: [${message}].`
80
+ );
81
+ }
46
82
 
47
- const stringsOnly = args.filter((val) => isTypeString(val));
83
+ /* "Expected 0 empty strings ..." */
84
+ if (nonEmptyStrings.length > 0) {
85
+ const count = emptyStrings.length;
86
+ warn.push(`Expected 0 empty strings, but got ${count}.`);
87
+ }
48
88
 
49
- const trimmed = stringsOnly.map((val) => val.trim());
89
+ /* Full Warn Message */
90
+ if (warn.length > 0) {
91
+ const newline = "\n";
92
+ const prefix = "\t" + "- ";
93
+ const message = warn.map((text) => `${prefix}${text}`).join(newline);
50
94
 
51
- const nonEmpty = trimmed.filter((val) => isNotEmptyString(val));
95
+ console.warn(
96
+ "[mergeClassNames] Warning: invalid arguments were provided and were ignored:",
97
+ newline,
98
+ message
99
+ );
100
+ }
52
101
 
53
- const className = nonEmpty.join(space);
54
102
  return className;
55
103
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-merge-class-names",
3
- "version": "2.0.3",
3
+ "version": "3.0.0",
4
4
  "description": "A straightforward utility for merging CSS class names in React + Tailwind and JavaScript projects.",
5
5
  "exports": {
6
6
  ".": {