@fusion.dev/helix-docs 0.186.1 → 0.188.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/content/building-on-the-headless-tier.mdx +42 -0
- package/content/coding-agents.mdx +96 -41
- package/content/metrics.mdx +221 -221
- package/content/using-helix-with-an-agent.mdx +70 -61
- package/dist/index.d.ts +3 -4
- package/dist/index.js +2 -3
- package/dist/pages.generated.js +1 -1
- package/dist/reference.d.ts +14 -13
- package/dist/reference.js +13 -7
- package/dist/sources.generated.js +429 -323
- package/package.json +9 -9
- package/dist/catalog.d.ts +0 -194
- package/dist/catalog.js +0 -163
- package/dist/naming.d.ts +0 -14
- package/dist/naming.js +0 -8
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-docs",
|
|
3
3
|
"description": "Versioned documentation content and registry for Helix.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.188.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
},
|
|
37
37
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@fusion.dev/helix": "0.
|
|
40
|
-
"@fusion.dev/helix-cem": "0.
|
|
41
|
-
"@fusion.dev/helix-headless": "0.
|
|
42
|
-
"@fusion.dev/helix-icons": "0.
|
|
43
|
-
"@fusion.dev/helix-map": "0.
|
|
44
|
-
"@fusion.dev/helix-styles": "0.
|
|
45
|
-
"@fusion.dev/helix-testing": "0.
|
|
46
|
-
"@fusion.dev/helix-theme": "0.
|
|
39
|
+
"@fusion.dev/helix": "0.188.0",
|
|
40
|
+
"@fusion.dev/helix-cem": "0.188.0",
|
|
41
|
+
"@fusion.dev/helix-headless": "0.188.0",
|
|
42
|
+
"@fusion.dev/helix-icons": "0.188.0",
|
|
43
|
+
"@fusion.dev/helix-map": "0.188.0",
|
|
44
|
+
"@fusion.dev/helix-styles": "0.188.0",
|
|
45
|
+
"@fusion.dev/helix-testing": "0.188.0",
|
|
46
|
+
"@fusion.dev/helix-theme": "0.188.0",
|
|
47
47
|
"@fusion.dev/scripts": "0.0.0-dev",
|
|
48
48
|
"lit": "^3.2.1",
|
|
49
49
|
"playwright": "^1.63.0"
|
package/dist/catalog.d.ts
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The component catalog: manifests and example markup, as one shape a reader
|
|
3
|
-
* can render.
|
|
4
|
-
*
|
|
5
|
-
* **Pure, and it lives here for the same reason `reference()` does.** Reading
|
|
6
|
-
* the manifests and the `.examples/*.html` files off disk is the caller's job,
|
|
7
|
-
* because a content package that touched the filesystem would trace itself
|
|
8
|
-
* into every consumer's server bundle.
|
|
9
|
-
*
|
|
10
|
-
* Two sources and no third: the manifests describe the API, and the example
|
|
11
|
-
* files hold the markup. Nothing about a component is written down here, which
|
|
12
|
-
* is what keeps a site from drifting away from the library it documents.
|
|
13
|
-
*/
|
|
14
|
-
import type { HelixManifest } from '@fusion.dev/helix-cem';
|
|
15
|
-
export interface ApiMember {
|
|
16
|
-
description: string;
|
|
17
|
-
name: string;
|
|
18
|
-
/**
|
|
19
|
-
* Where the platform feature this is built on is specified, if it is one.
|
|
20
|
-
*
|
|
21
|
-
* Optional here and required on `PropertyDoc`, because a property always has
|
|
22
|
-
* the field even when it is empty and a slot or a part is built on nothing.
|
|
23
|
-
* It is on the member rather than only on the property so the Read table can
|
|
24
|
-
* carry a mark: `form` and `labels` are read-only and are the two members in
|
|
25
|
-
* the library that most need one.
|
|
26
|
-
*/
|
|
27
|
-
references?: {
|
|
28
|
-
label: string;
|
|
29
|
-
url: string;
|
|
30
|
-
}[];
|
|
31
|
-
type: string;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* A property, which carries a default where an attribute does not.
|
|
35
|
-
*
|
|
36
|
-
* Separate from `ApiMember` rather than an optional field on it, because a slot
|
|
37
|
-
* and a CSS part have no default and a column of empty cells is a table saying
|
|
38
|
-
* the data is missing rather than that the concept does not apply.
|
|
39
|
-
*/
|
|
40
|
-
export interface PropertyDoc {
|
|
41
|
-
default: string;
|
|
42
|
-
description: string;
|
|
43
|
-
name: string;
|
|
44
|
-
/** Whether it is a getter, so a reader is not invited to set it. */
|
|
45
|
-
readonly: boolean;
|
|
46
|
-
/** Where the platform feature this is built on is specified. */
|
|
47
|
-
references: {
|
|
48
|
-
label: string;
|
|
49
|
-
url: string;
|
|
50
|
-
}[];
|
|
51
|
-
type: string;
|
|
52
|
-
}
|
|
53
|
-
export interface EventDoc {
|
|
54
|
-
description: string;
|
|
55
|
-
name: string;
|
|
56
|
-
reactProp: string;
|
|
57
|
-
type: string;
|
|
58
|
-
}
|
|
59
|
-
export interface Element {
|
|
60
|
-
attributes: ApiMember[];
|
|
61
|
-
cssParts: ApiMember[];
|
|
62
|
-
cssProperties: ApiMember[];
|
|
63
|
-
cssStates: ApiMember[];
|
|
64
|
-
description: string;
|
|
65
|
-
/**
|
|
66
|
-
* The entry that registers the element, under the tier's package: the
|
|
67
|
-
* family's own, such as `filter-input`, or one of its own where the family's
|
|
68
|
-
* leaves it out, such as `filter-input/menu`.
|
|
69
|
-
*/
|
|
70
|
-
entry: string;
|
|
71
|
-
events: EventDoc[];
|
|
72
|
-
label: string;
|
|
73
|
-
methods: ApiMember[];
|
|
74
|
-
/** Role within the family. `Root` for its primary element. */
|
|
75
|
-
part: string;
|
|
76
|
-
properties: PropertyDoc[];
|
|
77
|
-
slots: ApiMember[];
|
|
78
|
-
summary: string;
|
|
79
|
-
tagName: string;
|
|
80
|
-
tier: 'headless' | 'styled';
|
|
81
|
-
}
|
|
82
|
-
export interface Example {
|
|
83
|
-
/** The example's own stylesheet, or empty where it needs none. */
|
|
84
|
-
css: string;
|
|
85
|
-
/** One line from the example's `@summary` comment, or empty where unwritten. */
|
|
86
|
-
description: string;
|
|
87
|
-
html: string;
|
|
88
|
-
label: string;
|
|
89
|
-
/**
|
|
90
|
-
* The frame layout this example asks for, where it asks for one.
|
|
91
|
-
*
|
|
92
|
-
* Absent on almost every example, which is the design rather than an
|
|
93
|
-
* oversight: the reference picks `centered` and only the exceptions say
|
|
94
|
-
* otherwise, so what is written down is the handful of facts that differ
|
|
95
|
-
* rather than a table of defaults kept by hand. A consumer that has no
|
|
96
|
-
* layouts can ignore it.
|
|
97
|
-
*/
|
|
98
|
-
layout?: string;
|
|
99
|
-
/**
|
|
100
|
-
* The least height the preview pane should give this example, in pixels.
|
|
101
|
-
*
|
|
102
|
-
* Present on the six overlay families and nowhere else. Height is derived
|
|
103
|
-
* from what the frame drew, so a declared one is a fact that can go stale;
|
|
104
|
-
* these are the examples where there is nothing to derive, because what they
|
|
105
|
-
* open is `position: fixed` and excluded from measurement by design.
|
|
106
|
-
*/
|
|
107
|
-
min?: number;
|
|
108
|
-
slug: string;
|
|
109
|
-
/**
|
|
110
|
-
* The same example authored in TSX, which is a file and never a conversion.
|
|
111
|
-
*
|
|
112
|
-
* **Both syntaxes are authored, neither derived.** A derived example is a
|
|
113
|
-
* function of its twin rather than a thing anybody wrote, and converting the
|
|
114
|
-
* HTML mechanically does not work: an example carrying a `<script>` becomes
|
|
115
|
-
* a JSX fragment with a `<script>` in it, which is a syntax error rather
|
|
116
|
-
* than a bad example.
|
|
117
|
-
*
|
|
118
|
-
* `helix component`'s `examples-paired` holds the two files to each other and
|
|
119
|
-
* `check:spec:visual-parity` holds the two pictures to each other.
|
|
120
|
-
*/
|
|
121
|
-
tsx: string;
|
|
122
|
-
/**
|
|
123
|
-
* Which tier the example shows, read from what it renders.
|
|
124
|
-
*
|
|
125
|
-
* Off the markup rather than off the filename, the same test `helix component`'s `tokens`
|
|
126
|
-
* uses to know a headless example's stylesheet may write raw values: an
|
|
127
|
-
* example is a headless one when it renders a `helix-headless-` element.
|
|
128
|
-
* Both tiers call theirs `preview.html`, the package directory carrying the
|
|
129
|
-
* tier, so the name cannot answer and this is the only fact available.
|
|
130
|
-
*/
|
|
131
|
-
tier: 'headless' | 'styled';
|
|
132
|
-
}
|
|
133
|
-
export interface Family {
|
|
134
|
-
aliases: string[];
|
|
135
|
-
/** What the component is for, from `@category`. The gallery groups on it. */
|
|
136
|
-
category: string;
|
|
137
|
-
documentation: string;
|
|
138
|
-
elements: Element[];
|
|
139
|
-
examples: Example[];
|
|
140
|
-
/**
|
|
141
|
-
* The entries of other families whose elements a page writes inside this
|
|
142
|
-
* one, such as `option` for Select: the family does not register them, so
|
|
143
|
-
* the page imports them beside it. The reference's usage lists them under
|
|
144
|
-
* the family's own entries.
|
|
145
|
-
*
|
|
146
|
-
* Read from the import lines the family's descriptions show, where each
|
|
147
|
-
* container says what to import beside it. See "A container does not
|
|
148
|
-
* register another family's children" in `helix/CONVENTIONS.md`.
|
|
149
|
-
*/
|
|
150
|
-
imports: string[];
|
|
151
|
-
label: string;
|
|
152
|
-
since: string;
|
|
153
|
-
slug: string;
|
|
154
|
-
/** The family's source directory, relative to the repository root. */
|
|
155
|
-
source: string;
|
|
156
|
-
status: string;
|
|
157
|
-
summary: string;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* One example as it sits on disk, before this decides what to call it.
|
|
161
|
-
*
|
|
162
|
-
* An example is up to two files, `<slug>.html` and an optional `<slug>.css`.
|
|
163
|
-
* The HTML is the list: a stylesheet on its own is not an example, and
|
|
164
|
-
* `helix component`'s `examples` fails on one whose markup is missing rather than showing a
|
|
165
|
-
* sandbox with a stylesheet and nothing to style.
|
|
166
|
-
*
|
|
167
|
-
* The pair is what the sandbox already shows, `index.html` beside `styles.css`,
|
|
168
|
-
* so the second file is the one the reader is looking at rather than a build
|
|
169
|
-
* step. Never an inline `style` attribute instead: it is unreachable from a
|
|
170
|
-
* stylesheet, cannot express a hover or a media query, and teaches a reader to
|
|
171
|
-
* write the one thing the library exists to avoid.
|
|
172
|
-
*/
|
|
173
|
-
export interface ExampleSource {
|
|
174
|
-
css: string;
|
|
175
|
-
/** Family folder the example was found in. */
|
|
176
|
-
family: string;
|
|
177
|
-
html: string;
|
|
178
|
-
/** File name without its extension: `preview`, `headless`, `cards.headless`. */
|
|
179
|
-
slug: string;
|
|
180
|
-
/** The authored TSX beside the HTML, never a conversion of it. */
|
|
181
|
-
tsx: string;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Every family across the given manifests, alphabetical, each with its elements
|
|
185
|
-
* and examples.
|
|
186
|
-
*
|
|
187
|
-
* The family a declaration belongs to comes from where its file is rather than
|
|
188
|
-
* from its tag name, which is the same reasoning `place()` carries for the
|
|
189
|
-
* reference: `helix-button-group` is one family and `helix-tab` is a part
|
|
190
|
-
* of another, and nothing in the name says which.
|
|
191
|
-
*/
|
|
192
|
-
export declare const catalog: (manifests: HelixManifest[], examples?: ExampleSource[]) => Family[];
|
|
193
|
-
/** The family of a given slug, from an already-built catalog. */
|
|
194
|
-
export declare const findInCatalog: (families: Family[], slug: string) => Family | undefined;
|
package/dist/catalog.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { displayName, startCase, tierOf } from './naming.js';
|
|
2
|
-
import { place } from './reference.js';
|
|
3
|
-
const CANONICAL = 'preview';
|
|
4
|
-
const HEADLESS = 'headless';
|
|
5
|
-
const HEADLESS_SUFFIX = /\.headless$/;
|
|
6
|
-
const withoutUndefined = (text) => text
|
|
7
|
-
.split('|')
|
|
8
|
-
.map((part) => part.trim())
|
|
9
|
-
.filter((part) => part !== 'undefined')
|
|
10
|
-
.join(' | ');
|
|
11
|
-
const PLATFORM_CALLBACK = /Callback$/;
|
|
12
|
-
const isPublic = (row) => row.privacy === undefined || row.privacy === 'public';
|
|
13
|
-
const properties = (rows) => (rows ?? [])
|
|
14
|
-
.filter((row) => row.kind === 'field' && isPublic(row) && row.static !== true)
|
|
15
|
-
.map((row) => ({
|
|
16
|
-
default: row.default === 'undefined' ? '' : (row.default ?? ''),
|
|
17
|
-
description: row.description ?? '',
|
|
18
|
-
name: row.name ?? '',
|
|
19
|
-
readonly: row.readonly === true,
|
|
20
|
-
references: row.helix?.references ?? [],
|
|
21
|
-
type: withoutUndefined(row.type?.text ?? ''),
|
|
22
|
-
}));
|
|
23
|
-
const methods = (rows) => (rows ?? [])
|
|
24
|
-
.filter((row) => row.kind === 'method' && isPublic(row) && !PLATFORM_CALLBACK.test(row.name ?? ''))
|
|
25
|
-
.map((row) => {
|
|
26
|
-
const args = (row.parameters ?? [])
|
|
27
|
-
.map((arg) => `${arg.name ?? ''}: ${arg.type?.text ?? 'unknown'}`)
|
|
28
|
-
.join(', ');
|
|
29
|
-
return {
|
|
30
|
-
description: row.description ?? '',
|
|
31
|
-
name: row.name ?? '',
|
|
32
|
-
type: `(${args}) => ${row.return?.type?.text ?? 'void'}`,
|
|
33
|
-
};
|
|
34
|
-
});
|
|
35
|
-
const members = (rows) => (rows ?? []).map((row) => ({
|
|
36
|
-
description: row.description ?? '',
|
|
37
|
-
name: row.name ?? '',
|
|
38
|
-
type: withoutUndefined(row.type?.text ?? ''),
|
|
39
|
-
}));
|
|
40
|
-
const ANNOTATION = /^[^\S\n]*<!--\s*@[\s\S]*?-->[^\S\n]*\n?/gm;
|
|
41
|
-
const withoutAnnotations = (html) => html.replace(ANNOTATION, '').trimStart();
|
|
42
|
-
const examplesOf = (slug, declared, sources) => {
|
|
43
|
-
const described = new Map((declared?.examples ?? []).map((entry) => [entry.slug ?? '', entry.description ?? '']));
|
|
44
|
-
const layouts = new Map((declared?.examples ?? []).map((entry) => [entry.slug ?? '', entry.layout ?? '']));
|
|
45
|
-
const minimums = new Map((declared?.examples ?? []).map((entry) => [entry.slug ?? '', entry.min ?? 0]));
|
|
46
|
-
return (sources
|
|
47
|
-
.filter((source) => source.family === slug)
|
|
48
|
-
.sort((a, b) => {
|
|
49
|
-
const pairOf = (slug) => slug === HEADLESS ? CANONICAL : slug.replace(HEADLESS_SUFFIX, '');
|
|
50
|
-
const twin = (slug) => (slug === HEADLESS || HEADLESS_SUFFIX.test(slug) ? 1 : 0);
|
|
51
|
-
const left = pairOf(a.slug);
|
|
52
|
-
const right = pairOf(b.slug);
|
|
53
|
-
if (left !== right) {
|
|
54
|
-
return left === CANONICAL ? -1 : right === CANONICAL ? 1 : left.localeCompare(right);
|
|
55
|
-
}
|
|
56
|
-
return twin(a.slug) - twin(b.slug);
|
|
57
|
-
})
|
|
58
|
-
.map((source) => {
|
|
59
|
-
const layout = layouts.get(source.slug);
|
|
60
|
-
const min = minimums.get(source.slug);
|
|
61
|
-
const mirrored = source.slug === HEADLESS ? CANONICAL : source.slug.replace(HEADLESS_SUFFIX, '');
|
|
62
|
-
return {
|
|
63
|
-
css: source.css,
|
|
64
|
-
description: described.get(source.slug) ?? '',
|
|
65
|
-
html: withoutAnnotations(source.html),
|
|
66
|
-
label: startCase(mirrored),
|
|
67
|
-
...(layout ? { layout } : {}),
|
|
68
|
-
...(min ? { min } : {}),
|
|
69
|
-
slug: source.slug,
|
|
70
|
-
tier: (source.html.includes('<helix-headless-') ? 'headless' : 'styled'),
|
|
71
|
-
tsx: source.tsx,
|
|
72
|
-
};
|
|
73
|
-
}));
|
|
74
|
-
};
|
|
75
|
-
const entriesOf = (manifest) => {
|
|
76
|
-
const entries = new Map();
|
|
77
|
-
for (const module of manifest.modules ?? []) {
|
|
78
|
-
const entry = /^src\/(.+)\/index\.ts$/.exec(module.path ?? '')?.[1];
|
|
79
|
-
if (!entry) {
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
for (const exported of module.exports ?? []) {
|
|
83
|
-
const from = exported.declaration?.module?.replace(/\.[jt]s$/, '');
|
|
84
|
-
const held = from === undefined ? undefined : entries.get(from);
|
|
85
|
-
if (from !== undefined && (held === undefined || entry.length < held.length)) {
|
|
86
|
-
entries.set(from, entry);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return entries;
|
|
91
|
-
};
|
|
92
|
-
export const catalog = (manifests, examples = []) => {
|
|
93
|
-
const byFamily = new Map();
|
|
94
|
-
const entryOf = new Map();
|
|
95
|
-
for (const manifest of manifests) {
|
|
96
|
-
const entries = entriesOf(manifest);
|
|
97
|
-
for (const module of manifest.modules ?? []) {
|
|
98
|
-
for (const declaration of module.declarations ?? []) {
|
|
99
|
-
if (!declaration.tagName) {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
const { family } = place(module.path);
|
|
103
|
-
if (!family) {
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
byFamily.set(family, [...(byFamily.get(family) ?? []), declaration]);
|
|
107
|
-
entryOf.set(declaration, entries.get((module.path ?? '').replace(/\.[jt]s$/, '')) ?? family);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return [...byFamily.entries()]
|
|
112
|
-
.map(([slug, entries]) => {
|
|
113
|
-
const root = entries.find((entry) => entry.tagName === `helix-${slug}`) ??
|
|
114
|
-
entries[0];
|
|
115
|
-
const named = (tag) => entries.find((entry) => entry.tagName === tag);
|
|
116
|
-
const roots = [named(`helix-${slug}`), named(`helix-${HEADLESS}-${slug}`)].filter((entry) => entry !== undefined);
|
|
117
|
-
return {
|
|
118
|
-
aliases: [...new Set(roots.flatMap((entry) => entry.helix?.aliases ?? []))],
|
|
119
|
-
category: root.helix?.category ?? '',
|
|
120
|
-
documentation: root.helix?.documentation ?? '',
|
|
121
|
-
elements: entries
|
|
122
|
-
.map((entry) => ({
|
|
123
|
-
attributes: members(entry.attributes),
|
|
124
|
-
cssParts: members(entry.cssParts),
|
|
125
|
-
cssProperties: members(entry.cssProperties),
|
|
126
|
-
cssStates: members(entry.cssStates),
|
|
127
|
-
description: entry.description ?? '',
|
|
128
|
-
entry: entryOf.get(entry) ?? slug,
|
|
129
|
-
events: (entry.events ?? []).map((event) => ({
|
|
130
|
-
description: event.description ?? '',
|
|
131
|
-
name: event.name ?? '',
|
|
132
|
-
reactProp: event.reactProp ?? `on${event.name ?? ''}`,
|
|
133
|
-
type: event.type?.text ?? '',
|
|
134
|
-
})),
|
|
135
|
-
label: displayName(entry.tagName),
|
|
136
|
-
methods: methods(entry.members),
|
|
137
|
-
part: entry.helix?.part ?? '',
|
|
138
|
-
properties: properties(entry.members),
|
|
139
|
-
slots: members(entry.slots),
|
|
140
|
-
summary: entry.summary ?? '',
|
|
141
|
-
tagName: entry.tagName,
|
|
142
|
-
tier: tierOf(entry.tagName),
|
|
143
|
-
}))
|
|
144
|
-
.sort((a, b) => Number(a.tier === 'headless') - Number(b.tier === 'headless') ||
|
|
145
|
-
a.tagName.localeCompare(b.tagName)),
|
|
146
|
-
examples: examplesOf(slug, root.helix, examples),
|
|
147
|
-
imports: importsOf(slug, entries),
|
|
148
|
-
label: startCase(slug),
|
|
149
|
-
since: root.helix?.since ?? '',
|
|
150
|
-
slug,
|
|
151
|
-
source: root.helix?.source ?? '',
|
|
152
|
-
status: root.helix?.status ?? '',
|
|
153
|
-
summary: root.summary ?? '',
|
|
154
|
-
};
|
|
155
|
-
})
|
|
156
|
-
.sort((a, b) => a.label.localeCompare(b.label));
|
|
157
|
-
};
|
|
158
|
-
const importsOf = (slug, declarations) => [
|
|
159
|
-
...new Set(declarations.flatMap((declaration) => [...(declaration.description ?? '').matchAll(/import '@fusion\.dev\/helix\/([a-z-]+)'/g)]
|
|
160
|
-
.map((match) => match[1] ?? '')
|
|
161
|
-
.filter((entry) => entry !== '' && entry !== slug))),
|
|
162
|
-
].sort();
|
|
163
|
-
export const findInCatalog = (families, slug) => families.find((family) => family.slug === slug);
|
package/dist/naming.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Display names for components.
|
|
3
|
-
*
|
|
4
|
-
* The product is Helix, so every component being called "HelixCard" inside the
|
|
5
|
-
* Helix site is noise: it repeats the one thing the reader already knows on
|
|
6
|
-
* every row of the sidebar. The tag keeps its prefix, because that is a real
|
|
7
|
-
* identifier a consumer types.
|
|
8
|
-
*/
|
|
9
|
-
/** `app-header` becomes `App Header`, and `qr-code` becomes `QR Code`. */
|
|
10
|
-
export declare const startCase: (slug: string) => string;
|
|
11
|
-
/** `helix-app-header` becomes `App Header`, `helix-headless-card` becomes `Card`. */
|
|
12
|
-
export declare const displayName: (tagName: string) => string;
|
|
13
|
-
/** Which tier a tag belongs to, read from the prefix rather than the manifest. */
|
|
14
|
-
export declare const tierOf: (tagName: string) => 'headless' | 'styled';
|
package/dist/naming.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
const INITIALISMS = new Set(['api', 'css', 'html', 'id', 'qr', 'ui', 'url']);
|
|
2
|
-
export const startCase = (slug) => slug
|
|
3
|
-
.split('-')
|
|
4
|
-
.filter(Boolean)
|
|
5
|
-
.map((word) => INITIALISMS.has(word) ? word.toUpperCase() : word.charAt(0).toUpperCase() + word.slice(1))
|
|
6
|
-
.join(' ');
|
|
7
|
-
export const displayName = (tagName) => startCase(tagName.replace(/^helix-(?:headless-)?/, ''));
|
|
8
|
-
export const tierOf = (tagName) => tagName.startsWith('helix-headless-') ? 'headless' : 'styled';
|