aboutsummaryrefslogtreecommitdiff
path: root/static/components
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2021-11-21 16:08:08 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2021-11-21 16:25:59 +0100
commite7d80fcfa91f92c712110d58151df0f8f1e6ed86 (patch)
tree9bc424729c8d9e6ef65d959cc0bfe7cc0f9145e8 /static/components
parentAdd basic rrule tab. (diff)
downloadcalp-e7d80fcfa91f92c712110d58151df0f8f1e6ed86.tar.gz
calp-e7d80fcfa91f92c712110d58151df0f8f1e6ed86.tar.xz
Rework popup components.
Previously popups were driven through some CSS hacks, which used labels with specific positioning, and z-index changes. This never really worked, and led the rest of the tree to be unmanagable. This commit replaces that system with a simpler one, which is being driven by javascript. This also allowed a much simpler tree, which allowed us to - make the popups rezisable (with a resize anchor) - move the window handle to above (configurable) - Add and remove tabs without having manually reflow where all labels are
Diffstat (limited to 'static/components')
-rw-r--r--static/components/popup-element.ts86
-rw-r--r--static/components/tab-element.ts28
2 files changed, 46 insertions, 68 deletions
diff --git a/static/components/popup-element.ts b/static/components/popup-element.ts
index cb67035f..e26ae578 100644
--- a/static/components/popup-element.ts
+++ b/static/components/popup-element.ts
@@ -7,7 +7,6 @@ import { close_popup, event_from_popup } from '../popup'
import { vcal_objects } from '../globals'
import { ComponentVEvent } from './vevent'
-import { TabElement } from './tab-element'
import { remove_event } from '../server_connect'
@@ -47,28 +46,58 @@ class PopupElement extends ComponentVEvent {
let body = (template.content.cloneNode(true) as DocumentFragment).firstElementChild!;
let uid = this.uid;
- // console.log(uid);
body.getElementsByClassName('populate-with-uid')
.forEach((e) => e.setAttribute('data-uid', uid));
- /* tabs */
- // for (let tab of body.querySelectorAll(".tabgroup .tab")) {
- // }
window.setTimeout(() => {
- // let tabs = this.querySelector('tab-element')!
- // .shadowRoot!
- // .querySelectorAll('label')
- // console.log(tabs);
- // console.log(this.getElementsByTagName('tab-element'))
- for (let tab of this.getElementsByTagName('tab-element')) {
- // console.log(tab_container);
- // let tab = tab_container.shadowRoot!;
- // tab.documentElement.style.setProperty('--i', i);
- popuplateTab(tab as TabElement, this.tabgroup_id, this.tabcount)
- this.tabcount += 1
+
+ /* tab change button */
+ let tabs = this.querySelectorAll('[role="tab"]')
+ /* list of all tabs */
+ // let tablist = this.querySelector('[role="tablist"]')!
+
+ tabs.forEach(tab => {
+ tab.addEventListener('click', () => {
+
+ /* hide all tab panels */
+ for (let tabcontent of this.querySelectorAll('[role="tabpanel"]')) {
+ tabcontent.setAttribute('hidden', 'true');
+ }
+ /* unselect all (selected) tab handles */
+ for (let item of this.querySelectorAll('[aria-selected="true"]')) {
+ item.setAttribute('aria-selected', 'false');
+ }
+ /* re-select ourselves */
+ tab.setAttribute('aria-selected', 'true');
+
+ /* unhide our target tab */
+ this.querySelector('#' + tab.getAttribute('aria-controls'))!
+ .removeAttribute('hidden')
+ });
+ });
+
+ /* tab contents */
+ let tabcontents = this.querySelectorAll('[role="tabpanel"]')
+
+ for (let i = 0; i < tabs.length; i++) {
+ let n = i + this.tabcount;
+ this.tabgroup_id
+ let tab = tabs[n];
+ let con = tabcontents[n];
+
+ let a = `${this.tabgroup_id}-tab-${n}`
+ let b = `${this.tabgroup_id}-con-${n}`
+
+ tab.id = a;
+ con.setAttribute('aria-labeledby', a);
+
+ con.id = b;
+ tab.setAttribute('aria-controls', b);
+
}
- (this.querySelector('tab-element label') as HTMLInputElement).click()
+ this.tabcount += tabs.length
+
});
/* end tabs */
@@ -126,27 +155,4 @@ class PopupElement extends ComponentVEvent {
this.style.left = offsetX + "px";
this.style.top = offsetY + "px";
}
-
- addTab(tab: TabElement) {
- let tabgroup = this.getElementsByClassName('tabgroup')![0]!
- tabgroup.append(tab);
- popuplateTab(tab, this.tabgroup_id, this.tabcount)
- this.tabcount += 1
- }
-}
-
-function popuplateTab(tab: HTMLElement, tabgroup: string, index: number) {
- // console.log(tab);
- let new_id = gensym();
- let input = tab.querySelector('input[type="radio"]') as HTMLInputElement;
- let label = tab.querySelector("label")!
- tab.style.setProperty('--tab-index', '' + index);
- /* TODO this throws a number of errors, but somehow still works...? */
- if (input !== null) {
- input.name = tabgroup
- input.id = new_id;
- }
- if (label !== null) {
- label.setAttribute('for', new_id);
- }
}
diff --git a/static/components/tab-element.ts b/static/components/tab-element.ts
deleted file mode 100644
index 9da6c504..00000000
--- a/static/components/tab-element.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-export { TabElement }
-
-/* <tab-element /> */
-class TabElement extends HTMLElement {
- constructor() {
- super();
- }
-
- connectedCallback() {
- let template
- = (document.getElementById('tab-template') as HTMLTemplateElement)
- .content
- // const shadowRoot = this.attachShadow({ mode: 'open' })
- // .appendChild(template.cloneNode(true));
-
- let content = Array.from(this.children, (e) => e.cloneNode(true))
-
- this.replaceChildren(template.cloneNode(true));
-
- let label = this.querySelector('label')
- if (!label) throw "Invalid tab"
-
- label.setAttribute('title', this.getAttribute('label-title') || '')
- label.innerText = this.getAttribute('label') || 'T'
-
- this.querySelector('slot[name="content"]')!.replaceWith(...content);
- }
-}