@qtoggle/qui 0.0.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.
Files changed (202) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.json +492 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  5. package/.github/ISSUE_TEMPLATE/improvement_proposal.md +20 -0
  6. package/.github/workflows/main.yml +74 -0
  7. package/.pre-commit-config.yaml +8 -0
  8. package/LICENSE.txt +177 -0
  9. package/README.md +4 -0
  10. package/font/dejavusans-bold.woff +0 -0
  11. package/font/dejavusans-bolditalic.woff +0 -0
  12. package/font/dejavusans-italic.woff +0 -0
  13. package/font/dejavusans-regular.woff +0 -0
  14. package/img/qui-icons.svg +1937 -0
  15. package/js/base/base.js +47 -0
  16. package/js/base/condition-variable.js +92 -0
  17. package/js/base/errors.js +36 -0
  18. package/js/base/i18n.js +20 -0
  19. package/js/base/mixwith.js +135 -0
  20. package/js/base/require-js-compat.js +78 -0
  21. package/js/base/signal.js +91 -0
  22. package/js/base/singleton.js +66 -0
  23. package/js/base/timer.js +126 -0
  24. package/js/config.js +184 -0
  25. package/js/forms/common-fields/check-field.js +42 -0
  26. package/js/forms/common-fields/choice-buttons-field.js +30 -0
  27. package/js/forms/common-fields/color-combo-field.js +37 -0
  28. package/js/forms/common-fields/combo-field.js +108 -0
  29. package/js/forms/common-fields/common-fields.js +23 -0
  30. package/js/forms/common-fields/composite-field.js +132 -0
  31. package/js/forms/common-fields/custom-html-field.js +51 -0
  32. package/js/forms/common-fields/email-field.js +30 -0
  33. package/js/forms/common-fields/file-picker-field.js +46 -0
  34. package/js/forms/common-fields/jquery-ui-field.js +111 -0
  35. package/js/forms/common-fields/labels-field.js +69 -0
  36. package/js/forms/common-fields/numeric-field.js +39 -0
  37. package/js/forms/common-fields/password-field.js +28 -0
  38. package/js/forms/common-fields/phone-field.js +26 -0
  39. package/js/forms/common-fields/progress-disk-field.js +69 -0
  40. package/js/forms/common-fields/push-button-field.js +138 -0
  41. package/js/forms/common-fields/slider-field.js +51 -0
  42. package/js/forms/common-fields/text-area-field.js +34 -0
  43. package/js/forms/common-fields/text-field.js +89 -0
  44. package/js/forms/common-fields/up-down-field.js +85 -0
  45. package/js/forms/common-forms/common-forms.js +16 -0
  46. package/js/forms/common-forms/options-form.js +77 -0
  47. package/js/forms/common-forms/page-form.js +115 -0
  48. package/js/forms/form-button.js +202 -0
  49. package/js/forms/form-field.js +1183 -0
  50. package/js/forms/form.js +1181 -0
  51. package/js/forms/forms.js +68 -0
  52. package/js/global-glass.js +100 -0
  53. package/js/icons/default-stock.js +173 -0
  54. package/js/icons/icon.js +64 -0
  55. package/js/icons/icons.js +16 -0
  56. package/js/icons/multi-state-sprites-icon.js +362 -0
  57. package/js/icons/stock-icon.js +219 -0
  58. package/js/icons/stock.js +98 -0
  59. package/js/icons/stocks.js +57 -0
  60. package/js/index.js +232 -0
  61. package/js/lib/jquery.longpress.js +79 -0
  62. package/js/lib/jquery.module.js +4 -0
  63. package/js/lib/logger.module.js +4 -0
  64. package/js/lib/pep.module.js +4 -0
  65. package/js/lists/common-items/common-items.js +5 -0
  66. package/js/lists/common-items/icon-label-list-item.js +86 -0
  67. package/js/lists/common-lists/common-lists.js +5 -0
  68. package/js/lists/common-lists/page-list.js +53 -0
  69. package/js/lists/list-item.js +147 -0
  70. package/js/lists/list.js +636 -0
  71. package/js/lists/lists.js +26 -0
  72. package/js/main-ui/main-ui.js +64 -0
  73. package/js/main-ui/menu-bar.js +144 -0
  74. package/js/main-ui/options-bar.js +181 -0
  75. package/js/main-ui/status.js +185 -0
  76. package/js/main-ui/top-bar.js +59 -0
  77. package/js/messages/common-message-forms/common-message-forms.js +7 -0
  78. package/js/messages/common-message-forms/confirm-message-form.js +81 -0
  79. package/js/messages/common-message-forms/simple-message-form.js +67 -0
  80. package/js/messages/common-message-forms/sticky-simple-message-form.js +27 -0
  81. package/js/messages/message-form.js +107 -0
  82. package/js/messages/messages.js +21 -0
  83. package/js/messages/sticky-modal-page.js +98 -0
  84. package/js/messages/sticky-modal-progress-message.js +27 -0
  85. package/js/messages/toast.js +164 -0
  86. package/js/navigation.js +654 -0
  87. package/js/pages/breadcrumbs.js +124 -0
  88. package/js/pages/common-pages/common-pages.js +6 -0
  89. package/js/pages/common-pages/modal-progress-page.js +83 -0
  90. package/js/pages/common-pages/structured-page.js +46 -0
  91. package/js/pages/page.js +1018 -0
  92. package/js/pages/pages-context.js +154 -0
  93. package/js/pages/pages.js +252 -0
  94. package/js/pwa.js +337 -0
  95. package/js/sections/section.js +612 -0
  96. package/js/sections/sections.js +300 -0
  97. package/js/tables/common-cells/common-cells.js +7 -0
  98. package/js/tables/common-cells/icon-label-table-cell.js +68 -0
  99. package/js/tables/common-cells/push-button-table-cell.js +133 -0
  100. package/js/tables/common-cells/simple-table-cell.js +37 -0
  101. package/js/tables/common-tables/common-tables.js +5 -0
  102. package/js/tables/common-tables/page-table.js +55 -0
  103. package/js/tables/table-cell.js +198 -0
  104. package/js/tables/table-row.js +126 -0
  105. package/js/tables/table.js +492 -0
  106. package/js/tables/tables.js +36 -0
  107. package/js/theme.js +304 -0
  108. package/js/utils/ajax.js +126 -0
  109. package/js/utils/array.js +194 -0
  110. package/js/utils/colors.js +445 -0
  111. package/js/utils/cookies.js +65 -0
  112. package/js/utils/crypto.js +439 -0
  113. package/js/utils/css.js +234 -0
  114. package/js/utils/date.js +300 -0
  115. package/js/utils/files.js +27 -0
  116. package/js/utils/gestures.js +165 -0
  117. package/js/utils/html.js +76 -0
  118. package/js/utils/misc.js +81 -0
  119. package/js/utils/object.js +324 -0
  120. package/js/utils/promise.js +49 -0
  121. package/js/utils/string.js +192 -0
  122. package/js/utils/url.js +187 -0
  123. package/js/utils/utils.js +3 -0
  124. package/js/utils/visibility-manager.js +211 -0
  125. package/js/views/common-views/common-views.js +7 -0
  126. package/js/views/common-views/icon-label-view.js +210 -0
  127. package/js/views/common-views/progress-view.js +89 -0
  128. package/js/views/common-views/structured-view.js +368 -0
  129. package/js/views/view.js +467 -0
  130. package/js/views/views.js +3 -0
  131. package/js/widgets/base-widget.js +23 -0
  132. package/js/widgets/common-widgets/check-button.js +109 -0
  133. package/js/widgets/common-widgets/choice-buttons.js +322 -0
  134. package/js/widgets/common-widgets/color-combo.js +104 -0
  135. package/js/widgets/common-widgets/combo.js +645 -0
  136. package/js/widgets/common-widgets/common-widgets.js +17 -0
  137. package/js/widgets/common-widgets/email-input.js +7 -0
  138. package/js/widgets/common-widgets/file-picker.js +133 -0
  139. package/js/widgets/common-widgets/labels.js +132 -0
  140. package/js/widgets/common-widgets/numeric-input.js +49 -0
  141. package/js/widgets/common-widgets/password-input.js +91 -0
  142. package/js/widgets/common-widgets/phone-input.js +7 -0
  143. package/js/widgets/common-widgets/progress-disk.js +174 -0
  144. package/js/widgets/common-widgets/push-button.js +155 -0
  145. package/js/widgets/common-widgets/slider.js +455 -0
  146. package/js/widgets/common-widgets/text-area.js +52 -0
  147. package/js/widgets/common-widgets/text-input.js +174 -0
  148. package/js/widgets/common-widgets/up-down.js +351 -0
  149. package/js/widgets/widgets.js +57 -0
  150. package/js/window.js +557 -0
  151. package/jsdoc.conf.json +20 -0
  152. package/less/base.less +123 -0
  153. package/less/forms/common-fields.less +101 -0
  154. package/less/forms/common-forms.less +5 -0
  155. package/less/forms/form-button.less +21 -0
  156. package/less/forms/form-field.less +266 -0
  157. package/less/forms/form.less +131 -0
  158. package/less/global-glass.less +64 -0
  159. package/less/icon-label-view.less +82 -0
  160. package/less/icons.less +144 -0
  161. package/less/lists.less +105 -0
  162. package/less/main-ui.less +328 -0
  163. package/less/messages.less +189 -0
  164. package/less/no-effects.less +24 -0
  165. package/less/pages/breadcrumbs.less +98 -0
  166. package/less/pages/common-pages.less +36 -0
  167. package/less/pages/page.less +70 -0
  168. package/less/progress-view.less +51 -0
  169. package/less/stock-icons.less +43 -0
  170. package/less/structured-view.less +245 -0
  171. package/less/tables.less +84 -0
  172. package/less/theme-dark.less +133 -0
  173. package/less/theme-light.less +132 -0
  174. package/less/theme.less +419 -0
  175. package/less/visibility-manager.less +11 -0
  176. package/less/widgets/check-button.less +96 -0
  177. package/less/widgets/choice-buttons.less +160 -0
  178. package/less/widgets/color-combo.less +33 -0
  179. package/less/widgets/combo.less +230 -0
  180. package/less/widgets/common-buttons.less +120 -0
  181. package/less/widgets/common.less +24 -0
  182. package/less/widgets/input.less +258 -0
  183. package/less/widgets/labels.less +81 -0
  184. package/less/widgets/progress-disk.less +70 -0
  185. package/less/widgets/slider.less +199 -0
  186. package/less/widgets/updown.less +115 -0
  187. package/less/widgets/various.less +36 -0
  188. package/package.json +47 -0
  189. package/pyproject.toml +45 -0
  190. package/qui/__init__.py +110 -0
  191. package/qui/constants.py +1 -0
  192. package/qui/exceptions.py +2 -0
  193. package/qui/j2template.py +71 -0
  194. package/qui/settings.py +60 -0
  195. package/qui/templates/manifest.json +25 -0
  196. package/qui/templates/qui.html +126 -0
  197. package/qui/templates/service-worker.js +188 -0
  198. package/qui/web/__init__.py +0 -0
  199. package/qui/web/tornado.py +220 -0
  200. package/scripts/postinstall.sh +10 -0
  201. package/webpack/webpack-adjust-css-urls-loader.js +36 -0
  202. package/webpack/webpack-common.js +384 -0
@@ -0,0 +1,174 @@
1
+
2
+ import $ from '$qui/lib/jquery.module.js'
3
+
4
+ import {asap} from '$qui/utils/misc.js'
5
+
6
+ import * as BaseWidget from '../base-widget.js' /* Needed */
7
+
8
+
9
+ $.widget('qui.textinput', $.qui.basewidget, {
10
+
11
+ options: {
12
+ name: '',
13
+ placeholder: '',
14
+ clearPlaceholder: false,
15
+ autocomplete: false,
16
+ continuousChange: true,
17
+ minLength: null,
18
+ maxLength: null,
19
+ readonly: false,
20
+ disabled: false
21
+ },
22
+
23
+ type: 'text',
24
+ _autocomplete_on: null,
25
+ _autocomplete_off: 'off',
26
+
27
+ _create: function () {
28
+ this.element.addClass('qui-text-input')
29
+
30
+ if (this.type === 'textarea') {
31
+ this._input = $('<textarea></textarea>')
32
+ }
33
+ else {
34
+ this._input = $('<input>', {type: this.type})
35
+ }
36
+
37
+ this.element.append(this._input)
38
+
39
+ if (this.options.name) {
40
+ this._input.attr('name', this.options.name)
41
+ }
42
+ if (this.options.placeholder) {
43
+ this._input.attr('placeholder', this.options.placeholder)
44
+ }
45
+
46
+ if (this.options.autocomplete === false && this._autocomplete_off != null) {
47
+ this._input.attr('autocomplete', this._autocomplete_off)
48
+ }
49
+ else if (this.options.autocomplete === true && this._autocomplete_on != null) {
50
+ this._input.attr('autocomplete', this._autocomplete_on)
51
+ }
52
+ else if (this.options.autocomplete != null) { /* Assuming a string */
53
+ this._input.attr('autocomplete', this.options.autocomplete)
54
+ }
55
+
56
+ if (this.options.minLength != null) {
57
+ this._input.attr('minlength', this.options.minLength)
58
+ }
59
+ if (this.options.maxLength != null) {
60
+ this._input.attr('maxlength', this.options.maxLength)
61
+ }
62
+ if (this.options.readonly) {
63
+ this._input.attr('readonly', 'readonly')
64
+ }
65
+ if (this.options.disabled) {
66
+ this._input.attr('disabled', 'disabled')
67
+ }
68
+
69
+ let widget = this
70
+
71
+ /* Manually propagate some events to parent */
72
+ this._input.on('focus blur', function (e) {
73
+ this.element.triggerHandler(e.type)
74
+ }.bind(this))
75
+
76
+ this._lastValue = ''
77
+ this._input.on('keydown paste cut', function () {
78
+ if (widget.options.continuousChange) {
79
+ asap(function () {
80
+ if (this.value !== widget._lastValue) {
81
+ widget.element.trigger('change')
82
+ widget._lastValue = this.value
83
+ }
84
+ }.bind(this))
85
+ }
86
+ })
87
+
88
+ this._input.on('change', function (e) {
89
+ if (widget.options.continuousChange) {
90
+ /* Change events are triggered by keydown & alike */
91
+ e.stopPropagation()
92
+ return
93
+ }
94
+
95
+ widget._lastValue = this.value
96
+ if (widget.options.clearPlaceholder) {
97
+ widget._input.attr('placeholder', '')
98
+ }
99
+ })
100
+ },
101
+
102
+ _setOption: function (key, value) {
103
+ this._super(key, value)
104
+
105
+ switch (key) {
106
+ case 'disabled':
107
+ if (value) {
108
+ this._input.attr('disabled', 'disabled')
109
+ }
110
+ else {
111
+ this._input.removeAttr('disabled')
112
+ }
113
+ break
114
+
115
+ case 'readonly':
116
+ if (value) {
117
+ this._input.attr('readonly', 'readonly')
118
+ }
119
+ else {
120
+ this._input.removeAttr('readonly')
121
+ }
122
+ break
123
+
124
+ case 'autocomplete':
125
+ if (value === false && this._autocomplete_off != null) {
126
+ this._input.attr('autocomplete', this._autocomplete_off)
127
+ }
128
+ else if (value === true && this._autocomplete_on != null) {
129
+ this._input.attr('autocomplete', this._autocomplete_on)
130
+ }
131
+ else if (value != null) { /* Assuming a string */
132
+ this._input.attr('autocomplete', value)
133
+ }
134
+ break
135
+
136
+ case 'placeholder':
137
+ this._input.attr('placeholder', value || '')
138
+ break
139
+
140
+ case 'minLength':
141
+ if (value != null) {
142
+ this._input.attr('minlength', value)
143
+ }
144
+ else {
145
+ this._input.removeAttr('minlength')
146
+ }
147
+ break
148
+
149
+ case 'maxLength':
150
+ if (value != null) {
151
+ this._input.attr('maxlength', value)
152
+ }
153
+ else {
154
+ this._input.removeAttr('maxlength')
155
+ }
156
+ break
157
+
158
+ case 'warning':
159
+ case 'error':
160
+ this._input.toggleClass(`has-${key}`, value != null)
161
+ break
162
+ }
163
+ },
164
+
165
+ getValue: function () {
166
+ return this._input.val()
167
+ },
168
+
169
+ setValue: function (value) {
170
+ this._input.val(value)
171
+ this._lastValue = value
172
+ }
173
+
174
+ })
@@ -0,0 +1,351 @@
1
+
2
+ import $ from '$qui/lib/jquery.module.js'
3
+
4
+ import {gettext} from '$qui/base/i18n.js'
5
+
6
+ import * as BaseWidget from '../base-widget.js' /* Needed */
7
+
8
+
9
+ $.widget('qui.updown', $.qui.basewidget, {
10
+
11
+ options: {
12
+ name: '',
13
+ min: 0,
14
+ max: 100,
15
+ step: 1,
16
+ fastFactor: 10,
17
+ decimals: 0,
18
+ continuousChange: true,
19
+ readonly: false,
20
+ disabled: false
21
+ },
22
+
23
+ _create: function () {
24
+ this._input = $('<input>', {type: 'text', class: 'qui-updown-input'})
25
+ this._downButton = $(
26
+ '<div></div>',
27
+ {class: 'qui-base-button qui-interactive-button qui-updown-button down', title: gettext('decrease')}
28
+ )
29
+ this._upButton = $(
30
+ '<div></div>',
31
+ {class: 'qui-base-button qui-interactive-button qui-updown-button up', title: gettext('increase')}
32
+ )
33
+
34
+ this._curVal = this.options.min
35
+ this._input.val(this.options.min.toFixed(this.options.decimals))
36
+
37
+ if (this.options.name) {
38
+ this._input.attr('name', this.options.name)
39
+ }
40
+ if (this.options.readonly) {
41
+ this.element.addClass('readonly')
42
+ }
43
+ if (this.options.disabled) {
44
+ this.element.addClass('disabled')
45
+ this._input.attr('disabled', 'disabled')
46
+ }
47
+
48
+ this.element.addClass('qui-updown-container')
49
+ this._input.attr('readonly', 'readonly')
50
+
51
+ this.element.append(this._input)
52
+
53
+ if (!this.options.disabled) {
54
+ this.element.attr('tabIndex', 0) /* Make the container focusable */
55
+ }
56
+
57
+ this.element.append(this._downButton)
58
+ this.element.append(this._upButton)
59
+
60
+ this._changed = false
61
+
62
+ let widget = this
63
+
64
+ /* Install the wheel handler */
65
+ this.element.on('mousewheel', function (e, delta) {
66
+ if (widget.options.readonly || widget.options.disabled) {
67
+ return
68
+ }
69
+
70
+ /* Ignore scroll events on unfocused widget */
71
+ if (!widget.element.is(':focus')) {
72
+ return
73
+ }
74
+
75
+ if (!widget.options.continuousChange) {
76
+ widget.element.focus() /* Needed for triggering the change event on blur */
77
+ }
78
+
79
+ let changed
80
+ let step = widget.options.step
81
+ if (e.shiftKey) {
82
+ step *= widget.options.fastFactor
83
+ }
84
+ if (delta > 0) {
85
+ changed = widget._increase(step)
86
+ }
87
+ else {
88
+ changed = widget._decrease(step)
89
+ }
90
+
91
+ if (changed) {
92
+ widget._markChange()
93
+ return false
94
+ }
95
+ })
96
+
97
+ /* Trigger change on input change */
98
+ this._input.on('change', function () {
99
+ let val = $(this).val()
100
+ val = widget._validate(val)
101
+ if (val == null) {
102
+ $(this).val(widget._curVal.toFixed(widget.options.decimals))
103
+ }
104
+ else {
105
+ $(this).val(val.toFixed(widget.options.decimals))
106
+ widget._curVal = val
107
+ widget._markChange()
108
+ }
109
+ })
110
+
111
+ /* Install the up/down buttons click handlers */
112
+ this._downButton.on('click', function () {
113
+ if (widget.options.readonly || widget.options.disabled) {
114
+ return
115
+ }
116
+
117
+ if (widget._decrease()) {
118
+ widget._markChange()
119
+ }
120
+ })
121
+ this._upButton.on('click', function () {
122
+ if (widget.options.readonly || widget.options.disabled) {
123
+ return
124
+ }
125
+
126
+ if (widget._increase()) {
127
+ widget._markChange()
128
+ }
129
+ })
130
+
131
+ let incDecLoopActive = false
132
+
133
+ function incLoop() {
134
+ widget._upButton.trigger('click')
135
+ if (incDecLoopActive) {
136
+ setTimeout(incLoop, 50)
137
+ }
138
+ }
139
+
140
+ function decLoop() {
141
+ widget._downButton.trigger('click')
142
+ if (incDecLoopActive) {
143
+ setTimeout(decLoop, 50)
144
+ }
145
+ }
146
+
147
+ /* Install up/down buttons long press handlers */
148
+
149
+ this._downButton.longpress(function () {
150
+ if (widget.options.readonly || widget.options.disabled) {
151
+ return
152
+ }
153
+
154
+ incDecLoopActive = true
155
+ decLoop()
156
+ })
157
+ this._downButton.on('pointerup pointerleave pointerout pointercancel', function () {
158
+ incDecLoopActive = false
159
+ })
160
+
161
+ this._upButton.longpress(function () {
162
+ if (widget.options.readonly || widget.options.disabled) {
163
+ return
164
+ }
165
+
166
+ incDecLoopActive = true
167
+ incLoop()
168
+ })
169
+ this._upButton.on('pointerup pointerleave pointerout pointercancel', function () {
170
+ incDecLoopActive = false
171
+ })
172
+
173
+ /* Install keys handler */
174
+ this.element.on('keydown', function (e) {
175
+ if (widget.options.readonly || widget.options.disabled) {
176
+ return
177
+ }
178
+
179
+ switch (e.which) {
180
+ case 40: /* Down */
181
+ if (widget._decrease()) {
182
+ widget._markChange()
183
+ return false
184
+ }
185
+
186
+ break
187
+
188
+ case 38: /* Up */
189
+ if (widget._increase()) {
190
+ widget._markChange()
191
+ return false
192
+ }
193
+
194
+ break
195
+
196
+ case 34: /* Page-down */
197
+ if (widget._decrease(widget.options.step * widget.options.fastFactor)) {
198
+ widget._markChange()
199
+ return false
200
+ }
201
+
202
+ break
203
+
204
+ case 33: /* Page-up */
205
+ if (widget._increase(widget.options.step * widget.options.fastFactor)) {
206
+ widget._markChange()
207
+ return false
208
+ }
209
+
210
+ break
211
+
212
+ case 35: /* End */
213
+ if (widget._curVal !== widget.options.min) {
214
+ widget._setValue(widget.options.min)
215
+ widget._markChange()
216
+ return false
217
+ }
218
+
219
+ break
220
+
221
+ case 36: /* Home */
222
+ if (widget._curVal !== widget.options.max) {
223
+ widget._setValue(widget.options.max)
224
+ widget._markChange()
225
+ return false
226
+ }
227
+
228
+ break
229
+
230
+ }
231
+ })
232
+
233
+ /* Transfer focus from input to container */
234
+ this._input.on('focus', function () {
235
+ widget.element.focus()
236
+ })
237
+
238
+ this.element.on('blur', function () {
239
+ if (widget._changed) {
240
+ widget._changed = false
241
+ widget.element.trigger('change', widget._curVal)
242
+ }
243
+ })
244
+ },
245
+
246
+ getValue: function () {
247
+ return this._curVal
248
+ },
249
+
250
+ setValue: function (value) {
251
+ value = this._validate(value)
252
+ if (value == null) {
253
+ return
254
+ }
255
+
256
+ this._setValue(value)
257
+ },
258
+
259
+ _setValue: function (value) {
260
+ this._curVal = value
261
+ this._input.val(value.toFixed(this.options.decimals))
262
+ },
263
+
264
+ _increase: function (step = this.options.step) {
265
+ let oldVal = this._curVal
266
+ let val = this._validate(oldVal + step)
267
+
268
+ if (oldVal !== val) {
269
+ this._setValue(val)
270
+ return true
271
+ }
272
+ else {
273
+ return false
274
+ }
275
+ },
276
+
277
+ _decrease: function (step = this.options.step) {
278
+ let oldVal = this._curVal
279
+ let val = this._validate(oldVal - step)
280
+
281
+ if (oldVal !== val) {
282
+ this._setValue(val)
283
+ return true
284
+ }
285
+ else {
286
+ return false
287
+ }
288
+ },
289
+
290
+ _markChange: function () {
291
+ if (this.options.continuousChange) {
292
+ this.element.trigger('change', this._curVal)
293
+ }
294
+ else {
295
+ this._changed = true
296
+ }
297
+ },
298
+
299
+ _validate: function (value) {
300
+ value = parseFloat(value)
301
+ if (isNaN(value)) {
302
+ return null
303
+ }
304
+
305
+ value = Math.max(this.options.min, value)
306
+ value = Math.min(this.options.max, value)
307
+
308
+ return value
309
+ },
310
+
311
+ _setOption: function (key, value) {
312
+ this._super(key, value)
313
+
314
+ switch (key) {
315
+ case 'readonly':
316
+ this.element.toggleClass('readonly', value)
317
+
318
+ break
319
+
320
+ case 'disabled':
321
+ this.element.toggleClass('disabled', value)
322
+ if (value) {
323
+ this.element.removeAttr('tabIndex')
324
+ this._input.attr('disabled', 'disabled')
325
+ }
326
+ else {
327
+ this.element.attr('tabIndex', 0)
328
+ this._input.removeAttr('disabled')
329
+ }
330
+ break
331
+
332
+ case 'decimals':
333
+ this._input.val(this._curVal.toFixed(this.options.decimals))
334
+ break
335
+
336
+ case 'min':
337
+ if (this._curVal < this.options.min) {
338
+ this._setValue(this.options.min)
339
+ }
340
+ break
341
+
342
+ case 'max':
343
+ if (this._curVal > this.options.max) {
344
+ this._setValue(this.options.max)
345
+ }
346
+ break
347
+
348
+ }
349
+ }
350
+
351
+ })
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @namespace qui.widgets
3
+ */
4
+
5
+ import $ from '$qui/lib/jquery.module.js'
6
+
7
+ import StockIcon from '$qui/icons/stock-icon.js'
8
+ import * as Window from '$qui/window.js'
9
+
10
+ import './common-widgets/common-widgets.js' /* Needed so that jQueryUI-based widgets are not left out of the bundle */
11
+
12
+
13
+ function initButtons() {
14
+ /* Toggle "active" class when pressed/released */
15
+ Window.$document.on('pointerdown pointerup pointercancel pointerleave', '.qui-base-button', function (e) {
16
+
17
+ let active = e.type === 'pointerdown'
18
+ let $this = $(this)
19
+
20
+ if (!$this.hasClass('active') && active) {
21
+ $this.addClass('active')
22
+ $this.trigger('pressed')
23
+ }
24
+ else if ($this.hasClass('active') && !active) {
25
+ $this.removeClass('active')
26
+ $this.trigger('released')
27
+ }
28
+
29
+ })
30
+ }
31
+
32
+ /**
33
+ * Create a caption made of an icon and a text.
34
+ * @alias qui.widgets.makeIconTextCaption
35
+ * @param {qui.icons.Icon} icon
36
+ * @param {String} text
37
+ * @returns {jQuery}
38
+ */
39
+ export function makeIconTextCaption(icon, text) {
40
+ let containerDiv = $('<div></div>', {class: 'qui-icon-text-caption-container'})
41
+ let iconDiv = $('<div></div>', {class: 'qui-icon-text-caption-icon'})
42
+ let textSpan = $('<span></span>', {class: 'qui-icon-text-caption-text'})
43
+
44
+ if (icon instanceof StockIcon) {
45
+ icon = icon.alterDefault({variant: 'white', scale: 0.75})
46
+ }
47
+
48
+ containerDiv.append(iconDiv).append(textSpan)
49
+ icon.applyTo(iconDiv)
50
+ textSpan.text(text)
51
+
52
+ return containerDiv
53
+ }
54
+
55
+ export function init() {
56
+ initButtons()
57
+ }