@jackens/nnn 2025.9.7 → 2025.11.4
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/nnn.d.ts +22 -11
- package/nnn.js +27 -2
- package/package.json +3 -1
- package/readme.md +33 -4
package/nnn.d.ts
CHANGED
|
@@ -4,17 +4,6 @@ export type CNode = {
|
|
|
4
4
|
};
|
|
5
5
|
/** Argument type for the `c` helper. */
|
|
6
6
|
export type CRoot = Record<PropertyKey, CNode>;
|
|
7
|
-
/** Argument type accepted by the `escape_values` and `escape` helpers. */
|
|
8
|
-
export type EscapeMap = Map<unknown, (value?: unknown) => string>;
|
|
9
|
-
declare const IS_FINITE: unique symbol;
|
|
10
|
-
/** `number` type excluding `±Infinity` and `NaN`. */
|
|
11
|
-
export type FiniteNumber = number & {
|
|
12
|
-
readonly [IS_FINITE]: true;
|
|
13
|
-
};
|
|
14
|
-
/** Argument type for the `h` and `s` helpers. */
|
|
15
|
-
export type HArgs1 = Record<PropertyKey, unknown> | null | undefined | Node | string | number | HArgs;
|
|
16
|
-
/** Argument type for the `h` and `s` helpers. */
|
|
17
|
-
export type HArgs = [string | Node, ...HArgs1[]];
|
|
18
7
|
/**
|
|
19
8
|
* A minimal JS-to-CSS (CSS‑in‑JS) helper.
|
|
20
9
|
*
|
|
@@ -27,14 +16,31 @@ export type HArgs = [string | Node, ...HArgs1[]];
|
|
|
27
16
|
* - Top-level keys beginning with `@` (at-rules) are not concatenated with parent keys.
|
|
28
17
|
*/
|
|
29
18
|
export declare const c: (root: CRoot, splitter?: string) => string;
|
|
19
|
+
/**
|
|
20
|
+
* A responsive‑web‑design helper that generates CSS rules for a grid layout.
|
|
21
|
+
*
|
|
22
|
+
* - `root` and `selector` specify where to apply the generated rules (see `c`).
|
|
23
|
+
* - `cell_width_px` and `cell_height_px` specify the base cell dimensions in pixels.
|
|
24
|
+
* - Each entry in `specs` is a tuple of:
|
|
25
|
+
* - `max_width`: maximum number of cells in a row (viewport width breakpoint).
|
|
26
|
+
* - `width` (optional, default: `1`): number of cells occupied by the element.
|
|
27
|
+
* - `height` (optional): number of cells in height occupied by the element.
|
|
28
|
+
*/
|
|
29
|
+
export declare const rwd: (root: CRoot, selector: string, cell_width_px: number, cell_height_px: number, ...specs: [number, number?, number?][]) => void;
|
|
30
30
|
/** A tiny CSV parsing helper. */
|
|
31
31
|
export declare const csv_parse: (csv: string, separator?: string) => string[][];
|
|
32
|
+
/** Argument type accepted by the `escape_values` and `escape` helpers. */
|
|
33
|
+
export type EscapeMap = Map<unknown, (value?: unknown) => string>;
|
|
32
34
|
/** Escapes array `values` using the provided `escape_map`. */
|
|
33
35
|
export declare const escape_values: (escape_map: EscapeMap, values: unknown[]) => string[];
|
|
34
36
|
/** Escapes interpolated template `values` using the provided `escape_map`. */
|
|
35
37
|
export declare const escape: (escape_map: EscapeMap, template: TemplateStringsArray, ...values: unknown[]) => string;
|
|
36
38
|
/** Applies Polish‑specific typographic corrections. */
|
|
37
39
|
export declare const fix_typography: (node: Node) => void;
|
|
40
|
+
/** Argument type for the `h` and `s` helpers. */
|
|
41
|
+
export type HArgs1 = Record<PropertyKey, unknown> | null | undefined | Node | string | number | HArgs;
|
|
42
|
+
/** Argument type for the `h` and `s` helpers. */
|
|
43
|
+
export type HArgs = [string | Node, ...HArgs1[]];
|
|
38
44
|
/**
|
|
39
45
|
* A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also `s`).
|
|
40
46
|
*
|
|
@@ -79,6 +85,11 @@ export declare const svg_use: (id: string, ...args: HArgs1[]) => SVGSVGElement;
|
|
|
79
85
|
export declare const has_own: (ref: unknown, key: unknown) => boolean;
|
|
80
86
|
/** Checks whether the argument is an array. */
|
|
81
87
|
export declare const is_array: (arg: unknown) => arg is unknown[];
|
|
88
|
+
declare const IS_FINITE: unique symbol;
|
|
89
|
+
/** `number` type excluding `±Infinity` and `NaN`. */
|
|
90
|
+
export type FiniteNumber = number & {
|
|
91
|
+
readonly [IS_FINITE]: true;
|
|
92
|
+
};
|
|
82
93
|
/** Checks whether the argument is a finite number (excluding `±Infinity` and `NaN`). */
|
|
83
94
|
export declare const is_finite_number: (arg: unknown) => arg is FiniteNumber;
|
|
84
95
|
/** Checks whether the argument is a number. */
|
package/nnn.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var _c = (node, prefix, result, splitter) => {
|
|
3
3
|
const queue = [[node, prefix]];
|
|
4
4
|
while (queue.length > 0) {
|
|
5
|
-
const [style_0, prefix_0] = queue.shift()
|
|
5
|
+
const [style_0, prefix_0] = queue.shift();
|
|
6
6
|
if (style_0 == null || prefix_0 == null) {
|
|
7
7
|
continue;
|
|
8
8
|
}
|
|
@@ -50,6 +50,30 @@ var c = (root, splitter = "$$") => {
|
|
|
50
50
|
}
|
|
51
51
|
return chunks.join("");
|
|
52
52
|
};
|
|
53
|
+
var rwd = (root, selector, cell_width_px, cell_height_px, ...specs) => {
|
|
54
|
+
const main = pro(root)[selector];
|
|
55
|
+
main.boxSizing = "border-box";
|
|
56
|
+
main.display = "block";
|
|
57
|
+
main.float = "left";
|
|
58
|
+
main.width = "100%";
|
|
59
|
+
main.height = `${cell_height_px}px`;
|
|
60
|
+
specs.sort(([a], [b]) => a - b);
|
|
61
|
+
for (let [max_width, width, height] of specs) {
|
|
62
|
+
const node = max_width === 1 ? main : pro(root)[`@media(min-width:${cell_width_px * max_width}px)`][selector];
|
|
63
|
+
width ??= 1;
|
|
64
|
+
let gcd = 100 * width;
|
|
65
|
+
let tmp = max_width;
|
|
66
|
+
while (tmp) {
|
|
67
|
+
[gcd, tmp] = [tmp, gcd % tmp];
|
|
68
|
+
}
|
|
69
|
+
const w_100_per_gcd = 100 * width / gcd;
|
|
70
|
+
node.width = max_width === gcd ? `${w_100_per_gcd}%` : `calc(${w_100_per_gcd}% / ${max_width / gcd})`;
|
|
71
|
+
if (height != null) {
|
|
72
|
+
node.height = `${cell_height_px * height}px`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
console.log(root);
|
|
76
|
+
};
|
|
53
77
|
var csv_parse = (csv, separator = ",") => {
|
|
54
78
|
const main_pattern = /\n|(?<!")("(?:[^"]|"")*")(?!")/g;
|
|
55
79
|
const line_pattern = new RegExp(`${separator}|(?<!")\\s*"((?:[^"]|"")*)"\\s*(?!")`, "g");
|
|
@@ -134,7 +158,7 @@ var _h = (namespace_uri) => {
|
|
|
134
158
|
}
|
|
135
159
|
}
|
|
136
160
|
}
|
|
137
|
-
} else if (is_string(arg)) {
|
|
161
|
+
} else if (is_string(arg) || is_number(arg)) {
|
|
138
162
|
child = document.createTextNode(arg);
|
|
139
163
|
}
|
|
140
164
|
if (child != null) {
|
|
@@ -214,6 +238,7 @@ export {
|
|
|
214
238
|
uuid_v1,
|
|
215
239
|
svg_use,
|
|
216
240
|
s,
|
|
241
|
+
rwd,
|
|
217
242
|
pro,
|
|
218
243
|
pl_ural,
|
|
219
244
|
pick,
|
package/package.json
CHANGED
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
"nnn",
|
|
27
27
|
"omit",
|
|
28
28
|
"pick",
|
|
29
|
+
"RWD",
|
|
30
|
+
"Responsive Web Design",
|
|
29
31
|
"SVG",
|
|
30
32
|
"typography",
|
|
31
33
|
"uuid",
|
|
@@ -36,5 +38,5 @@
|
|
|
36
38
|
"name": "@jackens/nnn",
|
|
37
39
|
"type": "module",
|
|
38
40
|
"types": "nnn.d.ts",
|
|
39
|
-
"version": "2025.
|
|
41
|
+
"version": "2025.11.4"
|
|
40
42
|
}
|
package/readme.md
CHANGED
|
@@ -53,6 +53,7 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
53
53
|
- [`pick`](#pick): Runtime implementation of TypeScript’s `Pick` (see also `omit`).
|
|
54
54
|
- [`pl_ural`](#pl_ural): Chooses the appropriate Polish noun form based on a numeric value.
|
|
55
55
|
- [`pro`](#pro): A `Proxy`-based helper that safely creates nested structures on access and allows deep assignment without guards.
|
|
56
|
+
- [`rwd`](#rwd): A responsive‑web‑design helper that generates CSS rules for a grid layout.
|
|
56
57
|
- [`s`](#s): A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
|
|
57
58
|
- [`svg_use`](#svg_use): Shorthand for: `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
|
|
58
59
|
- [`uuid_v1`](#uuid_v1): Generates a UUID v1 (time-based) identifier.
|
|
@@ -458,6 +459,11 @@ expect(h('span', 'text').outerHTML).to.deep.equal('<span>text</span>')
|
|
|
458
459
|
expect(h('span', { $innerText: 'text' }).outerHTML).to.deep.equal('<span>text</span>')
|
|
459
460
|
```
|
|
460
461
|
|
|
462
|
+
```ts
|
|
463
|
+
expect(h('span', '42').outerHTML).to.deep.equal('<span>42</span>')
|
|
464
|
+
expect(h('span', 42).outerHTML).to.deep.equal('<span>42</span>')
|
|
465
|
+
```
|
|
466
|
+
|
|
461
467
|
```ts
|
|
462
468
|
expect(h('div', { style: 'margin:0;padding:0' }).outerHTML)
|
|
463
469
|
.to.deep.equal('<div style="margin:0;padding:0"></div>')
|
|
@@ -668,16 +674,25 @@ JavaScript syntax highlighting helper (built on `nanolight`).
|
|
|
668
674
|
#### Usage Examples
|
|
669
675
|
|
|
670
676
|
```ts
|
|
671
|
-
const code_js =
|
|
677
|
+
const code_js = "const answer_to_life_the_universe_and_everything = { 42: 42 }['42'] /* 42 */"
|
|
678
|
+
|
|
679
|
+
console.log(nanolight_js(code_js))
|
|
672
680
|
|
|
673
681
|
expect(nanolight_js(code_js)).to.deep.equal([
|
|
674
682
|
['span', { class: 'keyword' }, 'const'],
|
|
675
683
|
' ',
|
|
676
|
-
['span', { class: 'literal' }, '
|
|
684
|
+
['span', { class: 'literal' }, 'answer_to_life_the_universe_and_everything'],
|
|
677
685
|
' ',
|
|
678
686
|
['span', { class: 'operator' }, '='],
|
|
687
|
+
' { ',
|
|
688
|
+
['span', { class: 'number' }, '42'],
|
|
689
|
+
['span', { class: 'operator' }, ':'],
|
|
679
690
|
' ',
|
|
680
|
-
['span', { class: 'number' }, '42']
|
|
691
|
+
['span', { class: 'number' }, '42'],
|
|
692
|
+
' }[',
|
|
693
|
+
['span', { class: 'string' }, "'42'"],
|
|
694
|
+
'] ',
|
|
695
|
+
['span', { class: 'comment' }, '/* 42 */']
|
|
681
696
|
])
|
|
682
697
|
```
|
|
683
698
|
|
|
@@ -777,6 +792,21 @@ pro(ref).one.two.three.four = 1234
|
|
|
777
792
|
expect(ref).to.deep.equal({ one: { two: { three: { four: 1234 } } } })
|
|
778
793
|
```
|
|
779
794
|
|
|
795
|
+
### rwd
|
|
796
|
+
|
|
797
|
+
```ts
|
|
798
|
+
const rwd: (root: CRoot, selector: string, cell_width_px: number, cell_height_px: number, ...specs: [number, number?, number?][]) => void;
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
A responsive‑web‑design helper that generates CSS rules for a grid layout.
|
|
802
|
+
|
|
803
|
+
- `root` and `selector` specify where to apply the generated rules (see `c`).
|
|
804
|
+
- `cell_width_px` and `cell_height_px` specify the base cell dimensions in pixels.
|
|
805
|
+
- Each entry in `specs` is a tuple of:
|
|
806
|
+
- `max_width`: maximum number of cells in a row (viewport width breakpoint).
|
|
807
|
+
- `width` (optional, default: `1`): number of cells occupied by the element.
|
|
808
|
+
- `height` (optional): number of cells in height occupied by the element.
|
|
809
|
+
|
|
780
810
|
### s
|
|
781
811
|
|
|
782
812
|
```ts
|
|
@@ -812,7 +842,6 @@ Shorthand for: `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
|
|
|
812
842
|
|
|
813
843
|
```ts
|
|
814
844
|
const uuid_v1: (date?: Date, node?: string) => string;
|
|
815
|
-
export {};
|
|
816
845
|
```
|
|
817
846
|
|
|
818
847
|
Generates a UUID v1 (time-based) identifier.
|