@reliability-design/web 1.0.2 → 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 (145) hide show
  1. package/dist/components/rel-accordion/README.md +132 -0
  2. package/dist/components/rel-accordion/rel-accordion.ts +61 -29
  3. package/dist/components/rel-alert/README.md +141 -0
  4. package/dist/components/rel-alert/rel-alert.ts +110 -67
  5. package/dist/components/rel-avatar/README.md +119 -0
  6. package/dist/components/rel-avatar/rel-avatar.ts +8 -15
  7. package/dist/components/rel-badge/README.md +86 -0
  8. package/dist/components/rel-badge/rel-badge.ts +28 -21
  9. package/dist/components/rel-breadcrumb/README.md +102 -0
  10. package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +24 -18
  11. package/dist/components/rel-button/README.md +130 -0
  12. package/dist/components/rel-button/rel-button.ts +39 -59
  13. package/dist/components/rel-calendar/README.md +109 -0
  14. package/dist/components/rel-calendar/index.ts +1 -0
  15. package/dist/components/rel-calendar/rel-calendar.ts +467 -0
  16. package/dist/components/rel-card/README.md +94 -0
  17. package/dist/components/rel-card/rel-card.ts +21 -11
  18. package/dist/components/rel-cardmedia/README.md +127 -0
  19. package/dist/components/rel-cardmedia/rel-cardmedia.ts +22 -18
  20. package/dist/components/rel-carousel/README.md +166 -0
  21. package/dist/components/rel-carousel/index.ts +1 -0
  22. package/dist/components/rel-carousel/rel-carousel.ts +469 -0
  23. package/dist/components/rel-chart/README.md +286 -0
  24. package/dist/components/rel-chart/index.ts +1 -0
  25. package/dist/components/rel-chart/rel-chart.ts +736 -0
  26. package/dist/components/rel-checkbox/README.md +77 -0
  27. package/dist/components/rel-checkbox/rel-checkbox.ts +36 -45
  28. package/dist/components/rel-chip/README.md +114 -0
  29. package/dist/components/rel-chip/rel-chip.ts +47 -122
  30. package/dist/components/rel-container/README.md +99 -0
  31. package/dist/components/rel-container/rel-container.ts +1 -6
  32. package/dist/components/rel-date-picker/README.md +253 -0
  33. package/dist/components/rel-date-picker/index.ts +1 -0
  34. package/dist/components/rel-date-picker/rel-date-picker.ts +916 -0
  35. package/dist/components/rel-divider/README.md +100 -0
  36. package/dist/components/rel-divider/rel-divider.ts +37 -37
  37. package/dist/components/rel-drawer/README.md +200 -0
  38. package/dist/components/rel-drawer/index.ts +1 -0
  39. package/dist/components/rel-drawer/rel-drawer.ts +621 -0
  40. package/dist/components/rel-kbd/README.md +151 -0
  41. package/dist/components/rel-kbd/rel-kbd.ts +118 -0
  42. package/dist/components/rel-layout/README.md +88 -0
  43. package/dist/components/rel-layout/rel-layout.ts +12 -14
  44. package/dist/components/rel-menu/README.md +151 -0
  45. package/dist/components/rel-menu/rel-menu.ts +18 -10
  46. package/dist/components/rel-menubar/README.md +329 -0
  47. package/dist/components/rel-menubar/index.ts +2 -0
  48. package/dist/components/rel-menubar/rel-menubar-menu.ts +16 -0
  49. package/dist/components/rel-menubar/rel-menubar.ts +576 -0
  50. package/dist/components/rel-nav-menu/README.md +289 -0
  51. package/dist/components/rel-nav-menu/index.ts +3 -0
  52. package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +143 -0
  53. package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +53 -0
  54. package/dist/components/rel-nav-menu/rel-nav-menu.ts +331 -0
  55. package/dist/components/rel-navbar/README.md +126 -0
  56. package/dist/components/rel-navbar/rel-navbar.ts +91 -0
  57. package/dist/components/rel-otp/README.md +440 -0
  58. package/dist/components/rel-otp/index.ts +1 -0
  59. package/dist/components/rel-otp/rel-otp.ts +504 -0
  60. package/dist/components/rel-pagination/README.md +410 -0
  61. package/dist/components/rel-pagination/index.ts +1 -0
  62. package/dist/components/rel-pagination/rel-pagination.ts +376 -0
  63. package/dist/components/rel-popover/README.md +568 -0
  64. package/dist/components/rel-popover/index.ts +2 -0
  65. package/dist/components/rel-popover/rel-popover-content.ts +55 -0
  66. package/dist/components/rel-popover/rel-popover.ts +327 -0
  67. package/dist/components/rel-progress/README.md +110 -0
  68. package/dist/components/rel-progress/rel-progress.ts +58 -20
  69. package/dist/components/rel-quote-page/README.md +166 -0
  70. package/dist/components/rel-quote-page/rel-quote-page.ts +816 -0
  71. package/dist/components/rel-radio/README.md +120 -0
  72. package/dist/components/rel-radio/rel-radio.ts +41 -73
  73. package/dist/components/rel-resizable/README.md +140 -0
  74. package/dist/components/rel-resizable/index.ts +3 -0
  75. package/dist/components/rel-resizable/rel-resizable-group.ts +374 -0
  76. package/dist/components/rel-resizable/rel-resizable-handle.ts +149 -0
  77. package/dist/components/rel-resizable/rel-resizable-panel.ts +47 -0
  78. package/dist/components/rel-segmented-button/README.md +141 -0
  79. package/dist/components/rel-segmented-button/rel-segmented-button.ts +18 -13
  80. package/dist/components/rel-select/README.md +107 -0
  81. package/dist/components/rel-select/rel-select.ts +14 -14
  82. package/dist/components/rel-sheet/README.md +224 -0
  83. package/dist/components/rel-sheet/rel-sheet.ts +683 -0
  84. package/dist/components/rel-sidebar/README.md +209 -0
  85. package/dist/components/rel-sidebar/rel-sidebar.ts +1158 -0
  86. package/dist/components/rel-slider/README.md +135 -0
  87. package/dist/components/rel-slider/rel-slider.ts +19 -7
  88. package/dist/components/rel-snackbar/README.md +134 -0
  89. package/dist/components/rel-snackbar/rel-snackbar.ts +73 -2
  90. package/dist/components/rel-stepper/README.md +160 -0
  91. package/dist/components/rel-stepper/rel-stepper.ts +29 -8
  92. package/dist/components/rel-switch/README.md +102 -0
  93. package/dist/components/rel-switch/rel-switch.ts +22 -11
  94. package/dist/components/rel-tab/README.md +163 -0
  95. package/dist/components/rel-tab/rel-tab.ts +46 -22
  96. package/dist/components/rel-table/README.md +178 -0
  97. package/dist/components/rel-table/rel-table-body.ts +16 -0
  98. package/dist/components/rel-table/rel-table-caption.ts +22 -0
  99. package/dist/components/rel-table/rel-table-cell.ts +49 -0
  100. package/dist/components/rel-table/rel-table-footer.ts +18 -0
  101. package/dist/components/rel-table/rel-table-head.ts +33 -0
  102. package/dist/components/rel-table/rel-table-header.ts +16 -0
  103. package/dist/components/rel-table/rel-table-row.ts +32 -0
  104. package/dist/components/rel-table/rel-table.ts +47 -0
  105. package/dist/components/rel-textfield/README.md +90 -0
  106. package/dist/components/rel-textfield/rel-textfield.ts +37 -21
  107. package/dist/components/rel-toast/README.md +148 -0
  108. package/dist/components/rel-toast/rel-toast.ts +32 -14
  109. package/dist/components/rel-tooltip/README.md +103 -0
  110. package/dist/components/rel-tooltip/rel-tooltip.ts +9 -9
  111. package/dist/index.d.mts +846 -7
  112. package/dist/index.d.ts +846 -7
  113. package/dist/index.js +10860 -1803
  114. package/dist/index.js.map +1 -1
  115. package/dist/index.mjs +10820 -1809
  116. package/dist/index.mjs.map +1 -1
  117. package/dist/styles/vars.css +293 -183
  118. package/dist/vars-ITL2K3KO.css +294 -0
  119. package/package.json +2 -2
  120. package/dist/components/rel-accordion/rel-accordion.stories.ts +0 -313
  121. package/dist/components/rel-alert/rel-alert.stories.ts +0 -412
  122. package/dist/components/rel-avatar/rel-avatar.stories.ts +0 -327
  123. package/dist/components/rel-badge/rel-badge.stories.ts +0 -350
  124. package/dist/components/rel-breadcrumb/rel-breadcrumb.stories.ts +0 -306
  125. package/dist/components/rel-button/rel-button.stories.ts +0 -356
  126. package/dist/components/rel-card/rel-card.stories.ts +0 -299
  127. package/dist/components/rel-cardmedia/rel-cardmedia.stories.ts +0 -368
  128. package/dist/components/rel-checkbox/rel-checkbox.stories.ts +0 -414
  129. package/dist/components/rel-chip/rel-chip.stories.ts +0 -552
  130. package/dist/components/rel-container/rel-container.stories.ts +0 -239
  131. package/dist/components/rel-divider/rel-divider.stories.ts +0 -229
  132. package/dist/components/rel-layout/rel-layout.stories.ts +0 -713
  133. package/dist/components/rel-menu/rel-menu.stories.ts +0 -910
  134. package/dist/components/rel-progress/rel-progress.stories.ts +0 -817
  135. package/dist/components/rel-radio/rel-radio.stories.ts +0 -1048
  136. package/dist/components/rel-segmented-button/rel-segmented-button.stories.ts +0 -1079
  137. package/dist/components/rel-select/rel-select.stories.ts +0 -1201
  138. package/dist/components/rel-slider/rel-slider.stories.ts +0 -730
  139. package/dist/components/rel-snackbar/rel-snackbar.stories.ts +0 -808
  140. package/dist/components/rel-stepper/rel-stepper.stories.ts +0 -752
  141. package/dist/components/rel-switch/rel-switch.stories.ts +0 -441
  142. package/dist/components/rel-tab/rel-tab.stories.ts +0 -492
  143. package/dist/components/rel-textfield/rel-textfield.stories.ts +0 -710
  144. package/dist/components/rel-toast/rel-toast.stories.ts +0 -394
  145. package/dist/components/rel-tooltip/rel-tooltip.stories.ts +0 -364
@@ -0,0 +1,376 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { customElement, property, state } from "lit/decorators.js";
3
+
4
+ type DensityType = "comfortable" | "compact";
5
+ type VariantType = "default" | "icons";
6
+ type PageItem = { type: "page"; value: number } | { type: "ellipsis" } | { type: "prev" } | { type: "next" };
7
+
8
+ @customElement("rel-pagination")
9
+ export class RelPagination extends LitElement {
10
+ @property({ type: Number }) page?: number;
11
+ @property({ type: Number }) defaultPage = 1;
12
+ @property({ type: Number }) totalPages!: number;
13
+ @property({ type: Number }) siblingCount = 1;
14
+ @property({ type: Number }) boundaryCount = 1;
15
+ @property({ type: Boolean, reflect: true }) disabled = false;
16
+ @property({ type: String }) density: DensityType = "comfortable";
17
+ @property({ type: String }) variant: VariantType = "default";
18
+ @property({ type: String }) hrefTemplate = "";
19
+ @property({ type: String }) ariaLabel = "Pagination";
20
+
21
+ @state() private currentPage = 1;
22
+
23
+ static styles = css`
24
+ :host {
25
+ display: inline-block;
26
+ font-family: var(--rel-fontFamilies-primary);
27
+ }
28
+
29
+ nav {
30
+ display: flex;
31
+ align-items: center;
32
+ gap: var(--rel-spacing-space-2xs);
33
+ }
34
+
35
+ nav.compact {
36
+ gap: var(--rel-spacing-space-3xs);
37
+ }
38
+
39
+ button,
40
+ a {
41
+ display: inline-flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ min-width: 40px;
45
+ height: 40px;
46
+ padding: 0 var(--rel-spacing-space-sm);
47
+ font-family: var(--rel-fontFamilies-primary);
48
+ font-size: var(--rel-fontSizes-sm);
49
+ font-weight: var(--rel-fontWeights-medium);
50
+ color: var(--rel-colors-gray-heading);
51
+ background: var(--rel-colors-white);
52
+ border: var(--rel-borders-width-stroke-100) solid var(--rel-colors-gray-border);
53
+ border-radius: var(--rel-borders-radius-border-radius-200);
54
+ cursor: pointer;
55
+ transition: all 0.15s ease;
56
+ text-decoration: none;
57
+ outline: none;
58
+ user-select: none;
59
+ }
60
+
61
+ nav.compact button,
62
+ nav.compact a {
63
+ min-width: 32px;
64
+ height: 32px;
65
+ padding: 0 var(--rel-spacing-space-xs);
66
+ font-size: var(--rel-fontSizes-xs);
67
+ }
68
+
69
+ button:hover:not(:disabled),
70
+ a:hover:not([aria-disabled="true"]) {
71
+ background: var(--rel-surface-secondary, #fafafa);
72
+ border-color: var(--rel-colors-gray-primary, #333);
73
+ }
74
+
75
+ button:focus-visible,
76
+ a:focus-visible {
77
+ outline: 2px solid var(--rel-colors-blue-primary);
78
+ outline-offset: 2px;
79
+ }
80
+
81
+ button:disabled,
82
+ a[aria-disabled="true"] {
83
+ opacity: 0.5;
84
+ cursor: not-allowed;
85
+ pointer-events: none;
86
+ }
87
+
88
+ button[aria-current="page"],
89
+ a[aria-current="page"] {
90
+ background: var(--rel-colors-gray-heading);
91
+ color: var(--rel-colors-white);
92
+ border-color: var(--rel-colors-gray-heading);
93
+ font-weight: var(--rel-fontWeights-semibold);
94
+ }
95
+
96
+ button[aria-current="page"]:hover,
97
+ a[aria-current="page"]:hover {
98
+ background: var(--rel-colors-gray-primary);
99
+ border-color: var(--rel-colors-gray-primary);
100
+ }
101
+
102
+ .ellipsis {
103
+ display: inline-flex;
104
+ align-items: center;
105
+ justify-content: center;
106
+ min-width: 40px;
107
+ height: 40px;
108
+ color: var(--rel-colors-gray-placeholder);
109
+ font-size: var(--rel-fontSizes-sm);
110
+ user-select: none;
111
+ }
112
+
113
+ nav.compact .ellipsis {
114
+ min-width: 32px;
115
+ height: 32px;
116
+ font-size: var(--rel-fontSizes-xs);
117
+ }
118
+
119
+ .icon {
120
+ width: 16px;
121
+ height: 16px;
122
+ display: inline-block;
123
+ }
124
+
125
+ nav.compact .icon {
126
+ width: 14px;
127
+ height: 14px;
128
+ }
129
+
130
+ :host([disabled]) nav {
131
+ opacity: 0.5;
132
+ pointer-events: none;
133
+ }
134
+ `;
135
+
136
+ connectedCallback() {
137
+ super.connectedCallback();
138
+ this.currentPage = this.page ?? this.defaultPage;
139
+ }
140
+
141
+ updated(changedProperties: Map<string, any>) {
142
+ // Handle controlled mode: sync currentPage with page prop
143
+ if (changedProperties.has("page") && this.page !== undefined) {
144
+ this.currentPage = this.page;
145
+ }
146
+ }
147
+
148
+ private get activePage(): number {
149
+ return this.page ?? this.currentPage;
150
+ }
151
+
152
+ private generatePageItems(): PageItem[] {
153
+ const items: PageItem[] = [];
154
+ const current = this.activePage;
155
+ const total = this.totalPages;
156
+ const sibling = this.siblingCount;
157
+ const boundary = this.boundaryCount;
158
+
159
+ items.push({ type: "prev" });
160
+
161
+ // Calculate page ranges
162
+ const leftBoundary = Array.from({ length: Math.min(boundary, total) }, (_, i) => i + 1);
163
+ const rightBoundary = Array.from(
164
+ { length: Math.min(boundary, total) },
165
+ (_, i) => total - boundary + i + 1
166
+ ).filter((p) => p > 0);
167
+
168
+ const leftSiblings = Array.from(
169
+ { length: sibling },
170
+ (_, i) => current - sibling + i
171
+ ).filter((p) => p > boundary && p < current);
172
+
173
+ const rightSiblings = Array.from(
174
+ { length: sibling },
175
+ (_, i) => current + i + 1
176
+ ).filter((p) => p > current && p <= total - boundary);
177
+
178
+ // Combine all visible pages
179
+ const visiblePages = new Set([
180
+ ...leftBoundary,
181
+ ...leftSiblings,
182
+ current,
183
+ ...rightSiblings,
184
+ ...rightBoundary,
185
+ ]);
186
+
187
+ const sortedPages = Array.from(visiblePages).sort((a, b) => a - b);
188
+
189
+ // Build items with ellipsis
190
+ sortedPages.forEach((page, index) => {
191
+ if (index > 0) {
192
+ const prevPage = sortedPages[index - 1];
193
+ if (page - prevPage > 1) {
194
+ items.push({ type: "ellipsis" });
195
+ }
196
+ }
197
+ items.push({ type: "page", value: page });
198
+ });
199
+
200
+ items.push({ type: "next" });
201
+
202
+ return items;
203
+ }
204
+
205
+ private handlePageChange(newPage: number) {
206
+ if (this.disabled || newPage < 1 || newPage > this.totalPages || newPage === this.activePage) {
207
+ return;
208
+ }
209
+
210
+ // If uncontrolled, update internal state
211
+ if (this.page === undefined) {
212
+ this.currentPage = newPage;
213
+ }
214
+
215
+ // Always emit event
216
+ this.dispatchEvent(
217
+ new CustomEvent("rel-change", {
218
+ detail: { page: newPage },
219
+ bubbles: true,
220
+ composed: true,
221
+ })
222
+ );
223
+ }
224
+
225
+ private handleKeyDown(event: KeyboardEvent, callback: () => void) {
226
+ if (event.key === "Enter" || event.key === " ") {
227
+ event.preventDefault();
228
+ callback();
229
+ }
230
+ }
231
+
232
+ private renderPrevIcon() {
233
+ return html`
234
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
235
+ <path d="M15 18l-6-6 6-6" />
236
+ </svg>
237
+ `;
238
+ }
239
+
240
+ private renderNextIcon() {
241
+ return html`
242
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
243
+ <path d="M9 18l6-6-6-6" />
244
+ </svg>
245
+ `;
246
+ }
247
+
248
+ private renderItem(item: PageItem) {
249
+ const current = this.activePage;
250
+ const useLinks = !!this.hrefTemplate;
251
+
252
+ if (item.type === "ellipsis") {
253
+ return html`<span class="ellipsis">…</span>`;
254
+ }
255
+
256
+ if (item.type === "prev") {
257
+ const disabled = current === 1 || this.disabled;
258
+ const targetPage = current - 1;
259
+
260
+ if (useLinks) {
261
+ const href = disabled ? "#" : this.hrefTemplate.replace("{page}", String(targetPage));
262
+ return html`
263
+ <a
264
+ href="${href}"
265
+ aria-label="Go to previous page"
266
+ aria-disabled="${disabled}"
267
+ @click="${(e: Event) => {
268
+ if (disabled) {
269
+ e.preventDefault();
270
+ return;
271
+ }
272
+ e.preventDefault();
273
+ this.handlePageChange(targetPage);
274
+ }}"
275
+ >
276
+ ${this.variant === "icons" ? this.renderPrevIcon() : "Previous"}
277
+ </a>
278
+ `;
279
+ }
280
+
281
+ return html`
282
+ <button
283
+ type="button"
284
+ aria-label="Go to previous page"
285
+ ?disabled="${disabled}"
286
+ @click="${() => this.handlePageChange(targetPage)}"
287
+ >
288
+ ${this.variant === "icons" ? this.renderPrevIcon() : "Previous"}
289
+ </button>
290
+ `;
291
+ }
292
+
293
+ if (item.type === "next") {
294
+ const disabled = current === this.totalPages || this.disabled;
295
+ const targetPage = current + 1;
296
+
297
+ if (useLinks) {
298
+ const href = disabled ? "#" : this.hrefTemplate.replace("{page}", String(targetPage));
299
+ return html`
300
+ <a
301
+ href="${href}"
302
+ aria-label="Go to next page"
303
+ aria-disabled="${disabled}"
304
+ @click="${(e: Event) => {
305
+ if (disabled) {
306
+ e.preventDefault();
307
+ return;
308
+ }
309
+ e.preventDefault();
310
+ this.handlePageChange(targetPage);
311
+ }}"
312
+ >
313
+ ${this.variant === "icons" ? this.renderNextIcon() : "Next"}
314
+ </a>
315
+ `;
316
+ }
317
+
318
+ return html`
319
+ <button
320
+ type="button"
321
+ aria-label="Go to next page"
322
+ ?disabled="${disabled}"
323
+ @click="${() => this.handlePageChange(targetPage)}"
324
+ >
325
+ ${this.variant === "icons" ? this.renderNextIcon() : "Next"}
326
+ </button>
327
+ `;
328
+ }
329
+
330
+ // Page item
331
+ const pageNum = item.value;
332
+ const isCurrent = pageNum === current;
333
+
334
+ if (useLinks) {
335
+ const href = this.hrefTemplate.replace("{page}", String(pageNum));
336
+ return html`
337
+ <a
338
+ href="${href}"
339
+ aria-label="Go to page ${pageNum}"
340
+ aria-current="${isCurrent ? "page" : "false"}"
341
+ @click="${(e: Event) => {
342
+ e.preventDefault();
343
+ this.handlePageChange(pageNum);
344
+ }}"
345
+ >
346
+ ${pageNum}
347
+ </a>
348
+ `;
349
+ }
350
+
351
+ return html`
352
+ <button
353
+ type="button"
354
+ aria-label="Go to page ${pageNum}"
355
+ aria-current="${isCurrent ? "page" : "false"}"
356
+ @click="${() => this.handlePageChange(pageNum)}"
357
+ >
358
+ ${pageNum}
359
+ </button>
360
+ `;
361
+ }
362
+
363
+ render() {
364
+ const items = this.generatePageItems();
365
+
366
+ return html`
367
+ <nav
368
+ class="${this.density === "compact" ? "compact" : ""}"
369
+ aria-label="${this.ariaLabel}"
370
+ role="navigation"
371
+ >
372
+ ${items.map((item) => this.renderItem(item))}
373
+ </nav>
374
+ `;
375
+ }
376
+ }