@cssdoc/core 0.2.0 → 0.3.1
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/dist/index.d.mts +139 -29
- package/dist/index.mjs +292 -303
- package/package.json +4 -5
- package/grammar/CssDoc.grammarkdown +0 -406
package/dist/index.d.mts
CHANGED
|
@@ -26,8 +26,30 @@
|
|
|
26
26
|
interface ModifierConvention {
|
|
27
27
|
/** The structural form. An open union — further forms may be added without a breaking change. */
|
|
28
28
|
structure: "chained" | "suffix" | "attribute";
|
|
29
|
-
/**
|
|
30
|
-
|
|
29
|
+
/**
|
|
30
|
+
* The prefix/delimiter, interpreted per {@link ModifierConvention.structure}. May be a single
|
|
31
|
+
* string or several — any one of which marks a modifier. Separators are matched literally.
|
|
32
|
+
*/
|
|
33
|
+
separator: string | string[];
|
|
34
|
+
/**
|
|
35
|
+
* The delimiter that marks a **BEM-style element** inside the base class name (e.g. `"__"` in
|
|
36
|
+
* `.block__element`). When set (`suffix` structure only), a matching class is recorded as a
|
|
37
|
+
* {@link https://cssdoc.dev part} rather than a modifier. Its own modifiers
|
|
38
|
+
* (`.block__element--mod`) are captured as part of the element name for now.
|
|
39
|
+
*/
|
|
40
|
+
elementSeparator?: string | string[];
|
|
41
|
+
/**
|
|
42
|
+
* Class prefixes that mark a **state** rather than a modifier (e.g. `["is-", "has-"]`). A class
|
|
43
|
+
* chained to the base whose name starts with one of these is recorded as a state, and is never
|
|
44
|
+
* treated as a modifier. Opt-in; no preset sets it by default.
|
|
45
|
+
*/
|
|
46
|
+
statePrefixes?: string[];
|
|
47
|
+
/**
|
|
48
|
+
* Native pseudo-classes (without the `:`) to recognize as states when they appear on the base,
|
|
49
|
+
* e.g. `["disabled", "checked"]`. Defaults to {@link DEFAULT_STATE_PSEUDO_CLASSES} — a curated set
|
|
50
|
+
* of form/UI states, deliberately excluding ubiquitous interaction pseudos (`:hover`, `:focus`).
|
|
51
|
+
*/
|
|
52
|
+
statePseudoClasses?: string[];
|
|
31
53
|
/**
|
|
32
54
|
* Split the modifier body into `prop`/`value` on {@link ModifierConvention.propValueSeparator}?
|
|
33
55
|
* Defaults to `false`. Ignored for `attribute` (which always derives `prop` from the attribute name
|
|
@@ -37,11 +59,18 @@ interface ModifierConvention {
|
|
|
37
59
|
/** The separator for the `prop`/`value` split. Defaults to `-`. */
|
|
38
60
|
propValueSeparator?: string;
|
|
39
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* The pseudo-classes cssdoc treats as component states by default — form and UI states a component
|
|
64
|
+
* meaningfully declares. Ubiquitous interaction pseudos (`:hover`, `:focus`, `:active`) are omitted so
|
|
65
|
+
* incidental rules don't become documented states; add them via `statePseudoClasses` if you want them.
|
|
66
|
+
*/
|
|
67
|
+
declare const DEFAULT_STATE_PSEUDO_CLASSES: readonly string[];
|
|
40
68
|
/** The built-in convention presets. Other schemes use the custom object (see the docs). */
|
|
41
69
|
declare const MODIFIER_PRESETS: {
|
|
42
|
-
/** BEM / SUIT — `.button--primary`. The default. */readonly bem: {
|
|
70
|
+
/** BEM / SUIT — `.button--primary`, with `.button__element` sub-elements. The default. */readonly bem: {
|
|
43
71
|
readonly structure: "suffix";
|
|
44
72
|
readonly separator: "--";
|
|
73
|
+
readonly elementSeparator: "__";
|
|
45
74
|
readonly propValue: false;
|
|
46
75
|
}; /** rscss — `.button.-color-secondary`, split into `prop`/`value`. */
|
|
47
76
|
readonly rscss: {
|
|
@@ -84,13 +113,60 @@ interface ModifierHit {
|
|
|
84
113
|
*/
|
|
85
114
|
declare class ModifierMatcher {
|
|
86
115
|
readonly convention: ModifierConvention;
|
|
87
|
-
|
|
116
|
+
/** The separator(s), longest-first so overlapping prefixes (e.g. `--` before `-`) match greedily. */
|
|
117
|
+
private readonly separators;
|
|
118
|
+
/** The separators as a non-capturing regex alternation, e.g. `(?:is-|has-)` (or `(?:)` when empty). */
|
|
119
|
+
private readonly sepAlt;
|
|
120
|
+
/** BEM-style element separators (longest-first), or empty when the convention has none. */
|
|
121
|
+
private readonly elementSeparators;
|
|
122
|
+
/** The element separators as a non-capturing alternation, or `""` when there are none. */
|
|
123
|
+
private readonly elementSepAlt;
|
|
124
|
+
/** State-class prefixes (longest-first), or empty when the convention has none. */
|
|
125
|
+
private readonly statePrefixes;
|
|
126
|
+
/** Native pseudo-classes (no `:`) recognized as states. */
|
|
127
|
+
private readonly statePseudoClasses;
|
|
88
128
|
constructor(convention: ModifierConvention);
|
|
129
|
+
/** Does a class name (no leading dot) start with one of the convention's state prefixes? */
|
|
130
|
+
private isStateClass;
|
|
131
|
+
/** Strip a leading chained-class separator from `name` (the longest that matches), else return it. */
|
|
132
|
+
private stripPrefix;
|
|
133
|
+
/** Return the suffix body — the part after the first (longest) non-empty separator occurrence. */
|
|
134
|
+
private stripToBody;
|
|
89
135
|
/**
|
|
90
136
|
* Every modifier attached to `baseNoDot` within one selector. `selector` should have its pseudos
|
|
91
137
|
* already dropped (as `parse.ts`/`index.ts` do); the base is given without its leading dot.
|
|
92
138
|
*/
|
|
93
139
|
modifiersIn(selector: string, baseNoDot: string): ModifierHit[];
|
|
140
|
+
/**
|
|
141
|
+
* Every BEM-style element attached to `baseNoDot` within one selector (`.base<elementSep><name>`),
|
|
142
|
+
* as parts, each with any element-scoped modifiers (`.base__element--mod` → element `base__element`
|
|
143
|
+
* with modifier `mod`). Only meaningful for `suffix` conventions with an `elementSeparator`.
|
|
144
|
+
*/
|
|
145
|
+
elementsIn(selector: string, baseNoDot: string): {
|
|
146
|
+
name: string;
|
|
147
|
+
modifiers: ModifierHit[];
|
|
148
|
+
}[];
|
|
149
|
+
/**
|
|
150
|
+
* Split `.base__element--mod`-style tokens into the element class (`base__element`) and, if a
|
|
151
|
+
* modifier separator follows the element name, the element-scoped modifier.
|
|
152
|
+
*/
|
|
153
|
+
private splitElementModifier;
|
|
154
|
+
/**
|
|
155
|
+
* Every state class chained to `baseNoDot` within one selector — a class whose name starts with one
|
|
156
|
+
* of the convention's {@link ModifierConvention.statePrefixes} (e.g. `.tabs.is-open` → `is-open`).
|
|
157
|
+
* Empty when the convention sets no state prefixes.
|
|
158
|
+
*/
|
|
159
|
+
statesIn(selector: string, baseNoDot: string): {
|
|
160
|
+
name: string;
|
|
161
|
+
}[];
|
|
162
|
+
/**
|
|
163
|
+
* Every native pseudo-class on the selector recognized as a state — a `:name` whose `name` is in the
|
|
164
|
+
* convention's {@link ModifierConvention.statePseudoClasses} (e.g. `.tab:disabled` → `disabled`).
|
|
165
|
+
* Pseudo-elements (`::part`) and pseudos not in the set are ignored.
|
|
166
|
+
*/
|
|
167
|
+
pseudoStatesIn(selector: string): {
|
|
168
|
+
name: string;
|
|
169
|
+
}[];
|
|
94
170
|
/** Derive `prop`/`value` for a modifier `name` (as returned by {@link modifiersIn} or authored). */
|
|
95
171
|
analyze(name: string): {
|
|
96
172
|
prop: string;
|
|
@@ -105,9 +181,15 @@ declare class ModifierMatcher {
|
|
|
105
181
|
* look like a modifier usage of `baseNoDot`? Replaces the old `startsWith("-")` gate.
|
|
106
182
|
*/
|
|
107
183
|
looksLikeUsage(token: string, baseNoDot?: string): boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Classify a host-document class token relative to `baseNoDot`: a `modifier` usage, a `state` class
|
|
186
|
+
* (a `statePrefixes` prefix), a BEM `element` class (`base<elementSep>…`), or `undefined` if it's
|
|
187
|
+
* none of those. Consumer-side linting routes each kind to the right "unknown-…" check.
|
|
188
|
+
*/
|
|
189
|
+
usageKind(token: string, baseNoDot?: string): "modifier" | "state" | "element" | undefined;
|
|
108
190
|
/** Canonicalize an attribute expression (bracket-inner): normalize quotes to double, trim. */
|
|
109
191
|
private normalizeAttribute;
|
|
110
|
-
/** Does an attribute-expression's name carry the convention's required
|
|
192
|
+
/** Does an attribute-expression's name carry one of the convention's required prefixes? */
|
|
111
193
|
private attributeMatches;
|
|
112
194
|
}
|
|
113
195
|
//#endregion
|
|
@@ -191,9 +273,9 @@ declare class CssDocConfiguration {
|
|
|
191
273
|
setSupportForTags(definitions: readonly CssDocTagDefinition[], supported: boolean): void;
|
|
192
274
|
/** Disable support for every standard tag (custom tags added later remain supported). */
|
|
193
275
|
setNoStandardTags(): void;
|
|
194
|
-
/** The names (without `@`) of every standard tag
|
|
276
|
+
/** The names (without `@`) of every standard tag — the canonical vocabulary from `@cssdoc/spec`. */
|
|
195
277
|
static readonly standardTagNames: readonly string[];
|
|
196
|
-
/** A fresh set of the standard tag definitions (new instances on each call). */
|
|
278
|
+
/** A fresh set of the standard tag definitions (new instances on each call), built from the spec. */
|
|
197
279
|
static standardTags(): CssDocTagDefinition[];
|
|
198
280
|
}
|
|
199
281
|
//#endregion
|
|
@@ -242,13 +324,23 @@ interface CssModifier {
|
|
|
242
324
|
interface CssPart {
|
|
243
325
|
/** The part class without the leading dot, e.g. `item`. */
|
|
244
326
|
name: string;
|
|
245
|
-
/** Prose from a `@part`
|
|
327
|
+
/** Prose from a `@part` doc tag, when authored. */
|
|
246
328
|
description?: string;
|
|
329
|
+
/** The part's own modifiers, e.g. `.block__element--active` on a BEM element. Present when non-empty. */
|
|
330
|
+
modifiers?: CssModifier[];
|
|
247
331
|
}
|
|
248
|
-
/**
|
|
332
|
+
/**
|
|
333
|
+
* How a component state is spelled — the CSSOM custom state `:state(x)`, a native pseudo-class
|
|
334
|
+
* (`:disabled`), or a state class from the convention's `statePrefixes` (`.is-open`). Only `custom`
|
|
335
|
+
* maps to a Custom Elements Manifest `cssStates` entry.
|
|
336
|
+
*/
|
|
337
|
+
type CssStateKind = "custom" | "pseudo-class" | "class";
|
|
338
|
+
/** A component state — from `:state()`, a native pseudo-class, or a state class (`@cssstate`). */
|
|
249
339
|
interface CssState {
|
|
250
|
-
/** The state name, e.g. `open` or `
|
|
340
|
+
/** The state name without its punctuation, e.g. `open`, `selected`, or `disabled`. */
|
|
251
341
|
name: string;
|
|
342
|
+
/** How the state is expressed in CSS. */
|
|
343
|
+
kind: CssStateKind;
|
|
252
344
|
/** Prose from a `@cssstate` doc tag, when authored. */
|
|
253
345
|
description?: string;
|
|
254
346
|
}
|
|
@@ -321,13 +413,14 @@ type CssRecordKind = "component" | "utility" | "rule" | "declaration";
|
|
|
321
413
|
*/
|
|
322
414
|
type CssReleaseStage = "alpha" | "beta" | "experimental" | "internal" | "public";
|
|
323
415
|
/**
|
|
324
|
-
* A node in an authored
|
|
325
|
-
* children
|
|
416
|
+
* A node in an authored structure tree (`@structure`), written as nested CSS: a compound selector for
|
|
417
|
+
* the element and its children (the rules nested inside it). Emitters render the tree and, via
|
|
418
|
+
* {@link toMermaid}, a diagram.
|
|
326
419
|
*/
|
|
327
420
|
interface StructureNode {
|
|
328
|
-
/** The node's selector
|
|
421
|
+
/** The node's compound selector, e.g. `.tabs`, `.tab.-selected`, or `.list:has(.tab)`. */
|
|
329
422
|
selector: string;
|
|
330
|
-
/** Child nodes (one
|
|
423
|
+
/** Child nodes (rules nested one brace level deeper). */
|
|
331
424
|
children: StructureNode[];
|
|
332
425
|
}
|
|
333
426
|
/** One documented CSS record: its base class plus everything derived from the CSS + doc comments. */
|
|
@@ -354,9 +447,11 @@ interface CssDocEntry {
|
|
|
354
447
|
accessibility?: string;
|
|
355
448
|
/** AST-extracted modifiers, annotated with `@modifier` prose where authored. */
|
|
356
449
|
modifiers: CssModifier[];
|
|
357
|
-
/** AST-extracted sub-element parts, annotated with `@part
|
|
450
|
+
/** AST-extracted sub-element parts (class-based), annotated with `@part` prose where authored. */
|
|
358
451
|
parts: CssPart[];
|
|
359
|
-
/**
|
|
452
|
+
/** Shadow-DOM exposed parts (`::part(name)`), from `@csspart` or a `::part()` selector. */
|
|
453
|
+
shadowParts: CssPart[];
|
|
454
|
+
/** States the component reacts to, from `@cssstate`, `:state()`, pseudo-classes, or state classes. */
|
|
360
455
|
states: CssState[];
|
|
361
456
|
/** Named slots the component shell exposes, from `@slot`. */
|
|
362
457
|
slots: CssSlot[];
|
|
@@ -374,8 +469,10 @@ interface CssDocEntry {
|
|
|
374
469
|
conditions: CssCondition[];
|
|
375
470
|
/** `@example` blocks, verbatim. */
|
|
376
471
|
examples: string[];
|
|
377
|
-
/** The authored `@structure`
|
|
472
|
+
/** The authored `@structure` element tree (top-level nodes), when present. */
|
|
378
473
|
structure?: StructureNode[];
|
|
474
|
+
/** An optional prose description leading the `@structure` body, when authored. */
|
|
475
|
+
structureDescription?: string;
|
|
379
476
|
/** `@demo <spec>` (e.g. `self:button`), when authored. */
|
|
380
477
|
demo?: string;
|
|
381
478
|
/** Component-level deprecation replacement text, when authored (the argument to a `@deprecated` tag). */
|
|
@@ -388,6 +485,8 @@ interface CssDocEntry {
|
|
|
388
485
|
*/
|
|
389
486
|
customBlocks?: Record<string, string[]>;
|
|
390
487
|
}
|
|
488
|
+
/** A PostCSS parse function — turns a source string into a Root. Inject one to read a non-CSS dialect. */
|
|
489
|
+
type CssParse = (css: string) => import("postcss").Root;
|
|
391
490
|
/** Options for {@link parseCssDocs}. */
|
|
392
491
|
interface ParseOptions {
|
|
393
492
|
/**
|
|
@@ -404,10 +503,15 @@ interface ParseOptions {
|
|
|
404
503
|
configuration?: CssDocConfiguration;
|
|
405
504
|
/**
|
|
406
505
|
* The modifier convention — how modifier classes are spelled (BEM `.button--primary` by default;
|
|
407
|
-
* `rscss`, `bare`, or a custom
|
|
408
|
-
*
|
|
506
|
+
* `rscss`, `bare`, or a custom `ModifierConvention` for SUIT/CUBE/etc.). Overrides the
|
|
507
|
+
* `configuration`'s convention when both are given.
|
|
409
508
|
*/
|
|
410
509
|
modifierConvention?: ModifierConventionInput;
|
|
510
|
+
/**
|
|
511
|
+
* The PostCSS parser to read `css` with. Defaults to `postcss.parse` (plain CSS). Inject a dialect
|
|
512
|
+
* parser (e.g. `postcss-scss`/`postcss-less` via `@cssdoc/dialects`) to document `.scss`/`.less`.
|
|
513
|
+
*/
|
|
514
|
+
parse?: CssParse;
|
|
411
515
|
}
|
|
412
516
|
//#endregion
|
|
413
517
|
//#region src/parse.d.ts
|
|
@@ -488,8 +592,10 @@ interface ParsedDoc {
|
|
|
488
592
|
releaseStage?: CssReleaseStage;
|
|
489
593
|
/** `@modifier` prose, keyed by the modifier class without its dot (e.g. `-color-secondary`). */
|
|
490
594
|
modifiers: Map<string, DocModifier>;
|
|
491
|
-
/** `@part
|
|
595
|
+
/** `@part` descriptions, keyed by the class part name without its dot (e.g. `item`). */
|
|
492
596
|
parts: Map<string, string>;
|
|
597
|
+
/** `@csspart` descriptions (shadow-DOM `::part()`), keyed by the bare part name (e.g. `header`). */
|
|
598
|
+
cssParts: Map<string, string>;
|
|
493
599
|
/** `@cssproperty` declarations. */
|
|
494
600
|
cssProperties: DocCssProperty[];
|
|
495
601
|
/** `@cssstate` descriptions, keyed by state name. */
|
|
@@ -506,8 +612,10 @@ interface ParsedDoc {
|
|
|
506
612
|
conditions: DocCondition[];
|
|
507
613
|
/** `@example` blocks. */
|
|
508
614
|
examples: string[];
|
|
509
|
-
/** `@structure` — the
|
|
615
|
+
/** `@structure` — the nested-CSS body, parsed into a selector tree by {@link parseStructure}. */
|
|
510
616
|
structure?: StructureNode[];
|
|
617
|
+
/** An optional prose description leading the `@structure` body. */
|
|
618
|
+
structureDescription?: string;
|
|
511
619
|
/** The `<replacement>` argument from a `@deprecated` tag. */
|
|
512
620
|
deprecated?: string;
|
|
513
621
|
/** `@demo <spec>`. */
|
|
@@ -539,16 +647,18 @@ declare function parseDocComment(raw: string, configuration?: CssDocConfiguratio
|
|
|
539
647
|
*/
|
|
540
648
|
declare function recordNameOf(commentText: string, configuration?: CssDocConfiguration): string | undefined;
|
|
541
649
|
/**
|
|
542
|
-
* Parse a `@structure` body —
|
|
543
|
-
*
|
|
544
|
-
*
|
|
650
|
+
* Parse a `@structure` body — nested CSS (brace-delimited rules) — into a {@link StructureNode} tree.
|
|
651
|
+
* Each rule's selector becomes a node; nested rules become its children. Because a node is a real
|
|
652
|
+
* compound selector, `:has()` (contains), `:is()` / selector-lists (one-of), and `:not()` (not) express
|
|
653
|
+
* relationships natively. Leaf nodes are written as empty rules (`.tab {}`). A malformed body parses to
|
|
654
|
+
* an empty tree rather than throwing.
|
|
545
655
|
*
|
|
546
656
|
* @example
|
|
547
657
|
* ```
|
|
548
|
-
* .tabs
|
|
549
|
-
* .list
|
|
550
|
-
*
|
|
551
|
-
*
|
|
658
|
+
* .tabs {
|
|
659
|
+
* .list { .tab {} }
|
|
660
|
+
* .panel {}
|
|
661
|
+
* }
|
|
552
662
|
* ```
|
|
553
663
|
*/
|
|
554
664
|
declare function parseStructure(raw: string): StructureNode[];
|
|
@@ -585,4 +695,4 @@ declare function toMermaid(roots: StructureNode[], options?: {
|
|
|
585
695
|
*/
|
|
586
696
|
declare function toJson(model: CssDocEntry[]): string;
|
|
587
697
|
//#endregion
|
|
588
|
-
export { type CssAnimation, type CssCondition, CssDocConfiguration, type CssDocEntry, type CssDocSyntaxKind, CssDocTagDefinition, type CssDocTagDefinitionOptions, type CssFunction, type CssLayer, type CssModifier, type CssPart, type CssPropertyDeclared, type CssRecordKind, type CssReleaseStage, type CssSlot, type CssState, DEFAULT_MODIFIER_CONVENTION, type DocCondition, type DocCssProperty, type DocModifier, MODIFIER_PRESETS, type ModifierConvention, type ModifierConventionInput, type ModifierHit, ModifierMatcher, type ParseOptions, type ParsedDoc, RECORD_TAGS, type StructureNode, parseCssDocs, parseDocComment, parseStructure, recordNameOf, resolveModifierConvention, stripCommentFraming, toJson, toMermaid };
|
|
698
|
+
export { type CssAnimation, type CssCondition, CssDocConfiguration, type CssDocEntry, type CssDocSyntaxKind, CssDocTagDefinition, type CssDocTagDefinitionOptions, type CssFunction, type CssLayer, type CssModifier, type CssParse, type CssPart, type CssPropertyDeclared, type CssRecordKind, type CssReleaseStage, type CssSlot, type CssState, DEFAULT_MODIFIER_CONVENTION, DEFAULT_STATE_PSEUDO_CLASSES, type DocCondition, type DocCssProperty, type DocModifier, MODIFIER_PRESETS, type ModifierConvention, type ModifierConventionInput, type ModifierHit, ModifierMatcher, type ParseOptions, type ParsedDoc, RECORD_TAGS, type StructureNode, parseCssDocs, parseDocComment, parseStructure, recordNameOf, resolveModifierConvention, stripCommentFraming, toJson, toMermaid };
|