jedison 1.15.0 → 1.16.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/CHANGELOG.md +8 -0
- package/dist/cjs/jedison.cjs +1 -1
- package/dist/cjs/jedison.cjs.map +1 -1
- package/dist/esm/jedison.js +344 -82
- package/dist/esm/jedison.js.map +1 -1
- package/dist/umd/jedison.umd.js +1 -1
- package/dist/umd/jedison.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/esm/jedison.js
CHANGED
|
@@ -116,6 +116,36 @@ function getType(value) {
|
|
|
116
116
|
}
|
|
117
117
|
return type2;
|
|
118
118
|
}
|
|
119
|
+
const DEFAULT_ATTRIBUTE_ALLOWLIST = [
|
|
120
|
+
"id",
|
|
121
|
+
"class",
|
|
122
|
+
"title",
|
|
123
|
+
"name",
|
|
124
|
+
"value",
|
|
125
|
+
"disabled",
|
|
126
|
+
"always-enabled",
|
|
127
|
+
"always-disabled"
|
|
128
|
+
];
|
|
129
|
+
const DEFAULT_ATTRIBUTE_ALLOWED_PREFIXES = ["aria-", "data-"];
|
|
130
|
+
function filterAttributes(attributes, options = {}) {
|
|
131
|
+
const {
|
|
132
|
+
allowlist = DEFAULT_ATTRIBUTE_ALLOWLIST,
|
|
133
|
+
allowedPrefixes = DEFAULT_ATTRIBUTE_ALLOWED_PREFIXES
|
|
134
|
+
} = options;
|
|
135
|
+
const result = {};
|
|
136
|
+
if (!isObject(attributes)) {
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
const allowed = new Set(allowlist.map((name) => name.toLowerCase()));
|
|
140
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
141
|
+
const normalizedKey = key.trim().toLowerCase();
|
|
142
|
+
const isAllowed = allowed.has(normalizedKey) || allowedPrefixes.some((prefix) => normalizedKey.startsWith(prefix));
|
|
143
|
+
if (isAllowed) {
|
|
144
|
+
result[key] = value;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
119
149
|
const UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
120
150
|
function mergeDeep(target, ...sources) {
|
|
121
151
|
if (!sources.length) return target;
|
|
@@ -148,14 +178,14 @@ function combineDeep(target, ...sources) {
|
|
|
148
178
|
Object.keys(source).forEach((key) => {
|
|
149
179
|
if (UNSAFE_KEYS.has(key)) return;
|
|
150
180
|
if (isObject(source[key])) {
|
|
151
|
-
if (!target[key]) {
|
|
181
|
+
if (!isObject(target[key])) {
|
|
152
182
|
Object.assign(target, {
|
|
153
183
|
[key]: {}
|
|
154
184
|
});
|
|
155
185
|
}
|
|
156
186
|
combineDeep(target[key], source[key]);
|
|
157
187
|
} else if (Array.isArray(source[key])) {
|
|
158
|
-
if (!target[key]) {
|
|
188
|
+
if (!Array.isArray(target[key])) {
|
|
159
189
|
target[key] = [];
|
|
160
190
|
}
|
|
161
191
|
target[key].push(...source[key]);
|
|
@@ -430,6 +460,10 @@ function getSchemaXOption(schema, option) {
|
|
|
430
460
|
if (schema["x-options"] && isSet(schema["x-options"][option])) {
|
|
431
461
|
return schema["x-options"][option];
|
|
432
462
|
}
|
|
463
|
+
if (option === "switcherInput" && schema["x-embedSwitcher"] === true) {
|
|
464
|
+
console.warn(`Jedison: schema option "x-embedSwitcher" is deprecated. Use "x-switcherInput: 'select-inline'" instead.`);
|
|
465
|
+
return "select-inline";
|
|
466
|
+
}
|
|
433
467
|
for (const alias of getAliasesFor(option)) {
|
|
434
468
|
const xAlias = "x-" + alias;
|
|
435
469
|
if (isSet(schema[xAlias])) {
|
|
@@ -1778,8 +1812,28 @@ class EventEmitter {
|
|
|
1778
1812
|
}
|
|
1779
1813
|
callbacks.push(callback);
|
|
1780
1814
|
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1815
|
+
/**
|
|
1816
|
+
* Removes event listeners for a named event.
|
|
1817
|
+
* @public
|
|
1818
|
+
* @param {string} name - The name of the event
|
|
1819
|
+
* @param {function} [callback] - When given, only this specific callback is
|
|
1820
|
+
* removed; when omitted, all listeners for the event are removed.
|
|
1821
|
+
*/
|
|
1822
|
+
off(name, callback) {
|
|
1823
|
+
if (typeof callback !== "function") {
|
|
1824
|
+
this.listeners.delete(name);
|
|
1825
|
+
return;
|
|
1826
|
+
}
|
|
1827
|
+
const callbacks = this.listeners.get(name);
|
|
1828
|
+
if (!callbacks) {
|
|
1829
|
+
return;
|
|
1830
|
+
}
|
|
1831
|
+
const remaining = callbacks.filter((cb) => cb !== callback);
|
|
1832
|
+
if (remaining.length === 0) {
|
|
1833
|
+
this.listeners.delete(name);
|
|
1834
|
+
} else {
|
|
1835
|
+
this.listeners.set(name, remaining);
|
|
1836
|
+
}
|
|
1783
1837
|
}
|
|
1784
1838
|
/**
|
|
1785
1839
|
* Triggers the callback function of a named event listener
|
|
@@ -2145,6 +2199,7 @@ class Editor {
|
|
|
2145
2199
|
this.addEventListeners();
|
|
2146
2200
|
this.setVisibility();
|
|
2147
2201
|
this.setContainerAttributes();
|
|
2202
|
+
this.appendSchemaButtons();
|
|
2148
2203
|
this.refreshUI();
|
|
2149
2204
|
const alwaysShowErrors = this.instance.jedison.getOption("showErrors") === "always" || getSchemaXOption(this.instance.schema, "showErrors") === "always";
|
|
2150
2205
|
if (alwaysShowErrors) {
|
|
@@ -2158,6 +2213,14 @@ class Editor {
|
|
|
2158
2213
|
}
|
|
2159
2214
|
static resolves(schema) {
|
|
2160
2215
|
}
|
|
2216
|
+
/**
|
|
2217
|
+
* Whether this editor already renders a heading for each of its children
|
|
2218
|
+
* (e.g. an accordion toggle or a nav tab label), so a child editor can
|
|
2219
|
+
* skip drawing its own duplicate heading/panel when embedded here.
|
|
2220
|
+
*/
|
|
2221
|
+
static providesChildHeading() {
|
|
2222
|
+
return false;
|
|
2223
|
+
}
|
|
2161
2224
|
/**
|
|
2162
2225
|
* Initializes the editor
|
|
2163
2226
|
*/
|
|
@@ -2200,6 +2263,62 @@ class Editor {
|
|
|
2200
2263
|
}
|
|
2201
2264
|
}
|
|
2202
2265
|
}
|
|
2266
|
+
/**
|
|
2267
|
+
* Renders schema-defined action buttons (the `x-buttons` keyword) into the
|
|
2268
|
+
* editor container. Works for every editor because it lives on the base
|
|
2269
|
+
* class, next to setAttributes()/setContainerAttributes(). Both `x-buttons`
|
|
2270
|
+
* and `x-options.buttons` spellings resolve through getSchemaXOption().
|
|
2271
|
+
*
|
|
2272
|
+
* Security decisions from issue #62:
|
|
2273
|
+
* - The label is HTML sanitized through the existing DOMPurify pipeline
|
|
2274
|
+
* (purifyContent(), decision 9c / F6) before being handed to the theme.
|
|
2275
|
+
* - The `attributes` bag is filtered against an allowlist (filterAttributes(),
|
|
2276
|
+
* decision 6a / F1); `always-enabled` / `always-disabled` are intentionally
|
|
2277
|
+
* allowed (decision 6b, trusted-schema stance).
|
|
2278
|
+
* - Each button emits a `jedison:<name>` event on the root Jedison instance
|
|
2279
|
+
* through the internal EventEmitter (decision 1c / 2), carrying a live
|
|
2280
|
+
* payload `{ jedison, editor, path }` (decision 8). Consumers subscribe with
|
|
2281
|
+
* `jedison.on('jedison:<name>', ({ jedison, editor, path }) => ...)`. The
|
|
2282
|
+
* listener map is private to the instance, so the payload is not exposed to
|
|
2283
|
+
* unrelated scripts on the page (F3 contained).
|
|
2284
|
+
* - Click listeners are registered through storedEventListeners so destroy()
|
|
2285
|
+
* cleans them up.
|
|
2286
|
+
*/
|
|
2287
|
+
appendSchemaButtons() {
|
|
2288
|
+
const buttons = getSchemaXOption(this.instance.schema, "buttons");
|
|
2289
|
+
if (!isArray(buttons)) {
|
|
2290
|
+
return;
|
|
2291
|
+
}
|
|
2292
|
+
const domPurifyOptions = this.instance.jedison.getOption("domPurifyOptions");
|
|
2293
|
+
buttons.forEach((config) => {
|
|
2294
|
+
if (!isObject(config)) {
|
|
2295
|
+
return;
|
|
2296
|
+
}
|
|
2297
|
+
const rawLabel = isString(config.label) ? config.label : "";
|
|
2298
|
+
const label = this.purifyEnabled ? this.purifyContent(rawLabel, domPurifyOptions) : rawLabel;
|
|
2299
|
+
const attributes = filterAttributes(config.attributes);
|
|
2300
|
+
const button = this.theme.getXButton({ label, attributes });
|
|
2301
|
+
this.control.container.appendChild(button);
|
|
2302
|
+
const eventName = isObject(config.event) && isString(config.event.name) ? config.event.name : null;
|
|
2303
|
+
if (!eventName) {
|
|
2304
|
+
return;
|
|
2305
|
+
}
|
|
2306
|
+
const handler = () => {
|
|
2307
|
+
const jedison = this.instance.jedison;
|
|
2308
|
+
jedison.emit("jedison:" + eventName, {
|
|
2309
|
+
jedison,
|
|
2310
|
+
editor: this,
|
|
2311
|
+
path: this.instance.path
|
|
2312
|
+
});
|
|
2313
|
+
};
|
|
2314
|
+
button.addEventListener("click", handler);
|
|
2315
|
+
this.storedEventListeners.push({
|
|
2316
|
+
element: button,
|
|
2317
|
+
eventType: "click",
|
|
2318
|
+
handler
|
|
2319
|
+
});
|
|
2320
|
+
});
|
|
2321
|
+
}
|
|
2203
2322
|
/**
|
|
2204
2323
|
* Builds the editor control and appends it to the editor container
|
|
2205
2324
|
*/
|
|
@@ -2508,6 +2627,7 @@ class EditorIfThenElse extends Editor {
|
|
|
2508
2627
|
this.refreshDisabledState();
|
|
2509
2628
|
this.control.childrenSlot.innerHTML = "";
|
|
2510
2629
|
this.control.childrenSlot.appendChild(this.instance.activeInstance.ui.control.container);
|
|
2630
|
+
this.control.switcherSlot = this.instance.activeInstance.ui.control.switcherSlot;
|
|
2511
2631
|
if (this.disabled || this.instance.isReadOnly()) {
|
|
2512
2632
|
this.instance.activeInstance.ui.disable();
|
|
2513
2633
|
} else {
|
|
@@ -4131,7 +4251,7 @@ class EditorObject extends Editor {
|
|
|
4131
4251
|
return {
|
|
4132
4252
|
title: this.getTitle(),
|
|
4133
4253
|
description: this.getDescription(),
|
|
4134
|
-
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
|
|
4254
|
+
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden") ?? this.isEmbeddedInParentChrome(),
|
|
4135
4255
|
id: this.getIdFromPath(this.instance.path),
|
|
4136
4256
|
enablePropertiesToggle,
|
|
4137
4257
|
addProperty,
|
|
@@ -4147,9 +4267,20 @@ class EditorObject extends Editor {
|
|
|
4147
4267
|
titleIconClass: getSchemaXOption(this.instance.schema, "titleIconClass")
|
|
4148
4268
|
};
|
|
4149
4269
|
}
|
|
4270
|
+
isEmbeddedInParentChrome() {
|
|
4271
|
+
var _a;
|
|
4272
|
+
const autoFlat = getSchemaXOption(this.instance.schema, "autoFlat") ?? this.instance.jedison.getOption("autoFlat");
|
|
4273
|
+
if (!autoFlat) return false;
|
|
4274
|
+
const parentInstance = this.instance.parent;
|
|
4275
|
+
if (!parentInstance) return false;
|
|
4276
|
+
const ParentEditorClass = this.instance.jedison.uiResolver.getClass(parentInstance.schema);
|
|
4277
|
+
return !!((_a = ParentEditorClass == null ? void 0 : ParentEditorClass.providesChildHeading) == null ? void 0 : _a.call(ParentEditorClass));
|
|
4278
|
+
}
|
|
4150
4279
|
build() {
|
|
4151
4280
|
this.propertyActivators = {};
|
|
4152
|
-
const
|
|
4281
|
+
const explicitCard = getSchemaXOption(this.instance.schema, "card");
|
|
4282
|
+
const globalCard = this.instance.jedison.getOption("card");
|
|
4283
|
+
const card = explicitCard ?? (this.isEmbeddedInParentChrome() ? false : globalCard);
|
|
4153
4284
|
const config = this.getObjectControlConfig();
|
|
4154
4285
|
this.control = card === false ? this.theme.getObjectControlFlat(config) : this.theme.getObjectControl(config);
|
|
4155
4286
|
this.control.jsonData.input.value = JSON.stringify(this.instance.getValue(), null, 2);
|
|
@@ -4400,6 +4531,7 @@ class EditorObjectCategories extends EditorObject {
|
|
|
4400
4531
|
init() {
|
|
4401
4532
|
super.init();
|
|
4402
4533
|
this.activeCategoryName = null;
|
|
4534
|
+
this.userSelectedCategory = false;
|
|
4403
4535
|
}
|
|
4404
4536
|
navigateTo(path) {
|
|
4405
4537
|
const nextChildPath = this.getNextChildPath(path);
|
|
@@ -4419,6 +4551,7 @@ class EditorObjectCategories extends EditorObject {
|
|
|
4419
4551
|
categoryName = defaultLabel;
|
|
4420
4552
|
}
|
|
4421
4553
|
this.activeCategoryName = categoryName;
|
|
4554
|
+
this.userSelectedCategory = true;
|
|
4422
4555
|
this.refreshUI();
|
|
4423
4556
|
}
|
|
4424
4557
|
}
|
|
@@ -4469,9 +4602,6 @@ class EditorObjectCategories extends EditorObject {
|
|
|
4469
4602
|
}
|
|
4470
4603
|
categoriesMap.get(categoryName).children.push(child);
|
|
4471
4604
|
});
|
|
4472
|
-
if (!categoriesMap.has(this.activeCategoryName)) {
|
|
4473
|
-
this.activeCategoryName = categoriesMap.keys().next().value;
|
|
4474
|
-
}
|
|
4475
4605
|
const categoryOrder = getSchemaXOption(this.instance.schema, "categoryOrder");
|
|
4476
4606
|
const allNames = Array.from(categoriesMap.keys());
|
|
4477
4607
|
let orderedCategoryNames = allNames;
|
|
@@ -4480,6 +4610,9 @@ class EditorObjectCategories extends EditorObject {
|
|
|
4480
4610
|
const unspecified = allNames.filter((name) => !categoryOrder.includes(name));
|
|
4481
4611
|
orderedCategoryNames = [...specifiedFirst, ...unspecified];
|
|
4482
4612
|
}
|
|
4613
|
+
if (!this.userSelectedCategory || !categoriesMap.has(this.activeCategoryName)) {
|
|
4614
|
+
this.activeCategoryName = orderedCategoryNames[0];
|
|
4615
|
+
}
|
|
4483
4616
|
orderedCategoryNames.forEach((categoryName) => {
|
|
4484
4617
|
const category = categoriesMap.get(categoryName);
|
|
4485
4618
|
const active = categoryName === this.activeCategoryName;
|
|
@@ -4494,6 +4627,7 @@ class EditorObjectCategories extends EditorObject {
|
|
|
4494
4627
|
});
|
|
4495
4628
|
tab.list.addEventListener("click", () => {
|
|
4496
4629
|
this.activeCategoryName = categoryName;
|
|
4630
|
+
this.userSelectedCategory = true;
|
|
4497
4631
|
});
|
|
4498
4632
|
const pane = document.createElement("div");
|
|
4499
4633
|
this.theme.setTabPaneAttributes(pane, active, id);
|
|
@@ -4517,6 +4651,9 @@ class EditorObjectNav extends EditorObject {
|
|
|
4517
4651
|
const hasNavFormat = regex.test(format2);
|
|
4518
4652
|
return getSchemaType(schema) === "object" && hasNavFormat;
|
|
4519
4653
|
}
|
|
4654
|
+
static providesChildHeading() {
|
|
4655
|
+
return true;
|
|
4656
|
+
}
|
|
4520
4657
|
init() {
|
|
4521
4658
|
super.init();
|
|
4522
4659
|
this.activeTabIndex = 0;
|
|
@@ -4603,11 +4740,35 @@ class EditorObjectAccordion extends EditorObject {
|
|
|
4603
4740
|
static resolves(schema) {
|
|
4604
4741
|
return getSchemaType(schema) === "object" && getSchemaXOption(schema, "format") === "accordion";
|
|
4605
4742
|
}
|
|
4743
|
+
static providesChildHeading() {
|
|
4744
|
+
return true;
|
|
4745
|
+
}
|
|
4606
4746
|
getObjectControlConfig() {
|
|
4607
4747
|
return { ...super.getObjectControlConfig(), isAccordionProperties: true };
|
|
4608
4748
|
}
|
|
4749
|
+
refreshAccordionWarnings() {
|
|
4750
|
+
if (!this.accordionToggles) return;
|
|
4751
|
+
const navWarning = getSchemaXOption(this.instance.schema, "navWarning") ?? true;
|
|
4752
|
+
const navWarningMessage = getSchemaXOption(this.instance.schema, "navWarningMessage");
|
|
4753
|
+
this.instance.children.forEach((child) => {
|
|
4754
|
+
if (!child.isActive) return;
|
|
4755
|
+
const toggle = this.accordionToggles[child.getKey()];
|
|
4756
|
+
if (!toggle) return;
|
|
4757
|
+
const existing = toggle.querySelector(".jedi-legend-warning");
|
|
4758
|
+
if (existing) existing.parentNode.removeChild(existing);
|
|
4759
|
+
if (navWarning && child.hasNestedValidationErrors()) {
|
|
4760
|
+
const warning = document.createElement("span");
|
|
4761
|
+
warning.classList.add("jedi-legend-warning");
|
|
4762
|
+
warning.textContent = "⚠";
|
|
4763
|
+
if (navWarningMessage) warning.setAttribute("title", navWarningMessage);
|
|
4764
|
+
this.theme.styleLegendWarning(warning);
|
|
4765
|
+
toggle.appendChild(warning);
|
|
4766
|
+
}
|
|
4767
|
+
});
|
|
4768
|
+
}
|
|
4609
4769
|
refreshEditors() {
|
|
4610
4770
|
this.control.childrenSlot.replaceChildren();
|
|
4771
|
+
this.accordionToggles = {};
|
|
4611
4772
|
const accordionId = this.control.childrenSlot.id;
|
|
4612
4773
|
this.instance.children.forEach((child) => {
|
|
4613
4774
|
if (!child.isActive) return;
|
|
@@ -4617,12 +4778,18 @@ class EditorObjectAccordion extends EditorObject {
|
|
|
4617
4778
|
const accordionItem = this.theme.getAccordionItem({ title, id, accordionId });
|
|
4618
4779
|
accordionItem.body.appendChild(child.ui.control.container);
|
|
4619
4780
|
this.control.childrenSlot.appendChild(accordionItem.container);
|
|
4781
|
+
this.accordionToggles[child.getKey()] = accordionItem.toggle;
|
|
4620
4782
|
if (this.disabled || this.instance.isReadOnly()) {
|
|
4621
4783
|
child.ui.disable();
|
|
4622
4784
|
} else {
|
|
4623
4785
|
child.ui.enable();
|
|
4624
4786
|
}
|
|
4625
4787
|
});
|
|
4788
|
+
this.refreshAccordionWarnings();
|
|
4789
|
+
}
|
|
4790
|
+
showValidationErrors(errors, force = false) {
|
|
4791
|
+
super.showValidationErrors(errors, force);
|
|
4792
|
+
this.refreshAccordionWarnings();
|
|
4626
4793
|
}
|
|
4627
4794
|
}
|
|
4628
4795
|
class EditorObjectHorizontal extends EditorObject {
|
|
@@ -5443,6 +5610,9 @@ class EditorArrayNav extends EditorArray {
|
|
|
5443
5610
|
const hasNavFormat = regex.test(format2);
|
|
5444
5611
|
return getSchemaType(schema) === "array" && hasNavFormat;
|
|
5445
5612
|
}
|
|
5613
|
+
static providesChildHeading() {
|
|
5614
|
+
return true;
|
|
5615
|
+
}
|
|
5446
5616
|
navigateTo(path) {
|
|
5447
5617
|
const nextChildPath = this.getNextChildPath(path);
|
|
5448
5618
|
if (nextChildPath) {
|
|
@@ -5597,7 +5767,7 @@ class EditorMultiple extends Editor {
|
|
|
5597
5767
|
}
|
|
5598
5768
|
build() {
|
|
5599
5769
|
this.switcherInput = getSchemaXOption(this.instance.schema, "switcherInput") ?? this.instance.jedison.getOption("switcherInput");
|
|
5600
|
-
this.embedSwitcher =
|
|
5770
|
+
this.embedSwitcher = this.instance.jedison.getOption("embedSwitcher");
|
|
5601
5771
|
this.control = this.theme.getMultipleControl({
|
|
5602
5772
|
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
|
|
5603
5773
|
id: this.getIdFromPath(this.instance.path),
|
|
@@ -5609,6 +5779,7 @@ class EditorMultiple extends Editor {
|
|
|
5609
5779
|
if (this.embedSwitcher) {
|
|
5610
5780
|
this.control.header.style.display = "none";
|
|
5611
5781
|
}
|
|
5782
|
+
this.switcherWrapper = this.theme.getSwitcherOwner();
|
|
5612
5783
|
this.instance.on("change", (initiator) => {
|
|
5613
5784
|
if (initiator === "api") return;
|
|
5614
5785
|
const jedison = this.instance.jedison;
|
|
@@ -5663,35 +5834,22 @@ class EditorMultiple extends Editor {
|
|
|
5663
5834
|
}
|
|
5664
5835
|
}
|
|
5665
5836
|
refreshUI() {
|
|
5666
|
-
var _a;
|
|
5667
5837
|
this.refreshDisabledState();
|
|
5668
5838
|
this.control.childrenSlot.innerHTML = "";
|
|
5669
5839
|
this.control.childrenSlot.appendChild(this.instance.activeInstance.ui.control.container);
|
|
5670
|
-
|
|
5671
|
-
|
|
5840
|
+
const slot = this.instance.activeInstance.ui.control.switcherSlot;
|
|
5841
|
+
this.control.switcherSlot = slot;
|
|
5842
|
+
if (this.embedSwitcher || this.switcherInput === "modal" || this.switcherInput === "select-inline") {
|
|
5672
5843
|
if (slot) {
|
|
5673
|
-
|
|
5674
|
-
|
|
5844
|
+
this.switcherWrapper.innerHTML = "";
|
|
5845
|
+
this.switcherWrapper.appendChild(this.control.switcher.container);
|
|
5846
|
+
this.insertBySwitcherDepth(slot, this.switcherWrapper, this.getNestedSwitcherDepth(this.instance.activeInstance));
|
|
5675
5847
|
this.control.header.style.display = "none";
|
|
5676
5848
|
} else {
|
|
5677
5849
|
this.control.header.style.display = "";
|
|
5678
5850
|
this.control.header.appendChild(this.control.switcher.container);
|
|
5679
5851
|
}
|
|
5680
5852
|
}
|
|
5681
|
-
if (this.switcherInput === "modal" || this.switcherInput === "select-inline") {
|
|
5682
|
-
const childControl = this.instance.activeInstance.ui.control;
|
|
5683
|
-
const infoContainer = childControl.infoContainer;
|
|
5684
|
-
const titleEl = childControl.legendText || childControl.label;
|
|
5685
|
-
if (infoContainer) {
|
|
5686
|
-
infoContainer.after(this.control.switcher.container);
|
|
5687
|
-
this.control.header.style.display = "none";
|
|
5688
|
-
} else if (titleEl) {
|
|
5689
|
-
const infoEl = (_a = childControl.info) == null ? void 0 : _a.container;
|
|
5690
|
-
const anchor = infoEl && infoEl.parentNode ? infoEl : titleEl;
|
|
5691
|
-
anchor.after(this.control.switcher.container);
|
|
5692
|
-
this.control.header.style.display = "none";
|
|
5693
|
-
}
|
|
5694
|
-
}
|
|
5695
5853
|
if (this.switcherInput === "select") {
|
|
5696
5854
|
this.control.switcher.input.value = this.instance.index;
|
|
5697
5855
|
}
|
|
@@ -5719,6 +5877,23 @@ class EditorMultiple extends Editor {
|
|
|
5719
5877
|
getErrorFeedback(config) {
|
|
5720
5878
|
return this.theme.getAlert(config);
|
|
5721
5879
|
}
|
|
5880
|
+
// Counts how many EditorMultiple owners sit between `instance` and the real
|
|
5881
|
+
// leaf control, so stacked switchers in a shared slot can be ordered
|
|
5882
|
+
// outer-first instead of shuffling with every refresh.
|
|
5883
|
+
getNestedSwitcherDepth(instance) {
|
|
5884
|
+
if (!instance || !instance.activeInstance) return 0;
|
|
5885
|
+
const childDepth = this.getNestedSwitcherDepth(instance.activeInstance);
|
|
5886
|
+
return instance.ui.switcherWrapper ? childDepth + 1 : childDepth;
|
|
5887
|
+
}
|
|
5888
|
+
insertBySwitcherDepth(slot, wrapper, depth) {
|
|
5889
|
+
wrapper.dataset.switcherDepth = depth;
|
|
5890
|
+
const sibling = Array.from(slot.children).find((child) => Number(child.dataset.switcherDepth) < depth);
|
|
5891
|
+
if (sibling) {
|
|
5892
|
+
slot.insertBefore(wrapper, sibling);
|
|
5893
|
+
} else {
|
|
5894
|
+
slot.appendChild(wrapper);
|
|
5895
|
+
}
|
|
5896
|
+
}
|
|
5722
5897
|
}
|
|
5723
5898
|
class EditorNull extends Editor {
|
|
5724
5899
|
static resolves(schema) {
|
|
@@ -6302,37 +6477,24 @@ class EditorArrayCheckboxes extends Editor {
|
|
|
6302
6477
|
const values = this.getEnumSourceValues();
|
|
6303
6478
|
const schemaItems = this.instance.schema.items || {};
|
|
6304
6479
|
const titles = getSchemaXOption(schemaItems, "enumTitles") || values;
|
|
6305
|
-
const id = this.getIdFromPath(this.instance.path);
|
|
6306
|
-
const messagesId = id + "-messages";
|
|
6307
|
-
const descriptionId = id + "-description";
|
|
6308
|
-
const describedBy = messagesId + " " + descriptionId;
|
|
6309
6480
|
this.control.checkboxControls.forEach((cc) => {
|
|
6310
6481
|
if (cc.parentNode) cc.parentNode.removeChild(cc);
|
|
6311
6482
|
});
|
|
6312
|
-
this.
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
label.setAttribute("for", checkboxId);
|
|
6328
|
-
labelText.textContent = titles && titles[index2] !== void 0 ? titles[index2] : value;
|
|
6329
|
-
checkboxControl.appendChild(checkbox);
|
|
6330
|
-
checkboxControl.appendChild(label);
|
|
6331
|
-
label.appendChild(labelText);
|
|
6332
|
-
this.control.checkboxes.push(checkbox);
|
|
6333
|
-
this.control.labels.push(label);
|
|
6334
|
-
this.control.labelTexts.push(labelText);
|
|
6335
|
-
this.control.checkboxControls.push(checkboxControl);
|
|
6483
|
+
const rebuilt = this.theme.getCheckboxesControl({
|
|
6484
|
+
title: this.getTitle(),
|
|
6485
|
+
description: this.getDescription(),
|
|
6486
|
+
values,
|
|
6487
|
+
titles,
|
|
6488
|
+
id: this.getIdFromPath(this.instance.path),
|
|
6489
|
+
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
|
|
6490
|
+
inline: getSchemaXOption(this.instance.schema, "format") === "checkboxes-inline",
|
|
6491
|
+
info: this.getInfo()
|
|
6492
|
+
});
|
|
6493
|
+
this.control.checkboxes = rebuilt.checkboxes;
|
|
6494
|
+
this.control.labels = rebuilt.labels;
|
|
6495
|
+
this.control.labelTexts = rebuilt.labelTexts;
|
|
6496
|
+
this.control.checkboxControls = rebuilt.checkboxControls;
|
|
6497
|
+
this.control.checkboxControls.forEach((checkboxControl) => {
|
|
6336
6498
|
this.control.fieldset.insertBefore(checkboxControl, this.control.description);
|
|
6337
6499
|
});
|
|
6338
6500
|
this.addDragHandles();
|
|
@@ -6982,6 +7144,7 @@ class Jedison extends EventEmitter {
|
|
|
6982
7144
|
editJsonData: false,
|
|
6983
7145
|
enablePropertiesToggle: false,
|
|
6984
7146
|
enableCollapseToggle: false,
|
|
7147
|
+
autoFlat: false,
|
|
6985
7148
|
btnContents: true,
|
|
6986
7149
|
btnIcons: true,
|
|
6987
7150
|
arrayDelete: true,
|
|
@@ -7307,6 +7470,20 @@ class Jedison extends EventEmitter {
|
|
|
7307
7470
|
}
|
|
7308
7471
|
});
|
|
7309
7472
|
}
|
|
7473
|
+
if (this.isEditor) {
|
|
7474
|
+
const schemaTypeArray = getSchemaType(config.schema);
|
|
7475
|
+
if (isArray(schemaTypeArray)) {
|
|
7476
|
+
const inferTypeSource = getSchemaXOption(config.schema, "inferType");
|
|
7477
|
+
if (isSet(inferTypeSource)) {
|
|
7478
|
+
const siblingPath = resolveInstancePath(config.path, inferTypeSource);
|
|
7479
|
+
const siblingInstance = this.getInstance(siblingPath);
|
|
7480
|
+
const siblingValue = siblingInstance ? siblingInstance.getValue() : void 0;
|
|
7481
|
+
if (isSet(siblingValue) && schemaTypeArray.includes(siblingValue)) {
|
|
7482
|
+
config.schema = { ...config.schema, type: siblingValue };
|
|
7483
|
+
}
|
|
7484
|
+
}
|
|
7485
|
+
}
|
|
7486
|
+
}
|
|
7310
7487
|
const schemaOneOf = getSchemaOneOf(config.schema);
|
|
7311
7488
|
const schemaAnyOf = getSchemaAnyOf(config.schema);
|
|
7312
7489
|
const schemaIf = getSchemaIf(config.schema);
|
|
@@ -7886,6 +8063,25 @@ class Theme {
|
|
|
7886
8063
|
html.classList.add("jedi-children-slot");
|
|
7887
8064
|
return html;
|
|
7888
8065
|
}
|
|
8066
|
+
/**
|
|
8067
|
+
* Wrapper used by EditorMultiple to embed an inline switcher next to a control's title
|
|
8068
|
+
*/
|
|
8069
|
+
getSwitcherSlot() {
|
|
8070
|
+
const html = document.createElement("span");
|
|
8071
|
+
html.classList.add("jedi-switcher-slot");
|
|
8072
|
+
return html;
|
|
8073
|
+
}
|
|
8074
|
+
/**
|
|
8075
|
+
* Per-owner wrapper inside a switcherSlot — lets more than one EditorMultiple
|
|
8076
|
+
* embed a switcher into the same slot (e.g. nested anyOf/oneOf) without one
|
|
8077
|
+
* overwriting the other.
|
|
8078
|
+
*/
|
|
8079
|
+
getSwitcherOwner() {
|
|
8080
|
+
const html = document.createElement("span");
|
|
8081
|
+
html.classList.add("jedi-switcher-owner");
|
|
8082
|
+
html.style.marginInlineStart = "0.25rem";
|
|
8083
|
+
return html;
|
|
8084
|
+
}
|
|
7889
8085
|
/**
|
|
7890
8086
|
* Wrapper for error messages
|
|
7891
8087
|
*/
|
|
@@ -8150,6 +8346,42 @@ class Theme {
|
|
|
8150
8346
|
button.appendChild(text);
|
|
8151
8347
|
return button;
|
|
8152
8348
|
}
|
|
8349
|
+
/**
|
|
8350
|
+
* A schema-defined action button (x-buttons keyword).
|
|
8351
|
+
*
|
|
8352
|
+
* This method only renders: the label is expected to be already sanitized by
|
|
8353
|
+
* the editor (Editor.purifyContent(), decision 9c) and the attributes are
|
|
8354
|
+
* expected to be already filtered against the allowlist by the editor
|
|
8355
|
+
* (utils.filterAttributes(), decision 6a). The theme does not sanitize or
|
|
8356
|
+
* filter. No theme styling is applied, only the unstyled `jedi-x-button` hook
|
|
8357
|
+
* class (decision 4).
|
|
8358
|
+
* @param {object} config - Button config
|
|
8359
|
+
* @param {string} [config.label] - Pre-sanitized HTML label
|
|
8360
|
+
* @param {object} [config.attributes] - Pre-filtered HTML attributes
|
|
8361
|
+
* @return {HTMLButtonElement}
|
|
8362
|
+
*/
|
|
8363
|
+
getXButton(config = {}) {
|
|
8364
|
+
const button = document.createElement("button");
|
|
8365
|
+
const label = document.createElement("span");
|
|
8366
|
+
button.classList.add("jedi-x-button");
|
|
8367
|
+
button.setAttribute("type", "button");
|
|
8368
|
+
label.classList.add("jedi-x-button-label");
|
|
8369
|
+
label.innerHTML = config.label ?? "";
|
|
8370
|
+
button.appendChild(label);
|
|
8371
|
+
const attributes = isObject(config.attributes) ? config.attributes : {};
|
|
8372
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
8373
|
+
if (key === "class") {
|
|
8374
|
+
String(value).split(" ").forEach((cls) => {
|
|
8375
|
+
if (cls) {
|
|
8376
|
+
button.classList.add(cls);
|
|
8377
|
+
}
|
|
8378
|
+
});
|
|
8379
|
+
} else {
|
|
8380
|
+
button.setAttribute(key, value);
|
|
8381
|
+
}
|
|
8382
|
+
}
|
|
8383
|
+
return button;
|
|
8384
|
+
}
|
|
8153
8385
|
getAddPropertyButton(config) {
|
|
8154
8386
|
const html = this.getButton(config);
|
|
8155
8387
|
html.classList.add("jedi-add-property-btn");
|
|
@@ -8345,6 +8577,7 @@ class Theme {
|
|
|
8345
8577
|
const messages = this.getMessagesSlot({
|
|
8346
8578
|
id: messagesId
|
|
8347
8579
|
});
|
|
8580
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
8348
8581
|
if (((_a = config == null ? void 0 : config.info) == null ? void 0 : _a.variant) === "modal") {
|
|
8349
8582
|
this.infoAsModal(info, config.id, config.info);
|
|
8350
8583
|
}
|
|
@@ -8352,11 +8585,12 @@ class Theme {
|
|
|
8352
8585
|
if (isObject(config.info)) {
|
|
8353
8586
|
container.appendChild(info.container);
|
|
8354
8587
|
}
|
|
8588
|
+
container.appendChild(switcherSlot);
|
|
8355
8589
|
container.appendChild(placeholder);
|
|
8356
8590
|
container.appendChild(description);
|
|
8357
8591
|
container.appendChild(messages);
|
|
8358
8592
|
container.appendChild(actions);
|
|
8359
|
-
return { container, placeholder, label, info, labelText, description, messages, actions };
|
|
8593
|
+
return { container, placeholder, label, info, labelText, description, messages, actions, switcherSlot };
|
|
8360
8594
|
}
|
|
8361
8595
|
/**
|
|
8362
8596
|
* Object control is a card containing multiple editors.
|
|
@@ -8422,7 +8656,7 @@ class Theme {
|
|
|
8422
8656
|
propertiesContainer: quickAddPropertyContainer
|
|
8423
8657
|
});
|
|
8424
8658
|
const fieldset = this.getFieldset();
|
|
8425
|
-
const { legend, infoContainer, legendText, right } = this.getLegend({
|
|
8659
|
+
const { legend, left, infoContainer, legendText, right } = this.getLegend({
|
|
8426
8660
|
content: config.title,
|
|
8427
8661
|
id: config.id,
|
|
8428
8662
|
titleHidden: config.titleHidden,
|
|
@@ -8453,10 +8687,9 @@ class Theme {
|
|
|
8453
8687
|
body.appendChild(description);
|
|
8454
8688
|
}
|
|
8455
8689
|
body.appendChild(messages);
|
|
8456
|
-
const switcherSlot =
|
|
8457
|
-
|
|
8690
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
8691
|
+
left.appendChild(switcherSlot);
|
|
8458
8692
|
if (config.readOnly === false) {
|
|
8459
|
-
right.appendChild(switcherSlot);
|
|
8460
8693
|
right.appendChild(actions);
|
|
8461
8694
|
}
|
|
8462
8695
|
body.appendChild(childrenSlot);
|
|
@@ -8511,6 +8744,9 @@ class Theme {
|
|
|
8511
8744
|
const ariaLive = this.getPropertiesAriaLive();
|
|
8512
8745
|
const messages = this.getMessagesSlot();
|
|
8513
8746
|
const childrenSlot = this.getChildrenSlot();
|
|
8747
|
+
if (config.isAccordion || config.isAccordionProperties) {
|
|
8748
|
+
childrenSlot.id = "accordion-" + config.id;
|
|
8749
|
+
}
|
|
8514
8750
|
const propertiesActivators = this.getPropertiesActivators();
|
|
8515
8751
|
const info = this.getInfo(config.info);
|
|
8516
8752
|
const description = this.getDescription({ content: config.description });
|
|
@@ -8537,8 +8773,7 @@ class Theme {
|
|
|
8537
8773
|
const collapse = document.createElement("div");
|
|
8538
8774
|
const collapseToggle = document.createElement("div");
|
|
8539
8775
|
const infoContainer = document.createElement("div");
|
|
8540
|
-
const switcherSlot =
|
|
8541
|
-
switcherSlot.classList.add("jedi-switcher-slot");
|
|
8776
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
8542
8777
|
const legend = document.createElement("div");
|
|
8543
8778
|
legend.classList.add("jedi-editor-legend");
|
|
8544
8779
|
legend.style.display = "flex";
|
|
@@ -8559,6 +8794,7 @@ class Theme {
|
|
|
8559
8794
|
this.visuallyHidden(legendText);
|
|
8560
8795
|
}
|
|
8561
8796
|
left.appendChild(legendText);
|
|
8797
|
+
left.appendChild(switcherSlot);
|
|
8562
8798
|
if (((_a = config == null ? void 0 : config.info) == null ? void 0 : _a.variant) === "modal") {
|
|
8563
8799
|
this.infoAsModal(info, config.id, config.info);
|
|
8564
8800
|
}
|
|
@@ -8567,8 +8803,6 @@ class Theme {
|
|
|
8567
8803
|
}
|
|
8568
8804
|
const innerWrapper = document.createElement("div");
|
|
8569
8805
|
innerWrapper.appendChild(legend);
|
|
8570
|
-
innerWrapper.appendChild(propertiesContainer);
|
|
8571
|
-
innerWrapper.appendChild(quickAddPropertyContainer);
|
|
8572
8806
|
container.appendChild(innerWrapper);
|
|
8573
8807
|
if (config.addProperty) {
|
|
8574
8808
|
quickAddPropertyContainer.appendChild(quickAddPropertyControl.container);
|
|
@@ -8579,11 +8813,12 @@ class Theme {
|
|
|
8579
8813
|
}
|
|
8580
8814
|
body.appendChild(messages);
|
|
8581
8815
|
if (config.readOnly === false) {
|
|
8582
|
-
right.appendChild(switcherSlot);
|
|
8583
8816
|
right.appendChild(actions);
|
|
8584
8817
|
}
|
|
8585
8818
|
body.appendChild(childrenSlot);
|
|
8586
8819
|
innerWrapper.appendChild(body);
|
|
8820
|
+
innerWrapper.appendChild(propertiesContainer);
|
|
8821
|
+
innerWrapper.appendChild(quickAddPropertyContainer);
|
|
8587
8822
|
if (config.editJsonData) {
|
|
8588
8823
|
actions.appendChild(jsonData.toggle);
|
|
8589
8824
|
}
|
|
@@ -8676,8 +8911,11 @@ class Theme {
|
|
|
8676
8911
|
chevron.style.display = "inline-block";
|
|
8677
8912
|
chevron.style.transition = "transform 0.1s ease";
|
|
8678
8913
|
chevron.style.marginRight = "0.5em";
|
|
8914
|
+
const titleSpan = document.createElement("span");
|
|
8915
|
+
titleSpan.style.marginRight = "0.5em";
|
|
8916
|
+
titleSpan.textContent = config.title;
|
|
8679
8917
|
toggle.appendChild(chevron);
|
|
8680
|
-
toggle.appendChild(
|
|
8918
|
+
toggle.appendChild(titleSpan);
|
|
8681
8919
|
const collapse = document.createElement("div");
|
|
8682
8920
|
collapse.classList.add("jedi-accordion-collapse");
|
|
8683
8921
|
collapse.style.display = "none";
|
|
@@ -8730,7 +8968,7 @@ class Theme {
|
|
|
8730
8968
|
const footer = this.getArrayFooter();
|
|
8731
8969
|
const fieldset = this.getFieldset();
|
|
8732
8970
|
const info = this.getInfo(config.info);
|
|
8733
|
-
const { legend, legendText, infoContainer, right } = this.getLegend({
|
|
8971
|
+
const { legend, left, legendText, infoContainer, right } = this.getLegend({
|
|
8734
8972
|
content: config.title,
|
|
8735
8973
|
id: config.id,
|
|
8736
8974
|
titleHidden: config.titleHidden,
|
|
@@ -8773,10 +9011,9 @@ class Theme {
|
|
|
8773
9011
|
body.appendChild(description);
|
|
8774
9012
|
}
|
|
8775
9013
|
body.appendChild(messages);
|
|
8776
|
-
const switcherSlot =
|
|
8777
|
-
|
|
9014
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
9015
|
+
left.appendChild(switcherSlot);
|
|
8778
9016
|
if (config.readOnly === false) {
|
|
8779
|
-
right.appendChild(switcherSlot);
|
|
8780
9017
|
right.appendChild(actions);
|
|
8781
9018
|
}
|
|
8782
9019
|
actions.appendChild(btnGroup);
|
|
@@ -8969,6 +9206,7 @@ class Theme {
|
|
|
8969
9206
|
content: config.description,
|
|
8970
9207
|
id: descriptionId
|
|
8971
9208
|
});
|
|
9209
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
8972
9210
|
if (((_a = config == null ? void 0 : config.info) == null ? void 0 : _a.variant) === "modal") {
|
|
8973
9211
|
this.infoAsModal(info, config.id, config.info);
|
|
8974
9212
|
}
|
|
@@ -8976,11 +9214,12 @@ class Theme {
|
|
|
8976
9214
|
if (isObject(config.info)) {
|
|
8977
9215
|
container.appendChild(info.container);
|
|
8978
9216
|
}
|
|
9217
|
+
container.appendChild(switcherSlot);
|
|
8979
9218
|
container.appendChild(br);
|
|
8980
9219
|
container.appendChild(description);
|
|
8981
9220
|
container.appendChild(messages);
|
|
8982
9221
|
container.appendChild(actions);
|
|
8983
|
-
return { container, label, info, labelText, description, messages, actions };
|
|
9222
|
+
return { container, label, info, labelText, description, messages, actions, switcherSlot };
|
|
8984
9223
|
}
|
|
8985
9224
|
/**
|
|
8986
9225
|
* A Textarea
|
|
@@ -9007,6 +9246,7 @@ class Theme {
|
|
|
9007
9246
|
const messages = this.getMessagesSlot({
|
|
9008
9247
|
id: messagesId
|
|
9009
9248
|
});
|
|
9249
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
9010
9250
|
input.setAttribute("aria-describedby", describedBy);
|
|
9011
9251
|
input.setAttribute("id", config.id);
|
|
9012
9252
|
input.setAttribute("name", config.id);
|
|
@@ -9018,11 +9258,12 @@ class Theme {
|
|
|
9018
9258
|
if (isObject(config.info)) {
|
|
9019
9259
|
container.appendChild(info.container);
|
|
9020
9260
|
}
|
|
9261
|
+
container.appendChild(switcherSlot);
|
|
9021
9262
|
container.appendChild(input);
|
|
9022
9263
|
container.appendChild(description);
|
|
9023
9264
|
container.appendChild(messages);
|
|
9024
9265
|
container.appendChild(actions);
|
|
9025
|
-
return { container, input, label, info, labelText, description, messages, actions };
|
|
9266
|
+
return { container, input, label, info, labelText, description, messages, actions, switcherSlot };
|
|
9026
9267
|
}
|
|
9027
9268
|
adaptForTableTextareaControl(control) {
|
|
9028
9269
|
this.visuallyHidden(control.label);
|
|
@@ -9054,6 +9295,7 @@ class Theme {
|
|
|
9054
9295
|
const messages = this.getMessagesSlot({
|
|
9055
9296
|
id: messagesId
|
|
9056
9297
|
});
|
|
9298
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
9057
9299
|
input.setAttribute("aria-describedby", describedBy);
|
|
9058
9300
|
input.setAttribute("type", config.type);
|
|
9059
9301
|
input.setAttribute("id", config.id);
|
|
@@ -9066,11 +9308,12 @@ class Theme {
|
|
|
9066
9308
|
if (isObject(config.info)) {
|
|
9067
9309
|
container.appendChild(info.container);
|
|
9068
9310
|
}
|
|
9311
|
+
container.appendChild(switcherSlot);
|
|
9069
9312
|
container.appendChild(input);
|
|
9070
9313
|
container.appendChild(description);
|
|
9071
9314
|
container.appendChild(messages);
|
|
9072
9315
|
container.appendChild(actions);
|
|
9073
|
-
return { container, input, label, info, labelText, description, messages, actions };
|
|
9316
|
+
return { container, input, label, info, labelText, description, messages, actions, switcherSlot };
|
|
9074
9317
|
}
|
|
9075
9318
|
getInputRangeControl(config) {
|
|
9076
9319
|
const control = this.getInputControl(config);
|
|
@@ -9140,8 +9383,10 @@ class Theme {
|
|
|
9140
9383
|
radios.push(radio);
|
|
9141
9384
|
labels.push(label);
|
|
9142
9385
|
});
|
|
9386
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
9143
9387
|
container.appendChild(fieldset);
|
|
9144
9388
|
fieldset.appendChild(legend);
|
|
9389
|
+
legend.appendChild(switcherSlot);
|
|
9145
9390
|
if (isObject(config.info)) {
|
|
9146
9391
|
legendText.after(info.container);
|
|
9147
9392
|
}
|
|
@@ -9164,7 +9409,8 @@ class Theme {
|
|
|
9164
9409
|
labelTexts,
|
|
9165
9410
|
radioControls,
|
|
9166
9411
|
description,
|
|
9167
|
-
messages
|
|
9412
|
+
messages,
|
|
9413
|
+
switcherSlot
|
|
9168
9414
|
};
|
|
9169
9415
|
}
|
|
9170
9416
|
adaptForTableRadiosControl(control) {
|
|
@@ -9201,6 +9447,7 @@ class Theme {
|
|
|
9201
9447
|
input.setAttribute("id", config.id);
|
|
9202
9448
|
input.setAttribute("name", config.id);
|
|
9203
9449
|
input.setAttribute("aria-describedby", describedBy);
|
|
9450
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
9204
9451
|
if (((_a = config == null ? void 0 : config.info) == null ? void 0 : _a.variant) === "modal") {
|
|
9205
9452
|
this.infoAsModal(info, config.id, config.info);
|
|
9206
9453
|
}
|
|
@@ -9211,9 +9458,10 @@ class Theme {
|
|
|
9211
9458
|
if (isObject(config.info)) {
|
|
9212
9459
|
formGroup.appendChild(info.container);
|
|
9213
9460
|
}
|
|
9461
|
+
formGroup.appendChild(switcherSlot);
|
|
9214
9462
|
formGroup.appendChild(description);
|
|
9215
9463
|
formGroup.appendChild(messages);
|
|
9216
|
-
return { container, formGroup, input, label, info, labelText, description, messages, actions };
|
|
9464
|
+
return { container, formGroup, input, label, info, labelText, description, messages, actions, switcherSlot };
|
|
9217
9465
|
}
|
|
9218
9466
|
adaptForTableCheckboxControl(control, td) {
|
|
9219
9467
|
this.visuallyHidden(control.label);
|
|
@@ -9270,8 +9518,10 @@ class Theme {
|
|
|
9270
9518
|
if (((_a = config == null ? void 0 : config.info) == null ? void 0 : _a.variant) === "modal") {
|
|
9271
9519
|
this.infoAsModal(info, config.id, config.info);
|
|
9272
9520
|
}
|
|
9521
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
9273
9522
|
container.appendChild(fieldset);
|
|
9274
9523
|
fieldset.appendChild(legend);
|
|
9524
|
+
legend.appendChild(switcherSlot);
|
|
9275
9525
|
if (isObject(config.info)) {
|
|
9276
9526
|
legendText.after(info.container);
|
|
9277
9527
|
}
|
|
@@ -9293,7 +9543,8 @@ class Theme {
|
|
|
9293
9543
|
labelTexts,
|
|
9294
9544
|
checkboxControls,
|
|
9295
9545
|
description,
|
|
9296
|
-
messages
|
|
9546
|
+
messages,
|
|
9547
|
+
switcherSlot
|
|
9297
9548
|
};
|
|
9298
9549
|
}
|
|
9299
9550
|
adaptForTableCheckboxesControl(control, td) {
|
|
@@ -9336,6 +9587,7 @@ class Theme {
|
|
|
9336
9587
|
}
|
|
9337
9588
|
input.appendChild(option);
|
|
9338
9589
|
});
|
|
9590
|
+
const switcherSlot = this.getSwitcherSlot();
|
|
9339
9591
|
if (((_a = config == null ? void 0 : config.info) == null ? void 0 : _a.variant) === "modal") {
|
|
9340
9592
|
this.infoAsModal(info, config.id, config.info);
|
|
9341
9593
|
}
|
|
@@ -9343,11 +9595,12 @@ class Theme {
|
|
|
9343
9595
|
if (isObject(config.info)) {
|
|
9344
9596
|
container.appendChild(info.container);
|
|
9345
9597
|
}
|
|
9598
|
+
container.appendChild(switcherSlot);
|
|
9346
9599
|
container.appendChild(input);
|
|
9347
9600
|
container.appendChild(description);
|
|
9348
9601
|
container.appendChild(messages);
|
|
9349
9602
|
container.appendChild(actions);
|
|
9350
|
-
return { container, input, label, info, labelText, description, messages, actions };
|
|
9603
|
+
return { container, input, label, info, labelText, description, messages, actions, switcherSlot };
|
|
9351
9604
|
}
|
|
9352
9605
|
adaptForTableSelectControl(control) {
|
|
9353
9606
|
this.visuallyHidden(control.label);
|
|
@@ -9780,8 +10033,11 @@ class ThemeBootstrap3 extends Theme {
|
|
|
9780
10033
|
chevron.style.display = "inline-block";
|
|
9781
10034
|
chevron.style.transition = "transform 0.1s ease";
|
|
9782
10035
|
chevron.style.marginRight = "0.5em";
|
|
10036
|
+
const titleSpan = document.createElement("span");
|
|
10037
|
+
titleSpan.style.marginRight = "0.5em";
|
|
10038
|
+
titleSpan.textContent = config.title;
|
|
9783
10039
|
toggle.appendChild(chevron);
|
|
9784
|
-
toggle.appendChild(
|
|
10040
|
+
toggle.appendChild(titleSpan);
|
|
9785
10041
|
const collapse = document.createElement("div");
|
|
9786
10042
|
collapse.id = collapseId;
|
|
9787
10043
|
collapse.classList.add("panel-collapse", "collapse");
|
|
@@ -10308,8 +10564,11 @@ class ThemeBootstrap4 extends Theme {
|
|
|
10308
10564
|
}
|
|
10309
10565
|
chevron.classList.add("d-inline-block", "mr-2");
|
|
10310
10566
|
chevron.style.transition = "transform 0.1s ease";
|
|
10567
|
+
const titleSpan = document.createElement("span");
|
|
10568
|
+
titleSpan.classList.add("mr-1");
|
|
10569
|
+
titleSpan.textContent = config.title;
|
|
10311
10570
|
toggle.appendChild(chevron);
|
|
10312
|
-
toggle.appendChild(
|
|
10571
|
+
toggle.appendChild(titleSpan);
|
|
10313
10572
|
const collapse = document.createElement("div");
|
|
10314
10573
|
collapse.id = collapseId;
|
|
10315
10574
|
collapse.classList.add("collapse");
|
|
@@ -10859,8 +11118,11 @@ class ThemeBootstrap5 extends Theme {
|
|
|
10859
11118
|
}
|
|
10860
11119
|
chevron.classList.add("d-inline-block", "me-2");
|
|
10861
11120
|
chevron.style.transition = "transform 0.1s ease";
|
|
11121
|
+
const titleSpan = document.createElement("span");
|
|
11122
|
+
titleSpan.classList.add("me-1");
|
|
11123
|
+
titleSpan.textContent = config.title;
|
|
10862
11124
|
toggle.appendChild(chevron);
|
|
10863
|
-
toggle.appendChild(
|
|
11125
|
+
toggle.appendChild(titleSpan);
|
|
10864
11126
|
const collapse = document.createElement("div");
|
|
10865
11127
|
collapse.id = collapseId;
|
|
10866
11128
|
collapse.classList.add("accordion-collapse", "collapse");
|