lilact 0.19.0 → 0.20.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.
Files changed (33) hide show
  1. package/README.md +1 -1
  2. package/dist/lilact.development.js +129 -29
  3. package/dist/lilact.development.js.map +2 -2
  4. package/dist/lilact.development.min.js +18 -18
  5. package/dist/lilact.development.min.js.map +3 -3
  6. package/dist/lilact.production.min.js +17 -17
  7. package/docs/assets/search.js +1 -1
  8. package/docs/functions/misc.deepEqual.html +1 -1
  9. package/docs/functions/misc.forwardRef.html +1 -1
  10. package/docs/functions/misc.getComponentByPointer.html +1 -1
  11. package/docs/functions/misc.isAsync.html +1 -1
  12. package/docs/functions/misc.isClass.html +1 -1
  13. package/docs/functions/misc.isEmpty.html +1 -1
  14. package/docs/functions/misc.isError.html +1 -1
  15. package/docs/functions/misc.isThenable.html +1 -1
  16. package/docs/functions/misc.shallowEqual.html +1 -1
  17. package/docs/functions/misc.toBool.html +1 -1
  18. package/docs/functions/timers.timeoutPromise.html +20 -11
  19. package/docs/index.html +1 -1
  20. package/docs/static/lilact.development.js +129 -29
  21. package/docs/static/lilact.development.js.map +2 -2
  22. package/docs/static/lilact.development.min.js +18 -18
  23. package/docs/static/lilact.development.min.js.map +3 -3
  24. package/docs/static/lilact.production.min.js +17 -17
  25. package/docs/variables/misc.Children.html +19 -10
  26. package/examples/lilact.development.js +129 -29
  27. package/examples/lilact.development.js.map +2 -2
  28. package/examples/lilact.development.min.js +18 -18
  29. package/examples/lilact.development.min.js.map +3 -3
  30. package/examples/lilact.production.min.js +17 -17
  31. package/package.json +1 -1
  32. package/src/lilact.jsx +1 -1
  33. package/src/misc.jsx +164 -46
package/src/misc.jsx CHANGED
@@ -116,55 +116,173 @@ export function Portal({children, view})
116
116
  Portal.displayName = "Portal";
117
117
 
118
118
  /**
119
- * Children namespace for utilities that operate on `props.children`. `Children` is deprecated
120
- * and not recommended by React documentation itself. But `only` and `toArray` are used
121
- * extensively everywhere, so I included them.
119
+ * Children namespace for utilities that operate on `props.children`.
122
120
  *
123
- * @property only - Filters to the single child (or returns null/throws based on count).
124
- * @property toArray - Converts children to a flat array.
121
+ * - Flattens nested arrays recursively.
122
+ * - Omits `null` and `undefined` items (common React-like behavior).
125
123
  */
126
124
  export const Children = {
127
-
128
- /**
129
- * Returns the only child from a children collection.
130
- *
131
- * @param children - The children to read.
132
- * @returns The single child (or null/exception based on the number of children).
133
- */
134
- only(children) {
135
- children = [...children];
136
- let i=0;
137
- while(i<children.length) {
138
- if(children[i]?.constructor?.name==='Array') {
139
- children.splice(i, 1, ...children[i]);
140
- i--;
141
- }
142
- else if(children[i]===null || children[i]===undefined) {
143
- children.splice(i, 1);
144
- i--;
145
- }
146
- if(i>1) {
147
- throw new Error("No child or child is not the only one");
148
- }
149
- i++;
150
- }
151
- if(children.length===1) return children[0];
152
-
153
- },
154
-
155
- /**
156
- * Converts component children into a flat array.
157
- *
158
- * @param children - The children to convert.
159
- * @returns An array representation of the children.
160
- */
161
- toArray(children) {
162
- if(children) {
163
- if(children?.constructor?.name==='Array') return [...children];
164
- return [children];
165
- }
166
- return [];
167
- }
125
+ /**
126
+ * @param {any} x
127
+ * @returns {boolean}
128
+ */
129
+ _isNil(x) {
130
+ return x === null || x === undefined;
131
+ },
132
+
133
+ /**
134
+ * Recursively flattens nested arrays into `out`, omitting null/undefined.
135
+ * @param {Array<any>} out
136
+ * @param {any} input
137
+ */
138
+ _flattenInto(out, input) {
139
+ if (this._isNil(input)) return;
140
+
141
+ if (Array.isArray(input)) {
142
+ for (const v of input) this._flattenInto(out, v);
143
+ return;
144
+ }
145
+
146
+ out.push(input);
147
+ },
148
+
149
+ /**
150
+ * Converts an iterable children collection into a flat array,
151
+ * omitting `null`/`undefined`.
152
+ *
153
+ * @param {Iterable<any>} children
154
+ * @returns {Array<any>}
155
+ */
156
+ toArray(children) {
157
+ const out = [];
158
+ // Per your rule, children is always iterable (often []), but keep it robust anyway.
159
+ if (!children) return out;
160
+
161
+ for (const item of children) {
162
+ this._flattenInto(out, item);
163
+ }
164
+ return out;
165
+ },
166
+
167
+ /**
168
+ * Returns the number of non-null/undefined children (after flattening).
169
+ * @param {Iterable<any>} children
170
+ * @returns {number}
171
+ */
172
+ count(children) {
173
+ return this.toArray(children).length;
174
+ },
175
+
176
+ /**
177
+ * Returns the single child from a children collection (after flattening & omitting nil),
178
+ * or throws if the remaining count is not exactly 1.
179
+ *
180
+ * @param {Iterable<any>} children
181
+ * @returns {any}
182
+ */
183
+ only(children) {
184
+ const arr = this.toArray(children);
185
+ if (arr.length !== 1) {
186
+ throw new Error(
187
+ arr.length === 0
188
+ ? "Expected exactly one child, but received none."
189
+ : "Expected exactly one child, but received more than one."
190
+ );
191
+ }
192
+ return arr[0];
193
+ },
194
+
195
+ /**
196
+ * Maps over children (after flattening & omitting nil).
197
+ *
198
+ * @param {Iterable<any>} children
199
+ * @param {(child:any, index:number)=>any} fn
200
+ * @returns {Array<any>}
201
+ */
202
+ map(children, fn) {
203
+ const arr = this.toArray(children);
204
+ const out = [];
205
+ for (let i = 0; i < arr.length; i++) out.push(fn(arr[i], i));
206
+ return out;
207
+ },
208
+
209
+ /**
210
+ * Iterates over children (after flattening & omitting nil).
211
+ * @param {Iterable<any>} children
212
+ * @param {(child:any, index:number)=>void} fn
213
+ */
214
+ forEach(children, fn) {
215
+ const arr = this.toArray(children);
216
+ for (let i = 0; i < arr.length; i++) fn(arr[i], i);
217
+ },
218
+
219
+ /**
220
+ * Finds the first child for which predicate returns true.
221
+ *
222
+ * @param {Iterable<any>} children
223
+ * @param {(child:any, index:number)=>boolean} predicate
224
+ * @returns {any|undefined}
225
+ */
226
+ find(children, predicate) {
227
+ const arr = this.toArray(children);
228
+ for (let i = 0; i < arr.length; i++) {
229
+ if (predicate(arr[i], i)) return arr[i];
230
+ }
231
+ return undefined;
232
+ },
233
+
234
+ /**
235
+ * Finds exactly one matching child.
236
+ * Throws if matched count is not exactly 1.
237
+ *
238
+ * @param {Iterable<any>} children
239
+ * @param {(child:any, index:number)=>boolean} predicate
240
+ * @returns {any}
241
+ */
242
+ pickOne(children, predicate) {
243
+ const arr = this.toArray(children);
244
+
245
+ let found;
246
+ let matches = 0;
247
+
248
+ for (let i = 0; i < arr.length; i++) {
249
+ if (predicate(arr[i], i)) {
250
+ matches++;
251
+ found = arr[i];
252
+ if (matches > 1) break;
253
+ }
254
+ }
255
+
256
+ if (matches !== 1) {
257
+ throw new Error(
258
+ matches === 0
259
+ ? "pickOne expected exactly one matching child, but matched none."
260
+ : "pickOne expected exactly one matching child, but matched multiple."
261
+ );
262
+ }
263
+
264
+ return found;
265
+ },
266
+
267
+ /**
268
+ * Returns the first non-nil child (after flattening), or undefined.
269
+ * @param {Iterable<any>} children
270
+ * @returns {any|undefined}
271
+ */
272
+ first(children) {
273
+ const arr = this.toArray(children);
274
+ return arr[0];
275
+ },
276
+
277
+ /**
278
+ * Returns the last non-nil child (after flattening), or undefined.
279
+ * @param {Iterable<any>} children
280
+ * @returns {any|undefined}
281
+ */
282
+ last(children) {
283
+ const arr = this.toArray(children);
284
+ return arr.length ? arr[arr.length - 1] : undefined;
285
+ }
168
286
  };
169
287
 
170
288