@reliability-design/web 1.0.3 → 1.0.6

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 (114) hide show
  1. package/dist/components/rel-accordion/README.md +132 -0
  2. package/dist/components/rel-accordion/rel-accordion.ts +43 -16
  3. package/dist/components/rel-alert/README.md +141 -0
  4. package/dist/components/rel-alert/rel-alert.ts +18 -7
  5. package/dist/components/rel-avatar/README.md +119 -0
  6. package/dist/components/rel-badge/README.md +86 -0
  7. package/dist/components/rel-badge/rel-badge.ts +6 -6
  8. package/dist/components/rel-breadcrumb/README.md +102 -0
  9. package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +12 -6
  10. package/dist/components/rel-button/README.md +130 -0
  11. package/dist/components/rel-calendar/README.md +109 -0
  12. package/dist/components/rel-calendar/index.ts +1 -0
  13. package/dist/components/rel-calendar/rel-calendar.ts +467 -0
  14. package/dist/components/rel-card/README.md +94 -0
  15. package/dist/components/rel-card/rel-card.ts +12 -3
  16. package/dist/components/rel-cardmedia/README.md +127 -0
  17. package/dist/components/rel-cardmedia/rel-cardmedia.ts +14 -4
  18. package/dist/components/rel-carousel/README.md +166 -0
  19. package/dist/components/rel-carousel/index.ts +1 -0
  20. package/dist/components/rel-carousel/rel-carousel.ts +469 -0
  21. package/dist/components/rel-chart/README.md +286 -0
  22. package/dist/components/rel-chart/index.ts +1 -0
  23. package/dist/components/rel-chart/rel-chart.ts +736 -0
  24. package/dist/components/rel-checkbox/README.md +77 -0
  25. package/dist/components/rel-checkbox/rel-checkbox.ts +18 -10
  26. package/dist/components/rel-chip/README.md +114 -0
  27. package/dist/components/rel-chip/rel-chip.ts +20 -4
  28. package/dist/components/rel-container/README.md +99 -0
  29. package/dist/components/rel-date-picker/README.md +253 -0
  30. package/dist/components/rel-date-picker/index.ts +1 -0
  31. package/dist/components/rel-date-picker/rel-date-picker.ts +916 -0
  32. package/dist/components/rel-divider/README.md +100 -0
  33. package/dist/components/rel-drawer/README.md +200 -0
  34. package/dist/components/rel-drawer/index.ts +1 -0
  35. package/dist/components/rel-drawer/rel-drawer.ts +621 -0
  36. package/dist/components/rel-kbd/README.md +151 -0
  37. package/dist/components/rel-kbd/rel-kbd.ts +118 -0
  38. package/dist/components/rel-layout/README.md +88 -0
  39. package/dist/components/rel-menu/README.md +151 -0
  40. package/dist/components/rel-menu/rel-menu.ts +18 -10
  41. package/dist/components/rel-menubar/README.md +329 -0
  42. package/dist/components/rel-menubar/index.ts +2 -0
  43. package/dist/components/rel-menubar/rel-menubar-menu.ts +16 -0
  44. package/dist/components/rel-menubar/rel-menubar.ts +576 -0
  45. package/dist/components/rel-nav-menu/README.md +289 -0
  46. package/dist/components/rel-nav-menu/index.ts +3 -0
  47. package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +143 -0
  48. package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +53 -0
  49. package/dist/components/rel-nav-menu/rel-nav-menu.ts +331 -0
  50. package/dist/components/rel-navbar/README.md +126 -0
  51. package/dist/components/rel-navbar/rel-navbar.ts +91 -0
  52. package/dist/components/rel-otp/README.md +440 -0
  53. package/dist/components/rel-otp/index.ts +1 -0
  54. package/dist/components/rel-otp/rel-otp.ts +504 -0
  55. package/dist/components/rel-pagination/README.md +410 -0
  56. package/dist/components/rel-pagination/index.ts +1 -0
  57. package/dist/components/rel-pagination/rel-pagination.ts +376 -0
  58. package/dist/components/rel-popover/README.md +568 -0
  59. package/dist/components/rel-popover/index.ts +2 -0
  60. package/dist/components/rel-popover/rel-popover-content.ts +55 -0
  61. package/dist/components/rel-popover/rel-popover.ts +327 -0
  62. package/dist/components/rel-progress/README.md +110 -0
  63. package/dist/components/rel-progress/rel-progress.ts +32 -5
  64. package/dist/components/rel-quote-page/README.md +166 -0
  65. package/dist/components/rel-quote-page/rel-quote-page.ts +816 -0
  66. package/dist/components/rel-radio/README.md +120 -0
  67. package/dist/components/rel-radio/rel-radio.ts +13 -5
  68. package/dist/components/rel-resizable/README.md +140 -0
  69. package/dist/components/rel-resizable/index.ts +3 -0
  70. package/dist/components/rel-resizable/rel-resizable-group.ts +374 -0
  71. package/dist/components/rel-resizable/rel-resizable-handle.ts +149 -0
  72. package/dist/components/rel-resizable/rel-resizable-panel.ts +47 -0
  73. package/dist/components/rel-segmented-button/README.md +141 -0
  74. package/dist/components/rel-segmented-button/rel-segmented-button.ts +18 -13
  75. package/dist/components/rel-select/README.md +107 -0
  76. package/dist/components/rel-select/rel-select.ts +14 -14
  77. package/dist/components/rel-sheet/README.md +224 -0
  78. package/dist/components/rel-sheet/rel-sheet.ts +683 -0
  79. package/dist/components/rel-sidebar/README.md +209 -0
  80. package/dist/components/rel-sidebar/rel-sidebar.ts +1158 -0
  81. package/dist/components/rel-slider/README.md +135 -0
  82. package/dist/components/rel-slider/rel-slider.ts +19 -7
  83. package/dist/components/rel-snackbar/README.md +134 -0
  84. package/dist/components/rel-snackbar/rel-snackbar.ts +67 -2
  85. package/dist/components/rel-stepper/README.md +160 -0
  86. package/dist/components/rel-stepper/rel-stepper.ts +6 -6
  87. package/dist/components/rel-switch/README.md +102 -0
  88. package/dist/components/rel-switch/rel-switch.ts +15 -6
  89. package/dist/components/rel-tab/README.md +163 -0
  90. package/dist/components/rel-tab/rel-tab.ts +36 -14
  91. package/dist/components/rel-table/README.md +178 -0
  92. package/dist/components/rel-table/rel-table-body.ts +16 -0
  93. package/dist/components/rel-table/rel-table-caption.ts +22 -0
  94. package/dist/components/rel-table/rel-table-cell.ts +49 -0
  95. package/dist/components/rel-table/rel-table-footer.ts +18 -0
  96. package/dist/components/rel-table/rel-table-head.ts +33 -0
  97. package/dist/components/rel-table/rel-table-header.ts +16 -0
  98. package/dist/components/rel-table/rel-table-row.ts +32 -0
  99. package/dist/components/rel-table/rel-table.ts +47 -0
  100. package/dist/components/rel-textfield/README.md +90 -0
  101. package/dist/components/rel-textfield/rel-textfield.ts +35 -19
  102. package/dist/components/rel-toast/README.md +148 -0
  103. package/dist/components/rel-toast/rel-toast.ts +32 -14
  104. package/dist/components/rel-tooltip/README.md +103 -0
  105. package/dist/components/rel-tooltip/rel-tooltip.ts +9 -9
  106. package/dist/index.d.mts +836 -1
  107. package/dist/index.d.ts +836 -1
  108. package/dist/index.js +10658 -1493
  109. package/dist/index.js.map +1 -1
  110. package/dist/index.mjs +10616 -1499
  111. package/dist/index.mjs.map +1 -1
  112. package/dist/styles/vars.css +293 -183
  113. package/dist/{vars-6ZIUPIU4.css → vars-ITL2K3KO.css} +293 -183
  114. package/package.json +1 -1
@@ -0,0 +1,469 @@
1
+ import { LitElement, html, css, nothing } from "lit";
2
+ import { customElement, property, state, query } from "lit/decorators.js";
3
+
4
+ @customElement("rel-carousel")
5
+ export class RelCarousel extends LitElement {
6
+ @property({ type: Number, reflect: true }) value = 0;
7
+ @property({ type: Boolean }) loop = false;
8
+ @property({ type: Boolean }) autoplay = false;
9
+ @property({ type: Number }) interval = 5000;
10
+ @property({ type: Boolean, attribute: "pause-on-hover" }) pauseOnHover = true;
11
+ @property({ type: Boolean, attribute: "show-buttons" }) showButtons = true;
12
+ @property({ type: Boolean, attribute: "show-dots" }) showDots = true;
13
+ @property({ type: String }) orientation: "horizontal" | "vertical" = "horizontal";
14
+ @property({ type: String }) align: "start" | "center" | "end" = "center";
15
+ @property({ type: Number, attribute: "slides-per-view" }) slidesPerView = 1;
16
+ @property({ type: Number }) gap?: number;
17
+ @property({ type: Boolean, reflect: true }) disabled = false;
18
+
19
+ @state() private slideCount = 0;
20
+ @state() private isDragging = false;
21
+ @state() private dragStartX = 0;
22
+ @state() private currentTranslate = 0;
23
+ @state() private prevTranslate = 0;
24
+
25
+ @query(".viewport") private viewport?: HTMLElement;
26
+ @query(".track") private track?: HTMLElement;
27
+ @query("slot") private slotElement?: HTMLSlotElement;
28
+
29
+ private autoplayTimer?: number;
30
+ private animationId?: number;
31
+ private prefersReducedMotion = false;
32
+
33
+ static styles = css`
34
+ :host {
35
+ display: block;
36
+ font-family: var(--rel-fontFamilies-primary);
37
+ position: relative;
38
+ user-select: none;
39
+ }
40
+
41
+ :host([disabled]) {
42
+ opacity: 0.6;
43
+ pointer-events: none;
44
+ }
45
+
46
+ .viewport {
47
+ overflow: hidden;
48
+ position: relative;
49
+ width: 100%;
50
+ }
51
+
52
+ .track {
53
+ display: flex;
54
+ transition: transform 0.3s ease-out;
55
+ will-change: transform;
56
+ }
57
+
58
+ .track.dragging {
59
+ transition: none;
60
+ }
61
+
62
+ .track.no-transition {
63
+ transition: none;
64
+ }
65
+
66
+ ::slotted(*) {
67
+ flex: 0 0 100%;
68
+ min-width: 0;
69
+ }
70
+
71
+ /* Navigation buttons */
72
+ .nav-button {
73
+ position: absolute;
74
+ top: 50%;
75
+ transform: translateY(-50%);
76
+ z-index: 10;
77
+ width: 40px;
78
+ height: 40px;
79
+ border-radius: 50%;
80
+ border: 1px solid var(--rel-border-default);
81
+ background: var(--rel-colors-white);
82
+ color: var(--rel-colors-gray-primary);
83
+ cursor: pointer;
84
+ display: flex;
85
+ align-items: center;
86
+ justify-content: center;
87
+ transition: all 0.15s ease;
88
+ box-shadow: var(--rel-shadows-shadow-100);
89
+ }
90
+
91
+ .nav-button:hover:not(:disabled) {
92
+ background: var(--rel-surface-secondary);
93
+ }
94
+
95
+ .nav-button:focus-visible {
96
+ outline: 2px solid var(--rel-colors-blue-primary);
97
+ outline-offset: 2px;
98
+ }
99
+
100
+ .nav-button:disabled {
101
+ opacity: 0.4;
102
+ cursor: not-allowed;
103
+ }
104
+
105
+ .nav-button.prev {
106
+ left: 12px;
107
+ }
108
+
109
+ .nav-button.next {
110
+ right: 12px;
111
+ }
112
+
113
+ .nav-button svg {
114
+ width: 20px;
115
+ height: 20px;
116
+ }
117
+
118
+ /* Dots indicator */
119
+ .dots {
120
+ display: flex;
121
+ justify-content: center;
122
+ gap: var(--rel-spacing-space-xs);
123
+ margin-top: var(--rel-spacing-space-md);
124
+ }
125
+
126
+ .dot {
127
+ width: 8px;
128
+ height: 8px;
129
+ border-radius: 50%;
130
+ border: none;
131
+ background: var(--rel-colors-gray-border);
132
+ cursor: pointer;
133
+ padding: 0;
134
+ transition: all 0.15s ease;
135
+ }
136
+
137
+ .dot:hover {
138
+ background: var(--rel-colors-gray-divider);
139
+ }
140
+
141
+ .dot.active {
142
+ background: var(--rel-colors-green-primary);
143
+ width: 24px;
144
+ border-radius: 4px;
145
+ }
146
+
147
+ .dot:focus-visible {
148
+ outline: 2px solid var(--rel-colors-blue-primary);
149
+ outline-offset: 2px;
150
+ }
151
+
152
+ /* Reduced motion support */
153
+ @media (prefers-reduced-motion: reduce) {
154
+ .track {
155
+ transition: none;
156
+ }
157
+ }
158
+ `;
159
+
160
+ connectedCallback() {
161
+ super.connectedCallback();
162
+ this.prefersReducedMotion = window.matchMedia(
163
+ "(prefers-reduced-motion: reduce)"
164
+ ).matches;
165
+
166
+ if (this.autoplay) {
167
+ this.startAutoplay();
168
+ }
169
+ }
170
+
171
+ disconnectedCallback() {
172
+ super.disconnectedCallback();
173
+ this.stopAutoplay();
174
+ if (this.animationId) {
175
+ cancelAnimationFrame(this.animationId);
176
+ }
177
+ }
178
+
179
+ private handleSlotChange() {
180
+ const slot = this.slotElement;
181
+ if (!slot) return;
182
+
183
+ const elements = slot.assignedElements();
184
+ this.slideCount = elements.length;
185
+
186
+ // Ensure value is within bounds
187
+ if (this.value >= this.slideCount) {
188
+ this.value = this.slideCount - 1;
189
+ }
190
+ if (this.value < 0) {
191
+ this.value = 0;
192
+ }
193
+
194
+ this.updateTransform();
195
+ }
196
+
197
+ private updateTransform() {
198
+ if (!this.track || !this.viewport) return;
199
+
200
+ const slideWidth = this.viewport.offsetWidth;
201
+ const gapValue = this.gap ?? 0;
202
+ const translate = -(this.value * (slideWidth + gapValue));
203
+
204
+ this.currentTranslate = translate;
205
+ this.prevTranslate = translate;
206
+ this.track.style.transform = `translateX(${translate}px)`;
207
+
208
+ if (this.gap) {
209
+ this.track.style.gap = `${this.gap}px`;
210
+ } else {
211
+ this.track.style.gap = "";
212
+ }
213
+ }
214
+
215
+ private goToPrevious() {
216
+ if (this.disabled) return;
217
+
218
+ if (this.value > 0) {
219
+ this.value--;
220
+ } else if (this.loop) {
221
+ this.value = this.slideCount - 1;
222
+ }
223
+
224
+ this.updateTransform();
225
+ this.emitChange();
226
+ }
227
+
228
+ private goToNext() {
229
+ if (this.disabled) return;
230
+
231
+ if (this.value < this.slideCount - 1) {
232
+ this.value++;
233
+ } else if (this.loop) {
234
+ this.value = 0;
235
+ }
236
+
237
+ this.updateTransform();
238
+ this.emitChange();
239
+ }
240
+
241
+ private goToSlide(index: number) {
242
+ if (this.disabled || index < 0 || index >= this.slideCount) return;
243
+
244
+ this.value = index;
245
+ this.updateTransform();
246
+ this.emitChange();
247
+ }
248
+
249
+ private emitChange() {
250
+ this.dispatchEvent(
251
+ new CustomEvent("rel-change", {
252
+ detail: { value: this.value },
253
+ bubbles: true,
254
+ composed: true,
255
+ })
256
+ );
257
+ }
258
+
259
+ private startAutoplay() {
260
+ if (!this.autoplay || this.disabled) return;
261
+
262
+ this.stopAutoplay();
263
+ this.autoplayTimer = window.setInterval(() => {
264
+ this.goToNext();
265
+ }, this.interval);
266
+ }
267
+
268
+ private stopAutoplay() {
269
+ if (this.autoplayTimer) {
270
+ clearInterval(this.autoplayTimer);
271
+ this.autoplayTimer = undefined;
272
+ }
273
+ }
274
+
275
+ private handlePointerDown(e: PointerEvent) {
276
+ if (this.disabled || !this.track) return;
277
+
278
+ this.isDragging = true;
279
+ this.dragStartX = e.clientX;
280
+ this.prevTranslate = this.currentTranslate;
281
+
282
+ this.track.classList.add("dragging");
283
+
284
+ if (this.autoplay && this.pauseOnHover) {
285
+ this.stopAutoplay();
286
+ }
287
+
288
+ e.preventDefault();
289
+ }
290
+
291
+ private handlePointerMove(e: PointerEvent) {
292
+ if (!this.isDragging || !this.track) return;
293
+
294
+ const currentX = e.clientX;
295
+ const deltaX = currentX - this.dragStartX;
296
+ this.currentTranslate = this.prevTranslate + deltaX;
297
+
298
+ if (!this.prefersReducedMotion && this.animationId) {
299
+ cancelAnimationFrame(this.animationId);
300
+ }
301
+
302
+ this.animationId = requestAnimationFrame(() => {
303
+ if (this.track) {
304
+ this.track.style.transform = `translateX(${this.currentTranslate}px)`;
305
+ }
306
+ });
307
+ }
308
+
309
+ private handlePointerUp(e: PointerEvent) {
310
+ if (!this.isDragging || !this.track || !this.viewport) return;
311
+
312
+ this.isDragging = false;
313
+ this.track.classList.remove("dragging");
314
+
315
+ const deltaX = e.clientX - this.dragStartX;
316
+ const slideWidth = this.viewport.offsetWidth;
317
+ const threshold = slideWidth * 0.2; // 20% threshold
318
+
319
+ if (Math.abs(deltaX) > threshold) {
320
+ if (deltaX > 0 && (this.value > 0 || this.loop)) {
321
+ this.goToPrevious();
322
+ } else if (deltaX < 0 && (this.value < this.slideCount - 1 || this.loop)) {
323
+ this.goToNext();
324
+ } else {
325
+ this.updateTransform();
326
+ }
327
+ } else {
328
+ this.updateTransform();
329
+ }
330
+
331
+ if (this.autoplay) {
332
+ this.startAutoplay();
333
+ }
334
+ }
335
+
336
+ private handleKeyDown(e: KeyboardEvent) {
337
+ if (this.disabled) return;
338
+
339
+ switch (e.key) {
340
+ case "ArrowLeft":
341
+ e.preventDefault();
342
+ this.goToPrevious();
343
+ break;
344
+ case "ArrowRight":
345
+ e.preventDefault();
346
+ this.goToNext();
347
+ break;
348
+ case "Home":
349
+ e.preventDefault();
350
+ this.goToSlide(0);
351
+ break;
352
+ case "End":
353
+ e.preventDefault();
354
+ this.goToSlide(this.slideCount - 1);
355
+ break;
356
+ }
357
+ }
358
+
359
+ private handleMouseEnter() {
360
+ if (this.autoplay && this.pauseOnHover) {
361
+ this.stopAutoplay();
362
+ }
363
+ }
364
+
365
+ private handleMouseLeave() {
366
+ if (this.autoplay && this.pauseOnHover) {
367
+ this.startAutoplay();
368
+ }
369
+ }
370
+
371
+ updated(changedProperties: Map<string, any>) {
372
+ if (changedProperties.has("autoplay") || changedProperties.has("interval")) {
373
+ if (this.autoplay) {
374
+ this.startAutoplay();
375
+ } else {
376
+ this.stopAutoplay();
377
+ }
378
+ }
379
+
380
+ if (changedProperties.has("value")) {
381
+ this.updateTransform();
382
+ }
383
+ }
384
+
385
+ render() {
386
+ const canGoPrev = this.loop || this.value > 0;
387
+ const canGoNext = this.loop || this.value < this.slideCount - 1;
388
+
389
+ return html`
390
+ <div
391
+ class="viewport"
392
+ part="viewport"
393
+ role="region"
394
+ aria-roledescription="carousel"
395
+ aria-label="Carousel"
396
+ @keydown=${this.handleKeyDown}
397
+ @mouseenter=${this.handleMouseEnter}
398
+ @mouseleave=${this.handleMouseLeave}
399
+ tabindex="0"
400
+ >
401
+ <div
402
+ class="track"
403
+ part="track"
404
+ @pointerdown=${this.handlePointerDown}
405
+ @pointermove=${this.handlePointerMove}
406
+ @pointerup=${this.handlePointerUp}
407
+ @pointercancel=${this.handlePointerUp}
408
+ >
409
+ <slot @slotchange=${this.handleSlotChange}></slot>
410
+ </div>
411
+
412
+ ${this.showButtons
413
+ ? html`
414
+ <button
415
+ class="nav-button prev"
416
+ part="prev-button"
417
+ aria-label="Previous slide"
418
+ ?disabled=${!canGoPrev || this.disabled}
419
+ @click=${this.goToPrevious}
420
+ >
421
+ <svg viewBox="0 0 16 16" fill="none">
422
+ <path
423
+ d="M10 12L6 8L10 4"
424
+ stroke="currentColor"
425
+ stroke-width="2"
426
+ stroke-linecap="round"
427
+ stroke-linejoin="round"
428
+ />
429
+ </svg>
430
+ </button>
431
+
432
+ <button
433
+ class="nav-button next"
434
+ part="next-button"
435
+ aria-label="Next slide"
436
+ ?disabled=${!canGoNext || this.disabled}
437
+ @click=${this.goToNext}
438
+ >
439
+ <svg viewBox="0 0 16 16" fill="none">
440
+ <path
441
+ d="M6 4L10 8L6 12"
442
+ stroke="currentColor"
443
+ stroke-width="2"
444
+ stroke-linecap="round"
445
+ stroke-linejoin="round"
446
+ />
447
+ </svg>
448
+ </button>
449
+ `
450
+ : nothing}
451
+ </div>
452
+
453
+ ${this.showDots && this.slideCount > 1
454
+ ? html`
455
+ <div class="dots" part="dots">
456
+ ${Array.from({ length: this.slideCount }, (_, i) => html`
457
+ <button
458
+ class="dot ${i === this.value ? "active" : ""}"
459
+ part="dot"
460
+ aria-label="Go to slide ${i + 1}"
461
+ @click=${() => this.goToSlide(i)}
462
+ ></button>
463
+ `)}
464
+ </div>
465
+ `
466
+ : nothing}
467
+ `;
468
+ }
469
+ }