kemet-ui 1.1.0 → 1.2.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.
@@ -0,0 +1,239 @@
1
+ import { html, css, LitElement } from 'lit';
2
+
3
+ export default class KemetTrackerStep extends LitElement {
4
+ static get styles() {
5
+ return [
6
+ css`
7
+ :host {
8
+ --kemet-tracker-step-dot-size: 50px;
9
+ --kemet-tracker-step-dot-size-mobile: 25px;
10
+ --kemet-tracker-step-dot-gap: 4px;
11
+ --kemet-tracker-step-standard-line-weight: 1px;
12
+ --kemet-tracker-step-completed-line-weight: 3px;
13
+ --kemet-tracker-step-dot-transition: all 300ms ease-in-out;
14
+
15
+ position: relative;
16
+ width: 100%;
17
+ text-align: center;
18
+ }
19
+
20
+ .dot {
21
+ font-size: var(--kemet-tracker-step-dot-font-size, 90%);
22
+ color: var(--kemet-tracker-step-dot-color, var(--kemet-color-primary));
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ margin: 0 auto;
27
+ position: relative;
28
+ z-index: 1;
29
+ width: var(--kemet-tracker-step-dot-size);
30
+ height: var(--kemet-tracker-step-dot-size);
31
+ border-radius: 100%;
32
+ transition: var(--kemet-tracker-step-dot-transition);
33
+ background-color: var(--kemet-tracker-step-dot-background-color, var(--kemet-color-white));
34
+ }
35
+
36
+ .dot::after {
37
+ content: "";
38
+ width: unset;
39
+ height: unset;
40
+ position: absolute;
41
+ top: var(--kemet-tracker-step-dot-gap);
42
+ left: var(--kemet-tracker-step-dot-gap);
43
+ right: var(--kemet-tracker-step-dot-gap);
44
+ bottom: var(--kemet-tracker-step-dot-gap);
45
+ z-index: -1;
46
+ border-radius: 100%;
47
+ transition: var(--kemet-tracker-step-dot-transition);
48
+ border: var(--kemet-tracker-step-dot-border, 1px solid var(--kemet-color-primary));
49
+ background-color: var(--kemet-tracker-step-dot-fill-color, transparent);
50
+ }
51
+
52
+ :host([completed]) .dot {
53
+ color: var(--kemet-tracker-step-completed-color, var(--kemet-color-white));
54
+ }
55
+
56
+ :host([completed]) .dot::after {
57
+ border: 0;
58
+ background-color: var(--kemet-tracker-step-completed-fill-color, var(--kemet-color-success));
59
+ }
60
+
61
+ :host([current]) .dot.animate {
62
+ color: var(--kemet-tracker-step-current-color, var(--kemet-color-white));
63
+ }
64
+
65
+ :host([current]) .dot.animate::after {
66
+ border: 0;
67
+ background-color: var(--kemet-tracker-step-current-fill-color, var(--kemet-color-primary));
68
+ }
69
+
70
+ :host([mobile]) .dot {
71
+ width: var(--kemet-tracker-step-dot-size-mobile);
72
+ height: var(--kemet-tracker-step-dot-size-mobile);
73
+ }
74
+
75
+ .line {
76
+ display: block;
77
+ position: absolute;
78
+ left: 50%;
79
+ right: 0;
80
+ bottom: 0;
81
+ width: 100%;
82
+
83
+ /* standard */
84
+ top: calc((var(--kemet-tracker-step-dot-size) - var(--kemet-tracker-step-standard-line-weight)) / 2);
85
+ height: var(--kemet-tracker-step-standard-line-weight);
86
+ background-color: var(--kemet-tracker-step-line-color, var(--kemet-color-primary));
87
+ }
88
+
89
+ .line.completed {
90
+ width: 100%;
91
+ transform: scaleX(0);
92
+ transform-origin: left center;
93
+ top: calc((var(--kemet-tracker-step-dot-size) - var(--kemet-tracker-step-completed-line-weight)) / 2);
94
+ height: var(--kemet-tracker-step-completed-line-weight);
95
+ background-color: var(--kemet-tracker-step-completed-line-color, var(--kemet-color-primary));
96
+ animation-name: grow;
97
+ animation-delay: 1s;
98
+ animation-duration: 600ms;
99
+ animation-fill-mode: forwards;
100
+ }
101
+
102
+ :host([mobile]) .line {
103
+ top: calc((var(--kemet-tracker-step-dot-size-mobile) - var(--kemet-tracker-step-standard-line-weight)) / 2);
104
+ }
105
+
106
+ :host([mobile]) .line.completed {
107
+ top: calc((var(--kemet-tracker-step-dot-size-mobile) - var(--kemet-tracker-step-completed-line-weight)) / 2);
108
+ }
109
+
110
+ @keyframes grow {
111
+ from { transform: scaleX(0); }
112
+ to { transform: scaleX(1); }
113
+ }
114
+ `,
115
+ ];
116
+ }
117
+
118
+ static get properties() {
119
+ return {
120
+ /**
121
+ * The current step number
122
+ */
123
+ step: {
124
+ type: Number,
125
+ },
126
+ /**
127
+ * Determines whether or not a step renders as complete
128
+ */
129
+ completed: {
130
+ type: Boolean,
131
+ reflect: true,
132
+ },
133
+ /**
134
+ * Determines whether or not a step renders as the current step
135
+ */
136
+ current: {
137
+ type: Boolean,
138
+ reflect: true,
139
+ },
140
+ /**
141
+ * Is automatically added to the last step
142
+ */
143
+ last: {
144
+ type: Boolean,
145
+ reflect: true,
146
+ },
147
+ /**
148
+ * Determines if a step should render as mobile
149
+ */
150
+ mobile: {
151
+ type: Boolean,
152
+ reflect: true,
153
+ },
154
+ /**
155
+ * Hides the label inside of a dot
156
+ */
157
+ hideDotContent: {
158
+ type: Boolean,
159
+ reflect: true,
160
+ attribute: 'hide-dot-content',
161
+ },
162
+ /**
163
+ * The icon size for the completed check mark
164
+ */
165
+ completedSize: {
166
+ type: Number,
167
+ },
168
+ };
169
+ }
170
+
171
+ constructor() {
172
+ super();
173
+ this.completedSize = 16;
174
+ }
175
+
176
+ firstUpdated() {
177
+ this.tracker = this.closest('kemet-tracker');
178
+ }
179
+
180
+ render() {
181
+ return html`
182
+ ${this.makeLine()}
183
+ ${this.makeCompletedLine()}
184
+ <div class="dot" part="dot">${this.makeDotContent()}</div>
185
+ ${this.makeSlotContent()}
186
+ `;
187
+ }
188
+
189
+ makeLine() {
190
+ if (!this.last) {
191
+ return html`<div class="line" part="line"></div>`;
192
+ }
193
+
194
+ return null;
195
+ }
196
+
197
+ makeCompletedLine() {
198
+ if (this.completed && !this.last) {
199
+ return html`<div class="line completed" part="completed-line" @animationend=${() => this.handleCompletedLineEnd()}></div>`;
200
+ }
201
+
202
+ return null;
203
+ }
204
+
205
+ makeDotContent() {
206
+ if (this.completed && !this.mobile && !this.hideDotContent) {
207
+ return html`
208
+ <kemet-icon icon="check2" size=${this.completedSize}></kemet-icon>
209
+ `;
210
+ }
211
+
212
+ if (!this.mobile && !this.hideDotContent) {
213
+ return html`
214
+ <span>${this.step}/${this.tracker?.total}</span>
215
+ `;
216
+ }
217
+
218
+ return null;
219
+ }
220
+
221
+ makeSlotContent() {
222
+ if (!this.mobile) {
223
+ return html`<slot></slot>`;
224
+ }
225
+
226
+ return null;
227
+ }
228
+
229
+ handleCompletedLineEnd() {
230
+ const currentDot = this.tracker.querySelector('[current]').shadowRoot.querySelector('.dot');
231
+
232
+ if (currentDot) {
233
+ currentDot.classList.add('animate');
234
+ }
235
+ }
236
+ }
237
+
238
+ // eslint-disable-next-line no-unused-expressions
239
+ customElements.get('kemet-tracker-step') || customElements.define('kemet-tracker-step', KemetTrackerStep);
@@ -0,0 +1,76 @@
1
+ import { html, css, LitElement } from 'lit';
2
+
3
+ export default class KemetTracker extends LitElement {
4
+ static get styles() {
5
+ return [
6
+ css`
7
+ :host {
8
+ display: flex;
9
+ justify-content: center;
10
+ align-items: flex-start;
11
+ }
12
+ `,
13
+ ];
14
+ }
15
+
16
+ static get properties() {
17
+ return {
18
+ /**
19
+ * The total number of steps
20
+ */
21
+ total: {
22
+ type: Number,
23
+ },
24
+ /**
25
+ * The point at which the tracker goes from mobile to standard
26
+ */
27
+ breakpoint: {
28
+ type: String,
29
+ },
30
+ };
31
+ }
32
+
33
+ constructor() {
34
+ super();
35
+ this.breakpoint = '767px';
36
+ }
37
+
38
+ firstUpdated() {
39
+ // elements
40
+ this.steps = this.querySelectorAll('kemet-tracker-step');
41
+
42
+ // methods exe
43
+ this.isMobile();
44
+
45
+ // events
46
+ window.addEventListener('resize', () => {
47
+ this.isMobile();
48
+ });
49
+ }
50
+
51
+ render() {
52
+ return html`<slot @slotchange=${() => this.handleSlotChange()}></slot>`;
53
+ }
54
+
55
+ handleSlotChange() {
56
+ this.total = this.steps.length;
57
+
58
+ this.steps.forEach((step, index) => {
59
+ step.step = index + 1;
60
+ if (step.step === this.total) {
61
+ step.last = true;
62
+ }
63
+ });
64
+ }
65
+
66
+ isMobile() {
67
+ const mediaQuery = window.matchMedia(`(max-width: ${this.breakpoint})`);
68
+
69
+ this.steps.forEach((step) => {
70
+ step.mobile = mediaQuery.matches;
71
+ });
72
+ }
73
+ }
74
+
75
+ // eslint-disable-next-line no-unused-expressions
76
+ customElements.get('kemet-tracker') || customElements.define('kemet-tracker', KemetTracker);