@jsenv/navi 0.13.2 → 0.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2103,6 +2103,340 @@ const localStorageSignal = (key) => {
2103
2103
  return valueSignal;
2104
2104
  };
2105
2105
 
2106
+ const valueInLocalStorage = (
2107
+ key,
2108
+ { type = "string", fallback } = {},
2109
+ ) => {
2110
+ const converter = typeConverters[type];
2111
+ if (converter === undefined) {
2112
+ console.warn(
2113
+ `Invalid type "${type}" for "${key}" in local storage, expected one of ${Object.keys(
2114
+ typeConverters,
2115
+ ).join(", ")}`,
2116
+ );
2117
+ }
2118
+ const getValidityMessage = (
2119
+ valueToCheck,
2120
+ valueInLocalStorage = valueToCheck,
2121
+ ) => {
2122
+ if (!converter) {
2123
+ return "";
2124
+ }
2125
+ if (!converter.checkValidity) {
2126
+ return "";
2127
+ }
2128
+ const checkValidityResult = converter.checkValidity(valueToCheck);
2129
+ if (checkValidityResult === false) {
2130
+ return `${valueInLocalStorage}`;
2131
+ }
2132
+ if (!checkValidityResult) {
2133
+ return "";
2134
+ }
2135
+ return `${checkValidityResult}, got "${valueInLocalStorage}"`;
2136
+ };
2137
+
2138
+ const get = () => {
2139
+ let valueInLocalStorage = window.localStorage.getItem(key);
2140
+ if (valueInLocalStorage === null) {
2141
+ return fallback;
2142
+ }
2143
+ if (converter && converter.decode) {
2144
+ const valueDecoded = converter.decode(valueInLocalStorage);
2145
+ const validityMessage = getValidityMessage(
2146
+ valueDecoded,
2147
+ valueInLocalStorage,
2148
+ );
2149
+ if (validityMessage) {
2150
+ console.warn(
2151
+ `The value found in localStorage "${key}" is invalid: ${validityMessage}`,
2152
+ );
2153
+ return undefined;
2154
+ }
2155
+ return valueDecoded;
2156
+ }
2157
+ const validityMessage = getValidityMessage(valueInLocalStorage);
2158
+ if (validityMessage) {
2159
+ console.warn(
2160
+ `The value found in localStorage "${key}" is invalid: ${validityMessage}`,
2161
+ );
2162
+ return undefined;
2163
+ }
2164
+ return valueInLocalStorage;
2165
+ };
2166
+ const set = (value) => {
2167
+ if (value === undefined) {
2168
+ window.localStorage.removeItem(key);
2169
+ return;
2170
+ }
2171
+ const validityMessage = getValidityMessage(value);
2172
+ if (validityMessage) {
2173
+ console.warn(
2174
+ `The value to set in localStorage "${key}" is invalid: ${validityMessage}`,
2175
+ );
2176
+ }
2177
+ if (converter && converter.encode) {
2178
+ const valueEncoded = converter.encode(value);
2179
+ window.localStorage.setItem(key, valueEncoded);
2180
+ return;
2181
+ }
2182
+ window.localStorage.setItem(key, value);
2183
+ };
2184
+ const remove = () => {
2185
+ window.localStorage.removeItem(key);
2186
+ };
2187
+
2188
+ return [get, set, remove];
2189
+ };
2190
+
2191
+ const createNumberValidator = ({ min, max, step } = {}) => {
2192
+ return {
2193
+ decode: (value) => {
2194
+ const valueParsed = parseFloat(value);
2195
+ return valueParsed;
2196
+ },
2197
+ checkValidity: (value) => {
2198
+ if (typeof value !== "number") {
2199
+ return `must be a number`;
2200
+ }
2201
+ if (!Number.isFinite(value)) {
2202
+ return `must be finite`;
2203
+ }
2204
+ if (min !== undefined && value < min) {
2205
+ return min === 0 ? `must be positive` : `must be >= ${min}`;
2206
+ }
2207
+ if (max !== undefined && value > max) {
2208
+ return max === 0 ? `must be negative` : `must be <= ${max}`;
2209
+ }
2210
+ if (step !== undefined) {
2211
+ const remainder = (value - (min || 0)) % step;
2212
+ const epsilon = 0.0000001;
2213
+ if (remainder > epsilon && step - remainder > epsilon) {
2214
+ if (step === 1) {
2215
+ return `must be an integer`;
2216
+ }
2217
+ return `must be a multiple of ${step}`;
2218
+ }
2219
+ }
2220
+ return "";
2221
+ },
2222
+ };
2223
+ };
2224
+ const typeConverters = {
2225
+ boolean: {
2226
+ checkValidity: (value) => {
2227
+ if (typeof value !== "boolean") {
2228
+ return `must be a boolean`;
2229
+ }
2230
+ return "";
2231
+ },
2232
+ decode: (value) => {
2233
+ return value === "true";
2234
+ },
2235
+ encode: (value) => {
2236
+ return value ? "true" : "false";
2237
+ },
2238
+ },
2239
+ string: {
2240
+ checkValidity: (value) => {
2241
+ if (typeof value !== "string") {
2242
+ return `must be a string`;
2243
+ }
2244
+ return "";
2245
+ },
2246
+ },
2247
+ number: createNumberValidator(),
2248
+ float: createNumberValidator(),
2249
+ positive_number: createNumberValidator({ min: 0 }),
2250
+ integer: createNumberValidator({ step: 1 }),
2251
+ positive_integer: createNumberValidator({ min: 0, step: 1 }),
2252
+ percentage: {
2253
+ checkValidity: (value) => {
2254
+ if (typeof value !== "string") {
2255
+ return `must be a percentage`;
2256
+ }
2257
+ if (!value.endsWith("%")) {
2258
+ return `must end with %`;
2259
+ }
2260
+ const percentageString = value.slice(0, -1);
2261
+ const percentageFloat = parseFloat(percentageString);
2262
+ if (typeof percentageFloat !== "number") {
2263
+ return `must be a percentage`;
2264
+ }
2265
+ if (percentageFloat < 0 || percentageFloat > 100) {
2266
+ return `must be between 0 and 100`;
2267
+ }
2268
+ return "";
2269
+ },
2270
+ },
2271
+ object: {
2272
+ decode: (value) => {
2273
+ const valueParsed = JSON.parse(value);
2274
+ return valueParsed;
2275
+ },
2276
+ encode: (value) => {
2277
+ const valueStringified = JSON.stringify(value);
2278
+ return valueStringified;
2279
+ },
2280
+ checkValidity: (value) => {
2281
+ if (value === null || typeof value !== "object") {
2282
+ return `must be an object`;
2283
+ }
2284
+ return "";
2285
+ },
2286
+ },
2287
+ };
2288
+
2289
+ /**
2290
+ * Creates an advanced signal with optional source signal synchronization and local storage persistence.
2291
+ *
2292
+ * The sourceSignal option creates a fallback mechanism where:
2293
+ * 1. The signal initially takes the value from sourceSignal (if defined) or falls back to defaultValue
2294
+ * 2. The signal can be manually overridden with any value
2295
+ * 3. When sourceSignal changes, it will override the current value again
2296
+ *
2297
+ * This is useful for scenarios like UI state management where you want to:
2298
+ * - Start with a value from an external source (e.g., backend data)
2299
+ * - Allow temporary local overrides (e.g., user interactions)
2300
+ * - Reset to the external source when context changes (e.g., navigation, data refresh)
2301
+ *
2302
+ * @param {any} defaultValue - The default value to use when no other value is available
2303
+ * @param {Object} [options={}] - Configuration options
2304
+ * @param {import("@preact/signals").Signal} [options.sourceSignal] - Source signal to synchronize with. When the source signal changes, this signal will be updated
2305
+ * @param {string} [options.localStorageKey] - Key for local storage persistence. When provided, the signal value will be saved to and restored from localStorage
2306
+ * @param {"string" | "number" | "boolean" | "object"} [options.type="string"] - Type for localStorage serialization/deserialization
2307
+ * @returns {import("@preact/signals").Signal} A signal that can be synchronized with a source signal and/or persisted in localStorage
2308
+ *
2309
+ * @example
2310
+ * // Basic signal with default value
2311
+ * const count = stateSignal(0);
2312
+ *
2313
+ * @example
2314
+ * // Position that follows backend data but allows temporary overrides
2315
+ * const backendPosition = signal({ x: 100, y: 50 });
2316
+ * const currentPosition = stateSignal({ x: 0, y: 0 }, { sourceSignal: backendPosition });
2317
+ *
2318
+ * // Initially: currentPosition.value = { x: 100, y: 50 } (from backend)
2319
+ * // User drags: currentPosition.value = { x: 150, y: 80 } (manual override)
2320
+ * // Backend updates: backendPosition.value = { x: 200, y: 60 }
2321
+ * // Result: currentPosition.value = { x: 200, y: 60 } (reset to new backend value)
2322
+ *
2323
+ * @example
2324
+ * // Signal with localStorage persistence
2325
+ * const userPreference = stateSignal("light", {
2326
+ * localStorageKey: "theme",
2327
+ * type: "string"
2328
+ * });
2329
+ *
2330
+ * @example
2331
+ * // Combined: follows source with localStorage backup
2332
+ * const serverConfig = signal({ timeout: 5000 });
2333
+ * const appConfig = stateSignal({ timeout: 3000 }, {
2334
+ * sourceSignal: serverConfig,
2335
+ * localStorageKey: "app-config",
2336
+ * type: "object"
2337
+ * });
2338
+ */
2339
+ const stateSignal = (
2340
+ defaultValue,
2341
+ { sourceSignal, localStorageKey, type } = {},
2342
+ ) => {
2343
+ const advancedSignal = signal();
2344
+ if (sourceSignal) {
2345
+ connectSignalToSource(advancedSignal, sourceSignal, defaultValue);
2346
+ } else {
2347
+ advancedSignal.value = defaultValue;
2348
+ }
2349
+ if (localStorageKey) {
2350
+ connectSignalWithLocalStorage(advancedSignal, localStorageKey, { type });
2351
+ }
2352
+ return advancedSignal;
2353
+ };
2354
+
2355
+ const connectSignalToSource = (signal, sourceSignal, defaultValue) => {
2356
+ connectSignalFallbacks(signal, [sourceSignal], defaultValue);
2357
+ updateSignalOnChange(sourceSignal, signal);
2358
+ };
2359
+ const connectSignalFallbacks = (signal, fallbackSignals, defaultValue) => {
2360
+ if (fallbackSignals.length === 0) {
2361
+ signal.value = defaultValue;
2362
+ return () => {};
2363
+ }
2364
+ if (fallbackSignals.length === 1) {
2365
+ const [fallbackSignal] = fallbackSignals;
2366
+ const applyFallback = () => {
2367
+ const value = signal.value;
2368
+ const fallbackValue = fallbackSignal.value;
2369
+ if (value !== undefined) {
2370
+ return;
2371
+ }
2372
+ if (fallbackValue !== undefined) {
2373
+ signal.value = fallbackValue;
2374
+ return;
2375
+ }
2376
+ signal.value = defaultValue;
2377
+ };
2378
+ applyFallback();
2379
+ return effect(() => {
2380
+ applyFallback();
2381
+ });
2382
+ }
2383
+ const applyFallback = () => {
2384
+ const fallbackValues = fallbackSignals.map((s) => s.value);
2385
+ const value = signal.value;
2386
+ if (value !== undefined) {
2387
+ return;
2388
+ }
2389
+ for (const fallbackValue of fallbackValues) {
2390
+ if (fallbackValue === undefined) {
2391
+ continue;
2392
+ }
2393
+ signal.value = fallbackValue;
2394
+ return;
2395
+ }
2396
+ signal.value = defaultValue;
2397
+ };
2398
+ applyFallback();
2399
+ return effect(() => {
2400
+ applyFallback();
2401
+ });
2402
+ };
2403
+ const updateSignalOnChange = (sourceSignal, targetSignal) => {
2404
+ let sourcePreviousValue = sourceSignal.value;
2405
+ return effect(() => {
2406
+ const sourceValue = sourceSignal.value;
2407
+ if (sourcePreviousValue !== undefined && sourceValue !== undefined) {
2408
+ // console.log(
2409
+ // "value modified from",
2410
+ // sourcePreviousValue,
2411
+ // "to",
2412
+ // sourceValue,
2413
+ // );
2414
+ targetSignal.value = sourceValue;
2415
+ }
2416
+ sourcePreviousValue = sourceValue;
2417
+ });
2418
+ };
2419
+
2420
+ const connectSignalWithLocalStorage = (
2421
+ signal,
2422
+ key,
2423
+ { type = "string" } = {},
2424
+ ) => {
2425
+ const [get, set, remove] = valueInLocalStorage(key, { type });
2426
+ const valueFromLocalStorage = get();
2427
+ if (valueFromLocalStorage !== undefined) {
2428
+ signal.value = valueFromLocalStorage;
2429
+ }
2430
+ effect(() => {
2431
+ const value = signal.value;
2432
+ if (value === undefined || value === null) {
2433
+ remove();
2434
+ } else {
2435
+ set(value);
2436
+ }
2437
+ });
2438
+ };
2439
+
2106
2440
  const getCallerInfo = (targetFunction = null, additionalOffset = 0) => {
2107
2441
  const originalPrepareStackTrace = Error.prepareStackTrace;
2108
2442
  try {
@@ -4208,193 +4542,51 @@ const useStateArray = (
4208
4542
  return [array, add, remove, reset];
4209
4543
  };
4210
4544
 
4211
- const valueInLocalStorage = (key, options = {}) => {
4212
- const { type = "string" } = options;
4213
- const converter = typeConverters[type];
4214
- if (converter === undefined) {
4215
- console.warn(
4216
- `Invalid type "${type}" for "${key}" in local storage, expected one of ${Object.keys(
4217
- typeConverters,
4218
- ).join(", ")}`,
4219
- );
4220
- }
4221
- const getValidityMessage = (
4222
- valueToCheck,
4223
- valueInLocalStorage = valueToCheck,
4224
- ) => {
4225
- if (!converter) {
4226
- return "";
4227
- }
4228
- if (!converter.checkValidity) {
4229
- return "";
4230
- }
4231
- const checkValidityResult = converter.checkValidity(valueToCheck);
4232
- if (checkValidityResult === false) {
4233
- return `${valueInLocalStorage}`;
4234
- }
4235
- if (!checkValidityResult) {
4236
- return "";
4237
- }
4238
- return `${checkValidityResult}, got "${valueInLocalStorage}"`;
4239
- };
4240
-
4241
- const get = () => {
4242
- let valueInLocalStorage = window.localStorage.getItem(key);
4243
- if (valueInLocalStorage === null) {
4244
- return Object.hasOwn(options, "default") ? options.default : undefined;
4245
- }
4246
- if (converter && converter.decode) {
4247
- const valueDecoded = converter.decode(valueInLocalStorage);
4248
- const validityMessage = getValidityMessage(
4249
- valueDecoded,
4250
- valueInLocalStorage,
4251
- );
4252
- if (validityMessage) {
4253
- console.warn(
4254
- `The value found in localStorage "${key}" is invalid: ${validityMessage}`,
4255
- );
4256
- return undefined;
4257
- }
4258
- return valueDecoded;
4259
- }
4260
- const validityMessage = getValidityMessage(valueInLocalStorage);
4261
- if (validityMessage) {
4262
- console.warn(
4263
- `The value found in localStorage "${key}" is invalid: ${validityMessage}`,
4264
- );
4265
- return undefined;
4266
- }
4267
- return valueInLocalStorage;
4268
- };
4269
- const set = (value) => {
4270
- if (value === undefined) {
4271
- window.localStorage.removeItem(key);
4272
- return;
4273
- }
4274
- const validityMessage = getValidityMessage(value);
4275
- if (validityMessage) {
4276
- console.warn(
4277
- `The value to set in localStorage "${key}" is invalid: ${validityMessage}`,
4278
- );
4279
- }
4280
- if (converter && converter.encode) {
4281
- const valueEncoded = converter.encode(value);
4282
- window.localStorage.setItem(key, valueEncoded);
4283
- return;
4284
- }
4285
- window.localStorage.setItem(key, value);
4286
- };
4287
- const remove = () => {
4288
- window.localStorage.removeItem(key);
4545
+ /**
4546
+ * Creates a function that generates abort signals, automatically cancelling previous requests.
4547
+ *
4548
+ * This prevents race conditions when multiple fetch requests are triggered rapidly,
4549
+ * ensuring only the most recent request completes while canceling outdated ones.
4550
+ *
4551
+ * @param {string} [reason="Request superseded"] - Custom reason for the abort signal
4552
+ * @returns {() => AbortSignal} A function that returns a fresh AbortSignal and cancels the previous one
4553
+ *
4554
+ * @example
4555
+ * // Setup the request canceller
4556
+ * const cancelPrevious = createRequestCanceller();
4557
+ *
4558
+ * // Use it in sequential fetch operations
4559
+ * const searchUsers = async (query) => {
4560
+ * const signal = cancelPrevious(); // Cancels previous search
4561
+ * const response = await fetch(`/api/users?q=${query}`, { signal });
4562
+ * return response.json();
4563
+ * };
4564
+ *
4565
+ * // Rapid successive calls - only the last one will complete
4566
+ * searchUsers("john"); // Will be aborted
4567
+ * searchUsers("jane"); // Will be aborted
4568
+ * searchUsers("jack"); // Will complete
4569
+ *
4570
+ * @example
4571
+ * // With custom reason
4572
+ * const cancelPrevious = createRequestCanceller("Search cancelled");
4573
+ */
4574
+ const createRequestCanceller = (reason = "Request superseded") => {
4575
+ let previousAbortController;
4576
+ return () => {
4577
+ previousAbortController?.abort(reason);
4578
+ previousAbortController = new AbortController();
4579
+ return previousAbortController.signal;
4289
4580
  };
4290
-
4291
- return [get, set, remove];
4292
- };
4293
-
4294
- const typeConverters = {
4295
- boolean: {
4296
- checkValidity: (value) => {
4297
- if (typeof value !== "boolean") {
4298
- return `must be a boolean`;
4299
- }
4300
- return "";
4301
- },
4302
- decode: (value) => {
4303
- return value === "true";
4304
- },
4305
- },
4306
- string: {
4307
- checkValidity: (value) => {
4308
- if (typeof value !== "string") {
4309
- return `must be a string`;
4310
- }
4311
- return "";
4312
- },
4313
- },
4314
- number: {
4315
- decode: (value) => {
4316
- const valueParsed = parseFloat(value);
4317
- return valueParsed;
4318
- },
4319
- checkValidity: (value) => {
4320
- if (typeof value !== "number") {
4321
- return `must be a number`;
4322
- }
4323
- if (!Number.isFinite(value)) {
4324
- return `must be finite`;
4325
- }
4326
- return "";
4327
- },
4328
- },
4329
- positive_number: {
4330
- decode: (value) => {
4331
- const valueParsed = parseFloat(value);
4332
- return valueParsed;
4333
- },
4334
- checkValidity: (value) => {
4335
- if (typeof value !== "number") {
4336
- return `must be a number`;
4337
- }
4338
- if (value < 0) {
4339
- return `must be positive`;
4340
- }
4341
- return "";
4342
- },
4343
- },
4344
- positive_integer: {
4345
- decode: (value) => {
4346
- const valueParsed = parseInt(value, 10);
4347
- return valueParsed;
4348
- },
4349
- checkValidity: (value) => {
4350
- if (typeof value !== "number") {
4351
- return `must be a number`;
4352
- }
4353
- if (!Number.isInteger(value)) {
4354
- return `must be an integer`;
4355
- }
4356
- if (value < 0) {
4357
- return `must be positive`;
4358
- }
4359
- return "";
4360
- },
4361
- },
4362
- percentage: {
4363
- checkValidity: (value) => {
4364
- if (typeof value !== "string") {
4365
- return `must be a percentage`;
4366
- }
4367
- if (!value.endsWith("%")) {
4368
- return `must end with %`;
4369
- }
4370
- const percentageString = value.slice(0, -1);
4371
- const percentageFloat = parseFloat(percentageString);
4372
- if (typeof percentageFloat !== "number") {
4373
- return `must be a percentage`;
4374
- }
4375
- if (percentageFloat < 0 || percentageFloat > 100) {
4376
- return `must be between 0 and 100`;
4377
- }
4378
- return "";
4379
- },
4380
- },
4381
- object: {
4382
- decode: (value) => {
4383
- const valueParsed = JSON.parse(value);
4384
- return valueParsed;
4385
- },
4386
- encode: (value) => {
4387
- const valueStringified = JSON.stringify(value);
4388
- return valueStringified;
4389
- },
4390
- checkValidity: (value) => {
4391
- if (value === null || typeof value !== "object") {
4392
- return `must be an object`;
4393
- }
4394
- return "";
4395
- },
4396
- },
4397
4581
  };
4582
+ window.addEventListener("unhandledrejection", (event) => {
4583
+ if (
4584
+ event.reason?.name === "AbortError" &&
4585
+ event.reason?.message === "Request superseded"
4586
+ ) {
4587
+ event.preventDefault(); // 💥 empêche les "uncaught rejection" devtools pour nos cancellations
4588
+ }
4589
+ });
4398
4590
 
4399
4591
  /**
4400
4592
  * Merges a component's base className with className received from props.
@@ -4561,19 +4753,19 @@ const DIMENSION_PROPS = {
4561
4753
  return { minHeight: "100%", height: "auto" }; // Take full height outside flex
4562
4754
  },
4563
4755
  shrinkX: (value, { parentBoxFlow }) => {
4564
- if (!value) {
4565
- return null;
4566
- }
4567
4756
  if (parentBoxFlow === "row" || parentBoxFlow === "inline-row") {
4757
+ if (!value || value === "0") {
4758
+ return { flexShrink: 0 };
4759
+ }
4568
4760
  return { flexShrink: 1 };
4569
4761
  }
4570
4762
  return { maxWidth: "100%" };
4571
4763
  },
4572
4764
  shrinkY: (value, { parentBoxFlow }) => {
4573
- if (!value) {
4574
- return null;
4575
- }
4576
4765
  if (parentBoxFlow === "column" || parentBoxFlow === "inline-column") {
4766
+ if (!value || value === "0") {
4767
+ return { flexShrink: 0 };
4768
+ }
4577
4769
  return { flexShrink: 1 };
4578
4770
  }
4579
4771
  return { maxHeight: "100%" };
@@ -10726,6 +10918,7 @@ import.meta.css = /* css */ `
10726
10918
  --callout-background-color: white;
10727
10919
  --callout-icon-color: black;
10728
10920
  --callout-padding: 8px;
10921
+ --callout-z-index: 1000;
10729
10922
  }
10730
10923
  }
10731
10924
 
@@ -10737,7 +10930,7 @@ import.meta.css = /* css */ `
10737
10930
  position: absolute;
10738
10931
  top: 0;
10739
10932
  left: 0;
10740
- z-index: 1;
10933
+ z-index: var(--callout-z-index);
10741
10934
  display: block;
10742
10935
  height: auto;
10743
10936
  opacity: 0;
@@ -11940,31 +12133,28 @@ const READONLY_CONSTRAINT = {
11940
12133
  if (field.type === "hidden") {
11941
12134
  return null;
11942
12135
  }
12136
+ const isButton = field.tagName === "BUTTON";
12137
+ const isBusy = field.getAttribute("aria-busy") === "true";
11943
12138
  const readonlySilent = field.hasAttribute("data-readonly-silent");
12139
+ const messageAttribute = field.getAttribute("data-readonly-message");
11944
12140
  if (readonlySilent) {
11945
12141
  return { silent: true };
11946
12142
  }
11947
- const messageAttribute = field.getAttribute("data-readonly-message");
11948
- if (messageAttribute) {
11949
- return {
11950
- message: messageAttribute,
11951
- status: "info",
11952
- };
11953
- }
11954
- const isBusy = field.getAttribute("aria-busy") === "true";
11955
12143
  if (isBusy) {
11956
12144
  return {
11957
12145
  target: field,
11958
- message: `Cette action est en cours. Veuillez patienter.`,
12146
+ message:
12147
+ messageAttribute || `Cette action est en cours. Veuillez patienter.`,
11959
12148
  status: "info",
11960
12149
  };
11961
12150
  }
11962
12151
  return {
11963
12152
  target: field,
11964
12153
  message:
11965
- field.tagName === "BUTTON"
12154
+ messageAttribute ||
12155
+ (isButton
11966
12156
  ? `Cet action n'est pas disponible pour l'instant.`
11967
- : `Cet élément est en lecture seule et ne peut pas être modifié.`,
12157
+ : `Cet élément est en lecture seule et ne peut pas être modifié.`),
11968
12158
  status: "info",
11969
12159
  };
11970
12160
  },
@@ -15389,12 +15579,12 @@ const ButtonBasic = props => {
15389
15579
  };
15390
15580
  const renderButtonContentMemoized = useCallback(renderButtonContent, [children]);
15391
15581
  return jsxs(Box, {
15582
+ "data-readonly-silent": innerLoading ? "" : undefined,
15392
15583
  ...rest,
15393
15584
  as: "button",
15394
15585
  ref: ref,
15395
15586
  "data-icon": icon ? "" : undefined,
15396
15587
  "data-discrete": discrete ? "" : undefined,
15397
- "data-readonly-silent": innerLoading ? "" : undefined,
15398
15588
  "data-callout-arrow-x": "center",
15399
15589
  "aria-busy": innerLoading
15400
15590
  // style management
@@ -23597,5 +23787,5 @@ const UserSvg = () => jsx("svg", {
23597
23787
  })
23598
23788
  });
23599
23789
 
23600
- 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, createSelectionKeyboardShortcuts, createUniqueValueConstraint, enableDebugActions, enableDebugOnDocumentLoading, forwardActionRequested, goBack, goForward, goTo, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, localStorageSignal, openCallout, rawUrlPart, reload, removeCustomMessage, rerunActions, resource, setBaseUrl, setupRoutes, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useActiveRouteInfo, useCellsAndColumns, useConstraintValidityState, useDependenciesDiff, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useNavState$1 as useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, useUrlSearchParam, valueInLocalStorage };
23790
+ 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, createUniqueValueConstraint, enableDebugActions, enableDebugOnDocumentLoading, forwardActionRequested, goBack, goForward, goTo, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, localStorageSignal, openCallout, rawUrlPart, reload, removeCustomMessage, rerunActions, resource, setBaseUrl, setupRoutes, stateSignal, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useActiveRouteInfo, useCellsAndColumns, useConstraintValidityState, useDependenciesDiff, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useNavState$1 as useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, useUrlSearchParam, valueInLocalStorage };
23601
23791
  //# sourceMappingURL=jsenv_navi.js.map