@componyx/ui 0.0.0-stage → 1.0.4
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/AppSkin/AppSkin.css +1268 -0
- package/AppSkin/AppSkin.js +2748 -0
- package/AppSkin/Themes/Default.css +241 -0
- package/Base/Base.js +3407 -0
- package/Base/ComponentIcons.css +66 -0
- package/Base/Font/ComponentIcons.woff +0 -0
- package/Base/Font/UI.woff +0 -0
- package/Base/Library.js +8432 -0
- package/Base/NavigationManager.js +462 -0
- package/Base/ResponsiveTemplates.js +371 -0
- package/Base/Sanitizer.js +288 -0
- package/Base/Themes/Default.css +255 -0
- package/Base/UI.css +618 -0
- package/Base/UIResourcePath.js +6 -0
- package/Bindary/Bindary.js +2011 -0
- package/Bindary/Modules/Connection.js +216 -0
- package/Bindary/Modules/Core.js +854 -0
- package/Bindary/Modules/DataUpdater.js +351 -0
- package/Bindary/Modules/ExpressionEngine.js +347 -0
- package/Bindary/Modules/ProxyManager.js +482 -0
- package/Bindary/Modules/Renderer.js +605 -0
- package/Bindary/Modules/Router.js +291 -0
- package/Bindary/Modules/Scroller.js +89 -0
- package/Bindary/Modules/Template.js +1273 -0
- package/BookmarkSpy/BookmarkSpy.js +430 -0
- package/Box/Box.css +36 -0
- package/Box/Box.js +1685 -0
- package/Button/Button.css +470 -0
- package/Button/Button.js +1398 -0
- package/Button/Themes/Default.css +200 -0
- package/Carousel/Carousel.css +273 -0
- package/Carousel/Carousel.js +607 -0
- package/ColorButton/ColorButton.css +39 -0
- package/ColorButton/ColorButton.js +336 -0
- package/ColorPicker/ColorPicker.css +359 -0
- package/ColorPicker/ColorPicker.js +972 -0
- package/ComboBox/ComboBox.css +357 -0
- package/ComboBox/ComboBox.js +2342 -0
- package/ComboBox/Themes/Default.css +23 -0
- package/DataPager/DataPager.css +72 -0
- package/DataPager/DataPager.js +674 -0
- package/DatePicker/DatePicker.css +227 -0
- package/DatePicker/DatePicker.js +1531 -0
- package/DatePicker/Themes/Default.css +26 -0
- package/Dialog/Dialog.css +106 -0
- package/Dialog/Dialog.js +572 -0
- package/Dialog/Themes/Default.css +10 -0
- package/Editor/Data/Emoji.json +8285 -0
- package/Editor/Data/Special.json +1042 -0
- package/Editor/Editor.css +1562 -0
- package/Editor/Editor.js +4058 -0
- package/Editor/Font/Editor.woff +0 -0
- package/Editor/Modules/ComponentFactory.js +565 -0
- package/Editor/Modules/ContentManager.js +748 -0
- package/Editor/Modules/DialogManager.js +1234 -0
- package/Editor/Modules/EventManager.js +458 -0
- package/Editor/Modules/Format.js +950 -0
- package/Editor/Modules/History.js +191 -0
- package/Editor/Modules/LayoutState.js +379 -0
- package/Editor/Modules/ListManager.js +296 -0
- package/Editor/Modules/MenuManager.js +388 -0
- package/Editor/Modules/NodeManager.js +681 -0
- package/Editor/Modules/ParagraphButtons.js +122 -0
- package/Editor/Modules/Resizer.js +176 -0
- package/Editor/Modules/SelectionRange.js +564 -0
- package/Editor/Modules/SourceViewBuilder.js +212 -0
- package/Editor/Modules/SymbolPicker.js +208 -0
- package/Editor/Modules/Table.js +2327 -0
- package/Editor/Modules/TableDialog.js +757 -0
- package/Editor/Modules/Toolbar.js +375 -0
- package/Editor/Modules/TooltipMenu.js +125 -0
- package/Editor/Modules/Utility.js +131 -0
- package/Editor/Themes/Default.css +204 -0
- package/FileUpload/FileUpload.css +156 -0
- package/FileUpload/FileUpload.js +898 -0
- package/FileUpload/Themes/Default.css +17 -0
- package/Form/Form.css +1934 -0
- package/Form/Form.js +4943 -0
- package/Form/Modules/ActionManager.js +368 -0
- package/Form/Modules/BuildPanelManager.js +319 -0
- package/Form/Modules/ComponentFactory.js +468 -0
- package/Form/Modules/ComponentPanel.js +265 -0
- package/Form/Modules/ConfigPanelManager.js +685 -0
- package/Form/Modules/DataBinder.js +602 -0
- package/Form/Modules/DataObserver.js +717 -0
- package/Form/Modules/Draggable.js +756 -0
- package/Form/Modules/OptionsPanel.js +342 -0
- package/Form/Modules/Renderer.js +1889 -0
- package/Form/Modules/RuleEngine.js +585 -0
- package/Form/Modules/RulesPanel.js +1158 -0
- package/Form/Modules/Types.js +1709 -0
- package/Form/Modules/ValidationManager.js +194 -0
- package/Form/Themes/Default.css +216 -0
- package/FormField/FormField.css +468 -0
- package/FormField/FormField.js +576 -0
- package/FormField/Themes/Default.css +99 -0
- package/Grid/Grid.css +544 -0
- package/Grid/Grid.js +3761 -0
- package/Grid/Themes/Default.css +43 -0
- package/LICENSE +126 -0
- package/MaskedTextBox/MaskedTextBox.css +28 -0
- package/MaskedTextBox/MaskedTextBox.js +642 -0
- package/MaskedTextBox/Themes/Default.css +6 -0
- package/Menu/Menu.css +328 -0
- package/Menu/Menu.js +2386 -0
- package/Menu/Themes/Default.css +24 -0
- package/NumericBox/NumericBox.css +120 -0
- package/NumericBox/NumericBox.js +984 -0
- package/PanelBar/PanelBar.css +123 -0
- package/PanelBar/PanelBar.js +505 -0
- package/PanelBar/Themes/Default.css +51 -0
- package/PieChart/PieChart.css +95 -0
- package/PieChart/PieChart.js +820 -0
- package/PieChart/Themes/Default.css +9 -0
- package/README.md +178 -3
- package/Slider/Slider.css +348 -0
- package/Slider/Slider.js +1306 -0
- package/Slider/Themes/Default.css +44 -0
- package/TabStrip/TabStrip.css +52 -0
- package/TabStrip/TabStrip.js +362 -0
- package/TabStrip/Themes/Default.css +35 -0
- package/TimePicker/Themes/Default.css +30 -0
- package/TimePicker/TimePicker.css +253 -0
- package/TimePicker/TimePicker.js +1485 -0
- package/TooltipManager/Themes/Default.css +21 -0
- package/TooltipManager/TooltipManager.css +227 -0
- package/TooltipManager/TooltipManager.js +791 -0
- package/Validator/Validator.css +54 -0
- package/Validator/Validator.js +2508 -0
- package/componyx.html-data.json +619 -0
- package/index.js +27 -0
- package/package.json +43 -4
- package/types/AppSkin.d.ts +842 -0
- package/types/Base.d.ts +1034 -0
- package/types/Bindary.d.ts +1196 -0
- package/types/BookmarkSpy.d.ts +112 -0
- package/types/Box.d.ts +374 -0
- package/types/Button.d.ts +455 -0
- package/types/Carousel.d.ts +136 -0
- package/types/ColorButton.d.ts +120 -0
- package/types/ColorPicker.d.ts +225 -0
- package/types/ComboBox.d.ts +507 -0
- package/types/DataPager.d.ts +152 -0
- package/types/DatePicker.d.ts +354 -0
- package/types/Dialog.d.ts +160 -0
- package/types/Editor.d.ts +1289 -0
- package/types/FileUpload.d.ts +206 -0
- package/types/Form.d.ts +3078 -0
- package/types/FormField.d.ts +204 -0
- package/types/Grid.d.ts +911 -0
- package/types/Library.d.ts +1899 -0
- package/types/MaskedTextBox.d.ts +91 -0
- package/types/Menu.d.ts +577 -0
- package/types/NumericBox.d.ts +310 -0
- package/types/PanelBar.d.ts +223 -0
- package/types/PieChart.d.ts +224 -0
- package/types/ResponsiveTemplates.d.ts +108 -0
- package/types/Slider.d.ts +227 -0
- package/types/TabStrip.d.ts +185 -0
- package/types/TimePicker.d.ts +265 -0
- package/types/TooltipManager.d.ts +178 -0
- package/types/UI.d.ts +29 -0
- package/types/Validator.d.ts +653 -0
- package/types/index.d.ts +59 -0
- package/ui.css +11783 -0
- package/ui.js +79477 -0
- package/ui.min.css +138 -0
- package/ui.min.js +264 -0
- package/ui.min.js.map +1 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*! Componyx.UI | (c) E.H. Daanen / Componyx | BUSL-1.1 | componyx.com/license */
|
|
2
|
+
@property --scrollbar-opacity
|
|
3
|
+
{
|
|
4
|
+
syntax: "<number>";
|
|
5
|
+
inherits: true;
|
|
6
|
+
initial-value: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.panel-bar.theme
|
|
10
|
+
{
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
height: 100%;
|
|
14
|
+
min-height: 0; /* Allow children to shrink */
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.panel-bar.theme > .panel
|
|
18
|
+
{
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
flex-grow: 1;
|
|
22
|
+
height: 0px;
|
|
23
|
+
min-height: 40px; /* allow to shrink */
|
|
24
|
+
max-height: 40px; /* don't allow it to go beyond min-height */
|
|
25
|
+
transition: max-height 0.5s ease-in-out, background 0.5s ease-in-out; /* animate the max-height, not height, to avoid recalculations every anim. frame */
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.panel-bar.theme > .panel.expanded
|
|
29
|
+
{
|
|
30
|
+
height: 100%; /* actual height when expanded */
|
|
31
|
+
max-height: 100%; /* upper bound, we animate this */
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
/* Fixed header for each panel */
|
|
36
|
+
.panel-bar.theme > .panel > header
|
|
37
|
+
{
|
|
38
|
+
display: flex;
|
|
39
|
+
position: relative;
|
|
40
|
+
flex: 0 0 auto; /* Do not grow or shrink */
|
|
41
|
+
padding-left: 10px;
|
|
42
|
+
padding-right: 10px;
|
|
43
|
+
border-bottom-style: solid;
|
|
44
|
+
height: 40px;
|
|
45
|
+
line-height: 40px;
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
overflow: hidden;
|
|
48
|
+
white-space: nowrap;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
user-select: none;
|
|
51
|
+
transition: all 0.5s ease;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.panel-bar.theme > .panel > header > .icon
|
|
55
|
+
{
|
|
56
|
+
width: 32px;
|
|
57
|
+
height: 32px;
|
|
58
|
+
font-style: normal;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.panel-bar.theme > .panel > header > .title
|
|
62
|
+
{
|
|
63
|
+
flex-grow: 1; /* Take available space */
|
|
64
|
+
margin-right: 20px;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
text-overflow: ellipsis;
|
|
67
|
+
white-space: nowrap;
|
|
68
|
+
min-width: 0; /* Critical inside flex containers */
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* expand/collapse arrow for the header */
|
|
72
|
+
.panel-bar.theme > .panel > header::after
|
|
73
|
+
{
|
|
74
|
+
content: "";
|
|
75
|
+
position: absolute;
|
|
76
|
+
right: 10px;
|
|
77
|
+
top: 50%;
|
|
78
|
+
transform: translateY(-50%);
|
|
79
|
+
width: 0;
|
|
80
|
+
height: 0;
|
|
81
|
+
border-left: 6px solid transparent; /* Invisible border */
|
|
82
|
+
border-right: 6px solid transparent; /* Invisible border */
|
|
83
|
+
border-top-width: 6px;
|
|
84
|
+
border-bottom-width: 0px;
|
|
85
|
+
border-style: solid;
|
|
86
|
+
transition: all .5s ease-in-out;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.panel-bar.theme > .panel.expanded > header::after
|
|
90
|
+
{
|
|
91
|
+
transform: translateY(-50%) rotate(180deg); /* Rotate 180 degrees to point up */
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* Scrollable content area that shrinks when needed */
|
|
95
|
+
.panel-bar.theme > .panel > .content
|
|
96
|
+
{
|
|
97
|
+
flex: 1 1 auto; /* Takes up remaining space */
|
|
98
|
+
min-height: 0; /* Allow shrinking even if inner content is large */
|
|
99
|
+
overflow-y: scroll;
|
|
100
|
+
padding: 0px;
|
|
101
|
+
box-sizing: border-box;
|
|
102
|
+
scrollbar-width: thin;
|
|
103
|
+
transition: --scrollbar-opacity 0.2s 0.5s;
|
|
104
|
+
scrollbar-color: rgba(0, 0, 0, var(--scrollbar-opacity)) transparent;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.panel-bar.theme > .panel.expanded > .content
|
|
108
|
+
{
|
|
109
|
+
--scrollbar-opacity: 0.3;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.panel-bar.theme > .panel > .content::-webkit-scrollbar,
|
|
113
|
+
.panel-bar.theme > .panel > .content::-webkit-scrollbar-thumb,
|
|
114
|
+
.panel-bar.theme > .panel > .content::-webkit-scrollbar-button
|
|
115
|
+
{
|
|
116
|
+
background: transparent;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.panel-bar.theme > .panel.expanded > .content::-webkit-scrollbar-thumb,
|
|
120
|
+
.panel-bar.theme > .panel.expanded > .content::-webkit-scrollbar-button
|
|
121
|
+
{
|
|
122
|
+
background: rgba(0, 0, 0, var(--scrollbar-opacity));
|
|
123
|
+
}
|
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
/*! Componyx.UI | (c) E.H. Daanen / Componyx | BUSL-1.1 | componyx.com/license */
|
|
2
|
+
import '../Base/Base.js';
|
|
3
|
+
import '../Base/Library.js';
|
|
4
|
+
|
|
5
|
+
(function ()
|
|
6
|
+
{
|
|
7
|
+
/**
|
|
8
|
+
* PanelBar class.
|
|
9
|
+
* @class
|
|
10
|
+
* @memberof componyx.UI
|
|
11
|
+
* @augments componyx.UI.base.WebComponent
|
|
12
|
+
* @mixes componyx.UI.base.methods
|
|
13
|
+
* @param {String} id The id of the component.
|
|
14
|
+
* @param {Object|HTMLElement} properties The properties used to initialize the component or the container element.
|
|
15
|
+
* @returns {componyx.UI.PanelBar} An instance of the component.
|
|
16
|
+
*/
|
|
17
|
+
class PanelBar extends componyx.UI.base.WebComponent
|
|
18
|
+
{
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Internal CSS class name constants.
|
|
22
|
+
* You can override any of these classes on the Component instance by defining a property named
|
|
23
|
+
* `cssClass<Key>` where <Key> is the PascalCase key from this object.
|
|
24
|
+
* Example:
|
|
25
|
+
* 'PANEL' -> 'cssClassPanel'
|
|
26
|
+
* Be cautious: overriding these classes without including the default names may break styling and functionality.
|
|
27
|
+
* @constant
|
|
28
|
+
* @type {Readonly<Object<string, string>>}
|
|
29
|
+
*/
|
|
30
|
+
classOption =
|
|
31
|
+
{
|
|
32
|
+
PANEL: 'panel',
|
|
33
|
+
ICON: 'icon',
|
|
34
|
+
TITLE: 'title',
|
|
35
|
+
CONTENT: 'content',
|
|
36
|
+
EXPANDED: 'expanded',
|
|
37
|
+
DISABLED: 'disabled'
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
constructor(id, properties)
|
|
41
|
+
{
|
|
42
|
+
super(id, properties);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gets or sets a value indicating if a panel is expanded on the pointer enter event.
|
|
46
|
+
* @type {boolean}
|
|
47
|
+
*/
|
|
48
|
+
this.expandOnPointerEnter = false;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Gets or sets a value indicating if one panel or multiple panels can be expanded simultaneously.
|
|
52
|
+
* @type {Boolean}
|
|
53
|
+
*/
|
|
54
|
+
this.multiExpand = false;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Gets or sets the panels to render inside the panel-bar.
|
|
58
|
+
* @type {PanelBar.Panel[]}
|
|
59
|
+
*/
|
|
60
|
+
this.panels = [];
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @class
|
|
64
|
+
* @augments componyx.UI.base.Events
|
|
65
|
+
* @memberof componyx.UI.PanelBar
|
|
66
|
+
* @property {componyx.UI.base.Event} onPanelExpand - Fires when a panel expands. @see {@link componyx.UI.PanelBar.PanelBarEventArgs}
|
|
67
|
+
* @property {componyx.UI.base.Event} onPanelCollapse - Fires when a panel collapses. @see {@link componyx.UI.PanelBar.PanelBarEventArgs}
|
|
68
|
+
* @see {@link componyx.UI.base.Events}
|
|
69
|
+
*/
|
|
70
|
+
function PanelBarEvents(events)
|
|
71
|
+
{
|
|
72
|
+
Object.assign(this, events);
|
|
73
|
+
|
|
74
|
+
this.onPanelExpand = $base.static.createEvent('onPanelExpand');
|
|
75
|
+
this.onPanelCollapse = $base.static.createEvent('onPanelCollapse');
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* PanelBar events
|
|
79
|
+
* @type {componyx.UI.PanelBar.PanelBarEvents}
|
|
80
|
+
*/
|
|
81
|
+
this.events = new PanelBarEvents(this.events);
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @typedef {Object} PanelBarEventArgs
|
|
85
|
+
* @memberof componyx.UI.PanelBar
|
|
86
|
+
* @property {componyx.UI.PanelBar} panelBar - The PanelBar instance.
|
|
87
|
+
* @property {Object} eventArgs - The event object containing more detailed information about the event.
|
|
88
|
+
* @property {componyx.UI.PanelBar.Panel} eventArgs.panel - The panel instance associated with the event.
|
|
89
|
+
*/
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Gets the Panel class instance by the specified panel element.
|
|
94
|
+
* @param {HTMLElement} element The panel element.
|
|
95
|
+
* @returns {PanelBar.Panel}
|
|
96
|
+
*/
|
|
97
|
+
getPanelByElement(element)
|
|
98
|
+
{
|
|
99
|
+
return this.panels.find(p => p.element === element);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Gets the Panel class instance by the specified id.
|
|
104
|
+
* @param {String} id The panel identifier.
|
|
105
|
+
* @returns {PanelBar.Panel}
|
|
106
|
+
*/
|
|
107
|
+
getPanelById(id)
|
|
108
|
+
{
|
|
109
|
+
return this.panels.find(p => p.id === id);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Updates the title of the specified panel.
|
|
114
|
+
* @param {Componyx.PanelBar.Panel|HTMLElement|String} panel The Panel instance, element, or identifier.
|
|
115
|
+
* @param {HTMLElement|DocumentFragment|string} title The title presented in the panel header.
|
|
116
|
+
*/
|
|
117
|
+
updatePanelTitle(panel, title)
|
|
118
|
+
{
|
|
119
|
+
let panelEl = (panel instanceof HTMLElement) ? panel : (typeof panel === 'string') ? this.getPanelById(panel).element : panel.element,
|
|
120
|
+
cssClass = this.#getCssClass(this.classOption.TITLE),
|
|
121
|
+
headerTitleEl = panelEl.querySelector(`header .${cssClass}`);
|
|
122
|
+
|
|
123
|
+
if (typeof title === 'string')
|
|
124
|
+
headerTitleEl.innerHTML = title;
|
|
125
|
+
else
|
|
126
|
+
headerTitleEl.appendChild(title);
|
|
127
|
+
|
|
128
|
+
panel.title = title;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Shows the specified panel.
|
|
133
|
+
* @param {Componyx.PanelBar.Panel|HTMLElement|String} panel The Panel instance, element, or identifier.
|
|
134
|
+
*/
|
|
135
|
+
showPanel(panel)
|
|
136
|
+
{
|
|
137
|
+
let panelEl = (panel instanceof HTMLElement) ? panel : (typeof panel === 'string') ? this.getPanelById(panel).element : panel.element;
|
|
138
|
+
panelEl.style.display = '';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Hides the specified panel.
|
|
143
|
+
* @param {Componyx.PanelBar.Panel|HTMLElement|String} panel The Panel instance, element, or identifier.
|
|
144
|
+
*/
|
|
145
|
+
hidePanel(panel)
|
|
146
|
+
{
|
|
147
|
+
let panelEl = (panel instanceof HTMLElement) ? panel : (typeof panel === 'string') ? this.getPanelById(panel).element : panel.element;
|
|
148
|
+
panelEl.style.display = 'none';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Toggles the expand/collapse state of the specified panel element.
|
|
153
|
+
* If multiExpand is false, collapses all panels before expanding the selected one.
|
|
154
|
+
* @param {Componyx.PanelBar.Panel|HTMLElement|String} panel The Panel instance, element, or identifier.
|
|
155
|
+
*/
|
|
156
|
+
toggleExpandPanel(panel)
|
|
157
|
+
{
|
|
158
|
+
const panelEl = (panel instanceof HTMLElement) ? panel : (typeof panel === 'string') ? this.getPanelById(panel).element : panel.element,
|
|
159
|
+
cssClass = this.#getCssClass(this.classOption.EXPANDED);
|
|
160
|
+
|
|
161
|
+
if (panelEl.classList.contains(cssClass))
|
|
162
|
+
this.collapsePanel(panel);
|
|
163
|
+
else
|
|
164
|
+
this.expandPanel(panel);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Expands the specified panel element by adding the expand CSS class.
|
|
169
|
+
* Fires an event indicating the panel has expanded.
|
|
170
|
+
* @param {Componyx.PanelBar.Panel|HTMLElement|String} panel The Panel instance, element, or identifier.
|
|
171
|
+
* @param {Boolean} instant=false A value indicating if the default CSS animation should be skipped.
|
|
172
|
+
*/
|
|
173
|
+
expandPanel(panel, instant=false)
|
|
174
|
+
{
|
|
175
|
+
const panelEl = (panel instanceof HTMLElement) ? panel : (typeof panel === 'string') ? this.getPanelById(panel).element : panel.element,
|
|
176
|
+
cssClass = this.#getCssClass(this.classOption.EXPANDED);
|
|
177
|
+
|
|
178
|
+
panel = this.getPanelByElement(panelEl);
|
|
179
|
+
|
|
180
|
+
if (!this.multiExpand)
|
|
181
|
+
this.collapseAllPanels(instant);
|
|
182
|
+
|
|
183
|
+
if (instant)
|
|
184
|
+
{
|
|
185
|
+
panelEl.style.transition = 'none';
|
|
186
|
+
void panelEl.offsetHeight; // force reflow to pickup transition change
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
panelEl.classList.add(cssClass);
|
|
190
|
+
this.events.onPanelExpand.fire(this, { panel });
|
|
191
|
+
panel.expanded = true;
|
|
192
|
+
|
|
193
|
+
if (instant)
|
|
194
|
+
requestAnimationFrame(() => { panelEl.style.transition = ''; });
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Collapses the specified panel element by removing the expand CSS class.
|
|
199
|
+
* Fires an event indicating the panel has collapsed.
|
|
200
|
+
* @param {Componyx.PanelBar.Panel|HTMLElement|String} panel The Panel instance, element, or identifier.
|
|
201
|
+
* @param {Boolean} instant=false A value indicating if the default CSS animation should be skipped.
|
|
202
|
+
*/
|
|
203
|
+
collapsePanel(panel, instant = false)
|
|
204
|
+
{
|
|
205
|
+
const panelEl = (panel instanceof HTMLElement) ? panel : (typeof panel === 'string') ? this.getPanelById(panel).element : panel.element,
|
|
206
|
+
cssClass = this.#getCssClass(this.classOption.EXPANDED);
|
|
207
|
+
|
|
208
|
+
if (instant)
|
|
209
|
+
{
|
|
210
|
+
panelEl.style.transition = 'none';
|
|
211
|
+
void panelEl.offsetHeight; // force reflow to pickup transition change
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
panel = this.getPanelByElement(panelEl);
|
|
215
|
+
panelEl.classList.remove(cssClass);
|
|
216
|
+
|
|
217
|
+
this.events.onPanelCollapse.fire(this, { panel });
|
|
218
|
+
panel.expanded = false;
|
|
219
|
+
|
|
220
|
+
if (instant)
|
|
221
|
+
requestAnimationFrame(() => { panelEl.style.transition = ''; });
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Disables the specified panel.
|
|
226
|
+
* @param {Componyx.PanelBar.Panel|HTMLElement|String} panel The Panel instance, element, or identifier.
|
|
227
|
+
*/
|
|
228
|
+
disablePanel(panel)
|
|
229
|
+
{
|
|
230
|
+
const panelEl = (panel instanceof HTMLElement) ? panel : (typeof panel === 'string') ? this.getPanelById(panel).element : panel.element,
|
|
231
|
+
cssClass = this.#getCssClass(this.classOption.DISABLED);
|
|
232
|
+
|
|
233
|
+
panelEl.classList.add(cssClass);
|
|
234
|
+
panelEl.inert = true;
|
|
235
|
+
this.getPanelByElement(panelEl).disabled = true;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Enables the specified panel.
|
|
240
|
+
* @param {Componyx.PanelBar.Panel|HTMLElement|String} panel The Panel instance, element, or identifier.
|
|
241
|
+
*/
|
|
242
|
+
enablePanel(panel)
|
|
243
|
+
{
|
|
244
|
+
const panelEl = (panel instanceof HTMLElement) ? panel : (typeof panel === 'string') ? this.getPanelById(panel).element : panel.element,
|
|
245
|
+
cssClass = this.#getCssClass(this.classOption.DISABLED);
|
|
246
|
+
|
|
247
|
+
panelEl.classList.remove(cssClass);
|
|
248
|
+
panelEl.inert = false;
|
|
249
|
+
this.getPanelByElement(panelEl).disabled = false;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Collapses all panels by removing the expand CSS class from all expanded panels.
|
|
254
|
+
* @param {Boolean} instant=false A value indicating if the default CSS animation should be skipped.
|
|
255
|
+
*/
|
|
256
|
+
collapseAllPanels(instant = false)
|
|
257
|
+
{
|
|
258
|
+
const cssClass = this.#getCssClass(this.classOption.EXPANDED);
|
|
259
|
+
|
|
260
|
+
this.panels.forEach((panel) =>
|
|
261
|
+
{
|
|
262
|
+
const el = panel.element;
|
|
263
|
+
|
|
264
|
+
if (el && el.classList.contains(cssClass))
|
|
265
|
+
this.collapsePanel(el, instant);
|
|
266
|
+
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Enables all panels.
|
|
272
|
+
*/
|
|
273
|
+
enableAllPanels()
|
|
274
|
+
{
|
|
275
|
+
this.panels.forEach((panel) =>
|
|
276
|
+
{
|
|
277
|
+
this.enablePanel(panel);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Disables all panels.
|
|
283
|
+
*/
|
|
284
|
+
disableAllPanels()
|
|
285
|
+
{
|
|
286
|
+
this.panels.forEach((panel) =>
|
|
287
|
+
{
|
|
288
|
+
this.disablePanel(panel);
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Shows all panels.
|
|
294
|
+
*/
|
|
295
|
+
showAllPanels()
|
|
296
|
+
{
|
|
297
|
+
this.panels.forEach((panel) =>
|
|
298
|
+
{
|
|
299
|
+
this.showPanel(panel);
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Hides all panels.
|
|
305
|
+
*/
|
|
306
|
+
hideAllPanels()
|
|
307
|
+
{
|
|
308
|
+
this.panels.forEach((panel) =>
|
|
309
|
+
{
|
|
310
|
+
this.hidePanel(panel);
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Renders the component.
|
|
316
|
+
*/
|
|
317
|
+
render()
|
|
318
|
+
{
|
|
319
|
+
if (this.renderState != $base.static.RenderState.RENDERING)
|
|
320
|
+
{
|
|
321
|
+
super.render(this.#preRender, 'panel-bar');
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// render logic after loading resources
|
|
326
|
+
this.#draw();
|
|
327
|
+
$lib.on(document, 'focus', this.#focus, null, this, true);
|
|
328
|
+
this.renderChildren();
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Destroys the component.
|
|
333
|
+
* @param {Boolean} keepEvents A value indicating if component events should be kept.
|
|
334
|
+
* @param {Boolean} removeElement=true A value indicating if the corresponding HTML Element should be removed.
|
|
335
|
+
* @see {@link componyx.UI.base.methods#destroy}
|
|
336
|
+
* @function
|
|
337
|
+
*/
|
|
338
|
+
destroy(keepEvents, removeElement = true)
|
|
339
|
+
{
|
|
340
|
+
this.#dispose();
|
|
341
|
+
super.destroy(keepEvents, removeElement);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
#preRender()
|
|
345
|
+
{
|
|
346
|
+
return [PanelBar.name];
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
#draw()
|
|
350
|
+
{
|
|
351
|
+
this.panels.forEach((panel, index) =>
|
|
352
|
+
{
|
|
353
|
+
this.#createPanel(panel, panel.templateId || `Content_${index}`);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Creates the panel
|
|
359
|
+
* @param {PanelBar.Panel} panel
|
|
360
|
+
* @private
|
|
361
|
+
*/
|
|
362
|
+
#createPanel(panel, templateId)
|
|
363
|
+
{
|
|
364
|
+
const panelEl = $lib.element(this.element, '', '', '',
|
|
365
|
+
{
|
|
366
|
+
"id": (!$lib.isEmpty(panel.id)) ? `${this.id}_${panel.id}` : undefined,
|
|
367
|
+
"class": this.#getCssClass(this.classOption.PANEL),
|
|
368
|
+
"style": panel.style || undefined
|
|
369
|
+
}),
|
|
370
|
+
headerTitleEl = $lib.element('', '', 'span', panel.title, { "class": this.#getCssClass(this.classOption.TITLE) }),
|
|
371
|
+
headerEl = $lib.element(panelEl, '', 'header', headerTitleEl),
|
|
372
|
+
contentEl = $lib.element(panelEl, '', '', '', { "class": this.#getCssClass(this.classOption.CONTENT) });
|
|
373
|
+
|
|
374
|
+
if (panel.cssClass)
|
|
375
|
+
panelEl.classList.add(panel.cssClass);
|
|
376
|
+
|
|
377
|
+
if (panel.hasIcon)
|
|
378
|
+
{
|
|
379
|
+
let iconEl = $lib.element(headerEl, headerTitleEl, 'i', '', { "class": this.#getCssClass(this.classOption.ICON) });
|
|
380
|
+
|
|
381
|
+
if (panel.cssClassIcon)
|
|
382
|
+
iconEl.classList.add(panel.cssClassIcon);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (panel.minHeight)
|
|
386
|
+
panelEl.style.minHeight = $lib.unit(panel.minHeight);
|
|
387
|
+
|
|
388
|
+
if (panel.maxHeight)
|
|
389
|
+
panelEl.style.minHeight = $lib.unit(panel.minHeight);
|
|
390
|
+
|
|
391
|
+
if (!panel.content)
|
|
392
|
+
panel.content = this.getTemplateContent(templateId);
|
|
393
|
+
|
|
394
|
+
if (panel.content)
|
|
395
|
+
$lib.element(contentEl, '', '', panel.content);
|
|
396
|
+
|
|
397
|
+
panel.element = panelEl;
|
|
398
|
+
panel.contentElement = contentEl;
|
|
399
|
+
|
|
400
|
+
if (panel.expanded)
|
|
401
|
+
this.expandPanel(panelEl);
|
|
402
|
+
|
|
403
|
+
if (panel.disabled)
|
|
404
|
+
{
|
|
405
|
+
let cssClass = this.#getCssClass(this.classOption.DISABLED);
|
|
406
|
+
panelEl.classList.add(cssClass);
|
|
407
|
+
panelEl.inert = true;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
this.#bindEvents(panelEl, headerEl);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
#getCssClass(cssClassValue)
|
|
414
|
+
{
|
|
415
|
+
return super.getCssClass(this.classOption, cssClassValue);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
#bindEvents(panelEl, headerEl)
|
|
419
|
+
{
|
|
420
|
+
if (this.expandOnPointerEnter)
|
|
421
|
+
$lib.on(panelEl, 'pointerenter', this.#pointerEnter, [panelEl], this, true);
|
|
422
|
+
|
|
423
|
+
$lib.on(headerEl, 'click', this.toggleExpandPanel, [panelEl], this, true);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
#pointerEnter(panelEl, event)
|
|
427
|
+
{
|
|
428
|
+
if (event.pointerType === "touch")
|
|
429
|
+
return;
|
|
430
|
+
|
|
431
|
+
this.expandPanel(panelEl);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
#focus(event)
|
|
435
|
+
{
|
|
436
|
+
const focusedEl = event.target,
|
|
437
|
+
cssClass = this.#getCssClass(this.classOption.PANEL);
|
|
438
|
+
|
|
439
|
+
if (this.contains(focusedEl))
|
|
440
|
+
{
|
|
441
|
+
const panelEl = focusedEl.closest('.' + cssClass);
|
|
442
|
+
this.expandPanel(panelEl);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
#dispose()
|
|
447
|
+
{
|
|
448
|
+
$lib.off(document, 'focus', this.#focus);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* The Panel class.
|
|
454
|
+
* @class Panel
|
|
455
|
+
* @memberof componyx.UI.PanelBar
|
|
456
|
+
* @param {Object} properties The properties used to initialize the object.
|
|
457
|
+
* @property {string} [id] Gets or sets the identifier of the panel.
|
|
458
|
+
* @property {boolean} [expanded] Gets or sets a value indicating if this panel is expanded.
|
|
459
|
+
* @property {boolean} [hasIcon] Gets or sets a value indicating if there is an icon in the panel header.
|
|
460
|
+
* @property {string} [cssClass] Gets or sets the css class of the panel. This class is combined with the default class set on the PanelBar component.
|
|
461
|
+
* @property {string} [cssClassIcon] Gets or sets the css class of the panel header icon. This class is combined with the default icon class set on the PanelBar component.
|
|
462
|
+
* @property {string} [style] Gets or sets the css style of the panel.
|
|
463
|
+
* @property {string} [minHeight] Gets or sets the minimum height of the panel in the desired CSS units.
|
|
464
|
+
* @property {string} [maxHeight] Gets or sets the maximum height of the panel in the desired CSS units.
|
|
465
|
+
* @property {HTMLElement|DocumentFragment|string} title Gets or sets the title presented in the panel header.
|
|
466
|
+
* @property {HTMLElement|DocumentFragment|string} content Gets or sets the content of the panel.
|
|
467
|
+
* @property {string} templateId Gets or sets the content template id of this panel.
|
|
468
|
+
* @property {HTMLElement} element Gets the rendered panel element.
|
|
469
|
+
* @property {HTMLElement} contentElement Gets the rendered panel content element.
|
|
470
|
+
*/
|
|
471
|
+
PanelBar.Panel = class Panel
|
|
472
|
+
{
|
|
473
|
+
constructor(properties)
|
|
474
|
+
{
|
|
475
|
+
this.id = null;
|
|
476
|
+
this.expanded = false;
|
|
477
|
+
this.hasIcon = false;
|
|
478
|
+
this.cssClass = '';
|
|
479
|
+
this.cssClassIcon = '';
|
|
480
|
+
this.style = '';
|
|
481
|
+
this.minHeight = '';
|
|
482
|
+
this.maxHeight = '';
|
|
483
|
+
this.title = '';
|
|
484
|
+
this.content = '';
|
|
485
|
+
this.templateId = '';
|
|
486
|
+
this.element = null;
|
|
487
|
+
this.contentElement = null;
|
|
488
|
+
Object.defineProperties(this, Object.getOwnPropertyDescriptors(properties));
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
// Preserve HTMLElement prototype and extend it with $base.methods
|
|
493
|
+
Object.assign(PanelBar.prototype, Object.fromEntries(Object.entries($base.methods).filter(([key]) => !['render', 'destroy', 'getCssClass'].includes(key))));
|
|
494
|
+
|
|
495
|
+
// Restore the constructor reference
|
|
496
|
+
PanelBar.prototype.constructor = PanelBar;
|
|
497
|
+
componyx.UI.PanelBar = PanelBar;
|
|
498
|
+
|
|
499
|
+
// Define the custom element
|
|
500
|
+
customElements.define(`${componyx.UI.tagPrefix}${PanelBar.name.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '')}`, PanelBar); // cui-panel-bar
|
|
501
|
+
})();
|
|
502
|
+
|
|
503
|
+
const PanelBar = componyx.UI.PanelBar;
|
|
504
|
+
|
|
505
|
+
export { PanelBar };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*! Componyx.UI | (c) E.H. Daanen / Componyx | BUSL-1.1 | componyx.com/license */
|
|
2
|
+
.panel-bar.theme.theme-default
|
|
3
|
+
{
|
|
4
|
+
background: var(--cui-color-surface);
|
|
5
|
+
box-shadow: -4px 0 8px var(--cui-box-shadow-color), 4px 0 8px var(--cui-box-shadow-color);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.panel-bar.theme.theme-default > .panel > header::after
|
|
9
|
+
{
|
|
10
|
+
border-top-color: var(--cui-border-color);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.panel-bar.theme.theme-default > .panel:hover > header::after,
|
|
14
|
+
.panel-bar.theme.theme-default > .panel.expanded > header::after
|
|
15
|
+
{
|
|
16
|
+
border-top-color: var(--cui-header-text-color);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.panel-bar.theme.theme-default > .panel > header
|
|
20
|
+
{
|
|
21
|
+
background: var(--cui-base-bg-color);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.panel-bar.theme.theme-default > .panel:not(.disabled):hover > header,
|
|
25
|
+
.panel-bar.theme.theme-default > .panel:not(.disabled).expanded > header
|
|
26
|
+
{
|
|
27
|
+
background: var(--cui-header-bg-color);
|
|
28
|
+
color: var(--cui-header-text-color);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.panel-bar.theme.theme-default > .panel
|
|
32
|
+
{
|
|
33
|
+
background: var(--cui-base-bg-color);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.panel-bar.theme.theme-default > .panel.expanded
|
|
37
|
+
{
|
|
38
|
+
background: var(--cui-color-surface);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.panel-bar.theme.theme-default > .panel.disabled
|
|
42
|
+
{
|
|
43
|
+
background: var(--cui-disabled-bg-color);
|
|
44
|
+
color: var(--cui-disabled-text-color);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.panel-bar.theme.theme-default > .panel.disabled > header
|
|
48
|
+
{
|
|
49
|
+
background: var(--cui-disabled-bg-color);
|
|
50
|
+
color: var(--cui-disabled-text-color);
|
|
51
|
+
}
|