Skip to content

Commit 23f37f9

Browse files
authored
Merge pull request #83 from webcomponents-preview/feature/nested-nav-groups
Feature/nested nav groups
2 parents cc5b7aa + 141782f commit 23f37f9

File tree

111 files changed

+1047
-1155
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+1047
-1155
lines changed

custom-elements-manifest.config.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { customElementGroupingPlugin } from '@webcomponents-preview/cem-plugin-g
99
export default {
1010
packagejson: true,
1111
litelement: true,
12-
globs: ['src/components/**/*.{component,plugin}.ts', 'src/components/**/EXAMPLES.md'],
12+
globs: ['src/**/*.{component,plugin}.ts', 'src/**/EXAMPLES.md'],
1313
outdir: 'dist',
1414
plugins: [
1515
customElementExamplesPlugin(),
@@ -23,8 +23,11 @@ export default {
2323
}),
2424
customElementGroupingPlugin({
2525
addGroups(componentPath) {
26-
const [, , group] = componentPath?.split('/') || [];
27-
return [group];
26+
const path = componentPath?.split('/') || [];
27+
const [, type, category, sub] = path;
28+
const group = `${type}/${category}`;
29+
30+
return path.length > 5 ? [`${group}/${sub}`] : [group];
2831
},
2932
}),
3033
],

scripts/separate-examples.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { readFile, writeFile } from 'node:fs/promises';
2+
import { basename, dirname } from 'node:path';
3+
import { cwd } from 'node:process';
4+
import { parseArgs } from 'node:util';
5+
6+
import glob from 'fast-glob';
7+
import prettier from 'prettier';
8+
9+
/**
10+
* Finds all examples in the component files and extracts them to a separate markdown file.
11+
* A markdown file named `EXAMPLES.md` is created for each component in the same directory
12+
* as the component file if examples have been found. Found examples will be removed from the
13+
* component files after extraction.
14+
*
15+
* For now, only one positional argument is supported, which is the glob pattern to match
16+
* the component files to look up. Any valid glob pattern of `fast-glob` is supported.
17+
* This script is meant to be run manually, see usage below.
18+
*
19+
* @usage node --loader ts-node/esm --no-warnings scripts/separate-examples.ts src/{components,plugins}/**\/*.ts
20+
* @link https://github.com/mrmlnc/fast-glob?tab=readme-ov-file#pattern-syntax
21+
*/
22+
23+
// todo expose options as cli arguments
24+
const examplesFileName = 'EXAMPLES.md';
25+
const removeFromComponent = true;
26+
const skipEmpty = true;
27+
const silent = false;
28+
29+
const { positionals: paths } = parseArgs({ allowPositionals: true });
30+
const componentPaths = await glob(paths, { cwd: cwd(), absolute: true, onlyFiles: true });
31+
32+
componentPaths.forEach(async (componentPath) => {
33+
const componentName = basename(componentPath);
34+
const content = await readFile(componentPath, 'utf-8');
35+
const matchAnyAnnotation = /\*\s+@(\w+)\s*\n*/;
36+
const matchExampleAnnotation = /\*\s+@example\s*\n*/;
37+
const matchJsDocEnd = /\*\//;
38+
const matchAnything = /[\s\S]*/;
39+
40+
// prepare match for examples
41+
const matchExamples = new RegExp(
42+
`(?<=${matchExampleAnnotation.source})(${matchAnything.source}?)(?:(?=${matchJsDocEnd.source})|(?=${matchAnyAnnotation.source}))`,
43+
'g',
44+
);
45+
const examples = Array
46+
// find all examples
47+
.from(content.matchAll(matchExamples))
48+
// remove leading asterisks and trim
49+
.map(([, match]) => match.replace(/^\s*\*\s/gm, '').trim());
50+
51+
// skip if no examples found
52+
if (skipEmpty && !examples.length) {
53+
if (!silent) console.info(`No examples found in ${componentName}`);
54+
return;
55+
}
56+
57+
// write examples to markdown file
58+
const componentDir = dirname(componentPath);
59+
const examplesPath = `${componentDir}/${examplesFileName}`;
60+
61+
// store prettified and joined examples
62+
let examplesContent = examples.join('\n\n\n');
63+
examplesContent = await prettier.format(examplesContent, { filepath: examplesPath });
64+
await writeFile(examplesPath, examplesContent, 'utf-8');
65+
66+
if (removeFromComponent) {
67+
// remove found examples from component file
68+
const replaceExamples = new RegExp(
69+
`(${matchExampleAnnotation.source}(${matchAnything.source}?))(?:(?=${matchJsDocEnd.source})|(?=${matchAnyAnnotation.source}))`,
70+
'g',
71+
);
72+
const cleanedContent = content
73+
// remove the examples
74+
.replace(replaceExamples, '')
75+
// remove now eventually empty block comment
76+
.replace(/^\/\*\*\s*\n\s*\*\/\s*\n/m, '');
77+
await writeFile(componentPath, cleanedContent, 'utf-8');
78+
}
79+
80+
// notify
81+
if (!silent) {
82+
console.info(`Separated ${examples.length} example${examples.length > 1 ? 's' : ''} from ${componentName}`);
83+
}
84+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
### Shows arbitrary HTML code example
2+
3+
```html
4+
<wcp-markdown-example>
5+
<pre slot="code">
6+
&lt;h1&gt;Readme&lt;/h1&gt;
7+
&lt;p&gt;Some readme content&lt;/p&gt;
8+
</pre>
9+
<div slot="preview">
10+
<h1>Readme</h1>
11+
<p>Some readme content</p>
12+
</div>
13+
</wcp-markdown-example>
14+
```

src/components/features/markdown-example/README.md

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,6 @@ or the enhanced markdown renderer which instruments this element under the hood.
1111

1212
**Mixins:** ColorSchemable
1313

14-
## Example
15-
16-
### Shows arbitrary HTML code example
17-
18-
```html
19-
<wcp-markdown-example>
20-
<pre slot="code">
21-
&lt;h1&gt;Readme&lt;/h1&gt;
22-
&lt;p&gt;Some readme content&lt;/p&gt;
23-
</pre>
24-
<div slot="preview">
25-
<h1>Readme</h1>
26-
<p>Some readme content</p>
27-
</div>
28-
</wcp-markdown-example>
29-
```
30-
3114
## Slots
3215

3316
| Name | Description |

src/components/features/markdown-example/markdown-example.component.ts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,6 @@ const MARKDOWN_EXAMPLE_TABS = { preview: { label: 'Preview' }, code: { label: 'C
1818
* or the enhanced markdown renderer which instruments this element under the hood. It can be used with the
1919
* `renderMarkdown` function provided by the `@/utils/markdown.utils`.
2020
*
21-
* @example
22-
* ### Shows arbitrary HTML code example
23-
*
24-
* ```html
25-
* <wcp-markdown-example>
26-
* <pre slot="code">
27-
* &lt;h1&gt;Readme&lt;/h1&gt;
28-
* &lt;p&gt;Some readme content&lt;/p&gt;
29-
* </pre>
30-
* <div slot="preview">
31-
* <h1>Readme</h1>
32-
* <p>Some readme content</p>
33-
* </div>
34-
* </wcp-markdown-example>
35-
* ```
36-
*
3721
* @slot code - Code example
3822
* @slot preview - Rendered example preview
3923
*

src/components/features/navigation/README.md

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### Non-interactive
2+
3+
This will probably only be used for the active item.
4+
5+
```html
6+
<wcp-navigation-item> Non-interactive </wcp-navigation-item>
7+
```
8+
9+
### With link
10+
11+
```html
12+
<wcp-navigation-item href="/home"> Home </wcp-navigation-item>
13+
```

src/components/features/navigation/navigation-item/README.md

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,6 @@
44

55
**Mixins:** ColorSchemable
66

7-
## Examples
8-
9-
### Non-interactive
10-
11-
This will probably only be used for the active item.
12-
13-
```html
14-
<wcp-navigation-item>
15-
Non-interactive
16-
</wcp-navigation-item>
17-
```
18-
19-
### With link
20-
21-
```html
22-
<wcp-navigation-item href="/home">
23-
Home
24-
</wcp-navigation-item>
25-
```
26-
277
## Properties
288

299
| Property | Attribute | Type | Default |

src/components/features/navigation/navigation-item/navigation-item.component.scss

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,33 @@
4545
}
4646
}
4747

48-
a,
4948
span {
5049
display: block;
5150
padding: var(---wcp-navigation-item-spacing);
5251

52+
overflow: hidden;
5353
text-decoration: none;
5454
text-overflow: ellipsis;
5555
white-space: nowrap;
5656

5757
background-color: var(---wcp-navigation-item-background);
5858
color: var(---wcp-navigation-item-color);
5959
}
60+
61+
// as the surrounding navigation element might be inset, we add the background
62+
// in front to fill the whole navigation width to increase the clickable area
63+
a {
64+
position: relative;
65+
color: inherit;
66+
text-decoration: none;
67+
68+
&::before {
69+
content: '';
70+
71+
position: absolute;
72+
inset: 0 100% 0 auto;
73+
width: calc(var(---wcp-aside-max-width, 100vw) - 100%);
74+
75+
background-color: var(---wcp-navigation-item-background);
76+
}
77+
}

src/components/features/navigation/navigation-item/navigation-item.component.ts

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,6 @@ import { ColorSchemable } from '@/mixins/color-schemable.mixin.js';
88
import styles from './navigation-item.component.scss';
99

1010
/**
11-
* @element wcp-navigation-item
12-
*
13-
* @example
14-
* ### Non-interactive
15-
*
16-
* This will probably only be used for the active item.
17-
*
18-
* ```html
19-
* <wcp-navigation-item>
20-
* Non-interactive
21-
* </wcp-navigation-item>
22-
* ```
23-
*
24-
* @example
25-
* ### With link
26-
*
27-
* ```html
28-
* <wcp-navigation-item href="/home">
29-
* Home
30-
* </wcp-navigation-item>
31-
* ```
32-
*
3311
* @slot - Default slot for contents
3412
*
3513
* @cssprop --wcp-navigation-item-spacing - Inner padding of the item
@@ -64,7 +42,11 @@ export class NavigationItem extends ColorSchemable(LitElement) {
6442
return html`
6543
${when(
6644
this.href !== undefined,
67-
() => html`<a href="${ifDefined(this.href)}"><slot></slot></a>`,
45+
() => html`
46+
<a href="${ifDefined(this.href)}">
47+
<span><slot></slot></span>
48+
</a>
49+
`,
6850
() => html`<span><slot></slot></span>`,
6951
)}
7052
`;

0 commit comments

Comments
 (0)