@excom/content-tabs 0.1.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/.rush/temp/chunked-rush-logs/content-tabs.apply-exports.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/content-tabs.build_docs.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/content-tabs.build_package-metas.chunks.jsonl +1 -0
- package/.rush/temp/operation/apply-exports/all.log +1 -0
- package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/apply-exports/state.json +3 -0
- package/.rush/temp/operation/build_docs/all.log +1 -0
- package/.rush/temp/operation/build_docs/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/build_docs/state.json +3 -0
- package/.rush/temp/operation/build_package-metas/all.log +1 -0
- package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/build_package-metas/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +3 -0
- package/config/rig.json +5 -0
- package/content-tabs-body.ts +26 -0
- package/content-tabs-header.ts +64 -0
- package/content-tabs.ts +174 -0
- package/index.css +5 -0
- package/index.ts +33 -0
- package/package.json +43 -0
- package/rush-logs/content-tabs.apply-exports.cache.log +1 -0
- package/rush-logs/content-tabs.apply-exports.log +1 -0
- package/rush-logs/content-tabs.build_docs.cache.log +1 -0
- package/rush-logs/content-tabs.build_docs.log +1 -0
- package/rush-logs/content-tabs.build_package-metas.cache.log +1 -0
- package/rush-logs/content-tabs.build_package-metas.log +1 -0
- package/src/content-tabs.css +137 -0
- package/support/custom-elements.json +376 -0
- package/support/demos/file-tabs.html +6 -0
- package/support/demos/multi.html +6 -0
- package/support/demos/named.html +6 -0
- package/support/demos/simple.html +8 -0
- package/support/dist-docs/content-tabs-body.md +20 -0
- package/support/dist-docs/content-tabs-header.md +26 -0
- package/support/dist-docs/content-tabs.md +183 -0
- package/support/docs/README.md +74 -0
- package/support/package-meta.json +252 -0
- package/support/tests/content-tabs.test.ts +426 -0
- package/support/tests/file-tabs.view.test.ts +26 -0
- package/support/tests/multi.view.test.ts +29 -0
- package/support/tests/named.view.test.ts +27 -0
- package/support/tests/simple.view.test.ts +29 -0
- package/tsconfig.json +5 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
|
package/config/rig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Neutron } from "@excom/neutron";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Panel paired with a `<content-tabs-header>` — shown when that header is
|
|
5
|
+
* open. Lives inside a `<content-tabs>`.
|
|
6
|
+
*
|
|
7
|
+
* @summary Tab panel — visible when its paired header is open.
|
|
8
|
+
*/
|
|
9
|
+
export const ContentTabsBody = Neutron({
|
|
10
|
+
tag: "content-tabs-body",
|
|
11
|
+
props: {
|
|
12
|
+
/**
|
|
13
|
+
* @option
|
|
14
|
+
* @state
|
|
15
|
+
* Visibility, kept in sync with the paired header's `is-open`. Set
|
|
16
|
+
* directly only if this body is not paired with a header.
|
|
17
|
+
*/
|
|
18
|
+
isOpen: Boolean,
|
|
19
|
+
/**
|
|
20
|
+
* @option
|
|
21
|
+
* Pairs this body with the `<content-tabs-header>` sharing the same
|
|
22
|
+
* `tab-name`. Unset headers / bodies pair by position instead.
|
|
23
|
+
*/
|
|
24
|
+
tabName: String,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ConstructorType, Neutron, TEvent } from "@excom/neutron";
|
|
2
|
+
|
|
3
|
+
export type ContentTabsHeaderOpenedEvent = TEvent & {
|
|
4
|
+
type: "content-tabs-header-opened";
|
|
5
|
+
detail: void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Clickable tab header — lives inside a `<content-tabs>`. Click opens
|
|
10
|
+
* (`single` / `toggle`) or toggles (`multi`) `is-open`, which keeps the
|
|
11
|
+
* paired `<content-tabs-body>` in sync.
|
|
12
|
+
*
|
|
13
|
+
* @summary Tab header — opens its paired body on click.
|
|
14
|
+
*
|
|
15
|
+
* @fires content-tabs-header-opened - Whenever `is-open` is set. The
|
|
16
|
+
* parent `<content-tabs>` listens for this to close sibling headers.
|
|
17
|
+
* @type ContentTabsHeaderOpenedEvent
|
|
18
|
+
*/
|
|
19
|
+
export const ContentTabsHeader = Neutron({
|
|
20
|
+
tag: "content-tabs-header",
|
|
21
|
+
props: {
|
|
22
|
+
/**
|
|
23
|
+
* @option
|
|
24
|
+
* Pairs this header with the `<content-tabs-body>` sharing the same
|
|
25
|
+
* `tab-name`. Unset headers / bodies pair by position instead.
|
|
26
|
+
*/
|
|
27
|
+
tabName: String,
|
|
28
|
+
/**
|
|
29
|
+
* @option
|
|
30
|
+
* @state
|
|
31
|
+
* Open state. Click sets or toggles this depending on the parent's
|
|
32
|
+
* `tab-type`; set it directly to drive the tab programmatically.
|
|
33
|
+
*/
|
|
34
|
+
isOpen: Boolean,
|
|
35
|
+
// private state
|
|
36
|
+
_parentTabs:
|
|
37
|
+
HTMLElement as unknown as ConstructorType<HTMLContentTabsElement>,
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
.defineMethods({
|
|
41
|
+
_getParentTabs: (element) => {
|
|
42
|
+
const tabs = element._parentTabs || element.closest("content-tabs");
|
|
43
|
+
return [tabs && { _parentTabs: tabs }, { returns: tabs }];
|
|
44
|
+
},
|
|
45
|
+
_handleClick: (element) => ({
|
|
46
|
+
isOpen: ["toggle", "multi"].includes(
|
|
47
|
+
// @ts-expect-error - TODO: method typing
|
|
48
|
+
element._getParentTabs()?.tabType as string
|
|
49
|
+
)
|
|
50
|
+
? !element.isOpen
|
|
51
|
+
: true,
|
|
52
|
+
}),
|
|
53
|
+
_syncCorrespondingBody: (element) => {
|
|
54
|
+
// @ts-expect-error - TODO: method typing
|
|
55
|
+
element._getParentTabs()?._queueSyncBody(element);
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
.onPropUnset("isOpen", () => [{ _syncCorrespondingBody: [] }])
|
|
59
|
+
.onPropSet("isOpen", () => [
|
|
60
|
+
{ _syncCorrespondingBody: [] },
|
|
61
|
+
{ emit: ["content-tabs-header-opened"] },
|
|
62
|
+
])
|
|
63
|
+
.onEvent("click", () => ({ _handleClick: [] }))
|
|
64
|
+
.onDisconnected(() => ({ _parentTabs: null }));
|
package/content-tabs.ts
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import type { ContentTabsBody } from "./content-tabs-body";
|
|
2
|
+
import type {
|
|
3
|
+
ContentTabsHeader,
|
|
4
|
+
ContentTabsHeaderOpenedEvent,
|
|
5
|
+
} from "./content-tabs-header";
|
|
6
|
+
import { ConstructorType, Neutron } from "@excom/neutron";
|
|
7
|
+
|
|
8
|
+
export type { ContentTabsHeaderOpenedEvent };
|
|
9
|
+
|
|
10
|
+
type TContentTabsHeader = typeof ContentTabsHeader.CustomElement;
|
|
11
|
+
type TContentTabsBody = typeof ContentTabsBody.CustomElement;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Open state of a `<content-tabs>` group. A tab is its header's
|
|
15
|
+
* `tab-name`, or its index among the group's own headers when unnamed.
|
|
16
|
+
* Nested groups are excluded.
|
|
17
|
+
*/
|
|
18
|
+
export interface ContentTabsProvision {
|
|
19
|
+
/** The group's `tab-type` (`null` when unset, behaves as `single`). */
|
|
20
|
+
tabType: string | null;
|
|
21
|
+
/** Every open tab, in header order. */
|
|
22
|
+
openTabs: Array<string | number>;
|
|
23
|
+
/** The first open tab; `null` when none is open. */
|
|
24
|
+
activeTab: string | number | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** A header's provision id: its `tab-name`, or its index among `headers`. */
|
|
28
|
+
const tabIdOf = (header: TContentTabsHeader, headers: TContentTabsHeader[]) =>
|
|
29
|
+
header.tabName || headers.indexOf(header);
|
|
30
|
+
|
|
31
|
+
/** Read `is-open` even if the header hasn't upgraded yet. */
|
|
32
|
+
const isHeaderOpen = (header: TContentTabsHeader) =>
|
|
33
|
+
header.isOpen ?? header.hasAttribute("is-open");
|
|
34
|
+
|
|
35
|
+
const isSameProvision = (
|
|
36
|
+
a: ContentTabsProvision | null | undefined,
|
|
37
|
+
b: ContentTabsProvision
|
|
38
|
+
) =>
|
|
39
|
+
!!a &&
|
|
40
|
+
a.tabType === b.tabType &&
|
|
41
|
+
a.activeTab === b.activeTab &&
|
|
42
|
+
a.openTabs.length === b.openTabs.length &&
|
|
43
|
+
a.openTabs.every((tab, i) => tab === b.openTabs[i]);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Tabs / accordion primitive. Click a `<content-tabs-header>` to show its
|
|
47
|
+
* paired `<content-tabs-body>` — pair by matching `tab-name`, or by
|
|
48
|
+
* position when both are unnamed. Nested `<content-tabs>` groups are
|
|
49
|
+
* isolated from their ancestors.
|
|
50
|
+
*
|
|
51
|
+
* `.provision` holds the open state (`{ tabType, openTabs, activeTab }`)
|
|
52
|
+
* so Quark can read which tab is active with `prop("provision")`.
|
|
53
|
+
*
|
|
54
|
+
* @summary Tabs / accordion — single, multi, or toggle selection.
|
|
55
|
+
*
|
|
56
|
+
* @listens content-tabs-header-opened - Closes sibling headers when
|
|
57
|
+
* `tab-type` is `single` (default) or `toggle`.
|
|
58
|
+
* @type ContentTabsHeaderOpenedEvent
|
|
59
|
+
*
|
|
60
|
+
* @child content-tabs-header - Clickable tab headers.
|
|
61
|
+
* @child content-tabs-body - Panels shown / hidden to match their header.
|
|
62
|
+
*/
|
|
63
|
+
export const ContentTabs = Neutron({
|
|
64
|
+
tag: "content-tabs",
|
|
65
|
+
props: {
|
|
66
|
+
/**
|
|
67
|
+
* @option
|
|
68
|
+
* Selection mode. `single` opens one header at a time (radio-like);
|
|
69
|
+
* `multi` allows any number open at once (accordion); `toggle` is
|
|
70
|
+
* like `single`, but re-clicking the open header closes it.
|
|
71
|
+
* @values single | multi | toggle
|
|
72
|
+
* @default single
|
|
73
|
+
*/
|
|
74
|
+
tabType: String,
|
|
75
|
+
/**
|
|
76
|
+
* @provision
|
|
77
|
+
* Open state: `{ tabType, openTabs, activeTab }`. A tab is its
|
|
78
|
+
* header's `tab-name`, or its index among this group's own headers
|
|
79
|
+
* when unnamed; `activeTab` is the first open one (`null` when none).
|
|
80
|
+
* Set after mount and after every header change (batched with the
|
|
81
|
+
* body sync). Not reflected as an attribute.
|
|
82
|
+
* @type ContentTabsProvision
|
|
83
|
+
*/
|
|
84
|
+
provision: Object as unknown as ConstructorType<ContentTabsProvision>,
|
|
85
|
+
|
|
86
|
+
// private state
|
|
87
|
+
_headersToSync: Array as unknown as ConstructorType<TContentTabsHeader[]>,
|
|
88
|
+
_mutationQueued: Boolean,
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
.defineMethods({
|
|
92
|
+
/* Own headers / bodies only. A nested `<content-tabs>` keeps its own
|
|
93
|
+
(nearest-group filter, not `:not(:scope …)`, which some selector
|
|
94
|
+
engines scope wrong). */
|
|
95
|
+
getHeaders: (element) => ({
|
|
96
|
+
returns: [...element.querySelectorAll("content-tabs-header")].filter(
|
|
97
|
+
(header) => header.closest("content-tabs") === element
|
|
98
|
+
) as TContentTabsHeader[],
|
|
99
|
+
}),
|
|
100
|
+
getBodies: (element) => ({
|
|
101
|
+
returns: [...element.querySelectorAll("content-tabs-body")].filter(
|
|
102
|
+
(body) => body.closest("content-tabs") === element
|
|
103
|
+
) as TContentTabsBody[],
|
|
104
|
+
}),
|
|
105
|
+
// @ts-expect-error - TODO: method typing
|
|
106
|
+
_syncBodies: ({ _headersToSync, getHeaders, getBodies }) => {
|
|
107
|
+
const allHeaders = getHeaders();
|
|
108
|
+
const allBodies = getBodies();
|
|
109
|
+
[...new Set(_headersToSync || [])].forEach((header) => {
|
|
110
|
+
const body = allBodies.find((body, bodyIndex) => {
|
|
111
|
+
if (header.tabName) {
|
|
112
|
+
return body.tabName === header.tabName;
|
|
113
|
+
}
|
|
114
|
+
return bodyIndex === allHeaders.indexOf(header);
|
|
115
|
+
});
|
|
116
|
+
if (body) {
|
|
117
|
+
body.isOpen = header.isOpen;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
_headersToSync: [],
|
|
122
|
+
_mutationQueued: false,
|
|
123
|
+
_syncProvision: [],
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
/**
|
|
127
|
+
* Rebuild `provision` from every own header (group-wide, once per
|
|
128
|
+
* batch). New object only when something changed, so Quark /
|
|
129
|
+
* `neutron-provision` listeners skip no-op batches.
|
|
130
|
+
*/
|
|
131
|
+
// @ts-expect-error - TODO: method typing
|
|
132
|
+
_syncProvision: ({ getHeaders, tabType, provision }) => {
|
|
133
|
+
const headers = getHeaders();
|
|
134
|
+
const openTabs = headers
|
|
135
|
+
.filter(isHeaderOpen)
|
|
136
|
+
.map((header) => tabIdOf(header, headers));
|
|
137
|
+
const next: ContentTabsProvision = {
|
|
138
|
+
tabType: tabType || null,
|
|
139
|
+
openTabs,
|
|
140
|
+
activeTab: openTabs.length ? openTabs[0] : null,
|
|
141
|
+
};
|
|
142
|
+
return isSameProvision(provision, next) ? {} : { provision: next };
|
|
143
|
+
},
|
|
144
|
+
// @ts-expect-error - TODO: method typing
|
|
145
|
+
_queueSyncBodies: ({ _mutationQueued, _syncBodies }) => {
|
|
146
|
+
if (!_mutationQueued) {
|
|
147
|
+
// Heavy DOM queries: cache and batch.
|
|
148
|
+
queueMicrotask(_syncBodies);
|
|
149
|
+
return { _mutationQueued: true };
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
_queueSyncBody: ({ _headersToSync }, header) => [
|
|
153
|
+
{ _headersToSync: [...(_headersToSync || []), header] },
|
|
154
|
+
{ _queueSyncBodies: [] },
|
|
155
|
+
],
|
|
156
|
+
})
|
|
157
|
+
.onEvent("content-tabs-header-opened", (element, e) => {
|
|
158
|
+
// Close sibling headers
|
|
159
|
+
e.stopPropagation();
|
|
160
|
+
if ([null, "single", "toggle"].includes(element.tabType)) {
|
|
161
|
+
element
|
|
162
|
+
.getHeaders()
|
|
163
|
+
// `e.target` is the header that opened
|
|
164
|
+
.filter((header) => header !== e.target)
|
|
165
|
+
.forEach((header) => (header.isOpen = false));
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
// Initial `is-open` headers may upgrade after this element, so the
|
|
169
|
+
// first provision read shares the same microtask queue as a change
|
|
170
|
+
.onConnected(() => ({ _queueSyncBodies: [] }))
|
|
171
|
+
.onDisconnected(
|
|
172
|
+
({ isMoving }) =>
|
|
173
|
+
!isMoving && { _headersToSync: null, _mutationQueued: false }
|
|
174
|
+
);
|
package/index.css
ADDED
package/index.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ContentTabs } from "./content-tabs";
|
|
2
|
+
import { ContentTabsBody } from "./content-tabs-body";
|
|
3
|
+
import { ContentTabsHeader } from "./content-tabs-header";
|
|
4
|
+
|
|
5
|
+
ContentTabs.define();
|
|
6
|
+
ContentTabsBody.define();
|
|
7
|
+
ContentTabsHeader.define();
|
|
8
|
+
|
|
9
|
+
export { ContentTabs, ContentTabsBody, ContentTabsHeader };
|
|
10
|
+
|
|
11
|
+
type T_HTMLContentTabsElement = typeof ContentTabs.CustomElement;
|
|
12
|
+
type T_HTMLContentTabsBodyElement = typeof ContentTabsBody.CustomElement;
|
|
13
|
+
type T_HTMLContentTabsHeaderElement = typeof ContentTabsHeader.CustomElement;
|
|
14
|
+
declare global {
|
|
15
|
+
interface HTMLContentTabsElement extends T_HTMLContentTabsElement {}
|
|
16
|
+
interface HTMLContentTabsBodyElement extends T_HTMLContentTabsBodyElement {}
|
|
17
|
+
interface HTMLContentTabsHeaderElement extends T_HTMLContentTabsHeaderElement {}
|
|
18
|
+
interface Window {
|
|
19
|
+
HTMLContentTabsElement: HTMLContentTabsElement;
|
|
20
|
+
HTMLContentTabsBodyElement: HTMLContentTabsBodyElement;
|
|
21
|
+
HTMLContentTabsHeaderElement: HTMLContentTabsHeaderElement;
|
|
22
|
+
}
|
|
23
|
+
interface HTMLElementTagNameMap {
|
|
24
|
+
"content-tabs": HTMLContentTabsElement;
|
|
25
|
+
"content-tabs-body": HTMLContentTabsBodyElement;
|
|
26
|
+
"content-tabs-header": HTMLContentTabsHeaderElement;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export type {
|
|
30
|
+
HTMLContentTabsBodyElement,
|
|
31
|
+
HTMLContentTabsElement,
|
|
32
|
+
HTMLContentTabsHeaderElement,
|
|
33
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@excom/content-tabs",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "<content-tabs> custom element",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=24.13.0"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@excom/valence": "^0.1.0",
|
|
12
|
+
"@excom/neutron": "^0.1.0"
|
|
13
|
+
},
|
|
14
|
+
"peerDependencies": {},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@excom/heft-rig": "^0.1.0"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"url": "excom-dev/nucleus",
|
|
20
|
+
"directory": "packages/content-tabs"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/excom-dev/nucleus/tree/main/packages/content-tabs/support/docs/README.md",
|
|
23
|
+
"bugs": "https://github.com/excom-dev/nucleus/issues",
|
|
24
|
+
"keywords": [
|
|
25
|
+
"content-tabs",
|
|
26
|
+
"neutron",
|
|
27
|
+
"custom-elements"
|
|
28
|
+
],
|
|
29
|
+
"excom": {
|
|
30
|
+
"packageType": "kit-element"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "node node_modules/@excom/heft-rig/scripts/vite-build.mjs",
|
|
34
|
+
"build:watch": "node node_modules/@excom/heft-rig/scripts/vite-build-watch.mjs",
|
|
35
|
+
"format": "node node_modules/@excom/heft-rig/scripts/format.mjs",
|
|
36
|
+
"test": "node node_modules/@excom/heft-rig/scripts/vitest.mjs",
|
|
37
|
+
"coverage": "node node_modules/@excom/heft-rig/scripts/coverage.mjs",
|
|
38
|
+
"dev": "node node_modules/@excom/heft-rig/scripts/vite-dev.mjs",
|
|
39
|
+
"preview": "node node_modules/@excom/heft-rig/scripts/vite-preview.mjs",
|
|
40
|
+
"build:package-metas": "node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs",
|
|
41
|
+
"build:docs": "node node_modules/@excom/heft-rig/scripts/build-docs.mjs"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Caching has been disabled for this project's "apply-exports" command.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This project does not define the caching behavior of the "build:docs" command, so caching has been disabled.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This project does not define the caching behavior of the "build:package-metas" command, so caching has been disabled.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
@import "@excom/valence/src/util.default.css";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Styles for `<content-tabs>`, `<content-tabs-header>`, and
|
|
5
|
+
* `<content-tabs-body>`. Primary layout lives on the `content-tabs`
|
|
6
|
+
* mixin; headers / bodies are styled via nested selectors.
|
|
7
|
+
* @element content-tabs
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* Aliases */
|
|
11
|
+
@custom-selector :--content-tabs content-tabs, .tag-content-tabs;
|
|
12
|
+
@custom-selector :--content-tabs-header content-tabs-header, .tag-content-tabs-header;
|
|
13
|
+
@custom-selector :--content-tabs-body content-tabs-body, .tag-content-tabs-body;
|
|
14
|
+
@custom-selector :--content-tab--is-open [is-open], [aria-selected="true"];
|
|
15
|
+
|
|
16
|
+
@define-mixin module-content-tabs {
|
|
17
|
+
:root {
|
|
18
|
+
/**
|
|
19
|
+
* Border color for `.file-tabs` headers / bodies.
|
|
20
|
+
* @cssproperty
|
|
21
|
+
* @syntax <color>
|
|
22
|
+
*/
|
|
23
|
+
--content-tabs-border-color: var(--v-muted-border-color, currentColor);
|
|
24
|
+
/**
|
|
25
|
+
* Border width for `.file-tabs` headers / bodies.
|
|
26
|
+
* @cssproperty
|
|
27
|
+
* @syntax <length>
|
|
28
|
+
*/
|
|
29
|
+
--content-tabs-border-width: var(--v-border-width, 2px);
|
|
30
|
+
/**
|
|
31
|
+
* Text color for the active header in `.underline`.
|
|
32
|
+
* @cssproperty
|
|
33
|
+
* @syntax <color>
|
|
34
|
+
*/
|
|
35
|
+
--content-tabs-color-active: var(--v-color-primary, inherit);
|
|
36
|
+
/**
|
|
37
|
+
* Padding for each header.
|
|
38
|
+
* @cssproperty
|
|
39
|
+
* @syntax <length>{1,4}
|
|
40
|
+
*/
|
|
41
|
+
--content-tabs-header-padding: 10px 15px;
|
|
42
|
+
/**
|
|
43
|
+
* Padding for each body in `.file-tabs`.
|
|
44
|
+
* @cssproperty
|
|
45
|
+
* @syntax <length>{1,4}
|
|
46
|
+
*/
|
|
47
|
+
--content-tabs-body-padding: var(--v-spacing, 15px);
|
|
48
|
+
/**
|
|
49
|
+
* Height of the `.file-tabs` active-tab accent bar.
|
|
50
|
+
* @cssproperty
|
|
51
|
+
* @syntax <length>
|
|
52
|
+
*/
|
|
53
|
+
--content-tabs-active-indicator-height: 2px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
:--content-tabs {
|
|
57
|
+
:--content-tabs-header {
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
position: relative;
|
|
60
|
+
user-select: none;
|
|
61
|
+
}
|
|
62
|
+
:--content-tabs-body {
|
|
63
|
+
display: none;
|
|
64
|
+
}
|
|
65
|
+
:--content-tabs-body:--content-tab--is-open {
|
|
66
|
+
display: block;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* File-explorer look — headers render as bordered folder tabs joined
|
|
71
|
+
* to the active body.
|
|
72
|
+
* @cssclass
|
|
73
|
+
*/
|
|
74
|
+
&.file-tabs {
|
|
75
|
+
> :--content-tabs-header {
|
|
76
|
+
/* compensate for lack of flexbox */
|
|
77
|
+
margin-right: -5px;
|
|
78
|
+
}
|
|
79
|
+
:--content-tabs-header {
|
|
80
|
+
border: var(--content-tabs-border-width) solid
|
|
81
|
+
var(--content-tabs-border-color);
|
|
82
|
+
border-bottom: 0;
|
|
83
|
+
padding: var(--content-tabs-header-padding);
|
|
84
|
+
display: inline-block;
|
|
85
|
+
|
|
86
|
+
&:not(:last-of-type) {
|
|
87
|
+
border-right: 0;
|
|
88
|
+
}
|
|
89
|
+
:--content-tabs-body {
|
|
90
|
+
margin-top: -1px;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
&:not(:has(:--content-tabs-header:--content-tab--is-open))
|
|
94
|
+
:--content-tabs-header:first-of-type,
|
|
95
|
+
:--content-tabs-header:--content-tab--is-open {
|
|
96
|
+
@mixin util-nested-card;
|
|
97
|
+
color: var(--v-primary);
|
|
98
|
+
|
|
99
|
+
&::after {
|
|
100
|
+
content: "";
|
|
101
|
+
position: absolute;
|
|
102
|
+
bottom: calc(var(--content-tabs-border-width) * -1);
|
|
103
|
+
left: 0;
|
|
104
|
+
width: 100%;
|
|
105
|
+
height: var(--content-tabs-active-indicator-height);
|
|
106
|
+
@mixin util-nested-card;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
&:not(:has(:--content-tabs-body:--content-tab--is-open))
|
|
110
|
+
:--content-tabs-body:first-of-type,
|
|
111
|
+
:--content-tabs-body:--content-tab--is-open {
|
|
112
|
+
border: var(--content-tabs-border-width) solid
|
|
113
|
+
var(--content-tabs-border-color);
|
|
114
|
+
padding: var(--content-tabs-body-padding);
|
|
115
|
+
@mixin util-nested-card;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Paper / underline look — the active header gets a bottom accent
|
|
120
|
+
* border instead of a bordered card.
|
|
121
|
+
* @cssclass
|
|
122
|
+
*/
|
|
123
|
+
&.underline {
|
|
124
|
+
:--content-tabs-header {
|
|
125
|
+
border-bottom: 2px solid transparent;
|
|
126
|
+
padding: var(--content-tabs-header-padding);
|
|
127
|
+
&:--content-tab--is-open {
|
|
128
|
+
color: var(--v-primary);
|
|
129
|
+
border-color: var(--v-primary-border);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
:--content-tabs-body:--content-tab--is-open {
|
|
133
|
+
margin-top: 8px;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|