@jsenv/navi 0.9.2 → 0.10.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/dist/jsenv_navi.js +581 -408
- package/index.js +5 -0
- package/package.json +1 -1
- package/src/components/callout/callout.js +3 -1
- package/src/components/details/details.jsx +7 -8
- package/src/components/field/button.jsx +6 -63
- package/src/components/field/checkbox_list.jsx +0 -1
- package/src/components/field/form.jsx +2 -17
- package/src/components/field/input_checkbox.jsx +0 -1
- package/src/components/field/input_textual.jsx +5 -142
- package/src/components/field/radio_list.jsx +0 -1
- package/src/components/field/select.jsx +0 -2
- package/src/components/field/use_form_events.js +4 -0
- package/src/components/keyboard_shortcuts/keyboard_shortcuts.js +1 -1
- package/src/components/link/link.jsx +27 -25
- package/src/components/text/text.jsx +28 -18
- package/src/validation/constraints/native_constraints.js +43 -18
- package/src/validation/constraints/same_as_constraint.js +42 -0
- package/src/validation/custom_constraint_validation.js +262 -59
- package/src/validation/demos/demo_same_as_constraint.html +259 -0
- package/src/validation/input_change_effect.js +106 -0
package/dist/jsenv_navi.js
CHANGED
|
@@ -520,22 +520,26 @@ const createPubSub = (clearOnPublish = false) => {
|
|
|
520
520
|
|
|
521
521
|
const createValueEffect = (value) => {
|
|
522
522
|
const callbackSet = new Set();
|
|
523
|
-
const
|
|
523
|
+
const valueCleanupSet = new Set();
|
|
524
|
+
|
|
525
|
+
const cleanup = () => {
|
|
526
|
+
for (const valueCleanup of valueCleanupSet) {
|
|
527
|
+
valueCleanup();
|
|
528
|
+
}
|
|
529
|
+
valueCleanupSet.clear();
|
|
530
|
+
};
|
|
524
531
|
|
|
525
532
|
const updateValue = (newValue) => {
|
|
526
533
|
if (newValue === value) {
|
|
527
534
|
return;
|
|
528
535
|
}
|
|
529
|
-
|
|
530
|
-
cleanup();
|
|
531
|
-
}
|
|
532
|
-
previousValueCleanupSet.clear();
|
|
536
|
+
cleanup();
|
|
533
537
|
const oldValue = value;
|
|
534
538
|
value = newValue;
|
|
535
539
|
for (const callback of callbackSet) {
|
|
536
540
|
const returnValue = callback(newValue, oldValue);
|
|
537
541
|
if (typeof returnValue === "function") {
|
|
538
|
-
|
|
542
|
+
valueCleanupSet.add(returnValue);
|
|
539
543
|
}
|
|
540
544
|
}
|
|
541
545
|
};
|
|
@@ -547,7 +551,7 @@ const createValueEffect = (value) => {
|
|
|
547
551
|
};
|
|
548
552
|
};
|
|
549
553
|
|
|
550
|
-
return [updateValue, addEffect];
|
|
554
|
+
return [updateValue, addEffect, cleanup];
|
|
551
555
|
};
|
|
552
556
|
|
|
553
557
|
// https://github.com/davidtheclark/tabbable/blob/master/index.js
|
|
@@ -11840,7 +11844,9 @@ const openCallout = (
|
|
|
11840
11844
|
addTeardown(onClose);
|
|
11841
11845
|
}
|
|
11842
11846
|
|
|
11843
|
-
const [updateLevel, addLevelEffect] =
|
|
11847
|
+
const [updateLevel, addLevelEffect, cleanupLevelEffects] =
|
|
11848
|
+
createValueEffect(undefined);
|
|
11849
|
+
addTeardown(cleanupLevelEffects);
|
|
11844
11850
|
|
|
11845
11851
|
// Create and add callout to document
|
|
11846
11852
|
const calloutElement = createCalloutElement();
|
|
@@ -12814,10 +12820,25 @@ const REQUIRED_CONSTRAINT = {
|
|
|
12814
12820
|
: undefined,
|
|
12815
12821
|
};
|
|
12816
12822
|
}
|
|
12817
|
-
if (
|
|
12818
|
-
return
|
|
12823
|
+
if (element.value) {
|
|
12824
|
+
return null;
|
|
12825
|
+
}
|
|
12826
|
+
if (requiredMessage) {
|
|
12827
|
+
return requiredMessage;
|
|
12819
12828
|
}
|
|
12820
|
-
|
|
12829
|
+
if (element.type === "password") {
|
|
12830
|
+
return element.hasAttribute("data-same-as")
|
|
12831
|
+
? `Veuillez confirmer le mot de passe.`
|
|
12832
|
+
: `Veuillez saisir un mot de passe.`;
|
|
12833
|
+
}
|
|
12834
|
+
if (element.type === "email") {
|
|
12835
|
+
return element.hasAttribute("data-same-as")
|
|
12836
|
+
? `Veuillez confirmer l'adresse e-mail`
|
|
12837
|
+
: `Veuillez saisir une adresse e-mail.`;
|
|
12838
|
+
}
|
|
12839
|
+
return element.hasAttribute("data-same-as")
|
|
12840
|
+
? `Veuillez confirmer le champ précédent`
|
|
12841
|
+
: `Veuillez remplir ce champ.`;
|
|
12821
12842
|
},
|
|
12822
12843
|
};
|
|
12823
12844
|
const PATTERN_CONSTRAINT = {
|
|
@@ -12832,19 +12853,19 @@ const PATTERN_CONSTRAINT = {
|
|
|
12832
12853
|
return null;
|
|
12833
12854
|
}
|
|
12834
12855
|
const regex = new RegExp(pattern);
|
|
12835
|
-
if (
|
|
12836
|
-
|
|
12837
|
-
if (patternMessage) {
|
|
12838
|
-
return patternMessage;
|
|
12839
|
-
}
|
|
12840
|
-
let message = `Veuillez respecter le format requis.`;
|
|
12841
|
-
const title = input.title;
|
|
12842
|
-
if (title) {
|
|
12843
|
-
message += `<br />${title}`;
|
|
12844
|
-
}
|
|
12845
|
-
return message;
|
|
12856
|
+
if (regex.test(value)) {
|
|
12857
|
+
return null;
|
|
12846
12858
|
}
|
|
12847
|
-
|
|
12859
|
+
const patternMessage = input.getAttribute("data-pattern-message");
|
|
12860
|
+
if (patternMessage) {
|
|
12861
|
+
return patternMessage;
|
|
12862
|
+
}
|
|
12863
|
+
let message = `Veuillez respecter le format requis.`;
|
|
12864
|
+
const title = input.title;
|
|
12865
|
+
if (title) {
|
|
12866
|
+
message += `<br />${title}`;
|
|
12867
|
+
}
|
|
12868
|
+
return message;
|
|
12848
12869
|
},
|
|
12849
12870
|
};
|
|
12850
12871
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/email#validation
|
|
@@ -12892,10 +12913,11 @@ const MIN_LENGTH_CONSTRAINT = {
|
|
|
12892
12913
|
return null;
|
|
12893
12914
|
}
|
|
12894
12915
|
if (valueLength < minLength) {
|
|
12916
|
+
const thisField = generateThisFieldText(element);
|
|
12895
12917
|
if (valueLength === 1) {
|
|
12896
|
-
return
|
|
12918
|
+
return `${thisField} doit contenir au moins ${minLength} caractère (il contient actuellement un seul caractère).`;
|
|
12897
12919
|
}
|
|
12898
|
-
return
|
|
12920
|
+
return `${thisField} doit contenir au moins ${minLength} caractères (il contient actuellement ${valueLength} caractères).`;
|
|
12899
12921
|
}
|
|
12900
12922
|
return null;
|
|
12901
12923
|
},
|
|
@@ -12909,6 +12931,14 @@ const INPUT_TYPE_SUPPORTING_MIN_LENGTH_SET = new Set([
|
|
|
12909
12931
|
"password",
|
|
12910
12932
|
]);
|
|
12911
12933
|
|
|
12934
|
+
const generateThisFieldText = (field) => {
|
|
12935
|
+
return field.type === "password"
|
|
12936
|
+
? "Ce mot de passe"
|
|
12937
|
+
: field.type === "email"
|
|
12938
|
+
? "Cette adresse e-mail"
|
|
12939
|
+
: "Ce champ";
|
|
12940
|
+
};
|
|
12941
|
+
|
|
12912
12942
|
const MAX_LENGTH_CONSTRAINT = {
|
|
12913
12943
|
name: "max_length",
|
|
12914
12944
|
check: (element) => {
|
|
@@ -12928,7 +12958,8 @@ const MAX_LENGTH_CONSTRAINT = {
|
|
|
12928
12958
|
const value = element.value;
|
|
12929
12959
|
const valueLength = value.length;
|
|
12930
12960
|
if (valueLength > maxLength) {
|
|
12931
|
-
|
|
12961
|
+
const thisField = generateThisFieldText(element);
|
|
12962
|
+
return `${thisField} doit contenir au maximum ${maxLength} caractères (il contient actuellement ${valueLength} caractères).`;
|
|
12932
12963
|
}
|
|
12933
12964
|
return null;
|
|
12934
12965
|
},
|
|
@@ -13097,6 +13128,154 @@ const READONLY_CONSTRAINT = {
|
|
|
13097
13128
|
},
|
|
13098
13129
|
};
|
|
13099
13130
|
|
|
13131
|
+
const SAME_AS_CONSTRAINT = {
|
|
13132
|
+
name: "same_as",
|
|
13133
|
+
check: (element) => {
|
|
13134
|
+
const sameAs = element.getAttribute("data-same-as");
|
|
13135
|
+
if (!sameAs) {
|
|
13136
|
+
return null;
|
|
13137
|
+
}
|
|
13138
|
+
|
|
13139
|
+
const otherElement = document.querySelector(sameAs);
|
|
13140
|
+
if (!otherElement) {
|
|
13141
|
+
console.warn(
|
|
13142
|
+
`Same as constraint: could not find element for selector ${sameAs}`,
|
|
13143
|
+
);
|
|
13144
|
+
return null;
|
|
13145
|
+
}
|
|
13146
|
+
|
|
13147
|
+
const value = element.value;
|
|
13148
|
+
const otherValue = otherElement.value;
|
|
13149
|
+
if (value === "" || otherValue === "") {
|
|
13150
|
+
// don't validate if one of the two values is empty
|
|
13151
|
+
return null;
|
|
13152
|
+
}
|
|
13153
|
+
|
|
13154
|
+
if (value === otherValue) {
|
|
13155
|
+
return null;
|
|
13156
|
+
}
|
|
13157
|
+
|
|
13158
|
+
const message = element.getAttribute("data-same-as-message");
|
|
13159
|
+
if (message) {
|
|
13160
|
+
return message;
|
|
13161
|
+
}
|
|
13162
|
+
|
|
13163
|
+
const type = element.type;
|
|
13164
|
+
if (type === "password") {
|
|
13165
|
+
return `Ce mot de passe doit être identique au précédent.`;
|
|
13166
|
+
}
|
|
13167
|
+
if (type === "email") {
|
|
13168
|
+
return `Cette adresse e-mail doit être identique a la précédente.`;
|
|
13169
|
+
}
|
|
13170
|
+
return `Ce champ doit être identique au précédent.`;
|
|
13171
|
+
},
|
|
13172
|
+
};
|
|
13173
|
+
|
|
13174
|
+
const listenInputChange = (input, callback) => {
|
|
13175
|
+
const [teardown, addTeardown] = createPubSub();
|
|
13176
|
+
|
|
13177
|
+
let valueAtInteraction;
|
|
13178
|
+
const oninput = () => {
|
|
13179
|
+
valueAtInteraction = undefined;
|
|
13180
|
+
};
|
|
13181
|
+
const onkeydown = (e) => {
|
|
13182
|
+
if (e.key === "Enter") {
|
|
13183
|
+
/**
|
|
13184
|
+
* Browser trigger a "change" event right after the enter is pressed
|
|
13185
|
+
* if the input value has changed.
|
|
13186
|
+
* We need to prevent the next change event otherwise we would request action twice
|
|
13187
|
+
*/
|
|
13188
|
+
valueAtInteraction = input.value;
|
|
13189
|
+
}
|
|
13190
|
+
if (e.key === "Escape") {
|
|
13191
|
+
/**
|
|
13192
|
+
* Browser trigger a "change" event right after the escape is pressed
|
|
13193
|
+
* if the input value has changed.
|
|
13194
|
+
* We need to prevent the next change event otherwise we would request action when
|
|
13195
|
+
* we actually want to cancel
|
|
13196
|
+
*/
|
|
13197
|
+
valueAtInteraction = input.value;
|
|
13198
|
+
}
|
|
13199
|
+
};
|
|
13200
|
+
const onchange = (e) => {
|
|
13201
|
+
if (
|
|
13202
|
+
valueAtInteraction !== undefined &&
|
|
13203
|
+
e.target.value === valueAtInteraction
|
|
13204
|
+
) {
|
|
13205
|
+
valueAtInteraction = undefined;
|
|
13206
|
+
return;
|
|
13207
|
+
}
|
|
13208
|
+
callback(e);
|
|
13209
|
+
};
|
|
13210
|
+
input.addEventListener("input", oninput);
|
|
13211
|
+
input.addEventListener("keydown", onkeydown);
|
|
13212
|
+
input.addEventListener("change", onchange);
|
|
13213
|
+
addTeardown(() => {
|
|
13214
|
+
input.removeEventListener("input", oninput);
|
|
13215
|
+
input.removeEventListener("keydown", onkeydown);
|
|
13216
|
+
input.removeEventListener("change", onchange);
|
|
13217
|
+
});
|
|
13218
|
+
|
|
13219
|
+
{
|
|
13220
|
+
// Handle programmatic value changes that don't trigger browser change events
|
|
13221
|
+
//
|
|
13222
|
+
// Problem: When input values are set programmatically (not by user typing),
|
|
13223
|
+
// browsers don't fire the 'change' event. However, our application logic
|
|
13224
|
+
// still needs to detect these changes.
|
|
13225
|
+
//
|
|
13226
|
+
// Example scenario:
|
|
13227
|
+
// 1. User starts editing (letter key pressed, value set programmatically)
|
|
13228
|
+
// 2. User doesn't type anything additional (this is the key part)
|
|
13229
|
+
// 3. User clicks outside to finish editing
|
|
13230
|
+
// 4. Without this code, no change event would fire despite the fact that the input value did change from its original state
|
|
13231
|
+
//
|
|
13232
|
+
// This distinction is crucial because:
|
|
13233
|
+
//
|
|
13234
|
+
// - If the user typed additional text after the initial programmatic value,
|
|
13235
|
+
// the browser would fire change events normally
|
|
13236
|
+
// - But when they don't type anything else, the browser considers it as "no user interaction"
|
|
13237
|
+
// even though the programmatic initial value represents a meaningful change
|
|
13238
|
+
//
|
|
13239
|
+
// We achieve this by checking if the input value has changed between focus and blur without any user interaction
|
|
13240
|
+
// if yes we fire the callback because input value did change
|
|
13241
|
+
let valueAtStart = input.value;
|
|
13242
|
+
let interacted = false;
|
|
13243
|
+
|
|
13244
|
+
const onfocus = () => {
|
|
13245
|
+
interacted = false;
|
|
13246
|
+
valueAtStart = input.value;
|
|
13247
|
+
};
|
|
13248
|
+
const oninput = (e) => {
|
|
13249
|
+
if (!e.isTrusted) {
|
|
13250
|
+
// non trusted "input" events will be ignored by the browser when deciding to fire "change" event
|
|
13251
|
+
// we ignore them too
|
|
13252
|
+
return;
|
|
13253
|
+
}
|
|
13254
|
+
interacted = true;
|
|
13255
|
+
};
|
|
13256
|
+
const onblur = (e) => {
|
|
13257
|
+
if (interacted) {
|
|
13258
|
+
return;
|
|
13259
|
+
}
|
|
13260
|
+
if (valueAtStart === input.value) {
|
|
13261
|
+
return;
|
|
13262
|
+
}
|
|
13263
|
+
callback(e);
|
|
13264
|
+
};
|
|
13265
|
+
|
|
13266
|
+
input.addEventListener("focus", onfocus);
|
|
13267
|
+
input.addEventListener("input", oninput);
|
|
13268
|
+
input.addEventListener("blur", onblur);
|
|
13269
|
+
addTeardown(() => {
|
|
13270
|
+
input.removeEventListener("focus", onfocus);
|
|
13271
|
+
input.removeEventListener("input", oninput);
|
|
13272
|
+
input.removeEventListener("blur", onblur);
|
|
13273
|
+
});
|
|
13274
|
+
}
|
|
13275
|
+
|
|
13276
|
+
return teardown;
|
|
13277
|
+
};
|
|
13278
|
+
|
|
13100
13279
|
/**
|
|
13101
13280
|
* Custom form validation implementation
|
|
13102
13281
|
*
|
|
@@ -13133,9 +13312,9 @@ const requestAction = (
|
|
|
13133
13312
|
target,
|
|
13134
13313
|
action,
|
|
13135
13314
|
{
|
|
13315
|
+
actionOrigin,
|
|
13136
13316
|
event,
|
|
13137
13317
|
requester = target,
|
|
13138
|
-
actionOrigin,
|
|
13139
13318
|
method = "rerun",
|
|
13140
13319
|
meta = {},
|
|
13141
13320
|
confirmMessage,
|
|
@@ -13205,12 +13384,8 @@ const requestAction = (
|
|
|
13205
13384
|
// Single element validation case
|
|
13206
13385
|
isValid = validationInterface.checkValidity({ fromRequestAction: true });
|
|
13207
13386
|
if (!isValid) {
|
|
13208
|
-
if (event) {
|
|
13209
|
-
event.preventDefault();
|
|
13210
|
-
}
|
|
13211
13387
|
validationInterface.reportValidity();
|
|
13212
13388
|
}
|
|
13213
|
-
|
|
13214
13389
|
elementForConfirmation = target;
|
|
13215
13390
|
elementForDispatch = target;
|
|
13216
13391
|
}
|
|
@@ -13247,6 +13422,15 @@ const requestAction = (
|
|
|
13247
13422
|
return true;
|
|
13248
13423
|
};
|
|
13249
13424
|
|
|
13425
|
+
const forwardActionRequested = (e, action, target = e.target) => {
|
|
13426
|
+
requestAction(target, action, {
|
|
13427
|
+
actionOrigin: e.detail?.actionOrigin,
|
|
13428
|
+
event: e.detail?.event || e,
|
|
13429
|
+
requester: e.detail?.requester,
|
|
13430
|
+
meta: e.detail?.meta,
|
|
13431
|
+
});
|
|
13432
|
+
};
|
|
13433
|
+
|
|
13250
13434
|
const closeValidationMessage = (element, reason) => {
|
|
13251
13435
|
const validationInterface = element.__validationInterface__;
|
|
13252
13436
|
if (!validationInterface) {
|
|
@@ -13259,6 +13443,7 @@ const closeValidationMessage = (element, reason) => {
|
|
|
13259
13443
|
return validationMessage.close(reason);
|
|
13260
13444
|
};
|
|
13261
13445
|
|
|
13446
|
+
const formInstrumentedWeakSet = new WeakSet();
|
|
13262
13447
|
const installCustomConstraintValidation = (
|
|
13263
13448
|
element,
|
|
13264
13449
|
elementReceivingValidationMessage = element,
|
|
@@ -13277,20 +13462,25 @@ const installCustomConstraintValidation = (
|
|
|
13277
13462
|
validationMessage: null,
|
|
13278
13463
|
};
|
|
13279
13464
|
|
|
13280
|
-
const
|
|
13465
|
+
const [teardown, addTeardown] = createPubSub();
|
|
13281
13466
|
{
|
|
13282
13467
|
const uninstall = () => {
|
|
13283
|
-
|
|
13284
|
-
cleanupCallback();
|
|
13285
|
-
}
|
|
13286
|
-
cleanupCallbackSet.clear();
|
|
13468
|
+
teardown();
|
|
13287
13469
|
};
|
|
13288
13470
|
validationInterface.uninstall = uninstall;
|
|
13289
13471
|
}
|
|
13290
13472
|
|
|
13473
|
+
const isForm = element.tagName === "FORM";
|
|
13474
|
+
if (isForm) {
|
|
13475
|
+
formInstrumentedWeakSet.add(element);
|
|
13476
|
+
addTeardown(() => {
|
|
13477
|
+
formInstrumentedWeakSet.delete(element);
|
|
13478
|
+
});
|
|
13479
|
+
}
|
|
13480
|
+
|
|
13291
13481
|
{
|
|
13292
13482
|
element.__validationInterface__ = validationInterface;
|
|
13293
|
-
|
|
13483
|
+
addTeardown(() => {
|
|
13294
13484
|
delete element.__validationInterface__;
|
|
13295
13485
|
});
|
|
13296
13486
|
}
|
|
@@ -13299,7 +13489,6 @@ const installCustomConstraintValidation = (
|
|
|
13299
13489
|
const cancelEvent = new CustomEvent("cancel", options);
|
|
13300
13490
|
element.dispatchEvent(cancelEvent);
|
|
13301
13491
|
};
|
|
13302
|
-
|
|
13303
13492
|
const closeElementValidationMessage = (reason) => {
|
|
13304
13493
|
if (validationInterface.validationMessage) {
|
|
13305
13494
|
validationInterface.validationMessage.close(reason);
|
|
@@ -13319,6 +13508,7 @@ const installCustomConstraintValidation = (
|
|
|
13319
13508
|
constraintSet.add(MIN_CONSTRAINT);
|
|
13320
13509
|
constraintSet.add(MAX_CONSTRAINT);
|
|
13321
13510
|
constraintSet.add(READONLY_CONSTRAINT);
|
|
13511
|
+
constraintSet.add(SAME_AS_CONSTRAINT);
|
|
13322
13512
|
{
|
|
13323
13513
|
validationInterface.registerConstraint = (constraint) => {
|
|
13324
13514
|
if (typeof constraint === "function") {
|
|
@@ -13337,6 +13527,8 @@ const installCustomConstraintValidation = (
|
|
|
13337
13527
|
let failedConstraintInfo = null;
|
|
13338
13528
|
const validityInfoMap = new Map();
|
|
13339
13529
|
|
|
13530
|
+
const hasTitleAttribute = element.hasAttribute("title");
|
|
13531
|
+
|
|
13340
13532
|
const resetValidity = ({ fromRequestAction } = {}) => {
|
|
13341
13533
|
if (fromRequestAction && failedConstraintInfo) {
|
|
13342
13534
|
for (const [key, customMessage] of customMessageMap) {
|
|
@@ -13354,7 +13546,7 @@ const installCustomConstraintValidation = (
|
|
|
13354
13546
|
validityInfoMap.clear();
|
|
13355
13547
|
failedConstraintInfo = null;
|
|
13356
13548
|
};
|
|
13357
|
-
|
|
13549
|
+
addTeardown(resetValidity);
|
|
13358
13550
|
|
|
13359
13551
|
const checkValidity = ({ fromRequestAction, skipReadonly } = {}) => {
|
|
13360
13552
|
resetValidity({ fromRequestAction });
|
|
@@ -13399,7 +13591,16 @@ const installCustomConstraintValidation = (
|
|
|
13399
13591
|
validityInfoMap.set(constraint, failedConstraintInfo);
|
|
13400
13592
|
}
|
|
13401
13593
|
|
|
13402
|
-
if (
|
|
13594
|
+
if (failedConstraintInfo) {
|
|
13595
|
+
if (!hasTitleAttribute) {
|
|
13596
|
+
// when a constraint is failing browser displays that constraint message if the element has no title attribute.
|
|
13597
|
+
// We want to do the same with our message (overriding the browser in the process to get better messages)
|
|
13598
|
+
element.setAttribute("title", failedConstraintInfo.message);
|
|
13599
|
+
}
|
|
13600
|
+
} else {
|
|
13601
|
+
if (!hasTitleAttribute) {
|
|
13602
|
+
element.removeAttribute("title");
|
|
13603
|
+
}
|
|
13403
13604
|
closeElementValidationMessage("becomes_valid");
|
|
13404
13605
|
}
|
|
13405
13606
|
|
|
@@ -13425,9 +13626,9 @@ const installCustomConstraintValidation = (
|
|
|
13425
13626
|
if (!skipFocus) {
|
|
13426
13627
|
element.focus();
|
|
13427
13628
|
}
|
|
13428
|
-
const
|
|
13629
|
+
const removeCloseOnCleanup = addTeardown(() => {
|
|
13429
13630
|
closeElementValidationMessage("cleanup");
|
|
13430
|
-
};
|
|
13631
|
+
});
|
|
13431
13632
|
|
|
13432
13633
|
const anchorElement =
|
|
13433
13634
|
failedConstraintInfo.target || elementReceivingValidationMessage;
|
|
@@ -13438,7 +13639,7 @@ const installCustomConstraintValidation = (
|
|
|
13438
13639
|
level: failedConstraintInfo.level,
|
|
13439
13640
|
closeOnClickOutside: failedConstraintInfo.closeOnClickOutside,
|
|
13440
13641
|
onClose: () => {
|
|
13441
|
-
|
|
13642
|
+
removeCloseOnCleanup();
|
|
13442
13643
|
validationInterface.validationMessage = null;
|
|
13443
13644
|
if (failedConstraintInfo) {
|
|
13444
13645
|
failedConstraintInfo.reportStatus = "closed";
|
|
@@ -13450,7 +13651,6 @@ const installCustomConstraintValidation = (
|
|
|
13450
13651
|
},
|
|
13451
13652
|
);
|
|
13452
13653
|
failedConstraintInfo.reportStatus = "reported";
|
|
13453
|
-
cleanupCallbackSet.add(closeOnCleanup);
|
|
13454
13654
|
};
|
|
13455
13655
|
validationInterface.checkValidity = checkValidity;
|
|
13456
13656
|
validationInterface.reportValidity = reportValidity;
|
|
@@ -13485,7 +13685,7 @@ const installCustomConstraintValidation = (
|
|
|
13485
13685
|
reportValidity();
|
|
13486
13686
|
}
|
|
13487
13687
|
};
|
|
13488
|
-
|
|
13688
|
+
addTeardown(() => {
|
|
13489
13689
|
customMessageMap.clear();
|
|
13490
13690
|
});
|
|
13491
13691
|
Object.assign(validationInterface, {
|
|
@@ -13494,6 +13694,7 @@ const installCustomConstraintValidation = (
|
|
|
13494
13694
|
});
|
|
13495
13695
|
}
|
|
13496
13696
|
|
|
13697
|
+
checkValidity();
|
|
13497
13698
|
{
|
|
13498
13699
|
const oninput = () => {
|
|
13499
13700
|
customMessageMap.clear();
|
|
@@ -13501,7 +13702,7 @@ const installCustomConstraintValidation = (
|
|
|
13501
13702
|
checkValidity();
|
|
13502
13703
|
};
|
|
13503
13704
|
element.addEventListener("input", oninput);
|
|
13504
|
-
|
|
13705
|
+
addTeardown(() => {
|
|
13505
13706
|
element.removeEventListener("input", oninput);
|
|
13506
13707
|
});
|
|
13507
13708
|
}
|
|
@@ -13513,13 +13714,7 @@ const installCustomConstraintValidation = (
|
|
|
13513
13714
|
checkValidity();
|
|
13514
13715
|
};
|
|
13515
13716
|
element.addEventListener("actionend", onactionend);
|
|
13516
|
-
|
|
13517
|
-
element.form.addEventListener("actionend", onactionend);
|
|
13518
|
-
cleanupCallbackSet.add(() => {
|
|
13519
|
-
element.form.removeEventListener("actionend", onactionend);
|
|
13520
|
-
});
|
|
13521
|
-
}
|
|
13522
|
-
cleanupCallbackSet.add(() => {
|
|
13717
|
+
addTeardown(() => {
|
|
13523
13718
|
element.removeEventListener("actionend", onactionend);
|
|
13524
13719
|
});
|
|
13525
13720
|
}
|
|
@@ -13529,37 +13724,119 @@ const installCustomConstraintValidation = (
|
|
|
13529
13724
|
element.reportValidity = () => {
|
|
13530
13725
|
reportValidity();
|
|
13531
13726
|
};
|
|
13532
|
-
|
|
13727
|
+
addTeardown(() => {
|
|
13533
13728
|
element.reportValidity = nativeReportValidity;
|
|
13534
13729
|
});
|
|
13535
13730
|
}
|
|
13536
13731
|
|
|
13537
|
-
{
|
|
13538
|
-
|
|
13539
|
-
|
|
13732
|
+
request_on_enter: {
|
|
13733
|
+
if (element.tagName !== "INPUT") {
|
|
13734
|
+
// maybe we want it too for checkboxes etc, we'll see
|
|
13735
|
+
break request_on_enter;
|
|
13736
|
+
}
|
|
13737
|
+
const onkeydown = (keydownEvent) => {
|
|
13738
|
+
if (keydownEvent.defaultPrevented) {
|
|
13540
13739
|
return;
|
|
13541
13740
|
}
|
|
13542
|
-
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13741
|
+
if (keydownEvent.key !== "Enter") {
|
|
13742
|
+
return;
|
|
13743
|
+
}
|
|
13744
|
+
if (element.hasAttribute("data-action")) {
|
|
13745
|
+
if (wouldKeydownSubmitForm(keydownEvent)) {
|
|
13746
|
+
keydownEvent.preventDefault();
|
|
13747
|
+
}
|
|
13748
|
+
dispatchActionRequestedCustomEvent(element, {
|
|
13749
|
+
event: keydownEvent,
|
|
13750
|
+
requester: element,
|
|
13751
|
+
});
|
|
13752
|
+
return;
|
|
13753
|
+
}
|
|
13754
|
+
const { form } = element;
|
|
13755
|
+
if (!form) {
|
|
13756
|
+
return;
|
|
13757
|
+
}
|
|
13758
|
+
keydownEvent.preventDefault();
|
|
13759
|
+
dispatchActionRequestedCustomEvent(form, {
|
|
13760
|
+
event: keydownEvent,
|
|
13761
|
+
requester: getFirstButtonSubmittingForm(form) || element,
|
|
13546
13762
|
});
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13763
|
+
};
|
|
13764
|
+
element.addEventListener("keydown", onkeydown);
|
|
13765
|
+
addTeardown(() => {
|
|
13766
|
+
element.removeEventListener("keydown", onkeydown);
|
|
13767
|
+
});
|
|
13768
|
+
}
|
|
13769
|
+
|
|
13770
|
+
{
|
|
13771
|
+
const onclick = (clickEvent) => {
|
|
13772
|
+
if (clickEvent.defaultPrevented) {
|
|
13773
|
+
return;
|
|
13774
|
+
}
|
|
13775
|
+
if (element.tagName !== "BUTTON") {
|
|
13776
|
+
return;
|
|
13550
13777
|
}
|
|
13778
|
+
if (element.hasAttribute("data-action")) {
|
|
13779
|
+
if (wouldClickSubmitForm(clickEvent)) {
|
|
13780
|
+
clickEvent.preventDefault();
|
|
13781
|
+
}
|
|
13782
|
+
dispatchActionRequestedCustomEvent(element, {
|
|
13783
|
+
event: clickEvent,
|
|
13784
|
+
requester: element,
|
|
13785
|
+
});
|
|
13786
|
+
return;
|
|
13787
|
+
}
|
|
13788
|
+
const { form } = element;
|
|
13789
|
+
if (!form) {
|
|
13790
|
+
return;
|
|
13791
|
+
}
|
|
13792
|
+
if (wouldClickSubmitForm(clickEvent)) {
|
|
13793
|
+
clickEvent.preventDefault();
|
|
13794
|
+
}
|
|
13795
|
+
dispatchActionRequestedCustomEvent(form, {
|
|
13796
|
+
event: clickEvent,
|
|
13797
|
+
requester: element,
|
|
13798
|
+
});
|
|
13551
13799
|
};
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13800
|
+
element.addEventListener("click", onclick);
|
|
13801
|
+
addTeardown(() => {
|
|
13802
|
+
element.removeEventListener("click", onclick);
|
|
13803
|
+
});
|
|
13804
|
+
}
|
|
13805
|
+
|
|
13806
|
+
request_on_input_change: {
|
|
13807
|
+
const isInput =
|
|
13808
|
+
element.tagName === "INPUT" || element.tagName === "TEXTAREA";
|
|
13809
|
+
if (!isInput) {
|
|
13810
|
+
break request_on_input_change;
|
|
13811
|
+
}
|
|
13812
|
+
const stop = listenInputChange(element, (e) => {
|
|
13813
|
+
if (element.hasAttribute("data-action")) {
|
|
13814
|
+
dispatchActionRequestedCustomEvent(element, {
|
|
13815
|
+
event: e,
|
|
13816
|
+
requester: element,
|
|
13817
|
+
});
|
|
13818
|
+
return;
|
|
13819
|
+
}
|
|
13820
|
+
const { form } = element;
|
|
13821
|
+
if (!form) {
|
|
13822
|
+
return;
|
|
13823
|
+
}
|
|
13824
|
+
dispatchActionRequestedCustomEvent(form, {
|
|
13825
|
+
event: e,
|
|
13826
|
+
requester: element,
|
|
13827
|
+
});
|
|
13828
|
+
});
|
|
13829
|
+
addTeardown(() => {
|
|
13830
|
+
stop();
|
|
13555
13831
|
});
|
|
13556
13832
|
}
|
|
13557
13833
|
|
|
13558
13834
|
execute_on_form_submit: {
|
|
13559
|
-
|
|
13560
|
-
if (!form) {
|
|
13835
|
+
if (!isForm) {
|
|
13561
13836
|
break execute_on_form_submit;
|
|
13562
13837
|
}
|
|
13838
|
+
// We will dispatch "action" when "submit" occurs (code called from.submit() to bypass validation)
|
|
13839
|
+
const form = element;
|
|
13563
13840
|
const removeListener = addEventListener(form, "submit", (e) => {
|
|
13564
13841
|
e.preventDefault();
|
|
13565
13842
|
const actionCustomEvent = new CustomEvent("action", {
|
|
@@ -13568,12 +13845,14 @@ const installCustomConstraintValidation = (
|
|
|
13568
13845
|
event: e,
|
|
13569
13846
|
method: "rerun",
|
|
13570
13847
|
requester: form,
|
|
13571
|
-
meta: {
|
|
13848
|
+
meta: {
|
|
13849
|
+
isSubmit: true,
|
|
13850
|
+
},
|
|
13572
13851
|
},
|
|
13573
13852
|
});
|
|
13574
13853
|
form.dispatchEvent(actionCustomEvent);
|
|
13575
13854
|
});
|
|
13576
|
-
|
|
13855
|
+
addTeardown(() => {
|
|
13577
13856
|
removeListener();
|
|
13578
13857
|
});
|
|
13579
13858
|
}
|
|
@@ -13587,7 +13866,7 @@ const installCustomConstraintValidation = (
|
|
|
13587
13866
|
}
|
|
13588
13867
|
};
|
|
13589
13868
|
element.addEventListener("keydown", onkeydown);
|
|
13590
|
-
|
|
13869
|
+
addTeardown(() => {
|
|
13591
13870
|
element.removeEventListener("keydown", onkeydown);
|
|
13592
13871
|
});
|
|
13593
13872
|
}
|
|
@@ -13595,7 +13874,11 @@ const installCustomConstraintValidation = (
|
|
|
13595
13874
|
{
|
|
13596
13875
|
const onblur = () => {
|
|
13597
13876
|
if (element.value === "") {
|
|
13598
|
-
dispatchCancelCustomEvent({
|
|
13877
|
+
dispatchCancelCustomEvent({
|
|
13878
|
+
detail: {
|
|
13879
|
+
reason: "blur_empty",
|
|
13880
|
+
},
|
|
13881
|
+
});
|
|
13599
13882
|
return;
|
|
13600
13883
|
}
|
|
13601
13884
|
// if we have failed constraint, we cancel too
|
|
@@ -13610,7 +13893,7 @@ const installCustomConstraintValidation = (
|
|
|
13610
13893
|
}
|
|
13611
13894
|
};
|
|
13612
13895
|
element.addEventListener("blur", onblur);
|
|
13613
|
-
|
|
13896
|
+
addTeardown(() => {
|
|
13614
13897
|
element.removeEventListener("blur", onblur);
|
|
13615
13898
|
});
|
|
13616
13899
|
}
|
|
@@ -13618,22 +13901,105 @@ const installCustomConstraintValidation = (
|
|
|
13618
13901
|
return validationInterface;
|
|
13619
13902
|
};
|
|
13620
13903
|
|
|
13621
|
-
|
|
13904
|
+
const wouldClickSubmitForm = (clickEvent) => {
|
|
13905
|
+
if (clickEvent.defaultPrevented) {
|
|
13906
|
+
return false;
|
|
13907
|
+
}
|
|
13908
|
+
const clickTarget = clickEvent.target;
|
|
13909
|
+
const { form } = clickTarget;
|
|
13910
|
+
if (!form) {
|
|
13911
|
+
return false;
|
|
13912
|
+
}
|
|
13913
|
+
const button = clickTarget.closest("button");
|
|
13914
|
+
if (!button) {
|
|
13915
|
+
return false;
|
|
13916
|
+
}
|
|
13917
|
+
const wouldSubmitFormByType =
|
|
13918
|
+
button.type === "submit" || button.type === "image";
|
|
13919
|
+
if (wouldSubmitFormByType) {
|
|
13920
|
+
return true;
|
|
13921
|
+
}
|
|
13922
|
+
if (button.type) {
|
|
13923
|
+
return false;
|
|
13924
|
+
}
|
|
13925
|
+
if (getFirstButtonSubmittingForm(form)) {
|
|
13926
|
+
// an other button is explicitly submitting the form, this one would not submit it
|
|
13927
|
+
return false;
|
|
13928
|
+
}
|
|
13929
|
+
// this is the only button inside the form without type attribute, so it defaults to type="submit"
|
|
13930
|
+
return true;
|
|
13931
|
+
};
|
|
13932
|
+
const getFirstButtonSubmittingForm = (form) => {
|
|
13933
|
+
return form.querySelector(
|
|
13934
|
+
`button[type="submit"], input[type="submit"], input[type="image"]`,
|
|
13935
|
+
);
|
|
13936
|
+
};
|
|
13937
|
+
|
|
13938
|
+
const wouldKeydownSubmitForm = (keydownEvent) => {
|
|
13939
|
+
if (keydownEvent.defaultPrevented) {
|
|
13940
|
+
return false;
|
|
13941
|
+
}
|
|
13942
|
+
const keydownTarget = keydownEvent.target;
|
|
13943
|
+
const { form } = keydownTarget;
|
|
13944
|
+
if (!form) {
|
|
13945
|
+
return false;
|
|
13946
|
+
}
|
|
13947
|
+
if (keydownEvent.key !== "Enter") {
|
|
13948
|
+
return false;
|
|
13949
|
+
}
|
|
13950
|
+
const isTextInput =
|
|
13951
|
+
keydownTarget.tagName === "INPUT" || keydownTarget.tagName === "TEXTAREA";
|
|
13952
|
+
if (!isTextInput) {
|
|
13953
|
+
return false;
|
|
13954
|
+
}
|
|
13955
|
+
return true;
|
|
13956
|
+
};
|
|
13622
13957
|
|
|
13623
|
-
const
|
|
13958
|
+
const dispatchActionRequestedCustomEvent = (
|
|
13959
|
+
fieldOrForm,
|
|
13960
|
+
{ actionOrigin = "action_prop", event, requester },
|
|
13961
|
+
) => {
|
|
13962
|
+
const actionRequestedCustomEvent = new CustomEvent("actionrequested", {
|
|
13963
|
+
cancelable: true,
|
|
13964
|
+
detail: {
|
|
13965
|
+
actionOrigin,
|
|
13966
|
+
event,
|
|
13967
|
+
requester,
|
|
13968
|
+
},
|
|
13969
|
+
});
|
|
13970
|
+
fieldOrForm.dispatchEvent(actionRequestedCustomEvent);
|
|
13971
|
+
};
|
|
13972
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Constraint_validation
|
|
13624
13973
|
const requestSubmit = HTMLFormElement.prototype.requestSubmit;
|
|
13625
13974
|
HTMLFormElement.prototype.requestSubmit = function (submitter) {
|
|
13626
|
-
|
|
13627
|
-
const
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
for (const requestSubmitCallback of requestSubmitCallbackSet) {
|
|
13631
|
-
requestSubmitCallback(this, { submitter, preventDefault });
|
|
13632
|
-
}
|
|
13633
|
-
if (prevented) {
|
|
13975
|
+
const form = this;
|
|
13976
|
+
const isInstrumented = formInstrumentedWeakSet.has(form);
|
|
13977
|
+
if (!isInstrumented) {
|
|
13978
|
+
requestSubmit.call(form, submitter);
|
|
13634
13979
|
return;
|
|
13635
13980
|
}
|
|
13636
|
-
|
|
13981
|
+
const programmaticEvent = new CustomEvent("programmatic_requestsubmit", {
|
|
13982
|
+
cancelable: true,
|
|
13983
|
+
detail: {
|
|
13984
|
+
submitter,
|
|
13985
|
+
},
|
|
13986
|
+
});
|
|
13987
|
+
dispatchActionRequestedCustomEvent(form, {
|
|
13988
|
+
event: programmaticEvent,
|
|
13989
|
+
requester: submitter,
|
|
13990
|
+
});
|
|
13991
|
+
|
|
13992
|
+
// When all fields are valid calling the native requestSubmit would let browser go through the
|
|
13993
|
+
// standard form validation steps leading to form submission.
|
|
13994
|
+
// We don't want that because we have our own action system to handle forms
|
|
13995
|
+
// If we did that the form submission would happen in parallel of our action system
|
|
13996
|
+
// and because we listen to "submit" event to dispatch "action" event
|
|
13997
|
+
// we would end up with two actions being executed.
|
|
13998
|
+
//
|
|
13999
|
+
// In case we have discrepencies in our implementation compared to the browser standard
|
|
14000
|
+
// this also prevent the native validation message to show up.
|
|
14001
|
+
|
|
14002
|
+
// requestSubmit.call(this, submitter);
|
|
13637
14003
|
};
|
|
13638
14004
|
|
|
13639
14005
|
// const submit = HTMLFormElement.prototype.submit;
|
|
@@ -14381,10 +14747,10 @@ const useKeyboardShortcuts = (
|
|
|
14381
14747
|
}
|
|
14382
14748
|
const { action } = shortcutCandidate;
|
|
14383
14749
|
return requestAction(element, action, {
|
|
14750
|
+
actionOrigin: "keyboard_shortcut",
|
|
14384
14751
|
event: keyboardEvent,
|
|
14385
14752
|
requester: document.activeElement,
|
|
14386
14753
|
confirmMessage: shortcutCandidate.confirmMessage,
|
|
14387
|
-
actionOrigin: "keyboard_shortcut",
|
|
14388
14754
|
meta: {
|
|
14389
14755
|
shortcut: shortcutCandidate,
|
|
14390
14756
|
},
|
|
@@ -18276,33 +18642,33 @@ const SummaryMarker = ({
|
|
|
18276
18642
|
|
|
18277
18643
|
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
18278
18644
|
.navi_details {
|
|
18279
|
-
display: flex;
|
|
18280
|
-
flex-direction: column;
|
|
18281
18645
|
position: relative;
|
|
18282
18646
|
z-index: 1;
|
|
18647
|
+
display: flex;
|
|
18283
18648
|
flex-shrink: 0;
|
|
18649
|
+
flex-direction: column;
|
|
18284
18650
|
}
|
|
18285
18651
|
|
|
18286
18652
|
.navi_details > summary {
|
|
18287
|
-
flex-shrink: 0;
|
|
18288
|
-
cursor: pointer;
|
|
18289
18653
|
display: flex;
|
|
18654
|
+
flex-shrink: 0;
|
|
18290
18655
|
flex-direction: column;
|
|
18656
|
+
cursor: pointer;
|
|
18291
18657
|
user-select: none;
|
|
18292
18658
|
}
|
|
18293
18659
|
.summary_body {
|
|
18294
18660
|
display: flex;
|
|
18661
|
+
width: 100%;
|
|
18295
18662
|
flex-direction: row;
|
|
18296
18663
|
align-items: center;
|
|
18297
|
-
width: 100%;
|
|
18298
18664
|
gap: 0.2em;
|
|
18299
18665
|
}
|
|
18300
18666
|
.summary_label {
|
|
18301
18667
|
display: flex;
|
|
18668
|
+
padding-right: 10px;
|
|
18302
18669
|
flex: 1;
|
|
18303
|
-
gap: 0.2em;
|
|
18304
18670
|
align-items: center;
|
|
18305
|
-
|
|
18671
|
+
gap: 0.2em;
|
|
18306
18672
|
}
|
|
18307
18673
|
|
|
18308
18674
|
.navi_details > summary:focus {
|
|
@@ -18477,7 +18843,6 @@ const DetailsWithAction = forwardRef((props, ref) => {
|
|
|
18477
18843
|
const isOpen = toggleEvent.newState === "open";
|
|
18478
18844
|
if (isOpen) {
|
|
18479
18845
|
requestAction(toggleEvent.target, effectiveAction, {
|
|
18480
|
-
actionOrigin: "action_prop",
|
|
18481
18846
|
event: toggleEvent,
|
|
18482
18847
|
method: "run"
|
|
18483
18848
|
});
|
|
@@ -20490,8 +20855,7 @@ const InputCheckboxWithAction = forwardRef((props, ref) => {
|
|
|
20490
20855
|
loading: loading || actionLoading,
|
|
20491
20856
|
onChange: e => {
|
|
20492
20857
|
requestAction(e.target, actionBoundToUIState, {
|
|
20493
|
-
event: e
|
|
20494
|
-
actionOrigin: "action_prop"
|
|
20858
|
+
event: e
|
|
20495
20859
|
});
|
|
20496
20860
|
onChange?.(e);
|
|
20497
20861
|
}
|
|
@@ -21127,8 +21491,6 @@ const InputTextualWithAction = forwardRef((props, ref) => {
|
|
|
21127
21491
|
cancelOnBlurInvalid,
|
|
21128
21492
|
cancelOnEscape,
|
|
21129
21493
|
actionErrorEffect,
|
|
21130
|
-
onInput,
|
|
21131
|
-
onKeyDown,
|
|
21132
21494
|
...rest
|
|
21133
21495
|
} = props;
|
|
21134
21496
|
const innerRef = useRef(null);
|
|
@@ -21140,17 +21502,6 @@ const InputTextualWithAction = forwardRef((props, ref) => {
|
|
|
21140
21502
|
const executeAction = useExecuteAction(innerRef, {
|
|
21141
21503
|
errorEffect: actionErrorEffect
|
|
21142
21504
|
});
|
|
21143
|
-
const valueAtInteractionRef = useRef(null);
|
|
21144
|
-
useOnInputChange(innerRef, e => {
|
|
21145
|
-
if (valueAtInteractionRef.current !== null && e.target.value === valueAtInteractionRef.current) {
|
|
21146
|
-
valueAtInteractionRef.current = null;
|
|
21147
|
-
return;
|
|
21148
|
-
}
|
|
21149
|
-
requestAction(e.target, boundAction, {
|
|
21150
|
-
event: e,
|
|
21151
|
-
actionOrigin: "action_prop"
|
|
21152
|
-
});
|
|
21153
|
-
});
|
|
21154
21505
|
// here updating the input won't call the associated action
|
|
21155
21506
|
// (user have to blur or press enter for this to happen)
|
|
21156
21507
|
// so we can keep the ui state on cancel/abort/error and let user decide
|
|
@@ -21171,16 +21522,12 @@ const InputTextualWithAction = forwardRef((props, ref) => {
|
|
|
21171
21522
|
if (!cancelOnEscape) {
|
|
21172
21523
|
return;
|
|
21173
21524
|
}
|
|
21174
|
-
/**
|
|
21175
|
-
* Browser trigger a "change" event right after the escape is pressed
|
|
21176
|
-
* if the input value has changed.
|
|
21177
|
-
* We need to prevent the next change event otherwise we would request action when
|
|
21178
|
-
* we actually want to cancel
|
|
21179
|
-
*/
|
|
21180
|
-
valueAtInteractionRef.current = e.target.value;
|
|
21181
21525
|
}
|
|
21182
21526
|
onCancel?.(e, reason);
|
|
21183
21527
|
},
|
|
21528
|
+
onRequested: e => {
|
|
21529
|
+
forwardActionRequested(e, boundAction);
|
|
21530
|
+
},
|
|
21184
21531
|
onPrevented: onActionPrevented,
|
|
21185
21532
|
onAction: executeAction,
|
|
21186
21533
|
onStart: onActionStart,
|
|
@@ -21191,33 +21538,11 @@ const InputTextualWithAction = forwardRef((props, ref) => {
|
|
|
21191
21538
|
"data-action": boundAction.name,
|
|
21192
21539
|
...rest,
|
|
21193
21540
|
ref: innerRef,
|
|
21194
|
-
loading: loading || actionLoading
|
|
21195
|
-
onInput: e => {
|
|
21196
|
-
valueAtInteractionRef.current = null;
|
|
21197
|
-
onInput?.(e);
|
|
21198
|
-
},
|
|
21199
|
-
onKeyDown: e => {
|
|
21200
|
-
if (e.key !== "Enter") {
|
|
21201
|
-
return;
|
|
21202
|
-
}
|
|
21203
|
-
e.preventDefault();
|
|
21204
|
-
/**
|
|
21205
|
-
* Browser trigger a "change" event right after the enter is pressed
|
|
21206
|
-
* if the input value has changed.
|
|
21207
|
-
* We need to prevent the next change event otherwise we would request action twice
|
|
21208
|
-
*/
|
|
21209
|
-
valueAtInteractionRef.current = e.target.value;
|
|
21210
|
-
requestAction(e.target, boundAction, {
|
|
21211
|
-
event: e,
|
|
21212
|
-
actionOrigin: "action_prop"
|
|
21213
|
-
});
|
|
21214
|
-
onKeyDown?.(e);
|
|
21215
|
-
}
|
|
21541
|
+
loading: loading || actionLoading
|
|
21216
21542
|
});
|
|
21217
21543
|
});
|
|
21218
21544
|
const InputTextualInsideForm = forwardRef((props, ref) => {
|
|
21219
21545
|
const {
|
|
21220
|
-
onKeyDown,
|
|
21221
21546
|
// We destructure formContext to avoid passing it to the underlying input element
|
|
21222
21547
|
// eslint-disable-next-line no-unused-vars
|
|
21223
21548
|
formContext,
|
|
@@ -21225,94 +21550,10 @@ const InputTextualInsideForm = forwardRef((props, ref) => {
|
|
|
21225
21550
|
} = props;
|
|
21226
21551
|
return jsx(InputTextualBasic, {
|
|
21227
21552
|
...rest,
|
|
21228
|
-
ref: ref
|
|
21229
|
-
onKeyDown: e => {
|
|
21230
|
-
if (e.key === "Enter") {
|
|
21231
|
-
const inputElement = e.target;
|
|
21232
|
-
const {
|
|
21233
|
-
form
|
|
21234
|
-
} = inputElement;
|
|
21235
|
-
const formSubmitButton = form.querySelector("button[type='submit'], input[type='submit'], input[type='image']");
|
|
21236
|
-
e.preventDefault();
|
|
21237
|
-
form.dispatchEvent(new CustomEvent("actionrequested", {
|
|
21238
|
-
detail: {
|
|
21239
|
-
requester: formSubmitButton ? formSubmitButton : inputElement,
|
|
21240
|
-
event: e,
|
|
21241
|
-
meta: {
|
|
21242
|
-
isSubmit: true
|
|
21243
|
-
},
|
|
21244
|
-
actionOrigin: "action_prop"
|
|
21245
|
-
}
|
|
21246
|
-
}));
|
|
21247
|
-
}
|
|
21248
|
-
onKeyDown?.(e);
|
|
21249
|
-
}
|
|
21553
|
+
ref: ref
|
|
21250
21554
|
});
|
|
21251
21555
|
});
|
|
21252
|
-
const useOnInputChange = (inputRef, callback) => {
|
|
21253
|
-
// we must use a custom event listener because preact bind onChange to onInput for compat with react
|
|
21254
|
-
useEffect(() => {
|
|
21255
|
-
const input = inputRef.current;
|
|
21256
|
-
input.addEventListener("change", callback);
|
|
21257
|
-
return () => {
|
|
21258
|
-
input.removeEventListener("change", callback);
|
|
21259
|
-
};
|
|
21260
|
-
}, [callback]);
|
|
21261
21556
|
|
|
21262
|
-
// Handle programmatic value changes that don't trigger browser change events
|
|
21263
|
-
//
|
|
21264
|
-
// Problem: When input values are set programmatically (not by user typing),
|
|
21265
|
-
// browsers don't fire the 'change' event. However, our application logic
|
|
21266
|
-
// still needs to detect these changes.
|
|
21267
|
-
//
|
|
21268
|
-
// Example scenario:
|
|
21269
|
-
// 1. User starts editing (letter key pressed, value set programmatically)
|
|
21270
|
-
// 2. User doesn't type anything additional (this is the key part)
|
|
21271
|
-
// 3. User clicks outside to finish editing
|
|
21272
|
-
// 4. Without this code, no change event would fire despite the fact that the input value did change from its original state
|
|
21273
|
-
//
|
|
21274
|
-
// This distinction is crucial because:
|
|
21275
|
-
//
|
|
21276
|
-
// - If the user typed additional text after the initial programmatic value,
|
|
21277
|
-
// the browser would fire change events normally
|
|
21278
|
-
// - But when they don't type anything else, the browser considers it as "no user interaction"
|
|
21279
|
-
// even though the programmatic initial value represents a meaningful change
|
|
21280
|
-
const valueAtStartRef = useRef();
|
|
21281
|
-
const interactedRef = useRef(false);
|
|
21282
|
-
useLayoutEffect(() => {
|
|
21283
|
-
const input = inputRef.current;
|
|
21284
|
-
valueAtStartRef.current = input.value;
|
|
21285
|
-
const onfocus = () => {
|
|
21286
|
-
interactedRef.current = false;
|
|
21287
|
-
valueAtStartRef.current = input.value;
|
|
21288
|
-
};
|
|
21289
|
-
const oninput = e => {
|
|
21290
|
-
if (!e.isTrusted) {
|
|
21291
|
-
// non trusted "input" events will be ignored by the browser when deciding to fire "change" event
|
|
21292
|
-
// we ignore them too
|
|
21293
|
-
return;
|
|
21294
|
-
}
|
|
21295
|
-
interactedRef.current = true;
|
|
21296
|
-
};
|
|
21297
|
-
const onblur = e => {
|
|
21298
|
-
if (interactedRef.current) {
|
|
21299
|
-
return;
|
|
21300
|
-
}
|
|
21301
|
-
if (valueAtStartRef.current === input.value) {
|
|
21302
|
-
return;
|
|
21303
|
-
}
|
|
21304
|
-
callback(e);
|
|
21305
|
-
};
|
|
21306
|
-
input.addEventListener("focus", onfocus);
|
|
21307
|
-
input.addEventListener("input", oninput);
|
|
21308
|
-
input.addEventListener("blur", onblur);
|
|
21309
|
-
return () => {
|
|
21310
|
-
input.removeEventListener("focus", onfocus);
|
|
21311
|
-
input.removeEventListener("input", oninput);
|
|
21312
|
-
input.removeEventListener("blur", onblur);
|
|
21313
|
-
};
|
|
21314
|
-
}, []);
|
|
21315
|
-
};
|
|
21316
21557
|
// As explained in https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/datetime-local#setting_timezones
|
|
21317
21558
|
// datetime-local does not support timezones
|
|
21318
21559
|
const convertToLocalTimezone = dateTimeString => {
|
|
@@ -21536,6 +21777,7 @@ const useFormEvents = (
|
|
|
21536
21777
|
elementRef,
|
|
21537
21778
|
{
|
|
21538
21779
|
onFormReset,
|
|
21780
|
+
onFormActionRequested,
|
|
21539
21781
|
onFormActionPrevented,
|
|
21540
21782
|
onFormActionStart,
|
|
21541
21783
|
onFormActionAbort,
|
|
@@ -21544,6 +21786,7 @@ const useFormEvents = (
|
|
|
21544
21786
|
},
|
|
21545
21787
|
) => {
|
|
21546
21788
|
onFormReset = useStableCallback(onFormReset);
|
|
21789
|
+
onFormActionRequested = useStableCallback(onFormActionRequested);
|
|
21547
21790
|
onFormActionPrevented = useStableCallback(onFormActionPrevented);
|
|
21548
21791
|
onFormActionStart = useStableCallback(onFormActionStart);
|
|
21549
21792
|
onFormActionAbort = useStableCallback(onFormActionAbort);
|
|
@@ -21567,6 +21810,7 @@ const useFormEvents = (
|
|
|
21567
21810
|
}
|
|
21568
21811
|
return addManyEventListeners(form, {
|
|
21569
21812
|
reset: onFormReset,
|
|
21813
|
+
actionrequested: onFormActionRequested,
|
|
21570
21814
|
actionprevented: onFormActionPrevented,
|
|
21571
21815
|
actionstart: onFormActionStart,
|
|
21572
21816
|
actionabort: onFormActionAbort,
|
|
@@ -21575,6 +21819,7 @@ const useFormEvents = (
|
|
|
21575
21819
|
});
|
|
21576
21820
|
}, [
|
|
21577
21821
|
onFormReset,
|
|
21822
|
+
onFormActionRequested,
|
|
21578
21823
|
onFormActionPrevented,
|
|
21579
21824
|
onFormActionStart,
|
|
21580
21825
|
onFormActionAbort,
|
|
@@ -21821,7 +22066,6 @@ const ButtonWithAction = forwardRef((props, ref) => {
|
|
|
21821
22066
|
const {
|
|
21822
22067
|
action,
|
|
21823
22068
|
loading,
|
|
21824
|
-
onClick,
|
|
21825
22069
|
actionErrorEffect,
|
|
21826
22070
|
onActionPrevented,
|
|
21827
22071
|
onActionStart,
|
|
@@ -21839,22 +22083,15 @@ const ButtonWithAction = forwardRef((props, ref) => {
|
|
|
21839
22083
|
const executeAction = useExecuteAction(innerRef, {
|
|
21840
22084
|
errorEffect: actionErrorEffect
|
|
21841
22085
|
});
|
|
22086
|
+
const innerLoading = loading || actionLoading;
|
|
21842
22087
|
useActionEvents(innerRef, {
|
|
21843
22088
|
onPrevented: onActionPrevented,
|
|
22089
|
+
onRequested: e => forwardActionRequested(e, boundAction),
|
|
21844
22090
|
onAction: executeAction,
|
|
21845
22091
|
onStart: onActionStart,
|
|
21846
22092
|
onError: onActionError,
|
|
21847
22093
|
onEnd: onActionEnd
|
|
21848
22094
|
});
|
|
21849
|
-
const handleClick = event => {
|
|
21850
|
-
event.preventDefault();
|
|
21851
|
-
const button = innerRef.current;
|
|
21852
|
-
requestAction(button, boundAction, {
|
|
21853
|
-
event,
|
|
21854
|
-
actionOrigin: "action_prop"
|
|
21855
|
-
});
|
|
21856
|
-
};
|
|
21857
|
-
const innerLoading = loading || actionLoading;
|
|
21858
22095
|
return jsx(ButtonBasic
|
|
21859
22096
|
// put data-action first to help find it in devtools
|
|
21860
22097
|
, {
|
|
@@ -21862,10 +22099,6 @@ const ButtonWithAction = forwardRef((props, ref) => {
|
|
|
21862
22099
|
...rest,
|
|
21863
22100
|
ref: innerRef,
|
|
21864
22101
|
loading: innerLoading,
|
|
21865
|
-
onClick: event => {
|
|
21866
|
-
handleClick(event);
|
|
21867
|
-
onClick?.(event);
|
|
21868
|
-
},
|
|
21869
22102
|
children: children
|
|
21870
22103
|
});
|
|
21871
22104
|
});
|
|
@@ -21874,7 +22107,6 @@ const ButtonInsideForm = forwardRef((props, ref) => {
|
|
|
21874
22107
|
// eslint-disable-next-line no-unused-vars
|
|
21875
22108
|
formContext,
|
|
21876
22109
|
type,
|
|
21877
|
-
onClick,
|
|
21878
22110
|
children,
|
|
21879
22111
|
loading,
|
|
21880
22112
|
readOnly,
|
|
@@ -21882,50 +22114,14 @@ const ButtonInsideForm = forwardRef((props, ref) => {
|
|
|
21882
22114
|
} = props;
|
|
21883
22115
|
const innerRef = useRef();
|
|
21884
22116
|
useImperativeHandle(ref, () => innerRef.current);
|
|
21885
|
-
const wouldSubmitFormByType = type === "submit" || type === "image";
|
|
21886
22117
|
const innerLoading = loading;
|
|
21887
22118
|
const innerReadOnly = readOnly;
|
|
21888
|
-
const handleClick = event => {
|
|
21889
|
-
const buttonElement = innerRef.current;
|
|
21890
|
-
const {
|
|
21891
|
-
form
|
|
21892
|
-
} = buttonElement;
|
|
21893
|
-
let wouldSubmitForm = wouldSubmitFormByType;
|
|
21894
|
-
if (!wouldSubmitForm && type === undefined) {
|
|
21895
|
-
const formSubmitButton = form.querySelector("button[type='submit'], input[type='submit'], input[type='image']");
|
|
21896
|
-
const wouldSubmitFormBecauseSingleButtonWithoutType = !formSubmitButton;
|
|
21897
|
-
wouldSubmitForm = wouldSubmitFormBecauseSingleButtonWithoutType;
|
|
21898
|
-
}
|
|
21899
|
-
if (!wouldSubmitForm) {
|
|
21900
|
-
if (buttonElement.hasAttribute("data-readonly")) {
|
|
21901
|
-
event.preventDefault();
|
|
21902
|
-
}
|
|
21903
|
-
return;
|
|
21904
|
-
}
|
|
21905
|
-
// prevent default behavior that would submit the form
|
|
21906
|
-
// we want to go through the action execution process (with validation and all)
|
|
21907
|
-
event.preventDefault();
|
|
21908
|
-
form.dispatchEvent(new CustomEvent("actionrequested", {
|
|
21909
|
-
detail: {
|
|
21910
|
-
requester: buttonElement,
|
|
21911
|
-
event,
|
|
21912
|
-
meta: {
|
|
21913
|
-
isSubmit: true
|
|
21914
|
-
},
|
|
21915
|
-
actionOrigin: "action_prop"
|
|
21916
|
-
}
|
|
21917
|
-
}));
|
|
21918
|
-
};
|
|
21919
22119
|
return jsx(ButtonBasic, {
|
|
21920
22120
|
...rest,
|
|
21921
22121
|
ref: innerRef,
|
|
21922
22122
|
type: type,
|
|
21923
22123
|
loading: innerLoading,
|
|
21924
22124
|
readOnly: innerReadOnly,
|
|
21925
|
-
onClick: event => {
|
|
21926
|
-
handleClick(event);
|
|
21927
|
-
onClick?.(event);
|
|
21928
|
-
},
|
|
21929
22125
|
children: children
|
|
21930
22126
|
});
|
|
21931
22127
|
});
|
|
@@ -21939,7 +22135,6 @@ const ButtonWithActionInsideForm = forwardRef((props, ref) => {
|
|
|
21939
22135
|
action,
|
|
21940
22136
|
loading,
|
|
21941
22137
|
children,
|
|
21942
|
-
onClick,
|
|
21943
22138
|
onActionPrevented,
|
|
21944
22139
|
onActionStart,
|
|
21945
22140
|
onActionAbort,
|
|
@@ -21988,16 +22183,8 @@ const ButtonWithActionInsideForm = forwardRef((props, ref) => {
|
|
|
21988
22183
|
ref: innerRef,
|
|
21989
22184
|
type: type,
|
|
21990
22185
|
loading: innerLoading,
|
|
21991
|
-
|
|
21992
|
-
|
|
21993
|
-
const form = button.form;
|
|
21994
|
-
event.preventDefault();
|
|
21995
|
-
requestAction(form, actionBoundToFormParams, {
|
|
21996
|
-
event,
|
|
21997
|
-
requester: button,
|
|
21998
|
-
actionOrigin: "action_prop"
|
|
21999
|
-
});
|
|
22000
|
-
onClick?.(event);
|
|
22186
|
+
onactionrequested: e => {
|
|
22187
|
+
forwardActionRequested(e, actionBoundToFormParams, e.target.form);
|
|
22001
22188
|
},
|
|
22002
22189
|
children: children
|
|
22003
22190
|
});
|
|
@@ -22148,8 +22335,7 @@ const CheckboxListWithAction = forwardRef((props, ref) => {
|
|
|
22148
22335
|
const checkbox = event.target;
|
|
22149
22336
|
requestAction(checkboxList, boundAction, {
|
|
22150
22337
|
event,
|
|
22151
|
-
requester: checkbox
|
|
22152
|
-
actionOrigin: "action_prop"
|
|
22338
|
+
requester: checkbox
|
|
22153
22339
|
});
|
|
22154
22340
|
},
|
|
22155
22341
|
loading: loading || actionLoading,
|
|
@@ -22374,13 +22560,7 @@ const FormWithAction = forwardRef((props, ref) => {
|
|
|
22374
22560
|
useActionEvents(innerRef, {
|
|
22375
22561
|
onPrevented: onActionPrevented,
|
|
22376
22562
|
onRequested: e => {
|
|
22377
|
-
|
|
22378
|
-
requestAction(form, actionBoundToUIState, {
|
|
22379
|
-
requester: e.detail?.requester,
|
|
22380
|
-
event: e.detail?.event || e,
|
|
22381
|
-
meta: e.detail?.meta,
|
|
22382
|
-
actionOrigin: e.detail?.actionOrigin
|
|
22383
|
-
});
|
|
22563
|
+
forwardActionRequested(e, actionBoundToUIState);
|
|
22384
22564
|
},
|
|
22385
22565
|
onAction: e => {
|
|
22386
22566
|
const form = innerRef.current;
|
|
@@ -22416,15 +22596,6 @@ const FormWithAction = forwardRef((props, ref) => {
|
|
|
22416
22596
|
...rest,
|
|
22417
22597
|
ref: innerRef,
|
|
22418
22598
|
loading: innerLoading,
|
|
22419
|
-
onrequestsubmit: e => {
|
|
22420
|
-
// prevent "submit" event that would be dispatched by the browser after form.requestSubmit()
|
|
22421
|
-
// (not super important because our <form> listen the "action" and do does preventDefault on "submit")
|
|
22422
|
-
e.preventDefault();
|
|
22423
|
-
requestAction(e.target, actionBoundToUIState, {
|
|
22424
|
-
event: e,
|
|
22425
|
-
actionOrigin: "action_prop"
|
|
22426
|
-
});
|
|
22427
|
-
},
|
|
22428
22599
|
children: jsx(FormActionContext.Provider, {
|
|
22429
22600
|
value: actionBoundToUIState,
|
|
22430
22601
|
children: jsx(LoadingElementContext.Provider, {
|
|
@@ -22591,8 +22762,7 @@ const RadioListWithAction = forwardRef((props, ref) => {
|
|
|
22591
22762
|
const radioListContainer = innerRef.current;
|
|
22592
22763
|
requestAction(radioListContainer, boundAction, {
|
|
22593
22764
|
event: e,
|
|
22594
|
-
requester: radio
|
|
22595
|
-
actionOrigin: "action_prop"
|
|
22765
|
+
requester: radio
|
|
22596
22766
|
});
|
|
22597
22767
|
},
|
|
22598
22768
|
loading: loading || actionLoading,
|
|
@@ -22668,7 +22838,6 @@ const SelectControlled = forwardRef((props, ref) => {
|
|
|
22668
22838
|
const selectElement = jsx("select", {
|
|
22669
22839
|
className: "navi_select",
|
|
22670
22840
|
ref: innerRef,
|
|
22671
|
-
"data-field": "",
|
|
22672
22841
|
"data-readonly": readOnly && !disabled ? "" : undefined,
|
|
22673
22842
|
onKeyDown: e => {
|
|
22674
22843
|
if (readOnly) {
|
|
@@ -22801,8 +22970,7 @@ const SelectWithAction = forwardRef((props, ref) => {
|
|
|
22801
22970
|
const optionSelected = select.querySelector(`option[value="${selectedValue}"]`);
|
|
22802
22971
|
requestAction(radioListContainer, boundAction, {
|
|
22803
22972
|
event,
|
|
22804
|
-
requester: optionSelected
|
|
22805
|
-
actionOrigin: "action_prop"
|
|
22973
|
+
requester: optionSelected
|
|
22806
22974
|
});
|
|
22807
22975
|
},
|
|
22808
22976
|
...rest,
|
|
@@ -24295,49 +24463,124 @@ const createSelectionKeyboardShortcuts = (selectionController, {
|
|
|
24295
24463
|
}];
|
|
24296
24464
|
};
|
|
24297
24465
|
|
|
24466
|
+
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
24467
|
+
:root {
|
|
24468
|
+
--navi-icon-align-y: center;
|
|
24469
|
+
}
|
|
24470
|
+
|
|
24471
|
+
.navi_text {
|
|
24472
|
+
display: inline-flex;
|
|
24473
|
+
align-items: baseline;
|
|
24474
|
+
gap: 0.1em;
|
|
24475
|
+
}
|
|
24476
|
+
|
|
24477
|
+
.navi_icon {
|
|
24478
|
+
--align-y: var(--navi-icon-align-y, center);
|
|
24479
|
+
|
|
24480
|
+
display: inline-flex;
|
|
24481
|
+
width: 1em;
|
|
24482
|
+
height: 1em;
|
|
24483
|
+
flex-shrink: 0;
|
|
24484
|
+
align-self: var(--align-y);
|
|
24485
|
+
line-height: 1em;
|
|
24486
|
+
}
|
|
24487
|
+
`;
|
|
24488
|
+
const useTypographyStyle = props => {
|
|
24489
|
+
const color = props.color;
|
|
24490
|
+
const bold = props.bold;
|
|
24491
|
+
const italic = props.italic;
|
|
24492
|
+
const underline = props.underline;
|
|
24493
|
+
const size = props.size;
|
|
24494
|
+
delete props.color;
|
|
24495
|
+
delete props.bold;
|
|
24496
|
+
delete props.italic;
|
|
24497
|
+
delete props.underline;
|
|
24498
|
+
delete props.size;
|
|
24499
|
+
return {
|
|
24500
|
+
color,
|
|
24501
|
+
fontWeight: bold ? "bold" : bold === undefined ? undefined : "normal",
|
|
24502
|
+
fontStyle: italic ? "italic" : italic === undefined ? undefined : "normal",
|
|
24503
|
+
fontSize: size,
|
|
24504
|
+
textDecoration: underline ? "underline" : underline === undefined ? undefined : "none"
|
|
24505
|
+
};
|
|
24506
|
+
};
|
|
24507
|
+
const Text = ({
|
|
24508
|
+
style,
|
|
24509
|
+
children,
|
|
24510
|
+
...rest
|
|
24511
|
+
}) => {
|
|
24512
|
+
const {
|
|
24513
|
+
all
|
|
24514
|
+
} = useLayoutStyle(rest);
|
|
24515
|
+
const innerStyle = withPropsStyle({
|
|
24516
|
+
...all,
|
|
24517
|
+
...useTypographyStyle(rest)
|
|
24518
|
+
}, style);
|
|
24519
|
+
return jsx("span", {
|
|
24520
|
+
...rest,
|
|
24521
|
+
className: "navi_text",
|
|
24522
|
+
style: innerStyle,
|
|
24523
|
+
children: children
|
|
24524
|
+
});
|
|
24525
|
+
};
|
|
24526
|
+
const Icon = ({
|
|
24527
|
+
style,
|
|
24528
|
+
children,
|
|
24529
|
+
...rest
|
|
24530
|
+
}) => {
|
|
24531
|
+
const {
|
|
24532
|
+
all
|
|
24533
|
+
} = useLayoutStyle(rest);
|
|
24534
|
+
const innerStyle = withPropsStyle({
|
|
24535
|
+
...all,
|
|
24536
|
+
...useTypographyStyle(rest)
|
|
24537
|
+
}, style);
|
|
24538
|
+
return jsx("span", {
|
|
24539
|
+
...rest,
|
|
24540
|
+
className: "navi_icon",
|
|
24541
|
+
style: innerStyle,
|
|
24542
|
+
children: children
|
|
24543
|
+
});
|
|
24544
|
+
};
|
|
24545
|
+
|
|
24298
24546
|
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
24299
24547
|
.navi_link {
|
|
24300
24548
|
border-radius: 2px;
|
|
24301
24549
|
}
|
|
24302
|
-
|
|
24550
|
+
/* Focus */
|
|
24303
24551
|
.navi_link:focus {
|
|
24304
24552
|
position: relative;
|
|
24305
24553
|
z-index: 1; /* Ensure focus outline is above other elements */
|
|
24306
24554
|
}
|
|
24307
|
-
|
|
24308
|
-
.navi_link[data-
|
|
24309
|
-
|
|
24310
|
-
opacity: 0.5;
|
|
24311
|
-
}
|
|
24312
|
-
|
|
24313
|
-
.navi_link[inert] {
|
|
24314
|
-
pointer-events: none;
|
|
24555
|
+
/* Visited */
|
|
24556
|
+
.navi_link[data-visited] {
|
|
24557
|
+
color: light-dark(#6a1b9a, #ab47bc);
|
|
24315
24558
|
}
|
|
24316
|
-
|
|
24559
|
+
/* Selected */
|
|
24317
24560
|
.navi_link[aria-selected] {
|
|
24318
24561
|
position: relative;
|
|
24319
24562
|
}
|
|
24320
|
-
|
|
24563
|
+
.navi_link[aria-selected="true"] {
|
|
24564
|
+
background-color: light-dark(#bbdefb, #2563eb);
|
|
24565
|
+
}
|
|
24321
24566
|
.navi_link[aria-selected] input[type="checkbox"] {
|
|
24322
24567
|
position: absolute;
|
|
24323
24568
|
opacity: 0;
|
|
24324
24569
|
}
|
|
24325
|
-
|
|
24326
|
-
/* Visual feedback for selected state */
|
|
24327
|
-
.navi_link[aria-selected="true"] {
|
|
24328
|
-
background-color: light-dark(#bbdefb, #2563eb);
|
|
24329
|
-
}
|
|
24330
|
-
|
|
24570
|
+
/* Active */
|
|
24331
24571
|
.navi_link[data-active] {
|
|
24332
24572
|
font-weight: bold;
|
|
24333
24573
|
}
|
|
24334
|
-
|
|
24335
|
-
.navi_link[data-
|
|
24336
|
-
|
|
24574
|
+
/* Readonly */
|
|
24575
|
+
.navi_link[data-readonly] > * {
|
|
24576
|
+
opacity: 0.5;
|
|
24337
24577
|
}
|
|
24338
|
-
|
|
24339
|
-
.navi_link[
|
|
24340
|
-
|
|
24578
|
+
/* Disabled */
|
|
24579
|
+
.navi_link[inert] {
|
|
24580
|
+
pointer-events: none;
|
|
24581
|
+
}
|
|
24582
|
+
.navi_link[inert] > * {
|
|
24583
|
+
opacity: 0.5;
|
|
24341
24584
|
}
|
|
24342
24585
|
`;
|
|
24343
24586
|
const Link = forwardRef((props, ref) => {
|
|
@@ -24389,7 +24632,10 @@ const LinkPlain = forwardRef((props, ref) => {
|
|
|
24389
24632
|
const {
|
|
24390
24633
|
all
|
|
24391
24634
|
} = useLayoutStyle(rest);
|
|
24392
|
-
const innerStyle = withPropsStyle(
|
|
24635
|
+
const innerStyle = withPropsStyle({
|
|
24636
|
+
...all,
|
|
24637
|
+
...useTypographyStyle(rest)
|
|
24638
|
+
}, style);
|
|
24393
24639
|
return jsx(LoadableInlineElement, {
|
|
24394
24640
|
loading: loading,
|
|
24395
24641
|
color: "light-dark(#355fcc, #3b82f6)",
|
|
@@ -24401,7 +24647,7 @@ const LinkPlain = forwardRef((props, ref) => {
|
|
|
24401
24647
|
style: innerStyle,
|
|
24402
24648
|
"aria-busy": loading,
|
|
24403
24649
|
inert: disabled,
|
|
24404
|
-
"data-
|
|
24650
|
+
"data-disabled": disabled ? "" : undefined,
|
|
24405
24651
|
"data-readonly": readOnly ? "" : undefined,
|
|
24406
24652
|
"data-active": active ? "" : undefined,
|
|
24407
24653
|
"data-visited": visited || isVisited ? "" : undefined,
|
|
@@ -28213,79 +28459,6 @@ const Overflow = ({
|
|
|
28213
28459
|
});
|
|
28214
28460
|
};
|
|
28215
28461
|
|
|
28216
|
-
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
28217
|
-
:root {
|
|
28218
|
-
--navi-icon-align-y: center;
|
|
28219
|
-
}
|
|
28220
|
-
|
|
28221
|
-
.navi_text {
|
|
28222
|
-
display: inline-flex;
|
|
28223
|
-
align-items: baseline;
|
|
28224
|
-
gap: 0.1em;
|
|
28225
|
-
}
|
|
28226
|
-
|
|
28227
|
-
.navi_icon {
|
|
28228
|
-
--align-y: var(--navi-icon-align-y, center);
|
|
28229
|
-
|
|
28230
|
-
display: inline-flex;
|
|
28231
|
-
width: 1em;
|
|
28232
|
-
height: 1em;
|
|
28233
|
-
flex-shrink: 0;
|
|
28234
|
-
align-self: var(--align-y);
|
|
28235
|
-
line-height: 1em;
|
|
28236
|
-
}
|
|
28237
|
-
`;
|
|
28238
|
-
const Text = ({
|
|
28239
|
-
color,
|
|
28240
|
-
bold,
|
|
28241
|
-
italic,
|
|
28242
|
-
underline,
|
|
28243
|
-
size,
|
|
28244
|
-
style,
|
|
28245
|
-
children,
|
|
28246
|
-
...rest
|
|
28247
|
-
}) => {
|
|
28248
|
-
const {
|
|
28249
|
-
all
|
|
28250
|
-
} = useLayoutStyle(rest);
|
|
28251
|
-
const innerStyle = withPropsStyle({
|
|
28252
|
-
...all,
|
|
28253
|
-
color,
|
|
28254
|
-
fontWeight: bold ? "bold" : undefined,
|
|
28255
|
-
fontStyle: italic ? "italic" : undefined,
|
|
28256
|
-
fontSize: size,
|
|
28257
|
-
textDecoration: underline ? "underline" : undefined
|
|
28258
|
-
}, style);
|
|
28259
|
-
return jsx("span", {
|
|
28260
|
-
...rest,
|
|
28261
|
-
className: "navi_text",
|
|
28262
|
-
style: innerStyle,
|
|
28263
|
-
children: children
|
|
28264
|
-
});
|
|
28265
|
-
};
|
|
28266
|
-
const Icon = ({
|
|
28267
|
-
color,
|
|
28268
|
-
size,
|
|
28269
|
-
style,
|
|
28270
|
-
children,
|
|
28271
|
-
...rest
|
|
28272
|
-
}) => {
|
|
28273
|
-
const {
|
|
28274
|
-
all
|
|
28275
|
-
} = useLayoutStyle(rest);
|
|
28276
|
-
const innerStyle = withPropsStyle({
|
|
28277
|
-
...all,
|
|
28278
|
-
color,
|
|
28279
|
-
fontSize: size
|
|
28280
|
-
}, style);
|
|
28281
|
-
return jsx("span", {
|
|
28282
|
-
...rest,
|
|
28283
|
-
className: "navi_icon",
|
|
28284
|
-
style: innerStyle,
|
|
28285
|
-
children: children
|
|
28286
|
-
});
|
|
28287
|
-
};
|
|
28288
|
-
|
|
28289
28462
|
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
28290
28463
|
.text_and_count {
|
|
28291
28464
|
display: flex;
|
|
@@ -28518,4 +28691,4 @@ const useDependenciesDiff = (inputs) => {
|
|
|
28518
28691
|
return diffRef.current;
|
|
28519
28692
|
};
|
|
28520
28693
|
|
|
28521
|
-
export { ActionRenderer, ActiveKeyboardShortcuts, Button, Checkbox, CheckboxList, Col, Colgroup, Details, Editable, ErrorBoundaryContext, FlexColumn, FlexItem, FlexRow, FontSizedSvg, Form, Icon, IconAndText, Input, Label, Link, LinkWithIcon, Overflow, Radio, RadioList, Route, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, Select, SelectionContext, Spacing, SummaryMarker, Tab, TabList, Table, TableCell, Tbody, Text, TextAndCount, Thead, Tr, UITransition, actionIntegratedVia, addCustomMessage, createAction, createSelectionKeyboardShortcuts, createUniqueValueConstraint, defineRoutes, enableDebugActions, enableDebugOnDocumentLoading, goBack, goForward, goTo, isCellSelected, isColumnSelected, isRowSelected, openCallout, rawUrlPart, reload, removeCustomMessage, rerunActions, resource, setBaseUrl, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useCellsAndColumns, useDependenciesDiff, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, valueInLocalStorage };
|
|
28694
|
+
export { ActionRenderer, ActiveKeyboardShortcuts, Button, Checkbox, CheckboxList, Col, Colgroup, Details, Editable, ErrorBoundaryContext, FlexColumn, FlexItem, FlexRow, FontSizedSvg, Form, Icon, IconAndText, Input, Label, Link, LinkWithIcon, Overflow, Radio, RadioList, Route, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, Select, SelectionContext, Spacing, SummaryMarker, Tab, TabList, Table, TableCell, Tbody, Text, TextAndCount, Thead, Tr, UITransition, actionIntegratedVia, addCustomMessage, createAction, createSelectionKeyboardShortcuts, createUniqueValueConstraint, defineRoutes, enableDebugActions, enableDebugOnDocumentLoading, forwardActionRequested, goBack, goForward, goTo, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, openCallout, rawUrlPart, reload, removeCustomMessage, rerunActions, resource, setBaseUrl, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useCellsAndColumns, useDependenciesDiff, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, valueInLocalStorage };
|