@fluid-topics/ftds-text-area 0.0.0-stage → 2.2.41
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 +25 -2
- package/build/define.d.ts +1 -0
- package/build/define.js +3 -0
- package/build/definitions.d.ts +5 -0
- package/build/definitions.js +4 -0
- package/build/ftds-text-area.d.ts +29 -0
- package/build/ftds-text-area.js +179 -0
- package/build/ftds-text-area.light.js +2621 -0
- package/build/ftds-text-area.min.js +2743 -0
- package/build/ftds-text-area.properties.d.ts +4 -0
- package/build/ftds-text-area.properties.js +1 -0
- package/build/ftds-text-area.styles.d.ts +10 -0
- package/build/ftds-text-area.styles.js +67 -0
- package/build/index.d.ts +4 -0
- package/build/index.js +4 -0
- package/package.json +34 -5
package/README.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
Design system text-area
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Install
|
|
4
|
+
|
|
5
|
+
```shell
|
|
6
|
+
npm install @fluid-topics/ftds-text-area
|
|
7
|
+
yarn add @fluid-topics/ftds-text-area
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { html } from "lit"
|
|
14
|
+
import "@fluid-topics/ftds-text-area"
|
|
15
|
+
|
|
16
|
+
function render() {
|
|
17
|
+
return html`
|
|
18
|
+
<ftds-text-area
|
|
19
|
+
label="Description"
|
|
20
|
+
value="Some text"
|
|
21
|
+
helperText="Describe your content in a few words"
|
|
22
|
+
height="150"
|
|
23
|
+
></ftds-text-area>
|
|
24
|
+
`
|
|
25
|
+
}
|
|
26
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/build/define.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { PropertyValues } from "lit";
|
|
2
|
+
import { ElementDefinitionsMap, FtdsBase } from "@fluid-topics/ft-wc-utils";
|
|
3
|
+
import { FtdsTextAreaProperties } from "./ftds-text-area.properties";
|
|
4
|
+
declare const FtdsTextArea_base: typeof FtdsBase & import("@fluid-topics/ft-wc-utils").Constructor<import("@fluid-topics/ft-wc-utils").FtInputInterface<string>> & import("@fluid-topics/ft-wc-utils").Constructor<import("@fluid-topics/ft-i18n").FtLitElementWithI18nInterface>;
|
|
5
|
+
export declare class FtdsTextArea extends FtdsTextArea_base implements FtdsTextAreaProperties {
|
|
6
|
+
static elementDefinitions: ElementDefinitionsMap;
|
|
7
|
+
static styles: import("lit").CSSResult[];
|
|
8
|
+
height?: number;
|
|
9
|
+
private fittedHeight;
|
|
10
|
+
private textarea?;
|
|
11
|
+
private baseInput?;
|
|
12
|
+
private scrollbarWidth;
|
|
13
|
+
private pendingHeightFit;
|
|
14
|
+
constructor();
|
|
15
|
+
protected willUpdate(changedProperties: PropertyValues): void;
|
|
16
|
+
focus(): void;
|
|
17
|
+
onInput(): void;
|
|
18
|
+
protected render(): import("lit").TemplateResult<1>;
|
|
19
|
+
protected firstUpdated(changedProperties: PropertyValues): void;
|
|
20
|
+
protected updated(changedProperties: PropertyValues): void;
|
|
21
|
+
private get fieldHeight();
|
|
22
|
+
private measureScrollbar;
|
|
23
|
+
private get insideStructure();
|
|
24
|
+
private fitHeightToContent;
|
|
25
|
+
private clampHeight;
|
|
26
|
+
private onKeyDown;
|
|
27
|
+
private onResize;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, } from "lit";
|
|
8
|
+
import { query, state, } from "lit/decorators.js";
|
|
9
|
+
import { FtdsBase, ignoreComposingEvents, numberProperty, Status, toFtInput, } from "@fluid-topics/ft-wc-utils";
|
|
10
|
+
import { scrollbarWidthCssVariable, styles, } from "./ftds-text-area.styles";
|
|
11
|
+
import { FtdsTypography } from "@fluid-topics/ftds-typography";
|
|
12
|
+
import { FtResizer, } from "@fluid-topics/ft-resizer";
|
|
13
|
+
import { withI18n } from "@fluid-topics/ft-i18n";
|
|
14
|
+
import { DesignSystemSize } from "@fluid-topics/design-system-variables";
|
|
15
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
16
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
17
|
+
import { FtdsBaseInput } from "@fluid-topics/ftds-base-input";
|
|
18
|
+
export class FtdsTextArea extends withI18n(toFtInput(FtdsBase)) {
|
|
19
|
+
constructor() {
|
|
20
|
+
var _a;
|
|
21
|
+
super();
|
|
22
|
+
this.fittedHeight = 0;
|
|
23
|
+
this.scrollbarWidth = 0;
|
|
24
|
+
this.pendingHeightFit = false;
|
|
25
|
+
this.value = (_a = this.value) !== null && _a !== void 0 ? _a : "";
|
|
26
|
+
}
|
|
27
|
+
willUpdate(changedProperties) {
|
|
28
|
+
var _a;
|
|
29
|
+
super.willUpdate(changedProperties);
|
|
30
|
+
this.value = (_a = this.value) !== null && _a !== void 0 ? _a : "";
|
|
31
|
+
}
|
|
32
|
+
focus() {
|
|
33
|
+
var _a;
|
|
34
|
+
(_a = this.textarea) === null || _a === void 0 ? void 0 : _a.focus();
|
|
35
|
+
}
|
|
36
|
+
onInput() {
|
|
37
|
+
var _a;
|
|
38
|
+
this.value = ((_a = this.textarea) === null || _a === void 0 ? void 0 : _a.value) || "";
|
|
39
|
+
super.onInput();
|
|
40
|
+
}
|
|
41
|
+
render() {
|
|
42
|
+
return html `
|
|
43
|
+
<style>
|
|
44
|
+
ftds-base-input::part(inside-structure) {
|
|
45
|
+
height: ${this.fieldHeight}px;
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
48
|
+
<ftds-base-input
|
|
49
|
+
.status=${this.status}
|
|
50
|
+
.size=${DesignSystemSize.large}
|
|
51
|
+
?disabled=${this.disabled}
|
|
52
|
+
|
|
53
|
+
.errorMessages=${this.errorMessages}
|
|
54
|
+
.warningMessages=${this.warningMessages}
|
|
55
|
+
.helperText=${this.helperText}
|
|
56
|
+
|
|
57
|
+
.label=${ifDefined(this.label)}
|
|
58
|
+
?raiseLabel=${this.focused || !!this.value}
|
|
59
|
+
>
|
|
60
|
+
<textarea
|
|
61
|
+
class="${classMap({ "ftds-text-area--with-scrollbar": this.scrollbarWidth > 0 })}"
|
|
62
|
+
name="${this.name}"
|
|
63
|
+
.value=${this.value}
|
|
64
|
+
?disabled=${this.disabled}
|
|
65
|
+
@input=${this.onInput}
|
|
66
|
+
@focus=${this.onFocus}
|
|
67
|
+
@blur=${this.onBlur}
|
|
68
|
+
@keydown=${this.onKeyDown}
|
|
69
|
+
aria-label="${ifDefined(this.label)}"
|
|
70
|
+
aria-invalid="${this.status === Status.error}"
|
|
71
|
+
aria-describedby="${this.messagesForScreenReaderElementId}"
|
|
72
|
+
></textarea>
|
|
73
|
+
${this.renderMessagesForScreenReader()}
|
|
74
|
+
<ft-resizer
|
|
75
|
+
style="${scrollbarWidthCssVariable.set(`${this.scrollbarWidth}px`)}"
|
|
76
|
+
@resize=${this.onResize}
|
|
77
|
+
@click=${(e) => e.stopPropagation()}
|
|
78
|
+
initialHeight="${this.fieldHeight}"
|
|
79
|
+
cursor="ns-resize"
|
|
80
|
+
ariaLabel="Resize text area">
|
|
81
|
+
</ft-resizer>
|
|
82
|
+
</ftds-base-input>
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
firstUpdated(changedProperties) {
|
|
86
|
+
super.firstUpdated(changedProperties);
|
|
87
|
+
this.fitHeightToContent();
|
|
88
|
+
new ResizeObserver(() => this.measureScrollbar()).observe(this.textarea);
|
|
89
|
+
new ResizeObserver(() => {
|
|
90
|
+
if (this.pendingHeightFit) {
|
|
91
|
+
this.fitHeightToContent();
|
|
92
|
+
}
|
|
93
|
+
}).observe(this);
|
|
94
|
+
}
|
|
95
|
+
updated(changedProperties) {
|
|
96
|
+
super.updated(changedProperties);
|
|
97
|
+
this.measureScrollbar();
|
|
98
|
+
if (changedProperties.has("height") || (changedProperties.has("value") && !this.focused && this.height === undefined)) {
|
|
99
|
+
this.fitHeightToContent();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
get fieldHeight() {
|
|
103
|
+
var _a;
|
|
104
|
+
return (_a = this.height) !== null && _a !== void 0 ? _a : this.fittedHeight;
|
|
105
|
+
}
|
|
106
|
+
measureScrollbar() {
|
|
107
|
+
this.scrollbarWidth = this.textarea ? this.textarea.offsetWidth - this.textarea.clientWidth : 0;
|
|
108
|
+
}
|
|
109
|
+
get insideStructure() {
|
|
110
|
+
var _a, _b;
|
|
111
|
+
return (_b = (_a = this.baseInput) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector("[part~=inside-structure]");
|
|
112
|
+
}
|
|
113
|
+
async fitHeightToContent() {
|
|
114
|
+
var _a;
|
|
115
|
+
await ((_a = this.baseInput) === null || _a === void 0 ? void 0 : _a.updateComplete);
|
|
116
|
+
const insideStructure = this.insideStructure;
|
|
117
|
+
if (!insideStructure || !this.textarea) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (insideStructure.offsetHeight === 0) {
|
|
121
|
+
// Hidden (e.g. inside a closed modal): fit once visible
|
|
122
|
+
this.pendingHeightFit = true;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
this.pendingHeightFit = false;
|
|
126
|
+
if (this.height !== undefined) {
|
|
127
|
+
this.height = this.clampHeight(this.height);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const containerHeight = insideStructure.offsetHeight - this.textarea.clientHeight;
|
|
131
|
+
const previousHeight = this.textarea.style.height;
|
|
132
|
+
this.textarea.style.height = "0px";
|
|
133
|
+
const contentHeight = this.textarea.scrollHeight;
|
|
134
|
+
this.textarea.style.height = previousHeight;
|
|
135
|
+
this.fittedHeight = this.clampHeight(containerHeight + contentHeight);
|
|
136
|
+
}
|
|
137
|
+
clampHeight(height) {
|
|
138
|
+
var _a, _b;
|
|
139
|
+
const style = this.insideStructure ? getComputedStyle(this.insideStructure) : undefined;
|
|
140
|
+
const minHeight = parseFloat((_a = style === null || style === void 0 ? void 0 : style.minHeight) !== null && _a !== void 0 ? _a : "") || 0;
|
|
141
|
+
const maxHeight = parseFloat((_b = style === null || style === void 0 ? void 0 : style.maxHeight) !== null && _b !== void 0 ? _b : "") || Infinity;
|
|
142
|
+
return Math.min(Math.max(height, minHeight), Math.max(minHeight, maxHeight));
|
|
143
|
+
}
|
|
144
|
+
onKeyDown(e) {
|
|
145
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
146
|
+
e.stopPropagation();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
onResize(event) {
|
|
150
|
+
this.height = this.clampHeight(event.detail.height);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
FtdsTextArea.elementDefinitions = {
|
|
154
|
+
"ftds-base-input": FtdsBaseInput,
|
|
155
|
+
"ft-resizer": FtResizer,
|
|
156
|
+
"ftds-typography": FtdsTypography,
|
|
157
|
+
};
|
|
158
|
+
// language=CSS
|
|
159
|
+
FtdsTextArea.styles = [
|
|
160
|
+
styles,
|
|
161
|
+
];
|
|
162
|
+
__decorate([
|
|
163
|
+
numberProperty()
|
|
164
|
+
], FtdsTextArea.prototype, "height", void 0);
|
|
165
|
+
__decorate([
|
|
166
|
+
state()
|
|
167
|
+
], FtdsTextArea.prototype, "fittedHeight", void 0);
|
|
168
|
+
__decorate([
|
|
169
|
+
query("textarea")
|
|
170
|
+
], FtdsTextArea.prototype, "textarea", void 0);
|
|
171
|
+
__decorate([
|
|
172
|
+
query("ftds-base-input")
|
|
173
|
+
], FtdsTextArea.prototype, "baseInput", void 0);
|
|
174
|
+
__decorate([
|
|
175
|
+
state()
|
|
176
|
+
], FtdsTextArea.prototype, "scrollbarWidth", void 0);
|
|
177
|
+
__decorate([
|
|
178
|
+
ignoreComposingEvents()
|
|
179
|
+
], FtdsTextArea.prototype, "onKeyDown", null);
|