kemet-ui 0.2.0 → 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 (87) hide show
  1. package/custom-elements.json +6323 -831
  2. package/dist/components/kemet-accordion/kemet-accordion-panel.js +178 -0
  3. package/dist/components/kemet-accordion/kemet-accordion.js +139 -0
  4. package/dist/components/kemet-badge/kemet-badge.js +102 -0
  5. package/dist/components/kemet-button/kemet-button.js +230 -0
  6. package/dist/components/kemet-carousel/kemet-carousel-current.js +36 -0
  7. package/dist/components/kemet-carousel/kemet-carousel-first.js +47 -0
  8. package/dist/components/kemet-carousel/kemet-carousel-last.js +47 -0
  9. package/dist/components/{kemet-carousel-link.js → kemet-carousel/kemet-carousel-link.js} +7 -2
  10. package/dist/components/{kemet-carousel-next.js → kemet-carousel/kemet-carousel-next.js} +3 -2
  11. package/dist/components/{kemet-carousel-prev.js → kemet-carousel/kemet-carousel-prev.js} +2 -1
  12. package/dist/components/kemet-carousel/kemet-carousel-slide.js +51 -0
  13. package/dist/components/kemet-carousel/kemet-carousel-total.js +36 -0
  14. package/dist/components/kemet-carousel/kemet-carousel.js +492 -0
  15. package/dist/components/kemet-checkbox/kemet-checkbox.js +298 -0
  16. package/dist/components/kemet-combo/kemet-combo.js +207 -0
  17. package/dist/components/kemet-count/kemet-count.js +112 -0
  18. package/dist/components/{kemet-draggable.js → kemet-draggable/kemet-draggable.js} +19 -6
  19. package/dist/components/{kemet-drawer.js → kemet-drawer/kemet-drawer.js} +38 -15
  20. package/dist/components/{kemet-drawer.styles.js → kemet-drawer/kemet-drawer.styles.js} +6 -0
  21. package/dist/components/kemet-field/kemet-field.js +233 -0
  22. package/dist/components/{kemet-flipcard-trigger.js → kemet-flipcard/kemet-flipcard-trigger.js} +4 -5
  23. package/dist/components/{kemet-flipcard.js → kemet-flipcard/kemet-flipcard.js} +26 -3
  24. package/dist/components/{kemet-icon.js → kemet-icon/kemet-icon.js} +19 -3
  25. package/dist/components/kemet-input/kemet-input.js +650 -0
  26. package/dist/components/kemet-modal/kemet-modal-close.js +38 -0
  27. package/dist/components/kemet-modal/kemet-modal.js +140 -0
  28. package/dist/components/{kemet-modal.styles.js → kemet-modal/kemet-modal.styles.js} +14 -2
  29. package/dist/components/{kemet-popover-close.js → kemet-popover/kemet-popover-close.js} +1 -1
  30. package/dist/components/{kemet-popover.effects.styles.js → kemet-popover/kemet-popover.effects.styles.js} +0 -0
  31. package/dist/components/{kemet-popover.js → kemet-popover/kemet-popover.js} +75 -12
  32. package/dist/components/{kemet-popover.tooltip.styles.js → kemet-popover/kemet-popover.tooltip.styles.js} +0 -0
  33. package/dist/components/kemet-radio/kemet-radio.js +214 -0
  34. package/dist/components/kemet-radio/kemet-radios.js +218 -0
  35. package/dist/components/{kemet-rotator.js → kemet-rotator/kemet-rotator.js} +23 -4
  36. package/dist/components/{kemet-scroll-link.js → kemet-scroll-link/kemet-scroll-link.js} +21 -2
  37. package/dist/components/{kemet-scroll-nav.js → kemet-scroll-nav/kemet-scroll-nav.js} +25 -2
  38. package/dist/components/{kemet-scroll-snap-paginator.js → kemet-scroll-snap/kemet-scroll-snap-paginator.js} +68 -26
  39. package/dist/components/{kemet-scroll-snap-slide.js → kemet-scroll-snap/kemet-scroll-snap-slide.js} +23 -13
  40. package/dist/components/{kemet-scroll-snap.js → kemet-scroll-snap/kemet-scroll-snap.js} +31 -16
  41. package/dist/components/kemet-select/kemet-option.js +45 -0
  42. package/dist/components/kemet-select/kemet-select.js +365 -0
  43. package/dist/components/{kemet-svg.js → kemet-svgs/kemet-svg.js} +18 -2
  44. package/dist/components/{kemet-svgs.js → kemet-svgs/kemet-svgs.js} +7 -3
  45. package/dist/components/{kemet-tab-panel.js → kemet-tabs/kemet-tab-panel.js} +15 -1
  46. package/dist/components/{kemet-tab.js → kemet-tabs/kemet-tab.js} +48 -1
  47. package/dist/components/kemet-tabs/kemet-tabs.js +556 -0
  48. package/dist/components/kemet-tabs/kemet-tabs.styles.js +200 -0
  49. package/dist/components/kemet-textarea/kemet-textarea.js +395 -0
  50. package/dist/components/kemet-toggle/kemet-toggle.js +225 -0
  51. package/dist/kemet-components.cjs +7251 -2465
  52. package/dist/kemet-components.js +7237 -2440
  53. package/dist/kemet-components.min.js +1641 -355
  54. package/dist/styles/components/_config.scss +4 -0
  55. package/dist/styles/components/accordion.scss +9 -0
  56. package/dist/styles/{scss/components → components}/drawer.scss +2 -2
  57. package/dist/styles/components/modal.scss +8 -0
  58. package/dist/styles/components/scrollsnap.scss +11 -0
  59. package/dist/styles/core/_config.scss +354 -0
  60. package/dist/styles/{scss/core → core}/_helpers.scss +113 -2
  61. package/dist/styles/{scss/core → core}/attributes.scss +16 -0
  62. package/dist/styles/core/base.scss +38 -0
  63. package/dist/styles/{scss/core → core}/layout.scss +6 -5
  64. package/dist/styles/kemet.components.css +12 -339
  65. package/dist/styles/kemet.components.css.map +1 -1
  66. package/dist/styles/{scss/kemet.components.scss → kemet.components.scss} +0 -3
  67. package/dist/styles/kemet.core.css +2371 -503
  68. package/dist/styles/kemet.core.css.map +1 -1
  69. package/dist/styles/kemet.core.scss +3 -0
  70. package/dist/utilities/controllers/forms.js +121 -0
  71. package/package.json +37 -57
  72. package/dist/components/kemet-accordion.js +0 -106
  73. package/dist/components/kemet-carousel-slide.js +0 -83
  74. package/dist/components/kemet-carousel.js +0 -236
  75. package/dist/components/kemet-modal-close.js +0 -19
  76. package/dist/components/kemet-modal.js +0 -75
  77. package/dist/components/kemet-ratio.js +0 -61
  78. package/dist/components/kemet-tabs.js +0 -350
  79. package/dist/styles/scss/components/_config.scss +0 -29
  80. package/dist/styles/scss/components/accordion.scss +0 -58
  81. package/dist/styles/scss/components/carousel.scss +0 -64
  82. package/dist/styles/scss/components/flipcard.scss +0 -14
  83. package/dist/styles/scss/components/modal.scss +0 -12
  84. package/dist/styles/scss/components/scrollsnap.scss +0 -68
  85. package/dist/styles/scss/components/tabs.scss +0 -73
  86. package/dist/styles/scss/core/_config.scss +0 -197
  87. package/dist/styles/scss/kemet.core.scss +0 -4
@@ -0,0 +1,298 @@
1
+ import { html, css, LitElement } from 'lit';
2
+ import { ifDefined } from 'lit/directives/if-defined.js';
3
+ import { live } from 'lit/directives/live.js';
4
+ import { FormSubmitController } from '../../utilities/controllers/forms.js';
5
+
6
+ export default class KemetCheckbox extends LitElement {
7
+ static get styles() {
8
+ return [
9
+ css`
10
+ *,
11
+ *::before,
12
+ *::after {
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ :host {
17
+ display: inline-block;
18
+ }
19
+
20
+ :host([disabled]) {
21
+ opacity: 0.5;
22
+ }
23
+
24
+ label {
25
+ display: inline-flex;
26
+ gap: 0.5rem;
27
+ align-items: center;
28
+ }
29
+
30
+ input {
31
+ cursor: pointer;
32
+ margin: 0;
33
+ padding: 0;
34
+ width: var(--kemet-checkbox-size, 18px);
35
+ height: var(--kemet-checkbox-size, 18px);
36
+ position: absolute;
37
+ opacity: 0;
38
+ }
39
+
40
+ button {
41
+ margin: 0;
42
+ border: none;
43
+ background: none;
44
+ }
45
+
46
+ [part='checkbox'] {
47
+ color: var(--kemet-checkbox-color, var(--kemet-color-primary));
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ width: var(--kemet-checkbox-size, 18px);
52
+ height: var(--kemet-checkbox-size, 18px);
53
+ border: var(--kemet-checkbox-border, 1px solid var(--kemet-color-primary));
54
+ }
55
+
56
+ :host([rounded]) [part='checkbox'] {
57
+ border-radius: var(--kemet-checkbox-border-radius, 4px);
58
+ }
59
+
60
+ :host([filled][checked]) [part='checkbox'],
61
+ :host([filled][indeterminate]) [part='checkbox'] {
62
+ border: none;
63
+ background-color: var(--kemet-checkbox-filled-background-color, var(--kemet-color-primary));
64
+ }
65
+
66
+ [part='mark'] {
67
+ display: flex;
68
+ width: calc(var(--kemet-checkbox-size, 18px) - 4px);
69
+ height: calc(var(--kemet-checkbox-size, 18px) - 4px);
70
+ }
71
+
72
+ :host([filled][checked]) [part='mark'],
73
+ :host([filled][indeterminate]) [part='mark'] {
74
+ color: var(--kemet-checkbox-filled-color, var(--kemet-color-white));
75
+ }
76
+
77
+ [part='message'] {
78
+ display: block;
79
+ margin-top: 0.5rem;
80
+ }
81
+
82
+ :host([status='error']) [part='message'] {
83
+ color: var(--kemet-color-error);
84
+ }
85
+
86
+ :host([status='warning']) [part='message'] {
87
+ color: var(--kemet-color-error);
88
+ }
89
+ `,
90
+ ];
91
+ }
92
+
93
+ static get properties() {
94
+ return {
95
+ label: {
96
+ type: String,
97
+ },
98
+ checked: {
99
+ type: Boolean,
100
+ reflect: true,
101
+ },
102
+ indeterminate: {
103
+ type: Boolean,
104
+ reflect: true,
105
+ },
106
+ name: {
107
+ type: String,
108
+ },
109
+ value: {
110
+ type: String,
111
+ },
112
+ disabled: {
113
+ type: Boolean,
114
+ reflect: true,
115
+ },
116
+ required: {
117
+ type: Boolean,
118
+ reflect: true,
119
+ },
120
+ focused: {
121
+ type: Boolean,
122
+ reflect: true,
123
+ },
124
+ rounded: {
125
+ type: Boolean,
126
+ reflect: true,
127
+ },
128
+ filled: {
129
+ type: Boolean,
130
+ reflect: true,
131
+ },
132
+ status: {
133
+ type: String,
134
+ reflect: true,
135
+ },
136
+ message: {
137
+ type: String,
138
+ },
139
+ };
140
+ }
141
+
142
+ constructor() {
143
+ super();
144
+
145
+ // managed properties
146
+ this.label = '';
147
+ this.name = 'checkbox';
148
+ this.disabled = false;
149
+ this.required = false;
150
+ this.rounded = false;
151
+ this.filled = false;
152
+ this.status = 'standard';
153
+
154
+ /**
155
+ * Used only for form reactive controller
156
+ */
157
+ this.formSubmitController = new FormSubmitController(this);
158
+ }
159
+
160
+ firstUpdated() {
161
+ this.input = this.shadowRoot.querySelector('input');
162
+ }
163
+
164
+ render() {
165
+ return html`
166
+ <label part="label">
167
+ <input
168
+ type="checkbox"
169
+ name=${ifDefined(this.name)}
170
+ .value=${this.value}
171
+ .indeterminate=${live(this.indeterminate)}
172
+ .checked=${live(this.checked)}
173
+ .disabled=${this.disabled}
174
+ .required=${this.required}
175
+ aria-checked=${this.checked ? 'true' : 'false'}
176
+ @click=${() => this.handleClick()}
177
+ @blur=${() => this.handleBlur()}
178
+ @focus=${() => this.handleFocus()}
179
+ @change=${() => this.handleChange()}
180
+ />
181
+ <button part="checkbox" aria-label=${this.label}>
182
+ ${this.makeCheckMark()}
183
+ </button>
184
+ <span part="text">${this.label}</span>
185
+ </label>
186
+ ${this.makeMessage()}
187
+ `;
188
+ }
189
+
190
+ click() {
191
+ this.input.click();
192
+ }
193
+
194
+ handleClick() {
195
+ this.checked = !this.checked;
196
+ this.indeterminate = false;
197
+
198
+ /**
199
+ * Fires when the state of the checkbox changes
200
+ */
201
+ this.dispatchEvent(
202
+ new CustomEvent('kemet-checkbox-change', {
203
+ bubbles: true,
204
+ composed: true,
205
+ detail: this,
206
+ }),
207
+ );
208
+ }
209
+
210
+ handleBlur() {
211
+ this.focused = false;
212
+
213
+ /**
214
+ * Fires when the checkbox loses or receives focus
215
+ */
216
+ this.dispatchEvent(
217
+ new CustomEvent('kemet-checkbox-focused', {
218
+ bubbles: true,
219
+ composed: true,
220
+ detail: false,
221
+ }),
222
+ );
223
+ }
224
+
225
+ handleFocus() {
226
+ this.focused = true;
227
+ /**
228
+ * Fires when the checkbox loses or receives focus
229
+ */
230
+ this.dispatchEvent(
231
+ new CustomEvent('kemet-checkbox-focused', {
232
+ bubbles: true,
233
+ composed: true,
234
+ detail: true,
235
+ }),
236
+ );
237
+ }
238
+
239
+ handleChange() {
240
+ this.value = this.checked;
241
+
242
+ if (this.input.checkValidity()) {
243
+ this.status = 'standard';
244
+ }
245
+ }
246
+
247
+ makeMessage() {
248
+ if (this.status === 'error' || this.status === 'warning') {
249
+ return html`<span part="message">${this.message}</span>`;
250
+ }
251
+
252
+ return null;
253
+ }
254
+
255
+ makeCheckMark() {
256
+ if (this.checked) {
257
+ return html`
258
+ <span part="mark">
259
+ <svg viewBox="0 0 16 16">
260
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
261
+ <g stroke="currentColor" stroke-width="2">
262
+ <g transform="translate(3.428571, 3.428571)">
263
+ <path d="M0,5.71428571 L3.42857143,9.14285714"></path>
264
+ <path d="M9.14285714,0 L3.42857143,9.14285714"></path>
265
+ </g>
266
+ </g>
267
+ </g>
268
+ </svg>
269
+ </span>
270
+ `;
271
+ }
272
+
273
+ if (!this.checked && this.indeterminate) {
274
+ return html`
275
+ <span part="mark">
276
+ <svg viewBox="0 0 16 16">
277
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
278
+ <g stroke="currentColor" stroke-width="2">
279
+ <g transform="translate(2.285714, 6.857143)">
280
+ <path d="M10.2857143,1.14285714 L1.14285714,1.14285714"></path>
281
+ </g>
282
+ </g>
283
+ </g>
284
+ </svg>
285
+ </span>
286
+ `;
287
+ }
288
+
289
+ return null;
290
+ }
291
+
292
+ checkValidity() {
293
+ return this.input.checkValidity();
294
+ }
295
+ }
296
+
297
+ // eslint-disable-next-line no-unused-expressions
298
+ customElements.get('kemet-checkbox') || customElements.define('kemet-checkbox', KemetCheckbox);
@@ -0,0 +1,207 @@
1
+ import { html, css, LitElement } from 'lit';
2
+
3
+ export default class KemetCombo extends LitElement {
4
+ static get styles() {
5
+ return [
6
+ css`
7
+ :host {
8
+ opacity: 0;
9
+ width: var(--kemet-combo-width, calc(100% - 2px));
10
+ margin: var(--kemet-combo-margin, 1rem auto);
11
+ pointer-events: none;
12
+ display: block;
13
+ position: relative;
14
+ transition: opacity 0.3s ease-in-out;
15
+ }
16
+
17
+ :host([show]) {
18
+ opacity: 1;
19
+ pointer-events: auto;
20
+ }
21
+
22
+ ul {
23
+ width: 100%;
24
+ max-height: var(--kemet-combo-max-height, calc(5 * 3rem));
25
+ position: absolute;
26
+ z-index: 1;
27
+ list-style: none;
28
+ margin: 0;
29
+ padding: 0;
30
+ overflow-y: scroll;
31
+ border: var(--kemet-combo-border, 1px solid var(--kemet-color-primary));
32
+ border-radius: var(--kemet-combo-border-radius, var(--kemet-border-radius));
33
+ background-color: var(--kemet-combo-background-color, var(--kemet-color-white));
34
+ box-shadow: var(--kemet-combo-shadow, 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1));
35
+ }
36
+ li {
37
+ line-height: 3rem;
38
+ padding: 0 1.5rem;
39
+ cursor: pointer;
40
+ }
41
+ li:hover,
42
+ li:focus {
43
+ color: var(--kemet-combo-hover-color, var(--kemet-color-white));
44
+ outline: none;
45
+ background-color: var(--kemet-combo-hover-background-color, var(--kemet-color-primary));
46
+ }
47
+ `,
48
+ ];
49
+ }
50
+
51
+ static get properties() {
52
+ return {
53
+ /**
54
+ * Uniquely identifies the component. Should match the slug used in a control.
55
+ */
56
+ slug: {
57
+ type: String,
58
+ },
59
+ /**
60
+ * An array of items listed for the combo box
61
+ */
62
+ options: {
63
+ type: Array,
64
+ },
65
+ /**
66
+ * Used internally
67
+ */
68
+ filteredOptions: {
69
+ type: Array,
70
+ },
71
+ /**
72
+ * Controls the display of the combo box
73
+ */
74
+ show: {
75
+ type: Boolean,
76
+ reflect: true,
77
+ },
78
+ };
79
+ }
80
+
81
+ firstUpdated() {
82
+ // standard properties
83
+ this.field = this.closest('kemet-field');
84
+ this.input = this.field.querySelector('[slot="input"]');
85
+
86
+ // managed properties
87
+ this.slug = this.field.slug;
88
+
89
+ // events listeners
90
+ this.input.addEventListener('kemet-input-input', this.handleInput.bind(this));
91
+ this.input.addEventListener('keydown', event => this.handleInputKeyDown(event));
92
+ }
93
+
94
+ render() {
95
+ return html`
96
+ <div
97
+ role="combobox"
98
+ aria-expanded=${this.show}
99
+ aria-controls="${this.slug}-listbox"
100
+ aria-haspopup="listbox"
101
+ id="${this.slug}-combobox"
102
+ aria-label="${this.field.label}"
103
+ >
104
+ <ul role="listbox" aria-labelledby="${this.slug}-label" id="${this.slug}-listbox">
105
+ ${this.makeOptions()}
106
+ </ul>
107
+ </div>
108
+ `;
109
+ }
110
+
111
+ makeOptions() {
112
+ if (this.input) {
113
+ this.filteredOptions = this.options.filter(
114
+ option => option.toLowerCase().indexOf(this.input.value.toLowerCase()) !== -1,
115
+ );
116
+
117
+ const options = this.filteredOptions.map(
118
+ (option, index) => html`<li
119
+ id="${this.slug}-option-${index}"
120
+ role="option"
121
+ tabindex="0"
122
+ aria-selected="false"
123
+ @click=${event => this.handleSelection(event)}
124
+ @keydown=${event => this.handleOptionKeyDown(event)}
125
+ >
126
+ ${option}
127
+ </li>`,
128
+ );
129
+
130
+ return options;
131
+ }
132
+
133
+ return null;
134
+ }
135
+
136
+ handleInput(event) {
137
+ this.makeOptions();
138
+
139
+ if (event.detail.length > 0) {
140
+ this.show = true;
141
+ } else {
142
+ this.show = false;
143
+ }
144
+ }
145
+
146
+ handleSelection(event) {
147
+ this.input.value = event.target.innerText;
148
+ this.show = false;
149
+
150
+ /**
151
+ * Fires when a selection has been made
152
+ */
153
+ this.dispatchEvent(
154
+ new CustomEvent('kemet-combo-selection', {
155
+ bubbles: true,
156
+ composed: true,
157
+ detail: event.target.getAttribute('id'),
158
+ }),
159
+ );
160
+ }
161
+
162
+ handleOptionKeyDown(event) {
163
+ event.preventDefault();
164
+
165
+ if (event.code === 'ArrowDown') {
166
+ const next = event.target.nextElementSibling;
167
+
168
+ if (next) {
169
+ next.focus();
170
+ } else {
171
+ this.shadowRoot.querySelector('li').focus();
172
+ }
173
+ }
174
+
175
+ if (event.code === 'ArrowUp') {
176
+ const previous = event.target.previousElementSibling;
177
+
178
+ if (previous) {
179
+ previous.focus();
180
+ } else {
181
+ this.shadowRoot.querySelector('li:last-child').focus();
182
+ }
183
+ }
184
+
185
+ if (event.code === 'Escape' || event.code === 'Tab') {
186
+ this.show = false;
187
+ this.input.focus();
188
+ }
189
+
190
+ if (event.code === 'Enter' || event.code === 'Space') {
191
+ this.handleSelection(event);
192
+ }
193
+ }
194
+
195
+ handleInputKeyDown(event) {
196
+ if (event.code === 'ArrowDown') {
197
+ this.shadowRoot.querySelector('li').focus();
198
+ }
199
+
200
+ if (event.code === 'Escape') {
201
+ this.show = false;
202
+ }
203
+ }
204
+ }
205
+
206
+ // eslint-disable-next-line no-unused-expressions
207
+ customElements.get('kemet-combo') || customElements.define('kemet-combo', KemetCombo);
@@ -0,0 +1,112 @@
1
+ import { html, css, LitElement } from 'lit';
2
+
3
+ export default class KemetCount extends LitElement {
4
+ static get styles() {
5
+ return [
6
+ css`
7
+ :host {
8
+ display: block;
9
+ font-size: var(--kemet-count-font-size, 90%);
10
+ margin-top: 0.8rem;
11
+ }
12
+ `,
13
+ ];
14
+ }
15
+
16
+ static get properties() {
17
+ return {
18
+ /**
19
+ * The text label shown to users
20
+ */
21
+ message: {
22
+ type: String,
23
+ },
24
+ /**
25
+ * The number of characters remaining
26
+ */
27
+ remaining: {
28
+ type: Number,
29
+ },
30
+ /**
31
+ * The maximum number of characters allowed
32
+ */
33
+ limit: {
34
+ type: Number,
35
+ },
36
+ /**
37
+ * Set to true if the field should validate as soon as the character limit is reached
38
+ */
39
+ validateImmediately: {
40
+ type: Boolean,
41
+ attribute: 'validate-immediately',
42
+ },
43
+ };
44
+ }
45
+
46
+ firstUpdated() {
47
+ this.field = this.closest('kemet-field');
48
+ this.inputSlot = this.field.querySelector('[slot="input"]');
49
+
50
+ this.remaining = this.limit - this.field.length;
51
+
52
+ this.field.addEventListener('kemet-field-input', (event) => {
53
+ this.remaining = this.limit - event.detail;
54
+
55
+ const nativeElement = this.input || this.textarea;
56
+
57
+ if (nativeElement) {
58
+ if (this.remaining < 0) {
59
+ nativeElement.validity.passedLimit = true;
60
+
61
+ if (this.validateImmediately) {
62
+ this.inputSlot.status = 'error';
63
+ this.inputSlot.invalid = true;
64
+
65
+ /**
66
+ * Fires when there's a change in status.
67
+ */
68
+ this.dispatchEvent(
69
+ new CustomEvent('kemet-count-status', {
70
+ bubbles: true,
71
+ composed: true,
72
+ detail: {
73
+ status: 'error',
74
+ validity: nativeElement.validity,
75
+ element: this.inputSlot,
76
+ },
77
+ }),
78
+ );
79
+ }
80
+ } else {
81
+ this.inputSlot.status = 'standard';
82
+ nativeElement.checkValidity();
83
+
84
+ /**
85
+ * Fires when there's a change in status.
86
+ */
87
+ this.dispatchEvent(
88
+ new CustomEvent('kemet-count-status', {
89
+ bubbles: true,
90
+ composed: true,
91
+ detail: {
92
+ status: 'standard',
93
+ validity: nativeElement.validity,
94
+ element: this.inputSlot,
95
+ },
96
+ }),
97
+ );
98
+ }
99
+ }
100
+ });
101
+
102
+ this.input = this.inputSlot.shadowRoot.querySelector('input');
103
+ this.textarea = this.inputSlot.shadowRoot.querySelector('textarea');
104
+ }
105
+
106
+ render() {
107
+ return html`${this.remaining} ${this.message}`;
108
+ }
109
+ }
110
+
111
+ // eslint-disable-next-line no-unused-expressions
112
+ customElements.get('kemet-count') || customElements.define('kemet-count', KemetCount);
@@ -1,6 +1,6 @@
1
1
  import { html, css, LitElement } from 'lit';
2
2
 
3
- export class KemetDraggable extends LitElement {
3
+ export default class KemetDraggable extends LitElement {
4
4
  static get styles() {
5
5
  return css`
6
6
  :host {
@@ -15,15 +15,28 @@ export class KemetDraggable extends LitElement {
15
15
 
16
16
  static get properties() {
17
17
  return {
18
+ /**
19
+ * A unique identifier used to store the element's position in local storage.
20
+ */
18
21
  memory: {
19
22
  type: String,
20
23
  },
24
+ /**
25
+ * The elements top position in pixels.
26
+ */
21
27
  top: {
22
28
  type: String,
23
29
  },
30
+ /**
31
+ * The element's left position in pixels.
32
+ */
24
33
  left: {
25
34
  type: String,
26
35
  },
36
+ /**
37
+ * If set to true, will measure the width and height
38
+ * of the element's content and apply it to the host element.
39
+ */
27
40
  measure: {
28
41
  type: Boolean,
29
42
  },
@@ -37,17 +50,16 @@ export class KemetDraggable extends LitElement {
37
50
  this.top = 'auto';
38
51
  this.left = 'auto';
39
52
  this.measure = false;
53
+ }
40
54
 
41
- // js property defaults
55
+ firstUpdated() {
56
+ // standard properties
42
57
  this.position1 = 0;
43
58
  this.position2 = 0;
44
59
  this.position3 = 0;
45
60
  this.position4 = 0;
46
61
  this.mouseMove = event => this.drag(event);
47
62
  this.mouseUp = () => this.stopDrag();
48
- }
49
-
50
- firstUpdated() {
51
63
  this.draggableElement = this.shadowRoot.getElementById('draggable');
52
64
 
53
65
  const savedPosition = JSON.parse(localStorage.getItem(this.memory));
@@ -126,4 +138,5 @@ export class KemetDraggable extends LitElement {
126
138
  }
127
139
  }
128
140
 
129
- window.customElements.define('kemet-draggable', KemetDraggable);
141
+ // eslint-disable-next-line no-unused-expressions
142
+ customElements.get('kemet-draggable') || customElements.define('kemet-draggable', KemetDraggable);