@papit/table-of-content 0.0.0-stage → 0.0.2
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 +138 -2
- package/asset/translations/en.json +7 -0
- package/lib/bundle.d.ts +66 -0
- package/lib/bundle.js +66 -0
- package/lib/react-wrapper.d.ts +38 -0
- package/lib/react-wrapper.js +1 -0
- package/package.json +101 -3
package/README.md
CHANGED
|
@@ -1,3 +1,139 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @papit/table-of-content
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A page-aware table of contents that builds a tree from the page's headings and highlights the ones currently in view. Clicking an item jumps to its section via the URL hash.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
[](https://github.com/onkelhoy/papit/actions/workflows/pull-request.yml)
|
|
11
|
+
[](https://www.npmjs.com/package/@papit/table-of-content)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @papit/table-of-content
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### HTML
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<script type="module" defer>
|
|
25
|
+
import "@papit/table-of-content";
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<pap-table-of-content></pap-table-of-content>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### JavaScript / TypeScript
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import "@papit/table-of-content";
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
Place `<pap-table-of-content>` anywhere on the page. By default it scans the **root node** (document or shadow root) for all heading elements and `role="heading"` elements, excluding those with `aria-hidden` or `data-skipped`.
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<pap-table-of-content></pap-table-of-content>
|
|
45
|
+
|
|
46
|
+
<main>
|
|
47
|
+
<h1>Introduction</h1>
|
|
48
|
+
<h2>Getting started</h2>
|
|
49
|
+
<h3>Prerequisites</h3>
|
|
50
|
+
<h2>API reference</h2>
|
|
51
|
+
</main>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
As the user scrolls, the items corresponding to visible headings receive the `marked` class and the host gains the `:state(scrolling)` custom state.
|
|
55
|
+
|
|
56
|
+
### Custom query
|
|
57
|
+
|
|
58
|
+
Override which elements are observed by setting the `query` attribute or property:
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<!-- Only observe h2 and h3 -->
|
|
62
|
+
<pap-table-of-content query="h2, h3"></pap-table-of-content>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Icons
|
|
66
|
+
|
|
67
|
+
Add a `data-icon` attribute to a heading to render a `pap-icon` beside its label in the tree:
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<h2 data-icon="star">Highlights</h2>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Reading the active set
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
const toc = document.querySelector("pap-table-of-content");
|
|
77
|
+
toc.addEventListener("change", () => {
|
|
78
|
+
console.log(toc.value); // [{ href: '#...', name: '...' }, ...]
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Properties
|
|
85
|
+
|
|
86
|
+
| Property | Attribute | Type | Default | Description |
|
|
87
|
+
| -------- | --------- | ---------------------------------- | --------------------- | --------------------------------------------------------------------- |
|
|
88
|
+
| `query` | `query` | `string` | All heading selectors | CSS selector used to discover headings. Reflected from the attribute. |
|
|
89
|
+
| `links` | — | `Link[]` | `[]` | Internal list of discovered links; not reflected. |
|
|
90
|
+
| `value` | — | `{ href: string; name: string }[]` | — | Read-only. Returns the subset of links currently marked as visible. |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Events
|
|
95
|
+
|
|
96
|
+
| Event | Detail | Description |
|
|
97
|
+
| -------- | ------ | ---------------------------------------------------------------------------------------- |
|
|
98
|
+
| `change` | — | Fired whenever the set of visible headings changes (throttled via IntersectionObserver). |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## CSS Parts
|
|
103
|
+
|
|
104
|
+
| Part | Element | Description |
|
|
105
|
+
| -------- | -------------------- | --------------------------------- |
|
|
106
|
+
| `tree` | `pap-treeview` | The root tree element. |
|
|
107
|
+
| `item` | `pap-treeitem` | Each individual tree item. |
|
|
108
|
+
| `anchor` | `<a>` inside an item | The anchor link inside each item. |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Custom States
|
|
113
|
+
|
|
114
|
+
| State | Description |
|
|
115
|
+
| ------------------- | --------------------------------------------------------------------------- |
|
|
116
|
+
| `:state(scrolling)` | Present while the page is scrolling; removed ~500 ms after scrolling stops. |
|
|
117
|
+
| `:state(active)` | Present while the inner `pap-treeview` is focused / active. |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
Licensed under the @Papit License 1.0 — Copyright (c) 2024 Henry Pap (@onkelhoy)
|
|
124
|
+
|
|
125
|
+
**Key points:**
|
|
126
|
+
|
|
127
|
+
- ✅ Free to use in commercial projects
|
|
128
|
+
- ✅ Free to modify and distribute
|
|
129
|
+
- ✅ Attribution required
|
|
130
|
+
- ❌ Cannot resell the component itself as a standalone product
|
|
131
|
+
|
|
132
|
+
See the [LICENSE](https://github.com/onkelhoy/papit/blob/main/LICENSE) file for full details.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Related packages
|
|
137
|
+
|
|
138
|
+
- [@papit/web-component](https://github.com/onkelhoy/papit/tree/main/packages/web/engines/web-component) — Core utilities, decorators, and base component class
|
|
139
|
+
- [@papit/treeview](https://github.com/onkelhoy/papit/tree/main/packages/web/design-system/1-foundations/treeview) — Tree view and tree item components used for rendering
|
package/lib/bundle.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CustomElementInternals } from '@papit/web-component';
|
|
2
|
+
|
|
3
|
+
declare type Link = {
|
|
4
|
+
href: string;
|
|
5
|
+
name: string;
|
|
6
|
+
icon: string | null;
|
|
7
|
+
reference: HTMLElement;
|
|
8
|
+
marked: boolean;
|
|
9
|
+
level: number;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* `<pap-table-of-content>` — a scroll-aware table of contents web component.
|
|
14
|
+
*
|
|
15
|
+
* Scans the root node for heading elements (or any element matching {@link query}),
|
|
16
|
+
* assigns stable `id` attributes derived from their text content, and renders them
|
|
17
|
+
* as a hierarchical `<pap-treeview>`. Items corresponding to headings that are
|
|
18
|
+
* currently intersecting the viewport are highlighted with the `marked` CSS class.
|
|
19
|
+
*
|
|
20
|
+
* @fires change - Dispatched whenever the set of visible (intersecting) headings
|
|
21
|
+
* changes. Read {@link value} inside the handler to get the current active set.
|
|
22
|
+
*
|
|
23
|
+
* @csspart tree - The root `<pap-treeview>` element.
|
|
24
|
+
* @csspart item - Each `<pap-treeitem>` element.
|
|
25
|
+
* @csspart anchor - The `<a>` element inside each tree item.
|
|
26
|
+
*
|
|
27
|
+
* @cssprop --space-3 - Inline padding applied to each tree item's content area (default `0.75rem`).
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```html
|
|
31
|
+
* <pap-table-of-content></pap-table-of-content>
|
|
32
|
+
*
|
|
33
|
+
* <main>
|
|
34
|
+
* <h1>Intro</h1>
|
|
35
|
+
* <h2>Details</h2>
|
|
36
|
+
* <h3>Sub-section</h3>
|
|
37
|
+
* </main>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class TableOfContent extends CustomElementInternals {
|
|
41
|
+
static sheet: CSSStyleSheet;
|
|
42
|
+
/**
|
|
43
|
+
* The currently visible headings as plain objects.
|
|
44
|
+
* Useful for driving external navigation UI or breadcrumbs.
|
|
45
|
+
*
|
|
46
|
+
* @returns An array of `{ href, name }` pairs for every link whose
|
|
47
|
+
* `marked` flag is `true`.
|
|
48
|
+
*/
|
|
49
|
+
get value(): {
|
|
50
|
+
href: string;
|
|
51
|
+
name: string;
|
|
52
|
+
}[];
|
|
53
|
+
private observer;
|
|
54
|
+
links: Link[];
|
|
55
|
+
query: string;
|
|
56
|
+
private handleobserve;
|
|
57
|
+
private handleenter;
|
|
58
|
+
private handleactive;
|
|
59
|
+
private handleinactive;
|
|
60
|
+
private stopscrolling;
|
|
61
|
+
private buildHierarchy;
|
|
62
|
+
private renderTreeItems;
|
|
63
|
+
render(): Node;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { }
|
package/lib/bundle.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var f=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var s=(h,o,t,r)=>{for(var e=r>1?void 0:r?g(o,t):o,n=h.length-1,a;n>=0;n--)(a=h[n])&&(e=(r?a(o,t,e):a(e))||e);return r&&e&&f(o,t,e),e};import{bind as c,CustomElementInternals as b,debounce as w,html as l,property as v,unsafeHTML as k}from"@papit/web-component";import"@papit/treeview";var m=new CSSStyleSheet;m.replaceSync(`:host {
|
|
2
|
+
pap-treeview {
|
|
3
|
+
list-style: none;
|
|
4
|
+
padding: 0;
|
|
5
|
+
|
|
6
|
+
pap-treeitem {
|
|
7
|
+
|
|
8
|
+
a {
|
|
9
|
+
color: currentColor;
|
|
10
|
+
text-decoration: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
&:hover {
|
|
14
|
+
&>a {
|
|
15
|
+
text-decoration: underline;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&::part(content) {
|
|
20
|
+
padding-inline: var(--space-3, 0.75rem);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&:has(pap-treeitem.marked) {
|
|
24
|
+
|
|
25
|
+
&::part(content) {
|
|
26
|
+
background-color: var(--background);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
pap-treeitem:not(.marked) {
|
|
30
|
+
&::part(content) {
|
|
31
|
+
background-color: var(--background);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
&:hover,
|
|
38
|
+
&.marked {
|
|
39
|
+
&::part(content) {
|
|
40
|
+
background-color: var(--background-dark);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}`);var u=m;var i=class extends b{constructor(){super(...arguments);this.observer=new IntersectionObserver(this.handleobserve);this.links=[];this.query=['[role="heading"]',"h1","h2","h3","h4","h5","h6"].map(t=>t+":not([aria-hidden]):not([data-skipped])").join(",")}static{this.sheet=u}get value(){return this.links.filter(t=>t.marked).map(t=>({href:t.href,name:t.name}))}handleobserve(t,r){t.forEach(e=>{let n=this.links.find(a=>a.reference===e.target);n&&(n.marked=("isVisible"in e?e.isVisible:!1)||e.isIntersecting)}),this.dispatchEvent(new Event("change")),this._internals.states.add("scrolling"),this.stopscrolling(),this.throttleUpdate()}handleenter(t){t.target instanceof HTMLElement&&(window.location.hash=t.target.querySelector("a")?.getAttribute("href")??"")}handleactive(){this._internals.states.add("active")}handleinactive(){this._internals.states.delete("active")}stopscrolling(){this._internals.states.delete("scrolling")}buildHierarchy(t){let r=[],e=[];for(let n of t){let a={...n,children:[]};for(;e.length>0&&e[e.length-1].level>=n.level;)e.pop();e.length===0?r.push(a):e[e.length-1].item.children.push(a),e.push({item:a,level:n.level})}return r}renderTreeItems(t){return t.length===0?null:t.map(r=>{let e=r.children.length>0,n=r.marked;return e?l`
|
|
47
|
+
<pap-treeitem part="item" @enter="${this.handleenter}" aria-expanded="true" class="${n?"marked":""}">
|
|
48
|
+
<a part="anchor" tabindex="-1" href="${r.href}">
|
|
49
|
+
${r.icon&&l`<pap-icon name="${r.icon}"></pap-icon>`}
|
|
50
|
+
${k(r.name)}
|
|
51
|
+
</a>
|
|
52
|
+
${this.renderTreeItems(r.children)}
|
|
53
|
+
</pap-treeitem>
|
|
54
|
+
`:l`
|
|
55
|
+
<pap-treeitem part="item" @enter="${this.handleenter}" aria-expanded="true" class="${n?"marked":""}">
|
|
56
|
+
<a part="anchor" tabindex="-1" href="${r.href}">
|
|
57
|
+
${r.icon&&l`<pap-icon name="${r.icon}"></pap-icon>`}
|
|
58
|
+
${k(r.name)}
|
|
59
|
+
</a>
|
|
60
|
+
</pap-treeitem>
|
|
61
|
+
`})}render(){let t=this.buildHierarchy(this.links);return l`
|
|
62
|
+
<slot></slot>
|
|
63
|
+
<pap-treeview @active="${this.handleactive}" @inactive="${this.handleinactive}" part="tree">
|
|
64
|
+
${this.renderTreeItems(t)}
|
|
65
|
+
</pap-treeview>
|
|
66
|
+
`}};s([v({attribute:!1})],i.prototype,"links",2),s([v({reflect:!1,after(){let t=this.getRootNode(),r=[];(t instanceof Document||t instanceof ShadowRoot||t instanceof HTMLElement)&&t.querySelectorAll(this.query).forEach(e=>{if(!(e instanceof HTMLElement))return;let n=e.textContent??e.getAttribute("aria-label");if(!n)return;let a=0;if(e.hasAttribute("aria-level"))a=Number(e.getAttribute("aria-level"));else if(e instanceof HTMLHeadingElement){let d=e.nodeName.match(/H(\d)/i);d&&(a=parseInt(d[1],10))}let p=n.toLowerCase().replace(/\s/g,"-");e.setAttribute("id",p),r.push({reference:e,href:"#"+p,name:n,icon:e.getAttribute("data-icon"),marked:!1,level:a}),this.observer.observe(e)}),this.links=r,this.requestUpdate()}})],i.prototype,"query",2),s([c],i.prototype,"handleobserve",1),s([c],i.prototype,"handleenter",1),s([c],i.prototype,"handleactive",1),s([c],i.prototype,"handleinactive",1),s([w(500)],i.prototype,"stopscrolling",1);if(!window.customElements)throw new Error("Custom Elements not supported");window.customElements.get("pap-table-of-content")||window.customElements.define("pap-table-of-content",i);export{i as TableOfContent};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
import type { ReactElement } from 'react';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
|
+
import type { Ref } from 'react';
|
|
5
|
+
import type { TableOfContent as TableOfContent_2 } from '@papit/table-of-content';
|
|
6
|
+
|
|
7
|
+
/** React wrapper for the `pap-table-of-content` element. */
|
|
8
|
+
export declare function TableOfContent({ ref, onChange, links, ...props }: TableOfContentProps): ReactElement;
|
|
9
|
+
|
|
10
|
+
export declare interface TableOfContentProps extends Omit<HTMLAttributes<TableOfContent_2>, "links" | "query" | "disabled" | "onChange"> {
|
|
11
|
+
links?: TableOfContent_2["links"];
|
|
12
|
+
query?: TableOfContent_2["query"];
|
|
13
|
+
/**
|
|
14
|
+
* Reactive disabled property.
|
|
15
|
+
* - `rerender: false` → does not trigger a re-render when changed
|
|
16
|
+
* - `type: Boolean` → coerces values to `true`/`false`
|
|
17
|
+
* - `aria: 'aria-disabled'` → syncs to ARIA for accessibility
|
|
18
|
+
* - `removeAttribute: true` → removes `disabled` attribute when false
|
|
19
|
+
*/
|
|
20
|
+
disabled?: TableOfContent_2["disabled"];
|
|
21
|
+
/**
|
|
22
|
+
* Dispatched whenever the set of visible (intersecting) headings
|
|
23
|
+
* changes. Read {@link value} inside the handler to get the current active set.
|
|
24
|
+
*/
|
|
25
|
+
onChange?: (event: Event) => void;
|
|
26
|
+
ref?: Ref<TableOfContent_2>;
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare module "react" {
|
|
31
|
+
namespace JSX {
|
|
32
|
+
interface IntrinsicElements {
|
|
33
|
+
"pap-table-of-content": Omit<TableOfContentProps, "onChange" | "links">;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{useCallback as u,useEffect as i,useRef as c}from"react";import{jsx as s}from"react/jsx-runtime";typeof window<"u"&&import("@papit/table-of-content");function p({ref:t,onChange:l,links:r,...f}){let o=c(null),a=u(e=>{o.current=e;let n;return typeof t=="function"?n=t(e):t&&(t.current=e),()=>{o.current=null,typeof n=="function"?n():typeof t=="function"?t(null):t&&(t.current=null)}},[t]);return i(()=>{let e=o.current;if(!(!e||!l))return e.addEventListener("change",l),()=>e.removeEventListener("change",l)},[l]),i(()=>{let e=o.current;if(!e)return;let n=!0;return customElements.whenDefined("pap-table-of-content").then(()=>{n&&r!==void 0&&(e.links=r)}),()=>{n=!1}},[r]),s("pap-table-of-content",{suppressHydrationWarning:!0,...f,ref:a})}export{p as TableOfContent};
|
package/package.json
CHANGED
|
@@ -1,6 +1,104 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@papit/table-of-content",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
|
|
3
|
+
"description": "A page-aware table of contents that builds a tree from the page's headings and highlights the ones currently in view. Clicking an item jumps to its section via the URL hash.",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"papit",
|
|
6
|
+
"web-component",
|
|
7
|
+
"typescript",
|
|
8
|
+
"table-of-content",
|
|
9
|
+
"toc",
|
|
10
|
+
"navigation",
|
|
11
|
+
"headings"
|
|
12
|
+
],
|
|
13
|
+
"version": "0.0.2",
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "npx @papit/build --error",
|
|
16
|
+
"analyse": "npx @papit/analyse",
|
|
17
|
+
"generate:react": "npx @papit/react",
|
|
18
|
+
"watch": "tsc -w",
|
|
19
|
+
"start": "npx @papit/server --info --live",
|
|
20
|
+
"test": "npx playwright test -c tests/playwright.config.ts $@",
|
|
21
|
+
"preversion": "papit-version",
|
|
22
|
+
"postversion": "papit-version",
|
|
23
|
+
"component": "npm create @papit --component",
|
|
24
|
+
"test:update-snapshots": "npx playwright test --update-snapshots -c tests/playwright.config.ts",
|
|
25
|
+
"test:chrome": "npm test -- --project=chromium"
|
|
26
|
+
},
|
|
27
|
+
"main": "./lib/bundle.js",
|
|
28
|
+
"types": "./lib/bundle.d.ts",
|
|
29
|
+
"type": "module",
|
|
30
|
+
"files": [
|
|
31
|
+
"asset/",
|
|
32
|
+
"lib/"
|
|
33
|
+
],
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"import": "./lib/bundle.js",
|
|
37
|
+
"types": "./lib/bundle.d.ts"
|
|
38
|
+
},
|
|
39
|
+
"./react": {
|
|
40
|
+
"import": "./lib/react-wrapper.js",
|
|
41
|
+
"types": "./lib/react-wrapper.d.ts"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"author": "henry",
|
|
45
|
+
"private": false,
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public",
|
|
48
|
+
"registry": "https://registry.npmjs.org/"
|
|
49
|
+
},
|
|
50
|
+
"license": "LicenseRef-Papit-1.0",
|
|
51
|
+
"homepage": "https://github.com/onkelhoy/papit/tree/main/packages/web/design-system/atoms/table-of-content",
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/onkelhoy/papit/issues"
|
|
54
|
+
},
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "git+https://github.com/onkelhoy/papit.git",
|
|
58
|
+
"directory": "packages/web/design-system/atoms/table-of-content"
|
|
59
|
+
},
|
|
60
|
+
"sideEffects": true,
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=18"
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@papit/treeview": "0.0.11",
|
|
66
|
+
"@papit/web-component": "0.0.11"
|
|
67
|
+
},
|
|
68
|
+
"peerDependencies": {
|
|
69
|
+
"react": "^19"
|
|
70
|
+
},
|
|
71
|
+
"peerDependenciesMeta": {
|
|
72
|
+
"react": {
|
|
73
|
+
"optional": true
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"@papit/codeblock": "0.1.14",
|
|
78
|
+
"@papit/router": "0.1.7",
|
|
79
|
+
"@papit/tabs": "0.1.7",
|
|
80
|
+
"@papit/theme": "0.0.3",
|
|
81
|
+
"@papit/translator": "0.1.1",
|
|
82
|
+
"@playwright/test": "1.64.1",
|
|
83
|
+
"playwright": "1.64.1",
|
|
84
|
+
"typescript": "5.9.3"
|
|
85
|
+
},
|
|
86
|
+
"browserslist": [
|
|
87
|
+
"defaults",
|
|
88
|
+
"not IE 11",
|
|
89
|
+
"not dead"
|
|
90
|
+
],
|
|
91
|
+
"papit": {
|
|
92
|
+
"publish": true,
|
|
93
|
+
"type": "web-component",
|
|
94
|
+
"main": "table-of-content",
|
|
95
|
+
"htmlprefix": "pap",
|
|
96
|
+
"components": {
|
|
97
|
+
"table-of-content": {
|
|
98
|
+
"className": "TableOfContent",
|
|
99
|
+
"htmlprefix": "pap"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"remoteVersion": ""
|
|
6
104
|
}
|