@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.
@@ -9,53 +9,75 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- /* https://github.com/mui/material-ui/blob/master/packages/mui-base/src/TextareaAutosize/TextareaAutosize.js */
12
+ /* https://github.com/mui/material-ui/blob/master/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx */
13
13
  import React, { forwardRef, useEffect, useMemo, useRef, useState } from "react";
14
14
  import ReactDOM from "react-dom";
15
15
  import { debounce, mergeRefs, useClientLayoutEffect } from "../util";
16
+ const updateState = (prevState, newState, renders) => {
17
+ const { outerHeightStyle, overflow } = newState;
18
+ // Need a large enough difference to update the height.
19
+ // This prevents infinite rendering loop.
20
+ if (renders.current < 20 &&
21
+ ((outerHeightStyle > 0 &&
22
+ Math.abs((prevState.outerHeightStyle || 0) - outerHeightStyle) > 1) ||
23
+ prevState.overflow !== overflow)) {
24
+ renders.current += 1;
25
+ return {
26
+ overflow,
27
+ outerHeightStyle,
28
+ };
29
+ }
30
+ if (process.env.NODE_ENV !== "production") {
31
+ if (renders.current === 20) {
32
+ console.error([
33
+ "Textarea: Too many re-renders. The layout is unstable.",
34
+ "TextareaAutosize limits the number of renders to prevent an infinite loop.",
35
+ ].join("\n"));
36
+ }
37
+ }
38
+ return prevState;
39
+ };
16
40
  /**
17
- * https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/ownerDocument.ts
18
- * https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/ownerWindow.ts
41
+ * https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/ownerDocument/ownerDocument.ts
42
+ * https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/ownerWindow/ownerWindow.ts
19
43
  */
20
44
  const ownerWindow = (node) => {
21
45
  const doc = (node && node.ownerDocument) || document;
22
46
  return doc.defaultView || window;
23
47
  };
24
- function getStyleValue(computedStyle, property) {
25
- return parseInt(computedStyle[property], 10) || 0;
48
+ function getStyleValue(value) {
49
+ return parseInt(value, 10) || 0;
26
50
  }
27
51
  const TextareaAutosize = forwardRef((_a, ref) => {
28
- var { className, onChange, maxRows, minRows = 1, style, value } = _a, other = __rest(_a, ["className", "onChange", "maxRows", "minRows", "style", "value"]);
52
+ var { className, onChange, maxRows, minRows = 1, autoScrollbar, style, value } = _a, other = __rest(_a, ["className", "onChange", "maxRows", "minRows", "autoScrollbar", "style", "value"]);
29
53
  const { current: isControlled } = useRef(value != null);
30
54
  const inputRef = useRef(null);
31
55
  const handleRef = useMemo(() => mergeRefs([inputRef, ref]), [ref]);
32
56
  const shadowRef = useRef(null);
33
57
  const renders = useRef(0);
34
- const [state, setState] = useState({});
58
+ const [state, setState] = useState({ outerHeightStyle: 0 });
35
59
  const getUpdatedState = React.useCallback(() => {
36
- if (!inputRef.current || !shadowRef.current)
37
- return;
38
60
  const input = inputRef.current;
39
61
  const containerWindow = ownerWindow(input);
40
62
  const computedStyle = containerWindow.getComputedStyle(input);
41
63
  // If input's width is shrunk and it's not visible, don't sync height.
42
64
  if (computedStyle.width === "0px") {
43
- return;
65
+ return { outerHeightStyle: 0 };
44
66
  }
45
67
  const inputShallow = shadowRef.current;
46
68
  inputShallow.style.width = computedStyle.width;
47
- inputShallow.value = input.value || (other === null || other === void 0 ? void 0 : other.placeholder) || "x";
69
+ inputShallow.value = input.value || other.placeholder || "x";
48
70
  if (inputShallow.value.slice(-1) === "\n") {
49
71
  // Certain fonts which overflow the line height will cause the textarea
50
72
  // to report a different scrollHeight depending on whether the last line
51
73
  // is empty. Make it non-empty to avoid this issue.
52
74
  inputShallow.value += " ";
53
75
  }
54
- const boxSizing = computedStyle["box-sizing"];
55
- const padding = getStyleValue(computedStyle, "padding-bottom") +
56
- getStyleValue(computedStyle, "padding-top");
57
- const border = getStyleValue(computedStyle, "border-bottom-width") +
58
- getStyleValue(computedStyle, "border-top-width");
76
+ const boxSizing = computedStyle.boxSizing;
77
+ const padding = getStyleValue(computedStyle.paddingBottom) +
78
+ getStyleValue(computedStyle.paddingTop);
79
+ const border = getStyleValue(computedStyle.borderBottomWidth) +
80
+ getStyleValue(computedStyle.borderTopWidth);
59
81
  // The height of the inner content
60
82
  const innerHeight = inputShallow.scrollHeight - padding;
61
83
  // Measure height of a textarea with a single row
@@ -74,77 +96,50 @@ const TextareaAutosize = forwardRef((_a, ref) => {
74
96
  const outerHeightStyle = outerHeight + (boxSizing === "border-box" ? padding + border : 0);
75
97
  const overflow = Math.abs(outerHeight - innerHeight) <= 1;
76
98
  return { outerHeightStyle, overflow };
77
- }, [maxRows, minRows, other === null || other === void 0 ? void 0 : other.placeholder]);
99
+ }, [maxRows, minRows, other.placeholder]);
78
100
  const syncHeight = React.useCallback(() => {
79
101
  const newState = getUpdatedState();
80
102
  if (isEmpty(newState)) {
81
103
  return;
82
104
  }
83
- setState((prevState) => {
84
- return updateState(prevState, newState);
85
- });
105
+ setState((prevState) => updateState(prevState, newState, renders));
86
106
  }, [getUpdatedState]);
87
- const updateState = (prevState, newState) => {
88
- const { outerHeightStyle, overflow } = newState;
89
- // Need a large enough difference to update the height.
90
- // This prevents infinite rendering loop.
91
- if (renders.current < 20 &&
92
- ((outerHeightStyle > 0 &&
93
- Math.abs((prevState.outerHeightStyle || 0) - outerHeightStyle) > 1) ||
94
- prevState.overflow !== overflow)) {
95
- renders.current += 1;
96
- return {
97
- overflow,
98
- outerHeightStyle,
99
- };
100
- }
101
- if (process.env.NODE_ENV !== "production") {
102
- if (renders.current === 20) {
103
- console.error([
104
- "Textarea: Too many re-renders. The layout is unstable.",
105
- "TextareaAutosize limits the number of renders to prevent an infinite loop.",
106
- ].join("\n"));
107
+ useClientLayoutEffect(() => {
108
+ const syncHeightWithFlushSync = () => {
109
+ const newState = getUpdatedState();
110
+ if (isEmpty(newState)) {
111
+ return;
107
112
  }
108
- }
109
- return prevState;
110
- };
111
- const withFlushSync = () => {
112
- const newState = getUpdatedState();
113
- if (isEmpty(newState)) {
114
- return;
115
- }
116
- // In React 18, state updates in a ResizeObserver's callback are happening after the paint which causes flickering
117
- // when doing some visual updates in it. Using flushSync ensures that the dom will be painted after the states updates happen
118
- // Related issue - https://github.com/facebook/react/issues/24331
119
- ReactDOM.flushSync(() => {
120
- setState((prevState) => {
121
- return updateState(prevState, newState);
113
+ // In React 18, state updates in a ResizeObserver's callback are happening after
114
+ // the paint, this leads to an infinite rendering.
115
+ //
116
+ // Using flushSync ensures that the states is updated before the next pain.
117
+ // Related issue - https://github.com/facebook/react/issues/24331
118
+ ReactDOM.flushSync(() => {
119
+ setState((prevState) => updateState(prevState, newState, renders));
122
120
  });
123
- });
124
- };
125
- React.useEffect(() => {
126
- const handleResize = debounce(() => {
121
+ };
122
+ const handleResize = () => {
127
123
  renders.current = 0;
128
- if (inputRef.current) {
129
- withFlushSync();
130
- }
131
- });
132
- let resizeObserver;
124
+ syncHeightWithFlushSync();
125
+ };
126
+ const debounceHandleResize = debounce(handleResize);
133
127
  const input = inputRef.current;
134
128
  const containerWindow = ownerWindow(input);
135
- containerWindow.addEventListener("resize", handleResize);
129
+ containerWindow.addEventListener("resize", debounceHandleResize);
130
+ let resizeObserver;
136
131
  if (typeof ResizeObserver !== "undefined") {
137
132
  resizeObserver = new ResizeObserver(handleResize);
138
133
  resizeObserver.observe(input);
139
134
  }
140
135
  return () => {
141
- handleResize.clear();
142
- containerWindow.removeEventListener("resize", handleResize);
136
+ debounceHandleResize.clear();
137
+ containerWindow.removeEventListener("resize", debounceHandleResize);
143
138
  if (resizeObserver) {
144
139
  resizeObserver.disconnect();
145
140
  }
146
141
  };
147
- });
142
+ }, [getUpdatedState]);
148
143
  useClientLayoutEffect(() => {
149
144
  syncHeight();
150
145
  });
@@ -163,7 +158,10 @@ const TextareaAutosize = forwardRef((_a, ref) => {
163
158
  return (React.createElement(React.Fragment, null,
164
159
  React.createElement("textarea", Object.assign({ value: value, onChange: handleChange, ref: handleRef,
165
160
  // Apply the rows prop to get a "correct" first SSR paint
166
- rows: minRows, style: Object.assign(Object.assign({ height: state.outerHeightStyle }, (state.overflow ? { overflow: "hidden" } : {})), style) }, other, { className: className })),
161
+ rows: minRows, style: Object.assign({ height: state.outerHeightStyle,
162
+ // Need a large enough difference to allow scrolling.
163
+ // This prevents infinite rendering loop.
164
+ overflow: state.overflow && !autoScrollbar ? "hidden" : undefined }, style) }, other, { className: className })),
167
165
  React.createElement("textarea", { "aria-hidden": true, className: className, readOnly: true, ref: shadowRef, tabIndex: -1, style: Object.assign({
168
166
  // Visibility needed to hide the extra text area on iPads
169
167
  visibility: "hidden",
@@ -178,7 +176,7 @@ function isEmpty(obj) {
178
176
  return (obj === undefined ||
179
177
  obj === null ||
180
178
  Object.keys(obj).length === 0 ||
181
- ((obj === null || obj === void 0 ? void 0 : obj.outerHeightStyle) === 0 && !(obj === null || obj === void 0 ? void 0 : obj.overflow)));
179
+ (obj.outerHeightStyle === 0 && !obj.overflow));
182
180
  }
183
181
  export default TextareaAutosize;
184
182
  //# sourceMappingURL=TextareaAutoSize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextareaAutoSize.js","sourceRoot":"","sources":["../../src/util/TextareaAutoSize.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TextareaAutoSize.js","sourceRoot":"","sources":["../../src/util/TextareaAutoSize.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navikt/ds-react",
3
- "version": "5.10.4",
3
+ "version": "5.11.1",
4
4
  "description": "Aksel react-components for NAV designsystem",
5
5
  "author": "Aksel | NAV designsystem team",
6
6
  "license": "MIT",
@@ -38,8 +38,8 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@floating-ui/react": "0.25.4",
41
- "@navikt/aksel-icons": "^5.10.4",
42
- "@navikt/ds-tokens": "^5.10.4",
41
+ "@navikt/aksel-icons": "^5.11.1",
42
+ "@navikt/ds-tokens": "^5.11.1",
43
43
  "@radix-ui/react-tabs": "1.0.0",
44
44
  "@radix-ui/react-toggle-group": "1.0.0",
45
45
  "clsx": "^1.2.1",
@@ -5,11 +5,11 @@ import React, {
5
5
  useEffect,
6
6
  useState,
7
7
  } from "react";
8
- import { FormFieldProps, useFormField } from "./useFormField";
9
- import { ReadOnlyIcon } from "./ReadOnlyIcon";
10
8
  import { Loader } from "../loader";
11
9
  import { BodyShort } from "../typography";
12
10
  import { omit } from "../util";
11
+ import { ReadOnlyIcon } from "./ReadOnlyIcon";
12
+ import { FormFieldProps, useFormField } from "./useFormField";
13
13
 
14
14
  const SelectedIcon = () => (
15
15
  <svg
@@ -134,7 +134,11 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
134
134
  <span className="navds-switch__track">
135
135
  <span className="navds-switch__thumb">
136
136
  {loading ? (
137
- <Loader size="xsmall" aria-live="polite" />
137
+ <Loader
138
+ size="xsmall"
139
+ aria-live="polite"
140
+ variant={checked ? "interaction" : "neutral"}
141
+ />
138
142
  ) : checked ? (
139
143
  <SelectedIcon />
140
144
  ) : null}
@@ -45,7 +45,13 @@ export interface TextareaProps
45
45
  /**
46
46
  * Enables resizing of field
47
47
  */
48
- resize?: boolean;
48
+ resize?: boolean | "vertical" | "horizontal";
49
+ /**
50
+ * Textarea will stop growing and get a scrollbar when there's no more room to grow.
51
+ * Requires `display:flex` on the parent.
52
+ * Experimental feature that may be removed or get breaking changes in a minor version.
53
+ */
54
+ UNSAFE_autoScrollbar?: boolean;
49
55
  /**
50
56
  * i18n-translations for counter-text
51
57
  */
@@ -86,6 +92,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
86
92
  maxLength,
87
93
  hideLabel = false,
88
94
  resize,
95
+ UNSAFE_autoScrollbar,
89
96
  i18n,
90
97
  readOnly,
91
98
  ...rest
@@ -121,7 +128,9 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
121
128
  "navds-form-field--readonly": readOnly,
122
129
  "navds-textarea--readonly": readOnly,
123
130
  "navds-textarea--error": hasError,
124
- "navds-textarea--resize": resize,
131
+ "navds-textarea--autoscrollbar": UNSAFE_autoScrollbar,
132
+ [`navds-textarea--resize-${resize === true ? "both" : resize}`]:
133
+ resize,
125
134
  }
126
135
  )}
127
136
  >
@@ -157,6 +166,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
157
166
  : setControlledValue(e.target.value)
158
167
  }
159
168
  minRows={getMinRows()}
169
+ autoScrollbar={UNSAFE_autoScrollbar}
160
170
  ref={ref}
161
171
  readOnly={readOnly}
162
172
  className={cl(
@@ -1,6 +1,7 @@
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
  import type { TextareaProps } from "./Textarea";
5
6
 
6
7
  interface Props {
@@ -13,19 +14,45 @@ interface Props {
13
14
  const TextareaCounter = ({ maxLength, currentLength, size, i18n }: Props) => {
14
15
  const difference = maxLength - currentLength;
15
16
 
17
+ const [debouncedDiff, setDebouncedDiff] = useState(difference);
18
+
19
+ useEffect(() => {
20
+ const debounceFunc = debounce(() => {
21
+ setDebouncedDiff(difference);
22
+ }, 2000);
23
+ debounceFunc();
24
+
25
+ return () => {
26
+ debounceFunc.clear();
27
+ };
28
+ }, [difference]);
29
+
16
30
  return (
17
- <BodyShort
18
- className={cl("navds-textarea__counter", {
19
- "navds-textarea__counter--error": difference < 0,
20
- })}
21
- role={difference < 20 ? "status" : undefined}
22
- size={size}
23
- >
24
- {difference < 0
25
- ? `${Math.abs(difference)} ${i18n?.counterTooMuch ?? "tegn for mye"}`
26
- : `${difference} ${i18n?.counterLeft ?? "tegn igjen"}`}
27
- </BodyShort>
31
+ <>
32
+ {difference < 20 && (
33
+ <span
34
+ role="status"
35
+ className="navds-textarea__sr-counter navds-sr-only"
36
+ >
37
+ {getCounterText(debouncedDiff, i18n)}
38
+ </span>
39
+ )}
40
+
41
+ <BodyShort
42
+ className={cl("navds-textarea__counter", {
43
+ "navds-textarea__counter--error": difference < 0,
44
+ })}
45
+ size={size}
46
+ >
47
+ {getCounterText(difference, i18n)}
48
+ </BodyShort>
49
+ </>
28
50
  );
29
51
  };
30
52
 
53
+ const getCounterText = (difference: number, i18n: TextareaProps["i18n"]) =>
54
+ difference < 0
55
+ ? `${Math.abs(difference)} ${i18n?.counterTooMuch ?? "tegn for mye"}`
56
+ : `${difference} ${i18n?.counterLeft ?? "tegn igjen"}`;
57
+
31
58
  export default TextareaCounter;
@@ -1,5 +1,6 @@
1
1
  import { Meta, StoryObj } from "@storybook/react";
2
2
  import React from "react";
3
+ import { Button } from "../../button";
3
4
  import { Textarea } from "../index";
4
5
 
5
6
  const meta: Meta<typeof Textarea> = {
@@ -16,10 +17,13 @@ export const Default: StoryObj<typeof Textarea> = {
16
17
  args: {
17
18
  maxLength: 0,
18
19
  label: "Ipsum enim quis culpa",
19
- resize: false,
20
20
  },
21
21
 
22
22
  argTypes: {
23
+ resize: {
24
+ control: { type: "radio" },
25
+ options: [true, "vertical", "horizontal"],
26
+ },
23
27
  size: {
24
28
  control: { type: "radio" },
25
29
  options: ["medium", "small"],
@@ -99,7 +103,7 @@ export const HideLabel = () => {
99
103
  };
100
104
 
101
105
  export const MaxLength = () => {
102
- return <Textarea maxLength={200} label="Ipsum enim quis culpa" />;
106
+ return <Textarea maxLength={50} label="Ipsum enim quis culpa" />;
103
107
  };
104
108
 
105
109
  export const MinRows = () => {
@@ -138,3 +142,35 @@ export const Readonly = () => {
138
142
  </div>
139
143
  );
140
144
  };
145
+
146
+ export const AutoScrollbar = (props) => (
147
+ <div
148
+ style={{
149
+ border: "1px solid lightGreen",
150
+ height: "90vh",
151
+ display: "flex",
152
+ flexDirection: "column",
153
+ }}
154
+ >
155
+ <div style={{ border: "1px dashed gray" }}>
156
+ <h1>Header</h1>
157
+ </div>
158
+ <Textarea
159
+ resize
160
+ label="Textarea with autoScrollbar"
161
+ description="Description"
162
+ maxLength={30}
163
+ UNSAFE_autoScrollbar
164
+ {...props}
165
+ />
166
+ <div style={{ border: "1px dashed gray" }}>
167
+ <Button>Send</Button>
168
+ </div>
169
+ </div>
170
+ );
171
+ AutoScrollbar.argTypes = {
172
+ error: { type: "string" },
173
+ hideLabel: { type: "boolean" },
174
+ maxRows: { type: "number" },
175
+ minRows: { type: "number" },
176
+ };