@justeattakeaway/pie-textarea 0.3.0 → 0.4.0
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 +5 -4
- package/custom-elements.json +45 -13
- package/dist/index.d.ts +18 -4
- package/dist/index.js +142 -32
- package/dist/react.d.ts +18 -4
- package/dist/react.js +5 -5
- package/package.json +4 -2
- package/src/defs.ts +12 -2
- package/src/index.ts +40 -9
- package/src/textarea.scss +76 -9
package/README.md
CHANGED
|
@@ -72,10 +72,11 @@ import { PieTextarea } from '@justeattakeaway/pie-textarea/dist/react';
|
|
|
72
72
|
|
|
73
73
|
## Props
|
|
74
74
|
|
|
75
|
-
| Property
|
|
76
|
-
|
|
77
|
-
| `disabled` | `boolean`
|
|
78
|
-
| `size`
|
|
75
|
+
| Property | Type | Default | Description |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| `disabled` | `boolean` | `false` | Indicates whether or not the textarea is disabled. |
|
|
78
|
+
| `size` | `"small"`, `"medium"`, `"large"` | `"medium"` | The size of the textarea field. |
|
|
79
|
+
| `resize` | `"auto"`, `"manual"` | `"auto"` | Controls the resizing behaviour of the textarea. |
|
|
79
80
|
|
|
80
81
|
In your markup or JSX, you can then use these to set the properties for the `pie-textarea` component:
|
|
81
82
|
|
package/custom-elements.json
CHANGED
|
@@ -20,13 +20,21 @@
|
|
|
20
20
|
},
|
|
21
21
|
"default": "['small', 'medium', 'large']"
|
|
22
22
|
},
|
|
23
|
+
{
|
|
24
|
+
"kind": "variable",
|
|
25
|
+
"name": "resizeModes",
|
|
26
|
+
"type": {
|
|
27
|
+
"text": "['auto', 'manual']"
|
|
28
|
+
},
|
|
29
|
+
"default": "['auto', 'manual']"
|
|
30
|
+
},
|
|
23
31
|
{
|
|
24
32
|
"kind": "variable",
|
|
25
33
|
"name": "defaultProps",
|
|
26
34
|
"type": {
|
|
27
35
|
"text": "DefaultProps"
|
|
28
36
|
},
|
|
29
|
-
"default": "{\n size: 'medium',\n}",
|
|
37
|
+
"default": "{\n disabled: false,\n size: 'medium',\n resize: 'auto',\n}",
|
|
30
38
|
"description": "Default values for optional properties that have default fallback values in the component."
|
|
31
39
|
}
|
|
32
40
|
],
|
|
@@ -39,6 +47,14 @@
|
|
|
39
47
|
"module": "src/defs.js"
|
|
40
48
|
}
|
|
41
49
|
},
|
|
50
|
+
{
|
|
51
|
+
"kind": "js",
|
|
52
|
+
"name": "resizeModes",
|
|
53
|
+
"declaration": {
|
|
54
|
+
"name": "resizeModes",
|
|
55
|
+
"module": "src/defs.js"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
42
58
|
{
|
|
43
59
|
"kind": "js",
|
|
44
60
|
"name": "defaultProps",
|
|
@@ -70,9 +86,6 @@
|
|
|
70
86
|
{
|
|
71
87
|
"kind": "field",
|
|
72
88
|
"name": "disabled",
|
|
73
|
-
"type": {
|
|
74
|
-
"text": "TextareaProps['disabled'] | undefined"
|
|
75
|
-
},
|
|
76
89
|
"privacy": "public",
|
|
77
90
|
"attribute": "disabled",
|
|
78
91
|
"reflects": true
|
|
@@ -80,27 +93,46 @@
|
|
|
80
93
|
{
|
|
81
94
|
"kind": "field",
|
|
82
95
|
"name": "size",
|
|
83
|
-
"type": {
|
|
84
|
-
"text": "TextareaProps['size'] | undefined"
|
|
85
|
-
},
|
|
86
96
|
"privacy": "public",
|
|
87
97
|
"attribute": "size"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"kind": "field",
|
|
101
|
+
"name": "resize",
|
|
102
|
+
"privacy": "public",
|
|
103
|
+
"attribute": "resize"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"kind": "field",
|
|
107
|
+
"name": "_textarea",
|
|
108
|
+
"type": {
|
|
109
|
+
"text": "HTMLTextAreaElement"
|
|
110
|
+
},
|
|
111
|
+
"privacy": "private"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"kind": "field",
|
|
115
|
+
"name": "_throttledResize",
|
|
116
|
+
"privacy": "private"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"kind": "method",
|
|
120
|
+
"name": "handleResize",
|
|
121
|
+
"privacy": "private"
|
|
88
122
|
}
|
|
89
123
|
],
|
|
90
124
|
"attributes": [
|
|
91
125
|
{
|
|
92
126
|
"name": "disabled",
|
|
93
|
-
"type": {
|
|
94
|
-
"text": "TextareaProps['disabled'] | undefined"
|
|
95
|
-
},
|
|
96
127
|
"fieldName": "disabled"
|
|
97
128
|
},
|
|
98
129
|
{
|
|
99
130
|
"name": "size",
|
|
100
|
-
"type": {
|
|
101
|
-
"text": "TextareaProps['size'] | undefined"
|
|
102
|
-
},
|
|
103
131
|
"fieldName": "size"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"name": "resize",
|
|
135
|
+
"fieldName": "resize"
|
|
104
136
|
}
|
|
105
137
|
],
|
|
106
138
|
"mixins": [
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';
|
|
2
2
|
import type { CSSResult } from 'lit';
|
|
3
3
|
import type { GenericConstructor } from '@justeattakeaway/pie-webc-core';
|
|
4
4
|
import type { LitElement } from 'lit';
|
|
5
|
+
import type { PropertyValues } from 'lit';
|
|
5
6
|
import type { RTLInterface } from '@justeattakeaway/pie-webc-core';
|
|
6
7
|
import type { TemplateResult } from 'lit-html';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* The default values for the `TextareaProps` that are required (i.e. they have a fallback value in the component).
|
|
10
11
|
*/
|
|
11
|
-
declare type DefaultProps =
|
|
12
|
+
declare type DefaultProps = ComponentDefaultProps<TextareaProps>;
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Default values for optional properties that have default fallback values in the component.
|
|
@@ -24,14 +25,21 @@ export declare class PieTextarea extends PieTextarea_base implements TextareaPro
|
|
|
24
25
|
mode: ShadowRootMode;
|
|
25
26
|
slotAssignment?: SlotAssignmentMode | undefined;
|
|
26
27
|
};
|
|
27
|
-
disabled
|
|
28
|
-
size
|
|
28
|
+
disabled: boolean;
|
|
29
|
+
size: "small" | "medium" | "large";
|
|
30
|
+
resize: "auto" | "manual";
|
|
31
|
+
private _textarea;
|
|
32
|
+
private _throttledResize;
|
|
33
|
+
private handleResize;
|
|
34
|
+
updated(changedProperties: PropertyValues<this>): void;
|
|
29
35
|
render(): TemplateResult<1>;
|
|
30
36
|
static styles: CSSResult;
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
declare const PieTextarea_base: GenericConstructor<RTLInterface> & typeof LitElement;
|
|
34
40
|
|
|
41
|
+
export declare const resizeModes: readonly ["auto", "manual"];
|
|
42
|
+
|
|
35
43
|
export declare const sizes: readonly ["small", "medium", "large"];
|
|
36
44
|
|
|
37
45
|
export declare interface TextareaProps {
|
|
@@ -43,6 +51,12 @@ export declare interface TextareaProps {
|
|
|
43
51
|
* The size of the textarea field. Can be `small`, `medium` or `large`. Defaults to `medium`.
|
|
44
52
|
*/
|
|
45
53
|
size?: typeof sizes[number];
|
|
54
|
+
/**
|
|
55
|
+
* The resize mode of the textarea. Can be `auto` or `manual`. Defaults to `auto`.
|
|
56
|
+
* When set to `auto`, the textarea will resize vertically as needed.
|
|
57
|
+
* When set to `manual`, the textarea will not resize automatically but can be resized by the user.
|
|
58
|
+
*/
|
|
59
|
+
resize?: typeof resizeModes[number];
|
|
46
60
|
}
|
|
47
61
|
|
|
48
62
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,50 +1,160 @@
|
|
|
1
|
-
import { LitElement as
|
|
2
|
-
import { property as
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { LitElement as $, html as B, unsafeCSS as D } from "lit";
|
|
2
|
+
import { property as O, query as N } from "lit/decorators.js";
|
|
3
|
+
import { RtlMixin as A, validPropertyValues as w, defineCustomElement as G } from "@justeattakeaway/pie-webc-core";
|
|
4
|
+
var b = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
|
|
5
|
+
function H(e) {
|
|
6
|
+
return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
|
|
7
|
+
}
|
|
8
|
+
var P = "Expected a function", I = 0 / 0, q = "[object Symbol]", U = /^\s+|\s+$/g, V = /^[-+]0x[0-9a-f]+$/i, X = /^0b[01]+$/i, J = /^0o[0-7]+$/i, K = parseInt, Q = typeof b == "object" && b && b.Object === Object && b, Y = typeof self == "object" && self && self.Object === Object && self, Z = Q || Y || Function("return this")(), ee = Object.prototype, te = ee.toString, re = Math.max, ae = Math.min, j = function() {
|
|
9
|
+
return Z.Date.now();
|
|
10
|
+
};
|
|
11
|
+
function ie(e, t, r) {
|
|
12
|
+
var i, n, s, d, o, c, p = 0, _ = !1, u = !1, y = !0;
|
|
13
|
+
if (typeof e != "function")
|
|
14
|
+
throw new TypeError(P);
|
|
15
|
+
t = R(t) || 0, v(r) && (_ = !!r.leading, u = "maxWait" in r, s = u ? re(R(r.maxWait) || 0, t) : s, y = "trailing" in r ? !!r.trailing : y);
|
|
16
|
+
function z(a) {
|
|
17
|
+
var l = i, h = n;
|
|
18
|
+
return i = n = void 0, p = a, d = e.apply(h, l), d;
|
|
19
|
+
}
|
|
20
|
+
function C(a) {
|
|
21
|
+
return p = a, o = setTimeout(g, t), _ ? z(a) : d;
|
|
22
|
+
}
|
|
23
|
+
function M(a) {
|
|
24
|
+
var l = a - c, h = a - p, E = t - l;
|
|
25
|
+
return u ? ae(E, s - h) : E;
|
|
26
|
+
}
|
|
27
|
+
function W(a) {
|
|
28
|
+
var l = a - c, h = a - p;
|
|
29
|
+
return c === void 0 || l >= t || l < 0 || u && h >= s;
|
|
30
|
+
}
|
|
31
|
+
function g() {
|
|
32
|
+
var a = j();
|
|
33
|
+
if (W(a))
|
|
34
|
+
return S(a);
|
|
35
|
+
o = setTimeout(g, M(a));
|
|
36
|
+
}
|
|
37
|
+
function S(a) {
|
|
38
|
+
return o = void 0, y && i ? z(a) : (i = n = void 0, d);
|
|
39
|
+
}
|
|
40
|
+
function L() {
|
|
41
|
+
o !== void 0 && clearTimeout(o), p = 0, i = c = n = o = void 0;
|
|
42
|
+
}
|
|
43
|
+
function F() {
|
|
44
|
+
return o === void 0 ? d : S(j());
|
|
45
|
+
}
|
|
46
|
+
function k() {
|
|
47
|
+
var a = j(), l = W(a);
|
|
48
|
+
if (i = arguments, n = this, c = a, l) {
|
|
49
|
+
if (o === void 0)
|
|
50
|
+
return C(c);
|
|
51
|
+
if (u)
|
|
52
|
+
return o = setTimeout(g, t), z(c);
|
|
53
|
+
}
|
|
54
|
+
return o === void 0 && (o = setTimeout(g, t)), d;
|
|
55
|
+
}
|
|
56
|
+
return k.cancel = L, k.flush = F, k;
|
|
57
|
+
}
|
|
58
|
+
function ne(e, t, r) {
|
|
59
|
+
var i = !0, n = !0;
|
|
60
|
+
if (typeof e != "function")
|
|
61
|
+
throw new TypeError(P);
|
|
62
|
+
return v(r) && (i = "leading" in r ? !!r.leading : i, n = "trailing" in r ? !!r.trailing : n), ie(e, t, {
|
|
63
|
+
leading: i,
|
|
64
|
+
maxWait: t,
|
|
65
|
+
trailing: n
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function v(e) {
|
|
69
|
+
var t = typeof e;
|
|
70
|
+
return !!e && (t == "object" || t == "function");
|
|
71
|
+
}
|
|
72
|
+
function oe(e) {
|
|
73
|
+
return !!e && typeof e == "object";
|
|
74
|
+
}
|
|
75
|
+
function de(e) {
|
|
76
|
+
return typeof e == "symbol" || oe(e) && te.call(e) == q;
|
|
77
|
+
}
|
|
78
|
+
function R(e) {
|
|
79
|
+
if (typeof e == "number")
|
|
80
|
+
return e;
|
|
81
|
+
if (de(e))
|
|
82
|
+
return I;
|
|
83
|
+
if (v(e)) {
|
|
84
|
+
var t = typeof e.valueOf == "function" ? e.valueOf() : e;
|
|
85
|
+
e = v(t) ? t + "" : t;
|
|
86
|
+
}
|
|
87
|
+
if (typeof e != "string")
|
|
88
|
+
return e === 0 ? e : +e;
|
|
89
|
+
e = e.replace(U, "");
|
|
90
|
+
var r = X.test(e);
|
|
91
|
+
return r || J.test(e) ? K(e.slice(2), r ? 2 : 8) : V.test(e) ? I : +e;
|
|
92
|
+
}
|
|
93
|
+
var se = ne;
|
|
94
|
+
const le = /* @__PURE__ */ H(se), ce = `*,*:after,*:before{box-sizing:inherit}.c-textareaWrapper{--textarea-line-height: calc(var(--dt-font-body-l-line-height) * 1px);--textarea-border-thickness: 1px;--textarea-resize: none;--textarea-padding-inline: var(--dt-spacing-d);--textarea-padding-block: var(--dt-spacing-c);--textarea-background-color: var(--dt-color-container-default);--textarea-border-color: var(--dt-color-interactive-form);--textarea-content-color: var(--dt-color-content-default);--textarea-height: calc((var(--textarea-line-height) * 2) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));line-height:0}.c-textareaWrapper textarea{font-size:calc(var(--dt-font-body-l-size) * 1px);line-height:var(--textarea-line-height);font-family:var(--dt-font-body-l-family);resize:var(--textarea-resize);border:var(--textarea-border-thickness) solid var(--textarea-border-color);background-color:var(--textarea-background-color);color:var(--textarea-content-color);border-radius:var(--dt-radius-rounded-c);block-size:var(--textarea-height);max-block-size:var(--textarea-max-height);min-block-size:var(--textarea-min-height);padding-block-start:var(--textarea-padding-block);padding-block-end:var(--textarea-padding-block);padding-inline-start:var(--textarea-padding-inline);padding-inline-end:var(--textarea-padding-inline)}.c-textareaWrapper textarea[disabled]{--textarea-background-color: var(--dt-color-disabled-01);--textarea-border-color: var(--dt-color-disabled-01);--textarea-content-color: var(--dt-color-content-disabled)}@media (hover: hover){.c-textareaWrapper textarea:hover:not([disabled]){--textarea-background-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) + calc(-1 * var(--dt-color-hover-01))))}}.c-textareaWrapper textarea:focus-visible{box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer);outline:none}.c-textareaWrapper[data-pie-size=large]{--textarea-padding-block: var(--dt-spacing-d)}.c-textareaWrapper[data-pie-size=small]{--textarea-padding-block: var(--dt-spacing-b)}.c-textareaWrapper[data-pie-resize=manual]{--textarea-resize: vertical;--textarea-min-height: calc((var(--textarea-line-height) * 1) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2))}@media (pointer: coarse){.c-textareaWrapper[data-pie-resize=manual]{--textarea-height: calc((var(--textarea-line-height) * 6) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));--textarea-min-height: calc((var(--textarea-line-height) * 6) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));--textarea-max-height: calc((var(--textarea-line-height) * 6) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));--textarea-resize: none}}.c-textareaWrapper[data-pie-resize=auto]{--textarea-max-height: calc((var(--textarea-line-height) * 6) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));--textarea-min-height: var(--textarea-height)}
|
|
95
|
+
`, fe = ["small", "medium", "large"], pe = ["auto", "manual"], x = {
|
|
96
|
+
disabled: !1,
|
|
97
|
+
size: "medium",
|
|
98
|
+
resize: "auto"
|
|
8
99
|
};
|
|
9
|
-
var
|
|
10
|
-
for (var
|
|
11
|
-
(
|
|
12
|
-
return i &&
|
|
100
|
+
var ue = Object.defineProperty, he = Object.getOwnPropertyDescriptor, m = (e, t, r, i) => {
|
|
101
|
+
for (var n = i > 1 ? void 0 : i ? he(t, r) : t, s = e.length - 1, d; s >= 0; s--)
|
|
102
|
+
(d = e[s]) && (n = (i ? d(t, r, n) : d(n)) || n);
|
|
103
|
+
return i && n && ue(t, r, n), n;
|
|
13
104
|
};
|
|
14
|
-
const
|
|
15
|
-
class
|
|
105
|
+
const T = "pie-textarea";
|
|
106
|
+
class f extends A($) {
|
|
16
107
|
constructor() {
|
|
17
|
-
super(...arguments), this.size =
|
|
108
|
+
super(...arguments), this.disabled = x.disabled, this.size = x.size, this.resize = x.resize, this._throttledResize = le(() => {
|
|
109
|
+
this.resize === "auto" && (this._textarea.style.height = "auto", this._textarea.style.height = `${this._textarea.scrollHeight + 2}px`);
|
|
110
|
+
}, 100);
|
|
111
|
+
}
|
|
112
|
+
handleResize() {
|
|
113
|
+
this._throttledResize();
|
|
114
|
+
}
|
|
115
|
+
updated(t) {
|
|
116
|
+
this.resize === "auto" && (t.has("resize") || t.has("size")) && this.handleResize();
|
|
18
117
|
}
|
|
19
118
|
render() {
|
|
20
119
|
const {
|
|
21
120
|
disabled: t,
|
|
22
|
-
|
|
121
|
+
resize: r,
|
|
122
|
+
size: i
|
|
23
123
|
} = this;
|
|
24
|
-
return
|
|
124
|
+
return B`
|
|
25
125
|
<div
|
|
26
|
-
class="c-
|
|
27
|
-
data-test-id="pie-textarea-
|
|
28
|
-
data-pie-size
|
|
126
|
+
class="c-textareaWrapper"
|
|
127
|
+
data-test-id="pie-textarea-wrapper"
|
|
128
|
+
data-pie-size="${i}"
|
|
129
|
+
data-pie-resize="${r}">
|
|
29
130
|
<textarea
|
|
30
131
|
data-test-id="pie-textarea"
|
|
132
|
+
@input=${this.handleResize}
|
|
31
133
|
?disabled=${t}
|
|
32
134
|
></textarea>
|
|
33
135
|
</div>`;
|
|
34
136
|
}
|
|
35
137
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
],
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
],
|
|
45
|
-
|
|
138
|
+
f.shadowRootOptions = { ...$.shadowRootOptions, delegatesFocus: !0 };
|
|
139
|
+
f.styles = D(ce);
|
|
140
|
+
m([
|
|
141
|
+
O({ type: Boolean, reflect: !0 })
|
|
142
|
+
], f.prototype, "disabled", 2);
|
|
143
|
+
m([
|
|
144
|
+
O({ type: String }),
|
|
145
|
+
w(T, fe, x.size)
|
|
146
|
+
], f.prototype, "size", 2);
|
|
147
|
+
m([
|
|
148
|
+
O({ type: String }),
|
|
149
|
+
w(T, pe, x.resize)
|
|
150
|
+
], f.prototype, "resize", 2);
|
|
151
|
+
m([
|
|
152
|
+
N("textarea")
|
|
153
|
+
], f.prototype, "_textarea", 2);
|
|
154
|
+
G(T, f);
|
|
46
155
|
export {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
156
|
+
f as PieTextarea,
|
|
157
|
+
x as defaultProps,
|
|
158
|
+
pe as resizeModes,
|
|
159
|
+
fe as sizes
|
|
50
160
|
};
|
package/dist/react.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';
|
|
2
2
|
import type { CSSResult } from 'lit';
|
|
3
3
|
import type { GenericConstructor } from '@justeattakeaway/pie-webc-core';
|
|
4
4
|
import type { LitElement } from 'lit';
|
|
5
|
+
import type { PropertyValues } from 'lit';
|
|
5
6
|
import * as React_2 from 'react';
|
|
6
7
|
import type { RTLInterface } from '@justeattakeaway/pie-webc-core';
|
|
7
8
|
import type { TemplateResult } from 'lit-html';
|
|
@@ -9,7 +10,7 @@ import type { TemplateResult } from 'lit-html';
|
|
|
9
10
|
/**
|
|
10
11
|
* The default values for the `TextareaProps` that are required (i.e. they have a fallback value in the component).
|
|
11
12
|
*/
|
|
12
|
-
declare type DefaultProps =
|
|
13
|
+
declare type DefaultProps = ComponentDefaultProps<TextareaProps>;
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Default values for optional properties that have default fallback values in the component.
|
|
@@ -27,8 +28,13 @@ declare class PieTextarea_2 extends PieTextarea_base implements TextareaProps {
|
|
|
27
28
|
mode: ShadowRootMode;
|
|
28
29
|
slotAssignment?: SlotAssignmentMode | undefined;
|
|
29
30
|
};
|
|
30
|
-
disabled
|
|
31
|
-
size
|
|
31
|
+
disabled: boolean;
|
|
32
|
+
size: "small" | "medium" | "large";
|
|
33
|
+
resize: "auto" | "manual";
|
|
34
|
+
private _textarea;
|
|
35
|
+
private _throttledResize;
|
|
36
|
+
private handleResize;
|
|
37
|
+
updated(changedProperties: PropertyValues<this>): void;
|
|
32
38
|
render(): TemplateResult<1>;
|
|
33
39
|
static styles: CSSResult;
|
|
34
40
|
}
|
|
@@ -37,6 +43,8 @@ declare const PieTextarea_base: GenericConstructor<RTLInterface> & typeof LitEle
|
|
|
37
43
|
|
|
38
44
|
declare type ReactBaseType = React_2.HTMLAttributes<HTMLTextAreaElement>;
|
|
39
45
|
|
|
46
|
+
export declare const resizeModes: readonly ["auto", "manual"];
|
|
47
|
+
|
|
40
48
|
export declare const sizes: readonly ["small", "medium", "large"];
|
|
41
49
|
|
|
42
50
|
export declare interface TextareaProps {
|
|
@@ -48,6 +56,12 @@ export declare interface TextareaProps {
|
|
|
48
56
|
* The size of the textarea field. Can be `small`, `medium` or `large`. Defaults to `medium`.
|
|
49
57
|
*/
|
|
50
58
|
size?: typeof sizes[number];
|
|
59
|
+
/**
|
|
60
|
+
* The resize mode of the textarea. Can be `auto` or `manual`. Defaults to `auto`.
|
|
61
|
+
* When set to `auto`, the textarea will resize vertically as needed.
|
|
62
|
+
* When set to `manual`, the textarea will not resize automatically but can be resized by the user.
|
|
63
|
+
*/
|
|
64
|
+
resize?: typeof resizeModes[number];
|
|
51
65
|
}
|
|
52
66
|
|
|
53
67
|
export { }
|
package/dist/react.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import * as e from "react";
|
|
2
2
|
import { createComponent as t } from "@lit/react";
|
|
3
3
|
import { PieTextarea as a } from "./index.js";
|
|
4
|
-
import { defaultProps as f, sizes as T } from "./index.js";
|
|
4
|
+
import { defaultProps as P, resizeModes as f, sizes as T } from "./index.js";
|
|
5
5
|
import "lit";
|
|
6
6
|
import "lit/decorators.js";
|
|
7
|
-
import "lit/directives/if-defined.js";
|
|
8
7
|
import "@justeattakeaway/pie-webc-core";
|
|
9
8
|
const r = t({
|
|
10
9
|
displayName: "PieTextarea",
|
|
@@ -12,9 +11,10 @@ const r = t({
|
|
|
12
11
|
react: e,
|
|
13
12
|
tagName: "pie-textarea",
|
|
14
13
|
events: {}
|
|
15
|
-
}),
|
|
14
|
+
}), x = r;
|
|
16
15
|
export {
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
x as PieTextarea,
|
|
17
|
+
P as defaultProps,
|
|
18
|
+
f as resizeModes,
|
|
19
19
|
T as sizes
|
|
20
20
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-textarea",
|
|
3
3
|
"description": "PIE Design System Textarea built using Web Components",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -37,10 +37,12 @@
|
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@custom-elements-manifest/analyzer": "0.9.0",
|
|
39
39
|
"@justeattakeaway/pie-components-config": "0.16.0",
|
|
40
|
+
"@types/lodash.throttle": "4.1.9",
|
|
40
41
|
"cem-plugin-module-file-extensions": "0.0.5"
|
|
41
42
|
},
|
|
42
43
|
"dependencies": {
|
|
43
|
-
"@justeattakeaway/pie-webc-core": "0.
|
|
44
|
+
"@justeattakeaway/pie-webc-core": "0.24.0",
|
|
45
|
+
"lodash.throttle": "4.1.1"
|
|
44
46
|
},
|
|
45
47
|
"volta": {
|
|
46
48
|
"extends": "../../../package.json"
|
package/src/defs.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';
|
|
2
2
|
|
|
3
3
|
export const sizes = ['small', 'medium', 'large'] as const;
|
|
4
|
+
export const resizeModes = ['auto', 'manual'] as const;
|
|
4
5
|
|
|
5
6
|
export interface TextareaProps {
|
|
6
7
|
/**
|
|
@@ -12,16 +13,25 @@ export interface TextareaProps {
|
|
|
12
13
|
* The size of the textarea field. Can be `small`, `medium` or `large`. Defaults to `medium`.
|
|
13
14
|
*/
|
|
14
15
|
size?: typeof sizes[number];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The resize mode of the textarea. Can be `auto` or `manual`. Defaults to `auto`.
|
|
19
|
+
* When set to `auto`, the textarea will resize vertically as needed.
|
|
20
|
+
* When set to `manual`, the textarea will not resize automatically but can be resized by the user.
|
|
21
|
+
*/
|
|
22
|
+
resize?: typeof resizeModes[number];
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
/**
|
|
18
26
|
* The default values for the `TextareaProps` that are required (i.e. they have a fallback value in the component).
|
|
19
27
|
*/
|
|
20
|
-
type DefaultProps =
|
|
28
|
+
type DefaultProps = ComponentDefaultProps<TextareaProps>;
|
|
21
29
|
|
|
22
30
|
/**
|
|
23
31
|
* Default values for optional properties that have default fallback values in the component.
|
|
24
32
|
*/
|
|
25
33
|
export const defaultProps: DefaultProps = {
|
|
34
|
+
disabled: false,
|
|
26
35
|
size: 'medium',
|
|
36
|
+
resize: 'auto',
|
|
27
37
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
LitElement, html, unsafeCSS, PropertyValues,
|
|
3
|
+
} from 'lit';
|
|
4
|
+
import { property, query } from 'lit/decorators.js';
|
|
5
|
+
import throttle from 'lodash.throttle';
|
|
4
6
|
|
|
5
7
|
import { validPropertyValues, RtlMixin, defineCustomElement } from '@justeattakeaway/pie-webc-core';
|
|
6
8
|
|
|
7
9
|
import styles from './textarea.scss?inline';
|
|
8
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
TextareaProps, defaultProps, sizes, resizeModes,
|
|
12
|
+
} from './defs';
|
|
9
13
|
|
|
10
14
|
// Valid values available to consumers
|
|
11
15
|
export * from './defs';
|
|
@@ -19,25 +23,52 @@ export class PieTextarea extends RtlMixin(LitElement) implements TextareaProps {
|
|
|
19
23
|
static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };
|
|
20
24
|
|
|
21
25
|
@property({ type: Boolean, reflect: true })
|
|
22
|
-
public disabled
|
|
26
|
+
public disabled = defaultProps.disabled;
|
|
23
27
|
|
|
24
28
|
@property({ type: String })
|
|
25
29
|
@validPropertyValues(componentSelector, sizes, defaultProps.size)
|
|
26
|
-
public size
|
|
30
|
+
public size = defaultProps.size;
|
|
31
|
+
|
|
32
|
+
@property({ type: String })
|
|
33
|
+
@validPropertyValues(componentSelector, resizeModes, defaultProps.resize)
|
|
34
|
+
public resize = defaultProps.resize;
|
|
35
|
+
|
|
36
|
+
@query('textarea')
|
|
37
|
+
private _textarea!: HTMLTextAreaElement;
|
|
38
|
+
|
|
39
|
+
private _throttledResize = throttle(() => {
|
|
40
|
+
if (this.resize === 'auto') {
|
|
41
|
+
this._textarea.style.height = 'auto';
|
|
42
|
+
this._textarea.style.height = `${this._textarea.scrollHeight + 2}px`; // +2 for border thicknesses
|
|
43
|
+
}
|
|
44
|
+
}, 100);
|
|
45
|
+
|
|
46
|
+
private handleResize () {
|
|
47
|
+
this._throttledResize();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
updated (changedProperties: PropertyValues<this>) {
|
|
51
|
+
if (this.resize === 'auto' && (changedProperties.has('resize') || changedProperties.has('size'))) {
|
|
52
|
+
this.handleResize();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
27
55
|
|
|
28
56
|
render () {
|
|
29
57
|
const {
|
|
30
58
|
disabled,
|
|
59
|
+
resize,
|
|
31
60
|
size,
|
|
32
61
|
} = this;
|
|
33
62
|
|
|
34
63
|
return html`
|
|
35
64
|
<div
|
|
36
|
-
class="c-
|
|
37
|
-
data-test-id="pie-textarea-
|
|
38
|
-
data-pie-size
|
|
65
|
+
class="c-textareaWrapper"
|
|
66
|
+
data-test-id="pie-textarea-wrapper"
|
|
67
|
+
data-pie-size="${size}"
|
|
68
|
+
data-pie-resize="${resize}">
|
|
39
69
|
<textarea
|
|
40
70
|
data-test-id="pie-textarea"
|
|
71
|
+
@input=${this.handleResize}
|
|
41
72
|
?disabled=${disabled}
|
|
42
73
|
></textarea>
|
|
43
74
|
</div>`;
|
package/src/textarea.scss
CHANGED
|
@@ -1,22 +1,89 @@
|
|
|
1
1
|
@use '@justeattakeaway/pie-css/scss' as p;
|
|
2
2
|
|
|
3
|
-
.
|
|
4
|
-
|
|
3
|
+
// Heights are being defined based on the line height of the text and the padding.
|
|
4
|
+
// Changing the `size` property affects the padding and therefore the height of the textarea.
|
|
5
|
+
// Default height is two lines of text.
|
|
6
|
+
// Minimum height in manual resize mode is one line of text.
|
|
7
|
+
// Maximum height in auto resize mode is six lines of text.
|
|
8
|
+
.c-textareaWrapper {
|
|
9
|
+
--textarea-line-height: #{p.line-height(--dt-font-body-l-line-height)};
|
|
10
|
+
--textarea-border-thickness: 1px;
|
|
11
|
+
--textarea-resize: none;
|
|
12
|
+
--textarea-padding-inline: var(--dt-spacing-d);
|
|
13
|
+
--textarea-padding-block: var(--dt-spacing-c);
|
|
14
|
+
--textarea-background-color: var(--dt-color-container-default);
|
|
15
|
+
--textarea-border-color: var(--dt-color-interactive-form);
|
|
16
|
+
--textarea-content-color: var(--dt-color-content-default);
|
|
5
17
|
|
|
6
|
-
height
|
|
18
|
+
// Default height is two lines of text
|
|
19
|
+
--textarea-height: calc((var(--textarea-line-height) * 2) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));
|
|
20
|
+
|
|
21
|
+
line-height: 0; // Remove once there is text outside the textarea
|
|
22
|
+
|
|
23
|
+
textarea {
|
|
24
|
+
@include p.font-size(--dt-font-body-l-size);
|
|
25
|
+
line-height: var(--textarea-line-height);
|
|
26
|
+
font-family: var(--dt-font-body-l-family);
|
|
27
|
+
resize: var(--textarea-resize);
|
|
28
|
+
border: var(--textarea-border-thickness) solid var(--textarea-border-color);
|
|
29
|
+
background-color: var(--textarea-background-color);
|
|
30
|
+
color: var(--textarea-content-color);
|
|
31
|
+
|
|
32
|
+
border-radius: var(--dt-radius-rounded-c);
|
|
33
|
+
block-size: var(--textarea-height);
|
|
34
|
+
max-block-size: var(--textarea-max-height);
|
|
35
|
+
min-block-size: var(--textarea-min-height);
|
|
36
|
+
|
|
37
|
+
padding-block-start: var(--textarea-padding-block);
|
|
38
|
+
padding-block-end: var(--textarea-padding-block);
|
|
39
|
+
padding-inline-start: var(--textarea-padding-inline);
|
|
40
|
+
padding-inline-end: var(--textarea-padding-inline);
|
|
41
|
+
|
|
42
|
+
&[disabled] {
|
|
43
|
+
--textarea-background-color: var(--dt-color-disabled-01);
|
|
44
|
+
--textarea-border-color: var(--dt-color-disabled-01);
|
|
45
|
+
--textarea-content-color: var(--dt-color-content-disabled);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@media (hover: hover) {
|
|
49
|
+
&:hover:not([disabled]) {
|
|
50
|
+
--textarea-background-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) + calc(-1 * var(--dt-color-hover-01))));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&:focus-visible {
|
|
55
|
+
@include p.focus;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
7
58
|
|
|
8
59
|
&[data-pie-size="large"] {
|
|
9
|
-
--textarea-
|
|
60
|
+
--textarea-padding-block: var(--dt-spacing-d);
|
|
10
61
|
}
|
|
11
62
|
|
|
12
63
|
&[data-pie-size="small"] {
|
|
13
|
-
--textarea-
|
|
64
|
+
--textarea-padding-block: var(--dt-spacing-b);
|
|
14
65
|
}
|
|
15
66
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
67
|
+
&[data-pie-resize="manual"] {
|
|
68
|
+
--textarea-resize: vertical;
|
|
69
|
+
|
|
70
|
+
// Minimum is one line of text
|
|
71
|
+
--textarea-min-height: calc((var(--textarea-line-height) * 1) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2)); // One line of text
|
|
72
|
+
|
|
73
|
+
@media (pointer: coarse) {
|
|
74
|
+
// Fixed size for touch devices
|
|
75
|
+
--textarea-height: calc((var(--textarea-line-height) * 6) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));
|
|
76
|
+
--textarea-min-height: calc((var(--textarea-line-height) * 6) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));
|
|
77
|
+
--textarea-max-height: calc((var(--textarea-line-height) * 6) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));
|
|
78
|
+
--textarea-resize: none;
|
|
79
|
+
}
|
|
19
80
|
}
|
|
20
|
-
}
|
|
21
81
|
|
|
82
|
+
&[data-pie-resize="auto"] {
|
|
83
|
+
// Maximum is six lines of text
|
|
84
|
+
--textarea-max-height: calc((var(--textarea-line-height) * 6) + (var(--textarea-padding-block) * 2) + (var(--textarea-border-thickness) * 2));
|
|
22
85
|
|
|
86
|
+
// Minimum is two lines of text
|
|
87
|
+
--textarea-min-height: var(--textarea-height);
|
|
88
|
+
}
|
|
89
|
+
}
|