xmlui 0.10.7 → 0.10.8

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xmlui",
3
- "version": "0.10.7",
3
+ "version": "0.10.8",
4
4
  "sideEffects": false,
5
5
  "scripts": {
6
6
  "start-test-bed": "cd src/testing/infrastructure && xmlui start",
@@ -81,6 +81,7 @@ const DataLoader_1 = require("../components-core/loader/DataLoader");
81
81
  const DatePicker_1 = require("./DatePicker/DatePicker");
82
82
  const DateInput_1 = require("./DateInput/DateInput");
83
83
  const TimeInput_1 = require("./TimeInput/TimeInput");
84
+ const Timer_1 = require("./Timer/Timer");
84
85
  const Redirect_1 = require("./Redirect/Redirect");
85
86
  const Tabs_1 = require("./Tabs/Tabs");
86
87
  const Bookmark_1 = require("./Bookmark/Bookmark");
@@ -390,6 +391,7 @@ class ComponentRegistry {
390
391
  this.registerCoreComponent(DatePicker_1.datePickerComponentRenderer);
391
392
  this.registerCoreComponent(DateInput_1.dateInputComponentRenderer);
392
393
  this.registerCoreComponent(TimeInput_1.timeInputComponentRenderer);
394
+ this.registerCoreComponent(Timer_1.timerComponentRenderer);
393
395
  }
394
396
  if (process.env.VITE_INCLUDE_REST_COMPONENTS !== "false") {
395
397
  //TODO, if it proves to be a working solution, make these components skippable, too
@@ -42,22 +42,25 @@ exports.TableMd = (0, metadata_helpers_1.createMetadata)({
42
42
  description: "This property holds an array of page sizes (numbers) the user can select for " +
43
43
  "pagination. If this property is not defined, the component allows only a page size of 10 items.",
44
44
  },
45
- showPageInfo: (0, metadata_helpers_1.d)("Whether to show page information", undefined, "boolean", TableNative_1.defaultProps.showPageInfo),
46
- showPageSizeSelector: (0, metadata_helpers_1.d)("Whether to show the page size selector", undefined, "boolean", TableNative_1.defaultProps.showPageSizeSelector),
47
- showCurrentPage: (0, metadata_helpers_1.d)("Whether to show the current page indicator", undefined, "boolean", TableNative_1.defaultProps.showCurrentPage),
45
+ showPageInfo: (0, metadata_helpers_1.d)("Whether to show page information. It works the same as the [Pagination component property](./Pagination#showpageinfo).", undefined, "boolean", TableNative_1.defaultProps.showPageInfo),
46
+ showPageSizeSelector: (0, metadata_helpers_1.d)("Whether to show the page size selector. It works the same as the [Pagination component property](./Pagination#showpagesizeselector).", undefined, "boolean", TableNative_1.defaultProps.showPageSizeSelector),
47
+ showCurrentPage: (0, metadata_helpers_1.d)("Whether to show the current page indicator. It works the same as the [Pagination component property](./Pagination#showcurrentpage).", undefined, "boolean", TableNative_1.defaultProps.showCurrentPage),
48
48
  pageSizeSelectorPosition: {
49
- description: "Determines where to place the page size selector in the layout.",
49
+ description: "Determines where to place the page size selector in the layout. " +
50
+ "It works the same as the [Pagination component property](./Pagination#pagesizeselectorposition).",
50
51
  options: PaginationNative_1.PositionValues,
51
52
  type: "string",
52
53
  default: TableNative_1.defaultProps.pageSizeSelectorPosition,
53
54
  },
54
55
  pageInfoPosition: {
55
- description: "Determines where to place the page information in the layout.",
56
+ description: "Determines where to place the page information in the layout. " +
57
+ "It works the same as the [Pagination component property](./Pagination#pageinfoposition).",
56
58
  options: PaginationNative_1.PositionValues,
57
59
  type: "string",
58
60
  default: TableNative_1.defaultProps.pageInfoPosition,
59
61
  },
60
- buttonRowPosition: (0, metadata_helpers_1.d)("Determines where to place the pagination button row in the layout.", PaginationNative_1.PositionValues, "string", TableNative_1.defaultProps.buttonRowPosition),
62
+ buttonRowPosition: (0, metadata_helpers_1.d)("Determines where to place the pagination button row in the layout. " +
63
+ "It works the same as the [Pagination component property](./Pagination#buttonrowposition).", PaginationNative_1.PositionValues, "string", TableNative_1.defaultProps.buttonRowPosition),
61
64
  rowDisabledPredicate: (0, metadata_helpers_1.d)(`This property defines a predicate function with a return value that determines if the ` +
62
65
  `row should be disabled. The function retrieves the item to display and should return ` +
63
66
  `a Boolean-like value.`),
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.timerComponentRenderer = exports.TimerMd = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const renderers_1 = require("../../components-core/renderers");
6
+ const TimerNative_1 = require("./TimerNative");
7
+ const metadata_helpers_1 = require("../metadata-helpers");
8
+ const COMP = "Timer";
9
+ exports.TimerMd = (0, metadata_helpers_1.createMetadata)({
10
+ status: "stable",
11
+ description: "`Timer` is a non-visual component that fires events at regular intervals. " +
12
+ "It can be enabled or disabled and ensures that the timer event handler " +
13
+ "completes before firing the next event.",
14
+ props: {
15
+ enabled: {
16
+ description: "Whether the timer is enabled and should fire events.",
17
+ valueType: "boolean",
18
+ defaultValue: TimerNative_1.defaultProps.enabled,
19
+ },
20
+ interval: {
21
+ description: "The interval in milliseconds between timer events.",
22
+ valueType: "number",
23
+ defaultValue: TimerNative_1.defaultProps.interval,
24
+ },
25
+ initialDelay: {
26
+ description: "The delay in milliseconds before the first timer event.",
27
+ valueType: "number",
28
+ defaultValue: TimerNative_1.defaultProps.initialDelay,
29
+ },
30
+ once: {
31
+ description: "Whether the timer should stop after firing its first tick event.",
32
+ valueType: "boolean",
33
+ defaultValue: TimerNative_1.defaultProps.once,
34
+ },
35
+ },
36
+ events: {
37
+ tick: {
38
+ description: "This event is triggered at each interval when the ${COMP} is enabled.",
39
+ },
40
+ },
41
+ apis: {
42
+ pause: {
43
+ description: "Pauses the timer. The timer can be resumed later from where it left off.",
44
+ signature: "pause()",
45
+ },
46
+ resume: {
47
+ description: "Resumes a paused timer. If the timer is not paused, this method has no effect.",
48
+ signature: "resume()",
49
+ },
50
+ isPaused: {
51
+ description: "Returns whether the timer is currently paused.",
52
+ signature: "isPaused(): boolean",
53
+ },
54
+ isRunning: {
55
+ description: "Returns whether the timer is currently running (enabled and not paused).",
56
+ signature: "isRunning(): boolean",
57
+ },
58
+ },
59
+ });
60
+ exports.timerComponentRenderer = (0, renderers_1.createComponentRenderer)(COMP, exports.TimerMd, ({ node, extractValue, lookupEventHandler, registerComponentApi }) => {
61
+ return ((0, jsx_runtime_1.jsx)(TimerNative_1.Timer, { enabled: extractValue.asOptionalBoolean(node.props.enabled), interval: extractValue.asOptionalNumber(node.props.interval), initialDelay: extractValue.asOptionalNumber(node.props.initialDelay), once: extractValue.asOptionalBoolean(node.props.once), onTick: lookupEventHandler("tick"), registerComponentApi: registerComponentApi }));
62
+ });
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.Timer = exports.defaultProps = void 0;
24
+ const jsx_runtime_1 = require("react/jsx-runtime");
25
+ const react_1 = require("react");
26
+ exports.defaultProps = {
27
+ enabled: true,
28
+ interval: 1000,
29
+ once: false,
30
+ initialDelay: 0,
31
+ };
32
+ exports.Timer = (0, react_1.forwardRef)(function Timer(_a, forwardedRef) {
33
+ var { enabled = exports.defaultProps.enabled, interval = exports.defaultProps.interval, once = exports.defaultProps.once, initialDelay = exports.defaultProps.initialDelay, onTick, registerComponentApi, style, className } = _a, rest = __rest(_a, ["enabled", "interval", "once", "initialDelay", "onTick", "registerComponentApi", "style", "className"]);
34
+ const [isPaused, setIsPaused] = (0, react_1.useState)(false);
35
+ const [hasExecutedOnce, setHasExecutedOnce] = (0, react_1.useState)(false);
36
+ const [hasEverStarted, setHasEverStarted] = (0, react_1.useState)(false);
37
+ const intervalRef = (0, react_1.useRef)(null);
38
+ const initialDelayRef = (0, react_1.useRef)(null);
39
+ const handlerRunningRef = (0, react_1.useRef)(false);
40
+ // Refs for current values to ensure handleTick has stable dependencies
41
+ const enabledRef = (0, react_1.useRef)(enabled);
42
+ const isPausedRef = (0, react_1.useRef)(isPaused);
43
+ const intervalRef2 = (0, react_1.useRef)(interval);
44
+ const onTickRef = (0, react_1.useRef)(onTick);
45
+ const onceRef = (0, react_1.useRef)(once);
46
+ const hasExecutedOnceRef = (0, react_1.useRef)(hasExecutedOnce);
47
+ const hasEverStartedRef = (0, react_1.useRef)(hasEverStarted);
48
+ // Update refs when values change
49
+ enabledRef.current = enabled;
50
+ isPausedRef.current = isPaused;
51
+ intervalRef2.current = interval;
52
+ onTickRef.current = onTick;
53
+ onceRef.current = once;
54
+ hasExecutedOnceRef.current = hasExecutedOnce;
55
+ hasEverStartedRef.current = hasEverStarted;
56
+ // Derived state
57
+ const isRunning = enabled && !isPaused && (intervalRef.current !== null || initialDelayRef.current !== null);
58
+ const isInInitialDelay = initialDelayRef.current !== null;
59
+ // Timer API methods
60
+ const pause = (0, react_1.useCallback)(() => {
61
+ // Pause if timer is enabled and currently running (not already paused)
62
+ if (enabled && !isPaused) {
63
+ setIsPaused(true);
64
+ if (intervalRef.current) {
65
+ clearInterval(intervalRef.current);
66
+ intervalRef.current = null;
67
+ }
68
+ if (initialDelayRef.current) {
69
+ clearTimeout(initialDelayRef.current);
70
+ initialDelayRef.current = null;
71
+ }
72
+ }
73
+ }, [enabled, isPaused]);
74
+ const resume = (0, react_1.useCallback)(() => {
75
+ // Resume if timer is enabled and currently paused
76
+ if (enabled && isPaused) {
77
+ setIsPaused(false);
78
+ // The useEffect will handle restarting the timer
79
+ }
80
+ }, [enabled, isPaused]);
81
+ // Create API object once
82
+ const timerApi = (0, react_1.useMemo)(() => ({
83
+ pause,
84
+ resume,
85
+ isPaused: () => isPaused,
86
+ isRunning: () => isRunning && !isPaused,
87
+ }), [pause, resume, isPaused, isRunning]);
88
+ // Register both APIs together
89
+ (0, react_1.useImperativeHandle)(forwardedRef, () => timerApi, [timerApi]);
90
+ (0, react_1.useEffect)(() => {
91
+ if (registerComponentApi) {
92
+ registerComponentApi(timerApi);
93
+ }
94
+ }, [registerComponentApi, timerApi]);
95
+ const handleTick = (0, react_1.useCallback)(() => __awaiter(this, void 0, void 0, function* () {
96
+ // Check if timer should still be running (enabled, not paused, valid interval)
97
+ if (!enabledRef.current || isPausedRef.current || intervalRef2.current <= 0) {
98
+ return;
99
+ }
100
+ // Prevent re-firing if the previous event hasn't completed yet
101
+ if (handlerRunningRef.current) {
102
+ return;
103
+ }
104
+ if (onTickRef.current) {
105
+ handlerRunningRef.current = true;
106
+ try {
107
+ yield onTickRef.current();
108
+ // Mark that the timer has actually started executing (for initial delay logic)
109
+ if (!hasEverStartedRef.current) {
110
+ setHasEverStarted(true);
111
+ }
112
+ // If this is a "once" timer and it's the very first execution, mark it as executed
113
+ // After the first execution, the timer becomes a regular timer that can be paused/resumed
114
+ if (onceRef.current && !hasExecutedOnceRef.current) {
115
+ setHasExecutedOnce(true);
116
+ }
117
+ }
118
+ finally {
119
+ handlerRunningRef.current = false;
120
+ }
121
+ }
122
+ }), []);
123
+ (0, react_1.useEffect)(() => {
124
+ // Clear any existing timers first
125
+ if (intervalRef.current) {
126
+ clearInterval(intervalRef.current);
127
+ intervalRef.current = null;
128
+ }
129
+ if (initialDelayRef.current) {
130
+ clearTimeout(initialDelayRef.current);
131
+ initialDelayRef.current = null;
132
+ }
133
+ // If "once" is true and the timer has already executed, don't start the timer
134
+ if (once && hasExecutedOnce) {
135
+ return;
136
+ }
137
+ if (enabled && !isPaused && interval > 0) {
138
+ // Helper to start the actual timer
139
+ const startTicking = () => {
140
+ intervalRef.current = (once && !hasExecutedOnce)
141
+ ? setTimeout(handleTick, interval)
142
+ : setInterval(handleTick, interval);
143
+ };
144
+ // Only apply initial delay if timer has never been started before
145
+ if (initialDelay > 0 && !hasEverStarted) {
146
+ initialDelayRef.current = setTimeout(() => {
147
+ initialDelayRef.current = null;
148
+ startTicking();
149
+ }, initialDelay);
150
+ }
151
+ else {
152
+ startTicking();
153
+ }
154
+ }
155
+ return () => {
156
+ if (intervalRef.current) {
157
+ clearInterval(intervalRef.current);
158
+ intervalRef.current = null;
159
+ }
160
+ if (initialDelayRef.current) {
161
+ clearTimeout(initialDelayRef.current);
162
+ initialDelayRef.current = null;
163
+ }
164
+ };
165
+ }, [enabled, interval, once, hasExecutedOnce, isPaused, initialDelay, hasEverStarted]);
166
+ // Reset state when enabled changes
167
+ (0, react_1.useEffect)(() => {
168
+ if (enabled && once) {
169
+ // Reset hasExecutedOnce when enabled changes from false to true for "once" timers
170
+ setHasExecutedOnce(false);
171
+ }
172
+ if (!enabled) {
173
+ // Reset pause state when timer is disabled
174
+ setIsPaused(false);
175
+ }
176
+ }, [enabled, once]);
177
+ // Timer is a non-visual component
178
+ return ((0, jsx_runtime_1.jsx)("div", Object.assign({ ref: forwardedRef, style: Object.assign({ display: "none" }, style), className: className, "data-timer-enabled": enabled, "data-timer-interval": interval, "data-timer-initial-delay": initialDelay, "data-timer-once": once, "data-timer-running": isRunning, "data-timer-paused": isPaused, "data-timer-in-initial-delay": isInInitialDelay, "data-timer-has-executed": hasExecutedOnce }, rest)));
179
+ });
@@ -56,11 +56,12 @@ const ComponentDecorator = (0, react_1.forwardRef)((props, forwardedRef) => {
56
56
  }
57
57
  if (node) {
58
58
  Object.entries(shallowAttrs).forEach(([key, value]) => {
59
+ var _a, _b;
59
60
  if (value !== undefined) {
60
- node.setAttribute(key, value);
61
+ (_a = node.setAttribute) === null || _a === void 0 ? void 0 : _a.call(node, key, value);
61
62
  }
62
63
  else {
63
- node.removeAttribute(key);
64
+ (_b = node.removeAttribute) === null || _b === void 0 ? void 0 : _b.call(node, key);
64
65
  }
65
66
  });
66
67
  }
@@ -106,7 +106,14 @@ class Backend {
106
106
  localContext: localContext,
107
107
  eventArgs: args,
108
108
  appContext: Object.assign(Object.assign(Object.assign({}, date_functions_1.dateFunctions), misc_utils_1.miscellaneousUtils), { delay: misc_1.delay,
109
- Errors: Errors_1.default, createFile: (...args) => new File(args[0], args[1], args[2]), getDate: date_utils_1.getDate }),
109
+ Errors: Errors_1.default, createFile: (...args) => new File(args[0], args[1], args[2]), appendBlob: (blob1, blob2) => {
110
+ if (!blob1 && !blob2)
111
+ return;
112
+ const newBlob = new Blob([blob1, blob2], {
113
+ type: (blob1 === null || blob1 === void 0 ? void 0 : blob1.type) || (blob2 === null || blob2 === void 0 ? void 0 : blob2.type) || "application/octet-stream",
114
+ });
115
+ return newBlob;
116
+ }, getDate: date_utils_1.getDate }),
110
117
  });
111
118
  yield (0, statementUtils_1.runEventHandlerCode)(src, evalContext);
112
119
  return ((_g = (_f = evalContext.mainThread) === null || _f === void 0 ? void 0 : _f.blocks) === null || _g === void 0 ? void 0 : _g.length)