@jackens/nnn 2026.9.30 → 2026.11.16
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 +219 -600
- package/nnn.d.ts +26 -88
- package/nnn.js +135 -270
- package/package.json +14 -10
package/nnn.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Represents a CSS rule node for the {@link c} helper. Keys are CSS properties or nested selectors. */
|
|
2
2
|
export type CNode = {
|
|
3
|
-
[attributeOrSelector: string]: string | number | CNode | undefined
|
|
3
|
+
[attributeOrSelector: string]: string | number | CNode | null | undefined
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
6
|
* A minimal CSS-in-JS helper that converts a JavaScript object hierarchy into a CSS string.
|
|
@@ -10,76 +10,25 @@ export type CNode = {
|
|
|
10
10
|
* An object describing CSS rules.
|
|
11
11
|
* Keys are selectors or at-rules; values are either CSS property values or nested rule objects.
|
|
12
12
|
* Nested selectors are appended to the parent selector as is (e.g. `'.c'` inside `a` → `a.c`), so a leading space is needed for a descendant combinator (e.g. `' .c'` → `a .c`).
|
|
13
|
+
* If a nested selector contains `&`, every `&` is replaced with the parent selector instead (e.g. `'&:hover'` → `a:hover`, `'.c &'` → `.c a`).
|
|
13
14
|
* A selector key may contain comma-separated alternatives (e.g. `'.b,.c'`); when nested, each alternative is combined with each parent alternative (cartesian product), producing a comma-joined selector list (e.g. `'a.b,a.c'`).
|
|
14
|
-
*
|
|
15
|
+
* Commas inside brackets or quotes (e.g. `':is(.b,.c)'`, `'[title="b,c"]'`) do not separate alternatives; whitespace after a separating comma is ignored (use `&` for a descendant combinator in a non-first alternative, e.g. `'.b,& .c'` → `a.b,a .c`).
|
|
16
|
+
* At-rules (e.g. `'@media …'`) wrap their nested rules; an at-rule nested in a selector wraps that selector (e.g. `{ a: { '@media(…)': { color: 'red' } } }` → `@media(…){a{color:red}}`).
|
|
17
|
+
* Inside a top-level `:root` rule nested keys are concatenated into property names (e.g. `{ ':root': { '--': { bg: 'red' } } }` → `:root{--bg:red}`).
|
|
18
|
+
* Properties without a selector (top-level or directly in a top-level at-rule, e.g. `@font-face`) are emitted as bare declarations.
|
|
15
19
|
* `null`/`undefined` values are skipped.
|
|
16
20
|
*
|
|
17
21
|
* @param splitter
|
|
18
22
|
*
|
|
19
23
|
* A delimiter used to create unique keys (default: `'$$'`).
|
|
20
24
|
* The substring from `splitter` to the end of a key is ignored (e.g. `src$$1` → `src`).
|
|
25
|
+
* An empty `splitter` disables this feature.
|
|
21
26
|
*
|
|
22
27
|
* @returns
|
|
23
28
|
*
|
|
24
29
|
* A CSS string representing the compiled rules.
|
|
25
30
|
*/
|
|
26
31
|
export declare const c: (node: CNode, splitter?: string) => string
|
|
27
|
-
/**
|
|
28
|
-
* Options of a {@link createLexer} spec controlling the lexer state stack.
|
|
29
|
-
*
|
|
30
|
-
* @property in
|
|
31
|
-
*
|
|
32
|
-
* State(s) in which the spec is active (default: `'root'`).
|
|
33
|
-
*
|
|
34
|
-
* @property pop
|
|
35
|
-
*
|
|
36
|
-
* Whether to pop the current state off the stack after a match (the `'root'` state at the bottom is never popped).
|
|
37
|
-
*
|
|
38
|
-
* @property push
|
|
39
|
-
*
|
|
40
|
-
* State to push onto the stack after a match (applied after `pop`).
|
|
41
|
-
*/
|
|
42
|
-
export type LexerSpecOptions = {
|
|
43
|
-
in?: string | string[]
|
|
44
|
-
pop?: boolean
|
|
45
|
-
push?: string
|
|
46
|
-
}
|
|
47
|
-
/** A {@link createLexer} spec: a `[metadata, pattern, options?]` tuple. */
|
|
48
|
-
export type LexerSpec<M> = [metadata: M, pattern: string | RegExp, options?: LexerSpecOptions]
|
|
49
|
-
/**
|
|
50
|
-
* A helper for building simple stateful lexers (see also {@link nanolightTs}).
|
|
51
|
-
*
|
|
52
|
-
* @remarks
|
|
53
|
-
*
|
|
54
|
-
* 1. Matches starting at an earlier position take precedence.
|
|
55
|
-
* 2. Among matches at the same position, the longer one wins.
|
|
56
|
-
* 3. Among matches of the same position and length, the one defined earlier wins.
|
|
57
|
-
* 4. Only specs active in the current state (the top of the state stack, initially `'root'`) are considered.
|
|
58
|
-
* 5. Patterns are matched against the whole input, so `^`, `$`, `\b` and lookbehinds see the text around the current position; a sticky (`y`) `RegExp` matches only at the current position.
|
|
59
|
-
* 6. Empty matches are ignored.
|
|
60
|
-
*
|
|
61
|
-
* @param decorator
|
|
62
|
-
*
|
|
63
|
-
* A function that wraps each chunk of the input.
|
|
64
|
-
* It receives the matched text (`chunk`) and the `metadata` of the spec whose pattern produced the match.
|
|
65
|
-
* For unmatched text between matches, `metadata` is `undefined`.
|
|
66
|
-
*
|
|
67
|
-
* @param specs
|
|
68
|
-
*
|
|
69
|
-
* An array of tuples `[metadata, pattern, options?]` where:
|
|
70
|
-
*
|
|
71
|
-
* - `metadata`: arbitrary data (e.g., a CSS class name) passed to `decorator` when the pattern matches.
|
|
72
|
-
* - `pattern`: a `string` (matched literally) or `RegExp` to match against the input.
|
|
73
|
-
* - `options`: optional {@link LexerSpecOptions} (states in which the spec is active and state transitions).
|
|
74
|
-
*
|
|
75
|
-
* @returns
|
|
76
|
-
*
|
|
77
|
-
* A lexer function that accepts an input string and returns an array of decorated chunks covering the whole input (in order).
|
|
78
|
-
*/
|
|
79
|
-
export declare const createLexer: <M, T>(
|
|
80
|
-
decorator: (chunk: string, metadata?: M) => T,
|
|
81
|
-
...specs: LexerSpec<M>[]
|
|
82
|
-
) => (code: string) => T[]
|
|
83
32
|
/** Single argument type for the {@link h} and {@link s} helpers. */
|
|
84
33
|
export type HArgs1 = Record<PropertyKey, unknown> | null | undefined | Node | string | number | HArgs
|
|
85
34
|
/** Tuple argument type for the {@link h} and {@link s} helpers. */
|
|
@@ -97,9 +46,9 @@ export type HArgs = [string | Node, ...HArgs1[]]
|
|
|
97
46
|
* Additional arguments processed as follows:
|
|
98
47
|
*
|
|
99
48
|
* - `Object`: maps attributes/properties.
|
|
100
|
-
* - Keys starting with `$` set element properties (without the `$` prefix); if the value is a plain object, it is shallow-merged into the existing property instead of replacing it (useful e.g. for `$style`).
|
|
101
|
-
* - Other keys set attributes: a key prefixed with `xlink:` sets the attribute via `setAttributeNS` in the
|
|
102
|
-
* A value of `true` sets an empty attribute (e.g. `checked=""`), a value of `false` removes the attribute.
|
|
49
|
+
* - Keys starting with `$` set element properties (without the `$` prefix); if the value is a plain object (created by `{…}` or `Object.create(null)`), it is shallow-merged into the existing property instead of replacing it (useful e.g. for `$style`), other values (including arrays and class instances) replace the property.
|
|
50
|
+
* - Other keys set attributes: a key prefixed with `xlink:`, `xml:` or `xmlns:` sets the attribute via `setAttributeNS` in the corresponding namespace; any other key sets it via `setAttribute`.
|
|
51
|
+
* A value of `true` sets an empty attribute (e.g. `checked=""`), a value of `false` removes the attribute, a value of `null`/`undefined` leaves the attribute unchanged.
|
|
103
52
|
* - `null`/`undefined`: ignored.
|
|
104
53
|
* - `Node`: appended as a child.
|
|
105
54
|
* - `string`/`number`: converted to a `Text` node and appended.
|
|
@@ -111,6 +60,7 @@ export type HArgs = [string | Node, ...HArgs1[]]
|
|
|
111
60
|
*/
|
|
112
61
|
export declare const h: {
|
|
113
62
|
<T extends keyof HTMLElementTagNameMap>(tag: T, ...args: HArgs1[]): HTMLElementTagNameMap[T]
|
|
63
|
+
(tag: string, ...args: HArgs1[]): HTMLElement
|
|
114
64
|
<N extends Node>(node: N, ...args: HArgs1[]): N
|
|
115
65
|
(tagOrNode: string | Node, ...args: HArgs1[]): Node
|
|
116
66
|
}
|
|
@@ -127,9 +77,9 @@ export declare const h: {
|
|
|
127
77
|
* Additional arguments processed as follows:
|
|
128
78
|
*
|
|
129
79
|
* - `Object`: maps attributes/properties.
|
|
130
|
-
* - Keys starting with `$` set element properties (without the `$` prefix); if the value is a plain object, it is shallow-merged into the existing property instead of replacing it.
|
|
131
|
-
* - Other keys set attributes: a key prefixed with `xlink:` sets the attribute via `setAttributeNS` in the
|
|
132
|
-
* A value of `true` sets an empty attribute
|
|
80
|
+
* - Keys starting with `$` set element properties (without the `$` prefix); if the value is a plain object (created by `{…}` or `Object.create(null)`), it is shallow-merged into the existing property instead of replacing it, other values (including arrays and class instances) replace the property.
|
|
81
|
+
* - Other keys set attributes: a key prefixed with `xlink:`, `xml:` or `xmlns:` sets the attribute via `setAttributeNS` in the corresponding namespace (e.g. `xml:lang`); any other key sets it via `setAttribute`.
|
|
82
|
+
* A value of `true` sets an empty attribute, a value of `false` removes the attribute, a value of `null`/`undefined` leaves the attribute unchanged.
|
|
133
83
|
* - `null`/`undefined`: ignored.
|
|
134
84
|
* - `Node`: appended as a child.
|
|
135
85
|
* - `string`/`number`: converted to a `Text` node and appended.
|
|
@@ -141,6 +91,7 @@ export declare const h: {
|
|
|
141
91
|
*/
|
|
142
92
|
export declare const s: {
|
|
143
93
|
<T extends keyof SVGElementTagNameMap>(tag: T, ...args: HArgs1[]): SVGElementTagNameMap[T]
|
|
94
|
+
(tag: string, ...args: HArgs1[]): SVGElement
|
|
144
95
|
<N extends Node>(node: N, ...args: HArgs1[]): N
|
|
145
96
|
(tagOrNode: string | Node, ...args: HArgs1[]): Node
|
|
146
97
|
}
|
|
@@ -150,7 +101,7 @@ export declare const s: {
|
|
|
150
101
|
* Equivalent to:
|
|
151
102
|
*
|
|
152
103
|
* ```ts
|
|
153
|
-
* s('svg', ['use', {
|
|
104
|
+
* s('svg', ['use', { href: '#' + id }], ...args)
|
|
154
105
|
* ```
|
|
155
106
|
*
|
|
156
107
|
* @param id
|
|
@@ -166,23 +117,6 @@ export declare const s: {
|
|
|
166
117
|
* An `SVGSVGElement` containing a `<use>` element.
|
|
167
118
|
*/
|
|
168
119
|
export declare const svgUse: (id: string, ...args: HArgs1[]) => SVGSVGElement
|
|
169
|
-
/**
|
|
170
|
-
* A Monokai-inspired color scheme for use with the {@link c} helper and {@link nanolightTs} lexer.
|
|
171
|
-
* It styles `pre` and `code>span` elements with the class names produced by {@link nanolightTs} (with light, dark and print variants).
|
|
172
|
-
*/
|
|
173
|
-
export declare const monokai: CNode
|
|
174
|
-
/**
|
|
175
|
-
* A TypeScript/JavaScript syntax highlighting lexer built using {@link createLexer}.
|
|
176
|
-
*
|
|
177
|
-
* @param code
|
|
178
|
-
*
|
|
179
|
-
* The source code string to tokenize.
|
|
180
|
-
*
|
|
181
|
-
* @returns
|
|
182
|
-
*
|
|
183
|
-
* An array of {@link HArgs1} elements suitable for rendering with {@link h}: plain `string`s for unrecognized text (e.g. whitespace) and `['span', { class }, chunk]` tuples for recognized tokens (class names are styled by {@link monokai}).
|
|
184
|
-
*/
|
|
185
|
-
export declare const nanolightTs: (code: string) => HArgs1[]
|
|
186
120
|
/**
|
|
187
121
|
* A responsive web design helper that generates CSS rules for a grid-like layout of floating elements.
|
|
188
122
|
* It modifies `root` in place: it sets base styles for `selector` and adds a `@media(min-width:…px)` rule for each breakpoint.
|
|
@@ -197,24 +131,28 @@ export declare const nanolightTs: (code: string) => HArgs1[]
|
|
|
197
131
|
*
|
|
198
132
|
* @param cellWidthPx
|
|
199
133
|
*
|
|
200
|
-
* The base cell width in pixels.
|
|
134
|
+
* The base cell width in pixels (a positive number).
|
|
201
135
|
*
|
|
202
136
|
* @param cellHeightPx
|
|
203
137
|
*
|
|
204
|
-
* The base cell height in pixels.
|
|
138
|
+
* The base cell height in pixels (a positive number).
|
|
205
139
|
*
|
|
206
140
|
* @param specs
|
|
207
141
|
*
|
|
208
|
-
* An array of breakpoint specifications, each a tuple of:
|
|
142
|
+
* An array of breakpoint specifications, each a tuple of positive integers:
|
|
209
143
|
*
|
|
210
|
-
* - `
|
|
211
|
-
* - `width` (optional, default `1`): number of horizontal cells the element spans.
|
|
144
|
+
* - `columns`: number of cells per row; the breakpoint is `min-width: cellWidthPx * columns` (`1` modifies the base rule).
|
|
145
|
+
* - `width` (optional, default `1`, at most `columns`): number of horizontal cells the element spans.
|
|
212
146
|
* - `height` (optional, default `1`): number of vertical cells the element spans.
|
|
147
|
+
*
|
|
148
|
+
* @throws
|
|
149
|
+
*
|
|
150
|
+
* A `RangeError` if any of the numeric arguments is out of range.
|
|
213
151
|
*/
|
|
214
152
|
export declare const rwd: (
|
|
215
153
|
root: CNode,
|
|
216
154
|
selector: string,
|
|
217
155
|
cellWidthPx: number,
|
|
218
156
|
cellHeightPx: number,
|
|
219
|
-
...specs: [number, number
|
|
157
|
+
...specs: [columns: number, width?: number, height?: number][]
|
|
220
158
|
) => void
|