@qnc/qnc_data_tables 1.2.0 → 1.3.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/intermediate/qnc_data_tables_inline_css.js +2 -2
- package/package.json +5 -3
- package/dist/bound_stored_value.d.ts +0 -39
- package/dist/bound_stored_value.js +0 -134
- package/dist/bound_stored_value.ts +0 -158
- package/dist/column_manager.d.ts +0 -45
- package/dist/column_manager.js +0 -124
- package/dist/column_manager.ts +0 -160
- package/dist/column_resizing.d.ts +0 -3
- package/dist/column_resizing.js +0 -30
- package/dist/column_resizing.ts +0 -52
- package/dist/column_sorting.d.ts +0 -11
- package/dist/column_sorting.js +0 -53
- package/dist/column_sorting.ts +0 -63
- package/dist/conditionally_wrapped_element.d.ts +0 -5
- package/dist/conditionally_wrapped_element.js +0 -14
- package/dist/conditionally_wrapped_element.ts +0 -17
- package/dist/create_mithril_app.d.ts +0 -3
- package/dist/create_mithril_app.js +0 -25
- package/dist/create_mithril_app.ts +0 -35
- package/dist/create_style.d.ts +0 -4
- package/dist/create_style.js +0 -9
- package/dist/create_style.ts +0 -10
- package/dist/custom_element.d.ts +0 -23
- package/dist/custom_element.js +0 -63
- package/dist/custom_element.ts +0 -71
- package/dist/event_names.d.ts +0 -1
- package/dist/event_names.js +0 -1
- package/dist/event_names.ts +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -4
- package/dist/index.ts +0 -8
- package/dist/mithril_view.d.ts +0 -16
- package/dist/mithril_view.js +0 -493
- package/dist/mithril_view.ts +0 -1029
- package/dist/optional_storage.d.ts +0 -6
- package/dist/optional_storage.js +0 -18
- package/dist/optional_storage.ts +0 -23
- package/dist/overflow_class_manager.d.ts +0 -20
- package/dist/overflow_class_manager.js +0 -30
- package/dist/overflow_class_manager.ts +0 -40
- package/dist/prepare_cell_html.d.ts +0 -5
- package/dist/prepare_cell_html.js +0 -38
- package/dist/prepare_cell_html.ts +0 -48
- package/dist/renderer.d.ts +0 -16
- package/dist/renderer.js +0 -51
- package/dist/renderer.ts +0 -86
- package/dist/selection_fieldset_controller.d.ts +0 -35
- package/dist/selection_fieldset_controller.js +0 -85
- package/dist/selection_fieldset_controller.ts +0 -104
- package/dist/state_machine.d.ts +0 -68
- package/dist/state_machine.js +0 -334
- package/dist/state_machine.ts +0 -458
- package/dist/state_types.d.ts +0 -62
- package/dist/state_types.js +0 -1
- package/dist/state_types.ts +0 -84
- package/dist/table_manager.d.ts +0 -10
- package/dist/table_manager.js +0 -19
- package/dist/table_manager.ts +0 -32
- package/dist/table_options.d.ts +0 -177
- package/dist/table_options.js +0 -109
- package/dist/table_options.ts +0 -150
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/watched_mutable_value.d.ts +0 -15
- package/dist/watched_mutable_value.js +0 -23
- package/dist/watched_mutable_value.ts +0 -23
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/** Two purposes: automatic key-prefixing, and the ability to create a "dummy storage" */
|
|
2
|
-
export declare function optional_storage_wrapper(storage: Storage | null, key_prefix: string): {
|
|
3
|
-
get(key: string): string | null;
|
|
4
|
-
set(key: string, value: string): void;
|
|
5
|
-
};
|
|
6
|
-
export type OptionalStorage = ReturnType<typeof optional_storage_wrapper>;
|
package/dist/optional_storage.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/** Two purposes: automatic key-prefixing, and the ability to create a "dummy storage" */
|
|
2
|
-
export function optional_storage_wrapper(storage, key_prefix) {
|
|
3
|
-
if (!storage)
|
|
4
|
-
return {
|
|
5
|
-
get(key) {
|
|
6
|
-
return null;
|
|
7
|
-
},
|
|
8
|
-
set(key, value) { },
|
|
9
|
-
};
|
|
10
|
-
return {
|
|
11
|
-
get(key) {
|
|
12
|
-
return storage.getItem(`${key_prefix}${key}`);
|
|
13
|
-
},
|
|
14
|
-
set(key, value) {
|
|
15
|
-
storage.setItem(`${key_prefix}${key}`, value);
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
}
|
package/dist/optional_storage.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/** Two purposes: automatic key-prefixing, and the ability to create a "dummy storage" */
|
|
2
|
-
export function optional_storage_wrapper(
|
|
3
|
-
storage: Storage | null,
|
|
4
|
-
key_prefix: string,
|
|
5
|
-
) {
|
|
6
|
-
if (!storage)
|
|
7
|
-
return {
|
|
8
|
-
get(key: string) {
|
|
9
|
-
return null;
|
|
10
|
-
},
|
|
11
|
-
set(key: string, value: string) {},
|
|
12
|
-
};
|
|
13
|
-
return {
|
|
14
|
-
get(key: string) {
|
|
15
|
-
return storage.getItem(`${key_prefix}${key}`);
|
|
16
|
-
},
|
|
17
|
-
set(key: string, value: string) {
|
|
18
|
-
storage.setItem(`${key_prefix}${key}`, value);
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type OptionalStorage = ReturnType<typeof optional_storage_wrapper>;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
Responsible for toggling "[PREFIX][SIDE]" classes on a possibly-overflowing element.
|
|
3
|
-
|
|
4
|
-
Nothing project-specific here
|
|
5
|
-
*/
|
|
6
|
-
export declare class OverflowClassManager {
|
|
7
|
-
readonly root: Element;
|
|
8
|
-
readonly class_prefix: string;
|
|
9
|
-
constructor(root: Element, class_prefix: string);
|
|
10
|
-
/**
|
|
11
|
-
detector _may_ have zero size; that's okay (it _should_ have 0 size in at least one dimension)
|
|
12
|
-
|
|
13
|
-
detector _may_ be longer (in one dimension) than root; that's also okay
|
|
14
|
-
|
|
15
|
-
detector should be positioned [side]-most inside the root (this is tricky if root has padding).
|
|
16
|
-
|
|
17
|
-
If root element can scroll in both directions, you need to be careful about how you setup your detectors. Eg. right detector should either be full-height, or should use sticky positioning so that it never goes completely above or completely below root. The only way right detector should not intersect (at all) with root is if it is to-the-right-of root.
|
|
18
|
-
*/
|
|
19
|
-
setup_overflow_detector(detector: Element, side: "left" | "right" | "top" | "bottom"): void;
|
|
20
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
Responsible for toggling "[PREFIX][SIDE]" classes on a possibly-overflowing element.
|
|
3
|
-
|
|
4
|
-
Nothing project-specific here
|
|
5
|
-
*/
|
|
6
|
-
export class OverflowClassManager {
|
|
7
|
-
constructor(root, class_prefix) {
|
|
8
|
-
this.root = root;
|
|
9
|
-
this.class_prefix = class_prefix;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
detector _may_ have zero size; that's okay (it _should_ have 0 size in at least one dimension)
|
|
13
|
-
|
|
14
|
-
detector _may_ be longer (in one dimension) than root; that's also okay
|
|
15
|
-
|
|
16
|
-
detector should be positioned [side]-most inside the root (this is tricky if root has padding).
|
|
17
|
-
|
|
18
|
-
If root element can scroll in both directions, you need to be careful about how you setup your detectors. Eg. right detector should either be full-height, or should use sticky positioning so that it never goes completely above or completely below root. The only way right detector should not intersect (at all) with root is if it is to-the-right-of root.
|
|
19
|
-
*/
|
|
20
|
-
setup_overflow_detector(detector, side) {
|
|
21
|
-
const class_name = `${this.class_prefix}${side}`;
|
|
22
|
-
new IntersectionObserver((entries, observer) => {
|
|
23
|
-
if (entries[0]) {
|
|
24
|
-
this.root.classList.toggle(class_name, !entries[0].isIntersecting);
|
|
25
|
-
}
|
|
26
|
-
}, {
|
|
27
|
-
root: this.root,
|
|
28
|
-
}).observe(detector);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
Responsible for toggling "[PREFIX][SIDE]" classes on a possibly-overflowing element.
|
|
3
|
-
|
|
4
|
-
Nothing project-specific here
|
|
5
|
-
*/
|
|
6
|
-
export class OverflowClassManager {
|
|
7
|
-
constructor(
|
|
8
|
-
readonly root: Element,
|
|
9
|
-
readonly class_prefix: string,
|
|
10
|
-
) {}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
detector _may_ have zero size; that's okay (it _should_ have 0 size in at least one dimension)
|
|
14
|
-
|
|
15
|
-
detector _may_ be longer (in one dimension) than root; that's also okay
|
|
16
|
-
|
|
17
|
-
detector should be positioned [side]-most inside the root (this is tricky if root has padding).
|
|
18
|
-
|
|
19
|
-
If root element can scroll in both directions, you need to be careful about how you setup your detectors. Eg. right detector should either be full-height, or should use sticky positioning so that it never goes completely above or completely below root. The only way right detector should not intersect (at all) with root is if it is to-the-right-of root.
|
|
20
|
-
*/
|
|
21
|
-
setup_overflow_detector(
|
|
22
|
-
detector: Element,
|
|
23
|
-
side: "left" | "right" | "top" | "bottom",
|
|
24
|
-
) {
|
|
25
|
-
const class_name = `${this.class_prefix}${side}`;
|
|
26
|
-
new IntersectionObserver(
|
|
27
|
-
(entries, observer) => {
|
|
28
|
-
if (entries[0]) {
|
|
29
|
-
this.root.classList.toggle(
|
|
30
|
-
class_name,
|
|
31
|
-
!entries[0].isIntersecting,
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
root: this.root,
|
|
37
|
-
},
|
|
38
|
-
).observe(detector);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
If html represents exactly one node, and that node is an HTMLElement, return that element.
|
|
3
|
-
Otherwise, wrap in a div.
|
|
4
|
-
*/
|
|
5
|
-
export function prepare_cell_html(html) {
|
|
6
|
-
const t = document.createElement("template");
|
|
7
|
-
t.innerHTML = html;
|
|
8
|
-
if (t.content.childNodes.length == 1 &&
|
|
9
|
-
t.content.children[0] instanceof HTMLElement) {
|
|
10
|
-
const element = t.content.children[0];
|
|
11
|
-
if (element.hasAttribute("data-qdt-full-cell"))
|
|
12
|
-
return element;
|
|
13
|
-
if (element instanceof HTMLDivElement ||
|
|
14
|
-
element instanceof HTMLAnchorElement) {
|
|
15
|
-
return as_flex_container(element, "div");
|
|
16
|
-
}
|
|
17
|
-
if (element instanceof HTMLButtonElement ||
|
|
18
|
-
element instanceof HTMLLabelElement) {
|
|
19
|
-
return as_flex_container(element, "span");
|
|
20
|
-
}
|
|
21
|
-
return doubly_wrapped(html);
|
|
22
|
-
}
|
|
23
|
-
return doubly_wrapped(html);
|
|
24
|
-
}
|
|
25
|
-
function as_flex_container(element, wrapper_tag) {
|
|
26
|
-
const inner = document.createElement(wrapper_tag);
|
|
27
|
-
for (const child of Array.from(element.childNodes)) {
|
|
28
|
-
inner.appendChild(child);
|
|
29
|
-
}
|
|
30
|
-
element.appendChild(inner);
|
|
31
|
-
element.classList.add("qdt-flex-cell");
|
|
32
|
-
return element;
|
|
33
|
-
}
|
|
34
|
-
function doubly_wrapped(content) {
|
|
35
|
-
const outer = document.createElement("div");
|
|
36
|
-
outer.innerHTML = content;
|
|
37
|
-
return as_flex_container(outer, "div");
|
|
38
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
If html represents exactly one node, and that node is an HTMLElement, return that element.
|
|
3
|
-
Otherwise, wrap in a div.
|
|
4
|
-
*/
|
|
5
|
-
export function prepare_cell_html(html: string): HTMLElement {
|
|
6
|
-
const t = document.createElement("template");
|
|
7
|
-
t.innerHTML = html;
|
|
8
|
-
if (
|
|
9
|
-
t.content.childNodes.length == 1 &&
|
|
10
|
-
t.content.children[0] instanceof HTMLElement
|
|
11
|
-
) {
|
|
12
|
-
const element = t.content.children[0];
|
|
13
|
-
if (element.hasAttribute("data-qdt-full-cell")) return element;
|
|
14
|
-
|
|
15
|
-
if (
|
|
16
|
-
element instanceof HTMLDivElement ||
|
|
17
|
-
element instanceof HTMLAnchorElement
|
|
18
|
-
) {
|
|
19
|
-
return as_flex_container(element, "div");
|
|
20
|
-
}
|
|
21
|
-
if (
|
|
22
|
-
element instanceof HTMLButtonElement ||
|
|
23
|
-
element instanceof HTMLLabelElement
|
|
24
|
-
) {
|
|
25
|
-
return as_flex_container(element, "span");
|
|
26
|
-
}
|
|
27
|
-
return doubly_wrapped(html);
|
|
28
|
-
}
|
|
29
|
-
return doubly_wrapped(html);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function as_flex_container(
|
|
33
|
-
element: HTMLElement,
|
|
34
|
-
wrapper_tag: string,
|
|
35
|
-
): HTMLElement {
|
|
36
|
-
const inner = document.createElement(wrapper_tag);
|
|
37
|
-
for (const child of Array.from(element.childNodes)) {
|
|
38
|
-
inner.appendChild(child);
|
|
39
|
-
}
|
|
40
|
-
element.appendChild(inner);
|
|
41
|
-
element.classList.add("qdt-flex-cell");
|
|
42
|
-
return element;
|
|
43
|
-
}
|
|
44
|
-
function doubly_wrapped(content: string): HTMLElement {
|
|
45
|
-
const outer = document.createElement("div");
|
|
46
|
-
outer.innerHTML = content;
|
|
47
|
-
return as_flex_container(outer, "div");
|
|
48
|
-
}
|
package/dist/renderer.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import m from "mithril";
|
|
2
|
-
export declare class Renderer {
|
|
3
|
-
/**
|
|
4
|
-
Given some phrasing content and some help text, return an "augmented" version of that phrasing content with some means of accessing the help text.
|
|
5
|
-
The help text might be long; it should not take up space on the page.
|
|
6
|
-
The final rendered result should not be much wider than the initial phrasing content (this may be used inside space-constrained locations, like <th> elements).
|
|
7
|
-
*/
|
|
8
|
-
render_with_help_text(phrasing_content: m.Children, help: string): m.Vnode<any, any>;
|
|
9
|
-
render_with_optional_help_text(phrasing_content: m.Children, help: string): m.Children;
|
|
10
|
-
render_header(args: {
|
|
11
|
-
label: m.Children;
|
|
12
|
-
sortable: boolean;
|
|
13
|
-
sorted: "no" | "forward" | "reverse";
|
|
14
|
-
set_sort: (direction: "forward" | "reverse") => void;
|
|
15
|
-
}): m.Vnode<any, any>;
|
|
16
|
-
}
|
package/dist/renderer.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Here we implement a class for performing various low-level rendering operations, which users might want to override (ie. so that the generated markup works better with their stylesheet or to use custom components that are used elsewhere on their site). You should NOT implement a custom Renderer in order to change or add functionality (and we'll do our best with the method signatures/documentation to prevent that).
|
|
3
|
-
*/
|
|
4
|
-
import m from "mithril";
|
|
5
|
-
export class Renderer {
|
|
6
|
-
/**
|
|
7
|
-
Given some phrasing content and some help text, return an "augmented" version of that phrasing content with some means of accessing the help text.
|
|
8
|
-
The help text might be long; it should not take up space on the page.
|
|
9
|
-
The final rendered result should not be much wider than the initial phrasing content (this may be used inside space-constrained locations, like <th> elements).
|
|
10
|
-
*/
|
|
11
|
-
render_with_help_text(phrasing_content, help) {
|
|
12
|
-
return m("span", { title: help }, phrasing_content, m("span", {
|
|
13
|
-
tabindex: 0,
|
|
14
|
-
onclick: function (e) {
|
|
15
|
-
alert(help);
|
|
16
|
-
// This allows you to render help text inside other interactive elements
|
|
17
|
-
e.preventDefault();
|
|
18
|
-
e.stopPropagation();
|
|
19
|
-
},
|
|
20
|
-
onkeydown: function (e) {
|
|
21
|
-
if (e.key == "Enter" || e.key == " ") {
|
|
22
|
-
this.click();
|
|
23
|
-
// in case you pressed space, don't scroll page
|
|
24
|
-
e.preventDefault();
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
className: "qnc-data-table-help-text",
|
|
28
|
-
}));
|
|
29
|
-
}
|
|
30
|
-
render_with_optional_help_text(phrasing_content, help) {
|
|
31
|
-
if (help)
|
|
32
|
-
return this.render_with_help_text(phrasing_content, help);
|
|
33
|
-
return phrasing_content;
|
|
34
|
-
}
|
|
35
|
-
render_header(args) {
|
|
36
|
-
// entire header text is a (clickable) button (similar to many file browser and other UIs) :
|
|
37
|
-
if (args.sortable)
|
|
38
|
-
return m("button", {
|
|
39
|
-
onclick: () => args.set_sort(args.sorted == "forward" ? "reverse" : "forward"),
|
|
40
|
-
className: "qnc-data-table-header-button",
|
|
41
|
-
type: "button",
|
|
42
|
-
},
|
|
43
|
-
// The wrapping span is so that you can see (in your browser's dev tools) exactly how wide the button content is, in case you want to fix column width at that width
|
|
44
|
-
// (note - button _might_ also suffice for this, but users might style button as full-width, for increased click target size)
|
|
45
|
-
m("span", m("span", { className: "qnc-data-table-header-button-text" }, args.label), args.sorted == "forward" &&
|
|
46
|
-
m("span", { className: "qnc-data-table-sort-indicator" }, " ▲"), args.sorted == "reverse" &&
|
|
47
|
-
m("span", { className: "qnc-data-table-sort-indicator" }, " ▼")));
|
|
48
|
-
// The wrapping span is so that you can see (in your browser's dev tools) exactly how wide the text content is, in case you want to fix column width at that width
|
|
49
|
-
return m("span", args.label);
|
|
50
|
-
}
|
|
51
|
-
}
|
package/dist/renderer.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Here we implement a class for performing various low-level rendering operations, which users might want to override (ie. so that the generated markup works better with their stylesheet or to use custom components that are used elsewhere on their site). You should NOT implement a custom Renderer in order to change or add functionality (and we'll do our best with the method signatures/documentation to prevent that).
|
|
3
|
-
*/
|
|
4
|
-
import m from "mithril";
|
|
5
|
-
|
|
6
|
-
export class Renderer {
|
|
7
|
-
/**
|
|
8
|
-
Given some phrasing content and some help text, return an "augmented" version of that phrasing content with some means of accessing the help text.
|
|
9
|
-
The help text might be long; it should not take up space on the page.
|
|
10
|
-
The final rendered result should not be much wider than the initial phrasing content (this may be used inside space-constrained locations, like <th> elements).
|
|
11
|
-
*/
|
|
12
|
-
render_with_help_text(phrasing_content: m.Children, help: string) {
|
|
13
|
-
return m(
|
|
14
|
-
"span",
|
|
15
|
-
{ title: help },
|
|
16
|
-
phrasing_content,
|
|
17
|
-
m("span", {
|
|
18
|
-
tabindex: 0,
|
|
19
|
-
onclick: function (e: MouseEvent) {
|
|
20
|
-
alert(help);
|
|
21
|
-
// This allows you to render help text inside other interactive elements
|
|
22
|
-
e.preventDefault();
|
|
23
|
-
e.stopPropagation();
|
|
24
|
-
},
|
|
25
|
-
onkeydown: function (e: KeyboardEvent) {
|
|
26
|
-
if (e.key == "Enter" || e.key == " ") {
|
|
27
|
-
this.click();
|
|
28
|
-
// in case you pressed space, don't scroll page
|
|
29
|
-
e.preventDefault();
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
className: "qnc-data-table-help-text",
|
|
33
|
-
}),
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
render_with_optional_help_text(phrasing_content: m.Children, help: string) {
|
|
37
|
-
if (help) return this.render_with_help_text(phrasing_content, help);
|
|
38
|
-
return phrasing_content;
|
|
39
|
-
}
|
|
40
|
-
render_header(args: {
|
|
41
|
-
label: m.Children;
|
|
42
|
-
sortable: boolean;
|
|
43
|
-
sorted: "no" | "forward" | "reverse";
|
|
44
|
-
set_sort: (direction: "forward" | "reverse") => void;
|
|
45
|
-
}) {
|
|
46
|
-
// entire header text is a (clickable) button (similar to many file browser and other UIs) :
|
|
47
|
-
if (args.sortable)
|
|
48
|
-
return m(
|
|
49
|
-
"button",
|
|
50
|
-
{
|
|
51
|
-
onclick: () =>
|
|
52
|
-
args.set_sort(
|
|
53
|
-
args.sorted == "forward" ? "reverse" : "forward",
|
|
54
|
-
),
|
|
55
|
-
className: "qnc-data-table-header-button",
|
|
56
|
-
type: "button",
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
// The wrapping span is so that you can see (in your browser's dev tools) exactly how wide the button content is, in case you want to fix column width at that width
|
|
60
|
-
// (note - button _might_ also suffice for this, but users might style button as full-width, for increased click target size)
|
|
61
|
-
m(
|
|
62
|
-
"span",
|
|
63
|
-
m(
|
|
64
|
-
"span",
|
|
65
|
-
{ className: "qnc-data-table-header-button-text" },
|
|
66
|
-
args.label,
|
|
67
|
-
),
|
|
68
|
-
args.sorted == "forward" &&
|
|
69
|
-
m(
|
|
70
|
-
"span",
|
|
71
|
-
{ className: "qnc-data-table-sort-indicator" },
|
|
72
|
-
" ▲",
|
|
73
|
-
),
|
|
74
|
-
args.sorted == "reverse" &&
|
|
75
|
-
m(
|
|
76
|
-
"span",
|
|
77
|
-
{ className: "qnc-data-table-sort-indicator" },
|
|
78
|
-
" ▼",
|
|
79
|
-
),
|
|
80
|
-
),
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// The wrapping span is so that you can see (in your browser's dev tools) exactly how wide the text content is, in case you want to fix column width at that width
|
|
84
|
-
return m("span", args.label);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { TableManager } from "./table_manager.js";
|
|
2
|
-
/**
|
|
3
|
-
Intended to wrap a <fieldset> element of "selection action buttons".
|
|
4
|
-
Responsible for:
|
|
5
|
-
- dynamically updating fieldset's "disabled" attribute
|
|
6
|
-
- dynamically updating fieldset's legend (to include # of selected items)
|
|
7
|
-
- providing access to the TableManager of the connected data table
|
|
8
|
-
|
|
9
|
-
Intended for use when you're generating selection action buttons on your backend (in initial page HTML).
|
|
10
|
-
|
|
11
|
-
If you're building selection action buttons on the front-end, this is probably not the best approach.
|
|
12
|
-
*/
|
|
13
|
-
export declare class QdtSelectionFieldsetController extends HTMLElement {
|
|
14
|
-
private fieldset;
|
|
15
|
-
private legend;
|
|
16
|
-
private table;
|
|
17
|
-
private on_selection_change;
|
|
18
|
-
constructor();
|
|
19
|
-
connectedCallback(): void;
|
|
20
|
-
private static get selected_attributes();
|
|
21
|
-
attributeChangedCallback(name: string, old_value: string, new_value: string): void;
|
|
22
|
-
private connect_table;
|
|
23
|
-
private connect_fieldset;
|
|
24
|
-
private render;
|
|
25
|
-
required_table_manager(): TableManager;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
Registers a custom element (<qdt-selection-fieldset-controller>) for wrapping a <fieldset> element.
|
|
29
|
-
The custom element:
|
|
30
|
-
- requires a "table-id" attribute to be set, which must be the id of a data table element
|
|
31
|
-
- dynamically updates the fieldset's "disabled" attribute
|
|
32
|
-
- dynamically updates the fieldset's legend (to include # of selected items)
|
|
33
|
-
- provides access to the TableManager of the connected data table
|
|
34
|
-
*/
|
|
35
|
-
export declare function register_selection_fieldset_controller_custom_element(): void;
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { BaseQncDataTable } from "./custom_element.js";
|
|
2
|
-
/**
|
|
3
|
-
Intended to wrap a <fieldset> element of "selection action buttons".
|
|
4
|
-
Responsible for:
|
|
5
|
-
- dynamically updating fieldset's "disabled" attribute
|
|
6
|
-
- dynamically updating fieldset's legend (to include # of selected items)
|
|
7
|
-
- providing access to the TableManager of the connected data table
|
|
8
|
-
|
|
9
|
-
Intended for use when you're generating selection action buttons on your backend (in initial page HTML).
|
|
10
|
-
|
|
11
|
-
If you're building selection action buttons on the front-end, this is probably not the best approach.
|
|
12
|
-
*/
|
|
13
|
-
export class QdtSelectionFieldsetController extends HTMLElement {
|
|
14
|
-
constructor() {
|
|
15
|
-
super();
|
|
16
|
-
this.fieldset = null;
|
|
17
|
-
this.legend = null;
|
|
18
|
-
this.table = null;
|
|
19
|
-
this.on_selection_change = () => this.render();
|
|
20
|
-
}
|
|
21
|
-
connectedCallback() {
|
|
22
|
-
this.connect_table();
|
|
23
|
-
this.connect_fieldset();
|
|
24
|
-
this.render();
|
|
25
|
-
}
|
|
26
|
-
static get selected_attributes() {
|
|
27
|
-
return ["table-id"];
|
|
28
|
-
}
|
|
29
|
-
attributeChangedCallback(name, old_value, new_value) {
|
|
30
|
-
this.connect_table();
|
|
31
|
-
this.render();
|
|
32
|
-
}
|
|
33
|
-
connect_table() {
|
|
34
|
-
this.table = null;
|
|
35
|
-
const id = this.getAttribute("table-id");
|
|
36
|
-
if (!id) {
|
|
37
|
-
console.error(`${this.tagName} requires "table-id" attribute`);
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
const table = document.getElementById(id);
|
|
41
|
-
if (!table) {
|
|
42
|
-
console.error(`"${id}" does not reference any element by id`);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
if (!(table instanceof BaseQncDataTable)) {
|
|
46
|
-
console.error(`"${id}" references an HTML element, but it is not a BaseQncDataTable`);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
this.table = table;
|
|
50
|
-
this.table
|
|
51
|
-
.required_table_manager()
|
|
52
|
-
.add_selected_ids_changed_listener(this.on_selection_change);
|
|
53
|
-
}
|
|
54
|
-
connect_fieldset() {
|
|
55
|
-
this.fieldset = this.querySelector("fieldset");
|
|
56
|
-
if (!this.fieldset)
|
|
57
|
-
console.warn("Could not find a fieldset descendant. Our presence is meaningless.");
|
|
58
|
-
this.legend = this.querySelector("legend");
|
|
59
|
-
}
|
|
60
|
-
render() {
|
|
61
|
-
const selected_count = this.table
|
|
62
|
-
? this.table.required_table_manager().selected_ids.size
|
|
63
|
-
: 0;
|
|
64
|
-
if (this.fieldset)
|
|
65
|
-
this.fieldset.disabled = selected_count == 0;
|
|
66
|
-
if (this.legend)
|
|
67
|
-
this.legend.innerText = `With ${selected_count} selected item(s):`;
|
|
68
|
-
}
|
|
69
|
-
required_table_manager() {
|
|
70
|
-
if (!this.table)
|
|
71
|
-
throw new Error("We are not connected to a table");
|
|
72
|
-
return this.table.required_table_manager();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
Registers a custom element (<qdt-selection-fieldset-controller>) for wrapping a <fieldset> element.
|
|
77
|
-
The custom element:
|
|
78
|
-
- requires a "table-id" attribute to be set, which must be the id of a data table element
|
|
79
|
-
- dynamically updates the fieldset's "disabled" attribute
|
|
80
|
-
- dynamically updates the fieldset's legend (to include # of selected items)
|
|
81
|
-
- provides access to the TableManager of the connected data table
|
|
82
|
-
*/
|
|
83
|
-
export function register_selection_fieldset_controller_custom_element() {
|
|
84
|
-
customElements.define("qdt-selection-fieldset-controller", QdtSelectionFieldsetController);
|
|
85
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { TableManager } from "./table_manager.js";
|
|
2
|
-
import { BaseQncDataTable } from "./custom_element.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
Intended to wrap a <fieldset> element of "selection action buttons".
|
|
6
|
-
Responsible for:
|
|
7
|
-
- dynamically updating fieldset's "disabled" attribute
|
|
8
|
-
- dynamically updating fieldset's legend (to include # of selected items)
|
|
9
|
-
- providing access to the TableManager of the connected data table
|
|
10
|
-
|
|
11
|
-
Intended for use when you're generating selection action buttons on your backend (in initial page HTML).
|
|
12
|
-
|
|
13
|
-
If you're building selection action buttons on the front-end, this is probably not the best approach.
|
|
14
|
-
*/
|
|
15
|
-
export class QdtSelectionFieldsetController extends HTMLElement {
|
|
16
|
-
private fieldset: HTMLFieldSetElement | null = null;
|
|
17
|
-
private legend: HTMLLegendElement | null = null;
|
|
18
|
-
private table: BaseQncDataTable | null = null;
|
|
19
|
-
|
|
20
|
-
private on_selection_change: () => void;
|
|
21
|
-
|
|
22
|
-
constructor() {
|
|
23
|
-
super();
|
|
24
|
-
this.on_selection_change = () => this.render();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
connectedCallback() {
|
|
28
|
-
this.connect_table();
|
|
29
|
-
this.connect_fieldset();
|
|
30
|
-
this.render();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
private static get selected_attributes() {
|
|
34
|
-
return ["table-id"];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
attributeChangedCallback(
|
|
38
|
-
name: string,
|
|
39
|
-
old_value: string,
|
|
40
|
-
new_value: string,
|
|
41
|
-
) {
|
|
42
|
-
this.connect_table();
|
|
43
|
-
this.render();
|
|
44
|
-
}
|
|
45
|
-
private connect_table() {
|
|
46
|
-
this.table = null;
|
|
47
|
-
|
|
48
|
-
const id = this.getAttribute("table-id");
|
|
49
|
-
if (!id) {
|
|
50
|
-
console.error(`${this.tagName} requires "table-id" attribute`);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const table = document.getElementById(id);
|
|
54
|
-
if (!table) {
|
|
55
|
-
console.error(`"${id}" does not reference any element by id`);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
if (!(table instanceof BaseQncDataTable)) {
|
|
59
|
-
console.error(
|
|
60
|
-
`"${id}" references an HTML element, but it is not a BaseQncDataTable`,
|
|
61
|
-
);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
this.table = table;
|
|
65
|
-
this.table
|
|
66
|
-
.required_table_manager()
|
|
67
|
-
.add_selected_ids_changed_listener(this.on_selection_change);
|
|
68
|
-
}
|
|
69
|
-
private connect_fieldset() {
|
|
70
|
-
this.fieldset = this.querySelector("fieldset");
|
|
71
|
-
if (!this.fieldset)
|
|
72
|
-
console.warn(
|
|
73
|
-
"Could not find a fieldset descendant. Our presence is meaningless.",
|
|
74
|
-
);
|
|
75
|
-
this.legend = this.querySelector("legend");
|
|
76
|
-
}
|
|
77
|
-
private render() {
|
|
78
|
-
const selected_count = this.table
|
|
79
|
-
? this.table.required_table_manager().selected_ids.size
|
|
80
|
-
: 0;
|
|
81
|
-
|
|
82
|
-
if (this.fieldset) this.fieldset.disabled = selected_count == 0;
|
|
83
|
-
if (this.legend)
|
|
84
|
-
this.legend.innerText = `With ${selected_count} selected item(s):`;
|
|
85
|
-
}
|
|
86
|
-
required_table_manager(): TableManager {
|
|
87
|
-
if (!this.table) throw new Error("We are not connected to a table");
|
|
88
|
-
return this.table.required_table_manager();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
Registers a custom element (<qdt-selection-fieldset-controller>) for wrapping a <fieldset> element.
|
|
93
|
-
The custom element:
|
|
94
|
-
- requires a "table-id" attribute to be set, which must be the id of a data table element
|
|
95
|
-
- dynamically updates the fieldset's "disabled" attribute
|
|
96
|
-
- dynamically updates the fieldset's legend (to include # of selected items)
|
|
97
|
-
- provides access to the TableManager of the connected data table
|
|
98
|
-
*/
|
|
99
|
-
export function register_selection_fieldset_controller_custom_element() {
|
|
100
|
-
customElements.define(
|
|
101
|
-
"qdt-selection-fieldset-controller",
|
|
102
|
-
QdtSelectionFieldsetController,
|
|
103
|
-
);
|
|
104
|
-
}
|