1/*
2 * RapidContext <https://www.rapidcontext.com/>
3 * Copyright (c) 2007-2025 Per Cederberg. All rights reserved.
4 *
5 * This program is free software: you can redistribute it and/or
6 * modify it under the terms of the BSD license.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * See the RapidContext LICENSE for more details.
13 */
14
15// Namespace initialization
16if (typeof(RapidContext) == "undefined") {
17 RapidContext = {};
18}
19RapidContext.Widget = RapidContext.Widget || { Classes: {} };
20
21/**
22 * Creates a new button widget.
23 *
24 * @constructor
25 * @param {Object} attrs the widget and node attributes
26 * @param {boolean} [attrs.disabled] the disabled widget flag, defaults to
27 * false
28 * @param {boolean} [attrs.hidden] the hidden widget flag, defaults to false
29 * @param {boolean} [attrs.highlight] the highlight option flag,
30 * defaults to false
31 * @param {string} [attrs.icon] the icon reference to use, defaults
32 * to null (no icon)
33 * @param {...(string|Node|Array)} [child] the child widgets or DOM nodes
34 *
35 * @return {Widget} the widget DOM node
36 *
37 * @class The button widget class. Used to provide a simple push
38 * button, using the `<button>` HTML element.
39 * @extends RapidContext.Widget
40 *
41 * @example <caption>JavaScript</caption>
42 * let closeBtn = RapidContext.Widget.Button({ icon: "OK", highlight: true }, "Close");
43 *
44 * @example <caption>User Interface XML</caption>
45 * <Button id="closeBtn" icon="OK" highlight="true">Close</Button>
46 */
47RapidContext.Widget.Button = function (attrs/*, ...*/) {
48 function textNode(val) {
49 const el = document.createElement("t");
50 el.innerText = String(val && val.textContent || val).trim();
51 return el;
52 }
53 const o = RapidContext.UI.BUTTON({ type: attrs.type || "button" });
54 RapidContext.Widget._widgetMixin(o, RapidContext.Widget.Button);
55 o.addClass("widgetButton");
56 o.setAttrs(attrs);
57 Array.from(arguments).slice(1).filter(Boolean).forEach((item) => {
58 o.addChildNode((item.nodeType === 1) ? item : textNode(item));
59 });
60 return o;
61};
62
63// Register widget class
64RapidContext.Widget.Classes.Button = RapidContext.Widget.Button;
65
66/**
67 * Updates the widget or HTML DOM node attributes.
68 *
69 * @param {Object} attrs the widget and node attributes to set
70 * @param {boolean} [attrs.disabled] the disabled widget flag
71 * @param {boolean} [attrs.hidden] the hidden widget flag
72 * @param {boolean} [attrs.highlight] the highlight option flag
73 * @param {Icon|Object|string} [attrs.icon] the icon reference to use
74 */
75RapidContext.Widget.Button.prototype.setAttrs = function (attrs) {
76 attrs = { ...attrs };
77 if ("highlight" in attrs) {
78 this.classList.toggle("primary", RapidContext.Data.bool(attrs.highlight));
79 delete attrs.highlight;
80 }
81 if ("icon" in attrs) {
82 const child = this.querySelector("i");
83 if (!attrs.icon) {
84 child && RapidContext.Widget.destroyWidget(child);
85 } else if (!child) {
86 this.insertBefore(RapidContext.Widget.Icon(attrs.icon), this.firstChild);
87 } else if (attrs.icon.nodeType) {
88 child.replaceWith(attrs.icon);
89 } else if (child.setAttrs) {
90 child.setAttrs(attrs.icon);
91 } else if (typeof(attrs.icon) === "string") {
92 child.className = attrs.icon;
93 } else {
94 Object.keys(attrs.icon).forEach((k) => child.setAttribute(k, attrs.icon[k]));
95 }
96 delete attrs.icon;
97 }
98 this.__setAttrs(attrs);
99};
100
RapidContext
Access · Discovery · Insight
www.rapidcontext.com