@navikt/ds-react 5.10.4 → 5.11.1
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/_docs.json +38 -0
- package/cjs/form/Switch.js +3 -3
- package/cjs/form/Textarea.js +4 -3
- package/cjs/form/TextareaCounter.js +45 -6
- package/cjs/util/TextareaAutoSize.js +67 -69
- package/esm/form/Switch.js +3 -3
- package/esm/form/Switch.js.map +1 -1
- package/esm/form/Textarea.d.ts +7 -1
- package/esm/form/Textarea.js +4 -3
- package/esm/form/Textarea.js.map +1 -1
- package/esm/form/TextareaCounter.js +22 -6
- package/esm/form/TextareaCounter.js.map +1 -1
- package/esm/util/TextareaAutoSize.d.ts +4 -0
- package/esm/util/TextareaAutoSize.js +67 -69
- package/esm/util/TextareaAutoSize.js.map +1 -1
- package/package.json +3 -3
- package/src/form/Switch.tsx +7 -3
- package/src/form/Textarea.tsx +12 -2
- package/src/form/TextareaCounter.tsx +39 -12
- package/src/form/stories/textarea.stories.tsx +38 -2
- package/src/util/TextareaAutoSize.tsx +99 -82
package/_docs.json
CHANGED
|
@@ -3507,6 +3507,25 @@
|
|
|
3507
3507
|
}
|
|
3508
3508
|
],
|
|
3509
3509
|
"required": false,
|
|
3510
|
+
"type": {
|
|
3511
|
+
"name": "boolean | \"vertical\" | \"horizontal\""
|
|
3512
|
+
}
|
|
3513
|
+
},
|
|
3514
|
+
"UNSAFE_autoScrollbar": {
|
|
3515
|
+
"defaultValue": null,
|
|
3516
|
+
"description": "Textarea will stop growing and get a scrollbar when there's no more room to grow.\nRequires `display:flex` on the parent.\nExperimental feature that may be removed or get breaking changes in a minor version.",
|
|
3517
|
+
"name": "UNSAFE_autoScrollbar",
|
|
3518
|
+
"parent": {
|
|
3519
|
+
"fileName": "src/form/Textarea.tsx",
|
|
3520
|
+
"name": "TextareaProps"
|
|
3521
|
+
},
|
|
3522
|
+
"declarations": [
|
|
3523
|
+
{
|
|
3524
|
+
"fileName": "src/form/Textarea.tsx",
|
|
3525
|
+
"name": "TextareaProps"
|
|
3526
|
+
}
|
|
3527
|
+
],
|
|
3528
|
+
"required": false,
|
|
3510
3529
|
"type": {
|
|
3511
3530
|
"name": "boolean"
|
|
3512
3531
|
}
|
|
@@ -10411,6 +10430,25 @@
|
|
|
10411
10430
|
"name": "number"
|
|
10412
10431
|
}
|
|
10413
10432
|
},
|
|
10433
|
+
"autoScrollbar": {
|
|
10434
|
+
"defaultValue": null,
|
|
10435
|
+
"description": "If true, textarea will never get `overflow:hidden`",
|
|
10436
|
+
"name": "autoScrollbar",
|
|
10437
|
+
"parent": {
|
|
10438
|
+
"fileName": "src/util/TextareaAutoSize.tsx",
|
|
10439
|
+
"name": "TextareaAutosizeProps"
|
|
10440
|
+
},
|
|
10441
|
+
"declarations": [
|
|
10442
|
+
{
|
|
10443
|
+
"fileName": "src/util/TextareaAutoSize.tsx",
|
|
10444
|
+
"name": "TextareaAutosizeProps"
|
|
10445
|
+
}
|
|
10446
|
+
],
|
|
10447
|
+
"required": false,
|
|
10448
|
+
"type": {
|
|
10449
|
+
"name": "boolean"
|
|
10450
|
+
}
|
|
10451
|
+
},
|
|
10414
10452
|
"className": {
|
|
10415
10453
|
"defaultValue": null,
|
|
10416
10454
|
"description": "",
|
package/cjs/form/Switch.js
CHANGED
|
@@ -40,11 +40,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
40
|
exports.Switch = void 0;
|
|
41
41
|
const clsx_1 = __importDefault(require("clsx"));
|
|
42
42
|
const react_1 = __importStar(require("react"));
|
|
43
|
-
const useFormField_1 = require("./useFormField");
|
|
44
|
-
const ReadOnlyIcon_1 = require("./ReadOnlyIcon");
|
|
45
43
|
const loader_1 = require("../loader");
|
|
46
44
|
const typography_1 = require("../typography");
|
|
47
45
|
const util_1 = require("../util");
|
|
46
|
+
const ReadOnlyIcon_1 = require("./ReadOnlyIcon");
|
|
47
|
+
const useFormField_1 = require("./useFormField");
|
|
48
48
|
const SelectedIcon = () => (react_1.default.createElement("svg", { width: "12", height: "10", viewBox: "0 0 12 10", fill: "none", xmlns: "http://www.w3.org/2000/svg", focusable: false, role: "img", "aria-hidden": true, "aria-label": "Deaktiver valg" },
|
|
49
49
|
react_1.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M11.2674 0.647802C11.8762 1.20971 11.9141 2.1587 11.3522 2.76743L5.35221 9.26743C5.07531 9.56739 4.68813 9.74155 4.27998 9.74971C3.87184 9.75787 3.478 9.59933 3.18934 9.31067L0.68934 6.81067C0.103553 6.22488 0.103553 5.27513 0.68934 4.68935C1.27513 4.10356 2.22487 4.10356 2.81066 4.68935L4.20673 6.08541L9.14779 0.732587C9.7097 0.123856 10.6587 0.0858967 11.2674 0.647802Z", fill: "currentColor" })));
|
|
50
50
|
/**
|
|
@@ -86,7 +86,7 @@ exports.Switch = (0, react_1.forwardRef)((props, ref) => {
|
|
|
86
86
|
(_a = props === null || props === void 0 ? void 0 : props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
87
87
|
}, className: (0, clsx_1.default)(className, "navds-switch__input") })),
|
|
88
88
|
react_1.default.createElement("span", { className: "navds-switch__track" },
|
|
89
|
-
react_1.default.createElement("span", { className: "navds-switch__thumb" }, loading ? (react_1.default.createElement(loader_1.Loader, { size: "xsmall", "aria-live": "polite" })) : checked ? (react_1.default.createElement(SelectedIcon, null)) : null)),
|
|
89
|
+
react_1.default.createElement("span", { className: "navds-switch__thumb" }, loading ? (react_1.default.createElement(loader_1.Loader, { size: "xsmall", "aria-live": "polite", variant: checked ? "interaction" : "neutral" })) : checked ? (react_1.default.createElement(SelectedIcon, null)) : null)),
|
|
90
90
|
react_1.default.createElement("label", { htmlFor: inputProps.id, className: "navds-switch__label-wrapper" },
|
|
91
91
|
react_1.default.createElement("div", { className: (0, clsx_1.default)("navds-switch__content", {
|
|
92
92
|
"navds-sr-only": hideLabel,
|
package/cjs/form/Textarea.js
CHANGED
|
@@ -60,7 +60,7 @@ const useFormField_1 = require("./useFormField");
|
|
|
60
60
|
exports.Textarea = (0, react_1.forwardRef)((props, ref) => {
|
|
61
61
|
var _a, _b, _c;
|
|
62
62
|
const { inputProps, errorId, showErrorMsg, hasError, size, inputDescriptionId, } = (0, useFormField_1.useFormField)(props, "textarea");
|
|
63
|
-
const { label, className, description, maxLength, hideLabel = false, resize, i18n, readOnly } = props, rest = __rest(props, ["label", "className", "description", "maxLength", "hideLabel", "resize", "i18n", "readOnly"]);
|
|
63
|
+
const { label, className, description, maxLength, hideLabel = false, resize, UNSAFE_autoScrollbar, i18n, readOnly } = props, rest = __rest(props, ["label", "className", "description", "maxLength", "hideLabel", "resize", "UNSAFE_autoScrollbar", "i18n", "readOnly"]);
|
|
64
64
|
const maxLengthId = (0, util_1.useId)();
|
|
65
65
|
const hasMaxLength = maxLength !== undefined && maxLength > 0;
|
|
66
66
|
const [controlledValue, setControlledValue] = (0, react_1.useState)((_a = props === null || props === void 0 ? void 0 : props.defaultValue) !== null && _a !== void 0 ? _a : "");
|
|
@@ -79,7 +79,8 @@ exports.Textarea = (0, react_1.forwardRef)((props, ref) => {
|
|
|
79
79
|
"navds-form-field--readonly": readOnly,
|
|
80
80
|
"navds-textarea--readonly": readOnly,
|
|
81
81
|
"navds-textarea--error": hasError,
|
|
82
|
-
"navds-textarea--
|
|
82
|
+
"navds-textarea--autoscrollbar": UNSAFE_autoScrollbar,
|
|
83
|
+
[`navds-textarea--resize-${resize === true ? "both" : resize}`]: resize,
|
|
83
84
|
}) },
|
|
84
85
|
react_1.default.createElement(typography_1.Label, { htmlFor: inputProps.id, size: size, className: (0, clsx_1.default)("navds-form-field__label", {
|
|
85
86
|
"navds-sr-only": hideLabel,
|
|
@@ -92,7 +93,7 @@ exports.Textarea = (0, react_1.forwardRef)((props, ref) => {
|
|
|
92
93
|
react_1.default.createElement("div", { className: "navds-textarea__wrapper" },
|
|
93
94
|
react_1.default.createElement(TextareaAutoSize_1.default, Object.assign({}, (0, util_1.omit)(rest, ["error", "errorId", "size"]), inputProps, { onChange: (e) => props.onChange
|
|
94
95
|
? props.onChange(e)
|
|
95
|
-
: setControlledValue(e.target.value), minRows: getMinRows(), ref: ref, readOnly: readOnly, className: (0, clsx_1.default)("navds-textarea__input", "navds-body-short", `navds-body-short--${size !== null && size !== void 0 ? size : "medium"}`) }, (describedBy ? { "aria-describedby": describedBy } : {}))),
|
|
96
|
+
: setControlledValue(e.target.value), minRows: getMinRows(), autoScrollbar: UNSAFE_autoScrollbar, ref: ref, readOnly: readOnly, className: (0, clsx_1.default)("navds-textarea__input", "navds-body-short", `navds-body-short--${size !== null && size !== void 0 ? size : "medium"}`) }, (describedBy ? { "aria-describedby": describedBy } : {}))),
|
|
96
97
|
hasMaxLength && !readOnly && !inputProps.disabled && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
97
98
|
react_1.default.createElement("span", { id: maxLengthId, className: "navds-sr-only" }, `Tekstområde med plass til ${maxLength} tegn.`),
|
|
98
99
|
react_1.default.createElement(TextareaCounter_1.default, { maxLength: maxLength, currentLength: (_c = (_b = props.value) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : controlledValue === null || controlledValue === void 0 ? void 0 : controlledValue.length, size: size, i18n: i18n })))),
|
|
@@ -1,18 +1,57 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
29
|
const clsx_1 = __importDefault(require("clsx"));
|
|
7
|
-
const react_1 =
|
|
30
|
+
const react_1 = __importStar(require("react"));
|
|
8
31
|
const typography_1 = require("../typography");
|
|
32
|
+
const debounce_1 = __importDefault(require("../util/debounce"));
|
|
9
33
|
const TextareaCounter = ({ maxLength, currentLength, size, i18n }) => {
|
|
10
|
-
var _a, _b;
|
|
11
34
|
const difference = maxLength - currentLength;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
35
|
+
const [debouncedDiff, setDebouncedDiff] = (0, react_1.useState)(difference);
|
|
36
|
+
(0, react_1.useEffect)(() => {
|
|
37
|
+
const debounceFunc = (0, debounce_1.default)(() => {
|
|
38
|
+
setDebouncedDiff(difference);
|
|
39
|
+
}, 2000);
|
|
40
|
+
debounceFunc();
|
|
41
|
+
return () => {
|
|
42
|
+
debounceFunc.clear();
|
|
43
|
+
};
|
|
44
|
+
}, [difference]);
|
|
45
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
46
|
+
difference < 20 && (react_1.default.createElement("span", { role: "status", className: "navds-textarea__sr-counter navds-sr-only" }, getCounterText(debouncedDiff, i18n))),
|
|
47
|
+
react_1.default.createElement(typography_1.BodyShort, { className: (0, clsx_1.default)("navds-textarea__counter", {
|
|
48
|
+
"navds-textarea__counter--error": difference < 0,
|
|
49
|
+
}), size: size }, getCounterText(difference, i18n))));
|
|
50
|
+
};
|
|
51
|
+
const getCounterText = (difference, i18n) => {
|
|
52
|
+
var _a, _b;
|
|
53
|
+
return difference < 0
|
|
15
54
|
? `${Math.abs(difference)} ${(_a = i18n === null || i18n === void 0 ? void 0 : i18n.counterTooMuch) !== null && _a !== void 0 ? _a : "tegn for mye"}`
|
|
16
|
-
: `${difference} ${(_b = i18n === null || i18n === void 0 ? void 0 : i18n.counterLeft) !== null && _b !== void 0 ? _b : "tegn igjen"}
|
|
55
|
+
: `${difference} ${(_b = i18n === null || i18n === void 0 ? void 0 : i18n.counterLeft) !== null && _b !== void 0 ? _b : "tegn igjen"}`;
|
|
17
56
|
};
|
|
18
57
|
exports.default = TextareaCounter;
|
|
@@ -37,53 +37,75 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
-
/* https://github.com/mui/material-ui/blob/master/packages/mui-base/src/TextareaAutosize/TextareaAutosize.
|
|
40
|
+
/* https://github.com/mui/material-ui/blob/master/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx */
|
|
41
41
|
const react_1 = __importStar(require("react"));
|
|
42
42
|
const react_dom_1 = __importDefault(require("react-dom"));
|
|
43
43
|
const util_1 = require("../util");
|
|
44
|
+
const updateState = (prevState, newState, renders) => {
|
|
45
|
+
const { outerHeightStyle, overflow } = newState;
|
|
46
|
+
// Need a large enough difference to update the height.
|
|
47
|
+
// This prevents infinite rendering loop.
|
|
48
|
+
if (renders.current < 20 &&
|
|
49
|
+
((outerHeightStyle > 0 &&
|
|
50
|
+
Math.abs((prevState.outerHeightStyle || 0) - outerHeightStyle) > 1) ||
|
|
51
|
+
prevState.overflow !== overflow)) {
|
|
52
|
+
renders.current += 1;
|
|
53
|
+
return {
|
|
54
|
+
overflow,
|
|
55
|
+
outerHeightStyle,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (process.env.NODE_ENV !== "production") {
|
|
59
|
+
if (renders.current === 20) {
|
|
60
|
+
console.error([
|
|
61
|
+
"Textarea: Too many re-renders. The layout is unstable.",
|
|
62
|
+
"TextareaAutosize limits the number of renders to prevent an infinite loop.",
|
|
63
|
+
].join("\n"));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return prevState;
|
|
67
|
+
};
|
|
44
68
|
/**
|
|
45
|
-
* https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/ownerDocument.ts
|
|
46
|
-
* https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/ownerWindow.ts
|
|
69
|
+
* https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/ownerDocument/ownerDocument.ts
|
|
70
|
+
* https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/ownerWindow/ownerWindow.ts
|
|
47
71
|
*/
|
|
48
72
|
const ownerWindow = (node) => {
|
|
49
73
|
const doc = (node && node.ownerDocument) || document;
|
|
50
74
|
return doc.defaultView || window;
|
|
51
75
|
};
|
|
52
|
-
function getStyleValue(
|
|
53
|
-
return parseInt(
|
|
76
|
+
function getStyleValue(value) {
|
|
77
|
+
return parseInt(value, 10) || 0;
|
|
54
78
|
}
|
|
55
79
|
const TextareaAutosize = (0, react_1.forwardRef)((_a, ref) => {
|
|
56
|
-
var { className, onChange, maxRows, minRows = 1, style, value } = _a, other = __rest(_a, ["className", "onChange", "maxRows", "minRows", "style", "value"]);
|
|
80
|
+
var { className, onChange, maxRows, minRows = 1, autoScrollbar, style, value } = _a, other = __rest(_a, ["className", "onChange", "maxRows", "minRows", "autoScrollbar", "style", "value"]);
|
|
57
81
|
const { current: isControlled } = (0, react_1.useRef)(value != null);
|
|
58
82
|
const inputRef = (0, react_1.useRef)(null);
|
|
59
83
|
const handleRef = (0, react_1.useMemo)(() => (0, util_1.mergeRefs)([inputRef, ref]), [ref]);
|
|
60
84
|
const shadowRef = (0, react_1.useRef)(null);
|
|
61
85
|
const renders = (0, react_1.useRef)(0);
|
|
62
|
-
const [state, setState] = (0, react_1.useState)({});
|
|
86
|
+
const [state, setState] = (0, react_1.useState)({ outerHeightStyle: 0 });
|
|
63
87
|
const getUpdatedState = react_1.default.useCallback(() => {
|
|
64
|
-
if (!inputRef.current || !shadowRef.current)
|
|
65
|
-
return;
|
|
66
88
|
const input = inputRef.current;
|
|
67
89
|
const containerWindow = ownerWindow(input);
|
|
68
90
|
const computedStyle = containerWindow.getComputedStyle(input);
|
|
69
91
|
// If input's width is shrunk and it's not visible, don't sync height.
|
|
70
92
|
if (computedStyle.width === "0px") {
|
|
71
|
-
return;
|
|
93
|
+
return { outerHeightStyle: 0 };
|
|
72
94
|
}
|
|
73
95
|
const inputShallow = shadowRef.current;
|
|
74
96
|
inputShallow.style.width = computedStyle.width;
|
|
75
|
-
inputShallow.value = input.value ||
|
|
97
|
+
inputShallow.value = input.value || other.placeholder || "x";
|
|
76
98
|
if (inputShallow.value.slice(-1) === "\n") {
|
|
77
99
|
// Certain fonts which overflow the line height will cause the textarea
|
|
78
100
|
// to report a different scrollHeight depending on whether the last line
|
|
79
101
|
// is empty. Make it non-empty to avoid this issue.
|
|
80
102
|
inputShallow.value += " ";
|
|
81
103
|
}
|
|
82
|
-
const boxSizing = computedStyle
|
|
83
|
-
const padding = getStyleValue(computedStyle
|
|
84
|
-
getStyleValue(computedStyle
|
|
85
|
-
const border = getStyleValue(computedStyle
|
|
86
|
-
getStyleValue(computedStyle
|
|
104
|
+
const boxSizing = computedStyle.boxSizing;
|
|
105
|
+
const padding = getStyleValue(computedStyle.paddingBottom) +
|
|
106
|
+
getStyleValue(computedStyle.paddingTop);
|
|
107
|
+
const border = getStyleValue(computedStyle.borderBottomWidth) +
|
|
108
|
+
getStyleValue(computedStyle.borderTopWidth);
|
|
87
109
|
// The height of the inner content
|
|
88
110
|
const innerHeight = inputShallow.scrollHeight - padding;
|
|
89
111
|
// Measure height of a textarea with a single row
|
|
@@ -102,77 +124,50 @@ const TextareaAutosize = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
102
124
|
const outerHeightStyle = outerHeight + (boxSizing === "border-box" ? padding + border : 0);
|
|
103
125
|
const overflow = Math.abs(outerHeight - innerHeight) <= 1;
|
|
104
126
|
return { outerHeightStyle, overflow };
|
|
105
|
-
}, [maxRows, minRows, other
|
|
127
|
+
}, [maxRows, minRows, other.placeholder]);
|
|
106
128
|
const syncHeight = react_1.default.useCallback(() => {
|
|
107
129
|
const newState = getUpdatedState();
|
|
108
130
|
if (isEmpty(newState)) {
|
|
109
131
|
return;
|
|
110
132
|
}
|
|
111
|
-
setState((prevState) =>
|
|
112
|
-
return updateState(prevState, newState);
|
|
113
|
-
});
|
|
133
|
+
setState((prevState) => updateState(prevState, newState, renders));
|
|
114
134
|
}, [getUpdatedState]);
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
((outerHeightStyle > 0 &&
|
|
121
|
-
Math.abs((prevState.outerHeightStyle || 0) - outerHeightStyle) > 1) ||
|
|
122
|
-
prevState.overflow !== overflow)) {
|
|
123
|
-
renders.current += 1;
|
|
124
|
-
return {
|
|
125
|
-
overflow,
|
|
126
|
-
outerHeightStyle,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
if (process.env.NODE_ENV !== "production") {
|
|
130
|
-
if (renders.current === 20) {
|
|
131
|
-
console.error([
|
|
132
|
-
"Textarea: Too many re-renders. The layout is unstable.",
|
|
133
|
-
"TextareaAutosize limits the number of renders to prevent an infinite loop.",
|
|
134
|
-
].join("\n"));
|
|
135
|
+
(0, util_1.useClientLayoutEffect)(() => {
|
|
136
|
+
const syncHeightWithFlushSync = () => {
|
|
137
|
+
const newState = getUpdatedState();
|
|
138
|
+
if (isEmpty(newState)) {
|
|
139
|
+
return;
|
|
135
140
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
// In React 18, state updates in a ResizeObserver's callback are happening after the paint which causes flickering
|
|
145
|
-
// when doing some visual updates in it. Using flushSync ensures that the dom will be painted after the states updates happen
|
|
146
|
-
// Related issue - https://github.com/facebook/react/issues/24331
|
|
147
|
-
react_dom_1.default.flushSync(() => {
|
|
148
|
-
setState((prevState) => {
|
|
149
|
-
return updateState(prevState, newState);
|
|
141
|
+
// In React 18, state updates in a ResizeObserver's callback are happening after
|
|
142
|
+
// the paint, this leads to an infinite rendering.
|
|
143
|
+
//
|
|
144
|
+
// Using flushSync ensures that the states is updated before the next pain.
|
|
145
|
+
// Related issue - https://github.com/facebook/react/issues/24331
|
|
146
|
+
react_dom_1.default.flushSync(() => {
|
|
147
|
+
setState((prevState) => updateState(prevState, newState, renders));
|
|
150
148
|
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
react_1.default.useEffect(() => {
|
|
154
|
-
const handleResize = (0, util_1.debounce)(() => {
|
|
149
|
+
};
|
|
150
|
+
const handleResize = () => {
|
|
155
151
|
renders.current = 0;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
});
|
|
160
|
-
let resizeObserver;
|
|
152
|
+
syncHeightWithFlushSync();
|
|
153
|
+
};
|
|
154
|
+
const debounceHandleResize = (0, util_1.debounce)(handleResize);
|
|
161
155
|
const input = inputRef.current;
|
|
162
156
|
const containerWindow = ownerWindow(input);
|
|
163
|
-
containerWindow.addEventListener("resize",
|
|
157
|
+
containerWindow.addEventListener("resize", debounceHandleResize);
|
|
158
|
+
let resizeObserver;
|
|
164
159
|
if (typeof ResizeObserver !== "undefined") {
|
|
165
160
|
resizeObserver = new ResizeObserver(handleResize);
|
|
166
161
|
resizeObserver.observe(input);
|
|
167
162
|
}
|
|
168
163
|
return () => {
|
|
169
|
-
|
|
170
|
-
containerWindow.removeEventListener("resize",
|
|
164
|
+
debounceHandleResize.clear();
|
|
165
|
+
containerWindow.removeEventListener("resize", debounceHandleResize);
|
|
171
166
|
if (resizeObserver) {
|
|
172
167
|
resizeObserver.disconnect();
|
|
173
168
|
}
|
|
174
169
|
};
|
|
175
|
-
});
|
|
170
|
+
}, [getUpdatedState]);
|
|
176
171
|
(0, util_1.useClientLayoutEffect)(() => {
|
|
177
172
|
syncHeight();
|
|
178
173
|
});
|
|
@@ -191,7 +186,10 @@ const TextareaAutosize = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
191
186
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
192
187
|
react_1.default.createElement("textarea", Object.assign({ value: value, onChange: handleChange, ref: handleRef,
|
|
193
188
|
// Apply the rows prop to get a "correct" first SSR paint
|
|
194
|
-
rows: minRows, style: Object.assign(
|
|
189
|
+
rows: minRows, style: Object.assign({ height: state.outerHeightStyle,
|
|
190
|
+
// Need a large enough difference to allow scrolling.
|
|
191
|
+
// This prevents infinite rendering loop.
|
|
192
|
+
overflow: state.overflow && !autoScrollbar ? "hidden" : undefined }, style) }, other, { className: className })),
|
|
195
193
|
react_1.default.createElement("textarea", { "aria-hidden": true, className: className, readOnly: true, ref: shadowRef, tabIndex: -1, style: Object.assign({
|
|
196
194
|
// Visibility needed to hide the extra text area on iPads
|
|
197
195
|
visibility: "hidden",
|
|
@@ -206,6 +204,6 @@ function isEmpty(obj) {
|
|
|
206
204
|
return (obj === undefined ||
|
|
207
205
|
obj === null ||
|
|
208
206
|
Object.keys(obj).length === 0 ||
|
|
209
|
-
(
|
|
207
|
+
(obj.outerHeightStyle === 0 && !obj.overflow));
|
|
210
208
|
}
|
|
211
209
|
exports.default = TextareaAutosize;
|
package/esm/form/Switch.js
CHANGED
|
@@ -11,11 +11,11 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
};
|
|
12
12
|
import cl from "clsx";
|
|
13
13
|
import React, { forwardRef, useEffect, useState, } from "react";
|
|
14
|
-
import { useFormField } from "./useFormField";
|
|
15
|
-
import { ReadOnlyIcon } from "./ReadOnlyIcon";
|
|
16
14
|
import { Loader } from "../loader";
|
|
17
15
|
import { BodyShort } from "../typography";
|
|
18
16
|
import { omit } from "../util";
|
|
17
|
+
import { ReadOnlyIcon } from "./ReadOnlyIcon";
|
|
18
|
+
import { useFormField } from "./useFormField";
|
|
19
19
|
const SelectedIcon = () => (React.createElement("svg", { width: "12", height: "10", viewBox: "0 0 12 10", fill: "none", xmlns: "http://www.w3.org/2000/svg", focusable: false, role: "img", "aria-hidden": true, "aria-label": "Deaktiver valg" },
|
|
20
20
|
React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M11.2674 0.647802C11.8762 1.20971 11.9141 2.1587 11.3522 2.76743L5.35221 9.26743C5.07531 9.56739 4.68813 9.74155 4.27998 9.74971C3.87184 9.75787 3.478 9.59933 3.18934 9.31067L0.68934 6.81067C0.103553 6.22488 0.103553 5.27513 0.68934 4.68935C1.27513 4.10356 2.22487 4.10356 2.81066 4.68935L4.20673 6.08541L9.14779 0.732587C9.7097 0.123856 10.6587 0.0858967 11.2674 0.647802Z", fill: "currentColor" })));
|
|
21
21
|
/**
|
|
@@ -57,7 +57,7 @@ export const Switch = forwardRef((props, ref) => {
|
|
|
57
57
|
(_a = props === null || props === void 0 ? void 0 : props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
58
58
|
}, className: cl(className, "navds-switch__input") })),
|
|
59
59
|
React.createElement("span", { className: "navds-switch__track" },
|
|
60
|
-
React.createElement("span", { className: "navds-switch__thumb" }, loading ? (React.createElement(Loader, { size: "xsmall", "aria-live": "polite" })) : checked ? (React.createElement(SelectedIcon, null)) : null)),
|
|
60
|
+
React.createElement("span", { className: "navds-switch__thumb" }, loading ? (React.createElement(Loader, { size: "xsmall", "aria-live": "polite", variant: checked ? "interaction" : "neutral" })) : checked ? (React.createElement(SelectedIcon, null)) : null)),
|
|
61
61
|
React.createElement("label", { htmlFor: inputProps.id, className: "navds-switch__label-wrapper" },
|
|
62
62
|
React.createElement("div", { className: cl("navds-switch__content", {
|
|
63
63
|
"navds-sr-only": hideLabel,
|
package/esm/form/Switch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.js","sourceRoot":"","sources":["../../src/form/Switch.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,EAAE,EACZ,UAAU,EAEV,SAAS,EACT,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,
|
|
1
|
+
{"version":3,"file":"Switch.js","sourceRoot":"","sources":["../../src/form/Switch.tsx"],"names":[],"mappings":"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"}
|
package/esm/form/Textarea.d.ts
CHANGED
|
@@ -36,7 +36,13 @@ export interface TextareaProps extends FormFieldProps, React.TextareaHTMLAttribu
|
|
|
36
36
|
/**
|
|
37
37
|
* Enables resizing of field
|
|
38
38
|
*/
|
|
39
|
-
resize?: boolean;
|
|
39
|
+
resize?: boolean | "vertical" | "horizontal";
|
|
40
|
+
/**
|
|
41
|
+
* Textarea will stop growing and get a scrollbar when there's no more room to grow.
|
|
42
|
+
* Requires `display:flex` on the parent.
|
|
43
|
+
* Experimental feature that may be removed or get breaking changes in a minor version.
|
|
44
|
+
*/
|
|
45
|
+
UNSAFE_autoScrollbar?: boolean;
|
|
40
46
|
/**
|
|
41
47
|
* i18n-translations for counter-text
|
|
42
48
|
*/
|
package/esm/form/Textarea.js
CHANGED
|
@@ -31,7 +31,7 @@ import { useFormField } from "./useFormField";
|
|
|
31
31
|
export const Textarea = forwardRef((props, ref) => {
|
|
32
32
|
var _a, _b, _c;
|
|
33
33
|
const { inputProps, errorId, showErrorMsg, hasError, size, inputDescriptionId, } = useFormField(props, "textarea");
|
|
34
|
-
const { label, className, description, maxLength, hideLabel = false, resize, i18n, readOnly } = props, rest = __rest(props, ["label", "className", "description", "maxLength", "hideLabel", "resize", "i18n", "readOnly"]);
|
|
34
|
+
const { label, className, description, maxLength, hideLabel = false, resize, UNSAFE_autoScrollbar, i18n, readOnly } = props, rest = __rest(props, ["label", "className", "description", "maxLength", "hideLabel", "resize", "UNSAFE_autoScrollbar", "i18n", "readOnly"]);
|
|
35
35
|
const maxLengthId = useId();
|
|
36
36
|
const hasMaxLength = maxLength !== undefined && maxLength > 0;
|
|
37
37
|
const [controlledValue, setControlledValue] = useState((_a = props === null || props === void 0 ? void 0 : props.defaultValue) !== null && _a !== void 0 ? _a : "");
|
|
@@ -50,7 +50,8 @@ export const Textarea = forwardRef((props, ref) => {
|
|
|
50
50
|
"navds-form-field--readonly": readOnly,
|
|
51
51
|
"navds-textarea--readonly": readOnly,
|
|
52
52
|
"navds-textarea--error": hasError,
|
|
53
|
-
"navds-textarea--
|
|
53
|
+
"navds-textarea--autoscrollbar": UNSAFE_autoScrollbar,
|
|
54
|
+
[`navds-textarea--resize-${resize === true ? "both" : resize}`]: resize,
|
|
54
55
|
}) },
|
|
55
56
|
React.createElement(Label, { htmlFor: inputProps.id, size: size, className: cl("navds-form-field__label", {
|
|
56
57
|
"navds-sr-only": hideLabel,
|
|
@@ -63,7 +64,7 @@ export const Textarea = forwardRef((props, ref) => {
|
|
|
63
64
|
React.createElement("div", { className: "navds-textarea__wrapper" },
|
|
64
65
|
React.createElement(TextareaAutosize, Object.assign({}, omit(rest, ["error", "errorId", "size"]), inputProps, { onChange: (e) => props.onChange
|
|
65
66
|
? props.onChange(e)
|
|
66
|
-
: setControlledValue(e.target.value), minRows: getMinRows(), ref: ref, readOnly: readOnly, className: cl("navds-textarea__input", "navds-body-short", `navds-body-short--${size !== null && size !== void 0 ? size : "medium"}`) }, (describedBy ? { "aria-describedby": describedBy } : {}))),
|
|
67
|
+
: setControlledValue(e.target.value), minRows: getMinRows(), autoScrollbar: UNSAFE_autoScrollbar, ref: ref, readOnly: readOnly, className: cl("navds-textarea__input", "navds-body-short", `navds-body-short--${size !== null && size !== void 0 ? size : "medium"}`) }, (describedBy ? { "aria-describedby": describedBy } : {}))),
|
|
67
68
|
hasMaxLength && !readOnly && !inputProps.disabled && (React.createElement(React.Fragment, null,
|
|
68
69
|
React.createElement("span", { id: maxLengthId, className: "navds-sr-only" }, `Tekstområde med plass til ${maxLength} tegn.`),
|
|
69
70
|
React.createElement(Counter, { maxLength: maxLength, currentLength: (_c = (_b = props.value) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : controlledValue === null || controlledValue === void 0 ? void 0 : controlledValue.length, size: size, i18n: i18n })))),
|
package/esm/form/Textarea.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.js","sourceRoot":"","sources":["../../src/form/Textarea.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,OAAO,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAkB,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Textarea.js","sourceRoot":"","sources":["../../src/form/Textarea.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,OAAO,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAkB,YAAY,EAAE,MAAM,gBAAgB,CAAC;AA0D9D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;;IACb,MAAM,EACJ,UAAU,EACV,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,IAAI,EACJ,kBAAkB,GACnB,GAAG,YAAY,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAEpC,MAAM,EACJ,KAAK,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,GAAG,KAAK,EACjB,MAAM,EACN,oBAAoB,EACpB,IAAI,EACJ,QAAQ,KAEN,KAAK,EADJ,IAAI,UACL,KAAK,EAXH,qHAWL,CAAQ,CAAC;IAEV,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAC5B,MAAM,YAAY,GAAG,SAAS,KAAK,SAAS,IAAI,SAAS,GAAG,CAAC,CAAC;IAE9D,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CACpD,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,YAAY,mCAAI,EAAE,CAC1B,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,IAAI,GAAG,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,EAAC,CAAC,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,IAAI,KAAK,OAAO,EAAE;YACpB,IAAI,GAAG,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,EAAC,CAAC,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;SAC1C;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE;QACrD,CAAC,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,EAAE,CAAC,EAAE,YAAY;KAClC,CAAC,CAAC;IAEH,OAAO,CACL,6BACE,SAAS,EAAE,EAAE,CACX,SAAS,EACT,kBAAkB,EAClB,qBAAqB,IAAI,EAAE,EAC3B;YACE,4BAA4B,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ;YACnD,4BAA4B,EAAE,QAAQ;YACtC,0BAA0B,EAAE,QAAQ;YACpC,uBAAuB,EAAE,QAAQ;YACjC,+BAA+B,EAAE,oBAAoB;YACrD,CAAC,0BAA0B,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAC7D,MAAM;SACT,CACF;QAED,oBAAC,KAAK,IACJ,OAAO,EAAE,UAAU,CAAC,EAAE,EACtB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE;gBACvC,eAAe,EAAE,SAAS;aAC3B,CAAC;YAEF,oBAAC,YAAY,IAAC,QAAQ,EAAE,QAAQ,GAAI;YACnC,KAAK,CACA;QACP,CAAC,CAAC,WAAW,IAAI,CAChB,oBAAC,SAAS,IACR,SAAS,EAAE,EAAE,CAAC,+BAA+B,EAAE;gBAC7C,eAAe,EAAE,SAAS;aAC3B,CAAC,EACF,EAAE,EAAE,kBAAkB,EACtB,IAAI,EAAE,IAAI,EACV,EAAE,EAAC,KAAK,IAEP,WAAW,CACF,CACb;QACD,6BAAK,SAAS,EAAC,yBAAyB;YACtC,oBAAC,gBAAgB,oBACX,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,EACxC,UAAU,IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,KAAK,CAAC,QAAQ;oBACZ,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACnB,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAExC,OAAO,EAAE,UAAU,EAAE,EACrB,aAAa,EAAE,oBAAoB,EACnC,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,EAAE,CACX,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,QAAQ,EAAE,CACxC,IACG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAC5D;YACD,YAAY,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,IAAI,CACpD;gBACE,8BAAM,EAAE,EAAE,WAAW,EAAE,SAAS,EAAC,eAAe,IAC7C,6BAA6B,SAAS,QAAQ,CAC1C;gBACP,oBAAC,OAAO,IACN,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,MAAA,MAAA,KAAK,CAAC,KAAK,0CAAE,MAAM,mCAAI,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,MAAM,EAC7D,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,IAAI,GACV,CACD,CACJ,CACG;QACN,6BACE,SAAS,EAAC,yBAAyB,EACnC,EAAE,EAAE,OAAO,mBACG,oBAAoB,eACxB,QAAQ,IAEjB,YAAY,IAAI,CACf,oBAAC,YAAY,IAAC,IAAI,EAAE,IAAI,IAAG,KAAK,CAAC,KAAK,CAAgB,CACvD,CACG,CACF,CACP,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
import cl from "clsx";
|
|
2
|
-
import React from "react";
|
|
2
|
+
import React, { useEffect, useState } from "react";
|
|
3
3
|
import { BodyShort } from "../typography";
|
|
4
|
+
import debounce from "../util/debounce";
|
|
4
5
|
const TextareaCounter = ({ maxLength, currentLength, size, i18n }) => {
|
|
5
|
-
var _a, _b;
|
|
6
6
|
const difference = maxLength - currentLength;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const [debouncedDiff, setDebouncedDiff] = useState(difference);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const debounceFunc = debounce(() => {
|
|
10
|
+
setDebouncedDiff(difference);
|
|
11
|
+
}, 2000);
|
|
12
|
+
debounceFunc();
|
|
13
|
+
return () => {
|
|
14
|
+
debounceFunc.clear();
|
|
15
|
+
};
|
|
16
|
+
}, [difference]);
|
|
17
|
+
return (React.createElement(React.Fragment, null,
|
|
18
|
+
difference < 20 && (React.createElement("span", { role: "status", className: "navds-textarea__sr-counter navds-sr-only" }, getCounterText(debouncedDiff, i18n))),
|
|
19
|
+
React.createElement(BodyShort, { className: cl("navds-textarea__counter", {
|
|
20
|
+
"navds-textarea__counter--error": difference < 0,
|
|
21
|
+
}), size: size }, getCounterText(difference, i18n))));
|
|
22
|
+
};
|
|
23
|
+
const getCounterText = (difference, i18n) => {
|
|
24
|
+
var _a, _b;
|
|
25
|
+
return difference < 0
|
|
10
26
|
? `${Math.abs(difference)} ${(_a = i18n === null || i18n === void 0 ? void 0 : i18n.counterTooMuch) !== null && _a !== void 0 ? _a : "tegn for mye"}`
|
|
11
|
-
: `${difference} ${(_b = i18n === null || i18n === void 0 ? void 0 : i18n.counterLeft) !== null && _b !== void 0 ? _b : "tegn igjen"}
|
|
27
|
+
: `${difference} ${(_b = i18n === null || i18n === void 0 ? void 0 : i18n.counterLeft) !== null && _b !== void 0 ? _b : "tegn igjen"}`;
|
|
12
28
|
};
|
|
13
29
|
export default TextareaCounter;
|
|
14
30
|
//# sourceMappingURL=TextareaCounter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextareaCounter.js","sourceRoot":"","sources":["../../src/form/TextareaCounter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"TextareaCounter.js","sourceRoot":"","sources":["../../src/form/TextareaCounter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,QAAQ,MAAM,kBAAkB,CAAC;AAUxC,MAAM,eAAe,GAAG,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAS,EAAE,EAAE;IAC1E,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,CAAC;IAE7C,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAE/D,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,EAAE;YACjC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,YAAY,EAAE,CAAC;QAEf,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,OAAO,CACL;QACG,UAAU,GAAG,EAAE,IAAI,CAClB,8BACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,0CAA0C,IAEnD,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,CAC/B,CACR;QAED,oBAAC,SAAS,IACR,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE;gBACvC,gCAAgC,EAAE,UAAU,GAAG,CAAC;aACjD,CAAC,EACF,IAAI,EAAE,IAAI,IAET,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,CACvB,CACX,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,UAAkB,EAAE,IAA2B,EAAE,EAAE;;IACzE,OAAA,UAAU,GAAG,CAAC;QACZ,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,cAAc,mCAAI,cAAc,EAAE;QACrE,CAAC,CAAC,GAAG,UAAU,IAAI,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,WAAW,mCAAI,YAAY,EAAE,CAAA;CAAA,CAAC;AAE3D,eAAe,eAAe,CAAC"}
|
|
@@ -9,6 +9,10 @@ interface TextareaAutosizeProps extends Omit<React.TextareaHTMLAttributes<HTMLTe
|
|
|
9
9
|
* @default 1
|
|
10
10
|
*/
|
|
11
11
|
minRows?: number;
|
|
12
|
+
/**
|
|
13
|
+
* If true, textarea will never get `overflow:hidden`
|
|
14
|
+
*/
|
|
15
|
+
autoScrollbar?: boolean;
|
|
12
16
|
}
|
|
13
17
|
declare const TextareaAutosize: React.ForwardRefExoticComponent<TextareaAutosizeProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
14
18
|
export default TextareaAutosize;
|