@uxf/core 11.51.0 → 11.52.2
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/README.md +15 -249
- package/index.d.ts +2 -2
- package/index.js +2 -2
- package/package.json +1 -8
- package/utils/adjust-textarea-height.d.ts +1 -0
- package/utils/adjust-textarea-height.js +13 -0
- package/utils/adjust-textarea-height.test.js +83 -0
- package/utils/build-array.test.js +10 -0
- package/utils/camel-case-to-dash.test.js +8 -0
- package/utils/image.d.ts +0 -22
- package/utils/image.js +0 -41
- package/utils/{isBrowser.test.js → is-browser.test.js} +3 -3
- package/utils/{isServer.js → is-server.js} +2 -2
- package/utils/is-server.test.js +12 -0
- package/utils/trim-trailing-zeros.test.js +6 -6
- package/{Validators/FormValidator.js → validators/form-validator.js} +3 -3
- package/validators/form-validator.test.js +45 -0
- package/validators/validator.test.js +17 -0
- package/Validators/FormValidator.test.js +0 -45
- package/Validators/Validator.test.js +0 -17
- package/components/hide.d.ts +0 -10
- package/components/hide.js +0 -16
- package/components/show.d.ts +0 -10
- package/components/show.js +0 -16
- package/hooks/_useSimulatedButton.d.ts +0 -19
- package/hooks/_useSimulatedButton.js +0 -54
- package/hooks/useAnchorProps.d.ts +0 -14
- package/hooks/useAnchorProps.js +0 -68
- package/hooks/useBodyScrollLock.d.ts +0 -12
- package/hooks/useBodyScrollLock.js +0 -37
- package/hooks/useButtonProps.d.ts +0 -12
- package/hooks/useButtonProps.js +0 -61
- package/hooks/useClickableProps.d.ts +0 -14
- package/hooks/useClickableProps.js +0 -46
- package/hooks/useFocusReturn.d.ts +0 -4
- package/hooks/useFocusReturn.js +0 -37
- package/hooks/useFocusTrap.d.ts +0 -5
- package/hooks/useFocusTrap.js +0 -148
- package/hooks/useInputFocus.d.ts +0 -10
- package/hooks/useInputFocus.js +0 -29
- package/hooks/useIsMounted.d.ts +0 -4
- package/hooks/useIsMounted.js +0 -12
- package/hooks/useIsomorphicLayoutEffect.d.ts +0 -5
- package/hooks/useIsomorphicLayoutEffect.js +0 -9
- package/hooks/useKey.d.ts +0 -19
- package/hooks/useKey.js +0 -30
- package/hooks/useLatest.d.ts +0 -4
- package/hooks/useLatest.js +0 -12
- package/hooks/useMinWindowWidth.d.ts +0 -4
- package/hooks/useMinWindowWidth.js +0 -31
- package/hooks/useMouseDragToScroll.d.ts +0 -5
- package/hooks/useMouseDragToScroll.js +0 -41
- package/hooks/useOnMount.d.ts +0 -5
- package/hooks/useOnMount.js +0 -12
- package/hooks/useOnUnmount.d.ts +0 -5
- package/hooks/useOnUnmount.js +0 -17
- package/hooks/useOnUpdate.d.ts +0 -5
- package/hooks/useOnUpdate.js +0 -17
- package/hooks/usePagination.d.ts +0 -5
- package/hooks/usePagination.js +0 -23
- package/hooks/usePrevious.d.ts +0 -4
- package/hooks/usePrevious.js +0 -14
- package/hooks/useRafState.d.ts +0 -5
- package/hooks/useRafState.js +0 -20
- package/hooks/useTabs.d.ts +0 -16
- package/hooks/useTabs.js +0 -43
- package/hooks/useWindowScroll.d.ts +0 -7
- package/hooks/useWindowScroll.js +0 -24
- package/hooks/useWindowSize.d.ts +0 -7
- package/hooks/useWindowSize.js +0 -21
- package/next/index.d.ts +0 -2
- package/next/index.js +0 -7
- package/next/query-param.test.js +0 -35
- package/utils/buildArray.test.js +0 -10
- package/utils/camelCaseToDash.test.js +0 -8
- package/utils/composeRefs.d.ts +0 -5
- package/utils/composeRefs.js +0 -18
- package/utils/isServer.test.js +0 -12
- /package/{Validators/FormValidator.test.d.ts → utils/adjust-textarea-height.test.d.ts} +0 -0
- /package/utils/{bodyScrollLock.d.ts → body-scroll-lock.d.ts} +0 -0
- /package/utils/{bodyScrollLock.js → body-scroll-lock.js} +0 -0
- /package/utils/{buildArray.d.ts → build-array.d.ts} +0 -0
- /package/utils/{buildArray.js → build-array.js} +0 -0
- /package/{Validators/Validator.test.d.ts → utils/build-array.test.d.ts} +0 -0
- /package/utils/{camelCaseToDash.d.ts → camel-case-to-dash.d.ts} +0 -0
- /package/utils/{camelCaseToDash.js → camel-case-to-dash.js} +0 -0
- /package/{next/query-param.test.d.ts → utils/camel-case-to-dash.test.d.ts} +0 -0
- /package/utils/{isBrowser.d.ts → is-browser.d.ts} +0 -0
- /package/utils/{isBrowser.js → is-browser.js} +0 -0
- /package/utils/{buildArray.test.d.ts → is-browser.test.d.ts} +0 -0
- /package/utils/{isServer.d.ts → is-server.d.ts} +0 -0
- /package/utils/{camelCaseToDash.test.d.ts → is-server.test.d.ts} +0 -0
- /package/utils/{trimTrailingZeros.d.ts → trim-trailing-zeros.d.ts} +0 -0
- /package/utils/{trimTrailingZeros.js → trim-trailing-zeros.js} +0 -0
- /package/{Validators/FormValidator.d.ts → validators/form-validator.d.ts} +0 -0
- /package/{utils/isBrowser.test.d.ts → validators/form-validator.test.d.ts} +0 -0
- /package/{Validators/Validator.d.ts → validators/validator.d.ts} +0 -0
- /package/{Validators/Validator.js → validators/validator.js} +0 -0
- /package/{utils/isServer.test.d.ts → validators/validator.test.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -86,261 +86,27 @@ cookie.set("cookie-name", "value", /* ttl in seconds (optional) */, /* options (
|
|
|
86
86
|
cookie.delete("cookie-name", /* options (optional) */);
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
##
|
|
90
|
-
|
|
91
|
-
```tsx
|
|
92
|
-
import { useBodyScrollLock } from "@uxf/core/hooks/useBodyScrollLock";
|
|
93
|
-
import { useState } from "react";
|
|
94
|
-
|
|
95
|
-
const innerRef = useRef<HTMLDivElement>(null);
|
|
96
|
-
const [isOpen, setIsOpen] = useState<boolean>();
|
|
97
|
-
|
|
98
|
-
const clearAllOnclose = false;
|
|
99
|
-
|
|
100
|
-
useBodyScrollLock<HTMLDivElement>(innerRef, isOpen, {
|
|
101
|
-
allowTouchMove: undefined, // https://github.com/willmcpo/body-scroll-lock#allowtouchmove
|
|
102
|
-
clearAllOnClose: false, // optionally call clearAllBodyScrollLocks method on unmount
|
|
103
|
-
reserveScrollBarGap: undefined, // https://github.com/willmcpo/body-scroll-lock#reservescrollbargap
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
<div ref={innerRef}>Element which activates scroll lock on its parent elements.</div>
|
|
107
|
-
```
|
|
108
|
-
```tsx
|
|
109
|
-
import { useIsMounted } from "@uxf/core/hooks/useIsMounted";
|
|
110
|
-
|
|
111
|
-
const isMounted = useIsMounted();
|
|
112
|
-
```
|
|
113
|
-
```tsx
|
|
114
|
-
import { useIsomorphicLayoutEffect } from "@uxf/core/hooks/useIsomorphicLayoutEffect";
|
|
115
|
-
|
|
116
|
-
useIsomorphicLayoutEffect(() => {/* code */}, [/* deps */]);
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
```tsx
|
|
120
|
-
import { useKey } from "@uxf/core/hooks/useKey";
|
|
121
|
-
import { useRef } from "react";
|
|
122
|
-
|
|
123
|
-
const targetRef = useRef<HTMLDivElement>(null);
|
|
124
|
-
const disabled = false; // eg. for passing disabled state
|
|
125
|
-
|
|
126
|
-
useKey<HTMLDivElement>("Enter", () => console.log("callback"), {
|
|
127
|
-
disabled,
|
|
128
|
-
targetRef, // if not provided, then `document` will be used
|
|
129
|
-
type: "keydown"
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
<div ref={targetRef} tabIndex={0}>Element with callback triggerable by enter key.</div>
|
|
133
|
-
```
|
|
134
|
-
```tsx
|
|
135
|
-
import { useMinWindowWidth } from "@uxf/core/hooks/useMinWindowWidth";
|
|
136
|
-
|
|
137
|
-
const isDesktop = useMinWindowWidth(1200);
|
|
138
|
-
const isDesktopWithDebounce = useMinWindowWidth(1200, 200); // will be updated every 200 ms
|
|
139
|
-
|
|
140
|
-
const example = isDesktop ? "desktop" : "tablet";
|
|
141
|
-
const debouncedExample = isDesktopWithDebounce ? "debouncedDesktop" : "debouncedTablet";
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
```ts
|
|
145
|
-
import { usePagination } from "@uxf/core/hooks/usePagination";
|
|
146
|
-
|
|
147
|
-
const paginationItems = usePagination({ page: 1, count: 10 })
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
```tsx
|
|
151
|
-
import { useRafState } from "@uxf/core/hooks/useRafState";
|
|
152
|
-
|
|
153
|
-
const [state, setState] = useRafState<boolean>(false);
|
|
154
|
-
```
|
|
155
|
-
```tsx
|
|
156
|
-
import { useOnUnmount } from "@uxf/core/hooks/useOnUnmount";
|
|
157
|
-
|
|
158
|
-
const exampleCallback = () => {};
|
|
159
|
-
|
|
160
|
-
useOnUnmount(exampleCallback());
|
|
161
|
-
```
|
|
162
|
-
```tsx
|
|
163
|
-
import { useOnUpdate } from "@uxf/core/hooks/useOnUpdate";
|
|
164
|
-
|
|
165
|
-
useOnUpdate(() => {/* code */}, [/* deps */]);
|
|
166
|
-
```
|
|
167
|
-
```tsx
|
|
168
|
-
import { useWindowScroll } from "@uxf/core/hooks/useWindowScroll";
|
|
169
|
-
|
|
170
|
-
const windowScroll = useWindowScroll();
|
|
171
|
-
|
|
172
|
-
const example = windowScroll && windowScroll.y > 100 ? "scroled" : "on top";
|
|
173
|
-
```
|
|
174
|
-
```tsx
|
|
175
|
-
import { useWindowSize } from "@uxf/core/hooks/useWindowSize";
|
|
176
|
-
|
|
177
|
-
const windowSize = useWindowSize();
|
|
178
|
-
|
|
179
|
-
const example = windowSize && windowSize.width > 1200 ? "desktop" : "tablet";
|
|
180
|
-
```
|
|
181
|
-
```tsx
|
|
182
|
-
import { useFocusTrap } from "@uxf/core/hooks/useFocusTrap";
|
|
183
|
-
import { useState } from "react";
|
|
184
|
-
|
|
185
|
-
const [active, setActive] = useState<boolean>();
|
|
186
|
-
|
|
187
|
-
const focusTrapRef = useFocusTrap(active);
|
|
188
|
-
|
|
189
|
-
<div ref={focusTrapRef}>Element which trap focus inside if `active` is truthy.</div>
|
|
190
|
-
```
|
|
191
|
-
```tsx
|
|
192
|
-
import { useFocusReturn } from "@uxf/core/hooks/useFocusReturn";
|
|
193
|
-
import { useState } from "react";
|
|
194
|
-
|
|
195
|
-
const [active, setActive] = useState<boolean>();
|
|
196
|
-
|
|
197
|
-
// Returns focus to last active element, e.g. in Modal or Popover
|
|
198
|
-
useFocusReturn(active);
|
|
199
|
-
```
|
|
200
|
-
```tsx
|
|
201
|
-
import { useAnchorProps } from "@uxf/core/hooks/useAnchorProps";
|
|
202
|
-
import { AnchorHTMLAttributes } from "react";
|
|
203
|
-
|
|
204
|
-
// extends <a /> by `analyticsCallback`, `disabled`, `loading`, `submit` props
|
|
205
|
-
const anchorProps = useAnchorProps<AnchorHTMLAttributes<HTMLAnchorElement>>({
|
|
206
|
-
analyticsCallback: () => console.log("analytics"),
|
|
207
|
-
disabled: false,
|
|
208
|
-
href: "https://www.google.com/",
|
|
209
|
-
loading: false,
|
|
210
|
-
onClick: () => console.log("success"),
|
|
211
|
-
type: "submit", // simulate <button type="submit" /> function
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
<a {...anchorProps}>Click me</a>
|
|
215
|
-
|
|
216
|
-
// example with generics
|
|
217
|
-
import { UseAnchorProps, useAnchorProps } from "@uxf/core/hooks/useAnchorProps";
|
|
218
|
-
import { AnchorHTMLAttributes } from "react";
|
|
219
|
-
|
|
220
|
-
interface Props extends UseAnchorProps, AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
221
|
-
customProp?: boolean;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const anchorProps = useAnchorProps<Props>({
|
|
225
|
-
customProp: true,
|
|
226
|
-
loading: false,
|
|
227
|
-
href: "https://www.google.com/",
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
<a {...anchorProps}>Click me</a>
|
|
231
|
-
|
|
232
|
-
```
|
|
233
|
-
```tsx
|
|
234
|
-
import { useButtonProps } from "@uxf/core/hooks/useButtonProps";
|
|
235
|
-
import { ButtonHTMLAttributes } from "react";
|
|
236
|
-
|
|
237
|
-
// extends <button /> by `analyticsCallback` and `loading` props
|
|
238
|
-
const buttonProps = useButtonProps<ButtonHTMLAttributes<HTMLButtonElement>>({
|
|
239
|
-
analyticsCallback: () => console.log("analytics"),
|
|
240
|
-
disabled: false,
|
|
241
|
-
loading: false,
|
|
242
|
-
onClick: () => console.log("success"),
|
|
243
|
-
type: "submit",
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
<button {...buttonProps}>Click me</button>
|
|
247
|
-
|
|
248
|
-
// example with generics
|
|
249
|
-
import { UseButtonProps, useButtonProps } from "@uxf/core/hooks/useButtonProps";
|
|
250
|
-
import { ButtonHTMLAttributes } from "react";
|
|
251
|
-
|
|
252
|
-
interface Props extends UseButtonProps, ButtonHTMLAttributes<HTMLButtonElement> {
|
|
253
|
-
customProp?: boolean;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const buttonProps = useButtonProps<Props>({
|
|
257
|
-
customProp: true,
|
|
258
|
-
loading: false,
|
|
259
|
-
type: "submit",
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
<button {...buttonProps}>Click me</button>
|
|
263
|
-
```
|
|
264
|
-
```tsx
|
|
265
|
-
import { useClickableProps } from "@uxf/core/hooks/useClickableProps";
|
|
266
|
-
import { HTMLAttributes } from "react";
|
|
267
|
-
|
|
268
|
-
// extends any HTML element by `analyticsCallback`, `disabled`, `loading`, `submit` props
|
|
269
|
-
const clickableProps = useClickableProps<HTMLAttributes<HTMLDivElement>>({
|
|
270
|
-
analyticsCallback: () => console.log("analytics"),
|
|
271
|
-
disabled: false,
|
|
272
|
-
loading: false,
|
|
273
|
-
onClick: () => console.log("success"),
|
|
274
|
-
type: "submit", // simulate <button type="submit" /> function
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
<div {...clickableProps}>Click me</div>
|
|
278
|
-
|
|
279
|
-
// example with generics
|
|
280
|
-
import { UseClickableProps, useClickableProps } from "@uxf/core/hooks/useClickableProps";
|
|
281
|
-
import { HTMLAttributes } from "react";
|
|
282
|
-
|
|
283
|
-
interface Props extends UseClickableProps, HTMLAttributes<HTMLDivElement> {
|
|
284
|
-
customProp?: boolean;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const buttonProps = useClickableProps<Props>({
|
|
288
|
-
customProp: true,
|
|
289
|
-
hidden: false,
|
|
290
|
-
loading: false,
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
<button {...buttonProps}>Click me</button>
|
|
294
|
-
```
|
|
295
|
-
```tsx
|
|
296
|
-
import { useMouseDragToScroll } from "@uxf/core/hooks/useMouseDragToScroll";
|
|
297
|
-
|
|
298
|
-
const targetRef = useRef<HTMLDivElement>(null);
|
|
299
|
-
|
|
300
|
-
const style = useMouseDragToScroll(scrollRef);
|
|
301
|
-
|
|
302
|
-
<div style={style}>Drag to scroll</div>
|
|
303
|
-
```
|
|
304
|
-
```tsx
|
|
305
|
-
import { useInputFocus } from "@uxf/core/hooks/useInputFocus";
|
|
306
|
-
|
|
307
|
-
const focusRef = useRef<HTMLInputElement>(null); // or HTMLTextAreaElement
|
|
308
|
-
const { onBlur, onFocus } = props;
|
|
309
|
-
|
|
310
|
-
const input = useInputFocus(focusRef, onBlur, onFocus);
|
|
311
|
-
|
|
312
|
-
<div>Input is {input.focused}</div>
|
|
313
|
-
<button onClick={input.focus}>Focus input</button>
|
|
314
|
-
<input onBlur={input.onBlur} onFocus={input.onFocus} ref={focusRef} />
|
|
315
|
-
```
|
|
316
|
-
```tsx
|
|
317
|
-
import { useLatest } from "@uxf/core/hooks/useLatest";
|
|
318
|
-
|
|
319
|
-
const latestState = useLatest(someUnstableWhatever);
|
|
89
|
+
## Utils
|
|
320
90
|
|
|
321
|
-
|
|
322
|
-
latestState.current(); // use newest state of 'someUnstableWhatever' without affecting this effetct update
|
|
323
|
-
}, [latestState])
|
|
324
|
-
```
|
|
325
|
-
```tsx
|
|
326
|
-
import { usePrevious } from "@uxf/core/hooks/usePrevious";
|
|
91
|
+
### adjustTextareaHeight
|
|
327
92
|
|
|
328
|
-
|
|
93
|
+
Dynamically adjusts the height of a `<textarea>` based on its content and an optional number of rows.
|
|
329
94
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
```
|
|
95
|
+
#### Parameters
|
|
96
|
+
- **`element`**: The `<textarea>` to adjust.
|
|
97
|
+
- **`rows`** (optional): Minimum visible rows. Default is `4`.
|
|
334
98
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
99
|
+
#### Behavior
|
|
100
|
+
- Resets height to `"auto"` to measure content height.
|
|
101
|
+
- Adjusts height to fit content or the minimum height based on the `rows` parameter, calculated using `line-height` and `font-size`.
|
|
338
102
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
103
|
+
#### Usage
|
|
104
|
+
```typescript
|
|
105
|
+
adjustTextareaHeight(textarea); // Adjusts height (min 4 rows)
|
|
106
|
+
adjustTextareaHeight(textarea, 6); // With 6-row minimum
|
|
107
|
+
```
|
|
342
108
|
|
|
343
|
-
|
|
109
|
+
> **Note**: Requires valid `line-height` and `font-size` styles for accurate sizing.
|
|
344
110
|
|
|
345
111
|
### cx, cxa
|
|
346
112
|
It is our fork of `clsx` library https://github.com/lukeed/clsx
|
package/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./
|
|
1
|
+
export * from "./validators/form-validator";
|
|
2
|
+
export * from "./validators/validator";
|
package/index.js
CHANGED
|
@@ -15,5 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
// TODO @vejvis - remove me
|
|
18
|
-
__exportStar(require("./
|
|
19
|
-
__exportStar(require("./
|
|
18
|
+
__exportStar(require("./validators/form-validator"), exports);
|
|
19
|
+
__exportStar(require("./validators/validator"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxf/core",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.52.2",
|
|
4
4
|
"description": "UXF Core",
|
|
5
5
|
"author": "Petr Vejvoda <vejvoda@uxf.cz>",
|
|
6
6
|
"homepage": "https://gitlab.com/uxf-npm/core#readme",
|
|
@@ -22,12 +22,5 @@
|
|
|
22
22
|
"bugs": {
|
|
23
23
|
"url": "https://gitlab.com/uxf-npm/core/issues"
|
|
24
24
|
},
|
|
25
|
-
"peerDependencies": {
|
|
26
|
-
"react": ">=18.2.0"
|
|
27
|
-
},
|
|
28
|
-
"devDependencies": {
|
|
29
|
-
"@types/react": "18.3.5",
|
|
30
|
-
"react": "18.3.1"
|
|
31
|
-
},
|
|
32
25
|
"gitHead": "a2dee6aa67621f6eda17e63e88d0edf14f88455a"
|
|
33
26
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function adjustTextareaHeight(element: HTMLTextAreaElement, rows?: number): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.adjustTextareaHeight = adjustTextareaHeight;
|
|
4
|
+
function adjustTextareaHeight(element, rows = 4) {
|
|
5
|
+
element.style.height = "auto";
|
|
6
|
+
if (rows >= 1) {
|
|
7
|
+
const contentHeight = element.scrollHeight;
|
|
8
|
+
const lineHeight = parseFloat(window.getComputedStyle(element).getPropertyValue("line-height"));
|
|
9
|
+
const fontSize = parseFloat(window.getComputedStyle(element).getPropertyValue("font-size"));
|
|
10
|
+
const targetHeight = parseInt((rows * fontSize * (lineHeight / fontSize)).toFixed(3), 10);
|
|
11
|
+
element.style.height = Math.max(targetHeight, contentHeight) + "px";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// adjustTextareaHeight.spec.ts
|
|
4
|
+
const adjust_textarea_height_1 = require("./adjust-textarea-height");
|
|
5
|
+
describe("adjustTextareaHeight", () => {
|
|
6
|
+
let textarea;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
textarea = document.createElement("textarea");
|
|
9
|
+
document.body.appendChild(textarea);
|
|
10
|
+
});
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
document.body.removeChild(textarea);
|
|
13
|
+
jest.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
it('should reset the height of the textarea to "auto" before adjustment', () => {
|
|
16
|
+
textarea.style.height = "100px";
|
|
17
|
+
(0, adjust_textarea_height_1.adjustTextareaHeight)(textarea);
|
|
18
|
+
expect(textarea.style.height).toBe("auto");
|
|
19
|
+
});
|
|
20
|
+
it("should correctly adjust the height based on content height when rows are provided", () => {
|
|
21
|
+
jest.spyOn(window, "getComputedStyle").mockImplementation(() => ({
|
|
22
|
+
getPropertyValue: (property) => {
|
|
23
|
+
if (property === "line-height") {
|
|
24
|
+
return "20px";
|
|
25
|
+
}
|
|
26
|
+
if (property === "font-size") {
|
|
27
|
+
return "16px";
|
|
28
|
+
}
|
|
29
|
+
return "";
|
|
30
|
+
},
|
|
31
|
+
}));
|
|
32
|
+
textarea.style.height = "auto";
|
|
33
|
+
textarea.style.fontSize = "16px";
|
|
34
|
+
// Simulate some content with scrollHeight of 150px
|
|
35
|
+
Object.defineProperty(textarea, "scrollHeight", { value: 150, configurable: true });
|
|
36
|
+
(0, adjust_textarea_height_1.adjustTextareaHeight)(textarea, 4);
|
|
37
|
+
// Calculate expected target height
|
|
38
|
+
const fontSize = 16;
|
|
39
|
+
const lineHeight = 20;
|
|
40
|
+
const targetHeight = 4 * fontSize * (lineHeight / fontSize);
|
|
41
|
+
expect(textarea.style.height).toBe(`${Math.max(targetHeight, 150)}px`);
|
|
42
|
+
});
|
|
43
|
+
it("should handle a case when rows is not provided and default to 4", () => {
|
|
44
|
+
jest.spyOn(window, "getComputedStyle").mockImplementation(() => ({
|
|
45
|
+
getPropertyValue: (property) => {
|
|
46
|
+
if (property === "line-height") {
|
|
47
|
+
return "24px";
|
|
48
|
+
}
|
|
49
|
+
if (property === "font-size") {
|
|
50
|
+
return "16px";
|
|
51
|
+
}
|
|
52
|
+
return "";
|
|
53
|
+
},
|
|
54
|
+
}));
|
|
55
|
+
// Simulate some content with scrollHeight of 100px
|
|
56
|
+
Object.defineProperty(textarea, "scrollHeight", { value: 100, configurable: true });
|
|
57
|
+
(0, adjust_textarea_height_1.adjustTextareaHeight)(textarea);
|
|
58
|
+
// Default rows = 4
|
|
59
|
+
const fontSize = 16;
|
|
60
|
+
const lineHeight = 24;
|
|
61
|
+
const targetHeight = 4 * fontSize * (lineHeight / fontSize);
|
|
62
|
+
expect(textarea.style.height).toBe(`${Math.max(targetHeight, 100)}px`);
|
|
63
|
+
});
|
|
64
|
+
it("should not fail if rows is less than 1", () => {
|
|
65
|
+
jest.spyOn(window, "getComputedStyle").mockImplementation(() => ({
|
|
66
|
+
getPropertyValue: (property) => {
|
|
67
|
+
if (property === "line-height") {
|
|
68
|
+
return "18px";
|
|
69
|
+
}
|
|
70
|
+
if (property === "font-size") {
|
|
71
|
+
return "14px";
|
|
72
|
+
}
|
|
73
|
+
return "";
|
|
74
|
+
},
|
|
75
|
+
}));
|
|
76
|
+
// Simulate some content with scrollHeight of 80px
|
|
77
|
+
Object.defineProperty(textarea, "scrollHeight", { value: 80, configurable: true });
|
|
78
|
+
(0, adjust_textarea_height_1.adjustTextareaHeight)(textarea, 0);
|
|
79
|
+
// Target height should not be calculated when rows < 1,
|
|
80
|
+
// so only scrollHeight should matter
|
|
81
|
+
expect(textarea.style.height).toBe("auto");
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const build_array_1 = require("./build-array");
|
|
4
|
+
test("buildArray", () => {
|
|
5
|
+
expect((0, build_array_1.buildArray)()).toStrictEqual([]);
|
|
6
|
+
expect((0, build_array_1.buildArray)().add("uxf")).toStrictEqual(["uxf"]);
|
|
7
|
+
expect((0, build_array_1.buildArray)().add("ux").add("fans")).toStrictEqual(["ux", "fans"]);
|
|
8
|
+
expect((0, build_array_1.buildArray)().add("ux").when(true, "fans")).toStrictEqual(["ux", "fans"]);
|
|
9
|
+
expect((0, build_array_1.buildArray)().add("ux").when(false, "fans")).toStrictEqual(["ux"]);
|
|
10
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const camel_case_to_dash_1 = require("./camel-case-to-dash");
|
|
4
|
+
test("camelCaseToDash", () => {
|
|
5
|
+
expect((0, camel_case_to_dash_1.camelCaseToDash)("someName")).toBe("some-name");
|
|
6
|
+
expect((0, camel_case_to_dash_1.camelCaseToDash)("camelCaseString")).toBe("camel-case-string");
|
|
7
|
+
expect((0, camel_case_to_dash_1.camelCaseToDash)("seo")).toBe("seo");
|
|
8
|
+
});
|
package/utils/image.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { ImageResponse, ImageSource, ResizerImageProps, StaticImageData } from "./resizer";
|
|
3
2
|
export type Dimension = number | "auto";
|
|
4
3
|
export type Format = "avif" | "webp" | "original";
|
|
@@ -16,24 +15,3 @@ export type GetImgSrcSetOptions = ResizerImageProps & {
|
|
|
16
15
|
maxHiDpi?: 3 | 2 | 1;
|
|
17
16
|
};
|
|
18
17
|
export declare function getImgSrcSet(src: ImageSource, width?: Dimension, height?: Dimension, options?: GetImgSrcSetOptions): string | undefined;
|
|
19
|
-
/**
|
|
20
|
-
* @deprecated Use import from @uxf/ui instead.
|
|
21
|
-
*/
|
|
22
|
-
export type ImageSourcesOptions = Omit<GetImgSrcSetOptions, "quality" | "toFormat"> & {
|
|
23
|
-
isAvifDisabled?: boolean;
|
|
24
|
-
isWebPDisabled?: boolean;
|
|
25
|
-
};
|
|
26
|
-
interface ImageSourcesProps {
|
|
27
|
-
breakpointIndex?: number;
|
|
28
|
-
breakpoints?: string[];
|
|
29
|
-
height: Dimension;
|
|
30
|
-
options?: ImageSourcesOptions;
|
|
31
|
-
quality?: Quality;
|
|
32
|
-
src: ImageSource;
|
|
33
|
-
width: Dimension;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* @deprecated Use import from @uxf/ui instead.
|
|
37
|
-
*/
|
|
38
|
-
export declare function ImgSources(props: ImageSourcesProps): React.JSX.Element | null;
|
|
39
|
-
export {};
|
package/utils/image.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.isSrcString = isSrcString;
|
|
7
4
|
exports.isSrcImageResponse = isSrcImageResponse;
|
|
@@ -13,9 +10,6 @@ exports.getImgUniqueIdentifier = getImgUniqueIdentifier;
|
|
|
13
10
|
exports.getImgElementHeight = getImgElementHeight;
|
|
14
11
|
exports.getImgElementWidth = getImgElementWidth;
|
|
15
12
|
exports.getImgSrcSet = getImgSrcSet;
|
|
16
|
-
exports.ImgSources = ImgSources;
|
|
17
|
-
const hide_1 = require("@uxf/core-react/components/hide");
|
|
18
|
-
const react_1 = __importDefault(require("react"));
|
|
19
13
|
const file_1 = require("./file");
|
|
20
14
|
const is_empty_1 = require("./is-empty");
|
|
21
15
|
const is_not_nil_1 = require("./is-not-nil");
|
|
@@ -124,38 +118,3 @@ function getImgSrcSet(src, width, height, options = {}) {
|
|
|
124
118
|
}
|
|
125
119
|
return (0, resizer_1.resizerImageUrl)(src, w, h, { toFormat, ...restOptions });
|
|
126
120
|
}
|
|
127
|
-
/**
|
|
128
|
-
* @deprecated Use import from @uxf/ui instead.
|
|
129
|
-
*/
|
|
130
|
-
function ImgSources(props) {
|
|
131
|
-
var _a, _b;
|
|
132
|
-
if (isSrcString(props.src) && (0, is_empty_1.isEmpty)(props.src)) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
if (isSrcImageResponse(props.src) && (0, is_empty_1.isEmpty)(props.src.uuid)) {
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
if (isSrcStaticImageData(props.src) && (0, is_empty_1.isEmpty)(props.src.src)) {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
const media = (0, is_not_nil_1.isNotNil)(props.breakpoints) && (0, is_not_nil_1.isNotNil)(props.breakpointIndex)
|
|
142
|
-
? `(min-width: ${props.breakpoints[props.breakpointIndex]})`
|
|
143
|
-
: undefined;
|
|
144
|
-
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
145
|
-
react_1.default.createElement(hide_1.Hide, { when: Boolean((_a = props.options) === null || _a === void 0 ? void 0 : _a.isAvifDisabled) },
|
|
146
|
-
react_1.default.createElement("source", { media: media, srcSet: getImgSrcSet(props.src, props.width, props.height, {
|
|
147
|
-
...props.options,
|
|
148
|
-
quality: getImgQuality(props.quality, "avif"),
|
|
149
|
-
toFormat: "avif",
|
|
150
|
-
}), type: "image/avif" })),
|
|
151
|
-
react_1.default.createElement(hide_1.Hide, { when: Boolean((_b = props.options) === null || _b === void 0 ? void 0 : _b.isWebPDisabled) },
|
|
152
|
-
react_1.default.createElement("source", { media: media, srcSet: getImgSrcSet(props.src, props.width, props.height, {
|
|
153
|
-
...props.options,
|
|
154
|
-
quality: getImgQuality(props.quality, "webp"),
|
|
155
|
-
toFormat: "webp",
|
|
156
|
-
}), type: "image/webp" })),
|
|
157
|
-
react_1.default.createElement("source", { media: media, srcSet: getImgSrcSet(props.src, props.width, props.height, {
|
|
158
|
-
...props.options,
|
|
159
|
-
quality: getImgQuality(props.quality, "original"),
|
|
160
|
-
}) })));
|
|
161
|
-
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const is_browser_1 = require("./is-browser");
|
|
4
4
|
test("isBrowser", () => {
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
6
6
|
if (window === undefined) {
|
|
7
|
-
expect(
|
|
7
|
+
expect(is_browser_1.isBrowser).toBeFalsy();
|
|
8
8
|
}
|
|
9
9
|
else {
|
|
10
|
-
expect(
|
|
10
|
+
expect(is_browser_1.isBrowser).toBeTruthy();
|
|
11
11
|
}
|
|
12
12
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isServer = void 0;
|
|
4
|
-
const
|
|
5
|
-
exports.isServer = !
|
|
4
|
+
const is_browser_1 = require("./is-browser");
|
|
5
|
+
exports.isServer = !is_browser_1.isBrowser;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const is_browser_1 = require("./is-browser");
|
|
4
|
+
const is_server_1 = require("./is-server");
|
|
5
|
+
test("isServer", () => {
|
|
6
|
+
if (is_browser_1.isBrowser) {
|
|
7
|
+
expect(is_server_1.isServer).toBeFalsy();
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
expect(is_server_1.isServer).toBeTruthy();
|
|
11
|
+
}
|
|
12
|
+
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const trim_trailing_zeros_1 = require("./trim-trailing-zeros");
|
|
4
4
|
test("trimTrailingZeros", () => {
|
|
5
|
-
expect((0,
|
|
6
|
-
expect((0,
|
|
7
|
-
expect((0,
|
|
8
|
-
expect((0,
|
|
9
|
-
expect((0,
|
|
5
|
+
expect((0, trim_trailing_zeros_1.trimTrailingZeros)("1.0000")).toBe("1");
|
|
6
|
+
expect((0, trim_trailing_zeros_1.trimTrailingZeros)("1.")).toBe("1.");
|
|
7
|
+
expect((0, trim_trailing_zeros_1.trimTrailingZeros)("0")).toBe("0");
|
|
8
|
+
expect((0, trim_trailing_zeros_1.trimTrailingZeros)("100")).toBe("100");
|
|
9
|
+
expect((0, trim_trailing_zeros_1.trimTrailingZeros)("test .0")).toBe("test ");
|
|
10
10
|
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FormValidator = void 0;
|
|
4
|
-
const
|
|
4
|
+
const validator_1 = require("./validator");
|
|
5
5
|
const emptyValue = (value) => value === null || value === undefined || value === "";
|
|
6
6
|
// required
|
|
7
7
|
const required = (errorMessage) => (value) => emptyValue(value) ? errorMessage || "Vyplňte." : undefined;
|
|
8
8
|
// email
|
|
9
|
-
const isEmail = (errorMessage) => (value) => !emptyValue(value) && !
|
|
9
|
+
const isEmail = (errorMessage) => (value) => !emptyValue(value) && !validator_1.Validator.isEmail(value) ? errorMessage || "E-mail není validní" : undefined;
|
|
10
10
|
// phone
|
|
11
|
-
const isPhone = (errorMessage) => (value) => !emptyValue(value) && !
|
|
11
|
+
const isPhone = (errorMessage) => (value) => !emptyValue(value) && !validator_1.Validator.isPhone(value) ? errorMessage || "Telefon není validní" : undefined;
|
|
12
12
|
const isLessThan = (maxValue, errorMessage) => (value) => {
|
|
13
13
|
if (value === "") {
|
|
14
14
|
return undefined;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const form_validator_1 = require("./form-validator");
|
|
4
|
+
test("required", () => {
|
|
5
|
+
expect(form_validator_1.FormValidator.required("error")("not empty")).toBeUndefined();
|
|
6
|
+
expect(form_validator_1.FormValidator.required("error")(0)).toBeUndefined();
|
|
7
|
+
expect(form_validator_1.FormValidator.required("error")(false)).toBeUndefined();
|
|
8
|
+
expect(form_validator_1.FormValidator.required("error")("")).toBe("error");
|
|
9
|
+
expect(form_validator_1.FormValidator.required("error")(null)).toBe("error");
|
|
10
|
+
expect(form_validator_1.FormValidator.required("error")(undefined)).toBe("error");
|
|
11
|
+
});
|
|
12
|
+
test("isEmail", () => {
|
|
13
|
+
expect(form_validator_1.FormValidator.isEmail("error")("")).toBeUndefined();
|
|
14
|
+
expect(form_validator_1.FormValidator.isEmail("error")("dev@uxf.cz")).toBeUndefined();
|
|
15
|
+
expect(form_validator_1.FormValidator.isEmail("error")("dev@uxfcz")).toBe("error");
|
|
16
|
+
});
|
|
17
|
+
test("isPhone", () => {
|
|
18
|
+
expect(form_validator_1.FormValidator.isPhone("error")("")).toBeUndefined();
|
|
19
|
+
expect(form_validator_1.FormValidator.isPhone("error")("777888999")).toBeUndefined();
|
|
20
|
+
expect(form_validator_1.FormValidator.isPhone("error")("dev@uxfcz")).toBe("error");
|
|
21
|
+
});
|
|
22
|
+
test("isLessThan", () => {
|
|
23
|
+
expect(form_validator_1.FormValidator.isLessThan(10, "error")("")).toBeUndefined();
|
|
24
|
+
expect(form_validator_1.FormValidator.isLessThan(10, "error")("9.9")).toBeUndefined();
|
|
25
|
+
expect(form_validator_1.FormValidator.isLessThan(10, "error")("10")).toBe("error");
|
|
26
|
+
expect(form_validator_1.FormValidator.isLessThan(10, "error")("100")).toBe("error");
|
|
27
|
+
});
|
|
28
|
+
test("isLessOrEqualThan", () => {
|
|
29
|
+
expect(form_validator_1.FormValidator.isLessOrEqualThan(10, "error")("")).toBeUndefined();
|
|
30
|
+
expect(form_validator_1.FormValidator.isLessOrEqualThan(10, "error")("9.9")).toBeUndefined();
|
|
31
|
+
expect(form_validator_1.FormValidator.isLessOrEqualThan(10, "error")("10")).toBeUndefined();
|
|
32
|
+
expect(form_validator_1.FormValidator.isLessOrEqualThan(10, "error")("10.001")).toBe("error");
|
|
33
|
+
});
|
|
34
|
+
test("isGreaterThan", () => {
|
|
35
|
+
expect(form_validator_1.FormValidator.isGreaterThan(10, "error")("")).toBeUndefined();
|
|
36
|
+
expect(form_validator_1.FormValidator.isGreaterThan(10, "error")("9")).toBe("error");
|
|
37
|
+
expect(form_validator_1.FormValidator.isGreaterThan(10, "error")("10")).toBe("error");
|
|
38
|
+
expect(form_validator_1.FormValidator.isGreaterThan(10, "error")("10.001")).toBeUndefined();
|
|
39
|
+
});
|
|
40
|
+
test("isGreaterOrEqualThan", () => {
|
|
41
|
+
expect(form_validator_1.FormValidator.isGreaterOrEqualThan(10, "error")("")).toBeUndefined();
|
|
42
|
+
expect(form_validator_1.FormValidator.isGreaterOrEqualThan(10, "error")("9")).toBe("error");
|
|
43
|
+
expect(form_validator_1.FormValidator.isGreaterOrEqualThan(10, "error")("10")).toBeUndefined();
|
|
44
|
+
expect(form_validator_1.FormValidator.isGreaterOrEqualThan(10, "error")("10.001")).toBeUndefined();
|
|
45
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const validator_1 = require("./validator");
|
|
4
|
+
test("isEmail", () => {
|
|
5
|
+
expect(validator_1.Validator.isEmail("dev@uxf.cz")).toBe(true);
|
|
6
|
+
expect(validator_1.Validator.isEmail("dev@uxf.c")).toBe(false);
|
|
7
|
+
expect(validator_1.Validator.isEmail("dev@uxf@c")).toBe(false);
|
|
8
|
+
});
|
|
9
|
+
test("isPhone", () => {
|
|
10
|
+
expect(validator_1.Validator.isPhone("+420777000111")).toBe(true);
|
|
11
|
+
expect(validator_1.Validator.isPhone("00420777000111")).toBe(true);
|
|
12
|
+
expect(validator_1.Validator.isPhone("777000111")).toBe(true);
|
|
13
|
+
expect(validator_1.Validator.isPhone("77700011")).toBe(false);
|
|
14
|
+
expect(validator_1.Validator.isPhone("+1777000111")).toBe(true);
|
|
15
|
+
expect(validator_1.Validator.isPhone("+22777000111")).toBe(true);
|
|
16
|
+
expect(validator_1.Validator.isPhone("+001777000111")).toBe(true);
|
|
17
|
+
});
|