react-ui89 0.61.0 → 0.62.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/esm/index.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import * as React from 'react';
2
- import React__default, { createContext, useState, useContext, useEffect, useRef, useMemo, useImperativeHandle, useCallback } from 'react';
2
+ import React__default, { createContext, useState, useContext, useEffect, useRef, useImperativeHandle, useMemo, useCallback } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
- import DatePicker from 'react-datepicker';
5
- import Timeout from 'smart-timeout';
6
4
  import { useFloating, size, autoUpdate, useClick, useDismiss, useRole, useInteractions, FloatingPortal, FloatingFocusManager } from '@floating-ui/react';
5
+ import Timeout from 'smart-timeout';
7
6
  import { toast, ToastContainer } from 'react-toastify';
8
7
 
9
8
  var Ui89Theme;
@@ -208,33 +207,123 @@ function Ui89CardHorizontalConnection({ children, overflow, }) {
208
207
  return (React__default.createElement("div", { className: `ui89-card__horizontal-connection ${overflow ? "ui89-card__horizontal-connection--overflow" : ""}` }, children));
209
208
  }
210
209
 
211
- function Ui89DateTimePicker(props) {
212
- function datepickerOnChange(value) {
213
- if (props.onChange) {
214
- props.onChange(value);
215
- }
216
- }
217
- return (React__default.createElement("span", { className: "ui89-date-time-picker" },
218
- React__default.createElement(DatePicker, { className: ["ui89-input-box"].join(" "), calendarClassName: "ui89-typo-normal", showTimeSelect: true, dateFormat: props.dateFormat ?? "yyyy/MM/dd HH:mm:ss", timeFormat: "HH:mm", selected: props.value, onChange: datepickerOnChange, popperPlacement: "bottom-start" })));
210
+ function Ui89Scene({ look = Ui89Look.main, children }) {
211
+ return (React__default.createElement("div", { className: `ui89-scene ui-89-look-${look} ui89-typo-normal ui89-scrollbar` }, children));
219
212
  }
220
213
 
221
- const TimeAnimation = ({ children }) => {
222
- const [currentTime, setCurrentTime] = useState(new Date());
214
+ function useZIndexer(open) {
215
+ const overrides = useUi89();
216
+ const [value, setValue] = useState(overrides.currentZIndex);
223
217
  useEffect(() => {
224
- const tick = () => {
225
- const now = new Date();
226
- setCurrentTime(now);
227
- // Calculate time until the next exact second
228
- const msUntilNextSecond = 1000 - now.getMilliseconds();
229
- setTimeout(tick, msUntilNextSecond);
230
- };
231
- // Start the first tick
232
- const msUntilNextSecond = 1000 - currentTime.getMilliseconds();
233
- const timeoutId = setTimeout(tick, msUntilNextSecond);
234
- return () => clearTimeout(timeoutId);
235
- }, []);
236
- return React__default.createElement(React__default.Fragment, null, children({ now: currentTime }));
237
- };
218
+ if (open) {
219
+ setValue(overrides.nextZIndex());
220
+ }
221
+ }, [open]);
222
+ return {
223
+ value,
224
+ };
225
+ }
226
+
227
+ var Ui89PopoverPropsPlacement;
228
+ (function (Ui89PopoverPropsPlacement) {
229
+ Ui89PopoverPropsPlacement["top"] = "top";
230
+ Ui89PopoverPropsPlacement["topStart"] = "topStart";
231
+ Ui89PopoverPropsPlacement["topEnd"] = "topEnd";
232
+ Ui89PopoverPropsPlacement["right"] = "right";
233
+ Ui89PopoverPropsPlacement["rightStart"] = "rightStart";
234
+ Ui89PopoverPropsPlacement["rightEnd"] = "rightEnd";
235
+ Ui89PopoverPropsPlacement["bottom"] = "bottom";
236
+ Ui89PopoverPropsPlacement["bottomStart"] = "bottomStart";
237
+ Ui89PopoverPropsPlacement["bottomEnd"] = "bottomEnd";
238
+ Ui89PopoverPropsPlacement["left"] = "left";
239
+ Ui89PopoverPropsPlacement["leftStart"] = "leftStart";
240
+ Ui89PopoverPropsPlacement["leftEnd"] = "leftEnd";
241
+ })(Ui89PopoverPropsPlacement || (Ui89PopoverPropsPlacement = {}));
242
+ function toFloatingUiPlacement(placement) {
243
+ switch (placement) {
244
+ case Ui89PopoverPropsPlacement.top:
245
+ return "top";
246
+ case Ui89PopoverPropsPlacement.topStart:
247
+ return "top-start";
248
+ case Ui89PopoverPropsPlacement.topEnd:
249
+ return "top-end";
250
+ case Ui89PopoverPropsPlacement.right:
251
+ return "right";
252
+ case Ui89PopoverPropsPlacement.rightStart:
253
+ return "right-start";
254
+ case Ui89PopoverPropsPlacement.rightEnd:
255
+ return "right-end";
256
+ case Ui89PopoverPropsPlacement.bottom:
257
+ return "bottom";
258
+ case Ui89PopoverPropsPlacement.bottomStart:
259
+ return "bottom-start";
260
+ case Ui89PopoverPropsPlacement.bottomEnd:
261
+ return "bottom-end";
262
+ case Ui89PopoverPropsPlacement.left:
263
+ return "left";
264
+ case Ui89PopoverPropsPlacement.leftStart:
265
+ return "left-start";
266
+ case Ui89PopoverPropsPlacement.leftEnd:
267
+ return "left-end";
268
+ default:
269
+ throw new Error(`Unknown placement: ${placement}`);
270
+ }
271
+ }
272
+ function Ui89Popover(props) {
273
+ const zIndexer = useZIndexer(props.open);
274
+ const { refs, floatingStyles, context } = useFloating({
275
+ open: props.open,
276
+ onOpenChange: props.onOpenChange,
277
+ middleware: [
278
+ size({
279
+ apply({ availableWidth, availableHeight, elements }) {
280
+ let width = elements.reference.getBoundingClientRect().width;
281
+ if (props.popoverOverflowMaxWidth !== undefined) {
282
+ if (props.popoverOverflowMaxWidth > width) {
283
+ width = props.popoverOverflowMaxWidth;
284
+ }
285
+ }
286
+ const style = {
287
+ maxWidth: `${width}px`,
288
+ maxHeight: `${Math.max(0, availableHeight)}px`,
289
+ };
290
+ if (props.popoverOverflowForce) {
291
+ style.width = `${availableWidth}px`;
292
+ }
293
+ // Change styles, e.g.
294
+ Object.assign(elements.floating.style, style);
295
+ },
296
+ }),
297
+ ],
298
+ whileElementsMounted: autoUpdate,
299
+ placement: toFloatingUiPlacement(props.placement ?? Ui89PopoverPropsPlacement.bottomStart),
300
+ strategy: "fixed",
301
+ });
302
+ const click = useClick(context, {
303
+ keyboardHandlers: false,
304
+ });
305
+ const dismiss = useDismiss(context);
306
+ const role = useRole(context);
307
+ const { getReferenceProps, getFloatingProps } = useInteractions([
308
+ click,
309
+ dismiss,
310
+ role,
311
+ ]);
312
+ return (React__default.createElement(React__default.Fragment, null,
313
+ props.renderContainer({
314
+ setRef: refs.setReference,
315
+ props: getReferenceProps(),
316
+ }),
317
+ props.open && (React__default.createElement(FloatingPortal, null,
318
+ React__default.createElement(FloatingFocusManager, { context: context, modal: false, initialFocus: -1 },
319
+ React__default.createElement(Ui89Scene, null,
320
+ React__default.createElement("div", { ref: refs.setFloating, style: {
321
+ ...floatingStyles,
322
+ zIndex: zIndexer.value,
323
+ display: "flex",
324
+ flexDirection: "column",
325
+ } }, props.renderPopover())))))));
326
+ }
238
327
 
239
328
  function dateFormat(date, format) {
240
329
  const placeholders = {
@@ -255,85 +344,460 @@ function dateFormat(date, format) {
255
344
  return formattedDate;
256
345
  }
257
346
 
258
- function Ui89DigitalClock({ format = "HH:mm:ss", }) {
259
- function render({ now }) {
260
- return dateFormat(now, format);
261
- }
262
- return (React__default.createElement("span", { className: "ui89-typo-special" },
263
- React__default.createElement(TimeAnimation, null, render)));
264
- }
265
-
266
- function Ui89HighlightText({ theme, block, children, }) {
267
- return (React__default.createElement("span", { className: `ui89-highlight-text ui89-chosen-theme-${theme} ${block ? "ui89-highlight-text--block" : null}` }, children));
268
- }
269
-
270
- var Ui89HrPropsLook;
271
- (function (Ui89HrPropsLook) {
272
- Ui89HrPropsLook["straight"] = "straight";
273
- Ui89HrPropsLook["dotted"] = "dotted";
274
- Ui89HrPropsLook["dashed"] = "dashed";
275
- Ui89HrPropsLook["double"] = "double";
276
- })(Ui89HrPropsLook || (Ui89HrPropsLook = {}));
277
- function Ui89Hr({ look = "straight", theme }) {
278
- return (React__default.createElement("div", { className: `ui-89-hr ${`ui-89-hr--${look}`} ${theme !== undefined ? "ui-89-hr--use-theme" : ""} ${theme !== undefined ? `ui89-chosen-theme-${theme}` : ""}` },
279
- React__default.createElement("div", { className: "ui-89-hr__double" })));
280
- }
281
-
282
- function Ui89SpacePadding(props) {
283
- const gap = props.gap ?? 1;
284
- const style = {
285
- paddingTop: `calc(var(--ui89-safe-space) * ${props.gapTop ?? props.gapVertical ?? gap})`,
286
- paddingRight: `calc(var(--ui89-safe-space) * ${props.gapRight ?? props.gapHorizontal ?? gap})`,
287
- paddingBottom: `calc(var(--ui89-safe-space) * ${props.gapBottom ?? props.gapVertical ?? gap})`,
288
- paddingLeft: `calc(var(--ui89-safe-space) * ${props.gapLeft ?? props.gapHorizontal ?? gap})`,
347
+ let uniqueId = 0;
348
+ function throttledTimeout() {
349
+ const id = String(uniqueId++);
350
+ let callback;
351
+ return {
352
+ call(delay, f) {
353
+ callback = f;
354
+ if (Timeout.pending(id)) {
355
+ Timeout.restart(id);
356
+ }
357
+ else {
358
+ Timeout.set(id, () => callback(), delay);
359
+ }
360
+ },
361
+ /**
362
+ * If there is a call that has been scheduled, remove it from the queue.
363
+ */
364
+ abort() {
365
+ Timeout.clear(id, true);
366
+ },
367
+ /**
368
+ * Lets you know whether a call is pending.
369
+ */
370
+ isPending() {
371
+ return Timeout.pending(id);
372
+ },
289
373
  };
290
- return React__default.createElement("div", { style: style }, props.children);
291
374
  }
292
375
 
293
- function Ui89Indent(props) {
294
- const gap = props.gap ?? 1;
295
- return (React__default.createElement(Ui89SpacePadding, { gap: 0, gapLeft: gap }, props.children));
376
+ function useUpdatedRef(value) {
377
+ const valueRef = useRef(value);
378
+ useEffect(() => {
379
+ valueRef.current = value;
380
+ }, [value]);
381
+ return valueRef;
296
382
  }
297
383
 
298
- function Ui89InputCheckBox(props) {
299
- function toggle() {
300
- if (props.onChange) {
301
- props.onChange(!props.value);
384
+ const LAST_VALUE_CHANGED = Symbol("LAST_VALUE_CHANGED");
385
+ const OVERRIDEN_VALUE_UNDEFINED = Symbol("OVERRIDEN_VALUE_UNDEFINED");
386
+ function useDelayedOnChange(props) {
387
+ const valueRef = useUpdatedRef(props.value);
388
+ const onChangeRef = useUpdatedRef(props.onChange);
389
+ const [intermediateValue, setIntermediateValue] = useState(props.defaultValue || props.value);
390
+ useEffect(() => {
391
+ stateRef.current.setValue(props.value);
392
+ }, [props.value]);
393
+ function callOnChange() {
394
+ let newVal = stateRef.current.value;
395
+ if (props.filter !== undefined) {
396
+ newVal = props.filter(newVal);
397
+ }
398
+ if (newVal !== valueRef.current) {
399
+ onChangeRef.current?.call(null, newVal);
302
400
  }
401
+ return newVal;
303
402
  }
304
- return (React__default.createElement("span", { className: "ui89-input-check-box", onClick: toggle, role: "checkbox", "aria-checked": props.value ? "true" : "false" },
305
- React__default.createElement("span", { className: "ui89-input-check-box__x" }, props.value ? React__default.createElement(React__default.Fragment, null, "X") : React__default.createElement(React__default.Fragment, null, "\u00A0"))));
306
- }
307
-
308
- const useResizeObserver = (ref) => {
309
- const [size, setSize] = useState({ width: 0, height: 0 });
310
- useEffect(() => {
311
- const observer = new ResizeObserver((entries) => {
312
- for (let entry of entries) {
313
- setSize({
314
- width: entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width,
315
- height: entry.borderBoxSize?.[0]?.blockSize ?? entry.contentRect.height,
316
- });
317
- }
318
- });
319
- if (ref.current) {
320
- observer.observe(ref.current);
403
+ class StateUnknown {
404
+ state = "unknown";
405
+ value;
406
+ throttledTimeout;
407
+ constructor() {
408
+ this.throttledTimeout = throttledTimeout();
321
409
  }
322
- return () => {
323
- observer.disconnect();
324
- };
325
- }, [ref.current]);
326
- return {
327
- size,
328
- };
329
- };
330
-
331
- const useScrollYPosition = (ref) => {
332
- const [scrollY, setScrollY] = useState(0);
333
- const ticking = useRef(false);
334
- const observer = useRef(null);
335
- useEffect(() => {
336
- const element = ref.current;
410
+ setValue(newVal) {
411
+ setIntermediateValue(newVal);
412
+ }
413
+ onChange(newVal) {
414
+ setIntermediateValue(newVal);
415
+ stateRef.current.throttledTimeout.call(300, callOnChange);
416
+ }
417
+ onFocus() {
418
+ let newState = new StateFocus();
419
+ newState.value = stateRef.current.value;
420
+ newState.lastValue = newState.value;
421
+ setState(newState);
422
+ }
423
+ onBlur() { }
424
+ onConfirm() {
425
+ callOnChange();
426
+ }
427
+ }
428
+ class StateFocus {
429
+ state = "focus";
430
+ value;
431
+ lastValue;
432
+ /**
433
+ * If we receive a new value, we keep track of it here. We set this to
434
+ * OVERRIDEN_VALUE_UNDEFINED if the value is meant to be discarded.
435
+ */
436
+ overridenValue;
437
+ throttledTimeout;
438
+ constructor() {
439
+ this.overridenValue = OVERRIDEN_VALUE_UNDEFINED;
440
+ this.throttledTimeout = throttledTimeout();
441
+ }
442
+ setValue(newVal) {
443
+ if (stateRef.current.value === stateRef.current.lastValue) {
444
+ // No changes.
445
+ setIntermediateValue(newVal);
446
+ // Making sure we keep updating.
447
+ stateRef.current.lastValue = newVal;
448
+ }
449
+ else {
450
+ // There have been changes. Let's not bother the user.
451
+ stateRef.current.overridenValue = newVal;
452
+ }
453
+ }
454
+ onChange(newVal) {
455
+ // Discard last setValue call
456
+ stateRef.current.overridenValue = OVERRIDEN_VALUE_UNDEFINED;
457
+ stateRef.current.lastValue = LAST_VALUE_CHANGED;
458
+ setIntermediateValue(newVal);
459
+ stateRef.current.throttledTimeout.call(300, callOnChange);
460
+ }
461
+ onFocus() { }
462
+ onBlur() {
463
+ // We need to make sure that we emit immediately. Do not want to leave
464
+ // user waiting.
465
+ // We can cancel this one.
466
+ stateRef.current.throttledTimeout.abort();
467
+ if (stateRef.current.overridenValue !== OVERRIDEN_VALUE_UNDEFINED) {
468
+ stateRef.current.value = stateRef.current.overridenValue;
469
+ }
470
+ let newVal = callOnChange();
471
+ setIntermediateValue(newVal);
472
+ let newState = new StateUnknown();
473
+ newState.value = newVal;
474
+ setState(newState);
475
+ }
476
+ onConfirm() {
477
+ callOnChange();
478
+ }
479
+ }
480
+ const [state, setState] = useState(() => {
481
+ let newState = new StateUnknown();
482
+ newState.value = intermediateValue;
483
+ return newState;
484
+ });
485
+ const stateRef = useUpdatedRef(state);
486
+ stateRef.current.value = intermediateValue;
487
+ return state;
488
+ }
489
+
490
+ const Ui89InputText = React__default.forwardRef(function Ui89InputText({ value, placeholder, autoTrim = true, disabled, textAlign, onChange, onTyping, onFocus, onBlur, }, ref) {
491
+ const inputRef = useRef(null);
492
+ const delayedState = useDelayedOnChange({
493
+ defaultValue: "",
494
+ value,
495
+ onChange,
496
+ filter(value) {
497
+ if (autoTrim) {
498
+ if (typeof value === "string") {
499
+ value = value.replace(/\s+/g, " ").trim();
500
+ }
501
+ }
502
+ return value;
503
+ },
504
+ });
505
+ useImperativeHandle(ref, () => ({
506
+ focus: () => {
507
+ inputRef.current?.focus();
508
+ },
509
+ }));
510
+ return (React__default.createElement("div", null,
511
+ React__default.createElement("input", { ref: inputRef, className: [
512
+ "ui89-input-box",
513
+ disabled ? "ui89-input-box--disabled" : "",
514
+ ].join(" "), style: { textAlign }, type: "text", disabled: disabled, value: delayedState.value, onChange: (e) => delayedState.onChange(e.target.value), onBlur: delayedState.onBlur, onFocus: delayedState.onFocus, onKeyDown: (e) => {
515
+ if (e.key === "Enter") {
516
+ delayedState.onConfirm();
517
+ }
518
+ }, placeholder: placeholder })));
519
+ });
520
+
521
+ function stringRemoveAllWhitespace(str) {
522
+ return str.replace(/\s+/g, "");
523
+ }
524
+
525
+ function isTextNumber(text) {
526
+ return /^\d+(\.\d+)?$/.test(text);
527
+ }
528
+ function displayText(value) {
529
+ if (value === undefined) {
530
+ // No idea how to display this.
531
+ return "";
532
+ }
533
+ else if (isNaN(value)) {
534
+ // No idea what to display.
535
+ return "";
536
+ }
537
+ return value.toString();
538
+ }
539
+ function dotsMakeMoreSense(value) {
540
+ return value.replaceAll(",", ".");
541
+ }
542
+ function Ui89InputTextNumber(props) {
543
+ const wrappedValue = useMemo(() => {
544
+ return displayText(props.value);
545
+ }, [props.value]);
546
+ function implOnChange(value) {
547
+ if (props.onChange === undefined) {
548
+ return;
549
+ }
550
+ if (value === "") {
551
+ // Use empty value.
552
+ props.onChange(props.emptyValue);
553
+ return;
554
+ }
555
+ value = stringRemoveAllWhitespace(value);
556
+ value = dotsMakeMoreSense(value);
557
+ if (!isTextNumber(value)) {
558
+ // We end here.
559
+ return;
560
+ }
561
+ const numberValue = Number(value);
562
+ if (props.min !== undefined) {
563
+ if (numberValue <= props.min) {
564
+ value = String(props.min);
565
+ }
566
+ }
567
+ if (props.max !== undefined) {
568
+ if (numberValue >= props.max) {
569
+ value = String(props.max);
570
+ }
571
+ }
572
+ props.onChange(value);
573
+ }
574
+ return (React__default.createElement(Ui89InputText, { value: wrappedValue, onChange: implOnChange, disabled: props.disabled, textAlign: props.textAlign }));
575
+ }
576
+
577
+ function Ui89DateTimePicker(props) {
578
+ const [open, setOpen] = useState(false);
579
+ const [inputValue, setInputValue] = useState("");
580
+ const [viewDate, setViewDate] = useState(new Date());
581
+ const dateFormat$1 = props.dateFormat ?? "YYYY/MM/DD HH:mm:ss";
582
+ useEffect(() => {
583
+ if (props.value) {
584
+ setInputValue(dateFormat(props.value, dateFormat$1));
585
+ setViewDate(props.value);
586
+ }
587
+ else {
588
+ setInputValue("");
589
+ }
590
+ }, [props.value, dateFormat$1]);
591
+ function handleInputChange(val) {
592
+ setInputValue(val);
593
+ const date = new Date(val);
594
+ if (!isNaN(date.getTime())) {
595
+ if (props.onChange)
596
+ props.onChange(date);
597
+ setViewDate(date);
598
+ }
599
+ else if (val.trim() === "") {
600
+ if (props.onChange)
601
+ props.onChange(null);
602
+ }
603
+ }
604
+ function adjustMonth(offset) {
605
+ const newDate = new Date(viewDate);
606
+ newDate.setMonth(newDate.getMonth() + offset);
607
+ setViewDate(newDate);
608
+ }
609
+ function handleDayClick(day) {
610
+ const newDate = new Date(day);
611
+ if (props.value) {
612
+ newDate.setHours(props.value.getHours());
613
+ newDate.setMinutes(props.value.getMinutes());
614
+ newDate.setSeconds(props.value.getSeconds());
615
+ }
616
+ else {
617
+ newDate.setHours(12, 0, 0, 0);
618
+ }
619
+ if (props.onChange)
620
+ props.onChange(newDate);
621
+ }
622
+ function handleTimeChange(type, val) {
623
+ if (!props.value)
624
+ return;
625
+ const num = parseInt(val, 10);
626
+ if (isNaN(num))
627
+ return;
628
+ const newDate = new Date(props.value);
629
+ if (type === "h")
630
+ newDate.setHours(Math.min(23, Math.max(0, num)));
631
+ if (type === "m")
632
+ newDate.setMinutes(Math.min(59, Math.max(0, num)));
633
+ if (type === "s")
634
+ newDate.setSeconds(Math.min(59, Math.max(0, num)));
635
+ if (props.onChange)
636
+ props.onChange(newDate);
637
+ }
638
+ function renderCalendar() {
639
+ const year = viewDate.getFullYear();
640
+ const month = viewDate.getMonth();
641
+ const firstDay = new Date(year, month, 1);
642
+ const startDay = firstDay.getDay();
643
+ const startDate = new Date(year, month, 1 - startDay);
644
+ const days = [];
645
+ const current = new Date(startDate);
646
+ for (let i = 0; i < 42; i++) {
647
+ days.push(new Date(current));
648
+ current.setDate(current.getDate() + 1);
649
+ }
650
+ return (React__default.createElement("div", { style: { width: "300px", padding: "10px" } },
651
+ React__default.createElement("div", { style: {
652
+ display: "flex",
653
+ justifyContent: "space-between",
654
+ alignItems: "center",
655
+ marginBottom: "10px",
656
+ } },
657
+ React__default.createElement(Ui89Button, { size: Ui89ButtonPropsSize.square, onClick: () => adjustMonth(-1) }, "<"),
658
+ React__default.createElement("div", { className: "ui89-typo-normal" }, dateFormat(viewDate, "MM/YYYY")),
659
+ React__default.createElement(Ui89Button, { size: Ui89ButtonPropsSize.square, onClick: () => adjustMonth(1) }, ">")),
660
+ React__default.createElement("div", { style: {
661
+ display: "grid",
662
+ gridTemplateColumns: "repeat(7, 1fr)",
663
+ gap: "2px",
664
+ } },
665
+ ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((d) => (React__default.createElement("div", { key: d, className: "ui89-typo-small-bold", style: { textAlign: "center", padding: "5px" } }, d))),
666
+ days.map((d, i) => {
667
+ const isSelected = props.value &&
668
+ d.getDate() === props.value.getDate() &&
669
+ d.getMonth() === props.value.getMonth() &&
670
+ d.getFullYear() === props.value.getFullYear();
671
+ const isCurrentMonth = d.getMonth() === month;
672
+ return (React__default.createElement("div", { key: i, className: "ui89-typo-normal", onClick: () => handleDayClick(d), style: {
673
+ textAlign: "center",
674
+ padding: "5px",
675
+ cursor: "pointer",
676
+ backgroundColor: isSelected
677
+ ? "var(--ui89-theme-primary-bg-color)"
678
+ : "transparent",
679
+ opacity: isCurrentMonth ? 1 : 0.3,
680
+ } }, d.getDate()));
681
+ })),
682
+ props.value && (React__default.createElement("div", { style: {
683
+ display: "flex",
684
+ gap: "5px",
685
+ marginTop: "10px",
686
+ justifyContent: "center",
687
+ alignItems: "center",
688
+ } },
689
+ React__default.createElement("div", { style: { width: "35px" } },
690
+ React__default.createElement(Ui89InputTextNumber, { value: props.value.getHours(), onChange: (val) => handleTimeChange("h", val), min: 0, max: 23, textAlign: "right" })),
691
+ ":",
692
+ React__default.createElement("div", { style: { width: "35px" } },
693
+ React__default.createElement(Ui89InputTextNumber, { value: props.value.getMinutes(), onChange: (val) => handleTimeChange("m", val), min: 0, max: 59, textAlign: "right" })),
694
+ ":",
695
+ React__default.createElement("div", { style: { width: "35px" } },
696
+ React__default.createElement(Ui89InputTextNumber, { value: props.value.getSeconds(), onChange: (val) => handleTimeChange("s", val), min: 0, max: 59, textAlign: "right" }))))));
697
+ }
698
+ return (React__default.createElement(Ui89Popover, { open: open, onOpenChange: setOpen, popoverOverflowMaxWidth: 360, renderContainer: ({ setRef, props: popoverProps }) => (React__default.createElement("div", { className: "ui89-date-time-picker", ref: setRef, ...popoverProps },
699
+ React__default.createElement(Ui89InputText, { value: inputValue, onChange: handleInputChange, placeholder: dateFormat$1 }))), renderPopover: () => (React__default.createElement("div", { style: { maxWidth: "360px" } },
700
+ React__default.createElement(HoverShadow, null,
701
+ React__default.createElement(Ui89Card, null, renderCalendar())))) }));
702
+ }
703
+
704
+ const TimeAnimation = ({ children }) => {
705
+ const [currentTime, setCurrentTime] = useState(new Date());
706
+ useEffect(() => {
707
+ const tick = () => {
708
+ const now = new Date();
709
+ setCurrentTime(now);
710
+ // Calculate time until the next exact second
711
+ const msUntilNextSecond = 1000 - now.getMilliseconds();
712
+ setTimeout(tick, msUntilNextSecond);
713
+ };
714
+ // Start the first tick
715
+ const msUntilNextSecond = 1000 - currentTime.getMilliseconds();
716
+ const timeoutId = setTimeout(tick, msUntilNextSecond);
717
+ return () => clearTimeout(timeoutId);
718
+ }, []);
719
+ return React__default.createElement(React__default.Fragment, null, children({ now: currentTime }));
720
+ };
721
+
722
+ function Ui89DigitalClock({ format = "HH:mm:ss", }) {
723
+ function render({ now }) {
724
+ return dateFormat(now, format);
725
+ }
726
+ return (React__default.createElement("span", { className: "ui89-typo-special" },
727
+ React__default.createElement(TimeAnimation, null, render)));
728
+ }
729
+
730
+ function Ui89HighlightText({ theme, block, children, }) {
731
+ return (React__default.createElement("span", { className: `ui89-highlight-text ui89-chosen-theme-${theme} ${block ? "ui89-highlight-text--block" : null}` }, children));
732
+ }
733
+
734
+ var Ui89HrPropsLook;
735
+ (function (Ui89HrPropsLook) {
736
+ Ui89HrPropsLook["straight"] = "straight";
737
+ Ui89HrPropsLook["dotted"] = "dotted";
738
+ Ui89HrPropsLook["dashed"] = "dashed";
739
+ Ui89HrPropsLook["double"] = "double";
740
+ })(Ui89HrPropsLook || (Ui89HrPropsLook = {}));
741
+ function Ui89Hr({ look = "straight", theme }) {
742
+ return (React__default.createElement("div", { className: `ui-89-hr ${`ui-89-hr--${look}`} ${theme !== undefined ? "ui-89-hr--use-theme" : ""} ${theme !== undefined ? `ui89-chosen-theme-${theme}` : ""}` },
743
+ React__default.createElement("div", { className: "ui-89-hr__double" })));
744
+ }
745
+
746
+ function Ui89SpacePadding(props) {
747
+ const gap = props.gap ?? 1;
748
+ const style = {
749
+ paddingTop: `calc(var(--ui89-safe-space) * ${props.gapTop ?? props.gapVertical ?? gap})`,
750
+ paddingRight: `calc(var(--ui89-safe-space) * ${props.gapRight ?? props.gapHorizontal ?? gap})`,
751
+ paddingBottom: `calc(var(--ui89-safe-space) * ${props.gapBottom ?? props.gapVertical ?? gap})`,
752
+ paddingLeft: `calc(var(--ui89-safe-space) * ${props.gapLeft ?? props.gapHorizontal ?? gap})`,
753
+ };
754
+ return React__default.createElement("div", { style: style }, props.children);
755
+ }
756
+
757
+ function Ui89Indent(props) {
758
+ const gap = props.gap ?? 1;
759
+ return (React__default.createElement(Ui89SpacePadding, { gap: 0, gapLeft: gap }, props.children));
760
+ }
761
+
762
+ function Ui89InputCheckBox(props) {
763
+ function toggle() {
764
+ if (props.onChange) {
765
+ props.onChange(!props.value);
766
+ }
767
+ }
768
+ return (React__default.createElement("span", { className: "ui89-input-check-box", onClick: toggle, role: "checkbox", "aria-checked": props.value ? "true" : "false" },
769
+ React__default.createElement("span", { className: "ui89-input-check-box__x" }, props.value ? React__default.createElement(React__default.Fragment, null, "X") : React__default.createElement(React__default.Fragment, null, "\u00A0"))));
770
+ }
771
+
772
+ const useResizeObserver = (ref) => {
773
+ const [size, setSize] = useState({ width: 0, height: 0 });
774
+ useEffect(() => {
775
+ const observer = new ResizeObserver((entries) => {
776
+ for (let entry of entries) {
777
+ setSize({
778
+ width: entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width,
779
+ height: entry.borderBoxSize?.[0]?.blockSize ?? entry.contentRect.height,
780
+ });
781
+ }
782
+ });
783
+ if (ref.current) {
784
+ observer.observe(ref.current);
785
+ }
786
+ return () => {
787
+ observer.disconnect();
788
+ };
789
+ }, [ref.current]);
790
+ return {
791
+ size,
792
+ };
793
+ };
794
+
795
+ const useScrollYPosition = (ref) => {
796
+ const [scrollY, setScrollY] = useState(0);
797
+ const ticking = useRef(false);
798
+ const observer = useRef(null);
799
+ useEffect(() => {
800
+ const element = ref.current;
337
801
  if (!element)
338
802
  return;
339
803
  const handleScroll = () => {
@@ -469,384 +933,97 @@ function Ui89InputCheckList(props) {
469
933
  ? props.getValueKey(value)
470
934
  : String(value);
471
935
  }
472
- const valueSet = useMemo(() => {
473
- const set = new Set();
474
- for (const value of props.value) {
475
- set.add(getValueKey(value));
476
- }
477
- return set;
478
- }, [props.value]);
479
- const renderRow = (props2) => {
480
- const key = getValueKey(props2.row);
481
- const value = valueSet.has(key);
482
- const label = props.renderOption !== undefined
483
- ? props.renderOption({ option: props2.row, index: props2.index })
484
- : String(props2.row);
485
- function onChange(checked) {
486
- if (checked) {
487
- if (props.onSelect !== undefined) {
488
- props.onSelect(props2.row);
489
- }
490
- }
491
- else {
492
- if (props.onDeselect !== undefined) {
493
- props.onDeselect(props2.row);
494
- }
495
- }
496
- if (props.onChange !== undefined) {
497
- if (checked) {
498
- props.onChange([...props.value, props2.row]);
499
- }
500
- else {
501
- props.onChange(props.value.filter((item) => getValueKey(item) !== key));
502
- }
503
- }
504
- }
505
- function toggle() {
506
- onChange(!value);
507
- }
508
- return (React__default.createElement("div", { style: {
509
- display: "flex",
510
- alignItems: "center",
511
- gap: "var(--ui89-safe-space)",
512
- height: "100%",
513
- } },
514
- React__default.createElement(Ui89InputCheckBox, { value: value, onChange: onChange }),
515
- React__default.createElement("div", { className: "ui89-text-ellipsis", style: { minWidth: 0, cursor: "pointer" }, onClick: toggle }, label)));
516
- };
517
- return (React__default.createElement("div", { style: {
518
- display: "flex",
519
- flexDirection: "column",
520
- maxHeight: props.maxHeight,
521
- } },
522
- React__default.createElement(Ui89VirtualList, { rows: props.options, renderRow: renderRow, getRowKey: props.getValueKey, rowHeight: props.optionHeight ?? 40, maxHeight: "100%" })));
523
- }
524
-
525
- function Ui89InputCheckText(props) {
526
- function toggle() {
527
- if (props.onChange) {
528
- props.onChange(!props.value);
529
- }
530
- }
531
- return (React__default.createElement("span", { className: "ui89-input-check-text", onClick: toggle }, props.value ? "[X]" : "[ ]"));
532
- }
533
-
534
- function Ui89InputFileUpload(props) {
535
- const inputRef = useRef(null);
536
- function implOnChange(e) {
537
- if (!props.onChange) {
538
- return;
539
- }
540
- if (e.target.files === null) {
541
- props.onChange(null);
542
- return;
543
- }
544
- if (e.target.files.length === 0) {
545
- props.onChange(null);
546
- return;
547
- }
548
- props.onChange(e.target.files[0]);
549
- // Reset the file input's value to allow selecting the same file again.
550
- e.target.value = "";
551
- }
552
- function onClick() {
553
- if (inputRef.current === null) {
554
- return;
555
- }
556
- inputRef.current.click();
557
- }
558
- return (React__default.createElement("div", null,
559
- React__default.createElement("input", { ref: inputRef, className: "ui89-typo-special", type: "file", onChange: implOnChange, accept: props.accept, hidden: true }),
560
- props.value ? (React__default.createElement("div", { className: "ui89-input-file-upload" },
561
- React__default.createElement(Ui89Button, { onClick: onClick }, "Change"),
562
- React__default.createElement("span", { className: `ui89-input-file-upload__info ui89-text-single-line ui89-text-single-line--ellipsis-left`, title: props.value.name }, props.value.name))) : (React__default.createElement(Ui89Button, { onClick: onClick }, "Upload"))));
563
- }
564
-
565
- let uniqueId = 0;
566
- function throttledTimeout() {
567
- const id = String(uniqueId++);
568
- let callback;
569
- return {
570
- call(delay, f) {
571
- callback = f;
572
- if (Timeout.pending(id)) {
573
- Timeout.restart(id);
574
- }
575
- else {
576
- Timeout.set(id, () => callback(), delay);
577
- }
578
- },
579
- /**
580
- * If there is a call that has been scheduled, remove it from the queue.
581
- */
582
- abort() {
583
- Timeout.clear(id, true);
584
- },
585
- /**
586
- * Lets you know whether a call is pending.
587
- */
588
- isPending() {
589
- return Timeout.pending(id);
590
- },
591
- };
592
- }
593
-
594
- function useUpdatedRef(value) {
595
- const valueRef = useRef(value);
596
- useEffect(() => {
597
- valueRef.current = value;
598
- }, [value]);
599
- return valueRef;
600
- }
601
-
602
- const LAST_VALUE_CHANGED = Symbol("LAST_VALUE_CHANGED");
603
- const OVERRIDEN_VALUE_UNDEFINED = Symbol("OVERRIDEN_VALUE_UNDEFINED");
604
- function useDelayedOnChange(props) {
605
- const valueRef = useUpdatedRef(props.value);
606
- const onChangeRef = useUpdatedRef(props.onChange);
607
- const [intermediateValue, setIntermediateValue] = useState(props.defaultValue || props.value);
608
- useEffect(() => {
609
- stateRef.current.setValue(props.value);
610
- }, [props.value]);
611
- function callOnChange() {
612
- let newVal = stateRef.current.value;
613
- if (props.filter !== undefined) {
614
- newVal = props.filter(newVal);
615
- }
616
- if (newVal !== valueRef.current) {
617
- onChangeRef.current?.call(null, newVal);
618
- }
619
- return newVal;
620
- }
621
- class StateUnknown {
622
- state = "unknown";
623
- value;
624
- throttledTimeout;
625
- constructor() {
626
- this.throttledTimeout = throttledTimeout();
627
- }
628
- setValue(newVal) {
629
- setIntermediateValue(newVal);
630
- }
631
- onChange(newVal) {
632
- setIntermediateValue(newVal);
633
- stateRef.current.throttledTimeout.call(300, callOnChange);
634
- }
635
- onFocus() {
636
- let newState = new StateFocus();
637
- newState.value = stateRef.current.value;
638
- newState.lastValue = newState.value;
639
- setState(newState);
640
- }
641
- onBlur() { }
642
- onConfirm() {
643
- callOnChange();
644
- }
645
- }
646
- class StateFocus {
647
- state = "focus";
648
- value;
649
- lastValue;
650
- /**
651
- * If we receive a new value, we keep track of it here. We set this to
652
- * OVERRIDEN_VALUE_UNDEFINED if the value is meant to be discarded.
653
- */
654
- overridenValue;
655
- throttledTimeout;
656
- constructor() {
657
- this.overridenValue = OVERRIDEN_VALUE_UNDEFINED;
658
- this.throttledTimeout = throttledTimeout();
659
- }
660
- setValue(newVal) {
661
- if (stateRef.current.value === stateRef.current.lastValue) {
662
- // No changes.
663
- setIntermediateValue(newVal);
664
- // Making sure we keep updating.
665
- stateRef.current.lastValue = newVal;
666
- }
667
- else {
668
- // There have been changes. Let's not bother the user.
669
- stateRef.current.overridenValue = newVal;
670
- }
671
- }
672
- onChange(newVal) {
673
- // Discard last setValue call
674
- stateRef.current.overridenValue = OVERRIDEN_VALUE_UNDEFINED;
675
- stateRef.current.lastValue = LAST_VALUE_CHANGED;
676
- setIntermediateValue(newVal);
677
- stateRef.current.throttledTimeout.call(300, callOnChange);
678
- }
679
- onFocus() { }
680
- onBlur() {
681
- // We need to make sure that we emit immediately. Do not want to leave
682
- // user waiting.
683
- // We can cancel this one.
684
- stateRef.current.throttledTimeout.abort();
685
- if (stateRef.current.overridenValue !== OVERRIDEN_VALUE_UNDEFINED) {
686
- stateRef.current.value = stateRef.current.overridenValue;
687
- }
688
- let newVal = callOnChange();
689
- setIntermediateValue(newVal);
690
- let newState = new StateUnknown();
691
- newState.value = newVal;
692
- setState(newState);
693
- }
694
- onConfirm() {
695
- callOnChange();
696
- }
697
- }
698
- const [state, setState] = useState(() => {
699
- let newState = new StateUnknown();
700
- newState.value = intermediateValue;
701
- return newState;
702
- });
703
- const stateRef = useUpdatedRef(state);
704
- stateRef.current.value = intermediateValue;
705
- return state;
706
- }
707
-
708
- const Ui89InputText = React__default.forwardRef(function Ui89InputText({ value, placeholder, autoTrim = true, disabled, onChange, onTyping, onFocus, onBlur, }, ref) {
709
- const inputRef = useRef(null);
710
- const delayedState = useDelayedOnChange({
711
- defaultValue: "",
712
- value,
713
- onChange,
714
- filter(value) {
715
- if (autoTrim) {
716
- if (typeof value === "string") {
717
- value = value.replace(/\s+/g, " ").trim();
936
+ const valueSet = useMemo(() => {
937
+ const set = new Set();
938
+ for (const value of props.value) {
939
+ set.add(getValueKey(value));
940
+ }
941
+ return set;
942
+ }, [props.value]);
943
+ const renderRow = (props2) => {
944
+ const key = getValueKey(props2.row);
945
+ const value = valueSet.has(key);
946
+ const label = props.renderOption !== undefined
947
+ ? props.renderOption({ option: props2.row, index: props2.index })
948
+ : String(props2.row);
949
+ function onChange(checked) {
950
+ if (checked) {
951
+ if (props.onSelect !== undefined) {
952
+ props.onSelect(props2.row);
718
953
  }
719
954
  }
720
- return value;
721
- },
722
- });
723
- useImperativeHandle(ref, () => ({
724
- focus: () => {
725
- inputRef.current?.focus();
726
- },
727
- }));
728
- return (React__default.createElement("div", null,
729
- React__default.createElement("input", { ref: inputRef, className: [
730
- "ui89-input-box",
731
- disabled ? "ui89-input-box--disabled" : "",
732
- ].join(" "), type: "text", disabled: disabled, value: delayedState.value, onChange: (e) => delayedState.onChange(e.target.value), onBlur: delayedState.onBlur, onFocus: delayedState.onFocus, onKeyDown: (e) => {
733
- if (e.key === "Enter") {
734
- delayedState.onConfirm();
955
+ else {
956
+ if (props.onDeselect !== undefined) {
957
+ props.onDeselect(props2.row);
735
958
  }
736
- }, placeholder: placeholder })));
737
- });
738
-
739
- function Ui89Scene({ look = Ui89Look.main, children }) {
740
- return (React__default.createElement("div", { className: `ui89-scene ui-89-look-${look} ui89-typo-normal ui89-scrollbar` }, children));
741
- }
742
-
743
- function useZIndexer(open) {
744
- const overrides = useUi89();
745
- const [value, setValue] = useState(overrides.currentZIndex);
746
- useEffect(() => {
747
- if (open) {
748
- setValue(overrides.nextZIndex());
959
+ }
960
+ if (props.onChange !== undefined) {
961
+ if (checked) {
962
+ props.onChange([...props.value, props2.row]);
963
+ }
964
+ else {
965
+ props.onChange(props.value.filter((item) => getValueKey(item) !== key));
966
+ }
967
+ }
749
968
  }
750
- }, [open]);
751
- return {
752
- value,
969
+ function toggle() {
970
+ onChange(!value);
971
+ }
972
+ return (React__default.createElement("div", { style: {
973
+ display: "flex",
974
+ alignItems: "center",
975
+ gap: "var(--ui89-safe-space)",
976
+ height: "100%",
977
+ } },
978
+ React__default.createElement(Ui89InputCheckBox, { value: value, onChange: onChange }),
979
+ React__default.createElement("div", { className: "ui89-text-ellipsis", style: { minWidth: 0, cursor: "pointer" }, onClick: toggle }, label)));
753
980
  };
981
+ return (React__default.createElement("div", { style: {
982
+ display: "flex",
983
+ flexDirection: "column",
984
+ maxHeight: props.maxHeight,
985
+ } },
986
+ React__default.createElement(Ui89VirtualList, { rows: props.options, renderRow: renderRow, getRowKey: props.getValueKey, rowHeight: props.optionHeight ?? 40, maxHeight: "100%" })));
754
987
  }
755
988
 
756
- var Ui89PopoverPropsPlacement;
757
- (function (Ui89PopoverPropsPlacement) {
758
- Ui89PopoverPropsPlacement["top"] = "top";
759
- Ui89PopoverPropsPlacement["topStart"] = "topStart";
760
- Ui89PopoverPropsPlacement["topEnd"] = "topEnd";
761
- Ui89PopoverPropsPlacement["right"] = "right";
762
- Ui89PopoverPropsPlacement["rightStart"] = "rightStart";
763
- Ui89PopoverPropsPlacement["rightEnd"] = "rightEnd";
764
- Ui89PopoverPropsPlacement["bottom"] = "bottom";
765
- Ui89PopoverPropsPlacement["bottomStart"] = "bottomStart";
766
- Ui89PopoverPropsPlacement["bottomEnd"] = "bottomEnd";
767
- Ui89PopoverPropsPlacement["left"] = "left";
768
- Ui89PopoverPropsPlacement["leftStart"] = "leftStart";
769
- Ui89PopoverPropsPlacement["leftEnd"] = "leftEnd";
770
- })(Ui89PopoverPropsPlacement || (Ui89PopoverPropsPlacement = {}));
771
- function toFloatingUiPlacement(placement) {
772
- switch (placement) {
773
- case Ui89PopoverPropsPlacement.top:
774
- return "top";
775
- case Ui89PopoverPropsPlacement.topStart:
776
- return "top-start";
777
- case Ui89PopoverPropsPlacement.topEnd:
778
- return "top-end";
779
- case Ui89PopoverPropsPlacement.right:
780
- return "right";
781
- case Ui89PopoverPropsPlacement.rightStart:
782
- return "right-start";
783
- case Ui89PopoverPropsPlacement.rightEnd:
784
- return "right-end";
785
- case Ui89PopoverPropsPlacement.bottom:
786
- return "bottom";
787
- case Ui89PopoverPropsPlacement.bottomStart:
788
- return "bottom-start";
789
- case Ui89PopoverPropsPlacement.bottomEnd:
790
- return "bottom-end";
791
- case Ui89PopoverPropsPlacement.left:
792
- return "left";
793
- case Ui89PopoverPropsPlacement.leftStart:
794
- return "left-start";
795
- case Ui89PopoverPropsPlacement.leftEnd:
796
- return "left-end";
797
- default:
798
- throw new Error(`Unknown placement: ${placement}`);
989
+ function Ui89InputCheckText(props) {
990
+ function toggle() {
991
+ if (props.onChange) {
992
+ props.onChange(!props.value);
993
+ }
799
994
  }
995
+ return (React__default.createElement("span", { className: "ui89-input-check-text", onClick: toggle }, props.value ? "[X]" : "[ ]"));
800
996
  }
801
- function Ui89Popover(props) {
802
- const zIndexer = useZIndexer(props.open);
803
- const { refs, floatingStyles, context } = useFloating({
804
- open: props.open,
805
- onOpenChange: props.onOpenChange,
806
- middleware: [
807
- size({
808
- apply({ availableWidth, availableHeight, elements }) {
809
- let width = elements.reference.getBoundingClientRect().width;
810
- if (props.popoverOverflowMaxWidth !== undefined) {
811
- if (props.popoverOverflowMaxWidth > width) {
812
- width = props.popoverOverflowMaxWidth;
813
- }
814
- }
815
- // Change styles, e.g.
816
- Object.assign(elements.floating.style, {
817
- width: `${availableWidth}px`,
818
- maxWidth: `${width}px`,
819
- maxHeight: `${Math.max(0, availableHeight)}px`,
820
- });
821
- },
822
- }),
823
- ],
824
- whileElementsMounted: autoUpdate,
825
- placement: toFloatingUiPlacement(props.placement ?? Ui89PopoverPropsPlacement.bottomStart),
826
- strategy: "fixed",
827
- });
828
- const click = useClick(context);
829
- const dismiss = useDismiss(context);
830
- const role = useRole(context);
831
- const { getReferenceProps, getFloatingProps } = useInteractions([
832
- click,
833
- dismiss,
834
- role,
835
- ]);
836
- return (React__default.createElement(React__default.Fragment, null,
837
- props.renderContainer({
838
- setRef: refs.setReference,
839
- props: getReferenceProps(),
840
- }),
841
- props.open && (React__default.createElement(FloatingPortal, null,
842
- React__default.createElement(FloatingFocusManager, { context: context, modal: false, initialFocus: -1 },
843
- React__default.createElement(Ui89Scene, null,
844
- React__default.createElement("div", { ref: refs.setFloating, style: {
845
- ...floatingStyles,
846
- zIndex: zIndexer.value,
847
- display: "flex",
848
- flexDirection: "column",
849
- } }, props.renderPopover())))))));
997
+
998
+ function Ui89InputFileUpload(props) {
999
+ const inputRef = useRef(null);
1000
+ function implOnChange(e) {
1001
+ if (!props.onChange) {
1002
+ return;
1003
+ }
1004
+ if (e.target.files === null) {
1005
+ props.onChange(null);
1006
+ return;
1007
+ }
1008
+ if (e.target.files.length === 0) {
1009
+ props.onChange(null);
1010
+ return;
1011
+ }
1012
+ props.onChange(e.target.files[0]);
1013
+ // Reset the file input's value to allow selecting the same file again.
1014
+ e.target.value = "";
1015
+ }
1016
+ function onClick() {
1017
+ if (inputRef.current === null) {
1018
+ return;
1019
+ }
1020
+ inputRef.current.click();
1021
+ }
1022
+ return (React__default.createElement("div", null,
1023
+ React__default.createElement("input", { ref: inputRef, className: "ui89-typo-special", type: "file", onChange: implOnChange, accept: props.accept, hidden: true }),
1024
+ props.value ? (React__default.createElement("div", { className: "ui89-input-file-upload" },
1025
+ React__default.createElement(Ui89Button, { onClick: onClick }, "Change"),
1026
+ React__default.createElement("span", { className: `ui89-input-file-upload__info ui89-text-single-line ui89-text-single-line--ellipsis-left`, title: props.value.name }, props.value.name))) : (React__default.createElement(Ui89Button, { onClick: onClick }, "Upload"))));
850
1027
  }
851
1028
 
852
1029
  /**
@@ -920,7 +1097,7 @@ function Ui89InputSelect(props) {
920
1097
  searchInput.current?.focus();
921
1098
  }
922
1099
  return (React__default.createElement("div", { className: "ui89-input-select" },
923
- React__default.createElement(Ui89Popover, { open: isOpen, onOpenChange: setIsOpen, popoverOverflowMaxWidth: props.menuOverflowMaxWidth, renderContainer: (props2) => (React__default.createElement("div", { ref: props2.setRef, className: [
1100
+ React__default.createElement(Ui89Popover, { open: isOpen, onOpenChange: setIsOpen, popoverOverflowForce: true, popoverOverflowMaxWidth: props.menuOverflowMaxWidth, renderContainer: (props2) => (React__default.createElement("div", { ref: props2.setRef, className: [
924
1101
  "ui89-input-box",
925
1102
  "ui89-input-box--unselectable",
926
1103
  "ui89-input-box--clickable",
@@ -936,62 +1113,6 @@ function Ui89InputSelect(props) {
936
1113
  ].join(" ") }, "<empty>")))) })));
937
1114
  }
938
1115
 
939
- function stringRemoveAllWhitespace(str) {
940
- return str.replace(/\s+/g, "");
941
- }
942
-
943
- function isTextNumber(text) {
944
- return /^\d+(\.\d+)?$/.test(text);
945
- }
946
- function displayText(value) {
947
- if (value === undefined) {
948
- // No idea how to display this.
949
- return "";
950
- }
951
- else if (isNaN(value)) {
952
- // No idea what to display.
953
- return "";
954
- }
955
- return value.toString();
956
- }
957
- function dotsMakeMoreSense(value) {
958
- return value.replaceAll(",", ".");
959
- }
960
- function Ui89InputTextNumber(props) {
961
- const wrappedValue = useMemo(() => {
962
- return displayText(props.value);
963
- }, [props.value]);
964
- function implOnChange(value) {
965
- if (props.onChange === undefined) {
966
- return;
967
- }
968
- if (value === "") {
969
- // Use empty value.
970
- props.onChange(props.emptyValue);
971
- return;
972
- }
973
- value = stringRemoveAllWhitespace(value);
974
- value = dotsMakeMoreSense(value);
975
- if (!isTextNumber(value)) {
976
- // We end here.
977
- return;
978
- }
979
- const numberValue = Number(value);
980
- if (props.min !== undefined) {
981
- if (numberValue <= props.min) {
982
- value = String(props.min);
983
- }
984
- }
985
- if (props.max !== undefined) {
986
- if (numberValue >= props.max) {
987
- value = String(props.max);
988
- }
989
- }
990
- props.onChange(value);
991
- }
992
- return (React__default.createElement(Ui89InputText, { value: wrappedValue, onChange: implOnChange, disabled: props.disabled }));
993
- }
994
-
995
1116
  function Ui89InputNumber(props) {
996
1117
  const wrappedValue = useMemo(() => {
997
1118
  if (props.value !== undefined && props.value !== null) {
@@ -1018,7 +1139,7 @@ function Ui89InputNumber(props) {
1018
1139
  }
1019
1140
  }
1020
1141
  }
1021
- return (React__default.createElement(Ui89InputTextNumber, { emptyValue: props.emptyValue, value: wrappedValue, onChange: wrappedOnChange, min: props.min, max: props.max, disabled: props.disabled, precision: props.precision }));
1142
+ return (React__default.createElement(Ui89InputTextNumber, { emptyValue: props.emptyValue, value: wrappedValue, onChange: wrappedOnChange, min: props.min, max: props.max, disabled: props.disabled, precision: props.precision, textAlign: props.textAlign }));
1022
1143
  }
1023
1144
 
1024
1145
  function Ui89InputPassword({ value, placeholder, disabled, onChange, }) {