basecoat-css 0.3.2 → 0.3.3
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/dist/basecoat.cdn.css +747 -245
- package/dist/basecoat.cdn.min.css +1 -1
- package/dist/basecoat.css +248 -47
- package/dist/js/all.js +5 -4
- package/dist/js/all.min.js +1 -1
- package/dist/js/command.js +148 -0
- package/dist/js/command.min.js +1 -0
- package/dist/js/select.js +5 -4
- package/dist/js/select.min.js +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
const initCommand = (container) => {
|
|
3
|
+
const input = container.querySelector('header input');
|
|
4
|
+
const menu = container.querySelector('[role="menu"]');
|
|
5
|
+
|
|
6
|
+
if (!input || !menu) {
|
|
7
|
+
const missing = [];
|
|
8
|
+
if (!input) missing.push('input');
|
|
9
|
+
if (!menu) missing.push('menu');
|
|
10
|
+
console.error(`Command component initialization failed. Missing element(s): ${missing.join(', ')}`, container);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const allMenuItems = Array.from(menu.querySelectorAll('[role="menuitem"]'));
|
|
15
|
+
const menuItems = allMenuItems.filter(item =>
|
|
16
|
+
!item.hasAttribute('disabled') &&
|
|
17
|
+
item.getAttribute('aria-disabled') !== 'true'
|
|
18
|
+
);
|
|
19
|
+
let visibleMenuItems = [...menuItems];
|
|
20
|
+
let activeIndex = -1;
|
|
21
|
+
|
|
22
|
+
const setActiveItem = (index) => {
|
|
23
|
+
if (activeIndex > -1 && menuItems[activeIndex]) {
|
|
24
|
+
menuItems[activeIndex].classList.remove('active');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
activeIndex = index;
|
|
28
|
+
|
|
29
|
+
if (activeIndex > -1) {
|
|
30
|
+
const activeItem = menuItems[activeIndex];
|
|
31
|
+
activeItem.classList.add('active');
|
|
32
|
+
if (activeItem.id) {
|
|
33
|
+
input.setAttribute('aria-activedescendant', activeItem.id);
|
|
34
|
+
} else {
|
|
35
|
+
input.removeAttribute('aria-activedescendant');
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
input.removeAttribute('aria-activedescendant');
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const filterMenuItems = () => {
|
|
43
|
+
const searchTerm = input.value.trim().toLowerCase();
|
|
44
|
+
|
|
45
|
+
setActiveItem(-1);
|
|
46
|
+
|
|
47
|
+
visibleMenuItems = [];
|
|
48
|
+
allMenuItems.forEach(item => {
|
|
49
|
+
const itemText = (item.dataset.label || item.textContent).trim().toLowerCase();
|
|
50
|
+
const keywords = (item.dataset.keywords || '').toLowerCase();
|
|
51
|
+
const matches = itemText.includes(searchTerm) || keywords.includes(searchTerm);
|
|
52
|
+
item.setAttribute('aria-hidden', String(!matches));
|
|
53
|
+
if (matches && menuItems.includes(item)) {
|
|
54
|
+
visibleMenuItems.push(item);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (visibleMenuItems.length > 0) {
|
|
59
|
+
setActiveItem(menuItems.indexOf(visibleMenuItems[0]));
|
|
60
|
+
visibleMenuItems[0].scrollIntoView({ block: 'nearest' });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
input.addEventListener('input', filterMenuItems);
|
|
65
|
+
|
|
66
|
+
const handleKeyNavigation = (event) => {
|
|
67
|
+
if (!['ArrowDown', 'ArrowUp', 'Enter', 'Home', 'End'].includes(event.key)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (event.key === 'Enter') {
|
|
72
|
+
event.preventDefault();
|
|
73
|
+
if (activeIndex > -1) {
|
|
74
|
+
menuItems[activeIndex]?.click();
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (visibleMenuItems.length === 0) return;
|
|
80
|
+
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
|
|
83
|
+
const currentVisibleIndex = activeIndex > -1 ? visibleMenuItems.indexOf(menuItems[activeIndex]) : -1;
|
|
84
|
+
let nextVisibleIndex = currentVisibleIndex;
|
|
85
|
+
|
|
86
|
+
switch (event.key) {
|
|
87
|
+
case 'ArrowDown':
|
|
88
|
+
if (currentVisibleIndex < visibleMenuItems.length - 1) {
|
|
89
|
+
nextVisibleIndex = currentVisibleIndex + 1;
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
case 'ArrowUp':
|
|
93
|
+
if (currentVisibleIndex > 0) {
|
|
94
|
+
nextVisibleIndex = currentVisibleIndex - 1;
|
|
95
|
+
} else if (currentVisibleIndex === -1) {
|
|
96
|
+
nextVisibleIndex = 0;
|
|
97
|
+
}
|
|
98
|
+
break;
|
|
99
|
+
case 'Home':
|
|
100
|
+
nextVisibleIndex = 0;
|
|
101
|
+
break;
|
|
102
|
+
case 'End':
|
|
103
|
+
nextVisibleIndex = visibleMenuItems.length - 1;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (nextVisibleIndex !== currentVisibleIndex) {
|
|
108
|
+
const newActiveItem = visibleMenuItems[nextVisibleIndex];
|
|
109
|
+
setActiveItem(menuItems.indexOf(newActiveItem));
|
|
110
|
+
newActiveItem.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
menu.addEventListener('mousemove', (event) => {
|
|
115
|
+
const menuItem = event.target.closest('[role="menuitem"]');
|
|
116
|
+
if (menuItem && visibleMenuItems.includes(menuItem)) {
|
|
117
|
+
const index = menuItems.indexOf(menuItem);
|
|
118
|
+
if (index !== activeIndex) {
|
|
119
|
+
setActiveItem(index);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
menu.addEventListener('click', (event) => {
|
|
125
|
+
const clickedItem = event.target.closest('[role="menuitem"]');
|
|
126
|
+
if (clickedItem && visibleMenuItems.includes(clickedItem)) {
|
|
127
|
+
const dialog = container.closest('dialog.command-dialog');
|
|
128
|
+
if (dialog && !clickedItem.hasAttribute('data-keep-command-open')) {
|
|
129
|
+
dialog.close();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
input.addEventListener('keydown', handleKeyNavigation);
|
|
135
|
+
|
|
136
|
+
if (visibleMenuItems.length > 0) {
|
|
137
|
+
setActiveItem(menuItems.indexOf(visibleMenuItems[0]));
|
|
138
|
+
visibleMenuItems[0].scrollIntoView({ block: 'nearest' });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
container.dataset.commandInitialized = true;
|
|
142
|
+
container.dispatchEvent(new CustomEvent('basecoat:initialized'));
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
if (window.basecoat) {
|
|
146
|
+
window.basecoat.register('command', '.command:not([data-command-initialized])', initCommand);
|
|
147
|
+
}
|
|
148
|
+
})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{const e=e=>{const t=e.querySelector("header input"),n=e.querySelector('[role="menu"]');if(!t||!n){const i=[];return t||i.push("input"),n||i.push("menu"),void console.error(`Command component initialization failed. Missing element(s): ${i.join(", ")}`,e)}const i=Array.from(n.querySelectorAll('[role="menuitem"]')),o=i.filter((e=>!e.hasAttribute("disabled")&&"true"!==e.getAttribute("aria-disabled")));let a=[...o],r=-1;const s=e=>{if(r>-1&&o[r]&&o[r].classList.remove("active"),r=e,r>-1){const e=o[r];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")};t.addEventListener("input",(()=>{const e=t.value.trim().toLowerCase();s(-1),a=[],i.forEach((t=>{const n=(t.dataset.label||t.textContent).trim().toLowerCase(),i=(t.dataset.keywords||"").toLowerCase(),r=n.includes(e)||i.includes(e);t.setAttribute("aria-hidden",String(!r)),r&&o.includes(t)&&a.push(t)})),a.length>0&&(s(o.indexOf(a[0])),a[0].scrollIntoView({block:"nearest"}))}));n.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="menuitem"]');if(t&&a.includes(t)){const e=o.indexOf(t);e!==r&&s(e)}})),n.addEventListener("click",(t=>{const n=t.target.closest('[role="menuitem"]');if(n&&a.includes(n)){const t=e.closest("dialog.command-dialog");t&&!n.hasAttribute("data-keep-command-open")&&t.close()}})),t.addEventListener("keydown",(e=>{if(!["ArrowDown","ArrowUp","Enter","Home","End"].includes(e.key))return;if("Enter"===e.key)return e.preventDefault(),void(r>-1&&o[r]?.click());if(0===a.length)return;e.preventDefault();const t=r>-1?a.indexOf(o[r]):-1;let n=t;switch(e.key){case"ArrowDown":t<a.length-1&&(n=t+1);break;case"ArrowUp":t>0?n=t-1:-1===t&&(n=0);break;case"Home":n=0;break;case"End":n=a.length-1}if(n!==t){const e=a[n];s(o.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}})),a.length>0&&(s(o.indexOf(a[0])),a[0].scrollIntoView({block:"nearest"})),e.dataset.commandInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("command",".command:not([data-command-initialized])",e)})();
|
package/dist/js/select.js
CHANGED
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const allOptions = Array.from(listbox.querySelectorAll('[role="option"]'));
|
|
20
|
+
const options = allOptions.filter(opt => opt.getAttribute('aria-disabled') !== 'true');
|
|
20
21
|
let visibleOptions = [...options];
|
|
21
22
|
let activeIndex = -1;
|
|
22
23
|
|
|
@@ -69,7 +70,7 @@
|
|
|
69
70
|
const resetFilter = () => {
|
|
70
71
|
filter.value = '';
|
|
71
72
|
visibleOptions = [...options];
|
|
72
|
-
|
|
73
|
+
allOptions.forEach(opt => opt.setAttribute('aria-hidden', 'false'));
|
|
73
74
|
};
|
|
74
75
|
|
|
75
76
|
if (hasTransition()) {
|
|
@@ -110,11 +111,11 @@
|
|
|
110
111
|
setActiveOption(-1);
|
|
111
112
|
|
|
112
113
|
visibleOptions = [];
|
|
113
|
-
|
|
114
|
+
allOptions.forEach(option => {
|
|
114
115
|
const optionText = (option.dataset.label || option.textContent).trim().toLowerCase();
|
|
115
116
|
const matches = optionText.includes(searchTerm);
|
|
116
117
|
option.setAttribute('aria-hidden', String(!matches));
|
|
117
|
-
if (matches) {
|
|
118
|
+
if (matches && options.includes(option)) {
|
|
118
119
|
visibleOptions.push(option);
|
|
119
120
|
}
|
|
120
121
|
});
|
package/dist/js/select.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{const e=e=>{const t=e.querySelector(":scope > button"),a=t.querySelector(":scope > span"),
|
|
1
|
+
(()=>{const e=e=>{const t=e.querySelector(":scope > button"),a=t.querySelector(":scope > span"),i=e.querySelector(":scope > [data-popover]"),n=i.querySelector('[role="listbox"]'),r=e.querySelector(':scope > input[type="hidden"]'),o=e.querySelector('header input[type="text"]');if(!(t&&i&&n&&r)){const a=[];return t||a.push("trigger"),i||a.push("popover"),n||a.push("listbox"),r||a.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${a.join(", ")}`,e)}const s=Array.from(n.querySelectorAll('[role="option"]')),d=s.filter((e=>"true"!==e.getAttribute("aria-disabled")));let c=[...d],l=-1;const u=e=>{if(l>-1&&d[l]&&d[l].classList.remove("active"),l=e,l>-1){const e=d[l];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},v=()=>{const e=getComputedStyle(i);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},p=(t,i=!0)=>{if(t&&(a.innerHTML=t.dataset.label||t.innerHTML,r.value=t.dataset.value,n.querySelector('[role="option"][aria-selected="true"]')?.removeAttribute("aria-selected"),t.setAttribute("aria-selected","true"),i)){const a=new CustomEvent("change",{detail:{value:t.dataset.value},bubbles:!0});e.dispatchEvent(a)}},b=(e=!0)=>{if("true"!==i.getAttribute("aria-hidden")){if(o){const e=()=>{o.value="",c=[...d],s.forEach((e=>e.setAttribute("aria-hidden","false")))};v()?i.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),i.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),u(-1)}},f=e=>{if(!e)return;const t=r.value,a=e.dataset.value;null!=a&&a!==t&&p(e),b()};if(o){const e=()=>{const e=o.value.trim().toLowerCase();u(-1),c=[],s.forEach((t=>{const a=(t.dataset.label||t.textContent).trim().toLowerCase().includes(e);t.setAttribute("aria-hidden",String(!a)),a&&d.includes(t)&&c.push(t)}))};o.addEventListener("input",e)}let E=d.find((e=>e.dataset.value===r.value));E||(E=d.find((e=>void 0!==e.dataset.value))??d[0]),p(E,!1);const h=e=>{const a="false"===i.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!a)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void b();if("Enter"===e.key)return void(l>-1&&f(d[l]));if(0===c.length)return;const n=l>-1?c.indexOf(d[l]):-1;let r=n;switch(e.key){case"ArrowDown":n<c.length-1&&(r=n+1);break;case"ArrowUp":n>0?r=n-1:-1===n&&(r=0);break;case"Home":r=0;break;case"End":r=c.length-1}if(r!==n){const e=c[r];u(d.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};n.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&c.includes(t)){const e=d.indexOf(t);e!==l&&u(e)}})),n.addEventListener("mouseleave",(()=>{const e=n.querySelector('[role="option"][aria-selected="true"]');u(e?d.indexOf(e):-1)})),t.addEventListener("keydown",h),o&&o.addEventListener("keydown",h);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?b():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),o&&(v()?i.addEventListener("transitionend",(()=>{o.focus()}),{once:!0}):o.focus()),i.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const a=n.querySelector('[role="option"][aria-selected="true"]');a&&(u(d.indexOf(a)),a.scrollIntoView({block:"nearest"}))})()})),n.addEventListener("click",(e=>{const t=e.target.closest('[role="option"]');t&&f(t)})),document.addEventListener("click",(t=>{e.contains(t.target)||b(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&b(!1)})),i.setAttribute("aria-hidden","true"),e.selectByValue=e=>{const t=d.find((t=>t.dataset.value===e));f(t)},e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "basecoat-css",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Tailwind CSS for Basecoat components",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "hunvreus",
|
|
@@ -26,8 +26,7 @@
|
|
|
26
26
|
"css",
|
|
27
27
|
"html",
|
|
28
28
|
"jinja",
|
|
29
|
-
"nunjucks"
|
|
30
|
-
"alpinejs"
|
|
29
|
+
"nunjucks"
|
|
31
30
|
],
|
|
32
31
|
"repository": {
|
|
33
32
|
"type": "git",
|
|
@@ -43,6 +42,8 @@
|
|
|
43
42
|
"./css": "./dist/basecoat.css",
|
|
44
43
|
"./all": "./dist/js/all.js",
|
|
45
44
|
"./all.min": "./dist/js/all.min.js",
|
|
45
|
+
"./command": "./dist/js/command.js",
|
|
46
|
+
"./command.min": "./dist/js/command.min.js",
|
|
46
47
|
"./dropdown-menu": "./dist/js/dropdown-menu.js",
|
|
47
48
|
"./dropdown-menu.min": "./dist/js/dropdown-menu.min.js",
|
|
48
49
|
"./popover": "./dist/js/popover.js",
|