@kaizen/components 1.67.3 → 1.67.5

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.
@@ -3,6 +3,10 @@ import { OverrideClassName } from "../types/OverrideClassName";
3
3
  export type TextAreaProps = {
4
4
  textAreaRef?: React.RefObject<HTMLTextAreaElement>;
5
5
  status?: "default" | "error" | "caution";
6
+ /**
7
+ * Grows the input height as more content is added
8
+ * Replace with CSS field-sizing once it's supported by all major browsers
9
+ */
6
10
  autogrow?: boolean;
7
11
  reversed?: boolean;
8
12
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaizen/components",
3
- "version": "1.67.3",
3
+ "version": "1.67.5",
4
4
  "description": "Kaizen component library",
5
5
  "author": "Geoffrey Chong <geoff.chong@cultureamp.com>",
6
6
  "homepage": "https://cultureamp.design",
@@ -58,7 +58,7 @@
58
58
  "date-fns": "^4.1.0",
59
59
  "lodash.debounce": "^4.0.8",
60
60
  "nanobus": "^4.5.0",
61
- "prosemirror-commands": "^1.6.1",
61
+ "prosemirror-commands": "^1.6.2",
62
62
  "prosemirror-history": "^1.4.1",
63
63
  "prosemirror-inputrules": "^1.4.0",
64
64
  "prosemirror-keymap": "^1.2.2",
@@ -77,7 +77,7 @@
77
77
  "react-focus-on": "^3.9.4",
78
78
  "react-media": "^1.10.0",
79
79
  "react-popper": "^2.3.0",
80
- "react-select": "^5.8.1",
80
+ "react-select": "^5.8.2",
81
81
  "react-textfit": "^1.1.1",
82
82
  "resize-observer-polyfill": "^1.5.1",
83
83
  "tsx": "^4.19.1",
@@ -89,8 +89,8 @@
89
89
  },
90
90
  "devDependencies": {
91
91
  "@cultureamp/frontend-apis": "^10.0.0",
92
- "@cultureamp/i18n-react-intl": "^2.6.3",
93
- "@tanstack/react-query": "^5.59.13",
92
+ "@cultureamp/i18n-react-intl": "^2.7.1",
93
+ "@tanstack/react-query": "^5.59.16",
94
94
  "@testing-library/dom": "^10.4.0",
95
95
  "@types/jest-axe": "^3.5.9",
96
96
  "@types/lodash.debounce": "^4.0.9",
@@ -112,15 +112,15 @@
112
112
  "react": "^18.3.1",
113
113
  "react-dom": "^18.3.1",
114
114
  "react-highlight": "^0.15.0",
115
- "react-intl": "^6.8.0",
116
- "rollup": "^4.24.0",
115
+ "react-intl": "^6.8.4",
116
+ "rollup": "^4.24.2",
117
117
  "sass": "^1.77.8",
118
118
  "serialize-query-params": "^2.0.2",
119
119
  "svgo": "^3.3.2",
120
120
  "tslib": "^2.7.0",
121
121
  "tsx": "^4.19.1",
122
122
  "@kaizen/design-tokens": "10.8.0",
123
- "@kaizen/package-bundler": "1.1.7"
123
+ "@kaizen/package-bundler": "1.1.8"
124
124
  },
125
125
  "peerDependencies": {
126
126
  "@cultureamp/i18n-react-intl": "^2.5.9",
@@ -0,0 +1,142 @@
1
+ .wrapper {
2
+ font-family: var(--typography-paragraph-body-font-family);
3
+ font-size: var(--typography-paragraph-body-font-size);
4
+ font-weight: var(--typography-paragraph-body-font-weight);
5
+ line-height: var(--typography-paragraph-body-line-height);
6
+ letter-spacing: var(--typography-paragraph-body-letter-spacing);
7
+ color: var(--color-purple-800-rgb);
8
+ }
9
+
10
+ .wrapperAutogrow {
11
+ display: grid;
12
+ }
13
+
14
+ .wrapperAutogrow::after {
15
+ content: attr(data-value) " ";
16
+ white-space: pre-wrap;
17
+ visibility: hidden;
18
+ }
19
+
20
+ /* these properties need to be set on both for autogrow to work properly */
21
+ .textarea,
22
+ .wrapperAutogrow::after {
23
+ border: var(--border-solid-border-width) var(--border-solid-border-style)
24
+ var(--color-gray-500);
25
+ border-radius: var(--border-solid-border-radius);
26
+ padding: var(--spacing-sm);
27
+ box-sizing: border-box;
28
+ width: 100%;
29
+ font: inherit;
30
+ }
31
+
32
+ .textareaAutogrow,
33
+ .wrapperAutogrow::after {
34
+ grid-area: 2 / 1;
35
+ }
36
+
37
+ .textarea {
38
+ display: block;
39
+ border: var(--border-solid-border-width) var(--border-solid-border-style)
40
+ var(--color-gray-500);
41
+ border-radius: var(--border-solid-border-radius);
42
+ padding: var(--spacing-sm);
43
+ resize: vertical;
44
+
45
+ &:focus {
46
+ outline: var(--border-focus-ring-border-width)
47
+ var(--border-focus-ring-border-style) var(--color-blue-500);
48
+ outline-offset: 1px;
49
+ }
50
+
51
+ &:disabled {
52
+ resize: none;
53
+ }
54
+ }
55
+
56
+ .textareaAutogrow {
57
+ overflow: hidden;
58
+ }
59
+
60
+ .default {
61
+ &:not(.error, .caution) {
62
+ &:disabled {
63
+ border-color: rgba(var(--color-gray-500-rgb), 0.3);
64
+ }
65
+ }
66
+
67
+ &:focus:not([disabled]),
68
+ &:hover:not([disabled]),
69
+ &:hover:focus:not([disabled]) {
70
+ background-color: var(--color-gray-200);
71
+ border-color: var(--color-gray-600);
72
+ }
73
+
74
+ &.error {
75
+ border-color: var(--color-red-500);
76
+
77
+ &:focus:not([disabled]),
78
+ &:hover:not([disabled]),
79
+ &:hover:focus:not([disabled]) {
80
+ border-color: var(--color-red-500);
81
+ }
82
+ }
83
+
84
+ &.caution {
85
+ border-color: var(--color-yellow-600);
86
+
87
+ &:focus:not([disabled]),
88
+ &:hover:not([disabled]),
89
+ &:hover:focus:not([disabled]) {
90
+ border-color: var(--color-yellow-600);
91
+ }
92
+ }
93
+
94
+ &.disabled {
95
+ background-color: var(--color-white);
96
+ border-color: rgba(var(--color-gray-500-rgb), 0.3);
97
+ color: rgba(var(--color-purple-800-rgb), 0.3);
98
+ }
99
+ }
100
+
101
+ .reversed {
102
+ border-color: rgba(var(--color-white-rgb), 0.65);
103
+ background: transparent;
104
+ color: var(--color-white);
105
+
106
+ &:focus {
107
+ outline-color: var(--color-blue-300);
108
+ }
109
+
110
+ &:focus:not([disabled]),
111
+ &:hover:not([disabled]),
112
+ &:hover:focus:not([disabled]) {
113
+ background: rgba(var(--color-white-rgb), 0.1);
114
+ border-color: var(--color-white);
115
+ }
116
+
117
+ &.error {
118
+ border-color: var(--color-red-300);
119
+
120
+ &:focus:not([disabled]),
121
+ &:hover:not([disabled]),
122
+ &:hover:focus:not([disabled]) {
123
+ border-color: var(--color-red-300);
124
+ }
125
+ }
126
+
127
+ &.caution {
128
+ border-color: var(--color-yellow-400);
129
+
130
+ &:focus:not([disabled]),
131
+ &:hover:not([disabled]),
132
+ &:hover:focus:not([disabled]) {
133
+ border-color: var(--color-yellow-400);
134
+ }
135
+ }
136
+
137
+ &.disabled {
138
+ background: transparent;
139
+ border-color: rgba(var(--color-white-rgb), 0.3);
140
+ color: rgba(var(--color-white-rgb), 0.3);
141
+ }
142
+ }
@@ -1,16 +1,15 @@
1
- import React, {
2
- TextareaHTMLAttributes,
3
- useEffect,
4
- useRef,
5
- useState,
6
- } from "react"
1
+ import React, { TextareaHTMLAttributes, useRef, useState } from "react"
7
2
  import classnames from "classnames"
8
3
  import { OverrideClassName } from "~components/types/OverrideClassName"
9
- import styles from "./TextArea.module.scss"
4
+ import styles from "./TextArea.module.css"
10
5
 
11
6
  export type TextAreaProps = {
12
7
  textAreaRef?: React.RefObject<HTMLTextAreaElement>
13
8
  status?: "default" | "error" | "caution"
9
+ /**
10
+ * Grows the input height as more content is added
11
+ * Replace with CSS field-sizing once it's supported by all major browsers
12
+ */
14
13
  autogrow?: boolean
15
14
  reversed?: boolean
16
15
  /**
@@ -32,73 +31,46 @@ export const TextArea = ({
32
31
  onChange: propsOnChange,
33
32
  ...restProps
34
33
  }: TextAreaProps): JSX.Element => {
35
- const [textAreaHeight, setTextAreaHeight] = useState<string>("auto")
36
- const [parentHeight, setParentHeight] = useState<string>("auto")
37
34
  const [internalValue, setInternalValue] = useState<
38
35
  string | number | readonly string[] | undefined
39
- >(autogrow ? defaultValue : undefined)
36
+ >(autogrow && !value ? defaultValue : undefined)
40
37
  // ^ holds an internal state of the value so that autogrow can still work with uncontrolled textareas
41
- // essentially forces the textarea into an (interally) controlled mode if autogrow is true
42
- const textAreaRef = propsTextAreaRef || useRef(null)
43
-
44
- useEffect(() => {
45
- if (!autogrow) return
46
-
47
- const scrollHeight = textAreaRef.current!.scrollHeight
48
- if (scrollHeight < 1) return
49
-
50
- const borderWidth = textAreaRef.current
51
- ? parseInt(getComputedStyle(textAreaRef.current).borderTopWidth, 10)
52
- : 0
53
- const newHeight = scrollHeight + borderWidth * 2
54
- setParentHeight(`${newHeight}px`)
55
- setTextAreaHeight(`${newHeight}px`)
56
- }, [internalValue])
57
-
58
- const onChange = !autogrow
59
- ? undefined
60
- : (event: React.ChangeEvent<HTMLTextAreaElement>): void => {
61
- setTextAreaHeight("auto")
62
- // ^ this is required to avoid the textarea height from building up indefinitely
63
- // see https://medium.com/@lucasalgus/creating-a-custom-auto-resize-textarea-component-for-your-react-web-application-6959c0ad68bc#2dee
64
-
65
- setInternalValue(event.target.value)
66
- if (propsOnChange) {
67
- propsOnChange(event)
68
- }
69
- }
70
-
71
- const getWrapperStyle = (): { minHeight: string } | undefined =>
72
- autogrow ? { minHeight: parentHeight } : undefined
73
-
74
- const getTextAreaStyle = (): { height: string } | undefined =>
75
- autogrow ? { height: textAreaHeight } : undefined
38
+ // essentially forces the textarea into an (interally) controlled mode if autogrow is true and mode is uncontrolled
76
39
 
77
40
  const controlledValue = value || internalValue
41
+ const textAreaRef = propsTextAreaRef || useRef(null)
42
+
43
+ const onChange = (event: React.ChangeEvent<HTMLTextAreaElement>): void => {
44
+ propsOnChange && propsOnChange(event)
45
+ setInternalValue(event.target.value)
46
+ }
78
47
 
79
48
  return (
80
- <div className={styles.wrapper} style={getWrapperStyle()}>
49
+ <div
50
+ className={classnames(styles.wrapper, {
51
+ [styles.wrapperAutogrow]: autogrow,
52
+ })}
53
+ data-value={autogrow ? controlledValue : undefined}
54
+ >
81
55
  <textarea
82
56
  className={classnames(
83
57
  styles.textarea,
84
58
  styles[status],
85
59
  reversed ? styles.reversed : styles.default,
86
- disabled && styles.disabled
60
+ {
61
+ [styles.disabled]: disabled,
62
+ [styles.textareaAutogrow]: autogrow,
63
+ }
87
64
  )}
88
65
  rows={rows}
89
- onChange={onChange || propsOnChange}
66
+ onChange={onChange}
90
67
  value={controlledValue}
91
68
  defaultValue={controlledValue ? undefined : defaultValue}
92
69
  // ^ React throws a warning if you specify both a value and a defaultValue
93
70
  ref={textAreaRef}
94
- style={getTextAreaStyle()}
95
71
  disabled={disabled}
96
72
  {...restProps}
97
73
  />
98
-
99
- {/* Textareas aren't able to have pseudo elements like ::after on them,
100
- so we have to create an element ourselves for the focus ring */}
101
- <div className={styles.focusRing} />
102
74
  </div>
103
75
  )
104
76
  }
@@ -21,8 +21,8 @@ Add the following (CDN for the variable icon font) to your Storybook `preview-he
21
21
 
22
22
  ```html
23
23
  <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
24
- <link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,400,0..1,0" />
25
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,400,0..1,0" />
24
+ <link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,400,0..1,0&display=block" />
25
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,400,0..1,0&display=block" />
26
26
  ```
27
27
 
28
28
  ## Overview
@@ -1,13 +0,0 @@
1
- 'use strict';
2
-
3
- var styles = {
4
- "wrapper": "TextArea-module_wrapper__ytS6M",
5
- "textarea": "TextArea-module_textarea__GeHn4",
6
- "focusRing": "TextArea-module_focusRing__kECqH",
7
- "default": "TextArea-module_default__Z8jvR",
8
- "error": "TextArea-module_error__XOQRm",
9
- "caution": "TextArea-module_caution__9BGd0",
10
- "disabled": "TextArea-module_disabled__N09tP",
11
- "reversed": "TextArea-module_reversed__-SoNq"
12
- };
13
- module.exports = styles;
@@ -1,11 +0,0 @@
1
- var styles = {
2
- "wrapper": "TextArea-module_wrapper__ytS6M",
3
- "textarea": "TextArea-module_textarea__GeHn4",
4
- "focusRing": "TextArea-module_focusRing__kECqH",
5
- "default": "TextArea-module_default__Z8jvR",
6
- "error": "TextArea-module_error__XOQRm",
7
- "caution": "TextArea-module_caution__9BGd0",
8
- "disabled": "TextArea-module_disabled__N09tP",
9
- "reversed": "TextArea-module_reversed__-SoNq"
10
- };
11
- export { styles as default };
@@ -1,137 +0,0 @@
1
- @import "~@kaizen/design-tokens/sass/spacing";
2
- @import "~@kaizen/design-tokens/sass/color";
3
- @import "~@kaizen/design-tokens/sass/border";
4
- @import "../../styles/utils/forms";
5
- @import "../../styles/utils/form-variables";
6
-
7
- // Vars
8
- $input-disabled-opacity: 0.3;
9
- $input-disabled-border-alpha: 50%;
10
-
11
- .wrapper {
12
- position: relative;
13
- }
14
-
15
- .textarea {
16
- @include form-input-reset;
17
-
18
- border-radius: $border-solid-border-radius;
19
- width: 100%;
20
- border: $border-solid-border-width $border-solid-border-style $color-gray-500;
21
- padding: $spacing-sm;
22
- color: $color-purple-800-rgb;
23
- display: block;
24
- resize: vertical;
25
-
26
- @include form-input-placeholder {
27
- line-height: 1.5;
28
- color: $dt-color-form-text-color-placeholder;
29
- }
30
-
31
- &:disabled {
32
- resize: none;
33
- }
34
- }
35
-
36
- .textarea:focus + .focusRing {
37
- $focus-ring-offset: 3px;
38
-
39
- position: absolute;
40
- background: transparent;
41
- border-radius: $border-focus-ring-border-radius;
42
- border-width: $border-focus-ring-border-width;
43
- border-style: $border-focus-ring-border-style;
44
- border-color: transparent;
45
- inset: -$focus-ring-offset;
46
- pointer-events: none;
47
- }
48
-
49
- .textarea.default {
50
- @include form-input-focus-state {
51
- background-color: $color-gray-200;
52
- border-color: $color-gray-600;
53
- }
54
-
55
- &:focus + .focusRing {
56
- border-color: $color-blue-500;
57
- }
58
-
59
- &:not(.error, .caution) {
60
- &:disabled {
61
- border-color: rgba($color-gray-500-rgb, $input-disabled-opacity);
62
- }
63
- }
64
-
65
- &.error {
66
- border-color: $color-red-500;
67
-
68
- @include form-input-focus-state {
69
- border-color: $color-red-500;
70
- }
71
- }
72
-
73
- &.caution {
74
- border-color: $color-yellow-600;
75
-
76
- @include form-input-focus-state {
77
- border-color: $color-yellow-600;
78
- }
79
- }
80
-
81
- &.disabled {
82
- background-color: $color-white;
83
- border-color: rgba($color-gray-500-rgb, $input-disabled-opacity);
84
- color: rgba($color-purple-800-rgb, $input-disabled-opacity);
85
-
86
- @include form-input-placeholder {
87
- opacity: $input-disabled-opacity;
88
- }
89
- }
90
- }
91
-
92
- // Reversed (Dark Backgrounds)
93
- .textarea.reversed {
94
- border-color: rgba($color-white-rgb, 0.65);
95
- background: transparent;
96
- color: $color-white;
97
-
98
- @include form-input-focus-state {
99
- background: rgba($color-white-rgb, 0.1);
100
- border-color: $color-white;
101
- }
102
-
103
- @include form-input-placeholder {
104
- line-height: 1.5;
105
- color: $color-white;
106
- }
107
-
108
- &:focus + .focusRing {
109
- border-color: $color-blue-300;
110
- }
111
-
112
- &.error {
113
- border-color: $color-red-300;
114
-
115
- @include form-input-focus-state {
116
- border-color: $color-red-300;
117
- }
118
- }
119
-
120
- &.caution {
121
- border-color: $color-yellow-400;
122
-
123
- @include form-input-focus-state {
124
- border-color: $color-yellow-400;
125
- }
126
- }
127
-
128
- &.disabled {
129
- background: transparent;
130
- border-color: rgba($color-white-rgb, $input-disabled-opacity);
131
- color: rgba($color-white-rgb, $input-disabled-opacity);
132
-
133
- @include form-input-placeholder {
134
- opacity: $input-disabled-opacity;
135
- }
136
- }
137
- }