@phcdevworks/spectre-components 0.0.1 → 1.1.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.
Files changed (62) hide show
  1. package/README.md +113 -40
  2. package/dist/base-2rD8EmdC.d.cts +32 -0
  3. package/dist/base-2rD8EmdC.d.ts +32 -0
  4. package/dist/button.cjs +295 -170
  5. package/dist/button.cjs.map +1 -1
  6. package/dist/button.d.cts +30 -61
  7. package/dist/button.d.ts +30 -61
  8. package/dist/button.js +296 -171
  9. package/dist/button.js.map +1 -1
  10. package/dist/checkbox.cjs +286 -71
  11. package/dist/checkbox.cjs.map +1 -1
  12. package/dist/checkbox.d.cts +38 -43
  13. package/dist/checkbox.d.ts +38 -43
  14. package/dist/checkbox.js +287 -72
  15. package/dist/checkbox.js.map +1 -1
  16. package/dist/fieldset.cjs +233 -88
  17. package/dist/fieldset.cjs.map +1 -1
  18. package/dist/fieldset.d.cts +23 -40
  19. package/dist/fieldset.d.ts +23 -40
  20. package/dist/fieldset.js +233 -88
  21. package/dist/fieldset.js.map +1 -1
  22. package/dist/form-iI7vV-3W.d.cts +6 -0
  23. package/dist/form-iI7vV-3W.d.ts +6 -0
  24. package/dist/index.cjs +564 -1029
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +5 -2
  27. package/dist/index.d.ts +5 -2
  28. package/dist/index.js +566 -1030
  29. package/dist/index.js.map +1 -1
  30. package/dist/input.cjs +232 -119
  31. package/dist/input.cjs.map +1 -1
  32. package/dist/input.d.cts +52 -68
  33. package/dist/input.d.ts +52 -68
  34. package/dist/input.js +232 -119
  35. package/dist/input.js.map +1 -1
  36. package/dist/label.cjs +232 -73
  37. package/dist/label.cjs.map +1 -1
  38. package/dist/label.d.cts +13 -22
  39. package/dist/label.d.ts +13 -22
  40. package/dist/label.js +232 -73
  41. package/dist/label.js.map +1 -1
  42. package/dist/projectable-BzDQ4xp_.d.cts +17 -0
  43. package/dist/projectable-s3SgvjGX.d.ts +17 -0
  44. package/dist/radio.cjs +286 -71
  45. package/dist/radio.cjs.map +1 -1
  46. package/dist/radio.d.cts +38 -43
  47. package/dist/radio.d.ts +38 -43
  48. package/dist/radio.js +287 -72
  49. package/dist/radio.js.map +1 -1
  50. package/dist/select.cjs +292 -163
  51. package/dist/select.cjs.map +1 -1
  52. package/dist/select.d.cts +35 -58
  53. package/dist/select.d.ts +35 -58
  54. package/dist/select.js +293 -163
  55. package/dist/select.js.map +1 -1
  56. package/dist/textarea.cjs +191 -290
  57. package/dist/textarea.cjs.map +1 -1
  58. package/dist/textarea.d.cts +41 -58
  59. package/dist/textarea.d.ts +41 -58
  60. package/dist/textarea.js +191 -290
  61. package/dist/textarea.js.map +1 -1
  62. package/package.json +13 -12
package/dist/textarea.js CHANGED
@@ -4,227 +4,201 @@ import { ifDefined } from 'lit/directives/if-defined.js';
4
4
  import { getInputClasses } from '@phcdevworks/spectre-ui';
5
5
 
6
6
  // src/components/textarea/sp-textarea.ts
7
- var spectreInputTypes = [
8
- "text",
9
- "email",
10
- "password",
11
- "search",
12
- "tel",
13
- "url",
14
- "number",
15
- "date",
16
- "datetime-local",
17
- "month",
18
- "time",
19
- "week"
20
- ];
21
- var spectreInputSizes = ["sm", "md", "lg"];
22
- function isInputType(value) {
23
- return spectreInputTypes.includes(value);
24
- }
25
- function isInputSize(value) {
26
- return spectreInputSizes.includes(value);
27
- }
28
- var SpectreInputElement = class extends LitElement {
7
+ var SpectreBaseElement = class extends LitElement {
29
8
  constructor() {
30
9
  super(...arguments);
31
- this.ariaLabel = null;
32
- this.ariaLabelledBy = null;
33
- this.ariaDescribedBy = null;
34
- this.autofocus = false;
35
- this.disabled = false;
36
- this.fullWidth = false;
37
- this.invalid = false;
38
- this.loading = false;
39
- this.pill = false;
40
- this.readonly = false;
41
- this.required = false;
42
- this.size = "md";
43
- this.success = false;
44
- this.title = "";
45
- this.type = "text";
46
- this.value = "";
10
+ this._ariaLabel = null;
11
+ this._ariaLabelledBy = null;
12
+ this._ariaDescribedBy = null;
13
+ this._title = "";
14
+ this._id = "";
15
+ }
16
+ get ariaLabel() {
17
+ return this._ariaLabel;
18
+ }
19
+ set ariaLabel(value) {
20
+ if (this._ariaLabel === value) {
21
+ return;
22
+ }
23
+ this._ariaLabel = value;
24
+ this._removeHostAttribute("aria-label");
25
+ this.requestUpdate();
26
+ }
27
+ get ariaLabelledBy() {
28
+ return this._ariaLabelledBy;
29
+ }
30
+ set ariaLabelledBy(value) {
31
+ if (this._ariaLabelledBy === value) {
32
+ return;
33
+ }
34
+ this._ariaLabelledBy = value;
35
+ this._removeHostAttribute("aria-labelledby");
36
+ this.requestUpdate();
37
+ }
38
+ get ariaDescribedBy() {
39
+ return this._ariaDescribedBy;
40
+ }
41
+ set ariaDescribedBy(value) {
42
+ if (this._ariaDescribedBy === value) {
43
+ return;
44
+ }
45
+ this._ariaDescribedBy = value;
46
+ this._removeHostAttribute("aria-describedby");
47
+ this.requestUpdate();
48
+ }
49
+ get title() {
50
+ return this._title;
51
+ }
52
+ set title(value) {
53
+ const normalizedValue = value ?? "";
54
+ if (this._title === normalizedValue) {
55
+ return;
56
+ }
57
+ this._title = normalizedValue;
58
+ this._removeHostAttribute("title");
59
+ this.requestUpdate();
47
60
  }
48
61
  get id() {
49
- return this._id ?? "";
62
+ return this._id;
50
63
  }
51
64
  set id(value) {
52
- if ((this._id ?? "") === value) {
65
+ const normalizedValue = value ?? "";
66
+ if (this._id === normalizedValue) {
53
67
  return;
54
68
  }
55
- this._id = value;
56
- const host = this;
57
- if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
58
- HTMLElement.prototype.removeAttribute.call(host, "id");
59
- }
69
+ this._id = normalizedValue;
70
+ this._removeHostAttribute("id");
60
71
  this.requestUpdate();
61
72
  }
73
+ // Spectre components intentionally render in light DOM so the global
74
+ // `@phcdevworks/spectre-ui` styling contract can apply directly.
62
75
  createRenderRoot() {
63
76
  return this;
64
77
  }
65
78
  connectedCallback() {
66
79
  super.connectedCallback();
67
- const hostId = super.getAttribute("id");
68
- if (hostId !== null) {
69
- this.id = hostId;
70
- }
80
+ const proxiedAttributes = [
81
+ "id",
82
+ "title",
83
+ "aria-label",
84
+ "aria-labelledby",
85
+ "aria-describedby"
86
+ ];
87
+ proxiedAttributes.forEach((attr) => {
88
+ const value = super.getAttribute(attr);
89
+ if (value !== null) {
90
+ this.setAttribute(attr, value);
91
+ }
92
+ });
71
93
  }
72
94
  getAttribute(qualifiedName) {
73
- if (qualifiedName === "id") {
74
- return this.id || null;
95
+ switch (qualifiedName) {
96
+ case "id":
97
+ return this.id || null;
98
+ case "title":
99
+ return this.title || null;
100
+ case "aria-label":
101
+ return this.ariaLabel;
102
+ case "aria-labelledby":
103
+ return this.ariaLabelledBy;
104
+ case "aria-describedby":
105
+ return this.ariaDescribedBy;
106
+ default:
107
+ return super.getAttribute(qualifiedName);
75
108
  }
76
- return super.getAttribute(qualifiedName);
77
109
  }
78
110
  hasAttribute(qualifiedName) {
79
- if (qualifiedName === "id") {
80
- return this.id !== "";
111
+ switch (qualifiedName) {
112
+ case "id":
113
+ return this.id !== "";
114
+ case "title":
115
+ return this.title !== "";
116
+ case "aria-label":
117
+ return this.ariaLabel !== null;
118
+ case "aria-labelledby":
119
+ return this.ariaLabelledBy !== null;
120
+ case "aria-describedby":
121
+ return this.ariaDescribedBy !== null;
122
+ default:
123
+ return super.hasAttribute(qualifiedName);
81
124
  }
82
- return super.hasAttribute(qualifiedName);
83
125
  }
84
126
  setAttribute(qualifiedName, value) {
85
- if (qualifiedName === "id") {
86
- this.id = value;
87
- return;
127
+ switch (qualifiedName) {
128
+ case "id":
129
+ this.id = value;
130
+ break;
131
+ case "title":
132
+ this.title = value;
133
+ break;
134
+ case "aria-label":
135
+ this.ariaLabel = value;
136
+ break;
137
+ case "aria-labelledby":
138
+ this.ariaLabelledBy = value;
139
+ break;
140
+ case "aria-describedby":
141
+ this.ariaDescribedBy = value;
142
+ break;
143
+ default:
144
+ super.setAttribute(qualifiedName, value);
88
145
  }
89
- super.setAttribute(qualifiedName, value);
90
146
  }
91
147
  removeAttribute(qualifiedName) {
92
- if (qualifiedName === "id") {
93
- this.id = "";
94
- return;
148
+ switch (qualifiedName) {
149
+ case "id":
150
+ this.id = "";
151
+ break;
152
+ case "title":
153
+ this.title = "";
154
+ break;
155
+ case "aria-label":
156
+ this.ariaLabel = null;
157
+ break;
158
+ case "aria-labelledby":
159
+ this.ariaLabelledBy = null;
160
+ break;
161
+ case "aria-describedby":
162
+ this.ariaDescribedBy = null;
163
+ break;
164
+ default:
165
+ super.removeAttribute(qualifiedName);
95
166
  }
96
- super.removeAttribute(qualifiedName);
97
167
  }
98
- willUpdate(changedProperties) {
99
- if (changedProperties.has("size") && !isInputSize(this.size)) {
100
- this.size = "md";
101
- }
102
- if (changedProperties.has("type") && !isInputType(this.type)) {
103
- this.type = "text";
104
- }
105
- if (changedProperties.has("value") && this.value == null) {
106
- this.value = "";
107
- }
108
- if (changedProperties.has("maxlength")) {
109
- if (this.maxlength == null || !Number.isInteger(this.maxlength) || this.maxlength < 0) {
110
- this.maxlength = void 0;
111
- }
112
- }
113
- if (changedProperties.has("minlength")) {
114
- if (this.minlength == null || !Number.isInteger(this.minlength) || this.minlength < 0) {
115
- this.minlength = void 0;
116
- }
168
+ _removeHostAttribute(name) {
169
+ const host = this;
170
+ if (HTMLElement.prototype.hasAttribute.call(host, name)) {
171
+ HTMLElement.prototype.removeAttribute.call(host, name);
117
172
  }
118
173
  }
119
- get inputClasses() {
120
- return getInputClasses({
121
- fullWidth: this.fullWidth,
122
- pill: this.pill,
123
- size: this.size,
124
- state: this.isDisabled ? this.disabled ? "disabled" : "loading" : this.invalid ? "error" : this.success ? "success" : "default"
125
- });
126
- }
127
- get isDisabled() {
128
- return this.disabled || this.loading;
129
- }
130
- get nativeInput() {
131
- return this.querySelector("[data-sp-input-native]");
132
- }
133
174
  get forwardedAriaLabel() {
134
- const ariaLabel = this.ariaLabel?.trim();
135
- return ariaLabel ? ariaLabel : void 0;
175
+ const value = this.ariaLabel?.trim();
176
+ return value ? value : void 0;
136
177
  }
137
178
  get forwardedAriaLabelledBy() {
138
- const ariaLabelledBy = this.ariaLabelledBy?.trim();
139
- return ariaLabelledBy ? ariaLabelledBy : void 0;
179
+ const value = this.ariaLabelledBy?.trim();
180
+ return value ? value : void 0;
140
181
  }
141
182
  get forwardedAriaDescribedBy() {
142
- const ariaDescribedBy = this.ariaDescribedBy?.trim();
143
- return ariaDescribedBy ? ariaDescribedBy : void 0;
183
+ const value = this.ariaDescribedBy?.trim();
184
+ return value ? value : void 0;
144
185
  }
145
- handleInput(event) {
146
- const input = event.currentTarget;
147
- this.value = input.value;
148
- }
149
- handleChange(event) {
150
- const input = event.currentTarget;
151
- this.value = input.value;
152
- }
153
- focus(options) {
154
- this.nativeInput?.focus(options);
155
- }
156
- blur() {
157
- this.nativeInput?.blur();
158
- }
159
- render() {
160
- return html`
161
- <input
162
- aria-busy=${this.loading ? "true" : "false"}
163
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
164
- aria-invalid=${ifDefined(this.invalid ? "true" : void 0)}
165
- aria-label=${ifDefined(this.forwardedAriaLabel)}
166
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
167
- autocomplete=${ifDefined(this.autocomplete)}
168
- ?autofocus=${this.autofocus}
169
- class=${this.inputClasses}
170
- data-sp-input-native
171
- ?disabled=${this.isDisabled}
172
- ?readonly=${this.readonly}
173
- ?required=${this.required}
174
- id=${ifDefined(this.id || void 0)}
175
- inputmode=${ifDefined(this.inputmode)}
176
- max=${ifDefined(this.max)}
177
- maxlength=${ifDefined(this.maxlength)}
178
- min=${ifDefined(this.min)}
179
- minlength=${ifDefined(this.minlength)}
180
- name=${ifDefined(this.name)}
181
- placeholder=${ifDefined(this.placeholder)}
182
- step=${ifDefined(this.step)}
183
- title=${ifDefined(this.title || void 0)}
184
- type=${this.type}
185
- .value=${live(this.value)}
186
- @change=${this.handleChange}
187
- @input=${this.handleInput}
188
- />
189
- `;
190
- }
191
- };
192
- SpectreInputElement.properties = {
193
- ariaLabel: { attribute: "aria-label", type: String },
194
- ariaLabelledBy: { attribute: "aria-labelledby", type: String },
195
- ariaDescribedBy: { attribute: "aria-describedby", type: String },
196
- autocomplete: { type: String },
197
- autofocus: { type: Boolean, reflect: true },
198
- disabled: { type: Boolean, reflect: true },
199
- fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
200
- inputmode: { type: String },
201
- invalid: { type: Boolean, reflect: true },
202
- loading: { type: Boolean, reflect: true },
203
- max: { type: String },
204
- maxlength: { type: Number },
205
- min: { type: String },
206
- minlength: { type: Number },
207
- name: { type: String },
208
- pill: { type: Boolean, reflect: true },
209
- placeholder: { type: String },
210
- readonly: { type: Boolean, reflect: true },
211
- required: { type: Boolean, reflect: true },
212
- size: { type: String, reflect: true },
213
- step: { type: String },
214
- success: { type: Boolean, reflect: true },
215
- title: { type: String, reflect: true },
216
- type: { type: String, reflect: true },
217
- value: { type: String }
218
186
  };
219
-
220
- // src/components/textarea/sp-textarea.ts
187
+ SpectreBaseElement.properties = {};
188
+ var spectreInputSizes = ["sm", "md", "lg"];
189
+ function isInputSize(value) {
190
+ return spectreInputSizes.includes(value);
191
+ }
192
+ function normalizeInt(value, fallback, min = 0) {
193
+ if (value == null || typeof value !== "number" || !Number.isInteger(value) || value < min) {
194
+ return fallback;
195
+ }
196
+ return value;
197
+ }
221
198
  var DEFAULT_ROWS = 2;
222
- var SpectreTextareaElement = class extends LitElement {
199
+ var SpectreTextareaElement = class extends SpectreBaseElement {
223
200
  constructor() {
224
201
  super(...arguments);
225
- this.ariaLabel = null;
226
- this.ariaLabelledBy = null;
227
- this.ariaDescribedBy = null;
228
202
  this.autofocus = false;
229
203
  this.disabled = false;
230
204
  this.fullWidth = false;
@@ -236,80 +210,23 @@ var SpectreTextareaElement = class extends LitElement {
236
210
  this.rows = DEFAULT_ROWS;
237
211
  this.size = "md";
238
212
  this.success = false;
239
- this.title = "";
240
213
  this.value = "";
241
214
  }
242
- get id() {
243
- return this._id ?? "";
244
- }
245
- set id(value) {
246
- if ((this._id ?? "") === value) {
247
- return;
248
- }
249
- this._id = value;
250
- const host = this;
251
- if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
252
- HTMLElement.prototype.removeAttribute.call(host, "id");
253
- }
254
- this.requestUpdate();
255
- }
256
- createRenderRoot() {
257
- return this;
258
- }
259
- connectedCallback() {
260
- super.connectedCallback();
261
- const hostId = super.getAttribute("id");
262
- if (hostId !== null) {
263
- this.id = hostId;
264
- }
265
- }
266
- getAttribute(qualifiedName) {
267
- if (qualifiedName === "id") {
268
- return this.id || null;
269
- }
270
- return super.getAttribute(qualifiedName);
271
- }
272
- hasAttribute(qualifiedName) {
273
- if (qualifiedName === "id") {
274
- return this.id !== "";
275
- }
276
- return super.hasAttribute(qualifiedName);
277
- }
278
- setAttribute(qualifiedName, value) {
279
- if (qualifiedName === "id") {
280
- this.id = value;
281
- return;
282
- }
283
- super.setAttribute(qualifiedName, value);
284
- }
285
- removeAttribute(qualifiedName) {
286
- if (qualifiedName === "id") {
287
- this.id = "";
288
- return;
289
- }
290
- super.removeAttribute(qualifiedName);
291
- }
292
215
  willUpdate(changedProperties) {
293
216
  if (changedProperties.has("size") && !isInputSize(this.size)) {
294
217
  this.size = "md";
295
218
  }
296
219
  if (changedProperties.has("rows")) {
297
- if (this.rows == null || !Number.isInteger(this.rows) || this.rows < 1) {
298
- this.rows = DEFAULT_ROWS;
299
- }
220
+ this.rows = normalizeInt(this.rows, DEFAULT_ROWS, 1);
300
221
  }
301
222
  if (changedProperties.has("value") && this.value == null) {
302
223
  this.value = "";
303
224
  }
304
225
  if (changedProperties.has("maxlength")) {
305
- if (this.maxlength == null || !Number.isInteger(this.maxlength) || this.maxlength < 0) {
306
- this.maxlength = void 0;
307
- }
226
+ this.maxlength = normalizeInt(this.maxlength, void 0);
308
227
  }
309
228
  if (changedProperties.has("minlength")) {
310
- if (this.minlength == null || !Number.isInteger(this.minlength) || this.minlength < 0) {
311
- this.minlength = void 0;
312
- }
229
+ this.minlength = normalizeInt(this.minlength, void 0);
313
230
  }
314
231
  }
315
232
  get textareaClasses() {
@@ -326,18 +243,6 @@ var SpectreTextareaElement = class extends LitElement {
326
243
  get nativeTextarea() {
327
244
  return this.querySelector("[data-sp-textarea-native]");
328
245
  }
329
- get forwardedAriaLabel() {
330
- const ariaLabel = this.ariaLabel?.trim();
331
- return ariaLabel ? ariaLabel : void 0;
332
- }
333
- get forwardedAriaLabelledBy() {
334
- const ariaLabelledBy = this.ariaLabelledBy?.trim();
335
- return ariaLabelledBy ? ariaLabelledBy : void 0;
336
- }
337
- get forwardedAriaDescribedBy() {
338
- const ariaDescribedBy = this.ariaDescribedBy?.trim();
339
- return ariaDescribedBy ? ariaDescribedBy : void 0;
340
- }
341
246
  handleInput(event) {
342
247
  const textarea = event.currentTarget;
343
248
  this.value = textarea.value;
@@ -353,57 +258,53 @@ var SpectreTextareaElement = class extends LitElement {
353
258
  this.nativeTextarea?.blur();
354
259
  }
355
260
  render() {
356
- return html`
357
- <textarea
358
- aria-busy=${this.loading ? "true" : "false"}
359
- aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}
360
- aria-invalid=${ifDefined(this.invalid ? "true" : void 0)}
361
- aria-label=${ifDefined(this.forwardedAriaLabel)}
362
- aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}
363
- autocomplete=${ifDefined(this.autocomplete)}
364
- ?autofocus=${this.autofocus}
365
- class=${this.textareaClasses}
366
- data-sp-textarea-native
367
- ?disabled=${this.isDisabled}
368
- inputmode=${ifDefined(this.inputmode)}
369
- ?readonly=${this.readonly}
370
- ?required=${this.required}
371
- id=${ifDefined(this.id || void 0)}
372
- maxlength=${ifDefined(this.maxlength)}
373
- minlength=${ifDefined(this.minlength)}
374
- name=${ifDefined(this.name)}
375
- placeholder=${ifDefined(this.placeholder)}
376
- rows=${this.rows}
377
- title=${ifDefined(this.title || void 0)}
378
- .value=${live(this.value)}
379
- @change=${this.handleChange}
380
- @input=${this.handleInput}
381
- ></textarea>
382
- `;
261
+ return html`<textarea
262
+ aria-busy="${this.loading ? "true" : "false"}"
263
+ aria-describedby="${ifDefined(this.forwardedAriaDescribedBy)}"
264
+ aria-invalid="${ifDefined(this.invalid ? "true" : void 0)}"
265
+ aria-label="${ifDefined(this.forwardedAriaLabel)}"
266
+ aria-labelledby="${ifDefined(this.forwardedAriaLabelledBy)}"
267
+ autocomplete="${ifDefined(this.autocomplete || void 0)}"
268
+ ?autofocus="${this.autofocus}"
269
+ class="${this.textareaClasses}"
270
+ data-sp-textarea-native
271
+ ?disabled="${this.isDisabled}"
272
+ form="${ifDefined(this.form || void 0)}"
273
+ inputmode="${ifDefined(this.inputmode || void 0)}"
274
+ ?readonly="${this.readonly}"
275
+ ?required="${this.required}"
276
+ id="${ifDefined(this.id || void 0)}"
277
+ maxlength="${ifDefined(this.maxlength)}"
278
+ minlength="${ifDefined(this.minlength)}"
279
+ name="${ifDefined(this.name || void 0)}"
280
+ placeholder="${ifDefined(this.placeholder || void 0)}"
281
+ rows="${this.rows}"
282
+ title="${ifDefined(this.title || void 0)}"
283
+ .value="${live(this.value)}"
284
+ @change="${this.handleChange}"
285
+ @input="${this.handleInput}"
286
+ ></textarea>`;
383
287
  }
384
288
  };
385
289
  SpectreTextareaElement.properties = {
386
- ariaLabel: { attribute: "aria-label", type: String },
387
- ariaLabelledBy: { attribute: "aria-labelledby", type: String },
388
- ariaDescribedBy: { attribute: "aria-describedby", type: String },
389
- autocomplete: { type: String },
290
+ autocomplete: { type: String, reflect: true },
390
291
  autofocus: { type: Boolean, reflect: true },
391
292
  disabled: { type: Boolean, reflect: true },
293
+ form: { type: String },
392
294
  fullWidth: { attribute: "full-width", type: Boolean, reflect: true },
393
- inputmode: { type: String },
295
+ inputmode: { type: String, reflect: true },
394
296
  invalid: { type: Boolean, reflect: true },
395
297
  loading: { type: Boolean, reflect: true },
396
- maxlength: { type: Number },
397
- minlength: { type: Number },
398
- name: { type: String },
298
+ maxlength: { type: Number, reflect: true },
299
+ minlength: { type: Number, reflect: true },
300
+ name: { type: String, reflect: true },
399
301
  pill: { type: Boolean, reflect: true },
400
- placeholder: { type: String },
302
+ placeholder: { type: String, reflect: true },
401
303
  readonly: { type: Boolean, reflect: true },
402
304
  required: { type: Boolean, reflect: true },
403
305
  rows: { type: Number },
404
306
  size: { type: String, reflect: true },
405
307
  success: { type: Boolean, reflect: true },
406
- title: { type: String, reflect: true },
407
308
  value: { type: String }
408
309
  };
409
310
  function defineSpectreTextarea(tagName = "sp-textarea") {