@jsenv/navi 0.14.16 → 0.14.17
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 +474 -165
- package/dist/jsenv_navi.js.map +40 -26
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -4,7 +4,7 @@ import { jsxs, jsx, Fragment } from "preact/jsx-runtime";
|
|
|
4
4
|
import { createIterableWeakSet, mergeOneStyle, stringifyStyle, createPubSub, mergeTwoStyles, normalizeStyles, createGroupTransitionController, getElementSignature, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, resolveCSSSize, findBefore, findAfter, createValueEffect, createStyleController, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, allowWheelThrough, resolveCSSColor, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, hasCSSSizeUnit, activeElementSignal, canInterceptKeys, pickLightOrDark, resolveColorLuminance, initFocusGroup, dragAfterThreshold, getScrollContainer, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement, elementIsFocusable } from "@jsenv/dom";
|
|
5
5
|
import { prefixFirstAndIndentRemainingLines } from "@jsenv/humanize";
|
|
6
6
|
import { effect, signal, computed, batch, useSignal } from "@preact/signals";
|
|
7
|
-
import { createContext, toChildArray, createRef, cloneElement } from "preact";
|
|
7
|
+
import { createContext, render, isValidElement, toChildArray, createRef, cloneElement } from "preact";
|
|
8
8
|
import { createPortal, forwardRef } from "preact/compat";
|
|
9
9
|
|
|
10
10
|
const actionPrivatePropertiesWeakMap = new WeakMap();
|
|
@@ -4736,6 +4736,23 @@ const DIMENSION_PROPS = {
|
|
|
4736
4736
|
height: PASS_THROUGH,
|
|
4737
4737
|
minHeight: PASS_THROUGH,
|
|
4738
4738
|
maxHeight: PASS_THROUGH,
|
|
4739
|
+
square: (v) => {
|
|
4740
|
+
if (!v) {
|
|
4741
|
+
return null;
|
|
4742
|
+
}
|
|
4743
|
+
return {
|
|
4744
|
+
aspectRatio: "1/1",
|
|
4745
|
+
};
|
|
4746
|
+
},
|
|
4747
|
+
circle: (v) => {
|
|
4748
|
+
if (!v) {
|
|
4749
|
+
return null;
|
|
4750
|
+
}
|
|
4751
|
+
return {
|
|
4752
|
+
aspectRatio: "1/1",
|
|
4753
|
+
borderRadius: "100%",
|
|
4754
|
+
};
|
|
4755
|
+
},
|
|
4739
4756
|
expand: applyOnTwoProps("expandX", "expandY"),
|
|
4740
4757
|
shrink: applyOnTwoProps("shrinkX", "shrinkY"),
|
|
4741
4758
|
// apply after width/height to override if both are set
|
|
@@ -5625,12 +5642,18 @@ const initPseudoStyles = (
|
|
|
5625
5642
|
return teardown;
|
|
5626
5643
|
};
|
|
5627
5644
|
|
|
5628
|
-
const applyStyle = (
|
|
5645
|
+
const applyStyle = (
|
|
5646
|
+
element,
|
|
5647
|
+
style,
|
|
5648
|
+
pseudoState,
|
|
5649
|
+
pseudoNamedStyles,
|
|
5650
|
+
preventInitialTransition,
|
|
5651
|
+
) => {
|
|
5629
5652
|
if (!element) {
|
|
5630
5653
|
return;
|
|
5631
5654
|
}
|
|
5632
5655
|
const styleToApply = getStyleToApply(style, pseudoState, pseudoNamedStyles);
|
|
5633
|
-
updateStyle(element, styleToApply);
|
|
5656
|
+
updateStyle(element, styleToApply, preventInitialTransition);
|
|
5634
5657
|
};
|
|
5635
5658
|
|
|
5636
5659
|
const PSEUDO_STATE_DEFAULT = {};
|
|
@@ -5684,11 +5707,10 @@ const getStyleToApply = (styles, pseudoState, pseudoNamedStyles) => {
|
|
|
5684
5707
|
};
|
|
5685
5708
|
|
|
5686
5709
|
const styleKeySetWeakMap = new WeakMap();
|
|
5687
|
-
const
|
|
5710
|
+
const elementTransitionWeakMap = new WeakMap();
|
|
5688
5711
|
const elementRenderedWeakSet = new WeakSet();
|
|
5689
5712
|
const NO_STYLE_KEY_SET = new Set();
|
|
5690
|
-
|
|
5691
|
-
const updateStyle = (element, style) => {
|
|
5713
|
+
const updateStyle = (element, style, preventInitialTransition) => {
|
|
5692
5714
|
const styleKeySet = style ? new Set(Object.keys(style)) : NO_STYLE_KEY_SET;
|
|
5693
5715
|
const oldStyleKeySet = styleKeySetWeakMap.get(element) || NO_STYLE_KEY_SET;
|
|
5694
5716
|
// TRANSITION ANTI-FLICKER STRATEGY:
|
|
@@ -5703,26 +5725,26 @@ const updateStyle = (element, style) => {
|
|
|
5703
5725
|
let styleKeySetToApply = styleKeySet;
|
|
5704
5726
|
if (!elementRenderedWeakSet.has(element)) {
|
|
5705
5727
|
const hasTransition = styleKeySet.has("transition");
|
|
5706
|
-
if (hasTransition) {
|
|
5707
|
-
if (
|
|
5708
|
-
|
|
5728
|
+
if (hasTransition || preventInitialTransition) {
|
|
5729
|
+
if (elementTransitionWeakMap.has(element)) {
|
|
5730
|
+
elementTransitionWeakMap.set(element, style?.transition);
|
|
5709
5731
|
} else {
|
|
5710
5732
|
element.style.transition = "none";
|
|
5711
|
-
|
|
5733
|
+
elementTransitionWeakMap.set(element, style?.transition);
|
|
5712
5734
|
}
|
|
5713
5735
|
// Don't apply the transition property now - we've set it to "none" temporarily
|
|
5714
5736
|
styleKeySetToApply = new Set(styleKeySet);
|
|
5715
5737
|
styleKeySetToApply.delete("transition");
|
|
5716
5738
|
}
|
|
5717
5739
|
requestAnimationFrame(() => {
|
|
5718
|
-
if (
|
|
5719
|
-
const transitionToRestore =
|
|
5740
|
+
if (elementTransitionWeakMap.has(element)) {
|
|
5741
|
+
const transitionToRestore = elementTransitionWeakMap.get(element);
|
|
5720
5742
|
if (transitionToRestore === undefined) {
|
|
5721
5743
|
element.style.transition = "";
|
|
5722
5744
|
} else {
|
|
5723
5745
|
element.style.transition = transitionToRestore;
|
|
5724
5746
|
}
|
|
5725
|
-
|
|
5747
|
+
elementTransitionWeakMap.delete(element);
|
|
5726
5748
|
}
|
|
5727
5749
|
elementRenderedWeakSet.add(element);
|
|
5728
5750
|
});
|
|
@@ -5798,6 +5820,10 @@ const Box = props => {
|
|
|
5798
5820
|
// -> introduced for <Input /> with a wrapped for loading, checkboxes, etc
|
|
5799
5821
|
pseudoStateSelector,
|
|
5800
5822
|
hasChildFunction,
|
|
5823
|
+
// preventInitialTransition can be used to prevent transition on mount
|
|
5824
|
+
// (when transition is set via props, this is done automatically)
|
|
5825
|
+
// so this prop is useful only when transition is enabled from "outside" (via CSS)
|
|
5826
|
+
preventInitialTransition,
|
|
5801
5827
|
children,
|
|
5802
5828
|
...rest
|
|
5803
5829
|
} = props;
|
|
@@ -5851,7 +5877,7 @@ const Box = props => {
|
|
|
5851
5877
|
// Style context dependencies
|
|
5852
5878
|
styleCSSVars, pseudoClasses, pseudoElements,
|
|
5853
5879
|
// Selectors
|
|
5854
|
-
visualSelector, pseudoStateSelector];
|
|
5880
|
+
visualSelector, pseudoStateSelector, preventInitialTransition];
|
|
5855
5881
|
let innerPseudoState;
|
|
5856
5882
|
if (basePseudoState && pseudoState) {
|
|
5857
5883
|
innerPseudoState = {};
|
|
@@ -6059,7 +6085,7 @@ const Box = props => {
|
|
|
6059
6085
|
}
|
|
6060
6086
|
const updateStyle = useCallback(state => {
|
|
6061
6087
|
const boxEl = ref.current;
|
|
6062
|
-
applyStyle(boxEl, boxStyles, state, boxPseudoNamedStyles);
|
|
6088
|
+
applyStyle(boxEl, boxStyles, state, boxPseudoNamedStyles, preventInitialTransition);
|
|
6063
6089
|
}, styleDeps);
|
|
6064
6090
|
const finalStyleDeps = [pseudoStateSelector, innerPseudoState, updateStyle];
|
|
6065
6091
|
// By default ":hover", ":active" are not tracked.
|
|
@@ -11204,6 +11230,20 @@ const useAutoFocus = (
|
|
|
11204
11230
|
}, []);
|
|
11205
11231
|
};
|
|
11206
11232
|
|
|
11233
|
+
const CalloutCloseContext = createContext();
|
|
11234
|
+
const useCalloutClose = () => {
|
|
11235
|
+
return useContext(CalloutCloseContext);
|
|
11236
|
+
};
|
|
11237
|
+
const renderIntoCallout = (jsx$1, calloutMessageElement, {
|
|
11238
|
+
close
|
|
11239
|
+
}) => {
|
|
11240
|
+
const calloutJsx = jsx(CalloutCloseContext.Provider, {
|
|
11241
|
+
value: close,
|
|
11242
|
+
children: jsx$1
|
|
11243
|
+
});
|
|
11244
|
+
render(calloutJsx, calloutMessageElement);
|
|
11245
|
+
};
|
|
11246
|
+
|
|
11207
11247
|
installImportMetaCss(import.meta);
|
|
11208
11248
|
/**
|
|
11209
11249
|
* A callout component that mimics native browser validation messages.
|
|
@@ -11310,6 +11350,10 @@ import.meta.css = /* css */ `
|
|
|
11310
11350
|
}
|
|
11311
11351
|
|
|
11312
11352
|
.navi_callout_message {
|
|
11353
|
+
position: relative;
|
|
11354
|
+
display: inline-flex;
|
|
11355
|
+
box-sizing: border-box;
|
|
11356
|
+
box-decoration-break: clone;
|
|
11313
11357
|
min-width: 0;
|
|
11314
11358
|
align-self: center;
|
|
11315
11359
|
word-break: break-word;
|
|
@@ -11452,28 +11496,44 @@ const openCallout = (
|
|
|
11452
11496
|
closeOnClickOutside = options.closeOnClickOutside;
|
|
11453
11497
|
}
|
|
11454
11498
|
|
|
11455
|
-
if (
|
|
11456
|
-
|
|
11457
|
-
newMessage
|
|
11458
|
-
|
|
11459
|
-
|
|
11499
|
+
if (isValidElement(newMessage)) {
|
|
11500
|
+
calloutMessageElement.innerHTML = "";
|
|
11501
|
+
renderIntoCallout(newMessage, calloutMessageElement, { close });
|
|
11502
|
+
} else if (newMessage instanceof Node) {
|
|
11503
|
+
// Handle DOM node (cloned from CSS selector)
|
|
11504
|
+
calloutMessageElement.innerHTML = "";
|
|
11505
|
+
calloutMessageElement.appendChild(newMessage);
|
|
11506
|
+
} else if (typeof newMessage === "function") {
|
|
11507
|
+
calloutMessageElement.innerHTML = "";
|
|
11508
|
+
newMessage({
|
|
11509
|
+
renderIntoCallout: (jsx) =>
|
|
11510
|
+
renderIntoCallout(jsx, calloutMessageElement, { close }),
|
|
11511
|
+
close,
|
|
11512
|
+
});
|
|
11513
|
+
} else {
|
|
11514
|
+
if (Error.isError(newMessage)) {
|
|
11515
|
+
const error = newMessage;
|
|
11516
|
+
newMessage = error.message;
|
|
11517
|
+
if (showErrorStack && error.stack) {
|
|
11518
|
+
newMessage += `<pre class="navi_callout_error_stack">${escapeHtml(String(error.stack))}</pre>`;
|
|
11519
|
+
}
|
|
11460
11520
|
}
|
|
11461
|
-
}
|
|
11462
11521
|
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11522
|
+
// Check if the message is a full HTML document (starts with DOCTYPE)
|
|
11523
|
+
if (typeof newMessage === "string" && isHtmlDocument(newMessage)) {
|
|
11524
|
+
// Create iframe to isolate the HTML document
|
|
11525
|
+
const iframe = document.createElement("iframe");
|
|
11526
|
+
iframe.style.border = "none";
|
|
11527
|
+
iframe.style.width = "100%";
|
|
11528
|
+
iframe.style.backgroundColor = "white";
|
|
11529
|
+
iframe.srcdoc = newMessage;
|
|
11471
11530
|
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
|
|
11475
|
-
|
|
11476
|
-
|
|
11531
|
+
// Clear existing content and add iframe
|
|
11532
|
+
calloutMessageElement.innerHTML = "";
|
|
11533
|
+
calloutMessageElement.appendChild(iframe);
|
|
11534
|
+
} else {
|
|
11535
|
+
calloutMessageElement.innerHTML = newMessage;
|
|
11536
|
+
}
|
|
11477
11537
|
}
|
|
11478
11538
|
};
|
|
11479
11539
|
{
|
|
@@ -11502,6 +11562,15 @@ const openCallout = (
|
|
|
11502
11562
|
document.removeEventListener("click", handleClickOutside, true);
|
|
11503
11563
|
});
|
|
11504
11564
|
}
|
|
11565
|
+
{
|
|
11566
|
+
const handleCustomCloseEvent = () => {
|
|
11567
|
+
close("custom_event");
|
|
11568
|
+
};
|
|
11569
|
+
calloutElement.addEventListener(
|
|
11570
|
+
"navi_callout_close",
|
|
11571
|
+
handleCustomCloseEvent,
|
|
11572
|
+
);
|
|
11573
|
+
}
|
|
11505
11574
|
Object.assign(callout, {
|
|
11506
11575
|
element: calloutElement,
|
|
11507
11576
|
update,
|
|
@@ -12234,6 +12303,189 @@ const generateSvgWithoutArrow = (width, height) => {
|
|
|
12234
12303
|
</svg>`;
|
|
12235
12304
|
};
|
|
12236
12305
|
|
|
12306
|
+
/**
|
|
12307
|
+
* Creates a live mirror of a source DOM element that automatically stays in sync.
|
|
12308
|
+
*
|
|
12309
|
+
* The mirror is implemented as a custom element (`<navi-mirror>`) that:
|
|
12310
|
+
* - Copies the source element's content (innerHTML) and attributes
|
|
12311
|
+
* - Automatically updates when the source element changes
|
|
12312
|
+
* - Efficiently manages observers based on DOM presence (starts observing when
|
|
12313
|
+
* added to DOM, stops when removed)
|
|
12314
|
+
* - Excludes the 'id' attribute to avoid conflicts
|
|
12315
|
+
*
|
|
12316
|
+
* @param {Element} sourceElement - The DOM element to mirror. Any changes to this
|
|
12317
|
+
* element's content, attributes, or structure will be automatically reflected
|
|
12318
|
+
* in the returned mirror element.
|
|
12319
|
+
*
|
|
12320
|
+
* @returns {NaviMirror} A custom element that mirrors the source element. Can be
|
|
12321
|
+
* inserted into the DOM like any other element. The mirror will automatically
|
|
12322
|
+
* start/stop observing the source based on its DOM presence.
|
|
12323
|
+
*/
|
|
12324
|
+
const createNaviMirror = (sourceElement) => {
|
|
12325
|
+
const naviMirror = new NaviMirror(sourceElement);
|
|
12326
|
+
return naviMirror;
|
|
12327
|
+
};
|
|
12328
|
+
|
|
12329
|
+
// Custom element that mirrors another element's content
|
|
12330
|
+
class NaviMirror extends HTMLElement {
|
|
12331
|
+
constructor(sourceElement) {
|
|
12332
|
+
super();
|
|
12333
|
+
this.sourceElement = null;
|
|
12334
|
+
this.sourceObserver = null;
|
|
12335
|
+
this.setSourceElement(sourceElement);
|
|
12336
|
+
}
|
|
12337
|
+
|
|
12338
|
+
setSourceElement(sourceElement) {
|
|
12339
|
+
this.sourceElement = sourceElement;
|
|
12340
|
+
this.updateFromSource();
|
|
12341
|
+
}
|
|
12342
|
+
|
|
12343
|
+
updateFromSource() {
|
|
12344
|
+
if (!this.sourceElement) return;
|
|
12345
|
+
|
|
12346
|
+
this.innerHTML = this.sourceElement.innerHTML;
|
|
12347
|
+
// Copy attributes from source (except id to avoid conflicts)
|
|
12348
|
+
for (const attr of Array.from(this.sourceElement.attributes)) {
|
|
12349
|
+
if (attr.name !== "id") {
|
|
12350
|
+
this.setAttribute(attr.name, attr.value);
|
|
12351
|
+
}
|
|
12352
|
+
}
|
|
12353
|
+
}
|
|
12354
|
+
|
|
12355
|
+
startObserving() {
|
|
12356
|
+
if (this.sourceObserver || !this.sourceElement) return;
|
|
12357
|
+
this.sourceObserver = new MutationObserver(() => {
|
|
12358
|
+
this.updateFromSource();
|
|
12359
|
+
});
|
|
12360
|
+
this.sourceObserver.observe(this.sourceElement, {
|
|
12361
|
+
childList: true,
|
|
12362
|
+
subtree: true,
|
|
12363
|
+
attributes: true,
|
|
12364
|
+
characterData: true,
|
|
12365
|
+
});
|
|
12366
|
+
}
|
|
12367
|
+
|
|
12368
|
+
stopObserving() {
|
|
12369
|
+
if (this.sourceObserver) {
|
|
12370
|
+
this.sourceObserver.disconnect();
|
|
12371
|
+
this.sourceObserver = null;
|
|
12372
|
+
}
|
|
12373
|
+
}
|
|
12374
|
+
|
|
12375
|
+
// Called when element is added to DOM
|
|
12376
|
+
connectedCallback() {
|
|
12377
|
+
this.startObserving();
|
|
12378
|
+
}
|
|
12379
|
+
|
|
12380
|
+
// Called when element is removed from DOM
|
|
12381
|
+
disconnectedCallback() {
|
|
12382
|
+
this.stopObserving();
|
|
12383
|
+
}
|
|
12384
|
+
}
|
|
12385
|
+
|
|
12386
|
+
// Register the custom element if not already registered
|
|
12387
|
+
if (!customElements.get("navi-mirror")) {
|
|
12388
|
+
customElements.define("navi-mirror", NaviMirror);
|
|
12389
|
+
}
|
|
12390
|
+
|
|
12391
|
+
const getMessageFromAttribute = (
|
|
12392
|
+
originalElement,
|
|
12393
|
+
attributeName,
|
|
12394
|
+
generatedMessage,
|
|
12395
|
+
) => {
|
|
12396
|
+
const selectorAttributeName = `${attributeName}-selector`;
|
|
12397
|
+
const eventAttributeName = `${attributeName}-event`;
|
|
12398
|
+
const resolutionSteps = [
|
|
12399
|
+
{
|
|
12400
|
+
description: "original element",
|
|
12401
|
+
element: originalElement,
|
|
12402
|
+
},
|
|
12403
|
+
{
|
|
12404
|
+
description: "closest fieldset",
|
|
12405
|
+
element: originalElement.closest("fieldset"),
|
|
12406
|
+
},
|
|
12407
|
+
{
|
|
12408
|
+
description: "closest form",
|
|
12409
|
+
element: originalElement.closest("form"),
|
|
12410
|
+
},
|
|
12411
|
+
];
|
|
12412
|
+
// Sub-steps for each element (in order of priority)
|
|
12413
|
+
const subSteps = ["event", "selector", "message"];
|
|
12414
|
+
let currentStepIndex = 0;
|
|
12415
|
+
let currentSubStepIndex = 0;
|
|
12416
|
+
const resolve = () => {
|
|
12417
|
+
while (currentStepIndex < resolutionSteps.length) {
|
|
12418
|
+
const { element } = resolutionSteps[currentStepIndex];
|
|
12419
|
+
if (element) {
|
|
12420
|
+
while (currentSubStepIndex < subSteps.length) {
|
|
12421
|
+
const subStep = subSteps[currentSubStepIndex];
|
|
12422
|
+
currentSubStepIndex++;
|
|
12423
|
+
if (subStep === "event") {
|
|
12424
|
+
const eventAttribute = element.getAttribute(eventAttributeName);
|
|
12425
|
+
if (eventAttribute) {
|
|
12426
|
+
return createEventHandler(element, eventAttribute);
|
|
12427
|
+
}
|
|
12428
|
+
}
|
|
12429
|
+
if (subStep === "selector") {
|
|
12430
|
+
const selectorAttribute = element.getAttribute(
|
|
12431
|
+
selectorAttributeName,
|
|
12432
|
+
);
|
|
12433
|
+
if (selectorAttribute) {
|
|
12434
|
+
return fromSelectorAttribute(selectorAttribute);
|
|
12435
|
+
}
|
|
12436
|
+
}
|
|
12437
|
+
if (subStep === "message") {
|
|
12438
|
+
const messageAttribute = element.getAttribute(attributeName);
|
|
12439
|
+
if (messageAttribute) {
|
|
12440
|
+
return messageAttribute;
|
|
12441
|
+
}
|
|
12442
|
+
}
|
|
12443
|
+
}
|
|
12444
|
+
}
|
|
12445
|
+
currentStepIndex++;
|
|
12446
|
+
currentSubStepIndex = 0;
|
|
12447
|
+
}
|
|
12448
|
+
return generatedMessage;
|
|
12449
|
+
};
|
|
12450
|
+
|
|
12451
|
+
const createEventHandler = (element, eventName) => {
|
|
12452
|
+
return ({ renderIntoCallout }) => {
|
|
12453
|
+
element.dispatchEvent(
|
|
12454
|
+
new CustomEvent(eventName, {
|
|
12455
|
+
detail: {
|
|
12456
|
+
render: (message) => {
|
|
12457
|
+
if (message) {
|
|
12458
|
+
renderIntoCallout(message);
|
|
12459
|
+
} else {
|
|
12460
|
+
// Resume resolution from next step
|
|
12461
|
+
const nextResult = resolve();
|
|
12462
|
+
renderIntoCallout(nextResult);
|
|
12463
|
+
}
|
|
12464
|
+
},
|
|
12465
|
+
},
|
|
12466
|
+
}),
|
|
12467
|
+
);
|
|
12468
|
+
};
|
|
12469
|
+
};
|
|
12470
|
+
|
|
12471
|
+
return resolve();
|
|
12472
|
+
};
|
|
12473
|
+
|
|
12474
|
+
// Helper function to resolve messages that might be CSS selectors
|
|
12475
|
+
const fromSelectorAttribute = (messageAttributeValue) => {
|
|
12476
|
+
// It's a CSS selector, find the DOM element
|
|
12477
|
+
const messageSourceElement = document.querySelector(messageAttributeValue);
|
|
12478
|
+
if (!messageSourceElement) {
|
|
12479
|
+
console.warn(
|
|
12480
|
+
`Message selector "${messageAttributeValue}" not found in DOM`,
|
|
12481
|
+
);
|
|
12482
|
+
return null; // Fallback to the generic message
|
|
12483
|
+
}
|
|
12484
|
+
const mirror = createNaviMirror(messageSourceElement);
|
|
12485
|
+
mirror.setAttribute("data-source-selector", messageAttributeValue);
|
|
12486
|
+
return mirror;
|
|
12487
|
+
};
|
|
12488
|
+
|
|
12237
12489
|
const generateFieldInvalidMessage = (template, { field }) => {
|
|
12238
12490
|
return replaceStringVars(template, {
|
|
12239
12491
|
"{field}": () => generateThisFieldText(field),
|
|
@@ -12271,6 +12523,7 @@ const replaceStringVars = (string, replacers) => {
|
|
|
12271
12523
|
|
|
12272
12524
|
const MIN_LOWER_LETTER_CONSTRAINT = {
|
|
12273
12525
|
name: "min_lower_letter",
|
|
12526
|
+
messageAttribute: "data-min-lower-letter-message",
|
|
12274
12527
|
check: (field) => {
|
|
12275
12528
|
const fieldValue = field.value;
|
|
12276
12529
|
if (!fieldValue && !field.required) {
|
|
@@ -12288,12 +12541,6 @@ const MIN_LOWER_LETTER_CONSTRAINT = {
|
|
|
12288
12541
|
}
|
|
12289
12542
|
}
|
|
12290
12543
|
if (numberOfLowercaseChars < min) {
|
|
12291
|
-
const messageAttribute = field.getAttribute(
|
|
12292
|
-
"data-min-lower-letter-message",
|
|
12293
|
-
);
|
|
12294
|
-
if (messageAttribute) {
|
|
12295
|
-
return messageAttribute;
|
|
12296
|
-
}
|
|
12297
12544
|
if (min === 0) {
|
|
12298
12545
|
return generateFieldInvalidMessage(
|
|
12299
12546
|
`{field} doit contenir au moins une lettre minuscule.`,
|
|
@@ -12310,6 +12557,7 @@ const MIN_LOWER_LETTER_CONSTRAINT = {
|
|
|
12310
12557
|
};
|
|
12311
12558
|
const MIN_UPPER_LETTER_CONSTRAINT = {
|
|
12312
12559
|
name: "min_upper_letter",
|
|
12560
|
+
messageAttribute: "data-min-upper-letter-message",
|
|
12313
12561
|
check: (field) => {
|
|
12314
12562
|
const fieldValue = field.value;
|
|
12315
12563
|
if (!fieldValue && !field.required) {
|
|
@@ -12327,12 +12575,6 @@ const MIN_UPPER_LETTER_CONSTRAINT = {
|
|
|
12327
12575
|
}
|
|
12328
12576
|
}
|
|
12329
12577
|
if (numberOfUppercaseChars < min) {
|
|
12330
|
-
const messageAttribute = field.getAttribute(
|
|
12331
|
-
"data-min-upper-letter-message",
|
|
12332
|
-
);
|
|
12333
|
-
if (messageAttribute) {
|
|
12334
|
-
return messageAttribute;
|
|
12335
|
-
}
|
|
12336
12578
|
if (min === 0) {
|
|
12337
12579
|
return generateFieldInvalidMessage(
|
|
12338
12580
|
`{field} doit contenir au moins une lettre majuscule.`,
|
|
@@ -12349,6 +12591,7 @@ const MIN_UPPER_LETTER_CONSTRAINT = {
|
|
|
12349
12591
|
};
|
|
12350
12592
|
const MIN_DIGIT_CONSTRAINT = {
|
|
12351
12593
|
name: "min_digit",
|
|
12594
|
+
messageAttribute: "data-min-digit-message",
|
|
12352
12595
|
check: (field) => {
|
|
12353
12596
|
const fieldValue = field.value;
|
|
12354
12597
|
if (!fieldValue && !field.required) {
|
|
@@ -12366,10 +12609,6 @@ const MIN_DIGIT_CONSTRAINT = {
|
|
|
12366
12609
|
}
|
|
12367
12610
|
}
|
|
12368
12611
|
if (numberOfDigitChars < min) {
|
|
12369
|
-
const messageAttribute = field.getAttribute("data-min-digit-message");
|
|
12370
|
-
if (messageAttribute) {
|
|
12371
|
-
return messageAttribute;
|
|
12372
|
-
}
|
|
12373
12612
|
if (min === 0) {
|
|
12374
12613
|
return generateFieldInvalidMessage(
|
|
12375
12614
|
`{field} doit contenir au moins un chiffre.`,
|
|
@@ -12384,44 +12623,39 @@ const MIN_DIGIT_CONSTRAINT = {
|
|
|
12384
12623
|
return "";
|
|
12385
12624
|
},
|
|
12386
12625
|
};
|
|
12387
|
-
const
|
|
12388
|
-
name: "
|
|
12626
|
+
const MIN_SPECIAL_CHAR_CONSTRAINT = {
|
|
12627
|
+
name: "min_special_char",
|
|
12628
|
+
messageAttribute: "data-min-special-char-message",
|
|
12389
12629
|
check: (field) => {
|
|
12390
12630
|
const fieldValue = field.value;
|
|
12391
12631
|
if (!fieldValue && !field.required) {
|
|
12392
12632
|
return "";
|
|
12393
12633
|
}
|
|
12394
|
-
const minSpecialChars = field.getAttribute("data-min-special-
|
|
12634
|
+
const minSpecialChars = field.getAttribute("data-min-special-char");
|
|
12395
12635
|
if (!minSpecialChars) {
|
|
12396
12636
|
return "";
|
|
12397
12637
|
}
|
|
12398
12638
|
const min = parseInt(minSpecialChars, 10);
|
|
12399
|
-
const
|
|
12400
|
-
if (!
|
|
12401
|
-
return "L'attribut data-special-
|
|
12639
|
+
const specialCharset = field.getAttribute("data-special-charset");
|
|
12640
|
+
if (!specialCharset) {
|
|
12641
|
+
return "L'attribut data-special-charset doit être défini pour utiliser data-min-special-char.";
|
|
12402
12642
|
}
|
|
12403
12643
|
|
|
12404
12644
|
let numberOfSpecialChars = 0;
|
|
12405
12645
|
for (const char of fieldValue) {
|
|
12406
|
-
if (
|
|
12646
|
+
if (specialCharset.includes(char)) {
|
|
12407
12647
|
numberOfSpecialChars++;
|
|
12408
12648
|
}
|
|
12409
12649
|
}
|
|
12410
12650
|
if (numberOfSpecialChars < min) {
|
|
12411
|
-
const messageAttribute = field.getAttribute(
|
|
12412
|
-
"data-min-special-chars-message",
|
|
12413
|
-
);
|
|
12414
|
-
if (messageAttribute) {
|
|
12415
|
-
return messageAttribute;
|
|
12416
|
-
}
|
|
12417
12651
|
if (min === 1) {
|
|
12418
12652
|
return generateFieldInvalidMessage(
|
|
12419
|
-
`{field} doit contenir au moins un caractère spécial. (${
|
|
12653
|
+
`{field} doit contenir au moins un caractère spécial. (${specialCharset})`,
|
|
12420
12654
|
{ field },
|
|
12421
12655
|
);
|
|
12422
12656
|
}
|
|
12423
12657
|
return generateFieldInvalidMessage(
|
|
12424
|
-
`{field} doit contenir au moins ${min} caractères spéciaux (${
|
|
12658
|
+
`{field} doit contenir au moins ${min} caractères spéciaux (${specialCharset})`,
|
|
12425
12659
|
{ field },
|
|
12426
12660
|
);
|
|
12427
12661
|
}
|
|
@@ -12431,6 +12665,7 @@ const MIN_SPECIAL_CHARS_CONSTRAINT = {
|
|
|
12431
12665
|
|
|
12432
12666
|
const READONLY_CONSTRAINT = {
|
|
12433
12667
|
name: "readonly",
|
|
12668
|
+
messageAttribute: "data-readonly-message",
|
|
12434
12669
|
check: (field, { skipReadonly }) => {
|
|
12435
12670
|
if (skipReadonly) {
|
|
12436
12671
|
return null;
|
|
@@ -12444,25 +12679,21 @@ const READONLY_CONSTRAINT = {
|
|
|
12444
12679
|
const isButton = field.tagName === "BUTTON";
|
|
12445
12680
|
const isBusy = field.getAttribute("aria-busy") === "true";
|
|
12446
12681
|
const readonlySilent = field.hasAttribute("data-readonly-silent");
|
|
12447
|
-
const messageAttribute = field.getAttribute("data-readonly-message");
|
|
12448
12682
|
if (readonlySilent) {
|
|
12449
12683
|
return { silent: true };
|
|
12450
12684
|
}
|
|
12451
12685
|
if (isBusy) {
|
|
12452
12686
|
return {
|
|
12453
12687
|
target: field,
|
|
12454
|
-
message:
|
|
12455
|
-
messageAttribute || `Cette action est en cours. Veuillez patienter.`,
|
|
12688
|
+
message: `Cette action est en cours. Veuillez patienter.`,
|
|
12456
12689
|
status: "info",
|
|
12457
12690
|
};
|
|
12458
12691
|
}
|
|
12459
12692
|
return {
|
|
12460
12693
|
target: field,
|
|
12461
|
-
message:
|
|
12462
|
-
|
|
12463
|
-
|
|
12464
|
-
? `Cet action n'est pas disponible pour l'instant.`
|
|
12465
|
-
: `Cet élément est en lecture seule et ne peut pas être modifié.`),
|
|
12694
|
+
message: isButton
|
|
12695
|
+
? `Cet action n'est pas disponible pour l'instant.`
|
|
12696
|
+
: `Cet élément est en lecture seule et ne peut pas être modifié.`,
|
|
12466
12697
|
status: "info",
|
|
12467
12698
|
};
|
|
12468
12699
|
},
|
|
@@ -12470,6 +12701,7 @@ const READONLY_CONSTRAINT = {
|
|
|
12470
12701
|
|
|
12471
12702
|
const SAME_AS_CONSTRAINT = {
|
|
12472
12703
|
name: "same_as",
|
|
12704
|
+
messageAttribute: "data-same-as-message",
|
|
12473
12705
|
check: (field) => {
|
|
12474
12706
|
const sameAs = field.getAttribute("data-same-as");
|
|
12475
12707
|
if (!sameAs) {
|
|
@@ -12494,10 +12726,6 @@ const SAME_AS_CONSTRAINT = {
|
|
|
12494
12726
|
if (fieldValue === otherFieldValue) {
|
|
12495
12727
|
return null;
|
|
12496
12728
|
}
|
|
12497
|
-
const messageAttribute = field.getAttribute("data-same-as-message");
|
|
12498
|
-
if (messageAttribute) {
|
|
12499
|
-
return messageAttribute;
|
|
12500
|
-
}
|
|
12501
12729
|
const type = field.type;
|
|
12502
12730
|
if (type === "password") {
|
|
12503
12731
|
return `Ce mot de passe doit être identique au précédent.`;
|
|
@@ -12511,6 +12739,7 @@ const SAME_AS_CONSTRAINT = {
|
|
|
12511
12739
|
|
|
12512
12740
|
const SINGLE_SPACE_CONSTRAINT = {
|
|
12513
12741
|
name: "single_space",
|
|
12742
|
+
messageAttribute: "data-single-space-message",
|
|
12514
12743
|
check: (field) => {
|
|
12515
12744
|
const singleSpace = field.hasAttribute("data-single-space");
|
|
12516
12745
|
if (!singleSpace) {
|
|
@@ -12521,10 +12750,6 @@ const SINGLE_SPACE_CONSTRAINT = {
|
|
|
12521
12750
|
const hasTrailingSpace = fieldValue.endsWith(" ");
|
|
12522
12751
|
const hasDoubleSpace = fieldValue.includes(" ");
|
|
12523
12752
|
if (hasLeadingSpace || hasDoubleSpace || hasTrailingSpace) {
|
|
12524
|
-
const messageAttribute = field.getAttribute("data-single-space-message");
|
|
12525
|
-
if (messageAttribute) {
|
|
12526
|
-
return messageAttribute;
|
|
12527
|
-
}
|
|
12528
12753
|
if (hasLeadingSpace) {
|
|
12529
12754
|
return generateFieldInvalidMessage(
|
|
12530
12755
|
`{field} ne doit pas commencer par un espace.`,
|
|
@@ -12555,6 +12780,7 @@ const SINGLE_SPACE_CONSTRAINT = {
|
|
|
12555
12780
|
// in our case it's just here in case some code is wrongly calling "requestAction" or "checkValidity" on a disabled element
|
|
12556
12781
|
const DISABLED_CONSTRAINT = {
|
|
12557
12782
|
name: "disabled",
|
|
12783
|
+
messageAttribute: "data-disabled-message",
|
|
12558
12784
|
check: (field) => {
|
|
12559
12785
|
if (field.disabled) {
|
|
12560
12786
|
return generateFieldInvalidMessage(`{field} est désactivé.`, { field });
|
|
@@ -12565,17 +12791,14 @@ const DISABLED_CONSTRAINT = {
|
|
|
12565
12791
|
|
|
12566
12792
|
const REQUIRED_CONSTRAINT = {
|
|
12567
12793
|
name: "required",
|
|
12794
|
+
messageAttribute: "data-required-message",
|
|
12568
12795
|
check: (field, { registerChange }) => {
|
|
12569
12796
|
if (!field.required) {
|
|
12570
12797
|
return null;
|
|
12571
12798
|
}
|
|
12572
|
-
const messageAttribute = field.getAttribute("data-required-message");
|
|
12573
12799
|
|
|
12574
12800
|
if (field.type === "checkbox") {
|
|
12575
12801
|
if (!field.checked) {
|
|
12576
|
-
if (messageAttribute) {
|
|
12577
|
-
return messageAttribute;
|
|
12578
|
-
}
|
|
12579
12802
|
return `Veuillez cocher cette case.`;
|
|
12580
12803
|
}
|
|
12581
12804
|
return null;
|
|
@@ -12586,19 +12809,12 @@ const REQUIRED_CONSTRAINT = {
|
|
|
12586
12809
|
if (!name) {
|
|
12587
12810
|
// If no name, check just this radio
|
|
12588
12811
|
if (!field.checked) {
|
|
12589
|
-
if (messageAttribute) {
|
|
12590
|
-
return messageAttribute;
|
|
12591
|
-
}
|
|
12592
12812
|
return `Veuillez sélectionner une option.`;
|
|
12593
12813
|
}
|
|
12594
12814
|
return null;
|
|
12595
12815
|
}
|
|
12596
12816
|
|
|
12597
12817
|
const closestFieldset = field.closest("fieldset");
|
|
12598
|
-
const fieldsetRequiredMessage = closestFieldset
|
|
12599
|
-
? closestFieldset.getAttribute("data-required-message")
|
|
12600
|
-
: null;
|
|
12601
|
-
|
|
12602
12818
|
// Find the container (form or closest fieldset)
|
|
12603
12819
|
const container = field.form || closestFieldset || document;
|
|
12604
12820
|
// Check if any radio with the same name is checked
|
|
@@ -12617,10 +12833,7 @@ const REQUIRED_CONSTRAINT = {
|
|
|
12617
12833
|
}
|
|
12618
12834
|
|
|
12619
12835
|
return {
|
|
12620
|
-
message:
|
|
12621
|
-
messageAttribute ||
|
|
12622
|
-
fieldsetRequiredMessage ||
|
|
12623
|
-
`Veuillez sélectionner une option.`,
|
|
12836
|
+
message: `Veuillez sélectionner une option.`,
|
|
12624
12837
|
target: closestFieldset
|
|
12625
12838
|
? closestFieldset.querySelector("legend")
|
|
12626
12839
|
: undefined,
|
|
@@ -12629,9 +12842,6 @@ const REQUIRED_CONSTRAINT = {
|
|
|
12629
12842
|
if (field.value) {
|
|
12630
12843
|
return null;
|
|
12631
12844
|
}
|
|
12632
|
-
if (messageAttribute) {
|
|
12633
|
-
return messageAttribute;
|
|
12634
|
-
}
|
|
12635
12845
|
if (field.type === "password") {
|
|
12636
12846
|
return field.hasAttribute("data-same-as")
|
|
12637
12847
|
? `Veuillez confirmer le mot de passe.`
|
|
@@ -12650,6 +12860,7 @@ const REQUIRED_CONSTRAINT = {
|
|
|
12650
12860
|
|
|
12651
12861
|
const PATTERN_CONSTRAINT = {
|
|
12652
12862
|
name: "pattern",
|
|
12863
|
+
messageAttribute: "data-pattern-message",
|
|
12653
12864
|
check: (field) => {
|
|
12654
12865
|
const pattern = field.pattern;
|
|
12655
12866
|
if (!pattern) {
|
|
@@ -12663,10 +12874,6 @@ const PATTERN_CONSTRAINT = {
|
|
|
12663
12874
|
if (regex.test(value)) {
|
|
12664
12875
|
return null;
|
|
12665
12876
|
}
|
|
12666
|
-
const messageAttribute = field.getAttribute("data-pattern-message");
|
|
12667
|
-
if (messageAttribute) {
|
|
12668
|
-
return messageAttribute;
|
|
12669
|
-
}
|
|
12670
12877
|
let message = generateFieldInvalidMessage(
|
|
12671
12878
|
`{field} ne correspond pas au format requis.`,
|
|
12672
12879
|
{ field },
|
|
@@ -12683,6 +12890,7 @@ const emailregex =
|
|
|
12683
12890
|
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
12684
12891
|
const TYPE_EMAIL_CONSTRAINT = {
|
|
12685
12892
|
name: "type_email",
|
|
12893
|
+
messageAttribute: "data-type-message",
|
|
12686
12894
|
check: (field) => {
|
|
12687
12895
|
if (field.type !== "email") {
|
|
12688
12896
|
return null;
|
|
@@ -12691,17 +12899,10 @@ const TYPE_EMAIL_CONSTRAINT = {
|
|
|
12691
12899
|
if (!value && !field.required) {
|
|
12692
12900
|
return null;
|
|
12693
12901
|
}
|
|
12694
|
-
const messageAttribute = field.getAttribute("data-type-email-message");
|
|
12695
12902
|
if (!value.includes("@")) {
|
|
12696
|
-
if (messageAttribute) {
|
|
12697
|
-
return messageAttribute;
|
|
12698
|
-
}
|
|
12699
12903
|
return `Veuillez inclure "@" dans l'adresse e-mail. Il manque un symbole "@" dans ${value}.`;
|
|
12700
12904
|
}
|
|
12701
12905
|
if (!emailregex.test(value)) {
|
|
12702
|
-
if (messageAttribute) {
|
|
12703
|
-
return messageAttribute;
|
|
12704
|
-
}
|
|
12705
12906
|
return `Veuillez saisir une adresse e-mail valide.`;
|
|
12706
12907
|
}
|
|
12707
12908
|
return null;
|
|
@@ -12710,6 +12911,7 @@ const TYPE_EMAIL_CONSTRAINT = {
|
|
|
12710
12911
|
|
|
12711
12912
|
const MIN_LENGTH_CONSTRAINT = {
|
|
12712
12913
|
name: "min_length",
|
|
12914
|
+
messageAttribute: "data-min-length-message",
|
|
12713
12915
|
check: (field) => {
|
|
12714
12916
|
if (field.tagName === "INPUT") {
|
|
12715
12917
|
if (!INPUT_TYPE_SUPPORTING_MIN_LENGTH_SET.has(field.type)) {
|
|
@@ -12731,10 +12933,6 @@ const MIN_LENGTH_CONSTRAINT = {
|
|
|
12731
12933
|
if (valueLength >= minLength) {
|
|
12732
12934
|
return null;
|
|
12733
12935
|
}
|
|
12734
|
-
const messageAttribute = field.getAttribute("data-min-length-message");
|
|
12735
|
-
if (messageAttribute) {
|
|
12736
|
-
return messageAttribute;
|
|
12737
|
-
}
|
|
12738
12936
|
if (valueLength === 1) {
|
|
12739
12937
|
return generateFieldInvalidMessage(
|
|
12740
12938
|
`{field} doit contenir au moins ${minLength} caractère (il contient actuellement un seul caractère).`,
|
|
@@ -12758,6 +12956,7 @@ const INPUT_TYPE_SUPPORTING_MIN_LENGTH_SET = new Set([
|
|
|
12758
12956
|
|
|
12759
12957
|
const MAX_LENGTH_CONSTRAINT = {
|
|
12760
12958
|
name: "max_length",
|
|
12959
|
+
messageAttribute: "data-max-length-message",
|
|
12761
12960
|
check: (field) => {
|
|
12762
12961
|
if (field.tagName === "INPUT") {
|
|
12763
12962
|
if (!INPUT_TYPE_SUPPORTING_MAX_LENGTH_SET.has(field.type)) {
|
|
@@ -12775,10 +12974,6 @@ const MAX_LENGTH_CONSTRAINT = {
|
|
|
12775
12974
|
if (valueLength <= maxLength) {
|
|
12776
12975
|
return null;
|
|
12777
12976
|
}
|
|
12778
|
-
const messageAttribute = field.getAttribute("data-max-length-message");
|
|
12779
|
-
if (messageAttribute) {
|
|
12780
|
-
return messageAttribute;
|
|
12781
|
-
}
|
|
12782
12977
|
return generateFieldInvalidMessage(
|
|
12783
12978
|
`{field} doit contenir au maximum ${maxLength} caractères (il contient actuellement ${valueLength} caractères).`,
|
|
12784
12979
|
{ field },
|
|
@@ -12791,6 +12986,7 @@ const INPUT_TYPE_SUPPORTING_MAX_LENGTH_SET = new Set(
|
|
|
12791
12986
|
|
|
12792
12987
|
const TYPE_NUMBER_CONSTRAINT = {
|
|
12793
12988
|
name: "type_number",
|
|
12989
|
+
messageAttribute: "data-type-message",
|
|
12794
12990
|
check: (field) => {
|
|
12795
12991
|
if (field.tagName !== "INPUT") {
|
|
12796
12992
|
return null;
|
|
@@ -12803,10 +12999,6 @@ const TYPE_NUMBER_CONSTRAINT = {
|
|
|
12803
12999
|
}
|
|
12804
13000
|
const value = field.valueAsNumber;
|
|
12805
13001
|
if (isNaN(value)) {
|
|
12806
|
-
const messageAttribute = field.getAttribute("data-type-number-message");
|
|
12807
|
-
if (messageAttribute) {
|
|
12808
|
-
return messageAttribute;
|
|
12809
|
-
}
|
|
12810
13002
|
return generateFieldInvalidMessage(`{field} doit être un nombre.`, {
|
|
12811
13003
|
field,
|
|
12812
13004
|
});
|
|
@@ -12817,6 +13009,7 @@ const TYPE_NUMBER_CONSTRAINT = {
|
|
|
12817
13009
|
|
|
12818
13010
|
const MIN_CONSTRAINT = {
|
|
12819
13011
|
name: "min",
|
|
13012
|
+
messageAttribute: "data-min-message",
|
|
12820
13013
|
check: (field) => {
|
|
12821
13014
|
if (field.tagName !== "INPUT") {
|
|
12822
13015
|
return null;
|
|
@@ -12835,10 +13028,6 @@ const MIN_CONSTRAINT = {
|
|
|
12835
13028
|
return null;
|
|
12836
13029
|
}
|
|
12837
13030
|
if (valueAsNumber < minNumber) {
|
|
12838
|
-
const messageAttribute = field.getAttribute("data-min-message");
|
|
12839
|
-
if (messageAttribute) {
|
|
12840
|
-
return messageAttribute;
|
|
12841
|
-
}
|
|
12842
13031
|
return generateFieldInvalidMessage(
|
|
12843
13032
|
`{field} doit être supérieur ou égal à <strong>${minString}</strong>.`,
|
|
12844
13033
|
{ field },
|
|
@@ -12854,11 +13043,7 @@ const MIN_CONSTRAINT = {
|
|
|
12854
13043
|
const [minHours, minMinutes] = min.split(":").map(Number);
|
|
12855
13044
|
const value = field.value;
|
|
12856
13045
|
const [hours, minutes] = value.split(":").map(Number);
|
|
12857
|
-
const messageAttribute = field.getAttribute("data-min-message");
|
|
12858
13046
|
if (hours < minHours || (hours === minHours && minMinutes < minutes)) {
|
|
12859
|
-
if (messageAttribute) {
|
|
12860
|
-
return messageAttribute;
|
|
12861
|
-
}
|
|
12862
13047
|
return generateFieldInvalidMessage(
|
|
12863
13048
|
`{field} doit être <strong>${min}</strong> ou plus.`,
|
|
12864
13049
|
{ field },
|
|
@@ -12877,6 +13062,7 @@ const MIN_CONSTRAINT = {
|
|
|
12877
13062
|
|
|
12878
13063
|
const MAX_CONSTRAINT = {
|
|
12879
13064
|
name: "max",
|
|
13065
|
+
messageAttribute: "data-max-message",
|
|
12880
13066
|
check: (field) => {
|
|
12881
13067
|
if (field.tagName !== "INPUT") {
|
|
12882
13068
|
return null;
|
|
@@ -12895,10 +13081,6 @@ const MAX_CONSTRAINT = {
|
|
|
12895
13081
|
return null;
|
|
12896
13082
|
}
|
|
12897
13083
|
if (valueAsNumber > maxNumber) {
|
|
12898
|
-
const messageAttribute = field.getAttribute("data-max-message");
|
|
12899
|
-
if (messageAttribute) {
|
|
12900
|
-
return messageAttribute;
|
|
12901
|
-
}
|
|
12902
13084
|
return generateFieldInvalidMessage(
|
|
12903
13085
|
`{field} être <strong>${maxAttribute}</strong> ou plus.`,
|
|
12904
13086
|
{ field },
|
|
@@ -12915,10 +13097,6 @@ const MAX_CONSTRAINT = {
|
|
|
12915
13097
|
const value = field.value;
|
|
12916
13098
|
const [hours, minutes] = value.split(":").map(Number);
|
|
12917
13099
|
if (hours > maxHours || (hours === maxHours && maxMinutes > minutes)) {
|
|
12918
|
-
const messageAttribute = field.getAttribute("data-max-message");
|
|
12919
|
-
if (messageAttribute) {
|
|
12920
|
-
return messageAttribute;
|
|
12921
|
-
}
|
|
12922
13100
|
return generateFieldInvalidMessage(
|
|
12923
13101
|
`{field} doit être <strong>${max}</strong> ou moins.`,
|
|
12924
13102
|
{ field },
|
|
@@ -13094,7 +13272,7 @@ const NAVI_CONSTRAINT_SET = new Set([
|
|
|
13094
13272
|
// the order matters here, the last constraint is picked first when multiple constraints fail
|
|
13095
13273
|
// so it's better to keep the most complex constraints at the beginning of the list
|
|
13096
13274
|
// so the more basic ones shows up first
|
|
13097
|
-
|
|
13275
|
+
MIN_SPECIAL_CHAR_CONSTRAINT,
|
|
13098
13276
|
SINGLE_SPACE_CONSTRAINT,
|
|
13099
13277
|
MIN_DIGIT_CONSTRAINT,
|
|
13100
13278
|
MIN_UPPER_LETTER_CONSTRAINT,
|
|
@@ -13376,6 +13554,21 @@ const installCustomConstraintValidation = (
|
|
|
13376
13554
|
typeof checkResult === "string"
|
|
13377
13555
|
? { message: checkResult }
|
|
13378
13556
|
: checkResult;
|
|
13557
|
+
constraintValidityInfo.messageString = constraintValidityInfo.message;
|
|
13558
|
+
|
|
13559
|
+
if (constraint.messageAttribute) {
|
|
13560
|
+
const messageFromAttribute = getMessageFromAttribute(
|
|
13561
|
+
element,
|
|
13562
|
+
constraint.messageAttribute,
|
|
13563
|
+
constraintValidityInfo.message,
|
|
13564
|
+
);
|
|
13565
|
+
if (messageFromAttribute !== constraintValidityInfo.message) {
|
|
13566
|
+
constraintValidityInfo.message = messageFromAttribute;
|
|
13567
|
+
if (typeof messageFromAttribute === "string") {
|
|
13568
|
+
constraintValidityInfo.messageString = messageFromAttribute;
|
|
13569
|
+
}
|
|
13570
|
+
}
|
|
13571
|
+
}
|
|
13379
13572
|
const thisConstraintFailureInfo = {
|
|
13380
13573
|
name: constraint.name,
|
|
13381
13574
|
constraint,
|
|
@@ -13409,7 +13602,7 @@ const installCustomConstraintValidation = (
|
|
|
13409
13602
|
if (!hasTitleAttribute) {
|
|
13410
13603
|
// when a constraint is failing browser displays that constraint message if the element has no title attribute.
|
|
13411
13604
|
// We want to do the same with our message (overriding the browser in the process to get better messages)
|
|
13412
|
-
element.setAttribute("title", failedConstraintInfo.
|
|
13605
|
+
element.setAttribute("title", failedConstraintInfo.messageString);
|
|
13413
13606
|
}
|
|
13414
13607
|
} else {
|
|
13415
13608
|
if (!hasTitleAttribute) {
|
|
@@ -13874,7 +14067,15 @@ const useCustomValidationRef = (elementRef, targetSelector) => {
|
|
|
13874
14067
|
return null;
|
|
13875
14068
|
}
|
|
13876
14069
|
let target;
|
|
13877
|
-
{
|
|
14070
|
+
if (targetSelector) {
|
|
14071
|
+
target = element.querySelector(targetSelector);
|
|
14072
|
+
if (!target) {
|
|
14073
|
+
console.warn(
|
|
14074
|
+
`useCustomValidationRef: targetSelector "${targetSelector}" did not match in element`,
|
|
14075
|
+
);
|
|
14076
|
+
return null;
|
|
14077
|
+
}
|
|
14078
|
+
} else {
|
|
13878
14079
|
target = element;
|
|
13879
14080
|
}
|
|
13880
14081
|
const unsubscribe = subscribe(element, target);
|
|
@@ -13912,7 +14113,28 @@ const unsubscribe = (element) => {
|
|
|
13912
14113
|
}
|
|
13913
14114
|
};
|
|
13914
14115
|
|
|
13915
|
-
const
|
|
14116
|
+
const NO_CONSTRAINTS = [];
|
|
14117
|
+
const useConstraints = (elementRef, props, { targetSelector } = {}) => {
|
|
14118
|
+
const {
|
|
14119
|
+
constraints = NO_CONSTRAINTS,
|
|
14120
|
+
disabledMessage,
|
|
14121
|
+
requiredMessage,
|
|
14122
|
+
patternMessage,
|
|
14123
|
+
minLengthMessage,
|
|
14124
|
+
maxLengthMessage,
|
|
14125
|
+
typeMessage,
|
|
14126
|
+
minMessage,
|
|
14127
|
+
maxMessage,
|
|
14128
|
+
singleSpaceMessage,
|
|
14129
|
+
sameAsMessage,
|
|
14130
|
+
minDigitMessage,
|
|
14131
|
+
minLowerLetterMessage,
|
|
14132
|
+
minUpperLetterMessage,
|
|
14133
|
+
minSpecialCharMessage,
|
|
14134
|
+
availableMessage,
|
|
14135
|
+
...remainingProps
|
|
14136
|
+
} = props;
|
|
14137
|
+
|
|
13916
14138
|
const customValidationRef = useCustomValidationRef(
|
|
13917
14139
|
elementRef,
|
|
13918
14140
|
targetSelector,
|
|
@@ -13930,6 +14152,96 @@ const useConstraints = (elementRef, constraints, targetSelector) => {
|
|
|
13930
14152
|
}
|
|
13931
14153
|
};
|
|
13932
14154
|
}, constraints);
|
|
14155
|
+
|
|
14156
|
+
useLayoutEffect(() => {
|
|
14157
|
+
const el = elementRef.current;
|
|
14158
|
+
if (!el) {
|
|
14159
|
+
return null;
|
|
14160
|
+
}
|
|
14161
|
+
const cleanupCallbackSet = new Set();
|
|
14162
|
+
const setupCustomEvent = (el, constraintName, Component) => {
|
|
14163
|
+
const attrName = `data-${constraintName}-message-event`;
|
|
14164
|
+
const customEventName = `${constraintName}_message_jsx`;
|
|
14165
|
+
el.setAttribute(attrName, customEventName);
|
|
14166
|
+
const onCustomEvent = (e) => {
|
|
14167
|
+
e.detail.render(Component);
|
|
14168
|
+
};
|
|
14169
|
+
el.addEventListener(customEventName, onCustomEvent);
|
|
14170
|
+
cleanupCallbackSet.add(() => {
|
|
14171
|
+
el.removeEventListener(customEventName, onCustomEvent);
|
|
14172
|
+
el.removeAttribute(attrName);
|
|
14173
|
+
});
|
|
14174
|
+
};
|
|
14175
|
+
|
|
14176
|
+
if (disabledMessage) {
|
|
14177
|
+
setupCustomEvent(el, "disabled", disabledMessage);
|
|
14178
|
+
}
|
|
14179
|
+
if (requiredMessage) {
|
|
14180
|
+
setupCustomEvent(el, "required", requiredMessage);
|
|
14181
|
+
}
|
|
14182
|
+
if (patternMessage) {
|
|
14183
|
+
setupCustomEvent(el, "pattern", patternMessage);
|
|
14184
|
+
}
|
|
14185
|
+
if (minLengthMessage) {
|
|
14186
|
+
setupCustomEvent(el, "min-length", minLengthMessage);
|
|
14187
|
+
}
|
|
14188
|
+
if (maxLengthMessage) {
|
|
14189
|
+
setupCustomEvent(el, "max-length", maxLengthMessage);
|
|
14190
|
+
}
|
|
14191
|
+
if (typeMessage) {
|
|
14192
|
+
setupCustomEvent(el, "type", typeMessage);
|
|
14193
|
+
}
|
|
14194
|
+
if (minMessage) {
|
|
14195
|
+
setupCustomEvent(el, "min", minMessage);
|
|
14196
|
+
}
|
|
14197
|
+
if (maxMessage) {
|
|
14198
|
+
setupCustomEvent(el, "max", maxMessage);
|
|
14199
|
+
}
|
|
14200
|
+
if (singleSpaceMessage) {
|
|
14201
|
+
setupCustomEvent(el, "single-space", singleSpaceMessage);
|
|
14202
|
+
}
|
|
14203
|
+
if (sameAsMessage) {
|
|
14204
|
+
setupCustomEvent(el, "same-as", sameAsMessage);
|
|
14205
|
+
}
|
|
14206
|
+
if (minDigitMessage) {
|
|
14207
|
+
setupCustomEvent(el, "min-digit", minDigitMessage);
|
|
14208
|
+
}
|
|
14209
|
+
if (minLowerLetterMessage) {
|
|
14210
|
+
setupCustomEvent(el, "min-lower-letter", minLowerLetterMessage);
|
|
14211
|
+
}
|
|
14212
|
+
if (minUpperLetterMessage) {
|
|
14213
|
+
setupCustomEvent(el, "min-upper-letter", minUpperLetterMessage);
|
|
14214
|
+
}
|
|
14215
|
+
if (minSpecialCharMessage) {
|
|
14216
|
+
setupCustomEvent(el, "min-special-char", minSpecialCharMessage);
|
|
14217
|
+
}
|
|
14218
|
+
if (availableMessage) {
|
|
14219
|
+
setupCustomEvent(el, "available", availableMessage);
|
|
14220
|
+
}
|
|
14221
|
+
return () => {
|
|
14222
|
+
for (const cleanupCallback of cleanupCallbackSet) {
|
|
14223
|
+
cleanupCallback();
|
|
14224
|
+
}
|
|
14225
|
+
};
|
|
14226
|
+
}, [
|
|
14227
|
+
disabledMessage,
|
|
14228
|
+
requiredMessage,
|
|
14229
|
+
patternMessage,
|
|
14230
|
+
minLengthMessage,
|
|
14231
|
+
maxLengthMessage,
|
|
14232
|
+
typeMessage,
|
|
14233
|
+
minMessage,
|
|
14234
|
+
maxMessage,
|
|
14235
|
+
singleSpaceMessage,
|
|
14236
|
+
sameAsMessage,
|
|
14237
|
+
minDigitMessage,
|
|
14238
|
+
minLowerLetterMessage,
|
|
14239
|
+
minUpperLetterMessage,
|
|
14240
|
+
minSpecialCharMessage,
|
|
14241
|
+
availableMessage,
|
|
14242
|
+
]);
|
|
14243
|
+
|
|
14244
|
+
return remainingProps;
|
|
13933
14245
|
};
|
|
13934
14246
|
|
|
13935
14247
|
const useInitialTextSelection = (ref, textSelection) => {
|
|
@@ -14660,6 +14972,8 @@ const useExecuteAction = (
|
|
|
14660
14972
|
message = errorMappingResult;
|
|
14661
14973
|
} else if (Error.isError(errorMappingResult)) {
|
|
14662
14974
|
message = errorMappingResult;
|
|
14975
|
+
} else if (isValidElement(errorMappingResult)) {
|
|
14976
|
+
message = errorMappingResult;
|
|
14663
14977
|
} else if (
|
|
14664
14978
|
typeof errorMappingResult === "object" &&
|
|
14665
14979
|
errorMappingResult !== null
|
|
@@ -15975,7 +16289,6 @@ const ButtonBasic = props => {
|
|
|
15975
16289
|
readOnly,
|
|
15976
16290
|
disabled,
|
|
15977
16291
|
loading,
|
|
15978
|
-
constraints = [],
|
|
15979
16292
|
autoFocus,
|
|
15980
16293
|
// visual
|
|
15981
16294
|
discrete,
|
|
@@ -15986,7 +16299,7 @@ const ButtonBasic = props => {
|
|
|
15986
16299
|
const defaultRef = useRef();
|
|
15987
16300
|
const ref = props.ref || defaultRef;
|
|
15988
16301
|
useAutoFocus(ref, autoFocus);
|
|
15989
|
-
useConstraints(ref,
|
|
16302
|
+
const remainingProps = useConstraints(ref, rest);
|
|
15990
16303
|
const innerLoading = loading || contextLoading && contextLoadingElement === ref.current;
|
|
15991
16304
|
const innerReadOnly = readOnly || contextReadOnly || innerLoading;
|
|
15992
16305
|
const innerDisabled = disabled || contextDisabled;
|
|
@@ -16002,7 +16315,7 @@ const ButtonBasic = props => {
|
|
|
16002
16315
|
const renderButtonContentMemoized = useCallback(renderButtonContent, [children]);
|
|
16003
16316
|
return jsxs(Box, {
|
|
16004
16317
|
"data-readonly-silent": innerLoading ? "" : undefined,
|
|
16005
|
-
...
|
|
16318
|
+
...remainingProps,
|
|
16006
16319
|
as: "button",
|
|
16007
16320
|
ref: ref,
|
|
16008
16321
|
"data-icon": icon ? "" : undefined,
|
|
@@ -16542,7 +16855,6 @@ const LinkPlain = props => {
|
|
|
16542
16855
|
disabled,
|
|
16543
16856
|
autoFocus,
|
|
16544
16857
|
spaceToClick = true,
|
|
16545
|
-
constraints = [],
|
|
16546
16858
|
onClick,
|
|
16547
16859
|
onKeyDown,
|
|
16548
16860
|
href,
|
|
@@ -16565,7 +16877,7 @@ const LinkPlain = props => {
|
|
|
16565
16877
|
const ref = props.ref || defaultRef;
|
|
16566
16878
|
const visited = useIsVisited(href);
|
|
16567
16879
|
useAutoFocus(ref, autoFocus);
|
|
16568
|
-
useConstraints(ref,
|
|
16880
|
+
const remainingProps = useConstraints(ref, rest);
|
|
16569
16881
|
const shouldDimColor = readOnly || disabled;
|
|
16570
16882
|
useDimColorWhen(ref, shouldDimColor);
|
|
16571
16883
|
// subscribe to document url to re-render and re-compute getHrefTargetInfo
|
|
@@ -16606,7 +16918,7 @@ const LinkPlain = props => {
|
|
|
16606
16918
|
as: "a",
|
|
16607
16919
|
color: anchor && !innerChildren ? "inherit" : undefined,
|
|
16608
16920
|
id: anchor ? href.slice(1) : undefined,
|
|
16609
|
-
...
|
|
16921
|
+
...remainingProps,
|
|
16610
16922
|
ref: ref,
|
|
16611
16923
|
href: href,
|
|
16612
16924
|
rel: innerRel,
|
|
@@ -17209,7 +17521,7 @@ const TabBasic = ({
|
|
|
17209
17521
|
});
|
|
17210
17522
|
};
|
|
17211
17523
|
|
|
17212
|
-
const
|
|
17524
|
+
const createAvailableConstraint = (
|
|
17213
17525
|
// the set might be incomplete (the front usually don't have the full copy of all the items from the backend)
|
|
17214
17526
|
// but this is already nice to help user with what we know
|
|
17215
17527
|
// it's also possible that front is unsync with backend, preventing user to choose a value
|
|
@@ -17220,7 +17532,8 @@ const createUniqueValueConstraint = (
|
|
|
17220
17532
|
message = `"{value}" est utilisé. Veuillez entrer une autre valeur.`,
|
|
17221
17533
|
) => {
|
|
17222
17534
|
return {
|
|
17223
|
-
name: "
|
|
17535
|
+
name: "available",
|
|
17536
|
+
messageAttribute: "data-available-message",
|
|
17224
17537
|
check: (field) => {
|
|
17225
17538
|
const fieldValue = field.value;
|
|
17226
17539
|
const hasConflict = existingValueSet.has(fieldValue);
|
|
@@ -17543,7 +17856,6 @@ const InputCheckboxBasic = props => {
|
|
|
17543
17856
|
required,
|
|
17544
17857
|
loading,
|
|
17545
17858
|
autoFocus,
|
|
17546
|
-
constraints = [],
|
|
17547
17859
|
onClick,
|
|
17548
17860
|
onInput,
|
|
17549
17861
|
color,
|
|
@@ -17559,7 +17871,7 @@ const InputCheckboxBasic = props => {
|
|
|
17559
17871
|
reportReadOnlyOnLabel?.(innerReadOnly);
|
|
17560
17872
|
reportDisabledOnLabel?.(innerDisabled);
|
|
17561
17873
|
useAutoFocus(ref, autoFocus);
|
|
17562
|
-
useConstraints(ref,
|
|
17874
|
+
const remainingProps = useConstraints(ref, rest);
|
|
17563
17875
|
const checked = Boolean(uiState);
|
|
17564
17876
|
const innerOnClick = useStableCallback(e => {
|
|
17565
17877
|
if (innerReadOnly) {
|
|
@@ -17606,7 +17918,7 @@ const InputCheckboxBasic = props => {
|
|
|
17606
17918
|
}, [color]);
|
|
17607
17919
|
return jsxs(Box, {
|
|
17608
17920
|
as: "span",
|
|
17609
|
-
...
|
|
17921
|
+
...remainingProps,
|
|
17610
17922
|
ref: undefined,
|
|
17611
17923
|
baseClassName: "navi_checkbox",
|
|
17612
17924
|
pseudoStateSelector: ".navi_native_field",
|
|
@@ -18101,7 +18413,6 @@ const InputRadioBasic = props => {
|
|
|
18101
18413
|
required,
|
|
18102
18414
|
loading,
|
|
18103
18415
|
autoFocus,
|
|
18104
|
-
constraints = [],
|
|
18105
18416
|
onClick,
|
|
18106
18417
|
onInput,
|
|
18107
18418
|
color,
|
|
@@ -18117,7 +18428,7 @@ const InputRadioBasic = props => {
|
|
|
18117
18428
|
reportReadOnlyOnLabel?.(innerReadOnly);
|
|
18118
18429
|
reportDisabledOnLabel?.(innerDisabled);
|
|
18119
18430
|
useAutoFocus(ref, autoFocus);
|
|
18120
|
-
useConstraints(ref,
|
|
18431
|
+
const remainingProps = useConstraints(ref, rest);
|
|
18121
18432
|
const checked = Boolean(uiState);
|
|
18122
18433
|
// we must first dispatch an event to inform all other radios they where unchecked
|
|
18123
18434
|
// this way each other radio uiStateController knows thery are unchecked
|
|
@@ -18191,7 +18502,7 @@ const InputRadioBasic = props => {
|
|
|
18191
18502
|
}, [color]);
|
|
18192
18503
|
return jsxs(Box, {
|
|
18193
18504
|
as: "span",
|
|
18194
|
-
...
|
|
18505
|
+
...remainingProps,
|
|
18195
18506
|
ref: undefined,
|
|
18196
18507
|
baseClassName: "navi_radio",
|
|
18197
18508
|
pseudoStateSelector: ".navi_native_field",
|
|
@@ -18515,7 +18826,6 @@ const InputRangeBasic = props => {
|
|
|
18515
18826
|
onInput,
|
|
18516
18827
|
readOnly,
|
|
18517
18828
|
disabled,
|
|
18518
|
-
constraints = [],
|
|
18519
18829
|
loading,
|
|
18520
18830
|
autoFocus,
|
|
18521
18831
|
autoFocusVisible,
|
|
@@ -18534,7 +18844,7 @@ const InputRangeBasic = props => {
|
|
|
18534
18844
|
autoFocusVisible,
|
|
18535
18845
|
autoSelect
|
|
18536
18846
|
});
|
|
18537
|
-
useConstraints(ref,
|
|
18847
|
+
const remainingProps = useConstraints(ref, rest);
|
|
18538
18848
|
const innerOnInput = useStableCallback(onInput);
|
|
18539
18849
|
const focusProxyId = `input_range_focus_proxy_${useId()}`;
|
|
18540
18850
|
const inertButFocusable = innerReadOnly && !innerDisabled;
|
|
@@ -18624,7 +18934,7 @@ const InputRangeBasic = props => {
|
|
|
18624
18934
|
pseudoClasses: InputPseudoClasses$1,
|
|
18625
18935
|
pseudoElements: InputPseudoElements$1,
|
|
18626
18936
|
hasChildFunction: true,
|
|
18627
|
-
...
|
|
18937
|
+
...remainingProps,
|
|
18628
18938
|
ref: undefined,
|
|
18629
18939
|
children: [jsx(LoaderBackground, {
|
|
18630
18940
|
loading: innerLoading,
|
|
@@ -18900,7 +19210,6 @@ const InputTextualBasic = props => {
|
|
|
18900
19210
|
onInput,
|
|
18901
19211
|
readOnly,
|
|
18902
19212
|
disabled,
|
|
18903
|
-
constraints = [],
|
|
18904
19213
|
loading,
|
|
18905
19214
|
autoFocus,
|
|
18906
19215
|
autoFocusVisible,
|
|
@@ -18919,7 +19228,7 @@ const InputTextualBasic = props => {
|
|
|
18919
19228
|
autoFocusVisible,
|
|
18920
19229
|
autoSelect
|
|
18921
19230
|
});
|
|
18922
|
-
useConstraints(ref,
|
|
19231
|
+
const remainingProps = useConstraints(ref, rest);
|
|
18923
19232
|
const innerOnInput = useStableCallback(onInput);
|
|
18924
19233
|
const renderInput = inputProps => {
|
|
18925
19234
|
return jsx(Box, {
|
|
@@ -18968,7 +19277,7 @@ const InputTextualBasic = props => {
|
|
|
18968
19277
|
pseudoClasses: InputPseudoClasses,
|
|
18969
19278
|
pseudoElements: InputPseudoElements,
|
|
18970
19279
|
hasChildFunction: true,
|
|
18971
|
-
...
|
|
19280
|
+
...remainingProps,
|
|
18972
19281
|
ref: undefined,
|
|
18973
19282
|
children: [jsx(LoaderBackground, {
|
|
18974
19283
|
loading: innerLoading,
|
|
@@ -19417,7 +19726,7 @@ const FormBasic = props => {
|
|
|
19417
19726
|
// instantiation validation to:
|
|
19418
19727
|
// - receive "requestsubmit" custom event ensure submit is prevented
|
|
19419
19728
|
// (and also execute action without validation if form.submit() is ever called)
|
|
19420
|
-
useConstraints(ref,
|
|
19729
|
+
const remainingProps = useConstraints(ref, rest);
|
|
19421
19730
|
const innerReadOnly = readOnly || loading;
|
|
19422
19731
|
const formContextValue = useMemo(() => {
|
|
19423
19732
|
return {
|
|
@@ -19425,7 +19734,7 @@ const FormBasic = props => {
|
|
|
19425
19734
|
};
|
|
19426
19735
|
}, [loading]);
|
|
19427
19736
|
return jsx(Box, {
|
|
19428
|
-
...
|
|
19737
|
+
...remainingProps,
|
|
19429
19738
|
as: "form",
|
|
19430
19739
|
ref: ref,
|
|
19431
19740
|
onReset: e => {
|
|
@@ -24325,5 +24634,5 @@ const UserSvg = () => jsx("svg", {
|
|
|
24325
24634
|
})
|
|
24326
24635
|
});
|
|
24327
24636
|
|
|
24328
|
-
export { ActionRenderer, ActiveKeyboardShortcuts, BadgeCount, Box, Button, Caption, CheckSvg, Checkbox, CheckboxList, Code, Col, Colgroup, Details, DialogLayout, Editable, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Form, HeartSvg, HomeSvg, Icon, Image, Input, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, MessageBox, Paragraph, Radio, RadioList, Route, RouteLink, Routes, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, SearchSvg, Select, SelectionContext, SettingsSvg, StarSvg, SummaryMarker, Svg, Tab, TabList, Table, TableCell, Tbody, Text, Thead, Title, Tr, UITransition, UserSvg, ViewportLayout, actionIntegratedVia, addCustomMessage, compareTwoJsValues, createAction, createRequestCanceller, createSelectionKeyboardShortcuts,
|
|
24637
|
+
export { ActionRenderer, ActiveKeyboardShortcuts, BadgeCount, Box, Button, Caption, CheckSvg, Checkbox, CheckboxList, Code, Col, Colgroup, Details, DialogLayout, Editable, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Form, HeartSvg, HomeSvg, Icon, Image, Input, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, MessageBox, Paragraph, Radio, RadioList, Route, RouteLink, Routes, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, SearchSvg, Select, SelectionContext, SettingsSvg, StarSvg, SummaryMarker, Svg, Tab, TabList, Table, TableCell, Tbody, Text, Thead, Title, Tr, UITransition, UserSvg, ViewportLayout, actionIntegratedVia, addCustomMessage, compareTwoJsValues, createAction, createAvailableConstraint, createRequestCanceller, createSelectionKeyboardShortcuts, enableDebugActions, enableDebugOnDocumentLoading, forwardActionRequested, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, localStorageSignal, navBack, navForward, navTo, openCallout, rawUrlPart, reload, removeCustomMessage, requestAction, rerunActions, resource, setBaseUrl, setupRoutes, stateSignal, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useActiveRouteInfo, useCalloutClose, useCellsAndColumns, useConstraintValidityState, useDependenciesDiff, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useNavState$1 as useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, useUrlSearchParam, valueInLocalStorage };
|
|
24329
24638
|
//# sourceMappingURL=jsenv_navi.js.map
|