snice 1.14.3 → 2.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 (185) hide show
  1. package/bin/templates/base/tsconfig.json +5 -4
  2. package/components/accordion/demo.html +403 -0
  3. package/components/accordion/snice-accordion-item.css +85 -0
  4. package/components/accordion/snice-accordion-item.ts +226 -0
  5. package/components/accordion/snice-accordion.css +31 -0
  6. package/components/accordion/snice-accordion.ts +182 -0
  7. package/components/accordion/snice-accordion.types.ts +32 -0
  8. package/components/alert/demo.html +445 -0
  9. package/components/alert/snice-alert.css +195 -0
  10. package/components/alert/snice-alert.ts +141 -0
  11. package/components/alert/snice-alert.types.ts +12 -0
  12. package/components/avatar/demo.html +598 -0
  13. package/components/avatar/snice-avatar.css +131 -0
  14. package/components/avatar/snice-avatar.ts +136 -0
  15. package/components/avatar/snice-avatar.types.ts +13 -0
  16. package/components/badge/demo.html +523 -0
  17. package/components/badge/snice-badge.css +161 -0
  18. package/components/badge/snice-badge.ts +117 -0
  19. package/components/badge/snice-badge.types.ts +16 -0
  20. package/components/breadcrumbs/demo.html +404 -0
  21. package/components/breadcrumbs/snice-breadcrumbs.css +133 -0
  22. package/components/breadcrumbs/snice-breadcrumbs.ts +191 -0
  23. package/components/breadcrumbs/snice-breadcrumbs.types.ts +26 -0
  24. package/components/breadcrumbs/snice-crumb.ts +26 -0
  25. package/components/button/demo.html +42 -0
  26. package/components/button/snice-button.css +230 -0
  27. package/components/button/snice-button.ts +169 -0
  28. package/components/button/snice-button.types.ts +25 -0
  29. package/components/card/demo.html +525 -0
  30. package/components/card/snice-card.css +140 -0
  31. package/components/card/snice-card.ts +102 -0
  32. package/components/card/snice-card.types.ts +10 -0
  33. package/components/checkbox/demo.html +253 -0
  34. package/components/checkbox/snice-checkbox.css +164 -0
  35. package/components/checkbox/snice-checkbox.ts +223 -0
  36. package/components/checkbox/snice-checkbox.types.ts +22 -0
  37. package/components/chip/demo.html +383 -0
  38. package/components/chip/snice-chip.css +195 -0
  39. package/components/chip/snice-chip.ts +139 -0
  40. package/components/chip/snice-chip.types.ts +15 -0
  41. package/components/date-picker/README.md +233 -0
  42. package/components/date-picker/demo.html +191 -0
  43. package/components/date-picker/snice-date-picker.css +330 -0
  44. package/components/date-picker/snice-date-picker.ts +777 -0
  45. package/components/date-picker/snice-date-picker.types.ts +83 -0
  46. package/components/divider/demo.html +233 -0
  47. package/components/divider/snice-divider.css +155 -0
  48. package/components/divider/snice-divider.ts +69 -0
  49. package/components/divider/snice-divider.types.ts +15 -0
  50. package/components/drawer/demo.html +328 -0
  51. package/components/drawer/snice-drawer.css +476 -0
  52. package/components/drawer/snice-drawer.ts +287 -0
  53. package/components/drawer/snice-drawer.types.ts +17 -0
  54. package/components/global.d.ts +14 -0
  55. package/components/input/demo.html +303 -0
  56. package/components/input/snice-input.css +257 -0
  57. package/components/input/snice-input.ts +442 -0
  58. package/components/input/snice-input.types.ts +59 -0
  59. package/components/input/test.html +77 -0
  60. package/components/layout/README.md +260 -0
  61. package/components/layout/demo.html +538 -0
  62. package/components/layout/snice-layout-blog.css +129 -0
  63. package/components/layout/snice-layout-blog.ts +48 -0
  64. package/components/layout/snice-layout-card.css +104 -0
  65. package/components/layout/snice-layout-card.ts +35 -0
  66. package/components/layout/snice-layout-centered.css +51 -0
  67. package/components/layout/snice-layout-centered.ts +22 -0
  68. package/components/layout/snice-layout-dashboard.css +98 -0
  69. package/components/layout/snice-layout-dashboard.ts +45 -0
  70. package/components/layout/snice-layout-fullscreen.css +72 -0
  71. package/components/layout/snice-layout-fullscreen.ts +34 -0
  72. package/components/layout/snice-layout-landing.css +92 -0
  73. package/components/layout/snice-layout-landing.ts +47 -0
  74. package/components/layout/snice-layout-minimal.css +16 -0
  75. package/components/layout/snice-layout-minimal.ts +19 -0
  76. package/components/layout/snice-layout-sidebar.css +117 -0
  77. package/components/layout/snice-layout-sidebar.ts +48 -0
  78. package/components/layout/snice-layout-split.css +103 -0
  79. package/components/layout/snice-layout-split.ts +29 -0
  80. package/components/layout/snice-layout.css +72 -0
  81. package/components/layout/snice-layout.ts +35 -0
  82. package/components/layout/snice-layout.types.ts +5 -0
  83. package/components/login/demo-auth-controller.ts +185 -0
  84. package/components/login/demo.html +470 -0
  85. package/components/login/snice-login.css +204 -0
  86. package/components/login/snice-login.ts +337 -0
  87. package/components/login/snice-login.types.ts +34 -0
  88. package/components/modal/demo.html +291 -0
  89. package/components/modal/snice-modal.css +203 -0
  90. package/components/modal/snice-modal.ts +233 -0
  91. package/components/modal/snice-modal.types.ts +21 -0
  92. package/components/pagination/demo.html +395 -0
  93. package/components/pagination/snice-pagination.ts +333 -0
  94. package/components/pagination/snice-pagination.types.ts +21 -0
  95. package/components/progress/demo.html +510 -0
  96. package/components/progress/snice-progress.css +267 -0
  97. package/components/progress/snice-progress.ts +247 -0
  98. package/components/progress/snice-progress.types.ts +19 -0
  99. package/components/radio/demo.html +287 -0
  100. package/components/radio/snice-radio.css +171 -0
  101. package/components/radio/snice-radio.ts +218 -0
  102. package/components/radio/snice-radio.types.ts +21 -0
  103. package/components/select/demo.html +511 -0
  104. package/components/select/snice-option.ts +52 -0
  105. package/components/select/snice-option.types.ts +14 -0
  106. package/components/select/snice-select.css +392 -0
  107. package/components/select/snice-select.ts +796 -0
  108. package/components/select/snice-select.types.ts +55 -0
  109. package/components/skeleton/demo.html +514 -0
  110. package/components/skeleton/snice-skeleton.css +109 -0
  111. package/components/skeleton/snice-skeleton.ts +126 -0
  112. package/components/skeleton/snice-skeleton.types.ts +11 -0
  113. package/components/switch/demo.html +284 -0
  114. package/components/switch/snice-switch.css +221 -0
  115. package/components/switch/snice-switch.ts +229 -0
  116. package/components/switch/snice-switch.types.ts +23 -0
  117. package/components/symbols.ts +23 -0
  118. package/components/table/demo-table-controller.ts +100 -0
  119. package/components/table/demo.html +480 -0
  120. package/components/table/snice-cell-boolean.ts +112 -0
  121. package/components/table/snice-cell-date.ts +210 -0
  122. package/components/table/snice-cell-duration.ts +91 -0
  123. package/components/table/snice-cell-filesize.ts +90 -0
  124. package/components/table/snice-cell-number.ts +165 -0
  125. package/components/table/snice-cell-progress.ts +83 -0
  126. package/components/table/snice-cell-rating.ts +82 -0
  127. package/components/table/snice-cell-sparkline.ts +253 -0
  128. package/components/table/snice-cell-text.ts +125 -0
  129. package/components/table/snice-cell.css +296 -0
  130. package/components/table/snice-cell.ts +473 -0
  131. package/components/table/snice-column.ts +353 -0
  132. package/components/table/snice-header.css +243 -0
  133. package/components/table/snice-header.ts +261 -0
  134. package/components/table/snice-progress.ts +66 -0
  135. package/components/table/snice-rating.ts +45 -0
  136. package/components/table/snice-row.css +255 -0
  137. package/components/table/snice-row.ts +331 -0
  138. package/components/table/snice-table.css +241 -0
  139. package/components/table/snice-table.ts +737 -0
  140. package/components/table/snice-table.types.ts +158 -0
  141. package/components/tabs/demo.html +487 -0
  142. package/components/tabs/snice-tab-panel.css +264 -0
  143. package/components/tabs/snice-tab-panel.ts +47 -0
  144. package/components/tabs/snice-tab.css +96 -0
  145. package/components/tabs/snice-tab.ts +65 -0
  146. package/components/tabs/snice-tabs.css +189 -0
  147. package/components/tabs/snice-tabs.ts +332 -0
  148. package/components/tabs/snice-tabs.types.ts +28 -0
  149. package/components/theme/theme.css +234 -0
  150. package/components/toast/demo.html +329 -0
  151. package/components/toast/snice-toast-container.ts +256 -0
  152. package/components/toast/snice-toast.css +213 -0
  153. package/components/toast/snice-toast.ts +276 -0
  154. package/components/toast/snice-toast.types.ts +35 -0
  155. package/components/tooltip/demo.html +350 -0
  156. package/components/tooltip/snice-tooltip-portal.css +79 -0
  157. package/components/tooltip/snice-tooltip.css +117 -0
  158. package/components/tooltip/snice-tooltip.ts +612 -0
  159. package/components/tooltip/snice-tooltip.types.ts +32 -0
  160. package/components/transitions.ts +94 -0
  161. package/components/tsconfig.json +18 -0
  162. package/dist/index.cjs +441 -329
  163. package/dist/index.cjs.map +1 -1
  164. package/dist/index.cjs.min.map +1 -1
  165. package/dist/index.esm.js +441 -329
  166. package/dist/index.esm.js.map +1 -1
  167. package/dist/index.esm.min.js +3 -3
  168. package/dist/index.esm.min.js.map +1 -1
  169. package/dist/index.iife.js +441 -329
  170. package/dist/index.iife.js.map +1 -1
  171. package/dist/index.iife.min.js +3 -3
  172. package/dist/index.iife.min.js.map +1 -1
  173. package/dist/symbols.esm.js +1 -1
  174. package/dist/transitions.esm.js +1 -1
  175. package/dist/types/controller.d.ts +1 -1
  176. package/dist/types/element.d.ts +10 -10
  177. package/dist/types/events.d.ts +2 -2
  178. package/dist/types/index.d.ts +1 -1
  179. package/dist/types/observe.d.ts +1 -1
  180. package/dist/types/request-response.d.ts +2 -3
  181. package/dist/types/router.d.ts +1 -1
  182. package/package.json +9 -3
  183. package/dist/index.cjs.min +0 -15
  184. package/dist/symbols.cjs +0 -103
  185. package/dist/transitions.cjs +0 -219
@@ -0,0 +1,333 @@
1
+ import { element, property, on, dispatch, watch, ready } from 'snice';
2
+
3
+ @element('snice-pagination')
4
+ export class SnicePagination extends HTMLElement {
5
+ @property({ type: Number, reflect: true })
6
+ current = 1;
7
+
8
+ @property({ type: Number, reflect: true })
9
+ total = 1;
10
+
11
+ @property({ type: Number, reflect: true })
12
+ siblings = 1;
13
+
14
+ @property({ type: Boolean, reflect: true })
15
+ showFirst = true;
16
+
17
+ @property({ type: Boolean, reflect: true })
18
+ showLast = true;
19
+
20
+ @property({ type: Boolean, reflect: true })
21
+ showPrev = true;
22
+
23
+ @property({ type: Boolean, reflect: true })
24
+ showNext = true;
25
+
26
+ @property({ reflect: true })
27
+ size: 'small' | 'medium' | 'large' = 'medium';
28
+
29
+ @property({ reflect: true })
30
+ variant: 'default' | 'rounded' | 'text' = 'default';
31
+
32
+ html() {
33
+ const pages = this.getPageNumbers();
34
+
35
+ return /*html*/`
36
+ <nav class="pagination" aria-label="Pagination">
37
+ ${this.showFirst ? /*html*/`
38
+ <button
39
+ class="pagination-button pagination-first"
40
+ ${this.current === 1 ? 'disabled' : ''}
41
+ aria-label="First page">
42
+ <svg width="16" height="16" viewBox="0 0 16 16">
43
+ <path d="M11 12L7 8L11 4M5 4V12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
44
+ </svg>
45
+ </button>
46
+ ` : ''}
47
+
48
+ ${this.showPrev ? /*html*/`
49
+ <button
50
+ class="pagination-button pagination-prev"
51
+ ${this.current === 1 ? 'disabled' : ''}
52
+ aria-label="Previous page">
53
+ <svg width="16" height="16" viewBox="0 0 16 16">
54
+ <path d="M10 12L6 8L10 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
55
+ </svg>
56
+ </button>
57
+ ` : ''}
58
+
59
+ <div class="pagination-pages">
60
+ ${pages.map(page =>
61
+ page === '...'
62
+ ? /*html*/`<span class="pagination-ellipsis">...</span>`
63
+ : /*html*/`
64
+ <button
65
+ class="pagination-button pagination-page ${page === this.current ? 'active' : ''}"
66
+ data-page="${page}"
67
+ aria-label="Page ${page}"
68
+ ${page === this.current ? 'aria-current="page"' : ''}>
69
+ ${page}
70
+ </button>
71
+ `
72
+ ).join('')}
73
+ </div>
74
+
75
+ ${this.showNext ? /*html*/`
76
+ <button
77
+ class="pagination-button pagination-next"
78
+ ${this.current === this.total ? 'disabled' : ''}
79
+ aria-label="Next page">
80
+ <svg width="16" height="16" viewBox="0 0 16 16">
81
+ <path d="M6 12L10 8L6 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
82
+ </svg>
83
+ </button>
84
+ ` : ''}
85
+
86
+ ${this.showLast ? /*html*/`
87
+ <button
88
+ class="pagination-button pagination-last"
89
+ ${this.current === this.total ? 'disabled' : ''}
90
+ aria-label="Last page">
91
+ <svg width="16" height="16" viewBox="0 0 16 16">
92
+ <path d="M5 12L9 8L5 4M11 4V12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
93
+ </svg>
94
+ </button>
95
+ ` : ''}
96
+ </nav>
97
+ `;
98
+ }
99
+
100
+ css() {
101
+ return /*css*/`
102
+ :host {
103
+ display: inline-block;
104
+ --pagination-gap: 4px;
105
+ --pagination-button-size: 32px;
106
+ --pagination-button-padding: 8px;
107
+ --pagination-font-size: 14px;
108
+ --pagination-border-radius: 4px;
109
+ }
110
+
111
+ :host([size="small"]) {
112
+ --pagination-button-size: 28px;
113
+ --pagination-button-padding: 6px;
114
+ --pagination-font-size: 12px;
115
+ }
116
+
117
+ :host([size="large"]) {
118
+ --pagination-button-size: 40px;
119
+ --pagination-button-padding: 10px;
120
+ --pagination-font-size: 16px;
121
+ }
122
+
123
+ :host([variant="rounded"]) {
124
+ --pagination-border-radius: 50%;
125
+ }
126
+
127
+ .pagination {
128
+ display: flex;
129
+ align-items: center;
130
+ gap: var(--pagination-gap);
131
+ }
132
+
133
+ .pagination-pages {
134
+ display: flex;
135
+ align-items: center;
136
+ gap: var(--pagination-gap);
137
+ }
138
+
139
+ .pagination-button {
140
+ display: flex;
141
+ align-items: center;
142
+ justify-content: center;
143
+ min-width: var(--pagination-button-size);
144
+ height: var(--pagination-button-size);
145
+ padding: 0 var(--pagination-button-padding);
146
+ background: white;
147
+ border: 1px solid #e5e7eb;
148
+ border-radius: var(--pagination-border-radius);
149
+ color: #374151;
150
+ font-size: var(--pagination-font-size);
151
+ cursor: pointer;
152
+ transition: all 0.2s;
153
+ font-family: inherit;
154
+ }
155
+
156
+ :host([variant="text"]) .pagination-button {
157
+ background: transparent;
158
+ border: none;
159
+ }
160
+
161
+ .pagination-button:hover:not(:disabled) {
162
+ background: #f3f4f6;
163
+ border-color: #d1d5db;
164
+ }
165
+
166
+ :host([variant="text"]) .pagination-button:hover:not(:disabled) {
167
+ background: #f3f4f6;
168
+ }
169
+
170
+ .pagination-button:disabled {
171
+ opacity: 0.5;
172
+ cursor: not-allowed;
173
+ }
174
+
175
+ .pagination-button.active {
176
+ background: #3b82f6;
177
+ border-color: #3b82f6;
178
+ color: white;
179
+ }
180
+
181
+ .pagination-button.active:hover {
182
+ background: #2563eb;
183
+ border-color: #2563eb;
184
+ }
185
+
186
+ .pagination-ellipsis {
187
+ padding: 0 8px;
188
+ color: #6b7280;
189
+ font-size: var(--pagination-font-size);
190
+ }
191
+
192
+ svg {
193
+ width: 16px;
194
+ height: 16px;
195
+ }
196
+ `;
197
+ }
198
+
199
+ private getPageNumbers(): (number | string)[] {
200
+ const pages: (number | string)[] = [];
201
+ const totalNumbers = this.siblings * 2 + 3;
202
+ const totalBlocks = totalNumbers + 2;
203
+
204
+ if (this.total <= totalBlocks) {
205
+ // Show all pages
206
+ for (let i = 1; i <= this.total; i++) {
207
+ pages.push(i);
208
+ }
209
+ } else {
210
+ const startPage = Math.max(2, this.current - this.siblings);
211
+ const endPage = Math.min(this.total - 1, this.current + this.siblings);
212
+
213
+ // Always show first page
214
+ pages.push(1);
215
+
216
+ // Add ellipsis if needed
217
+ if (startPage > 2) {
218
+ pages.push('...');
219
+ }
220
+
221
+ // Add middle pages
222
+ for (let i = startPage; i <= endPage; i++) {
223
+ pages.push(i);
224
+ }
225
+
226
+ // Add ellipsis if needed
227
+ if (endPage < this.total - 1) {
228
+ pages.push('...');
229
+ }
230
+
231
+ // Always show last page
232
+ pages.push(this.total);
233
+ }
234
+
235
+ return pages;
236
+ }
237
+
238
+ @on('click', '.pagination-first')
239
+ handleFirst() {
240
+ if (this.current !== 1) {
241
+ this.changePage(1);
242
+ }
243
+ }
244
+
245
+ @on('click', '.pagination-prev')
246
+ handlePrev() {
247
+ if (this.current > 1) {
248
+ this.changePage(this.current - 1);
249
+ }
250
+ }
251
+
252
+ @on('click', '.pagination-next')
253
+ handleNext() {
254
+ if (this.current < this.total) {
255
+ this.changePage(this.current + 1);
256
+ }
257
+ }
258
+
259
+ @on('click', '.pagination-last')
260
+ handleLast() {
261
+ if (this.current !== this.total) {
262
+ this.changePage(this.total);
263
+ }
264
+ }
265
+
266
+ @on('click', '.pagination-page')
267
+ handlePageClick(event: Event) {
268
+ const target = event.target as HTMLElement;
269
+ const button = target.closest('.pagination-page') as HTMLButtonElement;
270
+ if (button) {
271
+ const pageAttr = button.getAttribute('data-page');
272
+ if (pageAttr) {
273
+ const page = parseInt(pageAttr);
274
+ if (page !== this.current) {
275
+ this.changePage(page);
276
+ }
277
+ }
278
+ }
279
+ }
280
+
281
+ @dispatch('@snice/pagination-change', { bubbles: true, composed: true })
282
+ private changePage(page: number) {
283
+ const oldPage = this.current;
284
+ this.current = page;
285
+ // Force a re-render by updating the shadow DOM
286
+ this.updateView();
287
+ return {
288
+ page: this.current,
289
+ previousPage: oldPage
290
+ };
291
+ }
292
+
293
+ private updateView() {
294
+ // Update the shadow DOM with new HTML
295
+ if (this.shadowRoot) {
296
+ this.shadowRoot.innerHTML = `
297
+ <style>${this.css()}</style>
298
+ ${this.html()}
299
+ `;
300
+ }
301
+ }
302
+
303
+ // Public API
304
+ goToPage(page: number) {
305
+ if (page >= 1 && page <= this.total && page !== this.current) {
306
+ this.changePage(page);
307
+ }
308
+ }
309
+
310
+ nextPage() {
311
+ if (this.current < this.total) {
312
+ this.changePage(this.current + 1);
313
+ }
314
+ }
315
+
316
+ previousPage() {
317
+ if (this.current > 1) {
318
+ this.changePage(this.current - 1);
319
+ }
320
+ }
321
+
322
+ firstPage() {
323
+ if (this.current !== 1) {
324
+ this.changePage(1);
325
+ }
326
+ }
327
+
328
+ lastPage() {
329
+ if (this.current !== this.total) {
330
+ this.changePage(this.total);
331
+ }
332
+ }
333
+ }
@@ -0,0 +1,21 @@
1
+ export type PaginationSize = 'small' | 'medium' | 'large';
2
+ export type PaginationVariant = 'default' | 'rounded' | 'text';
3
+
4
+ export interface SnicePaginationElement extends HTMLElement {
5
+ current: number;
6
+ total: number;
7
+ siblings: number;
8
+ showFirst: boolean;
9
+ showLast: boolean;
10
+ showPrev: boolean;
11
+ showNext: boolean;
12
+ size: PaginationSize;
13
+ variant: PaginationVariant;
14
+
15
+ // Methods
16
+ goToPage(page: number): void;
17
+ nextPage(): void;
18
+ previousPage(): void;
19
+ firstPage(): void;
20
+ lastPage(): void;
21
+ }