@aurea-uds/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +39 -0
- package/dist/aurea.css +952 -0
- package/dist/aurea.js +171 -0
- package/package.json +22 -0
package/dist/aurea.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/* Aurea — comportamentos reutilizáveis do core.
|
|
2
|
+
*
|
|
3
|
+
* Seguro em qualquer página: nenhum trecho exige elementos específicos.
|
|
4
|
+
* O script interativo da documentação vive inline em apps/docs/index.html.
|
|
5
|
+
* Overlays (dialog/drawer/command) ganham gestão de foco na fase Primitives.
|
|
6
|
+
*/
|
|
7
|
+
(function () {
|
|
8
|
+
"use strict";
|
|
9
|
+
// SSR-safe: sem DOM (Node/SSR) o script é no-op em vez de lançar
|
|
10
|
+
// "document is not defined" ao ser importado (auditoria 18/07/2026, MÉDIO 13).
|
|
11
|
+
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
12
|
+
var root = document.documentElement;
|
|
13
|
+
|
|
14
|
+
function activateTab(tab) {
|
|
15
|
+
var list = tab.closest('[role="tablist"]');
|
|
16
|
+
if (!list) return;
|
|
17
|
+
var tabs = list.querySelectorAll('[role="tab"]');
|
|
18
|
+
for (var i = 0; i < tabs.length; i++) {
|
|
19
|
+
var active = tabs[i] === tab;
|
|
20
|
+
tabs[i].classList.toggle("active", active);
|
|
21
|
+
tabs[i].setAttribute("aria-selected", String(active));
|
|
22
|
+
tabs[i].tabIndex = active ? 0 : -1;
|
|
23
|
+
var panel = document.getElementById(tabs[i].getAttribute("aria-controls") || "");
|
|
24
|
+
if (panel && panel.hasAttribute("data-aurea-tabpanel")) panel.hidden = !active;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
document.addEventListener("click", function (event) {
|
|
29
|
+
var tab = event.target.closest && event.target.closest('[role="tab"]');
|
|
30
|
+
if (tab) activateTab(tab);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
document.addEventListener("keydown", function (event) {
|
|
34
|
+
var list = event.target.closest && event.target.closest('[role="tablist"]');
|
|
35
|
+
if (!list) return;
|
|
36
|
+
var tabs = Array.prototype.slice.call(list.querySelectorAll('[role="tab"]'));
|
|
37
|
+
var current = tabs.indexOf(document.activeElement);
|
|
38
|
+
if (current < 0) return;
|
|
39
|
+
var next = current;
|
|
40
|
+
if (event.key === "ArrowRight") next = (current + 1) % tabs.length;
|
|
41
|
+
else if (event.key === "ArrowLeft") next = (current - 1 + tabs.length) % tabs.length;
|
|
42
|
+
else if (event.key === "Home") next = 0;
|
|
43
|
+
else if (event.key === "End") next = tabs.length - 1;
|
|
44
|
+
else return;
|
|
45
|
+
event.preventDefault();
|
|
46
|
+
tabs[next].focus();
|
|
47
|
+
activateTab(tabs[next]);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Copiar código: comportamento do CORE, não do catálogo. Quem marca o gatilho com
|
|
51
|
+
// [data-aurea-copy] ganha o copiar de graça — o CodeBlock do React emite esse mesmo
|
|
52
|
+
// markup. Sem permissão de área de transferência, seleciona o texto pro Ctrl+C.
|
|
53
|
+
function copy(trigger) {
|
|
54
|
+
var scope = trigger.closest("[data-aurea-copy-scope]") || trigger.parentElement;
|
|
55
|
+
var source = scope && scope.querySelector("code, pre, [data-aurea-copy-source]");
|
|
56
|
+
if (!source) return;
|
|
57
|
+
function done() {
|
|
58
|
+
trigger.classList.add("is-done");
|
|
59
|
+
setTimeout(function () { trigger.classList.remove("is-done"); }, 1500);
|
|
60
|
+
}
|
|
61
|
+
function select() {
|
|
62
|
+
var range = document.createRange();
|
|
63
|
+
range.selectNodeContents(source);
|
|
64
|
+
var sel = window.getSelection();
|
|
65
|
+
sel.removeAllRanges();
|
|
66
|
+
sel.addRange(range);
|
|
67
|
+
}
|
|
68
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
69
|
+
navigator.clipboard.writeText(source.textContent).then(done, select);
|
|
70
|
+
} else select();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
document.addEventListener("click", function (event) {
|
|
74
|
+
var trigger = event.target.closest && event.target.closest("[data-aurea-copy]");
|
|
75
|
+
if (trigger) copy(trigger);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// TableOfContents: marca sozinho a seção em vista. IntersectionObserver com uma faixa
|
|
79
|
+
// estreita no alto da janela — a seção "atual" é a que cruza essa faixa, não a maior
|
|
80
|
+
// visível, senão o item pisca entre duas ao rolar. Sem observer (browser antigo), o
|
|
81
|
+
// índice continua sendo uma lista de links que funciona.
|
|
82
|
+
function tocSpy(toc) {
|
|
83
|
+
if (!window.IntersectionObserver) return;
|
|
84
|
+
var links = {}, targets = [];
|
|
85
|
+
var anchors = toc.querySelectorAll('a[href^="#"]');
|
|
86
|
+
for (var i = 0; i < anchors.length; i++) {
|
|
87
|
+
var id = anchors[i].getAttribute("href").slice(1);
|
|
88
|
+
var target = document.getElementById(id);
|
|
89
|
+
if (!target) continue;
|
|
90
|
+
links[id] = anchors[i];
|
|
91
|
+
targets.push(target);
|
|
92
|
+
}
|
|
93
|
+
if (!targets.length) return;
|
|
94
|
+
var seen = {};
|
|
95
|
+
var observer = new IntersectionObserver(function (entries) {
|
|
96
|
+
for (var i = 0; i < entries.length; i++) seen[entries[i].target.id] = entries[i].isIntersecting;
|
|
97
|
+
// o ÚLTIMO que cruza a faixa, não o primeiro: seção e subseção cruzam juntas e o
|
|
98
|
+
// item específico é o que interessa. Nada cruzando = topo da página = primeiro item.
|
|
99
|
+
var current = targets[0].id;
|
|
100
|
+
for (var j = 0; j < targets.length; j++) if (seen[targets[j].id]) current = targets[j].id;
|
|
101
|
+
for (var id in links) {
|
|
102
|
+
if (id === current) links[id].setAttribute("aria-current", "true");
|
|
103
|
+
else links[id].removeAttribute("aria-current");
|
|
104
|
+
}
|
|
105
|
+
}, {rootMargin: "0px 0px -75% 0px"});
|
|
106
|
+
for (var k = 0; k < targets.length; k++) observer.observe(targets[k]);
|
|
107
|
+
}
|
|
108
|
+
function initTocs() {
|
|
109
|
+
var tocs = document.querySelectorAll(".toc");
|
|
110
|
+
for (var t = 0; t < tocs.length; t++) tocSpy(tocs[t]);
|
|
111
|
+
}
|
|
112
|
+
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", initTocs);
|
|
113
|
+
else initTocs();
|
|
114
|
+
|
|
115
|
+
function toastStack() {
|
|
116
|
+
var stack = document.querySelector(".toast-stack");
|
|
117
|
+
if (!stack) {
|
|
118
|
+
stack = document.createElement("div");
|
|
119
|
+
stack.className = "toast-stack";
|
|
120
|
+
document.body.appendChild(stack);
|
|
121
|
+
}
|
|
122
|
+
return stack;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function showToast(title, message) {
|
|
126
|
+
var toast = document.createElement("div");
|
|
127
|
+
toast.className = "toast";
|
|
128
|
+
toast.setAttribute("role", "status");
|
|
129
|
+
var body = document.createElement("div");
|
|
130
|
+
var strong = document.createElement("strong");
|
|
131
|
+
strong.textContent = title;
|
|
132
|
+
body.appendChild(strong);
|
|
133
|
+
if (message) {
|
|
134
|
+
var text = document.createElement("div");
|
|
135
|
+
text.className = "muted";
|
|
136
|
+
text.textContent = message;
|
|
137
|
+
body.appendChild(text);
|
|
138
|
+
}
|
|
139
|
+
var close = document.createElement("button");
|
|
140
|
+
close.type = "button";
|
|
141
|
+
close.className = "btn btn-ghost btn-icon btn-sm";
|
|
142
|
+
close.setAttribute("aria-label", "Dispensar notificação");
|
|
143
|
+
close.textContent = "×";
|
|
144
|
+
toast.appendChild(body);
|
|
145
|
+
toast.appendChild(close);
|
|
146
|
+
|
|
147
|
+
var timer;
|
|
148
|
+
function remove() { clearTimeout(timer); toast.remove(); }
|
|
149
|
+
function schedule() { clearTimeout(timer); timer = setTimeout(remove, 4800); }
|
|
150
|
+
close.addEventListener("click", remove);
|
|
151
|
+
toast.addEventListener("mouseenter", function () { clearTimeout(timer); });
|
|
152
|
+
toast.addEventListener("mouseleave", schedule);
|
|
153
|
+
toast.addEventListener("focusin", function () { clearTimeout(timer); });
|
|
154
|
+
toast.addEventListener("focusout", function (event) {
|
|
155
|
+
if (!toast.contains(event.relatedTarget)) schedule();
|
|
156
|
+
});
|
|
157
|
+
toastStack().appendChild(toast);
|
|
158
|
+
schedule();
|
|
159
|
+
return toast;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
window.Aurea = {
|
|
163
|
+
setTheme: function (theme) { root.dataset.theme = theme; },
|
|
164
|
+
setDensity: function (density) { root.dataset.density = density; },
|
|
165
|
+
toggleTheme: function () {
|
|
166
|
+
root.dataset.theme = root.dataset.theme === "dark" ? "light" : "dark";
|
|
167
|
+
},
|
|
168
|
+
showToast: showToast,
|
|
169
|
+
copy: copy
|
|
170
|
+
};
|
|
171
|
+
})();
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aurea-uds/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The Aurea UDS stylesheet and its vanilla behaviour. Import @aurea-uds/fonts/css before this.",
|
|
5
|
+
"keywords": ["aurea", "design-system", "css", "design-tokens"],
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/victor1mor/aurea-uds.git",
|
|
10
|
+
"directory": "packages/core"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"exports": {
|
|
19
|
+
"./css": "./dist/aurea.css",
|
|
20
|
+
"./js": "./dist/aurea.js"
|
|
21
|
+
}
|
|
22
|
+
}
|