-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomponents.js
More file actions
158 lines (147 loc) · 10.5 KB
/
Copy pathcomponents.js
File metadata and controls
158 lines (147 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Shared site components — native custom elements, no build step.
//
// <site-header active="home|test|resources"> header + nav, one source of truth
// <site-footer> footer
// <ph-icon name="…" size="12"> inline Phosphor icon
//
// The elements use display:contents (see styles.css), so the markup they
// render lays out exactly as if it were written directly in the page.
(function () {
'use strict';
// Phosphor icon paths (regular weight, 256×256 viewBox, fill-based).
var ICONS = {
'arrow-right': 'M221.66 133.66l-72 72a8 8 0 0 1-11.32-11.32L196.69 136H40a8 8 0 0 1 0-16h156.69l-58.35-58.34a8 8 0 0 1 11.32-11.32l72 72a8 8 0 0 1 0 11.32Z',
'arrow-up-right': 'M200 64v104a8 8 0 0 1-16 0V83.31L69.66 197.66a8 8 0 0 1-11.32-11.32L172.69 72H88a8 8 0 0 1 0-16h104a8 8 0 0 1 8 8Z',
'arrow-up-right-bold': 'M204 64v104a12 12 0 0 1-24 0V93L72.49 200.49a12 12 0 0 1-17-17L163 76H88a12 12 0 0 1 0-24h104a12 12 0 0 1 12 12Z',
'arrow-right-bold': 'M224.49 136.49l-72 72a12 12 0 0 1-17-17L187 140H40a12 12 0 0 1 0-24h147l-51.49-51.51a12 12 0 0 1 17-17l72 72a12 12 0 0 1-.02 17Z',
'arrow-up': 'M205.66 117.66a8 8 0 0 1-11.32 0L136 59.31V216a8 8 0 0 1-16 0V59.31L61.66 117.66a8 8 0 0 1-11.32-11.32l72-72a8 8 0 0 1 11.32 0l72 72a8 8 0 0 1 0 11.32Z',
check: 'M229.66 77.66l-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69 218.34 66.34a8 8 0 0 1 11.32 11.32Z',
x: 'M205.66 194.34a8 8 0 0 1-11.32 11.32L128 139.31l-66.34 66.35a8 8 0 0 1-11.32-11.32L116.69 128 50.34 61.66a8 8 0 0 1 11.32-11.32L128 116.69l66.34-66.35a8 8 0 0 1 11.32 11.32L139.31 128Z',
moon: 'M233.54 142.23a8 8 0 0 0-8-2 88.08 88.08 0 0 1-109.8-109.8 8 8 0 0 0-10-10 104.84 104.84 0 0 0-52.91 37A104 104 0 0 0 136 224a103.09 103.09 0 0 0 62.52-20.88 104.84 104.84 0 0 0 37-52.91 8 8 0 0 0-1.98-7.98Zm-44.64 48.11A88 88 0 0 1 65.66 67.11a89 89 0 0 1 31.4-26A106 106 0 0 0 96 56a104.11 104.11 0 0 0 104 104 106 106 0 0 0 14.92-1.06 89 89 0 0 1-26.02 31.4Z',
monitor: 'M208 40H48a24 24 0 0 0-24 24v112a24 24 0 0 0 24 24h160a24 24 0 0 0 24-24V64a24 24 0 0 0-24-24Zm8 136a8 8 0 0 1-8 8H48a8 8 0 0 1-8-8V64a8 8 0 0 1 8-8h160a8 8 0 0 1 8 8ZM168 224a8 8 0 0 1-8 8H96a8 8 0 0 1 0-16h64a8 8 0 0 1 8 8Z',
sun: 'M120 40V16a8 8 0 0 1 16 0v24a8 8 0 0 1-16 0Zm72 88a64 64 0 1 1-64-64 64.07 64.07 0 0 1 64 64Zm-16 0a48 48 0 1 0-48 48 48.05 48.05 0 0 0 48-48ZM58.34 69.66a8 8 0 0 0 11.32-11.32l-16-16a8 8 0 0 0-11.32 11.32Zm0 116.68-16 16a8 8 0 0 0 11.32 11.32l16-16a8 8 0 0 0-11.32-11.32ZM192 72a8 8 0 0 0 5.66-2.34l16-16a8 8 0 0 0-11.32-11.32l-16 16A8 8 0 0 0 192 72Zm5.66 114.34a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32-11.32ZM48 128a8 8 0 0 0-8-8H16a8 8 0 0 0 0 16h24a8 8 0 0 0 8-8Zm80 80a8 8 0 0 0-8 8v24a8 8 0 0 0 16 0v-24a8 8 0 0 0-8-8Zm112-88h-24a8 8 0 0 0 0 16h24a8 8 0 0 0 0-16Z'
};
function iconSVG(name, size) {
var d = ICONS[name];
if (!d) return '';
return '<svg viewBox="0 0 256 256" width="' + size + '" height="' + size +
'" fill="currentColor" aria-hidden="true"><path d="' + d + '"/></svg>';
}
var PAGES = [
{ id: 'home', href: './', label: 'Home' },
{ id: 'test', href: 'quicktest.html', label: 'Test' },
{ id: 'resources', href: 'resources.html', label: 'Resources' }
];
// GitHub header button: repo slug + the octocat mark (16x16 octicon).
var GITHUB_REPO = 'thesysdev/openui';
var GITHUB_MARK = '<svg viewBox="0 0 16 16" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8Z"/></svg>';
class PhIcon extends HTMLElement {
connectedCallback() {
var size = this.getAttribute('size') || '16';
this.innerHTML = iconSVG(this.getAttribute('name'), size);
}
}
class SiteHeader extends HTMLElement {
connectedCallback() {
var active = this.getAttribute('active');
this.innerHTML =
'<a class="skip-link" href="#main">Skip to content</a>' +
'<header class="site-header">' +
'<div class="header-inner">' +
'<a href="./" class="wordmark" aria-label="Agentic Interface Framework — Home">' +
// Inline copy of logo.svg, recolored to currentColor.
'<svg viewBox="0 0 268 144" height="18" aria-hidden="true">' +
'<path fill="currentColor" d="M243.074 100.816C254.669 99.0662 265.489 107.047 267.241 118.643C268.996 130.239 261.016 141.061 249.421 142.817C237.821 144.573 226.994 136.592 225.241 124.991C223.489 113.391 231.472 102.566 243.074 100.816ZM0.123047 0.183838C30.3704 -0.193155 61.5253 0.117643 91.8252 0.171143V0.215088C93.8908 0.210607 95.9524 0.201319 98.0059 0.177979L97.9932 140.018L97.999 140.376C97.2973 140.793 63.8272 140.603 60.0508 140.6C60.1153 135.259 60.1187 129.849 60.1064 124.433C52.7323 124.42 45.365 124.437 38.0879 124.55L38.0977 140.584L0.115234 140.582C-0.129765 121.528 0.0923427 141.904 0.0898438 122.793L0.123047 0.183838ZM155.359 140.018L155.365 140.376C154.653 140.793 121.192 140.603 117.417 140.6C117.553 129.303 117.425 117.694 117.426 106.379L117.418 36.9084C117.417 24.797 117.261 12.2614 117.498 0.178955C121.813 0.364191 127.225 0.183088 131.623 0.183838C139.507 0.185341 147.499 0.267477 155.373 0.177979L155.359 140.018ZM175.123 0.183838C205.37 -0.193155 236.525 0.117643 266.825 0.171143L266.843 31.8098L213.088 31.8411L213.115 52.7961L260.897 52.8333C261.092 62.8495 261.082 74.4603 260.862 84.468L258.905 84.5022C243.743 84.4922 228.22 84.3146 213.088 84.55L213.098 140.584L175.115 140.582C174.87 121.528 175.092 101.904 175.09 82.7932L175.123 0.183838ZM38.0879 31.8411L38.1152 92.7961L60.0576 92.8127L60.0518 36.9084C60.0516 35.2222 60.0477 33.5277 60.043 31.8274L38.0879 31.8411Z"/>' +
'</svg>' +
'</a>' +
'<nav class="tabs" aria-label="Site pages">' +
PAGES.map(function (p) {
var current = p.id === active ? ' aria-current="page"' : '';
return '<a href="' + p.href + '" class="tab"' + current + '>' + p.label + '</a>';
}).join('') +
'<a class="gh-btn" href="https://github.com/' + GITHUB_REPO + '" target="_blank" rel="noopener" aria-label="OpenUI on GitHub">' +
GITHUB_MARK + '<span class="gh-stars" hidden></span>' +
'</a>' +
'</nav>' +
'</div>' +
'</header>';
// Star count: fetched from the GitHub API, cached for an hour.
// On any failure the count stays hidden and the button still links.
var stars = this.querySelector('.gh-stars');
function fmtStars(n) {
return n >= 1000 ? (n / 1000).toFixed(1).replace(/\.0$/, '') + 'k' : String(n);
}
function showStars(n) { stars.textContent = fmtStars(n); stars.hidden = false; }
var cached = null;
try { cached = JSON.parse(localStorage.getItem('aif-gh-stars')); } catch (e) {}
if (cached && cached.repo === GITHUB_REPO && typeof cached.v === 'number' && Date.now() - cached.t < 3600000) {
showStars(cached.v);
} else {
fetch('https://api.github.com/repos/' + GITHUB_REPO)
.then(function (r) { return r.ok ? r.json() : null; })
.then(function (d) {
if (!d || typeof d.stargazers_count !== 'number') return;
showStars(d.stargazers_count);
try { localStorage.setItem('aif-gh-stars', JSON.stringify({ v: d.stargazers_count, t: Date.now(), repo: GITHUB_REPO })); } catch (e) {}
})
.catch(function () {});
}
}
}
class SiteFooter extends HTMLElement {
connectedCallback() {
this.innerHTML =
'<footer class="site-footer">' +
'<div class="container footer-inner">' +
'<p class="footer-meta">Built by the open source community at ' +
'<a class="footer-link" href="https://openui.com" target="_blank" rel="noopener">OpenUI.com' +
'<span class="footer-arrow" aria-hidden="true">' + iconSVG('arrow-up-right-bold', 12) + '</span>' +
'</a>' +
'</p>' +
'</div>' +
'<div class="theme-switch" role="group" aria-label="Color theme">' +
'<button type="button" data-mode="light" aria-label="Light theme">' + iconSVG('sun', 15) + '</button>' +
'<button type="button" data-mode="system" aria-label="Follow system theme">' + iconSVG('monitor', 15) + '</button>' +
'<button type="button" data-mode="dark" aria-label="Dark theme">' + iconSVG('moon', 15) + '</button>' +
'</div>' +
'</footer>';
// Three-state theme switch: light / system / dark. The stored mode
// is applied pre-paint by the inline head script; "system" follows
// prefers-color-scheme live.
var buttons = this.querySelectorAll('.theme-switch button');
function storedMode() {
try { return localStorage.getItem('aif-theme') || 'system'; } catch (e) { return 'system'; }
}
function apply(mode) {
var dark = mode === 'dark' ||
(mode === 'system' && matchMedia('(prefers-color-scheme: dark)').matches);
if (dark) document.documentElement.dataset.theme = 'dark';
else delete document.documentElement.dataset.theme;
}
function reflect() {
var m = storedMode();
buttons.forEach(function (b) {
var on = b.dataset.mode === m;
b.classList.toggle('active', on);
b.setAttribute('aria-pressed', String(on));
});
}
buttons.forEach(function (b) {
b.addEventListener('click', function () {
try { localStorage.setItem('aif-theme', b.dataset.mode); } catch (e) { /* private mode */ }
apply(b.dataset.mode);
reflect();
});
});
matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function () {
if (storedMode() === 'system') apply('system');
});
reflect();
}
}
customElements.define('ph-icon', PhIcon);
customElements.define('site-header', SiteHeader);
customElements.define('site-footer', SiteFooter);
// Shared with page scripts (ait.js uses the icon registry for the modal).
window.AIF = { iconSVG: iconSVG };
})();