oc 0.50.49 → 0.50.51
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/.turbo/turbo-build.log +4 -4
- package/.turbo/turbo-test.log +47 -36
- package/CHANGELOG.md +12 -0
- package/dist/cli/facade/dev.d.ts +12 -12
- package/dist/components/oc-client/_package/package.json +5 -5
- package/dist/components/oc-client/_package/server.js +1 -1
- package/dist/components/oc-client/_package/src/oc-client.js +54 -56
- package/dist/components/oc-client/_package/src/oc-client.min.js +1 -1
- package/dist/components/oc-client/_package/src/oc-client.min.map +1 -1
- package/dist/components/oc-client/package-lock.json +2635 -10333
- package/dist/components/oc-client/package.json +2 -2
- package/dist/components/oc-client/src/oc-client.js +54 -56
- package/dist/components/oc-client/src/oc-client.min.js +1 -1
- package/dist/components/oc-client/src/oc-client.min.map +1 -1
- package/dist/registry/domain/extract-package.d.ts +2 -0
- package/dist/registry/domain/extract-package.js +3 -1
- package/dist/registry/domain/repository.js +4 -2
- package/dist/registry/routes/components.js +2 -2
- package/dist/registry/routes/publish.js +7 -0
- package/dist/registry/views/index.js +2 -1
- package/dist/registry/views/info.js +4 -3
- package/dist/registry/views/partials/component-parameters.js +6 -2
- package/dist/registry/views/partials/components-dependencies.js +1 -1
- package/dist/registry/views/partials/components-list.js +1 -1
- package/dist/registry/views/partials/components-plugins.js +1 -1
- package/dist/registry/views/partials/components-templates.js +3 -3
- package/dist/registry/views/partials/icon.d.ts +6 -0
- package/dist/registry/views/partials/icon.js +22 -0
- package/dist/registry/views/partials/layout.js +8 -4
- package/dist/registry/views/static/index.d.ts +1 -1
- package/dist/registry/views/static/index.js +22 -4
- package/dist/registry/views/static/info.d.ts +1 -1
- package/dist/registry/views/static/info.js +29 -0
- package/dist/registry/views/static/style.d.ts +1 -1
- package/dist/registry/views/static/style.js +799 -962
- package/package.json +24 -23
- package/tsconfig.json +1 -0
|
@@ -10,6 +10,7 @@ const component_author_1 = __importDefault(require("./partials/component-author"
|
|
|
10
10
|
const component_parameters_1 = __importDefault(require("./partials/component-parameters"));
|
|
11
11
|
const component_state_1 = __importDefault(require("./partials/component-state"));
|
|
12
12
|
const component_versions_1 = __importDefault(require("./partials/component-versions"));
|
|
13
|
+
const icon_1 = __importDefault(require("./partials/icon"));
|
|
13
14
|
const layout_1 = __importDefault(require("./partials/layout"));
|
|
14
15
|
const info_1 = __importDefault(require("./static/info"));
|
|
15
16
|
function formatDate(date) {
|
|
@@ -75,7 +76,7 @@ function statsJs(name, componentDetail) {
|
|
|
75
76
|
display: true,
|
|
76
77
|
position: 'top',
|
|
77
78
|
labels: {
|
|
78
|
-
color: '#
|
|
79
|
+
color: '#9aa4b2',
|
|
79
80
|
font: {
|
|
80
81
|
family: 'Inter, -apple-system, BlinkMacSystemFont, sans-serif',
|
|
81
82
|
size: 14,
|
|
@@ -203,7 +204,7 @@ function Info(vm) {
|
|
|
203
204
|
</script>
|
|
204
205
|
${statsAvailable ? statsJs(vm.component.name, vm.componentDetail) : ''}
|
|
205
206
|
`;
|
|
206
|
-
return ((0, jsx_runtime_1.jsxs)(layout_1.default, { scripts: scripts, href: href, title: vm.title, theme: vm.theme, robots: vm.robots, children: [(0, jsx_runtime_1.jsxs)("section", { class: "hero", children: [(0, jsx_runtime_1.jsx)("nav", { class: "breadcrumb", children: (0, jsx_runtime_1.
|
|
207
|
+
return ((0, jsx_runtime_1.jsxs)(layout_1.default, { scripts: scripts, href: href, title: vm.title, theme: vm.theme, robots: vm.robots, children: [(0, jsx_runtime_1.jsxs)("section", { class: "hero", children: [(0, jsx_runtime_1.jsx)("nav", { class: "breadcrumb", children: (0, jsx_runtime_1.jsxs)("a", { href: href, children: [(0, jsx_runtime_1.jsx)(icon_1.default, { name: "arrow-left", size: 14 }), " All components"] }) }), (0, jsx_runtime_1.jsx)("h1", { class: "component-title", safe: true, children: component.name }), (0, jsx_runtime_1.jsxs)("div", { class: "version-selector", children: [(0, jsx_runtime_1.jsx)("span", { class: "version-label", children: "Version:" }), (0, jsx_runtime_1.jsx)(component_versions_1.default, { versions: component.allVersions, selectedVersion: component.version })] }), (0, jsx_runtime_1.jsx)("p", { safe: true, class: "component-description", children: component.description }), (0, jsx_runtime_1.jsxs)("output", { class: "stats-badge", "aria-label": `Component statistics: Latest release on ${formatDate(publishDate)}`, children: [(0, jsx_runtime_1.jsxs)("div", { class: "chart-icon", "aria-hidden": "true", children: [(0, jsx_runtime_1.jsx)("div", { class: "chart-bar" }), (0, jsx_runtime_1.jsx)("div", { class: "chart-bar" }), (0, jsx_runtime_1.jsx)("div", { class: "chart-bar" })] }), (0, jsx_runtime_1.jsxs)("div", { class: "badge-text", safe: true, children: ["Latest Release: ", formatDate(publishDate), componentState()] })] })] }), (0, jsx_runtime_1.jsxs)("div", { class: "main-content", children: [(0, jsx_runtime_1.jsxs)("div", { class: "primary-content", children: [statsAvailable ? ((0, jsx_runtime_1.jsxs)("section", { class: "content-section collapsible-section", children: [(0, jsx_runtime_1.jsxs)("div", { class: "section-header collapsible-header", "data-target": "stats-content", children: [(0, jsx_runtime_1.jsx)("div", { class: "section-icon", children: (0, jsx_runtime_1.jsx)(icon_1.default, { name: "chart" }) }), (0, jsx_runtime_1.jsx)("h2", { class: "section-title", children: "Package Size History" }), (0, jsx_runtime_1.jsx)("button", { type: "button", class: "collapse-toggle", "aria-label": "Toggle package size history section", children: (0, jsx_runtime_1.jsx)("span", { class: "collapse-icon", children: "\u25BC" }) })] }), (0, jsx_runtime_1.jsx)("div", { class: "section-content collapsible-content", id: "stats-content", children: (0, jsx_runtime_1.jsx)("div", { class: "chart-container", style: "position: relative; height: 300px; margin-bottom: 2rem;", children: (0, jsx_runtime_1.jsx)("canvas", { id: "stats", width: "400", height: "200" }) }) })] })) : (''), (0, jsx_runtime_1.jsx)(component_parameters_1.default, { parameters: component.oc.parameters, currentValues: Object.fromEntries(Object.entries(component.oc.parameters || {})
|
|
207
208
|
.filter(([, param]) => {
|
|
208
209
|
return (param.default !== undefined || param.example !== undefined);
|
|
209
210
|
})
|
|
@@ -212,7 +213,7 @@ function Info(vm) {
|
|
|
212
213
|
? String(param.default)
|
|
213
214
|
: String(param.example);
|
|
214
215
|
return [paramName, value];
|
|
215
|
-
})) }), (0, jsx_runtime_1.jsx)("section", { class: "url-section", children: (0, jsx_runtime_1.jsxs)("div", { class: "content-section", children: [(0, jsx_runtime_1.jsxs)("div", { class: "section-header", children: [(0, jsx_runtime_1.jsx)("div", { class: "section-icon", children: "
|
|
216
|
+
})) }), (0, jsx_runtime_1.jsx)("section", { class: "url-section", children: (0, jsx_runtime_1.jsxs)("div", { class: "content-section", children: [(0, jsx_runtime_1.jsxs)("div", { class: "section-header", children: [(0, jsx_runtime_1.jsx)("div", { class: "section-icon", children: (0, jsx_runtime_1.jsx)(icon_1.default, { name: "link" }) }), (0, jsx_runtime_1.jsx)("h2", { class: "section-title", children: "Component URL" })] }), (0, jsx_runtime_1.jsxs)("div", { class: "section-content", children: [(0, jsx_runtime_1.jsx)("p", { style: "color: var(--color-text-secondary); margin-bottom: 1rem;", children: "You can edit the following area and then refresh or hit Enter to apply the change into the preview window." }), (0, jsx_runtime_1.jsxs)("div", { class: "url-input-group", children: [(0, jsx_runtime_1.jsx)("input", { class: "w-100", id: "href", type: "text", placeholder: "Insert component href here", value: componentHref }), (0, jsx_runtime_1.jsxs)("button", { type: "button", class: "btn btn-secondary copy-href", "aria-label": "Copy component URL", children: [(0, jsx_runtime_1.jsx)(icon_1.default, { name: "link", size: 15 }), (0, jsx_runtime_1.jsx)("span", { class: "copy-href-label", children: "Copy" })] })] }), (0, jsx_runtime_1.jsxs)("div", { class: "field", style: "margin-top: 1rem;", children: [(0, jsx_runtime_1.jsx)("p", { children: "Accept-Language header:" }), (0, jsx_runtime_1.jsx)("input", { class: "w-100", id: "lang", type: "text", value: "*", readonly: true })] })] })] }) }), (0, jsx_runtime_1.jsxs)("section", { class: "preview-section", children: [(0, jsx_runtime_1.jsxs)("div", { class: "preview-controls", children: [(0, jsx_runtime_1.jsx)("h2", { class: "section-title", children: "Live Preview" }), (0, jsx_runtime_1.jsxs)("div", { class: "preview-buttons", children: [(0, jsx_runtime_1.jsxs)("button", { type: "submit", class: "btn btn-primary refresh-preview", children: [(0, jsx_runtime_1.jsx)(icon_1.default, { name: "refresh", size: 15 }), " Refresh"] }), (0, jsx_runtime_1.jsxs)("button", { type: "submit", class: "btn btn-secondary open-preview", children: [(0, jsx_runtime_1.jsx)(icon_1.default, { name: "external", size: 15 }), " Open in New Tab"] })] })] }), (0, jsx_runtime_1.jsx)("iframe", { class: "preview-iframe", src: `~preview/${sandBoxDefaultQs}`, title: "Component Preview", style: "width: 100%; height: 500px; border: none; background: white;" })] })] }), (0, jsx_runtime_1.jsxs)("aside", { class: "sidebar", children: [(0, jsx_runtime_1.jsxs)("div", { class: "info-card", children: [(0, jsx_runtime_1.jsxs)("h3", { class: "section-title", style: "margin-bottom: 1.5rem;", children: [(0, jsx_runtime_1.jsx)(icon_1.default, { name: "info", size: 15 }), " Component Info"] }), (0, jsx_runtime_1.jsxs)("div", { class: "info-item", children: [(0, jsx_runtime_1.jsx)("span", { class: "info-label", children: "Author" }), (0, jsx_runtime_1.jsx)("span", { class: "info-value", children: (0, jsx_runtime_1.jsx)(component_author_1.default, { name: vm.parsedAuthor.name, email: vm.parsedAuthor.email, url: vm.parsedAuthor.url }) })] }), (0, jsx_runtime_1.jsxs)("div", { class: "info-item", children: [(0, jsx_runtime_1.jsx)("span", { class: "info-label", children: "Template" }), (0, jsx_runtime_1.jsx)("span", { safe: true, class: "info-value", children: template })] }), component.oc.files.template.size ? ((0, jsx_runtime_1.jsxs)("div", { class: "info-item", children: [(0, jsx_runtime_1.jsx)("span", { class: "info-label", children: "Size" }), (0, jsx_runtime_1.jsxs)("span", { class: "info-value", children: [Math.round(component.oc.files.template.size / 1024), " KB"] })] })) : (''), (0, jsx_runtime_1.jsxs)("div", { class: "info-item", children: [(0, jsx_runtime_1.jsx)("span", { class: "info-label", children: "Published" }), (0, jsx_runtime_1.jsx)("span", { safe: true, class: "info-value", children: formatDate(publishDate) })] }), (0, jsx_runtime_1.jsxs)("div", { class: "info-item", children: [(0, jsx_runtime_1.jsx)("span", { class: "info-label", children: "Publish Agent" }), (0, jsx_runtime_1.jsx)("span", { safe: true, class: "info-value", children: publishAgent })] })] }), repositoryUrl ? ((0, jsx_runtime_1.jsxs)("div", { class: "info-card", children: [(0, jsx_runtime_1.jsxs)("h3", { class: "section-title", style: "margin-bottom: 1.5rem;", children: [(0, jsx_runtime_1.jsx)(icon_1.default, { name: "link", size: 15 }), " Links"] }), (0, jsx_runtime_1.jsxs)("div", { class: "info-item", children: [(0, jsx_runtime_1.jsx)("span", { class: "info-label", children: "Repository" }), (0, jsx_runtime_1.jsx)("span", { class: "info-value", children: (0, jsx_runtime_1.jsx)("a", { href: repositoryUrl, children: "View Source" }) })] })] })) : (''), (0, jsx_runtime_1.jsxs)("div", { class: "info-card", children: [(0, jsx_runtime_1.jsxs)("h3", { class: "section-title", style: "margin-bottom: 1.5rem;", children: [(0, jsx_runtime_1.jsx)(icon_1.default, { name: "package", size: 15 }), " Dependencies"] }), (0, jsx_runtime_1.jsxs)("div", { class: "info-item", children: [(0, jsx_runtime_1.jsx)("span", { class: "info-label", children: "Node.js" }), (0, jsx_runtime_1.jsx)("span", { class: "info-value", children: dependencies && dependencies.length > 0
|
|
216
217
|
? dependencies.join(', ')
|
|
217
218
|
: 'None' })] }), (0, jsx_runtime_1.jsxs)("div", { class: "info-item", children: [(0, jsx_runtime_1.jsx)("span", { class: "info-label", children: "Plugins" }), (0, jsx_runtime_1.jsx)("span", { class: "info-value", children: component.oc.plugins && component.oc.plugins.length > 0
|
|
218
219
|
? component.oc.plugins.join(', ')
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
const jsx_runtime_1 = require("@kitajs/html/jsx-runtime");
|
|
7
|
+
const icon_1 = __importDefault(require("./icon"));
|
|
4
8
|
const componentParameters = ({ parameters, currentValues }) => {
|
|
5
9
|
if (!parameters || Object.keys(parameters).length === 0) {
|
|
6
|
-
return ((0, jsx_runtime_1.jsxs)("section", { class: "content-section", children: [(0, jsx_runtime_1.jsxs)("div", { class: "section-header", children: [(0, jsx_runtime_1.jsx)("div", { class: "section-icon", children: "
|
|
10
|
+
return ((0, jsx_runtime_1.jsxs)("section", { class: "content-section", children: [(0, jsx_runtime_1.jsxs)("div", { class: "section-header", children: [(0, jsx_runtime_1.jsx)("div", { class: "section-icon", children: (0, jsx_runtime_1.jsx)(icon_1.default, { name: "settings" }) }), (0, jsx_runtime_1.jsx)("h2", { class: "section-title", children: "Parameters" })] }), (0, jsx_runtime_1.jsx)("div", { class: "section-content", children: (0, jsx_runtime_1.jsx)("p", { class: "w-100", children: "This component has no parameters" }) })] }));
|
|
7
11
|
}
|
|
8
12
|
const parameterRow = (param, paramName) => {
|
|
9
13
|
const mandatory = param.mandatory ? 'mandatory' : 'optional';
|
|
@@ -26,6 +30,6 @@ const componentParameters = ({ parameters, currentValues }) => {
|
|
|
26
30
|
};
|
|
27
31
|
return ((0, jsx_runtime_1.jsxs)("div", { class: "parameter-item", children: [(0, jsx_runtime_1.jsxs)("div", { class: "parameter-header", children: [(0, jsx_runtime_1.jsx)("span", { class: "parameter-name", safe: true, children: paramName }), (0, jsx_runtime_1.jsxs)("span", { class: `parameter-type ${mandatory === 'mandatory' ? 'parameter-required' : ''}`, children: [param.type, ", ", mandatory] })] }), !!param.description && ((0, jsx_runtime_1.jsx)("p", { class: "parameter-description", safe: true, children: param.description })), param.type !== 'boolean' && !!param.example && ((0, jsx_runtime_1.jsxs)("p", { class: "parameter-description", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Example:" }), " ", param.example] })), !param.mandatory && !!param.default && ((0, jsx_runtime_1.jsxs)("p", { class: "parameter-description", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Default:" }), " ", (0, jsx_runtime_1.jsx)("span", { safe: true, children: String(param.default) })] })), renderInput()] }));
|
|
28
32
|
};
|
|
29
|
-
return ((0, jsx_runtime_1.jsxs)("section", { class: "content-section collapsible-section", children: [(0, jsx_runtime_1.jsxs)("div", { class: "section-header collapsible-header", "data-target": "parameters-content", children: [(0, jsx_runtime_1.jsx)("div", { class: "section-icon", children: "
|
|
33
|
+
return ((0, jsx_runtime_1.jsxs)("section", { class: "content-section collapsible-section", children: [(0, jsx_runtime_1.jsxs)("div", { class: "section-header collapsible-header", "data-target": "parameters-content", children: [(0, jsx_runtime_1.jsx)("div", { class: "section-icon", children: (0, jsx_runtime_1.jsx)(icon_1.default, { name: "settings" }) }), (0, jsx_runtime_1.jsx)("h2", { class: "section-title", children: "Parameters" }), (0, jsx_runtime_1.jsx)("button", { type: "button", class: "collapse-toggle", "aria-label": "Toggle parameters section", children: (0, jsx_runtime_1.jsx)("span", { class: "collapse-icon", children: "\u25BC" }) })] }), (0, jsx_runtime_1.jsx)("div", { class: "section-content collapsible-content", id: "parameters-content", children: (0, jsx_runtime_1.jsx)("div", { class: "parameter-grid", children: Object.keys(parameters).map((parameterName) => parameterRow(parameters[parameterName], parameterName)) }) })] }));
|
|
30
34
|
};
|
|
31
35
|
exports.default = componentParameters;
|
|
@@ -6,6 +6,6 @@ const ComponentsDependencies = (props) => {
|
|
|
6
6
|
const label = name + (core ? ' (node.js core dependency)' : `@${version}`);
|
|
7
7
|
return ((0, jsx_runtime_1.jsx)("a", { href: link, target: "_blank", rel: "noreferrer", children: (0, jsx_runtime_1.jsx)("div", { class: "componentRow row table", children: (0, jsx_runtime_1.jsx)("p", { safe: true, class: "release", children: label }) }) }));
|
|
8
8
|
};
|
|
9
|
-
return ((0, jsx_runtime_1.jsx)("div", { id: "components-dependencies", class: "box", children: props.availableDependencies.map(dependencyRow) }));
|
|
9
|
+
return ((0, jsx_runtime_1.jsx)("div", { id: "components-dependencies", class: "box", children: props.availableDependencies.length ? (props.availableDependencies.map(dependencyRow)) : ((0, jsx_runtime_1.jsx)("div", { class: "empty-state", children: "No dependencies registered" })) }));
|
|
10
10
|
};
|
|
11
11
|
exports.default = ComponentsDependencies;
|
|
@@ -17,6 +17,6 @@ const ComponentsList = (props) => {
|
|
|
17
17
|
? `${Math.round(component.oc.files.template.size / 1024)} kb`
|
|
18
18
|
: '? Kb' }))] }) })] }) }));
|
|
19
19
|
};
|
|
20
|
-
return ((0, jsx_runtime_1.jsxs)("div", { id: "components-list", class: "box", children: [(0, jsx_runtime_1.jsxs)("form", { id: "filter-components", children: [(0, jsx_runtime_1.jsxs)("div", { class: "filters", children: [(0, jsx_runtime_1.jsx)("input", { id: "search-filter", type: "text", "aria-label": "Filter by component name", placeholder: "Filter by
|
|
20
|
+
return ((0, jsx_runtime_1.jsxs)("div", { id: "components-list", class: "box", children: [(0, jsx_runtime_1.jsxs)("form", { id: "filter-components", children: [(0, jsx_runtime_1.jsxs)("div", { class: "filters", children: [(0, jsx_runtime_1.jsx)("input", { id: "search-filter", type: "text", "aria-label": "Filter by component name", placeholder: "Filter by name\u2026 ( press / )" }), (0, jsx_runtime_1.jsx)("input", { id: "author-filter", type: "text", "aria-label": "Filter by component author", placeholder: "Filter by component author" })] }), (0, jsx_runtime_1.jsxs)("div", { class: "states", children: [(0, jsx_runtime_1.jsx)("span", { children: "Hide:" }), (0, jsx_runtime_1.jsx)(selected_checkbox_1.default, { name: "deprecated", stateCounts: props.stateCounts }), (0, jsx_runtime_1.jsx)(selected_checkbox_1.default, { name: "experimental", stateCounts: props.stateCounts })] })] }), (0, jsx_runtime_1.jsx)("div", { class: "list-meta", children: (0, jsx_runtime_1.jsxs)("span", { id: "results-count", children: [props.components.length, " components"] }) }), (0, jsx_runtime_1.jsxs)("div", { class: "row header componentRow table", children: [(0, jsx_runtime_1.jsx)("div", { class: "title", children: "Component" }), (0, jsx_runtime_1.jsx)("div", { class: "author", children: "Author" }), (0, jsx_runtime_1.jsx)("div", { children: "Latest version" }), isRemote && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { class: "date", children: "Updated" }), (0, jsx_runtime_1.jsx)("div", { class: "activity", children: "Activity" })] })), sizeAvailable && (0, jsx_runtime_1.jsx)("div", { children: "Size" })] }), props.components.map(componentRow), (0, jsx_runtime_1.jsx)("div", { id: "components-empty", class: "empty-state hide", children: "No components match your filters." })] }));
|
|
21
21
|
};
|
|
22
22
|
exports.default = ComponentsList;
|
|
@@ -4,6 +4,6 @@ const jsx_runtime_1 = require("@kitajs/html/jsx-runtime");
|
|
|
4
4
|
const ComponentsPlugins = (props) => {
|
|
5
5
|
const pluginRow = ([name, description]) => ((0, jsx_runtime_1.jsx)("div", { class: "componentRow row table", children: (0, jsx_runtime_1.jsxs)("p", { class: "release", children: [(0, jsx_runtime_1.jsxs)("span", { style: "font-weight: bold", children: [name, description ? ':' : ''] }), description] }) }));
|
|
6
6
|
const plugins = Object.entries(props.availablePlugins);
|
|
7
|
-
return ((0, jsx_runtime_1.jsx)("div", { id: "components-plugins", class: "box", children: plugins.length ? plugins.map(pluginRow) :
|
|
7
|
+
return ((0, jsx_runtime_1.jsx)("div", { id: "components-plugins", class: "box", children: plugins.length ? (plugins.map(pluginRow)) : ((0, jsx_runtime_1.jsx)("div", { class: "empty-state", children: "No plugins registered" })) }));
|
|
8
8
|
};
|
|
9
9
|
exports.default = ComponentsPlugins;
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const jsx_runtime_1 = require("@kitajs/html/jsx-runtime");
|
|
4
4
|
const ComponentsTemplates = (props) => {
|
|
5
|
-
const externalLink = ({ global, url }) => ((0, jsx_runtime_1.jsx)("a", { safe: true, href: url, target: "_blank", rel: "noreferrer", children: global }));
|
|
5
|
+
const externalLink = ({ global, url }) => ((0, jsx_runtime_1.jsx)("a", { safe: true, href: url, target: "_blank", rel: "noreferrer", children: Array.isArray(global) ? global.join(', ') : global }));
|
|
6
6
|
const templateRow = ({ externals, type, version }) => {
|
|
7
|
-
const externalLinks = externals.
|
|
7
|
+
const externalLinks = externals.flatMap((external, i) => i === 0 ? [externalLink(external)] : [', ', externalLink(external)]);
|
|
8
8
|
const externalsLabel = externalLinks.length ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [" (Externals: ", externalLinks, ") "] })) : null;
|
|
9
9
|
return ((0, jsx_runtime_1.jsx)("div", { class: "componentRow row table", children: (0, jsx_runtime_1.jsxs)("p", { class: "release", children: [(0, jsx_runtime_1.jsxs)("a", { href: `https://www.npmjs.com/package/${type}`, target: "_blank", rel: "noreferrer", safe: true, children: [type, "@", version] }), externalsLabel] }) }));
|
|
10
10
|
};
|
|
11
|
-
return ((0, jsx_runtime_1.jsx)("div", { id: "components-templates", class: "box", children: props.templates.map(templateRow) }));
|
|
11
|
+
return ((0, jsx_runtime_1.jsx)("div", { id: "components-templates", class: "box", children: props.templates.length ? (props.templates.map(templateRow)) : ((0, jsx_runtime_1.jsx)("div", { class: "empty-state", children: "No templates registered" })) }));
|
|
12
12
|
};
|
|
13
13
|
exports.default = ComponentsTemplates;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type IconName = 'box' | 'clock' | 'layers' | 'package' | 'plug' | 'settings' | 'link' | 'chart' | 'info' | 'play' | 'refresh' | 'external' | 'sun' | 'moon' | 'arrow-left';
|
|
2
|
+
declare const Icon: ({ name, size }: {
|
|
3
|
+
name: IconName;
|
|
4
|
+
size?: number;
|
|
5
|
+
}) => JSX.Element;
|
|
6
|
+
export default Icon;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const jsx_runtime_1 = require("@kitajs/html/jsx-runtime");
|
|
4
|
+
const paths = {
|
|
5
|
+
box: '<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><polyline points="3.29 7 12 12 20.71 7"/><line x1="12" x2="12" y1="22" y2="12"/>',
|
|
6
|
+
clock: '<circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 15 14"/>',
|
|
7
|
+
layers: '<polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/>',
|
|
8
|
+
package: '<path d="m7.5 4.27 9 5.15"/><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><polyline points="3.29 7 12 12 20.71 7"/><line x1="12" x2="12" y1="22" y2="12"/>',
|
|
9
|
+
plug: '<path d="M12 22v-5"/><path d="M9 8V2"/><path d="M15 8V2"/><path d="M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z"/>',
|
|
10
|
+
settings: '<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>',
|
|
11
|
+
link: '<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>',
|
|
12
|
+
chart: '<line x1="12" x2="12" y1="20" y2="10"/><line x1="18" x2="18" y1="20" y2="4"/><line x1="6" x2="6" y1="20" y2="16"/>',
|
|
13
|
+
info: '<circle cx="12" cy="12" r="9"/><line x1="12" x2="12" y1="11" y2="16"/><line x1="12" x2="12.01" y1="8" y2="8"/>',
|
|
14
|
+
play: '<polygon points="6 3 20 12 6 21 6 3"/>',
|
|
15
|
+
refresh: '<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/>',
|
|
16
|
+
external: '<path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>',
|
|
17
|
+
sun: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/>',
|
|
18
|
+
moon: '<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>',
|
|
19
|
+
'arrow-left': '<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>'
|
|
20
|
+
};
|
|
21
|
+
const Icon = ({ name, size = 18 }) => ((0, jsx_runtime_1.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: String(size), height: String(size), viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: paths[name] }));
|
|
22
|
+
exports.default = Icon;
|
|
@@ -11,11 +11,15 @@ const Layout = ({ title, href, children, scripts, theme, robots }) => {
|
|
|
11
11
|
const normalizedHref = href
|
|
12
12
|
.replace('http://', '//')
|
|
13
13
|
.replace('https://', '//');
|
|
14
|
-
const
|
|
14
|
+
const sunSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/></svg>';
|
|
15
|
+
const moonSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>';
|
|
16
|
+
const themeIcon = theme === 'light' ? moonSvg : sunSvg;
|
|
15
17
|
const themeText = theme === 'light' ? 'Switch to Dark' : 'Switch to Light';
|
|
16
|
-
return ((0, jsx_runtime_1.jsxs)(html_1.Fragment, { children: ['<!DOCTYPE html>', (0, jsx_runtime_1.jsxs)("html", { lang: "en", "data-theme": theme, children: [(0, jsx_runtime_1.jsxs)("head", { children: [(0, jsx_runtime_1.jsx)("title", { safe: true, children: title }), (0, jsx_runtime_1.jsx)("meta", { charset: "UTF-8" }), (0, jsx_runtime_1.jsx)("meta", { name: "robots", content: robots ? 'index, follow' : 'noindex, nofollow' }), (0, jsx_runtime_1.jsx)("meta", { name: "language", content: "EN" }), (0, jsx_runtime_1.jsx)("meta", { name: "distribution", content: "global" }), (0, jsx_runtime_1.jsx)("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }), (0, jsx_runtime_1.jsx)("style", { children: style_1.default })] }), (0, jsx_runtime_1.jsxs)("body", { children: [(0, jsx_runtime_1.jsx)("header", { class: "header", children: (0, jsx_runtime_1.jsx)("div", { class: "container", children: (0, jsx_runtime_1.jsxs)("div", { class: "header-content", children: [(0, jsx_runtime_1.jsxs)("a", { class: "logo", href: href, children: [(0, jsx_runtime_1.jsx)("div", { class: "logo-icon", children: "OC" }), "OpenComponents Registry"] }), (0, jsx_runtime_1.jsxs)("button", { class: "theme-toggle", id: "theme-toggle", type: "button", "aria-label": `Switch to ${theme === 'light' ? 'dark' : 'light'} theme`, children: [(0, jsx_runtime_1.jsx)("span", { class: "theme-toggle-icon", "aria-hidden": "true", children: themeIcon }), (0, jsx_runtime_1.jsx)("span", { children: themeText })] })] }) }) }), (0, jsx_runtime_1.jsx)("main", { class: "container", children: children }), (0, jsx_runtime_1.jsx)("
|
|
18
|
+
return ((0, jsx_runtime_1.jsxs)(html_1.Fragment, { children: ['<!DOCTYPE html>', (0, jsx_runtime_1.jsxs)("html", { lang: "en", "data-theme": theme, children: [(0, jsx_runtime_1.jsxs)("head", { children: [(0, jsx_runtime_1.jsx)("title", { safe: true, children: title }), (0, jsx_runtime_1.jsx)("meta", { charset: "UTF-8" }), (0, jsx_runtime_1.jsx)("meta", { name: "robots", content: robots ? 'index, follow' : 'noindex, nofollow' }), (0, jsx_runtime_1.jsx)("meta", { name: "language", content: "EN" }), (0, jsx_runtime_1.jsx)("meta", { name: "distribution", content: "global" }), (0, jsx_runtime_1.jsx)("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }), (0, jsx_runtime_1.jsx)("style", { children: style_1.default })] }), (0, jsx_runtime_1.jsxs)("body", { children: [(0, jsx_runtime_1.jsx)("header", { class: "header", children: (0, jsx_runtime_1.jsx)("div", { class: "container", children: (0, jsx_runtime_1.jsxs)("div", { class: "header-content", children: [(0, jsx_runtime_1.jsxs)("a", { class: "logo", href: href, children: [(0, jsx_runtime_1.jsx)("div", { class: "logo-icon", children: "OC" }), "OpenComponents Registry"] }), (0, jsx_runtime_1.jsxs)("button", { class: "theme-toggle", id: "theme-toggle", type: "button", "aria-label": `Switch to ${theme === 'light' ? 'dark' : 'light'} theme`, children: [(0, jsx_runtime_1.jsx)("span", { class: "theme-toggle-icon", "aria-hidden": "true", children: themeIcon }), (0, jsx_runtime_1.jsx)("span", { children: themeText })] })] }) }) }), (0, jsx_runtime_1.jsx)("main", { class: "container", children: children }), (0, jsx_runtime_1.jsx)("footer", { class: "social container", children: (0, jsx_runtime_1.jsx)("iframe", { id: "gh_badge", title: "GitHub", src: "//ghbtns.com/github-btn.html?user=opencomponents&repo=oc&type=watch&count=true", width: "110", height: "20", frameborder: "0" }) }), (0, jsx_runtime_1.jsx)("script", { src: "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.min.js" }), (0, jsx_runtime_1.jsx)("script", { src: `${normalizedHref}oc-client/client.js` }), (0, jsx_runtime_1.jsx)("script", { children: `
|
|
17
19
|
// Theme switching functionality
|
|
18
20
|
(function() {
|
|
21
|
+
const sunSvg = ${JSON.stringify(sunSvg)};
|
|
22
|
+
const moonSvg = ${JSON.stringify(moonSvg)};
|
|
19
23
|
const themeToggle = document.getElementById('theme-toggle');
|
|
20
24
|
const themeIcon = themeToggle.querySelector('.theme-toggle-icon');
|
|
21
25
|
const themeText = themeToggle.querySelector('span:last-child');
|
|
@@ -41,10 +45,10 @@ const Layout = ({ title, href, children, scripts, theme, robots }) => {
|
|
|
41
45
|
function applyTheme(theme) {
|
|
42
46
|
document.documentElement.setAttribute('data-theme', theme);
|
|
43
47
|
if (theme === 'light') {
|
|
44
|
-
themeIcon.
|
|
48
|
+
themeIcon.innerHTML = moonSvg;
|
|
45
49
|
themeText.textContent = 'Switch to Dark';
|
|
46
50
|
} else {
|
|
47
|
-
themeIcon.
|
|
51
|
+
themeIcon.innerHTML = sunSvg;
|
|
48
52
|
themeText.textContent = 'Switch to Light';
|
|
49
53
|
}
|
|
50
54
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "'use strict';\n\nvar oc = oc || {};\noc.cmd = oc.cmd || [];\n\noc.cmd.push(function() {\n var escapeRegExp = function(s) {\n return String(s).replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n };\n\n var safeRegExp = function(pattern, flags) {\n try {\n return new RegExp(pattern, flags);\n } catch (e) {\n return new RegExp(escapeRegExp(pattern), flags);\n }\n };\n\n var componentsListChanged = function() {\n $('.componentRow').removeClass('hide');\n var s = $('#search-filter').val(),\n a = $('#author-filter').val(),\n r = safeRegExp(s, ''),\n ar = safeRegExp(a, 'i'),\n selectedCheckboxes = $('input[type=checkbox]:checked'),\n hiddenStates = [],\n hidden = 0,\n i;\n\n for (i = 0; i < selectedCheckboxes.length; i++) {\n hiddenStates.push($(selectedCheckboxes[i]).attr('name'));\n }\n\n for (i = 0; i < componentsList.length; i++) {\n var matches = !s || !!componentsList[i].name.match(r),\n matchesAuthor =\n !a ||\n (componentsList[i].author.name &&\n !!componentsList[i].author.name.match(ar)),\n selector = $('#component-' + componentsList[i].name),\n isHidden = false;\n\n for (var j = 0; j < hiddenStates.length; j++) {\n if (componentsList[i].state.toLowerCase() === hiddenStates[j]) {\n isHidden = true;\n }\n }\n\n var show = matches && matchesAuthor && !isHidden;\n selector[show ? 'removeClass' : 'addClass']('hide');\n if (!show) {\n hidden += 1;\n }\n }\n\n var totalShowing = componentsList.length - hidden,\n result =
|
|
1
|
+
declare const _default: "'use strict';\n\nvar oc = oc || {};\noc.cmd = oc.cmd || [];\n\noc.cmd.push(function() {\n var escapeRegExp = function(s) {\n return String(s).replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n };\n\n var safeRegExp = function(pattern, flags) {\n try {\n return new RegExp(pattern, flags);\n } catch (e) {\n return new RegExp(escapeRegExp(pattern), flags);\n }\n };\n\n var componentsListChanged = function() {\n $('.componentRow').removeClass('hide');\n var s = $('#search-filter').val(),\n a = $('#author-filter').val(),\n r = safeRegExp(s, ''),\n ar = safeRegExp(a, 'i'),\n selectedCheckboxes = $('input[type=checkbox]:checked'),\n hiddenStates = [],\n hidden = 0,\n i;\n\n for (i = 0; i < selectedCheckboxes.length; i++) {\n hiddenStates.push($(selectedCheckboxes[i]).attr('name'));\n }\n\n for (i = 0; i < componentsList.length; i++) {\n var matches = !s || !!componentsList[i].name.match(r),\n matchesAuthor =\n !a ||\n (componentsList[i].author.name &&\n !!componentsList[i].author.name.match(ar)),\n selector = $('#component-' + componentsList[i].name),\n isHidden = false;\n\n for (var j = 0; j < hiddenStates.length; j++) {\n if (componentsList[i].state.toLowerCase() === hiddenStates[j]) {\n isHidden = true;\n }\n }\n\n var show = matches && matchesAuthor && !isHidden;\n selector[show ? 'removeClass' : 'addClass']('hide');\n if (!show) {\n hidden += 1;\n }\n }\n\n var totalShowing = componentsList.length - hidden,\n result = totalShowing + (totalShowing === 1 ? ' component' : ' components');\n\n if (s) {\n result += ' matching \"' + s + '\"';\n if (a) {\n result += ' and';\n }\n }\n if (a) {\n result += ' by author \"' + a + '\"';\n }\n\n $('#results-count').text(result);\n $('#components-empty')[totalShowing === 0 ? 'removeClass' : 'addClass']('hide');\n\n return false;\n };\n\n var historyData = [];\n var historyRenderedCount = 0;\n var historyBatchSize = 50; // Number of items to render per batch\n var isLoadingMore = false;\n\n var renderHistoryBatch = function() {\n if (historyRenderedCount >= historyData.length || isLoadingMore) {\n return;\n }\n\n isLoadingMore = true;\n var historyContent = $('#history-content');\n var batchEnd = Math.min(historyRenderedCount + historyBatchSize, historyData.length);\n var batchHtml = '';\n\n for (var i = historyRenderedCount; i < batchEnd; i++) {\n var item = historyData[i];\n var templateSizeText = item.templateSize ? \n ' [' + Math.round(item.templateSize / 1024) + ' kb]' : '';\n \n batchHtml += '<a href=\"' + item.name + '/' + item.version + '/~info\">' +\n '<div class=\"componentRow row table\">' +\n '<p class=\"release\">' +\n item.publishDate + ' - Published ' + item.name + '@' + item.version +\n templateSizeText +\n '</p>' +\n '</div>' +\n '</a>';\n }\n\n // Append new batch to existing content\n historyContent.append(batchHtml);\n historyRenderedCount = batchEnd;\n \n // Add loading indicator if there are more items\n if (historyRenderedCount < historyData.length) {\n historyContent.append('<div id=\"history-loading-more\" class=\"loading-more\">Loading more...</div>');\n }\n \n isLoadingMore = false;\n };\n\n var setupHistoryScrollListener = function() {\n var historyContainer = $('#components-history');\n var checkScroll = function() {\n if (historyRenderedCount >= historyData.length) {\n return;\n }\n\n var containerTop = historyContainer.offset().top;\n var containerHeight = historyContainer.outerHeight();\n var scrollTop = $(window).scrollTop();\n var windowHeight = $(window).height();\n \n // Check if user scrolled close to the bottom of the history container\n var distanceFromBottom = (containerTop + containerHeight) - (scrollTop + windowHeight);\n \n if (distanceFromBottom < 200) { // Load more when 200px from bottom\n $('#history-loading-more').remove();\n renderHistoryBatch();\n }\n };\n\n $(window).on('scroll.history', checkScroll);\n \n // Also check on resize\n $(window).on('resize.history', checkScroll);\n };\n\n var loadComponentsHistory = function() {\n var historyLoader = $('#history-loader');\n var historyContent = $('#history-content');\n var historyError = $('#history-error');\n\n // Show loader\n historyLoader.show();\n historyContent.hide();\n historyError.hide();\n\n // Reset state\n historyData = [];\n historyRenderedCount = 0;\n isLoadingMore = false;\n\n // Remove any existing scroll listeners\n $(window).off('scroll.history resize.history');\n\n // Fetch history data\n fetch('~registry/history')\n .then(function(response) {\n if (!response.ok) {\n throw new Error('Failed to fetch history');\n }\n return response.json();\n })\n .then(function(data) {\n historyData = data.componentsHistory || [];\n \n // Clear content and show container\n historyContent.empty();\n historyLoader.hide();\n historyContent.show();\n \n if (historyData.length === 0) {\n historyContent.html('<p class=\"empty-state\">No components history available.</p>');\n return;\n }\n\n // Render first batch\n renderHistoryBatch();\n \n // Setup scroll listener for infinite loading\n setupHistoryScrollListener();\n })\n .catch(function(error) {\n console.error('Error loading components history:', error);\n historyLoader.hide();\n historyError.show();\n });\n };\n\n var isHistoryLoaded = false;\n\n var initialiseTabs = function() {\n var selectItem = function(target) {\n var $target = $(target);\n $('.box').hide();\n $target.show();\n $('#menuList a').removeClass('selected');\n $('#menuList a[href=\"' + target + '\"]').addClass('selected');\n\n // Keep URL in sync so tab survives refresh and back/forward\n try {\n if (history && history.replaceState && location.hash !== target) {\n history.replaceState(null, '', target);\n }\n } catch (e) {}\n\n // Clean up scroll listeners when leaving history tab\n if (target !== '#components-history') {\n $(window).off('scroll.history resize.history');\n }\n \n // Load history data when history tab is selected for the first time\n if (target === '#components-history' && !isHistoryLoaded) {\n loadComponentsHistory();\n isHistoryLoaded = true;\n }\n // Re-enable scroll listeners when returning to history tab\n else if (target === '#components-history' && isHistoryLoaded && historyRenderedCount < historyData.length) {\n setupHistoryScrollListener();\n }\n };\n\n var hash = location.href.split('#')[1] || '';\n var isHashValid = hash && $('#' + hash);\n var target = isHashValid ? '#' + hash : $($('#menuList a')[0]).attr('href');\n selectItem(target);\n\n $('#menuList a').click(function() {\n selectItem($(this).attr('href'));\n });\n };\n\n var debounce = function(fn, wait) {\n var t;\n return function() {\n var ctx = this, args = arguments;\n clearTimeout(t);\n t = setTimeout(function(){ fn.apply(ctx, args); }, wait);\n };\n };\n\n $('#filter-components')\n .submit(componentsListChanged)\n .keyup(debounce(componentsListChanged, 80));\n $('#filter-components input[type=checkbox]').change(componentsListChanged);\n\n if (q) {\n $('.search').val(q);\n }\n\n // Keyboard shortcuts: \"/\" focuses search, \"Esc\" clears the focused filter\n $(document).on('keydown', function(e) {\n var tag = (e.target && e.target.tagName) ? e.target.tagName.toLowerCase() : '';\n var typing = tag === 'input' || tag === 'textarea' || tag === 'select';\n\n if (e.key === '/' && !typing) {\n var $s = $('#search-filter');\n if ($s.length) {\n e.preventDefault();\n $s.focus();\n }\n } else if (e.key === 'Escape' && typing && $(e.target).closest('#filter-components').length) {\n $(e.target).val('');\n componentsListChanged();\n }\n });\n\n // Focus the search input only on a fresh load (no tab hash, no in-page nav)\n if (!location.hash) {\n var $searchInput = $('#search-filter');\n if ($searchInput.length) { $searchInput.focus(); }\n }\n\n componentsListChanged();\n initialiseTabs();\n});";
|
|
2
2
|
export default _default;
|
|
@@ -56,19 +56,20 @@ oc.cmd.push(function() {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
var totalShowing = componentsList.length - hidden,
|
|
59
|
-
result =
|
|
59
|
+
result = totalShowing + (totalShowing === 1 ? ' component' : ' components');
|
|
60
60
|
|
|
61
61
|
if (s) {
|
|
62
|
-
result += ' matching
|
|
62
|
+
result += ' matching "' + s + '"';
|
|
63
63
|
if (a) {
|
|
64
64
|
result += ' and';
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
if (a) {
|
|
68
|
-
result += '
|
|
68
|
+
result += ' by author "' + a + '"';
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
$('
|
|
71
|
+
$('#results-count').text(result);
|
|
72
|
+
$('#components-empty')[totalShowing === 0 ? 'removeClass' : 'addClass']('hide');
|
|
72
73
|
|
|
73
74
|
return false;
|
|
74
75
|
};
|
|
@@ -255,6 +256,23 @@ oc.cmd.push(function() {
|
|
|
255
256
|
$('.search').val(q);
|
|
256
257
|
}
|
|
257
258
|
|
|
259
|
+
// Keyboard shortcuts: "/" focuses search, "Esc" clears the focused filter
|
|
260
|
+
$(document).on('keydown', function(e) {
|
|
261
|
+
var tag = (e.target && e.target.tagName) ? e.target.tagName.toLowerCase() : '';
|
|
262
|
+
var typing = tag === 'input' || tag === 'textarea' || tag === 'select';
|
|
263
|
+
|
|
264
|
+
if (e.key === '/' && !typing) {
|
|
265
|
+
var $s = $('#search-filter');
|
|
266
|
+
if ($s.length) {
|
|
267
|
+
e.preventDefault();
|
|
268
|
+
$s.focus();
|
|
269
|
+
}
|
|
270
|
+
} else if (e.key === 'Escape' && typing && $(e.target).closest('#filter-components').length) {
|
|
271
|
+
$(e.target).val('');
|
|
272
|
+
componentsListChanged();
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
|
|
258
276
|
// Focus the search input only on a fresh load (no tab hash, no in-page nav)
|
|
259
277
|
if (!location.hash) {
|
|
260
278
|
var $searchInput = $('#search-filter');
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "\nvar oc = oc || {};\noc.cmd = oc.cmd || [];\n\noc.cmd.push(function() {\n $('#versions').change(function() {\n window.location = thisComponentHref + $(this).val() + '/~info';\n });\n\n var refreshPreview = function() {\n var splitted = $('#href')\n .val()\n .split('?'),\n url = splitted[0],\n lang = $('#lang').val();\n\n if (url.slice(-1) !== '/') {\n url += '/';\n }\n\n url = url.replace('http://', '//').replace('https://', '//');\n url += '~preview/?__ocAcceptLanguage=' + lang + '&';\n\n if (splitted.length > 1) {\n url += splitted[1];\n }\n\n $('.preview-iframe').attr('src', url);\n\n return false;\n };\n\n var updateHrefFromParameters = function() {\n var baseUrl = $('#href').val().split('?')[0];\n var params = {};\n \n // Collect all parameter values\n $('.parameter-input').each(function() {\n var paramName = $(this).data('parameter');\n var paramValue;\n \n // Handle different input types\n if ($(this).attr('type') === 'checkbox') {\n paramValue = $(this).is(':checked') ? 'true' : 'false';\n } else {\n paramValue = $(this).val();\n }\n \n if (paramValue && paramValue.trim() !== '' && paramValue !== 'false') {\n params[paramName] = paramValue.trim();\n }\n });\n \n // Build query string\n var queryString = Object.keys(params).map(function(key) {\n return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);\n }).join('&');\n \n // Update href\n var newHref = baseUrl + (queryString ? '?' + queryString : '');\n $('#href').val(newHref);\n \n return newHref;\n };\n\n $('.refresh-preview').click(refreshPreview);\n\n // Add Enter key handler for the href input field\n $('#href').keypress(function(e) {\n if (e.which === 13) { // Enter key\n refreshPreview();\n return false;\n }\n });\n\n // Handle parameter input changes\n $('.parameter-input').on('input blur change', function() {\n updateHrefFromParameters();\n });\n\n // Handle Enter key on parameter inputs (for text and number inputs)\n $('.parameter-input[type=\"text\"], .parameter-input[type=\"number\"]').keypress(function(e) {\n if (e.which === 13) { // Enter key\n updateHrefFromParameters();\n refreshPreview();\n return false;\n }\n });\n\n // Handle checkbox changes - immediately refresh preview\n $('.parameter-input[type=\"checkbox\"]').on('change', function() {\n updateHrefFromParameters();\n refreshPreview();\n });\n\n $('.open-preview').click(function() {\n refreshPreview();\n var url = $('.preview-iframe').attr('src');\n\n window.open(url, '_blank');\n return false;\n });\n\n // Collapsible sections functionality\n function initCollapsibleSections() {\n // Check if we're on mobile (screen width <= 1024px)\n var isMobile = window.innerWidth <= 1024;\n \n $('.collapsible-header').each(function() {\n var header = $(this);\n var content = $('#' + header.data('target'));\n var toggle = header.find('.collapse-toggle');\n \n // On mobile, start collapsed; on desktop, start expanded\n if (isMobile) {\n content.addClass('collapsed').removeClass('expanded');\n header.addClass('collapsed');\n } else {\n content.addClass('expanded').removeClass('collapsed');\n header.removeClass('collapsed');\n }\n \n // Handle click on header or toggle button\n header.on('click', function(e) {\n e.preventDefault();\n toggleSection(header, content);\n });\n \n toggle.on('click', function(e) {\n e.preventDefault();\n e.stopPropagation();\n toggleSection(header, content);\n });\n });\n }\n \n function toggleSection(header, content) {\n if (content.hasClass('collapsed')) {\n content.removeClass('collapsed').addClass('expanded');\n header.removeClass('collapsed');\n } else {\n content.removeClass('expanded').addClass('collapsed');\n header.addClass('collapsed');\n }\n }\n \n // Initialize collapsible sections on page load\n initCollapsibleSections();\n \n // Re-initialize on window resize\n $(window).on('resize', function() {\n initCollapsibleSections();\n });\n\n});";
|
|
1
|
+
declare const _default: "\nvar oc = oc || {};\noc.cmd = oc.cmd || [];\n\noc.cmd.push(function() {\n $('#versions').change(function() {\n window.location = thisComponentHref + $(this).val() + '/~info';\n });\n\n var refreshPreview = function() {\n var splitted = $('#href')\n .val()\n .split('?'),\n url = splitted[0],\n lang = $('#lang').val();\n\n if (url.slice(-1) !== '/') {\n url += '/';\n }\n\n url = url.replace('http://', '//').replace('https://', '//');\n url += '~preview/?__ocAcceptLanguage=' + lang + '&';\n\n if (splitted.length > 1) {\n url += splitted[1];\n }\n\n $('.preview-iframe').attr('src', url);\n\n return false;\n };\n\n var updateHrefFromParameters = function() {\n var baseUrl = $('#href').val().split('?')[0];\n var params = {};\n \n // Collect all parameter values\n $('.parameter-input').each(function() {\n var paramName = $(this).data('parameter');\n var paramValue;\n \n // Handle different input types\n if ($(this).attr('type') === 'checkbox') {\n paramValue = $(this).is(':checked') ? 'true' : 'false';\n } else {\n paramValue = $(this).val();\n }\n \n if (paramValue && paramValue.trim() !== '' && paramValue !== 'false') {\n params[paramName] = paramValue.trim();\n }\n });\n \n // Build query string\n var queryString = Object.keys(params).map(function(key) {\n return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);\n }).join('&');\n \n // Update href\n var newHref = baseUrl + (queryString ? '?' + queryString : '');\n $('#href').val(newHref);\n \n return newHref;\n };\n\n $('.refresh-preview').click(refreshPreview);\n\n // Add Enter key handler for the href input field\n $('#href').keypress(function(e) {\n if (e.which === 13) { // Enter key\n refreshPreview();\n return false;\n }\n });\n\n // Handle parameter input changes\n $('.parameter-input').on('input blur change', function() {\n updateHrefFromParameters();\n });\n\n // Handle Enter key on parameter inputs (for text and number inputs)\n $('.parameter-input[type=\"text\"], .parameter-input[type=\"number\"]').keypress(function(e) {\n if (e.which === 13) { // Enter key\n updateHrefFromParameters();\n refreshPreview();\n return false;\n }\n });\n\n // Handle checkbox changes - immediately refresh preview\n $('.parameter-input[type=\"checkbox\"]').on('change', function() {\n updateHrefFromParameters();\n refreshPreview();\n });\n\n $('.open-preview').click(function() {\n refreshPreview();\n var url = $('.preview-iframe').attr('src');\n\n window.open(url, '_blank');\n return false;\n });\n\n // Copy the component URL to the clipboard with inline feedback\n $('.copy-href').click(function() {\n var $btn = $(this);\n var $label = $btn.find('.copy-href-label');\n var value = $('#href').val();\n\n var onDone = function() {\n var prev = $label.text();\n $label.text('Copied');\n $btn.addClass('copied');\n setTimeout(function() {\n $label.text(prev || 'Copy');\n $btn.removeClass('copied');\n }, 1500);\n };\n\n if (navigator.clipboard && navigator.clipboard.writeText) {\n navigator.clipboard.writeText(value).then(onDone).catch(function() {\n $('#href').select();\n try { document.execCommand('copy'); onDone(); } catch (e) {}\n });\n } else {\n $('#href').select();\n try { document.execCommand('copy'); onDone(); } catch (e) {}\n }\n\n return false;\n });\n\n // Collapsible sections functionality\n function initCollapsibleSections() {\n // Check if we're on mobile (screen width <= 1024px)\n var isMobile = window.innerWidth <= 1024;\n \n $('.collapsible-header').each(function() {\n var header = $(this);\n var content = $('#' + header.data('target'));\n var toggle = header.find('.collapse-toggle');\n \n // On mobile, start collapsed; on desktop, start expanded\n if (isMobile) {\n content.addClass('collapsed').removeClass('expanded');\n header.addClass('collapsed');\n } else {\n content.addClass('expanded').removeClass('collapsed');\n header.removeClass('collapsed');\n }\n \n // Handle click on header or toggle button\n header.on('click', function(e) {\n e.preventDefault();\n toggleSection(header, content);\n });\n \n toggle.on('click', function(e) {\n e.preventDefault();\n e.stopPropagation();\n toggleSection(header, content);\n });\n });\n }\n \n function toggleSection(header, content) {\n if (content.hasClass('collapsed')) {\n content.removeClass('collapsed').addClass('expanded');\n header.removeClass('collapsed');\n } else {\n content.removeClass('expanded').addClass('collapsed');\n header.addClass('collapsed');\n }\n }\n \n // Initialize collapsible sections on page load\n initCollapsibleSections();\n \n // Re-initialize on window resize\n $(window).on('resize', function() {\n initCollapsibleSections();\n });\n\n});";
|
|
2
2
|
export default _default;
|
|
@@ -103,6 +103,35 @@ oc.cmd.push(function() {
|
|
|
103
103
|
return false;
|
|
104
104
|
});
|
|
105
105
|
|
|
106
|
+
// Copy the component URL to the clipboard with inline feedback
|
|
107
|
+
$('.copy-href').click(function() {
|
|
108
|
+
var $btn = $(this);
|
|
109
|
+
var $label = $btn.find('.copy-href-label');
|
|
110
|
+
var value = $('#href').val();
|
|
111
|
+
|
|
112
|
+
var onDone = function() {
|
|
113
|
+
var prev = $label.text();
|
|
114
|
+
$label.text('Copied');
|
|
115
|
+
$btn.addClass('copied');
|
|
116
|
+
setTimeout(function() {
|
|
117
|
+
$label.text(prev || 'Copy');
|
|
118
|
+
$btn.removeClass('copied');
|
|
119
|
+
}, 1500);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
123
|
+
navigator.clipboard.writeText(value).then(onDone).catch(function() {
|
|
124
|
+
$('#href').select();
|
|
125
|
+
try { document.execCommand('copy'); onDone(); } catch (e) {}
|
|
126
|
+
});
|
|
127
|
+
} else {
|
|
128
|
+
$('#href').select();
|
|
129
|
+
try { document.execCommand('copy'); onDone(); } catch (e) {}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return false;
|
|
133
|
+
});
|
|
134
|
+
|
|
106
135
|
// Collapsible sections functionality
|
|
107
136
|
function initCollapsibleSections() {
|
|
108
137
|
// Check if we're on mobile (screen width <= 1024px)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "\n@import url(\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap\");\n\n:root {\n /* Primary brand colors (consistent across themes) */\n --color-primary: #6366f1;\n --color-primary-dark: #4f46e5;\n --color-primary-light: #818cf8;\n --color-secondary: #06b6d4;\n --color-accent: #f59e0b;\n\n --gradient-primary: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n --gradient-secondary: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%);\n --gradient-accent: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n\n /* Legacy color mappings for backward compatibility */\n --color-warning: #ffe066;\n --color-warning-text: #7c3aed;\n --color-danger: #ffd6d6;\n --color-danger-text: #c92a2a;\n --color-state-border: #e9ecef;\n}\n\n/* Dark theme (default) */\n:root, [data-theme=\"dark\"] {\n --color-bg-primary: #0f0f23;\n --color-bg-secondary: #1a1a2e;\n --color-bg-card: #16213e;\n --color-bg-glass: rgba(255, 255, 255, 0.05);\n\n --color-text-primary: #ffffff;\n --color-text-secondary: #b4b4b8;\n --color-text-muted: #acacb9;\n\n --color-border: rgba(255, 255, 255, 0.1);\n --color-border-hover: rgba(255, 255, 255, 0.2);\n\n --gradient-card: rgba(255,255,255,0.03); /* Simplified from gradient */\n\n --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);\n --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n --shadow-glow: 0 0 20px rgba(99, 102, 241, 0.3);\n\n /* Dark theme text inverse (for buttons, etc) */\n --color-text-inverse: #ffffff;\n}\n\n/* Light theme */\n[data-theme=\"light\"] {\n --color-bg-primary: #ffffff;\n --color-bg-secondary: #f8fafc;\n --color-bg-card: #ffffff;\n --color-bg-glass: rgba(255, 255, 255, 0.8);\n\n --color-text-primary: #1e293b;\n --color-text-secondary: #475569; /* Improved contrast from #64748b */\n --color-text-muted: #64748b; /* Improved contrast from #94a3b8 */\n\n --color-border: rgba(0, 0, 0, 0.1);\n --color-border-hover: rgba(0, 0, 0, 0.15);\n\n --gradient-card: rgba(0,0,0,0.02); /* Simplified from gradient */\n\n --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);\n --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n --shadow-glow: 0 0 20px rgba(99, 102, 241, 0.2);\n\n /* Light theme text inverse (for buttons, etc) */\n --color-text-inverse: #ffffff;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n @view-transition {\n navigation: auto;\n }\n}\n\nbody {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n background: var(--color-bg-primary);\n color: var(--color-text-primary);\n line-height: 1.6;\n min-height: 100vh;\n overflow-x: hidden;\n}\n\n/* Animated background - Dark theme */\nbody::before {\n content: '';\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background:\n radial-gradient(circle at 20% 80%, rgba(99, 102, 241, 0.1) 0%, transparent 50%),\n radial-gradient(circle at 80% 20%, rgba(139, 92, 246, 0.1) 0%, transparent 50%),\n radial-gradient(circle at 40% 40%, rgba(6, 182, 212, 0.05) 0%, transparent 50%);\n z-index: -1;\n transition: opacity 0.3s ease;\n}\n\n/* Animated background - Light theme */\n[data-theme=\"light\"] body::before {\n background:\n radial-gradient(circle at 20% 80%, rgba(99, 102, 241, 0.03) 0%, transparent 50%),\n radial-gradient(circle at 80% 20%, rgba(139, 92, 246, 0.03) 0%, transparent 50%),\n radial-gradient(circle at 40% 40%, rgba(6, 182, 212, 0.02) 0%, transparent 50%);\n}\n\n.container {\n max-width: 1400px;\n margin: 0 auto;\n padding: 0 2rem;\n}\n\n/* Header */\n.header {\n background: var(--color-bg-glass);\n backdrop-filter: blur(20px);\n border-bottom: 1px solid var(--color-border);\n position: sticky;\n top: 0;\n z-index: 100;\n}\n\n.header-content {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 0;\n}\n\n.logo {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n text-decoration: none;\n color: var(--color-text-primary);\n font-weight: 700;\n font-size: 1.25rem;\n transition: all 0.3s ease;\n}\n\n.logo:hover {\n color: var(--color-primary-light);\n transform: translateY(-1px);\n}\n\n.logo-icon {\n color: #fff;\n width: 32px;\n height: 32px;\n background: var(--gradient-primary);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: bold;\n font-size: 1.1rem;\n}\n\n.logo img {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n}\n\n/* Theme Toggle Button */\n.theme-toggle {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n background: var(--color-bg-glass);\n border: 1px solid var(--color-border);\n border-radius: 8px;\n color: var(--color-text-primary);\n font-size: 0.875rem;\n font-weight: 500;\n transition: all 0.3s ease;\n cursor: pointer;\n backdrop-filter: blur(10px);\n}\n\n.theme-toggle:hover {\n border-color: var(--color-border-hover);\n background: var(--color-bg-card);\n transform: translateY(-1px);\n}\n\n.theme-toggle-icon {\n font-size: 1.1rem;\n transition: transform 0.3s ease;\n}\n\n.theme-toggle:hover .theme-toggle-icon {\n transform: rotate(15deg);\n}\n\nh1, h2, h3 {\n color: var(--color-text-primary);\n font-weight: 600;\n margin-bottom: 0.5em;\n}\n\nh1 {\n font-size: 3.5rem;\n font-weight: 700;\n background: var(--gradient-primary);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 1rem;\n text-align: center;\n}\n\nh2 {\n font-size: 1.5rem; /* Increased from 1.25rem */\n font-weight: 600;\n color: var(--color-text-primary);\n margin-bottom: 0.75em;\n}\n\nh3 {\n font-size: 1.25rem; /* Increased from 1.1rem */\n font-weight: 600;\n}\n\n/* Focus styles for accessibility */\n*:focus {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\n*:focus:not(:focus-visible) {\n outline: none;\n}\n\n*:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\na {\n color: var(--color-text-primary);\n text-decoration: none;\n transition: color 0.3s ease;\n border-radius: 4px; /* For better focus outline */\n}\na:hover {\n color: var(--color-primary);\n text-decoration: underline;\n}\na:focus {\n color: var(--color-primary);\n}\n\n#components-list a:hover {\n text-decoration: none;\n}\n\np {\n margin-top: 0;\n}\n\n.logo {\n margin-top: 10px;\n}\n\n.back {\n width: 100%;\n margin-top: -20px;\n margin-bottom: 1.5em;\n display: block;\n color: var(--color-text-muted);\n font-size: 0.95em;\n}\n\n/* Content Sections */\n.content-section {\n background: var(--color-bg-card);\n border-radius: 16px;\n border: 1px solid var(--color-border);\n overflow: hidden;\n transition: all 0.3s ease;\n margin-bottom: 2rem;\n}\n\n.content-section:hover {\n border-color: var(--color-border-hover);\n box-shadow: var(--shadow-lg);\n}\n\n.section-header {\n padding: 1.5rem 2rem;\n background: var(--gradient-card);\n border-bottom: 1px solid var(--color-border);\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.section-title {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--color-text-primary);\n}\n\n.section-icon {\n font-size: 1.25rem;\n /* Removed gradient background, border-radius, and container styling */\n /* Now just using emoji directly for better accessibility */\n}\n\n.section-content {\n padding: 2rem;\n}\n\n.code,\n.preview {\n width: 100%;\n background: var(--color-bg-card);\n border-radius: 16px;\n box-shadow: var(--shadow-md);\n margin-bottom: 1.5em;\n border: 1px solid var(--color-border);\n}\n\n.preview {\n height: 500px;\n}\n\n.preview iframe {\n width: 100%;\n height: 100%;\n border: none;\n background: white;\n border-radius: 0 0 16px 16px;\n}\n\n.table {\n width: 100%;\n}\n\n.w-100 {\n width: 100%;\n}\n\n.row {\n background: var(--color-bg-card);\n border: 1px solid var(--color-border);\n border-radius: 12px;\n width: 100%;\n display: flex;\n padding: 14px 0px;\n box-sizing: border-box;\n margin-bottom: 8px;\n align-items: center;\n box-shadow: var(--shadow-md);\n transition: all 0.3s ease;\n}\n\n.row.header {\n background: var(--gradient-card);\n border: 1px solid var(--color-border) !important;\n font-size: 1.1em;\n font-weight: 600;\n border-radius: 12px 12px 0 0;\n box-shadow: none;\n color: var(--color-text-primary);\n}\n\n.row.header div {\n font-weight: bold;\n margin: 0;\n align-self: flex-start;\n}\n\n.row.double {\n min-height: 60px;\n}\n\n.row div {\n word-wrap: break-word;\n}\n\n.row span {\n padding-right: 10px;\n}\n\n.componentRow {\n transition:\n box-shadow 0.2s,\n background 0.2s;\n}\n\n.componentRow:hover {\n background: var(--color-bg-glass);\n box-shadow: var(--shadow-lg);\n border-color: var(--color-primary);\n transform: translateY(-2px);\n}\n\n.componentRow .title .name {\n font-weight: bold;\n font-size: 1.15rem;\n margin: 0;\n width: 100%;\n color: var(--color-text-primary);\n}\n\n.componentRow .release {\n font-size: 1rem;\n margin: 0;\n width: 100%;\n color: var(--color-text-primary);\n}\n\n.componentRow .title .description {\n padding: 0;\n font-size: 0.98rem;\n color: var(--color-text-muted);\n}\n\n.social {\n width: 100%;\n margin-top: 20px;\n text-align: center;\n}\n\n.field {\n width: 100%;\n margin-bottom: 1em;\n}\n\n.field p,\n.field span,\n.field a {\n margin: 0;\n font-weight: 500;\n}\n\n.field p {\n color: var(--color-primary);\n font-weight: bold;\n margin-right: 10px;\n}\n\ninput[type=\"text\"],\ntextarea,\nselect {\n background: var(--color-bg-card);\n border: 1px solid var(--color-border);\n color: var(--color-text-primary);\n padding: 0.75rem 1rem;\n border-radius: 8px;\n font-family: inherit;\n font-size: 1rem;\n transition: all 0.3s ease;\n margin-bottom: 10px;\n box-sizing: border-box;\n}\n\ninput[type=\"text\"]:focus,\ntextarea:focus,\nselect:focus {\n outline: none;\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.btn {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n border-radius: 8px;\n font-size: 0.875rem;\n font-weight: 500;\n text-decoration: none;\n transition: all 0.3s ease;\n border: none;\n cursor: pointer;\n font-family: inherit;\n}\n\n.btn-primary {\n background: var(--gradient-primary);\n color: white;\n}\n\n.btn-primary:hover {\n transform: translateY(-1px);\n box-shadow: var(--shadow-glow);\n}\n\n.btn-secondary {\n background: var(--color-bg-glass);\n color: var(--color-text-primary);\n border: 1px solid var(--color-border);\n}\n\n.btn-secondary:hover {\n border-color: var(--color-border-hover);\n background: var(--color-bg-secondary);\n}\n\n.filters {\n width: 100%;\n display: flex;\n justify-content: space-between;\n gap: 1em;\n margin-bottom: 0.5em;\n}\n\n.row > * {\n flex: 0 1 8%;\n padding: 0px 5px;\n align-self: center;\n}\n\n.row > *:last-child {\n padding-right: 10px;\n}\n\n.row > *:first-child {\n padding-left: 10px;\n}\n\n.release,\n.title,\n.filters > * {\n flex: 1 0;\n}\n\n.title {\n display: flex;\n flex-direction: column;\n}\n\n.filters input {\n color: var(--color-text-primary);\n background-color: var(--color-bg-card);\n}\n\n#author-filter {\n flex: 0 1 30%;\n}\n\n.parameter {\n flex: 1 0;\n max-width: 25%;\n align-self: flex-start;\n}\n\n.parameter-description {\n flex: 1 0;\n max-width: 70%;\n}\n\n.author {\n flex: 0 1 15%;\n word-break: break-all;\n color: var(--color-text-secondary);\n}\n\n#href {\n height: 60px;\n}\n\n.states {\n width: 100%;\n margin-bottom: 30px;\n display: flex;\n align-items: center;\n gap: 1.5rem;\n flex-wrap: wrap;\n}\n\n.states > span {\n color: var(--color-text-secondary);\n font-weight: 500;\n font-size: 0.875rem;\n}\n\n.states input {\n margin-right: 6px;\n}\n\n/* Custom Checkbox Styling */\n.checkbox-wrapper {\n display: inline-flex;\n align-items: center;\n gap: 0.75rem;\n cursor: pointer;\n user-select: none;\n transition: all 0.3s ease;\n}\n\n.checkbox-wrapper:hover {\n transform: translateY(-1px);\n}\n\n.checkbox-input {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n}\n\n.checkbox-custom {\n position: relative;\n width: 20px;\n height: 20px;\n background: var(--color-bg-card);\n border: 2px solid var(--color-border);\n border-radius: 6px;\n transition: all 0.3s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.checkbox-input:checked + .checkbox-custom {\n background: var(--gradient-primary);\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.checkbox-input:focus + .checkbox-custom {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\n.checkbox-icon {\n width: 12px;\n height: 12px;\n stroke: white;\n stroke-width: 2;\n fill: none;\n stroke-linecap: round;\n stroke-linejoin: round;\n opacity: 0;\n transform: scale(0.8);\n transition: all 0.2s ease;\n}\n\n.checkbox-input:checked + .checkbox-custom .checkbox-icon {\n opacity: 1;\n transform: scale(1);\n}\n\n.checkbox-wrapper:hover .checkbox-custom {\n border-color: var(--color-border-hover);\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.15);\n}\n\n.checkbox-wrapper:hover .checkbox-input:checked + .checkbox-custom {\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2), 0 2px 8px rgba(99, 102, 241, 0.3);\n}\n\n/* Removed old details-state styling - now using state-badge class */\n\n#versions {\n margin-left: 10px;\n}\n\n/* Updated state styling to use modern badge design */\n.state {\n display: inline-flex;\n align-items: center;\n font-size: 0.875rem;\n font-weight: 600;\n padding: 0.375rem 0.75rem;\n border-radius: 12px;\n white-space: nowrap;\n transition: all 0.3s ease;\n border: 1px solid transparent;\n backdrop-filter: blur(10px);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n margin-right: 10px;\n}\n\n.table .state {\n /* Remove the old background and height - now using component-state classes */\n}\n\n/* Enhanced State Badge Styling - moved to component state section */\n\n/* Component State Badge Styling */\n.state-badge {\n display: inline-flex;\n align-items: center;\n font-size: 0.875rem;\n font-weight: 600;\n padding: 0.375rem 0.75rem;\n border-radius: 12px;\n white-space: nowrap;\n transition: all 0.3s ease;\n border: 1px solid transparent;\n backdrop-filter: blur(10px);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n margin-left: 0.75rem;\n}\n\n/* Mobile compact view - hidden on desktop */\n.mobile-compact {\n display: none;\n}\n\n.state-badge:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n}\n\n/* Experimental state - warm orange/yellow like in the image */\n.component-state-experimental {\n background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);\n color: #92400e;\n border: 1px solid rgba(245, 158, 11, 0.3);\n box-shadow: 0 2px 8px rgba(245, 158, 11, 0.2);\n}\n\n.component-state-experimental:hover {\n box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);\n}\n\n/* Deprecated state - red */\n.component-state-deprecated {\n background: linear-gradient(135deg, #f87171 0%, #ef4444 100%);\n color: #991b1b;\n border: 1px solid rgba(239, 68, 68, 0.3);\n box-shadow: 0 2px 8px rgba(239, 68, 68, 0.2);\n}\n\n.component-state-deprecated:hover {\n box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);\n}\n\n/* Stable state - green */\n.component-state-stable {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: #064e3b;\n border: 1px solid rgba(16, 185, 129, 0.3);\n box-shadow: 0 2px 8px rgba(16, 185, 129, 0.2);\n}\n\n.component-state-stable:hover {\n box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);\n}\n\n/* Beta state - blue */\n.component-state-beta {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: #1e3a8a;\n border: 1px solid rgba(59, 130, 246, 0.3);\n box-shadow: 0 2px 8px rgba(59, 130, 246, 0.2);\n}\n\n.component-state-beta:hover {\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);\n}\n\n/* Alpha state - purple */\n.component-state-alpha {\n background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);\n color: #4c1d95;\n border: 1px solid rgba(139, 92, 246, 0.3);\n box-shadow: 0 2px 8px rgba(139, 92, 246, 0.2);\n}\n\n.component-state-alpha:hover {\n box-shadow: 0 4px 12px rgba(139, 92, 246, 0.3);\n}\n\na.tab-link {\n color: var(--color-primary-light);\n font-weight: 500;\n padding: 0.5rem 1rem;\n border-radius: 8px;\n transition: all 0.3s ease;\n font-size: 1rem;\n line-height: 1.2;\n vertical-align: middle;\n display: inline-block;\n border: 1px solid transparent;\n}\n\na.tab-link:hover {\n background: var(--color-bg-glass);\n border-color: var(--color-border);\n}\n\na.tab-link.selected {\n background: var(--gradient-primary);\n color: white;\n text-decoration: none;\n border-color: var(--color-primary);\n}\n\n.bold {\n font-weight: bold;\n}\n\n.hide {\n display: none !important;\n}\n\n.box {\n background: var(--color-bg-card);\n border-radius: 12px; /* Reduced from 16px */\n border: 1px solid var(--color-border);\n padding: 1.5em 2em;\n margin-bottom: 2em;\n transition: all 0.3s ease;\n /* Removed default shadow */\n}\n\n.box:hover {\n border-color: var(--color-border-hover);\n box-shadow: var(--shadow-md); /* Only on hover */\n transform: translateY(-1px); /* Reduced from -2px */\n}\n\n/* Hero Section */\n.hero {\n padding: 3rem 0;\n text-align: center;\n position: relative;\n}\n\n/* Info Cards */\n.info-card {\n background: var(--color-bg-card);\n border: 1px solid var(--color-border);\n border-radius: 12px; /* Reduced from 16px */\n padding: 1.5rem;\n transition: all 0.3s ease;\n margin-bottom: 1.5rem;\n /* Removed default shadow */\n}\n\n.info-card:hover {\n border-color: var(--color-border-hover);\n transform: translateY(-1px); /* Reduced from -2px */\n box-shadow: var(--shadow-md); /* Reduced from shadow-lg */\n}\n\n.info-item {\n display: flex;\n align-items: start;\n padding: 0.75rem 0;\n border-bottom: 1px solid var(--color-border);\n}\n\n.info-item:last-child {\n border-bottom: none;\n}\n\n.info-label {\n font-weight: 500;\n color: var(--color-text-secondary);\n min-width: 100px;\n}\n\n.info-value {\n color: var(--color-text-primary);\n text-align: right;\n flex: 1;\n margin-left: 1rem;\n}\n\n/* Animations */\n@keyframes fadeInUp {\n from {\n opacity: 0;\n transform: translateY(30px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes float {\n 0%, 100% { transform: translateY(0px); }\n 50% { transform: translateY(-10px); }\n}\n\n/* Custom scrollbar */\n::-webkit-scrollbar {\n width: 8px;\n}\n\n::-webkit-scrollbar-track {\n background: var(--color-bg-secondary);\n}\n\n::-webkit-scrollbar-thumb {\n background: var(--color-border-hover);\n border-radius: 4px;\n}\n\n::-webkit-scrollbar-thumb:hover {\n background: var(--color-primary);\n}\n\n/* Main Content Layout */\n.main-content {\n display: grid;\n grid-template-columns: 1fr 350px;\n gap: 2rem;\n padding: 2rem 0;\n}\n\n.sidebar {\n display: grid;\n gap: 1.5rem;\n align-content: start;\n}\n\n/* Collapsible Sections */\n.collapsible-section {\n transition: all 0.3s ease;\n}\n\n.collapsible-header {\n cursor: pointer;\n user-select: none;\n position: relative;\n transition: all 0.3s ease;\n}\n\n.collapsible-header:hover {\n background: var(--color-bg-glass);\n}\n\n.collapse-toggle {\n position: absolute;\n right: 1.5rem;\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n color: var(--color-text-secondary);\n font-size: 1rem;\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 4px;\n transition: all 0.3s ease;\n}\n\n.collapse-toggle:hover {\n background: var(--color-bg-glass);\n color: var(--color-text-primary);\n}\n\n.collapse-icon {\n transition: transform 0.3s ease;\n display: inline-block;\n}\n\n.collapsible-content {\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n.collapsible-content.collapsed {\n max-height: 0;\n padding-top: 0;\n padding-bottom: 0;\n opacity: 0;\n}\n\n.collapsible-content.expanded {\n max-height: 2000px;\n opacity: 1;\n}\n\n.collapsible-header.collapsed .collapse-icon {\n transform: rotate(-90deg);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n\n .info-item {\n display: flex;\n justify-content: space-between;\n }\n\n .container {\n padding: 0 1rem;\n }\n\n h1 {\n font-size: 2.5rem;\n }\n\n .main-content {\n grid-template-columns: 1fr;\n gap: 1.5rem;\n }\n\n .sidebar {\n order: -1;\n }\n\n /* Mobile collapsible sections - collapsed by default */\n .collapsible-content {\n max-height: 0;\n padding-top: 0;\n padding-bottom: 0;\n opacity: 0;\n }\n\n .collapsible-header.collapsed .collapse-icon {\n transform: rotate(-90deg);\n }\n}\n\n@media (max-width: 900px) {\n .container {\n padding: 0 1rem;\n }\n\n .main-content {\n padding: 1rem 0;\n gap: 1rem;\n }\n\n .filters {\n flex-direction: column;\n gap: 0.5em;\n }\n\n /* Mobile responsive components list */\n .row.header {\n display: none; /* Hide desktop table header on mobile */\n }\n\n .componentRow {\n flex-direction: column !important;\n align-items: center !important;\n padding: 1rem !important;\n gap: 0.75rem !important;\n text-align: center !important;\n }\n\n /* Hide desktop table columns on mobile */\n .componentRow > .author,\n .componentRow > .date,\n .componentRow > .activity,\n .componentRow > div:not(.title):not(.state):not(.mobile-compact) {\n display: none !important;\n }\n\n /* Show mobile compact view */\n .mobile-compact {\n display: block !important;\n width: 100%;\n }\n\n .mobile-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 0.75rem;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n color: var(--color-text-secondary);\n width: 100%;\n }\n\n .mobile-meta span {\n background: var(--color-bg-glass);\n padding: 0.25rem 0.5rem;\n border-radius: 6px;\n border: 1px solid var(--color-border);\n font-size: 0.8rem;\n font-weight: 500;\n }\n\n .mobile-author {\n color: var(--color-primary) !important;\n }\n\n .mobile-version {\n color: var(--color-text-primary) !important;\n font-weight: 600;\n }\n\n .mobile-date {\n color: var(--color-text-muted) !important;\n }\n\n .mobile-activity {\n color: var(--color-accent) !important;\n }\n\n .mobile-size {\n color: var(--color-secondary) !important;\n }\n\n /* Center the title section on mobile */\n .componentRow .title {\n text-align: center !important;\n width: 100%;\n }\n\n .componentRow .title .name {\n text-align: center !important;\n }\n\n .componentRow .title .description {\n text-align: center !important;\n }\n\n .box, .info-card, .section-content {\n padding: 1.5rem 1rem;\n }\n\n .sidebar .info-card {\n padding: 1rem;\n }\n\n .sidebar .info-item {\n flex-direction: column;\n align-items: flex-start;\n gap: 0.5rem;\n }\n\n .sidebar .info-label {\n min-width: auto;\n font-weight: 600;\n }\n\n .sidebar .info-value {\n text-align: left;\n margin-left: 0;\n }\n\n h1 {\n font-size: 2rem;\n }\n}\n\n/* Loading states */\n.loader {\n text-align: center;\n padding: 2em;\n color: var(--color-text-muted);\n}\n\n.empty-state {\n text-align: center;\n padding: 2em;\n color: var(--color-text-muted);\n font-style: italic;\n margin: 0;\n}\n\n.loader p {\n margin: 0;\n font-style: italic;\n}\n\n.loader::before {\n content: '';\n display: inline-block;\n width: 20px;\n height: 20px;\n border: 2px solid var(--color-border);\n border-top: 2px solid var(--color-primary);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n margin-right: 0.5em;\n vertical-align: middle;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.loading-more {\n text-align: center;\n padding: 1em 2em;\n color: var(--color-text-muted);\n font-style: italic;\n font-size: 0.9em;\n border-top: 1px solid var(--color-border);\n margin-top: 1em;\n}\n\n.loading-more::before {\n content: '';\n display: inline-block;\n width: 16px;\n height: 16px;\n border: 2px solid var(--color-border);\n border-top: 2px solid var(--color-primary);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n margin-right: 0.5em;\n vertical-align: middle;\n}\n\n#history-error {\n text-align: center;\n padding: 2em;\n color: var(--color-danger-text);\n background-color: var(--color-danger);\n border: 1px solid var(--color-state-border);\n border-radius: 6px;\n margin: 1em 0;\n}\n\n#history-error p {\n margin: 0;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: var(--color-text-secondary);\n font-size: 0.875rem;\n}\n\n.breadcrumb a {\n color: var(--color-primary-light);\n text-decoration: none;\n transition: color 0.3s ease;\n}\n\n.breadcrumb a:hover {\n color: var(--color-primary);\n}\n\n/* Parameters */\n.parameter-grid {\n display: grid;\n gap: 1.5rem;\n}\n\n.parameter-item {\n background: var(--color-bg-glass);\n border: 1px solid var(--color-border);\n border-radius: 12px;\n padding: 1.5rem;\n transition: all 0.3s ease;\n}\n\n.parameter-item:hover {\n border-color: var(--color-primary);\n box-shadow: 0 0 20px rgba(99, 102, 241, 0.1);\n}\n\n.parameter-header {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-bottom: 1rem;\n}\n\n.parameter-name {\n font-weight: 600;\n color: var(--color-text-primary);\n}\n\n.parameter-type {\n background: var(--color-secondary);\n color: white;\n padding: 0.25rem 0.75rem;\n border-radius: 12px; /* Reduced from 20px */\n font-size: 0.75rem;\n font-weight: 500;\n}\n\n.parameter-required {\n background: var(--color-accent);\n}\n\n.parameter-description {\n color: var(--color-text-secondary);\n margin-bottom: 1rem;\n line-height: 1.5;\n}\n\n.parameter-input {\n width: 100%;\n background: var(--color-bg-secondary);\n border: 1px solid var(--color-border);\n color: var(--color-text-primary);\n padding: 0.75rem 1rem;\n border-radius: 8px;\n font-family: inherit;\n transition: all 0.3s ease;\n}\n\n.parameter-input:focus {\n outline: none;\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n/* Preview Section */\n.preview-section {\n background: var(--color-bg-card);\n border-radius: 16px;\n border: 1px solid var(--color-border);\n overflow: hidden;\n margin-top: 2rem;\n}\n\n.preview-controls {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 2rem;\n background: var(--color-bg-glass);\n border-bottom: 1px solid var(--color-border);\n}\n\n.preview-buttons {\n display: flex;\n gap: 0.75rem;\n}\n\n.preview-iframe {\n width: 100%;\n height: 500px;\n border: none;\n background: white;\n}\n\n.back {\n width: 100%;\n margin-top: -20px;\n margin-bottom: 1.5em;\n display: block;\n color: var(--color-text-muted);\n font-size: 0.95em;\n}\n\n/* Stats Badge */\n.stats-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.75rem;\n background: var(--color-bg-card);\n border: 1px solid var(--color-border);\n border-radius: 12px;\n padding: 0.75rem 1.25rem;\n margin: 1.5rem auto 0;\n box-shadow: var(--shadow-md);\n transition: all 0.3s ease;\n max-width: fit-content;\n}\n\n.stats-badge:hover {\n border-color: var(--color-border-hover);\n box-shadow: var(--shadow-lg);\n transform: translateY(-1px);\n}\n\n.stats-badge .chart-icon {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n.stats-badge .chart-bar {\n width: 4px;\n border-radius: 2px;\n background: var(--gradient-primary);\n}\n\n.stats-badge .chart-bar:nth-child(1) {\n height: 12px;\n background: var(--color-primary-light);\n}\n\n.stats-badge .chart-bar:nth-child(2) {\n height: 16px;\n background: var(--color-primary);\n}\n\n.stats-badge .chart-bar:nth-child(3) {\n height: 20px;\n background: var(--color-primary-dark);\n}\n\n.stats-badge .badge-text {\n color: var(--color-text-primary);\n font-size: 0.875rem;\n font-weight: 500;\n white-space: nowrap;\n}\n ";
|
|
1
|
+
declare const _default: "\n@import url(\"https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap\");\n\n:root {\n /* Brand accent (consistent across themes) */\n --color-primary: #6366f1;\n --color-primary-dark: #4f46e5;\n --color-primary-light: #818cf8;\n --color-secondary: #0891b2;\n --color-accent: #d97706;\n\n --gradient-primary: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n\n /* Spacing / radius scale */\n --radius-sm: 6px;\n --radius-md: 10px;\n --radius-lg: 14px;\n --radius-full: 999px;\n\n --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --font-mono: 'JetBrains Mono', 'SFMono-Regular', Menlo, Monaco, Consolas, monospace;\n}\n\n/* Dark theme (default) */\n:root, [data-theme=\"dark\"] {\n --color-bg-primary: #0b0e14;\n --color-bg-secondary: #11151d;\n --color-bg-card: #11151d;\n --color-bg-elevated: #161c26;\n --color-bg-glass: rgba(255, 255, 255, 0.04);\n --color-bg-hover: rgba(255, 255, 255, 0.035);\n\n --color-text-primary: #e6edf3;\n --color-text-secondary: #aeb6c2;\n --color-text-muted: #7d8693;\n\n --color-border: #222a37;\n --color-border-hover: #323c4d;\n\n --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);\n --shadow-md: 0 4px 12px -2px rgba(0, 0, 0, 0.4);\n --shadow-lg: 0 12px 28px -6px rgba(0, 0, 0, 0.5);\n --shadow-glow: 0 4px 16px -2px rgba(99, 102, 241, 0.4);\n\n --color-text-inverse: #ffffff;\n\n --tint-strength: 0.16;\n --tint-border: 0.32;\n --badge-text-lightness: 78%;\n}\n\n/* Light theme */\n[data-theme=\"light\"] {\n --color-bg-primary: #fbfcfd;\n --color-bg-secondary: #f4f6f8;\n --color-bg-card: #ffffff;\n --color-bg-elevated: #ffffff;\n --color-bg-glass: rgba(255, 255, 255, 0.7);\n --color-bg-hover: rgba(15, 23, 42, 0.025);\n\n --color-text-primary: #1f2328;\n --color-text-secondary: #4a535e;\n --color-text-muted: #6a737d;\n\n --color-border: #e2e6ea;\n --color-border-hover: #cdd3da;\n\n --shadow-sm: 0 1px 2px 0 rgba(15, 23, 42, 0.05);\n --shadow-md: 0 4px 12px -2px rgba(15, 23, 42, 0.08);\n --shadow-lg: 0 12px 28px -6px rgba(15, 23, 42, 0.12);\n --shadow-glow: 0 4px 16px -2px rgba(99, 102, 241, 0.25);\n\n --color-text-inverse: #ffffff;\n\n --tint-strength: 0.1;\n --tint-border: 0.28;\n --badge-text-lightness: 38%;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n @view-transition {\n navigation: auto;\n }\n}\n\nbody {\n font-family: var(--font-sans);\n background: var(--color-bg-primary);\n color: var(--color-text-primary);\n line-height: 1.6;\n min-height: 100vh;\n overflow-x: hidden;\n -webkit-font-smoothing: antialiased;\n text-rendering: optimizeLegibility;\n font-size: 15px;\n}\n\n.container {\n max-width: 1240px;\n margin: 0 auto;\n padding: 0 1.5rem;\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.header {\n background: color-mix(in srgb, var(--color-bg-primary) 80%, transparent);\n backdrop-filter: blur(12px);\n border-bottom: 1px solid var(--color-border);\n position: sticky;\n top: 0;\n z-index: 100;\n}\n\n.header-content {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.85rem 0;\n}\n\n.logo {\n display: inline-flex;\n align-items: center;\n gap: 0.65rem;\n text-decoration: none;\n color: var(--color-text-primary);\n font-weight: 600;\n font-size: 1.0rem;\n letter-spacing: -0.01em;\n transition: color 0.15s ease;\n margin-top: 0;\n}\n\n.logo:hover {\n color: var(--color-text-primary);\n text-decoration: none;\n}\n\n.logo-icon {\n color: #fff;\n width: 30px;\n height: 30px;\n background: var(--gradient-primary);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 0.8rem;\n letter-spacing: 0.02em;\n box-shadow: var(--shadow-sm);\n}\n\n.logo img {\n width: 30px;\n height: 30px;\n border-radius: 8px;\n}\n\n/* Theme Toggle Button */\n.theme-toggle {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.45rem 0.85rem;\n background: var(--color-bg-card);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n color: var(--color-text-secondary);\n font-size: 0.8rem;\n font-weight: 500;\n font-family: inherit;\n transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;\n cursor: pointer;\n}\n\n.theme-toggle:hover {\n border-color: var(--color-border-hover);\n color: var(--color-text-primary);\n background: var(--color-bg-elevated);\n}\n\n.theme-toggle-icon {\n font-size: 1rem;\n line-height: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--color-text-secondary);\n}\n\n.theme-toggle:hover .theme-toggle-icon { color: var(--color-text-primary); }\n.theme-toggle-icon svg { display: block; }\n\n/* \u2500\u2500 Typography \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nh1, h2, h3 {\n color: var(--color-text-primary);\n font-weight: 600;\n letter-spacing: -0.02em;\n margin-bottom: 0.4em;\n}\n\nh1 {\n font-size: 2rem;\n font-weight: 680;\n margin-bottom: 0.5rem;\n line-height: 1.2;\n}\n\nh2 {\n font-size: 1.2rem;\n font-weight: 600;\n}\n\nh3 {\n font-size: 1.05rem;\n font-weight: 600;\n}\n\n/* Focus styles for accessibility */\n*:focus {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n*:focus:not(:focus-visible) { outline: none; }\n*:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\na {\n color: var(--color-primary-light);\n text-decoration: none;\n transition: color 0.15s ease;\n border-radius: 4px;\n}\na:hover { color: var(--color-primary); text-decoration: underline; }\na:focus { color: var(--color-primary); }\n\n[data-theme=\"light\"] a { color: var(--color-primary-dark); }\n\n#components-list a:hover { text-decoration: none; }\n\np { margin-top: 0; }\n\n.back {\n width: 100%;\n margin-bottom: 1.5em;\n display: block;\n color: var(--color-text-muted);\n font-size: 0.9em;\n}\n\n/* \u2500\u2500 Hero \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.hero {\n padding: 2.5rem 0 1.5rem;\n position: relative;\n}\n\n.hero h1 { text-align: left; }\n\n.component-title {\n font-family: var(--font-mono);\n font-weight: 600;\n font-size: 1.85rem;\n letter-spacing: -0.01em;\n}\n\n.component-description {\n color: var(--color-text-secondary);\n max-width: 70ch;\n margin-bottom: 0.5rem;\n font-size: 1rem;\n}\n\n.version-selector {\n display: inline-flex;\n align-items: center;\n gap: 0.6rem;\n margin: 0.75rem 0;\n}\n\n.version-label {\n color: var(--color-text-muted);\n font-size: 0.85rem;\n font-weight: 500;\n}\n\n/* \u2500\u2500 Stats badge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.stats-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.6rem;\n background: var(--color-bg-card);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: 0.5rem 0.9rem;\n margin: 1rem 0 0;\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n font-weight: 500;\n max-width: fit-content;\n}\n\n.stats-badge .chart-icon {\n display: flex;\n align-items: flex-end;\n gap: 2px;\n height: 16px;\n}\n\n.stats-badge .chart-bar { width: 3px; border-radius: 2px; }\n.stats-badge .chart-bar:nth-child(1) { height: 8px; background: var(--color-primary-light); }\n.stats-badge .chart-bar:nth-child(2) { height: 12px; background: var(--color-primary); }\n.stats-badge .chart-bar:nth-child(3) { height: 16px; background: var(--color-primary-dark); }\n\n.stats-badge .badge-text {\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n font-weight: 500;\n white-space: nowrap;\n display: inline-flex;\n align-items: center;\n}\n\n/* \u2500\u2500 Main layout \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.main-content {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 320px;\n gap: 1.75rem;\n padding: 1rem 0 3rem;\n align-items: start;\n}\n\n.sidebar {\n display: grid;\n gap: 1.25rem;\n align-content: start;\n position: sticky;\n top: 5rem;\n}\n\n/* \u2500\u2500 Tabs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#menuList {\n display: flex;\n gap: 0.25rem;\n border-bottom: 1px solid var(--color-border);\n margin-bottom: 1.5rem !important;\n overflow-x: auto;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n#menuList::-webkit-scrollbar { display: none; height: 0; }\n\na.tab-link {\n color: var(--color-text-secondary);\n font-weight: 500;\n padding: 0.6rem 0.9rem;\n border-radius: 0;\n transition: color 0.15s ease, border-color 0.15s ease;\n font-size: 0.9rem;\n line-height: 1.2;\n display: inline-block;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -1px;\n white-space: nowrap;\n}\n\na.tab-link:hover {\n color: var(--color-text-primary);\n background: transparent;\n text-decoration: none;\n}\n\na.tab-link.selected {\n color: var(--color-primary-light);\n background: transparent;\n text-decoration: none;\n border-bottom-color: var(--color-primary);\n}\n\n[data-theme=\"light\"] a.tab-link.selected { color: var(--color-primary-dark); }\n\n/* \u2500\u2500 Cards / sections \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.content-section {\n background: var(--color-bg-card);\n border-radius: var(--radius-lg);\n border: 1px solid var(--color-border);\n overflow: hidden;\n margin-bottom: 1.5rem;\n}\n\n.section-header {\n padding: 1rem 1.5rem;\n background: var(--color-bg-glass);\n border-bottom: 1px solid var(--color-border);\n display: flex;\n align-items: center;\n gap: 0.7rem;\n}\n\n.section-title {\n font-size: 1.05rem;\n font-weight: 600;\n color: var(--color-text-primary);\n letter-spacing: -0.01em;\n}\n\n.section-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--color-primary-light);\n flex-shrink: 0;\n}\n\n.section-icon svg { width: 18px; height: 18px; display: block; }\n\n[data-theme=\"light\"] .section-icon { color: var(--color-primary); }\n\n.section-content { padding: 1.5rem; }\n\n.box {\n background: var(--color-bg-card);\n border-radius: var(--radius-lg);\n border: 1px solid var(--color-border);\n padding: 1.25rem;\n margin-bottom: 1.5em;\n}\n\n/* \u2500\u2500 Info cards (sidebar) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.info-card {\n background: var(--color-bg-card);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n padding: 1.25rem 1.35rem;\n}\n\n.info-card .section-title {\n font-size: 0.8rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-text-muted);\n font-weight: 600;\n margin-bottom: 1rem !important;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.info-card .section-title svg { width: 15px; height: 15px; color: var(--color-text-muted); }\n\n.info-item {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 1rem;\n padding: 0.6rem 0;\n border-bottom: 1px solid var(--color-border);\n font-size: 0.875rem;\n}\n\n.info-item:last-child { border-bottom: none; padding-bottom: 0; }\n.info-item:first-of-type { padding-top: 0; }\n\n.info-label {\n font-weight: 500;\n color: var(--color-text-muted);\n flex-shrink: 0;\n}\n\n.info-value {\n color: var(--color-text-primary);\n text-align: right;\n word-break: break-word;\n font-weight: 450;\n}\n\n.info-value a { word-break: break-all; }\n\n/* \u2500\u2500 List / table rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#components-list.box,\n#components-history.box,\n#components-templates.box,\n#components-dependencies.box,\n#components-plugins.box {\n padding: 0;\n overflow: hidden;\n}\n\n.row {\n background: transparent;\n border: none;\n border-bottom: 1px solid var(--color-border);\n border-radius: 0;\n width: 100%;\n display: flex;\n padding: 0.9rem 1.25rem;\n box-sizing: border-box;\n margin-bottom: 0;\n align-items: center;\n box-shadow: none;\n transition: background 0.12s ease;\n gap: 0.5rem;\n}\n\n.row:last-child { border-bottom: none; }\n\n.row.header {\n background: var(--color-bg-glass);\n border: none;\n border-bottom: 1px solid var(--color-border) !important;\n font-size: 0.72rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n border-radius: 0;\n box-shadow: none;\n color: var(--color-text-muted);\n}\n\n.row.header div {\n font-weight: 600;\n margin: 0;\n align-self: center;\n}\n\n.row.double { min-height: 56px; }\n.row div { word-wrap: break-word; }\n.row span { padding-right: 10px; }\n\n/* clickable component rows (anchors that wrap an entire row) */\n#components-list > a,\n#components-history a,\n#components-dependencies > a {\n display: block;\n color: inherit;\n}\n\n.componentRow { transition: background 0.12s ease; }\n\n.componentRow:hover {\n background: var(--color-bg-hover);\n box-shadow: none;\n border-color: var(--color-border);\n transform: none;\n}\n\n#components-list > a:focus-visible,\n#components-history a:focus-visible,\n#components-dependencies > a:focus-visible {\n outline: none;\n}\n\n#components-list > a:focus-visible .componentRow,\n#components-history a:focus-visible .componentRow,\n#components-dependencies > a:focus-visible .componentRow {\n background: var(--color-bg-hover);\n box-shadow: inset 2px 0 0 var(--color-primary);\n}\n\n.componentRow .title .name {\n font-weight: 600;\n font-size: 0.95rem;\n margin: 0;\n width: 100%;\n color: var(--color-text-primary);\n letter-spacing: -0.005em;\n}\n\n.componentRow:hover .title .name { color: var(--color-primary-light); }\n[data-theme=\"light\"] .componentRow:hover .title .name { color: var(--color-primary-dark); }\n\n.componentRow .release {\n font-size: 0.9rem;\n margin: 0;\n width: 100%;\n color: var(--color-text-secondary);\n}\n\n.componentRow .release a { color: var(--color-primary-light); }\n[data-theme=\"light\"] .componentRow .release a { color: var(--color-primary-dark); }\n\n.componentRow .title .description {\n padding: 0;\n font-size: 0.85rem;\n color: var(--color-text-muted);\n margin-top: 0.15rem;\n line-height: 1.45;\n}\n\n.row > * {\n flex: 0 1 9%;\n padding: 0 0.35rem;\n align-self: center;\n font-size: 0.875rem;\n}\n\n.row > *:last-child { padding-right: 0; }\n.row > *:first-child { padding-left: 0; }\n\n.release,\n.title,\n.filters > * {\n flex: 1 0;\n}\n\n.title {\n display: flex;\n flex-direction: column;\n gap: 0.1rem;\n}\n\n.author {\n flex: 0 1 15%;\n word-break: break-word;\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n}\n\n.date { color: var(--color-text-muted); font-size: 0.85rem; }\n.activity { color: var(--color-text-secondary); font-size: 0.85rem; }\n\n/* \u2500\u2500 Filters \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.filters {\n width: 100%;\n display: flex;\n justify-content: space-between;\n gap: 0.75rem;\n margin: 0;\n padding: 1.25rem 1.25rem 0.75rem;\n}\n\n.filters input {\n color: var(--color-text-primary);\n background-color: var(--color-bg-secondary);\n margin-bottom: 0;\n}\n\n#author-filter { flex: 0 1 30%; }\n\n.states {\n width: 100%;\n margin: 0;\n padding: 0 1.25rem 1.25rem;\n display: flex;\n align-items: center;\n gap: 1.25rem;\n flex-wrap: wrap;\n border-bottom: 1px solid var(--color-border);\n}\n\n.states > span {\n color: var(--color-text-muted);\n font-weight: 500;\n font-size: 0.8rem;\n}\n\n.states input { margin-right: 6px; }\n\n/* \u2500\u2500 List results meta bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.list-meta {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.7rem 1.25rem;\n font-size: 0.8rem;\n color: var(--color-text-muted);\n font-weight: 500;\n}\n\n#results-count { color: var(--color-text-secondary); }\n\n/* \u2500\u2500 Component URL copy group \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.url-input-group {\n display: flex;\n gap: 0.5rem;\n align-items: stretch;\n}\n\n.url-input-group #href {\n flex: 1;\n margin-bottom: 0;\n padding: 0.7rem 0.9rem;\n}\n\n.url-input-group .copy-href {\n flex-shrink: 0;\n white-space: nowrap;\n}\n\n.copy-href.copied {\n color: color-mix(in srgb, #10b981 70%, var(--color-text-primary));\n border-color: color-mix(in srgb, #10b981 var(--tint-border), transparent);\n background: color-mix(in srgb, #10b981 var(--tint-strength), transparent);\n}\n\n/* \u2500\u2500 Forms \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\ninput[type=\"text\"],\ninput[type=\"number\"],\ntextarea,\nselect {\n background: var(--color-bg-secondary);\n border: 1px solid var(--color-border);\n color: var(--color-text-primary);\n padding: 0.6rem 0.85rem;\n border-radius: var(--radius-md);\n font-family: inherit;\n font-size: 0.9rem;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n margin-bottom: 10px;\n box-sizing: border-box;\n}\n\ninput[type=\"text\"]:focus,\ninput[type=\"number\"]:focus,\ntextarea:focus,\nselect:focus {\n outline: none;\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);\n}\n\ninput::placeholder { color: var(--color-text-muted); }\n\nselect {\n cursor: pointer;\n padding-right: 2rem;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%237d8693' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 0.7rem center;\n}\n\n#versions { margin-left: 0; min-width: 160px; margin-bottom: 0; }\n\n.w-100 { width: 100%; }\n.table { width: 100%; }\n\n/* \u2500\u2500 Buttons \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.5rem 0.9rem;\n border-radius: var(--radius-md);\n font-size: 0.85rem;\n font-weight: 500;\n text-decoration: none;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n cursor: pointer;\n font-family: inherit;\n line-height: 1.2;\n}\n\n.btn-primary { background: var(--color-primary); color: #fff; }\n.btn-primary:hover {\n background: var(--color-primary-dark);\n color: #fff;\n text-decoration: none;\n box-shadow: var(--shadow-glow);\n}\n\n.btn-secondary {\n background: var(--color-bg-card);\n color: var(--color-text-primary);\n border: 1px solid var(--color-border);\n}\n.btn-secondary:hover {\n border-color: var(--color-border-hover);\n background: var(--color-bg-elevated);\n color: var(--color-text-primary);\n text-decoration: none;\n}\n\n/* \u2500\u2500 Fields \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.field { width: 100%; margin-bottom: 1em; }\n\n.field p,\n.field span,\n.field a {\n margin: 0;\n font-weight: 500;\n}\n\n.field p {\n color: var(--color-text-muted);\n font-weight: 600;\n font-size: 0.8rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n margin-bottom: 0.4rem;\n}\n\n#href {\n height: auto;\n font-family: var(--font-mono) !important;\n font-size: 0.825rem !important;\n}\n\n/* \u2500\u2500 Checkbox \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.checkbox-wrapper {\n display: inline-flex;\n align-items: center;\n gap: 0.6rem;\n cursor: pointer;\n user-select: none;\n}\n\n.checkbox-input {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n}\n\n.checkbox-custom {\n position: relative;\n width: 18px;\n height: 18px;\n background: var(--color-bg-secondary);\n border: 1.5px solid var(--color-border-hover);\n border-radius: 5px;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.checkbox-input:checked + .checkbox-custom {\n background: var(--color-primary);\n border-color: var(--color-primary);\n}\n\n.checkbox-input:focus-visible + .checkbox-custom {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\n.checkbox-icon {\n width: 11px;\n height: 11px;\n stroke: #fff;\n stroke-width: 2.5;\n fill: none;\n stroke-linecap: round;\n stroke-linejoin: round;\n opacity: 0;\n transform: scale(0.7);\n transition: all 0.15s ease;\n}\n\n.checkbox-input:checked + .checkbox-custom .checkbox-icon {\n opacity: 1;\n transform: scale(1);\n}\n\n.checkbox-wrapper:hover .checkbox-custom { border-color: var(--color-primary-light); }\n\n/* \u2500\u2500 State badges \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.state,\n.state-badge {\n display: inline-flex;\n align-items: center;\n font-size: 0.72rem;\n font-weight: 600;\n padding: 0.18rem 0.55rem;\n border-radius: var(--radius-full);\n white-space: nowrap;\n transition: none;\n border: 1px solid transparent;\n box-shadow: none;\n text-transform: capitalize;\n letter-spacing: 0.01em;\n line-height: 1.4;\n}\n\n.state-badge { margin-left: 0.6rem; }\n.state { margin-right: 0; }\n\n.state-badge:hover { transform: none; box-shadow: none; }\n\n.mobile-compact { display: none; }\n\n/* Tinted, flat state badges (per-state hue) */\n.component-state-experimental {\n background: color-mix(in srgb, #f59e0b var(--tint-strength), transparent);\n color: color-mix(in srgb, #f59e0b var(--badge-text-lightness), var(--color-text-primary));\n border-color: color-mix(in srgb, #f59e0b var(--tint-border), transparent);\n}\n.component-state-deprecated {\n background: color-mix(in srgb, #ef4444 var(--tint-strength), transparent);\n color: color-mix(in srgb, #ef4444 var(--badge-text-lightness), var(--color-text-primary));\n border-color: color-mix(in srgb, #ef4444 var(--tint-border), transparent);\n}\n.component-state-stable {\n background: color-mix(in srgb, #10b981 var(--tint-strength), transparent);\n color: color-mix(in srgb, #10b981 var(--badge-text-lightness), var(--color-text-primary));\n border-color: color-mix(in srgb, #10b981 var(--tint-border), transparent);\n}\n.component-state-beta {\n background: color-mix(in srgb, #3b82f6 var(--tint-strength), transparent);\n color: color-mix(in srgb, #3b82f6 var(--badge-text-lightness), var(--color-text-primary));\n border-color: color-mix(in srgb, #3b82f6 var(--tint-border), transparent);\n}\n.component-state-alpha {\n background: color-mix(in srgb, #8b5cf6 var(--tint-strength), transparent);\n color: color-mix(in srgb, #8b5cf6 var(--badge-text-lightness), var(--color-text-primary));\n border-color: color-mix(in srgb, #8b5cf6 var(--tint-border), transparent);\n}\n\n.bold { font-weight: 600; }\n.hide { display: none !important; }\n\n/* \u2500\u2500 Breadcrumb \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.breadcrumb {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: var(--color-text-secondary);\n font-size: 0.85rem;\n margin-bottom: 1rem;\n}\n\n.breadcrumb a { color: var(--color-text-muted); font-weight: 500; }\n.breadcrumb a:hover { color: var(--color-primary); text-decoration: none; }\n\n/* \u2500\u2500 Parameters \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.parameter-grid { display: grid; gap: 1rem; }\n\n.parameter-item {\n background: var(--color-bg-secondary);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: 1.1rem 1.25rem;\n transition: border-color 0.15s ease;\n}\n\n.parameter-item:hover { border-color: var(--color-border-hover); box-shadow: none; }\n\n.parameter-header {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n margin-bottom: 0.65rem;\n flex-wrap: wrap;\n}\n\n.parameter-name {\n font-weight: 600;\n color: var(--color-text-primary);\n font-family: var(--font-mono);\n font-size: 0.9rem;\n}\n\n.parameter-type {\n background: var(--color-bg-elevated);\n color: var(--color-text-secondary);\n border: 1px solid var(--color-border);\n padding: 0.12rem 0.5rem;\n border-radius: var(--radius-full);\n font-size: 0.7rem;\n font-weight: 500;\n}\n\n.parameter-required {\n background: color-mix(in srgb, var(--color-accent) var(--tint-strength), transparent);\n color: color-mix(in srgb, var(--color-accent) var(--badge-text-lightness), var(--color-text-primary));\n border-color: color-mix(in srgb, var(--color-accent) var(--tint-border), transparent);\n}\n\n.parameter-description {\n color: var(--color-text-secondary);\n margin-bottom: 0.65rem;\n line-height: 1.5;\n font-size: 0.875rem;\n}\n\n.parameter-description strong { color: var(--color-text-primary); font-weight: 600; }\n\n.parameter-input {\n width: 100%;\n background: var(--color-bg-card);\n border: 1px solid var(--color-border);\n color: var(--color-text-primary);\n padding: 0.55rem 0.8rem;\n border-radius: var(--radius-sm);\n font-family: var(--font-mono);\n font-size: 0.85rem;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n margin-bottom: 0;\n}\n\n.parameter-input:focus {\n outline: none;\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);\n}\n\n/* \u2500\u2500 Preview \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.preview-section {\n background: var(--color-bg-card);\n border-radius: var(--radius-lg);\n border: 1px solid var(--color-border);\n overflow: hidden;\n margin-top: 1.5rem;\n}\n\n.preview-controls {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.85rem 1.5rem;\n background: var(--color-bg-glass);\n border-bottom: 1px solid var(--color-border);\n gap: 1rem;\n flex-wrap: wrap;\n}\n\n.preview-buttons { display: flex; gap: 0.6rem; }\n\n.preview-iframe,\n.preview iframe {\n width: 100%;\n height: 500px;\n border: none;\n background: #fff;\n display: block;\n}\n\n.code,\n.preview {\n width: 100%;\n background: var(--color-bg-card);\n border-radius: var(--radius-lg);\n box-shadow: none;\n margin-bottom: 1.5em;\n border: 1px solid var(--color-border);\n overflow: hidden;\n}\n\n.preview { height: 500px; }\n\n/* \u2500\u2500 Collapsible \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.collapsible-header {\n cursor: pointer;\n user-select: none;\n position: relative;\n transition: background 0.15s ease;\n}\n\n.collapsible-header:hover { background: var(--color-bg-hover); }\n\n.collapse-toggle {\n position: absolute;\n right: 1.25rem;\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n color: var(--color-text-muted);\n font-size: 0.75rem;\n cursor: pointer;\n padding: 0.4rem;\n border-radius: var(--radius-sm);\n transition: color 0.15s ease, background 0.15s ease;\n}\n\n.collapse-toggle:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }\n\n.collapse-icon { transition: transform 0.2s ease; display: inline-block; }\n\n.collapsible-content { overflow: hidden; transition: all 0.25s ease; }\n\n.collapsible-content.collapsed { max-height: 0; padding-top: 0; padding-bottom: 0; opacity: 0; }\n.collapsible-content.expanded { max-height: 2000px; opacity: 1; }\n\n.collapsible-header.collapsed .collapse-icon { transform: rotate(-90deg); }\n\n/* \u2500\u2500 Loading / empty / error \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.loader { text-align: center; padding: 2em; color: var(--color-text-muted); }\n\n.empty-state {\n text-align: center;\n padding: 2.5em 2em;\n color: var(--color-text-muted);\n margin: 0;\n}\n\n.loader p { margin: 0; }\n\n.loader::before {\n content: '';\n display: inline-block;\n width: 18px;\n height: 18px;\n border: 2px solid var(--color-border);\n border-top: 2px solid var(--color-primary);\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n margin-right: 0.6em;\n vertical-align: middle;\n}\n\n@keyframes spin { to { transform: rotate(360deg); } }\n\n.loading-more {\n text-align: center;\n padding: 1em 2em;\n color: var(--color-text-muted);\n font-size: 0.85em;\n border-top: 1px solid var(--color-border);\n}\n\n.loading-more::before {\n content: '';\n display: inline-block;\n width: 14px;\n height: 14px;\n border: 2px solid var(--color-border);\n border-top: 2px solid var(--color-primary);\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n margin-right: 0.5em;\n vertical-align: middle;\n}\n\n#history-error {\n text-align: center;\n padding: 1.5em 2em;\n color: color-mix(in srgb, #ef4444 70%, var(--color-text-primary));\n background-color: color-mix(in srgb, #ef4444 var(--tint-strength), transparent);\n border: 1px solid color-mix(in srgb, #ef4444 var(--tint-border), transparent);\n border-radius: var(--radius-md);\n margin: 1em;\n}\n\n#history-error p { margin: 0; }\n\n/* \u2500\u2500 Footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.social {\n width: 100%;\n margin-top: 0;\n padding: 2rem 0 2.5rem;\n text-align: center;\n border-top: 1px solid var(--color-border);\n color: var(--color-text-muted);\n font-size: 0.85rem;\n}\n\n/* \u2500\u2500 Scrollbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n::-webkit-scrollbar { width: 10px; height: 10px; }\n::-webkit-scrollbar-track { background: transparent; }\n::-webkit-scrollbar-thumb { background: var(--color-border-hover); border-radius: 5px; border: 2px solid var(--color-bg-primary); }\n::-webkit-scrollbar-thumb:hover { background: var(--color-text-muted); }\n\n/* \u2500\u2500 Animations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@keyframes fadeInUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 1024px) {\n .container { padding: 0 1.25rem; }\n h1 { font-size: 1.75rem; }\n .main-content { grid-template-columns: 1fr; gap: 1.25rem; }\n .sidebar { order: -1; position: static; }\n .info-item { display: flex; justify-content: space-between; }\n .collapsible-content { max-height: 0; padding-top: 0; padding-bottom: 0; opacity: 0; }\n .collapsible-header.collapsed .collapse-icon { transform: rotate(-90deg); }\n}\n\n@media (max-width: 900px) {\n .container { padding: 0 1rem; }\n .main-content { padding: 0.5rem 0 2rem; gap: 1rem; }\n .filters { flex-direction: column; gap: 0.5em; }\n #author-filter { flex: 1 0; }\n\n .row.header { display: none; }\n\n .componentRow {\n flex-direction: column !important;\n align-items: flex-start !important;\n padding: 1rem 1.25rem !important;\n gap: 0.6rem !important;\n text-align: left !important;\n }\n\n .componentRow > .author,\n .componentRow > .date,\n .componentRow > .activity,\n .componentRow > div:not(.title):not(.state):not(.mobile-compact) {\n display: none !important;\n }\n\n .mobile-compact { display: block !important; width: 100%; }\n\n .mobile-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: center;\n font-size: 0.8rem;\n color: var(--color-text-secondary);\n width: 100%;\n }\n\n .mobile-meta span {\n background: var(--color-bg-secondary);\n padding: 0.2rem 0.5rem;\n border-radius: var(--radius-sm);\n border: 1px solid var(--color-border);\n font-size: 0.75rem;\n font-weight: 500;\n }\n\n .mobile-author { color: var(--color-text-secondary) !important; }\n .mobile-version { color: var(--color-text-primary) !important; font-weight: 600; }\n .mobile-date { color: var(--color-text-muted) !important; }\n .mobile-activity { color: var(--color-text-secondary) !important; }\n .mobile-size { color: var(--color-text-secondary) !important; }\n\n .componentRow .title { text-align: left !important; width: 100%; }\n .componentRow .title .name { text-align: left !important; }\n .componentRow .title .description { text-align: left !important; }\n\n .box, .info-card, .section-content { }\n .section-content { padding: 1.25rem; }\n\n .sidebar .info-item { flex-direction: column; align-items: flex-start; gap: 0.3rem; }\n .sidebar .info-label { min-width: auto; font-weight: 600; }\n .sidebar .info-value { text-align: left; margin-left: 0; }\n\n h1 { font-size: 1.6rem; }\n .component-title { font-size: 1.5rem; }\n .preview-controls { flex-direction: column; align-items: stretch; }\n .preview-buttons { justify-content: stretch; }\n .preview-buttons .btn { flex: 1; justify-content: center; }\n}\n ";
|
|
2
2
|
export default _default;
|